Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 //
0003 // pv88090-regulator.c - Regulator device driver for PV88090
0004 // Copyright (C) 2015  Powerventure Semiconductor Ltd.
0005 
0006 #include <linux/err.h>
0007 #include <linux/i2c.h>
0008 #include <linux/module.h>
0009 #include <linux/init.h>
0010 #include <linux/slab.h>
0011 #include <linux/regulator/driver.h>
0012 #include <linux/regulator/machine.h>
0013 #include <linux/regmap.h>
0014 #include <linux/irq.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/regulator/of_regulator.h>
0017 #include "pv88090-regulator.h"
0018 
0019 #define PV88090_MAX_REGULATORS  5
0020 
0021 /* PV88090 REGULATOR IDs */
0022 enum {
0023     /* BUCKs */
0024     PV88090_ID_BUCK1,
0025     PV88090_ID_BUCK2,
0026     PV88090_ID_BUCK3,
0027 
0028     /* LDOs */
0029     PV88090_ID_LDO1,
0030     PV88090_ID_LDO2,
0031 };
0032 
0033 struct pv88090_regulator {
0034     struct regulator_desc desc;
0035     unsigned int conf;
0036     unsigned int conf2;
0037 };
0038 
0039 struct pv88090 {
0040     struct device *dev;
0041     struct regmap *regmap;
0042     struct regulator_dev *rdev[PV88090_MAX_REGULATORS];
0043 };
0044 
0045 struct pv88090_buck_voltage {
0046     int min_uV;
0047     int max_uV;
0048     int uV_step;
0049 };
0050 
0051 static const struct regmap_config pv88090_regmap_config = {
0052     .reg_bits = 8,
0053     .val_bits = 8,
0054 };
0055 
0056 /* Current limits array (in uA) for BUCK1, BUCK2, BUCK3.
0057  *  Entry indexes corresponds to register values.
0058  */
0059 
0060 static const unsigned int pv88090_buck1_limits[] = {
0061      220000,  440000,  660000,  880000, 1100000, 1320000, 1540000, 1760000,
0062     1980000, 2200000, 2420000, 2640000, 2860000, 3080000, 3300000, 3520000,
0063     3740000, 3960000, 4180000, 4400000, 4620000, 4840000, 5060000, 5280000,
0064     5500000, 5720000, 5940000, 6160000, 6380000, 6600000, 6820000, 7040000
0065 };
0066 
0067 static const unsigned int pv88090_buck23_limits[] = {
0068     1496000, 2393000, 3291000, 4189000
0069 };
0070 
0071 static const struct pv88090_buck_voltage pv88090_buck_vol[3] = {
0072     {
0073         .min_uV = 600000,
0074         .max_uV = 1393750,
0075         .uV_step = 6250,
0076     },
0077 
0078     {
0079         .min_uV = 1400000,
0080         .max_uV = 2193750,
0081         .uV_step = 6250,
0082     },
0083     {
0084         .min_uV = 1250000,
0085         .max_uV = 2837500,
0086         .uV_step = 12500,
0087     },
0088 };
0089 
0090 static unsigned int pv88090_buck_get_mode(struct regulator_dev *rdev)
0091 {
0092     struct pv88090_regulator *info = rdev_get_drvdata(rdev);
0093     unsigned int data;
0094     int ret, mode = 0;
0095 
0096     ret = regmap_read(rdev->regmap, info->conf, &data);
0097     if (ret < 0)
0098         return ret;
0099 
0100     switch (data & PV88090_BUCK1_MODE_MASK) {
0101     case PV88090_BUCK_MODE_SYNC:
0102         mode = REGULATOR_MODE_FAST;
0103         break;
0104     case PV88090_BUCK_MODE_AUTO:
0105         mode = REGULATOR_MODE_NORMAL;
0106         break;
0107     case PV88090_BUCK_MODE_SLEEP:
0108         mode = REGULATOR_MODE_STANDBY;
0109         break;
0110     }
0111 
0112     return mode;
0113 }
0114 
0115 static int pv88090_buck_set_mode(struct regulator_dev *rdev,
0116                     unsigned int mode)
0117 {
0118     struct pv88090_regulator *info = rdev_get_drvdata(rdev);
0119     int val = 0;
0120 
0121     switch (mode) {
0122     case REGULATOR_MODE_FAST:
0123         val = PV88090_BUCK_MODE_SYNC;
0124         break;
0125     case REGULATOR_MODE_NORMAL:
0126         val = PV88090_BUCK_MODE_AUTO;
0127         break;
0128     case REGULATOR_MODE_STANDBY:
0129         val = PV88090_BUCK_MODE_SLEEP;
0130         break;
0131     default:
0132         return -EINVAL;
0133     }
0134 
0135     return regmap_update_bits(rdev->regmap, info->conf,
0136                     PV88090_BUCK1_MODE_MASK, val);
0137 }
0138 
0139 static const struct regulator_ops pv88090_buck_ops = {
0140     .get_mode = pv88090_buck_get_mode,
0141     .set_mode = pv88090_buck_set_mode,
0142     .enable = regulator_enable_regmap,
0143     .disable = regulator_disable_regmap,
0144     .is_enabled = regulator_is_enabled_regmap,
0145     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0146     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0147     .list_voltage = regulator_list_voltage_linear,
0148     .set_current_limit = regulator_set_current_limit_regmap,
0149     .get_current_limit = regulator_get_current_limit_regmap,
0150 };
0151 
0152 static const struct regulator_ops pv88090_ldo_ops = {
0153     .enable = regulator_enable_regmap,
0154     .disable = regulator_disable_regmap,
0155     .is_enabled = regulator_is_enabled_regmap,
0156     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0157     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0158     .list_voltage = regulator_list_voltage_linear,
0159 };
0160 
0161 #define PV88090_BUCK(chip, regl_name, min, step, max, limits_array) \
0162 {\
0163     .desc   =   {\
0164         .id = chip##_ID_##regl_name,\
0165         .name = __stringify(chip##_##regl_name),\
0166         .of_match = of_match_ptr(#regl_name),\
0167         .regulators_node = of_match_ptr("regulators"),\
0168         .type = REGULATOR_VOLTAGE,\
0169         .owner = THIS_MODULE,\
0170         .ops = &pv88090_buck_ops,\
0171         .min_uV = min, \
0172         .uV_step = step, \
0173         .n_voltages = ((max) - (min))/(step) + 1, \
0174         .enable_reg = PV88090_REG_##regl_name##_CONF0, \
0175         .enable_mask = PV88090_##regl_name##_EN, \
0176         .vsel_reg = PV88090_REG_##regl_name##_CONF0, \
0177         .vsel_mask = PV88090_V##regl_name##_MASK, \
0178         .curr_table = limits_array, \
0179         .n_current_limits = ARRAY_SIZE(limits_array), \
0180         .csel_reg = PV88090_REG_##regl_name##_CONF1, \
0181         .csel_mask = PV88090_##regl_name##_ILIM_MASK, \
0182     },\
0183     .conf = PV88090_REG_##regl_name##_CONF1, \
0184     .conf2 = PV88090_REG_##regl_name##_CONF2, \
0185 }
0186 
0187 #define PV88090_LDO(chip, regl_name, min, step, max) \
0188 {\
0189     .desc   =   {\
0190         .id = chip##_ID_##regl_name,\
0191         .name = __stringify(chip##_##regl_name),\
0192         .of_match = of_match_ptr(#regl_name),\
0193         .regulators_node = of_match_ptr("regulators"),\
0194         .type = REGULATOR_VOLTAGE,\
0195         .owner = THIS_MODULE,\
0196         .ops = &pv88090_ldo_ops,\
0197         .min_uV = min, \
0198         .uV_step = step, \
0199         .n_voltages = ((max) - (min))/(step) + 1, \
0200         .enable_reg = PV88090_REG_##regl_name##_CONT, \
0201         .enable_mask = PV88090_##regl_name##_EN, \
0202         .vsel_reg = PV88090_REG_##regl_name##_CONT, \
0203         .vsel_mask = PV88090_V##regl_name##_MASK, \
0204     },\
0205 }
0206 
0207 static struct pv88090_regulator pv88090_regulator_info[] = {
0208     PV88090_BUCK(PV88090, BUCK1, 600000, 6250, 1393750,
0209         pv88090_buck1_limits),
0210     PV88090_BUCK(PV88090, BUCK2, 600000, 6250, 1393750,
0211         pv88090_buck23_limits),
0212     PV88090_BUCK(PV88090, BUCK3, 600000, 6250, 1393750,
0213         pv88090_buck23_limits),
0214     PV88090_LDO(PV88090, LDO1, 1200000, 50000, 4350000),
0215     PV88090_LDO(PV88090, LDO2,  650000, 25000, 2225000),
0216 };
0217 
0218 static irqreturn_t pv88090_irq_handler(int irq, void *data)
0219 {
0220     struct pv88090 *chip = data;
0221     int i, reg_val, err, ret = IRQ_NONE;
0222 
0223     err = regmap_read(chip->regmap, PV88090_REG_EVENT_A, &reg_val);
0224     if (err < 0)
0225         goto error_i2c;
0226 
0227     if (reg_val & PV88090_E_VDD_FLT) {
0228         for (i = 0; i < PV88090_MAX_REGULATORS; i++) {
0229             if (chip->rdev[i] != NULL)
0230                 regulator_notifier_call_chain(chip->rdev[i],
0231                     REGULATOR_EVENT_UNDER_VOLTAGE,
0232                     NULL);
0233         }
0234 
0235         err = regmap_write(chip->regmap, PV88090_REG_EVENT_A,
0236             PV88090_E_VDD_FLT);
0237         if (err < 0)
0238             goto error_i2c;
0239 
0240         ret = IRQ_HANDLED;
0241     }
0242 
0243     if (reg_val & PV88090_E_OVER_TEMP) {
0244         for (i = 0; i < PV88090_MAX_REGULATORS; i++) {
0245             if (chip->rdev[i] != NULL)
0246                 regulator_notifier_call_chain(chip->rdev[i],
0247                     REGULATOR_EVENT_OVER_TEMP,
0248                     NULL);
0249         }
0250 
0251         err = regmap_write(chip->regmap, PV88090_REG_EVENT_A,
0252             PV88090_E_OVER_TEMP);
0253         if (err < 0)
0254             goto error_i2c;
0255 
0256         ret = IRQ_HANDLED;
0257     }
0258 
0259     return ret;
0260 
0261 error_i2c:
0262     dev_err(chip->dev, "I2C error : %d\n", err);
0263     return IRQ_NONE;
0264 }
0265 
0266 /*
0267  * I2C driver interface functions
0268  */
0269 static int pv88090_i2c_probe(struct i2c_client *i2c)
0270 {
0271     struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
0272     struct pv88090 *chip;
0273     struct regulator_config config = { };
0274     int error, i, ret = 0;
0275     unsigned int conf2, range, index;
0276 
0277     chip = devm_kzalloc(&i2c->dev, sizeof(struct pv88090), GFP_KERNEL);
0278     if (!chip)
0279         return -ENOMEM;
0280 
0281     chip->dev = &i2c->dev;
0282     chip->regmap = devm_regmap_init_i2c(i2c, &pv88090_regmap_config);
0283     if (IS_ERR(chip->regmap)) {
0284         error = PTR_ERR(chip->regmap);
0285         dev_err(chip->dev, "Failed to allocate register map: %d\n",
0286             error);
0287         return error;
0288     }
0289 
0290     i2c_set_clientdata(i2c, chip);
0291 
0292     if (i2c->irq != 0) {
0293         ret = regmap_write(chip->regmap, PV88090_REG_MASK_A, 0xFF);
0294         if (ret < 0) {
0295             dev_err(chip->dev,
0296                 "Failed to mask A reg: %d\n", ret);
0297             return ret;
0298         }
0299 
0300         ret = regmap_write(chip->regmap, PV88090_REG_MASK_B, 0xFF);
0301         if (ret < 0) {
0302             dev_err(chip->dev,
0303                 "Failed to mask B reg: %d\n", ret);
0304             return ret;
0305         }
0306 
0307         ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
0308                     pv88090_irq_handler,
0309                     IRQF_TRIGGER_LOW|IRQF_ONESHOT,
0310                     "pv88090", chip);
0311         if (ret != 0) {
0312             dev_err(chip->dev, "Failed to request IRQ: %d\n",
0313                 i2c->irq);
0314             return ret;
0315         }
0316 
0317         ret = regmap_update_bits(chip->regmap, PV88090_REG_MASK_A,
0318             PV88090_M_VDD_FLT | PV88090_M_OVER_TEMP, 0);
0319         if (ret < 0) {
0320             dev_err(chip->dev,
0321                 "Failed to update mask reg: %d\n", ret);
0322             return ret;
0323         }
0324 
0325     } else {
0326         dev_warn(chip->dev, "No IRQ configured\n");
0327     }
0328 
0329     config.dev = chip->dev;
0330     config.regmap = chip->regmap;
0331 
0332     for (i = 0; i < PV88090_MAX_REGULATORS; i++) {
0333         if (init_data)
0334             config.init_data = &init_data[i];
0335 
0336         if (i == PV88090_ID_BUCK2 || i == PV88090_ID_BUCK3) {
0337             ret = regmap_read(chip->regmap,
0338                 pv88090_regulator_info[i].conf2, &conf2);
0339             if (ret < 0)
0340                 return ret;
0341 
0342             conf2 = (conf2 >> PV88090_BUCK_VDAC_RANGE_SHIFT) &
0343                 PV88090_BUCK_VDAC_RANGE_MASK;
0344 
0345             ret = regmap_read(chip->regmap,
0346                 PV88090_REG_BUCK_FOLD_RANGE, &range);
0347             if (ret < 0)
0348                 return ret;
0349 
0350             range = (range >>
0351                  (PV88090_BUCK_VRANGE_GAIN_SHIFT + i - 1)) &
0352                 PV88090_BUCK_VRANGE_GAIN_MASK;
0353             index = ((range << 1) | conf2);
0354             if (index > PV88090_ID_BUCK3) {
0355                 dev_err(chip->dev,
0356                     "Invalid index(%d)\n", index);
0357                 return -EINVAL;
0358             }
0359 
0360             pv88090_regulator_info[i].desc.min_uV
0361                 = pv88090_buck_vol[index].min_uV;
0362             pv88090_regulator_info[i].desc.uV_step
0363                 = pv88090_buck_vol[index].uV_step;
0364             pv88090_regulator_info[i].desc.n_voltages
0365                 = ((pv88090_buck_vol[index].max_uV)
0366                 - (pv88090_buck_vol[index].min_uV))
0367                 /(pv88090_buck_vol[index].uV_step) + 1;
0368         }
0369 
0370         config.driver_data = (void *)&pv88090_regulator_info[i];
0371         chip->rdev[i] = devm_regulator_register(chip->dev,
0372             &pv88090_regulator_info[i].desc, &config);
0373         if (IS_ERR(chip->rdev[i])) {
0374             dev_err(chip->dev,
0375                 "Failed to register PV88090 regulator\n");
0376             return PTR_ERR(chip->rdev[i]);
0377         }
0378     }
0379 
0380     return 0;
0381 }
0382 
0383 static const struct i2c_device_id pv88090_i2c_id[] = {
0384     {"pv88090", 0},
0385     {},
0386 };
0387 MODULE_DEVICE_TABLE(i2c, pv88090_i2c_id);
0388 
0389 #ifdef CONFIG_OF
0390 static const struct of_device_id pv88090_dt_ids[] = {
0391     { .compatible = "pvs,pv88090", .data = &pv88090_i2c_id[0] },
0392     {},
0393 };
0394 MODULE_DEVICE_TABLE(of, pv88090_dt_ids);
0395 #endif
0396 
0397 static struct i2c_driver pv88090_regulator_driver = {
0398     .driver = {
0399         .name = "pv88090",
0400         .of_match_table = of_match_ptr(pv88090_dt_ids),
0401     },
0402     .probe_new = pv88090_i2c_probe,
0403     .id_table = pv88090_i2c_id,
0404 };
0405 
0406 module_i2c_driver(pv88090_regulator_driver);
0407 
0408 MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>");
0409 MODULE_DESCRIPTION("Regulator device driver for Powerventure PV88090");
0410 MODULE_LICENSE("GPL");