aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Shiyan <shc_work@mail.ru>2014-02-15 00:56:25 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2014-02-28 05:35:32 -0500
commitf590f99ab9c13731aede86b522c0b8bf140a292e (patch)
tree26252f39a4b6af791a88b1b25a71581967584e6b
parentde5013627fba6a9135a9aee1418ee927bbfdd8c8 (diff)
video: imxfb: Resolve mismatch between backlight/contrast
Currently, driver uses backlight class to control contrast value. This is not correct. This patch resolves this issue by removing backlight class from the driver and replace handling of LCDC PWM Contrast Control Register by contrast control through LCD class. Signed-off-by: Alexander Shiyan <shc_work@mail.ru> Acked-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r--drivers/video/imxfb.c124
1 files changed, 30 insertions, 94 deletions
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 3137a69fdfd0..398a8ca0e3dc 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -48,12 +48,6 @@
48 */ 48 */
49#define DEBUG_VAR 1 49#define DEBUG_VAR 1
50 50
51#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || \
52 (defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) && \
53 defined(CONFIG_FB_IMX_MODULE))
54#define PWMR_BACKLIGHT_AVAILABLE
55#endif
56
57#define DRIVER_NAME "imx-fb" 51#define DRIVER_NAME "imx-fb"
58 52
59#define LCDC_SSA 0x00 53#define LCDC_SSA 0x00
@@ -172,9 +166,6 @@ struct imxfb_info {
172 166
173 struct imx_fb_videomode *mode; 167 struct imx_fb_videomode *mode;
174 int num_modes; 168 int num_modes;
175#ifdef PWMR_BACKLIGHT_AVAILABLE
176 struct backlight_device *bl;
177#endif
178 169
179 struct regulator *lcd_pwr; 170 struct regulator *lcd_pwr;
180}; 171};
@@ -482,83 +473,6 @@ static int imxfb_set_par(struct fb_info *info)
482 return 0; 473 return 0;
483} 474}
484 475
485#ifdef PWMR_BACKLIGHT_AVAILABLE
486static int imxfb_bl_get_brightness(struct backlight_device *bl)
487{
488 struct imxfb_info *fbi = bl_get_data(bl);
489
490 return readl(fbi->regs + LCDC_PWMR) & 0xFF;
491}
492
493static int imxfb_bl_update_status(struct backlight_device *bl)
494{
495 struct imxfb_info *fbi = bl_get_data(bl);
496 int brightness = bl->props.brightness;
497
498 if (!fbi->pwmr)
499 return 0;
500
501 if (bl->props.power != FB_BLANK_UNBLANK)
502 brightness = 0;
503 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
504 brightness = 0;
505
506 fbi->pwmr = (fbi->pwmr & ~0xFF) | brightness;
507
508 if (bl->props.fb_blank != FB_BLANK_UNBLANK) {
509 clk_prepare_enable(fbi->clk_ipg);
510 clk_prepare_enable(fbi->clk_ahb);
511 clk_prepare_enable(fbi->clk_per);
512 }
513 writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
514 if (bl->props.fb_blank != FB_BLANK_UNBLANK) {
515 clk_disable_unprepare(fbi->clk_per);
516 clk_disable_unprepare(fbi->clk_ahb);
517 clk_disable_unprepare(fbi->clk_ipg);
518 }
519
520 return 0;
521}
522
523static const struct backlight_ops imxfb_lcdc_bl_ops = {
524 .update_status = imxfb_bl_update_status,
525 .get_brightness = imxfb_bl_get_brightness,
526};
527
528static void imxfb_init_backlight(struct imxfb_info *fbi)
529{
530 struct backlight_properties props;
531 struct backlight_device *bl;
532
533 if (fbi->bl)
534 return;
535
536 memset(&props, 0, sizeof(struct backlight_properties));
537 props.max_brightness = 0xff;
538 props.type = BACKLIGHT_RAW;
539 writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
540
541 bl = backlight_device_register("imxfb-bl", &fbi->pdev->dev, fbi,
542 &imxfb_lcdc_bl_ops, &props);
543 if (IS_ERR(bl)) {
544 dev_err(&fbi->pdev->dev, "error %ld on backlight register\n",
545 PTR_ERR(bl));
546 return;
547 }
548
549 fbi->bl = bl;
550 bl->props.power = FB_BLANK_UNBLANK;
551 bl->props.fb_blank = FB_BLANK_UNBLANK;
552 bl->props.brightness = imxfb_bl_get_brightness(bl);
553}
554
555static void imxfb_exit_backlight(struct imxfb_info *fbi)
556{
557 if (fbi->bl)
558 backlight_device_unregister(fbi->bl);
559}
560#endif
561
562static void imxfb_enable_controller(struct imxfb_info *fbi) 476static void imxfb_enable_controller(struct imxfb_info *fbi)
563{ 477{
564 478
@@ -697,10 +611,8 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
697 fbi->regs + LCDC_SIZE); 611 fbi->regs + LCDC_SIZE);
698 612
699 writel(fbi->pcr, fbi->regs + LCDC_PCR); 613 writel(fbi->pcr, fbi->regs + LCDC_PCR);
700#ifndef PWMR_BACKLIGHT_AVAILABLE
701 if (fbi->pwmr) 614 if (fbi->pwmr)
702 writel(fbi->pwmr, fbi->regs + LCDC_PWMR); 615 writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
703#endif
704 writel(fbi->lscr1, fbi->regs + LCDC_LSCR1); 616 writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
705 617
706 /* dmacr = 0 is no valid value, as we need DMA control marks. */ 618 /* dmacr = 0 is no valid value, as we need DMA control marks. */
@@ -844,6 +756,32 @@ static int imxfb_lcd_check_fb(struct lcd_device *lcddev, struct fb_info *fi)
844 return 0; 756 return 0;
845} 757}
846 758
759static int imxfb_lcd_get_contrast(struct lcd_device *lcddev)
760{
761 struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
762
763 return fbi->pwmr & 0xff;
764}
765
766static int imxfb_lcd_set_contrast(struct lcd_device *lcddev, int contrast)
767{
768 struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
769
770 if (fbi->pwmr && fbi->enabled) {
771 if (contrast > 255)
772 contrast = 255;
773 else if (contrast < 0)
774 contrast = 0;
775
776 fbi->pwmr &= ~0xff;
777 fbi->pwmr |= contrast;
778
779 writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
780 }
781
782 return 0;
783}
784
847static int imxfb_lcd_get_power(struct lcd_device *lcddev) 785static int imxfb_lcd_get_power(struct lcd_device *lcddev)
848{ 786{
849 struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev); 787 struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
@@ -870,6 +808,8 @@ static int imxfb_lcd_set_power(struct lcd_device *lcddev, int power)
870 808
871static struct lcd_ops imxfb_lcd_ops = { 809static struct lcd_ops imxfb_lcd_ops = {
872 .check_fb = imxfb_lcd_check_fb, 810 .check_fb = imxfb_lcd_check_fb,
811 .get_contrast = imxfb_lcd_get_contrast,
812 .set_contrast = imxfb_lcd_set_contrast,
873 .get_power = imxfb_lcd_get_power, 813 .get_power = imxfb_lcd_get_power,
874 .set_power = imxfb_lcd_set_power, 814 .set_power = imxfb_lcd_set_power,
875}; 815};
@@ -1062,11 +1002,10 @@ static int imxfb_probe(struct platform_device *pdev)
1062 goto failed_lcd; 1002 goto failed_lcd;
1063 } 1003 }
1064 1004
1005 lcd->props.max_contrast = 0xff;
1006
1065 imxfb_enable_controller(fbi); 1007 imxfb_enable_controller(fbi);
1066 fbi->pdev = pdev; 1008 fbi->pdev = pdev;
1067#ifdef PWMR_BACKLIGHT_AVAILABLE
1068 imxfb_init_backlight(fbi);
1069#endif
1070 1009
1071 return 0; 1010 return 0;
1072 1011
@@ -1105,9 +1044,6 @@ static int imxfb_remove(struct platform_device *pdev)
1105 1044
1106 imxfb_disable_controller(fbi); 1045 imxfb_disable_controller(fbi);
1107 1046
1108#ifdef PWMR_BACKLIGHT_AVAILABLE
1109 imxfb_exit_backlight(fbi);
1110#endif
1111 unregister_framebuffer(info); 1047 unregister_framebuffer(info);
1112 1048
1113 pdata = dev_get_platdata(&pdev->dev); 1049 pdata = dev_get_platdata(&pdev->dev);