diff options
author | Alexander Stein <alexander.stein@systec-electronic.com> | 2014-05-12 02:34:14 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-05-16 04:58:39 -0400 |
commit | 7edaa761ee81bf28804e45d405f163dea26bfa7f (patch) | |
tree | dc39e9ff7db5007a2b8a7daeeaacf436238ebd2f | |
parent | 7ceb1892c04c6c27765cc6139d6057b72dc86e95 (diff) |
video: mx3fb: Add backlight control support
This patch add backlight control support to allow dimming the backlight
using the internal PWM. Currently the brightness is set fixed to a
maximum of 255.
Signed-off-by: Alexander Stein <alexander.stein@systec-electronic.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r-- | drivers/video/fbdev/Kconfig | 1 | ||||
-rw-r--r-- | drivers/video/fbdev/mx3fb.c | 81 |
2 files changed, 82 insertions, 0 deletions
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 96f0f42d53bc..59c98bfd5a8a 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig | |||
@@ -2336,6 +2336,7 @@ config FB_MX3 | |||
2336 | select FB_CFB_FILLRECT | 2336 | select FB_CFB_FILLRECT |
2337 | select FB_CFB_COPYAREA | 2337 | select FB_CFB_COPYAREA |
2338 | select FB_CFB_IMAGEBLIT | 2338 | select FB_CFB_IMAGEBLIT |
2339 | select BACKLIGHT_CLASS_DEVICE | ||
2339 | default y | 2340 | default y |
2340 | help | 2341 | help |
2341 | This is a framebuffer device for the i.MX31 LCD Controller. So | 2342 | This is a framebuffer device for the i.MX31 LCD Controller. So |
diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c index ee95de80a487..c645a0a0c341 100644 --- a/drivers/video/fbdev/mx3fb.c +++ b/drivers/video/fbdev/mx3fb.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
28 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
29 | #include <linux/dma/ipu-dma.h> | 29 | #include <linux/dma/ipu-dma.h> |
30 | #include <linux/backlight.h> | ||
30 | 31 | ||
31 | #include <linux/platform_data/dma-imx.h> | 32 | #include <linux/platform_data/dma-imx.h> |
32 | #include <linux/platform_data/video-mx3fb.h> | 33 | #include <linux/platform_data/video-mx3fb.h> |
@@ -241,6 +242,7 @@ struct mx3fb_data { | |||
241 | void __iomem *reg_base; | 242 | void __iomem *reg_base; |
242 | spinlock_t lock; | 243 | spinlock_t lock; |
243 | struct device *dev; | 244 | struct device *dev; |
245 | struct backlight_device *bl; | ||
244 | 246 | ||
245 | uint32_t h_start_width; | 247 | uint32_t h_start_width; |
246 | uint32_t v_start_width; | 248 | uint32_t v_start_width; |
@@ -271,6 +273,71 @@ struct mx3fb_info { | |||
271 | struct fb_var_screeninfo cur_var; /* current var info */ | 273 | struct fb_var_screeninfo cur_var; /* current var info */ |
272 | }; | 274 | }; |
273 | 275 | ||
276 | static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value); | ||
277 | static u32 sdc_get_brightness(struct mx3fb_data *mx3fb); | ||
278 | |||
279 | static int mx3fb_bl_get_brightness(struct backlight_device *bl) | ||
280 | { | ||
281 | struct mx3fb_data *fbd = bl_get_data(bl); | ||
282 | |||
283 | return sdc_get_brightness(fbd); | ||
284 | } | ||
285 | |||
286 | static int mx3fb_bl_update_status(struct backlight_device *bl) | ||
287 | { | ||
288 | struct mx3fb_data *fbd = bl_get_data(bl); | ||
289 | int brightness = bl->props.brightness; | ||
290 | |||
291 | if (bl->props.power != FB_BLANK_UNBLANK) | ||
292 | brightness = 0; | ||
293 | if (bl->props.fb_blank != FB_BLANK_UNBLANK) | ||
294 | brightness = 0; | ||
295 | |||
296 | fbd->backlight_level = (fbd->backlight_level & ~0xFF) | brightness; | ||
297 | |||
298 | sdc_set_brightness(fbd, fbd->backlight_level); | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | static const struct backlight_ops mx3fb_lcdc_bl_ops = { | ||
304 | .update_status = mx3fb_bl_update_status, | ||
305 | .get_brightness = mx3fb_bl_get_brightness, | ||
306 | }; | ||
307 | |||
308 | static void mx3fb_init_backlight(struct mx3fb_data *fbd) | ||
309 | { | ||
310 | struct backlight_properties props; | ||
311 | struct backlight_device *bl; | ||
312 | |||
313 | if (fbd->bl) | ||
314 | return; | ||
315 | |||
316 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
317 | props.max_brightness = 0xff; | ||
318 | props.type = BACKLIGHT_RAW; | ||
319 | sdc_set_brightness(fbd, fbd->backlight_level); | ||
320 | |||
321 | bl = backlight_device_register("mx3fb-bl", fbd->dev, fbd, | ||
322 | &mx3fb_lcdc_bl_ops, &props); | ||
323 | if (IS_ERR(bl)) { | ||
324 | dev_err(fbd->dev, "error %ld on backlight register\n", | ||
325 | PTR_ERR(bl)); | ||
326 | return; | ||
327 | } | ||
328 | |||
329 | fbd->bl = bl; | ||
330 | bl->props.power = FB_BLANK_UNBLANK; | ||
331 | bl->props.fb_blank = FB_BLANK_UNBLANK; | ||
332 | bl->props.brightness = mx3fb_bl_get_brightness(bl); | ||
333 | } | ||
334 | |||
335 | static void mx3fb_exit_backlight(struct mx3fb_data *fbd) | ||
336 | { | ||
337 | if (fbd->bl) | ||
338 | backlight_device_unregister(fbd->bl); | ||
339 | } | ||
340 | |||
274 | static void mx3fb_dma_done(void *); | 341 | static void mx3fb_dma_done(void *); |
275 | 342 | ||
276 | /* Used fb-mode and bpp. Can be set on kernel command line, therefore file-static. */ | 343 | /* Used fb-mode and bpp. Can be set on kernel command line, therefore file-static. */ |
@@ -628,6 +695,16 @@ static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t a | |||
628 | return 0; | 695 | return 0; |
629 | } | 696 | } |
630 | 697 | ||
698 | static u32 sdc_get_brightness(struct mx3fb_data *mx3fb) | ||
699 | { | ||
700 | u32 brightness; | ||
701 | |||
702 | brightness = mx3fb_read_reg(mx3fb, SDC_PWM_CTRL); | ||
703 | brightness = (brightness >> 16) & 0xFF; | ||
704 | |||
705 | return brightness; | ||
706 | } | ||
707 | |||
631 | static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value) | 708 | static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value) |
632 | { | 709 | { |
633 | dev_dbg(mx3fb->dev, "%s: value = %d\n", __func__, value); | 710 | dev_dbg(mx3fb->dev, "%s: value = %d\n", __func__, value); |
@@ -1534,6 +1611,8 @@ static int mx3fb_probe(struct platform_device *pdev) | |||
1534 | if (ret < 0) | 1611 | if (ret < 0) |
1535 | goto eisdc0; | 1612 | goto eisdc0; |
1536 | 1613 | ||
1614 | mx3fb_init_backlight(mx3fb); | ||
1615 | |||
1537 | return 0; | 1616 | return 0; |
1538 | 1617 | ||
1539 | eisdc0: | 1618 | eisdc0: |
@@ -1556,6 +1635,8 @@ static int mx3fb_remove(struct platform_device *dev) | |||
1556 | chan = &mx3_fbi->idmac_channel->dma_chan; | 1635 | chan = &mx3_fbi->idmac_channel->dma_chan; |
1557 | release_fbi(fbi); | 1636 | release_fbi(fbi); |
1558 | 1637 | ||
1638 | mx3fb_exit_backlight(mx3fb); | ||
1639 | |||
1559 | dma_release_channel(chan); | 1640 | dma_release_channel(chan); |
1560 | dmaengine_put(); | 1641 | dmaengine_put(); |
1561 | 1642 | ||