2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3 * PCF50633 backlight device driver
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/slab.h>
19 #include <linux/platform_device.h>
21 #include <linux/backlight.h>
24 #include <linux/mfd/pcf50633/core.h>
25 #include <linux/mfd/pcf50633/backlight.h>
29 struct backlight_device
*bl
;
31 unsigned int brightness
;
32 unsigned int brightness_limit
;
36 * pcf50633_bl_set_brightness_limit
38 * Update the brightness limit for the pc50633 backlight. The actual brightness
39 * will not go above the limit. This is useful to limit power drain for example
42 * @dev: Pointer to a pcf50633 device
43 * @limit: The brightness limit. Valid values are 0-63
45 int pcf50633_bl_set_brightness_limit(struct pcf50633
*pcf
, unsigned int limit
)
47 struct pcf50633_bl
*pcf_bl
= platform_get_drvdata(pcf
->bl_pdev
);
52 pcf_bl
->brightness_limit
= limit
& 0x3f;
53 backlight_update_status(pcf_bl
->bl
);
58 static int pcf50633_bl_update_status(struct backlight_device
*bl
)
60 struct pcf50633_bl
*pcf_bl
= bl_get_data(bl
);
61 unsigned int new_brightness
;
64 if (bl
->props
.state
& (BL_CORE_SUSPENDED
| BL_CORE_FBBLANK
) ||
65 bl
->props
.power
!= FB_BLANK_UNBLANK
)
67 else if (bl
->props
.brightness
< pcf_bl
->brightness_limit
)
68 new_brightness
= bl
->props
.brightness
;
70 new_brightness
= pcf_bl
->brightness_limit
;
73 if (pcf_bl
->brightness
== new_brightness
)
77 pcf50633_reg_write(pcf_bl
->pcf
, PCF50633_REG_LEDOUT
,
79 if (!pcf_bl
->brightness
)
80 pcf50633_reg_write(pcf_bl
->pcf
, PCF50633_REG_LEDENA
, 1);
82 pcf50633_reg_write(pcf_bl
->pcf
, PCF50633_REG_LEDENA
, 0);
85 pcf_bl
->brightness
= new_brightness
;
90 static int pcf50633_bl_get_brightness(struct backlight_device
*bl
)
92 struct pcf50633_bl
*pcf_bl
= bl_get_data(bl
);
94 return pcf_bl
->brightness
;
97 static const struct backlight_ops pcf50633_bl_ops
= {
98 .get_brightness
= pcf50633_bl_get_brightness
,
99 .update_status
= pcf50633_bl_update_status
,
100 .options
= BL_CORE_SUSPENDRESUME
,
103 static int pcf50633_bl_probe(struct platform_device
*pdev
)
105 struct pcf50633_bl
*pcf_bl
;
106 struct device
*parent
= pdev
->dev
.parent
;
107 struct pcf50633_platform_data
*pcf50633_data
= dev_get_platdata(parent
);
108 struct pcf50633_bl_platform_data
*pdata
= pcf50633_data
->backlight_data
;
109 struct backlight_properties bl_props
;
111 pcf_bl
= devm_kzalloc(&pdev
->dev
, sizeof(*pcf_bl
), GFP_KERNEL
);
115 memset(&bl_props
, 0, sizeof(bl_props
));
116 bl_props
.type
= BACKLIGHT_RAW
;
117 bl_props
.max_brightness
= 0x3f;
118 bl_props
.power
= FB_BLANK_UNBLANK
;
121 bl_props
.brightness
= pdata
->default_brightness
;
122 pcf_bl
->brightness_limit
= pdata
->default_brightness_limit
;
124 bl_props
.brightness
= 0x3f;
125 pcf_bl
->brightness_limit
= 0x3f;
128 pcf_bl
->pcf
= dev_to_pcf50633(pdev
->dev
.parent
);
130 pcf_bl
->bl
= devm_backlight_device_register(&pdev
->dev
, pdev
->name
,
132 &pcf50633_bl_ops
, &bl_props
);
134 if (IS_ERR(pcf_bl
->bl
))
135 return PTR_ERR(pcf_bl
->bl
);
137 platform_set_drvdata(pdev
, pcf_bl
);
139 pcf50633_reg_write(pcf_bl
->pcf
, PCF50633_REG_LEDDIM
, pdata
->ramp_time
);
142 * Should be different from bl_props.brightness, so we do not exit
143 * update_status early the first time it's called
145 pcf_bl
->brightness
= pcf_bl
->bl
->props
.brightness
+ 1;
147 backlight_update_status(pcf_bl
->bl
);
152 static struct platform_driver pcf50633_bl_driver
= {
153 .probe
= pcf50633_bl_probe
,
155 .name
= "pcf50633-backlight",
159 module_platform_driver(pcf50633_bl_driver
);
161 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
162 MODULE_DESCRIPTION("PCF50633 backlight driver");
163 MODULE_LICENSE("GPL");
164 MODULE_ALIAS("platform:pcf50633-backlight");