diff --git a/Documentation/devicetree/bindings/leds/common.yaml b/Documentation/devicetree/bindings/leds/common.yaml index 328952d7acbb..3c14a98430e1 100644 --- a/Documentation/devicetree/bindings/leds/common.yaml +++ b/Documentation/devicetree/bindings/leds/common.yaml @@ -79,24 +79,27 @@ properties: the LED. $ref: /schemas/types.yaml#/definitions/string - enum: - # LED will act as a back-light, controlled by the framebuffer system - - backlight - # LED will turn on (but for leds-gpio see "default-state" property in - # Documentation/devicetree/bindings/leds/leds-gpio.yaml) - - default-on - # LED "double" flashes at a load average based rate - - heartbeat - # LED indicates disk activity - - disk-activity - # LED indicates IDE disk activity (deprecated), in new implementations - # use "disk-activity" - - ide-disk - # LED flashes at a fixed, configurable rate - - timer - # LED alters the brightness for the specified duration with one software - # timer (requires "led-pattern" property) - - pattern + oneOf: + - enum: + # LED will act as a back-light, controlled by the framebuffer system + - backlight + # LED will turn on (but for leds-gpio see "default-state" property in + # Documentation/devicetree/bindings/leds/leds-gpio.yaml) + - default-on + # LED "double" flashes at a load average based rate + - heartbeat + # LED indicates disk activity + - disk-activity + # LED indicates IDE disk activity (deprecated), in new implementations + # use "disk-activity" + - ide-disk + # LED flashes at a fixed, configurable rate + - timer + # LED alters the brightness for the specified duration with one software + # timer (requires "led-pattern" property) + - pattern + # LED is triggered by SD/MMC activity + - pattern: "^mmc[0-9]+$" led-pattern: description: | diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c index 00aecd67e348..a7e052c1db53 100644 --- a/drivers/leds/leds-pca963x.c +++ b/drivers/leds/leds-pca963x.c @@ -101,6 +101,7 @@ struct pca963x_led { struct pca963x *chip; struct led_classdev led_cdev; int led_num; /* 0 .. 15 potentially */ + bool blinking; u8 gdc; u8 gfrq; }; @@ -129,12 +130,21 @@ static int pca963x_brightness(struct pca963x_led *led, switch (brightness) { case LED_FULL: - val = (ledout & ~mask) | (PCA963X_LED_ON << shift); + if (led->blinking) { + val = (ledout & ~mask) | (PCA963X_LED_GRP_PWM << shift); + ret = i2c_smbus_write_byte_data(client, + PCA963X_PWM_BASE + + led->led_num, + LED_FULL); + } else { + val = (ledout & ~mask) | (PCA963X_LED_ON << shift); + } ret = i2c_smbus_write_byte_data(client, ledout_addr, val); break; case LED_OFF: val = ledout & ~mask; ret = i2c_smbus_write_byte_data(client, ledout_addr, val); + led->blinking = false; break; default: ret = i2c_smbus_write_byte_data(client, @@ -144,7 +154,11 @@ static int pca963x_brightness(struct pca963x_led *led, if (ret < 0) return ret; - val = (ledout & ~mask) | (PCA963X_LED_PWM << shift); + if (led->blinking) + val = (ledout & ~mask) | (PCA963X_LED_GRP_PWM << shift); + else + val = (ledout & ~mask) | (PCA963X_LED_PWM << shift); + ret = i2c_smbus_write_byte_data(client, ledout_addr, val); break; } @@ -181,6 +195,7 @@ static void pca963x_blink(struct pca963x_led *led) } mutex_unlock(&led->chip->mutex); + led->blinking = true; } static int pca963x_power_state(struct pca963x_led *led) @@ -275,6 +290,8 @@ static int pca963x_blink_set(struct led_classdev *led_cdev, led->gfrq = gfrq; pca963x_blink(led); + led->led_cdev.brightness = LED_FULL; + pca963x_led_set(led_cdev, LED_FULL); *delay_on = time_on; *delay_off = time_off; @@ -337,6 +354,7 @@ static int pca963x_register_leds(struct i2c_client *client, led->led_cdev.brightness_set_blocking = pca963x_led_set; if (hw_blink) led->led_cdev.blink_set = pca963x_blink_set; + led->blinking = false; init_data.fwnode = child; /* for backwards compatibility */