Lines Matching +full:i2c +full:- +full:r1p10
3 * IP from Cadence (ID T-CS-PE-0007-100, Version R1p10f2)
5 * This file is based on: drivers/i2c/zynq_i2c.c,
6 * with added driver-model support and code cleanup.
8 * SPDX-License-Identifier: GPL-2.0+
17 #include <i2c.h>
24 /* i2c register set */
71 #define CDNS_I2C_TRANSFER_SIZE (CDNS_I2C_TRANSFER_SIZE_MAX - 3)
80 int_status = readl(&cdns_i2c->interrupt_status); in cdns_i2c_debug_status()
82 status = readl(&cdns_i2c->status); in cdns_i2c_debug_status()
111 debug("TS%d ", readl(&cdns_i2c->transfer_size)); in cdns_i2c_debug_status()
136 int_status = readl(&cdns_i2c->interrupt_status); in cdns_i2c_wait()
143 writel(int_status & mask, &cdns_i2c->interrupt_status); in cdns_i2c_wait()
166 return -EINVAL; in cdns_i2c_calc_divs()
168 last_error = -1; in cdns_i2c_calc_divs()
174 div_b--; in cdns_i2c_calc_divs()
181 current_error = ((actual_fscl > fscl) ? (actual_fscl - fscl) : in cdns_i2c_calc_divs()
182 (fscl - actual_fscl)); in cdns_i2c_calc_divs()
209 return -EINVAL; in cdns_i2c_set_bus_speed()
212 ret = cdns_i2c_calc_divs(&speed_p, bus->input_freq, &div_a, &div_b); in cdns_i2c_set_bus_speed()
217 __func__, div_a, div_b, bus->input_freq, speed, speed_p); in cdns_i2c_set_bus_speed()
220 (div_a << CDNS_I2C_CONTROL_DIV_A_SHIFT), &bus->regs->control); in cdns_i2c_set_bus_speed()
222 /* Enable master mode, ack, and 7-bit addressing */ in cdns_i2c_set_bus_speed()
223 setbits_le32(&bus->regs->control, CDNS_I2C_CONTROL_MS | in cdns_i2c_set_bus_speed()
233 struct cdns_i2c_regs *regs = i2c_bus->regs; in cdns_i2c_write_data()
236 setbits_le32(®s->control, CDNS_I2C_CONTROL_CLR_FIFO); in cdns_i2c_write_data()
237 clrbits_le32(®s->control, CDNS_I2C_CONTROL_RW); in cdns_i2c_write_data()
243 setbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD); in cdns_i2c_write_data()
246 writel(0xFF, ®s->interrupt_status); in cdns_i2c_write_data()
248 writel(addr, ®s->address); in cdns_i2c_write_data()
250 while (len--) { in cdns_i2c_write_data()
251 writel(*(cur_data++), ®s->data); in cdns_i2c_write_data()
252 if (readl(®s->transfer_size) == CDNS_I2C_FIFO_DEPTH) { in cdns_i2c_write_data()
255 clrbits_le32(®s->control, in cdns_i2c_write_data()
257 return -ETIMEDOUT; in cdns_i2c_write_data()
263 if (!i2c_bus->hold_flag) in cdns_i2c_write_data()
264 clrbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD); in cdns_i2c_write_data()
268 return -ETIMEDOUT; in cdns_i2c_write_data()
281 struct cdns_i2c_regs *regs = i2c_bus->regs; in cdns_i2c_read_data()
287 return -EINVAL; in cdns_i2c_read_data()
293 setbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD); in cdns_i2c_read_data()
295 setbits_le32(®s->control, CDNS_I2C_CONTROL_CLR_FIFO | in cdns_i2c_read_data()
300 writel(curr_recv_count, ®s->transfer_size); in cdns_i2c_read_data()
302 writel(recv_count, ®s->transfer_size); in cdns_i2c_read_data()
306 writel(addr, ®s->address); in cdns_i2c_read_data()
310 hold_quirk = (i2c_bus->quirks & CDNS_I2C_BROKEN_HOLD_BIT) && updatetx; in cdns_i2c_read_data()
313 while (readl(®s->status) & CDNS_I2C_STATUS_RXDV) { in cdns_i2c_read_data()
315 !i2c_bus->hold_flag) { in cdns_i2c_read_data()
316 clrbits_le32(®s->control, in cdns_i2c_read_data()
319 *(cur_data)++ = readl(®s->data); in cdns_i2c_read_data()
320 recv_count--; in cdns_i2c_read_data()
321 curr_recv_count--; in cdns_i2c_read_data()
329 while (readl(®s->transfer_size) != in cdns_i2c_read_data()
330 (curr_recv_count - CDNS_I2C_FIFO_DEPTH)) in cdns_i2c_read_data()
336 if ((recv_count - CDNS_I2C_FIFO_DEPTH) > in cdns_i2c_read_data()
339 ®s->transfer_size); in cdns_i2c_read_data()
343 writel(recv_count - CDNS_I2C_FIFO_DEPTH, in cdns_i2c_read_data()
344 ®s->transfer_size); in cdns_i2c_read_data()
348 writel(addr, ®s->address); in cdns_i2c_read_data()
351 ®s->transfer_size); in cdns_i2c_read_data()
354 writel(recv_count, ®s->transfer_size); in cdns_i2c_read_data()
362 return -ETIMEDOUT; in cdns_i2c_read_data()
374 hold_quirk = !!(i2c_bus->quirks & CDNS_I2C_BROKEN_HOLD_BIT); in cdns_i2c_xfer()
384 for (count = 0; (count < nmsgs - 1) && hold_quirk; count++) { in cdns_i2c_xfer()
387 return -EOPNOTSUPP; in cdns_i2c_xfer()
391 i2c_bus->hold_flag = 1; in cdns_i2c_xfer()
392 setbits_le32(&i2c_bus->regs->control, CDNS_I2C_CONTROL_HOLD); in cdns_i2c_xfer()
394 i2c_bus->hold_flag = 0; in cdns_i2c_xfer()
398 for (; nmsgs > 0; nmsgs--, msg++) { in cdns_i2c_xfer()
399 debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len); in cdns_i2c_xfer()
400 if (msg->flags & I2C_M_RD) { in cdns_i2c_xfer()
401 ret = cdns_i2c_read_data(i2c_bus, msg->addr, msg->buf, in cdns_i2c_xfer()
402 msg->len); in cdns_i2c_xfer()
404 ret = cdns_i2c_write_data(i2c_bus, msg->addr, msg->buf, in cdns_i2c_xfer()
405 msg->len); in cdns_i2c_xfer()
409 return -EREMOTEIO; in cdns_i2c_xfer()
422 i2c_bus->regs = (struct cdns_i2c_regs *)devfdt_get_addr(dev); in cdns_i2c_ofdata_to_platdata()
423 if (!i2c_bus->regs) in cdns_i2c_ofdata_to_platdata()
424 return -ENOMEM; in cdns_i2c_ofdata_to_platdata()
427 i2c_bus->quirks = pdata->quirks; in cdns_i2c_ofdata_to_platdata()
429 i2c_bus->input_freq = 100000000; /* TODO hardcode input freq for now */ in cdns_i2c_ofdata_to_platdata()
444 { .compatible = "cdns,i2c-r1p10", .data = (ulong)&r1p10_i2c_def },
445 { .compatible = "cdns,i2c-r1p14" },
450 .name = "i2c-cdns",