0001
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");