diff options
Diffstat (limited to 'drivers/video/fbdev/mx3fb.c')
-rw-r--r-- | drivers/video/fbdev/mx3fb.c | 85 |
1 files changed, 82 insertions, 3 deletions
diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c index 142e860fb527..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); |
@@ -1496,7 +1573,7 @@ static int mx3fb_probe(struct platform_device *pdev) | |||
1496 | if (!sdc_reg) | 1573 | if (!sdc_reg) |
1497 | return -EINVAL; | 1574 | return -EINVAL; |
1498 | 1575 | ||
1499 | mx3fb = kzalloc(sizeof(*mx3fb), GFP_KERNEL); | 1576 | mx3fb = devm_kzalloc(&pdev->dev, sizeof(*mx3fb), GFP_KERNEL); |
1500 | if (!mx3fb) | 1577 | if (!mx3fb) |
1501 | return -ENOMEM; | 1578 | return -ENOMEM; |
1502 | 1579 | ||
@@ -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: |
@@ -1542,7 +1621,6 @@ ersdc0: | |||
1542 | dmaengine_put(); | 1621 | dmaengine_put(); |
1543 | iounmap(mx3fb->reg_base); | 1622 | iounmap(mx3fb->reg_base); |
1544 | eremap: | 1623 | eremap: |
1545 | kfree(mx3fb); | ||
1546 | dev_err(dev, "mx3fb: failed to register fb\n"); | 1624 | dev_err(dev, "mx3fb: failed to register fb\n"); |
1547 | return ret; | 1625 | return ret; |
1548 | } | 1626 | } |
@@ -1557,11 +1635,12 @@ static int mx3fb_remove(struct platform_device *dev) | |||
1557 | chan = &mx3_fbi->idmac_channel->dma_chan; | 1635 | chan = &mx3_fbi->idmac_channel->dma_chan; |
1558 | release_fbi(fbi); | 1636 | release_fbi(fbi); |
1559 | 1637 | ||
1638 | mx3fb_exit_backlight(mx3fb); | ||
1639 | |||
1560 | dma_release_channel(chan); | 1640 | dma_release_channel(chan); |
1561 | dmaengine_put(); | 1641 | dmaengine_put(); |
1562 | 1642 | ||
1563 | iounmap(mx3fb->reg_base); | 1643 | iounmap(mx3fb->reg_base); |
1564 | kfree(mx3fb); | ||
1565 | return 0; | 1644 | return 0; |
1566 | } | 1645 | } |
1567 | 1646 | ||