summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt20
-rw-r--r--arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi8
-rw-r--r--arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi8
-rw-r--r--drivers/leds/leds-qpnp-flash-v2.c225
4 files changed, 65 insertions, 196 deletions
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt b/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt
index 8365762e520f..2982cec02023 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt
@@ -70,6 +70,8 @@ Optional properties:
0: Flash strobe is used for LED1, LED2, LED3
1: Flash strobe is used for LED1, LED2 and GPIO10 is used for LED3
2: Flash strobe is used for LED1; GPIO9 is used for LED2; GPIO10 is used for LED3
+- switchX-supply : phandle of the regulator that needs to be used
+ as a supply for flash switch_X device.
Child node: Contains settings for each individual LED. Each LED channel needs a flash node and
torch node for itself, and an individual switch node to serve as an overall switch.
@@ -126,15 +128,6 @@ Optional properties:
be edge triggered. Otherwise, it is level triggered.
- qcom,hw-strobe-active-low : Boolean property to select strobe signal polarity. If defined, hw-strobe
signal polarity is set to active-low, else it is active-high.
-- reg<n> : reg<n> (<n> represents number. e.g. 0,1,2,..) subnode is to add support for
- multiple power sources. This subnode should only be specified for switch nodes.
- Required property inside regulator node:
- - regulator-name : Name of the regulator which has to be used for this
- switch node.
- Optional property inside regulator node:
- - max-voltage-uv : This specifies max voltage of regulator. Some switch
- or boost regulator does not need this property.
-
Example:
qcom,leds@d300 {
compatible = "qcom,qpnp-flash-led-v2";
@@ -160,6 +153,7 @@ Example:
qcom,hdrm-auto-mode;
qcom,isc-delay = <192>;
+ switch0-supply = <&pmicobalt_bob>;
pmi8998_flash0: qcom,flash_0 {
label = "flash";
@@ -254,10 +248,6 @@ Example:
qcom,led-mask = <3>;
qcom,default-led-trigger =
"switch0_trigger";
- reg0 {
- regulator-name = "pmicobalt_bob";
- max-voltage-uv = <3600000>;
- };
};
pmi8998_switch1: qcom,led_switch_1 {
@@ -266,10 +256,6 @@ Example:
qcom,led-mask = <4>;
qcom,default-led-trigger =
"switch1_trigger";
- reg0 {
- regulator-name = "pmicobalt_bob";
- max-voltage-uv = <3600000>;
- };
};
};
diff --git a/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi b/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi
index 41589d02f6fc..0e5a999e4642 100644
--- a/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi
@@ -357,10 +357,6 @@
qcom,led-name = "led:switch_0";
qcom,led-mask = <3>;
qcom,default-led-trigger = "switch0_trigger";
- reg0 {
- regulator-name = "pmfalcon_bob";
- max-voltage-uv = <3600000>;
- };
};
pm2falcon_switch1: qcom,led_switch_1 {
@@ -368,10 +364,6 @@
qcom,led-name = "led:switch_1";
qcom,led-mask = <4>;
qcom,default-led-trigger = "switch1_trigger";
- reg0 {
- regulator-name = "pmfalcon_bob";
- max-voltage-uv = <3600000>;
- };
};
};
};
diff --git a/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi b/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi
index b88b0e28c948..640aa53364a5 100644
--- a/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi
@@ -744,10 +744,6 @@
qcom,led-name = "led:switch_0";
qcom,led-mask = <3>;
qcom,default-led-trigger = "switch0_trigger";
- reg0 {
- regulator-name = "pmicobalt_bob";
- max-voltage-uv = <3600000>;
- };
};
pmicobalt_switch1: qcom,led_switch_1 {
@@ -755,10 +751,6 @@
qcom,led-name = "led:switch_1";
qcom,led-mask = <4>;
qcom,default-led-trigger = "switch1_trigger";
- reg0 {
- regulator-name = "pmicobalt_bob";
- max-voltage-uv = <3600000>;
- };
};
};
};
diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c
index 5129f130d70e..80f1d8af5905 100644
--- a/drivers/leds/leds-qpnp-flash-v2.c
+++ b/drivers/leds/leds-qpnp-flash-v2.c
@@ -173,18 +173,12 @@ struct flash_node_data {
bool led_on;
};
-struct flash_regulator_data {
- struct regulator *vreg;
- const char *reg_name;
- u32 max_volt_uv;
-};
struct flash_switch_data {
struct platform_device *pdev;
+ struct regulator *vreg;
struct led_classdev cdev;
- struct flash_regulator_data *reg_data;
int led_mask;
- int num_regulators;
bool regulator_on;
bool enabled;
};
@@ -426,34 +420,27 @@ static int qpnp_flash_led_hw_strobe_enable(struct flash_node_data *fnode,
static int qpnp_flash_led_regulator_enable(struct qpnp_flash_led *led,
struct flash_switch_data *snode, bool on)
{
- int i, rc = 0;
+ int rc = 0;
+
+ if (!snode || !snode->vreg)
+ return 0;
if (snode->regulator_on == on)
return 0;
- if (on == false) {
- i = snode->num_regulators;
- goto out;
- }
+ if (on)
+ rc = regulator_enable(snode->vreg);
+ else
+ rc = regulator_disable(snode->vreg);
- for (i = 0; i < snode->num_regulators; i++) {
- rc = regulator_enable(snode->reg_data[i].vreg);
- if (rc < 0) {
- dev_err(&led->pdev->dev,
- "regulator enable failed, rc=%d\n", rc);
- goto out;
- }
+ if (rc < 0) {
+ dev_err(&led->pdev->dev, "regulator_%s failed, rc=%d\n",
+ on ? "enable" : "disable", rc);
+ return rc;
}
- snode->regulator_on = true;
- return rc;
-
-out:
- while (i--)
- regulator_disable(snode->reg_data[i].vreg);
-
- snode->regulator_on = false;
- return rc;
+ snode->regulator_on = on ? true : false;
+ return 0;
}
static int get_property_from_fg(struct qpnp_flash_led *led,
@@ -835,7 +822,7 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
u8 val, mask;
if (snode->enabled == on) {
- dev_warn(&led->pdev->dev, "Switch node is already %s!\n",
+ dev_dbg(&led->pdev->dev, "Switch node is already %s!\n",
on ? "enabled" : "disabled");
return 0;
}
@@ -1182,104 +1169,6 @@ int qpnp_flash_led_unregister_irq_notifier(struct notifier_block *nb)
return atomic_notifier_chain_unregister(&irq_notifier_list, nb);
}
-static int qpnp_flash_led_regulator_setup(struct qpnp_flash_led *led,
- struct flash_switch_data *snode, bool on)
-{
- int i, rc = 0;
-
- if (on == false) {
- i = snode->num_regulators;
- goto out;
- }
-
- for (i = 0; i < snode->num_regulators; i++) {
- snode->reg_data[i].vreg = regulator_get(snode->cdev.dev,
- snode->reg_data[i].reg_name);
- if (IS_ERR(snode->reg_data[i].vreg)) {
- rc = PTR_ERR(snode->reg_data[i].vreg);
- dev_err(&led->pdev->dev,
- "Failed to get regulator, rc=%d\n", rc);
- goto out;
- }
-
- if (regulator_count_voltages(snode->reg_data[i].vreg) > 0) {
- rc = regulator_set_voltage(snode->reg_data[i].vreg,
- snode->reg_data[i].max_volt_uv,
- snode->reg_data[i].max_volt_uv);
- if (rc < 0) {
- dev_err(&led->pdev->dev,
- "regulator set voltage failed, rc=%d\n",
- rc);
- regulator_put(snode->reg_data[i].vreg);
- goto out;
- }
- }
- }
-
- return rc;
-
-out:
- while (i--) {
- if (regulator_count_voltages(snode->reg_data[i].vreg) > 0)
- regulator_set_voltage(snode->reg_data[i].vreg, 0,
- snode->reg_data[i].max_volt_uv);
-
- regulator_put(snode->reg_data[i].vreg);
- }
-
- return rc;
-}
-
-static int qpnp_flash_led_regulator_parse_dt(struct qpnp_flash_led *led,
- struct flash_switch_data *snode,
- struct device_node *node) {
-
- int i = 0, rc = 0, num_regs = 0;
- struct device_node *temp = NULL;
- const char *temp_string;
- u32 val;
-
- while ((temp = of_get_next_available_child(node, temp))) {
- if (of_find_property(temp, "regulator-name", NULL))
- num_regs++;
- }
- snode->num_regulators = num_regs;
-
- if (snode->num_regulators == 0)
- return 0;
-
- snode->reg_data = devm_kcalloc(&led->pdev->dev, snode->num_regulators,
- sizeof(*snode->reg_data),
- GFP_KERNEL);
- if (!snode->reg_data)
- return -ENOMEM;
-
- for_each_available_child_of_node(node, temp) {
- rc = of_property_read_string(temp, "regulator-name",
- &temp_string);
- if (!rc)
- snode->reg_data[i].reg_name = temp_string;
- else {
- dev_err(&led->pdev->dev,
- "Unable to read regulator name, rc=%d\n", rc);
- return rc;
- }
-
- rc = of_property_read_u32(temp, "max-voltage-uv", &val);
- if (!rc) {
- snode->reg_data[i].max_volt_uv = val;
- } else if (rc != -EINVAL) {
- dev_err(&led->pdev->dev,
- "Unable to read max voltage, rc=%d\n", rc);
- return rc;
- }
-
- i++;
- }
-
- return 0;
-}
-
static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
struct flash_node_data *fnode, struct device_node *node)
{
@@ -1466,7 +1355,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
fnode->pinctrl = devm_pinctrl_get(fnode->cdev.dev);
if (IS_ERR_OR_NULL(fnode->pinctrl)) {
- dev_warn(&led->pdev->dev, "No pinctrl defined\n");
+ dev_dbg(&led->pdev->dev, "No pinctrl defined\n");
fnode->pinctrl = NULL;
} else {
fnode->gpio_state_active =
@@ -1497,7 +1386,8 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led,
struct flash_switch_data *snode,
struct device_node *node)
{
- int rc = 0;
+ int rc = 0, num;
+ char reg_name[16], reg_sup_name[16];
rc = of_property_read_string(node, "qcom,led-name", &snode->cdev.name);
if (rc < 0) {
@@ -1506,6 +1396,12 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led,
return rc;
}
+ rc = sscanf(snode->cdev.name, "led:switch_%d", &num);
+ if (!rc) {
+ pr_err("No number for switch device?\n");
+ return -EINVAL;
+ }
+
rc = of_property_read_string(node, "qcom,default-led-trigger",
&snode->cdev.default_trigger);
if (rc < 0) {
@@ -1525,18 +1421,16 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led,
return -EINVAL;
}
- rc = qpnp_flash_led_regulator_parse_dt(led, snode, node);
- if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Unable to parse regulator data, rc=%d\n", rc);
- return rc;
- }
-
- if (snode->num_regulators) {
- rc = qpnp_flash_led_regulator_setup(led, snode, true);
- if (rc < 0) {
- dev_err(&led->pdev->dev,
- "Unable to setup regulator, rc=%d\n", rc);
+ scnprintf(reg_name, sizeof(reg_name), "switch%d-supply", num);
+ if (of_find_property(led->pdev->dev.of_node, reg_name, NULL)) {
+ scnprintf(reg_sup_name, sizeof(reg_sup_name), "switch%d", num);
+ snode->vreg = devm_regulator_get(&led->pdev->dev, reg_sup_name);
+ if (IS_ERR_OR_NULL(snode->vreg)) {
+ rc = PTR_ERR(snode->vreg);
+ if (rc != -EPROBE_DEFER)
+ dev_err(&led->pdev->dev, "Failed to get regulator, rc=%d\n",
+ rc);
+ snode->vreg = NULL;
return rc;
}
}
@@ -1889,26 +1783,35 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
return -ENOMEM;
temp = NULL;
- for (i = 0; i < led->num_fnodes; i++) {
- temp = of_get_next_available_child(node, temp);
- rc = qpnp_flash_led_parse_each_led_dt(led,
- &led->fnode[i], temp);
+ i = 0;
+ j = 0;
+ for_each_available_child_of_node(node, temp) {
+ rc = of_property_read_string(temp, "label", &temp_string);
if (rc < 0) {
dev_err(&pdev->dev,
- "Unable to parse flash node %d rc=%d\n", i, rc);
- goto error_led_register;
+ "Failed to parse label, rc=%d\n", rc);
+ return rc;
}
- }
- for (i = 0; i < led->num_snodes; i++) {
- temp = of_get_next_available_child(node, temp);
- rc = qpnp_flash_led_parse_and_register_switch(led,
- &led->snode[i], temp);
- if (rc < 0) {
- dev_err(&pdev->dev,
- "Unable to parse and register switch node, rc=%d\n",
- rc);
- goto error_switch_register;
+ if (!strcmp("flash", temp_string) ||
+ !strcmp("torch", temp_string)) {
+ rc = qpnp_flash_led_parse_each_led_dt(led,
+ &led->fnode[i++], temp);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Unable to parse flash node %d rc=%d\n",
+ i, rc);
+ goto error_led_register;
+ }
+ }
+
+ if (!strcmp("switch", temp_string)) {
+ rc = qpnp_flash_led_parse_and_register_switch(led,
+ &led->snode[j++], temp);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Unable to parse and register switch node, rc=%d\n",
+ rc);
+ goto error_switch_register;
+ }
}
}
@@ -2025,13 +1928,9 @@ static int qpnp_flash_led_remove(struct platform_device *pdev)
sysfs_remove_file(&led->snode[i].cdev.dev->kobj,
&qpnp_flash_led_attrs[j].attr);
- if (led->snode[i].num_regulators) {
- if (led->snode[i].regulator_on)
- qpnp_flash_led_regulator_enable(led,
- &led->snode[i], false);
- qpnp_flash_led_regulator_setup(led,
+ if (led->snode[i].regulator_on)
+ qpnp_flash_led_regulator_enable(led,
&led->snode[i], false);
- }
}
while (i > 0)