162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * BCM2835 master mode driver 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <linux/clk.h> 762306a36Sopenharmony_ci#include <linux/clkdev.h> 862306a36Sopenharmony_ci#include <linux/clk-provider.h> 962306a36Sopenharmony_ci#include <linux/completion.h> 1062306a36Sopenharmony_ci#include <linux/err.h> 1162306a36Sopenharmony_ci#include <linux/i2c.h> 1262306a36Sopenharmony_ci#include <linux/interrupt.h> 1362306a36Sopenharmony_ci#include <linux/io.h> 1462306a36Sopenharmony_ci#include <linux/module.h> 1562306a36Sopenharmony_ci#include <linux/of.h> 1662306a36Sopenharmony_ci#include <linux/platform_device.h> 1762306a36Sopenharmony_ci#include <linux/slab.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define BCM2835_I2C_C 0x0 2062306a36Sopenharmony_ci#define BCM2835_I2C_S 0x4 2162306a36Sopenharmony_ci#define BCM2835_I2C_DLEN 0x8 2262306a36Sopenharmony_ci#define BCM2835_I2C_A 0xc 2362306a36Sopenharmony_ci#define BCM2835_I2C_FIFO 0x10 2462306a36Sopenharmony_ci#define BCM2835_I2C_DIV 0x14 2562306a36Sopenharmony_ci#define BCM2835_I2C_DEL 0x18 2662306a36Sopenharmony_ci/* 2762306a36Sopenharmony_ci * 16-bit field for the number of SCL cycles to wait after rising SCL 2862306a36Sopenharmony_ci * before deciding the slave is not responding. 0 disables the 2962306a36Sopenharmony_ci * timeout detection. 3062306a36Sopenharmony_ci */ 3162306a36Sopenharmony_ci#define BCM2835_I2C_CLKT 0x1c 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define BCM2835_I2C_C_READ BIT(0) 3462306a36Sopenharmony_ci#define BCM2835_I2C_C_CLEAR BIT(4) /* bits 4 and 5 both clear */ 3562306a36Sopenharmony_ci#define BCM2835_I2C_C_ST BIT(7) 3662306a36Sopenharmony_ci#define BCM2835_I2C_C_INTD BIT(8) 3762306a36Sopenharmony_ci#define BCM2835_I2C_C_INTT BIT(9) 3862306a36Sopenharmony_ci#define BCM2835_I2C_C_INTR BIT(10) 3962306a36Sopenharmony_ci#define BCM2835_I2C_C_I2CEN BIT(15) 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci#define BCM2835_I2C_S_TA BIT(0) 4262306a36Sopenharmony_ci#define BCM2835_I2C_S_DONE BIT(1) 4362306a36Sopenharmony_ci#define BCM2835_I2C_S_TXW BIT(2) 4462306a36Sopenharmony_ci#define BCM2835_I2C_S_RXR BIT(3) 4562306a36Sopenharmony_ci#define BCM2835_I2C_S_TXD BIT(4) 4662306a36Sopenharmony_ci#define BCM2835_I2C_S_RXD BIT(5) 4762306a36Sopenharmony_ci#define BCM2835_I2C_S_TXE BIT(6) 4862306a36Sopenharmony_ci#define BCM2835_I2C_S_RXF BIT(7) 4962306a36Sopenharmony_ci#define BCM2835_I2C_S_ERR BIT(8) 5062306a36Sopenharmony_ci#define BCM2835_I2C_S_CLKT BIT(9) 5162306a36Sopenharmony_ci#define BCM2835_I2C_S_LEN BIT(10) /* Fake bit for SW error reporting */ 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#define BCM2835_I2C_FEDL_SHIFT 16 5462306a36Sopenharmony_ci#define BCM2835_I2C_REDL_SHIFT 0 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#define BCM2835_I2C_CDIV_MIN 0x0002 5762306a36Sopenharmony_ci#define BCM2835_I2C_CDIV_MAX 0xFFFE 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistruct bcm2835_i2c_dev { 6062306a36Sopenharmony_ci struct device *dev; 6162306a36Sopenharmony_ci void __iomem *regs; 6262306a36Sopenharmony_ci int irq; 6362306a36Sopenharmony_ci struct i2c_adapter adapter; 6462306a36Sopenharmony_ci struct completion completion; 6562306a36Sopenharmony_ci struct i2c_msg *curr_msg; 6662306a36Sopenharmony_ci struct clk *bus_clk; 6762306a36Sopenharmony_ci int num_msgs; 6862306a36Sopenharmony_ci u32 msg_err; 6962306a36Sopenharmony_ci u8 *msg_buf; 7062306a36Sopenharmony_ci size_t msg_buf_remaining; 7162306a36Sopenharmony_ci}; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_cistatic inline void bcm2835_i2c_writel(struct bcm2835_i2c_dev *i2c_dev, 7462306a36Sopenharmony_ci u32 reg, u32 val) 7562306a36Sopenharmony_ci{ 7662306a36Sopenharmony_ci writel(val, i2c_dev->regs + reg); 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic inline u32 bcm2835_i2c_readl(struct bcm2835_i2c_dev *i2c_dev, u32 reg) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci return readl(i2c_dev->regs + reg); 8262306a36Sopenharmony_ci} 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci#define to_clk_bcm2835_i2c(_hw) container_of(_hw, struct clk_bcm2835_i2c, hw) 8562306a36Sopenharmony_cistruct clk_bcm2835_i2c { 8662306a36Sopenharmony_ci struct clk_hw hw; 8762306a36Sopenharmony_ci struct bcm2835_i2c_dev *i2c_dev; 8862306a36Sopenharmony_ci}; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic int clk_bcm2835_i2c_calc_divider(unsigned long rate, 9162306a36Sopenharmony_ci unsigned long parent_rate) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci u32 divider = DIV_ROUND_UP(parent_rate, rate); 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci /* 9662306a36Sopenharmony_ci * Per the datasheet, the register is always interpreted as an even 9762306a36Sopenharmony_ci * number, by rounding down. In other words, the LSB is ignored. So, 9862306a36Sopenharmony_ci * if the LSB is set, increment the divider to avoid any issue. 9962306a36Sopenharmony_ci */ 10062306a36Sopenharmony_ci if (divider & 1) 10162306a36Sopenharmony_ci divider++; 10262306a36Sopenharmony_ci if ((divider < BCM2835_I2C_CDIV_MIN) || 10362306a36Sopenharmony_ci (divider > BCM2835_I2C_CDIV_MAX)) 10462306a36Sopenharmony_ci return -EINVAL; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci return divider; 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic int clk_bcm2835_i2c_set_rate(struct clk_hw *hw, unsigned long rate, 11062306a36Sopenharmony_ci unsigned long parent_rate) 11162306a36Sopenharmony_ci{ 11262306a36Sopenharmony_ci struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw); 11362306a36Sopenharmony_ci u32 redl, fedl; 11462306a36Sopenharmony_ci u32 divider = clk_bcm2835_i2c_calc_divider(rate, parent_rate); 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci if (divider == -EINVAL) 11762306a36Sopenharmony_ci return -EINVAL; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DIV, divider); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci /* 12262306a36Sopenharmony_ci * Number of core clocks to wait after falling edge before 12362306a36Sopenharmony_ci * outputting the next data bit. Note that both FEDL and REDL 12462306a36Sopenharmony_ci * can't be greater than CDIV/2. 12562306a36Sopenharmony_ci */ 12662306a36Sopenharmony_ci fedl = max(divider / 16, 1u); 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci /* 12962306a36Sopenharmony_ci * Number of core clocks to wait after rising edge before 13062306a36Sopenharmony_ci * sampling the next incoming data bit. 13162306a36Sopenharmony_ci */ 13262306a36Sopenharmony_ci redl = max(divider / 4, 1u); 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DEL, 13562306a36Sopenharmony_ci (fedl << BCM2835_I2C_FEDL_SHIFT) | 13662306a36Sopenharmony_ci (redl << BCM2835_I2C_REDL_SHIFT)); 13762306a36Sopenharmony_ci return 0; 13862306a36Sopenharmony_ci} 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_cistatic long clk_bcm2835_i2c_round_rate(struct clk_hw *hw, unsigned long rate, 14162306a36Sopenharmony_ci unsigned long *parent_rate) 14262306a36Sopenharmony_ci{ 14362306a36Sopenharmony_ci u32 divider = clk_bcm2835_i2c_calc_divider(rate, *parent_rate); 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci return DIV_ROUND_UP(*parent_rate, divider); 14662306a36Sopenharmony_ci} 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_cistatic unsigned long clk_bcm2835_i2c_recalc_rate(struct clk_hw *hw, 14962306a36Sopenharmony_ci unsigned long parent_rate) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw); 15262306a36Sopenharmony_ci u32 divider = bcm2835_i2c_readl(div->i2c_dev, BCM2835_I2C_DIV); 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci return DIV_ROUND_UP(parent_rate, divider); 15562306a36Sopenharmony_ci} 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_cistatic const struct clk_ops clk_bcm2835_i2c_ops = { 15862306a36Sopenharmony_ci .set_rate = clk_bcm2835_i2c_set_rate, 15962306a36Sopenharmony_ci .round_rate = clk_bcm2835_i2c_round_rate, 16062306a36Sopenharmony_ci .recalc_rate = clk_bcm2835_i2c_recalc_rate, 16162306a36Sopenharmony_ci}; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cistatic struct clk *bcm2835_i2c_register_div(struct device *dev, 16462306a36Sopenharmony_ci struct clk *mclk, 16562306a36Sopenharmony_ci struct bcm2835_i2c_dev *i2c_dev) 16662306a36Sopenharmony_ci{ 16762306a36Sopenharmony_ci struct clk_init_data init; 16862306a36Sopenharmony_ci struct clk_bcm2835_i2c *priv; 16962306a36Sopenharmony_ci char name[32]; 17062306a36Sopenharmony_ci const char *mclk_name; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci snprintf(name, sizeof(name), "%s_div", dev_name(dev)); 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci mclk_name = __clk_get_name(mclk); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci init.ops = &clk_bcm2835_i2c_ops; 17762306a36Sopenharmony_ci init.name = name; 17862306a36Sopenharmony_ci init.parent_names = (const char* []) { mclk_name }; 17962306a36Sopenharmony_ci init.num_parents = 1; 18062306a36Sopenharmony_ci init.flags = 0; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci priv = devm_kzalloc(dev, sizeof(struct clk_bcm2835_i2c), GFP_KERNEL); 18362306a36Sopenharmony_ci if (priv == NULL) 18462306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci priv->hw.init = &init; 18762306a36Sopenharmony_ci priv->i2c_dev = i2c_dev; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci clk_hw_register_clkdev(&priv->hw, "div", dev_name(dev)); 19062306a36Sopenharmony_ci return devm_clk_register(dev, &priv->hw); 19162306a36Sopenharmony_ci} 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_cistatic void bcm2835_fill_txfifo(struct bcm2835_i2c_dev *i2c_dev) 19462306a36Sopenharmony_ci{ 19562306a36Sopenharmony_ci u32 val; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci while (i2c_dev->msg_buf_remaining) { 19862306a36Sopenharmony_ci val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); 19962306a36Sopenharmony_ci if (!(val & BCM2835_I2C_S_TXD)) 20062306a36Sopenharmony_ci break; 20162306a36Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_FIFO, 20262306a36Sopenharmony_ci *i2c_dev->msg_buf); 20362306a36Sopenharmony_ci i2c_dev->msg_buf++; 20462306a36Sopenharmony_ci i2c_dev->msg_buf_remaining--; 20562306a36Sopenharmony_ci } 20662306a36Sopenharmony_ci} 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_cistatic void bcm2835_drain_rxfifo(struct bcm2835_i2c_dev *i2c_dev) 20962306a36Sopenharmony_ci{ 21062306a36Sopenharmony_ci u32 val; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci while (i2c_dev->msg_buf_remaining) { 21362306a36Sopenharmony_ci val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); 21462306a36Sopenharmony_ci if (!(val & BCM2835_I2C_S_RXD)) 21562306a36Sopenharmony_ci break; 21662306a36Sopenharmony_ci *i2c_dev->msg_buf = bcm2835_i2c_readl(i2c_dev, 21762306a36Sopenharmony_ci BCM2835_I2C_FIFO); 21862306a36Sopenharmony_ci i2c_dev->msg_buf++; 21962306a36Sopenharmony_ci i2c_dev->msg_buf_remaining--; 22062306a36Sopenharmony_ci } 22162306a36Sopenharmony_ci} 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci/* 22462306a36Sopenharmony_ci * Repeated Start Condition (Sr) 22562306a36Sopenharmony_ci * The BCM2835 ARM Peripherals datasheet mentions a way to trigger a Sr when it 22662306a36Sopenharmony_ci * talks about reading from a slave with 10 bit address. This is achieved by 22762306a36Sopenharmony_ci * issuing a write, poll the I2CS.TA flag and wait for it to be set, and then 22862306a36Sopenharmony_ci * issue a read. 22962306a36Sopenharmony_ci * A comment in https://github.com/raspberrypi/linux/issues/254 shows how the 23062306a36Sopenharmony_ci * firmware actually does it using polling and says that it's a workaround for 23162306a36Sopenharmony_ci * a problem in the state machine. 23262306a36Sopenharmony_ci * It turns out that it is possible to use the TXW interrupt to know when the 23362306a36Sopenharmony_ci * transfer is active, provided the FIFO has not been prefilled. 23462306a36Sopenharmony_ci */ 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_cistatic void bcm2835_i2c_start_transfer(struct bcm2835_i2c_dev *i2c_dev) 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci u32 c = BCM2835_I2C_C_ST | BCM2835_I2C_C_I2CEN; 23962306a36Sopenharmony_ci struct i2c_msg *msg = i2c_dev->curr_msg; 24062306a36Sopenharmony_ci bool last_msg = (i2c_dev->num_msgs == 1); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci if (!i2c_dev->num_msgs) 24362306a36Sopenharmony_ci return; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci i2c_dev->num_msgs--; 24662306a36Sopenharmony_ci i2c_dev->msg_buf = msg->buf; 24762306a36Sopenharmony_ci i2c_dev->msg_buf_remaining = msg->len; 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci if (msg->flags & I2C_M_RD) 25062306a36Sopenharmony_ci c |= BCM2835_I2C_C_READ | BCM2835_I2C_C_INTR; 25162306a36Sopenharmony_ci else 25262306a36Sopenharmony_ci c |= BCM2835_I2C_C_INTT; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci if (last_msg) 25562306a36Sopenharmony_ci c |= BCM2835_I2C_C_INTD; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_A, msg->addr); 25862306a36Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DLEN, msg->len); 25962306a36Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, c); 26062306a36Sopenharmony_ci} 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_cistatic void bcm2835_i2c_finish_transfer(struct bcm2835_i2c_dev *i2c_dev) 26362306a36Sopenharmony_ci{ 26462306a36Sopenharmony_ci i2c_dev->curr_msg = NULL; 26562306a36Sopenharmony_ci i2c_dev->num_msgs = 0; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci i2c_dev->msg_buf = NULL; 26862306a36Sopenharmony_ci i2c_dev->msg_buf_remaining = 0; 26962306a36Sopenharmony_ci} 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci/* 27262306a36Sopenharmony_ci * Note about I2C_C_CLEAR on error: 27362306a36Sopenharmony_ci * The I2C_C_CLEAR on errors will take some time to resolve -- if you were in 27462306a36Sopenharmony_ci * non-idle state and I2C_C_READ, it sets an abort_rx flag and runs through 27562306a36Sopenharmony_ci * the state machine to send a NACK and a STOP. Since we're setting CLEAR 27662306a36Sopenharmony_ci * without I2CEN, that NACK will be hanging around queued up for next time 27762306a36Sopenharmony_ci * we start the engine. 27862306a36Sopenharmony_ci */ 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_cistatic irqreturn_t bcm2835_i2c_isr(int this_irq, void *data) 28162306a36Sopenharmony_ci{ 28262306a36Sopenharmony_ci struct bcm2835_i2c_dev *i2c_dev = data; 28362306a36Sopenharmony_ci u32 val, err; 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci err = val & (BCM2835_I2C_S_CLKT | BCM2835_I2C_S_ERR); 28862306a36Sopenharmony_ci if (err) { 28962306a36Sopenharmony_ci i2c_dev->msg_err = err; 29062306a36Sopenharmony_ci goto complete; 29162306a36Sopenharmony_ci } 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci if (val & BCM2835_I2C_S_DONE) { 29462306a36Sopenharmony_ci if (!i2c_dev->curr_msg) { 29562306a36Sopenharmony_ci dev_err(i2c_dev->dev, "Got unexpected interrupt (from firmware?)\n"); 29662306a36Sopenharmony_ci } else if (i2c_dev->curr_msg->flags & I2C_M_RD) { 29762306a36Sopenharmony_ci bcm2835_drain_rxfifo(i2c_dev); 29862306a36Sopenharmony_ci val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); 29962306a36Sopenharmony_ci } 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci if ((val & BCM2835_I2C_S_RXD) || i2c_dev->msg_buf_remaining) 30262306a36Sopenharmony_ci i2c_dev->msg_err = BCM2835_I2C_S_LEN; 30362306a36Sopenharmony_ci else 30462306a36Sopenharmony_ci i2c_dev->msg_err = 0; 30562306a36Sopenharmony_ci goto complete; 30662306a36Sopenharmony_ci } 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci if (val & BCM2835_I2C_S_TXW) { 30962306a36Sopenharmony_ci if (!i2c_dev->msg_buf_remaining) { 31062306a36Sopenharmony_ci i2c_dev->msg_err = val | BCM2835_I2C_S_LEN; 31162306a36Sopenharmony_ci goto complete; 31262306a36Sopenharmony_ci } 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci bcm2835_fill_txfifo(i2c_dev); 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci if (i2c_dev->num_msgs && !i2c_dev->msg_buf_remaining) { 31762306a36Sopenharmony_ci i2c_dev->curr_msg++; 31862306a36Sopenharmony_ci bcm2835_i2c_start_transfer(i2c_dev); 31962306a36Sopenharmony_ci } 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci return IRQ_HANDLED; 32262306a36Sopenharmony_ci } 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci if (val & BCM2835_I2C_S_RXR) { 32562306a36Sopenharmony_ci if (!i2c_dev->msg_buf_remaining) { 32662306a36Sopenharmony_ci i2c_dev->msg_err = val | BCM2835_I2C_S_LEN; 32762306a36Sopenharmony_ci goto complete; 32862306a36Sopenharmony_ci } 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci bcm2835_drain_rxfifo(i2c_dev); 33162306a36Sopenharmony_ci return IRQ_HANDLED; 33262306a36Sopenharmony_ci } 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci return IRQ_NONE; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_cicomplete: 33762306a36Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, BCM2835_I2C_C_CLEAR); 33862306a36Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_S, BCM2835_I2C_S_CLKT | 33962306a36Sopenharmony_ci BCM2835_I2C_S_ERR | BCM2835_I2C_S_DONE); 34062306a36Sopenharmony_ci complete(&i2c_dev->completion); 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci return IRQ_HANDLED; 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_cistatic int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], 34662306a36Sopenharmony_ci int num) 34762306a36Sopenharmony_ci{ 34862306a36Sopenharmony_ci struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap); 34962306a36Sopenharmony_ci unsigned long time_left; 35062306a36Sopenharmony_ci int i; 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci for (i = 0; i < (num - 1); i++) 35362306a36Sopenharmony_ci if (msgs[i].flags & I2C_M_RD) { 35462306a36Sopenharmony_ci dev_warn_once(i2c_dev->dev, 35562306a36Sopenharmony_ci "only one read message supported, has to be last\n"); 35662306a36Sopenharmony_ci return -EOPNOTSUPP; 35762306a36Sopenharmony_ci } 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci i2c_dev->curr_msg = msgs; 36062306a36Sopenharmony_ci i2c_dev->num_msgs = num; 36162306a36Sopenharmony_ci reinit_completion(&i2c_dev->completion); 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci bcm2835_i2c_start_transfer(i2c_dev); 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci time_left = wait_for_completion_timeout(&i2c_dev->completion, 36662306a36Sopenharmony_ci adap->timeout); 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci bcm2835_i2c_finish_transfer(i2c_dev); 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci if (!time_left) { 37162306a36Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 37262306a36Sopenharmony_ci BCM2835_I2C_C_CLEAR); 37362306a36Sopenharmony_ci dev_err(i2c_dev->dev, "i2c transfer timed out\n"); 37462306a36Sopenharmony_ci return -ETIMEDOUT; 37562306a36Sopenharmony_ci } 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci if (!i2c_dev->msg_err) 37862306a36Sopenharmony_ci return num; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci dev_dbg(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err); 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci if (i2c_dev->msg_err & BCM2835_I2C_S_ERR) 38362306a36Sopenharmony_ci return -EREMOTEIO; 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci return -EIO; 38662306a36Sopenharmony_ci} 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_cistatic u32 bcm2835_i2c_func(struct i2c_adapter *adap) 38962306a36Sopenharmony_ci{ 39062306a36Sopenharmony_ci return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 39162306a36Sopenharmony_ci} 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_cistatic const struct i2c_algorithm bcm2835_i2c_algo = { 39462306a36Sopenharmony_ci .master_xfer = bcm2835_i2c_xfer, 39562306a36Sopenharmony_ci .functionality = bcm2835_i2c_func, 39662306a36Sopenharmony_ci}; 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci/* 39962306a36Sopenharmony_ci * The BCM2835 was reported to have problems with clock stretching: 40062306a36Sopenharmony_ci * https://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html 40162306a36Sopenharmony_ci * https://www.raspberrypi.org/forums/viewtopic.php?p=146272 40262306a36Sopenharmony_ci */ 40362306a36Sopenharmony_cistatic const struct i2c_adapter_quirks bcm2835_i2c_quirks = { 40462306a36Sopenharmony_ci .flags = I2C_AQ_NO_CLK_STRETCH, 40562306a36Sopenharmony_ci}; 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_cistatic int bcm2835_i2c_probe(struct platform_device *pdev) 40862306a36Sopenharmony_ci{ 40962306a36Sopenharmony_ci struct bcm2835_i2c_dev *i2c_dev; 41062306a36Sopenharmony_ci int ret; 41162306a36Sopenharmony_ci struct i2c_adapter *adap; 41262306a36Sopenharmony_ci struct clk *mclk; 41362306a36Sopenharmony_ci u32 bus_clk_rate; 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); 41662306a36Sopenharmony_ci if (!i2c_dev) 41762306a36Sopenharmony_ci return -ENOMEM; 41862306a36Sopenharmony_ci platform_set_drvdata(pdev, i2c_dev); 41962306a36Sopenharmony_ci i2c_dev->dev = &pdev->dev; 42062306a36Sopenharmony_ci init_completion(&i2c_dev->completion); 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci i2c_dev->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); 42362306a36Sopenharmony_ci if (IS_ERR(i2c_dev->regs)) 42462306a36Sopenharmony_ci return PTR_ERR(i2c_dev->regs); 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci mclk = devm_clk_get(&pdev->dev, NULL); 42762306a36Sopenharmony_ci if (IS_ERR(mclk)) 42862306a36Sopenharmony_ci return dev_err_probe(&pdev->dev, PTR_ERR(mclk), 42962306a36Sopenharmony_ci "Could not get clock\n"); 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci i2c_dev->bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev); 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci if (IS_ERR(i2c_dev->bus_clk)) 43462306a36Sopenharmony_ci return dev_err_probe(&pdev->dev, PTR_ERR(i2c_dev->bus_clk), 43562306a36Sopenharmony_ci "Could not register clock\n"); 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ci ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", 43862306a36Sopenharmony_ci &bus_clk_rate); 43962306a36Sopenharmony_ci if (ret < 0) { 44062306a36Sopenharmony_ci dev_warn(&pdev->dev, 44162306a36Sopenharmony_ci "Could not read clock-frequency property\n"); 44262306a36Sopenharmony_ci bus_clk_rate = I2C_MAX_STANDARD_MODE_FREQ; 44362306a36Sopenharmony_ci } 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci ret = clk_set_rate_exclusive(i2c_dev->bus_clk, bus_clk_rate); 44662306a36Sopenharmony_ci if (ret < 0) 44762306a36Sopenharmony_ci return dev_err_probe(&pdev->dev, ret, 44862306a36Sopenharmony_ci "Could not set clock frequency\n"); 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci ret = clk_prepare_enable(i2c_dev->bus_clk); 45162306a36Sopenharmony_ci if (ret) { 45262306a36Sopenharmony_ci dev_err(&pdev->dev, "Couldn't prepare clock"); 45362306a36Sopenharmony_ci goto err_put_exclusive_rate; 45462306a36Sopenharmony_ci } 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci i2c_dev->irq = platform_get_irq(pdev, 0); 45762306a36Sopenharmony_ci if (i2c_dev->irq < 0) { 45862306a36Sopenharmony_ci ret = i2c_dev->irq; 45962306a36Sopenharmony_ci goto err_disable_unprepare_clk; 46062306a36Sopenharmony_ci } 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci ret = request_irq(i2c_dev->irq, bcm2835_i2c_isr, IRQF_SHARED, 46362306a36Sopenharmony_ci dev_name(&pdev->dev), i2c_dev); 46462306a36Sopenharmony_ci if (ret) { 46562306a36Sopenharmony_ci dev_err(&pdev->dev, "Could not request IRQ\n"); 46662306a36Sopenharmony_ci goto err_disable_unprepare_clk; 46762306a36Sopenharmony_ci } 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci adap = &i2c_dev->adapter; 47062306a36Sopenharmony_ci i2c_set_adapdata(adap, i2c_dev); 47162306a36Sopenharmony_ci adap->owner = THIS_MODULE; 47262306a36Sopenharmony_ci adap->class = I2C_CLASS_DEPRECATED; 47362306a36Sopenharmony_ci snprintf(adap->name, sizeof(adap->name), "bcm2835 (%s)", 47462306a36Sopenharmony_ci of_node_full_name(pdev->dev.of_node)); 47562306a36Sopenharmony_ci adap->algo = &bcm2835_i2c_algo; 47662306a36Sopenharmony_ci adap->dev.parent = &pdev->dev; 47762306a36Sopenharmony_ci adap->dev.of_node = pdev->dev.of_node; 47862306a36Sopenharmony_ci adap->quirks = of_device_get_match_data(&pdev->dev); 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci /* 48162306a36Sopenharmony_ci * Disable the hardware clock stretching timeout. SMBUS 48262306a36Sopenharmony_ci * specifies a limit for how long the device can stretch the 48362306a36Sopenharmony_ci * clock, but core I2C doesn't. 48462306a36Sopenharmony_ci */ 48562306a36Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_CLKT, 0); 48662306a36Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0); 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci ret = i2c_add_adapter(adap); 48962306a36Sopenharmony_ci if (ret) 49062306a36Sopenharmony_ci goto err_free_irq; 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci return 0; 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_cierr_free_irq: 49562306a36Sopenharmony_ci free_irq(i2c_dev->irq, i2c_dev); 49662306a36Sopenharmony_cierr_disable_unprepare_clk: 49762306a36Sopenharmony_ci clk_disable_unprepare(i2c_dev->bus_clk); 49862306a36Sopenharmony_cierr_put_exclusive_rate: 49962306a36Sopenharmony_ci clk_rate_exclusive_put(i2c_dev->bus_clk); 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci return ret; 50262306a36Sopenharmony_ci} 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_cistatic void bcm2835_i2c_remove(struct platform_device *pdev) 50562306a36Sopenharmony_ci{ 50662306a36Sopenharmony_ci struct bcm2835_i2c_dev *i2c_dev = platform_get_drvdata(pdev); 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci clk_rate_exclusive_put(i2c_dev->bus_clk); 50962306a36Sopenharmony_ci clk_disable_unprepare(i2c_dev->bus_clk); 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci free_irq(i2c_dev->irq, i2c_dev); 51262306a36Sopenharmony_ci i2c_del_adapter(&i2c_dev->adapter); 51362306a36Sopenharmony_ci} 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_cistatic const struct of_device_id bcm2835_i2c_of_match[] = { 51662306a36Sopenharmony_ci { .compatible = "brcm,bcm2711-i2c" }, 51762306a36Sopenharmony_ci { .compatible = "brcm,bcm2835-i2c", .data = &bcm2835_i2c_quirks }, 51862306a36Sopenharmony_ci {}, 51962306a36Sopenharmony_ci}; 52062306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, bcm2835_i2c_of_match); 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_cistatic struct platform_driver bcm2835_i2c_driver = { 52362306a36Sopenharmony_ci .probe = bcm2835_i2c_probe, 52462306a36Sopenharmony_ci .remove_new = bcm2835_i2c_remove, 52562306a36Sopenharmony_ci .driver = { 52662306a36Sopenharmony_ci .name = "i2c-bcm2835", 52762306a36Sopenharmony_ci .of_match_table = bcm2835_i2c_of_match, 52862306a36Sopenharmony_ci }, 52962306a36Sopenharmony_ci}; 53062306a36Sopenharmony_cimodule_platform_driver(bcm2835_i2c_driver); 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ciMODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>"); 53362306a36Sopenharmony_ciMODULE_DESCRIPTION("BCM2835 I2C bus adapter"); 53462306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 53562306a36Sopenharmony_ciMODULE_ALIAS("platform:i2c-bcm2835"); 536