Commit | Line | Data |
---|---|---|
d83f778c SL |
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_new(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(regmap)) { | |
135 | ret = PTR_ERR(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(&i2c->dev, | |
143 | &max8893_regulators[id], | |
144 | &config); | |
145 | if (IS_ERR(rdev)) { | |
146 | ret = PTR_ERR(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 = { | |
964e1865 | 171 | .probe = max8893_probe_new, |
d83f778c SL |
172 | .driver = { |
173 | .name = "max8893", | |
46600ab1 | 174 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
d83f778c SL |
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"); |