diff options
author | Jaya Kumar <jayakumar.lkml@gmail.com> | 2010-03-10 18:21:24 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-12 18:52:32 -0500 |
commit | c1c341a060da1bd66a1982198b1a99765b07b8a2 (patch) | |
tree | 775a7bccfc5139450e312c6a3a1dd643aae4ceb8 | |
parent | d40f29bff30a1a50d7ad69bd150c9cda1ce1ba9d (diff) |
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>
-rw-r--r-- | arch/arm/mach-pxa/am300epd.c | 2 | ||||
-rw-r--r-- | drivers/video/broadsheetfb.c | 127 | ||||
-rw-r--r-- | include/video/broadsheetfb.h | 1 |
3 files changed, 112 insertions, 18 deletions
diff --git a/arch/arm/mach-pxa/am300epd.c b/arch/arm/mach-pxa/am300epd.c index 4bd10a17332e..993d75e66390 100644 --- a/arch/arm/mach-pxa/am300epd.c +++ b/arch/arm/mach-pxa/am300epd.c | |||
@@ -288,7 +288,7 @@ int __init am300_init(void) | |||
288 | } | 288 | } |
289 | 289 | ||
290 | module_param(panel_type, uint, 0); | 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 | MODULE_DESCRIPTION("board driver for am300 epd kit"); | 293 | MODULE_DESCRIPTION("board driver for am300 epd kit"); |
294 | MODULE_AUTHOR("Jaya Kumar"); | 294 | MODULE_AUTHOR("Jaya Kumar"); |
diff --git a/drivers/video/broadsheetfb.c b/drivers/video/broadsheetfb.c index df9ccb901d86..8f011062dec5 100644 --- a/drivers/video/broadsheetfb.c +++ b/drivers/video/broadsheetfb.c | |||
@@ -33,7 +33,60 @@ | |||
33 | 33 | ||
34 | #include <video/broadsheetfb.h> | 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 | #define DPY_W 800 | 90 | #define DPY_W 800 |
38 | #define DPY_H 600 | 91 | #define DPY_H 600 |
39 | 92 | ||
@@ -160,6 +213,14 @@ static void broadsheet_write_reg(struct broadsheetfb_par *par, u16 reg, | |||
160 | par->board->set_ctl(par, BS_CS, 1); | 213 | par->board->set_ctl(par, BS_CS, 1); |
161 | } | 214 | } |
162 | 215 | ||
216 | static void broadsheet_write_reg32(struct broadsheetfb_par *par, u16 reg, | ||
217 | u32 data) | ||
218 | { | ||
219 | broadsheet_write_reg(par, reg, cpu_to_le32(data) & 0xFFFF); | ||
220 | broadsheet_write_reg(par, reg + 2, (cpu_to_le32(data) >> 16) & 0xFFFF); | ||
221 | } | ||
222 | |||
223 | |||
163 | static u16 broadsheet_read_reg(struct broadsheetfb_par *par, u16 reg) | 224 | static u16 broadsheet_read_reg(struct broadsheetfb_par *par, u16 reg) |
164 | { | 225 | { |
165 | broadsheet_send_command(par, reg); | 226 | broadsheet_send_command(par, reg); |
@@ -170,24 +231,28 @@ static u16 broadsheet_read_reg(struct broadsheetfb_par *par, u16 reg) | |||
170 | static void __devinit broadsheet_init_display(struct broadsheetfb_par *par) | 231 | static void __devinit broadsheet_init_display(struct broadsheetfb_par *par) |
171 | { | 232 | { |
172 | u16 args[5]; | 233 | u16 args[5]; |
173 | 234 | int xres = par->info->var.xres; | |
174 | args[0] = DPY_W; | 235 | int yres = par->info->var.yres; |
175 | args[1] = DPY_H; | 236 | |
176 | args[2] = (100 | (1 << 8) | (1 << 9)); /* sdcfg */ | 237 | args[0] = panel_table[par->panel_index].w; |
177 | args[3] = 2; /* gdrv cfg */ | 238 | args[1] = panel_table[par->panel_index].h; |
178 | args[4] = (4 | (1 << 7)); /* lut index format */ | 239 | args[2] = panel_table[par->panel_index].sdcfg; |
240 | args[3] = panel_table[par->panel_index].gdcfg; | ||
241 | args[4] = panel_table[par->panel_index].lutfmt; | ||
179 | broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args); | 242 | broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args); |
180 | 243 | ||
181 | /* did the controller really set it? */ | 244 | /* did the controller really set it? */ |
182 | broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args); | 245 | broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args); |
183 | 246 | ||
184 | args[0] = 4; /* fsync len */ | 247 | args[0] = panel_table[par->panel_index].fsynclen; |
185 | args[1] = (10 << 8) | 4; /* fend/fbegin len */ | 248 | args[1] = panel_table[par->panel_index].fendfbegin; |
186 | args[2] = 10; /* line sync len */ | 249 | args[2] = panel_table[par->panel_index].lsynclen; |
187 | args[3] = (100 << 8) | 4; /* line end/begin len */ | 250 | args[3] = panel_table[par->panel_index].lendlbegin; |
188 | args[4] = 6; /* pixel clock cfg */ | 251 | args[4] = panel_table[par->panel_index].pixclk; |
189 | broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_TMG, 5, args); | 252 | broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_TMG, 5, args); |
190 | 253 | ||
254 | broadsheet_write_reg32(par, 0x310, xres*yres*2); | ||
255 | |||
191 | /* setup waveform */ | 256 | /* setup waveform */ |
192 | args[0] = 0x886; | 257 | args[0] = 0x886; |
193 | args[1] = 0; | 258 | args[1] = 0; |
@@ -207,8 +272,9 @@ static void __devinit broadsheet_init_display(struct broadsheetfb_par *par) | |||
207 | args[0] = 0x154; | 272 | args[0] = 0x154; |
208 | broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args); | 273 | broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args); |
209 | 274 | ||
210 | broadsheet_burst_write(par, DPY_W*DPY_H/2, | 275 | broadsheet_burst_write(par, (panel_table[par->panel_index].w * |
211 | (u16 *) par->info->screen_base); | 276 | panel_table[par->panel_index].h)/2, |
277 | (u16 *) par->info->screen_base); | ||
212 | 278 | ||
213 | broadsheet_send_command(par, BS_CMD_LD_IMG_END); | 279 | broadsheet_send_command(par, BS_CMD_LD_IMG_END); |
214 | 280 | ||
@@ -277,8 +343,9 @@ static void broadsheetfb_dpy_update(struct broadsheetfb_par *par) | |||
277 | 343 | ||
278 | args[0] = 0x154; | 344 | args[0] = 0x154; |
279 | broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args); | 345 | broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args); |
280 | broadsheet_burst_write(par, DPY_W*DPY_H/2, | 346 | broadsheet_burst_write(par, (panel_table[par->panel_index].w * |
281 | (u16 *) par->info->screen_base); | 347 | panel_table[par->panel_index].h)/2, |
348 | (u16 *) par->info->screen_base); | ||
282 | 349 | ||
283 | broadsheet_send_command(par, BS_CMD_LD_IMG_END); | 350 | broadsheet_send_command(par, BS_CMD_LD_IMG_END); |
284 | 351 | ||
@@ -436,6 +503,8 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev) | |||
436 | unsigned char *videomemory; | 503 | unsigned char *videomemory; |
437 | struct broadsheetfb_par *par; | 504 | struct broadsheetfb_par *par; |
438 | int i; | 505 | int i; |
506 | int dpyw, dpyh; | ||
507 | int panel_index; | ||
439 | 508 | ||
440 | /* pick up board specific routines */ | 509 | /* pick up board specific routines */ |
441 | board = dev->dev.platform_data; | 510 | board = dev->dev.platform_data; |
@@ -450,7 +519,24 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev) | |||
450 | if (!info) | 519 | if (!info) |
451 | goto err; | 520 | goto err; |
452 | 521 | ||
453 | videomemorysize = (DPY_W*DPY_H); | 522 | switch (board->get_panel_type()) { |
523 | case 37: | ||
524 | panel_index = 1; | ||
525 | break; | ||
526 | case 97: | ||
527 | panel_index = 2; | ||
528 | break; | ||
529 | case 6: | ||
530 | default: | ||
531 | panel_index = 0; | ||
532 | break; | ||
533 | } | ||
534 | |||
535 | dpyw = panel_table[panel_index].w; | ||
536 | dpyh = panel_table[panel_index].h; | ||
537 | |||
538 | videomemorysize = roundup((dpyw*dpyh), PAGE_SIZE); | ||
539 | |||
454 | videomemory = vmalloc(videomemorysize); | 540 | videomemory = vmalloc(videomemorysize); |
455 | if (!videomemory) | 541 | if (!videomemory) |
456 | goto err_fb_rel; | 542 | goto err_fb_rel; |
@@ -460,10 +546,17 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev) | |||
460 | info->screen_base = (char *)videomemory; | 546 | info->screen_base = (char *)videomemory; |
461 | info->fbops = &broadsheetfb_ops; | 547 | info->fbops = &broadsheetfb_ops; |
462 | 548 | ||
549 | broadsheetfb_var.xres = dpyw; | ||
550 | broadsheetfb_var.yres = dpyh; | ||
551 | broadsheetfb_var.xres_virtual = dpyw; | ||
552 | broadsheetfb_var.yres_virtual = dpyh; | ||
463 | info->var = broadsheetfb_var; | 553 | info->var = broadsheetfb_var; |
554 | |||
555 | broadsheetfb_fix.line_length = dpyw; | ||
464 | info->fix = broadsheetfb_fix; | 556 | info->fix = broadsheetfb_fix; |
465 | info->fix.smem_len = videomemorysize; | 557 | info->fix.smem_len = videomemorysize; |
466 | par = info->par; | 558 | par = info->par; |
559 | par->panel_index = panel_index; | ||
467 | par->info = info; | 560 | par->info = info; |
468 | par->board = board; | 561 | par->board = board; |
469 | par->write_reg = broadsheet_write_reg; | 562 | par->write_reg = broadsheet_write_reg; |
diff --git a/include/video/broadsheetfb.h b/include/video/broadsheetfb.h index a758534c0272..a2c2829ceb38 100644 --- a/include/video/broadsheetfb.h +++ b/include/video/broadsheetfb.h | |||
@@ -41,6 +41,7 @@ struct broadsheetfb_par { | |||
41 | void (*write_reg)(struct broadsheetfb_par *, u16 reg, u16 val); | 41 | void (*write_reg)(struct broadsheetfb_par *, u16 reg, u16 val); |
42 | u16 (*read_reg)(struct broadsheetfb_par *, u16 reg); | 42 | u16 (*read_reg)(struct broadsheetfb_par *, u16 reg); |
43 | wait_queue_head_t waitq; | 43 | wait_queue_head_t waitq; |
44 | int panel_index; | ||
44 | }; | 45 | }; |
45 | 46 | ||
46 | /* board specific routines */ | 47 | /* board specific routines */ |