This source file includes following definitions.
- adc_match
- adc_attach
- adc_refresh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/device.h>
22 #include <sys/sensors.h>
23
24 #include <dev/i2c/i2cvar.h>
25
26
27 #define AD741X_TEMP 0x00
28 #define AD741X_CONFIG 0x01
29 #define AD741X_THYST 0x02
30 #define AD741X_TOTI 0x03
31 #define AD741X_ADC 0x04
32 #define AD741X_CONFIG2 0x05
33
34 #define AD741X_CONFMASK 0xe0
35
36
37 #define ADC_TEMP 0
38 #define ADC_ADC0 1
39 #define ADC_ADC1 2
40 #define ADC_ADC2 3
41 #define ADC_ADC3 4
42 #define ADC_MAX_SENSORS 5
43
44 struct adc_softc {
45 struct device sc_dev;
46 i2c_tag_t sc_tag;
47 i2c_addr_t sc_addr;
48 int sc_chip;
49 u_int8_t sc_config;
50
51 struct ksensor sc_sensor[ADC_MAX_SENSORS];
52 struct ksensordev sc_sensordev;
53 };
54
55 int adc_match(struct device *, void *, void *);
56 void adc_attach(struct device *, struct device *, void *);
57 int adc_check(struct i2c_attach_args *, u_int8_t *, u_int8_t *);
58 void adc_refresh(void *);
59
60 struct cfattach adc_ca = {
61 sizeof(struct adc_softc), adc_match, adc_attach
62 };
63
64 struct cfdriver adc_cd = {
65 NULL, "adc", DV_DULL
66 };
67
68 int
69 adc_match(struct device *parent, void *match, void *aux)
70 {
71 struct i2c_attach_args *ia = aux;
72
73 if (strcmp(ia->ia_name, "ad7417") == 0 ||
74 strcmp(ia->ia_name, "ad7418") == 0)
75 return (1);
76 return (0);
77 }
78
79 void
80 adc_attach(struct device *parent, struct device *self, void *aux)
81 {
82 struct adc_softc *sc = (struct adc_softc *)self;
83 struct i2c_attach_args *ia = aux;
84 u_int8_t cmd, data;
85 int nsens = 0, i;
86
87 sc->sc_tag = ia->ia_tag;
88 sc->sc_addr = ia->ia_addr;
89
90 printf(": %s", ia->ia_name);
91
92 sc->sc_chip = 0;
93 if (strcmp(ia->ia_name, "ad7417") == 0)
94 sc->sc_chip = 7417;
95 if (strcmp(ia->ia_name, "ad7418") == 0)
96 sc->sc_chip = 7418;
97
98 if (sc->sc_chip != 0) {
99 cmd = AD741X_CONFIG2;
100 data = 0;
101 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
102 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
103 printf(", config2 reset failed\n");
104 return;
105 }
106 }
107
108 cmd = AD741X_CONFIG;
109 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
110 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
111 printf(", config reset failed\n");
112 return;
113 }
114 data &= 0xfe;
115 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
116 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
117 printf(", config reset failed\n");
118 return;
119 }
120 sc->sc_config = data;
121
122
123 strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
124 sizeof(sc->sc_sensordev.xname));
125
126 sc->sc_sensor[ADC_TEMP].type = SENSOR_TEMP;
127 strlcpy(sc->sc_sensor[ADC_TEMP].desc, "Internal",
128 sizeof(sc->sc_sensor[ADC_TEMP].desc));
129 nsens = 1;
130
131 if (sc->sc_chip == 7417 || sc->sc_chip == 7418) {
132 sc->sc_sensor[ADC_ADC0].type = SENSOR_INTEGER;
133 nsens++;
134 }
135 if (sc->sc_chip == 7417 || sc->sc_chip == 7418) {
136 sc->sc_sensor[ADC_ADC1].type = SENSOR_INTEGER;
137 sc->sc_sensor[ADC_ADC2].type = SENSOR_INTEGER;
138 sc->sc_sensor[ADC_ADC3].type = SENSOR_INTEGER;
139 nsens += 3;
140 }
141
142 if (sensor_task_register(sc, adc_refresh, 5) == NULL) {
143 printf(", unable to register update task\n");
144 return;
145 }
146
147 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[0]);
148 if (sc->sc_chip == 7417 || sc->sc_chip == 7418)
149 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[1]);
150 if (sc->sc_chip == 7417)
151 for (i = 2; i < nsens; i++)
152 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
153 sensordev_install(&sc->sc_sensordev);
154
155 printf("\n");
156 }
157
158 void
159 adc_refresh(void *arg)
160 {
161 struct adc_softc *sc = arg;
162 u_int8_t cmd, data[2], reg;
163 int i;
164
165 iic_acquire_bus(sc->sc_tag, 0);
166
167 reg = (sc->sc_config & AD741X_CONFMASK) | (0 << 5);
168 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
169 sc->sc_addr, &cmd, sizeof cmd, ®, sizeof reg, 0))
170 goto done;
171 delay(1000);
172 cmd = AD741X_TEMP;
173 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
174 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0))
175 goto done;
176 sc->sc_sensor[ADC_TEMP].value = 273150000 +
177 ((data[0] << 8 | data[1]) >> 6) * 250000;
178
179 if (sc->sc_chip == 0)
180 goto done;
181
182 if (sc->sc_chip == 7418) {
183 reg = (reg & AD741X_CONFMASK) | (4 << 5);
184 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
185 sc->sc_addr, &cmd, sizeof cmd, ®, sizeof reg, 0))
186 goto done;
187 delay(1000);
188 cmd = AD741X_ADC;
189 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
190 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0))
191 goto done;
192 sc->sc_sensor[ADC_ADC0].value =
193 (data[0] << 8 | data[1]) >> 6;
194 goto done;
195 }
196
197 for (i = 0; i < 4; i++) {
198 reg = (reg & AD741X_CONFMASK) | (i << 5);
199 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
200 sc->sc_addr, &cmd, sizeof cmd, ®, sizeof reg, 0))
201 goto done;
202 delay(1000);
203 cmd = AD741X_ADC;
204 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
205 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0))
206 goto done;
207 sc->sc_sensor[ADC_ADC0 + i].value =
208 (data[0] << 8 | data[1]) >> 6;
209 }
210
211 done:
212 iic_release_bus(sc->sc_tag, 0);
213 }