Skip to contentSkip to conversation

qcom: ipq4019: Add LDO regulator driver for SDHC controller

PATCH In review Sreedhar Sambangi 3 participants 4 messages Apr 4, 2016 – Apr 12, 2016

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

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

Change-Id I66f770878570b1f5b1db044ba626e0f6989acc3f
---
 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
index c77dc08..bb44873 100644
@@ -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
index 61bfbb9..3647e8e 100644
@@ -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

#1 lore raw
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 I66f770878570b1f5b1db044ba626e0f6989acc3f
---
 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.c
drivers/regulator/Kconfig +1 -0
index c77dc08..bb44873 100644
@@ -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

#2 lore raw
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 I66f770878570b1f5b1db044ba626e0f6989acc3f
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.c
drivers/regulator/Kconfig +0 -0
index c77dc08..bb44873 100644
@@ -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_IPQ4019

How 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 the regulator_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_RANGE would 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
#3 lore raw
Quoted 5 lines · Sreedhar Sambangi
Quoted 3 lines
Quoted 2 lines

+config REGULATOR_IPQ4019

How 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