diff options
-rw-r--r-- | drivers/leds/leds-lp5521.c | 78 |
1 files changed, 38 insertions, 40 deletions
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c index 1eab1557a612..341a41030fd8 100644 --- a/drivers/leds/leds-lp5521.c +++ b/drivers/leds/leds-lp5521.c | |||
@@ -125,6 +125,12 @@ struct lp5521_chip { | |||
125 | u8 num_leds; | 125 | u8 num_leds; |
126 | }; | 126 | }; |
127 | 127 | ||
128 | static inline void lp5521_wait_enable_done(void) | ||
129 | { | ||
130 | /* it takes more 488 us to update ENABLE register */ | ||
131 | usleep_range(500, 600); | ||
132 | } | ||
133 | |||
128 | static inline struct lp5521_led *cdev_to_led(struct led_classdev *cdev) | 134 | static inline struct lp5521_led *cdev_to_led(struct led_classdev *cdev) |
129 | { | 135 | { |
130 | return container_of(cdev, struct lp5521_led, cdev); | 136 | return container_of(cdev, struct lp5521_led, cdev); |
@@ -229,43 +235,56 @@ static int lp5521_set_led_current(struct lp5521_chip *chip, int led, u8 curr) | |||
229 | curr); | 235 | curr); |
230 | } | 236 | } |
231 | 237 | ||
232 | static void lp5521_init_engine(struct lp5521_chip *chip) | ||
233 | { | ||
234 | int i; | ||
235 | for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { | ||
236 | chip->engines[i].id = i + 1; | ||
237 | chip->engines[i].engine_mask = LP5521_ENG_MASK_BASE >> (i * 2); | ||
238 | chip->engines[i].prog_page = i; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | static int lp5521_configure(struct i2c_client *client) | 238 | static int lp5521_configure(struct i2c_client *client) |
243 | { | 239 | { |
244 | struct lp5521_chip *chip = i2c_get_clientdata(client); | 240 | struct lp5521_chip *chip = i2c_get_clientdata(client); |
245 | int ret; | 241 | int ret; |
246 | u8 cfg; | 242 | u8 cfg; |
243 | u8 val; | ||
247 | 244 | ||
248 | lp5521_init_engine(chip); | 245 | /* |
246 | * Make sure that the chip is reset by reading back the r channel | ||
247 | * current reg. This is dummy read is required on some platforms - | ||
248 | * otherwise further access to the R G B channels in the | ||
249 | * LP5521_REG_ENABLE register will not have any effect - strange! | ||
250 | */ | ||
251 | ret = lp5521_read(client, LP5521_REG_R_CURRENT, &val); | ||
252 | if (ret) { | ||
253 | dev_err(&client->dev, "error in resetting chip\n"); | ||
254 | return ret; | ||
255 | } | ||
256 | if (val != LP5521_REG_R_CURR_DEFAULT) { | ||
257 | dev_err(&client->dev, | ||
258 | "unexpected data in register (expected 0x%x got 0x%x)\n", | ||
259 | LP5521_REG_R_CURR_DEFAULT, val); | ||
260 | ret = -EINVAL; | ||
261 | return ret; | ||
262 | } | ||
263 | usleep_range(10000, 20000); | ||
249 | 264 | ||
250 | /* Set all PWMs to direct control mode */ | 265 | /* Set all PWMs to direct control mode */ |
251 | ret = lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT); | 266 | ret = lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT); |
252 | 267 | ||
253 | cfg = chip->pdata->update_config ? | 268 | cfg = chip->pdata->update_config ? |
254 | : (LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT); | 269 | : (LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT); |
255 | ret |= lp5521_write(client, LP5521_REG_CONFIG, cfg); | 270 | ret = lp5521_write(client, LP5521_REG_CONFIG, cfg); |
271 | if (ret) | ||
272 | return ret; | ||
256 | 273 | ||
257 | /* Initialize all channels PWM to zero -> leds off */ | 274 | /* Initialize all channels PWM to zero -> leds off */ |
258 | ret |= lp5521_write(client, LP5521_REG_R_PWM, 0); | 275 | lp5521_write(client, LP5521_REG_R_PWM, 0); |
259 | ret |= lp5521_write(client, LP5521_REG_G_PWM, 0); | 276 | lp5521_write(client, LP5521_REG_G_PWM, 0); |
260 | ret |= lp5521_write(client, LP5521_REG_B_PWM, 0); | 277 | lp5521_write(client, LP5521_REG_B_PWM, 0); |
261 | 278 | ||
262 | /* Set engines are set to run state when OP_MODE enables engines */ | 279 | /* Set engines are set to run state when OP_MODE enables engines */ |
263 | ret |= lp5521_write(client, LP5521_REG_ENABLE, | 280 | ret = lp5521_write(client, LP5521_REG_ENABLE, |
264 | LP5521_ENABLE_RUN_PROGRAM); | 281 | LP5521_ENABLE_RUN_PROGRAM); |
265 | /* enable takes 500us. 1 - 2 ms leaves some margin */ | 282 | if (ret) |
266 | usleep_range(1000, 2000); | 283 | return ret; |
267 | 284 | ||
268 | return ret; | 285 | lp5521_wait_enable_done(); |
286 | |||
287 | return 0; | ||
269 | } | 288 | } |
270 | 289 | ||
271 | static int lp5521_run_selftest(struct lp5521_chip *chip, char *buf) | 290 | static int lp5521_run_selftest(struct lp5521_chip *chip, char *buf) |
@@ -703,7 +722,6 @@ static int lp5521_init_device(struct lp5521_chip *chip) | |||
703 | struct lp5521_platform_data *pdata = chip->pdata; | 722 | struct lp5521_platform_data *pdata = chip->pdata; |
704 | struct i2c_client *client = chip->client; | 723 | struct i2c_client *client = chip->client; |
705 | int ret; | 724 | int ret; |
706 | u8 buf; | ||
707 | 725 | ||
708 | if (pdata->setup_resources) { | 726 | if (pdata->setup_resources) { |
709 | ret = pdata->setup_resources(); | 727 | ret = pdata->setup_resources(); |
@@ -725,26 +743,6 @@ static int lp5521_init_device(struct lp5521_chip *chip) | |||
725 | * appears to be enough for reset. | 743 | * appears to be enough for reset. |
726 | */ | 744 | */ |
727 | 745 | ||
728 | /* | ||
729 | * Make sure that the chip is reset by reading back the r channel | ||
730 | * current reg. This is dummy read is required on some platforms - | ||
731 | * otherwise further access to the R G B channels in the | ||
732 | * LP5521_REG_ENABLE register will not have any effect - strange! | ||
733 | */ | ||
734 | ret = lp5521_read(client, LP5521_REG_R_CURRENT, &buf); | ||
735 | if (ret) { | ||
736 | dev_err(&client->dev, "error in resetting chip\n"); | ||
737 | return ret; | ||
738 | } | ||
739 | if (buf != LP5521_REG_R_CURR_DEFAULT) { | ||
740 | dev_err(&client->dev, | ||
741 | "unexpected data in register (expected 0x%x got 0x%x)\n", | ||
742 | LP5521_REG_R_CURR_DEFAULT, buf); | ||
743 | ret = -EINVAL; | ||
744 | return ret; | ||
745 | } | ||
746 | usleep_range(10000, 20000); | ||
747 | |||
748 | ret = lp5521_detect(client); | 746 | ret = lp5521_detect(client); |
749 | if (ret) { | 747 | if (ret) { |
750 | dev_err(&client->dev, "Chip not found\n"); | 748 | dev_err(&client->dev, "Chip not found\n"); |