Line data Source code
1 : /* $OpenBSD: lm78_i2c.c,v 1.4 2015/03/14 03:38:47 jsg Exp $ */
2 :
3 : /*
4 : * Copyright (c) 2005 Mark Kettenis
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 : #include <dev/ic/lm78var.h>
26 :
27 : struct lm_i2c_softc {
28 : struct lm_softc sc_lmsc;
29 : i2c_tag_t sc_tag;
30 : i2c_addr_t sc_addr;
31 : };
32 :
33 : int lm_i2c_match(struct device *, void *, void *);
34 : void lm_i2c_attach(struct device *, struct device *, void *);
35 : u_int8_t lm_i2c_readreg(struct lm_softc *, int);
36 : void lm_i2c_writereg(struct lm_softc *, int, int);
37 :
38 : struct cfattach lm_i2c_ca = {
39 : sizeof(struct lm_i2c_softc), lm_i2c_match, lm_i2c_attach
40 : };
41 :
42 : int
43 0 : lm_i2c_match(struct device *parent, void *match, void *aux)
44 : {
45 0 : struct i2c_attach_args *ia = aux;
46 :
47 0 : if (strcmp(ia->ia_name, "as99127f") == 0 ||
48 0 : strcmp(ia->ia_name, "w83627dhg") == 0 ||
49 0 : strcmp(ia->ia_name, "w83627hf") == 0 ||
50 0 : strcmp(ia->ia_name, "w83781d") == 0 ||
51 0 : strcmp(ia->ia_name, "w83782d") == 0 ||
52 0 : strcmp(ia->ia_name, "w83783s") == 0 ||
53 0 : strcmp(ia->ia_name, "w83791d") == 0 ||
54 0 : strcmp(ia->ia_name, "w83792d") == 0) {
55 0 : return (1);
56 : }
57 : /*
58 : * XXX This chip doesn't have any real sensors, but we match
59 : * it for now, just to knock out its satellites.
60 : */
61 0 : if (strcmp(ia->ia_name, "w83791sd") == 0) {
62 0 : return (1);
63 : }
64 0 : return (0);
65 0 : }
66 :
67 : void
68 0 : lm_i2c_attach(struct device *parent, struct device *self, void *aux)
69 : {
70 0 : struct lm_i2c_softc *sc = (struct lm_i2c_softc *)self;
71 0 : struct i2c_attach_args *ia = aux;
72 0 : u_int8_t cmd, data;
73 :
74 0 : sc->sc_tag = ia->ia_tag;
75 0 : sc->sc_addr = ia->ia_addr;
76 :
77 : /* Bus-independent attachment. */
78 0 : sc->sc_lmsc.lm_writereg = lm_i2c_writereg;
79 0 : sc->sc_lmsc.lm_readreg = lm_i2c_readreg;
80 0 : lm_attach(&sc->sc_lmsc);
81 :
82 : /* Remember we attached to iic(4). */
83 0 : sc->sc_lmsc.sbusaddr = ia->ia_addr;
84 :
85 0 : iic_acquire_bus(sc->sc_tag, 0);
86 :
87 0 : cmd = 0x4a;
88 0 : iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
89 0 : sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0);
90 :
91 0 : iic_release_bus(sc->sc_tag, 0);
92 :
93 : /* Make the bus scan ignore the satellites. */
94 0 : iic_ignore_addr(0x48 + (data & 0x7));
95 0 : iic_ignore_addr(0x48 + ((data >> 4) & 0x7));
96 0 : }
97 :
98 : u_int8_t
99 0 : lm_i2c_readreg(struct lm_softc *lmsc, int reg)
100 : {
101 0 : struct lm_i2c_softc *sc = (struct lm_i2c_softc *)lmsc;
102 0 : u_int8_t cmd, data;
103 :
104 0 : iic_acquire_bus(sc->sc_tag, 0);
105 :
106 0 : cmd = reg;
107 0 : iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
108 0 : sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0);
109 :
110 0 : iic_release_bus(sc->sc_tag, 0);
111 :
112 0 : return data;
113 0 : }
114 :
115 : void
116 0 : lm_i2c_writereg(struct lm_softc *lmsc, int reg, int val)
117 : {
118 0 : struct lm_i2c_softc *sc = (struct lm_i2c_softc *)lmsc;
119 0 : u_int8_t cmd, data;
120 :
121 0 : iic_acquire_bus(sc->sc_tag, 0);
122 :
123 0 : cmd = reg;
124 0 : data = val;
125 0 : iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
126 0 : sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0);
127 :
128 0 : iic_release_bus(sc->sc_tag, 0);
129 0 : }
|