fbtft-io.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. #include <linux/export.h>
  2. #include <linux/errno.h>
  3. #include <linux/gpio.h>
  4. #include <linux/spi/spi.h>
  5. #include "fbtft.h"
  6. int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len)
  7. {
  8. struct spi_transfer t = {
  9. .tx_buf = buf,
  10. .len = len,
  11. };
  12. struct spi_message m;
  13. fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
  14. "%s(len=%d): ", __func__, len);
  15. if (!par->spi) {
  16. dev_err(par->info->device,
  17. "%s: par->spi is unexpectedly NULL\n", __func__);
  18. return -1;
  19. }
  20. spi_message_init(&m);
  21. if (par->txbuf.dma && buf == par->txbuf.buf) {
  22. t.tx_dma = par->txbuf.dma;
  23. m.is_dma_mapped = 1;
  24. }
  25. spi_message_add_tail(&t, &m);
  26. return spi_sync(par->spi, &m);
  27. }
  28. EXPORT_SYMBOL(fbtft_write_spi);
  29. /**
  30. * fbtft_write_spi_emulate_9() - write SPI emulating 9-bit
  31. * @par: Driver data
  32. * @buf: Buffer to write
  33. * @len: Length of buffer (must be divisible by 8)
  34. *
  35. * When 9-bit SPI is not available, this function can be used to emulate that.
  36. * par->extra must hold a transformation buffer used for transfer.
  37. */
  38. int fbtft_write_spi_emulate_9(struct fbtft_par *par, void *buf, size_t len)
  39. {
  40. u16 *src = buf;
  41. u8 *dst = par->extra;
  42. size_t size = len / 2;
  43. size_t added = 0;
  44. int bits, i, j;
  45. u64 val, dc, tmp;
  46. fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
  47. "%s(len=%d): ", __func__, len);
  48. if (!par->extra) {
  49. dev_err(par->info->device, "%s: error: par->extra is NULL\n",
  50. __func__);
  51. return -EINVAL;
  52. }
  53. if ((len % 8) != 0) {
  54. dev_err(par->info->device,
  55. "error: len=%zu must be divisible by 8\n", len);
  56. return -EINVAL;
  57. }
  58. for (i = 0; i < size; i += 8) {
  59. tmp = 0;
  60. bits = 63;
  61. for (j = 0; j < 7; j++) {
  62. dc = (*src & 0x0100) ? 1 : 0;
  63. val = *src & 0x00FF;
  64. tmp |= dc << bits;
  65. bits -= 8;
  66. tmp |= val << bits--;
  67. src++;
  68. }
  69. tmp |= ((*src & 0x0100) ? 1 : 0);
  70. *(u64 *)dst = cpu_to_be64(tmp);
  71. dst += 8;
  72. *dst++ = (u8)(*src++ & 0x00FF);
  73. added++;
  74. }
  75. return spi_write(par->spi, par->extra, size + added);
  76. }
  77. EXPORT_SYMBOL(fbtft_write_spi_emulate_9);
  78. int fbtft_read_spi(struct fbtft_par *par, void *buf, size_t len)
  79. {
  80. int ret;
  81. u8 txbuf[32] = { 0, };
  82. struct spi_transfer t = {
  83. .speed_hz = 2000000,
  84. .rx_buf = buf,
  85. .len = len,
  86. };
  87. struct spi_message m;
  88. if (!par->spi) {
  89. dev_err(par->info->device,
  90. "%s: par->spi is unexpectedly NULL\n", __func__);
  91. return -ENODEV;
  92. }
  93. if (par->startbyte) {
  94. if (len > 32) {
  95. dev_err(par->info->device,
  96. "len=%zu can't be larger than 32 when using 'startbyte'\n",
  97. len);
  98. return -EINVAL;
  99. }
  100. txbuf[0] = par->startbyte | 0x3;
  101. t.tx_buf = txbuf;
  102. fbtft_par_dbg_hex(DEBUG_READ, par, par->info->device, u8,
  103. txbuf, len, "%s(len=%d) txbuf => ", __func__, len);
  104. }
  105. spi_message_init(&m);
  106. spi_message_add_tail(&t, &m);
  107. ret = spi_sync(par->spi, &m);
  108. fbtft_par_dbg_hex(DEBUG_READ, par, par->info->device, u8, buf, len,
  109. "%s(len=%d) buf <= ", __func__, len);
  110. return ret;
  111. }
  112. EXPORT_SYMBOL(fbtft_read_spi);
  113. /*
  114. * Optimized use of gpiolib is twice as fast as no optimization
  115. * only one driver can use the optimized version at a time
  116. */
  117. int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len)
  118. {
  119. u8 data;
  120. int i;
  121. #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
  122. static u8 prev_data;
  123. #endif
  124. fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
  125. "%s(len=%d): ", __func__, len);
  126. while (len--) {
  127. data = *(u8 *) buf;
  128. /* Start writing by pulling down /WR */
  129. gpio_set_value(par->gpio.wr, 0);
  130. /* Set data */
  131. #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
  132. if (data == prev_data) {
  133. gpio_set_value(par->gpio.wr, 0); /* used as delay */
  134. } else {
  135. for (i = 0; i < 8; i++) {
  136. if ((data & 1) != (prev_data & 1))
  137. gpio_set_value(par->gpio.db[i],
  138. data & 1);
  139. data >>= 1;
  140. prev_data >>= 1;
  141. }
  142. }
  143. #else
  144. for (i = 0; i < 8; i++) {
  145. gpio_set_value(par->gpio.db[i], data & 1);
  146. data >>= 1;
  147. }
  148. #endif
  149. /* Pullup /WR */
  150. gpio_set_value(par->gpio.wr, 1);
  151. #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
  152. prev_data = *(u8 *) buf;
  153. #endif
  154. buf++;
  155. }
  156. return 0;
  157. }
  158. EXPORT_SYMBOL(fbtft_write_gpio8_wr);
  159. int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len)
  160. {
  161. u16 data;
  162. int i;
  163. #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
  164. static u16 prev_data;
  165. #endif
  166. fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
  167. "%s(len=%d): ", __func__, len);
  168. while (len) {
  169. data = *(u16 *) buf;
  170. /* Start writing by pulling down /WR */
  171. gpio_set_value(par->gpio.wr, 0);
  172. /* Set data */
  173. #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
  174. if (data == prev_data) {
  175. gpio_set_value(par->gpio.wr, 0); /* used as delay */
  176. } else {
  177. for (i = 0; i < 16; i++) {
  178. if ((data & 1) != (prev_data & 1))
  179. gpio_set_value(par->gpio.db[i],
  180. data & 1);
  181. data >>= 1;
  182. prev_data >>= 1;
  183. }
  184. }
  185. #else
  186. for (i = 0; i < 16; i++) {
  187. gpio_set_value(par->gpio.db[i], data & 1);
  188. data >>= 1;
  189. }
  190. #endif
  191. /* Pullup /WR */
  192. gpio_set_value(par->gpio.wr, 1);
  193. #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
  194. prev_data = *(u16 *) buf;
  195. #endif
  196. buf += 2;
  197. len -= 2;
  198. }
  199. return 0;
  200. }
  201. EXPORT_SYMBOL(fbtft_write_gpio16_wr);
  202. int fbtft_write_gpio16_wr_latched(struct fbtft_par *par, void *buf, size_t len)
  203. {
  204. dev_err(par->info->device, "%s: function not implemented\n", __func__);
  205. return -1;
  206. }
  207. EXPORT_SYMBOL(fbtft_write_gpio16_wr_latched);