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 7 int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len) 8 { 9 struct spi_transfer t = { 10 .tx_buf = buf, 11 .len = len, 12 }; 13 struct spi_message m; 14 15 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len, 16 "%s(len=%d): ", __func__, len); 17 18 if (!par->spi) { 19 dev_err(par->info->device, 20 "%s: par->spi is unexpectedly NULL\n", __func__); 21 return -1; 22 } 23 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; 28 } 29 spi_message_add_tail(&t, &m); 30 return spi_sync(par->spi, &m); 31 } 32 EXPORT_SYMBOL(fbtft_write_spi); 33 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) 39 * 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. 42 */ 43 int fbtft_write_spi_emulate_9(struct fbtft_par *par, void *buf, size_t len) 44 { 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; 51 52 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len, 53 "%s(len=%d): ", __func__, len); 54 55 if (!par->extra) { 56 dev_err(par->info->device, "%s: error: par->extra is NULL\n", 57 __func__); 58 return -EINVAL; 59 } 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; 64 } 65 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++; 76 } 77 tmp |= ((*src & 0x0100) ? 1 : 0); 78 *(u64 *)dst = cpu_to_be64(tmp); 79 dst += 8; 80 *dst++ = (u8)(*src++ & 0x00FF); 81 added++; 82 } 83 84 return spi_write(par->spi, par->extra, size + added); 85 } 86 EXPORT_SYMBOL(fbtft_write_spi_emulate_9); 87 88 int fbtft_read_spi(struct fbtft_par *par, void *buf, size_t len) 89 { 90 int ret; 91 u8 txbuf[32] = { 0, }; 92 struct spi_transfer t = { 93 .speed_hz = 2000000, 94 .rx_buf = buf, 95 .len = len, 96 }; 97 struct spi_message m; 98 99 if (!par->spi) { 100 dev_err(par->info->device, 101 "%s: par->spi is unexpectedly NULL\n", __func__); 102 return -ENODEV; 103 } 104 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; 111 } 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); 116 } 117 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); 123 124 return ret; 125 } 126 EXPORT_SYMBOL(fbtft_read_spi); 127 128 /* 129 * Optimized use of gpiolib is twice as fast as no optimization 130 * only one driver can use the optimized version at a time 131 */ 132 int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len) 133 { 134 u8 data; 135 int i; 136 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO 137 static u8 prev_data; 138 #endif 139 140 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len, 141 "%s(len=%d): ", __func__, len); 142 143 while (len--) { 144 data = *(u8 *)buf; 145 146 /* Start writing by pulling down /WR */ 147 gpio_set_value(par->gpio.wr, 0); 148 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; 160 } 161 } 162 #else 163 for (i = 0; i < 8; i++) { 164 gpio_set_value(par->gpio.db[i], data & 1); 165 data >>= 1; 166 } 167 #endif 168 169 /* Pullup /WR */ 170 gpio_set_value(par->gpio.wr, 1); 171 172 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO 173 prev_data = *(u8 *)buf; 174 #endif 175 buf++; 176 } 177 178 return 0; 179 } 180 EXPORT_SYMBOL(fbtft_write_gpio8_wr); 181 182 int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len) 183 { 184 u16 data; 185 int i; 186 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO 187 static u16 prev_data; 188 #endif 189 190 fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len, 191 "%s(len=%d): ", __func__, len); 192 193 while (len) { 194 data = *(u16 *)buf; 195 196 /* Start writing by pulling down /WR */ 197 gpio_set_value(par->gpio.wr, 0); 198 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; 210 } 211 } 212 #else 213 for (i = 0; i < 16; i++) { 214 gpio_set_value(par->gpio.db[i], data & 1); 215 data >>= 1; 216 } 217 #endif 218 219 /* Pullup /WR */ 220 gpio_set_value(par->gpio.wr, 1); 221 222 #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO 223 prev_data = *(u16 *)buf; 224 #endif 225 buf += 2; 226 len -= 2; 227 } 228 229 return 0; 230 } 231 EXPORT_SYMBOL(fbtft_write_gpio16_wr); 232 233 int fbtft_write_gpio16_wr_latched(struct fbtft_par *par, void *buf, size_t len) 234 { 235 dev_err(par->info->device, "%s: function not implemented\n", __func__); 236 return -1; 237 } 238 EXPORT_SYMBOL(fbtft_write_gpio16_wr_latched); 239