2 * TI LP8788 MFD - keyled driver
4 * Copyright 2012 Texas Instruments
6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
14 #include <linux/module.h>
15 #include <linux/slab.h>
16 #include <linux/err.h>
17 #include <linux/platform_device.h>
18 #include <linux/leds.h>
19 #include <linux/mutex.h>
20 #include <linux/mfd/lp8788.h>
21 #include <linux/mfd/lp8788-isink.h>
23 #define MAX_BRIGHTNESS LP8788_ISINK_MAX_PWM
24 #define DEFAULT_LED_NAME "keyboard-backlight"
29 struct work_struct work
;
30 struct led_classdev led_dev
;
31 enum lp8788_isink_number isink_num
;
32 enum led_brightness brightness
;
36 struct lp8788_led_config
{
37 enum lp8788_isink_scale scale
;
38 enum lp8788_isink_number num
;
42 static struct lp8788_led_config default_led_config
= {
43 .scale
= LP8788_ISINK_SCALE_100mA
,
44 .num
= LP8788_ISINK_3
,
48 static int lp8788_led_init_device(struct lp8788_led
*led
,
49 struct lp8788_led_platform_data
*pdata
)
51 struct lp8788_led_config
*cfg
= &default_led_config
;
56 cfg
->scale
= pdata
->scale
;
57 cfg
->num
= pdata
->num
;
58 cfg
->iout
= pdata
->iout_code
;
61 led
->isink_num
= cfg
->num
;
63 /* scale configuration */
64 addr
= LP8788_ISINK_CTRL
;
65 mask
= 1 << (cfg
->num
+ LP8788_ISINK_SCALE_OFFSET
);
66 val
= cfg
->scale
<< (cfg
->num
+ LP8788_ISINK_SCALE_OFFSET
);
67 ret
= lp8788_update_bits(led
->lp
, addr
, mask
, val
);
71 /* current configuration */
72 addr
= lp8788_iout_addr
[cfg
->num
];
73 mask
= lp8788_iout_mask
[cfg
->num
];
76 return lp8788_update_bits(led
->lp
, addr
, mask
, val
);
79 static void lp8788_led_enable(struct lp8788_led
*led
,
80 enum lp8788_isink_number num
, int on
)
85 if (lp8788_update_bits(led
->lp
, LP8788_ISINK_CTRL
, mask
, val
))
91 static void lp8788_led_work(struct work_struct
*work
)
93 struct lp8788_led
*led
= container_of(work
, struct lp8788_led
, work
);
94 enum lp8788_isink_number num
= led
->isink_num
;
96 u8 val
= led
->brightness
;
98 mutex_lock(&led
->lock
);
104 lp8788_write_byte(led
->lp
, lp8788_pwm_addr
[num
], val
);
107 mutex_unlock(&led
->lock
);
111 enable
= (val
> 0) ? 1 : 0;
112 if (enable
!= led
->on
)
113 lp8788_led_enable(led
, num
, enable
);
115 mutex_unlock(&led
->lock
);
118 static void lp8788_brightness_set(struct led_classdev
*led_cdev
,
119 enum led_brightness brt_val
)
121 struct lp8788_led
*led
=
122 container_of(led_cdev
, struct lp8788_led
, led_dev
);
124 led
->brightness
= brt_val
;
125 schedule_work(&led
->work
);
128 static int lp8788_led_probe(struct platform_device
*pdev
)
130 struct lp8788
*lp
= dev_get_drvdata(pdev
->dev
.parent
);
131 struct lp8788_led_platform_data
*led_pdata
;
132 struct lp8788_led
*led
;
135 led
= devm_kzalloc(lp
->dev
, sizeof(struct lp8788_led
), GFP_KERNEL
);
140 led
->led_dev
.max_brightness
= MAX_BRIGHTNESS
;
141 led
->led_dev
.brightness_set
= lp8788_brightness_set
;
143 led_pdata
= lp
->pdata
? lp
->pdata
->led_pdata
: NULL
;
145 if (!led_pdata
|| !led_pdata
->name
)
146 led
->led_dev
.name
= DEFAULT_LED_NAME
;
148 led
->led_dev
.name
= led_pdata
->name
;
150 mutex_init(&led
->lock
);
151 INIT_WORK(&led
->work
, lp8788_led_work
);
153 platform_set_drvdata(pdev
, led
);
155 ret
= lp8788_led_init_device(led
, led_pdata
);
157 dev_err(lp
->dev
, "led init device err: %d\n", ret
);
161 ret
= led_classdev_register(lp
->dev
, &led
->led_dev
);
163 dev_err(lp
->dev
, "led register err: %d\n", ret
);
170 static int lp8788_led_remove(struct platform_device
*pdev
)
172 struct lp8788_led
*led
= platform_get_drvdata(pdev
);
174 led_classdev_unregister(&led
->led_dev
);
175 flush_work(&led
->work
);
180 static struct platform_driver lp8788_led_driver
= {
181 .probe
= lp8788_led_probe
,
182 .remove
= lp8788_led_remove
,
184 .name
= LP8788_DEV_KEYLED
,
185 .owner
= THIS_MODULE
,
188 module_platform_driver(lp8788_led_driver
);
190 MODULE_DESCRIPTION("Texas Instruments LP8788 Keyboard LED Driver");
191 MODULE_AUTHOR("Milo Kim");
192 MODULE_LICENSE("GPL");
193 MODULE_ALIAS("platform:lp8788-keyled");