Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright (C) 2017 NXP
0004  * Copyright (C) 2019 Boundary Devices
0005  * Copyright (C) 2020 Amarula Solutions(India)
0006  */
0007 
0008 #include <linux/delay.h>
0009 #include <linux/err.h>
0010 #include <linux/gpio/consumer.h>
0011 #include <linux/i2c.h>
0012 #include <linux/module.h>
0013 #include <linux/regmap.h>
0014 #include <linux/regulator/driver.h>
0015 #include <linux/regulator/machine.h>
0016 
0017 /* registers */
0018 #define PF8X00_DEVICEID         0x00
0019 #define PF8X00_REVID            0x01
0020 #define PF8X00_EMREV            0x02
0021 #define PF8X00_PROGID           0x03
0022 #define PF8X00_IMS_INT          0x04
0023 #define PF8X00_IMS_THERM        0x07
0024 #define PF8X00_SW_MODE_INT      0x0a
0025 #define PF8X00_SW_MODE_MASK     0x0b
0026 #define PF8X00_IMS_SW_ILIM      0x12
0027 #define PF8X00_IMS_LDO_ILIM     0x15
0028 #define PF8X00_IMS_SW_UV        0x18
0029 #define PF8X00_IMS_SW_OV        0x1b
0030 #define PF8X00_IMS_LDO_UV       0x1e
0031 #define PF8X00_IMS_LDO_OV       0x21
0032 #define PF8X00_IMS_PWRON        0x24
0033 #define PF8X00_SYS_INT          0x27
0034 #define PF8X00_HARD_FAULT       0x29
0035 #define PF8X00_FSOB_FLAGS       0x2a
0036 #define PF8X00_FSOB_SELECT      0x2b
0037 #define PF8X00_ABIST_OV1        0x2c
0038 #define PF8X00_ABIST_OV2        0x2d
0039 #define PF8X00_ABIST_UV1        0x2e
0040 #define PF8X00_ABIST_UV2        0x2f
0041 #define PF8X00_TEST_FLAGS       0x30
0042 #define PF8X00_ABIST_RUN        0x31
0043 #define PF8X00_RANDOM_GEN       0x33
0044 #define PF8X00_RANDOM_CHK       0x34
0045 #define PF8X00_VMONEN1          0x35
0046 #define PF8X00_VMONEN2          0x36
0047 #define PF8X00_CTRL1            0x37
0048 #define PF8X00_CTRL2            0x38
0049 #define PF8X00_CTRL3            0x39
0050 #define PF8X00_PWRUP_CTRL       0x3a
0051 #define PF8X00_RESETBMCU        0x3c
0052 #define PF8X00_PGOOD            0x3d
0053 #define PF8X00_PWRDN_DLY1       0x3e
0054 #define PF8X00_PWRDN_DLY2       0x3f
0055 #define PF8X00_FREQ_CTRL        0x40
0056 #define PF8X00_COINCELL_CTRL        0x41
0057 #define PF8X00_PWRON            0x42
0058 #define PF8X00_WD_CONFIG        0x43
0059 #define PF8X00_WD_CLEAR         0x44
0060 #define PF8X00_WD_EXPIRE        0x45
0061 #define PF8X00_WD_COUNTER       0x46
0062 #define PF8X00_FAULT_COUNTER        0x47
0063 #define PF8X00_FSAFE_COUNTER        0x48
0064 #define PF8X00_FAULT_TIMER      0x49
0065 #define PF8X00_AMUX         0x4a
0066 #define PF8X00_SW1_CONFIG1      0x4d
0067 #define PF8X00_LDO1_CONFIG1     0x85
0068 #define PF8X00_VSNVS_CONFIG1        0x9d
0069 #define PF8X00_PAGE_SELECT      0x9f
0070 
0071 /* regulators */
0072 enum pf8x00_regulators {
0073     PF8X00_LDO1,
0074     PF8X00_LDO2,
0075     PF8X00_LDO3,
0076     PF8X00_LDO4,
0077     PF8X00_BUCK1,
0078     PF8X00_BUCK2,
0079     PF8X00_BUCK3,
0080     PF8X00_BUCK4,
0081     PF8X00_BUCK5,
0082     PF8X00_BUCK6,
0083     PF8X00_BUCK7,
0084     PF8X00_VSNVS,
0085 
0086     PF8X00_MAX_REGULATORS,
0087 };
0088 
0089 enum pf8x00_buck_states {
0090     SW_CONFIG1,
0091     SW_CONFIG2,
0092     SW_PWRUP,
0093     SW_MODE1,
0094     SW_RUN_VOLT,
0095     SW_STBY_VOLT,
0096 };
0097 #define PF8X00_SW_BASE(i)       (8 * (i - PF8X00_BUCK1) + PF8X00_SW1_CONFIG1)
0098 
0099 enum pf8x00_ldo_states {
0100     LDO_CONFIG1,
0101     LDO_CONFIG2,
0102     LDO_PWRUP,
0103     LDO_RUN_VOLT,
0104     LDO_STBY_VOLT,
0105 };
0106 #define PF8X00_LDO_BASE(i)      (6 * (i - PF8X00_LDO1) + PF8X00_LDO1_CONFIG1)
0107 
0108 enum swxilim_bits {
0109     SWXILIM_2100_MA,
0110     SWXILIM_2600_MA,
0111     SWXILIM_3000_MA,
0112     SWXILIM_4500_MA,
0113 };
0114 #define PF8X00_SWXILIM_SHIFT        3
0115 #define PF8X00_SWXILIM_MASK     GENMASK(4, 3)
0116 #define PF8X00_SWXPHASE_MASK        GENMASK(2, 0)
0117 #define PF8X00_SWXPHASE_SHIFT       7
0118 
0119 enum pf8x00_devid {
0120     PF8100          = 0x0,
0121     PF8121A         = BIT(1),
0122     PF8200          = BIT(3),
0123 };
0124 #define PF8X00_FAM          BIT(6)
0125 #define PF8X00_DEVICE_FAM_MASK      GENMASK(7, 4)
0126 #define PF8X00_DEVICE_ID_MASK       GENMASK(3, 0)
0127 
0128 struct pf8x00_regulator_data {
0129     struct regulator_desc desc;
0130     unsigned int suspend_enable_reg;
0131     unsigned int suspend_enable_mask;
0132     unsigned int suspend_voltage_reg;
0133     unsigned int suspend_voltage_cache;
0134 };
0135 
0136 struct pf8x00_chip {
0137     struct regmap *regmap;
0138     struct device *dev;
0139 };
0140 
0141 static const struct regmap_config pf8x00_regmap_config = {
0142     .reg_bits = 8,
0143     .val_bits = 8,
0144     .max_register = PF8X00_PAGE_SELECT,
0145     .cache_type = REGCACHE_RBTREE,
0146 };
0147 
0148 /* VLDOx output: 1.5V to 5.0V */
0149 static const int pf8x00_ldo_voltages[] = {
0150     1500000, 1600000, 1800000, 1850000, 2150000, 2500000, 2800000, 3000000,
0151     3100000, 3150000, 3200000, 3300000, 3350000, 1650000, 1700000, 5000000,
0152 };
0153 
0154 /* Output: 2.1A to 4.5A */
0155 static const unsigned int pf8x00_sw_current_table[] = {
0156     2100000, 2600000, 3000000, 4500000,
0157 };
0158 
0159 /* Output: 0.4V to 1.8V */
0160 #define PF8XOO_SW1_6_VOLTAGE_NUM 0xB2
0161 static const struct linear_range pf8x00_sw1_to_6_voltages[] = {
0162     REGULATOR_LINEAR_RANGE(400000, 0x00, 0xB0, 6250),
0163     REGULATOR_LINEAR_RANGE(1800000, 0xB1, 0xB1, 0),
0164 };
0165 
0166 /* Output: 1.0V to 4.1V */
0167 static const int pf8x00_sw7_voltages[] = {
0168     1000000, 1100000, 1200000, 1250000, 1300000, 1350000, 1500000, 1600000,
0169     1800000, 1850000, 2000000, 2100000, 2150000, 2250000, 2300000, 2400000,
0170     2500000, 2800000, 3150000, 3200000, 3250000, 3300000, 3350000, 3400000,
0171     3500000, 3800000, 4000000, 4100000, 4100000, 4100000, 4100000, 4100000,
0172 };
0173 
0174 /* Output: 1.8V, 3.0V, or 3.3V */
0175 static const int pf8x00_vsnvs_voltages[] = {
0176     0, 1800000, 3000000, 3300000,
0177 };
0178 
0179 static void swxilim_select(struct pf8x00_chip *chip, int id, int ilim)
0180 {
0181     u8 ilim_sel;
0182     u8 reg = PF8X00_SW_BASE(id) + SW_CONFIG2;
0183 
0184     switch (ilim) {
0185     case 2100:
0186         ilim_sel = SWXILIM_2100_MA;
0187         break;
0188     case 2600:
0189         ilim_sel = SWXILIM_2600_MA;
0190         break;
0191     case 3000:
0192         ilim_sel = SWXILIM_3000_MA;
0193         break;
0194     case 4500:
0195         ilim_sel = SWXILIM_4500_MA;
0196         break;
0197     default:
0198         ilim_sel = SWXILIM_2100_MA;
0199         break;
0200     }
0201 
0202     regmap_update_bits(chip->regmap, reg,
0203                     PF8X00_SWXILIM_MASK,
0204                     ilim_sel << PF8X00_SWXILIM_SHIFT);
0205 }
0206 
0207 static void handle_ilim_property(struct device_node *np,
0208                   const struct regulator_desc *desc,
0209                   struct regulator_config *config)
0210 {
0211     struct pf8x00_chip *chip = config->driver_data;
0212     int ret;
0213     int val;
0214 
0215     if ((desc->id >= PF8X00_BUCK1) && (desc->id <= PF8X00_BUCK7)) {
0216         ret = of_property_read_u32(np, "nxp,ilim-ma", &val);
0217         if (ret) {
0218             dev_dbg(chip->dev, "unspecified ilim for BUCK%d, use value stored in OTP\n",
0219                 desc->id - PF8X00_LDO4);
0220             return;
0221         }
0222 
0223         dev_warn(chip->dev, "nxp,ilim-ma is deprecated, please use regulator-max-microamp\n");
0224         swxilim_select(chip, desc->id, val);
0225 
0226     } else
0227         dev_warn(chip->dev, "nxp,ilim-ma used with incorrect regulator (%d)\n", desc->id);
0228 }
0229 
0230 static void handle_shift_property(struct device_node *np,
0231                   const struct regulator_desc *desc,
0232                   struct regulator_config *config)
0233 {
0234     unsigned char id = desc->id - PF8X00_LDO4;
0235     unsigned char reg = PF8X00_SW_BASE(id) + SW_CONFIG2;
0236     struct pf8x00_chip *chip = config->driver_data;
0237 
0238     int phase;
0239     int val;
0240     int ret;
0241     if ((desc->id >= PF8X00_BUCK1) && (desc->id <= PF8X00_BUCK7)) {
0242         ret = of_property_read_u32(np, "nxp,phase-shift", &val);
0243         if (ret) {
0244             dev_dbg(chip->dev,
0245                 "unspecified phase-shift for BUCK%d, using OTP configuration\n",
0246                 id);
0247             return;
0248         }
0249 
0250         if (val < 0 || val > 315 || val % 45 != 0) {
0251             dev_warn(config->dev,
0252                 "invalid phase_shift %d for BUCK%d, using OTP configuration\n",
0253                 val, id);
0254             return;
0255         }
0256 
0257         phase = val / 45;
0258 
0259         if (phase >= 1)
0260             phase -= 1;
0261         else
0262             phase = PF8X00_SWXPHASE_SHIFT;
0263 
0264         regmap_update_bits(chip->regmap, reg,
0265                 PF8X00_SWXPHASE_MASK,
0266                 phase);
0267     } else
0268         dev_warn(chip->dev, "nxp,phase-shift used with incorrect regulator (%d)\n", id);
0269 
0270 }
0271 
0272 static int pf8x00_of_parse_cb(struct device_node *np,
0273                   const struct regulator_desc *desc,
0274                   struct regulator_config *config)
0275 {
0276 
0277     handle_ilim_property(np, desc, config);
0278     handle_shift_property(np, desc, config);
0279 
0280     return 0;
0281 }
0282 
0283 static int pf8x00_suspend_enable(struct regulator_dev *rdev)
0284 {
0285     struct pf8x00_regulator_data *regl = rdev_get_drvdata(rdev);
0286     struct regmap *rmap = rdev_get_regmap(rdev);
0287 
0288     return regmap_update_bits(rmap, regl->suspend_enable_reg,
0289                   regl->suspend_enable_mask,
0290                   regl->suspend_enable_mask);
0291 }
0292 
0293 static int pf8x00_suspend_disable(struct regulator_dev *rdev)
0294 {
0295     struct pf8x00_regulator_data *regl = rdev_get_drvdata(rdev);
0296     struct regmap *rmap = rdev_get_regmap(rdev);
0297 
0298     return regmap_update_bits(rmap, regl->suspend_enable_reg,
0299                   regl->suspend_enable_mask, 0);
0300 }
0301 
0302 static int pf8x00_set_suspend_voltage(struct regulator_dev *rdev, int uV)
0303 {
0304     struct pf8x00_regulator_data *regl = rdev_get_drvdata(rdev);
0305     int ret;
0306 
0307     if (regl->suspend_voltage_cache == uV)
0308         return 0;
0309 
0310     ret = regulator_map_voltage_iterate(rdev, uV, uV);
0311     if (ret < 0) {
0312         dev_err(rdev_get_dev(rdev), "failed to map %i uV\n", uV);
0313         return ret;
0314     }
0315 
0316     dev_dbg(rdev_get_dev(rdev), "uV: %i, reg: 0x%x, msk: 0x%x, val: 0x%x\n",
0317         uV, regl->suspend_voltage_reg, regl->desc.vsel_mask, ret);
0318     ret = regmap_update_bits(rdev->regmap, regl->suspend_voltage_reg,
0319                  regl->desc.vsel_mask, ret);
0320     if (ret < 0) {
0321         dev_err(rdev_get_dev(rdev), "failed to set %i uV\n", uV);
0322         return ret;
0323     }
0324 
0325     regl->suspend_voltage_cache = uV;
0326 
0327     return 0;
0328 }
0329 
0330 static const struct regulator_ops pf8x00_ldo_ops = {
0331     .enable = regulator_enable_regmap,
0332     .disable = regulator_disable_regmap,
0333     .is_enabled = regulator_is_enabled_regmap,
0334     .list_voltage = regulator_list_voltage_table,
0335     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0336     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0337     .set_suspend_enable = pf8x00_suspend_enable,
0338     .set_suspend_disable = pf8x00_suspend_disable,
0339     .set_suspend_voltage = pf8x00_set_suspend_voltage,
0340 };
0341 
0342 
0343 static const struct regulator_ops pf8x00_buck1_6_ops = {
0344     .enable = regulator_enable_regmap,
0345     .disable = regulator_disable_regmap,
0346     .is_enabled = regulator_is_enabled_regmap,
0347     .list_voltage = regulator_list_voltage_linear_range,
0348     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0349     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0350     .get_current_limit = regulator_get_current_limit_regmap,
0351     .set_current_limit = regulator_set_current_limit_regmap,
0352     .set_suspend_enable = pf8x00_suspend_enable,
0353     .set_suspend_disable = pf8x00_suspend_disable,
0354     .set_suspend_voltage = pf8x00_set_suspend_voltage,
0355 };
0356 
0357 static const struct regulator_ops pf8x00_buck7_ops = {
0358     .enable = regulator_enable_regmap,
0359     .disable = regulator_disable_regmap,
0360     .is_enabled = regulator_is_enabled_regmap,
0361     .list_voltage = regulator_list_voltage_table,
0362     .map_voltage = regulator_map_voltage_ascend,
0363     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0364     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0365     .get_current_limit = regulator_get_current_limit_regmap,
0366     .set_current_limit = regulator_set_current_limit_regmap,
0367     .set_suspend_enable = pf8x00_suspend_enable,
0368     .set_suspend_disable = pf8x00_suspend_disable,
0369 };
0370 
0371 static const struct regulator_ops pf8x00_vsnvs_ops = {
0372     .enable = regulator_enable_regmap,
0373     .disable = regulator_disable_regmap,
0374     .is_enabled = regulator_is_enabled_regmap,
0375     .list_voltage = regulator_list_voltage_table,
0376     .map_voltage = regulator_map_voltage_ascend,
0377     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0378     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0379 };
0380 
0381 #define PF8X00LDO(_id, _name, base, voltages)           \
0382     [PF8X00_LDO ## _id] = {                 \
0383         .desc = {                   \
0384             .name = _name,              \
0385             .of_match = _name,          \
0386             .regulators_node = "regulators",    \
0387             .n_voltages = ARRAY_SIZE(voltages), \
0388             .ops = &pf8x00_ldo_ops,         \
0389             .type = REGULATOR_VOLTAGE,      \
0390             .id = PF8X00_LDO ## _id,        \
0391             .owner = THIS_MODULE,           \
0392             .volt_table = voltages,         \
0393             .vsel_reg = (base) + LDO_RUN_VOLT,  \
0394             .vsel_mask = 0xff,          \
0395             .enable_reg = (base) + LDO_CONFIG2, \
0396             .enable_val = 0x2,          \
0397             .disable_val = 0x0,         \
0398             .enable_mask = 2,           \
0399         },                      \
0400         .suspend_enable_reg = (base) + LDO_CONFIG2, \
0401         .suspend_enable_mask = 1,           \
0402         .suspend_voltage_reg = (base) + LDO_STBY_VOLT,  \
0403     }
0404 
0405 #define PF8X00BUCK(_id, _name, base, voltages)          \
0406     [PF8X00_BUCK ## _id] = {                \
0407         .desc = {                   \
0408             .name = _name,              \
0409             .of_match = _name,          \
0410             .regulators_node = "regulators",    \
0411             .of_parse_cb = pf8x00_of_parse_cb,  \
0412             .n_voltages = PF8XOO_SW1_6_VOLTAGE_NUM, \
0413             .ops = &pf8x00_buck1_6_ops,     \
0414             .type = REGULATOR_VOLTAGE,      \
0415             .id = PF8X00_BUCK ## _id,       \
0416             .owner = THIS_MODULE,           \
0417             .ramp_delay = 19000,            \
0418             .linear_ranges = pf8x00_sw1_to_6_voltages, \
0419             .n_linear_ranges = \
0420                 ARRAY_SIZE(pf8x00_sw1_to_6_voltages), \
0421             .vsel_reg = (base) + SW_RUN_VOLT,   \
0422             .vsel_mask = 0xff,          \
0423             .curr_table = pf8x00_sw_current_table, \
0424             .n_current_limits = \
0425                 ARRAY_SIZE(pf8x00_sw_current_table), \
0426             .csel_reg = (base) + SW_CONFIG2,    \
0427             .csel_mask = PF8X00_SWXILIM_MASK,   \
0428             .enable_reg = (base) + SW_MODE1,    \
0429             .enable_val = 0x3,          \
0430             .disable_val = 0x0,         \
0431             .enable_mask = 0x3,         \
0432             .enable_time = 500,         \
0433         },                      \
0434         .suspend_enable_reg = (base) + SW_MODE1,    \
0435         .suspend_enable_mask = 0xc,         \
0436         .suspend_voltage_reg = (base) + SW_STBY_VOLT,   \
0437     }
0438 
0439 #define PF8X00BUCK7(_name, base, voltages)          \
0440     [PF8X00_BUCK7] = {              \
0441         .desc = {                   \
0442             .name = _name,              \
0443             .of_match = _name,          \
0444             .regulators_node = "regulators",    \
0445             .of_parse_cb = pf8x00_of_parse_cb,  \
0446             .n_voltages = ARRAY_SIZE(voltages), \
0447             .ops = &pf8x00_buck7_ops,       \
0448             .type = REGULATOR_VOLTAGE,      \
0449             .id = PF8X00_BUCK7,     \
0450             .owner = THIS_MODULE,           \
0451             .ramp_delay = 19000,            \
0452             .volt_table = voltages,         \
0453             .vsel_reg = (base) + SW_RUN_VOLT,   \
0454             .vsel_mask = 0xff,          \
0455             .curr_table = pf8x00_sw_current_table, \
0456             .n_current_limits = \
0457                 ARRAY_SIZE(pf8x00_sw_current_table), \
0458             .csel_reg = (base) + SW_CONFIG2,    \
0459             .csel_mask = PF8X00_SWXILIM_MASK,   \
0460             .enable_reg = (base) + SW_MODE1,    \
0461             .enable_val = 0x3,          \
0462             .disable_val = 0x0,         \
0463             .enable_mask = 0x3,         \
0464             .enable_time = 500,         \
0465         },                      \
0466     }
0467 
0468 
0469 #define PF8X00VSNVS(_name, base, voltages)          \
0470     [PF8X00_VSNVS] = {                  \
0471         .desc = {                   \
0472             .name = _name,              \
0473             .of_match = _name,          \
0474             .regulators_node = "regulators",    \
0475             .n_voltages = ARRAY_SIZE(voltages), \
0476             .ops = &pf8x00_vsnvs_ops,       \
0477             .type = REGULATOR_VOLTAGE,      \
0478             .id = PF8X00_VSNVS,         \
0479             .owner = THIS_MODULE,           \
0480             .volt_table = voltages,         \
0481             .vsel_reg = (base),         \
0482             .vsel_mask = 0x3,           \
0483         },                      \
0484     }
0485 
0486 static struct pf8x00_regulator_data pf8x00_regs_data[PF8X00_MAX_REGULATORS] = {
0487     PF8X00LDO(1, "ldo1", PF8X00_LDO_BASE(PF8X00_LDO1), pf8x00_ldo_voltages),
0488     PF8X00LDO(2, "ldo2", PF8X00_LDO_BASE(PF8X00_LDO2), pf8x00_ldo_voltages),
0489     PF8X00LDO(3, "ldo3", PF8X00_LDO_BASE(PF8X00_LDO3), pf8x00_ldo_voltages),
0490     PF8X00LDO(4, "ldo4", PF8X00_LDO_BASE(PF8X00_LDO4), pf8x00_ldo_voltages),
0491     PF8X00BUCK(1, "buck1", PF8X00_SW_BASE(PF8X00_BUCK1), pf8x00_sw1_to_6_voltages),
0492     PF8X00BUCK(2, "buck2", PF8X00_SW_BASE(PF8X00_BUCK2), pf8x00_sw1_to_6_voltages),
0493     PF8X00BUCK(3, "buck3", PF8X00_SW_BASE(PF8X00_BUCK3), pf8x00_sw1_to_6_voltages),
0494     PF8X00BUCK(4, "buck4", PF8X00_SW_BASE(PF8X00_BUCK4), pf8x00_sw1_to_6_voltages),
0495     PF8X00BUCK(5, "buck5", PF8X00_SW_BASE(PF8X00_BUCK5), pf8x00_sw1_to_6_voltages),
0496     PF8X00BUCK(6, "buck6", PF8X00_SW_BASE(PF8X00_BUCK6), pf8x00_sw1_to_6_voltages),
0497     PF8X00BUCK7("buck7", PF8X00_SW_BASE(PF8X00_BUCK7), pf8x00_sw7_voltages),
0498     PF8X00VSNVS("vsnvs", PF8X00_VSNVS_CONFIG1, pf8x00_vsnvs_voltages),
0499 };
0500 
0501 static int pf8x00_identify(struct pf8x00_chip *chip)
0502 {
0503     unsigned int value;
0504     u8 dev_fam, dev_id;
0505     const char *name = NULL;
0506     int ret;
0507 
0508     ret = regmap_read(chip->regmap, PF8X00_DEVICEID, &value);
0509     if (ret) {
0510         dev_err(chip->dev, "failed to read chip family\n");
0511         return ret;
0512     }
0513 
0514     dev_fam = value & PF8X00_DEVICE_FAM_MASK;
0515     switch (dev_fam) {
0516     case PF8X00_FAM:
0517         break;
0518     default:
0519         dev_err(chip->dev,
0520             "Chip 0x%x is not from PF8X00 family\n", dev_fam);
0521         return ret;
0522     }
0523 
0524     dev_id = value & PF8X00_DEVICE_ID_MASK;
0525     switch (dev_id) {
0526     case PF8100:
0527         name = "PF8100";
0528         break;
0529     case PF8121A:
0530         name = "PF8121A";
0531         break;
0532     case PF8200:
0533         name = "PF8200";
0534         break;
0535     default:
0536         dev_err(chip->dev, "Unknown pf8x00 device id 0x%x\n", dev_id);
0537         return -ENODEV;
0538     }
0539 
0540     dev_info(chip->dev, "%s PMIC found.\n", name);
0541 
0542     return 0;
0543 }
0544 
0545 static int pf8x00_i2c_probe(struct i2c_client *client)
0546 {
0547     struct regulator_config config = { NULL, };
0548     struct pf8x00_chip *chip;
0549     int id;
0550     int ret;
0551 
0552     chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
0553     if (!chip)
0554         return -ENOMEM;
0555 
0556     i2c_set_clientdata(client, chip);
0557     chip->dev = &client->dev;
0558 
0559     chip->regmap = devm_regmap_init_i2c(client, &pf8x00_regmap_config);
0560     if (IS_ERR(chip->regmap)) {
0561         ret = PTR_ERR(chip->regmap);
0562         dev_err(&client->dev,
0563             "regmap allocation failed with err %d\n", ret);
0564         return ret;
0565     }
0566 
0567     ret = pf8x00_identify(chip);
0568     if (ret)
0569         return ret;
0570 
0571     for (id = 0; id < ARRAY_SIZE(pf8x00_regs_data); id++) {
0572         struct pf8x00_regulator_data *data = &pf8x00_regs_data[id];
0573         struct regulator_dev *rdev;
0574 
0575         config.dev = chip->dev;
0576         config.driver_data = data;
0577         config.regmap = chip->regmap;
0578 
0579         rdev = devm_regulator_register(&client->dev, &data->desc, &config);
0580         if (IS_ERR(rdev)) {
0581             dev_err(&client->dev,
0582                 "failed to register %s regulator\n", data->desc.name);
0583             return PTR_ERR(rdev);
0584         }
0585     }
0586 
0587     return 0;
0588 }
0589 
0590 static const struct of_device_id pf8x00_dt_ids[] = {
0591     { .compatible = "nxp,pf8100",},
0592     { .compatible = "nxp,pf8121a",},
0593     { .compatible = "nxp,pf8200",},
0594     { }
0595 };
0596 MODULE_DEVICE_TABLE(of, pf8x00_dt_ids);
0597 
0598 static const struct i2c_device_id pf8x00_i2c_id[] = {
0599     { "pf8100", 0 },
0600     { "pf8121a", 0 },
0601     { "pf8200", 0 },
0602     {},
0603 };
0604 MODULE_DEVICE_TABLE(i2c, pf8x00_i2c_id);
0605 
0606 static struct i2c_driver pf8x00_regulator_driver = {
0607     .id_table = pf8x00_i2c_id,
0608     .driver = {
0609         .name = "pf8x00",
0610         .of_match_table = pf8x00_dt_ids,
0611     },
0612     .probe_new = pf8x00_i2c_probe,
0613 };
0614 module_i2c_driver(pf8x00_regulator_driver);
0615 
0616 MODULE_AUTHOR("Jagan Teki <jagan@amarulasolutions.com>");
0617 MODULE_AUTHOR("Troy Kisky <troy.kisky@boundarydevices.com>");
0618 MODULE_DESCRIPTION("Regulator Driver for NXP's PF8100/PF8121A/PF8200 PMIC");
0619 MODULE_LICENSE("GPL v2");