fbdev: da8xx: add support for a regulator
authorBartosz Golaszewski <bgolaszewski@baylibre.com>
Mon, 22 Jul 2019 13:44:18 +0000 (15:44 +0200)
committerSekhar Nori <nsekhar@ti.com>
Mon, 26 Aug 2019 12:23:57 +0000 (17:53 +0530)
We want to remove the hacky platform data callback for power control.
Add a regulator to the driver data and enable/disable it next to
the current panel_power_ctrl() calls. We will use it in subsequent
patch on da850-evm.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Acked-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
drivers/video/fbdev/da8xx-fb.c

index b1cf248f3291856a465f66feefd519fc03c6268f..02dfe9e32eed381db824d739859838568dd12f15 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/clk.h>
 #include <linux/cpufreq.h>
 #include <linux/console.h>
+#include <linux/regulator/consumer.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -165,6 +166,7 @@ struct da8xx_fb_par {
 #endif
        unsigned int            lcdc_clk_rate;
        void (*panel_power_ctrl)(int);
+       struct regulator        *lcd_supply;
        u32 pseudo_palette[16];
        struct fb_videomode     mode;
        struct lcd_ctrl_config  cfg;
@@ -1066,6 +1068,7 @@ static void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par)
 static int fb_remove(struct platform_device *dev)
 {
        struct fb_info *info = dev_get_drvdata(&dev->dev);
+       int ret;
 
        if (info) {
                struct da8xx_fb_par *par = info->par;
@@ -1073,8 +1076,13 @@ static int fb_remove(struct platform_device *dev)
 #ifdef CONFIG_CPU_FREQ
                lcd_da8xx_cpufreq_deregister(par);
 #endif
-               if (par->panel_power_ctrl)
+               if (par->panel_power_ctrl) {
                        par->panel_power_ctrl(0);
+               } else if (par->lcd_supply) {
+                       ret = regulator_disable(par->lcd_supply);
+                       if (ret)
+                               return ret;
+               }
 
                lcd_disable_raster(DA8XX_FRAME_WAIT);
                lcdc_write(0, LCD_RASTER_CTRL_REG);
@@ -1179,15 +1187,25 @@ static int cfb_blank(int blank, struct fb_info *info)
        case FB_BLANK_UNBLANK:
                lcd_enable_raster();
 
-               if (par->panel_power_ctrl)
+               if (par->panel_power_ctrl) {
                        par->panel_power_ctrl(1);
+               } else if (par->lcd_supply) {
+                       ret = regulator_enable(par->lcd_supply);
+                       if (ret)
+                               return ret;
+               }
                break;
        case FB_BLANK_NORMAL:
        case FB_BLANK_VSYNC_SUSPEND:
        case FB_BLANK_HSYNC_SUSPEND:
        case FB_BLANK_POWERDOWN:
-               if (par->panel_power_ctrl)
+               if (par->panel_power_ctrl) {
                        par->panel_power_ctrl(0);
+               } else if (par->lcd_supply) {
+                       ret = regulator_disable(par->lcd_supply);
+                       if (ret)
+                               return ret;
+               }
 
                lcd_disable_raster(DA8XX_FRAME_WAIT);
                break;
@@ -1400,6 +1418,20 @@ static int fb_probe(struct platform_device *device)
                par->panel_power_ctrl(1);
        }
 
+       par->lcd_supply = devm_regulator_get_optional(&device->dev, "lcd");
+       if (IS_ERR(par->lcd_supply)) {
+               if (PTR_ERR(par->lcd_supply) == -EPROBE_DEFER) {
+                       ret = -EPROBE_DEFER;
+                       goto err_pm_runtime_disable;
+               }
+
+               par->lcd_supply = NULL;
+       } else {
+               ret = regulator_enable(par->lcd_supply);
+               if (ret)
+                       goto err_pm_runtime_disable;
+       }
+
        fb_videomode_to_var(&da8xx_fb_var, lcdc_info);
        par->cfg = *lcd_cfg;
 
@@ -1603,10 +1635,16 @@ static int fb_suspend(struct device *dev)
 {
        struct fb_info *info = dev_get_drvdata(dev);
        struct da8xx_fb_par *par = info->par;
+       int ret;
 
        console_lock();
-       if (par->panel_power_ctrl)
+       if (par->panel_power_ctrl) {
                par->panel_power_ctrl(0);
+       } else if (par->lcd_supply) {
+               ret = regulator_disable(par->lcd_supply);
+               if (ret)
+                       return ret;
+       }
 
        fb_set_suspend(info, 1);
        lcd_disable_raster(DA8XX_FRAME_WAIT);
@@ -1620,6 +1658,7 @@ static int fb_resume(struct device *dev)
 {
        struct fb_info *info = dev_get_drvdata(dev);
        struct da8xx_fb_par *par = info->par;
+       int ret;
 
        console_lock();
        pm_runtime_get_sync(dev);
@@ -1627,8 +1666,13 @@ static int fb_resume(struct device *dev)
        if (par->blank == FB_BLANK_UNBLANK) {
                lcd_enable_raster();
 
-               if (par->panel_power_ctrl)
+               if (par->panel_power_ctrl) {
                        par->panel_power_ctrl(1);
+               } else if (par->lcd_supply) {
+                       ret = regulator_enable(par->lcd_supply);
+                       if (ret)
+                               return ret;
+               }
        }
 
        fb_set_suspend(info, 0);