Lines Matching +full:i2c +full:- +full:0
1 // SPDX-License-Identifier: GPL-2.0-or-later
8 #include "i2c-viai2c-common.h"
24 #define ZXI2C_REG_CLK 0x10
25 #define ZXI2C_CLK_50M BIT(0)
26 #define ZXI2C_REG_REV 0x11
27 #define ZXI2C_REG_HCR 0x12
28 #define ZXI2C_HCR_RST_FIFO GENMASK(1, 0)
29 #define ZXI2C_REG_HTDR 0x13
30 #define ZXI2C_REG_HRDR 0x14
31 #define ZXI2C_REG_HTLR 0x15
32 #define ZXI2C_REG_HRLR 0x16
33 #define ZXI2C_REG_HWCNTR 0x18
34 #define ZXI2C_REG_HRCNTR 0x19
37 #define ZXI2C_GOLD_FSTP_100K 0xF3
38 #define ZXI2C_GOLD_FSTP_400K 0x38
39 #define ZXI2C_GOLD_FSTP_1M 0x13
40 #define ZXI2C_GOLD_FSTP_3400K 0x37
41 #define ZXI2C_HS_CTRL_CODE (0x08 << 8)
52 static int viai2c_fifo_xfer(struct viai2c *i2c) in viai2c_fifo_xfer() argument
56 struct i2c_msg *msg = i2c->msg; in viai2c_fifo_xfer()
57 void __iomem *base = i2c->base; in viai2c_fifo_xfer()
58 bool read = !!(msg->flags & I2C_M_RD); in viai2c_fifo_xfer()
59 struct viai2c_zhaoxin *priv = i2c->pltfm_priv; in viai2c_fifo_xfer()
66 priv->xfer_len = min_t(u16, msg->len - i2c->xfered_len, ZXI2C_FIFO_SIZE); in viai2c_fifo_xfer()
68 iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HRLR); in viai2c_fifo_xfer()
70 iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HTLR); in viai2c_fifo_xfer()
72 for (i = 0; i < priv->xfer_len; i++) in viai2c_fifo_xfer()
73 iowrite8(msg->buf[i2c->xfered_len + i], base + ZXI2C_REG_HTDR); in viai2c_fifo_xfer()
77 if (priv->hrv && msg->len == (i2c->xfered_len + priv->xfer_len)) { in viai2c_fifo_xfer()
83 u16 tcr_val = i2c->tcr; in viai2c_fifo_xfer()
86 tcr_val |= read ? VIAI2C_TCR_READ : 0; in viai2c_fifo_xfer()
87 writew(tcr_val | msg->addr, base + VIAI2C_REG_TCR); in viai2c_fifo_xfer()
89 return 0; in viai2c_fifo_xfer()
92 static int viai2c_fifo_irq_xfer(struct viai2c *i2c) in viai2c_fifo_irq_xfer() argument
96 struct i2c_msg *msg = i2c->msg; in viai2c_fifo_irq_xfer()
97 void __iomem *base = i2c->base; in viai2c_fifo_irq_xfer()
98 bool read = !!(msg->flags & I2C_M_RD); in viai2c_fifo_irq_xfer()
99 struct viai2c_zhaoxin *priv = i2c->pltfm_priv; in viai2c_fifo_irq_xfer()
103 for (i = 0; i < priv->xfer_len; i++) in viai2c_fifo_irq_xfer()
104 msg->buf[i2c->xfered_len + i] = ioread8(base + ZXI2C_REG_HRDR); in viai2c_fifo_irq_xfer()
106 i2c->xfered_len += priv->xfer_len; in viai2c_fifo_irq_xfer()
107 if (i2c->xfered_len == msg->len) in viai2c_fifo_irq_xfer()
115 priv->xfer_len = min_t(u16, msg->len - i2c->xfered_len, ZXI2C_FIFO_SIZE); in viai2c_fifo_irq_xfer()
117 iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HRLR); in viai2c_fifo_irq_xfer()
119 iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HTLR); in viai2c_fifo_irq_xfer()
121 for (i = 0; i < priv->xfer_len; i++) in viai2c_fifo_irq_xfer()
122 iowrite8(msg->buf[i2c->xfered_len + i], base + ZXI2C_REG_HTDR); in viai2c_fifo_irq_xfer()
126 if (priv->hrv && msg->len == (i2c->xfered_len + priv->xfer_len)) { in viai2c_fifo_irq_xfer()
136 return 0; in viai2c_fifo_irq_xfer()
143 struct viai2c *i2c = (struct viai2c *)i2c_get_adapdata(adap); in zxi2c_xfer() local
144 struct viai2c_zhaoxin *priv = i2c->pltfm_priv; in zxi2c_xfer()
145 void __iomem *base = i2c->base; in zxi2c_xfer()
147 ret = viai2c_wait_bus_not_busy(i2c); in zxi2c_xfer()
154 if (num == 1 && msgs->len >= 2 && (priv->hrv || msgs->len <= ZXI2C_FIFO_SIZE)) { in zxi2c_xfer()
162 i2c->msg = msgs; in zxi2c_xfer()
163 i2c->mode = VIAI2C_FIFO_MODE; in zxi2c_xfer()
164 priv->xfer_len = 0; in zxi2c_xfer()
165 i2c->xfered_len = 0; in zxi2c_xfer()
167 viai2c_fifo_xfer(i2c); in zxi2c_xfer()
169 if (!wait_for_completion_timeout(&i2c->complete, VIAI2C_TIMEOUT)) in zxi2c_xfer()
170 return -ETIMEDOUT; in zxi2c_xfer()
172 ret = i2c->ret; in zxi2c_xfer()
182 if (ret == -ETIMEDOUT) in zxi2c_xfer()
186 iowrite8(0, base + VIAI2C_REG_IMR); in zxi2c_xfer()
207 { I2C_MAX_STANDARD_MODE_FREQ, 0, ZXI2C_GOLD_FSTP_100K },
214 static void zxi2c_set_bus_speed(struct viai2c *i2c) in zxi2c_set_bus_speed() argument
216 struct viai2c_zhaoxin *priv = i2c->pltfm_priv; in zxi2c_set_bus_speed()
218 iowrite16(priv->tr, i2c->base + VIAI2C_REG_TR); in zxi2c_set_bus_speed()
219 iowrite8(ZXI2C_CLK_50M, i2c->base + ZXI2C_REG_CLK); in zxi2c_set_bus_speed()
220 iowrite16(priv->mcr, i2c->base + VIAI2C_REG_MCR); in zxi2c_set_bus_speed()
223 static void zxi2c_get_bus_speed(struct viai2c *i2c) in zxi2c_get_bus_speed() argument
228 struct viai2c_zhaoxin *priv = i2c->pltfm_priv; in zxi2c_get_bus_speed()
229 u32 acpi_speed = i2c_acpi_find_bus_speed(i2c->dev); in zxi2c_get_bus_speed()
232 for (i = 0; i < count; i++) in zxi2c_get_bus_speed()
233 if (acpi_speed == zxi2c_speed_params_table[i][0]) in zxi2c_get_bus_speed()
239 fstp = ioread8(i2c->base + VIAI2C_REG_TR); in zxi2c_get_bus_speed()
240 if (abs(fstp - params[2]) > 0x10) { in zxi2c_get_bus_speed()
245 dev_warn(i2c->dev, "FW FSTP[%x] might cause wrong timings, dropped\n", fstp); in zxi2c_get_bus_speed()
246 priv->tr = params[2] | 0xff00; in zxi2c_get_bus_speed()
248 priv->tr = fstp | 0xff00; in zxi2c_get_bus_speed()
251 i2c->tcr = params[1]; in zxi2c_get_bus_speed()
252 priv->mcr = ioread16(i2c->base + VIAI2C_REG_MCR); in zxi2c_get_bus_speed()
253 /* for Hs-mode, use 0x80 as controller code */ in zxi2c_get_bus_speed()
254 if (params[0] == I2C_MAX_HIGH_SPEED_MODE_FREQ) in zxi2c_get_bus_speed()
255 priv->mcr |= ZXI2C_HS_CTRL_CODE; in zxi2c_get_bus_speed()
257 dev_info(i2c->dev, "speed mode is %s\n", i2c_freq_mode_string(params[0])); in zxi2c_get_bus_speed()
262 struct viai2c *i2c = data; in zxi2c_isr() local
265 /* save the status and write-clear it */ in zxi2c_isr()
266 status = readw(i2c->base + VIAI2C_REG_ISR); in zxi2c_isr()
270 writew(status, i2c->base + VIAI2C_REG_ISR); in zxi2c_isr()
272 i2c->ret = 0; in zxi2c_isr()
274 i2c->ret = -EIO; in zxi2c_isr()
276 if (!i2c->ret) { in zxi2c_isr()
277 if (i2c->mode == VIAI2C_BYTE_MODE) in zxi2c_isr()
278 i2c->ret = viai2c_irq_xfer(i2c); in zxi2c_isr()
280 i2c->ret = viai2c_fifo_irq_xfer(i2c); in zxi2c_isr()
284 if (i2c->ret) in zxi2c_isr()
285 complete(&i2c->complete); in zxi2c_isr()
293 struct viai2c *i2c; in zxi2c_probe() local
297 error = viai2c_init(pdev, &i2c, VIAI2C_PLAT_ZHAOXIN); in zxi2c_probe()
301 i2c->irq = platform_get_irq(pdev, 0); in zxi2c_probe()
302 if (i2c->irq < 0) in zxi2c_probe()
303 return i2c->irq; in zxi2c_probe()
305 error = devm_request_irq(&pdev->dev, i2c->irq, zxi2c_isr, in zxi2c_probe()
306 IRQF_SHARED, pdev->name, i2c); in zxi2c_probe()
308 return dev_err_probe(&pdev->dev, error, in zxi2c_probe()
309 "failed to request irq %i\n", i2c->irq); in zxi2c_probe()
311 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in zxi2c_probe()
313 return -ENOMEM; in zxi2c_probe()
314 i2c->pltfm_priv = priv; in zxi2c_probe()
316 zxi2c_get_bus_speed(i2c); in zxi2c_probe()
317 zxi2c_set_bus_speed(i2c); in zxi2c_probe()
319 priv->hrv = ioread8(i2c->base + ZXI2C_REG_REV); in zxi2c_probe()
321 adap = &i2c->adapter; in zxi2c_probe()
322 adap->owner = THIS_MODULE; in zxi2c_probe()
323 adap->algo = &zxi2c_algorithm; in zxi2c_probe()
324 adap->quirks = &zxi2c_quirks; in zxi2c_probe()
325 adap->dev.parent = &pdev->dev; in zxi2c_probe()
326 ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev)); in zxi2c_probe()
327 snprintf(adap->name, sizeof(adap->name), "zhaoxin-%s-%s", in zxi2c_probe()
328 dev_name(pdev->dev.parent), dev_name(i2c->dev)); in zxi2c_probe()
329 i2c_set_adapdata(adap, i2c); in zxi2c_probe()
331 return devm_i2c_add_adapter(&pdev->dev, adap); in zxi2c_probe()
336 struct viai2c *i2c = dev_get_drvdata(dev); in zxi2c_resume() local
338 iowrite8(ZXI2C_CR_MST_RST, i2c->base + VIAI2C_REG_CR); in zxi2c_resume()
339 zxi2c_set_bus_speed(i2c); in zxi2c_resume()
341 return 0; in zxi2c_resume()
349 {"IIC1D17", 0 },