2 * Copyright (c) 2015 M. Warner Losh <imp@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
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.
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, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
35 #include <sys/errno.h>
36 #include <sys/libkern.h>
37 #include <sys/kthread.h>
38 #include <sys/malloc.h>
39 #include <sys/module.h>
40 #include <sys/mutex.h>
42 #include <sys/sysctl.h>
44 #include <dev/ow/ow.h>
45 #include <dev/ow/own.h>
47 #define OWT_DS1820 0x10 /* Also 18S20 */
48 #define OWT_DS1822 0x22 /* Very close to 18B20 */
49 #define OWT_DS18B20 0x28 /* Also MAX31820 */
50 #define OWT_DS1825 0x3B /* Just like 18B20 with address bits */
52 #define CONVERT_T 0x44
53 #define COPY_SCRATCHPAD 0x48
54 #define WRITE_SCRATCHPAD 0x4e
55 #define READ_POWER_SUPPLY 0xb4
56 #define RECALL_EE 0xb8
57 #define READ_SCRATCHPAD 0xbe
60 #define OW_TEMP_DONE 0x01
61 #define OW_TEMP_RUNNING 0x02
74 struct proc *event_thread;
78 ow_temp_probe(device_t dev)
81 switch (ow_get_family(dev)) {
83 device_set_desc(dev, "One Wire Temperature");
84 return BUS_PROBE_DEFAULT;
88 device_set_desc(dev, "Advanced One Wire Temperature");
89 return BUS_PROBE_DEFAULT;
96 ow_temp_read_scratchpad(device_t dev, uint8_t *scratch, int len)
100 own_self_command(dev, &cmd, READ_SCRATCHPAD);
101 cmd.xpt_read_len = len;
102 own_command_wait(dev, &cmd);
103 memcpy(scratch, cmd.xpt_read, len);
109 ow_temp_convert_t(device_t dev)
113 own_self_command(dev, &cmd, CONVERT_T);
114 own_command_wait(dev, &cmd);
121 ow_temp_read_power_supply(device_t dev, int *parasite)
125 own_self_command(dev, &cmd, READ_POWER_SUPPLY);
126 cmd.flags |= OW_FLAG_READ_BIT;
127 cmd.xpt_read_len = 1;
128 own_command_wait(dev, &cmd);
129 *parasite = !cmd.xpt_read[0]; /* parasites pull bus low */
135 ow_temp_event_thread(void *arg)
137 struct ow_temp_softc *sc;
138 uint8_t scratch[8 + 1];
143 pause("owtstart", device_get_unit(sc->dev) * hz / 100); // 10ms stagger
144 mtx_lock(&sc->temp_lock);
145 sc->flags |= OW_TEMP_RUNNING;
146 ow_temp_read_power_supply(sc->dev, &sc->parasite);
148 device_printf(sc->dev, "Running in parasitic mode unsupported\n");
149 while ((sc->flags & OW_TEMP_DONE) == 0) {
150 mtx_unlock(&sc->temp_lock);
151 ow_temp_convert_t(sc->dev);
152 mtx_lock(&sc->temp_lock);
153 msleep(sc, &sc->temp_lock, 0, "owtcvt", hz);
154 if (sc->flags & OW_TEMP_DONE)
156 for (retries = 5; retries > 0; retries--) {
157 mtx_unlock(&sc->temp_lock);
158 rv = ow_temp_read_scratchpad(sc->dev, scratch, sizeof(scratch));
159 mtx_lock(&sc->temp_lock);
161 crc = own_crc(sc->dev, scratch, sizeof(scratch) - 1);
162 if (crc == scratch[8]) {
163 if (sc->type == OWT_DS1820) {
166 * Formula from DS18S20 datasheet, page 6
167 * DS18S20 datahseet says count_per_c is 16, DS1820 does not
169 sc->temp = (int16_t)((scratch[0] & 0xfe) |
170 (scratch[1] << 8)) << 3;
171 sc->temp += 16 - scratch[6] - 4; /* count_per_c == 16 */
173 sc->temp = (int16_t)(scratch[0] | (scratch[1] << 8)) << 3;
175 sc->temp = (int16_t)(scratch[0] | (scratch[1] << 8));
176 sc->temp = sc->temp * 1000 / 16 + 273150;
183 msleep(sc, &sc->temp_lock, 0, "owtcvt", sc->reading_interval);
185 sc->flags &= ~OW_TEMP_RUNNING;
186 mtx_unlock(&sc->temp_lock);
191 ow_temp_attach(device_t dev)
193 struct ow_temp_softc *sc;
195 sc = device_get_softc(dev);
197 sc->type = ow_get_family(dev);
198 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
199 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
200 OID_AUTO, "temperature", CTLFLAG_RD | CTLTYPE_INT,
201 &sc->temp, 0, sysctl_handle_int,
202 "IK3", "Current Temperature");
203 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
204 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
205 OID_AUTO, "badcrc", CTLFLAG_RD,
207 "Number of Bad CRC on reading scratchpad");
208 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
209 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
210 OID_AUTO, "badread", CTLFLAG_RD,
212 "Number of errors on reading scratchpad");
213 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
214 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
215 OID_AUTO, "reading_interval", CTLFLAG_RW,
216 &sc->reading_interval, 0,
217 "ticks between reads");
218 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
219 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
220 OID_AUTO, "parasite", CTLFLAG_RW,
224 * Just do this for unit 0 to avoid locking
225 * the ow bus until that code can be put
229 sc->reading_interval = 10 * hz;
230 mtx_init(&sc->temp_lock, "lock for doing temperature", NULL, MTX_DEF);
231 /* Start the thread */
232 if (kproc_create(ow_temp_event_thread, sc, &sc->event_thread, 0, 0,
233 "%s event thread", device_get_nameunit(dev))) {
234 device_printf(dev, "unable to create event thread.\n");
235 panic("cbb_create_event_thread");
242 ow_temp_detach(device_t dev)
244 struct ow_temp_softc *sc;
246 sc = device_get_softc(dev);
249 * Wait for the thread to die. kproc_exit will do a wakeup
250 * on the event thread's struct thread * so that we know it is
251 * safe to proceed. IF the thread is running, set the please
252 * die flag and wait for it to comply. Since the wakeup on
253 * the event thread happens only in kproc_exit, we don't
256 mtx_lock(&sc->temp_lock);
257 sc->flags |= OW_TEMP_DONE;
258 while (sc->flags & OW_TEMP_RUNNING) {
260 msleep(sc->event_thread, &sc->temp_lock, PWAIT, "owtun", 0);
262 mtx_destroy(&sc->temp_lock);
267 devclass_t ow_temp_devclass;
269 static device_method_t ow_temp_methods[] = {
270 /* Device interface */
271 DEVMETHOD(device_probe, ow_temp_probe),
272 DEVMETHOD(device_attach, ow_temp_attach),
273 DEVMETHOD(device_detach, ow_temp_detach),
278 static driver_t ow_temp_driver = {
281 sizeof(struct ow_temp_softc),
284 DRIVER_MODULE(ow_temp, ow, ow_temp_driver, ow_temp_devclass, 0, 0);
285 MODULE_DEPEND(ow_temp, ow, 1, 1, 1);