i2c_mtk_debug.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. #include <linux/module.h>
  2. #include <linux/init.h>
  3. #include <linux/i2c.h>
  4. #include <linux/platform_device.h>
  5. #include <linux/dma-mapping.h>
  6. #include <linux/slab.h>
  7. #include <linux/errno.h>
  8. #include <linux/err.h>
  9. #include <linux/delay.h>
  10. #include "i2c-mtk.h"
  11. /* filer out error messages */
  12. static char data_buffer[256 * 4];
  13. static inline void i2c_writew_d(struct mt_i2c *i2c, u8 offset, u16 value)
  14. {
  15. writew(value, (void *)((i2c->base) + (offset)));
  16. }
  17. static inline u16 i2c_readw_d(struct mt_i2c *i2c, u8 offset)
  18. {
  19. return readw((void const *)((i2c->base) + (offset)));
  20. }
  21. int mt_i2c_test(int id, int addr)
  22. {
  23. int ret = 0;
  24. /* ret = i2c_trans_data(id, addr, buffer,,buffer, 1, 1, 0); */
  25. return ret;
  26. }
  27. EXPORT_SYMBOL(mt_i2c_test);
  28. int mt_i2c_test_wrrd(int id, int addr, int wr_len, int rd_len, char *wr_buf, char *rd_buf)
  29. {
  30. int ret;
  31. struct i2c_msg msg[2];
  32. struct i2c_adapter *adap;
  33. adap = i2c_get_adapter(id);
  34. if (!adap)
  35. return -1;
  36. msg[0].addr = addr;
  37. msg[0].flags = 0;
  38. msg[0].len = wr_len;
  39. msg[0].buf = wr_buf;
  40. /*for(i = 0; i < wr_len; i++)
  41. {
  42. printk("cxd wr_len = %d i2c_trans_data-%d = 0x%x\n",wr_len, i, wr_buf[i]);
  43. } */
  44. msg[1].addr = addr;
  45. msg[1].flags = I2C_M_RD;
  46. msg[1].len = rd_len;
  47. msg[1].buf = rd_buf;
  48. ret = i2c_transfer(adap, &msg[0], 2);
  49. /*printk("cxd i2c_trans_ret = %d\n", ret);
  50. for(ii = 0; ii<rd_len; ii++)
  51. {
  52. printk("cxd i2c_trans_data-%d = 0x%x\n", ii, rd_buf[ii]);
  53. } */
  54. return ret;
  55. }
  56. static ssize_t show_config(struct device *dev, struct device_attribute *attr, char *buff)
  57. {
  58. int len = strlen(data_buffer);
  59. memcpy(buff, data_buffer, len);
  60. pr_alert("Return Value:%s\n\n", data_buffer);
  61. return len;
  62. }
  63. static int pows(int x, int y)
  64. {
  65. int result = 1;
  66. while (y--)
  67. result *= x;
  68. return result;
  69. }
  70. int string2hex(const char *buffer, int cnt)
  71. {
  72. int c = 0;
  73. char t = 0;
  74. int count = cnt;
  75. while (count--) {
  76. t = *(buffer + cnt - count - 1);
  77. if (t >= 'A' && t <= 'F')
  78. c += ((t - 'A') + 10) * pows(16, count);
  79. else if (t >= '0' && t <= '9')
  80. c += (t - '0') * pows(16, count);
  81. else
  82. c = -1;
  83. }
  84. return c;
  85. }
  86. char *get_hexbuffer(char *data_buffer, char *hex_buffer)
  87. {
  88. char *ptr = data_buffer;
  89. int index = 0;
  90. while (*ptr && *++ptr) {
  91. *(hex_buffer + index++) = string2hex(ptr - 1, 2);
  92. ptr++;
  93. }
  94. *(hex_buffer + index) = 0;
  95. return hex_buffer;
  96. }
  97. int i2c_trans_data(int bus_id, int address, char *buf_wr, char *buf_rd, int operation, int len_wr,
  98. int len_rd)
  99. {
  100. int ret;
  101. struct i2c_msg msg;
  102. struct i2c_adapter *adap;
  103. adap = i2c_get_adapter(bus_id);
  104. if (!adap)
  105. return -1;
  106. msg.addr = address;
  107. if (operation == 2) {
  108. msg.flags = I2C_M_RD;
  109. msg.len = len_rd;
  110. msg.buf = (char *)buf_rd;
  111. } else {
  112. msg.flags = 0;
  113. msg.len = len_wr;
  114. msg.buf = (char *)buf_wr;
  115. }
  116. ret = i2c_transfer(adap, &msg, 1);
  117. /*if(ret > 0) {
  118. for(i = 0; i<msg.len; i++)
  119. {
  120. printk("cxd i2c_trans_data-%d = 0x%x\n", i, msg.buf[i]);
  121. }
  122. } */
  123. i2c_put_adapter(adap);
  124. return (ret == 1) ? msg.len : ret;
  125. }
  126. /* extern mt_i2c ; */
  127. static int i2c_test_reg(int bus_id, int val)
  128. {
  129. int ret = 0;
  130. struct i2c_adapter *adap;
  131. struct mt_i2c *i2c;
  132. adap = i2c_get_adapter(bus_id);
  133. if (!adap)
  134. return -1;
  135. i2c = container_of(adap, struct mt_i2c, adap);
  136. /* printk("I2C%d base address %8x\n", bus_id, (unsigned int)(i2c->base)); */
  137. /* write i2c writable register with 0 */
  138. i2c_writew_d(i2c, OFFSET_SLAVE_ADDR, val);
  139. i2c_writew_d(i2c, OFFSET_INTR_MASK, val);
  140. i2c_writew_d(i2c, OFFSET_INTR_STAT, val);
  141. i2c_writew_d(i2c, OFFSET_CONTROL, val);
  142. i2c_writew_d(i2c, OFFSET_TRANSFER_LEN, val);
  143. i2c_writew_d(i2c, OFFSET_TRANSAC_LEN, val);
  144. i2c_writew_d(i2c, OFFSET_DELAY_LEN, val);
  145. i2c_writew_d(i2c, OFFSET_TIMING, val);
  146. i2c_writew_d(i2c, OFFSET_EXT_CONF, val);
  147. i2c_writew_d(i2c, OFFSET_IO_CONFIG, val);
  148. i2c_writew_d(i2c, OFFSET_HS, val);
  149. /* If everything went ok (i.e. 1 msg transmitted), return #bytes
  150. transmitted, else error code. */
  151. i2c_put_adapter(adap);
  152. return ret;
  153. }
  154. static int i2c_soft_reset(int bus_id)
  155. {
  156. int ret = 0;
  157. struct i2c_adapter *adap;
  158. struct mt_i2c *i2c;
  159. adap = i2c_get_adapter(bus_id);
  160. if (!adap)
  161. return -1;
  162. i2c = container_of(adap, struct mt_i2c, adap);
  163. /* printk("I2C%d base address %8x\n", bus_id, (unsigned int)(i2c->base)); */
  164. /* write i2c writable register with 0 */
  165. i2c_writew_d(i2c, OFFSET_SOFTRESET, 1);
  166. /* If everything went ok (i.e. 1 msg transmitted), return #bytes
  167. transmitted, else error code. */
  168. i2c_put_adapter(adap);
  169. return ret;
  170. }
  171. static int i2c_ext_conf_test(int bus_id, int val)
  172. {
  173. int ret = 0;
  174. struct i2c_adapter *adap;
  175. struct mt_i2c *i2c;
  176. adap = i2c_get_adapter(bus_id);
  177. if (!adap)
  178. return -1;
  179. i2c = container_of(adap, struct mt_i2c, adap);
  180. /* printk("I2C%d base address %8x\n", bus_id, (unsigned int)(i2c->base)); */
  181. /* write i2c writable register with 0 */
  182. i2c_writew_d(i2c, OFFSET_EXT_CONF, val);
  183. /* printk("EXT_CONF 0x%x", i2c_readw_d(i2c, OFFSET_EXT_CONF)); */
  184. /* If everything went ok (i.e. 1 msg transmitted), return #bytes
  185. transmitted, else error code. */
  186. i2c_put_adapter(adap);
  187. return ret;
  188. }
  189. static void hex2string(unsigned char *in, unsigned char *out, int length)
  190. {
  191. unsigned char *ptr = in;
  192. unsigned char *ptrout = out;
  193. unsigned char t;
  194. while (length--) {
  195. t = (*ptr & 0xF0) >> 4;
  196. if (t < 10)
  197. *ptrout = t + '0';
  198. else
  199. *ptrout = t + 'A' - 10;
  200. ptrout++;
  201. t = (*ptr & 0x0F);
  202. if (t < 10)
  203. *ptrout = t + '0';
  204. else
  205. *ptrout = t + 'A' - 10;
  206. ptr++;
  207. ptrout++;
  208. }
  209. *ptrout = 0;
  210. }
  211. static ssize_t set_config(struct device *dev, struct device_attribute *attr, const char *buf,
  212. size_t count)
  213. {
  214. int bus_id;
  215. int address;
  216. int operation;
  217. int wr_number = 0;
  218. int rd_number = 0;
  219. int length = 0;
  220. void *vir_addr_wr = NULL;
  221. void *vir_addr_rd = NULL;
  222. /* int status; */
  223. int ret = 0;
  224. int scanf_ret = 0;
  225. unsigned char tmpbuffer[128];
  226. pr_alert("%s\n", buf);
  227. scanf_ret = sscanf
  228. (buf, "%d %x %d %d %d %s", &bus_id, &address, &operation, &wr_number, &rd_number,
  229. data_buffer);
  230. if (scanf_ret) {
  231. pr_alert("bus_id:%d,address:%x,operation:0x%x\n",
  232. bus_id, address, operation);
  233. if ((address != 0) && (operation <= 2)) {
  234. length = strlen(data_buffer);
  235. if (operation == 1) {
  236. if ((length >> 1) != wr_number)
  237. pr_alert("Error length of data number = %d,length = %d\n",
  238. wr_number, length >> 1);
  239. vir_addr_wr = kzalloc(wr_number, GFP_KERNEL);
  240. if (vir_addr_wr == NULL) {
  241. pr_err("alloc virtual memory failed\n");
  242. goto err;
  243. }
  244. get_hexbuffer(data_buffer, vir_addr_wr);
  245. pr_alert("data_buffer:%s\n", data_buffer);
  246. }
  247. if (operation == 2) {
  248. vir_addr_rd = kzalloc(rd_number, GFP_KERNEL);
  249. if (vir_addr_rd == NULL) {
  250. pr_err("alloc virtual memory failed\n");
  251. goto err;
  252. }
  253. }
  254. if (operation == 0) {
  255. vir_addr_wr = kzalloc(wr_number, GFP_KERNEL);
  256. if (vir_addr_wr == NULL) {
  257. pr_err("alloc virtual memory failed\n");
  258. goto err;
  259. }
  260. vir_addr_rd = kzalloc(rd_number, GFP_KERNEL);
  261. if (vir_addr_rd == NULL) {
  262. pr_err("alloc virtual memory failed\n");
  263. goto err;
  264. }
  265. get_hexbuffer(data_buffer, vir_addr_wr);
  266. pr_alert("data_buffer:%s\n", data_buffer);
  267. }
  268. if (operation == 0) { /* 0:WRRD 1:WR 2:RD */
  269. ret =
  270. mt_i2c_test_wrrd(bus_id, address, wr_number, rd_number,
  271. vir_addr_wr, vir_addr_rd);
  272. } else {
  273. ret =
  274. i2c_trans_data(bus_id, address, vir_addr_wr, vir_addr_rd,
  275. operation, wr_number, rd_number);
  276. }
  277. /* dealing */
  278. if (ret >= 0) {
  279. if (operation == 2) {
  280. hex2string(vir_addr_rd, tmpbuffer, rd_number);
  281. sprintf(data_buffer, "1 %s", tmpbuffer);
  282. pr_alert("Actual return Value:%d %s\n", ret, data_buffer);
  283. } else if (operation == 0) {
  284. hex2string(vir_addr_rd, tmpbuffer, rd_number);
  285. sprintf(data_buffer, "1 %s", tmpbuffer);
  286. pr_alert("Actual return Value:%d %s\n", ret, data_buffer);
  287. } else {
  288. sprintf(data_buffer, "1 %s", "00");
  289. pr_alert("Actual return Value:%d %s\n", ret, data_buffer);
  290. }
  291. } else if (ret < 0) {
  292. if (ret == -EINVAL)
  293. sprintf(data_buffer, "0 %s", "Invalid Parameter");
  294. else if (ret == -ETIMEDOUT)
  295. sprintf(data_buffer, "0 %s", "Transfer Timeout");
  296. else if (ret == -EREMOTEIO)
  297. sprintf(data_buffer, "0 %s", "Ack Error");
  298. else
  299. sprintf(data_buffer, "0 %s", "unknown error");
  300. pr_alert("Actual return Value:%d %p\n", ret, data_buffer);
  301. }
  302. kfree(vir_addr_rd);
  303. kfree(vir_addr_wr);
  304. } else {
  305. struct i2c_adapter *adap = i2c_get_adapter(bus_id);
  306. struct mt_i2c *i2c = i2c_get_adapdata(adap);
  307. if (operation == 3) {
  308. i2c_dump_info(i2c);
  309. } else if (operation == 4) {
  310. i2c_test_reg(bus_id, 0);
  311. i2c_dump_info(i2c);
  312. i2c_test_reg(bus_id, 0xFFFFFFFF);
  313. i2c_dump_info(i2c);
  314. } else if (operation == 5) {
  315. i2c_ext_conf_test(bus_id, address);
  316. } else if (operation == 9) {
  317. i2c_soft_reset(bus_id);
  318. i2c_dump_info(i2c);
  319. } else if (operation == 6) {
  320. if (bus_id == 0) {
  321. /* I2C0 PINMUX2 power on */
  322. /* hwPowerOn(MT65XX_POWER_LDO_VMC1,VOL_DEFAULT,"i2c_pinmux"); */
  323. /* hwPowerOn(MT65XX_POWER_LDO_VMCH1,VOL_DEFAULT,"i2c_pinmux"); */
  324. }
  325. } else if (operation == 7) {
  326. mt_i2c_test(1, 0x50);
  327. } else {
  328. dev_err(dev, "i2c debug system: Parameter invalid!\n");
  329. }
  330. }
  331. } else {
  332. /*parameter invalid */
  333. dev_err(dev, "i2c debug system: Parameter invalid!\n");
  334. }
  335. return count;
  336. err:
  337. pr_err("analyze failed\n");
  338. return -1;
  339. }
  340. static DEVICE_ATTR(ut, 0660, show_config, set_config);
  341. static int i2c_common_probe(struct platform_device *pdev)
  342. {
  343. int ret = 0;
  344. /* your code here£¬your should save client in your own way */
  345. pr_alert("i2c_common device probe\n");
  346. ret = device_create_file(&pdev->dev, &dev_attr_ut);
  347. pr_alert("i2c_common device probe ret = %d\n", ret);
  348. return ret;
  349. }
  350. static int i2c_common_remove(struct platform_device *pdev)
  351. {
  352. int ret = 0;
  353. /* your code here */
  354. device_remove_file(&pdev->dev, &dev_attr_ut);
  355. return ret;
  356. }
  357. static struct platform_driver i2c_common_driver = {
  358. .driver = {
  359. .name = "mt-iicd",
  360. .owner = THIS_MODULE,
  361. },
  362. .probe = i2c_common_probe,
  363. .remove = i2c_common_remove,
  364. };
  365. /* platform device */
  366. static struct platform_device i2c_common_device = {
  367. .name = "mt-iicd",
  368. };
  369. static int __init xxx_init(void)
  370. {
  371. pr_alert("i2c_common device init\n");
  372. platform_device_register(&i2c_common_device);
  373. return platform_driver_register(&i2c_common_driver);
  374. }
  375. static void __exit xxx_exit(void)
  376. {
  377. platform_driver_unregister(&i2c_common_driver);
  378. platform_device_unregister(&i2c_common_device);
  379. }
  380. module_init(xxx_init);
  381. module_exit(xxx_exit);
  382. /* module_platform_driver(i2c_common_driver); */
  383. MODULE_LICENSE("GPL");
  384. MODULE_DESCRIPTION("MediaTek I2C Bus Driver Test Driver");
  385. MODULE_AUTHOR("Ranran Lu");