Lines Matching +full:stop +full:- +full:ack
1 // SPDX-License-Identifier: GPL-2.0-or-later
16 #define UNIPHIER_I2C_DTRM_STO BIT(9) /* stop condition */
17 #define UNIPHIER_I2C_DTRM_NACK BIT(8) /* do not return ACK */
22 #define UNIPHIER_I2C_DREC_STS BIT(12) /* stop condition detected */
23 #define UNIPHIER_I2C_DREC_LRB BIT(11) /* no ACK */
56 complete(&priv->comp); in uniphier_i2c_interrupt()
68 reinit_completion(&priv->comp); in uniphier_i2c_xfer_byte()
71 writel(txdata, priv->membase + UNIPHIER_I2C_DTRM); in uniphier_i2c_xfer_byte()
73 time_left = wait_for_completion_timeout(&priv->comp, adap->timeout); in uniphier_i2c_xfer_byte()
75 return -ETIMEDOUT; in uniphier_i2c_xfer_byte()
77 rxdata = readl(priv->membase + UNIPHIER_I2C_DREC); in uniphier_i2c_xfer_byte()
94 return -EAGAIN; in uniphier_i2c_send_byte()
97 return -ENXIO; in uniphier_i2c_send_byte()
113 while (len--) { in uniphier_i2c_tx()
135 while (len--) { in uniphier_i2c_rx()
156 struct i2c_msg *msg, bool stop) in uniphier_i2c_xfer_one() argument
158 bool is_read = msg->flags & I2C_M_RD; in uniphier_i2c_xfer_one()
163 ret = uniphier_i2c_rx(adap, msg->addr, msg->len, msg->buf); in uniphier_i2c_xfer_one()
165 ret = uniphier_i2c_tx(adap, msg->addr, msg->len, msg->buf); in uniphier_i2c_xfer_one()
167 if (ret == -EAGAIN) /* could not acquire bus. bail out without STOP */ in uniphier_i2c_xfer_one()
170 if (ret == -ETIMEDOUT) { in uniphier_i2c_xfer_one()
172 stop = false; in uniphier_i2c_xfer_one()
176 if (stop) { in uniphier_i2c_xfer_one()
180 /* Failed to issue STOP. The bus needs recovery. */ in uniphier_i2c_xfer_one()
196 if (!(readl(priv->membase + UNIPHIER_I2C_DREC) & in uniphier_i2c_check_bus_busy()
198 if (priv->busy_cnt++ > 3) { in uniphier_i2c_check_bus_busy()
204 priv->busy_cnt = 0; in uniphier_i2c_check_bus_busy()
207 return -EAGAIN; in uniphier_i2c_check_bus_busy()
210 priv->busy_cnt = 0; in uniphier_i2c_check_bus_busy()
224 /* Emit STOP if it is the last message or I2C_M_STOP is set. */ in uniphier_i2c_xfer()
225 bool stop = (msg + 1 == emsg) || (msg->flags & I2C_M_STOP); in uniphier_i2c_xfer() local
227 ret = uniphier_i2c_xfer_one(adap, msg, stop); in uniphier_i2c_xfer()
250 writel(val, priv->membase + UNIPHIER_I2C_BRST); in uniphier_i2c_reset()
257 return !!(readl(priv->membase + UNIPHIER_I2C_BSTS) & in uniphier_i2c_get_scl()
266 priv->membase + UNIPHIER_I2C_BRST); in uniphier_i2c_set_scl()
273 return !!(readl(priv->membase + UNIPHIER_I2C_BSTS) & in uniphier_i2c_get_sda()
292 unsigned int cyc = priv->clk_cycle; in uniphier_i2c_hw_init()
297 * Bit30-16: clock cycles of tLOW. in uniphier_i2c_hw_init()
298 * Standard-mode: tLOW = 4.7 us, tHIGH = 4.0 us in uniphier_i2c_hw_init()
299 * Fast-mode: tLOW = 1.3 us, tHIGH = 0.6 us in uniphier_i2c_hw_init()
302 writel((cyc * 5 / 9 << 16) | cyc, priv->membase + UNIPHIER_I2C_CLK); in uniphier_i2c_hw_init()
309 struct device *dev = &pdev->dev; in uniphier_i2c_probe()
317 return -ENOMEM; in uniphier_i2c_probe()
319 priv->membase = devm_platform_ioremap_resource(pdev, 0); in uniphier_i2c_probe()
320 if (IS_ERR(priv->membase)) in uniphier_i2c_probe()
321 return PTR_ERR(priv->membase); in uniphier_i2c_probe()
327 if (of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed)) in uniphier_i2c_probe()
331 return dev_err_probe(dev, -EINVAL, "invalid clock-frequency %d\n", bus_speed); in uniphier_i2c_probe()
333 priv->clk = devm_clk_get_enabled(dev, NULL); in uniphier_i2c_probe()
334 if (IS_ERR(priv->clk)) in uniphier_i2c_probe()
335 return dev_err_probe(dev, PTR_ERR(priv->clk), "failed to enable clock\n"); in uniphier_i2c_probe()
337 clk_rate = clk_get_rate(priv->clk); in uniphier_i2c_probe()
339 return dev_err_probe(dev, -EINVAL, "input clock rate should not be zero\n"); in uniphier_i2c_probe()
341 priv->clk_cycle = clk_rate / bus_speed; in uniphier_i2c_probe()
342 init_completion(&priv->comp); in uniphier_i2c_probe()
343 priv->adap.owner = THIS_MODULE; in uniphier_i2c_probe()
344 priv->adap.algo = &uniphier_i2c_algo; in uniphier_i2c_probe()
345 priv->adap.dev.parent = dev; in uniphier_i2c_probe()
346 priv->adap.dev.of_node = dev->of_node; in uniphier_i2c_probe()
347 strscpy(priv->adap.name, "UniPhier I2C", sizeof(priv->adap.name)); in uniphier_i2c_probe()
348 priv->adap.bus_recovery_info = &uniphier_i2c_bus_recovery_info; in uniphier_i2c_probe()
349 i2c_set_adapdata(&priv->adap, priv); in uniphier_i2c_probe()
354 ret = devm_request_irq(dev, irq, uniphier_i2c_interrupt, 0, pdev->name, in uniphier_i2c_probe()
359 return i2c_add_adapter(&priv->adap); in uniphier_i2c_probe()
366 i2c_del_adapter(&priv->adap); in uniphier_i2c_remove()
373 clk_disable_unprepare(priv->clk); in uniphier_i2c_suspend()
383 ret = clk_prepare_enable(priv->clk); in uniphier_i2c_resume()
397 { .compatible = "socionext,uniphier-i2c" },
406 .name = "uniphier-i2c",