diff options
Diffstat (limited to 'drivers/leds/leds-bd2802.c')
| -rw-r--r-- | drivers/leds/leds-bd2802.c | 87 |
1 files changed, 37 insertions, 50 deletions
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c index 2db04231a792..2a08c5f27608 100644 --- a/drivers/leds/leds-bd2802.c +++ b/drivers/leds/leds-bd2802.c @@ -1,20 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * leds-bd2802.c - RGB LED Driver * * Copyright (C) 2009 Samsung Electronics * Kim Kyuwon <q1.kim@samsung.com> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * * Datasheet: http://www.rohm.com/products/databook/driver/pdf/bd2802gu-e.pdf - * */ #include <linux/module.h> #include <linux/i2c.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include <linux/leds.h> #include <linux/leds-bd2802.h> @@ -71,8 +67,8 @@ struct led_state { struct bd2802_led { struct bd2802_led_platform_data *pdata; struct i2c_client *client; + struct gpio_desc *reset; struct rw_semaphore rwsem; - struct work_struct work; struct led_state led[2]; @@ -205,7 +201,7 @@ static void bd2802_update_state(struct bd2802_led *led, enum led_ids id, return; if (bd2802_is_all_off(led) && !led->adf_on) { - gpio_set_value(led->pdata->reset_gpio, 0); + gpiod_set_value(led->reset, 1); return; } @@ -231,7 +227,7 @@ static void bd2802_configure(struct bd2802_led *led) static void bd2802_reset_cancel(struct bd2802_led *led) { - gpio_set_value(led->pdata->reset_gpio, 1); + gpiod_set_value(led->reset, 0); udelay(100); bd2802_configure(led); } @@ -425,7 +421,7 @@ static void bd2802_disable_adv_conf(struct bd2802_led *led) bd2802_addr_attributes[i]); if (bd2802_is_all_off(led)) - gpio_set_value(led->pdata->reset_gpio, 0); + gpiod_set_value(led->reset, 1); led->adf_on = 0; } @@ -518,29 +514,22 @@ static struct device_attribute *bd2802_attributes[] = { &bd2802_rgb_current_attr, }; -static void bd2802_led_work(struct work_struct *work) -{ - struct bd2802_led *led = container_of(work, struct bd2802_led, work); - - if (led->state) - bd2802_turn_on(led, led->led_id, led->color, led->state); - else - bd2802_turn_off(led, led->led_id, led->color); -} - #define BD2802_CONTROL_RGBS(name, id, clr) \ -static void bd2802_set_##name##_brightness(struct led_classdev *led_cdev,\ +static int bd2802_set_##name##_brightness(struct led_classdev *led_cdev,\ enum led_brightness value) \ { \ struct bd2802_led *led = \ container_of(led_cdev, struct bd2802_led, cdev_##name); \ led->led_id = id; \ led->color = clr; \ - if (value == LED_OFF) \ + if (value == LED_OFF) { \ led->state = BD2802_OFF; \ - else \ + bd2802_turn_off(led, led->led_id, led->color); \ + } else { \ led->state = BD2802_ON; \ - schedule_work(&led->work); \ + bd2802_turn_on(led, led->led_id, led->color, BD2802_ON);\ + } \ + return 0; \ } \ static int bd2802_set_##name##_blink(struct led_classdev *led_cdev, \ unsigned long *delay_on, unsigned long *delay_off) \ @@ -552,7 +541,7 @@ static int bd2802_set_##name##_blink(struct led_classdev *led_cdev, \ led->led_id = id; \ led->color = clr; \ led->state = BD2802_BLINK; \ - schedule_work(&led->work); \ + bd2802_turn_on(led, led->led_id, led->color, BD2802_BLINK); \ return 0; \ } @@ -567,11 +556,9 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) { int ret; - INIT_WORK(&led->work, bd2802_led_work); - led->cdev_led1r.name = "led1_R"; led->cdev_led1r.brightness = LED_OFF; - led->cdev_led1r.brightness_set = bd2802_set_led1r_brightness; + led->cdev_led1r.brightness_set_blocking = bd2802_set_led1r_brightness; led->cdev_led1r.blink_set = bd2802_set_led1r_blink; ret = led_classdev_register(&led->client->dev, &led->cdev_led1r); @@ -583,7 +570,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led1g.name = "led1_G"; led->cdev_led1g.brightness = LED_OFF; - led->cdev_led1g.brightness_set = bd2802_set_led1g_brightness; + led->cdev_led1g.brightness_set_blocking = bd2802_set_led1g_brightness; led->cdev_led1g.blink_set = bd2802_set_led1g_blink; ret = led_classdev_register(&led->client->dev, &led->cdev_led1g); @@ -595,7 +582,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led1b.name = "led1_B"; led->cdev_led1b.brightness = LED_OFF; - led->cdev_led1b.brightness_set = bd2802_set_led1b_brightness; + led->cdev_led1b.brightness_set_blocking = bd2802_set_led1b_brightness; led->cdev_led1b.blink_set = bd2802_set_led1b_blink; ret = led_classdev_register(&led->client->dev, &led->cdev_led1b); @@ -607,7 +594,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led2r.name = "led2_R"; led->cdev_led2r.brightness = LED_OFF; - led->cdev_led2r.brightness_set = bd2802_set_led2r_brightness; + led->cdev_led2r.brightness_set_blocking = bd2802_set_led2r_brightness; led->cdev_led2r.blink_set = bd2802_set_led2r_blink; ret = led_classdev_register(&led->client->dev, &led->cdev_led2r); @@ -619,7 +606,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led2g.name = "led2_G"; led->cdev_led2g.brightness = LED_OFF; - led->cdev_led2g.brightness_set = bd2802_set_led2g_brightness; + led->cdev_led2g.brightness_set_blocking = bd2802_set_led2g_brightness; led->cdev_led2g.blink_set = bd2802_set_led2g_blink; ret = led_classdev_register(&led->client->dev, &led->cdev_led2g); @@ -631,7 +618,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led2b.name = "led2_B"; led->cdev_led2b.brightness = LED_OFF; - led->cdev_led2b.brightness_set = bd2802_set_led2b_brightness; + led->cdev_led2b.brightness_set_blocking = bd2802_set_led2b_brightness; led->cdev_led2b.blink_set = bd2802_set_led2b_blink; led->cdev_led2b.flags |= LED_CORE_SUSPENDRESUME; @@ -661,7 +648,6 @@ failed_unregister_led1_R: static void bd2802_unregister_led_classdev(struct bd2802_led *led) { - cancel_work_sync(&led->work); led_classdev_unregister(&led->cdev_led2b); led_classdev_unregister(&led->cdev_led2g); led_classdev_unregister(&led->cdev_led2r); @@ -670,25 +656,28 @@ static void bd2802_unregister_led_classdev(struct bd2802_led *led) led_classdev_unregister(&led->cdev_led1r); } -static int bd2802_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bd2802_probe(struct i2c_client *client) { struct bd2802_led *led; - struct bd2802_led_platform_data *pdata; int ret, i; led = devm_kzalloc(&client->dev, sizeof(struct bd2802_led), GFP_KERNEL); - if (!led) { - dev_err(&client->dev, "failed to allocate driver data\n"); + if (!led) return -ENOMEM; - } led->client = client; - pdata = led->pdata = client->dev.platform_data; i2c_set_clientdata(client, led); - /* Configure RESET GPIO (L: RESET, H: RESET cancel) */ - gpio_request_one(pdata->reset_gpio, GPIOF_OUT_INIT_HIGH, "RGB_RESETB"); + /* + * Configure RESET GPIO (L: RESET, H: RESET cancel) + * + * We request the reset GPIO as OUT_LOW which means de-asserted, + * board files specifying this GPIO line in a machine descriptor + * table should take care to specify GPIO_ACTIVE_LOW for this line. + */ + led->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(led->reset)) + return PTR_ERR(led->reset); /* Tacss = min 0.1ms */ udelay(100); @@ -702,7 +691,7 @@ static int bd2802_probe(struct i2c_client *client, dev_info(&client->dev, "return 0x%02x\n", ret); /* To save the power, reset BD2802 after detecting */ - gpio_set_value(led->pdata->reset_gpio, 0); + gpiod_set_value(led->reset, 1); /* Default attributes */ led->wave_pattern = BD2802_PATTERN_HALF; @@ -732,19 +721,17 @@ failed_unregister_dev_file: return ret; } -static int bd2802_remove(struct i2c_client *client) +static void bd2802_remove(struct i2c_client *client) { struct bd2802_led *led = i2c_get_clientdata(client); int i; - gpio_set_value(led->pdata->reset_gpio, 0); + gpiod_set_value(led->reset, 1); bd2802_unregister_led_classdev(led); if (led->adf_on) bd2802_disable_adv_conf(led); for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) device_remove_file(&led->client->dev, bd2802_attributes[i]); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -767,7 +754,7 @@ static int bd2802_suspend(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct bd2802_led *led = i2c_get_clientdata(client); - gpio_set_value(led->pdata->reset_gpio, 0); + gpiod_set_value(led->reset, 1); return 0; } @@ -789,7 +776,7 @@ static int bd2802_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(bd2802_pm, bd2802_suspend, bd2802_resume); static const struct i2c_device_id bd2802_id[] = { - { "BD2802", 0 }, + { "BD2802" }, { } }; MODULE_DEVICE_TABLE(i2c, bd2802_id); |
