Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Alexander Stein and committed by
Tomi Valkeinen
7edaa761 7ceb1892

+82
+1
drivers/video/fbdev/Kconfig
··· 2336 2336 select FB_CFB_FILLRECT 2337 2337 select FB_CFB_COPYAREA 2338 2338 select FB_CFB_IMAGEBLIT 2339 + select BACKLIGHT_CLASS_DEVICE 2339 2340 default y 2340 2341 help 2341 2342 This is a framebuffer device for the i.MX31 LCD Controller. So
+81
drivers/video/fbdev/mx3fb.c
··· 27 27 #include <linux/clk.h> 28 28 #include <linux/mutex.h> 29 29 #include <linux/dma/ipu-dma.h> 30 + #include <linux/backlight.h> 30 31 31 32 #include <linux/platform_data/dma-imx.h> 32 33 #include <linux/platform_data/video-mx3fb.h> ··· 242 241 void __iomem *reg_base; 243 242 spinlock_t lock; 244 243 struct device *dev; 244 + struct backlight_device *bl; 245 245 246 246 uint32_t h_start_width; 247 247 uint32_t v_start_width; ··· 272 270 273 271 struct fb_var_screeninfo cur_var; /* current var info */ 274 272 }; 273 + 274 + static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value); 275 + static u32 sdc_get_brightness(struct mx3fb_data *mx3fb); 276 + 277 + static int mx3fb_bl_get_brightness(struct backlight_device *bl) 278 + { 279 + struct mx3fb_data *fbd = bl_get_data(bl); 280 + 281 + return sdc_get_brightness(fbd); 282 + } 283 + 284 + static int mx3fb_bl_update_status(struct backlight_device *bl) 285 + { 286 + struct mx3fb_data *fbd = bl_get_data(bl); 287 + int brightness = bl->props.brightness; 288 + 289 + if (bl->props.power != FB_BLANK_UNBLANK) 290 + brightness = 0; 291 + if (bl->props.fb_blank != FB_BLANK_UNBLANK) 292 + brightness = 0; 293 + 294 + fbd->backlight_level = (fbd->backlight_level & ~0xFF) | brightness; 295 + 296 + sdc_set_brightness(fbd, fbd->backlight_level); 297 + 298 + return 0; 299 + } 300 + 301 + static const struct backlight_ops mx3fb_lcdc_bl_ops = { 302 + .update_status = mx3fb_bl_update_status, 303 + .get_brightness = mx3fb_bl_get_brightness, 304 + }; 305 + 306 + static void mx3fb_init_backlight(struct mx3fb_data *fbd) 307 + { 308 + struct backlight_properties props; 309 + struct backlight_device *bl; 310 + 311 + if (fbd->bl) 312 + return; 313 + 314 + memset(&props, 0, sizeof(struct backlight_properties)); 315 + props.max_brightness = 0xff; 316 + props.type = BACKLIGHT_RAW; 317 + sdc_set_brightness(fbd, fbd->backlight_level); 318 + 319 + bl = backlight_device_register("mx3fb-bl", fbd->dev, fbd, 320 + &mx3fb_lcdc_bl_ops, &props); 321 + if (IS_ERR(bl)) { 322 + dev_err(fbd->dev, "error %ld on backlight register\n", 323 + PTR_ERR(bl)); 324 + return; 325 + } 326 + 327 + fbd->bl = bl; 328 + bl->props.power = FB_BLANK_UNBLANK; 329 + bl->props.fb_blank = FB_BLANK_UNBLANK; 330 + bl->props.brightness = mx3fb_bl_get_brightness(bl); 331 + } 332 + 333 + static void mx3fb_exit_backlight(struct mx3fb_data *fbd) 334 + { 335 + if (fbd->bl) 336 + backlight_device_unregister(fbd->bl); 337 + } 275 338 276 339 static void mx3fb_dma_done(void *); 277 340 ··· 693 626 spin_unlock_irqrestore(&mx3fb->lock, lock_flags); 694 627 695 628 return 0; 629 + } 630 + 631 + static u32 sdc_get_brightness(struct mx3fb_data *mx3fb) 632 + { 633 + u32 brightness; 634 + 635 + brightness = mx3fb_read_reg(mx3fb, SDC_PWM_CTRL); 636 + brightness = (brightness >> 16) & 0xFF; 637 + 638 + return brightness; 696 639 } 697 640 698 641 static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value) ··· 1611 1534 if (ret < 0) 1612 1535 goto eisdc0; 1613 1536 1537 + mx3fb_init_backlight(mx3fb); 1538 + 1614 1539 return 0; 1615 1540 1616 1541 eisdc0: ··· 1634 1555 1635 1556 chan = &mx3_fbi->idmac_channel->dma_chan; 1636 1557 release_fbi(fbi); 1558 + 1559 + mx3fb_exit_backlight(mx3fb); 1637 1560 1638 1561 dma_release_channel(chan); 1639 1562 dmaengine_put();