qcom: ipq4019: Add LDO regulator driver for SDHC controller
PATCH 2/2 qcom: ipq4019: Add LDO regulator driver for SDHC controller
From: Kirthik Srinivasan <[email protected]>
Add LDO regulator driver to enable SD /MMC card to switch between 3.0 volts and 1.8 volts
--- drivers/regulator/Kconfig | 7 + drivers/regulator/Makefile | 1 + drivers/regulator/ipq4019-regulator.c | 275 ++++++++++++++++++++++++++++++++++ 3 files changed, 283 insertions(+) create mode 100644 drivers/regulator/ipq4019-regulator.c
drivers/regulator/Kconfig +7 -0
@@ -843,5 +843,12 @@ config REGULATOR_WM8994 This driver provides support for the voltage regulators on the WM8994 CODEC. +config REGULATOR_IPQ4019 + tristate "IPQ4019 regulator support" + depends on ARCH_QCOM + help + This driver provides support for the voltage regulators of the + IPQ40xx devices. + endif
drivers/regulator/Makefile +1 -0
@@ -108,6 +108,7 @@ obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o +obj-$(CONFIG_REGULATOR_IPQ4019) += ipq4019-regulator.o ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
drivers/regulator/ipq4019-regulator.c new file +275 -0
275 lines not on this page · raw message
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Quoted 5 lines · Sreedhar Sambangi
From: Kirthik Srinivasan <[email protected]>
Add LDO regulator driver to enable SD /MMC card to switch between 3.0 volts and 1.8 volts
Quoted 8 lines
Change-Id I66f770878570b1f5b1db044ba626e0f6989acc3fSigned-off-by Kirthik Srinivasan <[email protected]>Signed-off-by Rajith Cherian <[email protected]>Signed-off-by Sreedhar Sambangi <[email protected]>--- drivers/regulator/Kconfig | 7 + drivers/regulator/Makefile | 1 + drivers/regulator/ipq4019-regulator.c | 275 ++++++++++++++++++++++++++++++++++
It'd be good to have the file name have qcom prepended. See the other qcom regulators as an example.
drivers/regulator/Kconfig config REGULATOR_WM8994 · line 846
Quoted 12 lines
3 files changed, 283 insertions(+) create mode 100644 drivers/regulator/ipq4019-regulator.cdrivers/regulator/Kconfig +1
-0@@ -843,5 +843,12 @@ config REGULATOR_WM8994 This driver provides support for the voltage regulators on the WM8994 CODEC. +config REGULATOR_IPQ4019
How bout REGULATOR_QCOM_IPQ4019.
Quoted 8 lines
drivers/regulator/Kconfig +6
-0+ tristate "IPQ4019 regulator support" + depends on ARCH_QCOM + help + This driver provides support for the voltage regulators of the + IPQ40xx devices. + endif
<snip>
Quoted 13 lines
drivers/regulator/Kconfig +13
-0+static int ipq4019_regulator_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, + unsigned *selector) +{ + struct ipq4019_regulator_data *data = rdev_get_drvdata(dev); + struct ipq4019_regulator_config *cfg = data->config; + + int ptr, best_val = INT_MAX, val; + + for (ptr = 0; ptr < cfg->nr_states; ptr++) + if (cfg->states[ptr].range < best_val && + cfg->states[ptr].range >= min_uV && + cfg->states[ptr].range <= max_uV) {
drivers/regulator/Kconfig
Quoted 10 lines
drivers/regulator/Kconfig +10
-0+ best_val = cfg->states[ptr].value; + if (selector) + *selector = ptr; + } + + if (best_val == INT_MAX) + return -EINVAL; + + val = readl(cfg->base); + val = val & (~(cfg->mask));
val &= mask
Quoted 7 lines
drivers/regulator/Kconfig +7
-0+ writel((val | best_val), cfg->base); + + data->range = cfg->states[ptr].range; + + return 0; +} +
drivers/regulator/Kconfig
Quoted 10 lines
drivers/regulator/Kconfig +10
-0+static int ipq4019_regulator_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + struct ipq4019_regulator_data *data = rdev_get_drvdata(dev); + struct ipq4019_regulator_config *cfg = data->config; + + if (selector >= cfg->nr_states) + return -EINVAL; + + return cfg->states[selector].range;
If you can define your ranges using LINEAR_RANGE, you can just use the regulator_list_voltage_linear_range.
drivers/regulator/Kconfig
Quoted 6 lines
drivers/regulator/Kconfig +6
-0+} + +static struct regulator_ops ipq4019_regulator_voltage_ops = { + .get_voltage = ipq4019_regulator_get_voltage, + .set_voltage = ipq4019_regulator_set_voltage, + .list_voltage = ipq4019_regulator_list_voltage,
No enable and disable?
Quoted 35 lines
drivers/regulator/Kconfig +35
-0+}; + +static struct ipq4019_regulator_config * +of_get_ipq4019_regulator_data(struct device *dev, struct device_node *np, const struct regulator_desc *desc) +{ + struct ipq4019_regulator_config *config; + struct property *prop; + int proplen, i; + + config = devm_kzalloc(dev, + sizeof(struct ipq4019_regulator_config), + GFP_KERNEL); + if (!config) + return ERR_PTR(-ENOMEM); + + config->init_data = of_get_regulator_init_data(dev, np, desc); + if (!config->init_data) + return ERR_PTR(-EINVAL); + + config->supply_name = config->init_data->constraints.name; + + + /* Fetch states. */ + prop = of_find_property(np, "states", NULL); + if (!prop) { + dev_err(dev, "No 'states' property found\n"); + return ERR_PTR(-EINVAL); + } + + proplen = prop->length / sizeof(int); + + config->states = devm_kzalloc(dev, + sizeof(struct ipq4019_regulator_state) + * (proplen / 2), + GFP_KERNEL);
drivers/regulator/Kconfig
Quoted 10 lines
drivers/regulator/Kconfig +10
-0+ if (!config->states) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < proplen / 2; i++) { + config->states[i].range = + be32_to_cpup((int *)prop->value + (i * 2)); + config->states[i].value = + be32_to_cpup((int *)prop->value + (i * 2 + 1)); + } + config->nr_states = i;
Is it necessary to encode all of this data in the DT? Is this varied between boards using the IPQ4019? Or are these values fixed for this chip? If they are fixed, it'd be better to put the data in a static structure or see if the REGULATOR_LINEAR_RANGE would work for you.
drivers/regulator/Kconfig
Quoted 13 lines
drivers/regulator/Kconfig +13
-0+ + prop = of_find_property(np, "mask", NULL); + if (!prop) { + dev_err(dev, "No 'states' property found\n"); + return ERR_PTR(-EINVAL); + } + + config->mask = be32_to_cpup((int *)prop->value); + config->type = REGULATOR_VOLTAGE; + + return config; +} +
<snip>
How many of these LDOs are being provided?
Regards,
Andy Gross
Quoted 16 lines · Andy Gross
Quoted 9 lines · Sreedhar Sambangi
From: Kirthik Srinivasan <[email protected]>
Add LDO regulator driver to enable SD /MMC card to switch between 3.0 volts and 1.8 volts
Change-Id I66f770878570b1f5b1db044ba626e0f6989acc3fSigned-off-by Kirthik Srinivasan <[email protected]>Signed-off-by Rajith Cherian <[email protected]>Signed-off-by Sreedhar Sambangi <[email protected]>Quoted 5 lines
--- drivers/regulator/Kconfig | 7 + drivers/regulator/Makefile | 1 + drivers/regulator/ipq4019-regulator.c | 275++++++++++++++++++++++++++++++++++
Quoted 2 lines
It'd be good to have the file name have qcom prepended. See the other qcom regulators as an example.
Sure, but is it reasonable to say qcom_ipq4019-regulator ? Since as of now ,this regulator driver is supporting only ipq4019 SOC.
Quoted 12 lines
Quoted 12 lines
3 files changed, 283 insertions(+) create mode 100644 drivers/regulator/ipq4019-regulator.cdrivers/regulator/Kconfig +0
-0@@ -843,5 +843,12 @@ config REGULATOR_WM8994 This driver provides support for the voltage regulators on the WM8994 CODEC.
Quoted 3 lines
drivers/regulator/Kconfig config REGULATOR_WM8994 · line 846
Quoted 1 line
drivers/regulator/Kconfig +1
-0+config REGULATOR_IPQ4019How bout
REGULATOR_QCOM_IPQ4019.
Sounds good, Will update in V2
Quoted 28 lines
Quoted 8 lines
drivers/regulator/Kconfig +6
-0+ tristate "IPQ4019 regulator support" + depends on ARCH_QCOM + help + This driver provides support for the voltage regulators of the + IPQ40xx devices. + endif<snip>
Quoted 17 lines
drivers/regulator/Kconfig +17
-0+static int ipq4019_regulator_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, + unsigned *selector) +{ + struct ipq4019_regulator_data *data = rdev_get_drvdata(dev); + struct ipq4019_regulator_config *cfg = data->config; + + int ptr, best_val = INT_MAX, val; + + for (ptr = 0; ptr < cfg->nr_states; ptr++) + if (cfg->states[ptr].range < best_val && + cfg->states[ptr].range >= min_uV && + cfg->states[ptr].range <= max_uV) { + best_val = cfg->states[ptr].value; + if (selector) + *selector = ptr; + }
Quoted 8 lines
drivers/regulator/Kconfig
Quoted 6 lines
drivers/regulator/Kconfig +6
-0+ + if (best_val == INT_MAX) + return -EINVAL; + + val = readl(cfg->base); + val = val & (~(cfg->mask));val &= mask
Thank you, Will fix this
Quoted 13 lines
Quoted 13 lines
drivers/regulator/Kconfig +12
-0+ writel((val | best_val), cfg->base); + + data->range = cfg->states[ptr].range; + + return 0; +} + +static int ipq4019_regulator_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + struct ipq4019_regulator_data *data = rdev_get_drvdata(dev); + struct ipq4019_regulator_config *cfg = data->config;
Quoted 8 lines
drivers/regulator/Kconfig
Quoted 5 lines
drivers/regulator/Kconfig +5
-0+ + if (selector >= cfg->nr_states) + return -EINVAL; + + return cfg->states[selector].range;If you can define your ranges using
LINEAR_RANGE, you can just use theregulator_list_voltage_linear_range.
Since we are supporting only two states , haven't gone through the approach of LINEAR_RANGE.but sure will look in to it.
Quoted 9 lines
drivers/regulator/Kconfig
Quoted 7 lines
drivers/regulator/Kconfig +6
-0+} + +static struct regulator_ops ipq4019_regulator_voltage_ops = { + .get_voltage = ipq4019_regulator_get_voltage, + .set_voltage = ipq4019_regulator_set_voltage, + .list_voltage = ipq4019_regulator_list_voltage,No enable and disable?
There is no such states like enable and disable.
Quoted 71 lines
Quoted 37 lines
drivers/regulator/Kconfig +4
-0+}; + +static struct ipq4019_regulator_config * +of_get_ipq4019_regulator_data(struct device *dev, struct device_node*np, const struct
regulator_desc*desc)drivers/regulator/Kconfig +31
-0+{ + struct ipq4019_regulator_config *config; + struct property *prop; + int proplen, i; + + config = devm_kzalloc(dev, + sizeof(struct ipq4019_regulator_config), + GFP_KERNEL); + if (!config) + return ERR_PTR(-ENOMEM); + + config->init_data = of_get_regulator_init_data(dev, np, desc); + if (!config->init_data) + return ERR_PTR(-EINVAL); + + config->supply_name = config->init_data->constraints.name; + + + /* Fetch states. */ + prop = of_find_property(np, "states", NULL); + if (!prop) { + dev_err(dev, "No 'states' property found\n"); + return ERR_PTR(-EINVAL); + } + + proplen = prop->length / sizeof(int); + + config->states = devm_kzalloc(dev, + sizeof(struct ipq4019_regulator_state) + * (proplen / 2), + GFP_KERNEL);drivers/regulator/Kconfig
Quoted 10 lines
drivers/regulator/Kconfig +10
-0+ if (!config->states) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < proplen / 2; i++) { + config->states[i].range = + be32_to_cpup((int *)prop->value + (i * 2)); + config->states[i].value = + be32_to_cpup((int *)prop->value + (i * 2 + 1)); + } + config->nr_states = i;Is it necessary to encode all of this data in the DT? Is this varied between boards using the IPQ4019? Or are these values fixed for this chip? If they are fixed, it'd be better to put the data in a static structure or see if the
REGULATOR_LINEAR_RANGEwould work for you.Quoted 13 lines
drivers/regulator/Kconfig +13
-0+ + prop = of_find_property(np, "mask", NULL); + if (!prop) { + dev_err(dev, "No 'states' property found\n"); + return ERR_PTR(-EINVAL); + } + + config->mask = be32_to_cpup((int *)prop->value); + config->type = REGULATOR_VOLTAGE; + + return config; +} +<snip>
Quoted 1 line
How many of these LDOs are being provided?
Only one sw configurabale LDO
Quoted 4 lines
Regards,
Andy Gross
Signature · 1 line
-Sree
Quoted 5 lines · Sreedhar Sambangi
Quoted 3 lines
Quoted 2 lines
+config
REGULATOR_IPQ4019How bout
REGULATOR_QCOM_IPQ4019.Sounds good, Will update in V2
Also prefix the name with “Qualcomm” and insert it in the list in order.
-M--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html