aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-viapro.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-viapro.c')
-rw-r--r--drivers/i2c/busses/i2c-viapro.c122
1 files changed, 41 insertions, 81 deletions
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index b420e752b1dc..5cf8fe182806 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -39,7 +39,6 @@
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <linux/kernel.h> 40#include <linux/kernel.h>
41#include <linux/stddef.h> 41#include <linux/stddef.h>
42#include <linux/sched.h>
43#include <linux/ioport.h> 42#include <linux/ioport.h>
44#include <linux/i2c.h> 43#include <linux/i2c.h>
45#include <linux/init.h> 44#include <linux/init.h>
@@ -54,34 +53,22 @@ static struct pci_dev *vt596_pdev;
54/* SMBus address offsets */ 53/* SMBus address offsets */
55static unsigned short vt596_smba; 54static unsigned short vt596_smba;
56#define SMBHSTSTS (vt596_smba + 0) 55#define SMBHSTSTS (vt596_smba + 0)
57#define SMBHSLVSTS (vt596_smba + 1)
58#define SMBHSTCNT (vt596_smba + 2) 56#define SMBHSTCNT (vt596_smba + 2)
59#define SMBHSTCMD (vt596_smba + 3) 57#define SMBHSTCMD (vt596_smba + 3)
60#define SMBHSTADD (vt596_smba + 4) 58#define SMBHSTADD (vt596_smba + 4)
61#define SMBHSTDAT0 (vt596_smba + 5) 59#define SMBHSTDAT0 (vt596_smba + 5)
62#define SMBHSTDAT1 (vt596_smba + 6) 60#define SMBHSTDAT1 (vt596_smba + 6)
63#define SMBBLKDAT (vt596_smba + 7) 61#define SMBBLKDAT (vt596_smba + 7)
64#define SMBSLVCNT (vt596_smba + 8)
65#define SMBSHDWCMD (vt596_smba + 9)
66#define SMBSLVEVT (vt596_smba + 0xA)
67#define SMBSLVDAT (vt596_smba + 0xC)
68 62
69/* PCI Address Constants */ 63/* PCI Address Constants */
70 64
71/* SMBus data in configuration space can be found in two places, 65/* SMBus data in configuration space can be found in two places,
72 We try to select the better one */ 66 We try to select the better one */
73 67
74static unsigned short smb_cf_hstcfg = 0xD2; 68static unsigned short SMBHSTCFG = 0xD2;
75
76#define SMBHSTCFG (smb_cf_hstcfg)
77#define SMBSLVC (smb_cf_hstcfg + 1)
78#define SMBSHDW1 (smb_cf_hstcfg + 2)
79#define SMBSHDW2 (smb_cf_hstcfg + 3)
80#define SMBREV (smb_cf_hstcfg + 4)
81 69
82/* Other settings */ 70/* Other settings */
83#define MAX_TIMEOUT 500 71#define MAX_TIMEOUT 500
84#define ENABLE_INT9 0
85 72
86/* VT82C596 constants */ 73/* VT82C596 constants */
87#define VT596_QUICK 0x00 74#define VT596_QUICK 0x00
@@ -107,12 +94,13 @@ MODULE_PARM_DESC(force_addr,
107 "EXTREMELY DANGEROUS!"); 94 "EXTREMELY DANGEROUS!");
108 95
109 96
97static struct pci_driver vt596_driver;
110static struct i2c_adapter vt596_adapter; 98static struct i2c_adapter vt596_adapter;
111 99
112#define FEATURE_I2CBLOCK (1<<0) 100#define FEATURE_I2CBLOCK (1<<0)
113static unsigned int vt596_features; 101static unsigned int vt596_features;
114 102
115/* Another internally used function */ 103/* Return -1 on error, 0 on success */
116static int vt596_transaction(void) 104static int vt596_transaction(void)
117{ 105{
118 int temp; 106 int temp;
@@ -127,23 +115,21 @@ static int vt596_transaction(void)
127 /* Make sure the SMBus host is ready to start transmitting */ 115 /* Make sure the SMBus host is ready to start transmitting */
128 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { 116 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
129 dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). " 117 dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). "
130 "Resetting...\n", temp); 118 "Resetting... ", temp);
131 119
132 outb_p(temp, SMBHSTSTS); 120 outb_p(temp, SMBHSTSTS);
133 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { 121 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
134 dev_dbg(&vt596_adapter.dev, "Failed! (0x%02x)\n", temp); 122 printk("Failed! (0x%02x)\n", temp);
135
136 return -1; 123 return -1;
137 } else { 124 } else {
138 dev_dbg(&vt596_adapter.dev, "Successfull!\n"); 125 printk("Successful!\n");
139 } 126 }
140 } 127 }
141 128
142 /* start the transaction by setting bit 6 */ 129 /* Start the transaction by setting bit 6 */
143 outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); 130 outb_p(inb(SMBHSTCNT) | 0x40, SMBHSTCNT);
144 131
145 /* We will always wait for a fraction of a second! 132 /* We will always wait for a fraction of a second */
146 I don't know if VIA needs this, Intel did */
147 do { 133 do {
148 msleep(1); 134 msleep(1);
149 temp = inb_p(SMBHSTSTS); 135 temp = inb_p(SMBHSTSTS);
@@ -152,33 +138,32 @@ static int vt596_transaction(void)
152 /* If the SMBus is still busy, we give up */ 138 /* If the SMBus is still busy, we give up */
153 if (timeout >= MAX_TIMEOUT) { 139 if (timeout >= MAX_TIMEOUT) {
154 result = -1; 140 result = -1;
155 dev_dbg(&vt596_adapter.dev, "SMBus Timeout!\n"); 141 dev_err(&vt596_adapter.dev, "SMBus timeout!\n");
156 } 142 }
157 143
158 if (temp & 0x10) { 144 if (temp & 0x10) {
159 result = -1; 145 result = -1;
160 dev_dbg(&vt596_adapter.dev, "Error: Failed bus transaction\n"); 146 dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n",
147 inb_p(SMBHSTCNT) & 0x3C);
161 } 148 }
162 149
163 if (temp & 0x08) { 150 if (temp & 0x08) {
164 result = -1; 151 result = -1;
165 dev_info(&vt596_adapter.dev, "Bus collision! SMBus may be " 152 dev_err(&vt596_adapter.dev, "SMBus collision!\n");
166 "locked until next hard\nreset. (sorry!)\n");
167 /* Clock stops and slave is stuck in mid-transmission */
168 } 153 }
169 154
170 if (temp & 0x04) { 155 if (temp & 0x04) {
171 result = -1; 156 result = -1;
172 dev_dbg(&vt596_adapter.dev, "Error: no response!\n"); 157 /* Quick commands are used to probe for chips, so
158 errors are expected, and we don't want to frighten the
159 user. */
160 if ((inb_p(SMBHSTCNT) & 0x3C) != VT596_QUICK)
161 dev_err(&vt596_adapter.dev, "Transaction error!\n");
173 } 162 }
174 163
175 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { 164 /* Resetting status register */
165 if (temp & 0x1F)
176 outb_p(temp, SMBHSTSTS); 166 outb_p(temp, SMBHSTSTS);
177 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
178 dev_warn(&vt596_adapter.dev, "Failed reset at end "
179 "of transaction (%02x)\n", temp);
180 }
181 }
182 167
183 dev_dbg(&vt596_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, " 168 dev_dbg(&vt596_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, "
184 "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), 169 "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
@@ -188,41 +173,29 @@ static int vt596_transaction(void)
188 return result; 173 return result;
189} 174}
190 175
191/* Return -1 on error. */ 176/* Return -1 on error, 0 on success */
192static s32 vt596_access(struct i2c_adapter *adap, u16 addr, 177static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
193 unsigned short flags, char read_write, u8 command, 178 unsigned short flags, char read_write, u8 command,
194 int size, union i2c_smbus_data *data) 179 int size, union i2c_smbus_data *data)
195{ 180{
196 int i, len; 181 int i;
197 182
198 switch (size) { 183 switch (size) {
199 case I2C_SMBUS_PROC_CALL:
200 dev_info(&vt596_adapter.dev,
201 "I2C_SMBUS_PROC_CALL not supported!\n");
202 return -1;
203 case I2C_SMBUS_QUICK: 184 case I2C_SMBUS_QUICK:
204 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
205 SMBHSTADD);
206 size = VT596_QUICK; 185 size = VT596_QUICK;
207 break; 186 break;
208 case I2C_SMBUS_BYTE: 187 case I2C_SMBUS_BYTE:
209 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
210 SMBHSTADD);
211 if (read_write == I2C_SMBUS_WRITE) 188 if (read_write == I2C_SMBUS_WRITE)
212 outb_p(command, SMBHSTCMD); 189 outb_p(command, SMBHSTCMD);
213 size = VT596_BYTE; 190 size = VT596_BYTE;
214 break; 191 break;
215 case I2C_SMBUS_BYTE_DATA: 192 case I2C_SMBUS_BYTE_DATA:
216 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
217 SMBHSTADD);
218 outb_p(command, SMBHSTCMD); 193 outb_p(command, SMBHSTCMD);
219 if (read_write == I2C_SMBUS_WRITE) 194 if (read_write == I2C_SMBUS_WRITE)
220 outb_p(data->byte, SMBHSTDAT0); 195 outb_p(data->byte, SMBHSTDAT0);
221 size = VT596_BYTE_DATA; 196 size = VT596_BYTE_DATA;
222 break; 197 break;
223 case I2C_SMBUS_WORD_DATA: 198 case I2C_SMBUS_WORD_DATA:
224 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
225 SMBHSTADD);
226 outb_p(command, SMBHSTCMD); 199 outb_p(command, SMBHSTCMD);
227 if (read_write == I2C_SMBUS_WRITE) { 200 if (read_write == I2C_SMBUS_WRITE) {
228 outb_p(data->word & 0xff, SMBHSTDAT0); 201 outb_p(data->word & 0xff, SMBHSTDAT0);
@@ -232,31 +205,30 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
232 break; 205 break;
233 case I2C_SMBUS_I2C_BLOCK_DATA: 206 case I2C_SMBUS_I2C_BLOCK_DATA:
234 if (!(vt596_features & FEATURE_I2CBLOCK)) 207 if (!(vt596_features & FEATURE_I2CBLOCK))
235 return -1; 208 goto exit_unsupported;
236 if (read_write == I2C_SMBUS_READ) 209 if (read_write == I2C_SMBUS_READ)
237 outb_p(I2C_SMBUS_BLOCK_MAX, SMBHSTDAT0); 210 outb_p(I2C_SMBUS_BLOCK_MAX, SMBHSTDAT0);
238 /* Fall through */ 211 /* Fall through */
239 case I2C_SMBUS_BLOCK_DATA: 212 case I2C_SMBUS_BLOCK_DATA:
240 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
241 SMBHSTADD);
242 outb_p(command, SMBHSTCMD); 213 outb_p(command, SMBHSTCMD);
243 if (read_write == I2C_SMBUS_WRITE) { 214 if (read_write == I2C_SMBUS_WRITE) {
244 len = data->block[0]; 215 u8 len = data->block[0];
245 if (len < 0)
246 len = 0;
247 if (len > I2C_SMBUS_BLOCK_MAX) 216 if (len > I2C_SMBUS_BLOCK_MAX)
248 len = I2C_SMBUS_BLOCK_MAX; 217 len = I2C_SMBUS_BLOCK_MAX;
249 outb_p(len, SMBHSTDAT0); 218 outb_p(len, SMBHSTDAT0);
250 i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ 219 inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */
251 for (i = 1; i <= len; i++) 220 for (i = 1; i <= len; i++)
252 outb_p(data->block[i], SMBBLKDAT); 221 outb_p(data->block[i], SMBBLKDAT);
253 } 222 }
254 size = (size == I2C_SMBUS_I2C_BLOCK_DATA) ? 223 size = (size == I2C_SMBUS_I2C_BLOCK_DATA) ?
255 VT596_I2C_BLOCK_DATA : VT596_BLOCK_DATA; 224 VT596_I2C_BLOCK_DATA : VT596_BLOCK_DATA;
256 break; 225 break;
226 default:
227 goto exit_unsupported;
257 } 228 }
258 229
259 outb_p((size & 0x3C) + (ENABLE_INT9 & 1), SMBHSTCNT); 230 outb_p(((addr & 0x7f) << 1) | read_write, SMBHSTADD);
231 outb_p((size & 0x3C), SMBHSTCNT);
260 232
261 if (vt596_transaction()) /* Error in transaction */ 233 if (vt596_transaction()) /* Error in transaction */
262 return -1; 234 return -1;
@@ -266,12 +238,6 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
266 238
267 switch (size) { 239 switch (size) {
268 case VT596_BYTE: 240 case VT596_BYTE:
269 /* Where is the result put? I assume here it is in
270 * SMBHSTDAT0 but it might just as well be in the
271 * SMBHSTCMD. No clue in the docs
272 */
273 data->byte = inb_p(SMBHSTDAT0);
274 break;
275 case VT596_BYTE_DATA: 241 case VT596_BYTE_DATA:
276 data->byte = inb_p(SMBHSTDAT0); 242 data->byte = inb_p(SMBHSTDAT0);
277 break; 243 break;
@@ -283,12 +249,17 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
283 data->block[0] = inb_p(SMBHSTDAT0); 249 data->block[0] = inb_p(SMBHSTDAT0);
284 if (data->block[0] > I2C_SMBUS_BLOCK_MAX) 250 if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
285 data->block[0] = I2C_SMBUS_BLOCK_MAX; 251 data->block[0] = I2C_SMBUS_BLOCK_MAX;
286 i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ 252 inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */
287 for (i = 1; i <= data->block[0]; i++) 253 for (i = 1; i <= data->block[0]; i++)
288 data->block[i] = inb_p(SMBBLKDAT); 254 data->block[i] = inb_p(SMBBLKDAT);
289 break; 255 break;
290 } 256 }
291 return 0; 257 return 0;
258
259exit_unsupported:
260 dev_warn(&vt596_adapter.dev, "Unsupported command invoked! (0x%02x)\n",
261 size);
262 return -1;
292} 263}
293 264
294static u32 vt596_func(struct i2c_adapter *adapter) 265static u32 vt596_func(struct i2c_adapter *adapter)
@@ -311,7 +282,6 @@ static struct i2c_adapter vt596_adapter = {
311 .owner = THIS_MODULE, 282 .owner = THIS_MODULE,
312 .class = I2C_CLASS_HWMON, 283 .class = I2C_CLASS_HWMON,
313 .algo = &smbus_algorithm, 284 .algo = &smbus_algorithm,
314 .name = "unset",
315}; 285};
316 286
317static int __devinit vt596_probe(struct pci_dev *pdev, 287static int __devinit vt596_probe(struct pci_dev *pdev,
@@ -328,12 +298,12 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
328 } 298 }
329 299
330 if ((pci_read_config_word(pdev, id->driver_data, &vt596_smba)) || 300 if ((pci_read_config_word(pdev, id->driver_data, &vt596_smba)) ||
331 !(vt596_smba & 0x1)) { 301 !(vt596_smba & 0x0001)) {
332 /* try 2nd address and config reg. for 596 */ 302 /* try 2nd address and config reg. for 596 */
333 if (id->device == PCI_DEVICE_ID_VIA_82C596_3 && 303 if (id->device == PCI_DEVICE_ID_VIA_82C596_3 &&
334 !pci_read_config_word(pdev, SMBBA2, &vt596_smba) && 304 !pci_read_config_word(pdev, SMBBA2, &vt596_smba) &&
335 (vt596_smba & 0x1)) { 305 (vt596_smba & 0x0001)) {
336 smb_cf_hstcfg = 0x84; 306 SMBHSTCFG = 0x84;
337 } else { 307 } else {
338 /* no matches at all */ 308 /* no matches at all */
339 dev_err(&pdev->dev, "Cannot configure " 309 dev_err(&pdev->dev, "Cannot configure "
@@ -351,7 +321,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
351 } 321 }
352 322
353found: 323found:
354 if (!request_region(vt596_smba, 8, "viapro-smbus")) { 324 if (!request_region(vt596_smba, 8, vt596_driver.name)) {
355 dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n", 325 dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n",
356 vt596_smba); 326 vt596_smba);
357 return -ENODEV; 327 return -ENODEV;
@@ -366,7 +336,7 @@ found:
366 pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01); 336 pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01);
367 dev_warn(&pdev->dev, "WARNING: SMBus interface set to new " 337 dev_warn(&pdev->dev, "WARNING: SMBus interface set to new "
368 "address 0x%04x!\n", vt596_smba); 338 "address 0x%04x!\n", vt596_smba);
369 } else if ((temp & 1) == 0) { 339 } else if (!(temp & 0x01)) {
370 if (force) { 340 if (force) {
371 /* NOTE: This assumes I/O space and other allocations 341 /* NOTE: This assumes I/O space and other allocations
372 * WERE done by the Bios! Don't complain if your 342 * WERE done by the Bios! Don't complain if your
@@ -374,7 +344,7 @@ found:
374 * :') Check for Bios updates before resorting to 344 * :') Check for Bios updates before resorting to
375 * this. 345 * this.
376 */ 346 */
377 pci_write_config_byte(pdev, SMBHSTCFG, temp | 1); 347 pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01);
378 dev_info(&pdev->dev, "Enabling SMBus device\n"); 348 dev_info(&pdev->dev, "Enabling SMBus device\n");
379 } else { 349 } else {
380 dev_err(&pdev->dev, "SMBUS: Error: Host SMBus " 350 dev_err(&pdev->dev, "SMBUS: Error: Host SMBus "
@@ -384,16 +354,6 @@ found:
384 } 354 }
385 } 355 }
386 356
387 if ((temp & 0x0E) == 8)
388 dev_dbg(&pdev->dev, "using Interrupt 9 for SMBus.\n");
389 else if ((temp & 0x0E) == 0)
390 dev_dbg(&pdev->dev, "using Interrupt SMI# for SMBus.\n");
391 else
392 dev_dbg(&pdev->dev, "Illegal Interrupt configuration "
393 "(or code out of date)!\n");
394
395 pci_read_config_byte(pdev, SMBREV, &temp);
396 dev_dbg(&pdev->dev, "SMBREV = 0x%X\n", temp);
397 dev_dbg(&pdev->dev, "VT596_smba = 0x%X\n", vt596_smba); 357 dev_dbg(&pdev->dev, "VT596_smba = 0x%X\n", vt596_smba);
398 358
399 switch (pdev->device) { 359 switch (pdev->device) {