Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 #include <linux/module.h>
0003 #include <linux/i2c.h>
0004 #include <linux/regmap.h>
0005 #include <linux/regulator/driver.h>
0006 
0007 enum fan53880_regulator_ids {
0008     FAN53880_LDO1,
0009     FAN53880_LDO2,
0010     FAN53880_LDO3,
0011     FAN53880_LDO4,
0012     FAN53880_BUCK,
0013     FAN53880_BOOST,
0014 };
0015 
0016 enum fan53880_registers {
0017     FAN53880_PRODUCT_ID = 0x00,
0018     FAN53880_SILICON_REV,
0019     FAN53880_BUCKVOUT,
0020     FAN53880_BOOSTVOUT,
0021     FAN53880_LDO1VOUT,
0022     FAN53880_LDO2VOUT,
0023     FAN53880_LDO3VOUT,
0024     FAN53880_LDO4VOUT,
0025     FAN53880_IOUT,
0026     FAN53880_ENABLE,
0027     FAN53880_ENABLE_BOOST,
0028 };
0029 
0030 #define FAN53880_ID 0x01
0031 
0032 static const struct regulator_ops fan53880_ops = {
0033     .list_voltage = regulator_list_voltage_linear_range,
0034     .map_voltage = regulator_map_voltage_linear_range,
0035     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0036     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0037     .enable = regulator_enable_regmap,
0038     .disable = regulator_disable_regmap,
0039     .is_enabled = regulator_is_enabled_regmap,
0040 };
0041 
0042 #define FAN53880_LDO(_num, _supply, _default)               \
0043     [FAN53880_LDO ## _num] = {                  \
0044         .name =        "LDO"#_num,              \
0045         .of_match =    of_match_ptr("LDO"#_num),        \
0046         .regulators_node = of_match_ptr("regulators"),      \
0047         .type =        REGULATOR_VOLTAGE,           \
0048         .owner =       THIS_MODULE,             \
0049         .linear_ranges =   (struct linear_range[]) {        \
0050               REGULATOR_LINEAR_RANGE(_default, 0x0, 0x0, 0),    \
0051               REGULATOR_LINEAR_RANGE(800000, 0xf, 0x73, 25000), \
0052         },                          \
0053         .n_linear_ranges = 2,                   \
0054         .n_voltages =      0x74,                \
0055         .vsel_reg =    FAN53880_LDO ## _num ## VOUT,    \
0056         .vsel_mask =       0x7f,                \
0057         .enable_reg =      FAN53880_ENABLE,         \
0058         .enable_mask =     BIT(_num - 1),           \
0059         .enable_time =     150,                 \
0060         .supply_name =     _supply,             \
0061         .ops =         &fan53880_ops,           \
0062     }
0063 
0064 static const struct regulator_desc fan53880_regulators[] = {
0065     FAN53880_LDO(1, "VIN12", 2800000),
0066     FAN53880_LDO(2, "VIN12", 2800000),
0067     FAN53880_LDO(3, "VIN3", 1800000),
0068     FAN53880_LDO(4, "VIN4", 1800000),
0069     [FAN53880_BUCK] = {
0070         .name =        "BUCK",
0071         .of_match =    of_match_ptr("BUCK"),
0072         .regulators_node = of_match_ptr("regulators"),
0073         .type =        REGULATOR_VOLTAGE,
0074         .owner =       THIS_MODULE,
0075         .linear_ranges =   (struct linear_range[]) {
0076               REGULATOR_LINEAR_RANGE(1100000, 0x0, 0x0, 0),
0077               REGULATOR_LINEAR_RANGE(600000, 0x1f, 0xf7, 12500),
0078         },
0079         .n_linear_ranges = 2,
0080         .n_voltages =      0xf8,
0081         .vsel_reg =    FAN53880_BUCKVOUT,
0082         .vsel_mask =       0xff,
0083         .enable_reg =      FAN53880_ENABLE,
0084         .enable_mask =     0x10,
0085         .enable_time =     480,
0086         .supply_name =     "PVIN",
0087         .ops =         &fan53880_ops,
0088     },
0089     [FAN53880_BOOST] = {
0090         .name =        "BOOST",
0091         .of_match =    of_match_ptr("BOOST"),
0092         .regulators_node = of_match_ptr("regulators"),
0093         .type =        REGULATOR_VOLTAGE,
0094         .owner =       THIS_MODULE,
0095         .linear_ranges =   (struct linear_range[]) {
0096               REGULATOR_LINEAR_RANGE(5000000, 0x0, 0x0, 0),
0097               REGULATOR_LINEAR_RANGE(3000000, 0x4, 0x70, 25000),
0098         },
0099         .n_linear_ranges = 2,
0100         .n_voltages =      0x71,
0101         .vsel_reg =    FAN53880_BOOSTVOUT,
0102         .vsel_mask =       0x7f,
0103         .enable_reg =      FAN53880_ENABLE_BOOST,
0104         .enable_mask =     0xff,
0105         .enable_time =     580,
0106         .supply_name =     "PVIN",
0107         .ops =         &fan53880_ops,
0108     },
0109 };
0110 
0111 static const struct regmap_config fan53880_regmap = {
0112     .reg_bits = 8,
0113     .val_bits = 8,
0114     .max_register = FAN53880_ENABLE_BOOST,
0115 };
0116 
0117 static int fan53880_i2c_probe(struct i2c_client *i2c)
0118 {
0119     struct regulator_config config = { };
0120     struct regulator_dev *rdev;
0121     struct regmap *regmap;
0122     int i, ret;
0123     unsigned int data;
0124 
0125     regmap = devm_regmap_init_i2c(i2c, &fan53880_regmap);
0126     if (IS_ERR(regmap)) {
0127         ret = PTR_ERR(regmap);
0128         dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret);
0129         return ret;
0130     }
0131 
0132     ret = regmap_read(regmap, FAN53880_PRODUCT_ID, &data);
0133     if (ret < 0) {
0134         dev_err(&i2c->dev, "Failed to read PRODUCT_ID: %d\n", ret);
0135         return ret;
0136     }
0137     if (data != FAN53880_ID) {
0138         dev_err(&i2c->dev, "Unsupported device id: 0x%x.\n", data);
0139         return -ENODEV;
0140     }
0141 
0142     config.dev = &i2c->dev;
0143     config.init_data = NULL;
0144 
0145     for (i = 0; i < ARRAY_SIZE(fan53880_regulators); i++) {
0146         rdev = devm_regulator_register(&i2c->dev,
0147                            &fan53880_regulators[i],
0148                            &config);
0149         if (IS_ERR(rdev)) {
0150             ret = PTR_ERR(rdev);
0151             dev_err(&i2c->dev, "Failed to register %s: %d\n",
0152                 fan53880_regulators[i].name, ret);
0153             return ret;
0154         }
0155     }
0156 
0157     return 0;
0158 }
0159 
0160 #ifdef CONFIG_OF
0161 static const struct of_device_id fan53880_dt_ids[] = {
0162     { .compatible = "onnn,fan53880", },
0163     {}
0164 };
0165 MODULE_DEVICE_TABLE(of, fan53880_dt_ids);
0166 #endif
0167 
0168 static const struct i2c_device_id fan53880_i2c_id[] = {
0169     { "fan53880", },
0170     {}
0171 };
0172 MODULE_DEVICE_TABLE(i2c, fan53880_i2c_id);
0173 
0174 static struct i2c_driver fan53880_regulator_driver = {
0175     .driver = {
0176         .name = "fan53880",
0177         .of_match_table = of_match_ptr(fan53880_dt_ids),
0178     },
0179     .probe_new = fan53880_i2c_probe,
0180     .id_table = fan53880_i2c_id,
0181 };
0182 module_i2c_driver(fan53880_regulator_driver);
0183 
0184 MODULE_DESCRIPTION("FAN53880 PMIC voltage regulator driver");
0185 MODULE_AUTHOR("Christoph Fritz <chf.fritz@googlemail.com>");
0186 MODULE_LICENSE("GPL");