Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /********************************************************************* |
| 2 | * |
| 3 | * Filename: via-ircc.h |
| 4 | * Version: 1.0 |
| 5 | * Description: Driver for the VIA VT8231/VT8233 IrDA chipsets |
| 6 | * Author: VIA Technologies, inc |
| 7 | * Date : 08/06/2003 |
| 8 | |
| 9 | Copyright (c) 1998-2003 VIA Technologies, Inc. |
| 10 | |
| 11 | This program is free software; you can redistribute it and/or modify it under |
| 12 | the terms of the GNU General Public License as published by the Free Software |
| 13 | Foundation; either version 2, or (at your option) any later version. |
| 14 | |
| 15 | This program is distributed in the hope that it will be useful, but WITHOUT |
| 16 | ANY WARRANTIES OR REPRESENTATIONS; without even the implied warranty of |
| 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| 18 | See the GNU General Public License for more details. |
| 19 | |
| 20 | You should have received a copy of the GNU General Public License along with |
| 21 | this program; if not, write to the Free Software Foundation, Inc., |
| 22 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 23 | |
| 24 | * Comment: |
| 25 | * jul/08/2002 : Rx buffer length should use Rx ring ptr. |
| 26 | * Oct/28/2002 : Add SB id for 3147 and 3177. |
| 27 | * jul/09/2002 : only implement two kind of dongle currently. |
| 28 | * Oct/02/2002 : work on VT8231 and VT8233 . |
| 29 | * Aug/06/2003 : change driver format to pci driver . |
| 30 | ********************************************************************/ |
| 31 | #ifndef via_IRCC_H |
| 32 | #define via_IRCC_H |
| 33 | #include <linux/time.h> |
| 34 | #include <linux/spinlock.h> |
| 35 | #include <linux/pm.h> |
| 36 | #include <linux/types.h> |
| 37 | #include <asm/io.h> |
| 38 | |
| 39 | #define MAX_TX_WINDOW 7 |
| 40 | #define MAX_RX_WINDOW 7 |
| 41 | |
| 42 | struct st_fifo_entry { |
| 43 | int status; |
| 44 | int len; |
| 45 | }; |
| 46 | |
| 47 | struct st_fifo { |
| 48 | struct st_fifo_entry entries[MAX_RX_WINDOW + 2]; |
| 49 | int pending_bytes; |
| 50 | int head; |
| 51 | int tail; |
| 52 | int len; |
| 53 | }; |
| 54 | |
| 55 | struct frame_cb { |
| 56 | void *start; /* Start of frame in DMA mem */ |
Paulius Zaleckas | efad798b | 2008-02-03 15:42:53 +0200 | [diff] [blame] | 57 | int len; /* Length of frame in DMA mem */ |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 58 | }; |
| 59 | |
| 60 | struct tx_fifo { |
| 61 | struct frame_cb queue[MAX_TX_WINDOW + 2]; /* Info about frames in queue */ |
| 62 | int ptr; /* Currently being sent */ |
Paulius Zaleckas | efad798b | 2008-02-03 15:42:53 +0200 | [diff] [blame] | 63 | int len; /* Length of queue */ |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 64 | int free; /* Next free slot */ |
| 65 | void *tail; /* Next free start in DMA mem */ |
| 66 | }; |
| 67 | |
| 68 | |
| 69 | struct eventflag // for keeping track of Interrupt Events |
| 70 | { |
| 71 | //--------tx part |
| 72 | unsigned char TxFIFOUnderRun; |
| 73 | unsigned char EOMessage; |
| 74 | unsigned char TxFIFOReady; |
| 75 | unsigned char EarlyEOM; |
| 76 | //--------rx part |
| 77 | unsigned char PHYErr; |
| 78 | unsigned char CRCErr; |
| 79 | unsigned char RxFIFOOverRun; |
| 80 | unsigned char EOPacket; |
| 81 | unsigned char RxAvail; |
| 82 | unsigned char TooLargePacket; |
| 83 | unsigned char SIRBad; |
| 84 | //--------unknown |
| 85 | unsigned char Unknown; |
| 86 | //---------- |
| 87 | unsigned char TimeOut; |
| 88 | unsigned char RxDMATC; |
| 89 | unsigned char TxDMATC; |
| 90 | }; |
| 91 | |
| 92 | /* Private data for each instance */ |
| 93 | struct via_ircc_cb { |
| 94 | struct st_fifo st_fifo; /* Info about received frames */ |
| 95 | struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ |
| 96 | |
| 97 | struct net_device *netdev; /* Yes! we are some kind of netdevice */ |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 98 | |
| 99 | struct irlap_cb *irlap; /* The link layer we are binded to */ |
| 100 | struct qos_info qos; /* QoS capabilities for this device */ |
| 101 | |
| 102 | chipio_t io; /* IrDA controller information */ |
| 103 | iobuff_t tx_buff; /* Transmit buffer */ |
| 104 | iobuff_t rx_buff; /* Receive buffer */ |
| 105 | dma_addr_t tx_buff_dma; |
| 106 | dma_addr_t rx_buff_dma; |
| 107 | |
| 108 | __u8 ier; /* Interrupt enable register */ |
| 109 | |
| 110 | struct timeval stamp; |
| 111 | struct timeval now; |
| 112 | |
| 113 | spinlock_t lock; /* For serializing operations */ |
| 114 | |
| 115 | __u32 flags; /* Interface flags */ |
| 116 | __u32 new_speed; |
| 117 | int index; /* Instance index */ |
| 118 | |
| 119 | struct eventflag EventFlag; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 120 | unsigned int chip_id; /* to remember chip id */ |
| 121 | unsigned int RetryCount; |
| 122 | unsigned int RxDataReady; |
| 123 | unsigned int RxLastCount; |
| 124 | }; |
| 125 | |
| 126 | |
| 127 | //---------I=Infrared, H=Host, M=Misc, T=Tx, R=Rx, ST=Status, |
| 128 | // CF=Config, CT=Control, L=Low, H=High, C=Count |
| 129 | #define I_CF_L_0 0x10 |
| 130 | #define I_CF_H_0 0x11 |
| 131 | #define I_SIR_BOF 0x12 |
| 132 | #define I_SIR_EOF 0x13 |
| 133 | #define I_ST_CT_0 0x15 |
| 134 | #define I_ST_L_1 0x16 |
| 135 | #define I_ST_H_1 0x17 |
| 136 | #define I_CF_L_1 0x18 |
| 137 | #define I_CF_H_1 0x19 |
| 138 | #define I_CF_L_2 0x1a |
| 139 | #define I_CF_H_2 0x1b |
| 140 | #define I_CF_3 0x1e |
| 141 | #define H_CT 0x20 |
| 142 | #define H_ST 0x21 |
| 143 | #define M_CT 0x22 |
| 144 | #define TX_CT_1 0x23 |
| 145 | #define TX_CT_2 0x24 |
| 146 | #define TX_ST 0x25 |
| 147 | #define RX_CT 0x26 |
| 148 | #define RX_ST 0x27 |
| 149 | #define RESET 0x28 |
| 150 | #define P_ADDR 0x29 |
| 151 | #define RX_C_L 0x2a |
| 152 | #define RX_C_H 0x2b |
| 153 | #define RX_P_L 0x2c |
| 154 | #define RX_P_H 0x2d |
| 155 | #define TX_C_L 0x2e |
| 156 | #define TX_C_H 0x2f |
| 157 | #define TIMER 0x32 |
| 158 | #define I_CF_4 0x33 |
| 159 | #define I_T_C_L 0x34 |
| 160 | #define I_T_C_H 0x35 |
| 161 | #define VERSION 0x3f |
| 162 | //------------------------------- |
| 163 | #define StartAddr 0x10 // the first register address |
| 164 | #define EndAddr 0x3f // the last register address |
| 165 | #define GetBit(val,bit) val = (unsigned char) ((val>>bit) & 0x1) |
| 166 | // Returns the bit |
| 167 | #define SetBit(val,bit) val= (unsigned char ) (val | (0x1 << bit)) |
| 168 | // Sets bit to 1 |
| 169 | #define ResetBit(val,bit) val= (unsigned char ) (val & ~(0x1 << bit)) |
| 170 | // Sets bit to 0 |
| 171 | |
| 172 | #define OFF 0 |
| 173 | #define ON 1 |
| 174 | #define DMA_TX_MODE 0x08 |
| 175 | #define DMA_RX_MODE 0x04 |
| 176 | |
| 177 | #define DMA1 0 |
| 178 | #define DMA2 0xc0 |
| 179 | #define MASK1 DMA1+0x0a |
| 180 | #define MASK2 DMA2+0x14 |
| 181 | |
| 182 | #define Clk_bit 0x40 |
| 183 | #define Tx_bit 0x01 |
| 184 | #define Rd_Valid 0x08 |
| 185 | #define RxBit 0x08 |
| 186 | |
| 187 | static void DisableDmaChannel(unsigned int channel) |
| 188 | { |
| 189 | switch (channel) { // 8 Bit DMA channels DMAC1 |
| 190 | case 0: |
| 191 | outb(4, MASK1); //mask channel 0 |
| 192 | break; |
| 193 | case 1: |
| 194 | outb(5, MASK1); //Mask channel 1 |
| 195 | break; |
| 196 | case 2: |
| 197 | outb(6, MASK1); //Mask channel 2 |
| 198 | break; |
| 199 | case 3: |
| 200 | outb(7, MASK1); //Mask channel 3 |
| 201 | break; |
| 202 | case 5: |
| 203 | outb(5, MASK2); //Mask channel 5 |
| 204 | break; |
| 205 | case 6: |
| 206 | outb(6, MASK2); //Mask channel 6 |
| 207 | break; |
| 208 | case 7: |
| 209 | outb(7, MASK2); //Mask channel 7 |
| 210 | break; |
| 211 | default: |
| 212 | break; |
| 213 | }; //Switch |
| 214 | } |
| 215 | |
| 216 | static unsigned char ReadLPCReg(int iRegNum) |
| 217 | { |
| 218 | unsigned char iVal; |
| 219 | |
| 220 | outb(0x87, 0x2e); |
| 221 | outb(0x87, 0x2e); |
| 222 | outb(iRegNum, 0x2e); |
| 223 | iVal = inb(0x2f); |
| 224 | outb(0xaa, 0x2e); |
| 225 | |
| 226 | return iVal; |
| 227 | } |
| 228 | |
| 229 | static void WriteLPCReg(int iRegNum, unsigned char iVal) |
| 230 | { |
| 231 | |
| 232 | outb(0x87, 0x2e); |
| 233 | outb(0x87, 0x2e); |
| 234 | outb(iRegNum, 0x2e); |
| 235 | outb(iVal, 0x2f); |
| 236 | outb(0xAA, 0x2e); |
| 237 | } |
| 238 | |
| 239 | static __u8 ReadReg(unsigned int BaseAddr, int iRegNum) |
| 240 | { |
| 241 | return ((__u8) inb(BaseAddr + iRegNum)); |
| 242 | } |
| 243 | |
| 244 | static void WriteReg(unsigned int BaseAddr, int iRegNum, unsigned char iVal) |
| 245 | { |
| 246 | outb(iVal, BaseAddr + iRegNum); |
| 247 | } |
| 248 | |
| 249 | static int WriteRegBit(unsigned int BaseAddr, unsigned char RegNum, |
| 250 | unsigned char BitPos, unsigned char value) |
| 251 | { |
| 252 | __u8 Rtemp, Wtemp; |
| 253 | |
| 254 | if (BitPos > 7) { |
| 255 | return -1; |
| 256 | } |
| 257 | if ((RegNum < StartAddr) || (RegNum > EndAddr)) |
| 258 | return -1; |
| 259 | Rtemp = ReadReg(BaseAddr, RegNum); |
| 260 | if (value == 0) |
| 261 | Wtemp = ResetBit(Rtemp, BitPos); |
| 262 | else { |
| 263 | if (value == 1) |
| 264 | Wtemp = SetBit(Rtemp, BitPos); |
| 265 | else |
| 266 | return -1; |
| 267 | } |
| 268 | WriteReg(BaseAddr, RegNum, Wtemp); |
| 269 | return 0; |
| 270 | } |
| 271 | |
| 272 | static __u8 CheckRegBit(unsigned int BaseAddr, unsigned char RegNum, |
| 273 | unsigned char BitPos) |
| 274 | { |
| 275 | __u8 temp; |
| 276 | |
| 277 | if (BitPos > 7) |
| 278 | return 0xff; |
| 279 | if ((RegNum < StartAddr) || (RegNum > EndAddr)) { |
| 280 | // printf("what is the register %x!\n",RegNum); |
| 281 | } |
| 282 | temp = ReadReg(BaseAddr, RegNum); |
| 283 | return GetBit(temp, BitPos); |
| 284 | } |
| 285 | |
| 286 | static void SetMaxRxPacketSize(__u16 iobase, __u16 size) |
| 287 | { |
| 288 | __u16 low, high; |
| 289 | if ((size & 0xe000) == 0) { |
| 290 | low = size & 0x00ff; |
| 291 | high = (size & 0x1f00) >> 8; |
| 292 | WriteReg(iobase, I_CF_L_2, low); |
| 293 | WriteReg(iobase, I_CF_H_2, high); |
| 294 | |
| 295 | } |
| 296 | |
| 297 | } |
| 298 | |
| 299 | //for both Rx and Tx |
| 300 | |
| 301 | static void SetFIFO(__u16 iobase, __u16 value) |
| 302 | { |
| 303 | switch (value) { |
| 304 | case 128: |
| 305 | WriteRegBit(iobase, 0x11, 0, 0); |
| 306 | WriteRegBit(iobase, 0x11, 7, 1); |
| 307 | break; |
| 308 | case 64: |
| 309 | WriteRegBit(iobase, 0x11, 0, 0); |
| 310 | WriteRegBit(iobase, 0x11, 7, 0); |
| 311 | break; |
| 312 | case 32: |
| 313 | WriteRegBit(iobase, 0x11, 0, 1); |
| 314 | WriteRegBit(iobase, 0x11, 7, 0); |
| 315 | break; |
| 316 | default: |
| 317 | WriteRegBit(iobase, 0x11, 0, 0); |
| 318 | WriteRegBit(iobase, 0x11, 7, 0); |
| 319 | } |
| 320 | |
| 321 | } |
| 322 | |
| 323 | #define CRC16(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,7,val) //0 for 32 CRC |
| 324 | /* |
| 325 | #define SetVFIR(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_H_0,5,val) |
| 326 | #define SetFIR(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,6,val) |
| 327 | #define SetMIR(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,5,val) |
| 328 | #define SetSIR(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,4,val) |
| 329 | */ |
| 330 | #define SIRFilter(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,3,val) |
| 331 | #define Filter(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,2,val) |
| 332 | #define InvertTX(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,1,val) |
| 333 | #define InvertRX(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_L_0,0,val) |
| 334 | //****************************I_CF_H_0 |
| 335 | #define EnableTX(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_H_0,4,val) |
| 336 | #define EnableRX(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_H_0,3,val) |
| 337 | #define EnableDMA(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_H_0,2,val) |
| 338 | #define SIRRecvAny(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_H_0,1,val) |
| 339 | #define DiableTrans(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_H_0,0,val) |
| 340 | //***************************I_SIR_BOF,I_SIR_EOF |
| 341 | #define SetSIRBOF(BaseAddr,val) WriteReg(BaseAddr,I_SIR_BOF,val) |
| 342 | #define SetSIREOF(BaseAddr,val) WriteReg(BaseAddr,I_SIR_EOF,val) |
| 343 | #define GetSIRBOF(BaseAddr) ReadReg(BaseAddr,I_SIR_BOF) |
| 344 | #define GetSIREOF(BaseAddr) ReadReg(BaseAddr,I_SIR_EOF) |
| 345 | //*******************I_ST_CT_0 |
| 346 | #define EnPhys(BaseAddr,val) WriteRegBit(BaseAddr,I_ST_CT_0,7,val) |
| 347 | #define IsModeError(BaseAddr) CheckRegBit(BaseAddr,I_ST_CT_0,6) //RO |
| 348 | #define IsVFIROn(BaseAddr) CheckRegBit(BaseAddr,0x14,0) //RO for VT1211 only |
| 349 | #define IsFIROn(BaseAddr) CheckRegBit(BaseAddr,I_ST_CT_0,5) //RO |
| 350 | #define IsMIROn(BaseAddr) CheckRegBit(BaseAddr,I_ST_CT_0,4) //RO |
| 351 | #define IsSIROn(BaseAddr) CheckRegBit(BaseAddr,I_ST_CT_0,3) //RO |
| 352 | #define IsEnableTX(BaseAddr) CheckRegBit(BaseAddr,I_ST_CT_0,2) //RO |
| 353 | #define IsEnableRX(BaseAddr) CheckRegBit(BaseAddr,I_ST_CT_0,1) //RO |
| 354 | #define Is16CRC(BaseAddr) CheckRegBit(BaseAddr,I_ST_CT_0,0) //RO |
| 355 | //***************************I_CF_3 |
| 356 | #define DisableAdjacentPulseWidth(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_3,5,val) //1 disable |
| 357 | #define DisablePulseWidthAdjust(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_3,4,val) //1 disable |
| 358 | #define UseOneRX(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_3,1,val) //0 use two RX |
| 359 | #define SlowIRRXLowActive(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_3,0,val) //0 show RX high=1 in SIR |
| 360 | //***************************H_CT |
| 361 | #define EnAllInt(BaseAddr,val) WriteRegBit(BaseAddr,H_CT,7,val) |
| 362 | #define TXStart(BaseAddr,val) WriteRegBit(BaseAddr,H_CT,6,val) |
| 363 | #define RXStart(BaseAddr,val) WriteRegBit(BaseAddr,H_CT,5,val) |
| 364 | #define ClearRXInt(BaseAddr,val) WriteRegBit(BaseAddr,H_CT,4,val) // 1 clear |
| 365 | //*****************H_ST |
| 366 | #define IsRXInt(BaseAddr) CheckRegBit(BaseAddr,H_ST,4) |
| 367 | #define GetIntIndentify(BaseAddr) ((ReadReg(BaseAddr,H_ST)&0xf1) >>1) |
| 368 | #define IsHostBusy(BaseAddr) CheckRegBit(BaseAddr,H_ST,0) |
| 369 | #define GetHostStatus(BaseAddr) ReadReg(BaseAddr,H_ST) //RO |
| 370 | //**************************M_CT |
| 371 | #define EnTXDMA(BaseAddr,val) WriteRegBit(BaseAddr,M_CT,7,val) |
| 372 | #define EnRXDMA(BaseAddr,val) WriteRegBit(BaseAddr,M_CT,6,val) |
| 373 | #define SwapDMA(BaseAddr,val) WriteRegBit(BaseAddr,M_CT,5,val) |
| 374 | #define EnInternalLoop(BaseAddr,val) WriteRegBit(BaseAddr,M_CT,4,val) |
| 375 | #define EnExternalLoop(BaseAddr,val) WriteRegBit(BaseAddr,M_CT,3,val) |
| 376 | //**************************TX_CT_1 |
| 377 | #define EnTXFIFOHalfLevelInt(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_1,4,val) //half empty int (1 half) |
| 378 | #define EnTXFIFOUnderrunEOMInt(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_1,5,val) |
| 379 | #define EnTXFIFOReadyInt(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_1,6,val) //int when reach it threshold (setting by bit 4) |
| 380 | //**************************TX_CT_2 |
| 381 | #define ForceUnderrun(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_2,7,val) // force an underrun int |
| 382 | #define EnTXCRC(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_2,6,val) //1 for FIR,MIR...0 (not SIR) |
| 383 | #define ForceBADCRC(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_2,5,val) //force an bad CRC |
| 384 | #define SendSIP(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_2,4,val) //send indication pulse for prevent SIR disturb |
| 385 | #define ClearEnTX(BaseAddr,val) WriteRegBit(BaseAddr,TX_CT_2,3,val) // opposite to EnTX |
| 386 | //*****************TX_ST |
| 387 | #define GetTXStatus(BaseAddr) ReadReg(BaseAddr,TX_ST) //RO |
| 388 | //**************************RX_CT |
| 389 | #define EnRXSpecInt(BaseAddr,val) WriteRegBit(BaseAddr,RX_CT,0,val) |
| 390 | #define EnRXFIFOReadyInt(BaseAddr,val) WriteRegBit(BaseAddr,RX_CT,1,val) //enable int when reach it threshold (setting by bit 7) |
| 391 | #define EnRXFIFOHalfLevelInt(BaseAddr,val) WriteRegBit(BaseAddr,RX_CT,7,val) //enable int when (1) half full...or (0) just not full |
| 392 | //*****************RX_ST |
| 393 | #define GetRXStatus(BaseAddr) ReadReg(BaseAddr,RX_ST) //RO |
| 394 | //***********************P_ADDR |
| 395 | #define SetPacketAddr(BaseAddr,addr) WriteReg(BaseAddr,P_ADDR,addr) |
| 396 | //***********************I_CF_4 |
| 397 | #define EnGPIOtoRX2(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_4,7,val) |
| 398 | #define EnTimerInt(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_4,1,val) |
| 399 | #define ClearTimerInt(BaseAddr,val) WriteRegBit(BaseAddr,I_CF_4,0,val) |
| 400 | //***********************I_T_C_L |
| 401 | #define WriteGIO(BaseAddr,val) WriteRegBit(BaseAddr,I_T_C_L,7,val) |
| 402 | #define ReadGIO(BaseAddr) CheckRegBit(BaseAddr,I_T_C_L,7) |
| 403 | #define ReadRX(BaseAddr) CheckRegBit(BaseAddr,I_T_C_L,3) //RO |
| 404 | #define WriteTX(BaseAddr,val) WriteRegBit(BaseAddr,I_T_C_L,0,val) |
| 405 | //***********************I_T_C_H |
| 406 | #define EnRX2(BaseAddr,val) WriteRegBit(BaseAddr,I_T_C_H,7,val) |
| 407 | #define ReadRX2(BaseAddr) CheckRegBit(BaseAddr,I_T_C_H,7) |
| 408 | //**********************Version |
| 409 | #define GetFIRVersion(BaseAddr) ReadReg(BaseAddr,VERSION) |
| 410 | |
| 411 | |
| 412 | static void SetTimer(__u16 iobase, __u8 count) |
| 413 | { |
| 414 | EnTimerInt(iobase, OFF); |
| 415 | WriteReg(iobase, TIMER, count); |
| 416 | EnTimerInt(iobase, ON); |
| 417 | } |
| 418 | |
| 419 | |
| 420 | static void SetSendByte(__u16 iobase, __u32 count) |
| 421 | { |
| 422 | __u32 low, high; |
| 423 | |
| 424 | if ((count & 0xf000) == 0) { |
| 425 | low = count & 0x00ff; |
| 426 | high = (count & 0x0f00) >> 8; |
| 427 | WriteReg(iobase, TX_C_L, low); |
| 428 | WriteReg(iobase, TX_C_H, high); |
| 429 | } |
| 430 | } |
| 431 | |
| 432 | static void ResetChip(__u16 iobase, __u8 type) |
| 433 | { |
| 434 | __u8 value; |
| 435 | |
| 436 | value = (type + 2) << 4; |
| 437 | WriteReg(iobase, RESET, type); |
| 438 | } |
| 439 | |
| 440 | static int CkRxRecv(__u16 iobase, struct via_ircc_cb *self) |
| 441 | { |
| 442 | __u8 low, high; |
| 443 | __u16 wTmp = 0, wTmp1 = 0, wTmp_new = 0; |
| 444 | |
| 445 | low = ReadReg(iobase, RX_C_L); |
| 446 | high = ReadReg(iobase, RX_C_H); |
| 447 | wTmp1 = high; |
| 448 | wTmp = (wTmp1 << 8) | low; |
| 449 | udelay(10); |
| 450 | low = ReadReg(iobase, RX_C_L); |
| 451 | high = ReadReg(iobase, RX_C_H); |
| 452 | wTmp1 = high; |
| 453 | wTmp_new = (wTmp1 << 8) | low; |
| 454 | if (wTmp_new != wTmp) |
| 455 | return 1; |
| 456 | else |
| 457 | return 0; |
| 458 | |
| 459 | } |
| 460 | |
| 461 | static __u16 RxCurCount(__u16 iobase, struct via_ircc_cb * self) |
| 462 | { |
| 463 | __u8 low, high; |
| 464 | __u16 wTmp = 0, wTmp1 = 0; |
| 465 | |
| 466 | low = ReadReg(iobase, RX_P_L); |
| 467 | high = ReadReg(iobase, RX_P_H); |
| 468 | wTmp1 = high; |
| 469 | wTmp = (wTmp1 << 8) | low; |
| 470 | return wTmp; |
| 471 | } |
| 472 | |
| 473 | /* This Routine can only use in recevie_complete |
| 474 | * for it will update last count. |
| 475 | */ |
| 476 | |
| 477 | static __u16 GetRecvByte(__u16 iobase, struct via_ircc_cb * self) |
| 478 | { |
| 479 | __u8 low, high; |
| 480 | __u16 wTmp, wTmp1, ret; |
| 481 | |
| 482 | low = ReadReg(iobase, RX_P_L); |
| 483 | high = ReadReg(iobase, RX_P_H); |
| 484 | wTmp1 = high; |
| 485 | wTmp = (wTmp1 << 8) | low; |
| 486 | |
| 487 | |
| 488 | if (wTmp >= self->RxLastCount) |
| 489 | ret = wTmp - self->RxLastCount; |
| 490 | else |
| 491 | ret = (0x8000 - self->RxLastCount) + wTmp; |
| 492 | self->RxLastCount = wTmp; |
| 493 | |
| 494 | /* RX_P is more actually the RX_C |
| 495 | low=ReadReg(iobase,RX_C_L); |
| 496 | high=ReadReg(iobase,RX_C_H); |
| 497 | |
| 498 | if(!(high&0xe000)) { |
| 499 | temp=(high<<8)+low; |
| 500 | return temp; |
| 501 | } |
| 502 | else return 0; |
| 503 | */ |
| 504 | return ret; |
| 505 | } |
| 506 | |
| 507 | static void Sdelay(__u16 scale) |
| 508 | { |
| 509 | __u8 bTmp; |
| 510 | int i, j; |
| 511 | |
| 512 | for (j = 0; j < scale; j++) { |
| 513 | for (i = 0; i < 0x20; i++) { |
| 514 | bTmp = inb(0xeb); |
| 515 | outb(bTmp, 0xeb); |
| 516 | } |
| 517 | } |
| 518 | } |
| 519 | |
| 520 | static void Tdelay(__u16 scale) |
| 521 | { |
| 522 | __u8 bTmp; |
| 523 | int i, j; |
| 524 | |
| 525 | for (j = 0; j < scale; j++) { |
| 526 | for (i = 0; i < 0x50; i++) { |
| 527 | bTmp = inb(0xeb); |
| 528 | outb(bTmp, 0xeb); |
| 529 | } |
| 530 | } |
| 531 | } |
| 532 | |
| 533 | |
| 534 | static void ActClk(__u16 iobase, __u8 value) |
| 535 | { |
| 536 | __u8 bTmp; |
| 537 | bTmp = ReadReg(iobase, 0x34); |
| 538 | if (value) |
| 539 | WriteReg(iobase, 0x34, bTmp | Clk_bit); |
| 540 | else |
| 541 | WriteReg(iobase, 0x34, bTmp & ~Clk_bit); |
| 542 | } |
| 543 | |
| 544 | static void ClkTx(__u16 iobase, __u8 Clk, __u8 Tx) |
| 545 | { |
| 546 | __u8 bTmp; |
| 547 | |
| 548 | bTmp = ReadReg(iobase, 0x34); |
| 549 | if (Clk == 0) |
| 550 | bTmp &= ~Clk_bit; |
| 551 | else { |
| 552 | if (Clk == 1) |
| 553 | bTmp |= Clk_bit; |
| 554 | } |
| 555 | WriteReg(iobase, 0x34, bTmp); |
| 556 | Sdelay(1); |
| 557 | if (Tx == 0) |
| 558 | bTmp &= ~Tx_bit; |
| 559 | else { |
| 560 | if (Tx == 1) |
| 561 | bTmp |= Tx_bit; |
| 562 | } |
| 563 | WriteReg(iobase, 0x34, bTmp); |
| 564 | } |
| 565 | |
| 566 | static void Wr_Byte(__u16 iobase, __u8 data) |
| 567 | { |
| 568 | __u8 bData = data; |
| 569 | // __u8 btmp; |
| 570 | int i; |
| 571 | |
| 572 | ClkTx(iobase, 0, 1); |
| 573 | |
| 574 | Tdelay(2); |
| 575 | ActClk(iobase, 1); |
| 576 | Tdelay(1); |
| 577 | |
| 578 | for (i = 0; i < 8; i++) { //LDN |
| 579 | |
| 580 | if ((bData >> i) & 0x01) { |
| 581 | ClkTx(iobase, 0, 1); //bit data = 1; |
| 582 | } else { |
| 583 | ClkTx(iobase, 0, 0); //bit data = 1; |
| 584 | } |
| 585 | Tdelay(2); |
| 586 | Sdelay(1); |
| 587 | ActClk(iobase, 1); //clk hi |
| 588 | Tdelay(1); |
| 589 | } |
| 590 | } |
| 591 | |
| 592 | static __u8 Rd_Indx(__u16 iobase, __u8 addr, __u8 index) |
| 593 | { |
| 594 | __u8 data = 0, bTmp, data_bit; |
| 595 | int i; |
| 596 | |
| 597 | bTmp = addr | (index << 1) | 0; |
| 598 | ClkTx(iobase, 0, 0); |
| 599 | Tdelay(2); |
| 600 | ActClk(iobase, 1); |
| 601 | udelay(1); |
| 602 | Wr_Byte(iobase, bTmp); |
| 603 | Sdelay(1); |
| 604 | ClkTx(iobase, 0, 0); |
| 605 | Tdelay(2); |
| 606 | for (i = 0; i < 10; i++) { |
| 607 | ActClk(iobase, 1); |
| 608 | Tdelay(1); |
| 609 | ActClk(iobase, 0); |
| 610 | Tdelay(1); |
| 611 | ClkTx(iobase, 0, 1); |
| 612 | Tdelay(1); |
| 613 | bTmp = ReadReg(iobase, 0x34); |
| 614 | if (!(bTmp & Rd_Valid)) |
| 615 | break; |
| 616 | } |
| 617 | if (!(bTmp & Rd_Valid)) { |
| 618 | for (i = 0; i < 8; i++) { |
| 619 | ActClk(iobase, 1); |
| 620 | Tdelay(1); |
| 621 | ActClk(iobase, 0); |
| 622 | bTmp = ReadReg(iobase, 0x34); |
| 623 | data_bit = 1 << i; |
| 624 | if (bTmp & RxBit) |
| 625 | data |= data_bit; |
| 626 | else |
| 627 | data &= ~data_bit; |
| 628 | Tdelay(2); |
| 629 | } |
| 630 | } else { |
| 631 | for (i = 0; i < 2; i++) { |
| 632 | ActClk(iobase, 1); |
| 633 | Tdelay(1); |
| 634 | ActClk(iobase, 0); |
| 635 | Tdelay(2); |
| 636 | } |
| 637 | bTmp = ReadReg(iobase, 0x34); |
| 638 | } |
| 639 | for (i = 0; i < 1; i++) { |
| 640 | ActClk(iobase, 1); |
| 641 | Tdelay(1); |
| 642 | ActClk(iobase, 0); |
| 643 | Tdelay(2); |
| 644 | } |
| 645 | ClkTx(iobase, 0, 0); |
| 646 | Tdelay(1); |
| 647 | for (i = 0; i < 3; i++) { |
| 648 | ActClk(iobase, 1); |
| 649 | Tdelay(1); |
| 650 | ActClk(iobase, 0); |
| 651 | Tdelay(2); |
| 652 | } |
| 653 | return data; |
| 654 | } |
| 655 | |
| 656 | static void Wr_Indx(__u16 iobase, __u8 addr, __u8 index, __u8 data) |
| 657 | { |
| 658 | int i; |
| 659 | __u8 bTmp; |
| 660 | |
| 661 | ClkTx(iobase, 0, 0); |
| 662 | udelay(2); |
| 663 | ActClk(iobase, 1); |
| 664 | udelay(1); |
| 665 | bTmp = addr | (index << 1) | 1; |
| 666 | Wr_Byte(iobase, bTmp); |
| 667 | Wr_Byte(iobase, data); |
| 668 | for (i = 0; i < 2; i++) { |
| 669 | ClkTx(iobase, 0, 0); |
| 670 | Tdelay(2); |
| 671 | ActClk(iobase, 1); |
| 672 | Tdelay(1); |
| 673 | } |
| 674 | ActClk(iobase, 0); |
| 675 | } |
| 676 | |
| 677 | static void ResetDongle(__u16 iobase) |
| 678 | { |
| 679 | int i; |
| 680 | ClkTx(iobase, 0, 0); |
| 681 | Tdelay(1); |
| 682 | for (i = 0; i < 30; i++) { |
| 683 | ActClk(iobase, 1); |
| 684 | Tdelay(1); |
| 685 | ActClk(iobase, 0); |
| 686 | Tdelay(1); |
| 687 | } |
| 688 | ActClk(iobase, 0); |
| 689 | } |
| 690 | |
| 691 | static void SetSITmode(__u16 iobase) |
| 692 | { |
| 693 | |
| 694 | __u8 bTmp; |
| 695 | |
| 696 | bTmp = ReadLPCReg(0x28); |
| 697 | WriteLPCReg(0x28, bTmp | 0x10); //select ITMOFF |
| 698 | bTmp = ReadReg(iobase, 0x35); |
| 699 | WriteReg(iobase, 0x35, bTmp | 0x40); // Driver ITMOFF |
| 700 | WriteReg(iobase, 0x28, bTmp | 0x80); // enable All interrupt |
| 701 | } |
| 702 | |
| 703 | static void SI_SetMode(__u16 iobase, int mode) |
| 704 | { |
| 705 | //__u32 dTmp; |
| 706 | __u8 bTmp; |
| 707 | |
| 708 | WriteLPCReg(0x28, 0x70); // S/W Reset |
| 709 | SetSITmode(iobase); |
| 710 | ResetDongle(iobase); |
| 711 | udelay(10); |
| 712 | Wr_Indx(iobase, 0x40, 0x0, 0x17); //RX ,APEN enable,Normal power |
| 713 | Wr_Indx(iobase, 0x40, 0x1, mode); //Set Mode |
| 714 | Wr_Indx(iobase, 0x40, 0x2, 0xff); //Set power to FIR VFIR > 1m |
| 715 | bTmp = Rd_Indx(iobase, 0x40, 1); |
| 716 | } |
| 717 | |
| 718 | static void InitCard(__u16 iobase) |
| 719 | { |
| 720 | ResetChip(iobase, 5); |
| 721 | WriteReg(iobase, I_ST_CT_0, 0x00); // open CHIP on |
| 722 | SetSIRBOF(iobase, 0xc0); // hardware default value |
| 723 | SetSIREOF(iobase, 0xc1); |
| 724 | } |
| 725 | |
| 726 | static void CommonInit(__u16 iobase) |
| 727 | { |
| 728 | // EnTXCRC(iobase,0); |
| 729 | SwapDMA(iobase, OFF); |
| 730 | SetMaxRxPacketSize(iobase, 0x0fff); //set to max:4095 |
| 731 | EnRXFIFOReadyInt(iobase, OFF); |
| 732 | EnRXFIFOHalfLevelInt(iobase, OFF); |
| 733 | EnTXFIFOHalfLevelInt(iobase, OFF); |
| 734 | EnTXFIFOUnderrunEOMInt(iobase, ON); |
| 735 | // EnTXFIFOReadyInt(iobase,ON); |
| 736 | InvertTX(iobase, OFF); |
| 737 | InvertRX(iobase, OFF); |
| 738 | // WriteLPCReg(0xF0,0); //(if VT1211 then do this) |
| 739 | if (IsSIROn(iobase)) { |
| 740 | SIRFilter(iobase, ON); |
| 741 | SIRRecvAny(iobase, ON); |
| 742 | } else { |
| 743 | SIRFilter(iobase, OFF); |
| 744 | SIRRecvAny(iobase, OFF); |
| 745 | } |
| 746 | EnRXSpecInt(iobase, ON); |
| 747 | WriteReg(iobase, I_ST_CT_0, 0x80); |
| 748 | EnableDMA(iobase, ON); |
| 749 | } |
| 750 | |
| 751 | static void SetBaudRate(__u16 iobase, __u32 rate) |
| 752 | { |
| 753 | __u8 value = 11, temp; |
| 754 | |
| 755 | if (IsSIROn(iobase)) { |
| 756 | switch (rate) { |
| 757 | case (__u32) (2400L): |
| 758 | value = 47; |
| 759 | break; |
| 760 | case (__u32) (9600L): |
| 761 | value = 11; |
| 762 | break; |
| 763 | case (__u32) (19200L): |
| 764 | value = 5; |
| 765 | break; |
| 766 | case (__u32) (38400L): |
| 767 | value = 2; |
| 768 | break; |
| 769 | case (__u32) (57600L): |
| 770 | value = 1; |
| 771 | break; |
| 772 | case (__u32) (115200L): |
| 773 | value = 0; |
| 774 | break; |
| 775 | default: |
| 776 | break; |
| 777 | }; |
| 778 | } else if (IsMIROn(iobase)) { |
| 779 | value = 0; // will automatically be fixed in 1.152M |
| 780 | } else if (IsFIROn(iobase)) { |
| 781 | value = 0; // will automatically be fixed in 4M |
| 782 | } |
| 783 | temp = (ReadReg(iobase, I_CF_H_1) & 0x03); |
| 784 | temp |= value << 2; |
| 785 | WriteReg(iobase, I_CF_H_1, temp); |
| 786 | } |
| 787 | |
| 788 | static void SetPulseWidth(__u16 iobase, __u8 width) |
| 789 | { |
| 790 | __u8 temp, temp1, temp2; |
| 791 | |
| 792 | temp = (ReadReg(iobase, I_CF_L_1) & 0x1f); |
| 793 | temp1 = (ReadReg(iobase, I_CF_H_1) & 0xfc); |
| 794 | temp2 = (width & 0x07) << 5; |
| 795 | temp |= temp2; |
| 796 | temp2 = (width & 0x18) >> 3; |
| 797 | temp1 |= temp2; |
| 798 | WriteReg(iobase, I_CF_L_1, temp); |
| 799 | WriteReg(iobase, I_CF_H_1, temp1); |
| 800 | } |
| 801 | |
| 802 | static void SetSendPreambleCount(__u16 iobase, __u8 count) |
| 803 | { |
| 804 | __u8 temp; |
| 805 | |
| 806 | temp = ReadReg(iobase, I_CF_L_1) & 0xe0; |
| 807 | temp |= count; |
| 808 | WriteReg(iobase, I_CF_L_1, temp); |
| 809 | |
| 810 | } |
| 811 | |
| 812 | static void SetVFIR(__u16 BaseAddr, __u8 val) |
| 813 | { |
| 814 | __u8 tmp; |
| 815 | |
| 816 | tmp = ReadReg(BaseAddr, I_CF_L_0); |
| 817 | WriteReg(BaseAddr, I_CF_L_0, tmp & 0x8f); |
| 818 | WriteRegBit(BaseAddr, I_CF_H_0, 5, val); |
| 819 | } |
| 820 | |
| 821 | static void SetFIR(__u16 BaseAddr, __u8 val) |
| 822 | { |
| 823 | __u8 tmp; |
| 824 | |
| 825 | WriteRegBit(BaseAddr, I_CF_H_0, 5, 0); |
| 826 | tmp = ReadReg(BaseAddr, I_CF_L_0); |
| 827 | WriteReg(BaseAddr, I_CF_L_0, tmp & 0x8f); |
| 828 | WriteRegBit(BaseAddr, I_CF_L_0, 6, val); |
| 829 | } |
| 830 | |
| 831 | static void SetMIR(__u16 BaseAddr, __u8 val) |
| 832 | { |
| 833 | __u8 tmp; |
| 834 | |
| 835 | WriteRegBit(BaseAddr, I_CF_H_0, 5, 0); |
| 836 | tmp = ReadReg(BaseAddr, I_CF_L_0); |
| 837 | WriteReg(BaseAddr, I_CF_L_0, tmp & 0x8f); |
| 838 | WriteRegBit(BaseAddr, I_CF_L_0, 5, val); |
| 839 | } |
| 840 | |
| 841 | static void SetSIR(__u16 BaseAddr, __u8 val) |
| 842 | { |
| 843 | __u8 tmp; |
| 844 | |
| 845 | WriteRegBit(BaseAddr, I_CF_H_0, 5, 0); |
| 846 | tmp = ReadReg(BaseAddr, I_CF_L_0); |
| 847 | WriteReg(BaseAddr, I_CF_L_0, tmp & 0x8f); |
| 848 | WriteRegBit(BaseAddr, I_CF_L_0, 4, val); |
| 849 | } |
| 850 | |
| 851 | #endif /* via_IRCC_H */ |