1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | #include <linux/module.h> |
3 | #include <linux/i2c.h> |
4 | #include <linux/of.h> |
5 | #include <linux/regmap.h> |
6 | #include <linux/regulator/driver.h> |
7 | |
8 | static const struct regulator_ops max8893_ops = { |
9 | .is_enabled = regulator_is_enabled_regmap, |
10 | .enable = regulator_enable_regmap, |
11 | .disable = regulator_disable_regmap, |
12 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
13 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
14 | .list_voltage = regulator_list_voltage_linear, |
15 | .map_voltage = regulator_map_voltage_linear, |
16 | }; |
17 | |
18 | static const struct regulator_desc max8893_regulators[] = { |
19 | { |
20 | .name = "BUCK" , |
21 | .supply_name = "in-buck" , |
22 | .of_match = of_match_ptr("buck" ), |
23 | .regulators_node = of_match_ptr("regulators" ), |
24 | .n_voltages = 0x11, |
25 | .id = 6, |
26 | .ops = &max8893_ops, |
27 | .type = REGULATOR_VOLTAGE, |
28 | .owner = THIS_MODULE, |
29 | .min_uV = 800000, |
30 | .uV_step = 100000, |
31 | .vsel_reg = 0x4, |
32 | .vsel_mask = 0x1f, |
33 | .enable_reg = 0x0, |
34 | .enable_mask = BIT(7), |
35 | }, |
36 | { |
37 | .name = "LDO1" , |
38 | .supply_name = "in-ldo1" , |
39 | .of_match = of_match_ptr("ldo1" ), |
40 | .regulators_node = of_match_ptr("regulators" ), |
41 | .n_voltages = 0x12, |
42 | .id = 1, |
43 | .ops = &max8893_ops, |
44 | .type = REGULATOR_VOLTAGE, |
45 | .owner = THIS_MODULE, |
46 | .min_uV = 1600000, |
47 | .uV_step = 100000, |
48 | .vsel_reg = 0x5, |
49 | .vsel_mask = 0x1f, |
50 | .enable_reg = 0x0, |
51 | .enable_mask = BIT(5), |
52 | }, |
53 | { |
54 | .name = "LDO2" , |
55 | .supply_name = "in-ldo2" , |
56 | .of_match = of_match_ptr("ldo2" ), |
57 | .regulators_node = of_match_ptr("regulators" ), |
58 | .n_voltages = 0x16, |
59 | .id = 2, |
60 | .ops = &max8893_ops, |
61 | .type = REGULATOR_VOLTAGE, |
62 | .owner = THIS_MODULE, |
63 | .min_uV = 1200000, |
64 | .uV_step = 100000, |
65 | .vsel_reg = 0x6, |
66 | .vsel_mask = 0x1f, |
67 | .enable_reg = 0x0, |
68 | .enable_mask = BIT(4), |
69 | }, |
70 | { |
71 | .name = "LDO3" , |
72 | .supply_name = "in-ldo3" , |
73 | .of_match = of_match_ptr("ldo3" ), |
74 | .regulators_node = of_match_ptr("regulators" ), |
75 | .n_voltages = 0x12, |
76 | .id = 3, |
77 | .ops = &max8893_ops, |
78 | .type = REGULATOR_VOLTAGE, |
79 | .owner = THIS_MODULE, |
80 | .min_uV = 1600000, |
81 | .uV_step = 100000, |
82 | .vsel_reg = 0x7, |
83 | .vsel_mask = 0x1f, |
84 | .enable_reg = 0x0, |
85 | .enable_mask = BIT(3), |
86 | }, |
87 | { |
88 | .name = "LDO4" , |
89 | .supply_name = "in-ldo4" , |
90 | .of_match = of_match_ptr("ldo4" ), |
91 | .regulators_node = of_match_ptr("regulators" ), |
92 | .n_voltages = 0x1a, |
93 | .id = 4, |
94 | .ops = &max8893_ops, |
95 | .type = REGULATOR_VOLTAGE, |
96 | .owner = THIS_MODULE, |
97 | .min_uV = 800000, |
98 | .uV_step = 100000, |
99 | .vsel_reg = 0x8, |
100 | .vsel_mask = 0x1f, |
101 | .enable_reg = 0x0, |
102 | .enable_mask = BIT(2), |
103 | }, |
104 | { |
105 | .name = "LDO5" , |
106 | .supply_name = "in-ldo5" , |
107 | .of_match = of_match_ptr("ldo5" ), |
108 | .regulators_node = of_match_ptr("regulators" ), |
109 | .n_voltages = 0x1a, |
110 | .id = 5, |
111 | .ops = &max8893_ops, |
112 | .type = REGULATOR_VOLTAGE, |
113 | .owner = THIS_MODULE, |
114 | .min_uV = 800000, |
115 | .uV_step = 100000, |
116 | .vsel_reg = 0x9, |
117 | .vsel_mask = 0x1f, |
118 | .enable_reg = 0x0, |
119 | .enable_mask = BIT(1), |
120 | } |
121 | }; |
122 | |
123 | static const struct regmap_config max8893_regmap = { |
124 | .reg_bits = 8, |
125 | .val_bits = 8, |
126 | }; |
127 | |
128 | static int max8893_probe(struct i2c_client *i2c) |
129 | { |
130 | int id, ret; |
131 | struct regulator_config config = {.dev = &i2c->dev}; |
132 | struct regmap *regmap = devm_regmap_init_i2c(i2c, &max8893_regmap); |
133 | |
134 | if (IS_ERR(ptr: regmap)) { |
135 | ret = PTR_ERR(ptr: regmap); |
136 | dev_err(&i2c->dev, "regmap init failed: %d\n" , ret); |
137 | return ret; |
138 | } |
139 | |
140 | for (id = 0; id < ARRAY_SIZE(max8893_regulators); id++) { |
141 | struct regulator_dev *rdev; |
142 | rdev = devm_regulator_register(dev: &i2c->dev, |
143 | regulator_desc: &max8893_regulators[id], |
144 | config: &config); |
145 | if (IS_ERR(ptr: rdev)) { |
146 | ret = PTR_ERR(ptr: rdev); |
147 | dev_err(&i2c->dev, "failed to register %s: %d\n" , |
148 | max8893_regulators[id].name, ret); |
149 | return ret; |
150 | } |
151 | } |
152 | |
153 | return 0; |
154 | } |
155 | |
156 | #ifdef CONFIG_OF |
157 | static const struct of_device_id max8893_dt_match[] = { |
158 | { .compatible = "maxim,max8893" }, |
159 | { /* sentinel */ }, |
160 | }; |
161 | MODULE_DEVICE_TABLE(of, max8893_dt_match); |
162 | #endif |
163 | |
164 | static const struct i2c_device_id max8893_ids[] = { |
165 | { "max8893" , 0 }, |
166 | { }, |
167 | }; |
168 | MODULE_DEVICE_TABLE(i2c, max8893_ids); |
169 | |
170 | static struct i2c_driver max8893_driver = { |
171 | .probe = max8893_probe, |
172 | .driver = { |
173 | .name = "max8893" , |
174 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
175 | .of_match_table = of_match_ptr(max8893_dt_match), |
176 | }, |
177 | .id_table = max8893_ids, |
178 | }; |
179 | |
180 | module_i2c_driver(max8893_driver); |
181 | |
182 | MODULE_DESCRIPTION("Maxim MAX8893 PMIC driver" ); |
183 | MODULE_AUTHOR("Sergey Larin <cerg2010cerg2010@mail.ru>" ); |
184 | MODULE_LICENSE("GPL" ); |
185 | |