ismt.c revision 1.1 1 /*-
2 * Copyright (c) 2016 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Masanobu SAITOH.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /*-
31 * Copyright (C) 2014 Intel Corporation
32 * All rights reserved.
33 *
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions
36 * are met:
37 * 1. Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 * 2. Redistributions in binary form must reproduce the above copyright
40 * notice, this list of conditions and the following disclaimer in the
41 * documentation and/or other materials provided with the distribution.
42 * 3. Neither the name of Intel Corporation nor the names of its
43 * contributors may be used to endorse or promote products derived from
44 * this software without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 */
58
59 #include <sys/cdefs.h>
60 #if 0
61 __FBSDID("$FreeBSD: head/sys/dev/ismt/ismt.c 266474 2014-05-20 19:55:06Z jimharris $");
62 #endif
63 __KERNEL_RCSID(0, "$NetBSD: ismt.c,v 1.1 2016/01/05 11:24:43 msaitoh Exp $");
64
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/device.h>
68 #include <sys/errno.h>
69 #include <sys/kernel.h>
70 #include <sys/module.h>
71 #include <sys/mutex.h>
72 #include <sys/proc.h>
73
74 #include <sys/bus.h>
75
76 #include <dev/pci/pcidevs.h>
77 #include <dev/pci/pcireg.h>
78 #include <dev/pci/pcivar.h>
79
80 #include <dev/i2c/i2cvar.h>
81
82 #define ISMT_DESC_ENTRIES 32
83
84 /* Hardware Descriptor Constants - Control Field */
85 #define ISMT_DESC_CWRL 0x01 /* Command/Write Length */
86 #define ISMT_DESC_BLK 0X04 /* Perform Block Transaction */
87 #define ISMT_DESC_FAIR 0x08 /* Set fairness flag upon successful arbit. */
88 #define ISMT_DESC_PEC 0x10 /* Packet Error Code */
89 #define ISMT_DESC_I2C 0x20 /* I2C Enable */
90 #define ISMT_DESC_INT 0x40 /* Interrupt */
91 #define ISMT_DESC_SOE 0x80 /* Stop On Error */
92
93 /* Hardware Descriptor Constants - Status Field */
94 #define ISMT_DESC_SCS 0x01 /* Success */
95 #define ISMT_DESC_DLTO 0x04 /* Data Low Time Out */
96 #define ISMT_DESC_NAK 0x08 /* NAK Received */
97 #define ISMT_DESC_CRC 0x10 /* CRC Error */
98 #define ISMT_DESC_CLTO 0x20 /* Clock Low Time Out */
99 #define ISMT_DESC_COL 0x40 /* Collisions */
100 #define ISMT_DESC_LPR 0x80 /* Large Packet Received */
101
102 /* Macros */
103 #define ISMT_DESC_ADDR_RW(addr, is_read) ((addr << 1) | (is_read))
104
105 /* iSMT General Register address offsets (SMBBAR + <addr>) */
106 #define ISMT_GR_GCTRL 0x000 /* General Control */
107 #define ISMT_GR_SMTICL 0x008 /* SMT Interrupt Cause Location */
108 #define ISMT_GR_ERRINTMSK 0x010 /* Error Interrupt Mask */
109 #define ISMT_GR_ERRAERMSK 0x014 /* Error AER Mask */
110 #define ISMT_GR_ERRSTS 0x018 /* Error Status */
111 #define ISMT_GR_ERRINFO 0x01c /* Error Information */
112
113 /* iSMT Master Registers */
114 #define ISMT_MSTR_MDBA 0x100 /* Master Descriptor Base Address */
115 #define ISMT_MSTR_MCTRL 0x108 /* Master Control */
116 #define ISMT_MSTR_MSTS 0x10c /* Master Status */
117 #define ISMT_MSTR_MDS 0x110 /* Master Descriptor Size */
118 #define ISMT_MSTR_RPOLICY 0x114 /* Retry Policy */
119
120 /* iSMT Miscellaneous Registers */
121 #define ISMT_SPGT 0x300 /* SMBus PHY Global Timing */
122
123 /* General Control Register (GCTRL) bit definitions */
124 #define ISMT_GCTRL_TRST 0x04 /* Target Reset */
125 #define ISMT_GCTRL_KILL 0x08 /* Kill */
126 #define ISMT_GCTRL_SRST 0x40 /* Soft Reset */
127
128 /* Master Control Register (MCTRL) bit definitions */
129 #define ISMT_MCTRL_SS 0x01 /* Start/Stop */
130 #define ISMT_MCTRL_MEIE 0x10 /* Master Error Interrupt Enable */
131 #define ISMT_MCTRL_FMHP 0x00ff0000 /* Firmware Master Head Ptr (FMHP) */
132
133 /* Master Status Register (MSTS) bit definitions */
134 #define ISMT_MSTS_HMTP 0xff0000 /* HW Master Tail Pointer (HMTP) */
135 #define ISMT_MSTS_MIS 0x20 /* Master Interrupt Status (MIS) */
136 #define ISMT_MSTS_MEIS 0x10 /* Master Error Int Status (MEIS) */
137 #define ISMT_MSTS_IP 0x01 /* In Progress */
138
139 /* Master Descriptor Size (MDS) bit definitions */
140 #define ISMT_MDS_MASK 0xff /* Master Descriptor Size mask (MDS) */
141
142 /* SMBus PHY Global Timing Register (SPGT) bit definitions */
143 #define ISMT_SPGT_SPD_MASK 0xc0000000 /* SMBus Speed mask */
144 #define ISMT_SPGT_SPD_80K 0x00 /* 80 kHz */
145 #define ISMT_SPGT_SPD_100K (0x1 << 30) /* 100 kHz */
146 #define ISMT_SPGT_SPD_400K (0x2 << 30) /* 400 kHz */
147 #define ISMT_SPGT_SPD_1M (0x3 << 30) /* 1 MHz */
148
149 /* MSI Control Register (MSICTL) bit definitions */
150 #define ISMT_MSICTL_MSIE 0x01 /* MSI Enable */
151
152 #define ISMT_MAX_BLOCK_SIZE 32 /* per SMBus spec */
153
154 #define ISMT_INTR_TIMEOUT (hz / 50) /* 0.02s */
155 #define ISMT_POLL_DELAY 100 /* 100usec */
156 #define ISMT_POLL_COUNT 200 /* 100usec * 200 = 0.02s */
157
158 //#define ISMT_DEBUG aprint_debug_dev
159 #ifndef ISMT_DEBUG
160 #define ISMT_DEBUG(...)
161 #endif
162
163 /* iSMT Hardware Descriptor */
164 struct ismt_desc {
165 uint8_t tgtaddr_rw; /* target address & r/w bit */
166 uint8_t wr_len_cmd; /* write length in bytes or a command */
167 uint8_t rd_len; /* read length */
168 uint8_t control; /* control bits */
169 uint8_t status; /* status bits */
170 uint8_t retry; /* collision retry and retry count */
171 uint8_t rxbytes; /* received bytes */
172 uint8_t txbytes; /* transmitted bytes */
173 uint32_t dptr_low; /* lower 32 bit of the data pointer */
174 uint32_t dptr_high; /* upper 32 bit of the data pointer */
175 } __packed;
176
177 #define DESC_SIZE (ISMT_DESC_ENTRIES * sizeof(struct ismt_desc))
178
179 #define DMA_BUFFER_SIZE 64
180
181 struct ismt_softc {
182 device_t pcidev;
183 device_t smbdev;
184
185 struct i2c_controller sc_i2c_tag;
186 kmutex_t sc_i2c_mutex;
187
188 pci_chipset_tag_t sc_pc;
189 pcitag_t sc_pcitag;
190 pci_intr_handle_t *sc_pihp;
191 void *sc_ih;
192
193 bus_space_tag_t mmio_tag;
194 bus_space_handle_t mmio_handle;
195 bus_size_t mmio_size;
196
197 uint8_t head;
198
199 struct ismt_desc *desc;
200 bus_dma_tag_t desc_dma_tag;
201 bus_dmamap_t desc_dma_map;
202 bus_dma_segment_t desc_dma_seg;
203 int desc_rseg;
204
205 uint8_t *dma_buffer;
206 bus_dma_tag_t dma_buffer_dma_tag;
207 bus_dmamap_t dma_buffer_dma_map;
208 bus_dma_segment_t dma_buffer_dma_seg;
209 int dma_buffer_rseg;
210
211 uint8_t using_msi;
212 };
213
214 static int ismt_intr(void *);
215 static int ismt_i2c_acquire_bus(void *, int);
216 static void ismt_i2c_release_bus(void *, int);
217 static int ismt_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
218 size_t, void *, size_t, int);
219 static struct ismt_desc *ismt_alloc_desc(struct ismt_softc *);
220 static int ismt_submit(struct ismt_softc *, struct ismt_desc *,
221 i2c_addr_t, uint8_t, int);
222 static int ismt_quick(struct ismt_softc *, i2c_addr_t, i2c_op_t, int);
223 static int ismt_sendb(struct ismt_softc *, i2c_addr_t, i2c_op_t, char,
224 int);
225 static int ismt_recvb(struct ismt_softc *, i2c_addr_t, i2c_op_t, int);
226 static int ismt_writeb(struct ismt_softc *, i2c_addr_t, i2c_op_t, uint8_t,
227 char, int);
228 static int ismt_writew(struct ismt_softc *, i2c_addr_t, i2c_op_t, uint8_t,
229 uint16_t, int);
230 static int ismt_readb(struct ismt_softc *, i2c_addr_t, i2c_op_t, char,
231 int);
232 static int ismt_readw(struct ismt_softc *, i2c_addr_t, i2c_op_t, char,
233 int);
234
235 static int ismt_match(device_t, cfdata_t, void *);
236 static void ismt_attach(device_t, device_t, void *);
237 static int ismt_detach(device_t, int);
238 static int ismt_rescan(device_t, const char *, const int *);
239 static void ismt_config_interrupts(device_t);
240 static void ismt_chdet(device_t, device_t);
241
242 CFATTACH_DECL3_NEW(ismt, sizeof(struct ismt_softc),
243 ismt_match, ismt_attach, ismt_detach, NULL, ismt_rescan, ismt_chdet,
244 DVF_DETACH_SHUTDOWN);
245
246 static int
247 ismt_intr(void *arg)
248 {
249 struct ismt_softc *sc = arg;
250 uint32_t val;
251
252 val = bus_space_read_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MSTS);
253 if ((sc->using_msi == 0)
254 && (val & (ISMT_MSTS_MIS | ISMT_MSTS_MEIS)) == 0)
255 return 0; /* Not for me */
256
257 ISMT_DEBUG(sc->pcidev, "%s MSTS = 0x%08x\n", __func__, val);
258
259 val |= (ISMT_MSTS_MIS | ISMT_MSTS_MEIS);
260 bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MSTS, val);
261
262 if (sc->using_msi)
263 wakeup(sc);
264
265 return 1;
266 }
267
268 static int
269 ismt_i2c_acquire_bus(void *cookie, int flags)
270 {
271 struct ismt_softc *sc = cookie;
272
273 mutex_enter(&sc->sc_i2c_mutex);
274 return 0;
275 }
276
277 static void
278 ismt_i2c_release_bus(void *cookie, int flags)
279 {
280 struct ismt_softc *sc = cookie;
281
282 mutex_exit(&sc->sc_i2c_mutex);
283 }
284
285 static int
286 ismt_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr,
287 const void *cmd, size_t cmdlen, void *buf, size_t buflen, int flags)
288 {
289 struct ismt_softc *sc = cookie;
290 uint8_t *p = buf;
291 int rv;
292
293 ISMT_DEBUG(sc->pcidev, "exec: op %d, addr 0x%02x, cmdlen %zu, "
294 " buflen %zu, flags 0x%02x\n", op, addr, cmdlen, buflen, flags);
295
296 if ((cmdlen == 0) && (buflen == 0))
297 return ismt_quick(sc, addr, op, flags);
298
299 if (I2C_OP_READ_P(op) && (cmdlen == 0) && (buflen == 1)) {
300 rv = ismt_recvb(sc, addr, op, flags);
301 if (rv == -1)
302 return -1;
303 *p = (uint8_t)rv;
304 return 0;
305 }
306
307 if ((I2C_OP_READ_P(op)) && (cmdlen == 1) && (buflen == 1)) {
308 rv = ismt_readb(sc, addr, op, *(const uint8_t*)cmd, flags);
309 if (rv == -1)
310 return -1;
311 *p = (uint8_t)rv;
312 return 0;
313 }
314
315 if ((I2C_OP_READ_P(op)) && (cmdlen == 1) && (buflen == 2)) {
316 rv = ismt_readw(sc, addr, op, *(const uint8_t*)cmd, flags);
317 if (rv == -1)
318 return -1;
319 *(uint16_t *)p = (uint16_t)rv;
320 return 0;
321 }
322
323 if ((I2C_OP_WRITE_P(op)) && (cmdlen == 0) && (buflen == 1))
324 return ismt_sendb(sc, addr, op, *(uint8_t*)buf, flags);
325
326 if ((I2C_OP_WRITE_P(op)) && (cmdlen == 1) && (buflen == 1))
327 return ismt_writeb(sc, addr, op, *(const uint8_t*)cmd,
328 *(uint8_t*)buf, flags);
329
330 if ((I2C_OP_WRITE_P(op)) && (cmdlen == 1) && (buflen == 2))
331 return ismt_writew(sc, addr, op,
332 *(const uint8_t*)cmd, *((uint16_t *)buf), flags);
333
334 return -1;
335 }
336
337 static struct ismt_desc *
338 ismt_alloc_desc(struct ismt_softc *sc)
339 {
340 struct ismt_desc *desc;
341
342 KASSERT(mutex_owned(&sc->sc_i2c_mutex));
343
344 desc = &sc->desc[sc->head++];
345 if (sc->head == ISMT_DESC_ENTRIES)
346 sc->head = 0;
347
348 memset(desc, 0, sizeof(*desc));
349
350 return (desc);
351 }
352
353 static int
354 ismt_submit(struct ismt_softc *sc, struct ismt_desc *desc, i2c_addr_t slave,
355 uint8_t is_read, int flags)
356 {
357 uint32_t err, fmhp, val;
358 int timeout, i;
359
360 if (sc->using_msi == 0)
361 flags |= I2C_F_POLL;
362 desc->control |= ISMT_DESC_FAIR;
363 if ((flags & I2C_F_POLL) == 0)
364 desc->control |= ISMT_DESC_INT;
365
366 desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(slave, is_read);
367 desc->dptr_low = (sc->dma_buffer_dma_map->dm_segs[0].ds_addr
368 & 0xFFFFFFFFLL);
369 desc->dptr_high = (sc->dma_buffer_dma_map->dm_segs[0].ds_addr >> 32);
370
371 bus_dmamap_sync(sc->desc_dma_tag, sc->desc_dma_map,
372 desc - &sc->desc[0], sizeof(struct ismt_desc),
373 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
374
375 fmhp = sc->head << 16;
376 val = bus_space_read_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MCTRL);
377 val &= ~ISMT_MCTRL_FMHP;
378 val |= fmhp;
379 bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MCTRL, val);
380
381 /* set the start bit */
382 val = bus_space_read_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MCTRL);
383 val |= ISMT_MCTRL_SS;
384 bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MCTRL, val);
385
386 i = 0;
387 if ((flags & I2C_F_POLL) == 0) {
388 timeout = ISMT_INTR_TIMEOUT;
389 if (timeout == 0)
390 timeout = 1;
391 err = tsleep(sc, PWAIT, "ismt_wait", timeout);
392 if (err != 0) {
393 ISMT_DEBUG(sc->pcidev, "%s timeout\n", __func__);
394 return -1;
395 }
396 } else {
397 /* Polling */
398 for (i = 0; i < ISMT_POLL_COUNT; i++) {
399 val = bus_space_read_4(sc->mmio_tag, sc->mmio_handle,
400 ISMT_MSTR_MSTS);
401 if ((val & (ISMT_MSTS_MIS | ISMT_MSTS_MEIS)) != 0) {
402 ismt_intr(sc);
403 err = 0;
404 break;
405 }
406 delay(ISMT_POLL_DELAY);
407 }
408 if (i >= ISMT_POLL_COUNT) {
409 ISMT_DEBUG(sc->pcidev, "%s polling timeout. "
410 "MSTS = %08x\n", __func__, val);
411 return -1;
412 }
413 }
414
415 bus_dmamap_sync(sc->desc_dma_tag, sc->desc_dma_map,
416 desc - &sc->desc[0], sizeof(struct ismt_desc),
417 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
418 ISMT_DEBUG(sc->pcidev, "%s status=0x%02x\n", __func__, desc->status);
419
420 if (desc->status & ISMT_DESC_SCS)
421 return 0;
422
423 if (desc->status & ISMT_DESC_NAK)
424 return -1;
425
426 if (desc->status & ISMT_DESC_CRC)
427 return -1;
428
429 if (desc->status & ISMT_DESC_COL)
430 return -1;
431
432 if (desc->status & ISMT_DESC_LPR)
433 return -1;
434
435 if (desc->status & (ISMT_DESC_DLTO | ISMT_DESC_CLTO))
436 return -1;
437
438 return -1;
439 }
440
441 static int
442 ismt_quick(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, int flags)
443 {
444 struct ismt_desc *desc;
445 int is_read;
446
447 ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
448
449 desc = ismt_alloc_desc(sc);
450 is_read = I2C_OP_READ_P(op);
451 return (ismt_submit(sc, desc, slave, is_read, flags));
452 }
453
454 static int
455 ismt_sendb(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, char byte,
456 int flags)
457 {
458 struct ismt_desc *desc;
459
460 ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
461
462 desc = ismt_alloc_desc(sc);
463 desc->control = ISMT_DESC_CWRL;
464 desc->wr_len_cmd = byte;
465
466 return (ismt_submit(sc, desc, slave, 0, flags));
467 }
468
469 static int
470 ismt_recvb(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, int flags)
471 {
472 struct ismt_desc *desc;
473 int err;
474
475 ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
476
477 desc = ismt_alloc_desc(sc);
478 desc->rd_len = 1;
479
480 err = ismt_submit(sc, desc, slave, 1, flags);
481
482 if (err != 0)
483 return (err);
484
485 return sc->dma_buffer[0];
486 }
487
488 static int
489 ismt_writeb(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, uint8_t cmd,
490 char byte, int flags)
491 {
492 struct ismt_desc *desc;
493
494 ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
495
496 desc = ismt_alloc_desc(sc);
497 desc->wr_len_cmd = 2;
498 sc->dma_buffer[0] = cmd;
499 sc->dma_buffer[1] = byte;
500
501 return (ismt_submit(sc, desc, slave, 0, flags));
502 }
503
504 static int
505 ismt_writew(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, uint8_t cmd,
506 uint16_t word, int flags)
507 {
508 struct ismt_desc *desc;
509
510 ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
511
512 desc = ismt_alloc_desc(sc);
513 desc->wr_len_cmd = 3;
514 sc->dma_buffer[0] = cmd;
515 sc->dma_buffer[1] = word & 0xFF;
516 sc->dma_buffer[2] = word >> 8;
517
518 return (ismt_submit(sc, desc, slave, 0, flags));
519 }
520
521 static int
522 ismt_readb(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, char cmd,
523 int flags)
524 {
525 struct ismt_desc *desc;
526 int err;
527
528 ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
529
530 desc = ismt_alloc_desc(sc);
531 desc->control = ISMT_DESC_CWRL;
532 desc->wr_len_cmd = cmd;
533 desc->rd_len = 1;
534
535 err = ismt_submit(sc, desc, slave, 1, flags);
536
537 if (err != 0)
538 return (err);
539
540 return sc->dma_buffer[0];
541 }
542
543 static int
544 ismt_readw(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, char cmd,
545 int flags)
546 {
547 struct ismt_desc *desc;
548 uint16_t word;
549 int err;
550
551 ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
552
553 desc = ismt_alloc_desc(sc);
554 desc->control = ISMT_DESC_CWRL;
555 desc->wr_len_cmd = cmd;
556 desc->rd_len = 2;
557
558 err = ismt_submit(sc, desc, slave, 1, flags);
559
560 if (err != 0)
561 return (err);
562
563 word = sc->dma_buffer[0] | (sc->dma_buffer[1] << 8);
564
565 return word;
566 }
567
568 #if 0
569 static int
570 ismt_pcall(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, char cmd,
571 uint16_t sdata, uint16_t *rdata, int flags)
572 {
573 struct ismt_desc *desc;
574 int err;
575
576 ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
577
578 desc = ismt_alloc_desc(sc);
579 desc->wr_len_cmd = 3;
580 desc->rd_len = 2;
581 sc->dma_buffer[0] = cmd;
582 sc->dma_buffer[1] = sdata & 0xff;
583 sc->dma_buffer[2] = sdata >> 8;
584
585 err = ismt_submit(sc, desc, slave, 0, flags);
586
587 if (err != 0)
588 return (err);
589
590 *rdata = sc->dma_buffer[0] | (sc->dma_buffer[1] << 8);
591
592 return (err);
593 }
594
595 static int
596 ismt_bwrite(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, char cmd,
597 u_char count, char *buf, int flags)
598 {
599 struct ismt_desc *desc;
600
601 ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
602
603 if (count == 0 || count > ISMT_MAX_BLOCK_SIZE)
604 return -1;
605
606 desc = ismt_alloc_desc(sc);
607 desc->control = ISMT_DESC_I2C;
608 desc->wr_len_cmd = count + 1;
609 sc->dma_buffer[0] = cmd;
610 memcpy(&sc->dma_buffer[1], buf, count);
611
612 return (ismt_submit(sc, desc, slave, 0, flags));
613 }
614
615 static int
616 ismt_bread(struct ismt_softc *sc, i2c_addr_t slave, i2c_op_t op, char cmd,
617 u_char *count, char *buf, int flags)
618 {
619 struct ismt_desc *desc;
620 int err;
621
622 ISMT_DEBUG(sc->pcidev, "%s\n", __func__);
623
624 if (*count == 0 || *count > ISMT_MAX_BLOCK_SIZE)
625 return -1;
626
627 desc = ismt_alloc_desc(sc);
628 desc->control = ISMT_DESC_I2C | ISMT_DESC_CWRL;
629 desc->wr_len_cmd = cmd;
630 desc->rd_len = *count;
631
632 err = ismt_submit(sc, desc, slave, 0, flags);
633
634 if (err != 0)
635 return (err);
636
637 memcpy(buf, sc->dma_buffer, desc->rxbytes);
638 *count = desc->rxbytes;
639
640 return (err);
641 }
642 #endif
643
644 static int
645 ismt_detach(device_t self, int flags)
646 {
647 struct ismt_softc *sc;
648 int rv = 0;
649
650 ISMT_DEBUG(self, "%s\n", __func__);
651 sc = device_private(self);
652 if (sc->smbdev != NULL) {
653 rv = config_detach(sc->smbdev, flags);
654 if (rv != 0)
655 return rv;
656 }
657 if (sc->sc_ih != NULL) {
658 pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
659 sc->sc_ih = NULL;
660 }
661 if (sc->sc_pihp != NULL) {
662 pci_intr_release(sc->sc_pc, sc->sc_pihp, 1);
663 sc->sc_pihp = NULL;
664 }
665
666 bus_dmamap_unload(sc->desc_dma_tag, sc->desc_dma_map);
667 bus_dmamap_unload(sc->dma_buffer_dma_tag, sc->dma_buffer_dma_map);
668
669 bus_dmamem_free(sc->desc_dma_tag, &sc->desc_dma_seg, sc->desc_rseg);
670 bus_dmamem_free(sc->dma_buffer_dma_tag, &sc->dma_buffer_dma_seg,
671 sc->dma_buffer_rseg);
672
673 if (sc->mmio_size)
674 bus_space_unmap(sc->mmio_tag, sc->mmio_handle, sc->mmio_size);
675
676 mutex_destroy(&sc->sc_i2c_mutex);
677 return rv;
678 }
679
680 static void
681 ismt_attach(device_t parent, device_t self, void *aux)
682 {
683 struct ismt_softc *sc = device_private(self);
684 struct pci_attach_args *pa = aux;
685 const char *intrstr = NULL;
686 char intrbuf[PCI_INTRSTR_LEN];
687 pcireg_t reg;
688 int val;
689
690 sc->pcidev = self;
691 sc->sc_pc = pa->pa_pc;
692 sc->sc_pcitag = pa->pa_tag;
693
694 /* Enable busmastering */
695 reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
696 reg |= PCI_COMMAND_MASTER_ENABLE;
697 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
698
699 pci_aprint_devinfo(pa, NULL);
700
701 /* Map mem space */
702 if (pci_mapreg_map(pa, PCI_BAR0, PCI_MAPREG_TYPE_MEM, 0,
703 &sc->mmio_tag, &sc->mmio_handle, NULL, &sc->mmio_size)) {
704 aprint_error_dev(self, "can't map mem space\n");
705 goto fail;
706 }
707
708 if (pci_dma64_available(pa)) {
709 sc->desc_dma_tag = pa->pa_dmat64;
710 sc->dma_buffer_dma_tag = pa->pa_dmat64;
711 } else {
712 sc->desc_dma_tag = pa->pa_dmat;
713 sc->dma_buffer_dma_tag = pa->pa_dmat;
714 }
715 bus_dmamem_alloc(sc->desc_dma_tag, DESC_SIZE, PAGE_SIZE, 0,
716 &sc->desc_dma_seg, ISMT_DESC_ENTRIES, &sc->desc_rseg,
717 BUS_DMA_WAITOK);
718 bus_dmamem_alloc(sc->dma_buffer_dma_tag, DMA_BUFFER_SIZE, PAGE_SIZE, 0,
719 &sc->dma_buffer_dma_seg, 1, &sc->dma_buffer_rseg, BUS_DMA_WAITOK);
720
721 bus_dmamem_map(sc->desc_dma_tag, &sc->desc_dma_seg,
722 sc->desc_rseg, DESC_SIZE, (void **)&sc->desc, BUS_DMA_COHERENT);
723 bus_dmamem_map(sc->dma_buffer_dma_tag, &sc->dma_buffer_dma_seg,
724 sc->dma_buffer_rseg, DMA_BUFFER_SIZE, (void **)&sc->dma_buffer,
725 BUS_DMA_COHERENT);
726
727 bus_dmamap_create(sc->desc_dma_tag, DESC_SIZE, 1,
728 DESC_SIZE, 0, 0, &sc->desc_dma_map);
729 bus_dmamap_create(sc->dma_buffer_dma_tag, DMA_BUFFER_SIZE, 1,
730 DMA_BUFFER_SIZE, 0, 0, &sc->dma_buffer_dma_map);
731
732 bus_dmamap_load(sc->desc_dma_tag,
733 sc->desc_dma_map, sc->desc, DESC_SIZE, NULL, 0);
734 bus_dmamap_load(sc->dma_buffer_dma_tag,
735 sc->dma_buffer_dma_map, sc->dma_buffer, DMA_BUFFER_SIZE,
736 NULL, 0);
737
738 bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MDBA,
739 (sc->desc_dma_map->dm_segs[0].ds_addr & 0xFFFFFFFFLL));
740 bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MDBA + 4,
741 (sc->desc_dma_map->dm_segs[0].ds_addr >> 32));
742
743 /* initialize the Master Control Register (MCTRL) */
744 bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MCTRL,
745 ISMT_MCTRL_MEIE);
746
747 /* initialize the Master Status Register (MSTS) */
748 bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MSTS, 0);
749
750 /* initialize the Master Descriptor Size (MDS) */
751 val = bus_space_read_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MDS);
752 val &= ~ISMT_MDS_MASK;
753 val |= (ISMT_DESC_ENTRIES - 1);
754 bus_space_write_4(sc->mmio_tag, sc->mmio_handle, ISMT_MSTR_MDS, val);
755
756 if (pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0)) {
757 aprint_error_dev(self, "couldn't map interrupt\n");
758 return;
759 }
760 intrstr = pci_intr_string(pa->pa_pc, sc->sc_pihp[0], intrbuf,
761 sizeof(intrbuf));
762 sc->sc_ih = pci_intr_establish(pa->pa_pc, sc->sc_pihp[0], IPL_BIO,
763 ismt_intr, sc);
764 if (sc->sc_ih == NULL) {
765 aprint_error_dev(sc->pcidev, "unable to establish %s\n",
766 (pci_intr_type(sc->sc_pihp[0])
767 == PCI_INTR_TYPE_MSI) ? "MSI" : "INTx");
768 /* Polling */
769 }
770
771 if (pci_intr_type(sc->sc_pihp[0]) == PCI_INTR_TYPE_MSI)
772 sc->using_msi = 1;
773
774 aprint_normal_dev(sc->pcidev, "interrupting at %s\n", intrstr);
775
776 sc->smbdev = NULL;
777 mutex_init(&sc->sc_i2c_mutex, MUTEX_DEFAULT, IPL_NONE);
778 if (!pmf_device_register(self, NULL, NULL))
779 aprint_error_dev(self, "couldn't establish power handler\n");
780
781 config_interrupts(self, ismt_config_interrupts);
782 return;
783
784 fail:
785 ismt_detach(sc->pcidev, 0);
786
787 return;
788 }
789
790 static int
791 ismt_match(device_t parent, cfdata_t match, void *aux)
792 {
793 struct pci_attach_args *pa = aux;
794
795 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
796 return 0;
797
798 switch (PCI_PRODUCT(pa->pa_id)) {
799 case PCI_PRODUCT_INTEL_S1200_SMBUS_0:
800 case PCI_PRODUCT_INTEL_S1200_SMBUS_1:
801 case PCI_PRODUCT_INTEL_C2000_SMBUS:
802 break;
803 default:
804 return 0;
805 }
806
807 return 1;
808 }
809
810 static int
811 ismt_rescan(device_t self, const char *ifattr, const int *flags)
812 {
813 struct ismt_softc *sc = device_private(self);
814 struct i2cbus_attach_args iba;
815
816 if (!ifattr_match(ifattr, "i2cbus"))
817 return 0;
818
819 if (sc->smbdev)
820 return 0;
821
822 /* Attach I2C bus */
823 sc->sc_i2c_tag.ic_cookie = sc;
824 sc->sc_i2c_tag.ic_acquire_bus = ismt_i2c_acquire_bus;
825 sc->sc_i2c_tag.ic_release_bus = ismt_i2c_release_bus;
826 sc->sc_i2c_tag.ic_exec = ismt_i2c_exec;
827
828 memset(&iba, 0, sizeof(iba));
829 iba.iba_type = I2C_TYPE_SMBUS;
830 iba.iba_tag = &sc->sc_i2c_tag;
831 sc->smbdev = config_found_ia(self, ifattr, &iba, iicbus_print);
832
833 return 0;
834 }
835
836 static void
837 ismt_config_interrupts(device_t self)
838 {
839 int flags = 0;
840
841 ismt_rescan(self, "i2cbus", &flags);
842 }
843
844 static void
845 ismt_chdet(device_t self, device_t child)
846 {
847 struct ismt_softc *sc = device_private(self);
848
849 if (sc->smbdev == child)
850 sc->smbdev = NULL;
851
852 }
853
854 MODULE(MODULE_CLASS_DRIVER, ismt, "pci");
855
856 #ifdef _MODULE
857 #include "ioconf.c"
858 #endif
859
860 static int
861 ismt_modcmd(modcmd_t cmd, void *opaque)
862 {
863 int error = 0;
864
865 switch (cmd) {
866 case MODULE_CMD_INIT:
867 #ifdef _MODULE
868 error = config_init_component(cfdriver_ioconf_ismt,
869 cfattach_ioconf_ismt, cfdata_ioconf_ismt);
870 #endif
871 return error;
872 case MODULE_CMD_FINI:
873 #ifdef _MODULE
874 error = config_fini_component(cfdriver_ioconf_ismt,
875 cfattach_ioconf_ismt, cfdata_ioconf_ismt);
876 #endif
877 return error;
878 default:
879 return ENOTTY;
880 }
881 }
882