diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-04 09:05:12 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-04 09:05:12 -0700 |
commit | d55696af8d91e8f21dacd74a236e6dcc4f6d78c4 (patch) | |
tree | 99c14624b8da7ad38f357c3ca225dc5c0e46ab9d /drivers/video/fbdev/mx3fb.c | |
parent | 4dc4226f994db264c844a5fcf556935c66f963a5 (diff) | |
parent | fbc6c4a13bbfb420eedfdb26a0a859f9c07e8a7b (diff) | |
download | op-kernel-dev-d55696af8d91e8f21dacd74a236e6dcc4f6d78c4.zip op-kernel-dev-d55696af8d91e8f21dacd74a236e6dcc4f6d78c4.tar.gz |
Merge tag 'fbdev-main-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux into next
Pull main fbdev changes from Tomi Valkeinen:
"Mainly fixes and small improvements. The biggest change seems to be
backlight control support for mx3fb"
* tag 'fbdev-main-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (31 commits)
drivers/video/fbdev/fb-puv3.c: Add header files for function unifb_mmap
video: fbdev: s3fb.c: Fix for possible null pointer dereference
video: fbdev: grvga.c: Fix for possible null pointer dereference
matroxfb: perform a dummy read of M_STATUS
video: of: display_timing: fix default native-mode setting
video: delete unneeded call to platform_get_drvdata
video: mx3fb: Add backlight control support
video: omap: delete support for early fbmem allocation
video: of: display_timing: remove two unsafe error messages
fbdev: fbmem: remove positive test on unsigned values
fbcon: Fix memory leak in con2fb_release_oldinfo()
video: Kconfig: Add a dependency to the Goldfish framebuffer driver
video: exynos: Add a dependency to the menu
video: mx3fb: Use devm_kzalloc
video/nuc900: allow modular build
video: atmel needs FB_BACKLIGHT
video: export fb_prepare_logo
video/mbx: fix building debugfs support
video/omap: fix modular build
video: clarify I2C dependencies
...
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 142e860..c645a0a 100644 --- a/drivers/video/fbdev/mx3fb.c +++ b/drivers/video/fbdev/mx3fb.c @@ -27,6 +27,7 @@ #include <linux/clk.h> #include <linux/mutex.h> #include <linux/dma/ipu-dma.h> +#include <linux/backlight.h> #include <linux/platform_data/dma-imx.h> #include <linux/platform_data/video-mx3fb.h> @@ -241,6 +242,7 @@ struct mx3fb_data { void __iomem *reg_base; spinlock_t lock; struct device *dev; + struct backlight_device *bl; uint32_t h_start_width; uint32_t v_start_width; @@ -271,6 +273,71 @@ struct mx3fb_info { struct fb_var_screeninfo cur_var; /* current var info */ }; +static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value); +static u32 sdc_get_brightness(struct mx3fb_data *mx3fb); + +static int mx3fb_bl_get_brightness(struct backlight_device *bl) +{ + struct mx3fb_data *fbd = bl_get_data(bl); + + return sdc_get_brightness(fbd); +} + +static int mx3fb_bl_update_status(struct backlight_device *bl) +{ + struct mx3fb_data *fbd = bl_get_data(bl); + int brightness = bl->props.brightness; + + if (bl->props.power != FB_BLANK_UNBLANK) + brightness = 0; + if (bl->props.fb_blank != FB_BLANK_UNBLANK) + brightness = 0; + + fbd->backlight_level = (fbd->backlight_level & ~0xFF) | brightness; + + sdc_set_brightness(fbd, fbd->backlight_level); + + return 0; +} + +static const struct backlight_ops mx3fb_lcdc_bl_ops = { + .update_status = mx3fb_bl_update_status, + .get_brightness = mx3fb_bl_get_brightness, +}; + +static void mx3fb_init_backlight(struct mx3fb_data *fbd) +{ + struct backlight_properties props; + struct backlight_device *bl; + + if (fbd->bl) + return; + + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 0xff; + props.type = BACKLIGHT_RAW; + sdc_set_brightness(fbd, fbd->backlight_level); + + bl = backlight_device_register("mx3fb-bl", fbd->dev, fbd, + &mx3fb_lcdc_bl_ops, &props); + if (IS_ERR(bl)) { + dev_err(fbd->dev, "error %ld on backlight register\n", + PTR_ERR(bl)); + return; + } + + fbd->bl = bl; + bl->props.power = FB_BLANK_UNBLANK; + bl->props.fb_blank = FB_BLANK_UNBLANK; + bl->props.brightness = mx3fb_bl_get_brightness(bl); +} + +static void mx3fb_exit_backlight(struct mx3fb_data *fbd) +{ + if (fbd->bl) + backlight_device_unregister(fbd->bl); +} + static void mx3fb_dma_done(void *); /* 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 return 0; } +static u32 sdc_get_brightness(struct mx3fb_data *mx3fb) +{ + u32 brightness; + + brightness = mx3fb_read_reg(mx3fb, SDC_PWM_CTRL); + brightness = (brightness >> 16) & 0xFF; + + return brightness; +} + static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value) { dev_dbg(mx3fb->dev, "%s: value = %d\n", __func__, value); @@ -1496,7 +1573,7 @@ static int mx3fb_probe(struct platform_device *pdev) if (!sdc_reg) return -EINVAL; - mx3fb = kzalloc(sizeof(*mx3fb), GFP_KERNEL); + mx3fb = devm_kzalloc(&pdev->dev, sizeof(*mx3fb), GFP_KERNEL); if (!mx3fb) return -ENOMEM; @@ -1534,6 +1611,8 @@ static int mx3fb_probe(struct platform_device *pdev) if (ret < 0) goto eisdc0; + mx3fb_init_backlight(mx3fb); + return 0; eisdc0: @@ -1542,7 +1621,6 @@ ersdc0: dmaengine_put(); iounmap(mx3fb->reg_base); eremap: - kfree(mx3fb); dev_err(dev, "mx3fb: failed to register fb\n"); return ret; } @@ -1557,11 +1635,12 @@ static int mx3fb_remove(struct platform_device *dev) chan = &mx3_fbi->idmac_channel->dma_chan; release_fbi(fbi); + mx3fb_exit_backlight(mx3fb); + dma_release_channel(chan); dmaengine_put(); iounmap(mx3fb->reg_base); - kfree(mx3fb); return 0; } |