66 * Ingi Kim <ingi2.kim@samsung.com>
77 */
88
9- #include <linux/delay.h>
109#include <linux/err.h>
1110#include <linux/gpio/consumer.h>
11+ #include <linux/leds-expresswire.h>
1212#include <linux/led-class-flash.h>
1313#include <linux/module.h>
1414#include <linux/mutex.h>
3737#define KTD2692_REG_FLASH_CURRENT_BASE 0x80
3838#define KTD2692_REG_MODE_BASE 0xA0
3939
40- /* Set bit coding time for expresswire interface */
41- #define KTD2692_TIME_RESET_US 700
42- #define KTD2692_TIME_DATA_START_TIME_US 10
43- #define KTD2692_TIME_HIGH_END_OF_DATA_US 350
44- #define KTD2692_TIME_LOW_END_OF_DATA_US 10
45- #define KTD2692_TIME_SHORT_BITSET_US 4
46- #define KTD2692_TIME_LONG_BITSET_US 12
47-
4840/* KTD2692 default length of name */
4941#define KTD2692_NAME_LENGTH 20
5042
51- enum ktd2692_bitset {
52- KTD2692_LOW = 0 ,
53- KTD2692_HIGH ,
54- };
55-
5643/* Movie / Flash Mode Control */
5744enum ktd2692_led_mode {
5845 KTD2692_MODE_DISABLE = 0 , /* default */
@@ -71,7 +58,19 @@ struct ktd2692_led_config_data {
7158 enum led_brightness max_brightness ;
7259};
7360
61+ const struct expresswire_timing ktd2692_timing = {
62+ .poweroff_us = 700 ,
63+ .data_start_us = 10 ,
64+ .end_of_data_low_us = 10 ,
65+ .end_of_data_high_us = 350 ,
66+ .short_bitset_us = 4 ,
67+ .long_bitset_us = 12
68+ };
69+
7470struct ktd2692_context {
71+ /* Common ExpressWire properties (ctrl GPIO and timing) */
72+ struct expresswire_common_props props ;
73+
7574 /* Related LED Flash class device */
7675 struct led_classdev_flash fled_cdev ;
7776
@@ -80,7 +79,6 @@ struct ktd2692_context {
8079 struct regulator * regulator ;
8180
8281 struct gpio_desc * aux_gpio ;
83- struct gpio_desc * ctrl_gpio ;
8482
8583 enum ktd2692_led_mode mode ;
8684 enum led_brightness torch_brightness ;
@@ -92,67 +90,6 @@ static struct ktd2692_context *fled_cdev_to_led(
9290 return container_of (fled_cdev , struct ktd2692_context , fled_cdev );
9391}
9492
95- static void ktd2692_expresswire_start (struct ktd2692_context * led )
96- {
97- gpiod_direction_output (led -> ctrl_gpio , KTD2692_HIGH );
98- udelay (KTD2692_TIME_DATA_START_TIME_US );
99- }
100-
101- static void ktd2692_expresswire_reset (struct ktd2692_context * led )
102- {
103- gpiod_direction_output (led -> ctrl_gpio , KTD2692_LOW );
104- udelay (KTD2692_TIME_RESET_US );
105- }
106-
107- static void ktd2692_expresswire_end (struct ktd2692_context * led )
108- {
109- gpiod_direction_output (led -> ctrl_gpio , KTD2692_LOW );
110- udelay (KTD2692_TIME_LOW_END_OF_DATA_US );
111- gpiod_direction_output (led -> ctrl_gpio , KTD2692_HIGH );
112- udelay (KTD2692_TIME_HIGH_END_OF_DATA_US );
113- }
114-
115- static void ktd2692_expresswire_set_bit (struct ktd2692_context * led , bool bit )
116- {
117- /*
118- * The Low Bit(0) and High Bit(1) is based on a time detection
119- * algorithm between time low and time high
120- * Time_(L_LB) : Low time of the Low Bit(0)
121- * Time_(H_LB) : High time of the LOW Bit(0)
122- * Time_(L_HB) : Low time of the High Bit(1)
123- * Time_(H_HB) : High time of the High Bit(1)
124- *
125- * It can be simplified to:
126- * Low Bit(0) : 2 * Time_(H_LB) < Time_(L_LB)
127- * High Bit(1) : 2 * Time_(L_HB) < Time_(H_HB)
128- * HIGH ___ ____ _.. _________ ___
129- * |_________| |_.. |____| |__|
130- * LOW <L_LB> <H_LB> <L_HB> <H_HB>
131- * [ Low Bit (0) ] [ High Bit(1) ]
132- */
133- if (bit ) {
134- gpiod_direction_output (led -> ctrl_gpio , KTD2692_LOW );
135- udelay (KTD2692_TIME_SHORT_BITSET_US );
136- gpiod_direction_output (led -> ctrl_gpio , KTD2692_HIGH );
137- udelay (KTD2692_TIME_LONG_BITSET_US );
138- } else {
139- gpiod_direction_output (led -> ctrl_gpio , KTD2692_LOW );
140- udelay (KTD2692_TIME_LONG_BITSET_US );
141- gpiod_direction_output (led -> ctrl_gpio , KTD2692_HIGH );
142- udelay (KTD2692_TIME_SHORT_BITSET_US );
143- }
144- }
145-
146- static void ktd2692_expresswire_write (struct ktd2692_context * led , u8 value )
147- {
148- int i ;
149-
150- ktd2692_expresswire_start (led );
151- for (i = 7 ; i >= 0 ; i -- )
152- ktd2692_expresswire_set_bit (led , value & BIT (i ));
153- ktd2692_expresswire_end (led );
154- }
155-
15693static int ktd2692_led_brightness_set (struct led_classdev * led_cdev ,
15794 enum led_brightness brightness )
15895{
@@ -163,14 +100,14 @@ static int ktd2692_led_brightness_set(struct led_classdev *led_cdev,
163100
164101 if (brightness == LED_OFF ) {
165102 led -> mode = KTD2692_MODE_DISABLE ;
166- gpiod_direction_output (led -> aux_gpio , KTD2692_LOW );
103+ gpiod_direction_output (led -> aux_gpio , 0 );
167104 } else {
168- ktd2692_expresswire_write ( led , brightness |
105+ expresswire_write_u8 ( & led -> props , brightness |
169106 KTD2692_REG_MOVIE_CURRENT_BASE );
170107 led -> mode = KTD2692_MODE_MOVIE ;
171108 }
172109
173- ktd2692_expresswire_write ( led , led -> mode | KTD2692_REG_MODE_BASE );
110+ expresswire_write_u8 ( & led -> props , led -> mode | KTD2692_REG_MODE_BASE );
174111 mutex_unlock (& led -> lock );
175112
176113 return 0 ;
@@ -187,17 +124,17 @@ static int ktd2692_led_flash_strobe_set(struct led_classdev_flash *fled_cdev,
187124
188125 if (state ) {
189126 flash_tm_reg = GET_TIMEOUT_OFFSET (timeout -> val , timeout -> step );
190- ktd2692_expresswire_write ( led , flash_tm_reg
127+ expresswire_write_u8 ( & led -> props , flash_tm_reg
191128 | KTD2692_REG_FLASH_TIMEOUT_BASE );
192129
193130 led -> mode = KTD2692_MODE_FLASH ;
194- gpiod_direction_output (led -> aux_gpio , KTD2692_HIGH );
131+ gpiod_direction_output (led -> aux_gpio , 1 );
195132 } else {
196133 led -> mode = KTD2692_MODE_DISABLE ;
197- gpiod_direction_output (led -> aux_gpio , KTD2692_LOW );
134+ gpiod_direction_output (led -> aux_gpio , 0 );
198135 }
199136
200- ktd2692_expresswire_write ( led , led -> mode | KTD2692_REG_MODE_BASE );
137+ expresswire_write_u8 ( & led -> props , led -> mode | KTD2692_REG_MODE_BASE );
201138
202139 fled_cdev -> led_cdev .brightness = LED_OFF ;
203140 led -> mode = KTD2692_MODE_DISABLE ;
@@ -247,12 +184,12 @@ static void ktd2692_init_flash_timeout(struct led_classdev_flash *fled_cdev,
247184static void ktd2692_setup (struct ktd2692_context * led )
248185{
249186 led -> mode = KTD2692_MODE_DISABLE ;
250- ktd2692_expresswire_reset ( led );
251- gpiod_direction_output (led -> aux_gpio , KTD2692_LOW );
187+ expresswire_power_off ( & led -> props );
188+ gpiod_direction_output (led -> aux_gpio , 0 );
252189
253- ktd2692_expresswire_write ( led , (KTD2692_MM_MIN_CURR_THRESHOLD_SCALE - 1 )
190+ expresswire_write_u8 ( & led -> props , (KTD2692_MM_MIN_CURR_THRESHOLD_SCALE - 1 )
254191 | KTD2692_REG_MM_MIN_CURR_THRESHOLD_BASE );
255- ktd2692_expresswire_write ( led , KTD2692_FLASH_MODE_CURR_PERCENT (45 )
192+ expresswire_write_u8 ( & led -> props , KTD2692_FLASH_MODE_CURR_PERCENT (45 )
256193 | KTD2692_REG_FLASH_CURRENT_BASE );
257194}
258195
@@ -277,8 +214,8 @@ static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev,
277214 if (!np )
278215 return - ENXIO ;
279216
280- led -> ctrl_gpio = devm_gpiod_get (dev , "ctrl" , GPIOD_ASIS );
281- ret = PTR_ERR_OR_ZERO (led -> ctrl_gpio );
217+ led -> props . ctrl_gpio = devm_gpiod_get (dev , "ctrl" , GPIOD_ASIS );
218+ ret = PTR_ERR_OR_ZERO (led -> props . ctrl_gpio );
282219 if (ret )
283220 return dev_err_probe (dev , ret , "cannot get ctrl-gpios\n" );
284221
@@ -412,6 +349,7 @@ static struct platform_driver ktd2692_driver = {
412349
413350module_platform_driver (ktd2692_driver );
414351
352+ MODULE_IMPORT_NS (EXPRESSWIRE );
415353MODULE_AUTHOR ("Ingi Kim <ingi2.kim@samsung.com>" );
416354MODULE_DESCRIPTION ("Kinetic KTD2692 LED driver" );
417355MODULE_LICENSE ("GPL v2" );
0 commit comments