This source file includes following definitions.
- owsbm_match
- owsbm_attach
- owsbm_detach
- owsbm_activate
- owsbm_update
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include <sys/param.h>
27 #include <sys/systm.h>
28 #include <sys/device.h>
29 #include <sys/kernel.h>
30 #include <sys/proc.h>
31 #include <sys/rwlock.h>
32 #include <sys/sensors.h>
33
34 #include <dev/onewire/onewiredevs.h>
35 #include <dev/onewire/onewirereg.h>
36 #include <dev/onewire/onewirevar.h>
37
38
39 #define DSSBM_CMD_READ_SCRATCHPAD 0xbe
40 #define DSSBM_CMD_WRITE_SCRATCHPAD 0x4e
41 #define DSSBM_CMD_COPY_SCRATCHPAD 0x48
42
43 #define DSSBM_CMD_RECALL_MEMORY 0xb8
44
45 #define DSSBM_CMD_CONVERT_T 0x44
46 #define DSSBM_CMD_CONVERT_V 0xb4
47
48
49 #define DS2438_SP_STATUS 0
50 #define DS2438_SP_TEMP_LSB 1
51 #define DS2438_SP_TEMP_MSB 2
52 #define DS2438_SP_VOLT_LSB 3
53 #define DS2438_SP_VOLT_MSB 4
54 #define DS2438_SP_CURRENT_LSB 5
55 #define DS2438_SP_CURRENT_MSB 6
56 #define DS2438_SP_THRESHOLD 7
57 #define DS2438_SP_CRC 8
58
59 struct owsbm_softc {
60 struct device sc_dev;
61
62 void * sc_onewire;
63 u_int64_t sc_rom;
64
65 struct ksensordev sc_sensordev;
66
67 struct ksensor sc_temp;
68 struct ksensor sc_voltage_vdd;
69 struct ksensor sc_voltage_vad;
70 struct ksensor sc_voltage_cr;
71
72 struct sensor_task *sc_sensortask;
73
74 struct rwlock sc_lock;
75 };
76
77 int owsbm_match(struct device *, void *, void *);
78 void owsbm_attach(struct device *, struct device *, void *);
79 int owsbm_detach(struct device *, int);
80 int owsbm_activate(struct device *, enum devact);
81
82 void owsbm_update(void *);
83
84 struct cfattach owsbm_ca = {
85 sizeof(struct owsbm_softc),
86 owsbm_match,
87 owsbm_attach,
88 owsbm_detach,
89 owsbm_activate
90 };
91
92 struct cfdriver owsbm_cd = {
93 NULL, "owsbm", DV_DULL
94 };
95
96 static const struct onewire_matchfam owsbm_fams[] = {
97 { ONEWIRE_FAMILY_DS2438 }
98 };
99
100 int
101 owsbm_match(struct device *parent, void *match, void *aux)
102 {
103 return (onewire_matchbyfam(aux, owsbm_fams,
104 sizeof(owsbm_fams) /sizeof(owsbm_fams[0])));
105 }
106
107 void
108 owsbm_attach(struct device *parent, struct device *self, void *aux)
109 {
110 struct owsbm_softc *sc = (struct owsbm_softc *)self;
111 struct onewire_attach_args *oa = aux;
112
113 sc->sc_onewire = oa->oa_onewire;
114 sc->sc_rom = oa->oa_rom;
115
116
117 strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
118 sizeof(sc->sc_sensordev.xname));
119 sc->sc_temp.type = SENSOR_TEMP;
120 sensor_attach(&sc->sc_sensordev, &sc->sc_temp);
121
122
123 sc->sc_voltage_vdd.type = SENSOR_VOLTS_DC;
124 strlcpy(sc->sc_voltage_vdd.desc, "VDD", sizeof(sc->sc_voltage_vdd.desc));
125 sensor_attach(&sc->sc_sensordev, &sc->sc_voltage_vdd);
126
127
128 sc->sc_voltage_vad.type = SENSOR_VOLTS_DC;
129 strlcpy(sc->sc_voltage_vad.desc, "VAD", sizeof(sc->sc_voltage_vad.desc));
130 sensor_attach(&sc->sc_sensordev, &sc->sc_voltage_vad);
131
132
133 sc->sc_voltage_cr.type = SENSOR_VOLTS_DC;
134 strlcpy(sc->sc_voltage_cr.desc, "CR", sizeof(sc->sc_voltage_cr.desc));
135 sensor_attach(&sc->sc_sensordev, &sc->sc_voltage_cr);
136
137 sc->sc_sensortask = sensor_task_register(sc, owsbm_update, 10);
138 if (sc->sc_sensortask == NULL) {
139 printf(": unable to register owsbm update task\n");
140 return;
141 }
142
143 sensordev_install(&sc->sc_sensordev);
144
145 rw_init(&sc->sc_lock, sc->sc_dev.dv_xname);
146 printf("\n");
147 }
148
149 int
150 owsbm_detach(struct device *self, int flags)
151 {
152 struct owsbm_softc *sc = (struct owsbm_softc *)self;
153
154 rw_enter_write(&sc->sc_lock);
155 sensordev_deinstall(&sc->sc_sensordev);
156 if (sc->sc_sensortask != NULL)
157 sensor_task_unregister(sc->sc_sensortask);
158 rw_exit_write(&sc->sc_lock);
159
160 return (0);
161 }
162
163 int
164 owsbm_activate(struct device *self, enum devact act)
165 {
166 return (0);
167 }
168
169 void
170 owsbm_update(void *arg)
171 {
172 struct owsbm_softc *sc = arg;
173 u_int8_t data[9];
174
175 rw_enter_write(&sc->sc_lock);
176 onewire_lock(sc->sc_onewire, 0);
177 if (onewire_reset(sc->sc_onewire) != 0)
178 goto done;
179
180 onewire_matchrom(sc->sc_onewire, sc->sc_rom);
181 onewire_write_byte(sc->sc_onewire, DSSBM_CMD_CONVERT_T);
182 if (onewire_reset(sc->sc_onewire) != 0)
183 goto done;
184
185 onewire_matchrom(sc->sc_onewire, sc->sc_rom);
186 onewire_write_byte(sc->sc_onewire, DSSBM_CMD_CONVERT_V);
187 if (onewire_reset(sc->sc_onewire) != 0)
188 goto done;
189
190 onewire_matchrom(sc->sc_onewire, sc->sc_rom);
191
192 onewire_write_byte(sc->sc_onewire, DSSBM_CMD_RECALL_MEMORY);
193 onewire_write_byte(sc->sc_onewire, 0);
194
195 if (onewire_reset(sc->sc_onewire) != 0)
196 goto done;
197
198 onewire_matchrom(sc->sc_onewire, sc->sc_rom);
199
200 onewire_write_byte(sc->sc_onewire, DSSBM_CMD_READ_SCRATCHPAD);
201 onewire_write_byte(sc->sc_onewire, 0);
202 onewire_read_block(sc->sc_onewire, data, 9);
203 if (onewire_crc(data, 8) == data[DS2438_SP_CRC]) {
204 sc->sc_temp.value = 273150000 +
205 (int)(((u_int16_t)data[DS2438_SP_TEMP_MSB] << 5) |
206 ((u_int16_t)data[DS2438_SP_TEMP_LSB] >> 3)) * 31250;
207 sc->sc_voltage_vdd.value =
208 (int)(((u_int16_t)data[DS2438_SP_VOLT_MSB] << 8) |
209 data[DS2438_SP_VOLT_LSB]) * 10000;
210
211 sc->sc_voltage_cr.value =
212 (int)(((u_int16_t)data[DS2438_SP_CURRENT_MSB] << 8) |
213 data[DS2438_SP_CURRENT_LSB]) * 244;
214 }
215
216
217
218 if (onewire_reset(sc->sc_onewire) != 0)
219 goto done;
220
221 onewire_matchrom(sc->sc_onewire, sc->sc_rom);
222 onewire_write_byte(sc->sc_onewire, DSSBM_CMD_WRITE_SCRATCHPAD);
223 onewire_write_byte(sc->sc_onewire, 0);
224 onewire_write_byte(sc->sc_onewire, 0x7);
225
226 if (onewire_reset(sc->sc_onewire) != 0)
227 goto done;
228
229 onewire_matchrom(sc->sc_onewire, sc->sc_rom);
230 onewire_write_byte(sc->sc_onewire, DSSBM_CMD_CONVERT_V);
231 if (onewire_reset(sc->sc_onewire) != 0)
232 goto done;
233
234 onewire_matchrom(sc->sc_onewire, sc->sc_rom);
235
236 onewire_write_byte(sc->sc_onewire, DSSBM_CMD_RECALL_MEMORY);
237 onewire_write_byte(sc->sc_onewire, 0);
238
239 if (onewire_reset(sc->sc_onewire) != 0)
240 goto done;
241
242 onewire_matchrom(sc->sc_onewire, sc->sc_rom);
243 onewire_write_byte(sc->sc_onewire, DSSBM_CMD_READ_SCRATCHPAD);
244 onewire_write_byte(sc->sc_onewire, 0);
245 onewire_read_block(sc->sc_onewire, data, 9);
246 if (onewire_crc(data, 8) == data[8]) {
247 sc->sc_voltage_vad.value =
248 (int)(((u_int16_t)data[DS2438_SP_VOLT_MSB] << 8) |
249 data[DS2438_SP_VOLT_LSB]) * 10000;
250 }
251
252
253
254 if (onewire_reset(sc->sc_onewire) != 0)
255 goto done;
256
257 onewire_matchrom(sc->sc_onewire, sc->sc_rom);
258 onewire_write_byte(sc->sc_onewire, DSSBM_CMD_WRITE_SCRATCHPAD);
259 onewire_write_byte(sc->sc_onewire, 0);
260 onewire_write_byte(sc->sc_onewire, 0xf);
261 onewire_reset(sc->sc_onewire);
262
263 done:
264 onewire_unlock(sc->sc_onewire);
265 rw_exit_write(&sc->sc_lock);
266 }