Lines Matching +full:scl +full:- +full:open +full:- +full:drain
1 // SPDX-License-Identifier: GPL-2.0-or-later
92 for (i = 0; i < siic->read_cmd_len; i++) { in i2c_sirfsoc_read_data()
94 data = readl(siic->base + SIRFSOC_I2C_DATA_BUF + i); in i2c_sirfsoc_read_data()
95 siic->buf[siic->finished_len++] = in i2c_sirfsoc_read_data()
106 if (siic->msg_read) { in i2c_sirfsoc_queue_cmd()
107 while (((siic->finished_len + i) < siic->msg_len) in i2c_sirfsoc_queue_cmd()
108 && (siic->cmd_ptr < SIRFSOC_I2C_CMD_BUF_MAX)) { in i2c_sirfsoc_queue_cmd()
110 if (((siic->finished_len + i) == in i2c_sirfsoc_queue_cmd()
111 (siic->msg_len - 1)) && siic->last) in i2c_sirfsoc_queue_cmd()
114 siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++)); in i2c_sirfsoc_queue_cmd()
118 siic->read_cmd_len = i; in i2c_sirfsoc_queue_cmd()
120 while ((siic->cmd_ptr < SIRFSOC_I2C_CMD_BUF_MAX - 1) in i2c_sirfsoc_queue_cmd()
121 && (siic->finished_len < siic->msg_len)) { in i2c_sirfsoc_queue_cmd()
123 if ((siic->finished_len == (siic->msg_len - 1)) in i2c_sirfsoc_queue_cmd()
124 && siic->last) in i2c_sirfsoc_queue_cmd()
127 siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++)); in i2c_sirfsoc_queue_cmd()
128 writel(siic->buf[siic->finished_len++], in i2c_sirfsoc_queue_cmd()
129 siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++)); in i2c_sirfsoc_queue_cmd()
132 siic->cmd_ptr = 0; in i2c_sirfsoc_queue_cmd()
135 writel(SIRFSOC_I2C_START_CMD, siic->base + SIRFSOC_I2C_CMD_START); in i2c_sirfsoc_queue_cmd()
141 u32 i2c_stat = readl(siic->base + SIRFSOC_I2C_STATUS); in i2c_sirfsoc_irq()
145 siic->err_status = SIRFSOC_I2C_ERR_NOACK; in i2c_sirfsoc_irq()
146 writel(SIRFSOC_I2C_STAT_ERR, siic->base + SIRFSOC_I2C_STATUS); in i2c_sirfsoc_irq()
149 dev_dbg(&siic->adapter.dev, "ACK not received\n"); in i2c_sirfsoc_irq()
151 dev_err(&siic->adapter.dev, "I2C error\n"); in i2c_sirfsoc_irq()
155 * we get NOACK while accessing non-existing clients, otherwise in i2c_sirfsoc_irq()
158 writel(readl(siic->base + SIRFSOC_I2C_CTRL) | SIRFSOC_I2C_RESET, in i2c_sirfsoc_irq()
159 siic->base + SIRFSOC_I2C_CTRL); in i2c_sirfsoc_irq()
160 while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET) in i2c_sirfsoc_irq()
163 complete(&siic->done); in i2c_sirfsoc_irq()
166 if (siic->msg_read) in i2c_sirfsoc_irq()
168 if (siic->finished_len == siic->msg_len) in i2c_sirfsoc_irq()
169 complete(&siic->done); in i2c_sirfsoc_irq()
173 writel(SIRFSOC_I2C_STAT_CMD_DONE, siic->base + SIRFSOC_I2C_STATUS); in i2c_sirfsoc_irq()
185 /* no data and last message -> add STOP */ in i2c_sirfsoc_set_address()
186 if (siic->last && (msg->len == 0)) in i2c_sirfsoc_set_address()
189 writel(regval, siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++)); in i2c_sirfsoc_set_address()
194 if (msg->flags & I2C_M_REV_DIR_ADDR) in i2c_sirfsoc_set_address()
197 writel(addr, siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++)); in i2c_sirfsoc_set_address()
202 u32 regval = readl(siic->base + SIRFSOC_I2C_CTRL); in i2c_sirfsoc_xfer_msg()
204 int timeout = msecs_to_jiffies((msg->len + 1) * 50); in i2c_sirfsoc_xfer_msg()
209 siic->base + SIRFSOC_I2C_CTRL); in i2c_sirfsoc_xfer_msg()
212 if (wait_for_completion_timeout(&siic->done, timeout) == 0) { in i2c_sirfsoc_xfer_msg()
213 siic->err_status = SIRFSOC_I2C_ERR_TIMEOUT; in i2c_sirfsoc_xfer_msg()
214 dev_err(&siic->adapter.dev, "Transfer timeout\n"); in i2c_sirfsoc_xfer_msg()
218 siic->base + SIRFSOC_I2C_CTRL); in i2c_sirfsoc_xfer_msg()
219 writel(0, siic->base + SIRFSOC_I2C_CMD_START); in i2c_sirfsoc_xfer_msg()
222 if (siic->err_status == SIRFSOC_I2C_ERR_TIMEOUT) { in i2c_sirfsoc_xfer_msg()
223 writel(readl(siic->base + SIRFSOC_I2C_CTRL) | SIRFSOC_I2C_RESET, in i2c_sirfsoc_xfer_msg()
224 siic->base + SIRFSOC_I2C_CTRL); in i2c_sirfsoc_xfer_msg()
225 while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET) in i2c_sirfsoc_xfer_msg()
228 return siic->err_status ? -EAGAIN : 0; in i2c_sirfsoc_xfer_msg()
239 struct sirfsoc_i2c *siic = adap->algo_data; in i2c_sirfsoc_xfer()
242 clk_enable(siic->clk); in i2c_sirfsoc_xfer()
245 siic->buf = msgs[i].buf; in i2c_sirfsoc_xfer()
246 siic->msg_len = msgs[i].len; in i2c_sirfsoc_xfer()
247 siic->msg_read = !!(msgs[i].flags & I2C_M_RD); in i2c_sirfsoc_xfer()
248 siic->err_status = 0; in i2c_sirfsoc_xfer()
249 siic->cmd_ptr = 0; in i2c_sirfsoc_xfer()
250 siic->finished_len = 0; in i2c_sirfsoc_xfer()
251 siic->last = (i == (num - 1)); in i2c_sirfsoc_xfer()
255 clk_disable(siic->clk); in i2c_sirfsoc_xfer()
260 clk_disable(siic->clk); in i2c_sirfsoc_xfer()
282 clk = clk_get(&pdev->dev, NULL); in i2c_sirfsoc_probe()
285 dev_err(&pdev->dev, "Clock get failed\n"); in i2c_sirfsoc_probe()
291 dev_err(&pdev->dev, "Clock prepare failed\n"); in i2c_sirfsoc_probe()
297 dev_err(&pdev->dev, "Clock enable failed\n"); in i2c_sirfsoc_probe()
303 siic = devm_kzalloc(&pdev->dev, sizeof(*siic), GFP_KERNEL); in i2c_sirfsoc_probe()
305 err = -ENOMEM; in i2c_sirfsoc_probe()
308 adap = &siic->adapter; in i2c_sirfsoc_probe()
309 adap->class = I2C_CLASS_DEPRECATED; in i2c_sirfsoc_probe()
311 siic->base = devm_platform_ioremap_resource(pdev, 0); in i2c_sirfsoc_probe()
312 if (IS_ERR(siic->base)) { in i2c_sirfsoc_probe()
313 err = PTR_ERR(siic->base); in i2c_sirfsoc_probe()
322 err = devm_request_irq(&pdev->dev, irq, i2c_sirfsoc_irq, 0, in i2c_sirfsoc_probe()
323 dev_name(&pdev->dev), siic); in i2c_sirfsoc_probe()
327 adap->algo = &i2c_sirfsoc_algo; in i2c_sirfsoc_probe()
328 adap->algo_data = siic; in i2c_sirfsoc_probe()
329 adap->retries = 3; in i2c_sirfsoc_probe()
331 adap->dev.of_node = pdev->dev.of_node; in i2c_sirfsoc_probe()
332 adap->dev.parent = &pdev->dev; in i2c_sirfsoc_probe()
333 adap->nr = pdev->id; in i2c_sirfsoc_probe()
335 strlcpy(adap->name, "sirfsoc-i2c", sizeof(adap->name)); in i2c_sirfsoc_probe()
338 init_completion(&siic->done); in i2c_sirfsoc_probe()
342 writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL); in i2c_sirfsoc_probe()
343 while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET) in i2c_sirfsoc_probe()
346 siic->base + SIRFSOC_I2C_CTRL); in i2c_sirfsoc_probe()
348 siic->clk = clk; in i2c_sirfsoc_probe()
350 err = of_property_read_u32(pdev->dev.of_node, in i2c_sirfsoc_probe()
351 "clock-frequency", &bitrate); in i2c_sirfsoc_probe()
357 * Since i2c is open drain interface that allows the slave to in i2c_sirfsoc_probe()
358 * stall the transaction by holding the SCL line at '0', the RTL in i2c_sirfsoc_probe()
359 * implementation is waiting for SCL feedback from the pin after in i2c_sirfsoc_probe()
360 * setting it to High-Z ('1'). This wait adds to the high-time in i2c_sirfsoc_probe()
363 * takes for the board pull-up resistor to rise the SCL line. in i2c_sirfsoc_probe()
364 * For slow SCL settings these additions are negligible, in i2c_sirfsoc_probe()
369 * the different ranges of i2c bus clock frequency, to make the SCL in i2c_sirfsoc_probe()
379 writel(regval, siic->base + SIRFSOC_I2C_CLK_CTRL); in i2c_sirfsoc_probe()
381 writel(0xFF, siic->base + SIRFSOC_I2C_SDA_DELAY); in i2c_sirfsoc_probe()
383 writel(regval, siic->base + SIRFSOC_I2C_SDA_DELAY); in i2c_sirfsoc_probe()
391 dev_info(&pdev->dev, " I2C adapter ready to operate\n"); in i2c_sirfsoc_probe()
408 struct sirfsoc_i2c *siic = adapter->algo_data; in i2c_sirfsoc_remove()
410 writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL); in i2c_sirfsoc_remove()
412 clk_unprepare(siic->clk); in i2c_sirfsoc_remove()
413 clk_put(siic->clk); in i2c_sirfsoc_remove()
421 struct sirfsoc_i2c *siic = adapter->algo_data; in i2c_sirfsoc_suspend()
423 clk_enable(siic->clk); in i2c_sirfsoc_suspend()
424 siic->sda_delay = readl(siic->base + SIRFSOC_I2C_SDA_DELAY); in i2c_sirfsoc_suspend()
425 siic->clk_div = readl(siic->base + SIRFSOC_I2C_CLK_CTRL); in i2c_sirfsoc_suspend()
426 clk_disable(siic->clk); in i2c_sirfsoc_suspend()
433 struct sirfsoc_i2c *siic = adapter->algo_data; in i2c_sirfsoc_resume()
435 clk_enable(siic->clk); in i2c_sirfsoc_resume()
436 writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL); in i2c_sirfsoc_resume()
437 while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET) in i2c_sirfsoc_resume()
440 siic->base + SIRFSOC_I2C_CTRL); in i2c_sirfsoc_resume()
441 writel(siic->clk_div, siic->base + SIRFSOC_I2C_CLK_CTRL); in i2c_sirfsoc_resume()
442 writel(siic->sda_delay, siic->base + SIRFSOC_I2C_SDA_DELAY); in i2c_sirfsoc_resume()
443 clk_disable(siic->clk); in i2c_sirfsoc_resume()
454 { .compatible = "sirf,prima2-i2c", },