dm thin metadata: fix __udivdi3 undefined on 32-bit
[linux/fpc-iii.git] / drivers / staging / fbtft / fbtft-io.c
bloba6f091fb975c71262dade439dad5b22e48d2fe5b
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"
7 int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len)
9 struct spi_transfer t = {
10 .tx_buf = buf,
11 .len = len,
13 struct spi_message m;
15 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
16 "%s(len=%d): ", __func__, len);
18 if (!par->spi) {
19 dev_err(par->info->device,
20 "%s: par->spi is unexpectedly NULL\n", __func__);
21 return -1;
24 spi_message_init(&m);
25 if (par->txbuf.dma && buf == par->txbuf.buf) {
26 t.tx_dma = par->txbuf.dma;
27 m.is_dma_mapped = 1;
29 spi_message_add_tail(&t, &m);
30 return spi_sync(par->spi, &m);
32 EXPORT_SYMBOL(fbtft_write_spi);
34 /**
35 * fbtft_write_spi_emulate_9() - write SPI emulating 9-bit
36 * @par: Driver data
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)
45 u16 *src = buf;
46 u8 *dst = par->extra;
47 size_t size = len / 2;
48 size_t added = 0;
49 int bits, i, j;
50 u64 val, dc, tmp;
52 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
53 "%s(len=%d): ", __func__, len);
55 if (!par->extra) {
56 dev_err(par->info->device, "%s: error: par->extra is NULL\n",
57 __func__);
58 return -EINVAL;
60 if ((len % 8) != 0) {
61 dev_err(par->info->device,
62 "error: len=%zu must be divisible by 8\n", len);
63 return -EINVAL;
66 for (i = 0; i < size; i += 8) {
67 tmp = 0;
68 bits = 63;
69 for (j = 0; j < 7; j++) {
70 dc = (*src & 0x0100) ? 1 : 0;
71 val = *src & 0x00FF;
72 tmp |= dc << bits;
73 bits -= 8;
74 tmp |= val << bits--;
75 src++;
77 tmp |= ((*src & 0x0100) ? 1 : 0);
78 *(u64 *)dst = cpu_to_be64(tmp);
79 dst += 8;
80 *dst++ = (u8)(*src++ & 0x00FF);
81 added++;
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)
90 int ret;
91 u8 txbuf[32] = { 0, };
92 struct spi_transfer t = {
93 .speed_hz = 2000000,
94 .rx_buf = buf,
95 .len = len,
97 struct spi_message m;
99 if (!par->spi) {
100 dev_err(par->info->device,
101 "%s: par->spi is unexpectedly NULL\n", __func__);
102 return -ENODEV;
105 if (par->startbyte) {
106 if (len > 32) {
107 dev_err(par->info->device,
108 "len=%zu can't be larger than 32 when using 'startbyte'\n",
109 len);
110 return -EINVAL;
112 txbuf[0] = par->startbyte | 0x3;
113 t.tx_buf = txbuf;
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);
124 return ret;
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)
134 u8 data;
135 int i;
136 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
137 static u8 prev_data;
138 #endif
140 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
141 "%s(len=%d): ", __func__, len);
143 while (len--) {
144 data = *(u8 *) buf;
146 /* Start writing by pulling down /WR */
147 gpio_set_value(par->gpio.wr, 0);
149 /* Set data */
150 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
151 if (data == prev_data) {
152 gpio_set_value(par->gpio.wr, 0); /* used as delay */
153 } else {
154 for (i = 0; i < 8; i++) {
155 if ((data & 1) != (prev_data & 1))
156 gpio_set_value(par->gpio.db[i],
157 data & 1);
158 data >>= 1;
159 prev_data >>= 1;
162 #else
163 for (i = 0; i < 8; i++) {
164 gpio_set_value(par->gpio.db[i], data & 1);
165 data >>= 1;
167 #endif
169 /* Pullup /WR */
170 gpio_set_value(par->gpio.wr, 1);
172 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
173 prev_data = *(u8 *) buf;
174 #endif
175 buf++;
178 return 0;
180 EXPORT_SYMBOL(fbtft_write_gpio8_wr);
182 int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len)
184 u16 data;
185 int i;
186 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
187 static u16 prev_data;
188 #endif
190 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
191 "%s(len=%d): ", __func__, len);
193 while (len) {
194 data = *(u16 *) buf;
196 /* Start writing by pulling down /WR */
197 gpio_set_value(par->gpio.wr, 0);
199 /* Set data */
200 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
201 if (data == prev_data) {
202 gpio_set_value(par->gpio.wr, 0); /* used as delay */
203 } else {
204 for (i = 0; i < 16; i++) {
205 if ((data & 1) != (prev_data & 1))
206 gpio_set_value(par->gpio.db[i],
207 data & 1);
208 data >>= 1;
209 prev_data >>= 1;
212 #else
213 for (i = 0; i < 16; i++) {
214 gpio_set_value(par->gpio.db[i], data & 1);
215 data >>= 1;
217 #endif
219 /* Pullup /WR */
220 gpio_set_value(par->gpio.wr, 1);
222 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
223 prev_data = *(u16 *) buf;
224 #endif
225 buf += 2;
226 len -= 2;
229 return 0;
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__);
236 return -1;
238 EXPORT_SYMBOL(fbtft_write_gpio16_wr_latched);