Lines Matching +full:regulator +full:- +full:soft +full:- +full:start
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
17 #include <linux/regulator/driver.h>
46 /* Soft start strength of a voltage switch type regulator */
56 * struct spmi_regulator_init_data - spmi-regulator initialization data
58 * used to enable the regulator, if any
66 * used to force the regulator into high power
74 * @vs_soft_start_strength: This parameter sets the soft start strength for
78 * then the soft start strength will be left at its
231 /* Common regulator control register layout */
241 /* Common regulator mode register layout */
260 /* Common regulator pull down control register layout */
263 /* LDO regulator current limit control register layout */
266 /* LDO regulator soft start control register layout */
269 /* VS regulator over current protection control register layout */
273 /* VS regulator soft start control register layout */
277 /* Boost regulator current limit control register layout */
291 /* Clock rate in kHz of the FTSMPS regulator reference clock. */
308 /* Clock rate in kHz of the FTSMPS426 regulator reference clock. */
328 * struct spmi_voltage_range - regulator set point voltage mapping description
343 * (max_uV - min_uV) % step_uV == 0
344 * (set_point_min_uV - min_uV) % step_uV == 0*
345 * (set_point_max_uV - min_uV) % step_uV == 0*
346 * n_voltages = (set_point_max_uV - set_point_min_uV) / step_uV + 1
449 * These tables contain the physically available PMIC regulator voltage setpoint
570 return regmap_bulk_read(vreg->regmap, vreg->base + addr, buf, len); in spmi_vreg_read()
576 return regmap_bulk_write(vreg->regmap, vreg->base + addr, buf, len); in spmi_vreg_write()
582 return regmap_update_bits(vreg->regmap, vreg->base + addr, mask, val); in spmi_vreg_update_bits()
589 if (vreg->ocp_irq) { in spmi_regulator_vs_enable()
590 vreg->ocp_count = 0; in spmi_regulator_vs_enable()
591 vreg->vs_enable_time = ktime_get(); in spmi_regulator_vs_enable()
614 lim_min_uV = vreg->set_points->range[0].set_point_min_uV; in spmi_regulator_select_voltage()
616 vreg->set_points->range[vreg->set_points->count - 1].set_point_max_uV; in spmi_regulator_select_voltage()
622 dev_err(vreg->dev, in spmi_regulator_select_voltage()
625 return -EINVAL; in spmi_regulator_select_voltage()
629 for (i = vreg->set_points->count - 1; i > 0; i--) { in spmi_regulator_select_voltage()
630 range_max_uV = vreg->set_points->range[i - 1].set_point_max_uV; in spmi_regulator_select_voltage()
636 range = &vreg->set_points->range[range_id]; in spmi_regulator_select_voltage()
642 voltage_sel = DIV_ROUND_UP(uV - range->min_uV, range->step_uV); in spmi_regulator_select_voltage()
643 uV = voltage_sel * range->step_uV + range->min_uV; in spmi_regulator_select_voltage()
646 dev_err(vreg->dev, in spmi_regulator_select_voltage()
650 return -EINVAL; in spmi_regulator_select_voltage()
655 selector += vreg->set_points->range[i].n_voltages; in spmi_regulator_select_voltage()
656 selector += (uV - range->set_point_min_uV) / range->step_uV; in spmi_regulator_select_voltage()
668 range = vreg->set_points->range; in spmi_sw_selector_to_hw()
669 end = range + vreg->set_points->count; in spmi_sw_selector_to_hw()
672 if (selector < range->n_voltages) { in spmi_sw_selector_to_hw()
677 offset = range->set_point_min_uV - range->min_uV; in spmi_sw_selector_to_hw()
678 offset /= range->step_uV; in spmi_sw_selector_to_hw()
680 *range_sel = range->range_sel; in spmi_sw_selector_to_hw()
684 selector -= range->n_voltages; in spmi_sw_selector_to_hw()
687 return -EINVAL; in spmi_sw_selector_to_hw()
695 const struct spmi_voltage_range *r = vreg->set_points->range; in spmi_hw_selector_to_sw()
696 const struct spmi_voltage_range *end = r + vreg->set_points->count; in spmi_hw_selector_to_sw()
699 if (r == range && range->n_voltages) { in spmi_hw_selector_to_sw()
706 offset = range->set_point_min_uV - range->min_uV; in spmi_hw_selector_to_sw()
707 offset /= range->step_uV; in spmi_hw_selector_to_sw()
709 return -EINVAL; in spmi_hw_selector_to_sw()
711 max_hw_sel = range->set_point_max_uV - range->min_uV; in spmi_hw_selector_to_sw()
712 max_hw_sel /= range->step_uV; in spmi_hw_selector_to_sw()
714 return -EINVAL; in spmi_hw_selector_to_sw()
716 return sw_sel + hw_sel - offset; in spmi_hw_selector_to_sw()
718 sw_sel += r->n_voltages; in spmi_hw_selector_to_sw()
721 return -EINVAL; in spmi_hw_selector_to_sw()
730 range = vreg->set_points->range; in spmi_regulator_find_range()
731 end = range + vreg->set_points->count; in spmi_regulator_find_range()
736 if (range->range_sel == range_sel) in spmi_regulator_find_range()
753 if (uV < range->min_uV && max_uV >= range->min_uV) in spmi_regulator_select_voltage_same_range()
754 uV = range->min_uV; in spmi_regulator_select_voltage_same_range()
756 if (uV < range->min_uV || uV > range->max_uV) { in spmi_regulator_select_voltage_same_range()
765 uV = DIV_ROUND_UP(uV - range->min_uV, range->step_uV); in spmi_regulator_select_voltage_same_range()
766 uV = uV * range->step_uV + range->min_uV; in spmi_regulator_select_voltage_same_range()
777 for (i = 0; i < vreg->set_points->count; i++) { in spmi_regulator_select_voltage_same_range()
778 if (uV >= vreg->set_points->range[i].set_point_min_uV in spmi_regulator_select_voltage_same_range()
779 && uV <= vreg->set_points->range[i].set_point_max_uV) { in spmi_regulator_select_voltage_same_range()
781 (uV - vreg->set_points->range[i].set_point_min_uV) in spmi_regulator_select_voltage_same_range()
782 / vreg->set_points->range[i].step_uV; in spmi_regulator_select_voltage_same_range()
786 selector += vreg->set_points->range[i].n_voltages; in spmi_regulator_select_voltage_same_range()
789 if (selector >= vreg->set_points->n_voltages) in spmi_regulator_select_voltage_same_range()
850 diff_uV = abs(spmi_regulator_common_list_voltage(rdev, new_selector) - in spmi_regulator_set_voltage_time_sel()
853 return DIV_ROUND_UP(diff_uV, vreg->slew_rate); in spmi_regulator_set_voltage_time_sel()
866 return -EINVAL; in spmi_regulator_common_get_voltage()
881 range = vreg->set_points->range; in spmi_regulator_ftsmps426_get_voltage()
883 return (uV - range->set_point_min_uV) / range->step_uV; in spmi_regulator_ftsmps426_get_voltage()
935 * In case of range 1: voltage_sel is a 5 bit value, bits[7-5] set to in spmi_regulator_ult_lo_smps_set_voltage()
955 return -EINVAL; in spmi_regulator_ult_lo_smps_get_voltage()
957 if (range->range_sel == 1) in spmi_regulator_ult_lo_smps_get_voltage()
970 if (selector >= vreg->set_points->n_voltages) in spmi_regulator_common_list_voltage()
973 for (i = 0; i < vreg->set_points->count; i++) { in spmi_regulator_common_list_voltage()
974 if (selector < vreg->set_points->range[i].n_voltages) { in spmi_regulator_common_list_voltage()
975 uV = selector * vreg->set_points->range[i].step_uV in spmi_regulator_common_list_voltage()
976 + vreg->set_points->range[i].set_point_min_uV; in spmi_regulator_common_list_voltage()
980 selector -= vreg->set_points->range[i].n_voltages; in spmi_regulator_common_list_voltage()
1088 return -EINVAL; in spmi_regulator_ftsmps426_set_mode()
1100 if (load_uA >= vreg->hpm_min_load) in spmi_regulator_common_set_load()
1129 enum spmi_regulator_logical_type type = vreg->logical_type; in spmi_regulator_set_ilim()
1142 return -EINVAL; in spmi_regulator_set_ilim()
1144 reg = (ilim_uA - 1) / 500; in spmi_regulator_set_ilim()
1157 vreg->vs_enable_time = ktime_get(); in spmi_regulator_vs_clear_ocp()
1182 vreg->vs_enable_time); in spmi_regulator_vs_ocp_isr()
1190 vreg->ocp_count = 0; in spmi_regulator_vs_ocp_isr()
1195 vreg->ocp_count++; in spmi_regulator_vs_ocp_isr()
1197 if (vreg->ocp_count == 1) { in spmi_regulator_vs_ocp_isr()
1200 } else if (vreg->ocp_count <= vreg->ocp_max_retries) { in spmi_regulator_vs_ocp_isr()
1202 schedule_delayed_work(&vreg->ocp_work, in spmi_regulator_vs_ocp_isr()
1203 msecs_to_jiffies(vreg->ocp_retry_delay_ms) + 1); in spmi_regulator_vs_ocp_isr()
1205 dev_err(vreg->dev, in spmi_regulator_vs_ocp_isr()
1207 vreg->ocp_count); in spmi_regulator_vs_ocp_isr()
1265 avs_ctl |= ((pmic_sts - 4) << 10); in spmi_saw_set_vdd()
1284 dev_dbg(&rdev->dev, "range_sel = %02X voltage_sel = %02X", \ in spmi_regulator_saw_set_voltage()
1286 return -EINVAL; in spmi_regulator_saw_set_voltage()
1536 struct spmi_voltage_range *range = points->range; in spmi_calculate_num_voltages()
1538 for (; range < points->range + points->count; range++) { in spmi_calculate_num_voltages()
1540 if (range->set_point_max_uV) { in spmi_calculate_num_voltages()
1541 n = range->set_point_max_uV - range->set_point_min_uV; in spmi_calculate_num_voltages()
1542 n = (n / range->step_uV) + 1; in spmi_calculate_num_voltages()
1544 range->n_voltages = n; in spmi_calculate_num_voltages()
1545 points->n_voltages += n; in spmi_calculate_num_voltages()
1554 u8 version[SPMI_COMMON_REG_SUBTYPE - SPMI_COMMON_REG_DIG_MAJOR_REV + 1]; in spmi_regulator_match()
1560 dev_dbg(vreg->dev, "could not read version registers\n"); in spmi_regulator_match()
1564 - SPMI_COMMON_REG_DIG_MAJOR_REV]; in spmi_regulator_match()
1567 type = version[SPMI_COMMON_REG_TYPE - in spmi_regulator_match()
1569 subtype = version[SPMI_COMMON_REG_SUBTYPE - in spmi_regulator_match()
1578 if (mapping->type == type && mapping->subtype == subtype in spmi_regulator_match()
1579 && mapping->revision_min <= dig_major_rev in spmi_regulator_match()
1580 && mapping->revision_max >= dig_major_rev) in spmi_regulator_match()
1584 dev_err(vreg->dev, in spmi_regulator_match()
1585 "unsupported regulator: name=%s type=0x%02X, subtype=0x%02X, dig major rev=0x%02X\n", in spmi_regulator_match()
1586 vreg->desc.name, type, subtype, dig_major_rev); in spmi_regulator_match()
1588 return -ENODEV; in spmi_regulator_match()
1591 vreg->logical_type = mapping->logical_type; in spmi_regulator_match()
1592 vreg->set_points = mapping->set_points; in spmi_regulator_match()
1593 vreg->hpm_min_load = mapping->hpm_min_load; in spmi_regulator_match()
1594 vreg->desc.ops = mapping->ops; in spmi_regulator_match()
1596 if (mapping->set_points) { in spmi_regulator_match()
1597 if (!mapping->set_points->n_voltages) in spmi_regulator_match()
1598 spmi_calculate_num_voltages(mapping->set_points); in spmi_regulator_match()
1599 vreg->desc.n_voltages = mapping->set_points->n_voltages; in spmi_regulator_match()
1614 dev_err(vreg->dev, "spmi read failed, ret=%d\n", ret); in spmi_regulator_init_slew_rate()
1620 return -EINVAL; in spmi_regulator_init_slew_rate()
1622 switch (vreg->logical_type) { in spmi_regulator_init_slew_rate()
1638 slew_rate = SPMI_FTSMPS_CLOCK_RATE * range->step_uV * (1 << step); in spmi_regulator_init_slew_rate()
1644 vreg->slew_rate = max(slew_rate, 1); in spmi_regulator_init_slew_rate()
1655 const struct spmi_voltage_range *range = &vreg->set_points->range[0]; in spmi_regulator_init_slew_rate_ftsmps426()
1659 dev_err(vreg->dev, "spmi read failed, ret=%d\n", ret); in spmi_regulator_init_slew_rate_ftsmps426()
1667 slew_rate = clock_rate * range->step_uV; in spmi_regulator_init_slew_rate_ftsmps426()
1673 vreg->slew_rate = max(slew_rate, 1); in spmi_regulator_init_slew_rate_ftsmps426()
1685 type = vreg->logical_type; in spmi_regulator_init_registers()
1692 if (!(data->pin_ctrl_enable & SPMI_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT)) { in spmi_regulator_init_registers()
1700 data->pin_ctrl_enable & SPMI_COMMON_ENABLE_FOLLOW_ALL_MASK; in spmi_regulator_init_registers()
1708 if (!(data->pin_ctrl_hpm & SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT)) { in spmi_regulator_init_registers()
1715 data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_ALL_MASK; in spmi_regulator_init_registers()
1724 data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK; in spmi_regulator_init_registers()
1736 /* Set soft start strength and over current protection for VS. */ in spmi_regulator_init_registers()
1738 if (data->vs_soft_start_strength in spmi_regulator_init_registers()
1740 reg = data->vs_soft_start_strength in spmi_regulator_init_registers()
1759 data->pin_ctrl_enable = SPMI_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT; in spmi_regulator_get_dt_config()
1760 data->pin_ctrl_hpm = SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT; in spmi_regulator_get_dt_config()
1761 data->vs_soft_start_strength = SPMI_VS_SOFT_START_STR_HW_DEFAULT; in spmi_regulator_get_dt_config()
1764 of_property_read_u32(node, "qcom,ocp-max-retries", in spmi_regulator_get_dt_config()
1765 &vreg->ocp_max_retries); in spmi_regulator_get_dt_config()
1766 of_property_read_u32(node, "qcom,ocp-retry-delay", in spmi_regulator_get_dt_config()
1767 &vreg->ocp_retry_delay_ms); in spmi_regulator_get_dt_config()
1768 of_property_read_u32(node, "qcom,pin-ctrl-enable", in spmi_regulator_get_dt_config()
1769 &data->pin_ctrl_enable); in spmi_regulator_get_dt_config()
1770 of_property_read_u32(node, "qcom,pin-ctrl-hpm", &data->pin_ctrl_hpm); in spmi_regulator_get_dt_config()
1771 of_property_read_u32(node, "qcom,vs-soft-start-strength", in spmi_regulator_get_dt_config()
1772 &data->vs_soft_start_strength); in spmi_regulator_get_dt_config()
1790 struct spmi_regulator *vreg = config->driver_data; in spmi_regulator_of_parse()
1791 struct device *dev = config->dev; in spmi_regulator_of_parse()
1796 if (!vreg->ocp_max_retries) in spmi_regulator_of_parse()
1797 vreg->ocp_max_retries = SPMI_VS_OCP_DEFAULT_MAX_RETRIES; in spmi_regulator_of_parse()
1798 if (!vreg->ocp_retry_delay_ms) in spmi_regulator_of_parse()
1799 vreg->ocp_retry_delay_ms = SPMI_VS_OCP_DEFAULT_RETRY_DELAY_MS; in spmi_regulator_of_parse()
1807 switch (vreg->logical_type) { in spmi_regulator_of_parse()
1832 if (vreg->logical_type != SPMI_REGULATOR_LOGICAL_TYPE_VS) in spmi_regulator_of_parse()
1833 vreg->ocp_irq = 0; in spmi_regulator_of_parse()
1835 if (vreg->ocp_irq) { in spmi_regulator_of_parse()
1836 ret = devm_request_irq(dev, vreg->ocp_irq, in spmi_regulator_of_parse()
1841 vreg->ocp_irq, ret); in spmi_regulator_of_parse()
1845 INIT_DELAYED_WORK(&vreg->ocp_work, spmi_regulator_vs_ocp_work); in spmi_regulator_of_parse()
1883 { "5vs1", 0x8300, "vin_5vs", "ocp-5vs1", },
1884 { "5vs2", 0x8400, "vin_5vs", "ocp-5vs2", },
2086 { .compatible = "qcom,pm8004-regulators", .data = &pm8004_regulators },
2087 { .compatible = "qcom,pm8005-regulators", .data = &pm8005_regulators },
2088 { .compatible = "qcom,pm8841-regulators", .data = &pm8841_regulators },
2089 { .compatible = "qcom,pm8916-regulators", .data = &pm8916_regulators },
2090 { .compatible = "qcom,pm8941-regulators", .data = &pm8941_regulators },
2091 { .compatible = "qcom,pm8950-regulators", .data = &pm8950_regulators },
2092 { .compatible = "qcom,pm8994-regulators", .data = &pm8994_regulators },
2093 { .compatible = "qcom,pmi8994-regulators", .data = &pmi8994_regulators },
2094 { .compatible = "qcom,pm660-regulators", .data = &pm660_regulators },
2095 { .compatible = "qcom,pm660l-regulators", .data = &pm660l_regulators },
2096 { .compatible = "qcom,pms405-regulators", .data = &pms405_regulators },
2111 struct device *dev = &pdev->dev; in qcom_spmi_regulator_probe()
2112 struct device_node *node = pdev->dev.of_node; in qcom_spmi_regulator_probe()
2120 return -ENOMEM; in qcom_spmi_regulator_probe()
2124 regmap = dev_get_regmap(dev->parent, NULL); in qcom_spmi_regulator_probe()
2126 return -ENODEV; in qcom_spmi_regulator_probe()
2128 match = of_match_device(qcom_spmi_regulator_match, &pdev->dev); in qcom_spmi_regulator_probe()
2130 return -ENODEV; in qcom_spmi_regulator_probe()
2132 if (of_find_property(node, "qcom,saw-reg", &lenp)) { in qcom_spmi_regulator_probe()
2133 syscon = of_parse_phandle(node, "qcom,saw-reg", 0); in qcom_spmi_regulator_probe()
2140 for (reg = match->data; reg->name; reg++) { in qcom_spmi_regulator_probe()
2143 reg_node = of_get_child_by_name(node, reg->name); in qcom_spmi_regulator_probe()
2144 reg_prop = of_find_property(reg_node, "qcom,saw-slave", in qcom_spmi_regulator_probe()
2153 return -ENOMEM; in qcom_spmi_regulator_probe()
2155 vreg->dev = dev; in qcom_spmi_regulator_probe()
2156 vreg->base = reg->base; in qcom_spmi_regulator_probe()
2157 vreg->regmap = regmap; in qcom_spmi_regulator_probe()
2158 if (reg->ocp) { in qcom_spmi_regulator_probe()
2159 vreg->ocp_irq = platform_get_irq_byname(pdev, reg->ocp); in qcom_spmi_regulator_probe()
2160 if (vreg->ocp_irq < 0) { in qcom_spmi_regulator_probe()
2161 ret = vreg->ocp_irq; in qcom_spmi_regulator_probe()
2165 vreg->desc.id = -1; in qcom_spmi_regulator_probe()
2166 vreg->desc.owner = THIS_MODULE; in qcom_spmi_regulator_probe()
2167 vreg->desc.type = REGULATOR_VOLTAGE; in qcom_spmi_regulator_probe()
2168 vreg->desc.enable_reg = reg->base + SPMI_COMMON_REG_ENABLE; in qcom_spmi_regulator_probe()
2169 vreg->desc.enable_mask = SPMI_COMMON_ENABLE_MASK; in qcom_spmi_regulator_probe()
2170 vreg->desc.enable_val = SPMI_COMMON_ENABLE; in qcom_spmi_regulator_probe()
2171 vreg->desc.name = name = reg->name; in qcom_spmi_regulator_probe()
2172 vreg->desc.supply_name = reg->supply; in qcom_spmi_regulator_probe()
2173 vreg->desc.of_match = reg->name; in qcom_spmi_regulator_probe()
2174 vreg->desc.of_parse_cb = spmi_regulator_of_parse; in qcom_spmi_regulator_probe()
2175 vreg->desc.of_map_mode = spmi_regulator_of_map_mode; in qcom_spmi_regulator_probe()
2177 ret = spmi_regulator_match(vreg, reg->force_type); in qcom_spmi_regulator_probe()
2182 reg_node = of_get_child_by_name(node, reg->name); in qcom_spmi_regulator_probe()
2183 reg_prop = of_find_property(reg_node, "qcom,saw-leader", in qcom_spmi_regulator_probe()
2187 spmi_saw_ops = *(vreg->desc.ops); in qcom_spmi_regulator_probe()
2190 vreg->desc.ops = &spmi_saw_ops; in qcom_spmi_regulator_probe()
2194 if (vreg->set_points && vreg->set_points->count == 1) { in qcom_spmi_regulator_probe()
2196 range = vreg->set_points->range; in qcom_spmi_regulator_probe()
2197 vreg->desc.uV_step = range->step_uV; in qcom_spmi_regulator_probe()
2203 rdev = devm_regulator_register(dev, &vreg->desc, &config); in qcom_spmi_regulator_probe()
2210 INIT_LIST_HEAD(&vreg->node); in qcom_spmi_regulator_probe()
2211 list_add(&vreg->node, vreg_list); in qcom_spmi_regulator_probe()
2218 if (vreg->ocp_irq) in qcom_spmi_regulator_probe()
2219 cancel_delayed_work_sync(&vreg->ocp_work); in qcom_spmi_regulator_probe()
2229 if (vreg->ocp_irq) in qcom_spmi_regulator_remove()
2230 cancel_delayed_work_sync(&vreg->ocp_work); in qcom_spmi_regulator_remove()
2237 .name = "qcom-spmi-regulator",
2245 MODULE_DESCRIPTION("Qualcomm SPMI PMIC regulator driver");
2247 MODULE_ALIAS("platform:qcom-spmi-regulator");