i2c-algo-sgi.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * i2c-algo-sgi.c: i2c driver algorithm used by the VINO (SGI Indy) and
  3. * MACE (SGI O2) chips.
  4. *
  5. * This file is subject to the terms and conditions of the GNU General Public
  6. * License version 2 as published by the Free Software Foundation.
  7. *
  8. * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <linux/init.h>
  13. #include <linux/errno.h>
  14. #include <linux/delay.h>
  15. #include <linux/i2c.h>
  16. #include <linux/i2c-algo-sgi.h>
  17. #define SGI_I2C_FORCE_IDLE (0 << 0)
  18. #define SGI_I2C_NOT_IDLE (1 << 0)
  19. #define SGI_I2C_WRITE (0 << 1)
  20. #define SGI_I2C_READ (1 << 1)
  21. #define SGI_I2C_RELEASE_BUS (0 << 2)
  22. #define SGI_I2C_HOLD_BUS (1 << 2)
  23. #define SGI_I2C_XFER_DONE (0 << 4)
  24. #define SGI_I2C_XFER_BUSY (1 << 4)
  25. #define SGI_I2C_ACK (0 << 5)
  26. #define SGI_I2C_NACK (1 << 5)
  27. #define SGI_I2C_BUS_OK (0 << 7)
  28. #define SGI_I2C_BUS_ERR (1 << 7)
  29. #define get_control() adap->getctrl(adap->data)
  30. #define set_control(val) adap->setctrl(adap->data, val)
  31. #define read_data() adap->rdata(adap->data)
  32. #define write_data(val) adap->wdata(adap->data, val)
  33. static int wait_xfer_done(struct i2c_algo_sgi_data *adap)
  34. {
  35. int i;
  36. for (i = 0; i < adap->xfer_timeout; i++) {
  37. if ((get_control() & SGI_I2C_XFER_BUSY) == 0)
  38. return 0;
  39. udelay(1);
  40. }
  41. return -ETIMEDOUT;
  42. }
  43. static int wait_ack(struct i2c_algo_sgi_data *adap)
  44. {
  45. int i;
  46. if (wait_xfer_done(adap))
  47. return -ETIMEDOUT;
  48. for (i = 0; i < adap->ack_timeout; i++) {
  49. if ((get_control() & SGI_I2C_NACK) == 0)
  50. return 0;
  51. udelay(1);
  52. }
  53. return -ETIMEDOUT;
  54. }
  55. static int force_idle(struct i2c_algo_sgi_data *adap)
  56. {
  57. int i;
  58. set_control(SGI_I2C_FORCE_IDLE);
  59. for (i = 0; i < adap->xfer_timeout; i++) {
  60. if ((get_control() & SGI_I2C_NOT_IDLE) == 0)
  61. goto out;
  62. udelay(1);
  63. }
  64. return -ETIMEDOUT;
  65. out:
  66. if (get_control() & SGI_I2C_BUS_ERR)
  67. return -EIO;
  68. return 0;
  69. }
  70. static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr,
  71. int rd)
  72. {
  73. if (rd)
  74. set_control(SGI_I2C_NOT_IDLE);
  75. /* Check if bus is idle, eventually force it to do so */
  76. if (get_control() & SGI_I2C_NOT_IDLE)
  77. if (force_idle(adap))
  78. return -EIO;
  79. /* Write out the i2c chip address and specify operation */
  80. set_control(SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE);
  81. if (rd)
  82. addr |= 1;
  83. write_data(addr);
  84. if (wait_ack(adap))
  85. return -EIO;
  86. return 0;
  87. }
  88. static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf,
  89. unsigned int len)
  90. {
  91. int i;
  92. set_control(SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE);
  93. for (i = 0; i < len; i++) {
  94. if (wait_xfer_done(adap))
  95. return -EIO;
  96. buf[i] = read_data();
  97. }
  98. set_control(SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE);
  99. return 0;
  100. }
  101. static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf,
  102. unsigned int len)
  103. {
  104. int i;
  105. /* We are already in write state */
  106. for (i = 0; i < len; i++) {
  107. write_data(buf[i]);
  108. if (wait_ack(adap))
  109. return -EIO;
  110. }
  111. return 0;
  112. }
  113. static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
  114. int num)
  115. {
  116. struct i2c_algo_sgi_data *adap = i2c_adap->algo_data;
  117. struct i2c_msg *p;
  118. int i, err = 0;
  119. for (i = 0; !err && i < num; i++) {
  120. p = &msgs[i];
  121. err = do_address(adap, p->addr, p->flags & I2C_M_RD);
  122. if (err || !p->len)
  123. continue;
  124. if (p->flags & I2C_M_RD)
  125. err = i2c_read(adap, p->buf, p->len);
  126. else
  127. err = i2c_write(adap, p->buf, p->len);
  128. }
  129. return (err < 0) ? err : i;
  130. }
  131. static u32 sgi_func(struct i2c_adapter *adap)
  132. {
  133. return I2C_FUNC_SMBUS_EMUL;
  134. }
  135. static const struct i2c_algorithm sgi_algo = {
  136. .master_xfer = sgi_xfer,
  137. .functionality = sgi_func,
  138. };
  139. /*
  140. * registering functions to load algorithms at runtime
  141. */
  142. int i2c_sgi_add_bus(struct i2c_adapter *adap)
  143. {
  144. adap->algo = &sgi_algo;
  145. return i2c_add_adapter(adap);
  146. }
  147. EXPORT_SYMBOL(i2c_sgi_add_bus);
  148. MODULE_AUTHOR("Ladislav Michl <ladis@linux-mips.org>");
  149. MODULE_DESCRIPTION("I2C-Bus SGI algorithm");
  150. MODULE_LICENSE("GPL");