Commit 1b85a5a5 authored by Álvaro Fernández Rojas's avatar Álvaro Fernández Rojas Committed by Jacek Anaszewski

leds: bcm6328: improve blink support

BCM6328 controller has a margin of 20ms per blink step, which means that
we can only set it to 20, 40, 60 ... 1260 ms (0x3f * 20ms).
However, when checking if delay_on == delay_off, we were not considering
the case when the user had set delay_on=20 and delay_off=21, since this
will cause the driver to fallback to software blinking.
This update fixes this issue and improves blink steps by rounding them
in a more sensible way. Now 30-49ms is rounded to 40 ms, and previous
behaviour implied 40-59ms being rounded to 40 ms.
Signed-off-by: default avatarÁlvaro Fernández Rojas <noltari@gmail.com>
Signed-off-by: default avatarJacek Anaszewski <j.anaszewski@samsung.com>
parent 6e636a0a
...@@ -140,6 +140,18 @@ static void bcm6328_led_set(struct led_classdev *led_cdev, ...@@ -140,6 +140,18 @@ static void bcm6328_led_set(struct led_classdev *led_cdev,
spin_unlock_irqrestore(led->lock, flags); spin_unlock_irqrestore(led->lock, flags);
} }
static unsigned long bcm6328_blink_delay(unsigned long delay)
{
unsigned long bcm6328_delay;
bcm6328_delay = delay + BCM6328_LED_INTERVAL_MS / 2;
bcm6328_delay = bcm6328_delay / BCM6328_LED_INTERVAL_MS;
if (bcm6328_delay == 0)
bcm6328_delay = 1;
return bcm6328_delay;
}
static int bcm6328_blink_set(struct led_classdev *led_cdev, static int bcm6328_blink_set(struct led_classdev *led_cdev,
unsigned long *delay_on, unsigned long *delay_off) unsigned long *delay_on, unsigned long *delay_off)
{ {
...@@ -153,16 +165,14 @@ static int bcm6328_blink_set(struct led_classdev *led_cdev, ...@@ -153,16 +165,14 @@ static int bcm6328_blink_set(struct led_classdev *led_cdev,
if (!*delay_off) if (!*delay_off)
*delay_off = BCM6328_LED_DEF_DELAY; *delay_off = BCM6328_LED_DEF_DELAY;
if (*delay_on != *delay_off) { delay = bcm6328_blink_delay(*delay_on);
if (delay != bcm6328_blink_delay(*delay_off)) {
dev_dbg(led_cdev->dev, dev_dbg(led_cdev->dev,
"fallback to soft blinking (delay_on != delay_off)\n"); "fallback to soft blinking (delay_on != delay_off)\n");
return -EINVAL; return -EINVAL;
} }
delay = *delay_on / BCM6328_LED_INTERVAL_MS; if (delay > BCM6328_LED_INTV_MASK) {
if (delay == 0) {
delay = 1;
} else if (delay > BCM6328_LED_INTV_MASK) {
dev_dbg(led_cdev->dev, dev_dbg(led_cdev->dev,
"fallback to soft blinking (delay > %ums)\n", "fallback to soft blinking (delay > %ums)\n",
BCM6328_LED_INTV_MASK * BCM6328_LED_INTERVAL_MS); BCM6328_LED_INTV_MASK * BCM6328_LED_INTERVAL_MS);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment