aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fbdev/mx3fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbdev/mx3fb.c')
-rw-r--r--drivers/video/fbdev/mx3fb.c85
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
276static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value);
277static u32 sdc_get_brightness(struct mx3fb_data *mx3fb);
278
279static 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
286static 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
303static const struct backlight_ops mx3fb_lcdc_bl_ops = {
304 .update_status = mx3fb_bl_update_status,
305 .get_brightness = mx3fb_bl_get_brightness,
306};
307
308static 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
335static void mx3fb_exit_backlight(struct mx3fb_data *fbd)
336{
337 if (fbd->bl)
338 backlight_device_unregister(fbd->bl);
339}
340
274static void mx3fb_dma_done(void *); 341static 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
698static 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
631static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value) 708static 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
1539eisdc0: 1618eisdc0:
@@ -1542,7 +1621,6 @@ ersdc0:
1542 dmaengine_put(); 1621 dmaengine_put();
1543 iounmap(mx3fb->reg_base); 1622 iounmap(mx3fb->reg_base);
1544eremap: 1623eremap:
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