- New Functionality
- Prepare and add support for ACPI enumeration; lp855x_bl - Fix-ups - Use Regmap API to conduct endianess conversions; qcom-wled - Remove superfluous code; qcom-wled - Fix formatting issues; qcom-wled - Bug Fixes - Provide error checking/validation of DT supplied strings; qcom-wled - Request dynamic amount of values when reading from DT; qcom-wled - Fix off-by-one issue when reading from DT; qcom-wled -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAmHdeHIACgkQUa+KL4f8 d2HeMg/+Km3libIwVk+UBQxQ6eAMlNQuYtCr3FRD11EqS8dRYrpYR8K7cGyvnnP0 OohJ7wGnMnhvvJlDNZFXBTNfzlx3G6gsiGQ3gcd1U1kbB/oE5cJUU8LWvwaE/cbv 1t5BGNsyDcF9KWiWGRYrneg96FKMQXF8azlxmskxlpIidAup+cGFYVfl5cjP/AHc LNF6RJ0XiuRUQ39eVtyagEcxyHaLYGdmoZZC9sXsoDMY91/DzPRUkQrMJzbpejYC thwKvlpMXiUSC3LXx4Bq0vEi+nScpOWvmC4jvv82IWVYSZ4muJc/QsmBQxJLXmh6 vHXcsUbzdTiqNaRQi7M2pdhJ0VVWP4w+8AW+jSVziuT61m28O/odplxIVTZ4L27k eOp8VSCMNPjoV0Tkhqhv119wJu/E8O1vk8K7k0t+xtNtZZpamUfVoWYrJY35xnaB PVE+SXsEKcJESpHt2Rmpq8x28cUwnGXvDVjtxub6EcGcQw0pZ+UifCZX1wIz5LUK mkqP0VrG70MXtBoN19UGK2YIevxC61DAFViatkk+x4DrVMQnqgn/a3YtJBm+I5Me bxgGTbMJeyZ4gAbSJ6ZCOeR2gukE1UoTDmB74bc7dYrRqXSrxhwm+G6nQefjs6OY FLmx8p3kCHQS34yWHGH4eKxeeKBC1m/GI2U8zPe0E5VIczDeNhY= =Iq3N -----END PGP SIGNATURE----- Merge tag 'backlight-next-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight Pull backlight updates from Lee Jones: "New Functionality: - Prepare and add support for ACPI enumeration; lp855x_bl Fix-ups: - Use Regmap API to conduct endianess conversions; qcom-wled - Remove superfluous code; qcom-wled - Fix formatting issues; qcom-wled Bug Fixes: - Provide error checking/validation of DT supplied strings; qcom-wled - Request dynamic amount of values when reading from DT; qcom-wled - Fix off-by-one issue when reading from DT; qcom-wled" * tag 'backlight-next-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight: backlight: qcom-wled: Respect enabled-strings in set_brightness backlight: qcom-wled: Remove unnecessary double whitespace backlight: qcom-wled: Provide enabled_strings default for WLED 4 and 5 backlight: qcom-wled: Remove unnecessary 4th default string in WLED3 backlight: qcom-wled: Override default length with qcom,enabled-strings backlight: qcom-wled: Fix off-by-one maximum with default num_strings backlight: qcom-wled: Use cpu_to_le16 macro to perform conversion backlight: qcom-wled: Pass number of elements to read to read_u32_array backlight: qcom-wled: Validate enabled string indices in DT backlight: lp855x: Add support ACPI enumeration backlight: lp855x: Add dev helper variable to lp855x_probe() backlight: lp855x: Move device_config setting out of lp855x_configure()
This commit is contained in:
commit
1cc8d14c41
|
@ -5,6 +5,7 @@
|
|||
* Copyright (C) 2011 Texas Instruments
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/i2c.h>
|
||||
|
@ -170,22 +171,6 @@ static int lp855x_configure(struct lp855x *lp)
|
|||
int i, ret;
|
||||
struct lp855x_platform_data *pd = lp->pdata;
|
||||
|
||||
switch (lp->chip_id) {
|
||||
case LP8550:
|
||||
case LP8551:
|
||||
case LP8552:
|
||||
case LP8553:
|
||||
case LP8556:
|
||||
lp->cfg = &lp855x_dev_cfg;
|
||||
break;
|
||||
case LP8555:
|
||||
case LP8557:
|
||||
lp->cfg = &lp8557_dev_cfg;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (lp->cfg->pre_init_device) {
|
||||
ret = lp->cfg->pre_init_device(lp);
|
||||
if (ret) {
|
||||
|
@ -346,7 +331,7 @@ static int lp855x_parse_dt(struct lp855x *lp)
|
|||
{
|
||||
struct device *dev = lp->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct lp855x_platform_data *pdata;
|
||||
struct lp855x_platform_data *pdata = lp->pdata;
|
||||
int rom_length;
|
||||
|
||||
if (!node) {
|
||||
|
@ -354,10 +339,6 @@ static int lp855x_parse_dt(struct lp855x *lp)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return -ENOMEM;
|
||||
|
||||
of_property_read_string(node, "bl-name", &pdata->name);
|
||||
of_property_read_u8(node, "dev-ctrl", &pdata->device_control);
|
||||
of_property_read_u8(node, "init-brt", &pdata->initial_brightness);
|
||||
|
@ -384,8 +365,6 @@ static int lp855x_parse_dt(struct lp855x *lp)
|
|||
pdata->rom_data = &rom[0];
|
||||
}
|
||||
|
||||
lp->pdata = pdata;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
@ -395,28 +374,89 @@ static int lp855x_parse_dt(struct lp855x *lp)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int lp855x_parse_acpi(struct lp855x *lp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* On ACPI the device has already been initialized by the firmware
|
||||
* and is in register mode, so we can read back the settings from
|
||||
* the registers.
|
||||
*/
|
||||
ret = i2c_smbus_read_byte_data(lp->client, lp->cfg->reg_brightness);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
lp->pdata->initial_brightness = ret;
|
||||
|
||||
ret = i2c_smbus_read_byte_data(lp->client, lp->cfg->reg_devicectrl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
lp->pdata->device_control = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
|
||||
{
|
||||
const struct acpi_device_id *acpi_id = NULL;
|
||||
struct device *dev = &cl->dev;
|
||||
struct lp855x *lp;
|
||||
int ret;
|
||||
|
||||
if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
|
||||
return -EIO;
|
||||
|
||||
lp = devm_kzalloc(&cl->dev, sizeof(struct lp855x), GFP_KERNEL);
|
||||
lp = devm_kzalloc(dev, sizeof(struct lp855x), GFP_KERNEL);
|
||||
if (!lp)
|
||||
return -ENOMEM;
|
||||
|
||||
lp->client = cl;
|
||||
lp->dev = &cl->dev;
|
||||
lp->dev = dev;
|
||||
lp->pdata = dev_get_platdata(dev);
|
||||
|
||||
if (id) {
|
||||
lp->chipname = id->name;
|
||||
lp->chip_id = id->driver_data;
|
||||
lp->pdata = dev_get_platdata(&cl->dev);
|
||||
} else {
|
||||
acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
|
||||
if (!acpi_id)
|
||||
return -ENODEV;
|
||||
|
||||
lp->chipname = acpi_id->id;
|
||||
lp->chip_id = acpi_id->driver_data;
|
||||
}
|
||||
|
||||
switch (lp->chip_id) {
|
||||
case LP8550:
|
||||
case LP8551:
|
||||
case LP8552:
|
||||
case LP8553:
|
||||
case LP8556:
|
||||
lp->cfg = &lp855x_dev_cfg;
|
||||
break;
|
||||
case LP8555:
|
||||
case LP8557:
|
||||
lp->cfg = &lp8557_dev_cfg;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!lp->pdata) {
|
||||
lp->pdata = devm_kzalloc(dev, sizeof(*lp->pdata), GFP_KERNEL);
|
||||
if (!lp->pdata)
|
||||
return -ENOMEM;
|
||||
|
||||
if (id) {
|
||||
ret = lp855x_parse_dt(lp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
ret = lp855x_parse_acpi(lp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (lp->pdata->period_ns > 0)
|
||||
|
@ -424,30 +464,27 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
|
|||
else
|
||||
lp->mode = REGISTER_BASED;
|
||||
|
||||
lp->supply = devm_regulator_get(lp->dev, "power");
|
||||
lp->supply = devm_regulator_get(dev, "power");
|
||||
if (IS_ERR(lp->supply)) {
|
||||
if (PTR_ERR(lp->supply) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
lp->supply = NULL;
|
||||
}
|
||||
|
||||
lp->enable = devm_regulator_get_optional(lp->dev, "enable");
|
||||
lp->enable = devm_regulator_get_optional(dev, "enable");
|
||||
if (IS_ERR(lp->enable)) {
|
||||
ret = PTR_ERR(lp->enable);
|
||||
if (ret == -ENODEV) {
|
||||
lp->enable = NULL;
|
||||
} else {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(lp->dev, "error getting enable regulator: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
return dev_err_probe(dev, ret, "getting enable regulator\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (lp->supply) {
|
||||
ret = regulator_enable(lp->supply);
|
||||
if (ret < 0) {
|
||||
dev_err(&cl->dev, "failed to enable supply: %d\n", ret);
|
||||
dev_err(dev, "failed to enable supply: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -455,7 +492,7 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
|
|||
if (lp->enable) {
|
||||
ret = regulator_enable(lp->enable);
|
||||
if (ret < 0) {
|
||||
dev_err(lp->dev, "failed to enable vddio: %d\n", ret);
|
||||
dev_err(dev, "failed to enable vddio: %d\n", ret);
|
||||
goto disable_supply;
|
||||
}
|
||||
|
||||
|
@ -470,20 +507,19 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
|
|||
|
||||
ret = lp855x_configure(lp);
|
||||
if (ret) {
|
||||
dev_err(lp->dev, "device config err: %d", ret);
|
||||
dev_err(dev, "device config err: %d", ret);
|
||||
goto disable_vddio;
|
||||
}
|
||||
|
||||
ret = lp855x_backlight_register(lp);
|
||||
if (ret) {
|
||||
dev_err(lp->dev,
|
||||
"failed to register backlight. err: %d\n", ret);
|
||||
dev_err(dev, "failed to register backlight. err: %d\n", ret);
|
||||
goto disable_vddio;
|
||||
}
|
||||
|
||||
ret = sysfs_create_group(&lp->dev->kobj, &lp855x_attr_group);
|
||||
ret = sysfs_create_group(&dev->kobj, &lp855x_attr_group);
|
||||
if (ret) {
|
||||
dev_err(lp->dev, "failed to register sysfs. err: %d\n", ret);
|
||||
dev_err(dev, "failed to register sysfs. err: %d\n", ret);
|
||||
goto disable_vddio;
|
||||
}
|
||||
|
||||
|
@ -540,10 +576,20 @@ static const struct i2c_device_id lp855x_ids[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(i2c, lp855x_ids);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static const struct acpi_device_id lp855x_acpi_match[] = {
|
||||
/* Xiaomi specific HID used for the LP8556 on the Mi Pad 2 */
|
||||
{ "XMCC0001", LP8556 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, lp855x_acpi_match);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver lp855x_driver = {
|
||||
.driver = {
|
||||
.name = "lp855x",
|
||||
.of_match_table = of_match_ptr(lp855x_dt_ids),
|
||||
.acpi_match_table = ACPI_PTR(lp855x_acpi_match),
|
||||
},
|
||||
.probe = lp855x_probe,
|
||||
.remove = lp855x_remove,
|
||||
|
|
|
@ -231,14 +231,14 @@ struct wled {
|
|||
static int wled3_set_brightness(struct wled *wled, u16 brightness)
|
||||
{
|
||||
int rc, i;
|
||||
u8 v[2];
|
||||
__le16 v;
|
||||
|
||||
v[0] = brightness & 0xff;
|
||||
v[1] = (brightness >> 8) & 0xf;
|
||||
v = cpu_to_le16(brightness & WLED3_SINK_REG_BRIGHT_MAX);
|
||||
|
||||
for (i = 0; i < wled->cfg.num_strings; ++i) {
|
||||
rc = regmap_bulk_write(wled->regmap, wled->ctrl_addr +
|
||||
WLED3_SINK_REG_BRIGHT(i), v, 2);
|
||||
WLED3_SINK_REG_BRIGHT(wled->cfg.enabled_strings[i]),
|
||||
&v, sizeof(v));
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
@ -250,18 +250,18 @@ static int wled4_set_brightness(struct wled *wled, u16 brightness)
|
|||
{
|
||||
int rc, i;
|
||||
u16 low_limit = wled->max_brightness * 4 / 1000;
|
||||
u8 v[2];
|
||||
__le16 v;
|
||||
|
||||
/* WLED4's lower limit of operation is 0.4% */
|
||||
if (brightness > 0 && brightness < low_limit)
|
||||
brightness = low_limit;
|
||||
|
||||
v[0] = brightness & 0xff;
|
||||
v[1] = (brightness >> 8) & 0xf;
|
||||
v = cpu_to_le16(brightness & WLED3_SINK_REG_BRIGHT_MAX);
|
||||
|
||||
for (i = 0; i < wled->cfg.num_strings; ++i) {
|
||||
rc = regmap_bulk_write(wled->regmap, wled->sink_addr +
|
||||
WLED4_SINK_REG_BRIGHT(i), v, 2);
|
||||
WLED4_SINK_REG_BRIGHT(wled->cfg.enabled_strings[i]),
|
||||
&v, sizeof(v));
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
@ -273,21 +273,20 @@ static int wled5_set_brightness(struct wled *wled, u16 brightness)
|
|||
{
|
||||
int rc, offset;
|
||||
u16 low_limit = wled->max_brightness * 1 / 1000;
|
||||
u8 v[2];
|
||||
__le16 v;
|
||||
|
||||
/* WLED5's lower limit is 0.1% */
|
||||
if (brightness < low_limit)
|
||||
brightness = low_limit;
|
||||
|
||||
v[0] = brightness & 0xff;
|
||||
v[1] = (brightness >> 8) & 0x7f;
|
||||
v = cpu_to_le16(brightness & WLED5_SINK_REG_BRIGHT_MAX_15B);
|
||||
|
||||
offset = (wled->cfg.mod_sel == MOD_A) ?
|
||||
WLED5_SINK_REG_MOD_A_BRIGHTNESS_LSB :
|
||||
WLED5_SINK_REG_MOD_B_BRIGHTNESS_LSB;
|
||||
|
||||
rc = regmap_bulk_write(wled->regmap, wled->sink_addr + offset,
|
||||
v, 2);
|
||||
&v, sizeof(v));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -572,7 +571,7 @@ unlock_mutex:
|
|||
|
||||
static void wled_auto_string_detection(struct wled *wled)
|
||||
{
|
||||
int rc = 0, i, delay_time_us;
|
||||
int rc = 0, i, j, delay_time_us;
|
||||
u32 sink_config = 0;
|
||||
u8 sink_test = 0, sink_valid = 0, val;
|
||||
bool fault_set;
|
||||
|
@ -619,14 +618,15 @@ static void wled_auto_string_detection(struct wled *wled)
|
|||
|
||||
/* Iterate through the strings one by one */
|
||||
for (i = 0; i < wled->cfg.num_strings; i++) {
|
||||
sink_test = BIT((WLED4_SINK_REG_CURR_SINK_SHFT + i));
|
||||
j = wled->cfg.enabled_strings[i];
|
||||
sink_test = BIT((WLED4_SINK_REG_CURR_SINK_SHFT + j));
|
||||
|
||||
/* Enable feedback control */
|
||||
rc = regmap_write(wled->regmap, wled->ctrl_addr +
|
||||
WLED3_CTRL_REG_FEEDBACK_CONTROL, i + 1);
|
||||
WLED3_CTRL_REG_FEEDBACK_CONTROL, j + 1);
|
||||
if (rc < 0) {
|
||||
dev_err(wled->dev, "Failed to enable feedback for SINK %d rc = %d\n",
|
||||
i + 1, rc);
|
||||
j + 1, rc);
|
||||
goto failed_detect;
|
||||
}
|
||||
|
||||
|
@ -635,7 +635,7 @@ static void wled_auto_string_detection(struct wled *wled)
|
|||
WLED4_SINK_REG_CURR_SINK, sink_test);
|
||||
if (rc < 0) {
|
||||
dev_err(wled->dev, "Failed to configure SINK %d rc=%d\n",
|
||||
i + 1, rc);
|
||||
j + 1, rc);
|
||||
goto failed_detect;
|
||||
}
|
||||
|
||||
|
@ -662,7 +662,7 @@ static void wled_auto_string_detection(struct wled *wled)
|
|||
|
||||
if (fault_set)
|
||||
dev_dbg(wled->dev, "WLED OVP fault detected with SINK %d\n",
|
||||
i + 1);
|
||||
j + 1);
|
||||
else
|
||||
sink_valid |= sink_test;
|
||||
|
||||
|
@ -702,15 +702,16 @@ static void wled_auto_string_detection(struct wled *wled)
|
|||
/* Enable valid sinks */
|
||||
if (wled->version == 4) {
|
||||
for (i = 0; i < wled->cfg.num_strings; i++) {
|
||||
j = wled->cfg.enabled_strings[i];
|
||||
if (sink_config &
|
||||
BIT(WLED4_SINK_REG_CURR_SINK_SHFT + i))
|
||||
BIT(WLED4_SINK_REG_CURR_SINK_SHFT + j))
|
||||
val = WLED4_SINK_REG_STR_MOD_MASK;
|
||||
else
|
||||
/* Disable modulator_en for unused sink */
|
||||
val = 0;
|
||||
|
||||
rc = regmap_write(wled->regmap, wled->sink_addr +
|
||||
WLED4_SINK_REG_STR_MOD_EN(i), val);
|
||||
WLED4_SINK_REG_STR_MOD_EN(j), val);
|
||||
if (rc < 0) {
|
||||
dev_err(wled->dev, "Failed to configure MODULATOR_EN rc=%d\n",
|
||||
rc);
|
||||
|
@ -949,7 +950,7 @@ static const struct wled_config wled3_config_defaults = {
|
|||
.cs_out_en = false,
|
||||
.ext_gen = false,
|
||||
.cabc = false,
|
||||
.enabled_strings = {0, 1, 2, 3},
|
||||
.enabled_strings = {0, 1, 2},
|
||||
};
|
||||
|
||||
static int wled4_setup(struct wled *wled)
|
||||
|
@ -1080,6 +1081,7 @@ static const struct wled_config wled4_config_defaults = {
|
|||
.cabc = false,
|
||||
.external_pfet = false,
|
||||
.auto_detection_enabled = false,
|
||||
.enabled_strings = {0, 1, 2, 3},
|
||||
};
|
||||
|
||||
static int wled5_setup(struct wled *wled)
|
||||
|
@ -1193,6 +1195,7 @@ static const struct wled_config wled5_config_defaults = {
|
|||
.cabc = false,
|
||||
.external_pfet = false,
|
||||
.auto_detection_enabled = false,
|
||||
.enabled_strings = {0, 1, 2, 3},
|
||||
};
|
||||
|
||||
static const u32 wled3_boost_i_limit_values[] = {
|
||||
|
@ -1256,21 +1259,6 @@ static const struct wled_var_cfg wled5_ovp_cfg = {
|
|||
.size = 16,
|
||||
};
|
||||
|
||||
static u32 wled3_num_strings_values_fn(u32 idx)
|
||||
{
|
||||
return idx + 1;
|
||||
}
|
||||
|
||||
static const struct wled_var_cfg wled3_num_strings_cfg = {
|
||||
.fn = wled3_num_strings_values_fn,
|
||||
.size = 3,
|
||||
};
|
||||
|
||||
static const struct wled_var_cfg wled4_num_strings_cfg = {
|
||||
.fn = wled3_num_strings_values_fn,
|
||||
.size = 4,
|
||||
};
|
||||
|
||||
static u32 wled3_switch_freq_values_fn(u32 idx)
|
||||
{
|
||||
return 19200 / (2 * (1 + idx));
|
||||
|
@ -1344,11 +1332,6 @@ static int wled_configure(struct wled *wled)
|
|||
.val_ptr = &cfg->switch_freq,
|
||||
.cfg = &wled3_switch_freq_cfg,
|
||||
},
|
||||
{
|
||||
.name = "qcom,num-strings",
|
||||
.val_ptr = &cfg->num_strings,
|
||||
.cfg = &wled3_num_strings_cfg,
|
||||
},
|
||||
};
|
||||
|
||||
const struct wled_u32_opts wled4_opts[] = {
|
||||
|
@ -1372,11 +1355,6 @@ static int wled_configure(struct wled *wled)
|
|||
.val_ptr = &cfg->switch_freq,
|
||||
.cfg = &wled3_switch_freq_cfg,
|
||||
},
|
||||
{
|
||||
.name = "qcom,num-strings",
|
||||
.val_ptr = &cfg->num_strings,
|
||||
.cfg = &wled4_num_strings_cfg,
|
||||
},
|
||||
};
|
||||
|
||||
const struct wled_u32_opts wled5_opts[] = {
|
||||
|
@ -1400,11 +1378,6 @@ static int wled_configure(struct wled *wled)
|
|||
.val_ptr = &cfg->switch_freq,
|
||||
.cfg = &wled3_switch_freq_cfg,
|
||||
},
|
||||
{
|
||||
.name = "qcom,num-strings",
|
||||
.val_ptr = &cfg->num_strings,
|
||||
.cfg = &wled4_num_strings_cfg,
|
||||
},
|
||||
{
|
||||
.name = "qcom,modulator-sel",
|
||||
.val_ptr = &cfg->mod_sel,
|
||||
|
@ -1523,16 +1496,57 @@ static int wled_configure(struct wled *wled)
|
|||
*bool_opts[i].val_ptr = true;
|
||||
}
|
||||
|
||||
cfg->num_strings = cfg->num_strings + 1;
|
||||
|
||||
string_len = of_property_count_elems_of_size(dev->of_node,
|
||||
"qcom,enabled-strings",
|
||||
sizeof(u32));
|
||||
if (string_len > 0)
|
||||
of_property_read_u32_array(dev->of_node,
|
||||
if (string_len > 0) {
|
||||
if (string_len > wled->max_string_count) {
|
||||
dev_err(dev, "Cannot have more than %d strings\n",
|
||||
wled->max_string_count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32_array(dev->of_node,
|
||||
"qcom,enabled-strings",
|
||||
wled->cfg.enabled_strings,
|
||||
sizeof(u32));
|
||||
string_len);
|
||||
if (rc) {
|
||||
dev_err(dev, "Failed to read %d elements from qcom,enabled-strings: %d\n",
|
||||
string_len, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = 0; i < string_len; ++i) {
|
||||
if (wled->cfg.enabled_strings[i] >= wled->max_string_count) {
|
||||
dev_err(dev,
|
||||
"qcom,enabled-strings index %d at %d is out of bounds\n",
|
||||
wled->cfg.enabled_strings[i], i);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
cfg->num_strings = string_len;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32(dev->of_node, "qcom,num-strings", &val);
|
||||
if (!rc) {
|
||||
if (val < 1 || val > wled->max_string_count) {
|
||||
dev_err(dev, "qcom,num-strings must be between 1 and %d\n",
|
||||
wled->max_string_count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (string_len > 0) {
|
||||
dev_warn(dev, "Only one of qcom,num-strings or qcom,enabled-strings"
|
||||
" should be set\n");
|
||||
if (val > string_len) {
|
||||
dev_err(dev, "qcom,num-strings exceeds qcom,enabled-strings\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
cfg->num_strings = val;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue