1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2012 Andreas Tobler
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 ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * 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/systm.h>
34 #include <sys/module.h>
35 #include <sys/callout.h>
36 #include <sys/conf.h>
37 #include <sys/cpu.h>
38 #include <sys/ctype.h>
39 #include <sys/kernel.h>
40 #include <sys/reboot.h>
41 #include <sys/rman.h>
42 #include <sys/sysctl.h>
43 #include <sys/limits.h>
44
45 #include <machine/bus.h>
46 #include <machine/md_var.h>
47
48 #include <dev/iicbus/iicbus.h>
49 #include <dev/iicbus/iiconf.h>
50
51 #include <dev/ofw/openfirm.h>
52 #include <dev/ofw/ofw_bus.h>
53 #include <powerpc/powermac/powermac_thermal.h>
54
55 /* Sensor: Maxim DS1631 */
56
57 #define DS1631_STOP 0x22
58 #define DS1631_START 0x51
59 #define DS1631_RESET 0x54
60 #define DS1631_TEMP 0xAA
61 #define DS1631_CONTROL 0xAC
62 #define DS1631_CONTROL_1SHOT 0x01
63 #define DS1631_CONTROL_9BIT 0x00
64 #define DS1631_CONTROL_10BIT 0x04
65 #define DS1631_CONTROL_11BIT 0x08
66 #define DS1631_CONTROL_12BIT 0x0C
67
68
69
70 /* Regular bus attachment functions */
71 static int ds1631_probe(device_t);
72 static int ds1631_attach(device_t);
73
74 struct ds1631_softc {
75 struct pmac_therm sc_sensor;
76 device_t sc_dev;
77 struct intr_config_hook enum_hook;
78 uint32_t sc_addr;
79 uint32_t init_done;
80 };
81
82 struct write_data {
83 uint8_t reg;
84 uint8_t val;
85 };
86
87 struct read_data {
88 uint8_t reg;
89 uint16_t val;
90 };
91
92 /* Utility functions */
93 static int ds1631_sensor_read(struct ds1631_softc *sc);
94 static int ds1631_sensor_sysctl(SYSCTL_HANDLER_ARGS);
95 static void ds1631_start(void *xdev);
96 static int ds1631_read_1(device_t dev, uint32_t addr, uint8_t reg,
97 uint8_t *data);
98 static int ds1631_read_2(device_t dev, uint32_t addr, uint8_t reg,
99 uint16_t *data);
100 static int ds1631_write(device_t dev, uint32_t addr, uint8_t reg,
101 uint8_t *buff, int len);
102
103 static device_method_t ds1631_methods[] = {
104 /* Device interface */
105 DEVMETHOD(device_probe, ds1631_probe),
106 DEVMETHOD(device_attach, ds1631_attach),
107 { 0, 0 },
108 };
109
110 static driver_t ds1631_driver = {
111 "ds1631",
112 ds1631_methods,
113 sizeof(struct ds1631_softc)
114 };
115
116 DRIVER_MODULE(ds1631, iicbus, ds1631_driver, 0, 0);
117
118 static int
119 ds1631_write(device_t dev, uint32_t addr, uint8_t reg, uint8_t *buff, int len)
120 {
121 uint8_t buf[4];
122 int try = 0;
123
124 struct iic_msg msg[] = {
125 { addr, IIC_M_WR, 0, buf }
126 };
127
128 /* Prepare the write msg. */
129 msg[0].len = len + 1;
130 buf[0] = reg;
131 memcpy(buf + 1, buff, len);
132
133 for (;;)
134 {
135 if (iicbus_transfer(dev, msg, nitems(msg)) == 0)
136 return (0);
137 if (++try > 5) {
138 device_printf(dev, "iicbus write failed\n");
139 return (-1);
140 }
141 pause("ds1631_write", hz);
142 }
143 }
144
145 static int
146 ds1631_read_1(device_t dev, uint32_t addr, uint8_t reg, uint8_t *data)
147 {
148 uint8_t buf[4];
149 int err, try = 0;
150
151 struct iic_msg msg[2] = {
152 { addr, IIC_M_WR, 1, ® },
153 { addr, IIC_M_RD, 1, buf },
154 };
155
156 for (;;)
157 {
158 err = iicbus_transfer(dev, msg, nitems(msg));
159 if (err != 0)
160 goto retry;
161
162 *data = *((uint8_t*)buf);
163 return (0);
164 retry:
165 if (++try > 5) {
166 device_printf(dev, "iicbus read failed\n");
167 return (-1);
168 }
169 pause("ds1631_read_1", hz);
170 }
171 }
172
173 static int
174 ds1631_read_2(device_t dev, uint32_t addr, uint8_t reg, uint16_t *data)
175 {
176 uint8_t buf[4];
177 int err, try = 0;
178
179 struct iic_msg msg[2] = {
180 { addr, IIC_M_WR, 1, ® },
181 { addr, IIC_M_RD, 2, buf },
182 };
183
184 for (;;)
185 {
186 err = iicbus_transfer(dev, msg, nitems(msg));
187 if (err != 0)
188 goto retry;
189
190 *data = *((uint16_t*)buf);
191 return (0);
192 retry:
193 if (++try > 5) {
194 device_printf(dev, "iicbus read failed\n");
195 return (-1);
196 }
197 pause("ds1631_read_2", hz);
198 }
199 }
200
201 static int
202 ds1631_probe(device_t dev)
203 {
204 const char *name, *compatible;
205 struct ds1631_softc *sc;
206
207 name = ofw_bus_get_name(dev);
208 compatible = ofw_bus_get_compat(dev);
209
210 if (!name)
211 return (ENXIO);
212
213 if (strcmp(name, "temp-monitor") != 0 ||
214 strcmp(compatible, "ds1631") != 0 )
215 return (ENXIO);
216
217 sc = device_get_softc(dev);
218 sc->sc_dev = dev;
219 sc->sc_addr = iicbus_get_addr(dev);
220
221 device_set_desc(dev, "Temp-Monitor DS1631");
222
223 return (0);
224 }
225
226 static int
227 ds1631_attach(device_t dev)
228 {
229 struct ds1631_softc *sc;
230
231 sc = device_get_softc(dev);
232
233 sc->enum_hook.ich_func = ds1631_start;
234 sc->enum_hook.ich_arg = dev;
235
236 /*
237 * We have to wait until interrupts are enabled. I2C read and write
238 * only works if the interrupts are available.
239 * The unin/i2c is controlled by the htpic on unin. But this is not
240 * the master. The openpic on mac-io is controlling the htpic.
241 * This one gets attached after the mac-io probing and then the
242 * interrupts will be available.
243 */
244
245 if (config_intrhook_establish(&sc->enum_hook) != 0)
246 return (ENOMEM);
247
248 return (0);
249 }
250 static int
251 ds1631_init(device_t dev, uint32_t addr)
252 {
253 uint8_t conf;
254 int err;
255 struct ds1631_softc *sc;
256
257 sc = device_get_softc(dev);
258
259 err = ds1631_read_1(dev, addr, DS1631_CONTROL, &conf);
260 if (err < 0) {
261 device_printf(dev, "ds1631 read config failed: %x\n", err);
262 return (-1);
263 }
264
265 /* Stop the conversion if not in 1SHOT mode. */
266 if (conf & ~DS1631_CONTROL_1SHOT)
267 err = ds1631_write(dev, addr, DS1631_STOP, &conf, 0);
268
269 /*
270 * Setup the resolution, 10-bit is enough. Each bit increase in
271 * resolution doubles the conversion time.
272 */
273 conf = DS1631_CONTROL_10BIT;
274
275 err = ds1631_write(dev, addr, DS1631_CONTROL, &conf, sizeof(conf));
276 if (err < 0) {
277 device_printf(dev, "ds1631 write config failed: %x\n", err);
278 return (-1);
279 }
280
281 /* And now start....*/
282 err = ds1631_write(dev, addr, DS1631_START, &conf, 0);
283
284 if (err < 0) {
285 device_printf(dev, "ds1631 write start failed: %x\n", err);
286 return (-1);
287 }
288
289 sc->init_done = 1;
290
291 return (0);
292
293 }
294 static void
295 ds1631_start(void *xdev)
296 {
297 phandle_t child, node;
298 struct ds1631_softc *sc;
299 struct sysctl_oid *oid, *sensroot_oid;
300 struct sysctl_ctx_list *ctx;
301 ssize_t plen;
302 int i;
303 char sysctl_desc[40], sysctl_name[40];
304
305 device_t dev = (device_t)xdev;
306
307 sc = device_get_softc(dev);
308
309 child = ofw_bus_get_node(dev);
310
311 ctx = device_get_sysctl_ctx(dev);
312 sensroot_oid = SYSCTL_ADD_NODE(ctx,
313 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "sensor",
314 CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "DS1631 Sensor Information");
315
316 if (OF_getprop(child, "hwsensor-zone", &sc->sc_sensor.zone,
317 sizeof(int)) < 0)
318 sc->sc_sensor.zone = 0;
319
320 plen = OF_getprop(child, "hwsensor-location", sc->sc_sensor.name,
321 sizeof(sc->sc_sensor.name));
322 if (plen == -1) {
323 /*
324 * Ok, no hwsensor-location property, so let's look for a
325 * location property on a sub node.
326 */
327 for (node = OF_child(child); node; node = OF_peer(node))
328 plen = OF_getprop(node, "location", sc->sc_sensor.name,
329 sizeof(sc->sc_sensor.name));
330 }
331
332 if (plen == -1) {
333 strcpy(sysctl_name, "sensor");
334 } else {
335 for (i = 0; i < strlen(sc->sc_sensor.name); i++) {
336 sysctl_name[i] = tolower(sc->sc_sensor.name[i]);
337 if (isspace(sysctl_name[i]))
338 sysctl_name[i] = '_';
339 }
340 sysctl_name[i] = 0;
341 }
342
343 /* Make up target temperatures. These are low, for the drive bay. */
344 if (sc->sc_sensor.zone == 0) {
345 sc->sc_sensor.target_temp = 400 + ZERO_C_TO_K;
346 sc->sc_sensor.max_temp = 500 + ZERO_C_TO_K;
347 } else {
348 sc->sc_sensor.target_temp = 300 + ZERO_C_TO_K;
349 sc->sc_sensor.max_temp = 500 + ZERO_C_TO_K;
350 }
351
352 sc->sc_sensor.read =
353 (int (*)(struct pmac_therm *sc))(ds1631_sensor_read);
354 pmac_thermal_sensor_register(&sc->sc_sensor);
355
356 sprintf(sysctl_desc,"%s %s", sc->sc_sensor.name, "(C)");
357 oid = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(sensroot_oid),
358 OID_AUTO, sysctl_name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
359 "Sensor Information");
360 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "temp",
361 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, dev,
362 0, ds1631_sensor_sysctl, "IK", sysctl_desc);
363
364 config_intrhook_disestablish(&sc->enum_hook);
365 }
366
367 static int
368 ds1631_sensor_read(struct ds1631_softc *sc)
369 {
370 uint16_t buf[2];
371 uint16_t read;
372 int err;
373
374 if (!sc->init_done)
375 ds1631_init(sc->sc_dev, sc->sc_addr);
376
377 err = ds1631_read_2(sc->sc_dev, sc->sc_addr, DS1631_TEMP, buf);
378 if (err < 0) {
379 device_printf(sc->sc_dev, "ds1631 read TEMP failed: %x\n", err);
380 return (-1);
381 }
382
383 read = *((int16_t *)buf);
384
385 /*
386 * The default mode of the ADC is 12-bit, the resolution is 0.0625 C
387 * per bit. The temperature is in tenth kelvin.
388 * We use 10-bit resolution which seems enough, resolution is 0.25 C.
389 */
390
391 return (((int16_t)(read) >> 6) * 25 / 10 + ZERO_C_TO_K);
392 }
393
394 static int
395 ds1631_sensor_sysctl(SYSCTL_HANDLER_ARGS)
396 {
397 device_t dev;
398 struct ds1631_softc *sc;
399 int error;
400 int temp;
401
402 dev = arg1;
403 sc = device_get_softc(dev);
404
405 temp = ds1631_sensor_read(sc);
406 if (temp < 0)
407 return (EIO);
408
409 error = sysctl_handle_int(oidp, &temp, 0, req);
410
411 return (error);
412 }
Cache object: feee068cb09d85283131151b1c534b3e
|