aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-amd8111.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-amd8111.c')
-rw-r--r--drivers/i2c/busses/i2c-amd8111.c72
1 files changed, 43 insertions, 29 deletions
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
index 0fbc7186c91a..5bba3fb50d71 100644
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -12,7 +12,6 @@
12#include <linux/pci.h> 12#include <linux/pci.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/stddef.h> 14#include <linux/stddef.h>
15#include <linux/sched.h>
16#include <linux/ioport.h> 15#include <linux/ioport.h>
17#include <linux/init.h> 16#include <linux/init.h>
18#include <linux/i2c.h> 17#include <linux/i2c.h>
@@ -76,7 +75,8 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus)
76 udelay(1); 75 udelay(1);
77 76
78 if (!timeout) { 77 if (!timeout) {
79 dev_warn(&smbus->dev->dev, "Timeout while waiting for IBF to clear\n"); 78 dev_warn(&smbus->dev->dev,
79 "Timeout while waiting for IBF to clear\n");
80 return -1; 80 return -1;
81 } 81 }
82 82
@@ -91,14 +91,16 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus)
91 udelay(1); 91 udelay(1);
92 92
93 if (!timeout) { 93 if (!timeout) {
94 dev_warn(&smbus->dev->dev, "Timeout while waiting for OBF to set\n"); 94 dev_warn(&smbus->dev->dev,
95 "Timeout while waiting for OBF to set\n");
95 return -1; 96 return -1;
96 } 97 }
97 98
98 return 0; 99 return 0;
99} 100}
100 101
101static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address, unsigned char *data) 102static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
103 unsigned char *data)
102{ 104{
103 if (amd_ec_wait_write(smbus)) 105 if (amd_ec_wait_write(smbus))
104 return -1; 106 return -1;
@@ -115,7 +117,8 @@ static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
115 return 0; 117 return 0;
116} 118}
117 119
118static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address, unsigned char data) 120static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address,
121 unsigned char data)
119{ 122{
120 if (amd_ec_wait_write(smbus)) 123 if (amd_ec_wait_write(smbus))
121 return -1; 124 return -1;
@@ -175,18 +178,19 @@ static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address,
175#define AMD_SMB_PRTCL_PEC 0x80 178#define AMD_SMB_PRTCL_PEC 0x80
176 179
177 180
178static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short flags, 181static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
179 char read_write, u8 command, int size, union i2c_smbus_data * data) 182 unsigned short flags, char read_write, u8 command, int size,
183 union i2c_smbus_data * data)
180{ 184{
181 struct amd_smbus *smbus = adap->algo_data; 185 struct amd_smbus *smbus = adap->algo_data;
182 unsigned char protocol, len, pec, temp[2]; 186 unsigned char protocol, len, pec, temp[2];
183 int i; 187 int i;
184 188
185 protocol = (read_write == I2C_SMBUS_READ) ? AMD_SMB_PRTCL_READ : AMD_SMB_PRTCL_WRITE; 189 protocol = (read_write == I2C_SMBUS_READ) ? AMD_SMB_PRTCL_READ
190 : AMD_SMB_PRTCL_WRITE;
186 pec = (flags & I2C_CLIENT_PEC) ? AMD_SMB_PRTCL_PEC : 0; 191 pec = (flags & I2C_CLIENT_PEC) ? AMD_SMB_PRTCL_PEC : 0;
187 192
188 switch (size) { 193 switch (size) {
189
190 case I2C_SMBUS_QUICK: 194 case I2C_SMBUS_QUICK:
191 protocol |= AMD_SMB_PRTCL_QUICK; 195 protocol |= AMD_SMB_PRTCL_QUICK;
192 read_write = I2C_SMBUS_WRITE; 196 read_write = I2C_SMBUS_WRITE;
@@ -208,8 +212,10 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
208 case I2C_SMBUS_WORD_DATA: 212 case I2C_SMBUS_WORD_DATA:
209 amd_ec_write(smbus, AMD_SMB_CMD, command); 213 amd_ec_write(smbus, AMD_SMB_CMD, command);
210 if (read_write == I2C_SMBUS_WRITE) { 214 if (read_write == I2C_SMBUS_WRITE) {
211 amd_ec_write(smbus, AMD_SMB_DATA, data->word); 215 amd_ec_write(smbus, AMD_SMB_DATA,
212 amd_ec_write(smbus, AMD_SMB_DATA + 1, data->word >> 8); 216 data->word & 0xff);
217 amd_ec_write(smbus, AMD_SMB_DATA + 1,
218 data->word >> 8);
213 } 219 }
214 protocol |= AMD_SMB_PRTCL_WORD_DATA | pec; 220 protocol |= AMD_SMB_PRTCL_WORD_DATA | pec;
215 break; 221 break;
@@ -217,27 +223,31 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
217 case I2C_SMBUS_BLOCK_DATA: 223 case I2C_SMBUS_BLOCK_DATA:
218 amd_ec_write(smbus, AMD_SMB_CMD, command); 224 amd_ec_write(smbus, AMD_SMB_CMD, command);
219 if (read_write == I2C_SMBUS_WRITE) { 225 if (read_write == I2C_SMBUS_WRITE) {
220 len = min_t(u8, data->block[0], 32); 226 len = min_t(u8, data->block[0],
227 I2C_SMBUS_BLOCK_MAX);
221 amd_ec_write(smbus, AMD_SMB_BCNT, len); 228 amd_ec_write(smbus, AMD_SMB_BCNT, len);
222 for (i = 0; i < len; i++) 229 for (i = 0; i < len; i++)
223 amd_ec_write(smbus, AMD_SMB_DATA + i, data->block[i + 1]); 230 amd_ec_write(smbus, AMD_SMB_DATA + i,
231 data->block[i + 1]);
224 } 232 }
225 protocol |= AMD_SMB_PRTCL_BLOCK_DATA | pec; 233 protocol |= AMD_SMB_PRTCL_BLOCK_DATA | pec;
226 break; 234 break;
227 235
228 case I2C_SMBUS_I2C_BLOCK_DATA: 236 case I2C_SMBUS_I2C_BLOCK_DATA:
229 len = min_t(u8, data->block[0], 32); 237 len = min_t(u8, data->block[0],
238 I2C_SMBUS_BLOCK_MAX);
230 amd_ec_write(smbus, AMD_SMB_CMD, command); 239 amd_ec_write(smbus, AMD_SMB_CMD, command);
231 amd_ec_write(smbus, AMD_SMB_BCNT, len); 240 amd_ec_write(smbus, AMD_SMB_BCNT, len);
232 if (read_write == I2C_SMBUS_WRITE) 241 if (read_write == I2C_SMBUS_WRITE)
233 for (i = 0; i < len; i++) 242 for (i = 0; i < len; i++)
234 amd_ec_write(smbus, AMD_SMB_DATA + i, data->block[i + 1]); 243 amd_ec_write(smbus, AMD_SMB_DATA + i,
244 data->block[i + 1]);
235 protocol |= AMD_SMB_PRTCL_I2C_BLOCK_DATA; 245 protocol |= AMD_SMB_PRTCL_I2C_BLOCK_DATA;
236 break; 246 break;
237 247
238 case I2C_SMBUS_PROC_CALL: 248 case I2C_SMBUS_PROC_CALL:
239 amd_ec_write(smbus, AMD_SMB_CMD, command); 249 amd_ec_write(smbus, AMD_SMB_CMD, command);
240 amd_ec_write(smbus, AMD_SMB_DATA, data->word); 250 amd_ec_write(smbus, AMD_SMB_DATA, data->word & 0xff);
241 amd_ec_write(smbus, AMD_SMB_DATA + 1, data->word >> 8); 251 amd_ec_write(smbus, AMD_SMB_DATA + 1, data->word >> 8);
242 protocol = AMD_SMB_PRTCL_PROC_CALL | pec; 252 protocol = AMD_SMB_PRTCL_PROC_CALL | pec;
243 read_write = I2C_SMBUS_READ; 253 read_write = I2C_SMBUS_READ;
@@ -248,7 +258,8 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
248 amd_ec_write(smbus, AMD_SMB_CMD, command); 258 amd_ec_write(smbus, AMD_SMB_CMD, command);
249 amd_ec_write(smbus, AMD_SMB_BCNT, len); 259 amd_ec_write(smbus, AMD_SMB_BCNT, len);
250 for (i = 0; i < len; i++) 260 for (i = 0; i < len; i++)
251 amd_ec_write(smbus, AMD_SMB_DATA + i, data->block[i + 1]); 261 amd_ec_write(smbus, AMD_SMB_DATA + i,
262 data->block[i + 1]);
252 protocol = AMD_SMB_PRTCL_BLOCK_PROC_CALL | pec; 263 protocol = AMD_SMB_PRTCL_BLOCK_PROC_CALL | pec;
253 read_write = I2C_SMBUS_READ; 264 read_write = I2C_SMBUS_READ;
254 break; 265 break;
@@ -280,7 +291,6 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
280 return 0; 291 return 0;
281 292
282 switch (size) { 293 switch (size) {
283
284 case I2C_SMBUS_BYTE: 294 case I2C_SMBUS_BYTE:
285 case I2C_SMBUS_BYTE_DATA: 295 case I2C_SMBUS_BYTE_DATA:
286 amd_ec_read(smbus, AMD_SMB_DATA, &data->byte); 296 amd_ec_read(smbus, AMD_SMB_DATA, &data->byte);
@@ -296,10 +306,11 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
296 case I2C_SMBUS_BLOCK_DATA: 306 case I2C_SMBUS_BLOCK_DATA:
297 case I2C_SMBUS_BLOCK_PROC_CALL: 307 case I2C_SMBUS_BLOCK_PROC_CALL:
298 amd_ec_read(smbus, AMD_SMB_BCNT, &len); 308 amd_ec_read(smbus, AMD_SMB_BCNT, &len);
299 len = min_t(u8, len, 32); 309 len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX);
300 case I2C_SMBUS_I2C_BLOCK_DATA: 310 case I2C_SMBUS_I2C_BLOCK_DATA:
301 for (i = 0; i < len; i++) 311 for (i = 0; i < len; i++)
302 amd_ec_read(smbus, AMD_SMB_DATA + i, data->block + i + 1); 312 amd_ec_read(smbus, AMD_SMB_DATA + i,
313 data->block + i + 1);
303 data->block[0] = len; 314 data->block[0] = len;
304 break; 315 break;
305 } 316 }
@@ -310,7 +321,8 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
310 321
311static u32 amd8111_func(struct i2c_adapter *adapter) 322static u32 amd8111_func(struct i2c_adapter *adapter)
312{ 323{
313 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | 324 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
325 I2C_FUNC_SMBUS_BYTE_DATA |
314 I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA | 326 I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA |
315 I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_PROC_CALL | 327 I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
316 I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_HWPEC_CALC; 328 I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_HWPEC_CALC;
@@ -329,12 +341,13 @@ static struct pci_device_id amd8111_ids[] = {
329 341
330MODULE_DEVICE_TABLE (pci, amd8111_ids); 342MODULE_DEVICE_TABLE (pci, amd8111_ids);
331 343
332static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_id *id) 344static int __devinit amd8111_probe(struct pci_dev *dev,
345 const struct pci_device_id *id)
333{ 346{
334 struct amd_smbus *smbus; 347 struct amd_smbus *smbus;
335 int error = -ENODEV; 348 int error;
336 349
337 if (~pci_resource_flags(dev, 0) & IORESOURCE_IO) 350 if (!(pci_resource_flags(dev, 0) & IORESOURCE_IO))
338 return -ENODEV; 351 return -ENODEV;
339 352
340 smbus = kzalloc(sizeof(struct amd_smbus), GFP_KERNEL); 353 smbus = kzalloc(sizeof(struct amd_smbus), GFP_KERNEL);
@@ -345,12 +358,15 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_
345 smbus->base = pci_resource_start(dev, 0); 358 smbus->base = pci_resource_start(dev, 0);
346 smbus->size = pci_resource_len(dev, 0); 359 smbus->size = pci_resource_len(dev, 0);
347 360
348 if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) 361 if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) {
362 error = -EBUSY;
349 goto out_kfree; 363 goto out_kfree;
364 }
350 365
351 smbus->adapter.owner = THIS_MODULE; 366 smbus->adapter.owner = THIS_MODULE;
352 snprintf(smbus->adapter.name, I2C_NAME_SIZE, 367 snprintf(smbus->adapter.name, I2C_NAME_SIZE,
353 "SMBus2 AMD8111 adapter at %04x", smbus->base); 368 "SMBus2 AMD8111 adapter at %04x", smbus->base);
369 smbus->adapter.id = I2C_HW_SMBUS_AMD8111;
354 smbus->adapter.class = I2C_CLASS_HWMON; 370 smbus->adapter.class = I2C_CLASS_HWMON;
355 smbus->adapter.algo = &smbus_algorithm; 371 smbus->adapter.algo = &smbus_algorithm;
356 smbus->adapter.algo_data = smbus; 372 smbus->adapter.algo_data = smbus;
@@ -358,11 +374,11 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_
358 /* set up the driverfs linkage to our parent device */ 374 /* set up the driverfs linkage to our parent device */
359 smbus->adapter.dev.parent = &dev->dev; 375 smbus->adapter.dev.parent = &dev->dev;
360 376
377 pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0);
361 error = i2c_add_adapter(&smbus->adapter); 378 error = i2c_add_adapter(&smbus->adapter);
362 if (error) 379 if (error)
363 goto out_release_region; 380 goto out_release_region;
364 381
365 pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0);
366 pci_set_drvdata(dev, smbus); 382 pci_set_drvdata(dev, smbus);
367 return 0; 383 return 0;
368 384
@@ -370,10 +386,9 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_
370 release_region(smbus->base, smbus->size); 386 release_region(smbus->base, smbus->size);
371 out_kfree: 387 out_kfree:
372 kfree(smbus); 388 kfree(smbus);
373 return -1; 389 return error;
374} 390}
375 391
376
377static void __devexit amd8111_remove(struct pci_dev *dev) 392static void __devexit amd8111_remove(struct pci_dev *dev)
378{ 393{
379 struct amd_smbus *smbus = pci_get_drvdata(dev); 394 struct amd_smbus *smbus = pci_get_drvdata(dev);
@@ -395,7 +410,6 @@ static int __init i2c_amd8111_init(void)
395 return pci_register_driver(&amd8111_driver); 410 return pci_register_driver(&amd8111_driver);
396} 411}
397 412
398
399static void __exit i2c_amd8111_exit(void) 413static void __exit i2c_amd8111_exit(void)
400{ 414{
401 pci_unregister_driver(&amd8111_driver); 415 pci_unregister_driver(&amd8111_driver);