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 | |
| 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>
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)}" |
