Lines Matching +full:stop +full:- +full:ack
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Derived from cx18-i2c.c
7 * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates.
11 #include "cobalt-driver.h"
12 #include "cobalt-i2c.h"
15 /* Clock prescaler register lo-byte */
18 /* Clock prescaler register high-byte */
32 /* CTR[7:0] - Control register */
40 /* CR[7:0] - Command register */
45 /* I2C stop condition */
54 /* I2C ack */
57 /* I2C Interrupt ack */
60 /* SR[7:0] - Status register */
65 /* Busy, I2C bus busy (as defined by start / stop bits) */
68 /* Arbitration lost - core lost arbitration */
88 (cobalt->bar1 + COBALT_I2C_0_BASE); in cobalt_i2c_regs()
91 (cobalt->bar1 + COBALT_I2C_1_BASE); in cobalt_i2c_regs()
94 (cobalt->bar1 + COBALT_I2C_2_BASE); in cobalt_i2c_regs()
97 (cobalt->bar1 + COBALT_I2C_3_BASE); in cobalt_i2c_regs()
100 (cobalt->bar1 + COBALT_I2C_HSMA_BASE); in cobalt_i2c_regs()
104 /* Do low-level i2c byte transfer.
105 * Returns -1 in case of an error or 0 otherwise.
108 struct i2c_adapter *adap, bool start, bool stop, in cobalt_tx_bytes() argument
118 iowrite8(data[i], ®s->txr_rxr); in cobalt_tx_bytes()
125 } else if (i == len - 1 && stop) { in cobalt_tx_bytes()
126 /* Write + Stop */ in cobalt_tx_bytes()
135 iowrite8(cmd, ®s->cr_sr); in cobalt_tx_bytes()
139 status = ioread8(®s->cr_sr); in cobalt_tx_bytes()
141 if (time_after(jiffies, start_time + adap->timeout)) in cobalt_tx_bytes()
142 return -ETIMEDOUT; in cobalt_tx_bytes()
144 status = ioread8(®s->cr_sr); in cobalt_tx_bytes()
147 /* Verify ACK */ in cobalt_tx_bytes()
149 /* NO ACK! */ in cobalt_tx_bytes()
150 return -EIO; in cobalt_tx_bytes()
156 return -EIO; in cobalt_tx_bytes()
162 /* Do low-level i2c byte read.
163 * Returns -1 in case of an error or 0 otherwise.
166 struct i2c_adapter *adap, bool start, bool stop, in cobalt_rx_bytes() argument
180 } else if (i == len - 1 && stop) { in cobalt_rx_bytes()
181 /* Read + Stop */ in cobalt_rx_bytes()
189 /* Last byte to read, no ACK */ in cobalt_rx_bytes()
190 if (i == len - 1) in cobalt_rx_bytes()
194 iowrite8(cmd, ®s->cr_sr); in cobalt_rx_bytes()
198 status = ioread8(®s->cr_sr); in cobalt_rx_bytes()
200 if (time_after(jiffies, start_time + adap->timeout)) in cobalt_rx_bytes()
201 return -ETIMEDOUT; in cobalt_rx_bytes()
203 status = ioread8(®s->cr_sr); in cobalt_rx_bytes()
209 return -EIO; in cobalt_rx_bytes()
213 data[i] = ioread8(®s->txr_rxr); in cobalt_rx_bytes()
218 /* Generate stop condition on i2c bus.
219 * The m00018 stop isn't doing the right thing (wrong timing).
220 * So instead send a start condition, 8 zeroes and a stop condition.
233 struct cobalt_i2c_data *data = adap->algo_data; in cobalt_xfer()
234 struct cobalt_i2c_regs __iomem *regs = data->regs; in cobalt_xfer()
241 int stop = (i == num - 1); in cobalt_xfer() local
244 flags = pmsg->flags; in cobalt_xfer()
246 if (!(pmsg->flags & I2C_M_NOSTART)) { in cobalt_xfer()
247 u8 addr = pmsg->addr << 1; in cobalt_xfer()
253 for (j = 0; j < adap->retries; j++) { in cobalt_xfer()
264 if (pmsg->flags & I2C_M_RD) { in cobalt_xfer()
266 ret = cobalt_rx_bytes(regs, adap, false, stop, in cobalt_xfer()
267 pmsg->buf, pmsg->len); in cobalt_xfer()
272 ret = cobalt_tx_bytes(regs, adap, false, stop, in cobalt_xfer()
273 pmsg->buf, pmsg->len); in cobalt_xfer()
291 /* template for i2c-bit-algo */
294 .algo = NULL, /* set by i2c-algo-bit */
304 /* init + register i2c algo-bit adapter */
315 prescale = ((ALT_CPU_FREQ) / (5 * I2C_FREQUENCY)) - 1; in cobalt_i2c_init()
320 struct i2c_adapter *adap = &cobalt->i2c_adap[i]; in cobalt_i2c_init()
323 iowrite8(M00018_CTR_BITMAP_EN_MSK, ®s->cr_sr); in cobalt_i2c_init()
324 iowrite8(0, ®s->ctr); in cobalt_i2c_init()
325 iowrite8(0, ®s->cr_sr); in cobalt_i2c_init()
331 adap->dev.parent = NULL; in cobalt_i2c_init()
334 return -ETIMEDOUT; in cobalt_i2c_init()
336 status = ioread8(®s->cr_sr); in cobalt_i2c_init()
340 iowrite8(0, ®s->ctr); in cobalt_i2c_init()
341 iowrite8(0, ®s->cr_sr); in cobalt_i2c_init()
344 iowrite8(prescale & 0xff, ®s->prerlo); in cobalt_i2c_init()
345 iowrite8((prescale >> 8) & 0xff, ®s->prerhi); in cobalt_i2c_init()
347 iowrite8(M00018_CTR_BITMAP_EN_MSK, ®s->ctr); in cobalt_i2c_init()
349 cobalt->i2c_data[i].cobalt = cobalt; in cobalt_i2c_init()
350 cobalt->i2c_data[i].regs = regs; in cobalt_i2c_init()
352 adap->algo = &cobalt_algo; in cobalt_i2c_init()
353 adap->algo_data = &cobalt->i2c_data[i]; in cobalt_i2c_init()
354 adap->retries = 3; in cobalt_i2c_init()
355 sprintf(adap->name + strlen(adap->name), in cobalt_i2c_init()
356 " #%d-%d", cobalt->instance, i); in cobalt_i2c_init()
357 i2c_set_adapdata(adap, &cobalt->v4l2_dev); in cobalt_i2c_init()
358 adap->dev.parent = &cobalt->pci_dev->dev; in cobalt_i2c_init()
362 adap->dev.parent = NULL; in cobalt_i2c_init()
365 while (i--) in cobalt_i2c_init()
366 i2c_del_adapter(&cobalt->i2c_adap[i]); in cobalt_i2c_init()
369 cobalt_info("registered bus %s\n", adap->name); in cobalt_i2c_init()
381 cobalt_err("unregistered bus %s\n", cobalt->i2c_adap[i].name); in cobalt_i2c_exit()
382 i2c_del_adapter(&cobalt->i2c_adap[i]); in cobalt_i2c_exit()