diff options
author | Fabio Estevam <fabio.estevam@freescale.com> | 2013-04-07 14:44:59 -0400 |
---|---|---|
committer | Shawn Guo <shawn.guo@linaro.org> | 2013-04-08 03:44:55 -0400 |
commit | 4344429d3d926d219671f607125cff51223a140a (patch) | |
tree | 38d3c3c93f5af889d98f8866962f142ff99f90d8 /drivers/video/mxsfb.c | |
parent | ac77bc227e96bb6d42b86ee5e20e4fa6a743d632 (diff) |
video: mxsfb: Introduce regulator support
Instead of using a custom binding for retrieving the GPIO that activates the
LCD from devicetree, use a standard regulator.
This approach has the advantage to be more generic.
For example: in the case of a board that has a PMIC supplying the LCD voltage,
the current approach would not work, as it only searches for a GPIO pin.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Diffstat (limited to 'drivers/video/mxsfb.c')
-rw-r--r-- | drivers/video/mxsfb.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index eac7c1ace7a5..1b2c26d1658c 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include <linux/module.h> | 42 | #include <linux/module.h> |
43 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
44 | #include <linux/of_device.h> | 44 | #include <linux/of_device.h> |
45 | #include <linux/of_gpio.h> | ||
46 | #include <video/of_display_timing.h> | 45 | #include <video/of_display_timing.h> |
47 | #include <linux/platform_device.h> | 46 | #include <linux/platform_device.h> |
48 | #include <linux/clk.h> | 47 | #include <linux/clk.h> |
@@ -50,6 +49,7 @@ | |||
50 | #include <linux/io.h> | 49 | #include <linux/io.h> |
51 | #include <linux/pinctrl/consumer.h> | 50 | #include <linux/pinctrl/consumer.h> |
52 | #include <linux/fb.h> | 51 | #include <linux/fb.h> |
52 | #include <linux/regulator/consumer.h> | ||
53 | #include <video/videomode.h> | 53 | #include <video/videomode.h> |
54 | 54 | ||
55 | #define REG_SET 4 | 55 | #define REG_SET 4 |
@@ -179,6 +179,7 @@ struct mxsfb_info { | |||
179 | unsigned dotclk_delay; | 179 | unsigned dotclk_delay; |
180 | const struct mxsfb_devdata *devdata; | 180 | const struct mxsfb_devdata *devdata; |
181 | u32 sync; | 181 | u32 sync; |
182 | struct regulator *reg_lcd; | ||
182 | }; | 183 | }; |
183 | 184 | ||
184 | #define mxsfb_is_v3(host) (host->devdata->ipversion == 3) | 185 | #define mxsfb_is_v3(host) (host->devdata->ipversion == 3) |
@@ -338,9 +339,19 @@ static void mxsfb_enable_controller(struct fb_info *fb_info) | |||
338 | { | 339 | { |
339 | struct mxsfb_info *host = to_imxfb_host(fb_info); | 340 | struct mxsfb_info *host = to_imxfb_host(fb_info); |
340 | u32 reg; | 341 | u32 reg; |
342 | int ret; | ||
341 | 343 | ||
342 | dev_dbg(&host->pdev->dev, "%s\n", __func__); | 344 | dev_dbg(&host->pdev->dev, "%s\n", __func__); |
343 | 345 | ||
346 | if (host->reg_lcd) { | ||
347 | ret = regulator_enable(host->reg_lcd); | ||
348 | if (ret) { | ||
349 | dev_err(&host->pdev->dev, | ||
350 | "lcd regulator enable failed: %d\n", ret); | ||
351 | return; | ||
352 | } | ||
353 | } | ||
354 | |||
344 | clk_prepare_enable(host->clk); | 355 | clk_prepare_enable(host->clk); |
345 | clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U); | 356 | clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U); |
346 | 357 | ||
@@ -362,6 +373,7 @@ static void mxsfb_disable_controller(struct fb_info *fb_info) | |||
362 | struct mxsfb_info *host = to_imxfb_host(fb_info); | 373 | struct mxsfb_info *host = to_imxfb_host(fb_info); |
363 | unsigned loop; | 374 | unsigned loop; |
364 | u32 reg; | 375 | u32 reg; |
376 | int ret; | ||
365 | 377 | ||
366 | dev_dbg(&host->pdev->dev, "%s\n", __func__); | 378 | dev_dbg(&host->pdev->dev, "%s\n", __func__); |
367 | 379 | ||
@@ -385,6 +397,13 @@ static void mxsfb_disable_controller(struct fb_info *fb_info) | |||
385 | clk_disable_unprepare(host->clk); | 397 | clk_disable_unprepare(host->clk); |
386 | 398 | ||
387 | host->enabled = 0; | 399 | host->enabled = 0; |
400 | |||
401 | if (host->reg_lcd) { | ||
402 | ret = regulator_disable(host->reg_lcd); | ||
403 | if (ret) | ||
404 | dev_err(&host->pdev->dev, | ||
405 | "lcd regulator disable failed: %d\n", ret); | ||
406 | } | ||
388 | } | 407 | } |
389 | 408 | ||
390 | static int mxsfb_set_par(struct fb_info *fb_info) | 409 | static int mxsfb_set_par(struct fb_info *fb_info) |
@@ -859,8 +878,6 @@ static int mxsfb_probe(struct platform_device *pdev) | |||
859 | struct fb_info *fb_info; | 878 | struct fb_info *fb_info; |
860 | struct fb_modelist *modelist; | 879 | struct fb_modelist *modelist; |
861 | struct pinctrl *pinctrl; | 880 | struct pinctrl *pinctrl; |
862 | int panel_enable; | ||
863 | enum of_gpio_flags flags; | ||
864 | int ret; | 881 | int ret; |
865 | 882 | ||
866 | if (of_id) | 883 | if (of_id) |
@@ -904,21 +921,9 @@ static int mxsfb_probe(struct platform_device *pdev) | |||
904 | goto fb_release; | 921 | goto fb_release; |
905 | } | 922 | } |
906 | 923 | ||
907 | panel_enable = of_get_named_gpio_flags(pdev->dev.of_node, | 924 | host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd"); |
908 | "panel-enable-gpios", 0, &flags); | 925 | if (IS_ERR(host->reg_lcd)) |
909 | if (gpio_is_valid(panel_enable)) { | 926 | host->reg_lcd = NULL; |
910 | unsigned long f = GPIOF_OUT_INIT_HIGH; | ||
911 | if (flags == OF_GPIO_ACTIVE_LOW) | ||
912 | f = GPIOF_OUT_INIT_LOW; | ||
913 | ret = devm_gpio_request_one(&pdev->dev, panel_enable, | ||
914 | f, "panel-enable"); | ||
915 | if (ret) { | ||
916 | dev_err(&pdev->dev, | ||
917 | "failed to request gpio %d: %d\n", | ||
918 | panel_enable, ret); | ||
919 | goto fb_release; | ||
920 | } | ||
921 | } | ||
922 | 927 | ||
923 | fb_info->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16, | 928 | fb_info->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16, |
924 | GFP_KERNEL); | 929 | GFP_KERNEL); |