i2c-iop3xx.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. /* ------------------------------------------------------------------------- */
  2. /* i2c-iop3xx.c i2c driver algorithms for Intel XScale IOP3xx & IXP46x */
  3. /* ------------------------------------------------------------------------- */
  4. /* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
  5. * <Peter dot Milne at D hyphen TACQ dot com>
  6. *
  7. * With acknowledgements to i2c-algo-ibm_ocp.c by
  8. * Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com
  9. *
  10. * And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund:
  11. *
  12. * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund
  13. *
  14. * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>,
  15. * Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com>
  16. *
  17. * Major cleanup by Deepak Saxena <dsaxena@plexity.net>, 01/2005:
  18. *
  19. * - Use driver model to pass per-chip info instead of hardcoding and #ifdefs
  20. * - Use ioremap/__raw_readl/__raw_writel instead of direct dereference
  21. * - Make it work with IXP46x chips
  22. * - Cleanup function names, coding style, etc
  23. *
  24. * - writing to slave address causes latchup on iop331.
  25. * fix: driver refuses to address self.
  26. *
  27. * This program is free software; you can redistribute it and/or modify
  28. * it under the terms of the GNU General Public License as published by
  29. * the Free Software Foundation, version 2.
  30. */
  31. #include <linux/interrupt.h>
  32. #include <linux/kernel.h>
  33. #include <linux/module.h>
  34. #include <linux/delay.h>
  35. #include <linux/slab.h>
  36. #include <linux/init.h>
  37. #include <linux/errno.h>
  38. #include <linux/platform_device.h>
  39. #include <linux/i2c.h>
  40. #include <linux/io.h>
  41. #include <linux/gpio.h>
  42. #include "i2c-iop3xx.h"
  43. /* global unit counter */
  44. static int i2c_id;
  45. static inline unsigned char
  46. iic_cook_addr(struct i2c_msg *msg)
  47. {
  48. unsigned char addr;
  49. addr = (msg->addr << 1);
  50. if (msg->flags & I2C_M_RD)
  51. addr |= 1;
  52. return addr;
  53. }
  54. static void
  55. iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap)
  56. {
  57. /* Follows devman 9.3 */
  58. __raw_writel(IOP3XX_ICR_UNIT_RESET, iop3xx_adap->ioaddr + CR_OFFSET);
  59. __raw_writel(IOP3XX_ISR_CLEARBITS, iop3xx_adap->ioaddr + SR_OFFSET);
  60. __raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET);
  61. }
  62. static void
  63. iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
  64. {
  65. u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE;
  66. /*
  67. * Every time unit enable is asserted, GPOD needs to be cleared
  68. * on IOP3XX to avoid data corruption on the bus.
  69. */
  70. #if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X)
  71. if (iop3xx_adap->id == 0) {
  72. gpio_set_value(7, 0);
  73. gpio_set_value(6, 0);
  74. } else {
  75. gpio_set_value(5, 0);
  76. gpio_set_value(4, 0);
  77. }
  78. #endif
  79. /* NB SR bits not same position as CR IE bits :-( */
  80. iop3xx_adap->SR_enabled =
  81. IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD |
  82. IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY;
  83. cr |= IOP3XX_ICR_ALD_IE | IOP3XX_ICR_BERR_IE |
  84. IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE;
  85. __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
  86. }
  87. static void
  88. iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
  89. {
  90. unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
  91. cr &= ~(IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE |
  92. IOP3XX_ICR_MSTOP | IOP3XX_ICR_SCLEN);
  93. __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
  94. }
  95. /*
  96. * NB: the handler has to clear the source of the interrupt!
  97. * Then it passes the SR flags of interest to BH via adap data
  98. */
  99. static irqreturn_t
  100. iop3xx_i2c_irq_handler(int this_irq, void *dev_id)
  101. {
  102. struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id;
  103. u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET);
  104. if ((sr &= iop3xx_adap->SR_enabled)) {
  105. __raw_writel(sr, iop3xx_adap->ioaddr + SR_OFFSET);
  106. iop3xx_adap->SR_received |= sr;
  107. wake_up_interruptible(&iop3xx_adap->waitq);
  108. }
  109. return IRQ_HANDLED;
  110. }
  111. /* check all error conditions, clear them , report most important */
  112. static int
  113. iop3xx_i2c_error(u32 sr)
  114. {
  115. int rc = 0;
  116. if ((sr & IOP3XX_ISR_BERRD)) {
  117. if ( !rc ) rc = -I2C_ERR_BERR;
  118. }
  119. if ((sr & IOP3XX_ISR_ALD)) {
  120. if ( !rc ) rc = -I2C_ERR_ALD;
  121. }
  122. return rc;
  123. }
  124. static inline u32
  125. iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap)
  126. {
  127. unsigned long flags;
  128. u32 sr;
  129. spin_lock_irqsave(&iop3xx_adap->lock, flags);
  130. sr = iop3xx_adap->SR_received;
  131. iop3xx_adap->SR_received = 0;
  132. spin_unlock_irqrestore(&iop3xx_adap->lock, flags);
  133. return sr;
  134. }
  135. /*
  136. * sleep until interrupted, then recover and analyse the SR
  137. * saved by handler
  138. */
  139. typedef int (* compare_func)(unsigned test, unsigned mask);
  140. /* returns 1 on correct comparison */
  141. static int
  142. iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap,
  143. unsigned flags, unsigned* status,
  144. compare_func compare)
  145. {
  146. unsigned sr = 0;
  147. int interrupted;
  148. int done;
  149. int rc = 0;
  150. do {
  151. interrupted = wait_event_interruptible_timeout (
  152. iop3xx_adap->waitq,
  153. (done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )),
  154. 1 * HZ;
  155. );
  156. if ((rc = iop3xx_i2c_error(sr)) < 0) {
  157. *status = sr;
  158. return rc;
  159. } else if (!interrupted) {
  160. *status = sr;
  161. return -ETIMEDOUT;
  162. }
  163. } while(!done);
  164. *status = sr;
  165. return 0;
  166. }
  167. /*
  168. * Concrete compare_funcs
  169. */
  170. static int
  171. all_bits_clear(unsigned test, unsigned mask)
  172. {
  173. return (test & mask) == 0;
  174. }
  175. static int
  176. any_bits_set(unsigned test, unsigned mask)
  177. {
  178. return (test & mask) != 0;
  179. }
  180. static int
  181. iop3xx_i2c_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
  182. {
  183. return iop3xx_i2c_wait_event(
  184. iop3xx_adap,
  185. IOP3XX_ISR_TXEMPTY | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD,
  186. status, any_bits_set);
  187. }
  188. static int
  189. iop3xx_i2c_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
  190. {
  191. return iop3xx_i2c_wait_event(
  192. iop3xx_adap,
  193. IOP3XX_ISR_RXFULL | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD,
  194. status, any_bits_set);
  195. }
  196. static int
  197. iop3xx_i2c_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
  198. {
  199. return iop3xx_i2c_wait_event(
  200. iop3xx_adap, IOP3XX_ISR_UNITBUSY, status, all_bits_clear);
  201. }
  202. static int
  203. iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
  204. struct i2c_msg* msg)
  205. {
  206. unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
  207. int status;
  208. int rc;
  209. /* avoid writing to my slave address (hangs on 80331),
  210. * forbidden in Intel developer manual
  211. */
  212. if (msg->addr == MYSAR) {
  213. return -EBUSY;
  214. }
  215. __raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET);
  216. cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK);
  217. cr |= IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE;
  218. __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
  219. rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status);
  220. return rc;
  221. }
  222. static int
  223. iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte,
  224. int stop)
  225. {
  226. unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
  227. int status;
  228. int rc = 0;
  229. __raw_writel(byte, iop3xx_adap->ioaddr + DBR_OFFSET);
  230. cr &= ~IOP3XX_ICR_MSTART;
  231. if (stop) {
  232. cr |= IOP3XX_ICR_MSTOP;
  233. } else {
  234. cr &= ~IOP3XX_ICR_MSTOP;
  235. }
  236. cr |= IOP3XX_ICR_TBYTE;
  237. __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
  238. rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status);
  239. return rc;
  240. }
  241. static int
  242. iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte,
  243. int stop)
  244. {
  245. unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
  246. int status;
  247. int rc = 0;
  248. cr &= ~IOP3XX_ICR_MSTART;
  249. if (stop) {
  250. cr |= IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK;
  251. } else {
  252. cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK);
  253. }
  254. cr |= IOP3XX_ICR_TBYTE;
  255. __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
  256. rc = iop3xx_i2c_wait_rx_done(iop3xx_adap, &status);
  257. *byte = __raw_readl(iop3xx_adap->ioaddr + DBR_OFFSET);
  258. return rc;
  259. }
  260. static int
  261. iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, const char *buf, int count)
  262. {
  263. struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
  264. int ii;
  265. int rc = 0;
  266. for (ii = 0; rc == 0 && ii != count; ++ii)
  267. rc = iop3xx_i2c_write_byte(iop3xx_adap, buf[ii], ii==count-1);
  268. return rc;
  269. }
  270. static int
  271. iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count)
  272. {
  273. struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
  274. int ii;
  275. int rc = 0;
  276. for (ii = 0; rc == 0 && ii != count; ++ii)
  277. rc = iop3xx_i2c_read_byte(iop3xx_adap, &buf[ii], ii==count-1);
  278. return rc;
  279. }
  280. /*
  281. * Description: This function implements combined transactions. Combined
  282. * transactions consist of combinations of reading and writing blocks of data.
  283. * FROM THE SAME ADDRESS
  284. * Each transfer (i.e. a read or a write) is separated by a repeated start
  285. * condition.
  286. */
  287. static int
  288. iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg)
  289. {
  290. struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
  291. int rc;
  292. rc = iop3xx_i2c_send_target_addr(iop3xx_adap, pmsg);
  293. if (rc < 0) {
  294. return rc;
  295. }
  296. if ((pmsg->flags&I2C_M_RD)) {
  297. return iop3xx_i2c_readbytes(i2c_adap, pmsg->buf, pmsg->len);
  298. } else {
  299. return iop3xx_i2c_writebytes(i2c_adap, pmsg->buf, pmsg->len);
  300. }
  301. }
  302. /*
  303. * master_xfer() - main read/write entry
  304. */
  305. static int
  306. iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
  307. int num)
  308. {
  309. struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
  310. int im = 0;
  311. int ret = 0;
  312. int status;
  313. iop3xx_i2c_wait_idle(iop3xx_adap, &status);
  314. iop3xx_i2c_reset(iop3xx_adap);
  315. iop3xx_i2c_enable(iop3xx_adap);
  316. for (im = 0; ret == 0 && im != num; im++) {
  317. ret = iop3xx_i2c_handle_msg(i2c_adap, &msgs[im]);
  318. }
  319. iop3xx_i2c_transaction_cleanup(iop3xx_adap);
  320. if(ret)
  321. return ret;
  322. return im;
  323. }
  324. static u32
  325. iop3xx_i2c_func(struct i2c_adapter *adap)
  326. {
  327. return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
  328. }
  329. static const struct i2c_algorithm iop3xx_i2c_algo = {
  330. .master_xfer = iop3xx_i2c_master_xfer,
  331. .functionality = iop3xx_i2c_func,
  332. };
  333. static int
  334. iop3xx_i2c_remove(struct platform_device *pdev)
  335. {
  336. struct i2c_adapter *padapter = platform_get_drvdata(pdev);
  337. struct i2c_algo_iop3xx_data *adapter_data =
  338. (struct i2c_algo_iop3xx_data *)padapter->algo_data;
  339. struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  340. unsigned long cr = __raw_readl(adapter_data->ioaddr + CR_OFFSET);
  341. /*
  342. * Disable the actual HW unit
  343. */
  344. cr &= ~(IOP3XX_ICR_ALD_IE | IOP3XX_ICR_BERR_IE |
  345. IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE);
  346. __raw_writel(cr, adapter_data->ioaddr + CR_OFFSET);
  347. iounmap(adapter_data->ioaddr);
  348. release_mem_region(res->start, IOP3XX_I2C_IO_SIZE);
  349. kfree(adapter_data);
  350. kfree(padapter);
  351. return 0;
  352. }
  353. static int
  354. iop3xx_i2c_probe(struct platform_device *pdev)
  355. {
  356. struct resource *res;
  357. int ret, irq;
  358. struct i2c_adapter *new_adapter;
  359. struct i2c_algo_iop3xx_data *adapter_data;
  360. new_adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
  361. if (!new_adapter) {
  362. ret = -ENOMEM;
  363. goto out;
  364. }
  365. adapter_data = kzalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL);
  366. if (!adapter_data) {
  367. ret = -ENOMEM;
  368. goto free_adapter;
  369. }
  370. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  371. if (!res) {
  372. ret = -ENODEV;
  373. goto free_both;
  374. }
  375. if (!request_mem_region(res->start, IOP3XX_I2C_IO_SIZE, pdev->name)) {
  376. ret = -EBUSY;
  377. goto free_both;
  378. }
  379. /* set the adapter enumeration # */
  380. adapter_data->id = i2c_id++;
  381. adapter_data->ioaddr = ioremap(res->start, IOP3XX_I2C_IO_SIZE);
  382. if (!adapter_data->ioaddr) {
  383. ret = -ENOMEM;
  384. goto release_region;
  385. }
  386. irq = platform_get_irq(pdev, 0);
  387. if (irq < 0) {
  388. ret = -ENXIO;
  389. goto unmap;
  390. }
  391. ret = request_irq(irq, iop3xx_i2c_irq_handler, 0,
  392. pdev->name, adapter_data);
  393. if (ret) {
  394. ret = -EIO;
  395. goto unmap;
  396. }
  397. memcpy(new_adapter->name, pdev->name, strlen(pdev->name));
  398. new_adapter->owner = THIS_MODULE;
  399. new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
  400. new_adapter->dev.parent = &pdev->dev;
  401. new_adapter->nr = pdev->id;
  402. /*
  403. * Default values...should these come in from board code?
  404. */
  405. new_adapter->timeout = HZ;
  406. new_adapter->algo = &iop3xx_i2c_algo;
  407. init_waitqueue_head(&adapter_data->waitq);
  408. spin_lock_init(&adapter_data->lock);
  409. iop3xx_i2c_reset(adapter_data);
  410. iop3xx_i2c_enable(adapter_data);
  411. platform_set_drvdata(pdev, new_adapter);
  412. new_adapter->algo_data = adapter_data;
  413. i2c_add_numbered_adapter(new_adapter);
  414. return 0;
  415. unmap:
  416. iounmap(adapter_data->ioaddr);
  417. release_region:
  418. release_mem_region(res->start, IOP3XX_I2C_IO_SIZE);
  419. free_both:
  420. kfree(adapter_data);
  421. free_adapter:
  422. kfree(new_adapter);
  423. out:
  424. return ret;
  425. }
  426. static struct platform_driver iop3xx_i2c_driver = {
  427. .probe = iop3xx_i2c_probe,
  428. .remove = iop3xx_i2c_remove,
  429. .driver = {
  430. .owner = THIS_MODULE,
  431. .name = "IOP3xx-I2C",
  432. },
  433. };
  434. module_platform_driver(iop3xx_i2c_driver);
  435. MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>");
  436. MODULE_DESCRIPTION("IOP3xx iic algorithm and driver");
  437. MODULE_LICENSE("GPL");
  438. MODULE_ALIAS("platform:IOP3xx-I2C");