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 "error: len=%zu must be divisible by 8\n", len
);
66 for (i
= 0; i
< size
; i
+= 8) {
69 for (j
= 0; j
< 7; j
++) {
70 dc
= (*src
& 0x0100) ? 1 : 0;
77 tmp
|= ((*src
& 0x0100) ? 1 : 0);
78 *(u64
*)dst
= cpu_to_be64(tmp
);
80 *dst
++ = (u8
)(*src
++ & 0x00FF);
84 return spi_write(par
->spi
, par
->extra
, size
+ added
);
86 EXPORT_SYMBOL(fbtft_write_spi_emulate_9
);
88 int fbtft_read_spi(struct fbtft_par
*par
, void *buf
, size_t len
)
91 u8 txbuf
[32] = { 0, };
92 struct spi_transfer t
= {
100 dev_err(par
->info
->device
,
101 "%s: par->spi is unexpectedly NULL\n", __func__
);
105 if (par
->startbyte
) {
107 dev_err(par
->info
->device
,
108 "len=%zu can't be larger than 32 when using 'startbyte'\n",
112 txbuf
[0] = par
->startbyte
| 0x3;
114 fbtft_par_dbg_hex(DEBUG_READ
, par
, par
->info
->device
, u8
,
115 txbuf
, len
, "%s(len=%d) txbuf => ", __func__
, len
);
118 spi_message_init(&m
);
119 spi_message_add_tail(&t
, &m
);
120 ret
= spi_sync(par
->spi
, &m
);
121 fbtft_par_dbg_hex(DEBUG_READ
, par
, par
->info
->device
, u8
, buf
, len
,
122 "%s(len=%d) buf <= ", __func__
, len
);
126 EXPORT_SYMBOL(fbtft_read_spi
);
129 * Optimized use of gpiolib is twice as fast as no optimization
130 * only one driver can use the optimized version at a time
132 int fbtft_write_gpio8_wr(struct fbtft_par
*par
, void *buf
, size_t len
)
136 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
140 fbtft_par_dbg_hex(DEBUG_WRITE
, par
, par
->info
->device
, u8
, buf
, len
,
141 "%s(len=%d): ", __func__
, len
);
146 /* Start writing by pulling down /WR */
147 gpio_set_value(par
->gpio
.wr
, 0);
150 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
151 if (data
== prev_data
) {
152 gpio_set_value(par
->gpio
.wr
, 0); /* used as delay */
154 for (i
= 0; i
< 8; i
++) {
155 if ((data
& 1) != (prev_data
& 1))
156 gpio_set_value(par
->gpio
.db
[i
],
163 for (i
= 0; i
< 8; i
++) {
164 gpio_set_value(par
->gpio
.db
[i
], data
& 1);
170 gpio_set_value(par
->gpio
.wr
, 1);
172 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
173 prev_data
= *(u8
*) buf
;
180 EXPORT_SYMBOL(fbtft_write_gpio8_wr
);
182 int fbtft_write_gpio16_wr(struct fbtft_par
*par
, void *buf
, size_t len
)
186 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
187 static u16 prev_data
;
190 fbtft_par_dbg_hex(DEBUG_WRITE
, par
, par
->info
->device
, u8
, buf
, len
,
191 "%s(len=%d): ", __func__
, len
);
196 /* Start writing by pulling down /WR */
197 gpio_set_value(par
->gpio
.wr
, 0);
200 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
201 if (data
== prev_data
) {
202 gpio_set_value(par
->gpio
.wr
, 0); /* used as delay */
204 for (i
= 0; i
< 16; i
++) {
205 if ((data
& 1) != (prev_data
& 1))
206 gpio_set_value(par
->gpio
.db
[i
],
213 for (i
= 0; i
< 16; i
++) {
214 gpio_set_value(par
->gpio
.db
[i
], data
& 1);
220 gpio_set_value(par
->gpio
.wr
, 1);
222 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
223 prev_data
= *(u16
*) buf
;
231 EXPORT_SYMBOL(fbtft_write_gpio16_wr
);
233 int fbtft_write_gpio16_wr_latched(struct fbtft_par
*par
, void *buf
, size_t len
)
235 dev_err(par
->info
->device
, "%s: function not implemented\n", __func__
);
238 EXPORT_SYMBOL(fbtft_write_gpio16_wr_latched
);