Lines Matching +full:iic +full:- +full:emev2

1 // SPDX-License-Identifier: GPL-2.0
3 * I2C driver for the Renesas EMEV2 SoC
5 * Copyright (C) 2015 Wolfram Sang <wsa@sang-engineering.com>
7 * Copyright 2010-2015 Renesas Electronics Corporation
32 #define I2C_OFS_IICF0 0x20 /* IIC flag */
77 writeb((readb(priv->base + reg) & ~clear) | set, priv->base + reg); in em_clear_set_bit()
85 reinit_completion(&priv->msg_done); in em_i2c_wait_for_event()
87 time_left = wait_for_completion_timeout(&priv->msg_done, priv->adap.timeout); in em_i2c_wait_for_event()
90 return -ETIMEDOUT; in em_i2c_wait_for_event()
92 status = readb(priv->base + I2C_OFS_IICSE0); in em_i2c_wait_for_event()
93 return status & I2C_BIT_ALD0 ? -EAGAIN : status; in em_i2c_wait_for_event()
111 if (readb(priv->base + I2C_OFS_IICACT0) & I2C_BIT_IICE0) { in em_i2c_reset()
113 writeb(0, priv->base + I2C_OFS_IICACT0); in em_i2c_reset()
116 while (readb(priv->base + I2C_OFS_IICACT0) == 1 && retr) in em_i2c_reset()
117 retr--; in em_i2c_reset()
122 writeb(I2C_BIT_DFC0, priv->base + I2C_OFS_IICCL0); in em_i2c_reset()
125 writeb(I2C_BIT_STCEN | I2C_BIT_IICRSV, priv->base + I2C_OFS_IICF0); in em_i2c_reset()
128 writeb(I2C_BIT_WTIM0, priv->base + I2C_OFS_IICC0); in em_i2c_reset()
131 writeb(I2C_BIT_IICE0, priv->base + I2C_OFS_IICACT0); in em_i2c_reset()
134 while (readb(priv->base + I2C_OFS_IICACT0) == 0 && retr) in em_i2c_reset()
135 retr--; in em_i2c_reset()
143 int count, status, read = !!(msg->flags & I2C_M_RD); in __em_i2c_xfer()
150 writeb(i2c_8bit_addr_from_msg(msg), priv->base + I2C_OFS_IIC0); in __em_i2c_xfer()
176 for (count = 0; count < msg->len; count++) { in __em_i2c_xfer()
178 msg->buf[count] = readb(priv->base + I2C_OFS_IIC0); in __em_i2c_xfer()
189 writeb(msg->buf[count], priv->base + I2C_OFS_IIC0); in __em_i2c_xfer()
206 return status < 0 ? status : -ENXIO; in __em_i2c_xfer()
215 if (readb(priv->base + I2C_OFS_IICF0) & I2C_BIT_IICBSY) in em_i2c_xfer()
216 return -EAGAIN; in em_i2c_xfer()
219 ret = __em_i2c_xfer(adap, &msgs[i], (i == (num - 1))); in em_i2c_xfer()
234 if (!priv->slave) in em_i2c_slave_irq()
237 status = readb(priv->base + I2C_OFS_IICSE0); in em_i2c_slave_irq()
248 i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value); in em_i2c_slave_irq()
270 i2c_slave_event(priv->slave, event, &value); in em_i2c_slave_irq()
271 writeb(value, priv->base + I2C_OFS_IIC0); in em_i2c_slave_irq()
284 i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, in em_i2c_slave_irq()
288 value = readb(priv->base + I2C_OFS_IIC0); in em_i2c_slave_irq()
289 ret = i2c_slave_event(priv->slave, in em_i2c_slave_irq()
307 complete(&priv->msg_done); in em_i2c_irq_handler()
319 struct em_i2c_device *priv = i2c_get_adapdata(slave->adapter); in em_i2c_reg_slave()
321 if (priv->slave) in em_i2c_reg_slave()
322 return -EBUSY; in em_i2c_reg_slave()
324 if (slave->flags & I2C_CLIENT_TEN) in em_i2c_reg_slave()
325 return -EAFNOSUPPORT; in em_i2c_reg_slave()
327 priv->slave = slave; in em_i2c_reg_slave()
330 writeb(slave->addr << 1, priv->base + I2C_OFS_SVA0); in em_i2c_reg_slave()
337 struct em_i2c_device *priv = i2c_get_adapdata(slave->adapter); in em_i2c_unreg_slave()
339 WARN_ON(!priv->slave); in em_i2c_unreg_slave()
341 writeb(0, priv->base + I2C_OFS_SVA0); in em_i2c_unreg_slave()
348 synchronize_irq(priv->irq); in em_i2c_unreg_slave()
349 priv->slave = NULL; in em_i2c_unreg_slave()
366 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in em_i2c_probe()
368 return -ENOMEM; in em_i2c_probe()
370 priv->base = devm_platform_ioremap_resource(pdev, 0); in em_i2c_probe()
371 if (IS_ERR(priv->base)) in em_i2c_probe()
372 return PTR_ERR(priv->base); in em_i2c_probe()
374 strscpy(priv->adap.name, "EMEV2 I2C", sizeof(priv->adap.name)); in em_i2c_probe()
376 priv->sclk = devm_clk_get(&pdev->dev, "sclk"); in em_i2c_probe()
377 if (IS_ERR(priv->sclk)) in em_i2c_probe()
378 return PTR_ERR(priv->sclk); in em_i2c_probe()
380 ret = clk_prepare_enable(priv->sclk); in em_i2c_probe()
384 priv->adap.timeout = msecs_to_jiffies(100); in em_i2c_probe()
385 priv->adap.retries = 5; in em_i2c_probe()
386 priv->adap.dev.parent = &pdev->dev; in em_i2c_probe()
387 priv->adap.algo = &em_i2c_algo; in em_i2c_probe()
388 priv->adap.owner = THIS_MODULE; in em_i2c_probe()
389 priv->adap.dev.of_node = pdev->dev.of_node; in em_i2c_probe()
391 init_completion(&priv->msg_done); in em_i2c_probe()
394 i2c_set_adapdata(&priv->adap, priv); in em_i2c_probe()
396 em_i2c_reset(&priv->adap); in em_i2c_probe()
401 priv->irq = ret; in em_i2c_probe()
402 ret = devm_request_irq(&pdev->dev, priv->irq, em_i2c_irq_handler, 0, in em_i2c_probe()
407 ret = i2c_add_adapter(&priv->adap); in em_i2c_probe()
412 dev_info(&pdev->dev, "Added i2c controller %d, irq %d\n", priv->adap.nr, in em_i2c_probe()
413 priv->irq); in em_i2c_probe()
418 clk_disable_unprepare(priv->sclk); in em_i2c_probe()
426 i2c_del_adapter(&priv->adap); in em_i2c_remove()
427 clk_disable_unprepare(priv->sclk); in em_i2c_remove()
431 { .compatible = "renesas,iic-emev2", },
439 .name = "em-i2c",
445 MODULE_DESCRIPTION("EMEV2 I2C bus driver");
447 MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>");