aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/leds/leds-lp5521.c78
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
128static 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
128static inline struct lp5521_led *cdev_to_led(struct led_classdev *cdev) 134static 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
232static 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
242static int lp5521_configure(struct i2c_client *client) 238static 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
271static int lp5521_run_selftest(struct lp5521_chip *chip, char *buf) 290static 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");