Changeset 1504
- Timestamp:
- 08/25/02 16:33:27 (11 years ago)
- Files:
-
- 1 modified
-
lm-sensors/trunk/kernel/busses/i2c-sis630.c (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
lm-sensors/trunk/kernel/busses/i2c-sis630.c
r1497 r1504 17 17 along with this program; if not, write to the Free Software 18 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 21 /* 22 Changes: 23 24.08.2002 24 Fixed the typo in sis630_access (Thanks to Mark M. Hoffman) 25 Changed sis630_transaction. Now it's 2x faster (Thanks to Mark M. Hoffman) 19 26 */ 20 27 … … 97 104 union i2c_smbus_data *data); 98 105 static void sis630_do_pause(unsigned int amount); 99 static int sis630_transaction( void);106 static int sis630_transaction(int size); 100 107 static void sis630_inc(struct i2c_adapter *adapter); 101 108 static void sis630_dec(struct i2c_adapter *adapter); … … 145 152 } 146 153 147 int sis630_transaction( ) {154 int sis630_transaction(int size) { 148 155 int temp; 149 156 int result = 0; … … 152 159 /* 153 160 Make sure the SMBus host is ready to start transmitting. 154 Datasheet say SMB_STS are sticky bits, but on my Laptop155 (Clevo/Kapok 2202) SMBALT# (bit 7) cannot be cleared ???156 161 */ 157 if ((temp = sis630_read(SMB_STS)) != 0x80) {162 if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) { 158 163 #ifdef DEBUG 159 164 printk(KERN_DEBUG "i2c-sis630.o: SMBus busy (%02x). " 160 165 "Resetting...\n",temp); 161 166 #endif 162 sis630_write(SMB_STS, temp & 0xff); 163 if ((temp = sis630_read(SMB_STS)) != 0x80) { 167 /* kill smbus transaction */ 168 sis630_write(SMBHOST_CNT, 0x02); 169 170 if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) { 164 171 #ifdef DEBUG 165 172 printk(KERN_DEBUG "i2c-sis630.o: Failed! (%02x)\n", … … 174 181 } 175 182 176 /* start the transaction by setting bit 4 */ 177 sis630_write(SMBHOST_CNT, sis630_read(SMBHOST_CNT) | 0x10); 183 /* disable timeout interrupt and set clock to 56KHz */ 184 sis630_write(SMB_CNT, 0x20); 185 186 /* clear all sticky bits */ 187 temp = sis630_read(SMB_STS); 188 sis630_write(SMB_STS, temp & 0x1e); 189 190 /* start the transaction by setting bit 4 and size */ 191 sis630_write(SMBHOST_CNT,0x10 | (size & 0x07)); 178 192 179 193 /* We will always wait for a fraction of a second! */ … … 181 195 sis630_do_pause(1); 182 196 temp = sis630_read(SMB_STS); 183 } while (!(temp & 0x0 8) && (timeout++ < MAX_TIMEOUT));197 } while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT)); 184 198 185 199 /* If the SMBus is still busy, we give up */ … … 203 217 printk(KERN_ERR "i2c-sis630.o: Bus collision! " 204 218 "SMBus may be locked until next hard reset (or not...)\n"); 205 206 219 /* TBD: Datasheet say: 207 220 the software should clear this bit and restart SMBUS operation … … 209 222 } 210 223 211 if ((temp = sis630_read(SMB_STS)) != 0x80) { 212 sis630_write(SMB_STS, temp & 0xff); 213 } 214 215 if ((temp = sis630_read(SMB_STS)) != 0x80) { 216 #ifdef DEBUG 217 printk(KERN_DEBUG "i2c-sis630.o: Failed reset at end of " 218 "transaction (%02x)\n",temp); 219 #endif 220 } 224 /* clear all status "sticky" bits */ 225 sis630_write(SMB_STS, temp); 221 226 222 227 return result; … … 270 275 271 276 272 sis630_write(SMBHOST_CNT,(size & 0x07)); 273 274 if (sis630_transaction()) 277 if (sis630_transaction(size)) 275 278 return -1; 276 279 … … 281 284 282 285 switch(size) { 283 case I2C_SMBUS_BYTE:284 case I2C_SMBUS_BYTE_DATA:286 case SIS630_BYTE: 287 case SIS630_BYTE_DATA: 285 288 data->byte = sis630_read(SMB_BYTE); 286 289 break; 287 case I2C_SMBUS_PROC_CALL:288 case I2C_SMBUS_WORD_DATA:290 case SIS630_PCALL: 291 case SIS630_WORD_DATA: 289 292 data->word = sis630_read(SMB_BYTE) + (sis630_read(SMB_BYTE + 1) << 8); 290 293 break; … … 312 315 int sis630_setup(void) { 313 316 unsigned char b; 314 int rc;315 317 struct pci_dev *sis630_dev = NULL; 316 318 … … 337 339 in acpi io space and read acpi base addr 338 340 */ 339 if ((rc = pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, &b))) { 341 if (PCIBIOS_SUCCESSFUL != 342 pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) { 340 343 printk(KERN_ERR "i2c-sis630.o: Error: Can't read bios ctl reg\n"); 341 return rc; 342 } 344 return -ENODEV; 345 } 346 /* if ACPI already anbled , do nothing */ 343 347 if (!(b & 0x80) && 344 (rc = pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80))) { 348 PCIBIOS_SUCCESSFUL != 349 pci_write_config_byte(sis630_dev,SIS630_BIOS_CTL_REG,b|0x80)) { 345 350 printk(KERN_ERR "i2c-sis630.o: Error: Can't enable ACPI\n"); 346 return rc;351 return -ENODEV; 347 352 } 348 353 /* Determine the ACPI base address */ 349 if ((rc = pci_read_config_word(sis630_dev, SIS630_ACPI_BASE_REG,&acpi_base))) { 354 if (PCIBIOS_SUCCESSFUL != 355 pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) { 350 356 printk(KERN_ERR "i2c-sis630.o: Error: Can't determine ACPI base address\n"); 351 return rc;357 return -ENODEV; 352 358 } 353 359 … … 358 364 /* Everything is happy, let's grab the memory and set things up. */ 359 365 if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION, "sis630-smbus")){ 360 361 366 printk(KERN_ERR "i2c-sis630.o: SMBus registers 0x%04x-0x%04x " 362 367 "already in use!\n",acpi_base + SMB_STS, acpi_base + SMB_SAA);
