matrox_w1.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * matrox_w1.c
  3. *
  4. * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
  5. *
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  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. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. #include <asm/atomic.h>
  22. #include <asm/types.h>
  23. #include <asm/io.h>
  24. #include <linux/delay.h>
  25. #include <linux/kernel.h>
  26. #include <linux/module.h>
  27. #include <linux/list.h>
  28. #include <linux/interrupt.h>
  29. #include <linux/spinlock.h>
  30. #include <linux/timer.h>
  31. #include <linux/slab.h>
  32. #include <linux/pci_ids.h>
  33. #include <linux/pci.h>
  34. #include <linux/timer.h>
  35. #include "w1.h"
  36. #include "w1_int.h"
  37. #include "w1_log.h"
  38. MODULE_LICENSE("GPL");
  39. MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
  40. MODULE_DESCRIPTION("Driver for transport(Dallas 1-wire prtocol) over VGA DDC(matrox gpio).");
  41. static struct pci_device_id matrox_w1_tbl[] = {
  42. { PCI_DEVICE(PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400) },
  43. { },
  44. };
  45. MODULE_DEVICE_TABLE(pci, matrox_w1_tbl);
  46. static int __devinit matrox_w1_probe(struct pci_dev *, const struct pci_device_id *);
  47. static void __devexit matrox_w1_remove(struct pci_dev *);
  48. static struct pci_driver matrox_w1_pci_driver = {
  49. .name = "matrox_w1",
  50. .id_table = matrox_w1_tbl,
  51. .probe = matrox_w1_probe,
  52. .remove = __devexit_p(matrox_w1_remove),
  53. };
  54. /*
  55. * Matrox G400 DDC registers.
  56. */
  57. #define MATROX_G400_DDC_CLK (1<<4)
  58. #define MATROX_G400_DDC_DATA (1<<1)
  59. #define MATROX_BASE 0x3C00
  60. #define MATROX_STATUS 0x1e14
  61. #define MATROX_PORT_INDEX_OFFSET 0x00
  62. #define MATROX_PORT_DATA_OFFSET 0x0A
  63. #define MATROX_GET_CONTROL 0x2A
  64. #define MATROX_GET_DATA 0x2B
  65. #define MATROX_CURSOR_CTL 0x06
  66. struct matrox_device
  67. {
  68. void __iomem *base_addr;
  69. void __iomem *port_index;
  70. void __iomem *port_data;
  71. u8 data_mask;
  72. unsigned long phys_addr;
  73. void __iomem *virt_addr;
  74. unsigned long found;
  75. struct w1_bus_master *bus_master;
  76. };
  77. static u8 matrox_w1_read_ddc_bit(unsigned long);
  78. static void matrox_w1_write_ddc_bit(unsigned long, u8);
  79. /*
  80. * These functions read and write DDC Data bit.
  81. *
  82. * Using tristate pins, since i can't find any open-drain pin in whole motherboard.
  83. * Unfortunately we can't connect to Intel's 82801xx IO controller
  84. * since we don't know motherboard schema, wich has pretty unused(may be not) GPIO.
  85. *
  86. * I've heard that PIIX also has open drain pin.
  87. *
  88. * Port mapping.
  89. */
  90. static __inline__ u8 matrox_w1_read_reg(struct matrox_device *dev, u8 reg)
  91. {
  92. u8 ret;
  93. writeb(reg, dev->port_index);
  94. ret = readb(dev->port_data);
  95. barrier();
  96. return ret;
  97. }
  98. static __inline__ void matrox_w1_write_reg(struct matrox_device *dev, u8 reg, u8 val)
  99. {
  100. writeb(reg, dev->port_index);
  101. writeb(val, dev->port_data);
  102. wmb();
  103. }
  104. static void matrox_w1_write_ddc_bit(unsigned long data, u8 bit)
  105. {
  106. u8 ret;
  107. struct matrox_device *dev = (struct matrox_device *) data;
  108. if (bit)
  109. bit = 0;
  110. else
  111. bit = dev->data_mask;
  112. ret = matrox_w1_read_reg(dev, MATROX_GET_CONTROL);
  113. matrox_w1_write_reg(dev, MATROX_GET_CONTROL, ((ret & ~dev->data_mask) | bit));
  114. matrox_w1_write_reg(dev, MATROX_GET_DATA, 0x00);
  115. }
  116. static u8 matrox_w1_read_ddc_bit(unsigned long data)
  117. {
  118. u8 ret;
  119. struct matrox_device *dev = (struct matrox_device *) data;
  120. ret = matrox_w1_read_reg(dev, MATROX_GET_DATA);
  121. return ret;
  122. }
  123. static void matrox_w1_hw_init(struct matrox_device *dev)
  124. {
  125. matrox_w1_write_reg(dev, MATROX_GET_DATA, 0xFF);
  126. matrox_w1_write_reg(dev, MATROX_GET_CONTROL, 0x00);
  127. }
  128. static int __devinit matrox_w1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  129. {
  130. struct matrox_device *dev;
  131. int err;
  132. assert(pdev != NULL);
  133. assert(ent != NULL);
  134. if (pdev->vendor != PCI_VENDOR_ID_MATROX || pdev->device != PCI_DEVICE_ID_MATROX_G400)
  135. return -ENODEV;
  136. dev = kmalloc(sizeof(struct matrox_device) +
  137. sizeof(struct w1_bus_master), GFP_KERNEL);
  138. if (!dev) {
  139. dev_err(&pdev->dev,
  140. "%s: Failed to create new matrox_device object.\n",
  141. __func__);
  142. return -ENOMEM;
  143. }
  144. memset(dev, 0, sizeof(struct matrox_device) + sizeof(struct w1_bus_master));
  145. dev->bus_master = (struct w1_bus_master *)(dev + 1);
  146. /*
  147. * True for G400, for some other we need resource 0, see drivers/video/matrox/matroxfb_base.c
  148. */
  149. dev->phys_addr = pci_resource_start(pdev, 1);
  150. dev->virt_addr = ioremap_nocache(dev->phys_addr, 16384);
  151. if (!dev->virt_addr) {
  152. dev_err(&pdev->dev, "%s: failed to ioremap(0x%lx, %d).\n",
  153. __func__, dev->phys_addr, 16384);
  154. err = -EIO;
  155. goto err_out_free_device;
  156. }
  157. dev->base_addr = dev->virt_addr + MATROX_BASE;
  158. dev->port_index = dev->base_addr + MATROX_PORT_INDEX_OFFSET;
  159. dev->port_data = dev->base_addr + MATROX_PORT_DATA_OFFSET;
  160. dev->data_mask = (MATROX_G400_DDC_DATA);
  161. matrox_w1_hw_init(dev);
  162. dev->bus_master->data = (unsigned long) dev;
  163. dev->bus_master->read_bit = &matrox_w1_read_ddc_bit;
  164. dev->bus_master->write_bit = &matrox_w1_write_ddc_bit;
  165. err = w1_add_master_device(dev->bus_master);
  166. if (err)
  167. goto err_out_free_device;
  168. pci_set_drvdata(pdev, dev);
  169. dev->found = 1;
  170. dev_info(&pdev->dev, "Matrox G400 GPIO transport layer for 1-wire.\n");
  171. return 0;
  172. err_out_free_device:
  173. kfree(dev);
  174. return err;
  175. }
  176. static void __devexit matrox_w1_remove(struct pci_dev *pdev)
  177. {
  178. struct matrox_device *dev = pci_get_drvdata(pdev);
  179. assert(dev != NULL);
  180. if (dev->found) {
  181. w1_remove_master_device(dev->bus_master);
  182. iounmap(dev->virt_addr);
  183. }
  184. kfree(dev);
  185. }
  186. static int __init matrox_w1_init(void)
  187. {
  188. return pci_register_driver(&matrox_w1_pci_driver);
  189. }
  190. static void __exit matrox_w1_fini(void)
  191. {
  192. pci_unregister_driver(&matrox_w1_pci_driver);
  193. }
  194. module_init(matrox_w1_init);
  195. module_exit(matrox_w1_fini);