diff options
author | Eric Bénard <eric@eukrea.com> | 2010-07-16 09:09:07 -0400 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2010-07-26 08:29:21 -0400 |
commit | 7a2bb23c149e9f093b2b83c16c25991e32ef4ec3 (patch) | |
tree | 060e3488d629a3c48a2b4d1980149a960159b477 /drivers/video/imxfb.c | |
parent | 7e688f0d77f90c531747afa552d72ea70c2f0803 (diff) |
imxfb: add pwmr controlled backlight support
Signed-off-by: Eric Bénard <eric@eukrea.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/video/imxfb.c')
-rw-r--r-- | drivers/video/imxfb.c | 72 |
1 files changed, 71 insertions, 1 deletions
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index b4b6deceed15..43f0639b1c10 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c | |||
@@ -175,6 +175,7 @@ struct imxfb_info { | |||
175 | 175 | ||
176 | struct imx_fb_videomode *mode; | 176 | struct imx_fb_videomode *mode; |
177 | int num_modes; | 177 | int num_modes; |
178 | struct backlight_device *bl; | ||
178 | 179 | ||
179 | void (*lcd_power)(int); | 180 | void (*lcd_power)(int); |
180 | void (*backlight_power)(int); | 181 | void (*backlight_power)(int); |
@@ -449,6 +450,73 @@ static int imxfb_set_par(struct fb_info *info) | |||
449 | return 0; | 450 | return 0; |
450 | } | 451 | } |
451 | 452 | ||
453 | |||
454 | |||
455 | static int imxfb_bl_get_brightness(struct backlight_device *bl) | ||
456 | { | ||
457 | struct imxfb_info *fbi = bl_get_data(bl); | ||
458 | |||
459 | return readl(fbi->regs + LCDC_PWMR) & 0xFF; | ||
460 | } | ||
461 | |||
462 | static int imxfb_bl_update_status(struct backlight_device *bl) | ||
463 | { | ||
464 | struct imxfb_info *fbi = bl_get_data(bl); | ||
465 | int brightness = bl->props.brightness; | ||
466 | |||
467 | if (bl->props.power != FB_BLANK_UNBLANK) | ||
468 | brightness = 0; | ||
469 | if (bl->props.fb_blank != FB_BLANK_UNBLANK) | ||
470 | brightness = 0; | ||
471 | |||
472 | fbi->pwmr = (fbi->pwmr & ~0xFF) | brightness; | ||
473 | |||
474 | if (bl->props.fb_blank != FB_BLANK_UNBLANK) | ||
475 | clk_enable(fbi->clk); | ||
476 | writel(fbi->pwmr, fbi->regs + LCDC_PWMR); | ||
477 | if (bl->props.fb_blank != FB_BLANK_UNBLANK) | ||
478 | clk_disable(fbi->clk); | ||
479 | |||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | static const struct backlight_ops imxfb_lcdc_bl_ops = { | ||
484 | .update_status = imxfb_bl_update_status, | ||
485 | .get_brightness = imxfb_bl_get_brightness, | ||
486 | }; | ||
487 | |||
488 | static void imxfb_init_backlight(struct imxfb_info *fbi) | ||
489 | { | ||
490 | struct backlight_properties props; | ||
491 | struct backlight_device *bl; | ||
492 | |||
493 | if (fbi->bl) | ||
494 | return; | ||
495 | |||
496 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
497 | props.max_brightness = 0xff; | ||
498 | writel(fbi->pwmr, fbi->regs + LCDC_PWMR); | ||
499 | |||
500 | bl = backlight_device_register("imxfb-bl", &fbi->pdev->dev, fbi, | ||
501 | &imxfb_lcdc_bl_ops, &props); | ||
502 | if (IS_ERR(bl)) { | ||
503 | dev_err(&fbi->pdev->dev, "error %ld on backlight register\n", | ||
504 | PTR_ERR(bl)); | ||
505 | return; | ||
506 | } | ||
507 | |||
508 | fbi->bl = bl; | ||
509 | bl->props.power = FB_BLANK_UNBLANK; | ||
510 | bl->props.fb_blank = FB_BLANK_UNBLANK; | ||
511 | bl->props.brightness = imxfb_bl_get_brightness(bl); | ||
512 | } | ||
513 | |||
514 | static void imxfb_exit_backlight(struct imxfb_info *fbi) | ||
515 | { | ||
516 | if (fbi->bl) | ||
517 | backlight_device_unregister(fbi->bl); | ||
518 | } | ||
519 | |||
452 | static void imxfb_enable_controller(struct imxfb_info *fbi) | 520 | static void imxfb_enable_controller(struct imxfb_info *fbi) |
453 | { | 521 | { |
454 | pr_debug("Enabling LCD controller\n"); | 522 | pr_debug("Enabling LCD controller\n"); |
@@ -579,7 +647,6 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf | |||
579 | fbi->regs + LCDC_SIZE); | 647 | fbi->regs + LCDC_SIZE); |
580 | 648 | ||
581 | writel(fbi->pcr, fbi->regs + LCDC_PCR); | 649 | writel(fbi->pcr, fbi->regs + LCDC_PCR); |
582 | writel(fbi->pwmr, fbi->regs + LCDC_PWMR); | ||
583 | writel(fbi->lscr1, fbi->regs + LCDC_LSCR1); | 650 | writel(fbi->lscr1, fbi->regs + LCDC_LSCR1); |
584 | writel(fbi->dmacr, fbi->regs + LCDC_DMACR); | 651 | writel(fbi->dmacr, fbi->regs + LCDC_DMACR); |
585 | 652 | ||
@@ -779,6 +846,8 @@ static int __init imxfb_probe(struct platform_device *pdev) | |||
779 | } | 846 | } |
780 | 847 | ||
781 | imxfb_enable_controller(fbi); | 848 | imxfb_enable_controller(fbi); |
849 | fbi->pdev = pdev; | ||
850 | imxfb_init_backlight(fbi); | ||
782 | 851 | ||
783 | return 0; | 852 | return 0; |
784 | 853 | ||
@@ -816,6 +885,7 @@ static int __devexit imxfb_remove(struct platform_device *pdev) | |||
816 | 885 | ||
817 | imxfb_disable_controller(fbi); | 886 | imxfb_disable_controller(fbi); |
818 | 887 | ||
888 | imxfb_exit_backlight(fbi); | ||
819 | unregister_framebuffer(info); | 889 | unregister_framebuffer(info); |
820 | 890 | ||
821 | pdata = pdev->dev.platform_data; | 891 | pdata = pdev->dev.platform_data; |