Lines Matching +full:mpfs +full:- +full:clock

1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (c) 2018-2022 Microchip Corporation. All rights reserved.
91 * struct mchp_corei2c_dev - Microchip CoreI2C device private data
95 * @i2c_clk: clock reference for i2c input clock
100 * @bus_clk_rate: current i2c bus clock rate
121 u8 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_core_disable()
124 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_core_disable()
129 u8 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_core_enable()
132 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_core_enable()
143 u8 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_stop()
146 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_stop()
171 return -EINVAL; in mchp_corei2c_set_divisor()
173 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_set_divisor()
176 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_set_divisor()
178 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_set_divisor()
180 return -EIO; in mchp_corei2c_set_divisor()
187 u32 clk_rate = clk_get_rate(idev->i2c_clk); in mchp_corei2c_init()
188 u32 divisor = clk_rate / idev->bus_clk_rate; in mchp_corei2c_init()
204 if (idev->msg_len > 0) { in mchp_corei2c_empty_rx()
205 *idev->buf++ = readb(idev->base + CORE_I2C_DATA); in mchp_corei2c_empty_rx()
206 idev->msg_len--; in mchp_corei2c_empty_rx()
209 if (idev->msg_len <= 1) { in mchp_corei2c_empty_rx()
210 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_empty_rx()
212 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_empty_rx()
218 if (idev->msg_len > 0) in mchp_corei2c_fill_tx()
219 writeb(*idev->buf++, idev->base + CORE_I2C_DATA); in mchp_corei2c_fill_tx()
220 idev->msg_len--; in mchp_corei2c_fill_tx()
227 u32 status = idev->isr_status; in mchp_corei2c_handle_isr()
231 if (!idev->buf) in mchp_corei2c_handle_isr()
237 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_handle_isr()
239 writeb(idev->addr, idev->base + CORE_I2C_DATA); in mchp_corei2c_handle_isr()
240 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_handle_isr()
241 if (idev->msg_len == 0) in mchp_corei2c_handle_isr()
245 idev->msg_err = -EAGAIN; in mchp_corei2c_handle_isr()
250 if (idev->msg_len > 0) in mchp_corei2c_handle_isr()
258 idev->msg_err = -ENXIO; in mchp_corei2c_handle_isr()
262 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_handle_isr()
263 if (idev->msg_len == 1u) { in mchp_corei2c_handle_isr()
265 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_handle_isr()
268 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_handle_isr()
270 if (idev->msg_len < 1u) in mchp_corei2c_handle_isr()
278 if (idev->msg_len == 0) in mchp_corei2c_handle_isr()
290 complete(&idev->msg_complete); in mchp_corei2c_handle_isr()
301 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_isr()
303 idev->isr_status = readb(idev->base + CORE_I2C_STATUS); in mchp_corei2c_isr()
307 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_isr()
309 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_isr()
320 idev->addr = i2c_8bit_addr_from_msg(msg); in mchp_corei2c_xfer_msg()
321 idev->msg_len = msg->len; in mchp_corei2c_xfer_msg()
322 idev->buf = msg->buf; in mchp_corei2c_xfer_msg()
323 idev->msg_err = 0; in mchp_corei2c_xfer_msg()
325 reinit_completion(&idev->msg_complete); in mchp_corei2c_xfer_msg()
329 ctrl = readb(idev->base + CORE_I2C_CTRL); in mchp_corei2c_xfer_msg()
331 writeb(ctrl, idev->base + CORE_I2C_CTRL); in mchp_corei2c_xfer_msg()
333 time_left = wait_for_completion_timeout(&idev->msg_complete, in mchp_corei2c_xfer_msg()
334 idev->adapter.timeout); in mchp_corei2c_xfer_msg()
336 return -ETIMEDOUT; in mchp_corei2c_xfer_msg()
338 return idev->msg_err; in mchp_corei2c_xfer_msg()
372 idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL); in mchp_corei2c_probe()
374 return -ENOMEM; in mchp_corei2c_probe()
376 idev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in mchp_corei2c_probe()
377 if (IS_ERR(idev->base)) in mchp_corei2c_probe()
378 return PTR_ERR(idev->base); in mchp_corei2c_probe()
384 idev->i2c_clk = devm_clk_get(&pdev->dev, NULL); in mchp_corei2c_probe()
385 if (IS_ERR(idev->i2c_clk)) in mchp_corei2c_probe()
386 return dev_err_probe(&pdev->dev, PTR_ERR(idev->i2c_clk), in mchp_corei2c_probe()
387 "missing clock\n"); in mchp_corei2c_probe()
389 idev->dev = &pdev->dev; in mchp_corei2c_probe()
390 init_completion(&idev->msg_complete); in mchp_corei2c_probe()
392 ret = device_property_read_u32(idev->dev, "clock-frequency", in mchp_corei2c_probe()
393 &idev->bus_clk_rate); in mchp_corei2c_probe()
394 if (ret || !idev->bus_clk_rate) { in mchp_corei2c_probe()
395 dev_info(&pdev->dev, "default to 100kHz\n"); in mchp_corei2c_probe()
396 idev->bus_clk_rate = 100000; in mchp_corei2c_probe()
399 if (idev->bus_clk_rate > 400000) in mchp_corei2c_probe()
400 return dev_err_probe(&pdev->dev, -EINVAL, in mchp_corei2c_probe()
401 "clock-frequency too high: %d\n", in mchp_corei2c_probe()
402 idev->bus_clk_rate); in mchp_corei2c_probe()
409 ret = devm_request_irq(&pdev->dev, irq, mchp_corei2c_isr, IRQF_SHARED, in mchp_corei2c_probe()
410 pdev->name, idev); in mchp_corei2c_probe()
412 return dev_err_probe(&pdev->dev, ret, in mchp_corei2c_probe()
415 ret = clk_prepare_enable(idev->i2c_clk); in mchp_corei2c_probe()
417 return dev_err_probe(&pdev->dev, ret, in mchp_corei2c_probe()
418 "failed to enable clock\n"); in mchp_corei2c_probe()
422 clk_disable_unprepare(idev->i2c_clk); in mchp_corei2c_probe()
423 return dev_err_probe(&pdev->dev, ret, "failed to program clock divider\n"); in mchp_corei2c_probe()
426 i2c_set_adapdata(&idev->adapter, idev); in mchp_corei2c_probe()
427 snprintf(idev->adapter.name, sizeof(idev->adapter.name), in mchp_corei2c_probe()
428 "Microchip I2C hw bus at %08lx", (unsigned long)res->start); in mchp_corei2c_probe()
429 idev->adapter.owner = THIS_MODULE; in mchp_corei2c_probe()
430 idev->adapter.algo = &mchp_corei2c_algo; in mchp_corei2c_probe()
431 idev->adapter.dev.parent = &pdev->dev; in mchp_corei2c_probe()
432 idev->adapter.dev.of_node = pdev->dev.of_node; in mchp_corei2c_probe()
433 idev->adapter.timeout = HZ; in mchp_corei2c_probe()
437 ret = i2c_add_adapter(&idev->adapter); in mchp_corei2c_probe()
439 clk_disable_unprepare(idev->i2c_clk); in mchp_corei2c_probe()
443 dev_info(&pdev->dev, "registered CoreI2C bus driver\n"); in mchp_corei2c_probe()
452 clk_disable_unprepare(idev->i2c_clk); in mchp_corei2c_remove()
453 i2c_del_adapter(&idev->adapter); in mchp_corei2c_remove()
457 { .compatible = "microchip,mpfs-i2c" },
458 { .compatible = "microchip,corei2c-rtl-v7" },
467 .name = "microchip-corei2c",