Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
i2c-sis630.c
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002,2003 Alexander Malysh <[email protected]>
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18 
19 /*
20  Changes:
21  24.08.2002
22  Fixed the typo in sis630_access (Thanks to Mark M. Hoffman)
23  Changed sis630_transaction.(Thanks to Mark M. Hoffman)
24  18.09.2002
25  Added SIS730 as supported.
26  21.09.2002
27  Added high_clock module option.If this option is set
28  used Host Master Clock 56KHz (default 14KHz).For now we save old Host
29  Master Clock and after transaction completed restore (otherwise
30  it's confuse BIOS and hung Machine).
31  24.09.2002
32  Fixed typo in sis630_access
33  Fixed logical error by restoring of Host Master Clock
34  31.07.2003
35  Added block data read/write support.
36 */
37 
38 /*
39  Status: beta
40 
41  Supports:
42  SIS 630
43  SIS 730
44 
45  Note: we assume there can only be one device, with one SMBus interface.
46 */
47 
48 #include <linux/kernel.h>
49 #include <linux/module.h>
50 #include <linux/delay.h>
51 #include <linux/pci.h>
52 #include <linux/ioport.h>
53 #include <linux/init.h>
54 #include <linux/i2c.h>
55 #include <linux/acpi.h>
56 #include <linux/io.h>
57 
58 /* SIS630 SMBus registers */
59 #define SMB_STS 0x80 /* status */
60 #define SMB_EN 0x81 /* status enable */
61 #define SMB_CNT 0x82
62 #define SMBHOST_CNT 0x83
63 #define SMB_ADDR 0x84
64 #define SMB_CMD 0x85
65 #define SMB_PCOUNT 0x86 /* processed count */
66 #define SMB_COUNT 0x87
67 #define SMB_BYTE 0x88 /* ~0x8F data byte field */
68 #define SMBDEV_ADDR 0x90
69 #define SMB_DB0 0x91
70 #define SMB_DB1 0x92
71 #define SMB_SAA 0x93
72 
73 /* register count for request_region */
74 #define SIS630_SMB_IOREGION 20
75 
76 /* PCI address constants */
77 /* acpi base address register */
78 #define SIS630_ACPI_BASE_REG 0x74
79 /* bios control register */
80 #define SIS630_BIOS_CTL_REG 0x40
81 
82 /* Other settings */
83 #define MAX_TIMEOUT 500
84 
85 /* SIS630 constants */
86 #define SIS630_QUICK 0x00
87 #define SIS630_BYTE 0x01
88 #define SIS630_BYTE_DATA 0x02
89 #define SIS630_WORD_DATA 0x03
90 #define SIS630_PCALL 0x04
91 #define SIS630_BLOCK_DATA 0x05
92 
93 static struct pci_driver sis630_driver;
94 
95 /* insmod parameters */
96 static bool high_clock;
97 static bool force;
98 module_param(high_clock, bool, 0);
99 MODULE_PARM_DESC(high_clock, "Set Host Master Clock to 56KHz (default 14KHz).");
100 module_param(force, bool, 0);
101 MODULE_PARM_DESC(force, "Forcibly enable the SIS630. DANGEROUS!");
102 
103 /* acpi base address */
104 static unsigned short acpi_base;
105 
106 /* supported chips */
107 static int supported[] = {
110  0 /* terminates the list */
111 };
112 
113 static inline u8 sis630_read(u8 reg)
114 {
115  return inb(acpi_base + reg);
116 }
117 
118 static inline void sis630_write(u8 reg, u8 data)
119 {
120  outb(data, acpi_base + reg);
121 }
122 
123 static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 *oldclock)
124 {
125  int temp;
126 
127  /* Make sure the SMBus host is ready to start transmitting. */
128  if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) {
129  dev_dbg(&adap->dev, "SMBus busy (%02x).Resetting...\n",temp);
130  /* kill smbus transaction */
131  sis630_write(SMBHOST_CNT, 0x20);
132 
133  if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) {
134  dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
135  return -EBUSY;
136  } else {
137  dev_dbg(&adap->dev, "Successful!\n");
138  }
139  }
140 
141  /* save old clock, so we can prevent machine for hung */
142  *oldclock = sis630_read(SMB_CNT);
143 
144  dev_dbg(&adap->dev, "saved clock 0x%02x\n", *oldclock);
145 
146  /* disable timeout interrupt , set Host Master Clock to 56KHz if requested */
147  if (high_clock)
148  sis630_write(SMB_CNT, 0x20);
149  else
150  sis630_write(SMB_CNT, (*oldclock & ~0x40));
151 
152  /* clear all sticky bits */
153  temp = sis630_read(SMB_STS);
154  sis630_write(SMB_STS, temp & 0x1e);
155 
156  /* start the transaction by setting bit 4 and size */
157  sis630_write(SMBHOST_CNT,0x10 | (size & 0x07));
158 
159  return 0;
160 }
161 
162 static int sis630_transaction_wait(struct i2c_adapter *adap, int size)
163 {
164  int temp, result = 0, timeout = 0;
165 
166  /* We will always wait for a fraction of a second! */
167  do {
168  msleep(1);
169  temp = sis630_read(SMB_STS);
170  /* check if block transmitted */
171  if (size == SIS630_BLOCK_DATA && (temp & 0x10))
172  break;
173  } while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT));
174 
175  /* If the SMBus is still busy, we give up */
176  if (timeout > MAX_TIMEOUT) {
177  dev_dbg(&adap->dev, "SMBus Timeout!\n");
178  result = -ETIMEDOUT;
179  }
180 
181  if (temp & 0x02) {
182  dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
183  result = -ENXIO;
184  }
185 
186  if (temp & 0x04) {
187  dev_err(&adap->dev, "Bus collision!\n");
188  result = -EIO;
189  /*
190  TBD: Datasheet say:
191  the software should clear this bit and restart SMBUS operation.
192  Should we do it or user start request again?
193  */
194  }
195 
196  return result;
197 }
198 
199 static void sis630_transaction_end(struct i2c_adapter *adap, u8 oldclock)
200 {
201  int temp = 0;
202 
203  /* clear all status "sticky" bits */
204  sis630_write(SMB_STS, temp);
205 
206  dev_dbg(&adap->dev, "SMB_CNT before clock restore 0x%02x\n", sis630_read(SMB_CNT));
207 
208  /*
209  * restore old Host Master Clock if high_clock is set
210  * and oldclock was not 56KHz
211  */
212  if (high_clock && !(oldclock & 0x20))
213  sis630_write(SMB_CNT,(sis630_read(SMB_CNT) & ~0x20));
214 
215  dev_dbg(&adap->dev, "SMB_CNT after clock restore 0x%02x\n", sis630_read(SMB_CNT));
216 }
217 
218 static int sis630_transaction(struct i2c_adapter *adap, int size)
219 {
220  int result = 0;
221  u8 oldclock = 0;
222 
223  result = sis630_transaction_start(adap, size, &oldclock);
224  if (!result) {
225  result = sis630_transaction_wait(adap, size);
226  sis630_transaction_end(adap, oldclock);
227  }
228 
229  return result;
230 }
231 
232 static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *data, int read_write)
233 {
234  int i, len = 0, rc = 0;
235  u8 oldclock = 0;
236 
237  if (read_write == I2C_SMBUS_WRITE) {
238  len = data->block[0];
239  if (len < 0)
240  len = 0;
241  else if (len > 32)
242  len = 32;
243  sis630_write(SMB_COUNT, len);
244  for (i=1; i <= len; i++) {
245  dev_dbg(&adap->dev, "set data 0x%02x\n", data->block[i]);
246  /* set data */
247  sis630_write(SMB_BYTE+(i-1)%8, data->block[i]);
248  if (i==8 || (len<8 && i==len)) {
249  dev_dbg(&adap->dev, "start trans len=%d i=%d\n",len ,i);
250  /* first transaction */
251  rc = sis630_transaction_start(adap,
252  SIS630_BLOCK_DATA, &oldclock);
253  if (rc)
254  return rc;
255  }
256  else if ((i-1)%8 == 7 || i==len) {
257  dev_dbg(&adap->dev, "trans_wait len=%d i=%d\n",len,i);
258  if (i>8) {
259  dev_dbg(&adap->dev, "clear smbary_sts len=%d i=%d\n",len,i);
260  /*
261  If this is not first transaction,
262  we must clear sticky bit.
263  clear SMBARY_STS
264  */
265  sis630_write(SMB_STS,0x10);
266  }
267  rc = sis630_transaction_wait(adap,
269  if (rc) {
270  dev_dbg(&adap->dev, "trans_wait failed\n");
271  break;
272  }
273  }
274  }
275  }
276  else {
277  /* read request */
278  data->block[0] = len = 0;
279  rc = sis630_transaction_start(adap,
280  SIS630_BLOCK_DATA, &oldclock);
281  if (rc)
282  return rc;
283  do {
284  rc = sis630_transaction_wait(adap, SIS630_BLOCK_DATA);
285  if (rc) {
286  dev_dbg(&adap->dev, "trans_wait failed\n");
287  break;
288  }
289  /* if this first transaction then read byte count */
290  if (len == 0)
291  data->block[0] = sis630_read(SMB_COUNT);
292 
293  /* just to be sure */
294  if (data->block[0] > 32)
295  data->block[0] = 32;
296 
297  dev_dbg(&adap->dev, "block data read len=0x%x\n", data->block[0]);
298 
299  for (i=0; i < 8 && len < data->block[0]; i++,len++) {
300  dev_dbg(&adap->dev, "read i=%d len=%d\n", i, len);
301  data->block[len+1] = sis630_read(SMB_BYTE+i);
302  }
303 
304  dev_dbg(&adap->dev, "clear smbary_sts len=%d i=%d\n",len,i);
305 
306  /* clear SMBARY_STS */
307  sis630_write(SMB_STS,0x10);
308  } while(len < data->block[0]);
309  }
310 
311  sis630_transaction_end(adap, oldclock);
312 
313  return rc;
314 }
315 
316 /* Return negative errno on error. */
317 static s32 sis630_access(struct i2c_adapter *adap, u16 addr,
318  unsigned short flags, char read_write,
319  u8 command, int size, union i2c_smbus_data *data)
320 {
321  int status;
322 
323  switch (size) {
324  case I2C_SMBUS_QUICK:
325  sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
326  size = SIS630_QUICK;
327  break;
328  case I2C_SMBUS_BYTE:
329  sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
330  if (read_write == I2C_SMBUS_WRITE)
331  sis630_write(SMB_CMD, command);
332  size = SIS630_BYTE;
333  break;
334  case I2C_SMBUS_BYTE_DATA:
335  sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
336  sis630_write(SMB_CMD, command);
337  if (read_write == I2C_SMBUS_WRITE)
338  sis630_write(SMB_BYTE, data->byte);
339  size = SIS630_BYTE_DATA;
340  break;
341  case I2C_SMBUS_PROC_CALL:
342  case I2C_SMBUS_WORD_DATA:
343  sis630_write(SMB_ADDR,((addr & 0x7f) << 1) | (read_write & 0x01));
344  sis630_write(SMB_CMD, command);
345  if (read_write == I2C_SMBUS_WRITE) {
346  sis630_write(SMB_BYTE, data->word & 0xff);
347  sis630_write(SMB_BYTE + 1,(data->word & 0xff00) >> 8);
348  }
350  break;
352  sis630_write(SMB_ADDR,((addr & 0x7f) << 1) | (read_write & 0x01));
353  sis630_write(SMB_CMD, command);
354  size = SIS630_BLOCK_DATA;
355  return sis630_block_data(adap, data, read_write);
356  default:
357  dev_warn(&adap->dev, "Unsupported transaction %d\n",
358  size);
359  return -EOPNOTSUPP;
360  }
361 
362  status = sis630_transaction(adap, size);
363  if (status)
364  return status;
365 
366  if ((size != SIS630_PCALL) &&
367  ((read_write == I2C_SMBUS_WRITE) || (size == SIS630_QUICK))) {
368  return 0;
369  }
370 
371  switch(size) {
372  case SIS630_BYTE:
373  case SIS630_BYTE_DATA:
374  data->byte = sis630_read(SMB_BYTE);
375  break;
376  case SIS630_PCALL:
377  case SIS630_WORD_DATA:
378  data->word = sis630_read(SMB_BYTE) + (sis630_read(SMB_BYTE + 1) << 8);
379  break;
380  }
381 
382  return 0;
383 }
384 
385 static u32 sis630_func(struct i2c_adapter *adapter)
386 {
390 }
391 
392 static int __devinit sis630_setup(struct pci_dev *sis630_dev)
393 {
394  unsigned char b;
395  struct pci_dev *dummy = NULL;
396  int retval, i;
397 
398  /* check for supported SiS devices */
399  for (i=0; supported[i] > 0 ; i++) {
400  if ((dummy = pci_get_device(PCI_VENDOR_ID_SI, supported[i], dummy)))
401  break; /* found */
402  }
403 
404  if (dummy) {
405  pci_dev_put(dummy);
406  }
407  else if (force) {
408  dev_err(&sis630_dev->dev, "WARNING: Can't detect SIS630 compatible device, but "
409  "loading because of force option enabled\n");
410  }
411  else {
412  return -ENODEV;
413  }
414 
415  /*
416  Enable ACPI first , so we can accsess reg 74-75
417  in acpi io space and read acpi base addr
418  */
419  if (pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) {
420  dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n");
421  retval = -ENODEV;
422  goto exit;
423  }
424  /* if ACPI already enabled , do nothing */
425  if (!(b & 0x80) &&
426  pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) {
427  dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n");
428  retval = -ENODEV;
429  goto exit;
430  }
431 
432  /* Determine the ACPI base address */
433  if (pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) {
434  dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n");
435  retval = -ENODEV;
436  goto exit;
437  }
438 
439  dev_dbg(&sis630_dev->dev, "ACPI base at 0x%04x\n", acpi_base);
440 
441  retval = acpi_check_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION,
442  sis630_driver.name);
443  if (retval)
444  goto exit;
445 
446  /* Everything is happy, let's grab the memory and set things up. */
447  if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION,
448  sis630_driver.name)) {
449  dev_err(&sis630_dev->dev, "SMBus registers 0x%04x-0x%04x already "
450  "in use!\n", acpi_base + SMB_STS, acpi_base + SMB_SAA);
451  retval = -EBUSY;
452  goto exit;
453  }
454 
455  retval = 0;
456 
457 exit:
458  if (retval)
459  acpi_base = 0;
460  return retval;
461 }
462 
463 
464 static const struct i2c_algorithm smbus_algorithm = {
465  .smbus_xfer = sis630_access,
466  .functionality = sis630_func,
467 };
468 
469 static struct i2c_adapter sis630_adapter = {
470  .owner = THIS_MODULE,
471  .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
472  .algo = &smbus_algorithm,
473 };
474 
475 static DEFINE_PCI_DEVICE_TABLE(sis630_ids) = {
478  { 0, }
479 };
480 
481 MODULE_DEVICE_TABLE (pci, sis630_ids);
482 
483 static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_id *id)
484 {
485  if (sis630_setup(dev)) {
486  dev_err(&dev->dev, "SIS630 comp. bus not detected, module not inserted.\n");
487  return -ENODEV;
488  }
489 
490  /* set up the sysfs linkage to our parent device */
491  sis630_adapter.dev.parent = &dev->dev;
492 
493  snprintf(sis630_adapter.name, sizeof(sis630_adapter.name),
494  "SMBus SIS630 adapter at %04x", acpi_base + SMB_STS);
495 
496  return i2c_add_adapter(&sis630_adapter);
497 }
498 
499 static void __devexit sis630_remove(struct pci_dev *dev)
500 {
501  if (acpi_base) {
502  i2c_del_adapter(&sis630_adapter);
504  acpi_base = 0;
505  }
506 }
507 
508 
509 static struct pci_driver sis630_driver = {
510  .name = "sis630_smbus",
511  .id_table = sis630_ids,
512  .probe = sis630_probe,
513  .remove = __devexit_p(sis630_remove),
514 };
515 
516 module_pci_driver(sis630_driver);
517 
518 MODULE_LICENSE("GPL");
519 MODULE_AUTHOR("Alexander Malysh <[email protected]>");
520 MODULE_DESCRIPTION("SIS630 SMBus driver");