nouveau_i2c.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  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->bit.setsda = nv04_i2c_setsda;
  146. i2c->bit.setscl = nv04_i2c_setscl;
  147. i2c->bit.getsda = nv04_i2c_getsda;
  148. i2c->bit.getscl = nv04_i2c_getscl;
  149. i2c->rd = entry->read;
  150. i2c->wr = entry->write;
  151. break;
  152. case 4:
  153. i2c->bit.setsda = nv4e_i2c_setsda;
  154. i2c->bit.setscl = nv4e_i2c_setscl;
  155. i2c->bit.getsda = nv4e_i2c_getsda;
  156. i2c->bit.getscl = nv4e_i2c_getscl;
  157. i2c->rd = 0x600800 + entry->read;
  158. i2c->wr = 0x600800 + entry->write;
  159. break;
  160. case 5:
  161. i2c->bit.setsda = nv50_i2c_setsda;
  162. i2c->bit.setscl = nv50_i2c_setscl;
  163. i2c->bit.getsda = nv50_i2c_getsda;
  164. i2c->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->bit;
  186. i2c->bit.udelay = 40;
  187. i2c->bit.timeout = usecs_to_jiffies(5000);
  188. i2c->bit.data = i2c;
  189. ret = i2c_bit_add_bus(&i2c->adapter);
  190. } else {
  191. i2c->adapter.algo = &nouveau_dp_i2c_algo;
  192. ret = i2c_add_adapter(&i2c->adapter);
  193. }
  194. if (ret) {
  195. NV_ERROR(dev, "Failed to register i2c %d\n", index);
  196. kfree(i2c);
  197. return ret;
  198. }
  199. entry->chan = i2c;
  200. return 0;
  201. }
  202. void
  203. nouveau_i2c_fini(struct drm_device *dev, struct dcb_i2c_entry *entry)
  204. {
  205. if (!entry->chan)
  206. return;
  207. i2c_del_adapter(&entry->chan->adapter);
  208. kfree(entry->chan);
  209. entry->chan = NULL;
  210. }
  211. struct nouveau_i2c_chan *
  212. nouveau_i2c_find(struct drm_device *dev, int index)
  213. {
  214. struct drm_nouveau_private *dev_priv = dev->dev_private;
  215. struct dcb_i2c_entry *i2c = &dev_priv->vbios.dcb.i2c[index];
  216. if (index >= DCB_MAX_NUM_I2C_ENTRIES)
  217. return NULL;
  218. if (dev_priv->card_type >= NV_50 && (i2c->entry & 0x00000100)) {
  219. uint32_t reg = 0xe500, val;
  220. if (i2c->port_type == 6) {
  221. reg += i2c->read * 0x50;
  222. val = 0x2002;
  223. } else {
  224. reg += ((i2c->entry & 0x1e00) >> 9) * 0x50;
  225. val = 0xe001;
  226. }
  227. nv_wr32(dev, reg, (nv_rd32(dev, reg) & ~0xf003) | val);
  228. }
  229. if (!i2c->chan && nouveau_i2c_init(dev, i2c, index))
  230. return NULL;
  231. return i2c->chan;
  232. }
  233. bool
  234. nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr)
  235. {
  236. uint8_t buf[] = { 0 };
  237. struct i2c_msg msgs[] = {
  238. {
  239. .addr = addr,
  240. .flags = 0,
  241. .len = 1,
  242. .buf = buf,
  243. },
  244. {
  245. .addr = addr,
  246. .flags = I2C_M_RD,
  247. .len = 1,
  248. .buf = buf,
  249. }
  250. };
  251. return i2c_transfer(&i2c->adapter, msgs, 2) == 2;
  252. }
  253. int
  254. nouveau_i2c_identify(struct drm_device *dev, const char *what,
  255. struct i2c_board_info *info,
  256. bool (*match)(struct nouveau_i2c_chan *,
  257. struct i2c_board_info *),
  258. int index)
  259. {
  260. struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index);
  261. int i;
  262. NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index);
  263. for (i = 0; info[i].addr; i++) {
  264. if (nouveau_probe_i2c_addr(i2c, info[i].addr) &&
  265. (!match || match(i2c, &info[i]))) {
  266. NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);
  267. return i;
  268. }
  269. }
  270. NV_DEBUG(dev, "No devices found.\n");
  271. return -ENODEV;
  272. }