fan53880.c (5015B)
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 7enum fan53880_regulator_ids { 8 FAN53880_LDO1, 9 FAN53880_LDO2, 10 FAN53880_LDO3, 11 FAN53880_LDO4, 12 FAN53880_BUCK, 13 FAN53880_BOOST, 14}; 15 16enum 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 32static 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 .n_voltages = 0x74, \ 55 .vsel_reg = FAN53880_LDO ## _num ## VOUT, \ 56 .vsel_mask = 0x7f, \ 57 .enable_reg = FAN53880_ENABLE, \ 58 .enable_mask = BIT(_num - 1), \ 59 .enable_time = 150, \ 60 .supply_name = _supply, \ 61 .ops = &fan53880_ops, \ 62 } 63 64static const struct regulator_desc fan53880_regulators[] = { 65 FAN53880_LDO(1, "VIN12", 2800000), 66 FAN53880_LDO(2, "VIN12", 2800000), 67 FAN53880_LDO(3, "VIN3", 1800000), 68 FAN53880_LDO(4, "VIN4", 1800000), 69 [FAN53880_BUCK] = { 70 .name = "BUCK", 71 .of_match = of_match_ptr("BUCK"), 72 .regulators_node = of_match_ptr("regulators"), 73 .type = REGULATOR_VOLTAGE, 74 .owner = THIS_MODULE, 75 .linear_ranges = (struct linear_range[]) { 76 REGULATOR_LINEAR_RANGE(1100000, 0x0, 0x0, 0), 77 REGULATOR_LINEAR_RANGE(600000, 0x1f, 0xf7, 12500), 78 }, 79 .n_linear_ranges = 2, 80 .n_voltages = 0xf8, 81 .vsel_reg = FAN53880_BUCKVOUT, 82 .vsel_mask = 0xff, 83 .enable_reg = FAN53880_ENABLE, 84 .enable_mask = 0x10, 85 .enable_time = 480, 86 .supply_name = "PVIN", 87 .ops = &fan53880_ops, 88 }, 89 [FAN53880_BOOST] = { 90 .name = "BOOST", 91 .of_match = of_match_ptr("BOOST"), 92 .regulators_node = of_match_ptr("regulators"), 93 .type = REGULATOR_VOLTAGE, 94 .owner = THIS_MODULE, 95 .linear_ranges = (struct linear_range[]) { 96 REGULATOR_LINEAR_RANGE(5000000, 0x0, 0x0, 0), 97 REGULATOR_LINEAR_RANGE(3000000, 0x4, 0x70, 25000), 98 }, 99 .n_linear_ranges = 2, 100 .n_voltages = 0x71, 101 .vsel_reg = FAN53880_BOOSTVOUT, 102 .vsel_mask = 0x7f, 103 .enable_reg = FAN53880_ENABLE_BOOST, 104 .enable_mask = 0xff, 105 .enable_time = 580, 106 .supply_name = "PVIN", 107 .ops = &fan53880_ops, 108 }, 109}; 110 111static const struct regmap_config fan53880_regmap = { 112 .reg_bits = 8, 113 .val_bits = 8, 114 .max_register = FAN53880_ENABLE_BOOST, 115}; 116 117static int fan53880_i2c_probe(struct i2c_client *i2c) 118{ 119 struct regulator_config config = { }; 120 struct regulator_dev *rdev; 121 struct regmap *regmap; 122 int i, ret; 123 unsigned int data; 124 125 regmap = devm_regmap_init_i2c(i2c, &fan53880_regmap); 126 if (IS_ERR(regmap)) { 127 ret = PTR_ERR(regmap); 128 dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); 129 return ret; 130 } 131 132 ret = regmap_read(regmap, FAN53880_PRODUCT_ID, &data); 133 if (ret < 0) { 134 dev_err(&i2c->dev, "Failed to read PRODUCT_ID: %d\n", ret); 135 return ret; 136 } 137 if (data != FAN53880_ID) { 138 dev_err(&i2c->dev, "Unsupported device id: 0x%x.\n", data); 139 return -ENODEV; 140 } 141 142 config.dev = &i2c->dev; 143 config.init_data = NULL; 144 145 for (i = 0; i < ARRAY_SIZE(fan53880_regulators); i++) { 146 rdev = devm_regulator_register(&i2c->dev, 147 &fan53880_regulators[i], 148 &config); 149 if (IS_ERR(rdev)) { 150 ret = PTR_ERR(rdev); 151 dev_err(&i2c->dev, "Failed to register %s: %d\n", 152 fan53880_regulators[i].name, ret); 153 return ret; 154 } 155 } 156 157 return 0; 158} 159 160#ifdef CONFIG_OF 161static const struct of_device_id fan53880_dt_ids[] = { 162 { .compatible = "onnn,fan53880", }, 163 {} 164}; 165MODULE_DEVICE_TABLE(of, fan53880_dt_ids); 166#endif 167 168static const struct i2c_device_id fan53880_i2c_id[] = { 169 { "fan53880", }, 170 {} 171}; 172MODULE_DEVICE_TABLE(i2c, fan53880_i2c_id); 173 174static struct i2c_driver fan53880_regulator_driver = { 175 .driver = { 176 .name = "fan53880", 177 .of_match_table = of_match_ptr(fan53880_dt_ids), 178 }, 179 .probe_new = fan53880_i2c_probe, 180 .id_table = fan53880_i2c_id, 181}; 182module_i2c_driver(fan53880_regulator_driver); 183 184MODULE_DESCRIPTION("FAN53880 PMIC voltage regulator driver"); 185MODULE_AUTHOR("Christoph Fritz <chf.fritz@googlemail.com>"); 186MODULE_LICENSE("GPL");