summaryrefslogtreecommitdiff
path: root/drivers/leds/leds-bd2802.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds/leds-bd2802.c')
-rw-r--r--drivers/leds/leds-bd2802.c87
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);