1 #include <linux/export.h>
2 #include <linux/errno.h>
3 #include <linux/gpio.h>
4 #include <linux/spi/spi.h>
7 int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len)
9 struct spi_transfer t = {
15 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
16 "%s(len=%d): ", __func__, len);
19 dev_err(par->info->device,
20 "%s: par->spi is unexpectedly NULL\n", __func__);
25 if (par->txbuf.dma && buf == par->txbuf.buf) {
26 t.tx_dma = par->txbuf.dma;
29 spi_message_add_tail(&t, &m);
30 return spi_sync(par->spi, &m);
32 EXPORT_SYMBOL(fbtft_write_spi);
35 * fbtft_write_spi_emulate_9() - write SPI emulating 9-bit
37 * @buf: Buffer to write
38 * @len: Length of buffer (must be divisible by 8)
40 * When 9-bit SPI is not available, this function can be used to emulate that.
41 * par->extra must hold a transformation buffer used for transfer.
43 int fbtft_write_spi_emulate_9(struct fbtft_par *par, void *buf, size_t len)
47 size_t size = len / 2;
52 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
53 "%s(len=%d): ", __func__, len);
56 dev_err(par->info->device, "%s: error: par->extra is NULL\n",
61 dev_err(par->info->device,
62 "%s: error: len=%d must be divisible by 8\n",
67 for (i = 0; i < size; i += 8) {
70 for (j = 0; j < 7; j++) {
71 dc = (*src & 0x0100) ? 1 : 0;
78 tmp |= ((*src & 0x0100) ? 1 : 0);
79 *(u64 *)dst = cpu_to_be64(tmp);
81 *dst++ = (u8)(*src++ & 0x00FF);
85 return spi_write(par->spi, par->extra, size + added);
87 EXPORT_SYMBOL(fbtft_write_spi_emulate_9);
89 int fbtft_read_spi(struct fbtft_par *par, void *buf, size_t len)
92 u8 txbuf[32] = { 0, };
93 struct spi_transfer t = {
101 dev_err(par->info->device,
102 "%s: par->spi is unexpectedly NULL\n", __func__);
106 if (par->startbyte) {
108 dev_err(par->info->device,
109 "%s: len=%d can't be larger than 32 when using 'startbyte'\n",
113 txbuf[0] = par->startbyte | 0x3;
115 fbtft_par_dbg_hex(DEBUG_READ, par, par->info->device, u8,
116 txbuf, len, "%s(len=%d) txbuf => ", __func__, len);
119 spi_message_init(&m);
120 spi_message_add_tail(&t, &m);
121 ret = spi_sync(par->spi, &m);
122 fbtft_par_dbg_hex(DEBUG_READ, par, par->info->device, u8, buf, len,
123 "%s(len=%d) buf <= ", __func__, len);
127 EXPORT_SYMBOL(fbtft_read_spi);
130 * Optimized use of gpiolib is twice as fast as no optimization
131 * only one driver can use the optimized version at a time
133 int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len)
137 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
141 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
142 "%s(len=%d): ", __func__, len);
147 /* Start writing by pulling down /WR */
148 gpio_set_value(par->gpio.wr, 0);
151 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
152 if (data == prev_data) {
153 gpio_set_value(par->gpio.wr, 0); /* used as delay */
155 for (i = 0; i < 8; i++) {
156 if ((data & 1) != (prev_data & 1))
157 gpio_set_value(par->gpio.db[i],
164 for (i = 0; i < 8; i++) {
165 gpio_set_value(par->gpio.db[i], (data & 1));
171 gpio_set_value(par->gpio.wr, 1);
173 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
174 prev_data = *(u8 *) buf;
181 EXPORT_SYMBOL(fbtft_write_gpio8_wr);
183 int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len)
187 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
188 static u16 prev_data;
191 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
192 "%s(len=%d): ", __func__, len);
197 /* Start writing by pulling down /WR */
198 gpio_set_value(par->gpio.wr, 0);
201 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
202 if (data == prev_data) {
203 gpio_set_value(par->gpio.wr, 0); /* used as delay */
205 for (i = 0; i < 16; i++) {
206 if ((data & 1) != (prev_data & 1))
207 gpio_set_value(par->gpio.db[i],
214 for (i = 0; i < 16; i++) {
215 gpio_set_value(par->gpio.db[i], (data & 1));
221 gpio_set_value(par->gpio.wr, 1);
223 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
224 prev_data = *(u16 *) buf;
232 EXPORT_SYMBOL(fbtft_write_gpio16_wr);
234 int fbtft_write_gpio16_wr_latched(struct fbtft_par *par, void *buf, size_t len)
236 dev_err(par->info->device, "%s: function not implemented\n", __func__);
239 EXPORT_SYMBOL(fbtft_write_gpio16_wr_latched);