Commit 35c7d301 authored by Matt Ranostay's avatar Matt Ranostay Committed by Jacek Anaszewski

leds: pca963x: workaround group blink scaling issue

PCA9632TK part seems to incorrectly blink at ~1.3x of the programmed
rate. This patchset add a nxp,period-scale devicetree property to
adjust for this misconfiguration.
Signed-off-by: default avatarMatt Ranostay <matt@ranostay.consulting>
Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: default avatarJacek Anaszewski <j.anaszewski@samsung.com>
parent ed25e9ca
...@@ -7,6 +7,9 @@ Optional properties: ...@@ -7,6 +7,9 @@ Optional properties:
- nxp,totem-pole : use totem pole (push-pull) instead of open-drain (pca9632 defaults - nxp,totem-pole : use totem pole (push-pull) instead of open-drain (pca9632 defaults
to open-drain, newer chips to totem pole) to open-drain, newer chips to totem pole)
- nxp,hw-blink : use hardware blinking instead of software blinking - nxp,hw-blink : use hardware blinking instead of software blinking
- nxp,period-scale : In some configurations, the chip blinks faster than expected.
This parameter provides a scaling ratio (fixed point, decimal divided
by 1000) to compensate, e.g. 1300=1.3x and 750=0.75x.
Each led is represented as a sub-node of the nxp,pca963x device. Each led is represented as a sub-node of the nxp,pca963x device.
......
...@@ -59,6 +59,7 @@ struct pca963x_chipdef { ...@@ -59,6 +59,7 @@ struct pca963x_chipdef {
u8 grpfreq; u8 grpfreq;
u8 ledout_base; u8 ledout_base;
int n_leds; int n_leds;
unsigned int scaling;
}; };
static struct pca963x_chipdef pca963x_chipdefs[] = { static struct pca963x_chipdef pca963x_chipdefs[] = {
...@@ -189,6 +190,14 @@ static int pca963x_led_set(struct led_classdev *led_cdev, ...@@ -189,6 +190,14 @@ static int pca963x_led_set(struct led_classdev *led_cdev,
return pca963x_brightness(pca963x, value); return pca963x_brightness(pca963x, value);
} }
static unsigned int pca963x_period_scale(struct pca963x_led *pca963x,
unsigned int val)
{
unsigned int scaling = pca963x->chip->chipdef->scaling;
return scaling ? DIV_ROUND_CLOSEST(val * scaling, 1000) : val;
}
static int pca963x_blink_set(struct led_classdev *led_cdev, static int pca963x_blink_set(struct led_classdev *led_cdev,
unsigned long *delay_on, unsigned long *delay_off) unsigned long *delay_on, unsigned long *delay_off)
{ {
...@@ -207,14 +216,14 @@ static int pca963x_blink_set(struct led_classdev *led_cdev, ...@@ -207,14 +216,14 @@ static int pca963x_blink_set(struct led_classdev *led_cdev,
time_off = 500; time_off = 500;
} }
period = time_on + time_off; period = pca963x_period_scale(pca963x, time_on + time_off);
/* If period not supported by hardware, default to someting sane. */ /* If period not supported by hardware, default to someting sane. */
if ((period < PCA963X_BLINK_PERIOD_MIN) || if ((period < PCA963X_BLINK_PERIOD_MIN) ||
(period > PCA963X_BLINK_PERIOD_MAX)) { (period > PCA963X_BLINK_PERIOD_MAX)) {
time_on = 500; time_on = 500;
time_off = 500; time_off = 500;
period = time_on + time_off; period = pca963x_period_scale(pca963x, 1000);
} }
/* /*
...@@ -222,7 +231,7 @@ static int pca963x_blink_set(struct led_classdev *led_cdev, ...@@ -222,7 +231,7 @@ static int pca963x_blink_set(struct led_classdev *led_cdev,
* (time_on / period) = (GDC / 256) -> * (time_on / period) = (GDC / 256) ->
* GDC = ((time_on * 256) / period) * GDC = ((time_on * 256) / period)
*/ */
gdc = (time_on * 256) / period; gdc = (pca963x_period_scale(pca963x, time_on) * 256) / period;
/* /*
* From manual: period = ((GFRQ + 1) / 24) in seconds. * From manual: period = ((GFRQ + 1) / 24) in seconds.
...@@ -294,6 +303,9 @@ pca963x_dt_init(struct i2c_client *client, struct pca963x_chipdef *chip) ...@@ -294,6 +303,9 @@ pca963x_dt_init(struct i2c_client *client, struct pca963x_chipdef *chip)
else else
pdata->blink_type = PCA963X_SW_BLINK; pdata->blink_type = PCA963X_SW_BLINK;
if (of_property_read_u32(np, "nxp,period-scale", &chip->scaling))
chip->scaling = 1000;
return pdata; return pdata;
} }
......
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