summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-07-23 15:39:41 +0100
committerMark Brown <broonie@kernel.org>2026-07-23 15:39:41 +0100
commit579854af20cddf9bba6821581c860c97d53baee8 (patch)
treeb6c349de6576e820e78ba52fbb2114448083a67b /drivers
parentc56ae52ce2170e128cf8903feb63b4fb93d0fa3d (diff)
parent96fa4d69958cf90740d756d1e45cdb02cface41b (diff)
downloadlinux-next-579854af20cddf9bba6821581c860c97d53baee8.tar.gz
linux-next-579854af20cddf9bba6821581c860c97d53baee8.zip
Merge branch 'for-leds-next' of https://git.kernel.org/pub/scm/linux/kernel/git/lee/leds.git
Diffstat (limited to 'drivers')
-rw-r--r--drivers/leds/leds-pca9532.c6
-rw-r--r--drivers/leds/leds-st1202.c102
-rw-r--r--drivers/leds/rgb/leds-lp5860-core.c3
-rw-r--r--drivers/leds/rgb/leds-lp5860-spi.c10
-rw-r--r--drivers/leds/rgb/leds-pwm-multicolor.c2
-rw-r--r--drivers/leds/trigger/ledtrig-netdev.c46
6 files changed, 119 insertions, 50 deletions
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index f3bf59495b68..2d37e00e459d 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -327,9 +327,9 @@ static int pca9532_gpio_set_value(struct gpio_chip *gc, unsigned int offset,
struct pca9532_led *led = &data->leds[offset];
if (val)
- led->state = PCA9532_ON;
- else
led->state = PCA9532_OFF;
+ else
+ led->state = PCA9532_ON;
pca9532_setled(led);
@@ -349,7 +349,7 @@ static int pca9532_gpio_get_value(struct gpio_chip *gc, unsigned offset)
static int pca9532_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
{
/* To use as input ensure pin is not driven */
- pca9532_gpio_set_value(gc, offset, 0);
+ pca9532_gpio_set_value(gc, offset, 1);
return 0;
}
diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c
index 7f68d956f694..168df5ecf27b 100644
--- a/drivers/leds/leds-st1202.c
+++ b/drivers/leds/leds-st1202.c
@@ -31,10 +31,11 @@
#define ST1202_ILED_REG0 0x09
#define ST1202_MAX_LEDS 12
#define ST1202_MAX_PATTERNS 8
-#define ST1202_MILLIS_PATTERN_DUR_MAX 5660
+#define ST1202_MILLIS_PATTERN_DUR_MAX (ST1202_MILLIS_PATTERN_DUR_MIN * U8_MAX)
#define ST1202_MILLIS_PATTERN_DUR_MIN 22
#define ST1202_PATTERN_DUR 0x16
#define ST1202_PATTERN_PWM 0x1E
+#define ST1202_PATTERN_PWM_FULL 0x0FFF
#define ST1202_PATTERN_REP 0x15
struct st1202_led {
@@ -85,7 +86,7 @@ static int st1202_write_reg(struct st1202_chip *chip, int reg, uint8_t val)
static uint8_t st1202_prescalar_to_miliseconds(unsigned int value)
{
- return value / ST1202_MILLIS_PATTERN_DUR_MIN - 1;
+ return value / ST1202_MILLIS_PATTERN_DUR_MIN;
}
static int st1202_pwm_pattern_write(struct st1202_chip *chip, int led_num,
@@ -127,37 +128,11 @@ static int st1202_duration_pattern_write(struct st1202_chip *chip, int pattern,
st1202_prescalar_to_miliseconds(value));
}
-static void st1202_brightness_set(struct led_classdev *led_cdev,
- enum led_brightness value)
-{
- struct st1202_led *led = cdev_to_st1202_led(led_cdev);
- struct st1202_chip *chip = led->chip;
-
- guard(mutex)(&chip->lock);
-
- st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, value);
-}
-
-static enum led_brightness st1202_brightness_get(struct led_classdev *led_cdev)
-{
- struct st1202_led *led = cdev_to_st1202_led(led_cdev);
- struct st1202_chip *chip = led->chip;
- u8 value = 0;
-
- guard(mutex)(&chip->lock);
-
- st1202_read_reg(chip, ST1202_ILED_REG0 + led->led_num, &value);
-
- return value;
-}
-
-static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active)
+static int __st1202_channel_set(struct st1202_chip *chip, int led_num, bool active)
{
u8 chan_low, chan_high;
int ret;
- guard(mutex)(&chip->lock);
-
if (led_num <= 7) {
ret = st1202_read_reg(chip, ST1202_CHAN_ENABLE_LOW, &chan_low);
if (ret < 0)
@@ -185,6 +160,40 @@ static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active
return 0;
}
+static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active)
+{
+ guard(mutex)(&chip->lock);
+
+ return __st1202_channel_set(chip, led_num, active);
+}
+
+static void st1202_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ struct st1202_led *led = cdev_to_st1202_led(led_cdev);
+ struct st1202_chip *chip = led->chip;
+
+ guard(mutex)(&chip->lock);
+
+ for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++)
+ st1202_pwm_pattern_write(chip, led->led_num, patt, ST1202_PATTERN_PWM_FULL);
+ st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, value);
+ __st1202_channel_set(chip, led->led_num, !!value);
+}
+
+static enum led_brightness st1202_brightness_get(struct led_classdev *led_cdev)
+{
+ struct st1202_led *led = cdev_to_st1202_led(led_cdev);
+ struct st1202_chip *chip = led->chip;
+ u8 value = 0;
+
+ guard(mutex)(&chip->lock);
+
+ st1202_read_reg(chip, ST1202_ILED_REG0 + led->led_num, &value);
+
+ return value;
+}
+
static int st1202_led_set(struct led_classdev *ldev, enum led_brightness value)
{
struct st1202_led *led = cdev_to_st1202_led(ldev);
@@ -200,12 +209,16 @@ static int st1202_led_pattern_clear(struct led_classdev *ldev)
guard(mutex)(&chip->lock);
+ ret = st1202_write_reg(chip, ST1202_CONFIG_REG, ST1202_CONFIG_REG_SHFT);
+ if (ret != 0)
+ return ret;
+
for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++) {
- ret = st1202_pwm_pattern_write(chip, led->led_num, patt, LED_OFF);
+ ret = st1202_pwm_pattern_write(chip, led->led_num, patt, ST1202_PATTERN_PWM_FULL);
if (ret != 0)
return ret;
- ret = st1202_duration_pattern_write(chip, patt, ST1202_MILLIS_PATTERN_DUR_MIN);
+ ret = st1202_write_reg(chip, ST1202_PATTERN_DUR + patt, 0);
if (ret != 0)
return ret;
}
@@ -224,13 +237,19 @@ static int st1202_led_pattern_set(struct led_classdev *ldev,
if (len > ST1202_MAX_PATTERNS)
return -EINVAL;
- guard(mutex)(&chip->lock);
-
for (int patt = 0; patt < len; patt++) {
if (pattern[patt].delta_t < ST1202_MILLIS_PATTERN_DUR_MIN ||
pattern[patt].delta_t > ST1202_MILLIS_PATTERN_DUR_MAX)
return -EINVAL;
+ }
+ guard(mutex)(&chip->lock);
+
+ ret = st1202_write_reg(chip, ST1202_CONFIG_REG, ST1202_CONFIG_REG_SHFT);
+ if (ret != 0)
+ return ret;
+
+ for (int patt = 0; patt < len; patt++) {
ret = st1202_pwm_pattern_write(chip, led->led_num, patt, pattern[patt].brightness);
if (ret != 0)
return ret;
@@ -244,6 +263,10 @@ static int st1202_led_pattern_set(struct led_classdev *ldev,
if (ret != 0)
return ret;
+ ret = __st1202_channel_set(chip, led->led_num, true);
+ if (ret != 0)
+ return ret;
+
ret = st1202_write_reg(chip, ST1202_CONFIG_REG, (ST1202_CONFIG_REG_PATSR |
ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_SHFT));
if (ret != 0)
@@ -256,13 +279,19 @@ static int st1202_dt_init(struct st1202_chip *chip)
{
struct device *dev = &chip->client->dev;
struct st1202_led *led;
- int err, reg;
+ int err;
+ u32 reg;
for_each_available_child_of_node_scoped(dev_of_node(dev), child) {
err = of_property_read_u32(child, "reg", &reg);
if (err)
return dev_err_probe(dev, err, "Invalid register\n");
+ if (reg >= ST1202_MAX_LEDS)
+ return dev_err_probe(dev, -EINVAL,
+ "LED reg %u out of range [0, %d]\n",
+ reg, ST1202_MAX_LEDS - 1);
+
led = &chip->leds[reg];
led->is_active = true;
led->fwnode = of_fwnode_handle(child);
@@ -322,11 +351,6 @@ static int st1202_setup(struct st1202_chip *chip)
if (ret < 0)
return ret;
- ret = st1202_write_reg(chip, ST1202_CONFIG_REG,
- ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_PATSR);
- if (ret < 0)
- return ret;
-
return 0;
}
diff --git a/drivers/leds/rgb/leds-lp5860-core.c b/drivers/leds/rgb/leds-lp5860-core.c
index fd0e2f6e6e0f..e21d5f2302be 100644
--- a/drivers/leds/rgb/leds-lp5860-core.c
+++ b/drivers/leds/rgb/leds-lp5860-core.c
@@ -204,9 +204,9 @@ int lp5860_device_init(struct device *dev)
mutex_lock(&lp->lock);
ret = regmap_update_bits(lp->regmap, LP5860_REG_DEV_INITIAL, LP5860_MODE_MASK,
LP5860_MODE_1 << LP5860_MODE_SHIFT);
+ mutex_unlock(&lp->lock);
if (ret)
goto err_disable;
- mutex_unlock(&lp->lock);
ret = lp5860_init_dt(lp);
if (ret)
@@ -215,7 +215,6 @@ int lp5860_device_init(struct device *dev)
return 0;
err_disable:
- mutex_unlock(&lp->lock);
lp5860_chip_enable(lp, LP5860_CHIP_DISABLE);
return ret;
}
diff --git a/drivers/leds/rgb/leds-lp5860-spi.c b/drivers/leds/rgb/leds-lp5860-spi.c
index 5e0c44854a68..6bf6a625c28a 100644
--- a/drivers/leds/rgb/leds-lp5860-spi.c
+++ b/drivers/leds/rgb/leds-lp5860-spi.c
@@ -38,6 +38,7 @@ static int lp5860_probe(struct spi_device *spi)
struct device *dev = &spi->dev;
struct lp5860 *lp5860;
unsigned int multi_leds;
+ int ret;
multi_leds = device_get_child_node_count(dev);
if (!multi_leds) {
@@ -61,7 +62,10 @@ static int lp5860_probe(struct spi_device *spi)
"Failed to initialise Regmap.\n");
lp5860->dev = dev;
- mutex_init(&lp5860->lock);
+
+ ret = devm_mutex_init(dev, &lp5860->lock);
+ if (ret)
+ return ret;
spi_set_drvdata(spi, lp5860);
@@ -70,10 +74,6 @@ static int lp5860_probe(struct spi_device *spi)
static void lp5860_remove(struct spi_device *spi)
{
- struct lp5860 *lp5860 = spi_get_drvdata(spi);
-
- mutex_destroy(&lp5860->lock);
-
lp5860_device_remove(&spi->dev);
}
diff --git a/drivers/leds/rgb/leds-pwm-multicolor.c b/drivers/leds/rgb/leds-pwm-multicolor.c
index d5b303aab5d6..6365459ec27f 100644
--- a/drivers/leds/rgb/leds-pwm-multicolor.c
+++ b/drivers/leds/rgb/leds-pwm-multicolor.c
@@ -94,6 +94,8 @@ static int iterate_subleds(struct device *dev, struct pwm_mc_led *priv,
}
subled[priv->mc_cdev.num_colors].color_index = color;
+ fwnode_property_read_u32(fwnode, "default-intensity",
+ &subled[priv->mc_cdev.num_colors].intensity);
priv->mc_cdev.num_colors++;
}
diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
index 64c078e997f2..5b4e92c14dbb 100644
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -129,6 +129,22 @@ static void set_baseline_state(struct led_netdev_data *trigger_data)
trigger_data->link_speed == SPEED_10000)
blink_on = true;
+ if (test_bit(TRIGGER_NETDEV_LINK_25000, &trigger_data->mode) &&
+ trigger_data->link_speed == SPEED_25000)
+ blink_on = true;
+
+ if (test_bit(TRIGGER_NETDEV_LINK_40000, &trigger_data->mode) &&
+ trigger_data->link_speed == SPEED_40000)
+ blink_on = true;
+
+ if (test_bit(TRIGGER_NETDEV_LINK_50000, &trigger_data->mode) &&
+ trigger_data->link_speed == SPEED_50000)
+ blink_on = true;
+
+ if (test_bit(TRIGGER_NETDEV_LINK_100000, &trigger_data->mode) &&
+ trigger_data->link_speed == SPEED_100000)
+ blink_on = true;
+
if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) &&
trigger_data->duplex == DUPLEX_HALF)
blink_on = true;
@@ -342,6 +358,10 @@ static ssize_t netdev_led_attr_show(struct device *dev, char *buf,
case TRIGGER_NETDEV_LINK_2500:
case TRIGGER_NETDEV_LINK_5000:
case TRIGGER_NETDEV_LINK_10000:
+ case TRIGGER_NETDEV_LINK_25000:
+ case TRIGGER_NETDEV_LINK_40000:
+ case TRIGGER_NETDEV_LINK_50000:
+ case TRIGGER_NETDEV_LINK_100000:
case TRIGGER_NETDEV_HALF_DUPLEX:
case TRIGGER_NETDEV_FULL_DUPLEX:
case TRIGGER_NETDEV_TX:
@@ -378,6 +398,10 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
case TRIGGER_NETDEV_LINK_2500:
case TRIGGER_NETDEV_LINK_5000:
case TRIGGER_NETDEV_LINK_10000:
+ case TRIGGER_NETDEV_LINK_25000:
+ case TRIGGER_NETDEV_LINK_40000:
+ case TRIGGER_NETDEV_LINK_50000:
+ case TRIGGER_NETDEV_LINK_100000:
case TRIGGER_NETDEV_HALF_DUPLEX:
case TRIGGER_NETDEV_FULL_DUPLEX:
case TRIGGER_NETDEV_TX:
@@ -401,7 +425,11 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
test_bit(TRIGGER_NETDEV_LINK_1000, &mode) ||
test_bit(TRIGGER_NETDEV_LINK_2500, &mode) ||
test_bit(TRIGGER_NETDEV_LINK_5000, &mode) ||
- test_bit(TRIGGER_NETDEV_LINK_10000, &mode)))
+ test_bit(TRIGGER_NETDEV_LINK_10000, &mode) ||
+ test_bit(TRIGGER_NETDEV_LINK_25000, &mode) ||
+ test_bit(TRIGGER_NETDEV_LINK_40000, &mode) ||
+ test_bit(TRIGGER_NETDEV_LINK_50000, &mode) ||
+ test_bit(TRIGGER_NETDEV_LINK_100000, &mode)))
return -EINVAL;
cancel_delayed_work_sync(&trigger_data->work);
@@ -438,6 +466,10 @@ DEFINE_NETDEV_TRIGGER(link_1000, TRIGGER_NETDEV_LINK_1000);
DEFINE_NETDEV_TRIGGER(link_2500, TRIGGER_NETDEV_LINK_2500);
DEFINE_NETDEV_TRIGGER(link_5000, TRIGGER_NETDEV_LINK_5000);
DEFINE_NETDEV_TRIGGER(link_10000, TRIGGER_NETDEV_LINK_10000);
+DEFINE_NETDEV_TRIGGER(link_25000, TRIGGER_NETDEV_LINK_25000);
+DEFINE_NETDEV_TRIGGER(link_40000, TRIGGER_NETDEV_LINK_40000);
+DEFINE_NETDEV_TRIGGER(link_50000, TRIGGER_NETDEV_LINK_50000);
+DEFINE_NETDEV_TRIGGER(link_100000, TRIGGER_NETDEV_LINK_100000);
DEFINE_NETDEV_TRIGGER(half_duplex, TRIGGER_NETDEV_HALF_DUPLEX);
DEFINE_NETDEV_TRIGGER(full_duplex, TRIGGER_NETDEV_FULL_DUPLEX);
DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX);
@@ -526,6 +558,10 @@ static umode_t netdev_trig_link_speed_visible(struct kobject *kobj,
CHECK_LINK_MODE_ATTR(2500);
CHECK_LINK_MODE_ATTR(5000);
CHECK_LINK_MODE_ATTR(10000);
+ CHECK_LINK_MODE_ATTR(25000);
+ CHECK_LINK_MODE_ATTR(40000);
+ CHECK_LINK_MODE_ATTR(50000);
+ CHECK_LINK_MODE_ATTR(100000);
}
return 0;
@@ -538,6 +574,10 @@ static struct attribute *netdev_trig_link_speed_attrs[] = {
&dev_attr_link_2500.attr,
&dev_attr_link_5000.attr,
&dev_attr_link_10000.attr,
+ &dev_attr_link_25000.attr,
+ &dev_attr_link_40000.attr,
+ &dev_attr_link_50000.attr,
+ &dev_attr_link_100000.attr,
NULL
};
@@ -673,6 +713,10 @@ static void netdev_trig_work(struct work_struct *work)
test_bit(TRIGGER_NETDEV_LINK_2500, &trigger_data->mode) ||
test_bit(TRIGGER_NETDEV_LINK_5000, &trigger_data->mode) ||
test_bit(TRIGGER_NETDEV_LINK_10000, &trigger_data->mode) ||
+ test_bit(TRIGGER_NETDEV_LINK_25000, &trigger_data->mode) ||
+ test_bit(TRIGGER_NETDEV_LINK_40000, &trigger_data->mode) ||
+ test_bit(TRIGGER_NETDEV_LINK_50000, &trigger_data->mode) ||
+ test_bit(TRIGGER_NETDEV_LINK_100000, &trigger_data->mode) ||
test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) ||
test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &trigger_data->mode);
interval = jiffies_to_msecs(