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: Álvaro Fernández Rojas <noltari@gmail.com> Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
This commit is contained in:
parent
6e636a0a28
commit
1b85a5a5ef
|
@ -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,
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue