Fri Mar 9 22:27:15 2018 UTC ()
remove some unused code, add comments for credits & explanations


(macallan)
diff -r1.1 -r1.2 src/sys/dev/i2c/adadc.c

cvs diff -r1.1 -r1.2 src/sys/dev/i2c/adadc.c (expand / switch to unified diff)

--- src/sys/dev/i2c/adadc.c 2018/03/09 20:16:54 1.1
+++ src/sys/dev/i2c/adadc.c 2018/03/09 22:27:15 1.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: adadc.c,v 1.1 2018/03/09 20:16:54 macallan Exp $ */ 1/* $NetBSD: adadc.c,v 1.2 2018/03/09 22:27:15 macallan Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2018 Michael Lorenz 4 * Copyright (c) 2018 Michael Lorenz
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -16,30 +16,35 @@ @@ -16,30 +16,35 @@
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29/* a driver for Analog Devices AD7417 temperature sensors / ADCs */ 29/*
 30 * a driver for Analog Devices AD7417 temperature sensors / ADCs
 31 * very much macppc only for now since we need calibaration data to make sense
 32 * of the ADC inputs
 33 * info on how to get these from FreeBSD and Linux
 34 */
30 35
31#include <sys/cdefs.h> 36#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: adadc.c,v 1.1 2018/03/09 20:16:54 macallan Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: adadc.c,v 1.2 2018/03/09 22:27:15 macallan Exp $");
33 38
34#include <sys/param.h> 39#include <sys/param.h>
35#include <sys/systm.h> 40#include <sys/systm.h>
36#include <sys/device.h> 41#include <sys/device.h>
37#include <sys/conf.h> 42#include <sys/conf.h>
38#include <sys/bus.h> 43#include <sys/bus.h>
39 44
40#include <dev/i2c/i2cvar.h> 45#include <dev/i2c/i2cvar.h>
41 46
42#include <dev/sysmon/sysmonvar.h> 47#include <dev/sysmon/sysmonvar.h>
43 48
44#include <dev/ofw/openfirm.h> 49#include <dev/ofw/openfirm.h>
45 50
@@ -83,79 +88,88 @@ struct adadc_softc { @@ -83,79 +88,88 @@ struct adadc_softc {
83static int adadc_match(device_t, cfdata_t, void *); 88static int adadc_match(device_t, cfdata_t, void *);
84static void adadc_attach(device_t, device_t, void *); 89static void adadc_attach(device_t, device_t, void *);
85 90
86static void adadc_sensors_refresh(struct sysmon_envsys *, envsys_data_t *); 91static void adadc_sensors_refresh(struct sysmon_envsys *, envsys_data_t *);
87 92
88CFATTACH_DECL_NEW(adadc, sizeof(struct adadc_softc), 93CFATTACH_DECL_NEW(adadc, sizeof(struct adadc_softc),
89 adadc_match, adadc_attach, NULL, NULL); 94 adadc_match, adadc_attach, NULL, NULL);
90 95
91static const char * dstemp_compats[] = { 96static const char * dstemp_compats[] = {
92 "ad7417", 97 "ad7417",
93 NULL 98 NULL
94}; 99};
95 100
 101/* calibaration table from Darwin via Linux */
96static int slope[5] = {0, 0, 0x0320, 0x00a0, 0x1f40}; 102static int slope[5] = {0, 0, 0x0320, 0x00a0, 0x1f40};
97 103
98static int 104static int
99adadc_match(device_t parent, cfdata_t match, void *aux) 105adadc_match(device_t parent, cfdata_t match, void *aux)
100{ 106{
101 struct i2c_attach_args *ia = aux; 107 struct i2c_attach_args *ia = aux;
102 108
103 if (ia->ia_name == NULL) { 109 if (ia->ia_name == NULL) {
104 /* no ID registers on this chip */ 110 /*
 111 * XXX
 112 * this driver is pretty much useless without OF, should
 113 * probably remove this
 114 */
105 if ((ia->ia_addr & 0x2b) == 0x2b) 115 if ((ia->ia_addr & 0x2b) == 0x2b)
106 return 1; 116 return 1;
107 return 0; 117 return 0;
108 } else { 118 } else {
109 return iic_compat_match(ia, dstemp_compats); 119 return iic_compat_match(ia, dstemp_compats);
110 } 120 }
111} 121}
112 122
113static void 123static void
114adadc_attach(device_t parent, device_t self, void *aux) 124adadc_attach(device_t parent, device_t self, void *aux)
115{ 125{
116 struct adadc_softc *sc = device_private(self); 126 struct adadc_softc *sc = device_private(self);
117 struct i2c_attach_args *ia = aux; 127 struct i2c_attach_args *ia = aux;
118 envsys_data_t *s; 128 envsys_data_t *s;
119 int error, ch, cpuid; 129 int error, ch, cpuid;
120 uint32_t eeprom[40]; 130 uint32_t eeprom[40];
121 uint8_t cmd, data; 
122 char loc[256]; 131 char loc[256];
123 int which_cpu; 132 int which_cpu;
124 133
125 sc->sc_dev = self; 134 sc->sc_dev = self;
126 sc->sc_i2c = ia->ia_tag; 135 sc->sc_i2c = ia->ia_tag;
127 sc->sc_addr = ia->ia_addr; 136 sc->sc_addr = ia->ia_addr;
128 137
129 aprint_naive("\n"); 138 aprint_naive("\n");
130 aprint_normal(": AD7417\n"); 139 aprint_normal(": AD7417\n");
131 140
132 cmd = ADADC_CONFIG; 
133 error = iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, 
134 sc->sc_addr, &cmd, 1, &data, 1, 0); 
135 
136 sc->sc_sme = sysmon_envsys_create(); 141 sc->sc_sme = sysmon_envsys_create();
137 sc->sc_sme->sme_name = device_xname(self); 142 sc->sc_sme->sme_name = device_xname(self);
138 sc->sc_sme->sme_cookie = sc; 143 sc->sc_sme->sme_cookie = sc;
139 sc->sc_sme->sme_refresh = adadc_sensors_refresh; 144 sc->sc_sme->sme_refresh = adadc_sensors_refresh;
140 sc->sc_nsensors = 0; 145 sc->sc_nsensors = 0;
141 146
 147 /*
 148 * XXX
 149 * without OpenFirmware telling us how to interpret the ADC inputs we
 150 * should probably just expose the temperature and four ENVSYS_INTEGERs
 151 */
142 which_cpu = 0; 152 which_cpu = 0;
143 ch = OF_child(ia->ia_cookie); 153 ch = OF_child(ia->ia_cookie);
144 while (ch != 0) { 154 while (ch != 0) {
145 if (OF_getprop(ch, "location", loc, 32) > 0) { 155 if (OF_getprop(ch, "location", loc, 32) > 0) {
146 int reg = 0; 156 int reg = 0;
147 OF_getprop(ch, "reg", &reg, sizeof(reg)); 157 OF_getprop(ch, "reg", &reg, sizeof(reg));
148 s = &sc->sc_sensors[sc->sc_nsensors]; 158 s = &sc->sc_sensors[sc->sc_nsensors];
 159 /*
 160 * this setup matches my 2x 2.5GHz PCI-X G5, Linux and
 161 * FreeBSD hardcode these as well so we should be safe
 162 */
149 switch (reg) { 163 switch (reg) {
150 case 0: 164 case 0:
151 if (strstr(loc, "CPU B") != NULL) 165 if (strstr(loc, "CPU B") != NULL)
152 which_cpu = 1; 166 which_cpu = 1;
153 /* FALLTHROUGH */  167 /* FALLTHROUGH */
154 case 1: 168 case 1:
155 s->units = ENVSYS_STEMP; 169 s->units = ENVSYS_STEMP;
156 break; 170 break;
157 case 2: 171 case 2:
158 case 4: 172 case 4:
159 s->units = ENVSYS_SAMPS; 173 s->units = ENVSYS_SAMPS;
160 break; 174 break;
161 case 3: 175 case 3:
@@ -210,31 +224,36 @@ adadc_sensors_refresh(struct sysmon_envs @@ -210,31 +224,36 @@ adadc_sensors_refresh(struct sysmon_envs
210 } 224 }
211 cmd = ADADC_ADC; 225 cmd = ADADC_ADC;
212 /* now read the ADC register */ 226 /* now read the ADC register */
213 error = iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, 227 error = iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP,
214 sc->sc_addr, &cmd, 1, &rdata, 2, 0); 228 sc->sc_addr, &cmd, 1, &rdata, 2, 0);
215 rdata = be16toh(rdata) >> 6; 229 rdata = be16toh(rdata) >> 6;
216 if (edata->private == 1) { 230 if (edata->private == 1) {
217 int temp; 231 int temp;
218 temp = (rdata * sc->sc_diode_slope +  232 temp = (rdata * sc->sc_diode_slope +
219 sc->sc_diode_offset) >> 2; 233 sc->sc_diode_offset) >> 2;
220 /* 16.16 fixed point */ 234 /* 16.16 fixed point */
221 edata->value_cur = (temp >> 12) * 62500 + 273150000; 235 edata->value_cur = (temp >> 12) * 62500 + 273150000;
222 } else { 236 } else {
 237 /*
 238 * the input is 10bit, so converting to 8.4 fixed point
 239 * is more than enough
 240 */
223 int temp = rdata * slope[edata->private]; 241 int temp = rdata * slope[edata->private];
224 edata->value_cur = (temp >> 12) * 62500; 242 edata->value_cur = (temp >> 12) * 62500;
225 } 243 }
226 } else { 244 } else {
227 cmd = ADADC_TEMP; 245 cmd = ADADC_TEMP;
228 /* just read the temperature register */ 246 /* just read the temperature register */
229 error = iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, 247 error = iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP,
230 sc->sc_addr, &cmd, 1, &data, 2, 0); 248 sc->sc_addr, &cmd, 1, &data, 2, 0);
 249 /* 8.2 bit fixed point Celsius -> microkelvin */
231 edata->value_cur = ((data >> 6) * 250000) + 273150000; 250 edata->value_cur = ((data >> 6) * 250000) + 273150000;
232 } 251 }
233 iic_release_bus(sc->sc_i2c, 0); 252 iic_release_bus(sc->sc_i2c, 0);
234 253
235 if (error) { 254 if (error) {
236 edata->state = ENVSYS_SINVALID; 255 edata->state = ENVSYS_SINVALID;
237 } else { 256 } else {
238 edata->state = ENVSYS_SVALID; 257 edata->state = ENVSYS_SVALID;
239 } 258 }
240} 259}