Lines Matching +full:mode +full:- +full:recovery
1 // SPDX-License-Identifier: GPL-2.0-or-later
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()
158 bool is_read = msg->flags & I2C_M_RD; in uniphier_i2c_xfer_one()
159 bool recovery = false; in uniphier_i2c_xfer_one() local
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()
171 /* This error is fatal. Needs recovery. */ in uniphier_i2c_xfer_one()
173 recovery = true; in uniphier_i2c_xfer_one()
180 /* Failed to issue STOP. The bus needs recovery. */ in uniphier_i2c_xfer_one()
181 recovery = true; in uniphier_i2c_xfer_one()
186 if (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()
201 * in a wrong state. Try bus recovery. 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()
225 bool stop = (msg + 1 == emsg) || (msg->flags & I2C_M_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 dev_err(dev, "invalid clock-frequency %d\n", bus_speed); in uniphier_i2c_probe()
332 return -EINVAL; in uniphier_i2c_probe()
335 priv->clk = devm_clk_get_enabled(dev, NULL); in uniphier_i2c_probe()
336 if (IS_ERR(priv->clk)) { in uniphier_i2c_probe()
338 return PTR_ERR(priv->clk); in uniphier_i2c_probe()
341 clk_rate = clk_get_rate(priv->clk); in uniphier_i2c_probe()
344 return -EINVAL; in uniphier_i2c_probe()
347 priv->clk_cycle = clk_rate / bus_speed; in uniphier_i2c_probe()
348 init_completion(&priv->comp); in uniphier_i2c_probe()
349 priv->adap.owner = THIS_MODULE; in uniphier_i2c_probe()
350 priv->adap.algo = &uniphier_i2c_algo; in uniphier_i2c_probe()
351 priv->adap.dev.parent = dev; in uniphier_i2c_probe()
352 priv->adap.dev.of_node = dev->of_node; in uniphier_i2c_probe()
353 strscpy(priv->adap.name, "UniPhier I2C", sizeof(priv->adap.name)); in uniphier_i2c_probe()
354 priv->adap.bus_recovery_info = &uniphier_i2c_bus_recovery_info; in uniphier_i2c_probe()
355 i2c_set_adapdata(&priv->adap, priv); in uniphier_i2c_probe()
360 ret = devm_request_irq(dev, irq, uniphier_i2c_interrupt, 0, pdev->name, in uniphier_i2c_probe()
367 return i2c_add_adapter(&priv->adap); in uniphier_i2c_probe()
374 i2c_del_adapter(&priv->adap); in uniphier_i2c_remove()
381 clk_disable_unprepare(priv->clk); in uniphier_i2c_suspend()
391 ret = clk_prepare_enable(priv->clk); in uniphier_i2c_resume()
405 { .compatible = "socionext,uniphier-i2c" },
414 .name = "uniphier-i2c",