nouveau_i2c.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. * Copyright 2009 Red Hat Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * Authors: Ben Skeggs
  23. */
  24. #include "drmP.h"
  25. #include "nouveau_drv.h"
  26. #include "nouveau_i2c.h"
  27. #include "nouveau_hw.h"
  28. static void
  29. nv04_i2c_setscl(void *data, int state)
  30. {
  31. struct nouveau_i2c_chan *i2c = data;
  32. struct drm_device *dev = i2c->dev;
  33. uint8_t val;
  34. val = (NVReadVgaCrtc(dev, 0, i2c->wr) & 0xd0) | (state ? 0x20 : 0);
  35. NVWriteVgaCrtc(dev, 0, i2c->wr, val | 0x01);
  36. }
  37. static void
  38. nv04_i2c_setsda(void *data, int state)
  39. {
  40. struct nouveau_i2c_chan *i2c = data;
  41. struct drm_device *dev = i2c->dev;
  42. uint8_t val;
  43. val = (NVReadVgaCrtc(dev, 0, i2c->wr) & 0xe0) | (state ? 0x10 : 0);
  44. NVWriteVgaCrtc(dev, 0, i2c->wr, val | 0x01);
  45. }
  46. static int
  47. nv04_i2c_getscl(void *data)
  48. {
  49. struct nouveau_i2c_chan *i2c = data;
  50. struct drm_device *dev = i2c->dev;
  51. return !!(NVReadVgaCrtc(dev, 0, i2c->rd) & 4);
  52. }
  53. static int
  54. nv04_i2c_getsda(void *data)
  55. {
  56. struct nouveau_i2c_chan *i2c = data;
  57. struct drm_device *dev = i2c->dev;
  58. return !!(NVReadVgaCrtc(dev, 0, i2c->rd) & 8);
  59. }
  60. static void
  61. nv4e_i2c_setscl(void *data, int state)
  62. {
  63. struct nouveau_i2c_chan *i2c = data;
  64. struct drm_device *dev = i2c->dev;
  65. uint8_t val;
  66. val = (nv_rd32(dev, i2c->wr) & 0xd0) | (state ? 0x20 : 0);
  67. nv_wr32(dev, i2c->wr, val | 0x01);
  68. }
  69. static void
  70. nv4e_i2c_setsda(void *data, int state)
  71. {
  72. struct nouveau_i2c_chan *i2c = data;
  73. struct drm_device *dev = i2c->dev;
  74. uint8_t val;
  75. val = (nv_rd32(dev, i2c->wr) & 0xe0) | (state ? 0x10 : 0);
  76. nv_wr32(dev, i2c->wr, val | 0x01);
  77. }
  78. static int
  79. nv4e_i2c_getscl(void *data)
  80. {
  81. struct nouveau_i2c_chan *i2c = data;
  82. struct drm_device *dev = i2c->dev;
  83. return !!((nv_rd32(dev, i2c->rd) >> 16) & 4);
  84. }
  85. static int
  86. nv4e_i2c_getsda(void *data)
  87. {
  88. struct nouveau_i2c_chan *i2c = data;
  89. struct drm_device *dev = i2c->dev;
  90. return !!((nv_rd32(dev, i2c->rd) >> 16) & 8);
  91. }
  92. static int
  93. nv50_i2c_getscl(void *data)
  94. {
  95. struct nouveau_i2c_chan *i2c = data;
  96. struct drm_device *dev = i2c->dev;
  97. return !!(nv_rd32(dev, i2c->rd) & 1);
  98. }
  99. static int
  100. nv50_i2c_getsda(void *data)
  101. {
  102. struct nouveau_i2c_chan *i2c = data;
  103. struct drm_device *dev = i2c->dev;
  104. return !!(nv_rd32(dev, i2c->rd) & 2);
  105. }
  106. static void
  107. nv50_i2c_setscl(void *data, int state)
  108. {
  109. struct nouveau_i2c_chan *i2c = data;
  110. struct drm_device *dev = i2c->dev;
  111. nv_wr32(dev, i2c->wr, 4 | (i2c->data ? 2 : 0) | (state ? 1 : 0));
  112. }
  113. static void
  114. nv50_i2c_setsda(void *data, int state)
  115. {
  116. struct nouveau_i2c_chan *i2c = data;
  117. struct drm_device *dev = i2c->dev;
  118. nv_wr32(dev, i2c->wr,
  119. (nv_rd32(dev, i2c->rd) & 1) | 4 | (state ? 2 : 0));
  120. i2c->data = state;
  121. }
  122. static const uint32_t nv50_i2c_port[] = {
  123. 0x00e138, 0x00e150, 0x00e168, 0x00e180,
  124. 0x00e254, 0x00e274, 0x00e764, 0x00e780,
  125. 0x00e79c, 0x00e7b8
  126. };
  127. #define NV50_I2C_PORTS ARRAY_SIZE(nv50_i2c_port)
  128. int
  129. nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
  130. {
  131. struct drm_nouveau_private *dev_priv = dev->dev_private;
  132. struct nouveau_i2c_chan *i2c;
  133. int ret;
  134. if (entry->chan)
  135. return -EEXIST;
  136. if (dev_priv->card_type == NV_50 && entry->read >= NV50_I2C_PORTS) {
  137. NV_ERROR(dev, "unknown i2c port %d\n", entry->read);
  138. return -EINVAL;
  139. }
  140. i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
  141. if (i2c == NULL)
  142. return -ENOMEM;
  143. switch (entry->port_type) {
  144. case 0:
  145. i2c->algo.bit.setsda = nv04_i2c_setsda;
  146. i2c->algo.bit.setscl = nv04_i2c_setscl;
  147. i2c->algo.bit.getsda = nv04_i2c_getsda;
  148. i2c->algo.bit.getscl = nv04_i2c_getscl;
  149. i2c->rd = entry->read;
  150. i2c->wr = entry->write;
  151. break;
  152. case 4:
  153. i2c->algo.bit.setsda = nv4e_i2c_setsda;
  154. i2c->algo.bit.setscl = nv4e_i2c_setscl;
  155. i2c->algo.bit.getsda = nv4e_i2c_getsda;
  156. i2c->algo.bit.getscl = nv4e_i2c_getscl;
  157. i2c->rd = 0x600800 + entry->read;
  158. i2c->wr = 0x600800 + entry->write;
  159. break;
  160. case 5:
  161. i2c->algo.bit.setsda = nv50_i2c_setsda;
  162. i2c->algo.bit.setscl = nv50_i2c_setscl;
  163. i2c->algo.bit.getsda = nv50_i2c_getsda;
  164. i2c->algo.bit.getscl = nv50_i2c_getscl;
  165. i2c->rd = nv50_i2c_port[entry->read];
  166. i2c->wr = i2c->rd;
  167. break;
  168. case 6:
  169. i2c->rd = entry->read;
  170. i2c->wr = entry->write;
  171. break;
  172. default:
  173. NV_ERROR(dev, "DCB I2C port type %d unknown\n",
  174. entry->port_type);
  175. kfree(i2c);
  176. return -EINVAL;
  177. }
  178. snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
  179. "nouveau-%s-%d", pci_name(dev->pdev), index);
  180. i2c->adapter.owner = THIS_MODULE;
  181. i2c->adapter.dev.parent = &dev->pdev->dev;
  182. i2c->dev = dev;
  183. i2c_set_adapdata(&i2c->adapter, i2c);
  184. if (entry->port_type < 6) {
  185. i2c->adapter.algo_data = &i2c->algo.bit;
  186. i2c->algo.bit.udelay = 40;
  187. i2c->algo.bit.timeout = usecs_to_jiffies(5000);
  188. i2c->algo.bit.data = i2c;
  189. ret = i2c_bit_add_bus(&i2c->adapter);
  190. } else {
  191. i2c->adapter.algo_data = &i2c->algo.dp;
  192. i2c->algo.dp.running = false;
  193. i2c->algo.dp.address = 0;
  194. i2c->algo.dp.aux_ch = nouveau_dp_i2c_aux_ch;
  195. ret = i2c_dp_aux_add_bus(&i2c->adapter);
  196. }
  197. if (ret) {
  198. NV_ERROR(dev, "Failed to register i2c %d\n", index);
  199. kfree(i2c);
  200. return ret;
  201. }
  202. entry->chan = i2c;
  203. return 0;
  204. }
  205. void
  206. nouveau_i2c_fini(struct drm_device *dev, struct dcb_i2c_entry *entry)
  207. {
  208. if (!entry->chan)
  209. return;
  210. i2c_del_adapter(&entry->chan->adapter);
  211. kfree(entry->chan);
  212. entry->chan = NULL;
  213. }
  214. struct nouveau_i2c_chan *
  215. nouveau_i2c_find(struct drm_device *dev, int index)
  216. {
  217. struct drm_nouveau_private *dev_priv = dev->dev_private;
  218. struct nvbios *bios = &dev_priv->VBIOS;
  219. if (index > DCB_MAX_NUM_I2C_ENTRIES)
  220. return NULL;
  221. if (!bios->bdcb.dcb.i2c[index].chan) {
  222. if (nouveau_i2c_init(dev, &bios->bdcb.dcb.i2c[index], index))
  223. return NULL;
  224. }
  225. return bios->bdcb.dcb.i2c[index].chan;
  226. }