Skip to content

Commit 8913c2c

Browse files
Ansuellag-linaro
authored andcommitted
leds: leds-lp55xx: Generalize sysfs engine_leds
Generalize sysfs engine_leds since their implementation is the same across some lp55xx based LED driver. While at it simplify the implementation for show_engine_leds. Suggested-by: Lee Jones <[email protected]> Signed-off-by: Christian Marangi <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Lee Jones <[email protected]>
1 parent 082a4d3 commit 8913c2c

File tree

3 files changed

+131
-129
lines changed

3 files changed

+131
-129
lines changed

drivers/leds/leds-lp5523.c

Lines changed: 3 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -225,119 +225,6 @@ static int lp5523_init_program_engine(struct lp55xx_chip *chip)
225225
return ret;
226226
}
227227

228-
static int lp5523_mux_parse(const char *buf, u16 *mux, size_t len)
229-
{
230-
u16 tmp_mux = 0;
231-
int i;
232-
233-
len = min_t(int, len, LP5523_MAX_LEDS);
234-
235-
for (i = 0; i < len; i++) {
236-
switch (buf[i]) {
237-
case '1':
238-
tmp_mux |= (1 << i);
239-
break;
240-
case '0':
241-
break;
242-
case '\n':
243-
i = len;
244-
break;
245-
default:
246-
return -1;
247-
}
248-
}
249-
*mux = tmp_mux;
250-
251-
return 0;
252-
}
253-
254-
static void lp5523_mux_to_array(u16 led_mux, char *array)
255-
{
256-
int i, pos = 0;
257-
258-
for (i = 0; i < LP5523_MAX_LEDS; i++)
259-
pos += sprintf(array + pos, "%x", LED_ACTIVE(led_mux, i));
260-
261-
array[pos] = '\0';
262-
}
263-
264-
static ssize_t show_engine_leds(struct device *dev,
265-
struct device_attribute *attr,
266-
char *buf, int nr)
267-
{
268-
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
269-
struct lp55xx_chip *chip = led->chip;
270-
char mux[LP5523_MAX_LEDS + 1];
271-
272-
lp5523_mux_to_array(chip->engines[nr - 1].led_mux, mux);
273-
274-
return sprintf(buf, "%s\n", mux);
275-
}
276-
show_leds(1)
277-
show_leds(2)
278-
show_leds(3)
279-
280-
static int lp5523_load_mux(struct lp55xx_chip *chip, u16 mux, int nr)
281-
{
282-
struct lp55xx_engine *engine = &chip->engines[nr - 1];
283-
int ret;
284-
static const u8 mux_page[] = {
285-
[LP55XX_ENGINE_1] = LP5523_PAGE_MUX1,
286-
[LP55XX_ENGINE_2] = LP5523_PAGE_MUX2,
287-
[LP55XX_ENGINE_3] = LP5523_PAGE_MUX3,
288-
};
289-
290-
lp55xx_load_engine(chip);
291-
292-
ret = lp55xx_write(chip, LP5523_REG_PROG_PAGE_SEL, mux_page[nr]);
293-
if (ret)
294-
return ret;
295-
296-
ret = lp55xx_write(chip, LP5523_REG_PROG_MEM, (u8)(mux >> 8));
297-
if (ret)
298-
return ret;
299-
300-
ret = lp55xx_write(chip, LP5523_REG_PROG_MEM + 1, (u8)(mux));
301-
if (ret)
302-
return ret;
303-
304-
engine->led_mux = mux;
305-
return 0;
306-
}
307-
308-
static ssize_t store_engine_leds(struct device *dev,
309-
struct device_attribute *attr,
310-
const char *buf, size_t len, int nr)
311-
{
312-
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
313-
struct lp55xx_chip *chip = led->chip;
314-
struct lp55xx_engine *engine = &chip->engines[nr - 1];
315-
u16 mux = 0;
316-
ssize_t ret;
317-
318-
if (lp5523_mux_parse(buf, &mux, len))
319-
return -EINVAL;
320-
321-
mutex_lock(&chip->lock);
322-
323-
chip->engine_idx = nr;
324-
ret = -EINVAL;
325-
326-
if (engine->mode != LP55XX_ENGINE_LOAD)
327-
goto leave;
328-
329-
if (lp5523_load_mux(chip, mux, nr))
330-
goto leave;
331-
332-
ret = len;
333-
leave:
334-
mutex_unlock(&chip->lock);
335-
return ret;
336-
}
337-
store_leds(1)
338-
store_leds(2)
339-
store_leds(3)
340-
341228
static ssize_t lp5523_selftest(struct device *dev,
342229
struct device_attribute *attr,
343230
char *buf)
@@ -562,9 +449,9 @@ static ssize_t store_master_fader_leds(struct device *dev,
562449
LP55XX_DEV_ATTR_ENGINE_MODE(1);
563450
LP55XX_DEV_ATTR_ENGINE_MODE(2);
564451
LP55XX_DEV_ATTR_ENGINE_MODE(3);
565-
static LP55XX_DEV_ATTR_RW(engine1_leds, show_engine1_leds, store_engine1_leds);
566-
static LP55XX_DEV_ATTR_RW(engine2_leds, show_engine2_leds, store_engine2_leds);
567-
static LP55XX_DEV_ATTR_RW(engine3_leds, show_engine3_leds, store_engine3_leds);
452+
LP55XX_DEV_ATTR_ENGINE_LEDS(1);
453+
LP55XX_DEV_ATTR_ENGINE_LEDS(2);
454+
LP55XX_DEV_ATTR_ENGINE_LEDS(3);
568455
LP55XX_DEV_ATTR_ENGINE_LOAD(1);
569456
LP55XX_DEV_ATTR_ENGINE_LOAD(2);
570457
LP55XX_DEV_ATTR_ENGINE_LOAD(3);

drivers/leds/leds-lp55xx-common.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
/* If supported, each ENGINE have an equal amount of pages offset from page 0 */
6363
#define LP55xx_PAGE_OFFSET(n, pages) (((n) - 1) * (pages))
6464

65+
#define LED_ACTIVE(mux, led) (!!((mux) & (0x0001 << (led))))
66+
6567
/* External clock rate */
6668
#define LP55XX_CLK_32K 32768
6769

@@ -691,6 +693,113 @@ ssize_t lp55xx_store_engine_load(struct device *dev,
691693
}
692694
EXPORT_SYMBOL_GPL(lp55xx_store_engine_load);
693695

696+
static int lp55xx_mux_parse(struct lp55xx_chip *chip, const char *buf,
697+
u16 *mux, size_t len)
698+
{
699+
const struct lp55xx_device_config *cfg = chip->cfg;
700+
u16 tmp_mux = 0;
701+
int i;
702+
703+
len = min_t(int, len, cfg->max_channel);
704+
705+
for (i = 0; i < len; i++) {
706+
switch (buf[i]) {
707+
case '1':
708+
tmp_mux |= (1 << i);
709+
break;
710+
case '0':
711+
break;
712+
case '\n':
713+
i = len;
714+
break;
715+
default:
716+
return -1;
717+
}
718+
}
719+
*mux = tmp_mux;
720+
721+
return 0;
722+
}
723+
724+
ssize_t lp55xx_show_engine_leds(struct device *dev,
725+
struct device_attribute *attr,
726+
char *buf, int nr)
727+
{
728+
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
729+
struct lp55xx_chip *chip = led->chip;
730+
const struct lp55xx_device_config *cfg = chip->cfg;
731+
unsigned int led_active;
732+
int i, pos = 0;
733+
734+
for (i = 0; i < cfg->max_channel; i++) {
735+
led_active = LED_ACTIVE(chip->engines[nr - 1].led_mux, i);
736+
pos += sysfs_emit_at(buf, pos, "%x", led_active);
737+
}
738+
739+
pos += sysfs_emit_at(buf, pos, "\n");
740+
741+
return pos;
742+
}
743+
EXPORT_SYMBOL_GPL(lp55xx_show_engine_leds);
744+
745+
static int lp55xx_load_mux(struct lp55xx_chip *chip, u16 mux, int nr)
746+
{
747+
struct lp55xx_engine *engine = &chip->engines[nr - 1];
748+
const struct lp55xx_device_config *cfg = chip->cfg;
749+
u8 mux_page;
750+
int ret;
751+
752+
lp55xx_load_engine(chip);
753+
754+
/* Derive the MUX page offset by starting at the end of the ENGINE pages */
755+
mux_page = cfg->pages_per_engine * LP55XX_ENGINE_MAX + (nr - 1);
756+
ret = lp55xx_write(chip, LP55xx_REG_PROG_PAGE_SEL, mux_page);
757+
if (ret)
758+
return ret;
759+
760+
ret = lp55xx_write(chip, cfg->prog_mem_base.addr, (u8)(mux >> 8));
761+
if (ret)
762+
return ret;
763+
764+
ret = lp55xx_write(chip, cfg->prog_mem_base.addr + 1, (u8)(mux));
765+
if (ret)
766+
return ret;
767+
768+
engine->led_mux = mux;
769+
return 0;
770+
}
771+
772+
ssize_t lp55xx_store_engine_leds(struct device *dev,
773+
struct device_attribute *attr,
774+
const char *buf, size_t len, int nr)
775+
{
776+
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
777+
struct lp55xx_chip *chip = led->chip;
778+
struct lp55xx_engine *engine = &chip->engines[nr - 1];
779+
u16 mux = 0;
780+
ssize_t ret;
781+
782+
if (lp55xx_mux_parse(chip, buf, &mux, len))
783+
return -EINVAL;
784+
785+
mutex_lock(&chip->lock);
786+
787+
chip->engine_idx = nr;
788+
ret = -EINVAL;
789+
790+
if (engine->mode != LP55XX_ENGINE_LOAD)
791+
goto leave;
792+
793+
if (lp55xx_load_mux(chip, mux, nr))
794+
goto leave;
795+
796+
ret = len;
797+
leave:
798+
mutex_unlock(&chip->lock);
799+
return ret;
800+
}
801+
EXPORT_SYMBOL_GPL(lp55xx_store_engine_leds);
802+
694803
static struct attribute *lp55xx_engine_attributes[] = {
695804
&dev_attr_select_engine.attr,
696805
&dev_attr_run_engine.attr,

drivers/leds/leds-lp55xx-common.h

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,21 @@ static ssize_t store_engine##nr##_mode(struct device *dev, \
5151
static LP55XX_DEV_ATTR_RW(engine##nr##_mode, show_engine##nr##_mode, \
5252
store_engine##nr##_mode)
5353

54-
#define show_leds(nr) \
54+
#define LP55XX_DEV_ATTR_ENGINE_LEDS(nr) \
5555
static ssize_t show_engine##nr##_leds(struct device *dev, \
56-
struct device_attribute *attr, \
57-
char *buf) \
56+
struct device_attribute *attr, \
57+
char *buf) \
5858
{ \
59-
return show_engine_leds(dev, attr, buf, nr); \
60-
}
61-
62-
#define store_leds(nr) \
63-
static ssize_t store_engine##nr##_leds(struct device *dev, \
64-
struct device_attribute *attr, \
65-
const char *buf, size_t len) \
66-
{ \
67-
return store_engine_leds(dev, attr, buf, len, nr); \
68-
}
59+
return lp55xx_show_engine_leds(dev, attr, buf, nr); \
60+
} \
61+
static ssize_t store_engine##nr##_leds(struct device *dev, \
62+
struct device_attribute *attr, \
63+
const char *buf, size_t len) \
64+
{ \
65+
return lp55xx_store_engine_leds(dev, attr, buf, len, nr); \
66+
} \
67+
static LP55XX_DEV_ATTR_RW(engine##nr##_leds, show_engine##nr##_leds, \
68+
store_engine##nr##_leds)
6969

7070
#define LP55XX_DEV_ATTR_ENGINE_LOAD(nr) \
7171
static ssize_t store_engine##nr##_load(struct device *dev, \
@@ -238,5 +238,11 @@ extern ssize_t lp55xx_store_engine_mode(struct device *dev,
238238
extern ssize_t lp55xx_store_engine_load(struct device *dev,
239239
struct device_attribute *attr,
240240
const char *buf, size_t len, int nr);
241+
extern ssize_t lp55xx_show_engine_leds(struct device *dev,
242+
struct device_attribute *attr,
243+
char *buf, int nr);
244+
extern ssize_t lp55xx_store_engine_leds(struct device *dev,
245+
struct device_attribute *attr,
246+
const char *buf, size_t len, int nr);
241247

242248
#endif /* _LEDS_LP55XX_COMMON_H */

0 commit comments

Comments
 (0)