1 // SPDX-License-Identifier: GPL-2.0+ 2 #include <linux/module.h> 3 #include <linux/i2c.h> 4 #include <linux/regmap.h> 5 #include <linux/regulator/driver.h> 6 7 enum fan53880_regulator_ids { 8 FAN53880_LDO1, 9 FAN53880_LDO2, 10 FAN53880_LDO3, 11 FAN53880_LDO4, 12 FAN53880_BUCK, 13 FAN53880_BOOST, 14 }; 15 16 enum fan53880_registers { 17 FAN53880_PRODUCT_ID = 0x00, 18 FAN53880_SILICON_REV, 19 FAN53880_BUCKVOUT, 20 FAN53880_BOOSTVOUT, 21 FAN53880_LDO1VOUT, 22 FAN53880_LDO2VOUT, 23 FAN53880_LDO3VOUT, 24 FAN53880_LDO4VOUT, 25 FAN53880_IOUT, 26 FAN53880_ENABLE, 27 FAN53880_ENABLE_BOOST, 28 }; 29 30 #define FAN53880_ID 0x01 31 32 static const struct regulator_ops fan53880_ops = { 33 .list_voltage = regulator_list_voltage_linear_range, 34 .map_voltage = regulator_map_voltage_linear_range, 35 .set_voltage_sel = regulator_set_voltage_sel_regmap, 36 .get_voltage_sel = regulator_get_voltage_sel_regmap, 37 .enable = regulator_enable_regmap, 38 .disable = regulator_disable_regmap, 39 .is_enabled = regulator_is_enabled_regmap, 40 }; 41 42 #define FAN53880_LDO(_num, _supply, _default) \ 43 [FAN53880_LDO ## _num] = { \ 44 .name = "LDO"#_num, \ 45 .of_match = of_match_ptr("LDO"#_num), \ 46 .regulators_node = of_match_ptr("regulators"), \ 47 .type = REGULATOR_VOLTAGE, \ 48 .owner = THIS_MODULE, \ 49 .linear_ranges = (struct linear_range[]) { \ 50 REGULATOR_LINEAR_RANGE(_default, 0x0, 0x0, 0), \ 51 REGULATOR_LINEAR_RANGE(800000, 0xf, 0x73, 25000), \ 52 }, \ 53 .n_linear_ranges = 2, \ 54 .vsel_reg = FAN53880_LDO ## _num ## VOUT, \ 55 .vsel_mask = 0x7f, \ 56 .enable_reg = FAN53880_ENABLE, \ 57 .enable_mask = BIT(_num - 1), \ 58 .enable_time = 150, \ 59 .supply_name = _supply, \ 60 .ops = &fan53880_ops, \ 61 } 62 63 static const struct regulator_desc fan53880_regulators[] = { 64 FAN53880_LDO(1, "VIN12", 2800000), 65 FAN53880_LDO(2, "VIN12", 2800000), 66 FAN53880_LDO(3, "VIN3", 1800000), 67 FAN53880_LDO(4, "VIN4", 1800000), 68 [FAN53880_BUCK] = { 69 .name = "BUCK", 70 .of_match = of_match_ptr("BUCK"), 71 .regulators_node = of_match_ptr("regulators"), 72 .type = REGULATOR_VOLTAGE, 73 .owner = THIS_MODULE, 74 .linear_ranges = (struct linear_range[]) { 75 REGULATOR_LINEAR_RANGE(1100000, 0x0, 0x0, 0), 76 REGULATOR_LINEAR_RANGE(600000, 0x1f, 0xf7, 12500), 77 }, 78 .n_linear_ranges = 2, 79 .vsel_reg = FAN53880_BUCKVOUT, 80 .vsel_mask = 0x7f, 81 .enable_reg = FAN53880_ENABLE, 82 .enable_mask = 0x10, 83 .enable_time = 480, 84 .supply_name = "PVIN", 85 .ops = &fan53880_ops, 86 }, 87 [FAN53880_BOOST] = { 88 .name = "BOOST", 89 .of_match = of_match_ptr("BOOST"), 90 .regulators_node = of_match_ptr("regulators"), 91 .type = REGULATOR_VOLTAGE, 92 .owner = THIS_MODULE, 93 .linear_ranges = (struct linear_range[]) { 94 REGULATOR_LINEAR_RANGE(5000000, 0x0, 0x0, 0), 95 REGULATOR_LINEAR_RANGE(3000000, 0x4, 0x70, 25000), 96 }, 97 .n_linear_ranges = 2, 98 .vsel_reg = FAN53880_BOOSTVOUT, 99 .vsel_mask = 0x7f, 100 .enable_reg = FAN53880_ENABLE_BOOST, 101 .enable_mask = 0xff, 102 .enable_time = 580, 103 .supply_name = "PVIN", 104 .ops = &fan53880_ops, 105 }, 106 }; 107 108 static const struct regmap_config fan53880_regmap = { 109 .reg_bits = 8, 110 .val_bits = 8, 111 .max_register = FAN53880_ENABLE_BOOST, 112 }; 113 114 static int fan53880_i2c_probe(struct i2c_client *i2c, 115 const struct i2c_device_id *id) 116 { 117 struct regulator_config config = { }; 118 struct regulator_dev *rdev; 119 struct regmap *regmap; 120 int i, ret; 121 unsigned int data; 122 123 regmap = devm_regmap_init_i2c(i2c, &fan53880_regmap); 124 if (IS_ERR(regmap)) { 125 ret = PTR_ERR(regmap); 126 dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); 127 return ret; 128 } 129 130 ret = regmap_read(regmap, FAN53880_PRODUCT_ID, &data); 131 if (ret < 0) { 132 dev_err(&i2c->dev, "Failed to read PRODUCT_ID: %d\n", ret); 133 return ret; 134 } 135 if (data != FAN53880_ID) { 136 dev_err(&i2c->dev, "Unsupported device id: 0x%x.\n", data); 137 return -ENODEV; 138 } 139 140 config.dev = &i2c->dev; 141 config.init_data = NULL; 142 143 for (i = 0; i < ARRAY_SIZE(fan53880_regulators); i++) { 144 rdev = devm_regulator_register(&i2c->dev, 145 &fan53880_regulators[i], 146 &config); 147 if (IS_ERR(rdev)) { 148 ret = PTR_ERR(rdev); 149 dev_err(&i2c->dev, "Failed to register %s: %d\n", 150 fan53880_regulators[i].name, ret); 151 return ret; 152 } 153 } 154 155 return 0; 156 } 157 158 #ifdef CONFIG_OF 159 static const struct of_device_id fan53880_dt_ids[] = { 160 { .compatible = "onnn,fan53880", }, 161 {} 162 }; 163 MODULE_DEVICE_TABLE(of, fan53880_dt_ids); 164 #endif 165 166 static const struct i2c_device_id fan53880_i2c_id[] = { 167 { "fan53880", }, 168 {} 169 }; 170 MODULE_DEVICE_TABLE(i2c, fan53880_i2c_id); 171 172 static struct i2c_driver fan53880_regulator_driver = { 173 .driver = { 174 .name = "fan53880", 175 .of_match_table = of_match_ptr(fan53880_dt_ids), 176 }, 177 .probe = fan53880_i2c_probe, 178 .id_table = fan53880_i2c_id, 179 }; 180 module_i2c_driver(fan53880_regulator_driver); 181 182 MODULE_DESCRIPTION("FAN53880 PMIC voltage regulator driver"); 183 MODULE_AUTHOR("Christoph Fritz <chf.fritz@googlemail.com>"); 184 MODULE_LICENSE("GPL"); 185