1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2018-2021 Emmanuel Vadot <manu@FreeBSD.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include <sys/param.h>
32 #include <sys/bus.h>
33 #include <sys/clock.h>
34 #include <sys/kernel.h>
35 #include <sys/module.h>
36 #include <sys/mutex.h>
37 #include <sys/rman.h>
38 #include <machine/bus.h>
39
40 #include <dev/iicbus/iiconf.h>
41 #include <dev/iicbus/iicbus.h>
42
43 #include <dev/ofw/ofw_bus.h>
44 #include <dev/ofw/ofw_bus_subr.h>
45
46 #include <dev/iicbus/pmic/rockchip/rk808reg.h>
47 #include <dev/iicbus/pmic/rockchip/rk8xx.h>
48
49 static struct ofw_compat_data compat_data[] = {
50 {"rockchip,rk808", RK808},
51 {NULL, 0}
52 };
53
54 static struct rk8xx_regdef rk808_regdefs[] = {
55 {
56 .id = RK808_BUCK1,
57 .name = "DCDC_REG1",
58 .enable_reg = RK808_DCDC_EN,
59 .enable_mask = 0x1,
60 .voltage_reg = RK808_BUCK1_ON_VSEL,
61 .voltage_mask = 0x3F,
62 .voltage_min = 712500,
63 .voltage_max = 1500000,
64 .voltage_step = 12500,
65 .voltage_nstep = 64,
66 },
67 {
68 .id = RK808_BUCK2,
69 .name = "DCDC_REG2",
70 .enable_reg = RK808_DCDC_EN,
71 .enable_mask = 0x2,
72 .voltage_reg = RK808_BUCK2_ON_VSEL,
73 .voltage_mask = 0x3F,
74 .voltage_min = 712500,
75 .voltage_max = 1500000,
76 .voltage_step = 12500,
77 .voltage_nstep = 64,
78 },
79 {
80 /* BUCK3 voltage is calculated based on external resistor */
81 .id = RK808_BUCK3,
82 .name = "DCDC_REG3",
83 .enable_reg = RK808_DCDC_EN,
84 .enable_mask = 0x4,
85 },
86 {
87 .id = RK808_BUCK4,
88 .name = "DCDC_REG4",
89 .enable_reg = RK808_DCDC_EN,
90 .enable_mask = 0x8,
91 .voltage_reg = RK808_BUCK4_ON_VSEL,
92 .voltage_mask = 0xF,
93 .voltage_min = 1800000,
94 .voltage_max = 3300000,
95 .voltage_step = 100000,
96 .voltage_nstep = 16,
97 },
98 {
99 .id = RK808_LDO1,
100 .name = "LDO_REG1",
101 .enable_reg = RK808_LDO_EN,
102 .enable_mask = 0x1,
103 .voltage_reg = RK808_LDO1_ON_VSEL,
104 .voltage_mask = 0x1F,
105 .voltage_min = 1800000,
106 .voltage_max = 3400000,
107 .voltage_step = 100000,
108 .voltage_nstep = 17,
109 },
110 {
111 .id = RK808_LDO2,
112 .name = "LDO_REG2",
113 .enable_reg = RK808_LDO_EN,
114 .enable_mask = 0x2,
115 .voltage_reg = RK808_LDO2_ON_VSEL,
116 .voltage_mask = 0x1F,
117 .voltage_min = 1800000,
118 .voltage_max = 3400000,
119 .voltage_step = 100000,
120 .voltage_nstep = 17,
121 },
122 {
123 .id = RK808_LDO3,
124 .name = "LDO_REG3",
125 .enable_reg = RK808_LDO_EN,
126 .enable_mask = 0x4,
127 .voltage_reg = RK808_LDO3_ON_VSEL,
128 .voltage_mask = 0xF,
129 .voltage_min = 800000,
130 .voltage_max = 2500000,
131 .voltage_step = 100000,
132 .voltage_nstep = 18,
133 },
134 {
135 .id = RK808_LDO4,
136 .name = "LDO_REG4",
137 .enable_reg = RK808_LDO_EN,
138 .enable_mask = 0x8,
139 .voltage_reg = RK808_LDO4_ON_VSEL,
140 .voltage_mask = 0x1F,
141 .voltage_min = 1800000,
142 .voltage_max = 3400000,
143 .voltage_step = 100000,
144 .voltage_nstep = 17,
145 },
146 {
147 .id = RK808_LDO5,
148 .name = "LDO_REG5",
149 .enable_reg = RK808_LDO_EN,
150 .enable_mask = 0x10,
151 .voltage_reg = RK808_LDO5_ON_VSEL,
152 .voltage_mask = 0x1F,
153 .voltage_min = 1800000,
154 .voltage_max = 3400000,
155 .voltage_step = 100000,
156 .voltage_nstep = 17,
157 },
158 {
159 .id = RK808_LDO6,
160 .name = "LDO_REG6",
161 .enable_reg = RK808_LDO_EN,
162 .enable_mask = 0x20,
163 .voltage_reg = RK808_LDO6_ON_VSEL,
164 .voltage_mask = 0x1F,
165 .voltage_min = 800000,
166 .voltage_max = 2500000,
167 .voltage_step = 100000,
168 .voltage_nstep = 18,
169 },
170 {
171 .id = RK808_LDO7,
172 .name = "LDO_REG7",
173 .enable_reg = RK808_LDO_EN,
174 .enable_mask = 0x40,
175 .voltage_reg = RK808_LDO7_ON_VSEL,
176 .voltage_mask = 0x1F,
177 .voltage_min = 800000,
178 .voltage_max = 2500000,
179 .voltage_step = 100000,
180 .voltage_nstep = 18,
181 },
182 {
183 .id = RK808_LDO8,
184 .name = "LDO_REG8",
185 .enable_reg = RK808_LDO_EN,
186 .enable_mask = 0x80,
187 .voltage_reg = RK808_LDO8_ON_VSEL,
188 .voltage_mask = 0x1F,
189 .voltage_min = 1800000,
190 .voltage_max = 3400000,
191 .voltage_step = 100000,
192 .voltage_nstep = 17,
193 },
194 {
195 .id = RK808_SWITCH1,
196 .name = "SWITCH_REG1",
197 .enable_reg = RK808_DCDC_EN,
198 .enable_mask = 0x20,
199 .voltage_min = 3000000,
200 .voltage_max = 3000000,
201 },
202 {
203 .id = RK808_SWITCH2,
204 .name = "SWITCH_REG2",
205 .enable_reg = RK808_DCDC_EN,
206 .enable_mask = 0x40,
207 .voltage_min = 3000000,
208 .voltage_max = 3000000,
209 },
210 };
211
212 static int
213 rk808_probe(device_t dev)
214 {
215 if (!ofw_bus_status_okay(dev))
216 return (ENXIO);
217
218 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
219 return (ENXIO);
220
221 device_set_desc(dev, "RockChip RK808 PMIC");
222 return (BUS_PROBE_DEFAULT);
223 }
224
225 static int
226 rk808_attach(device_t dev)
227 {
228 struct rk8xx_softc *sc;
229
230 sc = device_get_softc(dev);
231 sc->dev = dev;
232
233 sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
234
235 sc->regdefs = rk808_regdefs;
236 sc->nregs = nitems(rk808_regdefs);
237 sc->rtc_regs.secs = RK808_RTC_SECS;
238 sc->rtc_regs.secs_mask = RK808_RTC_SECS_MASK;
239 sc->rtc_regs.minutes = RK808_RTC_MINUTES;
240 sc->rtc_regs.minutes_mask = RK808_RTC_MINUTES_MASK;
241 sc->rtc_regs.hours = RK808_RTC_HOURS;
242 sc->rtc_regs.hours_mask = RK808_RTC_HOURS_MASK;
243 sc->rtc_regs.days = RK808_RTC_DAYS;
244 sc->rtc_regs.days_mask = RK808_RTC_DAYS_MASK;
245 sc->rtc_regs.months = RK808_RTC_MONTHS;
246 sc->rtc_regs.months_mask = RK808_RTC_MONTHS_MASK;
247 sc->rtc_regs.years = RK808_RTC_YEARS;
248 sc->rtc_regs.weeks = RK808_RTC_WEEKS_MASK;
249 sc->rtc_regs.ctrl = RK808_RTC_CTRL;
250 sc->rtc_regs.ctrl_stop_mask = RK808_RTC_CTRL_STOP;
251 sc->rtc_regs.ctrl_ampm_mask = RK808_RTC_AMPM_MODE;
252 sc->rtc_regs.ctrl_gettime_mask = RK808_RTC_GET_TIME;
253 sc->rtc_regs.ctrl_readsel_mask = RK808_RTC_READSEL;
254 sc->dev_ctrl.dev_ctrl_reg = RK808_DEV_CTRL;
255 sc->dev_ctrl.pwr_off_mask = RK808_DEV_CTRL_OFF;
256
257 return (rk8xx_attach(sc));
258 }
259
260 static device_method_t rk808_methods[] = {
261 DEVMETHOD(device_probe, rk808_probe),
262 DEVMETHOD(device_attach, rk808_attach),
263
264 DEVMETHOD_END
265 };
266
267 DEFINE_CLASS_1(rk808_pmu, rk808_driver, rk808_methods,
268 sizeof(struct rk8xx_softc), rk8xx_driver);
269
270 EARLY_DRIVER_MODULE(rk808_pmu, iicbus, rk808_driver, 0, 0,
271 BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST);
272 EARLY_DRIVER_MODULE(iicbus, rk808_pmu, iicbus_driver, 0, 0,
273 BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST);
274 MODULE_DEPEND(rk808_pmu, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
275 MODULE_VERSION(rk808_pmu, 1);
Cache object: ca4b8badd6566cbfa62051e95dfc9073
|