18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * tps65218-regulator.c 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Regulator driver for TPS65218 PMIC 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com/ 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or 98c2ecf20Sopenharmony_ci * modify it under the terms of the GNU General Public License version 2 as 108c2ecf20Sopenharmony_ci * published by the Free Software Foundation. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * This program is distributed "as is" WITHOUT ANY WARRANTY of any 138c2ecf20Sopenharmony_ci * kind, whether expressed or implied; without even the implied warranty 148c2ecf20Sopenharmony_ci * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 158c2ecf20Sopenharmony_ci * GNU General Public License version 2 for more details. 168c2ecf20Sopenharmony_ci */ 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <linux/kernel.h> 198c2ecf20Sopenharmony_ci#include <linux/module.h> 208c2ecf20Sopenharmony_ci#include <linux/device.h> 218c2ecf20Sopenharmony_ci#include <linux/init.h> 228c2ecf20Sopenharmony_ci#include <linux/err.h> 238c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 248c2ecf20Sopenharmony_ci#include <linux/of_device.h> 258c2ecf20Sopenharmony_ci#include <linux/regmap.h> 268c2ecf20Sopenharmony_ci#include <linux/regulator/of_regulator.h> 278c2ecf20Sopenharmony_ci#include <linux/regulator/driver.h> 288c2ecf20Sopenharmony_ci#include <linux/regulator/machine.h> 298c2ecf20Sopenharmony_ci#include <linux/mfd/tps65218.h> 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define TPS65218_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \ 328c2ecf20Sopenharmony_ci _em, _cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm, \ 338c2ecf20Sopenharmony_ci _ct, _ncl) \ 348c2ecf20Sopenharmony_ci { \ 358c2ecf20Sopenharmony_ci .name = _name, \ 368c2ecf20Sopenharmony_ci .of_match = _of, \ 378c2ecf20Sopenharmony_ci .id = _id, \ 388c2ecf20Sopenharmony_ci .ops = &_ops, \ 398c2ecf20Sopenharmony_ci .n_voltages = _n, \ 408c2ecf20Sopenharmony_ci .type = _type, \ 418c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 428c2ecf20Sopenharmony_ci .vsel_reg = _vr, \ 438c2ecf20Sopenharmony_ci .vsel_mask = _vm, \ 448c2ecf20Sopenharmony_ci .csel_reg = _cr, \ 458c2ecf20Sopenharmony_ci .csel_mask = _cm, \ 468c2ecf20Sopenharmony_ci .curr_table = _ct, \ 478c2ecf20Sopenharmony_ci .n_current_limits = _ncl, \ 488c2ecf20Sopenharmony_ci .enable_reg = _er, \ 498c2ecf20Sopenharmony_ci .enable_mask = _em, \ 508c2ecf20Sopenharmony_ci .volt_table = NULL, \ 518c2ecf20Sopenharmony_ci .linear_ranges = _lr, \ 528c2ecf20Sopenharmony_ci .n_linear_ranges = _nlr, \ 538c2ecf20Sopenharmony_ci .ramp_delay = _delay, \ 548c2ecf20Sopenharmony_ci .fixed_uV = _fuv, \ 558c2ecf20Sopenharmony_ci .bypass_reg = _sr, \ 568c2ecf20Sopenharmony_ci .bypass_mask = _sm, \ 578c2ecf20Sopenharmony_ci } \ 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic const struct linear_range dcdc1_dcdc2_ranges[] = { 608c2ecf20Sopenharmony_ci REGULATOR_LINEAR_RANGE(850000, 0x0, 0x32, 10000), 618c2ecf20Sopenharmony_ci REGULATOR_LINEAR_RANGE(1375000, 0x33, 0x3f, 25000), 628c2ecf20Sopenharmony_ci}; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistatic const struct linear_range ldo1_dcdc3_ranges[] = { 658c2ecf20Sopenharmony_ci REGULATOR_LINEAR_RANGE(900000, 0x0, 0x1a, 25000), 668c2ecf20Sopenharmony_ci REGULATOR_LINEAR_RANGE(1600000, 0x1b, 0x3f, 50000), 678c2ecf20Sopenharmony_ci}; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cistatic const struct linear_range dcdc4_ranges[] = { 708c2ecf20Sopenharmony_ci REGULATOR_LINEAR_RANGE(1175000, 0x0, 0xf, 25000), 718c2ecf20Sopenharmony_ci REGULATOR_LINEAR_RANGE(1600000, 0x10, 0x34, 50000), 728c2ecf20Sopenharmony_ci}; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistatic int tps65218_pmic_set_voltage_sel(struct regulator_dev *dev, 758c2ecf20Sopenharmony_ci unsigned selector) 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci int ret; 788c2ecf20Sopenharmony_ci struct tps65218 *tps = rdev_get_drvdata(dev); 798c2ecf20Sopenharmony_ci unsigned int rid = rdev_get_id(dev); 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci /* Set the voltage based on vsel value and write protect level is 2 */ 828c2ecf20Sopenharmony_ci ret = tps65218_set_bits(tps, dev->desc->vsel_reg, dev->desc->vsel_mask, 838c2ecf20Sopenharmony_ci selector, TPS65218_PROTECT_L1); 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci /* Set GO bit for DCDC1/2 to initiate voltage transistion */ 868c2ecf20Sopenharmony_ci switch (rid) { 878c2ecf20Sopenharmony_ci case TPS65218_DCDC_1: 888c2ecf20Sopenharmony_ci case TPS65218_DCDC_2: 898c2ecf20Sopenharmony_ci ret = tps65218_set_bits(tps, TPS65218_REG_CONTRL_SLEW_RATE, 908c2ecf20Sopenharmony_ci TPS65218_SLEW_RATE_GO, 918c2ecf20Sopenharmony_ci TPS65218_SLEW_RATE_GO, 928c2ecf20Sopenharmony_ci TPS65218_PROTECT_L1); 938c2ecf20Sopenharmony_ci break; 948c2ecf20Sopenharmony_ci } 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci return ret; 978c2ecf20Sopenharmony_ci} 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_cistatic int tps65218_pmic_enable(struct regulator_dev *dev) 1008c2ecf20Sopenharmony_ci{ 1018c2ecf20Sopenharmony_ci struct tps65218 *tps = rdev_get_drvdata(dev); 1028c2ecf20Sopenharmony_ci int rid = rdev_get_id(dev); 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) 1058c2ecf20Sopenharmony_ci return -EINVAL; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci /* Enable the regulator and password protection is level 1 */ 1088c2ecf20Sopenharmony_ci return tps65218_set_bits(tps, dev->desc->enable_reg, 1098c2ecf20Sopenharmony_ci dev->desc->enable_mask, dev->desc->enable_mask, 1108c2ecf20Sopenharmony_ci TPS65218_PROTECT_L1); 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_cistatic int tps65218_pmic_disable(struct regulator_dev *dev) 1148c2ecf20Sopenharmony_ci{ 1158c2ecf20Sopenharmony_ci struct tps65218 *tps = rdev_get_drvdata(dev); 1168c2ecf20Sopenharmony_ci int rid = rdev_get_id(dev); 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) 1198c2ecf20Sopenharmony_ci return -EINVAL; 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci /* Disable the regulator and password protection is level 1 */ 1228c2ecf20Sopenharmony_ci return tps65218_clear_bits(tps, dev->desc->enable_reg, 1238c2ecf20Sopenharmony_ci dev->desc->enable_mask, TPS65218_PROTECT_L1); 1248c2ecf20Sopenharmony_ci} 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic int tps65218_pmic_set_suspend_enable(struct regulator_dev *dev) 1278c2ecf20Sopenharmony_ci{ 1288c2ecf20Sopenharmony_ci struct tps65218 *tps = rdev_get_drvdata(dev); 1298c2ecf20Sopenharmony_ci unsigned int rid = rdev_get_id(dev); 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci if (rid > TPS65218_LDO_1) 1328c2ecf20Sopenharmony_ci return -EINVAL; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci return tps65218_clear_bits(tps, dev->desc->bypass_reg, 1358c2ecf20Sopenharmony_ci dev->desc->bypass_mask, 1368c2ecf20Sopenharmony_ci TPS65218_PROTECT_L1); 1378c2ecf20Sopenharmony_ci} 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_cistatic int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev) 1408c2ecf20Sopenharmony_ci{ 1418c2ecf20Sopenharmony_ci struct tps65218 *tps = rdev_get_drvdata(dev); 1428c2ecf20Sopenharmony_ci unsigned int rid = rdev_get_id(dev); 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci if (rid > TPS65218_LDO_1) 1458c2ecf20Sopenharmony_ci return -EINVAL; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci /* 1488c2ecf20Sopenharmony_ci * Certain revisions of TPS65218 will need to have DCDC3 regulator 1498c2ecf20Sopenharmony_ci * enabled always, otherwise an immediate system reboot will occur 1508c2ecf20Sopenharmony_ci * during poweroff. 1518c2ecf20Sopenharmony_ci */ 1528c2ecf20Sopenharmony_ci if (rid == TPS65218_DCDC_3 && tps->rev == TPS65218_REV_2_1) 1538c2ecf20Sopenharmony_ci return 0; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci if (!tps->strobes[rid]) { 1568c2ecf20Sopenharmony_ci if (rid == TPS65218_DCDC_3) 1578c2ecf20Sopenharmony_ci tps->strobes[rid] = 3; 1588c2ecf20Sopenharmony_ci else 1598c2ecf20Sopenharmony_ci return -EINVAL; 1608c2ecf20Sopenharmony_ci } 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci return tps65218_set_bits(tps, dev->desc->bypass_reg, 1638c2ecf20Sopenharmony_ci dev->desc->bypass_mask, 1648c2ecf20Sopenharmony_ci tps->strobes[rid], TPS65218_PROTECT_L1); 1658c2ecf20Sopenharmony_ci} 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci/* Operations permitted on DCDC1, DCDC2 */ 1688c2ecf20Sopenharmony_cistatic const struct regulator_ops tps65218_dcdc12_ops = { 1698c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 1708c2ecf20Sopenharmony_ci .enable = tps65218_pmic_enable, 1718c2ecf20Sopenharmony_ci .disable = tps65218_pmic_disable, 1728c2ecf20Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 1738c2ecf20Sopenharmony_ci .set_voltage_sel = tps65218_pmic_set_voltage_sel, 1748c2ecf20Sopenharmony_ci .list_voltage = regulator_list_voltage_linear_range, 1758c2ecf20Sopenharmony_ci .map_voltage = regulator_map_voltage_linear_range, 1768c2ecf20Sopenharmony_ci .set_voltage_time_sel = regulator_set_voltage_time_sel, 1778c2ecf20Sopenharmony_ci .set_suspend_enable = tps65218_pmic_set_suspend_enable, 1788c2ecf20Sopenharmony_ci .set_suspend_disable = tps65218_pmic_set_suspend_disable, 1798c2ecf20Sopenharmony_ci}; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci/* Operations permitted on DCDC3, DCDC4 and LDO1 */ 1828c2ecf20Sopenharmony_cistatic const struct regulator_ops tps65218_ldo1_dcdc34_ops = { 1838c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 1848c2ecf20Sopenharmony_ci .enable = tps65218_pmic_enable, 1858c2ecf20Sopenharmony_ci .disable = tps65218_pmic_disable, 1868c2ecf20Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 1878c2ecf20Sopenharmony_ci .set_voltage_sel = tps65218_pmic_set_voltage_sel, 1888c2ecf20Sopenharmony_ci .list_voltage = regulator_list_voltage_linear_range, 1898c2ecf20Sopenharmony_ci .map_voltage = regulator_map_voltage_linear_range, 1908c2ecf20Sopenharmony_ci .set_suspend_enable = tps65218_pmic_set_suspend_enable, 1918c2ecf20Sopenharmony_ci .set_suspend_disable = tps65218_pmic_set_suspend_disable, 1928c2ecf20Sopenharmony_ci}; 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_cistatic const unsigned int ls3_currents[] = { 100000, 200000, 500000, 1000000 }; 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_cistatic int tps65218_pmic_set_input_current_lim(struct regulator_dev *dev, 1978c2ecf20Sopenharmony_ci int lim_uA) 1988c2ecf20Sopenharmony_ci{ 1998c2ecf20Sopenharmony_ci unsigned int index = 0; 2008c2ecf20Sopenharmony_ci unsigned int num_currents = ARRAY_SIZE(ls3_currents); 2018c2ecf20Sopenharmony_ci struct tps65218 *tps = rdev_get_drvdata(dev); 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci while (index < num_currents && ls3_currents[index] != lim_uA) 2048c2ecf20Sopenharmony_ci index++; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci if (index == num_currents) 2078c2ecf20Sopenharmony_ci return -EINVAL; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci return tps65218_set_bits(tps, dev->desc->csel_reg, dev->desc->csel_mask, 2108c2ecf20Sopenharmony_ci index << __builtin_ctz(dev->desc->csel_mask), 2118c2ecf20Sopenharmony_ci TPS65218_PROTECT_L1); 2128c2ecf20Sopenharmony_ci} 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_cistatic int tps65218_pmic_set_current_limit(struct regulator_dev *dev, 2158c2ecf20Sopenharmony_ci int min_uA, int max_uA) 2168c2ecf20Sopenharmony_ci{ 2178c2ecf20Sopenharmony_ci int index = 0; 2188c2ecf20Sopenharmony_ci unsigned int num_currents = ARRAY_SIZE(ls3_currents); 2198c2ecf20Sopenharmony_ci struct tps65218 *tps = rdev_get_drvdata(dev); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci while (index < num_currents && ls3_currents[index] <= max_uA) 2228c2ecf20Sopenharmony_ci index++; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci index--; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci if (index < 0 || ls3_currents[index] < min_uA) 2278c2ecf20Sopenharmony_ci return -EINVAL; 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci return tps65218_set_bits(tps, dev->desc->csel_reg, dev->desc->csel_mask, 2308c2ecf20Sopenharmony_ci index << __builtin_ctz(dev->desc->csel_mask), 2318c2ecf20Sopenharmony_ci TPS65218_PROTECT_L1); 2328c2ecf20Sopenharmony_ci} 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_cistatic const struct regulator_ops tps65218_ls23_ops = { 2358c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 2368c2ecf20Sopenharmony_ci .enable = tps65218_pmic_enable, 2378c2ecf20Sopenharmony_ci .disable = tps65218_pmic_disable, 2388c2ecf20Sopenharmony_ci .set_input_current_limit = tps65218_pmic_set_input_current_lim, 2398c2ecf20Sopenharmony_ci .set_current_limit = tps65218_pmic_set_current_limit, 2408c2ecf20Sopenharmony_ci .get_current_limit = regulator_get_current_limit_regmap, 2418c2ecf20Sopenharmony_ci}; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci/* Operations permitted on DCDC5, DCDC6 */ 2448c2ecf20Sopenharmony_cistatic const struct regulator_ops tps65218_dcdc56_pmic_ops = { 2458c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 2468c2ecf20Sopenharmony_ci .enable = tps65218_pmic_enable, 2478c2ecf20Sopenharmony_ci .disable = tps65218_pmic_disable, 2488c2ecf20Sopenharmony_ci .set_suspend_enable = tps65218_pmic_set_suspend_enable, 2498c2ecf20Sopenharmony_ci .set_suspend_disable = tps65218_pmic_set_suspend_disable, 2508c2ecf20Sopenharmony_ci}; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistatic const struct regulator_desc regulators[] = { 2538c2ecf20Sopenharmony_ci TPS65218_REGULATOR("DCDC1", "regulator-dcdc1", TPS65218_DCDC_1, 2548c2ecf20Sopenharmony_ci REGULATOR_VOLTAGE, tps65218_dcdc12_ops, 64, 2558c2ecf20Sopenharmony_ci TPS65218_REG_CONTROL_DCDC1, 2568c2ecf20Sopenharmony_ci TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1, 2578c2ecf20Sopenharmony_ci TPS65218_ENABLE1_DC1_EN, 0, 0, dcdc1_dcdc2_ranges, 2588c2ecf20Sopenharmony_ci 2, 4000, 0, TPS65218_REG_SEQ3, 2598c2ecf20Sopenharmony_ci TPS65218_SEQ3_DC1_SEQ_MASK, NULL, 0), 2608c2ecf20Sopenharmony_ci TPS65218_REGULATOR("DCDC2", "regulator-dcdc2", TPS65218_DCDC_2, 2618c2ecf20Sopenharmony_ci REGULATOR_VOLTAGE, tps65218_dcdc12_ops, 64, 2628c2ecf20Sopenharmony_ci TPS65218_REG_CONTROL_DCDC2, 2638c2ecf20Sopenharmony_ci TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1, 2648c2ecf20Sopenharmony_ci TPS65218_ENABLE1_DC2_EN, 0, 0, dcdc1_dcdc2_ranges, 2658c2ecf20Sopenharmony_ci 2, 4000, 0, TPS65218_REG_SEQ3, 2668c2ecf20Sopenharmony_ci TPS65218_SEQ3_DC2_SEQ_MASK, NULL, 0), 2678c2ecf20Sopenharmony_ci TPS65218_REGULATOR("DCDC3", "regulator-dcdc3", TPS65218_DCDC_3, 2688c2ecf20Sopenharmony_ci REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64, 2698c2ecf20Sopenharmony_ci TPS65218_REG_CONTROL_DCDC3, 2708c2ecf20Sopenharmony_ci TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, 2718c2ecf20Sopenharmony_ci TPS65218_ENABLE1_DC3_EN, 0, 0, ldo1_dcdc3_ranges, 2, 2728c2ecf20Sopenharmony_ci 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC3_SEQ_MASK, 2738c2ecf20Sopenharmony_ci NULL, 0), 2748c2ecf20Sopenharmony_ci TPS65218_REGULATOR("DCDC4", "regulator-dcdc4", TPS65218_DCDC_4, 2758c2ecf20Sopenharmony_ci REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 53, 2768c2ecf20Sopenharmony_ci TPS65218_REG_CONTROL_DCDC4, 2778c2ecf20Sopenharmony_ci TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1, 2788c2ecf20Sopenharmony_ci TPS65218_ENABLE1_DC4_EN, 0, 0, dcdc4_ranges, 2, 2798c2ecf20Sopenharmony_ci 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC4_SEQ_MASK, 2808c2ecf20Sopenharmony_ci NULL, 0), 2818c2ecf20Sopenharmony_ci TPS65218_REGULATOR("DCDC5", "regulator-dcdc5", TPS65218_DCDC_5, 2828c2ecf20Sopenharmony_ci REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1, 2838c2ecf20Sopenharmony_ci -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, 0, 2848c2ecf20Sopenharmony_ci 0, NULL, 0, 0, 1000000, TPS65218_REG_SEQ5, 2858c2ecf20Sopenharmony_ci TPS65218_SEQ5_DC5_SEQ_MASK, NULL, 0), 2868c2ecf20Sopenharmony_ci TPS65218_REGULATOR("DCDC6", "regulator-dcdc6", TPS65218_DCDC_6, 2878c2ecf20Sopenharmony_ci REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1, 2888c2ecf20Sopenharmony_ci -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, 0, 2898c2ecf20Sopenharmony_ci 0, NULL, 0, 0, 1800000, TPS65218_REG_SEQ5, 2908c2ecf20Sopenharmony_ci TPS65218_SEQ5_DC6_SEQ_MASK, NULL, 0), 2918c2ecf20Sopenharmony_ci TPS65218_REGULATOR("LDO1", "regulator-ldo1", TPS65218_LDO_1, 2928c2ecf20Sopenharmony_ci REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64, 2938c2ecf20Sopenharmony_ci TPS65218_REG_CONTROL_LDO1, 2948c2ecf20Sopenharmony_ci TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, 2958c2ecf20Sopenharmony_ci TPS65218_ENABLE2_LDO1_EN, 0, 0, ldo1_dcdc3_ranges, 2968c2ecf20Sopenharmony_ci 2, 0, 0, TPS65218_REG_SEQ6, 2978c2ecf20Sopenharmony_ci TPS65218_SEQ6_LDO1_SEQ_MASK, NULL, 0), 2988c2ecf20Sopenharmony_ci TPS65218_REGULATOR("LS2", "regulator-ls2", TPS65218_LS_2, 2998c2ecf20Sopenharmony_ci REGULATOR_CURRENT, tps65218_ls23_ops, 0, 0, 0, 3008c2ecf20Sopenharmony_ci TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS2_EN, 3018c2ecf20Sopenharmony_ci TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS2ILIM_MASK, 3028c2ecf20Sopenharmony_ci NULL, 0, 0, 0, 0, 0, ls3_currents, 3038c2ecf20Sopenharmony_ci ARRAY_SIZE(ls3_currents)), 3048c2ecf20Sopenharmony_ci TPS65218_REGULATOR("LS3", "regulator-ls3", TPS65218_LS_3, 3058c2ecf20Sopenharmony_ci REGULATOR_CURRENT, tps65218_ls23_ops, 0, 0, 0, 3068c2ecf20Sopenharmony_ci TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS3_EN, 3078c2ecf20Sopenharmony_ci TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS3ILIM_MASK, 3088c2ecf20Sopenharmony_ci NULL, 0, 0, 0, 0, 0, ls3_currents, 3098c2ecf20Sopenharmony_ci ARRAY_SIZE(ls3_currents)), 3108c2ecf20Sopenharmony_ci}; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_cistatic int tps65218_regulator_probe(struct platform_device *pdev) 3138c2ecf20Sopenharmony_ci{ 3148c2ecf20Sopenharmony_ci struct tps65218 *tps = dev_get_drvdata(pdev->dev.parent); 3158c2ecf20Sopenharmony_ci struct regulator_dev *rdev; 3168c2ecf20Sopenharmony_ci struct regulator_config config = { }; 3178c2ecf20Sopenharmony_ci int i, ret; 3188c2ecf20Sopenharmony_ci unsigned int val; 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci config.dev = &pdev->dev; 3218c2ecf20Sopenharmony_ci config.dev->of_node = tps->dev->of_node; 3228c2ecf20Sopenharmony_ci config.driver_data = tps; 3238c2ecf20Sopenharmony_ci config.regmap = tps->regmap; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci /* Allocate memory for strobes */ 3268c2ecf20Sopenharmony_ci tps->strobes = devm_kcalloc(&pdev->dev, 3278c2ecf20Sopenharmony_ci TPS65218_NUM_REGULATOR, sizeof(u8), 3288c2ecf20Sopenharmony_ci GFP_KERNEL); 3298c2ecf20Sopenharmony_ci if (!tps->strobes) 3308c2ecf20Sopenharmony_ci return -ENOMEM; 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(regulators); i++) { 3338c2ecf20Sopenharmony_ci rdev = devm_regulator_register(&pdev->dev, ®ulators[i], 3348c2ecf20Sopenharmony_ci &config); 3358c2ecf20Sopenharmony_ci if (IS_ERR(rdev)) { 3368c2ecf20Sopenharmony_ci dev_err(tps->dev, "failed to register %s regulator\n", 3378c2ecf20Sopenharmony_ci pdev->name); 3388c2ecf20Sopenharmony_ci return PTR_ERR(rdev); 3398c2ecf20Sopenharmony_ci } 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci ret = regmap_read(tps->regmap, regulators[i].bypass_reg, &val); 3428c2ecf20Sopenharmony_ci if (ret) 3438c2ecf20Sopenharmony_ci return ret; 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci tps->strobes[i] = val & regulators[i].bypass_mask; 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci return 0; 3498c2ecf20Sopenharmony_ci} 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_cistatic const struct platform_device_id tps65218_regulator_id_table[] = { 3528c2ecf20Sopenharmony_ci { "tps65218-regulator", }, 3538c2ecf20Sopenharmony_ci { /* sentinel */ } 3548c2ecf20Sopenharmony_ci}; 3558c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(platform, tps65218_regulator_id_table); 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_cistatic struct platform_driver tps65218_regulator_driver = { 3588c2ecf20Sopenharmony_ci .driver = { 3598c2ecf20Sopenharmony_ci .name = "tps65218-pmic", 3608c2ecf20Sopenharmony_ci }, 3618c2ecf20Sopenharmony_ci .probe = tps65218_regulator_probe, 3628c2ecf20Sopenharmony_ci .id_table = tps65218_regulator_id_table, 3638c2ecf20Sopenharmony_ci}; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_cimodule_platform_driver(tps65218_regulator_driver); 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ciMODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>"); 3688c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("TPS65218 voltage regulator driver"); 3698c2ecf20Sopenharmony_ciMODULE_ALIAS("platform:tps65218-pmic"); 3708c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 371