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