diff options
author | Koen Kooi <koen@dominion.thruhere.net> | 2011-11-30 08:50:27 +0100 |
---|---|---|
committer | Koen Kooi <koen@dominion.thruhere.net> | 2011-11-30 08:50:27 +0100 |
commit | 4ce8fc520934fe035a481ed1bff7e3e9fb655cdc (patch) | |
tree | 5085449f6bb25dcae9123952723266d3f295407d /recipes-kernel | |
parent | 9a9069a5960455ed6e67379dd836fab6a45d5def (diff) | |
download | meta-ti-4ce8fc520934fe035a481ed1bff7e3e9fb655cdc.tar.gz |
linux-ti335x-psp 3.1: add support for ST7735FB, but don't enable it in the beaglebone boardfile yet
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
Diffstat (limited to 'recipes-kernel')
4 files changed, 751 insertions, 6 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.1/beaglebone/defconfig b/recipes-kernel/linux/linux-ti33x-psp-3.1/beaglebone/defconfig index 00872ca9..fcff5914 100644 --- a/recipes-kernel/linux/linux-ti33x-psp-3.1/beaglebone/defconfig +++ b/recipes-kernel/linux/linux-ti33x-psp-3.1/beaglebone/defconfig | |||
@@ -2239,11 +2239,14 @@ CONFIG_FB_CFB_FILLRECT=y | |||
2239 | CONFIG_FB_CFB_COPYAREA=y | 2239 | CONFIG_FB_CFB_COPYAREA=y |
2240 | CONFIG_FB_CFB_IMAGEBLIT=y | 2240 | CONFIG_FB_CFB_IMAGEBLIT=y |
2241 | # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set | 2241 | # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set |
2242 | CONFIG_FB_SYS_FILLRECT=m | 2242 | CONFIG_FB_SYS_FILLRECT=y |
2243 | CONFIG_FB_SYS_COPYAREA=m | 2243 | CONFIG_FB_SYS_COPYAREA=y |
2244 | CONFIG_FB_SYS_IMAGEBLIT=m | 2244 | CONFIG_FB_SYS_IMAGEBLIT=y |
2245 | # CONFIG_FB_FOREIGN_ENDIAN is not set | 2245 | CONFIG_FB_FOREIGN_ENDIAN=y |
2246 | CONFIG_FB_SYS_FOPS=m | 2246 | CONFIG_FB_BOTH_ENDIAN=y |
2247 | # CONFIG_FB_BIG_ENDIAN is not set | ||
2248 | # CONFIG_FB_LITTLE_ENDIAN is not set | ||
2249 | CONFIG_FB_SYS_FOPS=y | ||
2247 | # CONFIG_FB_WMT_GE_ROPS is not set | 2250 | # CONFIG_FB_WMT_GE_ROPS is not set |
2248 | CONFIG_FB_DEFERRED_IO=y | 2251 | CONFIG_FB_DEFERRED_IO=y |
2249 | # CONFIG_FB_SVGALIB is not set | 2252 | # CONFIG_FB_SVGALIB is not set |
@@ -2264,6 +2267,7 @@ CONFIG_FB_DA8XX_CONSISTENT_DMA_SIZE=4 | |||
2264 | # CONFIG_FB_VIRTUAL is not set | 2267 | # CONFIG_FB_VIRTUAL is not set |
2265 | # CONFIG_FB_METRONOME is not set | 2268 | # CONFIG_FB_METRONOME is not set |
2266 | # CONFIG_FB_BROADSHEET is not set | 2269 | # CONFIG_FB_BROADSHEET is not set |
2270 | CONFIG_FB_ST7735=y | ||
2267 | # CONFIG_FB_OMAP_BOOTLOADER_INIT is not set | 2271 | # CONFIG_FB_OMAP_BOOTLOADER_INIT is not set |
2268 | CONFIG_OMAP2_VRAM=y | 2272 | CONFIG_OMAP2_VRAM=y |
2269 | CONFIG_OMAP2_VRFB=y | 2273 | CONFIG_OMAP2_VRFB=y |
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.1/st7735fb/0001-st7735fb-WIP-framebuffer-driver-supporting-Adafruit-.patch b/recipes-kernel/linux/linux-ti33x-psp-3.1/st7735fb/0001-st7735fb-WIP-framebuffer-driver-supporting-Adafruit-.patch new file mode 100644 index 00000000..5e915339 --- /dev/null +++ b/recipes-kernel/linux/linux-ti33x-psp-3.1/st7735fb/0001-st7735fb-WIP-framebuffer-driver-supporting-Adafruit-.patch | |||
@@ -0,0 +1,667 @@ | |||
1 | From a99fbc0639e6c42cd7c53c8d1d4852d04e9f8bb1 Mon Sep 17 00:00:00 2001 | ||
2 | From: Matt Porter <mporter@ti.com> | ||
3 | Date: Mon, 21 Nov 2011 12:55:23 -0500 | ||
4 | Subject: [PATCH 1/2] st7735fb: WIP framebuffer driver supporting Adafruit 1.8" SPI LCD | ||
5 | |||
6 | Signed-off-by: Matt Porter <mporter@ti.com> | ||
7 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
8 | --- | ||
9 | drivers/video/Kconfig | 11 + | ||
10 | drivers/video/Makefile | 1 + | ||
11 | drivers/video/st7735fb.c | 516 ++++++++++++++++++++++++++++++++++++++++++++++ | ||
12 | include/video/st7735fb.h | 86 ++++++++ | ||
13 | 4 files changed, 614 insertions(+), 0 deletions(-) | ||
14 | create mode 100644 drivers/video/st7735fb.c | ||
15 | create mode 100644 include/video/st7735fb.h | ||
16 | |||
17 | diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig | ||
18 | index 792b7841..4ac5eb1 100644 | ||
19 | --- a/drivers/video/Kconfig | ||
20 | +++ b/drivers/video/Kconfig | ||
21 | @@ -2394,6 +2394,17 @@ config FB_PUV3_UNIGFX | ||
22 | Choose this option if you want to use the Unigfx device as a | ||
23 | framebuffer device. Without the support of PCI & AGP. | ||
24 | |||
25 | +config FB_ST7735 | ||
26 | + tristate "ST7735 framebuffer support" | ||
27 | + depends on FB && SPI | ||
28 | + select FB_SYS_FILLRECT | ||
29 | + select FB_SYS_COPYAREA | ||
30 | + select FB_SYS_IMAGEBLIT | ||
31 | + select FB_SYS_FOPS | ||
32 | + select FB_DEFERRED_IO | ||
33 | + help | ||
34 | + Framebuffer support for the ST7735 display controller in SPI mode. | ||
35 | + | ||
36 | source "drivers/video/omap/Kconfig" | ||
37 | source "drivers/video/omap2/Kconfig" | ||
38 | |||
39 | diff --git a/drivers/video/Makefile b/drivers/video/Makefile | ||
40 | index 8b83129..6b67f05 100644 | ||
41 | --- a/drivers/video/Makefile | ||
42 | +++ b/drivers/video/Makefile | ||
43 | @@ -141,6 +141,7 @@ obj-$(CONFIG_FB_MSM) += msm/ | ||
44 | obj-$(CONFIG_FB_NUC900) += nuc900fb.o | ||
45 | obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o | ||
46 | obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o | ||
47 | +obj-$(CONFIG_FB_ST7735) += st7735fb.o | ||
48 | |||
49 | # Platform or fallback drivers go here | ||
50 | obj-$(CONFIG_FB_UVESA) += uvesafb.o | ||
51 | diff --git a/drivers/video/st7735fb.c b/drivers/video/st7735fb.c | ||
52 | new file mode 100644 | ||
53 | index 0000000..500cc88 | ||
54 | --- /dev/null | ||
55 | +++ b/drivers/video/st7735fb.c | ||
56 | @@ -0,0 +1,516 @@ | ||
57 | +/* | ||
58 | + * linux/drivers/video/st7735fb.c -- FB driver for ST7735 LCD controller | ||
59 | + * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. | ||
60 | + * | ||
61 | + * Copyright (C) 2011, Matt Porter | ||
62 | + * | ||
63 | + * This file is subject to the terms and conditions of the GNU General Public | ||
64 | + * License. See the file COPYING in the main directory of this archive for | ||
65 | + * more details. | ||
66 | + */ | ||
67 | + | ||
68 | +#include <linux/module.h> | ||
69 | +#include <linux/kernel.h> | ||
70 | +#include <linux/errno.h> | ||
71 | +#include <linux/string.h> | ||
72 | +#include <linux/mm.h> | ||
73 | +#include <linux/vmalloc.h> | ||
74 | +#include <linux/slab.h> | ||
75 | +#include <linux/init.h> | ||
76 | +#include <linux/fb.h> | ||
77 | +#include <linux/gpio.h> | ||
78 | +#include <linux/spi/spi.h> | ||
79 | +#include <linux/delay.h> | ||
80 | +#include <linux/uaccess.h> | ||
81 | + | ||
82 | +#include <video/st7735fb.h> | ||
83 | + | ||
84 | +static struct st7735_function st7735_cfg_script[] = { | ||
85 | + { ST7735_START, ST7735_START}, | ||
86 | + { ST7735_CMD, ST7735_SWRESET}, | ||
87 | + { ST7735_DELAY, 150}, | ||
88 | + { ST7735_CMD, ST7735_SLPOUT}, | ||
89 | + { ST7735_DELAY, 500}, | ||
90 | + { ST7735_CMD, ST7735_FRMCTR1}, | ||
91 | + { ST7735_DATA, 0x01}, | ||
92 | + { ST7735_DATA, 0x2c}, | ||
93 | + { ST7735_DATA, 0x2d}, | ||
94 | + { ST7735_CMD, ST7735_FRMCTR2}, | ||
95 | + { ST7735_DATA, 0x01}, | ||
96 | + { ST7735_DATA, 0x2c}, | ||
97 | + { ST7735_DATA, 0x2d}, | ||
98 | + { ST7735_CMD, ST7735_FRMCTR3}, | ||
99 | + { ST7735_DATA, 0x01}, | ||
100 | + { ST7735_DATA, 0x2c}, | ||
101 | + { ST7735_DATA, 0x2d}, | ||
102 | + { ST7735_DATA, 0x01}, | ||
103 | + { ST7735_DATA, 0x2c}, | ||
104 | + { ST7735_DATA, 0x2d}, | ||
105 | + { ST7735_CMD, ST7735_INVCTR}, | ||
106 | + { ST7735_DATA, 0x07}, | ||
107 | + { ST7735_CMD, ST7735_PWCTR1}, | ||
108 | + { ST7735_DATA, 0xa2}, | ||
109 | + { ST7735_DATA, 0x02}, | ||
110 | + { ST7735_DATA, 0x84}, | ||
111 | + { ST7735_CMD, ST7735_PWCTR2}, | ||
112 | + { ST7735_DATA, 0xc5}, | ||
113 | + { ST7735_CMD, ST7735_PWCTR3}, | ||
114 | + { ST7735_DATA, 0x0a}, | ||
115 | + { ST7735_DATA, 0x00}, | ||
116 | + { ST7735_CMD, ST7735_PWCTR4}, | ||
117 | + { ST7735_DATA, 0x8a}, | ||
118 | + { ST7735_DATA, 0x2a}, | ||
119 | + { ST7735_CMD, ST7735_PWCTR5}, | ||
120 | + { ST7735_DATA, 0x8a}, | ||
121 | + { ST7735_DATA, 0xee}, | ||
122 | + { ST7735_CMD, ST7735_VMCTR1}, | ||
123 | + { ST7735_DATA, 0x0e}, | ||
124 | + { ST7735_CMD, ST7735_INVOFF}, | ||
125 | + { ST7735_CMD, ST7735_MADCTL}, | ||
126 | + { ST7735_DATA, 0xc8}, | ||
127 | + { ST7735_CMD, ST7735_COLMOD}, | ||
128 | + { ST7735_DATA, 0x05}, | ||
129 | + { ST7735_CMD, ST7735_CASET}, | ||
130 | + { ST7735_DATA, 0x00}, | ||
131 | + { ST7735_DATA, 0x00}, | ||
132 | + { ST7735_DATA, 0x00}, | ||
133 | + { ST7735_DATA, 0x00}, | ||
134 | + { ST7735_DATA, 0x7f}, | ||
135 | + { ST7735_CMD, ST7735_RASET}, | ||
136 | + { ST7735_DATA, 0x00}, | ||
137 | + { ST7735_DATA, 0x00}, | ||
138 | + { ST7735_DATA, 0x00}, | ||
139 | + { ST7735_DATA, 0x00}, | ||
140 | + { ST7735_DATA, 0x9f}, | ||
141 | + { ST7735_CMD, ST7735_GMCTRP1}, | ||
142 | + { ST7735_DATA, 0x02}, | ||
143 | + { ST7735_DATA, 0x1c}, | ||
144 | + { ST7735_DATA, 0x07}, | ||
145 | + { ST7735_DATA, 0x12}, | ||
146 | + { ST7735_DATA, 0x37}, | ||
147 | + { ST7735_DATA, 0x32}, | ||
148 | + { ST7735_DATA, 0x29}, | ||
149 | + { ST7735_DATA, 0x2d}, | ||
150 | + { ST7735_DATA, 0x29}, | ||
151 | + { ST7735_DATA, 0x25}, | ||
152 | + { ST7735_DATA, 0x2b}, | ||
153 | + { ST7735_DATA, 0x39}, | ||
154 | + { ST7735_DATA, 0x00}, | ||
155 | + { ST7735_DATA, 0x01}, | ||
156 | + { ST7735_DATA, 0x03}, | ||
157 | + { ST7735_DATA, 0x10}, | ||
158 | + { ST7735_CMD, ST7735_GMCTRN1}, | ||
159 | + { ST7735_DATA, 0x03}, | ||
160 | + { ST7735_DATA, 0x1d}, | ||
161 | + { ST7735_DATA, 0x07}, | ||
162 | + { ST7735_DATA, 0x06}, | ||
163 | + { ST7735_DATA, 0x2e}, | ||
164 | + { ST7735_DATA, 0x2c}, | ||
165 | + { ST7735_DATA, 0x29}, | ||
166 | + { ST7735_DATA, 0x2d}, | ||
167 | + { ST7735_DATA, 0x2e}, | ||
168 | + { ST7735_DATA, 0x2e}, | ||
169 | + { ST7735_DATA, 0x37}, | ||
170 | + { ST7735_DATA, 0x3f}, | ||
171 | + { ST7735_DATA, 0x00}, | ||
172 | + { ST7735_DATA, 0x00}, | ||
173 | + { ST7735_DATA, 0x02}, | ||
174 | + { ST7735_DATA, 0x10}, | ||
175 | + { ST7735_CMD, ST7735_DISPON}, | ||
176 | + { ST7735_DELAY, 100}, | ||
177 | + { ST7735_CMD, ST7735_NORON}, | ||
178 | + { ST7735_DELAY, 10}, | ||
179 | + { ST7735_END, ST7735_END}, | ||
180 | +}; | ||
181 | + | ||
182 | +static struct fb_fix_screeninfo st7735fb_fix __devinitdata = { | ||
183 | + .id = "ST7735", | ||
184 | + .type = FB_TYPE_PACKED_PIXELS, | ||
185 | + .visual = FB_VISUAL_PSEUDOCOLOR, | ||
186 | + .xpanstep = 0, | ||
187 | + .ypanstep = 0, | ||
188 | + .ywrapstep = 0, | ||
189 | + .line_length = WIDTH*BPP/8, | ||
190 | + .accel = FB_ACCEL_NONE, | ||
191 | +}; | ||
192 | + | ||
193 | +static struct fb_var_screeninfo st7735fb_var __devinitdata = { | ||
194 | + .xres = WIDTH, | ||
195 | + .yres = HEIGHT, | ||
196 | + .xres_virtual = WIDTH, | ||
197 | + .yres_virtual = HEIGHT, | ||
198 | + .bits_per_pixel = BPP, | ||
199 | + .nonstd = 1, | ||
200 | +}; | ||
201 | + | ||
202 | +static int st7735_write(struct st7735fb_par *par, u8 data) | ||
203 | +{ | ||
204 | + u8 txbuf[2]; /* allocation from stack must go */ | ||
205 | + | ||
206 | + txbuf[0] = data; | ||
207 | + | ||
208 | + return spi_write(par->spi, &txbuf[0], 1); | ||
209 | +} | ||
210 | + | ||
211 | +static void st7735_write_data(struct st7735fb_par *par, u8 data) | ||
212 | +{ | ||
213 | + int ret = 0; | ||
214 | + | ||
215 | + /* Set data mode */ | ||
216 | + gpio_set_value(par->dc, 1); | ||
217 | + | ||
218 | + ret = st7735_write(par, data); | ||
219 | + if (ret < 0) | ||
220 | + pr_err("%s: write data %02x failed with status %d\n", | ||
221 | + par->info->fix.id, data, ret); | ||
222 | +} | ||
223 | + | ||
224 | +static int st7735_write_data_buf(struct st7735fb_par *par, | ||
225 | + u8 *txbuf, int size) | ||
226 | +{ | ||
227 | + /* Set data mode */ | ||
228 | + gpio_set_value(par->dc, 1); | ||
229 | + | ||
230 | + /* Write entire buffer */ | ||
231 | + return spi_write(par->spi, txbuf, size); | ||
232 | +} | ||
233 | + | ||
234 | +static void st7735_write_cmd(struct st7735fb_par *par, u8 data) | ||
235 | +{ | ||
236 | + int ret = 0; | ||
237 | + | ||
238 | + /* Set command mode */ | ||
239 | + gpio_set_value(par->dc, 0); | ||
240 | + | ||
241 | + ret = st7735_write(par, data); | ||
242 | + if (ret < 0) | ||
243 | + pr_err("%s: write command %02x failed with status %d\n", | ||
244 | + par->info->fix.id, data, ret); | ||
245 | +} | ||
246 | + | ||
247 | +static void st7735_run_cfg_script(struct st7735fb_par *par) | ||
248 | +{ | ||
249 | + int i = 0; | ||
250 | + int end_script = 0; | ||
251 | + | ||
252 | + do { | ||
253 | + switch (st7735_cfg_script[i].cmd) | ||
254 | + { | ||
255 | + case ST7735_START: | ||
256 | + break; | ||
257 | + case ST7735_CMD: | ||
258 | + st7735_write_cmd(par, | ||
259 | + st7735_cfg_script[i].data & 0xff); | ||
260 | + break; | ||
261 | + case ST7735_DATA: | ||
262 | + st7735_write_data(par, | ||
263 | + st7735_cfg_script[i].data & 0xff); | ||
264 | + break; | ||
265 | + case ST7735_DELAY: | ||
266 | + mdelay(st7735_cfg_script[i].data); | ||
267 | + break; | ||
268 | + case ST7735_END: | ||
269 | + end_script = 1; | ||
270 | + } | ||
271 | + i++; | ||
272 | + } while (!end_script); | ||
273 | +} | ||
274 | + | ||
275 | +static void st7735_set_addr_win(struct st7735fb_par *par, | ||
276 | + int xs, int ys, int xe, int ye) | ||
277 | +{ | ||
278 | + st7735_write_cmd(par, ST7735_CASET); | ||
279 | + st7735_write_data(par, 0x00); | ||
280 | + st7735_write_data(par, xs+2); | ||
281 | + st7735_write_data(par, 0x00); | ||
282 | + st7735_write_data(par, xe+2); | ||
283 | + st7735_write_cmd(par, ST7735_RASET); | ||
284 | + st7735_write_data(par, 0x00); | ||
285 | + st7735_write_data(par, ys+1); | ||
286 | + st7735_write_data(par, 0x00); | ||
287 | + st7735_write_data(par, ye+1); | ||
288 | +} | ||
289 | + | ||
290 | +static void st7735_reset(struct st7735fb_par *par) | ||
291 | +{ | ||
292 | + /* Reset controller */ | ||
293 | + gpio_set_value(par->rst, 0); | ||
294 | + udelay(10); | ||
295 | + gpio_set_value(par->rst, 1); | ||
296 | + mdelay(120); | ||
297 | +} | ||
298 | + | ||
299 | +static void st7735fb_update_display(struct st7735fb_par *par) | ||
300 | +{ | ||
301 | + int ret = 0; | ||
302 | + u8 *vmem = par->info->screen_base; | ||
303 | + | ||
304 | + /* | ||
305 | + TODO: | ||
306 | + Allow a subset of pages to be passed in | ||
307 | + (for deferred I/O). Check pages against | ||
308 | + pan display settings to see if they | ||
309 | + should be updated. | ||
310 | + */ | ||
311 | + /* For now, just write the full 40KiB on each update */ | ||
312 | + | ||
313 | + /* Set row/column data window */ | ||
314 | + st7735_set_addr_win(par, 0, 0, WIDTH-1, HEIGHT-1); | ||
315 | + | ||
316 | + /* Internal RAM write command */ | ||
317 | + st7735_write_cmd(par, ST7735_RAMWR); | ||
318 | + | ||
319 | + /* Blast framebuffer to ST7735 internal display RAM */ | ||
320 | + ret = st7735_write_data_buf(par, vmem, WIDTH*HEIGHT*BPP/8); | ||
321 | + if (ret < 0) | ||
322 | + pr_err("%s: spi_write failed to update display buffer\n", | ||
323 | + par->info->fix.id); | ||
324 | +} | ||
325 | + | ||
326 | +static void st7735fb_deferred_io(struct fb_info *info, | ||
327 | + struct list_head *pagelist) | ||
328 | +{ | ||
329 | + st7735fb_update_display(info->par); | ||
330 | +} | ||
331 | + | ||
332 | +static int st7735fb_init_display(struct st7735fb_par *par) | ||
333 | +{ | ||
334 | + /* TODO: Need some error checking on gpios */ | ||
335 | + | ||
336 | + /* Request GPIOs and initialize to default values */ | ||
337 | + gpio_request_one(par->rst, GPIOF_OUT_INIT_HIGH, | ||
338 | + "ST7735 Reset Pin"); | ||
339 | + gpio_request_one(par->dc, GPIOF_OUT_INIT_LOW, | ||
340 | + "ST7735 Data/Command Pin"); | ||
341 | + | ||
342 | + st7735_reset(par); | ||
343 | + | ||
344 | + st7735_run_cfg_script(par); | ||
345 | + | ||
346 | + return 0; | ||
347 | +} | ||
348 | + | ||
349 | +void st7735fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | ||
350 | +{ | ||
351 | + struct st7735fb_par *par = info->par; | ||
352 | + | ||
353 | + sys_fillrect(info, rect); | ||
354 | + | ||
355 | + st7735fb_update_display(par); | ||
356 | +} | ||
357 | + | ||
358 | +void st7735fb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | ||
359 | +{ | ||
360 | + struct st7735fb_par *par = info->par; | ||
361 | + | ||
362 | + sys_copyarea(info, area); | ||
363 | + | ||
364 | + st7735fb_update_display(par); | ||
365 | +} | ||
366 | + | ||
367 | +void st7735fb_imageblit(struct fb_info *info, const struct fb_image *image) | ||
368 | +{ | ||
369 | + struct st7735fb_par *par = info->par; | ||
370 | + | ||
371 | + sys_imageblit(info, image); | ||
372 | + | ||
373 | + st7735fb_update_display(par); | ||
374 | +} | ||
375 | + | ||
376 | +static ssize_t st7735fb_write(struct fb_info *info, const char __user *buf, | ||
377 | + size_t count, loff_t *ppos) | ||
378 | +{ | ||
379 | + struct st7735fb_par *par = info->par; | ||
380 | + unsigned long p = *ppos; | ||
381 | + void *dst; | ||
382 | + int err = 0; | ||
383 | + unsigned long total_size; | ||
384 | + | ||
385 | + if (info->state != FBINFO_STATE_RUNNING) | ||
386 | + return -EPERM; | ||
387 | + | ||
388 | + total_size = info->fix.smem_len; | ||
389 | + | ||
390 | + if (p > total_size) | ||
391 | + return -EFBIG; | ||
392 | + | ||
393 | + if (count > total_size) { | ||
394 | + err = -EFBIG; | ||
395 | + count = total_size; | ||
396 | + } | ||
397 | + | ||
398 | + if (count + p > total_size) { | ||
399 | + if (!err) | ||
400 | + err = -ENOSPC; | ||
401 | + | ||
402 | + count = total_size - p; | ||
403 | + } | ||
404 | + | ||
405 | + dst = (void __force *) (info->screen_base + p); | ||
406 | + | ||
407 | + if (copy_from_user(dst, buf, count)) | ||
408 | + err = -EFAULT; | ||
409 | + | ||
410 | + if (!err) | ||
411 | + *ppos += count; | ||
412 | + | ||
413 | + st7735fb_update_display(par); | ||
414 | + | ||
415 | + return (err) ? err : count; | ||
416 | +} | ||
417 | + | ||
418 | +static struct fb_ops st7735fb_ops = { | ||
419 | + .owner = THIS_MODULE, | ||
420 | + .fb_read = fb_sys_read, | ||
421 | + .fb_write = st7735fb_write, | ||
422 | + .fb_fillrect = st7735fb_fillrect, | ||
423 | + .fb_copyarea = st7735fb_copyarea, | ||
424 | + .fb_imageblit = st7735fb_imageblit, | ||
425 | +}; | ||
426 | + | ||
427 | +static struct fb_deferred_io st7735fb_defio = { | ||
428 | + .delay = HZ, | ||
429 | + .deferred_io = st7735fb_deferred_io, | ||
430 | +}; | ||
431 | + | ||
432 | +static int __devinit st7735fb_probe (struct spi_device *spi) | ||
433 | +{ | ||
434 | + int chip = spi_get_device_id(spi)->driver_data; | ||
435 | + struct st7735fb_platform_data *pdata = spi->dev.platform_data; | ||
436 | + int vmem_size = WIDTH*HEIGHT*BPP/8; | ||
437 | + u8 *vmem; | ||
438 | + struct fb_info *info; | ||
439 | + struct st7735fb_par *par; | ||
440 | + int retval = -ENOMEM; | ||
441 | + | ||
442 | + if (chip != ST7735_DISPLAY_AF_TFT18) { | ||
443 | + pr_err("%s: only the %s device is supported\n", DRVNAME, | ||
444 | + to_spi_driver(spi->dev.driver)->id_table->name); | ||
445 | + return -EINVAL; | ||
446 | + } | ||
447 | + | ||
448 | + if (!pdata) { | ||
449 | + pr_err("%s: platform data required for rst and dc info\n", | ||
450 | + DRVNAME); | ||
451 | + return -EINVAL; | ||
452 | + } | ||
453 | + | ||
454 | + vmem = vzalloc(vmem_size); | ||
455 | + if (!vmem) | ||
456 | + return retval; | ||
457 | + | ||
458 | + info = framebuffer_alloc(sizeof(struct st7735fb_par), &spi->dev); | ||
459 | + if (!info) | ||
460 | + goto fballoc_fail; | ||
461 | + | ||
462 | + info->screen_base = (u8 __force __iomem *)vmem; | ||
463 | + info->fbops = &st7735fb_ops; | ||
464 | + info->fix = st7735fb_fix; | ||
465 | + info->fix.smem_len = vmem_size; | ||
466 | + info->var = st7735fb_var; | ||
467 | + /* Choose any packed pixel format as long as it's RGB565 */ | ||
468 | + info->var.red.offset = 11; | ||
469 | + info->var.red.length = 5; | ||
470 | + info->var.green.offset = 5; | ||
471 | + info->var.green.length = 6; | ||
472 | + info->var.blue.offset = 0; | ||
473 | + info->var.blue.length = 5; | ||
474 | + info->var.transp.offset = 0; | ||
475 | + info->var.transp.length = 0; | ||
476 | + info->flags = FBINFO_FLAG_DEFAULT | | ||
477 | +#ifdef __LITTLE_ENDIAN | ||
478 | + FBINFO_FOREIGN_ENDIAN | | ||
479 | +#endif | ||
480 | + FBINFO_VIRTFB; | ||
481 | + | ||
482 | + info->fbdefio = &st7735fb_defio; | ||
483 | + fb_deferred_io_init(info); | ||
484 | + | ||
485 | + par = info->par; | ||
486 | + par->info = info; | ||
487 | + par->spi = spi; | ||
488 | + par->rst = pdata->rst_gpio; | ||
489 | + par->dc = pdata->dc_gpio; | ||
490 | + | ||
491 | + retval = register_framebuffer(info); | ||
492 | + if (retval < 0) | ||
493 | + goto fbreg_fail; | ||
494 | + | ||
495 | + spi_set_drvdata(spi, info); | ||
496 | + | ||
497 | + retval = st7735fb_init_display(par); | ||
498 | + if (retval < 0) | ||
499 | + goto init_fail; | ||
500 | + | ||
501 | + printk(KERN_INFO | ||
502 | + "fb%d: %s frame buffer device,\n\tusing %d KiB of video memory\n", | ||
503 | + info->node, info->fix.id, vmem_size); | ||
504 | + | ||
505 | + return 0; | ||
506 | + | ||
507 | + | ||
508 | + /* TODO: release gpios on fail */ | ||
509 | +init_fail: | ||
510 | + spi_set_drvdata(spi, NULL); | ||
511 | + | ||
512 | +fbreg_fail: | ||
513 | + framebuffer_release(info); | ||
514 | + | ||
515 | +fballoc_fail: | ||
516 | + vfree(vmem); | ||
517 | + | ||
518 | + return retval; | ||
519 | +} | ||
520 | + | ||
521 | +static int __devexit st7735fb_remove(struct spi_device *spi) | ||
522 | +{ | ||
523 | + struct fb_info *info = spi_get_drvdata(spi); | ||
524 | + | ||
525 | + spi_set_drvdata(spi, NULL); | ||
526 | + | ||
527 | + if (info) { | ||
528 | + unregister_framebuffer(info); | ||
529 | + vfree(info->screen_base); | ||
530 | + framebuffer_release(info); | ||
531 | + } | ||
532 | + | ||
533 | + /* TODO: release gpios */ | ||
534 | + | ||
535 | + return 0; | ||
536 | +} | ||
537 | + | ||
538 | +static const struct spi_device_id st7735fb_ids[] = { | ||
539 | + { "adafruit_tft18", ST7735_DISPLAY_AF_TFT18 }, | ||
540 | + { }, | ||
541 | +}; | ||
542 | + | ||
543 | +MODULE_DEVICE_TABLE(spi, st7735fb_ids); | ||
544 | + | ||
545 | +static struct spi_driver st7735fb_driver = { | ||
546 | + .driver = { | ||
547 | + .name = "st7735fb", | ||
548 | + .owner = THIS_MODULE, | ||
549 | + }, | ||
550 | + .id_table = st7735fb_ids, | ||
551 | + .probe = st7735fb_probe, | ||
552 | + .remove = __devexit_p(st7735fb_remove), | ||
553 | +}; | ||
554 | + | ||
555 | +static int __init st7735fb_init(void) | ||
556 | +{ | ||
557 | + return spi_register_driver(&st7735fb_driver); | ||
558 | +} | ||
559 | + | ||
560 | +static void __exit st7735fb_exit(void) | ||
561 | +{ | ||
562 | + spi_unregister_driver(&st7735fb_driver); | ||
563 | +} | ||
564 | + | ||
565 | +/* ------------------------------------------------------------------------- */ | ||
566 | + | ||
567 | +module_init(st7735fb_init); | ||
568 | +module_exit(st7735fb_exit); | ||
569 | + | ||
570 | +MODULE_DESCRIPTION("FB driver for ST7735 display controller"); | ||
571 | +MODULE_AUTHOR("Matt Porter"); | ||
572 | +MODULE_LICENSE("GPL"); | ||
573 | diff --git a/include/video/st7735fb.h b/include/video/st7735fb.h | ||
574 | new file mode 100644 | ||
575 | index 0000000..250f036 | ||
576 | --- /dev/null | ||
577 | +++ b/include/video/st7735fb.h | ||
578 | @@ -0,0 +1,86 @@ | ||
579 | +/* | ||
580 | + * linux/include/video/st7735fb.h -- FB driver for ST7735 LCD controller | ||
581 | + * | ||
582 | + * Copyright (C) 2011, Matt Porter | ||
583 | + * | ||
584 | + * This file is subject to the terms and conditions of the GNU General Public | ||
585 | + * License. See the file COPYING in the main directory of this archive for | ||
586 | + * more details. | ||
587 | + */ | ||
588 | + | ||
589 | +#define DRVNAME "st7735fb" | ||
590 | +#define WIDTH 128 | ||
591 | +#define HEIGHT 160 | ||
592 | +#define BPP 16 | ||
593 | + | ||
594 | +/* Supported display modules */ | ||
595 | +#define ST7735_DISPLAY_AF_TFT18 0 /* Adafruit SPI TFT 1.8" */ | ||
596 | + | ||
597 | +/* Init script function */ | ||
598 | +struct st7735_function { | ||
599 | + u16 cmd; | ||
600 | + u16 data; | ||
601 | +}; | ||
602 | + | ||
603 | +/* Init script commands */ | ||
604 | +enum st7735_cmd { | ||
605 | + ST7735_START, | ||
606 | + ST7735_END, | ||
607 | + ST7735_CMD, | ||
608 | + ST7735_DATA, | ||
609 | + ST7735_DELAY | ||
610 | +}; | ||
611 | + | ||
612 | +struct st7735fb_par { | ||
613 | + struct spi_device *spi; | ||
614 | + struct fb_info *info; | ||
615 | + int rst; | ||
616 | + int dc; | ||
617 | +}; | ||
618 | + | ||
619 | +struct st7735fb_platform_data { | ||
620 | + int rst_gpio; | ||
621 | + int dc_gpio; | ||
622 | +}; | ||
623 | + | ||
624 | +/* ST7735 Commands */ | ||
625 | +#define ST7735_NOP 0x0 | ||
626 | +#define ST7735_SWRESET 0x01 | ||
627 | +#define ST7735_RDDID 0x04 | ||
628 | +#define ST7735_RDDST 0x09 | ||
629 | +#define ST7735_SLPIN 0x10 | ||
630 | +#define ST7735_SLPOUT 0x11 | ||
631 | +#define ST7735_PTLON 0x12 | ||
632 | +#define ST7735_NORON 0x13 | ||
633 | +#define ST7735_INVOFF 0x20 | ||
634 | +#define ST7735_INVON 0x21 | ||
635 | +#define ST7735_DISPOFF 0x28 | ||
636 | +#define ST7735_DISPON 0x29 | ||
637 | +#define ST7735_CASET 0x2A | ||
638 | +#define ST7735_RASET 0x2B | ||
639 | +#define ST7735_RAMWR 0x2C | ||
640 | +#define ST7735_RAMRD 0x2E | ||
641 | +#define ST7735_COLMOD 0x3A | ||
642 | +#define ST7735_MADCTL 0x36 | ||
643 | +#define ST7735_FRMCTR1 0xB1 | ||
644 | +#define ST7735_FRMCTR2 0xB2 | ||
645 | +#define ST7735_FRMCTR3 0xB3 | ||
646 | +#define ST7735_INVCTR 0xB4 | ||
647 | +#define ST7735_DISSET5 0xB6 | ||
648 | +#define ST7735_PWCTR1 0xC0 | ||
649 | +#define ST7735_PWCTR2 0xC1 | ||
650 | +#define ST7735_PWCTR3 0xC2 | ||
651 | +#define ST7735_PWCTR4 0xC3 | ||
652 | +#define ST7735_PWCTR5 0xC4 | ||
653 | +#define ST7735_VMCTR1 0xC5 | ||
654 | +#define ST7735_RDID1 0xDA | ||
655 | +#define ST7735_RDID2 0xDB | ||
656 | +#define ST7735_RDID3 0xDC | ||
657 | +#define ST7735_RDID4 0xDD | ||
658 | +#define ST7735_GMCTRP1 0xE0 | ||
659 | +#define ST7735_GMCTRN1 0xE1 | ||
660 | +#define ST7735_PWCTR6 0xFC | ||
661 | + | ||
662 | + | ||
663 | + | ||
664 | + | ||
665 | -- | ||
666 | 1.7.2.5 | ||
667 | |||
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.1/st7735fb/0002-beaglebone-hack-in-support-for-the-WIP-st7735fb-driv.patch b/recipes-kernel/linux/linux-ti33x-psp-3.1/st7735fb/0002-beaglebone-hack-in-support-for-the-WIP-st7735fb-driv.patch new file mode 100644 index 00000000..1def7e26 --- /dev/null +++ b/recipes-kernel/linux/linux-ti33x-psp-3.1/st7735fb/0002-beaglebone-hack-in-support-for-the-WIP-st7735fb-driv.patch | |||
@@ -0,0 +1,73 @@ | |||
1 | From dd3f24640c209d8186010dbf2bbabe11f3eb52ce Mon Sep 17 00:00:00 2001 | ||
2 | From: Matt Porter <mporter@ti.com> | ||
3 | Date: Mon, 21 Nov 2011 12:56:52 -0500 | ||
4 | Subject: [PATCH 2/2] beaglebone: hack in support for the WIP st7735fb driver | ||
5 | |||
6 | Signed-off-by: Matt Porter <mporter@ti.com> | ||
7 | --- | ||
8 | arch/arm/mach-omap2/board-am335xevm.c | 28 ++++++++++++++++++++++++++++ | ||
9 | 1 files changed, 28 insertions(+), 0 deletions(-) | ||
10 | |||
11 | diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c | ||
12 | index b27fb97..f049aad 100644 | ||
13 | --- a/arch/arm/mach-omap2/board-am335xevm.c | ||
14 | +++ b/arch/arm/mach-omap2/board-am335xevm.c | ||
15 | @@ -51,6 +51,7 @@ | ||
16 | |||
17 | /* LCD controller is similar to DA850 */ | ||
18 | #include <video/da8xx-fb.h> | ||
19 | +#include <video/st7735fb.h> | ||
20 | |||
21 | #include "control.h" | ||
22 | #include "board-flash.h" | ||
23 | @@ -1094,6 +1095,23 @@ static struct spi_board_info am335x_spi1_slave_info[] = { | ||
24 | }, | ||
25 | }; | ||
26 | |||
27 | +static const struct st7735fb_platform_data bone_st7735fb_data = { | ||
28 | + .rst_gpio = GPIO_TO_PIN(3, 19), | ||
29 | + .dc_gpio = GPIO_TO_PIN(3, 21), | ||
30 | +}; | ||
31 | + | ||
32 | +static struct spi_board_info bone_spi1_slave_info[] = { | ||
33 | + { | ||
34 | + .modalias = "adafruit_tft18", | ||
35 | + .platform_data = &bone_st7735fb_data, | ||
36 | + .irq = -1, | ||
37 | + .max_speed_hz = 8000000, | ||
38 | + .bus_num = 2, | ||
39 | + .chip_select = 0, | ||
40 | + .mode = SPI_MODE_3, | ||
41 | + }, | ||
42 | +}; | ||
43 | + | ||
44 | static void evm_nand_init(int evm_id, int profile) | ||
45 | { | ||
46 | setup_pin_mux(nand_pin_mux); | ||
47 | @@ -1410,6 +1428,14 @@ static void spi1_init(int evm_id, int profile) | ||
48 | return; | ||
49 | } | ||
50 | |||
51 | +/* setup bone spi1 */ | ||
52 | +static void bone_spi1_init(int evm_id, int profile) | ||
53 | +{ | ||
54 | + setup_pin_mux(spi1_pin_mux); | ||
55 | + spi_register_board_info(bone_spi1_slave_info, | ||
56 | + ARRAY_SIZE(bone_spi1_slave_info)); | ||
57 | + return; | ||
58 | +} | ||
59 | |||
60 | static int beaglebone_phy_fixup(struct phy_device *phydev) | ||
61 | { | ||
62 | @@ -1567,6 +1593,8 @@ static struct evm_dev_cfg beaglebone_dev_cfg[] = { | ||
63 | {i2c2_init, DEV_ON_BASEBOARD, PROFILE_NONE}, | ||
64 | {mmc0_init, DEV_ON_BASEBOARD, PROFILE_NONE}, | ||
65 | {boneleds_init, DEV_ON_BASEBOARD, PROFILE_ALL}, | ||
66 | + /* HACK ALERT */ | ||
67 | + {bone_spi1_init, DEV_ON_BASEBOARD, PROFILE_NONE}, | ||
68 | {NULL, 0, 0}, | ||
69 | }; | ||
70 | |||
71 | -- | ||
72 | 1.7.2.5 | ||
73 | |||
diff --git a/recipes-kernel/linux/linux-ti33x-psp_3.1.bb b/recipes-kernel/linux/linux-ti33x-psp_3.1.bb index e1ad8968..46687493 100644 --- a/recipes-kernel/linux/linux-ti33x-psp_3.1.bb +++ b/recipes-kernel/linux/linux-ti33x-psp_3.1.bb | |||
@@ -11,7 +11,7 @@ MULTI_CONFIG_BASE_SUFFIX = "" | |||
11 | 11 | ||
12 | BRANCH = "v3.1-meta-ti-r1r+gitr1d84d8853fa30cf3db2571a5aec572accca4e29d" | 12 | BRANCH = "v3.1-meta-ti-r1r+gitr1d84d8853fa30cf3db2571a5aec572accca4e29d" |
13 | SRCREV = "1d84d8853fa30cf3db2571a5aec572accca4e29d" | 13 | SRCREV = "1d84d8853fa30cf3db2571a5aec572accca4e29d" |
14 | MACHINE_KERNEL_PR_append = "d+gitr${SRCREV}" | 14 | MACHINE_KERNEL_PR_append = "e+gitr${SRCREV}" |
15 | 15 | ||
16 | COMPATIBLE_MACHINE = "(ti33x)" | 16 | COMPATIBLE_MACHINE = "(ti33x)" |
17 | 17 | ||
@@ -54,6 +54,7 @@ PATCHES_OVER_PSP = " \ | |||
54 | file://adc/0008-tscadc-Trigger-through-sysfs.patch \ | 54 | file://adc/0008-tscadc-Trigger-through-sysfs.patch \ |
55 | file://adc/0009-meta-ti-Remove-debug-messages-for-meta-ti.patch \ | 55 | file://adc/0009-meta-ti-Remove-debug-messages-for-meta-ti.patch \ |
56 | file://adc/0010-tscadc-switch-to-polling-instead-of-interrupts.patch \ | 56 | file://adc/0010-tscadc-switch-to-polling-instead-of-interrupts.patch \ |
57 | file://st7735fb/0001-st7735fb-WIP-framebuffer-driver-supporting-Adafruit-.patch \ | ||
57 | " | 58 | " |
58 | 59 | ||
59 | SRC_URI += "${@base_contains('DISTRO_FEATURES', 'tipspkernel', "", "${PATCHES_OVER_PSP}", d)}" | 60 | SRC_URI += "${@base_contains('DISTRO_FEATURES', 'tipspkernel', "", "${PATCHES_OVER_PSP}", d)}" |