This source file includes following definitions.
- fintek_match
- fintek_read_reg
- fintek_write_reg
- fintek_attach
- fintek_refresh
- fintek_fullspeed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/device.h>
21 #include <sys/sensors.h>
22
23 #include <dev/i2c/i2cvar.h>
24
25
26 #define F_VCC 0
27 #define F_V1 1
28 #define F_V2 2
29 #define F_V3 3
30 #define F_TEMP1 4
31 #define F_TEMP2 5
32 #define F_FAN1 6
33 #define F_FAN2 7
34 #define F_NUM_SENSORS 8
35
36 struct fintek_softc {
37 struct device sc_dev;
38 i2c_tag_t sc_tag;
39 i2c_addr_t sc_addr;
40
41 struct ksensor sc_sensor[F_NUM_SENSORS];
42 struct ksensordev sc_sensordev;
43 };
44
45 int fintek_match(struct device *, void *, void *);
46 void fintek_attach(struct device *, struct device *, void *);
47
48 void fintek_refresh(void *);
49 int fintek_read_reg(struct fintek_softc *sc, u_int8_t cmd, u_int8_t *data,
50 size_t size);
51 int fintek_write_reg(struct fintek_softc *sc, u_int8_t cmd, u_int8_t *data,
52 size_t size);
53 void fintek_fullspeed(struct fintek_softc *sc);
54
55 struct cfattach fintek_ca = {
56 sizeof(struct fintek_softc), fintek_match, fintek_attach
57 };
58
59 struct cfdriver fintek_cd = {
60 NULL, "fintek", DV_DULL
61 };
62
63 #define FINTEK_CONFIG1 0x01
64 #define FINTEK_FAN1_LINEAR_MODE 0x10
65 #define FINTEK_FAN2_LINEAR_MODE 0x20
66 #define FINTEK_VOLT0 0x10
67 #define FINTEK_VOLT1 0x11
68 #define FINTEK_VOLT2 0x12
69 #define FINTEK_VOLT3 0x13
70 #define FINTEK_TEMP1 0x14
71 #define FINTEK_TEMP2 0x15
72 #define FINTEK_FAN1 0x16
73 #define FINTEK_FAN2 0x18
74 #define FINTEK_VERSION 0x5c
75 #define FINTEK_RSTCR 0x60
76 #define FINTEK_FAN1_MODE_MANUAL 0x30
77 #define FINTEK_FAN2_MODE_MANUAL 0xc0
78 #define FINTEK_PWM_DUTY1 0x76
79 #define FINTEK_PWM_DUTY2 0x86
80
81
82 #define FINTEK_OPTION_FULLSPEED 0x0001
83
84 int
85 fintek_match(struct device *parent, void *match, void *aux)
86 {
87 struct i2c_attach_args *ia = aux;
88
89 if (strcmp(ia->ia_name, "f75375") == 0)
90 return (1);
91 return (0);
92 }
93
94 int
95 fintek_read_reg(struct fintek_softc *sc, u_int8_t cmd, u_int8_t *data,
96 size_t size)
97 {
98 return iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
99 sc->sc_addr, &cmd, sizeof cmd, data, size, 0);
100 }
101
102 int
103 fintek_write_reg(struct fintek_softc *sc, u_int8_t cmd, u_int8_t *data,
104 size_t size)
105 {
106 return iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
107 sc->sc_addr, &cmd, sizeof cmd, data, size, 0);
108 }
109
110 void
111 fintek_attach(struct device *parent, struct device *self, void *aux)
112 {
113 struct fintek_softc *sc = (struct fintek_softc *)self;
114 struct i2c_attach_args *ia = aux;
115 u_int8_t cmd, data;
116 int i;
117
118 sc->sc_tag = ia->ia_tag;
119 sc->sc_addr = ia->ia_addr;
120
121 iic_acquire_bus(sc->sc_tag, 0);
122
123 cmd = FINTEK_VERSION;
124 if (fintek_read_reg(sc, cmd, &data, sizeof data))
125 goto failread;
126
127 printf(": F75375 rev %d.%d", data>> 4, data & 0xf);
128
129
130
131
132
133
134
135
136 if (sc->sc_dev.dv_cfdata->cf_flags & FINTEK_OPTION_FULLSPEED)
137 fintek_fullspeed(sc);
138
139 iic_release_bus(sc->sc_tag, 0);
140
141 strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
142 sizeof(sc->sc_sensordev.xname));
143
144 sc->sc_sensor[F_VCC].type = SENSOR_VOLTS_DC;
145 strlcpy(sc->sc_sensor[F_VCC].desc, "Vcc",
146 sizeof(sc->sc_sensor[F_VCC].desc));
147
148 sc->sc_sensor[F_V1].type = SENSOR_VOLTS_DC;
149 sc->sc_sensor[F_V2].type = SENSOR_VOLTS_DC;
150 sc->sc_sensor[F_V3].type = SENSOR_VOLTS_DC;
151
152 sc->sc_sensor[F_TEMP1].type = SENSOR_TEMP;
153 sc->sc_sensor[F_TEMP2].type = SENSOR_TEMP;
154
155 sc->sc_sensor[F_FAN1].type = SENSOR_FANRPM;
156 sc->sc_sensor[F_FAN2].type = SENSOR_FANRPM;
157
158 if (sensor_task_register(sc, fintek_refresh, 5) == NULL) {
159 printf(", unable to register update task\n");
160 return;
161 }
162
163 for (i = 0; i < F_NUM_SENSORS; i++) {
164 sc->sc_sensor[i].flags &= ~SENSOR_FINVALID;
165 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
166 }
167 sensordev_install(&sc->sc_sensordev);
168
169 printf("\n");
170 return;
171
172 failread:
173 printf("unable to read reg %d\n", cmd);
174 iic_release_bus(sc->sc_tag, 0);
175 return;
176 }
177
178
179 struct {
180 char sensor;
181 u_int8_t cmd;
182 } fintek_worklist[] = {
183 { F_VCC, FINTEK_VOLT0 },
184 { F_V1, FINTEK_VOLT1 },
185 { F_V2, FINTEK_VOLT2 },
186 { F_V3, FINTEK_VOLT3 },
187 { F_TEMP1, FINTEK_TEMP1 },
188 { F_TEMP2, FINTEK_TEMP2 },
189 { F_FAN1, FINTEK_FAN1 },
190 { F_FAN2, FINTEK_FAN2 }
191 };
192 #define FINTEK_WORKLIST_SZ (sizeof(fintek_worklist) / sizeof(fintek_worklist[0]))
193
194 void
195 fintek_refresh(void *arg)
196 {
197 struct fintek_softc *sc = arg;
198 u_int8_t cmd, data, data2;
199 int i;
200
201 iic_acquire_bus(sc->sc_tag, 0);
202
203 for (i = 0; i < FINTEK_WORKLIST_SZ; i++){
204 cmd = fintek_worklist[i].cmd;
205 if (fintek_read_reg(sc, cmd, &data, sizeof data)) {
206 sc->sc_sensor[i].flags |= SENSOR_FINVALID;
207 continue;
208 }
209 sc->sc_sensor[i].flags &= ~SENSOR_FINVALID;
210 switch (fintek_worklist[i].sensor) {
211 case F_VCC:
212 sc->sc_sensor[i].value = data * 16000;
213 break;
214 case F_V1:
215
216 case F_V2:
217
218 case F_V3:
219 sc->sc_sensor[i].value = data * 8000;
220 break;
221 case F_TEMP1:
222
223 case F_TEMP2:
224 sc->sc_sensor[i].value = 273150000 + data * 1000000;
225 break;
226 case F_FAN1:
227
228 case F_FAN2:
229
230 cmd = fintek_worklist[i].cmd + 1;
231 if (fintek_read_reg(sc, cmd, &data2, sizeof data2)) {
232 sc->sc_sensor[i].flags |= SENSOR_FINVALID;
233 continue;
234 }
235 if ((data == 0xff && data2 == 0xff) ||
236 (data == 0 && data2 == 0))
237 sc->sc_sensor[i].value = 0;
238 else
239 sc->sc_sensor[i].value = 1500000 /
240 (data << 8 | data2);
241 break;
242 default:
243 sc->sc_sensor[i].flags |= SENSOR_FINVALID;
244 break;
245 }
246 }
247
248 iic_release_bus(sc->sc_tag, 0);
249 }
250
251 void
252 fintek_fullspeed(struct fintek_softc *sc)
253 {
254 u_int8_t data;
255
256 data = FINTEK_FAN1_LINEAR_MODE | FINTEK_FAN2_LINEAR_MODE;
257 fintek_write_reg(sc, FINTEK_CONFIG1, &data, sizeof data);
258
259 data = FINTEK_FAN1_MODE_MANUAL | FINTEK_FAN2_MODE_MANUAL;
260 fintek_write_reg(sc, FINTEK_RSTCR, &data, sizeof data);
261
262 data = 0xff;
263 fintek_write_reg(sc, FINTEK_PWM_DUTY1, &data, sizeof data);
264 fintek_write_reg(sc, FINTEK_PWM_DUTY2, &data, sizeof data);
265 }