Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

broadsheetfb: add multiple panel type support

Update broadsheetfb to add support for multiple panel types. The 3.7" and
6" are known to work but the 9.7" is untested due to lack of hardware.

Signed-off-by: Jaya Kumar <jayakumar.lkml@gmail.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Krzysztof Helt <krzysztof.h1@wp.pl>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Jaya Kumar and committed by
Linus Torvalds
c1c341a0 d40f29bf

+111 -17
+1 -1
arch/arm/mach-pxa/am300epd.c
··· 288 288 } 289 289 290 290 module_param(panel_type, uint, 0); 291 - MODULE_PARM_DESC(panel_type, "Select the panel type: 6, 8, 97"); 291 + MODULE_PARM_DESC(panel_type, "Select the panel type: 37, 6, 97"); 292 292 293 293 MODULE_DESCRIPTION("board driver for am300 epd kit"); 294 294 MODULE_AUTHOR("Jaya Kumar");
+109 -16
drivers/video/broadsheetfb.c
··· 33 33 34 34 #include <video/broadsheetfb.h> 35 35 36 - /* Display specific information */ 36 + /* track panel specific parameters */ 37 + struct panel_info { 38 + int w; 39 + int h; 40 + u16 sdcfg; 41 + u16 gdcfg; 42 + u16 lutfmt; 43 + u16 fsynclen; 44 + u16 fendfbegin; 45 + u16 lsynclen; 46 + u16 lendlbegin; 47 + u16 pixclk; 48 + }; 49 + 50 + /* table of panel specific parameters to be indexed into by the board drivers */ 51 + static struct panel_info panel_table[] = { 52 + { /* standard 6" on TFT backplane */ 53 + .w = 800, 54 + .h = 600, 55 + .sdcfg = (100 | (1 << 8) | (1 << 9)), 56 + .gdcfg = 2, 57 + .lutfmt = (4 | (1 << 7)), 58 + .fsynclen = 4, 59 + .fendfbegin = (10 << 8) | 4, 60 + .lsynclen = 10, 61 + .lendlbegin = (100 << 8) | 4, 62 + .pixclk = 6, 63 + }, 64 + { /* custom 3.7" flexible on PET or steel */ 65 + .w = 320, 66 + .h = 240, 67 + .sdcfg = (67 | (0 << 8) | (0 << 9) | (0 << 10) | (0 << 12)), 68 + .gdcfg = 3, 69 + .lutfmt = (4 | (1 << 7)), 70 + .fsynclen = 0, 71 + .fendfbegin = (80 << 8) | 4, 72 + .lsynclen = 10, 73 + .lendlbegin = (80 << 8) | 20, 74 + .pixclk = 14, 75 + }, 76 + { /* standard 9.7" on TFT backplane */ 77 + .w = 1200, 78 + .h = 825, 79 + .sdcfg = (100 | (1 << 8) | (1 << 9) | (0 << 10) | (0 << 12)), 80 + .gdcfg = 2, 81 + .lutfmt = (4 | (1 << 7)), 82 + .fsynclen = 0, 83 + .fendfbegin = (4 << 8) | 4, 84 + .lsynclen = 4, 85 + .lendlbegin = (60 << 8) | 10, 86 + .pixclk = 3, 87 + }, 88 + }; 89 + 37 90 #define DPY_W 800 38 91 #define DPY_H 600 39 92 ··· 213 160 par->board->set_ctl(par, BS_CS, 1); 214 161 } 215 162 163 + static void broadsheet_write_reg32(struct broadsheetfb_par *par, u16 reg, 164 + u32 data) 165 + { 166 + broadsheet_write_reg(par, reg, cpu_to_le32(data) & 0xFFFF); 167 + broadsheet_write_reg(par, reg + 2, (cpu_to_le32(data) >> 16) & 0xFFFF); 168 + } 169 + 170 + 216 171 static u16 broadsheet_read_reg(struct broadsheetfb_par *par, u16 reg) 217 172 { 218 173 broadsheet_send_command(par, reg); ··· 231 170 static void __devinit broadsheet_init_display(struct broadsheetfb_par *par) 232 171 { 233 172 u16 args[5]; 173 + int xres = par->info->var.xres; 174 + int yres = par->info->var.yres; 234 175 235 - args[0] = DPY_W; 236 - args[1] = DPY_H; 237 - args[2] = (100 | (1 << 8) | (1 << 9)); /* sdcfg */ 238 - args[3] = 2; /* gdrv cfg */ 239 - args[4] = (4 | (1 << 7)); /* lut index format */ 176 + args[0] = panel_table[par->panel_index].w; 177 + args[1] = panel_table[par->panel_index].h; 178 + args[2] = panel_table[par->panel_index].sdcfg; 179 + args[3] = panel_table[par->panel_index].gdcfg; 180 + args[4] = panel_table[par->panel_index].lutfmt; 240 181 broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args); 241 182 242 183 /* did the controller really set it? */ 243 184 broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args); 244 185 245 - args[0] = 4; /* fsync len */ 246 - args[1] = (10 << 8) | 4; /* fend/fbegin len */ 247 - args[2] = 10; /* line sync len */ 248 - args[3] = (100 << 8) | 4; /* line end/begin len */ 249 - args[4] = 6; /* pixel clock cfg */ 186 + args[0] = panel_table[par->panel_index].fsynclen; 187 + args[1] = panel_table[par->panel_index].fendfbegin; 188 + args[2] = panel_table[par->panel_index].lsynclen; 189 + args[3] = panel_table[par->panel_index].lendlbegin; 190 + args[4] = panel_table[par->panel_index].pixclk; 250 191 broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_TMG, 5, args); 192 + 193 + broadsheet_write_reg32(par, 0x310, xres*yres*2); 251 194 252 195 /* setup waveform */ 253 196 args[0] = 0x886; ··· 272 207 args[0] = 0x154; 273 208 broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args); 274 209 275 - broadsheet_burst_write(par, DPY_W*DPY_H/2, 276 - (u16 *) par->info->screen_base); 210 + broadsheet_burst_write(par, (panel_table[par->panel_index].w * 211 + panel_table[par->panel_index].h)/2, 212 + (u16 *) par->info->screen_base); 277 213 278 214 broadsheet_send_command(par, BS_CMD_LD_IMG_END); 279 215 ··· 343 277 344 278 args[0] = 0x154; 345 279 broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args); 346 - broadsheet_burst_write(par, DPY_W*DPY_H/2, 347 - (u16 *) par->info->screen_base); 280 + broadsheet_burst_write(par, (panel_table[par->panel_index].w * 281 + panel_table[par->panel_index].h)/2, 282 + (u16 *) par->info->screen_base); 348 283 349 284 broadsheet_send_command(par, BS_CMD_LD_IMG_END); 350 285 ··· 503 436 unsigned char *videomemory; 504 437 struct broadsheetfb_par *par; 505 438 int i; 439 + int dpyw, dpyh; 440 + int panel_index; 506 441 507 442 /* pick up board specific routines */ 508 443 board = dev->dev.platform_data; ··· 519 450 if (!info) 520 451 goto err; 521 452 522 - videomemorysize = (DPY_W*DPY_H); 453 + switch (board->get_panel_type()) { 454 + case 37: 455 + panel_index = 1; 456 + break; 457 + case 97: 458 + panel_index = 2; 459 + break; 460 + case 6: 461 + default: 462 + panel_index = 0; 463 + break; 464 + } 465 + 466 + dpyw = panel_table[panel_index].w; 467 + dpyh = panel_table[panel_index].h; 468 + 469 + videomemorysize = roundup((dpyw*dpyh), PAGE_SIZE); 470 + 523 471 videomemory = vmalloc(videomemorysize); 524 472 if (!videomemory) 525 473 goto err_fb_rel; ··· 546 460 info->screen_base = (char *)videomemory; 547 461 info->fbops = &broadsheetfb_ops; 548 462 463 + broadsheetfb_var.xres = dpyw; 464 + broadsheetfb_var.yres = dpyh; 465 + broadsheetfb_var.xres_virtual = dpyw; 466 + broadsheetfb_var.yres_virtual = dpyh; 549 467 info->var = broadsheetfb_var; 468 + 469 + broadsheetfb_fix.line_length = dpyw; 550 470 info->fix = broadsheetfb_fix; 551 471 info->fix.smem_len = videomemorysize; 552 472 par = info->par; 473 + par->panel_index = panel_index; 553 474 par->info = info; 554 475 par->board = board; 555 476 par->write_reg = broadsheet_write_reg;
+1
include/video/broadsheetfb.h
··· 41 41 void (*write_reg)(struct broadsheetfb_par *, u16 reg, u16 val); 42 42 u16 (*read_reg)(struct broadsheetfb_par *, u16 reg); 43 43 wait_queue_head_t waitq; 44 + int panel_index; 44 45 }; 45 46 46 47 /* board specific routines */