diff options
Diffstat (limited to 'drivers/leds')
-rw-r--r-- | drivers/leds/leds-lp5521.c | 52 |
1 files changed, 8 insertions, 44 deletions
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c index e881a75dc39d..4d91c08656c5 100644 --- a/drivers/leds/leds-lp5521.c +++ b/drivers/leds/leds-lp5521.c | |||
@@ -98,7 +98,6 @@ | |||
98 | #define LP5521_EXT_CLK_USED 0x08 | 98 | #define LP5521_EXT_CLK_USED 0x08 |
99 | 99 | ||
100 | struct lp5521_engine { | 100 | struct lp5521_engine { |
101 | const struct attribute_group *attributes; | ||
102 | int id; | 101 | int id; |
103 | u8 mode; | 102 | u8 mode; |
104 | u8 prog_page; | 103 | u8 prog_page; |
@@ -225,25 +224,22 @@ static int lp5521_set_led_current(struct lp5521_chip *chip, int led, u8 curr) | |||
225 | curr); | 224 | curr); |
226 | } | 225 | } |
227 | 226 | ||
228 | static void lp5521_init_engine(struct lp5521_chip *chip, | 227 | static void lp5521_init_engine(struct lp5521_chip *chip) |
229 | const struct attribute_group *attr_group) | ||
230 | { | 228 | { |
231 | int i; | 229 | int i; |
232 | for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { | 230 | for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { |
233 | chip->engines[i].id = i + 1; | 231 | chip->engines[i].id = i + 1; |
234 | chip->engines[i].engine_mask = LP5521_ENG_MASK_BASE >> (i * 2); | 232 | chip->engines[i].engine_mask = LP5521_ENG_MASK_BASE >> (i * 2); |
235 | chip->engines[i].prog_page = i; | 233 | chip->engines[i].prog_page = i; |
236 | chip->engines[i].attributes = &attr_group[i]; | ||
237 | } | 234 | } |
238 | } | 235 | } |
239 | 236 | ||
240 | static int lp5521_configure(struct i2c_client *client, | 237 | static int lp5521_configure(struct i2c_client *client) |
241 | const struct attribute_group *attr_group) | ||
242 | { | 238 | { |
243 | struct lp5521_chip *chip = i2c_get_clientdata(client); | 239 | struct lp5521_chip *chip = i2c_get_clientdata(client); |
244 | int ret; | 240 | int ret; |
245 | 241 | ||
246 | lp5521_init_engine(chip, attr_group); | 242 | lp5521_init_engine(chip); |
247 | 243 | ||
248 | /* Set all PWMs to direct control mode */ | 244 | /* Set all PWMs to direct control mode */ |
249 | ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F); | 245 | ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F); |
@@ -329,9 +325,6 @@ static int lp5521_detect(struct i2c_client *client) | |||
329 | /* Set engine mode and create appropriate sysfs attributes, if required. */ | 325 | /* Set engine mode and create appropriate sysfs attributes, if required. */ |
330 | static int lp5521_set_mode(struct lp5521_engine *engine, u8 mode) | 326 | static int lp5521_set_mode(struct lp5521_engine *engine, u8 mode) |
331 | { | 327 | { |
332 | struct lp5521_chip *chip = engine_to_lp5521(engine); | ||
333 | struct i2c_client *client = chip->client; | ||
334 | struct device *dev = &client->dev; | ||
335 | int ret = 0; | 328 | int ret = 0; |
336 | 329 | ||
337 | /* if in that mode already do nothing, except for run */ | 330 | /* if in that mode already do nothing, except for run */ |
@@ -343,18 +336,10 @@ static int lp5521_set_mode(struct lp5521_engine *engine, u8 mode) | |||
343 | } else if (mode == LP5521_CMD_LOAD) { | 336 | } else if (mode == LP5521_CMD_LOAD) { |
344 | lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED); | 337 | lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED); |
345 | lp5521_set_engine_mode(engine, LP5521_CMD_LOAD); | 338 | lp5521_set_engine_mode(engine, LP5521_CMD_LOAD); |
346 | |||
347 | ret = sysfs_create_group(&dev->kobj, engine->attributes); | ||
348 | if (ret) | ||
349 | return ret; | ||
350 | } else if (mode == LP5521_CMD_DISABLED) { | 339 | } else if (mode == LP5521_CMD_DISABLED) { |
351 | lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED); | 340 | lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED); |
352 | } | 341 | } |
353 | 342 | ||
354 | /* remove load attribute from sysfs if not in load mode */ | ||
355 | if (engine->mode == LP5521_CMD_LOAD && mode != LP5521_CMD_LOAD) | ||
356 | sysfs_remove_group(&dev->kobj, engine->attributes); | ||
357 | |||
358 | engine->mode = mode; | 343 | engine->mode = mode; |
359 | 344 | ||
360 | return ret; | 345 | return ret; |
@@ -389,7 +374,10 @@ static int lp5521_do_store_load(struct lp5521_engine *engine, | |||
389 | goto fail; | 374 | goto fail; |
390 | 375 | ||
391 | mutex_lock(&chip->lock); | 376 | mutex_lock(&chip->lock); |
392 | ret = lp5521_load_program(engine, pattern); | 377 | if (engine->mode == LP5521_CMD_LOAD) |
378 | ret = lp5521_load_program(engine, pattern); | ||
379 | else | ||
380 | ret = -EINVAL; | ||
393 | mutex_unlock(&chip->lock); | 381 | mutex_unlock(&chip->lock); |
394 | 382 | ||
395 | if (ret) { | 383 | if (ret) { |
@@ -576,20 +564,8 @@ static struct attribute *lp5521_attributes[] = { | |||
576 | &dev_attr_engine2_mode.attr, | 564 | &dev_attr_engine2_mode.attr, |
577 | &dev_attr_engine3_mode.attr, | 565 | &dev_attr_engine3_mode.attr, |
578 | &dev_attr_selftest.attr, | 566 | &dev_attr_selftest.attr, |
579 | NULL | ||
580 | }; | ||
581 | |||
582 | static struct attribute *lp5521_engine1_attributes[] = { | ||
583 | &dev_attr_engine1_load.attr, | 567 | &dev_attr_engine1_load.attr, |
584 | NULL | ||
585 | }; | ||
586 | |||
587 | static struct attribute *lp5521_engine2_attributes[] = { | ||
588 | &dev_attr_engine2_load.attr, | 568 | &dev_attr_engine2_load.attr, |
589 | NULL | ||
590 | }; | ||
591 | |||
592 | static struct attribute *lp5521_engine3_attributes[] = { | ||
593 | &dev_attr_engine3_load.attr, | 569 | &dev_attr_engine3_load.attr, |
594 | NULL | 570 | NULL |
595 | }; | 571 | }; |
@@ -598,12 +574,6 @@ static const struct attribute_group lp5521_group = { | |||
598 | .attrs = lp5521_attributes, | 574 | .attrs = lp5521_attributes, |
599 | }; | 575 | }; |
600 | 576 | ||
601 | static const struct attribute_group lp5521_engine_group[] = { | ||
602 | {.attrs = lp5521_engine1_attributes }, | ||
603 | {.attrs = lp5521_engine2_attributes }, | ||
604 | {.attrs = lp5521_engine3_attributes }, | ||
605 | }; | ||
606 | |||
607 | static int lp5521_register_sysfs(struct i2c_client *client) | 577 | static int lp5521_register_sysfs(struct i2c_client *client) |
608 | { | 578 | { |
609 | struct device *dev = &client->dev; | 579 | struct device *dev = &client->dev; |
@@ -618,12 +588,6 @@ static void lp5521_unregister_sysfs(struct i2c_client *client) | |||
618 | 588 | ||
619 | sysfs_remove_group(&dev->kobj, &lp5521_group); | 589 | sysfs_remove_group(&dev->kobj, &lp5521_group); |
620 | 590 | ||
621 | for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { | ||
622 | if (chip->engines[i].mode == LP5521_CMD_LOAD) | ||
623 | sysfs_remove_group(&dev->kobj, | ||
624 | chip->engines[i].attributes); | ||
625 | } | ||
626 | |||
627 | for (i = 0; i < chip->num_leds; i++) | 591 | for (i = 0; i < chip->num_leds; i++) |
628 | sysfs_remove_group(&chip->leds[i].cdev.dev->kobj, | 592 | sysfs_remove_group(&chip->leds[i].cdev.dev->kobj, |
629 | &lp5521_led_attribute_group); | 593 | &lp5521_led_attribute_group); |
@@ -725,7 +689,7 @@ static int lp5521_probe(struct i2c_client *client, | |||
725 | 689 | ||
726 | dev_info(&client->dev, "%s programmable led chip found\n", id->name); | 690 | dev_info(&client->dev, "%s programmable led chip found\n", id->name); |
727 | 691 | ||
728 | ret = lp5521_configure(client, lp5521_engine_group); | 692 | ret = lp5521_configure(client); |
729 | if (ret < 0) { | 693 | if (ret < 0) { |
730 | dev_err(&client->dev, "error configuring chip\n"); | 694 | dev_err(&client->dev, "error configuring chip\n"); |
731 | goto fail2; | 695 | goto fail2; |