i2c-savage4.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*
  2. i2c-savage4.c - Part of lm_sensors, Linux kernel modules for hardware
  3. monitoring
  4. Copyright (C) 1998-2003 The LM Sensors Team
  5. Alexander Wold <awold@bigfoot.com>
  6. Mark D. Studebaker <mdsxyz123@yahoo.com>
  7. Based on i2c-voodoo3.c.
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. */
  20. /* This interfaces to the I2C bus of the Savage4 to gain access to
  21. the BT869 and possibly other I2C devices. The DDC bus is not
  22. yet supported because its register is not memory-mapped.
  23. However we leave the DDC code here, commented out, to make
  24. it easier to add later.
  25. */
  26. #include <linux/kernel.h>
  27. #include <linux/module.h>
  28. #include <linux/init.h>
  29. #include <linux/pci.h>
  30. #include <linux/i2c.h>
  31. #include <linux/i2c-algo-bit.h>
  32. #include <asm/io.h>
  33. /* 3DFX defines */
  34. #define PCI_CHIP_SAVAGE3D 0x8A20
  35. #define PCI_CHIP_SAVAGE3D_MV 0x8A21
  36. #define PCI_CHIP_SAVAGE4 0x8A22
  37. #define PCI_CHIP_SAVAGE2000 0x9102
  38. #define PCI_CHIP_PROSAVAGE_PM 0x8A25
  39. #define PCI_CHIP_PROSAVAGE_KM 0x8A26
  40. #define PCI_CHIP_SAVAGE_MX_MV 0x8c10
  41. #define PCI_CHIP_SAVAGE_MX 0x8c11
  42. #define PCI_CHIP_SAVAGE_IX_MV 0x8c12
  43. #define PCI_CHIP_SAVAGE_IX 0x8c13
  44. #define REG 0xff20 /* Serial Port 1 Register */
  45. /* bit locations in the register */
  46. #define DDC_ENAB 0x00040000
  47. #define DDC_SCL_OUT 0x00080000
  48. #define DDC_SDA_OUT 0x00100000
  49. #define DDC_SCL_IN 0x00200000
  50. #define DDC_SDA_IN 0x00400000
  51. #define I2C_ENAB 0x00000020
  52. #define I2C_SCL_OUT 0x00000001
  53. #define I2C_SDA_OUT 0x00000002
  54. #define I2C_SCL_IN 0x00000008
  55. #define I2C_SDA_IN 0x00000010
  56. /* initialization states */
  57. #define INIT2 0x20
  58. #define INIT3 0x04
  59. /* delays */
  60. #define CYCLE_DELAY 10
  61. #define TIMEOUT (HZ / 2)
  62. static void __iomem *ioaddr;
  63. /* The sav GPIO registers don't have individual masks for each bit
  64. so we always have to read before writing. */
  65. static void bit_savi2c_setscl(void *data, int val)
  66. {
  67. unsigned int r;
  68. r = readl(ioaddr + REG);
  69. if(val)
  70. r |= I2C_SCL_OUT;
  71. else
  72. r &= ~I2C_SCL_OUT;
  73. writel(r, ioaddr + REG);
  74. readl(ioaddr + REG); /* flush posted write */
  75. }
  76. static void bit_savi2c_setsda(void *data, int val)
  77. {
  78. unsigned int r;
  79. r = readl(ioaddr + REG);
  80. if(val)
  81. r |= I2C_SDA_OUT;
  82. else
  83. r &= ~I2C_SDA_OUT;
  84. writel(r, ioaddr + REG);
  85. readl(ioaddr + REG); /* flush posted write */
  86. }
  87. /* The GPIO pins are open drain, so the pins always remain outputs.
  88. We rely on the i2c-algo-bit routines to set the pins high before
  89. reading the input from other chips. */
  90. static int bit_savi2c_getscl(void *data)
  91. {
  92. return (0 != (readl(ioaddr + REG) & I2C_SCL_IN));
  93. }
  94. static int bit_savi2c_getsda(void *data)
  95. {
  96. return (0 != (readl(ioaddr + REG) & I2C_SDA_IN));
  97. }
  98. /* Configures the chip */
  99. static int config_s4(struct pci_dev *dev)
  100. {
  101. unsigned long cadr;
  102. /* map memory */
  103. cadr = dev->resource[0].start;
  104. cadr &= PCI_BASE_ADDRESS_MEM_MASK;
  105. ioaddr = ioremap_nocache(cadr, 0x0080000);
  106. if (ioaddr) {
  107. /* writel(0x8160, ioaddr + REG2); */
  108. writel(0x00000020, ioaddr + REG);
  109. dev_info(&dev->dev, "Using Savage4 at %p\n", ioaddr);
  110. return 0;
  111. }
  112. return -ENODEV;
  113. }
  114. static struct i2c_algo_bit_data sav_i2c_bit_data = {
  115. .setsda = bit_savi2c_setsda,
  116. .setscl = bit_savi2c_setscl,
  117. .getsda = bit_savi2c_getsda,
  118. .getscl = bit_savi2c_getscl,
  119. .udelay = CYCLE_DELAY,
  120. .mdelay = CYCLE_DELAY,
  121. .timeout = TIMEOUT
  122. };
  123. static struct i2c_adapter savage4_i2c_adapter = {
  124. .owner = THIS_MODULE,
  125. .name = "I2C Savage4 adapter",
  126. .algo_data = &sav_i2c_bit_data,
  127. };
  128. static struct pci_device_id savage4_ids[] __devinitdata = {
  129. { PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE4) },
  130. { PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE2000) },
  131. { 0, }
  132. };
  133. MODULE_DEVICE_TABLE (pci, savage4_ids);
  134. static int __devinit savage4_probe(struct pci_dev *dev, const struct pci_device_id *id)
  135. {
  136. int retval;
  137. retval = config_s4(dev);
  138. if (retval)
  139. return retval;
  140. /* set up the sysfs linkage to our parent device */
  141. savage4_i2c_adapter.dev.parent = &dev->dev;
  142. return i2c_bit_add_bus(&savage4_i2c_adapter);
  143. }
  144. static void __devexit savage4_remove(struct pci_dev *dev)
  145. {
  146. i2c_bit_del_bus(&savage4_i2c_adapter);
  147. iounmap(ioaddr);
  148. }
  149. static struct pci_driver savage4_driver = {
  150. .name = "savage4_smbus",
  151. .id_table = savage4_ids,
  152. .probe = savage4_probe,
  153. .remove = __devexit_p(savage4_remove),
  154. };
  155. static int __init i2c_savage4_init(void)
  156. {
  157. return pci_register_driver(&savage4_driver);
  158. }
  159. static void __exit i2c_savage4_exit(void)
  160. {
  161. pci_unregister_driver(&savage4_driver);
  162. }
  163. MODULE_AUTHOR("Alexander Wold <awold@bigfoot.com> "
  164. "and Mark D. Studebaker <mdsxyz123@yahoo.com>");
  165. MODULE_DESCRIPTION("Savage4 I2C/SMBus driver");
  166. MODULE_LICENSE("GPL");
  167. module_init(i2c_savage4_init);
  168. module_exit(i2c_savage4_exit);