Lines Matching +full:loongson +full:- +full:1 +full:c

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Loongson-2K/Loongson LS7A I2C controller mode driver
5 * Copyright (C) 2013 Loongson Technology Corporation Limited.
6 * Copyright (C) 2014-2017 Lemote, Inc.
7 * Copyright (C) 2018-2022 Loongson Technology Corporation Limited.
10 * Rewritten for mainline by Binbin Zhou <zhoubinbin@loongson.cn>
48 #define LS2X_SR_TIP BIT(1) /* Transmission state */
52 #define LS2X_CTR_EN BIT(7) /* 0: I2c frequency setting 1: Normal */
54 #define LS2X_CTR_MST BIT(5) /* 0: Target mode 1: Controller mode */
79 if (!(readb(priv->base + I2C_LS2X_SR) & LS2X_SR_IF)) in ls2x_i2c_isr()
82 writeb(LS2X_CR_IACK, priv->base + I2C_LS2X_CR); in ls2x_i2c_isr()
83 complete(&priv->cmd_complete); in ls2x_i2c_isr()
96 struct i2c_timings *t = &priv->i2c_t; in ls2x_i2c_adjust_bus_speed()
97 struct device *dev = priv->adapter.dev.parent; in ls2x_i2c_adjust_bus_speed()
102 if (acpi_speed || t->bus_freq_hz) in ls2x_i2c_adjust_bus_speed()
103 t->bus_freq_hz = max(t->bus_freq_hz, acpi_speed); in ls2x_i2c_adjust_bus_speed()
105 t->bus_freq_hz = LS2X_I2C_FREQ_STD; in ls2x_i2c_adjust_bus_speed()
108 writew(LS2X_I2C_PCLK_FREQ / (5 * t->bus_freq_hz) - 1, in ls2x_i2c_adjust_bus_speed()
109 priv->base + I2C_LS2X_PRER); in ls2x_i2c_adjust_bus_speed()
115 writeb(readb(priv->base + I2C_LS2X_CTR) & ~CTR_FREQ_MASK, in ls2x_i2c_init()
116 priv->base + I2C_LS2X_CTR); in ls2x_i2c_init()
121 writeb(readb(priv->base + I2C_LS2X_CTR) | CTR_READY_MASK, in ls2x_i2c_init()
122 priv->base + I2C_LS2X_CTR); in ls2x_i2c_init()
130 writeb(txdata, priv->base + I2C_LS2X_CR); in ls2x_i2c_xfer_byte()
132 time_left = wait_for_completion_timeout(&priv->cmd_complete, in ls2x_i2c_xfer_byte()
133 priv->adapter.timeout); in ls2x_i2c_xfer_byte()
135 return -ETIMEDOUT; in ls2x_i2c_xfer_byte()
137 rxdata = readb(priv->base + I2C_LS2X_SR); in ls2x_i2c_xfer_byte()
154 return -EAGAIN; in ls2x_i2c_send_byte()
157 return -ENXIO; in ls2x_i2c_send_byte()
166 writeb(LS2X_CR_STOP, priv->base + I2C_LS2X_CR); in ls2x_i2c_stop()
167 return readb_poll_timeout(priv->base + I2C_LS2X_SR, value, in ls2x_i2c_stop()
169 jiffies_to_usecs(priv->adapter.timeout)); in ls2x_i2c_stop()
174 reinit_completion(&priv->cmd_complete); in ls2x_i2c_start()
176 writeb(i2c_8bit_addr_from_msg(msgs), priv->base + I2C_LS2X_TXR); in ls2x_i2c_start()
183 u8 rxdata, *buf = msg->buf; in ls2x_i2c_rx()
184 u16 len = msg->len; in ls2x_i2c_rx()
191 while (len--) { in ls2x_i2c_rx()
198 *buf++ = readb(priv->base + I2C_LS2X_RXR); in ls2x_i2c_rx()
207 u8 *buf = msg->buf; in ls2x_i2c_tx()
208 u16 len = msg->len; in ls2x_i2c_tx()
215 while (len--) { in ls2x_i2c_tx()
216 writeb(*buf++, priv->base + I2C_LS2X_TXR); in ls2x_i2c_tx()
231 if (msg->flags & I2C_M_RD) in ls2x_i2c_xfer_one()
238 if (ret == -ETIMEDOUT) in ls2x_i2c_xfer_one()
261 ret = ls2x_i2c_xfer_one(priv, msg, msg == emsg - 1); in ls2x_i2c_xfer()
284 struct device *dev = &pdev->dev; in ls2x_i2c_probe()
288 return -ENOMEM; in ls2x_i2c_probe()
291 priv->base = devm_platform_ioremap_resource(pdev, 0); in ls2x_i2c_probe()
292 if (IS_ERR(priv->base)) in ls2x_i2c_probe()
293 return PTR_ERR(priv->base); in ls2x_i2c_probe()
300 adap = &priv->adapter; in ls2x_i2c_probe()
301 adap->retries = 5; in ls2x_i2c_probe()
302 adap->nr = pdev->id; in ls2x_i2c_probe()
303 adap->dev.parent = dev; in ls2x_i2c_probe()
304 adap->owner = THIS_MODULE; in ls2x_i2c_probe()
305 adap->algo = &ls2x_i2c_algo; in ls2x_i2c_probe()
306 adap->timeout = msecs_to_jiffies(100); in ls2x_i2c_probe()
307 device_set_node(&adap->dev, dev_fwnode(dev)); in ls2x_i2c_probe()
309 strscpy(adap->name, pdev->name, sizeof(adap->name)); in ls2x_i2c_probe()
310 init_completion(&priv->cmd_complete); in ls2x_i2c_probe()
315 ret = devm_request_irq(dev, irq, ls2x_i2c_isr, IRQF_SHARED, "ls2x-i2c", in ls2x_i2c_probe()
328 writeb(readb(priv->base + I2C_LS2X_CTR) & ~LS2X_CTR_IEN, in ls2x_i2c_suspend()
329 priv->base + I2C_LS2X_CTR); in ls2x_i2c_suspend()
344 { .compatible = "loongson,ls2k-i2c" },
345 { .compatible = "loongson,ls7a-i2c" },
351 { "LOON0004" }, /* Loongson LS7A */
359 .name = "ls2x-i2c",
367 MODULE_DESCRIPTION("Loongson LS2X I2C Bus driver");
368 MODULE_AUTHOR("Loongson Technology Corporation Limited");