aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/leds-lp5521.c52
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
100struct lp5521_engine { 100struct 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
228static void lp5521_init_engine(struct lp5521_chip *chip, 227static 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
240static int lp5521_configure(struct i2c_client *client, 237static 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. */
330static int lp5521_set_mode(struct lp5521_engine *engine, u8 mode) 326static 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
582static struct attribute *lp5521_engine1_attributes[] = {
583 &dev_attr_engine1_load.attr, 567 &dev_attr_engine1_load.attr,
584 NULL
585};
586
587static struct attribute *lp5521_engine2_attributes[] = {
588 &dev_attr_engine2_load.attr, 568 &dev_attr_engine2_load.attr,
589 NULL
590};
591
592static 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
601static const struct attribute_group lp5521_engine_group[] = {
602 {.attrs = lp5521_engine1_attributes },
603 {.attrs = lp5521_engine2_attributes },
604 {.attrs = lp5521_engine3_attributes },
605};
606
607static int lp5521_register_sysfs(struct i2c_client *client) 577static 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;