leds: leds-lp55xx: Generalize sysfs master_fader
Generalize sysfs master_fader since their implementation is the same across some lp55xx based LED driver. Suggested-by: Lee Jones <lee@kernel.org> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> Link: https://lore.kernel.org/r/20240626160027.19703-18-ansuelsmth@gmail.com Signed-off-by: Lee Jones <lee@kernel.org>
This commit is contained in:
parent
8913c2c147
commit
5a15b2ab57
@ -315,137 +315,6 @@ release_lock:
|
||||
return pos;
|
||||
}
|
||||
|
||||
#define show_fader(nr) \
|
||||
static ssize_t show_master_fader##nr(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
char *buf) \
|
||||
{ \
|
||||
return show_master_fader(dev, attr, buf, nr); \
|
||||
}
|
||||
|
||||
#define store_fader(nr) \
|
||||
static ssize_t store_master_fader##nr(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
const char *buf, size_t len) \
|
||||
{ \
|
||||
return store_master_fader(dev, attr, buf, len, nr); \
|
||||
}
|
||||
|
||||
static ssize_t show_master_fader(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf, int nr)
|
||||
{
|
||||
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
|
||||
struct lp55xx_chip *chip = led->chip;
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
ret = lp55xx_read(chip, LP5523_REG_MASTER_FADER_BASE + nr - 1, &val);
|
||||
mutex_unlock(&chip->lock);
|
||||
|
||||
if (ret == 0)
|
||||
ret = sprintf(buf, "%u\n", val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
show_fader(1)
|
||||
show_fader(2)
|
||||
show_fader(3)
|
||||
|
||||
static ssize_t store_master_fader(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len, int nr)
|
||||
{
|
||||
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
|
||||
struct lp55xx_chip *chip = led->chip;
|
||||
int ret;
|
||||
unsigned long val;
|
||||
|
||||
if (kstrtoul(buf, 0, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (val > 0xff)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
ret = lp55xx_write(chip, LP5523_REG_MASTER_FADER_BASE + nr - 1,
|
||||
(u8)val);
|
||||
mutex_unlock(&chip->lock);
|
||||
|
||||
if (ret == 0)
|
||||
ret = len;
|
||||
|
||||
return ret;
|
||||
}
|
||||
store_fader(1)
|
||||
store_fader(2)
|
||||
store_fader(3)
|
||||
|
||||
static ssize_t show_master_fader_leds(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
|
||||
struct lp55xx_chip *chip = led->chip;
|
||||
int i, ret, pos = 0;
|
||||
u8 val;
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
|
||||
for (i = 0; i < LP5523_MAX_LEDS; i++) {
|
||||
ret = lp55xx_read(chip, LP5523_REG_LED_CTRL_BASE + i, &val);
|
||||
if (ret)
|
||||
goto leave;
|
||||
|
||||
val = (val & LP5523_FADER_MAPPING_MASK)
|
||||
>> LP5523_FADER_MAPPING_SHIFT;
|
||||
if (val > 3) {
|
||||
ret = -EINVAL;
|
||||
goto leave;
|
||||
}
|
||||
buf[pos++] = val + '0';
|
||||
}
|
||||
buf[pos++] = '\n';
|
||||
ret = pos;
|
||||
leave:
|
||||
mutex_unlock(&chip->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t store_master_fader_leds(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
|
||||
struct lp55xx_chip *chip = led->chip;
|
||||
int i, n, ret;
|
||||
u8 val;
|
||||
|
||||
n = min_t(int, len, LP5523_MAX_LEDS);
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (buf[i] >= '0' && buf[i] <= '3') {
|
||||
val = (buf[i] - '0') << LP5523_FADER_MAPPING_SHIFT;
|
||||
ret = lp55xx_update_bits(chip,
|
||||
LP5523_REG_LED_CTRL_BASE + i,
|
||||
LP5523_FADER_MAPPING_MASK,
|
||||
val);
|
||||
if (ret)
|
||||
goto leave;
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
ret = len;
|
||||
leave:
|
||||
mutex_unlock(&chip->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LP55XX_DEV_ATTR_ENGINE_MODE(1);
|
||||
LP55XX_DEV_ATTR_ENGINE_MODE(2);
|
||||
LP55XX_DEV_ATTR_ENGINE_MODE(3);
|
||||
@ -456,14 +325,11 @@ LP55XX_DEV_ATTR_ENGINE_LOAD(1);
|
||||
LP55XX_DEV_ATTR_ENGINE_LOAD(2);
|
||||
LP55XX_DEV_ATTR_ENGINE_LOAD(3);
|
||||
static LP55XX_DEV_ATTR_RO(selftest, lp5523_selftest);
|
||||
static LP55XX_DEV_ATTR_RW(master_fader1, show_master_fader1,
|
||||
store_master_fader1);
|
||||
static LP55XX_DEV_ATTR_RW(master_fader2, show_master_fader2,
|
||||
store_master_fader2);
|
||||
static LP55XX_DEV_ATTR_RW(master_fader3, show_master_fader3,
|
||||
store_master_fader3);
|
||||
static LP55XX_DEV_ATTR_RW(master_fader_leds, show_master_fader_leds,
|
||||
store_master_fader_leds);
|
||||
LP55XX_DEV_ATTR_MASTER_FADER(1);
|
||||
LP55XX_DEV_ATTR_MASTER_FADER(2);
|
||||
LP55XX_DEV_ATTR_MASTER_FADER(3);
|
||||
static LP55XX_DEV_ATTR_RW(master_fader_leds, lp55xx_show_master_fader_leds,
|
||||
lp55xx_store_master_fader_leds);
|
||||
|
||||
static struct attribute *lp5523_attributes[] = {
|
||||
&dev_attr_engine1_mode.attr,
|
||||
@ -516,6 +382,12 @@ static struct lp55xx_device_config lp5523_cfg = {
|
||||
.reg_led_current_base = {
|
||||
.addr = LP5523_REG_LED_CURRENT_BASE,
|
||||
},
|
||||
.reg_master_fader_base = {
|
||||
.addr = LP5523_REG_MASTER_FADER_BASE,
|
||||
},
|
||||
.reg_led_ctrl_base = {
|
||||
.addr = LP5523_REG_LED_CTRL_BASE,
|
||||
},
|
||||
.pages_per_engine = LP5523_PAGES_PER_ENGINE,
|
||||
.max_channel = LP5523_MAX_LEDS,
|
||||
.post_init_device = lp5523_post_init_device,
|
||||
|
@ -64,6 +64,9 @@
|
||||
|
||||
#define LED_ACTIVE(mux, led) (!!((mux) & (0x0001 << (led))))
|
||||
|
||||
/* MASTER FADER common property */
|
||||
#define LP55xx_FADER_MAPPING_MASK GENMASK(7, 6)
|
||||
|
||||
/* External clock rate */
|
||||
#define LP55XX_CLK_32K 32768
|
||||
|
||||
@ -800,6 +803,116 @@ leave:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lp55xx_store_engine_leds);
|
||||
|
||||
ssize_t lp55xx_show_master_fader(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf, int nr)
|
||||
{
|
||||
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
|
||||
struct lp55xx_chip *chip = led->chip;
|
||||
const struct lp55xx_device_config *cfg = chip->cfg;
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
ret = lp55xx_read(chip, cfg->reg_master_fader_base.addr + nr - 1, &val);
|
||||
mutex_unlock(&chip->lock);
|
||||
|
||||
return ret ? ret : sysfs_emit(buf, "%u\n", val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lp55xx_show_master_fader);
|
||||
|
||||
ssize_t lp55xx_store_master_fader(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len, int nr)
|
||||
{
|
||||
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
|
||||
struct lp55xx_chip *chip = led->chip;
|
||||
const struct lp55xx_device_config *cfg = chip->cfg;
|
||||
int ret;
|
||||
unsigned long val;
|
||||
|
||||
if (kstrtoul(buf, 0, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (val > 0xff)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
ret = lp55xx_write(chip, cfg->reg_master_fader_base.addr + nr - 1,
|
||||
(u8)val);
|
||||
mutex_unlock(&chip->lock);
|
||||
|
||||
return ret ? ret : len;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lp55xx_store_master_fader);
|
||||
|
||||
ssize_t lp55xx_show_master_fader_leds(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
|
||||
struct lp55xx_chip *chip = led->chip;
|
||||
const struct lp55xx_device_config *cfg = chip->cfg;
|
||||
int i, ret, pos = 0;
|
||||
u8 val;
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
|
||||
for (i = 0; i < cfg->max_channel; i++) {
|
||||
ret = lp55xx_read(chip, cfg->reg_led_ctrl_base.addr + i, &val);
|
||||
if (ret)
|
||||
goto leave;
|
||||
|
||||
val = FIELD_GET(LP55xx_FADER_MAPPING_MASK, val);
|
||||
if (val > FIELD_MAX(LP55xx_FADER_MAPPING_MASK)) {
|
||||
ret = -EINVAL;
|
||||
goto leave;
|
||||
}
|
||||
buf[pos++] = val + '0';
|
||||
}
|
||||
buf[pos++] = '\n';
|
||||
ret = pos;
|
||||
leave:
|
||||
mutex_unlock(&chip->lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lp55xx_show_master_fader_leds);
|
||||
|
||||
ssize_t lp55xx_store_master_fader_leds(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
|
||||
struct lp55xx_chip *chip = led->chip;
|
||||
const struct lp55xx_device_config *cfg = chip->cfg;
|
||||
int i, n, ret;
|
||||
u8 val;
|
||||
|
||||
n = min_t(int, len, cfg->max_channel);
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (buf[i] >= '0' && buf[i] <= '3') {
|
||||
val = (buf[i] - '0') << __bf_shf(LP55xx_FADER_MAPPING_MASK);
|
||||
ret = lp55xx_update_bits(chip,
|
||||
cfg->reg_led_ctrl_base.addr + i,
|
||||
LP55xx_FADER_MAPPING_MASK,
|
||||
val);
|
||||
if (ret)
|
||||
goto leave;
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
ret = len;
|
||||
leave:
|
||||
mutex_unlock(&chip->lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lp55xx_store_master_fader_leds);
|
||||
|
||||
static struct attribute *lp55xx_engine_attributes[] = {
|
||||
&dev_attr_select_engine.attr,
|
||||
&dev_attr_run_engine.attr,
|
||||
|
@ -76,6 +76,22 @@ static ssize_t store_engine##nr##_load(struct device *dev, \
|
||||
} \
|
||||
static LP55XX_DEV_ATTR_WO(engine##nr##_load, store_engine##nr##_load)
|
||||
|
||||
#define LP55XX_DEV_ATTR_MASTER_FADER(nr) \
|
||||
static ssize_t show_master_fader##nr(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
char *buf) \
|
||||
{ \
|
||||
return lp55xx_show_master_fader(dev, attr, buf, nr); \
|
||||
} \
|
||||
static ssize_t store_master_fader##nr(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
const char *buf, size_t len) \
|
||||
{ \
|
||||
return lp55xx_store_master_fader(dev, attr, buf, len, nr); \
|
||||
} \
|
||||
static LP55XX_DEV_ATTR_RW(master_fader##nr, show_master_fader##nr, \
|
||||
store_master_fader##nr)
|
||||
|
||||
struct lp55xx_led;
|
||||
struct lp55xx_chip;
|
||||
|
||||
@ -103,6 +119,8 @@ struct lp55xx_reg {
|
||||
* @prog_mem_base : Chip specific base reg address for chip SMEM programming
|
||||
* @reg_led_pwm_base : Chip specific base reg address for LED PWM conf
|
||||
* @reg_led_current_base : Chip specific base reg address for LED current conf
|
||||
* @reg_master_fader_base : Chip specific base reg address for master fader base
|
||||
* @reg_led_ctrl_base : Chip specific base reg address for LED ctrl base
|
||||
* @pages_per_engine : Assigned pages for each engine
|
||||
* (if not set chip doesn't support pages)
|
||||
* @max_channel : Maximum number of channels
|
||||
@ -123,6 +141,8 @@ struct lp55xx_device_config {
|
||||
const struct lp55xx_reg prog_mem_base;
|
||||
const struct lp55xx_reg reg_led_pwm_base;
|
||||
const struct lp55xx_reg reg_led_current_base;
|
||||
const struct lp55xx_reg reg_master_fader_base;
|
||||
const struct lp55xx_reg reg_led_ctrl_base;
|
||||
const int pages_per_engine;
|
||||
const int max_channel;
|
||||
|
||||
@ -244,5 +264,17 @@ extern ssize_t lp55xx_show_engine_leds(struct device *dev,
|
||||
extern ssize_t lp55xx_store_engine_leds(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len, int nr);
|
||||
extern ssize_t lp55xx_show_master_fader(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf, int nr);
|
||||
extern ssize_t lp55xx_store_master_fader(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len, int nr);
|
||||
extern ssize_t lp55xx_show_master_fader_leds(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf);
|
||||
extern ssize_t lp55xx_store_master_fader_leds(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len);
|
||||
|
||||
#endif /* _LEDS_LP55XX_COMMON_H */
|
||||
|
Loading…
Reference in New Issue
Block a user