summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/leds/index.rst1
-rw-r--r--Documentation/leds/leds-cht-wcove.rst38
-rw-r--r--drivers/leds/leds-cht-wcove.c42
3 files changed, 77 insertions, 4 deletions
diff --git a/Documentation/leds/index.rst b/Documentation/leds/index.rst
index ce57254cb871..3ade16c18328 100644
--- a/Documentation/leds/index.rst
+++ b/Documentation/leds/index.rst
@@ -17,6 +17,7 @@ LEDs
uleds
leds-blinkm
+ leds-cht-wcove
leds-el15203000
leds-lm3556
leds-lp3944
diff --git a/Documentation/leds/leds-cht-wcove.rst b/Documentation/leds/leds-cht-wcove.rst
new file mode 100644
index 000000000000..5ec7cb60c4aa
--- /dev/null
+++ b/Documentation/leds/leds-cht-wcove.rst
@@ -0,0 +1,38 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===========================================================
+Kernel driver for Intel Cherry Trail Whiskey Cove PMIC LEDs
+===========================================================
+
+/sys/class/leds/<led>/hw_pattern
+--------------------------------
+
+Specify a hardware pattern for the Whiskey Cove PMIC LEDs.
+
+The only supported pattern is hardware breathing mode::
+
+ "0 2000 1 2000"
+
+ ^
+ |
+ Max-| ---
+ | / \
+ | / \
+ | / \ /
+ | / \ /
+ Min-|- ---
+ |
+ 0------2------4--> time (sec)
+
+The rise and fall times must be the same value.
+Supported values are 2000, 1000, 500 and 250 for
+breathing frequencies of 1/4, 1/2, 1 and 2 Hz.
+
+The set pattern only controls the timing. For max brightness the last
+set brightness is used and the max brightness can be changed
+while breathing by writing the brightness attribute.
+
+This is just like how blinking works in the LED subsystem,
+for both sw and hw blinking the brightness can also be changed
+while blinking. Breathing on this hw really is just a variant
+mode of blinking.
diff --git a/drivers/leds/leds-cht-wcove.c b/drivers/leds/leds-cht-wcove.c
index 166b140e132a..36fb4c2c3c13 100644
--- a/drivers/leds/leds-cht-wcove.c
+++ b/drivers/leds/leds-cht-wcove.c
@@ -217,9 +217,10 @@ static int cht_wc_leds_find_freq(unsigned long period)
return -1;
}
-static int cht_wc_leds_blink_set(struct led_classdev *cdev,
- unsigned long *delay_on,
- unsigned long *delay_off)
+static int cht_wc_leds_set_effect(struct led_classdev *cdev,
+ unsigned long *delay_on,
+ unsigned long *delay_off,
+ u8 effect)
{
struct cht_wc_led *led = container_of(cdev, struct cht_wc_led, cdev);
unsigned int ctrl;
@@ -246,7 +247,7 @@ static int cht_wc_leds_blink_set(struct led_classdev *cdev,
}
ret = regmap_update_bits(led->regmap, led->regs->fsm,
- CHT_WC_LED_EFF_MASK, CHT_WC_LED_EFF_BLINKING);
+ CHT_WC_LED_EFF_MASK, effect);
if (ret < 0)
dev_err(cdev->dev, "Failed to update LED FSM reg: %d\n", ret);
@@ -265,6 +266,37 @@ done:
return ret;
}
+static int cht_wc_leds_blink_set(struct led_classdev *cdev,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ return cht_wc_leds_set_effect(cdev, delay_on, delay_off, CHT_WC_LED_EFF_BLINKING);
+}
+
+static int cht_wc_leds_pattern_set(struct led_classdev *cdev,
+ struct led_pattern *pattern,
+ u32 len, int repeat)
+{
+ unsigned long delay_off, delay_on;
+
+ if (repeat > 0 || len != 2 ||
+ pattern[0].brightness != 0 || pattern[1].brightness != 1 ||
+ pattern[0].delta_t != pattern[1].delta_t ||
+ (pattern[0].delta_t != 250 && pattern[0].delta_t != 500 &&
+ pattern[0].delta_t != 1000 && pattern[0].delta_t != 2000))
+ return -EINVAL;
+
+ delay_off = pattern[0].delta_t;
+ delay_on = pattern[1].delta_t;
+
+ return cht_wc_leds_set_effect(cdev, &delay_on, &delay_off, CHT_WC_LED_EFF_BREATHING);
+}
+
+static int cht_wc_leds_pattern_clear(struct led_classdev *cdev)
+{
+ return cht_wc_leds_brightness_set(cdev, 0);
+}
+
static int cht_wc_led_save_regs(struct cht_wc_led *led,
struct cht_wc_led_saved_regs *saved_regs)
{
@@ -329,6 +361,8 @@ static int cht_wc_leds_probe(struct platform_device *pdev)
led->cdev.brightness_set_blocking = cht_wc_leds_brightness_set;
led->cdev.brightness_get = cht_wc_leds_brightness_get;
led->cdev.blink_set = cht_wc_leds_blink_set;
+ led->cdev.pattern_set = cht_wc_leds_pattern_set;
+ led->cdev.pattern_clear = cht_wc_leds_pattern_clear;
led->cdev.max_brightness = 255;
ret = led_classdev_register(&pdev->dev, &led->cdev);