diff options
author | Sam Ravnborg <sam@ravnborg.org> | 2017-07-20 22:05:24 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2017-09-06 14:20:31 +0200 |
commit | de7963ef3cf85d37aad6cc00f97d7cb48f7d5052 (patch) | |
tree | ba9d704e5f369258aab9346965bd4b64dae818f7 /drivers/video | |
parent | f35f76ac5157b8f07a3f2330333c0e1ca54a48f5 (diff) | |
download | barebox-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.h | 4 | ||||
-rw-r--r-- | drivers/video/atmel_lcdfb_core.c | 59 |
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; |