diff options
Diffstat (limited to 'drivers/regulator/spm-regulator.c')
| -rw-r--r-- | drivers/regulator/spm-regulator.c | 166 |
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, ®, 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, - ®, 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, ®, 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, ®, 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, ®, 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); |
