diff options
author | Tony Prisk <linux@prisktech.co.nz> | 2012-08-03 04:58:22 -0400 |
---|---|---|
committer | Tony Prisk <linux@prisktech.co.nz> | 2012-09-21 03:23:56 -0400 |
commit | e7b995371fe1e29838321fcdc3cfe35bb0d6bfc4 (patch) | |
tree | def3385d58244aa0c4da4098d0d99b92353a3416 /drivers/video/vt8500lcdfb.c | |
parent | 4001130df1a74948cfa8be02b420953a84ab83e8 (diff) |
video: vt8500: Add devicetree support for vt8500-fb and wm8505-fb
Update vt8500-fb, wm8505-fb and wmt-ge-rops to support device
tree bindings.
Small change in wm8505-fb.c to support WM8650 framebuffer color
format.
Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
Diffstat (limited to 'drivers/video/vt8500lcdfb.c')
-rw-r--r-- | drivers/video/vt8500lcdfb.c | 79 |
1 files changed, 68 insertions, 11 deletions
diff --git a/drivers/video/vt8500lcdfb.c b/drivers/video/vt8500lcdfb.c index 2a5fe6ede845..d24595cd0c9b 100644 --- a/drivers/video/vt8500lcdfb.c +++ b/drivers/video/vt8500lcdfb.c | |||
@@ -35,6 +35,13 @@ | |||
35 | #include "vt8500lcdfb.h" | 35 | #include "vt8500lcdfb.h" |
36 | #include "wmt_ge_rops.h" | 36 | #include "wmt_ge_rops.h" |
37 | 37 | ||
38 | #ifdef CONFIG_OF | ||
39 | #include <linux/of.h> | ||
40 | #include <linux/of_fdt.h> | ||
41 | #include <linux/memblock.h> | ||
42 | #endif | ||
43 | |||
44 | |||
38 | #define to_vt8500lcd_info(__info) container_of(__info, \ | 45 | #define to_vt8500lcd_info(__info) container_of(__info, \ |
39 | struct vt8500lcd_info, fb) | 46 | struct vt8500lcd_info, fb) |
40 | 47 | ||
@@ -270,15 +277,21 @@ static int __devinit vt8500lcd_probe(struct platform_device *pdev) | |||
270 | { | 277 | { |
271 | struct vt8500lcd_info *fbi; | 278 | struct vt8500lcd_info *fbi; |
272 | struct resource *res; | 279 | struct resource *res; |
273 | struct vt8500fb_platform_data *pdata = pdev->dev.platform_data; | ||
274 | void *addr; | 280 | void *addr; |
275 | int irq, ret; | 281 | int irq, ret; |
276 | 282 | ||
283 | struct fb_videomode of_mode; | ||
284 | struct device_node *np; | ||
285 | u32 bpp; | ||
286 | dma_addr_t fb_mem_phys; | ||
287 | unsigned long fb_mem_len; | ||
288 | void *fb_mem_virt; | ||
289 | |||
277 | ret = -ENOMEM; | 290 | ret = -ENOMEM; |
278 | fbi = NULL; | 291 | fbi = NULL; |
279 | 292 | ||
280 | fbi = kzalloc(sizeof(struct vt8500lcd_info) + sizeof(u32) * 16, | 293 | fbi = devm_kzalloc(&pdev->dev, sizeof(struct vt8500lcd_info) |
281 | GFP_KERNEL); | 294 | + sizeof(u32) * 16, GFP_KERNEL); |
282 | if (!fbi) { | 295 | if (!fbi) { |
283 | dev_err(&pdev->dev, "Failed to initialize framebuffer device\n"); | 296 | dev_err(&pdev->dev, "Failed to initialize framebuffer device\n"); |
284 | ret = -ENOMEM; | 297 | ret = -ENOMEM; |
@@ -333,9 +346,45 @@ static int __devinit vt8500lcd_probe(struct platform_device *pdev) | |||
333 | goto failed_free_res; | 346 | goto failed_free_res; |
334 | } | 347 | } |
335 | 348 | ||
336 | fbi->fb.fix.smem_start = pdata->video_mem_phys; | 349 | np = of_parse_phandle(pdev->dev.of_node, "default-mode", 0); |
337 | fbi->fb.fix.smem_len = pdata->video_mem_len; | 350 | if (!np) { |
338 | fbi->fb.screen_base = pdata->video_mem_virt; | 351 | pr_err("%s: No display description in Device Tree\n", __func__); |
352 | ret = -EINVAL; | ||
353 | goto failed_free_res; | ||
354 | } | ||
355 | |||
356 | /* | ||
357 | * This code is copied from Sascha Hauer's of_videomode helper | ||
358 | * and can be replaced with a call to the helper once mainlined | ||
359 | */ | ||
360 | ret = 0; | ||
361 | ret |= of_property_read_u32(np, "hactive", &of_mode.xres); | ||
362 | ret |= of_property_read_u32(np, "vactive", &of_mode.yres); | ||
363 | ret |= of_property_read_u32(np, "hback-porch", &of_mode.left_margin); | ||
364 | ret |= of_property_read_u32(np, "hfront-porch", &of_mode.right_margin); | ||
365 | ret |= of_property_read_u32(np, "hsync-len", &of_mode.hsync_len); | ||
366 | ret |= of_property_read_u32(np, "vback-porch", &of_mode.upper_margin); | ||
367 | ret |= of_property_read_u32(np, "vfront-porch", &of_mode.lower_margin); | ||
368 | ret |= of_property_read_u32(np, "vsync-len", &of_mode.vsync_len); | ||
369 | ret |= of_property_read_u32(np, "bpp", &bpp); | ||
370 | if (ret) { | ||
371 | pr_err("%s: Unable to read display properties\n", __func__); | ||
372 | goto failed_free_res; | ||
373 | } | ||
374 | of_mode.vmode = FB_VMODE_NONINTERLACED; | ||
375 | |||
376 | /* try allocating the framebuffer */ | ||
377 | fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8); | ||
378 | fb_mem_virt = dma_alloc_coherent(&pdev->dev, fb_mem_len, &fb_mem_phys, | ||
379 | GFP_KERNEL); | ||
380 | if (!fb_mem_virt) { | ||
381 | pr_err("%s: Failed to allocate framebuffer\n", __func__); | ||
382 | return -ENOMEM; | ||
383 | }; | ||
384 | |||
385 | fbi->fb.fix.smem_start = fb_mem_phys; | ||
386 | fbi->fb.fix.smem_len = fb_mem_len; | ||
387 | fbi->fb.screen_base = fb_mem_virt; | ||
339 | 388 | ||
340 | fbi->palette_size = PAGE_ALIGN(512); | 389 | fbi->palette_size = PAGE_ALIGN(512); |
341 | fbi->palette_cpu = dma_alloc_coherent(&pdev->dev, | 390 | fbi->palette_cpu = dma_alloc_coherent(&pdev->dev, |
@@ -370,10 +419,11 @@ static int __devinit vt8500lcd_probe(struct platform_device *pdev) | |||
370 | goto failed_free_irq; | 419 | goto failed_free_irq; |
371 | } | 420 | } |
372 | 421 | ||
373 | fb_videomode_to_var(&fbi->fb.var, &pdata->mode); | 422 | fb_videomode_to_var(&fbi->fb.var, &of_mode); |
374 | fbi->fb.var.bits_per_pixel = pdata->bpp; | 423 | |
375 | fbi->fb.var.xres_virtual = pdata->xres_virtual; | 424 | fbi->fb.var.xres_virtual = of_mode.xres; |
376 | fbi->fb.var.yres_virtual = pdata->yres_virtual; | 425 | fbi->fb.var.yres_virtual = of_mode.yres * 2; |
426 | fbi->fb.var.bits_per_pixel = bpp; | ||
377 | 427 | ||
378 | ret = vt8500lcd_set_par(&fbi->fb); | 428 | ret = vt8500lcd_set_par(&fbi->fb); |
379 | if (ret) { | 429 | if (ret) { |
@@ -448,12 +498,18 @@ static int __devexit vt8500lcd_remove(struct platform_device *pdev) | |||
448 | return 0; | 498 | return 0; |
449 | } | 499 | } |
450 | 500 | ||
501 | static const struct of_device_id via_dt_ids[] = { | ||
502 | { .compatible = "via,vt8500-fb", }, | ||
503 | {} | ||
504 | }; | ||
505 | |||
451 | static struct platform_driver vt8500lcd_driver = { | 506 | static struct platform_driver vt8500lcd_driver = { |
452 | .probe = vt8500lcd_probe, | 507 | .probe = vt8500lcd_probe, |
453 | .remove = __devexit_p(vt8500lcd_remove), | 508 | .remove = __devexit_p(vt8500lcd_remove), |
454 | .driver = { | 509 | .driver = { |
455 | .owner = THIS_MODULE, | 510 | .owner = THIS_MODULE, |
456 | .name = "vt8500-lcd", | 511 | .name = "vt8500-lcd", |
512 | .of_match_table = of_match_ptr(via_dt_ids), | ||
457 | }, | 513 | }, |
458 | }; | 514 | }; |
459 | 515 | ||
@@ -461,4 +517,5 @@ module_platform_driver(vt8500lcd_driver); | |||
461 | 517 | ||
462 | MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>"); | 518 | MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>"); |
463 | MODULE_DESCRIPTION("LCD controller driver for VIA VT8500"); | 519 | MODULE_DESCRIPTION("LCD controller driver for VIA VT8500"); |
464 | MODULE_LICENSE("GPL"); | 520 | MODULE_LICENSE("GPL v2"); |
521 | MODULE_DEVICE_TABLE(of, via_dt_ids); | ||