summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/leds/leds-max77705.c3
-rw-r--r--drivers/leds/leds-st1202.c89
2 files changed, 90 insertions, 2 deletions
diff --git a/drivers/leds/leds-max77705.c b/drivers/leds/leds-max77705.c
index 1e2054c1bf80..4fd803c95989 100644
--- a/drivers/leds/leds-max77705.c
+++ b/drivers/leds/leds-max77705.c
@@ -160,7 +160,6 @@ static int max77705_add_led(struct device *dev, struct regmap *regmap, struct fw
struct max77705_led *led;
struct led_classdev *cdev;
struct mc_subled *info;
- struct fwnode_handle *child;
struct led_init_data init_data = {};
led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
@@ -191,7 +190,7 @@ static int max77705_add_led(struct device *dev, struct regmap *regmap, struct fw
cdev->brightness_set_blocking = max77705_led_brightness_set_multi;
cdev->blink_set = max77705_rgb_blink;
- fwnode_for_each_child_node(np, child) {
+ fwnode_for_each_child_node_scoped(np, child) {
ret = max77705_parse_subled(dev, child, &info[i]);
if (ret < 0)
return ret;
diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c
index 168df5ecf27b..ead144155849 100644
--- a/drivers/leds/leds-st1202.c
+++ b/drivers/leds/leds-st1202.c
@@ -15,6 +15,7 @@
#include <linux/slab.h>
#include <linux/string.h>
+#define ST1202_BLINK_DEFAULT_DELAY 500
#define ST1202_CHAN_DISABLE_ALL 0x00
#define ST1202_CHAN_ENABLE_HIGH 0x03
#define ST1202_CHAN_ENABLE_LOW 0x02
@@ -275,6 +276,93 @@ static int st1202_led_pattern_set(struct led_classdev *ldev,
return 0;
}
+static int st1202_blink_set(struct led_classdev *led_cdev,
+ unsigned long *delay_on, unsigned long *delay_off)
+{
+ struct st1202_led *led = cdev_to_st1202_led(led_cdev);
+ struct st1202_chip *chip = led->chip;
+ unsigned long on, off;
+ int ret;
+
+ if (!*delay_on)
+ *delay_on = ST1202_BLINK_DEFAULT_DELAY;
+ if (!*delay_off)
+ *delay_off = ST1202_BLINK_DEFAULT_DELAY;
+
+ on = *delay_on;
+ off = *delay_off;
+
+ on = clamp_val(on, ST1202_MILLIS_PATTERN_DUR_MIN, ST1202_MILLIS_PATTERN_DUR_MAX);
+ off = clamp_val(off, ST1202_MILLIS_PATTERN_DUR_MIN, ST1202_MILLIS_PATTERN_DUR_MAX);
+ on = roundup(on, ST1202_MILLIS_PATTERN_DUR_MIN);
+ off = roundup(off, ST1202_MILLIS_PATTERN_DUR_MIN);
+
+ guard(mutex)(&chip->lock);
+
+ ret = st1202_write_reg(chip, ST1202_CONFIG_REG, ST1202_CONFIG_REG_SHFT);
+ if (ret)
+ return ret;
+
+ /* Zero out PWM for all other active channels to prevent them from blinking */
+ for (int chan = 0; chan < ST1202_MAX_LEDS; chan++) {
+ if (!chip->leds[chan].is_active || chan == led->led_num)
+ continue;
+
+ ret = st1202_pwm_pattern_write(chip, chan, 0, LED_OFF);
+ if (ret)
+ return ret;
+
+ ret = st1202_pwm_pattern_write(chip, chan, 1, LED_OFF);
+ if (ret)
+ return ret;
+ }
+
+ ret = st1202_pwm_pattern_write(chip, led->led_num, 0, ST1202_PATTERN_PWM_FULL);
+ if (ret)
+ return ret;
+
+ ret = st1202_pwm_pattern_write(chip, led->led_num, 1, LED_OFF);
+ if (ret)
+ return ret;
+
+ ret = st1202_duration_pattern_write(chip, 0, on);
+ if (ret)
+ return ret;
+
+ ret = st1202_duration_pattern_write(chip, 1, off);
+ if (ret)
+ return ret;
+
+ for (int pattern = 2; pattern < ST1202_MAX_PATTERNS; pattern++) {
+ ret = st1202_write_reg(chip, ST1202_PATTERN_DUR + pattern, 0);
+ if (ret)
+ return ret;
+ }
+
+ ret = st1202_write_reg(chip, ST1202_PATTERN_REP, U8_MAX);
+ if (ret)
+ return ret;
+
+ ret = st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, U8_MAX);
+ if (ret)
+ return ret;
+
+ ret = __st1202_channel_set(chip, led->led_num, true);
+ if (ret)
+ return ret;
+
+ ret = st1202_write_reg(chip, ST1202_CONFIG_REG,
+ ST1202_CONFIG_REG_PATSR | ST1202_CONFIG_REG_PATS |
+ ST1202_CONFIG_REG_SHFT);
+ if (ret)
+ return ret;
+
+ *delay_on = on;
+ *delay_off = off;
+
+ return 0;
+}
+
static int st1202_dt_init(struct st1202_chip *chip)
{
struct device *dev = &chip->client->dev;
@@ -301,6 +389,7 @@ static int st1202_dt_init(struct st1202_chip *chip)
led->led_cdev.pattern_set = st1202_led_pattern_set;
led->led_cdev.pattern_clear = st1202_led_pattern_clear;
led->led_cdev.default_trigger = "pattern";
+ led->led_cdev.blink_set = st1202_blink_set;
led->led_cdev.brightness_set = st1202_brightness_set;
led->led_cdev.brightness_get = st1202_brightness_get;
}