2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2003-2012 Broadcom Corporation
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
15 * the documentation and/or other materials provided with the
18 * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
38 #include <sys/module.h>
39 #include <sys/mutex.h>
43 #include <machine/bus.h>
45 #include <dev/iicbus/iiconf.h>
46 #include <dev/iicbus/iicbus.h>
47 #include <dev/iicbus/iicoc.h>
49 #include <dev/pci/pcireg.h>
50 #include <dev/pci/pcivar.h>
52 #include "iicbus_if.h"
54 static devclass_t iicoc_devclass;
59 static int iicoc_probe(device_t);
60 static int iicoc_attach(device_t);
61 static int iicoc_detach(device_t);
63 static int iicoc_start(device_t dev, u_char slave, int timeout);
64 static int iicoc_stop(device_t dev);
65 static int iicoc_read(device_t dev, char *buf,
66 int len, int *read, int last, int delay);
67 static int iicoc_write(device_t dev, const char *buf,
68 int len, int *sent, int timeout);
69 static int iicoc_repeated_start(device_t dev, u_char slave, int timeout);
72 device_t dev; /* Self */
73 u_int reg_shift; /* Chip specific */
76 struct resource *mem_res; /* Memory resource */
85 iicoc_dev_write(device_t dev, int reg, int value)
87 struct iicoc_softc *sc;
89 sc = device_get_softc(dev);
90 bus_write_1(sc->mem_res, reg<<sc->reg_shift, value);
94 iicoc_dev_read(device_t dev, int reg)
97 struct iicoc_softc *sc;
99 sc = device_get_softc(dev);
100 val = bus_read_1(sc->mem_res, reg<<sc->reg_shift);
105 iicoc_wait_on_status(device_t dev, uint8_t bit)
107 int tries = I2C_TIMEOUT;
111 status = iicoc_dev_read(dev, OC_I2C_STATUS_REG);
112 } while ((status & bit) != 0 && --tries > 0);
114 return (tries == 0 ? -1: 0);
118 iicoc_rd_cmd(device_t dev, uint8_t cmd)
122 iicoc_dev_write(dev, OC_I2C_CMD_REG, cmd);
123 if (iicoc_wait_on_status(dev, OC_STATUS_TIP) < 0) {
124 device_printf(dev, "read: Timeout waiting for TIP clear.\n");
127 data = iicoc_dev_read(dev, OC_I2C_DATA_REG);
132 iicoc_wr_cmd(device_t dev, uint8_t data, uint8_t cmd)
135 iicoc_dev_write(dev, OC_I2C_DATA_REG, data);
136 iicoc_dev_write(dev, OC_I2C_CMD_REG, cmd);
137 if (iicoc_wait_on_status(dev, OC_STATUS_TIP) < 0) {
138 device_printf(dev, "write: Timeout waiting for TIP clear.\n");
145 iicoc_wr_ack_cmd(device_t dev, uint8_t data, uint8_t cmd)
147 if (iicoc_wr_cmd(dev, data, cmd) < 0)
150 if (iicoc_dev_read(dev, OC_I2C_STATUS_REG) & OC_STATUS_NACK) {
151 device_printf(dev, "write: I2C command ACK Error.\n");
158 iicoc_init(device_t dev)
160 struct iicoc_softc *sc;
163 sc = device_get_softc(dev);
164 value = iicoc_dev_read(dev, OC_I2C_CTRL_REG);
165 iicoc_dev_write(dev, OC_I2C_CTRL_REG,
166 value & ~(OC_CONTROL_EN | OC_CONTROL_IEN));
167 value = (sc->clockfreq/(5 * sc->i2cfreq)) - 1;
168 iicoc_dev_write(dev, OC_I2C_PRESCALE_LO_REG, value & 0xff);
169 iicoc_dev_write(dev, OC_I2C_PRESCALE_HI_REG, value >> 8);
170 value = iicoc_dev_read(dev, OC_I2C_CTRL_REG);
171 iicoc_dev_write(dev, OC_I2C_CTRL_REG, value | OC_CONTROL_EN);
173 value = iicoc_dev_read(dev, OC_I2C_CTRL_REG);
174 /* return 0 on success, 1 on error */
175 return ((value & OC_CONTROL_EN) == 0);
179 iicoc_probe(device_t dev)
181 struct iicoc_softc *sc;
183 sc = device_get_softc(dev);
184 if ((pci_get_vendor(dev) == 0x184e) &&
185 (pci_get_device(dev) == 0x1011)) {
186 sc->clockfreq = XLP_I2C_CLKFREQ;
187 sc->i2cfreq = XLP_I2C_FREQ;
189 device_set_desc(dev, "Netlogic XLP I2C Controller");
190 return (BUS_PROBE_DEFAULT);
197 * We add all the devices which we know about.
198 * The generic attach routine will attach them if they are alive.
201 iicoc_attach(device_t dev)
204 struct iicoc_softc *sc;
206 sc = device_get_softc(dev);
207 bus = device_get_unit(dev);
210 mtx_init(&sc->sc_mtx, "iicoc", "iicoc", MTX_DEF);
212 sc->mem_res = bus_alloc_resource_anywhere(dev,
213 SYS_RES_MEMORY, &sc->mem_rid, 0x100, RF_ACTIVE);
215 if (sc->mem_res == NULL) {
216 device_printf(dev, "Could not allocate bus resource.\n");
220 sc->iicbus = device_add_child(dev, "iicbus", -1);
221 if (sc->iicbus == NULL) {
222 device_printf(dev, "Could not allocate iicbus instance.\n");
225 bus_generic_attach(dev);
231 iicoc_detach(device_t dev)
233 bus_generic_detach(dev);
234 device_delete_children(dev);
240 iicoc_start(device_t dev, u_char slave, int timeout)
242 int error = IIC_EBUSERR;
243 struct iicoc_softc *sc;
245 sc = device_get_softc(dev);
246 mtx_lock(&sc->sc_mtx);
247 sc->i2cdev_addr = (slave >> 1);
249 /* Verify the bus is idle */
250 if (iicoc_wait_on_status(dev, OC_STATUS_BUSY) < 0)
253 /* Write Slave Address */
254 if (iicoc_wr_ack_cmd(dev, slave, OC_COMMAND_START)) {
256 "I2C write slave address [0x%x] failed.\n", slave);
261 /* Verify Arbitration is not Lost */
262 if (iicoc_dev_read(dev, OC_I2C_STATUS_REG) & OC_STATUS_AL) {
263 device_printf(dev, "I2C Bus Arbitration Lost, Aborting.\n");
268 mtx_unlock(&sc->sc_mtx);
271 iicoc_dev_write(dev, OC_I2C_CMD_REG, OC_COMMAND_STOP);
272 iicoc_wait_on_status(dev, OC_STATUS_BUSY); /* wait for idle */
273 mtx_unlock(&sc->sc_mtx);
278 iicoc_stop(device_t dev)
281 struct iicoc_softc *sc;
283 sc = device_get_softc(dev);
284 mtx_lock(&sc->sc_mtx);
285 iicoc_dev_write(dev, OC_I2C_CMD_REG, OC_COMMAND_STOP);
286 iicoc_wait_on_status(dev, OC_STATUS_BUSY); /* wait for idle */
287 mtx_unlock(&sc->sc_mtx);
293 iicoc_write(device_t dev, const char *buf, int len,
294 int *sent, int timeout /* us */ )
300 /* Write Slave Offset */
301 if (iicoc_wr_ack_cmd(dev, value, OC_COMMAND_WRITE)) {
302 device_printf(dev, "I2C write slave offset failed.\n");
306 for (i = 1; i < len; i++) {
307 /* Write data byte */
309 if (iicoc_wr_cmd(dev, value, OC_COMMAND_WRITE)) {
310 device_printf(dev, "I2C write data byte %d failed.\n",
319 return (IIC_EBUSERR);
323 iicoc_read(device_t dev, char *buf, int len, int *read, int last,
329 for (i = 0; i < len; i++) {
331 cmd = (i == len - 1) ? OC_COMMAND_RDNACK : OC_COMMAND_READ;
332 data = iicoc_rd_cmd(dev, cmd);
335 "I2C read data byte %d failed.\n", i);
338 buf[i] = (uint8_t)data;
345 return (IIC_EBUSERR);
349 iicoc_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr)
352 struct iicoc_softc *sc;
354 sc = device_get_softc(dev);
355 mtx_lock(&sc->sc_mtx);
356 error = iicoc_init(dev);
357 mtx_unlock(&sc->sc_mtx);
362 iicoc_repeated_start(device_t dev, u_char slave, int timeout)
367 static device_method_t iicoc_methods[] = {
368 /* device interface */
369 DEVMETHOD(device_probe, iicoc_probe),
370 DEVMETHOD(device_attach, iicoc_attach),
371 DEVMETHOD(device_detach, iicoc_detach),
373 /* iicbus interface */
374 DEVMETHOD(iicbus_callback, iicbus_null_callback),
375 DEVMETHOD(iicbus_repeated_start, iicoc_repeated_start),
376 DEVMETHOD(iicbus_start, iicoc_start),
377 DEVMETHOD(iicbus_stop, iicoc_stop),
378 DEVMETHOD(iicbus_reset, iicoc_reset),
379 DEVMETHOD(iicbus_write, iicoc_write),
380 DEVMETHOD(iicbus_read, iicoc_read),
381 DEVMETHOD(iicbus_transfer, iicbus_transfer_gen),
386 static driver_t iicoc_driver = {
389 sizeof(struct iicoc_softc),
392 DRIVER_MODULE(iicoc, pci, iicoc_driver, iicoc_devclass, 0, 0);
393 DRIVER_MODULE(iicbus, iicoc, iicbus_driver, iicbus_devclass, 0, 0);