Line data Source code
1 : /* $OpenBSD: sdtemp.c,v 1.15 2014/11/14 07:03:22 jsg Exp $ */
2 :
3 : /*
4 : * Copyright (c) 2008 Theo de Raadt
5 : *
6 : * Permission to use, copy, modify, and distribute this software for any
7 : * purpose with or without fee is hereby granted, provided that the above
8 : * copyright notice and this permission notice appear in all copies.
9 : *
10 : * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 : * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 : * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 : * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 : * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 : * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
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 : /* JEDEC JC-42.4 registers */
27 : #define JC_TEMP 0x05
28 :
29 : /* Sensors */
30 : #define JCTEMP_TEMP 0
31 : #define JCTEMP_NUM_SENSORS 1
32 :
33 : struct sdtemp_softc {
34 : struct device sc_dev;
35 : i2c_tag_t sc_tag;
36 : i2c_addr_t sc_addr;
37 :
38 : struct ksensor sc_sensor[JCTEMP_NUM_SENSORS];
39 : struct ksensordev sc_sensordev;
40 : };
41 :
42 : int sdtemp_match(struct device *, void *, void *);
43 : void sdtemp_attach(struct device *, struct device *, void *);
44 : void sdtemp_refresh(void *);
45 :
46 : struct cfattach sdtemp_ca = {
47 : sizeof(struct sdtemp_softc), sdtemp_match, sdtemp_attach
48 : };
49 :
50 : struct cfdriver sdtemp_cd = {
51 : NULL, "sdtemp", DV_DULL
52 : };
53 :
54 : int
55 0 : sdtemp_match(struct device *parent, void *match, void *aux)
56 : {
57 0 : struct i2c_attach_args *ia = aux;
58 :
59 0 : if (strcmp(ia->ia_name, "se97") == 0 ||
60 0 : strcmp(ia->ia_name, "se98") == 0 ||
61 0 : strcmp(ia->ia_name, "max6604") == 0 ||
62 0 : strcmp(ia->ia_name, "mcp9804") == 0 ||
63 0 : strcmp(ia->ia_name, "mcp9805") == 0 ||
64 0 : strcmp(ia->ia_name, "mcp98242") == 0 ||
65 0 : strcmp(ia->ia_name, "mcp98243") == 0 ||
66 0 : strcmp(ia->ia_name, "mcp98244") == 0 ||
67 0 : strcmp(ia->ia_name, "adt7408") == 0 ||
68 0 : strcmp(ia->ia_name, "stts424e02") == 0 ||
69 0 : strcmp(ia->ia_name, "stts424") == 0 ||
70 0 : strcmp(ia->ia_name, "stts2002") == 0 ||
71 0 : strcmp(ia->ia_name, "stts2004") == 0 ||
72 0 : strcmp(ia->ia_name, "stts3000") == 0 ||
73 0 : strcmp(ia->ia_name, "ts3000b3") == 0 ||
74 0 : strcmp(ia->ia_name, "ts3000gb0") == 0 ||
75 0 : strcmp(ia->ia_name, "ts3000gb2") == 0 ||
76 0 : strcmp(ia->ia_name, "ts3001gb2") == 0 ||
77 0 : strcmp(ia->ia_name, "tse2004gb2") == 0 ||
78 0 : strcmp(ia->ia_name, "at30ts00") == 0 ||
79 0 : strcmp(ia->ia_name, "at30tse004") == 0 ||
80 0 : strcmp(ia->ia_name, "cat34ts02") == 0 ||
81 0 : strcmp(ia->ia_name, "cat34ts02c") == 0 ||
82 0 : strcmp(ia->ia_name, "cat34ts04") == 0 ||
83 0 : strcmp(ia->ia_name, "gt30ts00") == 0 ||
84 0 : strcmp(ia->ia_name, "gt34ts02") == 0)
85 0 : return (1);
86 0 : return (0);
87 0 : }
88 :
89 : void
90 0 : sdtemp_attach(struct device *parent, struct device *self, void *aux)
91 : {
92 0 : struct sdtemp_softc *sc = (struct sdtemp_softc *)self;
93 0 : struct i2c_attach_args *ia = aux;
94 :
95 0 : sc->sc_tag = ia->ia_tag;
96 0 : sc->sc_addr = ia->ia_addr;
97 :
98 0 : printf(": %s", ia->ia_name);
99 :
100 : /* Initialize sensor data. */
101 0 : strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
102 : sizeof(sc->sc_sensordev.xname));
103 :
104 0 : sc->sc_sensor[JCTEMP_TEMP].type = SENSOR_TEMP;
105 :
106 0 : if (sensor_task_register(sc, sdtemp_refresh, 5) == NULL) {
107 0 : printf(", unable to register update task\n");
108 0 : return;
109 : }
110 :
111 0 : sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[0]);
112 0 : sensordev_install(&sc->sc_sensordev);
113 :
114 0 : printf("\n");
115 0 : }
116 :
117 : void
118 0 : sdtemp_refresh(void *arg)
119 : {
120 0 : struct sdtemp_softc *sc = arg;
121 0 : u_int8_t cmd;
122 0 : int16_t data, sdata;
123 :
124 0 : iic_acquire_bus(sc->sc_tag, 0);
125 :
126 0 : cmd = JC_TEMP;
127 0 : if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
128 0 : &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
129 0 : sdata = betoh16(data) & 0x1fff;
130 0 : if (sdata & 0x1000)
131 0 : sdata -= 0x2000;
132 0 : sc->sc_sensor[JCTEMP_TEMP].value =
133 0 : 273150000 + 62500 * sdata;
134 0 : sc->sc_sensor[JCTEMP_TEMP].flags &= ~SENSOR_FINVALID;
135 : #if 0
136 : printf("sdtemp %04x %04x %d\n", data & 0xffff,
137 : (u_int)sdata & 0xffff,
138 : sc->sc_sensor[JCTEMP_TEMP].value);
139 : #endif
140 0 : }
141 :
142 0 : iic_release_bus(sc->sc_tag, 0);
143 0 : }
|