Lines Matching +full:bcm2835 +full:- +full:firmware
1 // SPDX-License-Identifier: GPL-2.0
3 * BCM2835 master mode driver
8 #include <linux/clk-provider.h>
71 writel(val, i2c_dev->regs + reg); in bcm2835_i2c_writel()
76 return readl(i2c_dev->regs + reg); in bcm2835_i2c_readl()
99 return -EINVAL; in clk_bcm2835_i2c_calc_divider()
111 if (divider == -EINVAL) in clk_bcm2835_i2c_set_rate()
112 return -EINVAL; in clk_bcm2835_i2c_set_rate()
114 bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DIV, divider); in clk_bcm2835_i2c_set_rate()
129 bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DEL, in clk_bcm2835_i2c_set_rate()
147 u32 divider = bcm2835_i2c_readl(div->i2c_dev, BCM2835_I2C_DIV); in clk_bcm2835_i2c_recalc_rate()
179 return ERR_PTR(-ENOMEM); in bcm2835_i2c_register_div()
181 priv->hw.init = &init; in bcm2835_i2c_register_div()
182 priv->i2c_dev = i2c_dev; in bcm2835_i2c_register_div()
184 clk_hw_register_clkdev(&priv->hw, "div", dev_name(dev)); in bcm2835_i2c_register_div()
185 return devm_clk_register(dev, &priv->hw); in bcm2835_i2c_register_div()
192 while (i2c_dev->msg_buf_remaining) { in bcm2835_fill_txfifo()
197 *i2c_dev->msg_buf); in bcm2835_fill_txfifo()
198 i2c_dev->msg_buf++; in bcm2835_fill_txfifo()
199 i2c_dev->msg_buf_remaining--; in bcm2835_fill_txfifo()
207 while (i2c_dev->msg_buf_remaining) { in bcm2835_drain_rxfifo()
211 *i2c_dev->msg_buf = bcm2835_i2c_readl(i2c_dev, in bcm2835_drain_rxfifo()
213 i2c_dev->msg_buf++; in bcm2835_drain_rxfifo()
214 i2c_dev->msg_buf_remaining--; in bcm2835_drain_rxfifo()
220 * The BCM2835 ARM Peripherals datasheet mentions a way to trigger a Sr when it
225 * firmware actually does it using polling and says that it's a workaround for
234 struct i2c_msg *msg = i2c_dev->curr_msg; in bcm2835_i2c_start_transfer()
235 bool last_msg = (i2c_dev->num_msgs == 1); in bcm2835_i2c_start_transfer()
237 if (!i2c_dev->num_msgs) in bcm2835_i2c_start_transfer()
240 i2c_dev->num_msgs--; in bcm2835_i2c_start_transfer()
241 i2c_dev->msg_buf = msg->buf; in bcm2835_i2c_start_transfer()
242 i2c_dev->msg_buf_remaining = msg->len; in bcm2835_i2c_start_transfer()
244 if (msg->flags & I2C_M_RD) in bcm2835_i2c_start_transfer()
252 bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_A, msg->addr); in bcm2835_i2c_start_transfer()
253 bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DLEN, msg->len); in bcm2835_i2c_start_transfer()
259 i2c_dev->curr_msg = NULL; in bcm2835_i2c_finish_transfer()
260 i2c_dev->num_msgs = 0; in bcm2835_i2c_finish_transfer()
262 i2c_dev->msg_buf = NULL; in bcm2835_i2c_finish_transfer()
263 i2c_dev->msg_buf_remaining = 0; in bcm2835_i2c_finish_transfer()
268 * The I2C_C_CLEAR on errors will take some time to resolve -- if you were in
269 * non-idle state and I2C_C_READ, it sets an abort_rx flag and runs through
284 i2c_dev->msg_err = err; in bcm2835_i2c_isr()
289 if (!i2c_dev->curr_msg) { in bcm2835_i2c_isr()
290 dev_err(i2c_dev->dev, "Got unexpected interrupt (from firmware?)\n"); in bcm2835_i2c_isr()
291 } else if (i2c_dev->curr_msg->flags & I2C_M_RD) { in bcm2835_i2c_isr()
296 if ((val & BCM2835_I2C_S_RXD) || i2c_dev->msg_buf_remaining) in bcm2835_i2c_isr()
297 i2c_dev->msg_err = BCM2835_I2C_S_LEN; in bcm2835_i2c_isr()
299 i2c_dev->msg_err = 0; in bcm2835_i2c_isr()
304 if (!i2c_dev->msg_buf_remaining) { in bcm2835_i2c_isr()
305 i2c_dev->msg_err = val | BCM2835_I2C_S_LEN; in bcm2835_i2c_isr()
311 if (i2c_dev->num_msgs && !i2c_dev->msg_buf_remaining) { in bcm2835_i2c_isr()
312 i2c_dev->curr_msg++; in bcm2835_i2c_isr()
320 if (!i2c_dev->msg_buf_remaining) { in bcm2835_i2c_isr()
321 i2c_dev->msg_err = val | BCM2835_I2C_S_LEN; in bcm2835_i2c_isr()
335 complete(&i2c_dev->completion); in bcm2835_i2c_isr()
347 for (i = 0; i < (num - 1); i++) in bcm2835_i2c_xfer()
349 dev_warn_once(i2c_dev->dev, in bcm2835_i2c_xfer()
351 return -EOPNOTSUPP; in bcm2835_i2c_xfer()
354 i2c_dev->curr_msg = msgs; in bcm2835_i2c_xfer()
355 i2c_dev->num_msgs = num; in bcm2835_i2c_xfer()
356 reinit_completion(&i2c_dev->completion); in bcm2835_i2c_xfer()
360 time_left = wait_for_completion_timeout(&i2c_dev->completion, in bcm2835_i2c_xfer()
361 adap->timeout); in bcm2835_i2c_xfer()
368 dev_err(i2c_dev->dev, "i2c transfer timed out\n"); in bcm2835_i2c_xfer()
369 return -ETIMEDOUT; in bcm2835_i2c_xfer()
372 if (!i2c_dev->msg_err) in bcm2835_i2c_xfer()
375 dev_dbg(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err); in bcm2835_i2c_xfer()
377 if (i2c_dev->msg_err & BCM2835_I2C_S_ERR) in bcm2835_i2c_xfer()
378 return -EREMOTEIO; in bcm2835_i2c_xfer()
380 return -EIO; in bcm2835_i2c_xfer()
394 * The BCM2835 was reported to have problems with clock stretching:
395 * https://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html
411 i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); in bcm2835_i2c_probe()
413 return -ENOMEM; in bcm2835_i2c_probe()
415 i2c_dev->dev = &pdev->dev; in bcm2835_i2c_probe()
416 init_completion(&i2c_dev->completion); in bcm2835_i2c_probe()
419 i2c_dev->regs = devm_ioremap_resource(&pdev->dev, mem); in bcm2835_i2c_probe()
420 if (IS_ERR(i2c_dev->regs)) in bcm2835_i2c_probe()
421 return PTR_ERR(i2c_dev->regs); in bcm2835_i2c_probe()
423 mclk = devm_clk_get(&pdev->dev, NULL); in bcm2835_i2c_probe()
425 return dev_err_probe(&pdev->dev, PTR_ERR(mclk), in bcm2835_i2c_probe()
428 i2c_dev->bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev); in bcm2835_i2c_probe()
430 if (IS_ERR(i2c_dev->bus_clk)) { in bcm2835_i2c_probe()
431 dev_err(&pdev->dev, "Could not register clock\n"); in bcm2835_i2c_probe()
432 return PTR_ERR(i2c_dev->bus_clk); in bcm2835_i2c_probe()
435 ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", in bcm2835_i2c_probe()
438 dev_warn(&pdev->dev, in bcm2835_i2c_probe()
439 "Could not read clock-frequency property\n"); in bcm2835_i2c_probe()
443 ret = clk_set_rate_exclusive(i2c_dev->bus_clk, bus_clk_rate); in bcm2835_i2c_probe()
445 dev_err(&pdev->dev, "Could not set clock frequency\n"); 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()
457 dev_err(&pdev->dev, "No IRQ resource\n"); in bcm2835_i2c_probe()
458 return -ENODEV; in bcm2835_i2c_probe()
460 i2c_dev->irq = irq->start; in bcm2835_i2c_probe()
462 ret = request_irq(i2c_dev->irq, bcm2835_i2c_isr, IRQF_SHARED, in bcm2835_i2c_probe()
463 dev_name(&pdev->dev), i2c_dev); in bcm2835_i2c_probe()
465 dev_err(&pdev->dev, "Could not request IRQ\n"); in bcm2835_i2c_probe()
466 return -ENODEV; in bcm2835_i2c_probe()
469 adap = &i2c_dev->adapter; in bcm2835_i2c_probe()
471 adap->owner = THIS_MODULE; in bcm2835_i2c_probe()
472 adap->class = I2C_CLASS_DEPRECATED; in bcm2835_i2c_probe()
473 snprintf(adap->name, sizeof(adap->name), "bcm2835 (%s)", in bcm2835_i2c_probe()
474 of_node_full_name(pdev->dev.of_node)); in bcm2835_i2c_probe()
475 adap->algo = &bcm2835_i2c_algo; in bcm2835_i2c_probe()
476 adap->dev.parent = &pdev->dev; in bcm2835_i2c_probe()
477 adap->dev.of_node = pdev->dev.of_node; in bcm2835_i2c_probe()
478 adap->quirks = of_device_get_match_data(&pdev->dev); in bcm2835_i2c_probe()
484 free_irq(i2c_dev->irq, i2c_dev); in bcm2835_i2c_probe()
493 clk_rate_exclusive_put(i2c_dev->bus_clk); in bcm2835_i2c_remove()
494 clk_disable_unprepare(i2c_dev->bus_clk); in bcm2835_i2c_remove()
496 free_irq(i2c_dev->irq, i2c_dev); in bcm2835_i2c_remove()
497 i2c_del_adapter(&i2c_dev->adapter); in bcm2835_i2c_remove()
503 { .compatible = "brcm,bcm2711-i2c" },
504 { .compatible = "brcm,bcm2835-i2c", .data = &bcm2835_i2c_quirks },
513 .name = "i2c-bcm2835",
520 MODULE_DESCRIPTION("BCM2835 I2C bus adapter");
522 MODULE_ALIAS("platform:i2c-bcm2835");