18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 28c2ecf20Sopenharmony_ci// 38c2ecf20Sopenharmony_ci// Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/kernel.h> 68c2ecf20Sopenharmony_ci#include <linux/module.h> 78c2ecf20Sopenharmony_ci#include <linux/init.h> 88c2ecf20Sopenharmony_ci#include <linux/err.h> 98c2ecf20Sopenharmony_ci#include <linux/of.h> 108c2ecf20Sopenharmony_ci#include <linux/of_device.h> 118c2ecf20Sopenharmony_ci#include <linux/regulator/of_regulator.h> 128c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 138c2ecf20Sopenharmony_ci#include <linux/regulator/driver.h> 148c2ecf20Sopenharmony_ci#include <linux/regulator/machine.h> 158c2ecf20Sopenharmony_ci#include <linux/regulator/pfuze100.h> 168c2ecf20Sopenharmony_ci#include <linux/i2c.h> 178c2ecf20Sopenharmony_ci#include <linux/slab.h> 188c2ecf20Sopenharmony_ci#include <linux/regmap.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define PFUZE_FLAG_DISABLE_SW BIT(1) 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define PFUZE_NUMREGS 128 238c2ecf20Sopenharmony_ci#define PFUZE100_VOL_OFFSET 0 248c2ecf20Sopenharmony_ci#define PFUZE100_STANDBY_OFFSET 1 258c2ecf20Sopenharmony_ci#define PFUZE100_MODE_OFFSET 3 268c2ecf20Sopenharmony_ci#define PFUZE100_CONF_OFFSET 4 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#define PFUZE100_DEVICEID 0x0 298c2ecf20Sopenharmony_ci#define PFUZE100_REVID 0x3 308c2ecf20Sopenharmony_ci#define PFUZE100_FABID 0x4 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#define PFUZE100_COINVOL 0x1a 338c2ecf20Sopenharmony_ci#define PFUZE100_SW1ABVOL 0x20 348c2ecf20Sopenharmony_ci#define PFUZE100_SW1ABMODE 0x23 358c2ecf20Sopenharmony_ci#define PFUZE100_SW1CVOL 0x2e 368c2ecf20Sopenharmony_ci#define PFUZE100_SW1CMODE 0x31 378c2ecf20Sopenharmony_ci#define PFUZE100_SW2VOL 0x35 388c2ecf20Sopenharmony_ci#define PFUZE100_SW2MODE 0x38 398c2ecf20Sopenharmony_ci#define PFUZE100_SW3AVOL 0x3c 408c2ecf20Sopenharmony_ci#define PFUZE100_SW3AMODE 0x3f 418c2ecf20Sopenharmony_ci#define PFUZE100_SW3BVOL 0x43 428c2ecf20Sopenharmony_ci#define PFUZE100_SW3BMODE 0x46 438c2ecf20Sopenharmony_ci#define PFUZE100_SW4VOL 0x4a 448c2ecf20Sopenharmony_ci#define PFUZE100_SW4MODE 0x4d 458c2ecf20Sopenharmony_ci#define PFUZE100_SWBSTCON1 0x66 468c2ecf20Sopenharmony_ci#define PFUZE100_VREFDDRCON 0x6a 478c2ecf20Sopenharmony_ci#define PFUZE100_VSNVSVOL 0x6b 488c2ecf20Sopenharmony_ci#define PFUZE100_VGEN1VOL 0x6c 498c2ecf20Sopenharmony_ci#define PFUZE100_VGEN2VOL 0x6d 508c2ecf20Sopenharmony_ci#define PFUZE100_VGEN3VOL 0x6e 518c2ecf20Sopenharmony_ci#define PFUZE100_VGEN4VOL 0x6f 528c2ecf20Sopenharmony_ci#define PFUZE100_VGEN5VOL 0x70 538c2ecf20Sopenharmony_ci#define PFUZE100_VGEN6VOL 0x71 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#define PFUZE100_SWxMODE_MASK 0xf 568c2ecf20Sopenharmony_ci#define PFUZE100_SWxMODE_APS_APS 0x8 578c2ecf20Sopenharmony_ci#define PFUZE100_SWxMODE_APS_OFF 0x4 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#define PFUZE100_VGENxLPWR BIT(6) 608c2ecf20Sopenharmony_ci#define PFUZE100_VGENxSTBY BIT(5) 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_cienum chips { PFUZE100, PFUZE200, PFUZE3000 = 3, PFUZE3001 = 0x31, }; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistruct pfuze_regulator { 658c2ecf20Sopenharmony_ci struct regulator_desc desc; 668c2ecf20Sopenharmony_ci unsigned char stby_reg; 678c2ecf20Sopenharmony_ci unsigned char stby_mask; 688c2ecf20Sopenharmony_ci bool sw_reg; 698c2ecf20Sopenharmony_ci}; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistruct pfuze_chip { 728c2ecf20Sopenharmony_ci int chip_id; 738c2ecf20Sopenharmony_ci int flags; 748c2ecf20Sopenharmony_ci struct regmap *regmap; 758c2ecf20Sopenharmony_ci struct device *dev; 768c2ecf20Sopenharmony_ci struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR]; 778c2ecf20Sopenharmony_ci struct regulator_dev *regulators[PFUZE100_MAX_REGULATOR]; 788c2ecf20Sopenharmony_ci struct pfuze_regulator *pfuze_regulators; 798c2ecf20Sopenharmony_ci}; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistatic const int pfuze100_swbst[] = { 828c2ecf20Sopenharmony_ci 5000000, 5050000, 5100000, 5150000, 838c2ecf20Sopenharmony_ci}; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistatic const int pfuze100_vsnvs[] = { 868c2ecf20Sopenharmony_ci 1000000, 1100000, 1200000, 1300000, 1500000, 1800000, 3000000, 878c2ecf20Sopenharmony_ci}; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic const int pfuze100_coin[] = { 908c2ecf20Sopenharmony_ci 2500000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000, 918c2ecf20Sopenharmony_ci}; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic const int pfuze3000_sw1a[] = { 948c2ecf20Sopenharmony_ci 700000, 725000, 750000, 775000, 800000, 825000, 850000, 875000, 958c2ecf20Sopenharmony_ci 900000, 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 968c2ecf20Sopenharmony_ci 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 978c2ecf20Sopenharmony_ci 1300000, 1325000, 1350000, 1375000, 1400000, 1425000, 1800000, 3300000, 988c2ecf20Sopenharmony_ci}; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_cistatic const int pfuze3000_sw2lo[] = { 1018c2ecf20Sopenharmony_ci 1500000, 1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1028c2ecf20Sopenharmony_ci}; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_cistatic const int pfuze3000_sw2hi[] = { 1058c2ecf20Sopenharmony_ci 2500000, 2800000, 2850000, 3000000, 3100000, 3150000, 3200000, 3300000, 1068c2ecf20Sopenharmony_ci}; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistatic const struct i2c_device_id pfuze_device_id[] = { 1098c2ecf20Sopenharmony_ci {.name = "pfuze100", .driver_data = PFUZE100}, 1108c2ecf20Sopenharmony_ci {.name = "pfuze200", .driver_data = PFUZE200}, 1118c2ecf20Sopenharmony_ci {.name = "pfuze3000", .driver_data = PFUZE3000}, 1128c2ecf20Sopenharmony_ci {.name = "pfuze3001", .driver_data = PFUZE3001}, 1138c2ecf20Sopenharmony_ci { } 1148c2ecf20Sopenharmony_ci}; 1158c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, pfuze_device_id); 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_cistatic const struct of_device_id pfuze_dt_ids[] = { 1188c2ecf20Sopenharmony_ci { .compatible = "fsl,pfuze100", .data = (void *)PFUZE100}, 1198c2ecf20Sopenharmony_ci { .compatible = "fsl,pfuze200", .data = (void *)PFUZE200}, 1208c2ecf20Sopenharmony_ci { .compatible = "fsl,pfuze3000", .data = (void *)PFUZE3000}, 1218c2ecf20Sopenharmony_ci { .compatible = "fsl,pfuze3001", .data = (void *)PFUZE3001}, 1228c2ecf20Sopenharmony_ci { } 1238c2ecf20Sopenharmony_ci}; 1248c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, pfuze_dt_ids); 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) 1278c2ecf20Sopenharmony_ci{ 1288c2ecf20Sopenharmony_ci struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev); 1298c2ecf20Sopenharmony_ci int id = rdev_get_id(rdev); 1308c2ecf20Sopenharmony_ci bool reg_has_ramp_delay; 1318c2ecf20Sopenharmony_ci unsigned int ramp_bits = 0; 1328c2ecf20Sopenharmony_ci int ret; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci switch (pfuze100->chip_id) { 1358c2ecf20Sopenharmony_ci case PFUZE3001: 1368c2ecf20Sopenharmony_ci /* no dynamic voltage scaling for PF3001 */ 1378c2ecf20Sopenharmony_ci reg_has_ramp_delay = false; 1388c2ecf20Sopenharmony_ci break; 1398c2ecf20Sopenharmony_ci case PFUZE3000: 1408c2ecf20Sopenharmony_ci reg_has_ramp_delay = (id < PFUZE3000_SWBST); 1418c2ecf20Sopenharmony_ci break; 1428c2ecf20Sopenharmony_ci case PFUZE200: 1438c2ecf20Sopenharmony_ci reg_has_ramp_delay = (id < PFUZE200_SWBST); 1448c2ecf20Sopenharmony_ci break; 1458c2ecf20Sopenharmony_ci case PFUZE100: 1468c2ecf20Sopenharmony_ci default: 1478c2ecf20Sopenharmony_ci reg_has_ramp_delay = (id < PFUZE100_SWBST); 1488c2ecf20Sopenharmony_ci break; 1498c2ecf20Sopenharmony_ci } 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci if (reg_has_ramp_delay) { 1528c2ecf20Sopenharmony_ci if (ramp_delay > 0) { 1538c2ecf20Sopenharmony_ci ramp_delay = 12500 / ramp_delay; 1548c2ecf20Sopenharmony_ci ramp_bits = (ramp_delay >> 1) - (ramp_delay >> 3); 1558c2ecf20Sopenharmony_ci } 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci ret = regmap_update_bits(pfuze100->regmap, 1588c2ecf20Sopenharmony_ci rdev->desc->vsel_reg + 4, 1598c2ecf20Sopenharmony_ci 0xc0, ramp_bits << 6); 1608c2ecf20Sopenharmony_ci if (ret < 0) 1618c2ecf20Sopenharmony_ci dev_err(pfuze100->dev, "ramp failed, err %d\n", ret); 1628c2ecf20Sopenharmony_ci } else { 1638c2ecf20Sopenharmony_ci ret = -EACCES; 1648c2ecf20Sopenharmony_ci } 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci return ret; 1678c2ecf20Sopenharmony_ci} 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_cistatic const struct regulator_ops pfuze100_ldo_regulator_ops = { 1708c2ecf20Sopenharmony_ci .enable = regulator_enable_regmap, 1718c2ecf20Sopenharmony_ci .disable = regulator_disable_regmap, 1728c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 1738c2ecf20Sopenharmony_ci .list_voltage = regulator_list_voltage_linear, 1748c2ecf20Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 1758c2ecf20Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 1768c2ecf20Sopenharmony_ci}; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_cistatic const struct regulator_ops pfuze100_fixed_regulator_ops = { 1798c2ecf20Sopenharmony_ci .enable = regulator_enable_regmap, 1808c2ecf20Sopenharmony_ci .disable = regulator_disable_regmap, 1818c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 1828c2ecf20Sopenharmony_ci .list_voltage = regulator_list_voltage_linear, 1838c2ecf20Sopenharmony_ci}; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_cistatic const struct regulator_ops pfuze100_sw_regulator_ops = { 1868c2ecf20Sopenharmony_ci .list_voltage = regulator_list_voltage_linear, 1878c2ecf20Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 1888c2ecf20Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 1898c2ecf20Sopenharmony_ci .set_voltage_time_sel = regulator_set_voltage_time_sel, 1908c2ecf20Sopenharmony_ci .set_ramp_delay = pfuze100_set_ramp_delay, 1918c2ecf20Sopenharmony_ci}; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistatic const struct regulator_ops pfuze100_sw_disable_regulator_ops = { 1948c2ecf20Sopenharmony_ci .enable = regulator_enable_regmap, 1958c2ecf20Sopenharmony_ci .disable = regulator_disable_regmap, 1968c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 1978c2ecf20Sopenharmony_ci .list_voltage = regulator_list_voltage_linear, 1988c2ecf20Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 1998c2ecf20Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 2008c2ecf20Sopenharmony_ci .set_voltage_time_sel = regulator_set_voltage_time_sel, 2018c2ecf20Sopenharmony_ci .set_ramp_delay = pfuze100_set_ramp_delay, 2028c2ecf20Sopenharmony_ci}; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cistatic const struct regulator_ops pfuze100_swb_regulator_ops = { 2058c2ecf20Sopenharmony_ci .enable = regulator_enable_regmap, 2068c2ecf20Sopenharmony_ci .disable = regulator_disable_regmap, 2078c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 2088c2ecf20Sopenharmony_ci .list_voltage = regulator_list_voltage_table, 2098c2ecf20Sopenharmony_ci .map_voltage = regulator_map_voltage_ascend, 2108c2ecf20Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 2118c2ecf20Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci}; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_cistatic const struct regulator_ops pfuze3000_sw_regulator_ops = { 2168c2ecf20Sopenharmony_ci .enable = regulator_enable_regmap, 2178c2ecf20Sopenharmony_ci .disable = regulator_disable_regmap, 2188c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 2198c2ecf20Sopenharmony_ci .list_voltage = regulator_list_voltage_table, 2208c2ecf20Sopenharmony_ci .map_voltage = regulator_map_voltage_ascend, 2218c2ecf20Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 2228c2ecf20Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 2238c2ecf20Sopenharmony_ci .set_voltage_time_sel = regulator_set_voltage_time_sel, 2248c2ecf20Sopenharmony_ci .set_ramp_delay = pfuze100_set_ramp_delay, 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci}; 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci#define PFUZE100_FIXED_REG(_chip, _name, base, voltage) \ 2298c2ecf20Sopenharmony_ci [_chip ## _ ## _name] = { \ 2308c2ecf20Sopenharmony_ci .desc = { \ 2318c2ecf20Sopenharmony_ci .name = #_name, \ 2328c2ecf20Sopenharmony_ci .n_voltages = 1, \ 2338c2ecf20Sopenharmony_ci .ops = &pfuze100_fixed_regulator_ops, \ 2348c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 2358c2ecf20Sopenharmony_ci .id = _chip ## _ ## _name, \ 2368c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 2378c2ecf20Sopenharmony_ci .min_uV = (voltage), \ 2388c2ecf20Sopenharmony_ci .enable_reg = (base), \ 2398c2ecf20Sopenharmony_ci .enable_mask = 0x10, \ 2408c2ecf20Sopenharmony_ci }, \ 2418c2ecf20Sopenharmony_ci } 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci#define PFUZE100_SW_REG(_chip, _name, base, min, max, step) \ 2448c2ecf20Sopenharmony_ci [_chip ## _ ## _name] = { \ 2458c2ecf20Sopenharmony_ci .desc = { \ 2468c2ecf20Sopenharmony_ci .name = #_name,\ 2478c2ecf20Sopenharmony_ci .n_voltages = ((max) - (min)) / (step) + 1, \ 2488c2ecf20Sopenharmony_ci .ops = &pfuze100_sw_regulator_ops, \ 2498c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 2508c2ecf20Sopenharmony_ci .id = _chip ## _ ## _name, \ 2518c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 2528c2ecf20Sopenharmony_ci .min_uV = (min), \ 2538c2ecf20Sopenharmony_ci .uV_step = (step), \ 2548c2ecf20Sopenharmony_ci .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \ 2558c2ecf20Sopenharmony_ci .vsel_mask = 0x3f, \ 2568c2ecf20Sopenharmony_ci .enable_reg = (base) + PFUZE100_MODE_OFFSET, \ 2578c2ecf20Sopenharmony_ci .enable_mask = 0xf, \ 2588c2ecf20Sopenharmony_ci }, \ 2598c2ecf20Sopenharmony_ci .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \ 2608c2ecf20Sopenharmony_ci .stby_mask = 0x3f, \ 2618c2ecf20Sopenharmony_ci .sw_reg = true, \ 2628c2ecf20Sopenharmony_ci } 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci#define PFUZE100_SWB_REG(_chip, _name, base, mask, voltages) \ 2658c2ecf20Sopenharmony_ci [_chip ## _ ## _name] = { \ 2668c2ecf20Sopenharmony_ci .desc = { \ 2678c2ecf20Sopenharmony_ci .name = #_name, \ 2688c2ecf20Sopenharmony_ci .n_voltages = ARRAY_SIZE(voltages), \ 2698c2ecf20Sopenharmony_ci .ops = &pfuze100_swb_regulator_ops, \ 2708c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 2718c2ecf20Sopenharmony_ci .id = _chip ## _ ## _name, \ 2728c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 2738c2ecf20Sopenharmony_ci .volt_table = voltages, \ 2748c2ecf20Sopenharmony_ci .vsel_reg = (base), \ 2758c2ecf20Sopenharmony_ci .vsel_mask = (mask), \ 2768c2ecf20Sopenharmony_ci .enable_reg = (base), \ 2778c2ecf20Sopenharmony_ci .enable_mask = 0x48, \ 2788c2ecf20Sopenharmony_ci }, \ 2798c2ecf20Sopenharmony_ci } 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci#define PFUZE100_VGEN_REG(_chip, _name, base, min, max, step) \ 2828c2ecf20Sopenharmony_ci [_chip ## _ ## _name] = { \ 2838c2ecf20Sopenharmony_ci .desc = { \ 2848c2ecf20Sopenharmony_ci .name = #_name, \ 2858c2ecf20Sopenharmony_ci .n_voltages = ((max) - (min)) / (step) + 1, \ 2868c2ecf20Sopenharmony_ci .ops = &pfuze100_ldo_regulator_ops, \ 2878c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 2888c2ecf20Sopenharmony_ci .id = _chip ## _ ## _name, \ 2898c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 2908c2ecf20Sopenharmony_ci .min_uV = (min), \ 2918c2ecf20Sopenharmony_ci .uV_step = (step), \ 2928c2ecf20Sopenharmony_ci .vsel_reg = (base), \ 2938c2ecf20Sopenharmony_ci .vsel_mask = 0xf, \ 2948c2ecf20Sopenharmony_ci .enable_reg = (base), \ 2958c2ecf20Sopenharmony_ci .enable_mask = 0x10, \ 2968c2ecf20Sopenharmony_ci }, \ 2978c2ecf20Sopenharmony_ci .stby_reg = (base), \ 2988c2ecf20Sopenharmony_ci .stby_mask = 0x20, \ 2998c2ecf20Sopenharmony_ci } 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci#define PFUZE100_COIN_REG(_chip, _name, base, mask, voltages) \ 3028c2ecf20Sopenharmony_ci [_chip ## _ ## _name] = { \ 3038c2ecf20Sopenharmony_ci .desc = { \ 3048c2ecf20Sopenharmony_ci .name = #_name, \ 3058c2ecf20Sopenharmony_ci .n_voltages = ARRAY_SIZE(voltages), \ 3068c2ecf20Sopenharmony_ci .ops = &pfuze100_swb_regulator_ops, \ 3078c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 3088c2ecf20Sopenharmony_ci .id = _chip ## _ ## _name, \ 3098c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 3108c2ecf20Sopenharmony_ci .volt_table = voltages, \ 3118c2ecf20Sopenharmony_ci .vsel_reg = (base), \ 3128c2ecf20Sopenharmony_ci .vsel_mask = (mask), \ 3138c2ecf20Sopenharmony_ci .enable_reg = (base), \ 3148c2ecf20Sopenharmony_ci .enable_mask = 0x8, \ 3158c2ecf20Sopenharmony_ci }, \ 3168c2ecf20Sopenharmony_ci } 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci#define PFUZE3000_VCC_REG(_chip, _name, base, min, max, step) { \ 3198c2ecf20Sopenharmony_ci .desc = { \ 3208c2ecf20Sopenharmony_ci .name = #_name, \ 3218c2ecf20Sopenharmony_ci .n_voltages = ((max) - (min)) / (step) + 1, \ 3228c2ecf20Sopenharmony_ci .ops = &pfuze100_ldo_regulator_ops, \ 3238c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 3248c2ecf20Sopenharmony_ci .id = _chip ## _ ## _name, \ 3258c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 3268c2ecf20Sopenharmony_ci .min_uV = (min), \ 3278c2ecf20Sopenharmony_ci .uV_step = (step), \ 3288c2ecf20Sopenharmony_ci .vsel_reg = (base), \ 3298c2ecf20Sopenharmony_ci .vsel_mask = 0x3, \ 3308c2ecf20Sopenharmony_ci .enable_reg = (base), \ 3318c2ecf20Sopenharmony_ci .enable_mask = 0x10, \ 3328c2ecf20Sopenharmony_ci }, \ 3338c2ecf20Sopenharmony_ci .stby_reg = (base), \ 3348c2ecf20Sopenharmony_ci .stby_mask = 0x20, \ 3358c2ecf20Sopenharmony_ci} 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci/* No linar case for the some switches of PFUZE3000 */ 3388c2ecf20Sopenharmony_ci#define PFUZE3000_SW_REG(_chip, _name, base, mask, voltages) \ 3398c2ecf20Sopenharmony_ci [_chip ## _ ## _name] = { \ 3408c2ecf20Sopenharmony_ci .desc = { \ 3418c2ecf20Sopenharmony_ci .name = #_name, \ 3428c2ecf20Sopenharmony_ci .n_voltages = ARRAY_SIZE(voltages), \ 3438c2ecf20Sopenharmony_ci .ops = &pfuze3000_sw_regulator_ops, \ 3448c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 3458c2ecf20Sopenharmony_ci .id = _chip ## _ ## _name, \ 3468c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 3478c2ecf20Sopenharmony_ci .volt_table = voltages, \ 3488c2ecf20Sopenharmony_ci .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \ 3498c2ecf20Sopenharmony_ci .vsel_mask = (mask), \ 3508c2ecf20Sopenharmony_ci .enable_reg = (base) + PFUZE100_MODE_OFFSET, \ 3518c2ecf20Sopenharmony_ci .enable_mask = 0xf, \ 3528c2ecf20Sopenharmony_ci .enable_val = 0x8, \ 3538c2ecf20Sopenharmony_ci .enable_time = 500, \ 3548c2ecf20Sopenharmony_ci }, \ 3558c2ecf20Sopenharmony_ci .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \ 3568c2ecf20Sopenharmony_ci .stby_mask = (mask), \ 3578c2ecf20Sopenharmony_ci .sw_reg = true, \ 3588c2ecf20Sopenharmony_ci } 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci#define PFUZE3000_SW3_REG(_chip, _name, base, min, max, step) { \ 3618c2ecf20Sopenharmony_ci .desc = { \ 3628c2ecf20Sopenharmony_ci .name = #_name,\ 3638c2ecf20Sopenharmony_ci .n_voltages = ((max) - (min)) / (step) + 1, \ 3648c2ecf20Sopenharmony_ci .ops = &pfuze100_sw_regulator_ops, \ 3658c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 3668c2ecf20Sopenharmony_ci .id = _chip ## _ ## _name, \ 3678c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 3688c2ecf20Sopenharmony_ci .min_uV = (min), \ 3698c2ecf20Sopenharmony_ci .uV_step = (step), \ 3708c2ecf20Sopenharmony_ci .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \ 3718c2ecf20Sopenharmony_ci .vsel_mask = 0xf, \ 3728c2ecf20Sopenharmony_ci }, \ 3738c2ecf20Sopenharmony_ci .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \ 3748c2ecf20Sopenharmony_ci .stby_mask = 0xf, \ 3758c2ecf20Sopenharmony_ci} 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci/* PFUZE100 */ 3788c2ecf20Sopenharmony_cistatic struct pfuze_regulator pfuze100_regulators[] = { 3798c2ecf20Sopenharmony_ci PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), 3808c2ecf20Sopenharmony_ci PFUZE100_SW_REG(PFUZE100, SW1C, PFUZE100_SW1CVOL, 300000, 1875000, 25000), 3818c2ecf20Sopenharmony_ci PFUZE100_SW_REG(PFUZE100, SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000), 3828c2ecf20Sopenharmony_ci PFUZE100_SW_REG(PFUZE100, SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000), 3838c2ecf20Sopenharmony_ci PFUZE100_SW_REG(PFUZE100, SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000), 3848c2ecf20Sopenharmony_ci PFUZE100_SW_REG(PFUZE100, SW4, PFUZE100_SW4VOL, 400000, 1975000, 25000), 3858c2ecf20Sopenharmony_ci PFUZE100_SWB_REG(PFUZE100, SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst), 3868c2ecf20Sopenharmony_ci PFUZE100_SWB_REG(PFUZE100, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), 3878c2ecf20Sopenharmony_ci PFUZE100_FIXED_REG(PFUZE100, VREFDDR, PFUZE100_VREFDDRCON, 750000), 3888c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE100, VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000), 3898c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE100, VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000), 3908c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE100, VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000), 3918c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE100, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000), 3928c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE100, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000), 3938c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE100, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), 3948c2ecf20Sopenharmony_ci PFUZE100_COIN_REG(PFUZE100, COIN, PFUZE100_COINVOL, 0x7, pfuze100_coin), 3958c2ecf20Sopenharmony_ci}; 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_cistatic struct pfuze_regulator pfuze200_regulators[] = { 3988c2ecf20Sopenharmony_ci PFUZE100_SW_REG(PFUZE200, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), 3998c2ecf20Sopenharmony_ci PFUZE100_SW_REG(PFUZE200, SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000), 4008c2ecf20Sopenharmony_ci PFUZE100_SW_REG(PFUZE200, SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000), 4018c2ecf20Sopenharmony_ci PFUZE100_SW_REG(PFUZE200, SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000), 4028c2ecf20Sopenharmony_ci PFUZE100_SWB_REG(PFUZE200, SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst), 4038c2ecf20Sopenharmony_ci PFUZE100_SWB_REG(PFUZE200, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), 4048c2ecf20Sopenharmony_ci PFUZE100_FIXED_REG(PFUZE200, VREFDDR, PFUZE100_VREFDDRCON, 750000), 4058c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE200, VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000), 4068c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE200, VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000), 4078c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE200, VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000), 4088c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE200, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000), 4098c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE200, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000), 4108c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE200, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), 4118c2ecf20Sopenharmony_ci PFUZE100_COIN_REG(PFUZE200, COIN, PFUZE100_COINVOL, 0x7, pfuze100_coin), 4128c2ecf20Sopenharmony_ci}; 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_cistatic struct pfuze_regulator pfuze3000_regulators[] = { 4158c2ecf20Sopenharmony_ci PFUZE3000_SW_REG(PFUZE3000, SW1A, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a), 4168c2ecf20Sopenharmony_ci PFUZE100_SW_REG(PFUZE3000, SW1B, PFUZE100_SW1CVOL, 700000, 1475000, 25000), 4178c2ecf20Sopenharmony_ci PFUZE3000_SW_REG(PFUZE3000, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo), 4188c2ecf20Sopenharmony_ci PFUZE3000_SW3_REG(PFUZE3000, SW3, PFUZE100_SW3AVOL, 900000, 1650000, 50000), 4198c2ecf20Sopenharmony_ci PFUZE100_SWB_REG(PFUZE3000, SWBST, PFUZE100_SWBSTCON1, 0x3, pfuze100_swbst), 4208c2ecf20Sopenharmony_ci PFUZE100_SWB_REG(PFUZE3000, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), 4218c2ecf20Sopenharmony_ci PFUZE100_FIXED_REG(PFUZE3000, VREFDDR, PFUZE100_VREFDDRCON, 750000), 4228c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE3000, VLDO1, PFUZE100_VGEN1VOL, 1800000, 3300000, 100000), 4238c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE3000, VLDO2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000), 4248c2ecf20Sopenharmony_ci PFUZE3000_VCC_REG(PFUZE3000, VCCSD, PFUZE100_VGEN3VOL, 2850000, 3300000, 150000), 4258c2ecf20Sopenharmony_ci PFUZE3000_VCC_REG(PFUZE3000, V33, PFUZE100_VGEN4VOL, 2850000, 3300000, 150000), 4268c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE3000, VLDO3, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000), 4278c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE3000, VLDO4, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), 4288c2ecf20Sopenharmony_ci}; 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_cistatic struct pfuze_regulator pfuze3001_regulators[] = { 4318c2ecf20Sopenharmony_ci PFUZE3000_SW_REG(PFUZE3001, SW1, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a), 4328c2ecf20Sopenharmony_ci PFUZE3000_SW_REG(PFUZE3001, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo), 4338c2ecf20Sopenharmony_ci PFUZE3000_SW3_REG(PFUZE3001, SW3, PFUZE100_SW3AVOL, 900000, 1650000, 50000), 4348c2ecf20Sopenharmony_ci PFUZE100_SWB_REG(PFUZE3001, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), 4358c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE3001, VLDO1, PFUZE100_VGEN1VOL, 1800000, 3300000, 100000), 4368c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE3001, VLDO2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000), 4378c2ecf20Sopenharmony_ci PFUZE3000_VCC_REG(PFUZE3001, VCCSD, PFUZE100_VGEN3VOL, 2850000, 3300000, 150000), 4388c2ecf20Sopenharmony_ci PFUZE3000_VCC_REG(PFUZE3001, V33, PFUZE100_VGEN4VOL, 2850000, 3300000, 150000), 4398c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE3001, VLDO3, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000), 4408c2ecf20Sopenharmony_ci PFUZE100_VGEN_REG(PFUZE3001, VLDO4, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), 4418c2ecf20Sopenharmony_ci}; 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci#ifdef CONFIG_OF 4448c2ecf20Sopenharmony_ci/* PFUZE100 */ 4458c2ecf20Sopenharmony_cistatic struct of_regulator_match pfuze100_matches[] = { 4468c2ecf20Sopenharmony_ci { .name = "sw1ab", }, 4478c2ecf20Sopenharmony_ci { .name = "sw1c", }, 4488c2ecf20Sopenharmony_ci { .name = "sw2", }, 4498c2ecf20Sopenharmony_ci { .name = "sw3a", }, 4508c2ecf20Sopenharmony_ci { .name = "sw3b", }, 4518c2ecf20Sopenharmony_ci { .name = "sw4", }, 4528c2ecf20Sopenharmony_ci { .name = "swbst", }, 4538c2ecf20Sopenharmony_ci { .name = "vsnvs", }, 4548c2ecf20Sopenharmony_ci { .name = "vrefddr", }, 4558c2ecf20Sopenharmony_ci { .name = "vgen1", }, 4568c2ecf20Sopenharmony_ci { .name = "vgen2", }, 4578c2ecf20Sopenharmony_ci { .name = "vgen3", }, 4588c2ecf20Sopenharmony_ci { .name = "vgen4", }, 4598c2ecf20Sopenharmony_ci { .name = "vgen5", }, 4608c2ecf20Sopenharmony_ci { .name = "vgen6", }, 4618c2ecf20Sopenharmony_ci { .name = "coin", }, 4628c2ecf20Sopenharmony_ci}; 4638c2ecf20Sopenharmony_ci 4648c2ecf20Sopenharmony_ci/* PFUZE200 */ 4658c2ecf20Sopenharmony_cistatic struct of_regulator_match pfuze200_matches[] = { 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_ci { .name = "sw1ab", }, 4688c2ecf20Sopenharmony_ci { .name = "sw2", }, 4698c2ecf20Sopenharmony_ci { .name = "sw3a", }, 4708c2ecf20Sopenharmony_ci { .name = "sw3b", }, 4718c2ecf20Sopenharmony_ci { .name = "swbst", }, 4728c2ecf20Sopenharmony_ci { .name = "vsnvs", }, 4738c2ecf20Sopenharmony_ci { .name = "vrefddr", }, 4748c2ecf20Sopenharmony_ci { .name = "vgen1", }, 4758c2ecf20Sopenharmony_ci { .name = "vgen2", }, 4768c2ecf20Sopenharmony_ci { .name = "vgen3", }, 4778c2ecf20Sopenharmony_ci { .name = "vgen4", }, 4788c2ecf20Sopenharmony_ci { .name = "vgen5", }, 4798c2ecf20Sopenharmony_ci { .name = "vgen6", }, 4808c2ecf20Sopenharmony_ci { .name = "coin", }, 4818c2ecf20Sopenharmony_ci}; 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci/* PFUZE3000 */ 4848c2ecf20Sopenharmony_cistatic struct of_regulator_match pfuze3000_matches[] = { 4858c2ecf20Sopenharmony_ci 4868c2ecf20Sopenharmony_ci { .name = "sw1a", }, 4878c2ecf20Sopenharmony_ci { .name = "sw1b", }, 4888c2ecf20Sopenharmony_ci { .name = "sw2", }, 4898c2ecf20Sopenharmony_ci { .name = "sw3", }, 4908c2ecf20Sopenharmony_ci { .name = "swbst", }, 4918c2ecf20Sopenharmony_ci { .name = "vsnvs", }, 4928c2ecf20Sopenharmony_ci { .name = "vrefddr", }, 4938c2ecf20Sopenharmony_ci { .name = "vldo1", }, 4948c2ecf20Sopenharmony_ci { .name = "vldo2", }, 4958c2ecf20Sopenharmony_ci { .name = "vccsd", }, 4968c2ecf20Sopenharmony_ci { .name = "v33", }, 4978c2ecf20Sopenharmony_ci { .name = "vldo3", }, 4988c2ecf20Sopenharmony_ci { .name = "vldo4", }, 4998c2ecf20Sopenharmony_ci}; 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ci/* PFUZE3001 */ 5028c2ecf20Sopenharmony_cistatic struct of_regulator_match pfuze3001_matches[] = { 5038c2ecf20Sopenharmony_ci 5048c2ecf20Sopenharmony_ci { .name = "sw1", }, 5058c2ecf20Sopenharmony_ci { .name = "sw2", }, 5068c2ecf20Sopenharmony_ci { .name = "sw3", }, 5078c2ecf20Sopenharmony_ci { .name = "vsnvs", }, 5088c2ecf20Sopenharmony_ci { .name = "vldo1", }, 5098c2ecf20Sopenharmony_ci { .name = "vldo2", }, 5108c2ecf20Sopenharmony_ci { .name = "vccsd", }, 5118c2ecf20Sopenharmony_ci { .name = "v33", }, 5128c2ecf20Sopenharmony_ci { .name = "vldo3", }, 5138c2ecf20Sopenharmony_ci { .name = "vldo4", }, 5148c2ecf20Sopenharmony_ci}; 5158c2ecf20Sopenharmony_ci 5168c2ecf20Sopenharmony_cistatic struct of_regulator_match *pfuze_matches; 5178c2ecf20Sopenharmony_ci 5188c2ecf20Sopenharmony_cistatic int pfuze_parse_regulators_dt(struct pfuze_chip *chip) 5198c2ecf20Sopenharmony_ci{ 5208c2ecf20Sopenharmony_ci struct device *dev = chip->dev; 5218c2ecf20Sopenharmony_ci struct device_node *np, *parent; 5228c2ecf20Sopenharmony_ci int ret; 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci np = of_node_get(dev->of_node); 5258c2ecf20Sopenharmony_ci if (!np) 5268c2ecf20Sopenharmony_ci return -EINVAL; 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci if (of_property_read_bool(np, "fsl,pfuze-support-disable-sw")) 5298c2ecf20Sopenharmony_ci chip->flags |= PFUZE_FLAG_DISABLE_SW; 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_ci parent = of_get_child_by_name(np, "regulators"); 5328c2ecf20Sopenharmony_ci if (!parent) { 5338c2ecf20Sopenharmony_ci dev_err(dev, "regulators node not found\n"); 5348c2ecf20Sopenharmony_ci of_node_put(np); 5358c2ecf20Sopenharmony_ci return -EINVAL; 5368c2ecf20Sopenharmony_ci } 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci switch (chip->chip_id) { 5398c2ecf20Sopenharmony_ci case PFUZE3001: 5408c2ecf20Sopenharmony_ci pfuze_matches = pfuze3001_matches; 5418c2ecf20Sopenharmony_ci ret = of_regulator_match(dev, parent, pfuze3001_matches, 5428c2ecf20Sopenharmony_ci ARRAY_SIZE(pfuze3001_matches)); 5438c2ecf20Sopenharmony_ci break; 5448c2ecf20Sopenharmony_ci case PFUZE3000: 5458c2ecf20Sopenharmony_ci pfuze_matches = pfuze3000_matches; 5468c2ecf20Sopenharmony_ci ret = of_regulator_match(dev, parent, pfuze3000_matches, 5478c2ecf20Sopenharmony_ci ARRAY_SIZE(pfuze3000_matches)); 5488c2ecf20Sopenharmony_ci break; 5498c2ecf20Sopenharmony_ci case PFUZE200: 5508c2ecf20Sopenharmony_ci pfuze_matches = pfuze200_matches; 5518c2ecf20Sopenharmony_ci ret = of_regulator_match(dev, parent, pfuze200_matches, 5528c2ecf20Sopenharmony_ci ARRAY_SIZE(pfuze200_matches)); 5538c2ecf20Sopenharmony_ci break; 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_ci case PFUZE100: 5568c2ecf20Sopenharmony_ci default: 5578c2ecf20Sopenharmony_ci pfuze_matches = pfuze100_matches; 5588c2ecf20Sopenharmony_ci ret = of_regulator_match(dev, parent, pfuze100_matches, 5598c2ecf20Sopenharmony_ci ARRAY_SIZE(pfuze100_matches)); 5608c2ecf20Sopenharmony_ci break; 5618c2ecf20Sopenharmony_ci } 5628c2ecf20Sopenharmony_ci 5638c2ecf20Sopenharmony_ci of_node_put(parent); 5648c2ecf20Sopenharmony_ci of_node_put(np); 5658c2ecf20Sopenharmony_ci if (ret < 0) { 5668c2ecf20Sopenharmony_ci dev_err(dev, "Error parsing regulator init data: %d\n", 5678c2ecf20Sopenharmony_ci ret); 5688c2ecf20Sopenharmony_ci return ret; 5698c2ecf20Sopenharmony_ci } 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci return 0; 5728c2ecf20Sopenharmony_ci} 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_cistatic inline struct regulator_init_data *match_init_data(int index) 5758c2ecf20Sopenharmony_ci{ 5768c2ecf20Sopenharmony_ci return pfuze_matches[index].init_data; 5778c2ecf20Sopenharmony_ci} 5788c2ecf20Sopenharmony_ci 5798c2ecf20Sopenharmony_cistatic inline struct device_node *match_of_node(int index) 5808c2ecf20Sopenharmony_ci{ 5818c2ecf20Sopenharmony_ci return pfuze_matches[index].of_node; 5828c2ecf20Sopenharmony_ci} 5838c2ecf20Sopenharmony_ci#else 5848c2ecf20Sopenharmony_cistatic int pfuze_parse_regulators_dt(struct pfuze_chip *chip) 5858c2ecf20Sopenharmony_ci{ 5868c2ecf20Sopenharmony_ci return 0; 5878c2ecf20Sopenharmony_ci} 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_cistatic inline struct regulator_init_data *match_init_data(int index) 5908c2ecf20Sopenharmony_ci{ 5918c2ecf20Sopenharmony_ci return NULL; 5928c2ecf20Sopenharmony_ci} 5938c2ecf20Sopenharmony_ci 5948c2ecf20Sopenharmony_cistatic inline struct device_node *match_of_node(int index) 5958c2ecf20Sopenharmony_ci{ 5968c2ecf20Sopenharmony_ci return NULL; 5978c2ecf20Sopenharmony_ci} 5988c2ecf20Sopenharmony_ci#endif 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_cistatic struct pfuze_chip *syspm_pfuze_chip; 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_cistatic void pfuze_power_off_prepare(void) 6038c2ecf20Sopenharmony_ci{ 6048c2ecf20Sopenharmony_ci dev_info(syspm_pfuze_chip->dev, "Configure standby mode for power off"); 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_ci /* Switch from default mode: APS/APS to APS/Off */ 6078c2ecf20Sopenharmony_ci regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW1ABMODE, 6088c2ecf20Sopenharmony_ci PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); 6098c2ecf20Sopenharmony_ci regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW1CMODE, 6108c2ecf20Sopenharmony_ci PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); 6118c2ecf20Sopenharmony_ci regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW2MODE, 6128c2ecf20Sopenharmony_ci PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); 6138c2ecf20Sopenharmony_ci regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW3AMODE, 6148c2ecf20Sopenharmony_ci PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); 6158c2ecf20Sopenharmony_ci regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW3BMODE, 6168c2ecf20Sopenharmony_ci PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); 6178c2ecf20Sopenharmony_ci regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW4MODE, 6188c2ecf20Sopenharmony_ci PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_ci regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN1VOL, 6218c2ecf20Sopenharmony_ci PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, 6228c2ecf20Sopenharmony_ci PFUZE100_VGENxSTBY); 6238c2ecf20Sopenharmony_ci regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN2VOL, 6248c2ecf20Sopenharmony_ci PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, 6258c2ecf20Sopenharmony_ci PFUZE100_VGENxSTBY); 6268c2ecf20Sopenharmony_ci regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN3VOL, 6278c2ecf20Sopenharmony_ci PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, 6288c2ecf20Sopenharmony_ci PFUZE100_VGENxSTBY); 6298c2ecf20Sopenharmony_ci regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN4VOL, 6308c2ecf20Sopenharmony_ci PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, 6318c2ecf20Sopenharmony_ci PFUZE100_VGENxSTBY); 6328c2ecf20Sopenharmony_ci regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN5VOL, 6338c2ecf20Sopenharmony_ci PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, 6348c2ecf20Sopenharmony_ci PFUZE100_VGENxSTBY); 6358c2ecf20Sopenharmony_ci regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN6VOL, 6368c2ecf20Sopenharmony_ci PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, 6378c2ecf20Sopenharmony_ci PFUZE100_VGENxSTBY); 6388c2ecf20Sopenharmony_ci} 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_cistatic int pfuze_power_off_prepare_init(struct pfuze_chip *pfuze_chip) 6418c2ecf20Sopenharmony_ci{ 6428c2ecf20Sopenharmony_ci if (pfuze_chip->chip_id != PFUZE100) { 6438c2ecf20Sopenharmony_ci dev_warn(pfuze_chip->dev, "Requested pm_power_off_prepare handler for not supported chip\n"); 6448c2ecf20Sopenharmony_ci return -ENODEV; 6458c2ecf20Sopenharmony_ci } 6468c2ecf20Sopenharmony_ci 6478c2ecf20Sopenharmony_ci if (pm_power_off_prepare) { 6488c2ecf20Sopenharmony_ci dev_warn(pfuze_chip->dev, "pm_power_off_prepare is already registered.\n"); 6498c2ecf20Sopenharmony_ci return -EBUSY; 6508c2ecf20Sopenharmony_ci } 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_ci if (syspm_pfuze_chip) { 6538c2ecf20Sopenharmony_ci dev_warn(pfuze_chip->dev, "syspm_pfuze_chip is already set.\n"); 6548c2ecf20Sopenharmony_ci return -EBUSY; 6558c2ecf20Sopenharmony_ci } 6568c2ecf20Sopenharmony_ci 6578c2ecf20Sopenharmony_ci syspm_pfuze_chip = pfuze_chip; 6588c2ecf20Sopenharmony_ci pm_power_off_prepare = pfuze_power_off_prepare; 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_ci return 0; 6618c2ecf20Sopenharmony_ci} 6628c2ecf20Sopenharmony_ci 6638c2ecf20Sopenharmony_cistatic int pfuze_identify(struct pfuze_chip *pfuze_chip) 6648c2ecf20Sopenharmony_ci{ 6658c2ecf20Sopenharmony_ci unsigned int value; 6668c2ecf20Sopenharmony_ci int ret; 6678c2ecf20Sopenharmony_ci 6688c2ecf20Sopenharmony_ci ret = regmap_read(pfuze_chip->regmap, PFUZE100_DEVICEID, &value); 6698c2ecf20Sopenharmony_ci if (ret) 6708c2ecf20Sopenharmony_ci return ret; 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_ci if (((value & 0x0f) == 0x8) && (pfuze_chip->chip_id == PFUZE100)) { 6738c2ecf20Sopenharmony_ci /* 6748c2ecf20Sopenharmony_ci * Freescale misprogrammed 1-3% of parts prior to week 8 of 2013 6758c2ecf20Sopenharmony_ci * as ID=8 in PFUZE100 6768c2ecf20Sopenharmony_ci */ 6778c2ecf20Sopenharmony_ci dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8"); 6788c2ecf20Sopenharmony_ci } else if ((value & 0x0f) != pfuze_chip->chip_id && 6798c2ecf20Sopenharmony_ci (value & 0xf0) >> 4 != pfuze_chip->chip_id && 6808c2ecf20Sopenharmony_ci (value != pfuze_chip->chip_id)) { 6818c2ecf20Sopenharmony_ci /* device id NOT match with your setting */ 6828c2ecf20Sopenharmony_ci dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value); 6838c2ecf20Sopenharmony_ci return -ENODEV; 6848c2ecf20Sopenharmony_ci } 6858c2ecf20Sopenharmony_ci 6868c2ecf20Sopenharmony_ci ret = regmap_read(pfuze_chip->regmap, PFUZE100_REVID, &value); 6878c2ecf20Sopenharmony_ci if (ret) 6888c2ecf20Sopenharmony_ci return ret; 6898c2ecf20Sopenharmony_ci dev_info(pfuze_chip->dev, 6908c2ecf20Sopenharmony_ci "Full layer: %x, Metal layer: %x\n", 6918c2ecf20Sopenharmony_ci (value & 0xf0) >> 4, value & 0x0f); 6928c2ecf20Sopenharmony_ci 6938c2ecf20Sopenharmony_ci ret = regmap_read(pfuze_chip->regmap, PFUZE100_FABID, &value); 6948c2ecf20Sopenharmony_ci if (ret) 6958c2ecf20Sopenharmony_ci return ret; 6968c2ecf20Sopenharmony_ci dev_info(pfuze_chip->dev, "FAB: %x, FIN: %x\n", 6978c2ecf20Sopenharmony_ci (value & 0xc) >> 2, value & 0x3); 6988c2ecf20Sopenharmony_ci 6998c2ecf20Sopenharmony_ci return 0; 7008c2ecf20Sopenharmony_ci} 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_cistatic const struct regmap_config pfuze_regmap_config = { 7038c2ecf20Sopenharmony_ci .reg_bits = 8, 7048c2ecf20Sopenharmony_ci .val_bits = 8, 7058c2ecf20Sopenharmony_ci .max_register = PFUZE_NUMREGS - 1, 7068c2ecf20Sopenharmony_ci .cache_type = REGCACHE_RBTREE, 7078c2ecf20Sopenharmony_ci}; 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_cistatic int pfuze100_regulator_probe(struct i2c_client *client, 7108c2ecf20Sopenharmony_ci const struct i2c_device_id *id) 7118c2ecf20Sopenharmony_ci{ 7128c2ecf20Sopenharmony_ci struct pfuze_chip *pfuze_chip; 7138c2ecf20Sopenharmony_ci struct pfuze_regulator_platform_data *pdata = 7148c2ecf20Sopenharmony_ci dev_get_platdata(&client->dev); 7158c2ecf20Sopenharmony_ci struct regulator_config config = { }; 7168c2ecf20Sopenharmony_ci int i, ret; 7178c2ecf20Sopenharmony_ci const struct of_device_id *match; 7188c2ecf20Sopenharmony_ci u32 regulator_num; 7198c2ecf20Sopenharmony_ci u32 sw_check_start, sw_check_end, sw_hi = 0x40; 7208c2ecf20Sopenharmony_ci 7218c2ecf20Sopenharmony_ci pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip), 7228c2ecf20Sopenharmony_ci GFP_KERNEL); 7238c2ecf20Sopenharmony_ci if (!pfuze_chip) 7248c2ecf20Sopenharmony_ci return -ENOMEM; 7258c2ecf20Sopenharmony_ci 7268c2ecf20Sopenharmony_ci if (client->dev.of_node) { 7278c2ecf20Sopenharmony_ci match = of_match_device(of_match_ptr(pfuze_dt_ids), 7288c2ecf20Sopenharmony_ci &client->dev); 7298c2ecf20Sopenharmony_ci if (!match) { 7308c2ecf20Sopenharmony_ci dev_err(&client->dev, "Error: No device match found\n"); 7318c2ecf20Sopenharmony_ci return -ENODEV; 7328c2ecf20Sopenharmony_ci } 7338c2ecf20Sopenharmony_ci pfuze_chip->chip_id = (int)(long)match->data; 7348c2ecf20Sopenharmony_ci } else if (id) { 7358c2ecf20Sopenharmony_ci pfuze_chip->chip_id = id->driver_data; 7368c2ecf20Sopenharmony_ci } else { 7378c2ecf20Sopenharmony_ci dev_err(&client->dev, "No dts match or id table match found\n"); 7388c2ecf20Sopenharmony_ci return -ENODEV; 7398c2ecf20Sopenharmony_ci } 7408c2ecf20Sopenharmony_ci 7418c2ecf20Sopenharmony_ci i2c_set_clientdata(client, pfuze_chip); 7428c2ecf20Sopenharmony_ci pfuze_chip->dev = &client->dev; 7438c2ecf20Sopenharmony_ci 7448c2ecf20Sopenharmony_ci pfuze_chip->regmap = devm_regmap_init_i2c(client, &pfuze_regmap_config); 7458c2ecf20Sopenharmony_ci if (IS_ERR(pfuze_chip->regmap)) { 7468c2ecf20Sopenharmony_ci ret = PTR_ERR(pfuze_chip->regmap); 7478c2ecf20Sopenharmony_ci dev_err(&client->dev, 7488c2ecf20Sopenharmony_ci "regmap allocation failed with err %d\n", ret); 7498c2ecf20Sopenharmony_ci return ret; 7508c2ecf20Sopenharmony_ci } 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_ci ret = pfuze_identify(pfuze_chip); 7538c2ecf20Sopenharmony_ci if (ret) { 7548c2ecf20Sopenharmony_ci dev_err(&client->dev, "unrecognized pfuze chip ID!\n"); 7558c2ecf20Sopenharmony_ci return ret; 7568c2ecf20Sopenharmony_ci } 7578c2ecf20Sopenharmony_ci 7588c2ecf20Sopenharmony_ci /* use the right regulators after identify the right device */ 7598c2ecf20Sopenharmony_ci switch (pfuze_chip->chip_id) { 7608c2ecf20Sopenharmony_ci case PFUZE3001: 7618c2ecf20Sopenharmony_ci pfuze_chip->pfuze_regulators = pfuze3001_regulators; 7628c2ecf20Sopenharmony_ci regulator_num = ARRAY_SIZE(pfuze3001_regulators); 7638c2ecf20Sopenharmony_ci sw_check_start = PFUZE3001_SW2; 7648c2ecf20Sopenharmony_ci sw_check_end = PFUZE3001_SW2; 7658c2ecf20Sopenharmony_ci sw_hi = 1 << 3; 7668c2ecf20Sopenharmony_ci break; 7678c2ecf20Sopenharmony_ci case PFUZE3000: 7688c2ecf20Sopenharmony_ci pfuze_chip->pfuze_regulators = pfuze3000_regulators; 7698c2ecf20Sopenharmony_ci regulator_num = ARRAY_SIZE(pfuze3000_regulators); 7708c2ecf20Sopenharmony_ci sw_check_start = PFUZE3000_SW2; 7718c2ecf20Sopenharmony_ci sw_check_end = PFUZE3000_SW2; 7728c2ecf20Sopenharmony_ci sw_hi = 1 << 3; 7738c2ecf20Sopenharmony_ci break; 7748c2ecf20Sopenharmony_ci case PFUZE200: 7758c2ecf20Sopenharmony_ci pfuze_chip->pfuze_regulators = pfuze200_regulators; 7768c2ecf20Sopenharmony_ci regulator_num = ARRAY_SIZE(pfuze200_regulators); 7778c2ecf20Sopenharmony_ci sw_check_start = PFUZE200_SW2; 7788c2ecf20Sopenharmony_ci sw_check_end = PFUZE200_SW3B; 7798c2ecf20Sopenharmony_ci break; 7808c2ecf20Sopenharmony_ci case PFUZE100: 7818c2ecf20Sopenharmony_ci default: 7828c2ecf20Sopenharmony_ci pfuze_chip->pfuze_regulators = pfuze100_regulators; 7838c2ecf20Sopenharmony_ci regulator_num = ARRAY_SIZE(pfuze100_regulators); 7848c2ecf20Sopenharmony_ci sw_check_start = PFUZE100_SW2; 7858c2ecf20Sopenharmony_ci sw_check_end = PFUZE100_SW4; 7868c2ecf20Sopenharmony_ci break; 7878c2ecf20Sopenharmony_ci } 7888c2ecf20Sopenharmony_ci dev_info(&client->dev, "pfuze%s found.\n", 7898c2ecf20Sopenharmony_ci (pfuze_chip->chip_id == PFUZE100) ? "100" : 7908c2ecf20Sopenharmony_ci (((pfuze_chip->chip_id == PFUZE200) ? "200" : 7918c2ecf20Sopenharmony_ci ((pfuze_chip->chip_id == PFUZE3000) ? "3000" : "3001")))); 7928c2ecf20Sopenharmony_ci 7938c2ecf20Sopenharmony_ci memcpy(pfuze_chip->regulator_descs, pfuze_chip->pfuze_regulators, 7948c2ecf20Sopenharmony_ci regulator_num * sizeof(struct pfuze_regulator)); 7958c2ecf20Sopenharmony_ci 7968c2ecf20Sopenharmony_ci ret = pfuze_parse_regulators_dt(pfuze_chip); 7978c2ecf20Sopenharmony_ci if (ret) 7988c2ecf20Sopenharmony_ci return ret; 7998c2ecf20Sopenharmony_ci 8008c2ecf20Sopenharmony_ci for (i = 0; i < regulator_num; i++) { 8018c2ecf20Sopenharmony_ci struct regulator_init_data *init_data; 8028c2ecf20Sopenharmony_ci struct regulator_desc *desc; 8038c2ecf20Sopenharmony_ci int val; 8048c2ecf20Sopenharmony_ci 8058c2ecf20Sopenharmony_ci desc = &pfuze_chip->regulator_descs[i].desc; 8068c2ecf20Sopenharmony_ci 8078c2ecf20Sopenharmony_ci if (pdata) 8088c2ecf20Sopenharmony_ci init_data = pdata->init_data[i]; 8098c2ecf20Sopenharmony_ci else 8108c2ecf20Sopenharmony_ci init_data = match_init_data(i); 8118c2ecf20Sopenharmony_ci 8128c2ecf20Sopenharmony_ci /* SW2~SW4 high bit check and modify the voltage value table */ 8138c2ecf20Sopenharmony_ci if (i >= sw_check_start && i <= sw_check_end) { 8148c2ecf20Sopenharmony_ci ret = regmap_read(pfuze_chip->regmap, 8158c2ecf20Sopenharmony_ci desc->vsel_reg, &val); 8168c2ecf20Sopenharmony_ci if (ret) { 8178c2ecf20Sopenharmony_ci dev_err(&client->dev, "Fails to read from the register.\n"); 8188c2ecf20Sopenharmony_ci return ret; 8198c2ecf20Sopenharmony_ci } 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_ci if (val & sw_hi) { 8228c2ecf20Sopenharmony_ci if (pfuze_chip->chip_id == PFUZE3000 || 8238c2ecf20Sopenharmony_ci pfuze_chip->chip_id == PFUZE3001) { 8248c2ecf20Sopenharmony_ci desc->volt_table = pfuze3000_sw2hi; 8258c2ecf20Sopenharmony_ci desc->n_voltages = ARRAY_SIZE(pfuze3000_sw2hi); 8268c2ecf20Sopenharmony_ci } else { 8278c2ecf20Sopenharmony_ci desc->min_uV = 800000; 8288c2ecf20Sopenharmony_ci desc->uV_step = 50000; 8298c2ecf20Sopenharmony_ci desc->n_voltages = 51; 8308c2ecf20Sopenharmony_ci } 8318c2ecf20Sopenharmony_ci } 8328c2ecf20Sopenharmony_ci } 8338c2ecf20Sopenharmony_ci 8348c2ecf20Sopenharmony_ci /* 8358c2ecf20Sopenharmony_ci * Allow SW regulators to turn off. Checking it trough a flag is 8368c2ecf20Sopenharmony_ci * a workaround to keep the backward compatibility with existing 8378c2ecf20Sopenharmony_ci * old dtb's which may relay on the fact that we didn't disable 8388c2ecf20Sopenharmony_ci * the switched regulator till yet. 8398c2ecf20Sopenharmony_ci */ 8408c2ecf20Sopenharmony_ci if (pfuze_chip->flags & PFUZE_FLAG_DISABLE_SW) { 8418c2ecf20Sopenharmony_ci if (pfuze_chip->chip_id == PFUZE100 || 8428c2ecf20Sopenharmony_ci pfuze_chip->chip_id == PFUZE200) { 8438c2ecf20Sopenharmony_ci if (pfuze_chip->regulator_descs[i].sw_reg) { 8448c2ecf20Sopenharmony_ci desc->ops = &pfuze100_sw_disable_regulator_ops; 8458c2ecf20Sopenharmony_ci desc->enable_val = 0x8; 8468c2ecf20Sopenharmony_ci desc->disable_val = 0x0; 8478c2ecf20Sopenharmony_ci desc->enable_time = 500; 8488c2ecf20Sopenharmony_ci } 8498c2ecf20Sopenharmony_ci } 8508c2ecf20Sopenharmony_ci } 8518c2ecf20Sopenharmony_ci 8528c2ecf20Sopenharmony_ci config.dev = &client->dev; 8538c2ecf20Sopenharmony_ci config.init_data = init_data; 8548c2ecf20Sopenharmony_ci config.driver_data = pfuze_chip; 8558c2ecf20Sopenharmony_ci config.of_node = match_of_node(i); 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_ci pfuze_chip->regulators[i] = 8588c2ecf20Sopenharmony_ci devm_regulator_register(&client->dev, desc, &config); 8598c2ecf20Sopenharmony_ci if (IS_ERR(pfuze_chip->regulators[i])) { 8608c2ecf20Sopenharmony_ci dev_err(&client->dev, "register regulator%s failed\n", 8618c2ecf20Sopenharmony_ci pfuze_chip->pfuze_regulators[i].desc.name); 8628c2ecf20Sopenharmony_ci return PTR_ERR(pfuze_chip->regulators[i]); 8638c2ecf20Sopenharmony_ci } 8648c2ecf20Sopenharmony_ci } 8658c2ecf20Sopenharmony_ci 8668c2ecf20Sopenharmony_ci if (of_property_read_bool(client->dev.of_node, 8678c2ecf20Sopenharmony_ci "fsl,pmic-stby-poweroff")) 8688c2ecf20Sopenharmony_ci return pfuze_power_off_prepare_init(pfuze_chip); 8698c2ecf20Sopenharmony_ci 8708c2ecf20Sopenharmony_ci return 0; 8718c2ecf20Sopenharmony_ci} 8728c2ecf20Sopenharmony_ci 8738c2ecf20Sopenharmony_cistatic int pfuze100_regulator_remove(struct i2c_client *client) 8748c2ecf20Sopenharmony_ci{ 8758c2ecf20Sopenharmony_ci if (syspm_pfuze_chip) { 8768c2ecf20Sopenharmony_ci syspm_pfuze_chip = NULL; 8778c2ecf20Sopenharmony_ci pm_power_off_prepare = NULL; 8788c2ecf20Sopenharmony_ci } 8798c2ecf20Sopenharmony_ci 8808c2ecf20Sopenharmony_ci return 0; 8818c2ecf20Sopenharmony_ci} 8828c2ecf20Sopenharmony_ci 8838c2ecf20Sopenharmony_cistatic struct i2c_driver pfuze_driver = { 8848c2ecf20Sopenharmony_ci .id_table = pfuze_device_id, 8858c2ecf20Sopenharmony_ci .driver = { 8868c2ecf20Sopenharmony_ci .name = "pfuze100-regulator", 8878c2ecf20Sopenharmony_ci .of_match_table = pfuze_dt_ids, 8888c2ecf20Sopenharmony_ci }, 8898c2ecf20Sopenharmony_ci .probe = pfuze100_regulator_probe, 8908c2ecf20Sopenharmony_ci .remove = pfuze100_regulator_remove, 8918c2ecf20Sopenharmony_ci}; 8928c2ecf20Sopenharmony_cimodule_i2c_driver(pfuze_driver); 8938c2ecf20Sopenharmony_ci 8948c2ecf20Sopenharmony_ciMODULE_AUTHOR("Robin Gong <b38343@freescale.com>"); 8958c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100/200/3000/3001 PMIC"); 8968c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 897