diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-viapro.c')
-rw-r--r-- | drivers/i2c/busses/i2c-viapro.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 862eb352a2d9..9f194d9efd91 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c | |||
@@ -36,6 +36,7 @@ | |||
36 | VT8237S 0x3372 yes | 36 | VT8237S 0x3372 yes |
37 | VT8251 0x3287 yes | 37 | VT8251 0x3287 yes |
38 | CX700 0x8324 yes | 38 | CX700 0x8324 yes |
39 | VX800/VX820 0x8353 yes | ||
39 | 40 | ||
40 | Note: we assume there can only be one device, with one SMBus interface. | 41 | Note: we assume there can only be one device, with one SMBus interface. |
41 | */ | 42 | */ |
@@ -82,6 +83,7 @@ static unsigned short SMBHSTCFG = 0xD2; | |||
82 | #define VT596_BYTE 0x04 | 83 | #define VT596_BYTE 0x04 |
83 | #define VT596_BYTE_DATA 0x08 | 84 | #define VT596_BYTE_DATA 0x08 |
84 | #define VT596_WORD_DATA 0x0C | 85 | #define VT596_WORD_DATA 0x0C |
86 | #define VT596_PROC_CALL 0x10 | ||
85 | #define VT596_BLOCK_DATA 0x14 | 87 | #define VT596_BLOCK_DATA 0x14 |
86 | #define VT596_I2C_BLOCK_DATA 0x34 | 88 | #define VT596_I2C_BLOCK_DATA 0x34 |
87 | 89 | ||
@@ -232,6 +234,12 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, | |||
232 | } | 234 | } |
233 | size = VT596_WORD_DATA; | 235 | size = VT596_WORD_DATA; |
234 | break; | 236 | break; |
237 | case I2C_SMBUS_PROC_CALL: | ||
238 | outb_p(command, SMBHSTCMD); | ||
239 | outb_p(data->word & 0xff, SMBHSTDAT0); | ||
240 | outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); | ||
241 | size = VT596_PROC_CALL; | ||
242 | break; | ||
235 | case I2C_SMBUS_I2C_BLOCK_DATA: | 243 | case I2C_SMBUS_I2C_BLOCK_DATA: |
236 | if (!(vt596_features & FEATURE_I2CBLOCK)) | 244 | if (!(vt596_features & FEATURE_I2CBLOCK)) |
237 | goto exit_unsupported; | 245 | goto exit_unsupported; |
@@ -262,6 +270,9 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, | |||
262 | if (status) | 270 | if (status) |
263 | return status; | 271 | return status; |
264 | 272 | ||
273 | if (size == VT596_PROC_CALL) | ||
274 | read_write = I2C_SMBUS_READ; | ||
275 | |||
265 | if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK)) | 276 | if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK)) |
266 | return 0; | 277 | return 0; |
267 | 278 | ||
@@ -271,6 +282,7 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, | |||
271 | data->byte = inb_p(SMBHSTDAT0); | 282 | data->byte = inb_p(SMBHSTDAT0); |
272 | break; | 283 | break; |
273 | case VT596_WORD_DATA: | 284 | case VT596_WORD_DATA: |
285 | case VT596_PROC_CALL: | ||
274 | data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); | 286 | data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); |
275 | break; | 287 | break; |
276 | case VT596_I2C_BLOCK_DATA: | 288 | case VT596_I2C_BLOCK_DATA: |
@@ -295,7 +307,7 @@ static u32 vt596_func(struct i2c_adapter *adapter) | |||
295 | { | 307 | { |
296 | u32 func = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | | 308 | u32 func = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | |
297 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | | 309 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | |
298 | I2C_FUNC_SMBUS_BLOCK_DATA; | 310 | I2C_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_DATA; |
299 | 311 | ||
300 | if (vt596_features & FEATURE_I2CBLOCK) | 312 | if (vt596_features & FEATURE_I2CBLOCK) |
301 | func |= I2C_FUNC_SMBUS_I2C_BLOCK; | 313 | func |= I2C_FUNC_SMBUS_I2C_BLOCK; |
@@ -320,10 +332,6 @@ static int __devinit vt596_probe(struct pci_dev *pdev, | |||
320 | unsigned char temp; | 332 | unsigned char temp; |
321 | int error = -ENODEV; | 333 | int error = -ENODEV; |
322 | 334 | ||
323 | /* driver_data might come from user-space, so check it */ | ||
324 | if (id->driver_data & 1 || id->driver_data > 0xff) | ||
325 | return -EINVAL; | ||
326 | |||
327 | /* Determine the address of the SMBus areas */ | 335 | /* Determine the address of the SMBus areas */ |
328 | if (force_addr) { | 336 | if (force_addr) { |
329 | vt596_smba = force_addr & 0xfff0; | 337 | vt596_smba = force_addr & 0xfff0; |
@@ -396,6 +404,7 @@ found: | |||
396 | 404 | ||
397 | switch (pdev->device) { | 405 | switch (pdev->device) { |
398 | case PCI_DEVICE_ID_VIA_CX700: | 406 | case PCI_DEVICE_ID_VIA_CX700: |
407 | case PCI_DEVICE_ID_VIA_VX800: | ||
399 | case PCI_DEVICE_ID_VIA_8251: | 408 | case PCI_DEVICE_ID_VIA_8251: |
400 | case PCI_DEVICE_ID_VIA_8237: | 409 | case PCI_DEVICE_ID_VIA_8237: |
401 | case PCI_DEVICE_ID_VIA_8237A: | 410 | case PCI_DEVICE_ID_VIA_8237A: |
@@ -459,6 +468,8 @@ static struct pci_device_id vt596_ids[] = { | |||
459 | .driver_data = SMBBA3 }, | 468 | .driver_data = SMBBA3 }, |
460 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700), | 469 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700), |
461 | .driver_data = SMBBA3 }, | 470 | .driver_data = SMBBA3 }, |
471 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800), | ||
472 | .driver_data = SMBBA3 }, | ||
462 | { 0, } | 473 | { 0, } |
463 | }; | 474 | }; |
464 | 475 | ||
@@ -468,7 +479,6 @@ static struct pci_driver vt596_driver = { | |||
468 | .name = "vt596_smbus", | 479 | .name = "vt596_smbus", |
469 | .id_table = vt596_ids, | 480 | .id_table = vt596_ids, |
470 | .probe = vt596_probe, | 481 | .probe = vt596_probe, |
471 | .dynids.use_driver_data = 1, | ||
472 | }; | 482 | }; |
473 | 483 | ||
474 | static int __init i2c_vt596_init(void) | 484 | static int __init i2c_vt596_init(void) |