Lines Matching +full:ctrl +full:- +full:len
1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (c) 2018-2022 Microchip Corporation. All rights reserved.
93 * struct mchp_corei2c_dev - Microchip CoreI2C device private data
131 u8 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_core_disable() local
133 ctrl &= ~CTRL_ENS1; in mchp_corei2c_core_disable()
134 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_core_disable()
139 u8 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_core_enable() local
141 ctrl |= CTRL_ENS1; in mchp_corei2c_core_enable()
142 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_core_enable()
153 u8 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_stop() local
155 ctrl |= CTRL_STO; in mchp_corei2c_stop()
156 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_stop()
162 u8 clkval, ctrl; in mchp_corei2c_set_divisor() local
181 return -EINVAL; in mchp_corei2c_set_divisor()
183 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_set_divisor()
184 ctrl &= ~CLK_MASK; in mchp_corei2c_set_divisor()
185 ctrl |= clkval; in mchp_corei2c_set_divisor()
186 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_set_divisor()
188 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_set_divisor()
189 if ((ctrl & CLK_MASK) != clkval) in mchp_corei2c_set_divisor()
190 return -EIO; in mchp_corei2c_set_divisor()
197 u32 clk_rate = clk_get_rate(idev->i2c_clk); in mchp_corei2c_init()
198 u32 divisor = clk_rate / idev->bus_clk_rate; in mchp_corei2c_init()
212 u8 ctrl; in mchp_corei2c_empty_rx() local
214 if (idev->msg_len > 0) { in mchp_corei2c_empty_rx()
215 *idev->buf++ = readb(idev->base + CORE_I2C_DATA); in mchp_corei2c_empty_rx()
216 idev->msg_len--; in mchp_corei2c_empty_rx()
219 if (idev->msg_len <= 1) { in mchp_corei2c_empty_rx()
220 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_empty_rx()
221 ctrl &= ~CTRL_AA; in mchp_corei2c_empty_rx()
222 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_empty_rx()
228 if (idev->msg_len > 0) in mchp_corei2c_fill_tx()
229 writeb(*idev->buf++, idev->base + CORE_I2C_DATA); in mchp_corei2c_fill_tx()
230 idev->msg_len--; in mchp_corei2c_fill_tx()
238 u8 ctrl; in mchp_corei2c_next_msg() local
240 if (idev->current_num >= idev->total_num) { in mchp_corei2c_next_msg()
241 complete(&idev->msg_complete); in mchp_corei2c_next_msg()
250 if (idev->msg_err) { in mchp_corei2c_next_msg()
251 complete(&idev->msg_complete); in mchp_corei2c_next_msg()
255 this_msg = idev->msg_queue++; in mchp_corei2c_next_msg()
257 if (idev->current_num < (idev->total_num - 1)) { in mchp_corei2c_next_msg()
258 struct i2c_msg *next_msg = idev->msg_queue; in mchp_corei2c_next_msg()
260 idev->restart_needed = next_msg->flags & I2C_M_RD; in mchp_corei2c_next_msg()
262 idev->restart_needed = false; in mchp_corei2c_next_msg()
265 idev->addr = i2c_8bit_addr_from_msg(this_msg); in mchp_corei2c_next_msg()
266 idev->msg_len = this_msg->len; in mchp_corei2c_next_msg()
267 idev->buf = this_msg->buf; in mchp_corei2c_next_msg()
269 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_next_msg()
270 ctrl |= CTRL_STA; in mchp_corei2c_next_msg()
271 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_next_msg()
273 idev->current_num++; in mchp_corei2c_next_msg()
278 u32 status = idev->isr_status; in mchp_corei2c_handle_isr()
279 u8 ctrl; in mchp_corei2c_handle_isr() local
282 if (!idev->buf) in mchp_corei2c_handle_isr()
288 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_handle_isr()
289 ctrl &= ~CTRL_STA; in mchp_corei2c_handle_isr()
290 writeb(idev->addr, idev->base + CORE_I2C_DATA); in mchp_corei2c_handle_isr()
291 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_handle_isr()
294 idev->msg_err = -EAGAIN; in mchp_corei2c_handle_isr()
299 if (idev->msg_len > 0) { in mchp_corei2c_handle_isr()
302 if (idev->restart_needed) in mchp_corei2c_handle_isr()
311 idev->msg_err = -ENXIO; in mchp_corei2c_handle_isr()
315 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_handle_isr()
316 if (idev->msg_len == 1u) { in mchp_corei2c_handle_isr()
317 ctrl &= ~CTRL_AA; in mchp_corei2c_handle_isr()
318 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_handle_isr()
320 ctrl |= CTRL_AA; in mchp_corei2c_handle_isr()
321 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_handle_isr()
323 if (idev->msg_len < 1u) in mchp_corei2c_handle_isr()
331 if (idev->msg_len == 0) in mchp_corei2c_handle_isr()
352 u8 ctrl; in mchp_corei2c_isr() local
354 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_isr()
355 if (ctrl & CTRL_SI) { in mchp_corei2c_isr()
356 idev->isr_status = readb(idev->base + CORE_I2C_STATUS); in mchp_corei2c_isr()
360 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_isr()
361 ctrl &= ~CTRL_SI; in mchp_corei2c_isr()
362 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_isr()
373 u8 ctrl; in mchp_corei2c_xfer() local
381 idev->restart_needed = false; in mchp_corei2c_xfer()
382 idev->msg_queue = msgs; in mchp_corei2c_xfer()
383 idev->total_num = num; in mchp_corei2c_xfer()
384 idev->current_num = 0; in mchp_corei2c_xfer()
390 idev->addr = i2c_8bit_addr_from_msg(this_msg); in mchp_corei2c_xfer()
391 idev->msg_len = this_msg->len; in mchp_corei2c_xfer()
392 idev->buf = this_msg->buf; in mchp_corei2c_xfer()
393 idev->msg_err = 0; in mchp_corei2c_xfer()
395 if (idev->total_num > 1) { in mchp_corei2c_xfer()
398 idev->restart_needed = next_msg->flags & I2C_M_RD; in mchp_corei2c_xfer()
401 idev->current_num++; in mchp_corei2c_xfer()
402 idev->msg_queue++; in mchp_corei2c_xfer()
404 reinit_completion(&idev->msg_complete); in mchp_corei2c_xfer()
409 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_xfer()
410 ctrl |= CTRL_STA; in mchp_corei2c_xfer()
411 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_xfer()
413 time_left = wait_for_completion_timeout(&idev->msg_complete, in mchp_corei2c_xfer()
414 idev->adapter.timeout); in mchp_corei2c_xfer()
416 return -ETIMEDOUT; in mchp_corei2c_xfer()
418 if (idev->msg_err) in mchp_corei2c_xfer()
419 return idev->msg_err; in mchp_corei2c_xfer()
446 msgs[CORE_I2C_SMBUS_MSG_WR].len = size; in mchp_corei2c_smbus_xfer()
462 msgs[CORE_I2C_SMBUS_MSG_WR].len = 1; in mchp_corei2c_smbus_xfer()
472 msgs[CORE_I2C_SMBUS_MSG_WR].buf = &data->byte; in mchp_corei2c_smbus_xfer()
476 msgs[CORE_I2C_SMBUS_MSG_WR].buf[1] = data->byte; in mchp_corei2c_smbus_xfer()
478 msgs[CORE_I2C_SMBUS_MSG_RD].len = size - 1; in mchp_corei2c_smbus_xfer()
479 msgs[CORE_I2C_SMBUS_MSG_RD].buf = &data->byte; in mchp_corei2c_smbus_xfer()
484 msgs[CORE_I2C_SMBUS_MSG_WR].buf[1] = data->word & 0xFF; in mchp_corei2c_smbus_xfer()
485 msgs[CORE_I2C_SMBUS_MSG_WR].buf[2] = (data->word >> 8) & 0xFF; in mchp_corei2c_smbus_xfer()
487 msgs[CORE_I2C_SMBUS_MSG_RD].len = size - 1; in mchp_corei2c_smbus_xfer()
495 data_len = data->block[0]; in mchp_corei2c_smbus_xfer()
496 msgs[CORE_I2C_SMBUS_MSG_WR].len = data_len + 2; in mchp_corei2c_smbus_xfer()
498 msgs[CORE_I2C_SMBUS_MSG_WR].buf[i + 1] = data->block[i]; in mchp_corei2c_smbus_xfer()
500 msgs[CORE_I2C_SMBUS_MSG_RD].len = I2C_SMBUS_BLOCK_MAX + 1; in mchp_corei2c_smbus_xfer()
505 return -EOPNOTSUPP; in mchp_corei2c_smbus_xfer()
508 mchp_corei2c_xfer(&idev->adapter, msgs, num_msgs); in mchp_corei2c_smbus_xfer()
514 data->word = (rx_buf[0] | (rx_buf[1] << 8)); in mchp_corei2c_smbus_xfer()
521 data->block[i] = rx_buf[i]; in mchp_corei2c_smbus_xfer()
540 idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL); in mchp_corei2c_probe()
542 return -ENOMEM; in mchp_corei2c_probe()
544 idev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in mchp_corei2c_probe()
545 if (IS_ERR(idev->base)) in mchp_corei2c_probe()
546 return PTR_ERR(idev->base); in mchp_corei2c_probe()
552 idev->i2c_clk = devm_clk_get(&pdev->dev, NULL); in mchp_corei2c_probe()
553 if (IS_ERR(idev->i2c_clk)) in mchp_corei2c_probe()
554 return dev_err_probe(&pdev->dev, PTR_ERR(idev->i2c_clk), in mchp_corei2c_probe()
557 idev->dev = &pdev->dev; in mchp_corei2c_probe()
558 init_completion(&idev->msg_complete); in mchp_corei2c_probe()
560 ret = device_property_read_u32(idev->dev, "clock-frequency", in mchp_corei2c_probe()
561 &idev->bus_clk_rate); in mchp_corei2c_probe()
562 if (ret || !idev->bus_clk_rate) { in mchp_corei2c_probe()
563 dev_info(&pdev->dev, "default to 100kHz\n"); in mchp_corei2c_probe()
564 idev->bus_clk_rate = 100000; in mchp_corei2c_probe()
567 if (idev->bus_clk_rate > 400000) in mchp_corei2c_probe()
568 return dev_err_probe(&pdev->dev, -EINVAL, in mchp_corei2c_probe()
569 "clock-frequency too high: %d\n", in mchp_corei2c_probe()
570 idev->bus_clk_rate); in mchp_corei2c_probe()
577 ret = devm_request_irq(&pdev->dev, irq, mchp_corei2c_isr, IRQF_SHARED, in mchp_corei2c_probe()
578 pdev->name, idev); in mchp_corei2c_probe()
580 return dev_err_probe(&pdev->dev, ret, in mchp_corei2c_probe()
583 ret = clk_prepare_enable(idev->i2c_clk); in mchp_corei2c_probe()
585 return dev_err_probe(&pdev->dev, ret, in mchp_corei2c_probe()
590 clk_disable_unprepare(idev->i2c_clk); in mchp_corei2c_probe()
591 return dev_err_probe(&pdev->dev, ret, "failed to program clock divider\n"); in mchp_corei2c_probe()
594 i2c_set_adapdata(&idev->adapter, idev); in mchp_corei2c_probe()
595 snprintf(idev->adapter.name, sizeof(idev->adapter.name), in mchp_corei2c_probe()
596 "Microchip I2C hw bus at %08lx", (unsigned long)res->start); in mchp_corei2c_probe()
597 idev->adapter.owner = THIS_MODULE; in mchp_corei2c_probe()
598 idev->adapter.algo = &mchp_corei2c_algo; in mchp_corei2c_probe()
599 idev->adapter.dev.parent = &pdev->dev; in mchp_corei2c_probe()
600 idev->adapter.dev.of_node = pdev->dev.of_node; in mchp_corei2c_probe()
601 idev->adapter.timeout = HZ; in mchp_corei2c_probe()
605 ret = i2c_add_adapter(&idev->adapter); in mchp_corei2c_probe()
607 clk_disable_unprepare(idev->i2c_clk); in mchp_corei2c_probe()
611 dev_info(&pdev->dev, "registered CoreI2C bus driver\n"); in mchp_corei2c_probe()
620 clk_disable_unprepare(idev->i2c_clk); in mchp_corei2c_remove()
621 i2c_del_adapter(&idev->adapter); in mchp_corei2c_remove()
625 { .compatible = "microchip,mpfs-i2c" },
626 { .compatible = "microchip,corei2c-rtl-v7" },
635 .name = "microchip-corei2c",