18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * BCM2835 master mode driver 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <linux/clk.h> 78c2ecf20Sopenharmony_ci#include <linux/clkdev.h> 88c2ecf20Sopenharmony_ci#include <linux/clk-provider.h> 98c2ecf20Sopenharmony_ci#include <linux/completion.h> 108c2ecf20Sopenharmony_ci#include <linux/err.h> 118c2ecf20Sopenharmony_ci#include <linux/i2c.h> 128c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 138c2ecf20Sopenharmony_ci#include <linux/io.h> 148c2ecf20Sopenharmony_ci#include <linux/module.h> 158c2ecf20Sopenharmony_ci#include <linux/of_device.h> 168c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 178c2ecf20Sopenharmony_ci#include <linux/slab.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define BCM2835_I2C_C 0x0 208c2ecf20Sopenharmony_ci#define BCM2835_I2C_S 0x4 218c2ecf20Sopenharmony_ci#define BCM2835_I2C_DLEN 0x8 228c2ecf20Sopenharmony_ci#define BCM2835_I2C_A 0xc 238c2ecf20Sopenharmony_ci#define BCM2835_I2C_FIFO 0x10 248c2ecf20Sopenharmony_ci#define BCM2835_I2C_DIV 0x14 258c2ecf20Sopenharmony_ci#define BCM2835_I2C_DEL 0x18 268c2ecf20Sopenharmony_ci/* 278c2ecf20Sopenharmony_ci * 16-bit field for the number of SCL cycles to wait after rising SCL 288c2ecf20Sopenharmony_ci * before deciding the slave is not responding. 0 disables the 298c2ecf20Sopenharmony_ci * timeout detection. 308c2ecf20Sopenharmony_ci */ 318c2ecf20Sopenharmony_ci#define BCM2835_I2C_CLKT 0x1c 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#define BCM2835_I2C_C_READ BIT(0) 348c2ecf20Sopenharmony_ci#define BCM2835_I2C_C_CLEAR BIT(4) /* bits 4 and 5 both clear */ 358c2ecf20Sopenharmony_ci#define BCM2835_I2C_C_ST BIT(7) 368c2ecf20Sopenharmony_ci#define BCM2835_I2C_C_INTD BIT(8) 378c2ecf20Sopenharmony_ci#define BCM2835_I2C_C_INTT BIT(9) 388c2ecf20Sopenharmony_ci#define BCM2835_I2C_C_INTR BIT(10) 398c2ecf20Sopenharmony_ci#define BCM2835_I2C_C_I2CEN BIT(15) 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#define BCM2835_I2C_S_TA BIT(0) 428c2ecf20Sopenharmony_ci#define BCM2835_I2C_S_DONE BIT(1) 438c2ecf20Sopenharmony_ci#define BCM2835_I2C_S_TXW BIT(2) 448c2ecf20Sopenharmony_ci#define BCM2835_I2C_S_RXR BIT(3) 458c2ecf20Sopenharmony_ci#define BCM2835_I2C_S_TXD BIT(4) 468c2ecf20Sopenharmony_ci#define BCM2835_I2C_S_RXD BIT(5) 478c2ecf20Sopenharmony_ci#define BCM2835_I2C_S_TXE BIT(6) 488c2ecf20Sopenharmony_ci#define BCM2835_I2C_S_RXF BIT(7) 498c2ecf20Sopenharmony_ci#define BCM2835_I2C_S_ERR BIT(8) 508c2ecf20Sopenharmony_ci#define BCM2835_I2C_S_CLKT BIT(9) 518c2ecf20Sopenharmony_ci#define BCM2835_I2C_S_LEN BIT(10) /* Fake bit for SW error reporting */ 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci#define BCM2835_I2C_FEDL_SHIFT 16 548c2ecf20Sopenharmony_ci#define BCM2835_I2C_REDL_SHIFT 0 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci#define BCM2835_I2C_CDIV_MIN 0x0002 578c2ecf20Sopenharmony_ci#define BCM2835_I2C_CDIV_MAX 0xFFFE 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistruct bcm2835_i2c_dev { 608c2ecf20Sopenharmony_ci struct device *dev; 618c2ecf20Sopenharmony_ci void __iomem *regs; 628c2ecf20Sopenharmony_ci int irq; 638c2ecf20Sopenharmony_ci struct i2c_adapter adapter; 648c2ecf20Sopenharmony_ci struct completion completion; 658c2ecf20Sopenharmony_ci struct i2c_msg *curr_msg; 668c2ecf20Sopenharmony_ci struct clk *bus_clk; 678c2ecf20Sopenharmony_ci int num_msgs; 688c2ecf20Sopenharmony_ci u32 msg_err; 698c2ecf20Sopenharmony_ci u8 *msg_buf; 708c2ecf20Sopenharmony_ci size_t msg_buf_remaining; 718c2ecf20Sopenharmony_ci}; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistatic inline void bcm2835_i2c_writel(struct bcm2835_i2c_dev *i2c_dev, 748c2ecf20Sopenharmony_ci u32 reg, u32 val) 758c2ecf20Sopenharmony_ci{ 768c2ecf20Sopenharmony_ci writel(val, i2c_dev->regs + reg); 778c2ecf20Sopenharmony_ci} 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic inline u32 bcm2835_i2c_readl(struct bcm2835_i2c_dev *i2c_dev, u32 reg) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci return readl(i2c_dev->regs + reg); 828c2ecf20Sopenharmony_ci} 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci#define to_clk_bcm2835_i2c(_hw) container_of(_hw, struct clk_bcm2835_i2c, hw) 858c2ecf20Sopenharmony_cistruct clk_bcm2835_i2c { 868c2ecf20Sopenharmony_ci struct clk_hw hw; 878c2ecf20Sopenharmony_ci struct bcm2835_i2c_dev *i2c_dev; 888c2ecf20Sopenharmony_ci}; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_cistatic int clk_bcm2835_i2c_calc_divider(unsigned long rate, 918c2ecf20Sopenharmony_ci unsigned long parent_rate) 928c2ecf20Sopenharmony_ci{ 938c2ecf20Sopenharmony_ci u32 divider = DIV_ROUND_UP(parent_rate, rate); 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci /* 968c2ecf20Sopenharmony_ci * Per the datasheet, the register is always interpreted as an even 978c2ecf20Sopenharmony_ci * number, by rounding down. In other words, the LSB is ignored. So, 988c2ecf20Sopenharmony_ci * if the LSB is set, increment the divider to avoid any issue. 998c2ecf20Sopenharmony_ci */ 1008c2ecf20Sopenharmony_ci if (divider & 1) 1018c2ecf20Sopenharmony_ci divider++; 1028c2ecf20Sopenharmony_ci if ((divider < BCM2835_I2C_CDIV_MIN) || 1038c2ecf20Sopenharmony_ci (divider > BCM2835_I2C_CDIV_MAX)) 1048c2ecf20Sopenharmony_ci return -EINVAL; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci return divider; 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic int clk_bcm2835_i2c_set_rate(struct clk_hw *hw, unsigned long rate, 1108c2ecf20Sopenharmony_ci unsigned long parent_rate) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw); 1138c2ecf20Sopenharmony_ci u32 redl, fedl; 1148c2ecf20Sopenharmony_ci u32 divider = clk_bcm2835_i2c_calc_divider(rate, parent_rate); 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci if (divider == -EINVAL) 1178c2ecf20Sopenharmony_ci return -EINVAL; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DIV, divider); 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci /* 1228c2ecf20Sopenharmony_ci * Number of core clocks to wait after falling edge before 1238c2ecf20Sopenharmony_ci * outputting the next data bit. Note that both FEDL and REDL 1248c2ecf20Sopenharmony_ci * can't be greater than CDIV/2. 1258c2ecf20Sopenharmony_ci */ 1268c2ecf20Sopenharmony_ci fedl = max(divider / 16, 1u); 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci /* 1298c2ecf20Sopenharmony_ci * Number of core clocks to wait after rising edge before 1308c2ecf20Sopenharmony_ci * sampling the next incoming data bit. 1318c2ecf20Sopenharmony_ci */ 1328c2ecf20Sopenharmony_ci redl = max(divider / 4, 1u); 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DEL, 1358c2ecf20Sopenharmony_ci (fedl << BCM2835_I2C_FEDL_SHIFT) | 1368c2ecf20Sopenharmony_ci (redl << BCM2835_I2C_REDL_SHIFT)); 1378c2ecf20Sopenharmony_ci return 0; 1388c2ecf20Sopenharmony_ci} 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cistatic long clk_bcm2835_i2c_round_rate(struct clk_hw *hw, unsigned long rate, 1418c2ecf20Sopenharmony_ci unsigned long *parent_rate) 1428c2ecf20Sopenharmony_ci{ 1438c2ecf20Sopenharmony_ci u32 divider = clk_bcm2835_i2c_calc_divider(rate, *parent_rate); 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci return DIV_ROUND_UP(*parent_rate, divider); 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistatic unsigned long clk_bcm2835_i2c_recalc_rate(struct clk_hw *hw, 1498c2ecf20Sopenharmony_ci unsigned long parent_rate) 1508c2ecf20Sopenharmony_ci{ 1518c2ecf20Sopenharmony_ci struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw); 1528c2ecf20Sopenharmony_ci u32 divider = bcm2835_i2c_readl(div->i2c_dev, BCM2835_I2C_DIV); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci return DIV_ROUND_UP(parent_rate, divider); 1558c2ecf20Sopenharmony_ci} 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_cistatic const struct clk_ops clk_bcm2835_i2c_ops = { 1588c2ecf20Sopenharmony_ci .set_rate = clk_bcm2835_i2c_set_rate, 1598c2ecf20Sopenharmony_ci .round_rate = clk_bcm2835_i2c_round_rate, 1608c2ecf20Sopenharmony_ci .recalc_rate = clk_bcm2835_i2c_recalc_rate, 1618c2ecf20Sopenharmony_ci}; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_cistatic struct clk *bcm2835_i2c_register_div(struct device *dev, 1648c2ecf20Sopenharmony_ci struct clk *mclk, 1658c2ecf20Sopenharmony_ci struct bcm2835_i2c_dev *i2c_dev) 1668c2ecf20Sopenharmony_ci{ 1678c2ecf20Sopenharmony_ci struct clk_init_data init; 1688c2ecf20Sopenharmony_ci struct clk_bcm2835_i2c *priv; 1698c2ecf20Sopenharmony_ci char name[32]; 1708c2ecf20Sopenharmony_ci const char *mclk_name; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci snprintf(name, sizeof(name), "%s_div", dev_name(dev)); 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci mclk_name = __clk_get_name(mclk); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci init.ops = &clk_bcm2835_i2c_ops; 1778c2ecf20Sopenharmony_ci init.name = name; 1788c2ecf20Sopenharmony_ci init.parent_names = (const char* []) { mclk_name }; 1798c2ecf20Sopenharmony_ci init.num_parents = 1; 1808c2ecf20Sopenharmony_ci init.flags = 0; 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci priv = devm_kzalloc(dev, sizeof(struct clk_bcm2835_i2c), GFP_KERNEL); 1838c2ecf20Sopenharmony_ci if (priv == NULL) 1848c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci priv->hw.init = &init; 1878c2ecf20Sopenharmony_ci priv->i2c_dev = i2c_dev; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci clk_hw_register_clkdev(&priv->hw, "div", dev_name(dev)); 1908c2ecf20Sopenharmony_ci return devm_clk_register(dev, &priv->hw); 1918c2ecf20Sopenharmony_ci} 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistatic void bcm2835_fill_txfifo(struct bcm2835_i2c_dev *i2c_dev) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci u32 val; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci while (i2c_dev->msg_buf_remaining) { 1988c2ecf20Sopenharmony_ci val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); 1998c2ecf20Sopenharmony_ci if (!(val & BCM2835_I2C_S_TXD)) 2008c2ecf20Sopenharmony_ci break; 2018c2ecf20Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_FIFO, 2028c2ecf20Sopenharmony_ci *i2c_dev->msg_buf); 2038c2ecf20Sopenharmony_ci i2c_dev->msg_buf++; 2048c2ecf20Sopenharmony_ci i2c_dev->msg_buf_remaining--; 2058c2ecf20Sopenharmony_ci } 2068c2ecf20Sopenharmony_ci} 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_cistatic void bcm2835_drain_rxfifo(struct bcm2835_i2c_dev *i2c_dev) 2098c2ecf20Sopenharmony_ci{ 2108c2ecf20Sopenharmony_ci u32 val; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci while (i2c_dev->msg_buf_remaining) { 2138c2ecf20Sopenharmony_ci val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); 2148c2ecf20Sopenharmony_ci if (!(val & BCM2835_I2C_S_RXD)) 2158c2ecf20Sopenharmony_ci break; 2168c2ecf20Sopenharmony_ci *i2c_dev->msg_buf = bcm2835_i2c_readl(i2c_dev, 2178c2ecf20Sopenharmony_ci BCM2835_I2C_FIFO); 2188c2ecf20Sopenharmony_ci i2c_dev->msg_buf++; 2198c2ecf20Sopenharmony_ci i2c_dev->msg_buf_remaining--; 2208c2ecf20Sopenharmony_ci } 2218c2ecf20Sopenharmony_ci} 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci/* 2248c2ecf20Sopenharmony_ci * Repeated Start Condition (Sr) 2258c2ecf20Sopenharmony_ci * The BCM2835 ARM Peripherals datasheet mentions a way to trigger a Sr when it 2268c2ecf20Sopenharmony_ci * talks about reading from a slave with 10 bit address. This is achieved by 2278c2ecf20Sopenharmony_ci * issuing a write, poll the I2CS.TA flag and wait for it to be set, and then 2288c2ecf20Sopenharmony_ci * issue a read. 2298c2ecf20Sopenharmony_ci * A comment in https://github.com/raspberrypi/linux/issues/254 shows how the 2308c2ecf20Sopenharmony_ci * firmware actually does it using polling and says that it's a workaround for 2318c2ecf20Sopenharmony_ci * a problem in the state machine. 2328c2ecf20Sopenharmony_ci * It turns out that it is possible to use the TXW interrupt to know when the 2338c2ecf20Sopenharmony_ci * transfer is active, provided the FIFO has not been prefilled. 2348c2ecf20Sopenharmony_ci */ 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_cistatic void bcm2835_i2c_start_transfer(struct bcm2835_i2c_dev *i2c_dev) 2378c2ecf20Sopenharmony_ci{ 2388c2ecf20Sopenharmony_ci u32 c = BCM2835_I2C_C_ST | BCM2835_I2C_C_I2CEN; 2398c2ecf20Sopenharmony_ci struct i2c_msg *msg = i2c_dev->curr_msg; 2408c2ecf20Sopenharmony_ci bool last_msg = (i2c_dev->num_msgs == 1); 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci if (!i2c_dev->num_msgs) 2438c2ecf20Sopenharmony_ci return; 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci i2c_dev->num_msgs--; 2468c2ecf20Sopenharmony_ci i2c_dev->msg_buf = msg->buf; 2478c2ecf20Sopenharmony_ci i2c_dev->msg_buf_remaining = msg->len; 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci if (msg->flags & I2C_M_RD) 2508c2ecf20Sopenharmony_ci c |= BCM2835_I2C_C_READ | BCM2835_I2C_C_INTR; 2518c2ecf20Sopenharmony_ci else 2528c2ecf20Sopenharmony_ci c |= BCM2835_I2C_C_INTT; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci if (last_msg) 2558c2ecf20Sopenharmony_ci c |= BCM2835_I2C_C_INTD; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_A, msg->addr); 2588c2ecf20Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DLEN, msg->len); 2598c2ecf20Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, c); 2608c2ecf20Sopenharmony_ci} 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_cistatic void bcm2835_i2c_finish_transfer(struct bcm2835_i2c_dev *i2c_dev) 2638c2ecf20Sopenharmony_ci{ 2648c2ecf20Sopenharmony_ci i2c_dev->curr_msg = NULL; 2658c2ecf20Sopenharmony_ci i2c_dev->num_msgs = 0; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci i2c_dev->msg_buf = NULL; 2688c2ecf20Sopenharmony_ci i2c_dev->msg_buf_remaining = 0; 2698c2ecf20Sopenharmony_ci} 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci/* 2728c2ecf20Sopenharmony_ci * Note about I2C_C_CLEAR on error: 2738c2ecf20Sopenharmony_ci * The I2C_C_CLEAR on errors will take some time to resolve -- if you were in 2748c2ecf20Sopenharmony_ci * non-idle state and I2C_C_READ, it sets an abort_rx flag and runs through 2758c2ecf20Sopenharmony_ci * the state machine to send a NACK and a STOP. Since we're setting CLEAR 2768c2ecf20Sopenharmony_ci * without I2CEN, that NACK will be hanging around queued up for next time 2778c2ecf20Sopenharmony_ci * we start the engine. 2788c2ecf20Sopenharmony_ci */ 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_cistatic irqreturn_t bcm2835_i2c_isr(int this_irq, void *data) 2818c2ecf20Sopenharmony_ci{ 2828c2ecf20Sopenharmony_ci struct bcm2835_i2c_dev *i2c_dev = data; 2838c2ecf20Sopenharmony_ci u32 val, err; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci err = val & (BCM2835_I2C_S_CLKT | BCM2835_I2C_S_ERR); 2888c2ecf20Sopenharmony_ci if (err) { 2898c2ecf20Sopenharmony_ci i2c_dev->msg_err = err; 2908c2ecf20Sopenharmony_ci goto complete; 2918c2ecf20Sopenharmony_ci } 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci if (val & BCM2835_I2C_S_DONE) { 2948c2ecf20Sopenharmony_ci if (!i2c_dev->curr_msg) { 2958c2ecf20Sopenharmony_ci dev_err(i2c_dev->dev, "Got unexpected interrupt (from firmware?)\n"); 2968c2ecf20Sopenharmony_ci } else if (i2c_dev->curr_msg->flags & I2C_M_RD) { 2978c2ecf20Sopenharmony_ci bcm2835_drain_rxfifo(i2c_dev); 2988c2ecf20Sopenharmony_ci val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); 2998c2ecf20Sopenharmony_ci } 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci if ((val & BCM2835_I2C_S_RXD) || i2c_dev->msg_buf_remaining) 3028c2ecf20Sopenharmony_ci i2c_dev->msg_err = BCM2835_I2C_S_LEN; 3038c2ecf20Sopenharmony_ci else 3048c2ecf20Sopenharmony_ci i2c_dev->msg_err = 0; 3058c2ecf20Sopenharmony_ci goto complete; 3068c2ecf20Sopenharmony_ci } 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci if (val & BCM2835_I2C_S_TXW) { 3098c2ecf20Sopenharmony_ci if (!i2c_dev->msg_buf_remaining) { 3108c2ecf20Sopenharmony_ci i2c_dev->msg_err = val | BCM2835_I2C_S_LEN; 3118c2ecf20Sopenharmony_ci goto complete; 3128c2ecf20Sopenharmony_ci } 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci bcm2835_fill_txfifo(i2c_dev); 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci if (i2c_dev->num_msgs && !i2c_dev->msg_buf_remaining) { 3178c2ecf20Sopenharmony_ci i2c_dev->curr_msg++; 3188c2ecf20Sopenharmony_ci bcm2835_i2c_start_transfer(i2c_dev); 3198c2ecf20Sopenharmony_ci } 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci return IRQ_HANDLED; 3228c2ecf20Sopenharmony_ci } 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci if (val & BCM2835_I2C_S_RXR) { 3258c2ecf20Sopenharmony_ci if (!i2c_dev->msg_buf_remaining) { 3268c2ecf20Sopenharmony_ci i2c_dev->msg_err = val | BCM2835_I2C_S_LEN; 3278c2ecf20Sopenharmony_ci goto complete; 3288c2ecf20Sopenharmony_ci } 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci bcm2835_drain_rxfifo(i2c_dev); 3318c2ecf20Sopenharmony_ci return IRQ_HANDLED; 3328c2ecf20Sopenharmony_ci } 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci return IRQ_NONE; 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_cicomplete: 3378c2ecf20Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, BCM2835_I2C_C_CLEAR); 3388c2ecf20Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_S, BCM2835_I2C_S_CLKT | 3398c2ecf20Sopenharmony_ci BCM2835_I2C_S_ERR | BCM2835_I2C_S_DONE); 3408c2ecf20Sopenharmony_ci complete(&i2c_dev->completion); 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci return IRQ_HANDLED; 3438c2ecf20Sopenharmony_ci} 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_cistatic int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], 3468c2ecf20Sopenharmony_ci int num) 3478c2ecf20Sopenharmony_ci{ 3488c2ecf20Sopenharmony_ci struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap); 3498c2ecf20Sopenharmony_ci unsigned long time_left; 3508c2ecf20Sopenharmony_ci int i; 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci for (i = 0; i < (num - 1); i++) 3538c2ecf20Sopenharmony_ci if (msgs[i].flags & I2C_M_RD) { 3548c2ecf20Sopenharmony_ci dev_warn_once(i2c_dev->dev, 3558c2ecf20Sopenharmony_ci "only one read message supported, has to be last\n"); 3568c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 3578c2ecf20Sopenharmony_ci } 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ci i2c_dev->curr_msg = msgs; 3608c2ecf20Sopenharmony_ci i2c_dev->num_msgs = num; 3618c2ecf20Sopenharmony_ci reinit_completion(&i2c_dev->completion); 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci bcm2835_i2c_start_transfer(i2c_dev); 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci time_left = wait_for_completion_timeout(&i2c_dev->completion, 3668c2ecf20Sopenharmony_ci adap->timeout); 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci bcm2835_i2c_finish_transfer(i2c_dev); 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci if (!time_left) { 3718c2ecf20Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 3728c2ecf20Sopenharmony_ci BCM2835_I2C_C_CLEAR); 3738c2ecf20Sopenharmony_ci dev_err(i2c_dev->dev, "i2c transfer timed out\n"); 3748c2ecf20Sopenharmony_ci return -ETIMEDOUT; 3758c2ecf20Sopenharmony_ci } 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci if (!i2c_dev->msg_err) 3788c2ecf20Sopenharmony_ci return num; 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci dev_dbg(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err); 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci if (i2c_dev->msg_err & BCM2835_I2C_S_ERR) 3838c2ecf20Sopenharmony_ci return -EREMOTEIO; 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci return -EIO; 3868c2ecf20Sopenharmony_ci} 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_cistatic u32 bcm2835_i2c_func(struct i2c_adapter *adap) 3898c2ecf20Sopenharmony_ci{ 3908c2ecf20Sopenharmony_ci return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 3918c2ecf20Sopenharmony_ci} 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_cistatic const struct i2c_algorithm bcm2835_i2c_algo = { 3948c2ecf20Sopenharmony_ci .master_xfer = bcm2835_i2c_xfer, 3958c2ecf20Sopenharmony_ci .functionality = bcm2835_i2c_func, 3968c2ecf20Sopenharmony_ci}; 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci/* 3998c2ecf20Sopenharmony_ci * The BCM2835 was reported to have problems with clock stretching: 4008c2ecf20Sopenharmony_ci * https://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html 4018c2ecf20Sopenharmony_ci * https://www.raspberrypi.org/forums/viewtopic.php?p=146272 4028c2ecf20Sopenharmony_ci */ 4038c2ecf20Sopenharmony_cistatic const struct i2c_adapter_quirks bcm2835_i2c_quirks = { 4048c2ecf20Sopenharmony_ci .flags = I2C_AQ_NO_CLK_STRETCH, 4058c2ecf20Sopenharmony_ci}; 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_cistatic int bcm2835_i2c_probe(struct platform_device *pdev) 4088c2ecf20Sopenharmony_ci{ 4098c2ecf20Sopenharmony_ci struct bcm2835_i2c_dev *i2c_dev; 4108c2ecf20Sopenharmony_ci struct resource *mem, *irq; 4118c2ecf20Sopenharmony_ci int ret; 4128c2ecf20Sopenharmony_ci struct i2c_adapter *adap; 4138c2ecf20Sopenharmony_ci struct clk *mclk; 4148c2ecf20Sopenharmony_ci u32 bus_clk_rate; 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); 4178c2ecf20Sopenharmony_ci if (!i2c_dev) 4188c2ecf20Sopenharmony_ci return -ENOMEM; 4198c2ecf20Sopenharmony_ci platform_set_drvdata(pdev, i2c_dev); 4208c2ecf20Sopenharmony_ci i2c_dev->dev = &pdev->dev; 4218c2ecf20Sopenharmony_ci init_completion(&i2c_dev->completion); 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 4248c2ecf20Sopenharmony_ci i2c_dev->regs = devm_ioremap_resource(&pdev->dev, mem); 4258c2ecf20Sopenharmony_ci if (IS_ERR(i2c_dev->regs)) 4268c2ecf20Sopenharmony_ci return PTR_ERR(i2c_dev->regs); 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci mclk = devm_clk_get(&pdev->dev, NULL); 4298c2ecf20Sopenharmony_ci if (IS_ERR(mclk)) 4308c2ecf20Sopenharmony_ci return dev_err_probe(&pdev->dev, PTR_ERR(mclk), 4318c2ecf20Sopenharmony_ci "Could not get clock\n"); 4328c2ecf20Sopenharmony_ci 4338c2ecf20Sopenharmony_ci i2c_dev->bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev); 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_ci if (IS_ERR(i2c_dev->bus_clk)) { 4368c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "Could not register clock\n"); 4378c2ecf20Sopenharmony_ci return PTR_ERR(i2c_dev->bus_clk); 4388c2ecf20Sopenharmony_ci } 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", 4418c2ecf20Sopenharmony_ci &bus_clk_rate); 4428c2ecf20Sopenharmony_ci if (ret < 0) { 4438c2ecf20Sopenharmony_ci dev_warn(&pdev->dev, 4448c2ecf20Sopenharmony_ci "Could not read clock-frequency property\n"); 4458c2ecf20Sopenharmony_ci bus_clk_rate = I2C_MAX_STANDARD_MODE_FREQ; 4468c2ecf20Sopenharmony_ci } 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_ci ret = clk_set_rate_exclusive(i2c_dev->bus_clk, bus_clk_rate); 4498c2ecf20Sopenharmony_ci if (ret < 0) { 4508c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "Could not set clock frequency\n"); 4518c2ecf20Sopenharmony_ci return ret; 4528c2ecf20Sopenharmony_ci } 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci ret = clk_prepare_enable(i2c_dev->bus_clk); 4558c2ecf20Sopenharmony_ci if (ret) { 4568c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "Couldn't prepare clock"); 4578c2ecf20Sopenharmony_ci return ret; 4588c2ecf20Sopenharmony_ci } 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 4618c2ecf20Sopenharmony_ci if (!irq) { 4628c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "No IRQ resource\n"); 4638c2ecf20Sopenharmony_ci return -ENODEV; 4648c2ecf20Sopenharmony_ci } 4658c2ecf20Sopenharmony_ci i2c_dev->irq = irq->start; 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_ci ret = request_irq(i2c_dev->irq, bcm2835_i2c_isr, IRQF_SHARED, 4688c2ecf20Sopenharmony_ci dev_name(&pdev->dev), i2c_dev); 4698c2ecf20Sopenharmony_ci if (ret) { 4708c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "Could not request IRQ\n"); 4718c2ecf20Sopenharmony_ci return -ENODEV; 4728c2ecf20Sopenharmony_ci } 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci adap = &i2c_dev->adapter; 4758c2ecf20Sopenharmony_ci i2c_set_adapdata(adap, i2c_dev); 4768c2ecf20Sopenharmony_ci adap->owner = THIS_MODULE; 4778c2ecf20Sopenharmony_ci adap->class = I2C_CLASS_DEPRECATED; 4788c2ecf20Sopenharmony_ci snprintf(adap->name, sizeof(adap->name), "bcm2835 (%s)", 4798c2ecf20Sopenharmony_ci of_node_full_name(pdev->dev.of_node)); 4808c2ecf20Sopenharmony_ci adap->algo = &bcm2835_i2c_algo; 4818c2ecf20Sopenharmony_ci adap->dev.parent = &pdev->dev; 4828c2ecf20Sopenharmony_ci adap->dev.of_node = pdev->dev.of_node; 4838c2ecf20Sopenharmony_ci adap->quirks = of_device_get_match_data(&pdev->dev); 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci /* 4868c2ecf20Sopenharmony_ci * Disable the hardware clock stretching timeout. SMBUS 4878c2ecf20Sopenharmony_ci * specifies a limit for how long the device can stretch the 4888c2ecf20Sopenharmony_ci * clock, but core I2C doesn't. 4898c2ecf20Sopenharmony_ci */ 4908c2ecf20Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_CLKT, 0); 4918c2ecf20Sopenharmony_ci bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0); 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci ret = i2c_add_adapter(adap); 4948c2ecf20Sopenharmony_ci if (ret) 4958c2ecf20Sopenharmony_ci free_irq(i2c_dev->irq, i2c_dev); 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci return ret; 4988c2ecf20Sopenharmony_ci} 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_cistatic int bcm2835_i2c_remove(struct platform_device *pdev) 5018c2ecf20Sopenharmony_ci{ 5028c2ecf20Sopenharmony_ci struct bcm2835_i2c_dev *i2c_dev = platform_get_drvdata(pdev); 5038c2ecf20Sopenharmony_ci 5048c2ecf20Sopenharmony_ci clk_rate_exclusive_put(i2c_dev->bus_clk); 5058c2ecf20Sopenharmony_ci clk_disable_unprepare(i2c_dev->bus_clk); 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_ci free_irq(i2c_dev->irq, i2c_dev); 5088c2ecf20Sopenharmony_ci i2c_del_adapter(&i2c_dev->adapter); 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_ci return 0; 5118c2ecf20Sopenharmony_ci} 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_cistatic const struct of_device_id bcm2835_i2c_of_match[] = { 5148c2ecf20Sopenharmony_ci { .compatible = "brcm,bcm2711-i2c" }, 5158c2ecf20Sopenharmony_ci { .compatible = "brcm,bcm2835-i2c", .data = &bcm2835_i2c_quirks }, 5168c2ecf20Sopenharmony_ci {}, 5178c2ecf20Sopenharmony_ci}; 5188c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, bcm2835_i2c_of_match); 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_cistatic struct platform_driver bcm2835_i2c_driver = { 5218c2ecf20Sopenharmony_ci .probe = bcm2835_i2c_probe, 5228c2ecf20Sopenharmony_ci .remove = bcm2835_i2c_remove, 5238c2ecf20Sopenharmony_ci .driver = { 5248c2ecf20Sopenharmony_ci .name = "i2c-bcm2835", 5258c2ecf20Sopenharmony_ci .of_match_table = bcm2835_i2c_of_match, 5268c2ecf20Sopenharmony_ci }, 5278c2ecf20Sopenharmony_ci}; 5288c2ecf20Sopenharmony_cimodule_platform_driver(bcm2835_i2c_driver); 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ciMODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>"); 5318c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("BCM2835 I2C bus adapter"); 5328c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 5338c2ecf20Sopenharmony_ciMODULE_ALIAS("platform:i2c-bcm2835"); 534