summaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorSam Ravnborg <sam@ravnborg.org>2017-07-20 22:05:24 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2017-09-06 14:20:31 +0200
commitde7963ef3cf85d37aad6cc00f97d7cb48f7d5052 (patch)
treeba9d704e5f369258aab9346965bd4b64dae818f7 /drivers/video
parentf35f76ac5157b8f07a3f2330333c0e1ca54a48f5 (diff)
downloadbarebox-de7963ef3cf85d37aad6cc00f97d7cb48f7d5052.tar.gz
barebox-de7963ef3cf85d37aad6cc00f97d7cb48f7d5052.tar.xz
atmel_lcdfb: define power_control gpio in platform_data
Simplify board specific code by specifying the power_control gpio direct in platform data. Move registration of the GPIO to the driver so we no longer need to duplicate this for each board. As an intended side-effect there is no longer any references to platform_data outside atmel_lcdc_register() so remove it from struct atmel_lcdfb_info The implementation assumes that GPIO=0 is the same as no power control. This prevents us from using any GPIO=0 for power control, but this is not considered a problem for current users. Future DT users will not have this limitation. This commit include a fix so we will actually power down if requested. Previously this was hardcoded to ON. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/atmel_lcdfb.h4
-rw-r--r--drivers/video/atmel_lcdfb_core.c59
2 files changed, 57 insertions, 6 deletions
diff --git a/drivers/video/atmel_lcdfb.h b/drivers/video/atmel_lcdfb.h
index 90992df029..a011d42019 100644
--- a/drivers/video/atmel_lcdfb.h
+++ b/drivers/video/atmel_lcdfb.h
@@ -25,10 +25,12 @@ struct atmel_lcdfb_info {
unsigned int dmacon;
unsigned int lcd_wiring_mode;
bool have_intensity_bit;
+
+ int gpio_power_control;
+ bool gpio_power_control_active_low;
struct clk *bus_clk;
struct clk *lcdc_clk;
- struct atmel_lcdfb_platform_data *pdata;
struct atmel_lcdfb_devdata *dev_data;
void *dma_desc;
};
diff --git a/drivers/video/atmel_lcdfb_core.c b/drivers/video/atmel_lcdfb_core.c
index cdeb927ad0..cc065397d8 100644
--- a/drivers/video/atmel_lcdfb_core.c
+++ b/drivers/video/atmel_lcdfb_core.c
@@ -19,6 +19,7 @@
*/
#include <common.h>
+#include <gpio.h>
#include <dma.h>
#include <io.h>
#include <linux/err.h>
@@ -39,13 +40,17 @@ static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo)
clk_disable(sinfo->lcdc_clk);
}
-static void atmel_lcdc_power_controller(struct fb_info *fb_info, int i)
+static void atmel_lcdc_power_controller(struct fb_info *fb_info, int on)
{
struct atmel_lcdfb_info *sinfo = fb_info->priv;
- struct atmel_lcdfb_platform_data *pdata = sinfo->pdata;
- if (pdata->atmel_lcdfb_power_control)
- pdata->atmel_lcdfb_power_control(1);
+ if (sinfo->gpio_power_control < 0)
+ return;
+
+ if (sinfo->gpio_power_control_active_low)
+ gpio_set_value(sinfo->gpio_power_control, !on);
+ else
+ gpio_set_value(sinfo->gpio_power_control, on);
}
/**
@@ -242,12 +247,44 @@ static struct fb_ops atmel_lcdc_ops = {
.fb_disable = atmel_lcdc_disable_controller,
};
+static int power_control_init(struct device_d *dev,
+ struct atmel_lcdfb_info *sinfo,
+ int gpio,
+ bool active_low)
+{
+ int ret;
+ const char *name = "lcdc_power";
+
+ sinfo->gpio_power_control = gpio;
+ sinfo->gpio_power_control_active_low = active_low;
+
+ /* If no GPIO specified then stop */
+ if (!gpio_is_valid(gpio))
+ return 0;
+
+ ret = gpio_request(gpio, name);
+ if (ret) {
+ dev_err(dev, "%s: can not request gpio %d (%d)\n",
+ name, gpio, ret);
+ return ret;
+ }
+ ret = gpio_direction_output(gpio, 1);
+ if (ret) {
+ dev_err(dev, "%s: can not configure gpio %d as output (%d)\n",
+ name, gpio, ret);
+ return ret;
+ }
+
+ return ret;
+}
+
int atmel_lcdc_register(struct device_d *dev, struct atmel_lcdfb_devdata *data)
{
struct resource *iores;
struct atmel_lcdfb_info *sinfo;
struct atmel_lcdfb_platform_data *pdata = dev->platform_data;
int ret = 0;
+ int gpio;
struct fb_info *info;
if (!pdata) {
@@ -256,7 +293,19 @@ int atmel_lcdc_register(struct device_d *dev, struct atmel_lcdfb_devdata *data)
}
sinfo = xzalloc(sizeof(*sinfo));
- sinfo->pdata = pdata;
+
+ /* If gpio == 0 (default in pdata) then we assume no power control */
+ gpio = pdata->gpio_power_control;
+ if (gpio == 0)
+ gpio = -1;
+
+ ret = power_control_init(dev,
+ sinfo,
+ gpio,
+ pdata->gpio_power_control_active_low);
+ if (ret)
+ goto err;
+
sinfo->guard_time = pdata->guard_time;
sinfo->lcdcon2 = pdata->default_lcdcon2;
sinfo->dmacon = pdata->default_dmacon;