2020#include <linux/module.h>
2121#include <linux/of.h>
2222#include <linux/of_device.h>
23+ #include <linux/delay.h>
24+ #include <linux/of_gpio.h>
25+ #include <linux/gpio.h>
2326
2427/* Used to indicate a device has no such register */
2528#define IS31FL32XX_REG_NONE 0xFF
@@ -45,12 +48,16 @@ struct is31fl32xx_led_data {
4548 unsigned int register_delay ;
4649 struct device * dev ;
4750 struct delayed_work register_work ;
51+ struct work_struct brightness_work ;
52+ enum led_brightness new_brightness ;
4853};
4954
5055struct is31fl32xx_priv {
5156 const struct is31fl32xx_chipdef * cdef ;
5257 struct i2c_client * client ;
5358 unsigned int num_leds ;
59+ struct mutex led_mutex ;
60+ struct gpio_desc * reset_gpio ;
5461 struct is31fl32xx_led_data leds [0 ];
5562};
5663
@@ -205,6 +212,33 @@ static int is31fl3216_software_shutdown(struct is31fl32xx_priv *priv,
205212 return is31fl32xx_write (priv , IS31FL3216_CONFIG_REG , value );
206213}
207214
215+ static void is31fl32xx_brightness_work (struct work_struct * work )
216+ {
217+ const struct is31fl32xx_led_data * led_data =
218+ container_of (work ,
219+ struct is31fl32xx_led_data ,
220+ brightness_work );
221+ const struct is31fl32xx_chipdef * cdef = led_data -> priv -> cdef ;
222+ u8 pwm_register_offset ;
223+ int ret ;
224+
225+ dev_dbg (led_data -> cdev .dev , "%s: %d\n" ,
226+ __func__ , led_data -> new_brightness );
227+ mutex_lock (& led_data -> priv -> led_mutex );
228+ /* NOTE: led_data->channel is 1-based */
229+ if (cdef -> pwm_registers_reversed )
230+ pwm_register_offset = cdef -> channels - led_data -> channel ;
231+ else
232+ pwm_register_offset = led_data -> channel - 1 ;
233+
234+ ret = is31fl32xx_write (led_data -> priv ,
235+ cdef -> pwm_register_base + pwm_register_offset ,
236+ led_data -> new_brightness );
237+
238+ is31fl32xx_write (led_data -> priv , cdef -> pwm_update_reg , 0 );
239+ mutex_unlock (& led_data -> priv -> led_mutex );
240+ }
241+
208242/*
209243 * NOTE: A mutex is not needed in this function because:
210244 * - All referenced data is read-only after probe()
@@ -229,29 +263,11 @@ static int is31fl3216_software_shutdown(struct is31fl32xx_priv *priv,
229263static void is31fl32xx_brightness_set (struct led_classdev * led_cdev ,
230264 enum led_brightness brightness )
231265{
232- const struct is31fl32xx_led_data * led_data =
266+ struct is31fl32xx_led_data * led_data =
233267 container_of (led_cdev , struct is31fl32xx_led_data , cdev );
234- const struct is31fl32xx_chipdef * cdef = led_data -> priv -> cdef ;
235- u8 pwm_register_offset ;
236- int ret ;
237-
238- dev_dbg (led_cdev -> dev , "%s: %d\n" , __func__ , brightness );
239-
240- /* NOTE: led_data->channel is 1-based */
241- if (cdef -> pwm_registers_reversed )
242- pwm_register_offset = cdef -> channels - led_data -> channel ;
243- else
244- pwm_register_offset = led_data -> channel - 1 ;
245-
246- ret = is31fl32xx_write (led_data -> priv ,
247- cdef -> pwm_register_base + pwm_register_offset ,
248- brightness );
249- if (ret )
250- dev_err (led_cdev -> dev ,
251- "set brightness %d for led[%d] failed\n" ,
252- brightness , pwm_register_offset );
253268
254- is31fl32xx_write (led_data -> priv , cdef -> pwm_update_reg , 0 );
269+ led_data -> new_brightness = brightness ;
270+ schedule_work (& led_data -> brightness_work );
255271}
256272
257273static int is31fl32xx_reset_regs (struct is31fl32xx_priv * priv )
@@ -298,7 +314,7 @@ static int is31fl32xx_init_regs(struct is31fl32xx_priv *priv)
298314
299315 ret = is31fl32xx_reset_regs (priv );
300316 if (ret )
301- return ret ;
317+ pr_err ( "%s, write to reset register failed\n" , __func__ ) ;
302318
303319 /*
304320 * Set enable bit for all channels.
@@ -377,6 +393,7 @@ static int is31fl32xx_parse_child_dt(const struct device *dev,
377393
378394 cdev -> brightness_set = is31fl32xx_brightness_set ;
379395
396+ INIT_WORK (& led_data -> brightness_work , is31fl32xx_brightness_work );
380397 return 0 ;
381398}
382399
@@ -482,24 +499,39 @@ static int is31fl32xx_probe(struct i2c_client *client,
482499 struct is31fl32xx_priv * priv ;
483500 int count ;
484501 int ret = 0 ;
502+ struct gpio_desc * gpio ;
485503
486504 of_dev_id = of_match_device (of_is31fl32xx_match , dev );
487505 if (!of_dev_id )
488506 return - EINVAL ;
489507
508+ gpio = devm_gpiod_get_optional (dev ,
509+ "reset" , GPIOD_OUT_HIGH );
510+ if (IS_ERR (gpio )) {
511+ int error = PTR_ERR (gpio );
512+
513+ dev_err (dev , "Failed to get reset gpio: %d\n" , error );
514+ return - EINVAL ;
515+ }
516+ gpiod_direction_output (gpio , 1 );
517+
490518 cdef = of_dev_id -> data ;
491519
492520 count = of_get_child_count (dev -> of_node );
493- if (!count )
521+ if (!count ) {
522+ dev_err (dev , "count is invalid\n" );
494523 return - EINVAL ;
524+ }
495525
496526 priv = devm_kzalloc (dev , sizeof_is31fl32xx_priv (count ),
497527 GFP_KERNEL );
498528 if (!priv )
499529 return - ENOMEM ;
500530
531+ mutex_init (& priv -> led_mutex );
501532 priv -> client = client ;
502533 priv -> cdef = cdef ;
534+ priv -> reset_gpio = gpio ;
503535 i2c_set_clientdata (client , priv );
504536
505537 ret = is31fl32xx_init_regs (priv );
@@ -515,11 +547,35 @@ static int is31fl32xx_probe(struct i2c_client *client,
515547
516548static int is31fl32xx_remove (struct i2c_client * client )
517549{
550+ int i ;
518551 struct is31fl32xx_priv * priv = i2c_get_clientdata (client );
519552
553+ for (i = 0 ; i < priv -> num_leds ; i ++ ) {
554+ struct is31fl32xx_led_data * led_data =
555+ & priv -> leds [i ];
556+ cancel_delayed_work_sync (& led_data -> register_work );
557+ cancel_work_sync (& led_data -> brightness_work );
558+ }
559+
520560 return is31fl32xx_reset_regs (priv );
521561}
522562
563+ static void is31fl32xx_shutdown (struct i2c_client * client )
564+ {
565+ int i ;
566+ struct is31fl32xx_priv * priv = i2c_get_clientdata (client );
567+
568+ for (i = 0 ; i < priv -> num_leds ; i ++ ) {
569+ struct is31fl32xx_led_data * led_data =
570+ & priv -> leds [i ];
571+ cancel_delayed_work_sync (& led_data -> register_work );
572+ cancel_work_sync (& led_data -> brightness_work );
573+ }
574+
575+ is31fl32xx_reset_regs (priv );
576+ gpiod_set_value (priv -> reset_gpio , 0 );
577+ }
578+
523579/*
524580 * i2c-core (and modalias) requires that id_table be properly filled,
525581 * even though it is not used for DeviceTree based instantiation.
@@ -543,6 +599,7 @@ static struct i2c_driver is31fl32xx_driver = {
543599 },
544600 .probe = is31fl32xx_probe ,
545601 .remove = is31fl32xx_remove ,
602+ .shutdown = is31fl32xx_shutdown ,
546603 .id_table = is31fl32xx_id ,
547604};
548605
0 commit comments