summaryrefslogtreecommitdiff
path: root/drivers/regulator/spm-regulator.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/spm-regulator.c')
-rw-r--r--drivers/regulator/spm-regulator.c166
1 files changed, 99 insertions, 67 deletions
diff --git a/drivers/regulator/spm-regulator.c b/drivers/regulator/spm-regulator.c
index 73bea0ada363..839a2b2eb2fa 100644
--- a/drivers/regulator/spm-regulator.c
+++ b/drivers/regulator/spm-regulator.c
@@ -16,11 +16,13 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/regmap.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/spmi.h>
+#include <linux/platform_device.h>
#include <linux/string.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
@@ -122,7 +124,8 @@ static const struct voltage_range hf_range1 = {1550000, 1550000, 3125000,
struct spm_vreg {
struct regulator_desc rdesc;
struct regulator_dev *rdev;
- struct spmi_device *spmi_dev;
+ struct platform_device *pdev;
+ struct regmap *regmap;
const struct voltage_range *range;
int uV;
int last_set_uV;
@@ -196,14 +199,18 @@ static int qpnp_smps_read_voltage(struct spm_vreg *vreg)
{
int rc;
u8 reg = 0;
+ uint val;
- rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
- vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT, &reg, 1);
+ rc = regmap_read(vreg->regmap,
+ vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT,
+ &val);
if (rc) {
- dev_err(&vreg->spmi_dev->dev, "%s: could not read voltage setpoint register, rc=%d\n",
+ dev_err(&vreg->pdev->dev,
+ "%s: could not read voltage setpoint register, rc=%d\n",
__func__, rc);
return rc;
}
+ reg = (u8)val;
vreg->last_set_vlevel = reg;
vreg->last_set_uV = spm_regulator_vlevel_to_uv(vreg, reg);
@@ -215,10 +222,11 @@ static int qpnp_smps_set_mode(struct spm_vreg *vreg, u8 mode)
{
int rc;
- rc = spmi_ext_register_writel(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
- vreg->spmi_base_addr + QPNP_SMPS_REG_MODE, &mode, 1);
+ rc = regmap_write(vreg->regmap,
+ vreg->spmi_base_addr + QPNP_SMPS_REG_MODE, mode);
if (rc)
- dev_err(&vreg->spmi_dev->dev, "%s: could not write to mode register, rc=%d\n",
+ dev_err(&vreg->pdev->dev,
+ "%s: could not write to mode register, rc=%d\n",
__func__, rc);
return rc;
@@ -275,12 +283,11 @@ static int spm_regulator_write_voltage(struct spm_vreg *vreg, int uV)
if (unlikely(vreg->bypass_spm || spm_failed)) {
/* Set voltage control register via SPMI. */
reg = vlevel;
- rc = spmi_ext_register_writel(vreg->spmi_dev->ctrl,
- vreg->spmi_dev->sid,
- vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT,
- &reg, 1);
+ rc = regmap_write(vreg->regmap,
+ vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT,
+ reg);
if (rc) {
- pr_err("%s: spmi_ext_register_writel failed, rc=%d\n",
+ pr_err("%s: regmap_write failed, rc=%d\n",
vreg->rdesc.name, rc);
return rc;
}
@@ -607,10 +614,13 @@ static int qpnp_smps_check_type(struct spm_vreg *vreg)
int rc;
u8 type[2];
- rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
- vreg->spmi_base_addr + QPNP_SMPS_REG_TYPE, type, 2);
+ rc = regmap_bulk_read(vreg->regmap,
+ vreg->spmi_base_addr + QPNP_SMPS_REG_TYPE,
+ type,
+ 2);
if (rc) {
- dev_err(&vreg->spmi_dev->dev, "%s: could not read type register, rc=%d\n",
+ dev_err(&vreg->pdev->dev,
+ "%s: could not read type register, rc=%d\n",
__func__, rc);
return rc;
}
@@ -627,7 +637,8 @@ static int qpnp_smps_check_type(struct spm_vreg *vreg)
&& type[1] == QPNP_HF_SUBTYPE) {
vreg->regulator_type = QPNP_TYPE_HF;
} else {
- dev_err(&vreg->spmi_dev->dev, "%s: invalid type=0x%02X, subtype=0x%02X register pair\n",
+ dev_err(&vreg->pdev->dev,
+ "%s: invalid type=0x%02X, subtype=0x%02X register pair\n",
__func__, type[0], type[1]);
return -ENODEV;
};
@@ -640,21 +651,25 @@ static int qpnp_smps_init_range(struct spm_vreg *vreg,
{
int rc;
u8 reg = 0;
+ uint val;
- rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
- vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_RANGE, &reg, 1);
+ rc = regmap_read(vreg->regmap,
+ vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_RANGE,
+ &val);
if (rc) {
- dev_err(&vreg->spmi_dev->dev, "%s: could not read voltage range register, rc=%d\n",
+ dev_err(&vreg->pdev->dev,
+ "%s: could not read voltage range register, rc=%d\n",
__func__, rc);
return rc;
}
+ reg = (u8)val;
if (reg == 0x00) {
vreg->range = range0;
} else if (reg == 0x01) {
vreg->range = range1;
} else {
- dev_err(&vreg->spmi_dev->dev, "%s: voltage range=%d is invalid\n",
+ dev_err(&vreg->pdev->dev, "%s: voltage range=%d is invalid\n",
__func__, reg);
rc = -EINVAL;
}
@@ -666,14 +681,18 @@ static int qpnp_ult_hf_init_range(struct spm_vreg *vreg)
{
int rc;
u8 reg = 0;
+ uint val;
- rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
- vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT, &reg, 1);
+ rc = regmap_read(vreg->regmap,
+ vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT,
+ &val);
if (rc) {
- dev_err(&vreg->spmi_dev->dev, "%s: could not read voltage range register, rc=%d\n",
+ dev_err(&vreg->pdev->dev,
+ "%s: could not read voltage range register, rc=%d\n",
__func__, rc);
return rc;
}
+ reg = (u8)val;
vreg->range = (reg < ULT_SMPS_RANGE_SPLIT) ? &ult_hf_range0 :
&ult_hf_range1;
@@ -709,8 +728,9 @@ static int qpnp_smps_init_mode(struct spm_vreg *vreg)
{
const char *mode_name;
int rc;
+ uint val;
- rc = of_property_read_string(vreg->spmi_dev->dev.of_node, "qcom,mode",
+ rc = of_property_read_string(vreg->pdev->dev.of_node, "qcom,mode",
&mode_name);
if (!rc) {
if (strcmp("pwm", mode_name) == 0) {
@@ -719,26 +739,28 @@ static int qpnp_smps_init_mode(struct spm_vreg *vreg)
(vreg->regulator_type != QPNP_TYPE_ULT_HF)) {
vreg->init_mode = QPNP_SMPS_MODE_AUTO;
} else {
- dev_err(&vreg->spmi_dev->dev, "%s: unknown regulator mode: %s\n",
+ dev_err(&vreg->pdev->dev,
+ "%s: unknown regulator mode: %s\n",
__func__, mode_name);
return -EINVAL;
}
- rc = spmi_ext_register_writel(vreg->spmi_dev->ctrl,
- vreg->spmi_dev->sid,
- vreg->spmi_base_addr + QPNP_SMPS_REG_MODE,
- &vreg->init_mode, 1);
+ rc = regmap_write(vreg->regmap,
+ vreg->spmi_base_addr + QPNP_SMPS_REG_MODE,
+ *&vreg->init_mode);
if (rc)
- dev_err(&vreg->spmi_dev->dev, "%s: could not write mode register, rc=%d\n",
+ dev_err(&vreg->pdev->dev,
+ "%s: could not write mode register, rc=%d\n",
__func__, rc);
} else {
- rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl,
- vreg->spmi_dev->sid,
- vreg->spmi_base_addr + QPNP_SMPS_REG_MODE,
- &vreg->init_mode, 1);
+ rc = regmap_read(vreg->regmap,
+ vreg->spmi_base_addr + QPNP_SMPS_REG_MODE,
+ &val);
if (rc)
- dev_err(&vreg->spmi_dev->dev, "%s: could not read mode register, rc=%d\n",
+ dev_err(&vreg->pdev->dev,
+ "%s: could not read mode register, rc=%d\n",
__func__, rc);
+ vreg->init_mode = (u8)val;
}
vreg->mode = vreg->init_mode;
@@ -751,14 +773,17 @@ static int qpnp_smps_init_step_rate(struct spm_vreg *vreg)
int rc;
u8 reg = 0;
int step = 0, delay;
+ uint val;
- rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
- vreg->spmi_base_addr + QPNP_SMPS_REG_STEP_CTRL, &reg, 1);
+ rc = regmap_read(vreg->regmap,
+ vreg->spmi_base_addr + QPNP_SMPS_REG_STEP_CTRL, &val);
if (rc) {
- dev_err(&vreg->spmi_dev->dev, "%s: could not read stepping control register, rc=%d\n",
+ dev_err(&vreg->pdev->dev,
+ "%s: could not read stepping control register, rc=%d\n",
__func__, rc);
return rc;
}
+ reg = (u8)val;
/* ULT buck does not support steps */
if (vreg->regulator_type != QPNP_TYPE_ULT_HF)
@@ -858,18 +883,18 @@ static int spm_regulator_avs_register(struct spm_vreg *vreg,
return 0;
}
-static int spm_regulator_probe(struct spmi_device *spmi)
+static int spm_regulator_probe(struct platform_device *pdev)
{
struct regulator_config reg_config = {};
- struct device_node *node = spmi->dev.of_node;
+ struct device_node *node = pdev->dev.of_node;
struct regulator_init_data *init_data;
struct spm_vreg *vreg;
- struct resource *res;
+ unsigned int base;
bool bypass_spm;
int rc;
if (!node) {
- dev_err(&spmi->dev, "%s: device node missing\n", __func__);
+ dev_err(&pdev->dev, "%s: device node missing\n", __func__);
return -ENODEV;
}
@@ -878,27 +903,34 @@ static int spm_regulator_probe(struct spmi_device *spmi)
rc = msm_spm_probe_done();
if (rc) {
if (rc != -EPROBE_DEFER)
- dev_err(&spmi->dev, "%s: spm unavailable, rc=%d\n",
+ dev_err(&pdev->dev,
+ "%s: spm unavailable, rc=%d\n",
__func__, rc);
return rc;
}
}
- vreg = devm_kzalloc(&spmi->dev, sizeof(*vreg), GFP_KERNEL);
+ vreg = devm_kzalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
if (!vreg) {
pr_err("allocation failed.\n");
return -ENOMEM;
}
- vreg->spmi_dev = spmi;
+ vreg->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ if (!vreg->regmap) {
+ dev_err(&pdev->dev, "Couldn't get parent's regmap\n");
+ return -EINVAL;
+ }
+ vreg->pdev = pdev;
vreg->bypass_spm = bypass_spm;
- res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&spmi->dev, "%s: node is missing base address\n",
- __func__);
- return -EINVAL;
+ rc = of_property_read_u32(pdev->dev.of_node, "reg", &base);
+ if (rc < 0) {
+ dev_err(&pdev->dev,
+ "Couldn't find reg in node = %s rc = %d\n",
+ pdev->dev.of_node->full_name, rc);
+ return rc;
}
- vreg->spmi_base_addr = res->start;
+ vreg->spmi_base_addr = base;
rc = qpnp_smps_check_type(vreg);
if (rc)
@@ -906,10 +938,10 @@ static int spm_regulator_probe(struct spmi_device *spmi)
/* Specify CPU 0 as default in order to handle shared regulator case. */
vreg->cpu_num = 0;
- of_property_read_u32(vreg->spmi_dev->dev.of_node, "qcom,cpu-num",
+ of_property_read_u32(vreg->pdev->dev.of_node, "qcom,cpu-num",
&vreg->cpu_num);
- of_property_read_u32(vreg->spmi_dev->dev.of_node, "qcom,recal-mask",
+ of_property_read_u32(vreg->pdev->dev.of_node, "qcom,recal-mask",
&vreg->recal_cluster_mask);
/*
@@ -940,9 +972,9 @@ static int spm_regulator_probe(struct spmi_device *spmi)
if (rc)
return rc;
- init_data = of_get_regulator_init_data(&spmi->dev, node);
+ init_data = of_get_regulator_init_data(&pdev->dev, node);
if (!init_data) {
- dev_err(&spmi->dev, "%s: unable to allocate memory\n",
+ dev_err(&pdev->dev, "%s: unable to allocate memory\n",
__func__);
return -ENOMEM;
}
@@ -953,7 +985,7 @@ static int spm_regulator_probe(struct spmi_device *spmi)
= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE;
if (!init_data->constraints.name) {
- dev_err(&spmi->dev, "%s: node is missing regulator name\n",
+ dev_err(&pdev->dev, "%s: node is missing regulator name\n",
__func__);
return -EINVAL;
}
@@ -967,7 +999,7 @@ static int spm_regulator_probe(struct spmi_device *spmi)
/ vreg->range->step_uV + 1;
vreg->max_step_uV = SPM_REGULATOR_MAX_STEP_UV;
- of_property_read_u32(vreg->spmi_dev->dev.of_node,
+ of_property_read_u32(vreg->pdev->dev.of_node,
"qcom,max-voltage-step", &vreg->max_step_uV);
if (vreg->max_step_uV > SPM_REGULATOR_MAX_STEP_UV)
@@ -977,7 +1009,7 @@ static int spm_regulator_probe(struct spmi_device *spmi)
pr_debug("%s: max single voltage step size=%u uV\n",
vreg->rdesc.name, vreg->max_step_uV);
- reg_config.dev = &spmi->dev;
+ reg_config.dev = &pdev->dev;
reg_config.init_data = init_data;
reg_config.driver_data = vreg;
reg_config.of_node = node;
@@ -985,18 +1017,18 @@ static int spm_regulator_probe(struct spmi_device *spmi)
if (IS_ERR(vreg->rdev)) {
rc = PTR_ERR(vreg->rdev);
- dev_err(&spmi->dev, "%s: regulator_register failed, rc=%d\n",
+ dev_err(&pdev->dev, "%s: regulator_register failed, rc=%d\n",
__func__, rc);
return rc;
}
- rc = spm_regulator_avs_register(vreg, &spmi->dev, node);
+ rc = spm_regulator_avs_register(vreg, &pdev->dev, node);
if (rc) {
regulator_unregister(vreg->rdev);
return rc;
}
- dev_set_drvdata(&spmi->dev, vreg);
+ dev_set_drvdata(&pdev->dev, vreg);
pr_info("name=%s, range=%s, voltage=%d uV, mode=%s, step rate=%d uV/us\n",
vreg->rdesc.name,
@@ -1009,9 +1041,9 @@ static int spm_regulator_probe(struct spmi_device *spmi)
return rc;
}
-static int spm_regulator_remove(struct spmi_device *spmi)
+static int spm_regulator_remove(struct platform_device *pdev)
{
- struct spm_vreg *vreg = dev_get_drvdata(&spmi->dev);
+ struct spm_vreg *vreg = dev_get_drvdata(&pdev->dev);
if (vreg->avs_rdev)
regulator_unregister(vreg->avs_rdev);
@@ -1025,13 +1057,13 @@ static struct of_device_id spm_regulator_match_table[] = {
{}
};
-static const struct spmi_device_id spm_regulator_id[] = {
+static const struct platform_device_id spm_regulator_id[] = {
{ SPM_REGULATOR_DRIVER_NAME, 0 },
{}
};
MODULE_DEVICE_TABLE(spmi, spm_regulator_id);
-static struct spmi_driver spm_regulator_driver = {
+static struct platform_driver spm_regulator_driver = {
.driver = {
.name = SPM_REGULATOR_DRIVER_NAME,
.of_match_table = spm_regulator_match_table,
@@ -1059,13 +1091,13 @@ int __init spm_regulator_init(void)
else
has_registered = true;
- return spmi_driver_register(&spm_regulator_driver);
+ return platform_driver_register(&spm_regulator_driver);
}
EXPORT_SYMBOL(spm_regulator_init);
static void __exit spm_regulator_exit(void)
{
- spmi_driver_unregister(&spm_regulator_driver);
+ platform_driver_unregister(&spm_regulator_driver);
}
arch_initcall(spm_regulator_init);