[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240620210401.22053-18-ansuelsmth@gmail.com>
Date: Thu, 20 Jun 2024 23:03:33 +0200
From: Christian Marangi <ansuelsmth@...il.com>
To: Pavel Machek <pavel@....cz>,
Lee Jones <lee@...nel.org>,
Rob Herring <robh@...nel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@...aro.org>,
Conor Dooley <conor+dt@...nel.org>,
Jacek Anaszewski <jacek.anaszewski@...il.com>,
linux-leds@...r.kernel.org,
devicetree@...r.kernel.org,
linux-kernel@...r.kernel.org
Cc: Christian Marangi <ansuelsmth@...il.com>
Subject: [PATCH v7 17/20] 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@...nel.org>
Signed-off-by: Christian Marangi <ansuelsmth@...il.com>
---
drivers/leds/leds-lp5523.c | 150 +++---------------------------
drivers/leds/leds-lp55xx-common.c | 113 ++++++++++++++++++++++
drivers/leds/leds-lp55xx-common.h | 32 +++++++
3 files changed, 156 insertions(+), 139 deletions(-)
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 9d91c2c5a3eb..1b3ffdc3dfa3 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -315,137 +315,6 @@ static ssize_t lp5523_selftest(struct device *dev,
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,
diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c
index f0b673c61396..dd7630aaa438 100644
--- a/drivers/leds/leds-lp55xx-common.c
+++ b/drivers/leds/leds-lp55xx-common.c
@@ -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 @@ ssize_t lp55xx_store_engine_leds(struct device *dev,
}
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,
diff --git a/drivers/leds/leds-lp55xx-common.h b/drivers/leds/leds-lp55xx-common.h
index 5f2394a6de15..6dcffa0db647 100644
--- a/drivers/leds/leds-lp55xx-common.h
+++ b/drivers/leds/leds-lp55xx-common.h
@@ -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 */
--
2.45.1
Powered by blists - more mailing lists