Lines Matching +full:mclk +full:- +full:div

1 // SPDX-License-Identifier: GPL-2.0
8 #include <linux/clk-provider.h>
27 * 16-bit field for the number of SCL cycles to wait after rising SCL
76 writel(val, i2c_dev->regs + reg); in bcm2835_i2c_writel()
81 return readl(i2c_dev->regs + reg); in bcm2835_i2c_readl()
104 return -EINVAL; in clk_bcm2835_i2c_calc_divider()
112 struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw); in clk_bcm2835_i2c_set_rate() local
116 if (divider == -EINVAL) in clk_bcm2835_i2c_set_rate()
117 return -EINVAL; in clk_bcm2835_i2c_set_rate()
119 bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DIV, divider); in clk_bcm2835_i2c_set_rate()
134 bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DEL, in clk_bcm2835_i2c_set_rate()
151 struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw); in clk_bcm2835_i2c_recalc_rate() local
152 u32 divider = bcm2835_i2c_readl(div->i2c_dev, BCM2835_I2C_DIV); in clk_bcm2835_i2c_recalc_rate()
164 struct clk *mclk, in bcm2835_i2c_register_div() argument
174 mclk_name = __clk_get_name(mclk); in bcm2835_i2c_register_div()
184 return ERR_PTR(-ENOMEM); in bcm2835_i2c_register_div()
186 priv->hw.init = &init; in bcm2835_i2c_register_div()
187 priv->i2c_dev = i2c_dev; in bcm2835_i2c_register_div()
189 clk_hw_register_clkdev(&priv->hw, "div", dev_name(dev)); in bcm2835_i2c_register_div()
190 return devm_clk_register(dev, &priv->hw); in bcm2835_i2c_register_div()
197 while (i2c_dev->msg_buf_remaining) { in bcm2835_fill_txfifo()
202 *i2c_dev->msg_buf); in bcm2835_fill_txfifo()
203 i2c_dev->msg_buf++; in bcm2835_fill_txfifo()
204 i2c_dev->msg_buf_remaining--; in bcm2835_fill_txfifo()
212 while (i2c_dev->msg_buf_remaining) { in bcm2835_drain_rxfifo()
216 *i2c_dev->msg_buf = bcm2835_i2c_readl(i2c_dev, in bcm2835_drain_rxfifo()
218 i2c_dev->msg_buf++; in bcm2835_drain_rxfifo()
219 i2c_dev->msg_buf_remaining--; in bcm2835_drain_rxfifo()
239 struct i2c_msg *msg = i2c_dev->curr_msg; in bcm2835_i2c_start_transfer()
240 bool last_msg = (i2c_dev->num_msgs == 1); in bcm2835_i2c_start_transfer()
242 if (!i2c_dev->num_msgs) in bcm2835_i2c_start_transfer()
245 i2c_dev->num_msgs--; in bcm2835_i2c_start_transfer()
246 i2c_dev->msg_buf = msg->buf; in bcm2835_i2c_start_transfer()
247 i2c_dev->msg_buf_remaining = msg->len; in bcm2835_i2c_start_transfer()
249 if (msg->flags & I2C_M_RD) in bcm2835_i2c_start_transfer()
257 bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_A, msg->addr); in bcm2835_i2c_start_transfer()
258 bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DLEN, msg->len); in bcm2835_i2c_start_transfer()
264 i2c_dev->curr_msg = NULL; in bcm2835_i2c_finish_transfer()
265 i2c_dev->num_msgs = 0; in bcm2835_i2c_finish_transfer()
267 i2c_dev->msg_buf = NULL; in bcm2835_i2c_finish_transfer()
268 i2c_dev->msg_buf_remaining = 0; in bcm2835_i2c_finish_transfer()
273 * The I2C_C_CLEAR on errors will take some time to resolve -- if you were in
274 * non-idle state and I2C_C_READ, it sets an abort_rx flag and runs through
289 i2c_dev->msg_err = err; in bcm2835_i2c_isr()
294 if (!i2c_dev->curr_msg) { in bcm2835_i2c_isr()
295 dev_err(i2c_dev->dev, "Got unexpected interrupt (from firmware?)\n"); in bcm2835_i2c_isr()
296 } else if (i2c_dev->curr_msg->flags & I2C_M_RD) { in bcm2835_i2c_isr()
301 if ((val & BCM2835_I2C_S_RXD) || i2c_dev->msg_buf_remaining) in bcm2835_i2c_isr()
302 i2c_dev->msg_err = BCM2835_I2C_S_LEN; in bcm2835_i2c_isr()
304 i2c_dev->msg_err = 0; in bcm2835_i2c_isr()
309 if (!i2c_dev->msg_buf_remaining) { in bcm2835_i2c_isr()
310 i2c_dev->msg_err = val | BCM2835_I2C_S_LEN; in bcm2835_i2c_isr()
316 if (i2c_dev->num_msgs && !i2c_dev->msg_buf_remaining) { in bcm2835_i2c_isr()
317 i2c_dev->curr_msg++; in bcm2835_i2c_isr()
325 if (!i2c_dev->msg_buf_remaining) { in bcm2835_i2c_isr()
326 i2c_dev->msg_err = val | BCM2835_I2C_S_LEN; in bcm2835_i2c_isr()
340 complete(&i2c_dev->completion); in bcm2835_i2c_isr()
352 for (i = 0; i < (num - 1); i++) in bcm2835_i2c_xfer()
354 dev_warn_once(i2c_dev->dev, in bcm2835_i2c_xfer()
356 return -EOPNOTSUPP; in bcm2835_i2c_xfer()
359 i2c_dev->curr_msg = msgs; in bcm2835_i2c_xfer()
360 i2c_dev->num_msgs = num; in bcm2835_i2c_xfer()
361 reinit_completion(&i2c_dev->completion); in bcm2835_i2c_xfer()
365 time_left = wait_for_completion_timeout(&i2c_dev->completion, in bcm2835_i2c_xfer()
366 adap->timeout); in bcm2835_i2c_xfer()
373 return -ETIMEDOUT; in bcm2835_i2c_xfer()
376 if (!i2c_dev->msg_err) in bcm2835_i2c_xfer()
379 dev_dbg(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err); in bcm2835_i2c_xfer()
381 if (i2c_dev->msg_err & BCM2835_I2C_S_ERR) in bcm2835_i2c_xfer()
382 return -EREMOTEIO; in bcm2835_i2c_xfer()
384 return -EIO; in bcm2835_i2c_xfer()
399 * https://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html
411 struct clk *mclk; in bcm2835_i2c_probe() local
414 i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); in bcm2835_i2c_probe()
416 return -ENOMEM; in bcm2835_i2c_probe()
418 i2c_dev->dev = &pdev->dev; in bcm2835_i2c_probe()
419 init_completion(&i2c_dev->completion); in bcm2835_i2c_probe()
421 i2c_dev->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); in bcm2835_i2c_probe()
422 if (IS_ERR(i2c_dev->regs)) in bcm2835_i2c_probe()
423 return PTR_ERR(i2c_dev->regs); in bcm2835_i2c_probe()
425 mclk = devm_clk_get(&pdev->dev, NULL); in bcm2835_i2c_probe()
426 if (IS_ERR(mclk)) in bcm2835_i2c_probe()
427 return dev_err_probe(&pdev->dev, PTR_ERR(mclk), in bcm2835_i2c_probe()
430 i2c_dev->bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev); in bcm2835_i2c_probe()
432 if (IS_ERR(i2c_dev->bus_clk)) in bcm2835_i2c_probe()
433 return dev_err_probe(&pdev->dev, PTR_ERR(i2c_dev->bus_clk), in bcm2835_i2c_probe()
436 ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", in bcm2835_i2c_probe()
439 dev_warn(&pdev->dev, in bcm2835_i2c_probe()
440 "Could not read clock-frequency property\n"); in bcm2835_i2c_probe()
444 ret = clk_set_rate_exclusive(i2c_dev->bus_clk, bus_clk_rate); in bcm2835_i2c_probe()
446 return dev_err_probe(&pdev->dev, ret, in bcm2835_i2c_probe()
449 ret = clk_prepare_enable(i2c_dev->bus_clk); in bcm2835_i2c_probe()
451 dev_err(&pdev->dev, "Couldn't prepare clock"); in bcm2835_i2c_probe()
455 i2c_dev->irq = platform_get_irq(pdev, 0); in bcm2835_i2c_probe()
456 if (i2c_dev->irq < 0) { in bcm2835_i2c_probe()
457 ret = i2c_dev->irq; in bcm2835_i2c_probe()
461 ret = request_irq(i2c_dev->irq, bcm2835_i2c_isr, IRQF_SHARED, in bcm2835_i2c_probe()
462 dev_name(&pdev->dev), i2c_dev); in bcm2835_i2c_probe()
464 dev_err(&pdev->dev, "Could not request IRQ\n"); in bcm2835_i2c_probe()
468 adap = &i2c_dev->adapter; in bcm2835_i2c_probe()
470 adap->owner = THIS_MODULE; in bcm2835_i2c_probe()
471 adap->class = I2C_CLASS_DEPRECATED; in bcm2835_i2c_probe()
472 snprintf(adap->name, sizeof(adap->name), "bcm2835 (%s)", in bcm2835_i2c_probe()
473 of_node_full_name(pdev->dev.of_node)); in bcm2835_i2c_probe()
474 adap->algo = &bcm2835_i2c_algo; in bcm2835_i2c_probe()
475 adap->dev.parent = &pdev->dev; in bcm2835_i2c_probe()
476 adap->dev.of_node = pdev->dev.of_node; in bcm2835_i2c_probe()
477 adap->quirks = of_device_get_match_data(&pdev->dev); in bcm2835_i2c_probe()
494 free_irq(i2c_dev->irq, i2c_dev); in bcm2835_i2c_probe()
496 clk_disable_unprepare(i2c_dev->bus_clk); in bcm2835_i2c_probe()
498 clk_rate_exclusive_put(i2c_dev->bus_clk); in bcm2835_i2c_probe()
507 clk_rate_exclusive_put(i2c_dev->bus_clk); in bcm2835_i2c_remove()
508 clk_disable_unprepare(i2c_dev->bus_clk); in bcm2835_i2c_remove()
510 free_irq(i2c_dev->irq, i2c_dev); in bcm2835_i2c_remove()
511 i2c_del_adapter(&i2c_dev->adapter); in bcm2835_i2c_remove()
515 { .compatible = "brcm,bcm2711-i2c" },
516 { .compatible = "brcm,bcm2835-i2c", .data = &bcm2835_i2c_quirks },
525 .name = "i2c-bcm2835",
534 MODULE_ALIAS("platform:i2c-bcm2835");