Lines Matching +full:mpfs +full:- +full:can
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()
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()
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()
156 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_stop()
181 return -EINVAL; in mchp_corei2c_set_divisor()
183 ctrl = readb(idev->base + CORE_I2C_CTRL); 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()
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()
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()
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()
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()
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()
282 if (!idev->buf) in mchp_corei2c_handle_isr()
288 ctrl = readb(idev->base + CORE_I2C_CTRL); 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()
318 writeb(ctrl, idev->base + CORE_I2C_CTRL); 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()
354 ctrl = readb(idev->base + CORE_I2C_CTRL); 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()
362 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_isr()
379 * to a location that it can access the queue information from. in mchp_corei2c_xfer()
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()
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()
473 msgs[CORE_I2C_SMBUS_MSG_WR].buf = &data->byte; in mchp_corei2c_smbus_xfer()
477 msgs[CORE_I2C_SMBUS_MSG_WR].buf[1] = data->byte; in mchp_corei2c_smbus_xfer()
479 msgs[CORE_I2C_SMBUS_MSG_RD].len = size - 1; in mchp_corei2c_smbus_xfer()
480 msgs[CORE_I2C_SMBUS_MSG_RD].buf = &data->byte; in mchp_corei2c_smbus_xfer()
485 msgs[CORE_I2C_SMBUS_MSG_WR].buf[1] = data->word & 0xFF; in mchp_corei2c_smbus_xfer()
486 msgs[CORE_I2C_SMBUS_MSG_WR].buf[2] = (data->word >> 8) & 0xFF; in mchp_corei2c_smbus_xfer()
488 msgs[CORE_I2C_SMBUS_MSG_RD].len = size - 1; in mchp_corei2c_smbus_xfer()
496 data_len = data->block[0]; in mchp_corei2c_smbus_xfer()
499 msgs[CORE_I2C_SMBUS_MSG_WR].buf[i + 1] = data->block[i]; in mchp_corei2c_smbus_xfer()
506 return -EOPNOTSUPP; in mchp_corei2c_smbus_xfer()
509 ret = mchp_corei2c_xfer(&idev->adapter, msgs, num_msgs); in mchp_corei2c_smbus_xfer()
518 data->word = (rx_buf[0] | (rx_buf[1] << 8)); in mchp_corei2c_smbus_xfer()
525 data->block[i] = rx_buf[i]; in mchp_corei2c_smbus_xfer()
544 idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL); in mchp_corei2c_probe()
546 return -ENOMEM; in mchp_corei2c_probe()
548 idev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in mchp_corei2c_probe()
549 if (IS_ERR(idev->base)) in mchp_corei2c_probe()
550 return PTR_ERR(idev->base); in mchp_corei2c_probe()
556 idev->i2c_clk = devm_clk_get(&pdev->dev, NULL); in mchp_corei2c_probe()
557 if (IS_ERR(idev->i2c_clk)) in mchp_corei2c_probe()
558 return dev_err_probe(&pdev->dev, PTR_ERR(idev->i2c_clk), in mchp_corei2c_probe()
561 idev->dev = &pdev->dev; in mchp_corei2c_probe()
562 init_completion(&idev->msg_complete); in mchp_corei2c_probe()
564 ret = device_property_read_u32(idev->dev, "clock-frequency", in mchp_corei2c_probe()
565 &idev->bus_clk_rate); in mchp_corei2c_probe()
566 if (ret || !idev->bus_clk_rate) { in mchp_corei2c_probe()
567 dev_info(&pdev->dev, "default to 100kHz\n"); in mchp_corei2c_probe()
568 idev->bus_clk_rate = 100000; in mchp_corei2c_probe()
571 if (idev->bus_clk_rate > 400000) in mchp_corei2c_probe()
572 return dev_err_probe(&pdev->dev, -EINVAL, in mchp_corei2c_probe()
573 "clock-frequency too high: %d\n", in mchp_corei2c_probe()
574 idev->bus_clk_rate); in mchp_corei2c_probe()
581 ret = devm_request_irq(&pdev->dev, irq, mchp_corei2c_isr, IRQF_SHARED, in mchp_corei2c_probe()
582 pdev->name, idev); in mchp_corei2c_probe()
584 return dev_err_probe(&pdev->dev, ret, in mchp_corei2c_probe()
587 ret = clk_prepare_enable(idev->i2c_clk); in mchp_corei2c_probe()
589 return dev_err_probe(&pdev->dev, ret, in mchp_corei2c_probe()
594 clk_disable_unprepare(idev->i2c_clk); in mchp_corei2c_probe()
595 return dev_err_probe(&pdev->dev, ret, "failed to program clock divider\n"); in mchp_corei2c_probe()
598 i2c_set_adapdata(&idev->adapter, idev); in mchp_corei2c_probe()
599 snprintf(idev->adapter.name, sizeof(idev->adapter.name), in mchp_corei2c_probe()
600 "Microchip I2C hw bus at %08lx", (unsigned long)res->start); in mchp_corei2c_probe()
601 idev->adapter.owner = THIS_MODULE; in mchp_corei2c_probe()
602 idev->adapter.algo = &mchp_corei2c_algo; in mchp_corei2c_probe()
603 idev->adapter.dev.parent = &pdev->dev; in mchp_corei2c_probe()
604 idev->adapter.dev.of_node = pdev->dev.of_node; in mchp_corei2c_probe()
605 idev->adapter.timeout = HZ; in mchp_corei2c_probe()
609 ret = i2c_add_adapter(&idev->adapter); in mchp_corei2c_probe()
611 clk_disable_unprepare(idev->i2c_clk); in mchp_corei2c_probe()
615 dev_info(&pdev->dev, "registered CoreI2C bus driver\n"); in mchp_corei2c_probe()
624 clk_disable_unprepare(idev->i2c_clk); in mchp_corei2c_remove()
625 i2c_del_adapter(&idev->adapter); in mchp_corei2c_remove()
629 { .compatible = "microchip,mpfs-i2c" },
630 { .compatible = "microchip,corei2c-rtl-v7" },
639 .name = "microchip-corei2c",