This source file includes following definitions.
- nviic_match
- nviic_attach
- nviic_i2c_acquire_bus
- nviic_i2c_release_bus
- nviic_i2c_exec
- nviic_read
- nviic_write
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/kernel.h>
23 #include <sys/rwlock.h>
24 #include <sys/proc.h>
25
26 #include <machine/bus.h>
27
28 #include <dev/pci/pcidevs.h>
29 #include <dev/pci/pcireg.h>
30 #include <dev/pci/pcivar.h>
31
32 #include <dev/i2c/i2cvar.h>
33
34
35 #define NVI_PCI_SMBASE1 0x20
36 #define NVI_PCI_SMBASE2 0x24
37
38 #define NVI_OLD_PCI_SMBASE1 0x50
39 #define NVI_OLD_PCI_SMBASE2 0x54
40
41 #define NVI_SMBASE(x) ((x) & 0xfffc)
42 #define NVI_SMBASE_SIZE 8
43
44
45 #define NVI_SMB_PRTCL 0x00
46 #define NVI_SMB_STS 0x01
47 #define NVI_SMB_ADDR 0x02
48 #define NVI_SMB_CMD 0x03
49 #define NVI_SMB_DATA(o) (0x04 + (o))
50 #define NVI_SMB_BCNT 0x24
51 #define NVI_SMB_ALRM_A 0x25
52 #define NVI_SMB_ALRM_D 0x26
53
54 #define NVI_SMB_STS_DONE 0x80
55 #define NVI_SMB_STS_ALRM 0x40
56 #define NVI_SMB_STS_RES 0x20
57 #define NVI_SMB_STS_STATUS 0x1f
58
59 #define NVI_SMB_PRTCL_WRITE 0x00
60 #define NVI_SMB_PRTCL_READ 0x01
61 #define NVI_SMB_PRTCL_QUICK 0x02
62 #define NVI_SMB_PRTCL_BYTE 0x04
63 #define NVI_SMB_PRTCL_BYTE_DATA 0x06
64 #define NVI_SMB_PRTCL_WORD_DATA 0x08
65 #define NVI_SMB_PRTCL_BLOCK_DATA 0x0a
66 #define NVI_SMB_PRTCL_PROC_CALL 0x0c
67 #define NVI_SMB_PRTCL_BLOCK_PROC_CALL 0x0d
68 #define NVI_SMB_PRTCL_PEC 0x80
69
70 #ifdef NVIIC_DEBUG
71 #define DPRINTF(x...) do { if (nviic_debug) printf(x); } while (0)
72 int nviic_debug = 1;
73 #else
74 #define DPRINTF(x...)
75 #endif
76
77
78 #define NVIIC_NBUS 2
79
80 int nviic_match(struct device *, void *, void *);
81 void nviic_attach(struct device *, struct device *, void *);
82
83 struct nviic_softc;
84
85 struct nviic_controller {
86 struct nviic_softc *nc_sc;
87 bus_space_handle_t nc_ioh;
88 struct rwlock nc_lock;
89 struct i2c_controller nc_i2c;
90 };
91
92 struct nviic_softc {
93 struct device sc_dev;
94 bus_space_tag_t sc_iot;
95 struct nviic_controller sc_nc[NVIIC_NBUS];
96 };
97
98 struct cfattach nviic_ca = {
99 sizeof(struct nviic_softc), nviic_match, nviic_attach
100 };
101
102 struct cfdriver nviic_cd = {
103 NULL, "nviic", DV_DULL
104 };
105
106 int nviic_i2c_acquire_bus(void *, int);
107 void nviic_i2c_release_bus(void *, int);
108 int nviic_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
109 size_t, void *, size_t, int);
110
111 u_int8_t nviic_read(struct nviic_controller *, bus_size_t);
112 void nviic_write(struct nviic_controller *, bus_size_t, u_int8_t);
113
114 #define DEVNAME(s) ((sc)->sc_dev.dv_xname)
115
116 const struct pci_matchid nviic_ids[] = {
117 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_NFORCE2_SMB },
118 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_NFORCE2_400_SMB },
119 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_NFORCE3_SMB },
120 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_NFORCE3_250_SMB },
121 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_NFORCE4_SMB },
122 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP51_SMB },
123 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP55_SMB },
124 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP61_SMB },
125 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP65_SMB },
126 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP67_SMB }
127 };
128
129 int
130 nviic_match(struct device *parent, void *match, void *aux)
131 {
132 return (pci_matchbyid(aux, nviic_ids,
133 sizeof(nviic_ids) / sizeof(nviic_ids[0])));
134 }
135
136 void
137 nviic_attach(struct device *parent, struct device *self, void *aux)
138 {
139 struct nviic_softc *sc = (struct nviic_softc *)self;
140 struct pci_attach_args *pa = aux;
141 struct nviic_controller *nc;
142 struct i2cbus_attach_args iba;
143 int baseregs[NVIIC_NBUS];
144 pcireg_t reg;
145 int i;
146
147 sc->sc_iot = pa->pa_iot;
148
149 printf("\n");
150
151
152 switch (PCI_PRODUCT(pa->pa_id)) {
153 case PCI_PRODUCT_NVIDIA_NFORCE2_SMB:
154 case PCI_PRODUCT_NVIDIA_NFORCE2_400_SMB:
155 case PCI_PRODUCT_NVIDIA_NFORCE3_SMB:
156 case PCI_PRODUCT_NVIDIA_NFORCE3_250_SMB:
157 case PCI_PRODUCT_NVIDIA_NFORCE4_SMB:
158 baseregs[0] = NVI_OLD_PCI_SMBASE1;
159 baseregs[1] = NVI_OLD_PCI_SMBASE2;
160 break;
161 default:
162 baseregs[0] = NVI_PCI_SMBASE1;
163 baseregs[1] = NVI_PCI_SMBASE2;
164 }
165
166 for (i = 0; i < NVIIC_NBUS; i++) {
167 nc = &sc->sc_nc[i];
168
169 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, baseregs[i]);
170 if (NVI_SMBASE(reg) == 0 ||
171 bus_space_map(sc->sc_iot, NVI_SMBASE(reg), NVI_SMBASE_SIZE,
172 0, &nc->nc_ioh)) {
173 printf("%s: unable to map space for bus %d\n",
174 DEVNAME(sc), i);
175 continue;
176 }
177
178 nc->nc_sc = sc;
179 rw_init(&nc->nc_lock, "nviic");
180 nc->nc_i2c.ic_cookie = nc;
181 nc->nc_i2c.ic_acquire_bus = nviic_i2c_acquire_bus;
182 nc->nc_i2c.ic_release_bus = nviic_i2c_release_bus;
183 nc->nc_i2c.ic_exec = nviic_i2c_exec;
184
185 bzero(&iba, sizeof(iba));
186 iba.iba_name = "iic";
187 iba.iba_tag = &nc->nc_i2c;
188 config_found(self, &iba, iicbus_print);
189 }
190 }
191
192 int
193 nviic_i2c_acquire_bus(void *arg, int flags)
194 {
195 struct nviic_controller *nc = arg;
196
197 if (cold || (flags & I2C_F_POLL))
198 return (0);
199
200 return (rw_enter(&nc->nc_lock, RW_WRITE | RW_INTR));
201 }
202
203 void
204 nviic_i2c_release_bus(void *arg, int flags)
205 {
206 struct nviic_controller *nc = arg;
207
208 if (cold || (flags & I2C_F_POLL))
209 return;
210
211 rw_exit(&nc->nc_lock);
212 }
213
214 int
215 nviic_i2c_exec(void *arg, i2c_op_t op, i2c_addr_t addr,
216 const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags)
217 {
218 struct nviic_controller *nc = arg;
219 #ifdef NVIIC_DEBUG
220 struct nviic_softc *sc = nc->nc_sc;
221 #endif
222 u_int8_t protocol;
223 u_int8_t *b;
224 u_int8_t sts;
225 int i;
226
227 DPRINTF("%s: exec op: %d addr: 0x%x cmdlen: %d len: %d flags 0x%x\n",
228 DEVNAME(sc), op, addr, cmdlen, len, flags);
229
230 if (cold)
231 flags |= I2C_F_POLL;
232
233 if (I2C_OP_STOP_P(op) == 0 || cmdlen > 1 || len > 2)
234 return (1);
235
236
237 nviic_write(nc, NVI_SMB_ADDR, addr << 1);
238
239
240 if (cmdlen > 0) {
241 b = (u_int8_t *)cmdbuf;
242 nviic_write(nc, NVI_SMB_CMD, b[0]);
243 }
244
245 b = (u_int8_t *)buf;
246
247
248 if (I2C_OP_WRITE_P(op)) {
249 for (i = 0; i < len; i++)
250 nviic_write(nc, NVI_SMB_DATA(i), b[i]);
251 }
252
253 switch (len) {
254 case 0:
255 protocol = NVI_SMB_PRTCL_BYTE;
256 break;
257 case 1:
258 protocol = NVI_SMB_PRTCL_BYTE_DATA;
259 break;
260 case 2:
261 protocol = NVI_SMB_PRTCL_WORD_DATA;
262 break;
263 }
264
265
266 if (I2C_OP_READ_P(op))
267 protocol |= NVI_SMB_PRTCL_READ;
268
269
270 nviic_write(nc, NVI_SMB_PRTCL, protocol);
271
272 for (i = 1000; i > 0; i--) {
273 delay(100);
274 if (nviic_read(nc, NVI_SMB_PRTCL) == 0)
275 break;
276 }
277 if (i == 0) {
278 DPRINTF("%s: timeout\n", DEVNAME(sc));
279 return (1);
280 }
281
282 sts = nviic_read(nc, NVI_SMB_STS);
283 if (sts & NVI_SMB_STS_STATUS)
284 return (1);
285
286
287 if (I2C_OP_READ_P(op)) {
288 for (i = 0; i < len; i++)
289 b[i] = nviic_read(nc, NVI_SMB_DATA(i));
290 }
291
292 return (0);
293 }
294
295 u_int8_t
296 nviic_read(struct nviic_controller *nc, bus_size_t r)
297 {
298 struct nviic_softc *sc = nc->nc_sc;
299
300 bus_space_barrier(sc->sc_iot, nc->nc_ioh, r, 1,
301 BUS_SPACE_BARRIER_READ);
302 return (bus_space_read_1(sc->sc_iot, nc->nc_ioh, r));
303 }
304
305 void
306 nviic_write(struct nviic_controller *nc, bus_size_t r, u_int8_t v)
307 {
308 struct nviic_softc *sc = nc->nc_sc;
309
310 bus_space_write_1(sc->sc_iot, nc->nc_ioh, r, v);
311 bus_space_barrier(sc->sc_iot, nc->nc_ioh, r, 1,
312 BUS_SPACE_BARRIER_WRITE);
313 }