1/* 2 * Copyright (C) 2014 Broadcom Corporation 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation version 2. 7 * 8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 9 * kind, whether express or implied; without even the implied warranty 10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13 14#include <linux/delay.h> 15#include <linux/i2c.h> 16#include <linux/interrupt.h> 17#include <linux/io.h> 18#include <linux/kernel.h> 19#include <linux/module.h> 20#include <linux/platform_device.h> 21#include <linux/slab.h> 22 23#define CFG_OFFSET 0x00 24#define CFG_RESET_SHIFT 31 25#define CFG_EN_SHIFT 30 26#define CFG_M_RETRY_CNT_SHIFT 16 27#define CFG_M_RETRY_CNT_MASK 0x0f 28 29#define TIM_CFG_OFFSET 0x04 30#define TIM_CFG_MODE_400_SHIFT 31 31 32#define M_FIFO_CTRL_OFFSET 0x0c 33#define M_FIFO_RX_FLUSH_SHIFT 31 34#define M_FIFO_TX_FLUSH_SHIFT 30 35#define M_FIFO_RX_CNT_SHIFT 16 36#define M_FIFO_RX_CNT_MASK 0x7f 37#define M_FIFO_RX_THLD_SHIFT 8 38#define M_FIFO_RX_THLD_MASK 0x3f 39 40#define M_CMD_OFFSET 0x30 41#define M_CMD_START_BUSY_SHIFT 31 42#define M_CMD_STATUS_SHIFT 25 43#define M_CMD_STATUS_MASK 0x07 44#define M_CMD_STATUS_SUCCESS 0x0 45#define M_CMD_STATUS_LOST_ARB 0x1 46#define M_CMD_STATUS_NACK_ADDR 0x2 47#define M_CMD_STATUS_NACK_DATA 0x3 48#define M_CMD_STATUS_TIMEOUT 0x4 49#define M_CMD_PROTOCOL_SHIFT 9 50#define M_CMD_PROTOCOL_MASK 0xf 51#define M_CMD_PROTOCOL_BLK_WR 0x7 52#define M_CMD_PROTOCOL_BLK_RD 0x8 53#define M_CMD_PEC_SHIFT 8 54#define M_CMD_RD_CNT_SHIFT 0 55#define M_CMD_RD_CNT_MASK 0xff 56 57#define IE_OFFSET 0x38 58#define IE_M_RX_FIFO_FULL_SHIFT 31 59#define IE_M_RX_THLD_SHIFT 30 60#define IE_M_START_BUSY_SHIFT 28 61 62#define IS_OFFSET 0x3c 63#define IS_M_RX_FIFO_FULL_SHIFT 31 64#define IS_M_RX_THLD_SHIFT 30 65#define IS_M_START_BUSY_SHIFT 28 66 67#define M_TX_OFFSET 0x40 68#define M_TX_WR_STATUS_SHIFT 31 69#define M_TX_DATA_SHIFT 0 70#define M_TX_DATA_MASK 0xff 71 72#define M_RX_OFFSET 0x44 73#define M_RX_STATUS_SHIFT 30 74#define M_RX_STATUS_MASK 0x03 75#define M_RX_PEC_ERR_SHIFT 29 76#define M_RX_DATA_SHIFT 0 77#define M_RX_DATA_MASK 0xff 78 79#define I2C_TIMEOUT_MESC 100 80#define M_TX_RX_FIFO_SIZE 64 81 82enum bus_speed_index { 83 I2C_SPD_100K = 0, 84 I2C_SPD_400K, 85}; 86 87struct bcm_iproc_i2c_dev { 88 struct device *device; 89 int irq; 90 91 void __iomem *base; 92 93 struct i2c_adapter adapter; 94 95 struct completion done; 96 int xfer_is_done; 97}; 98 99/* 100 * Can be expanded in the future if more interrupt status bits are utilized 101 */ 102#define ISR_MASK (1 << IS_M_START_BUSY_SHIFT) 103 104static irqreturn_t bcm_iproc_i2c_isr(int irq, void *data) 105{ 106 struct bcm_iproc_i2c_dev *iproc_i2c = data; 107 u32 status = readl(iproc_i2c->base + IS_OFFSET); 108 109 status &= ISR_MASK; 110 111 if (!status) 112 return IRQ_NONE; 113 114 writel(status, iproc_i2c->base + IS_OFFSET); 115 iproc_i2c->xfer_is_done = 1; 116 complete_all(&iproc_i2c->done); 117 118 return IRQ_HANDLED; 119} 120 121static int bcm_iproc_i2c_check_status(struct bcm_iproc_i2c_dev *iproc_i2c, 122 struct i2c_msg *msg) 123{ 124 u32 val; 125 126 val = readl(iproc_i2c->base + M_CMD_OFFSET); 127 val = (val >> M_CMD_STATUS_SHIFT) & M_CMD_STATUS_MASK; 128 129 switch (val) { 130 case M_CMD_STATUS_SUCCESS: 131 return 0; 132 133 case M_CMD_STATUS_LOST_ARB: 134 dev_dbg(iproc_i2c->device, "lost bus arbitration\n"); 135 return -EAGAIN; 136 137 case M_CMD_STATUS_NACK_ADDR: 138 dev_dbg(iproc_i2c->device, "NAK addr:0x%02x\n", msg->addr); 139 return -ENXIO; 140 141 case M_CMD_STATUS_NACK_DATA: 142 dev_dbg(iproc_i2c->device, "NAK data\n"); 143 return -ENXIO; 144 145 case M_CMD_STATUS_TIMEOUT: 146 dev_dbg(iproc_i2c->device, "bus timeout\n"); 147 return -ETIMEDOUT; 148 149 default: 150 dev_dbg(iproc_i2c->device, "unknown error code=%d\n", val); 151 return -EIO; 152 } 153} 154 155static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c, 156 struct i2c_msg *msg) 157{ 158 int ret, i; 159 u8 addr; 160 u32 val; 161 unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT_MESC); 162 163 /* check if bus is busy */ 164 if (!!(readl(iproc_i2c->base + M_CMD_OFFSET) & 165 BIT(M_CMD_START_BUSY_SHIFT))) { 166 dev_warn(iproc_i2c->device, "bus is busy\n"); 167 return -EBUSY; 168 } 169 170 /* format and load slave address into the TX FIFO */ 171 addr = msg->addr << 1 | (msg->flags & I2C_M_RD ? 1 : 0); 172 writel(addr, iproc_i2c->base + M_TX_OFFSET); 173 174 /* for a write transaction, load data into the TX FIFO */ 175 if (!(msg->flags & I2C_M_RD)) { 176 for (i = 0; i < msg->len; i++) { 177 val = msg->buf[i]; 178 179 /* mark the last byte */ 180 if (i == msg->len - 1) 181 val |= 1 << M_TX_WR_STATUS_SHIFT; 182 183 writel(val, iproc_i2c->base + M_TX_OFFSET); 184 } 185 } 186 187 /* mark as incomplete before starting the transaction */ 188 reinit_completion(&iproc_i2c->done); 189 iproc_i2c->xfer_is_done = 0; 190 191 /* 192 * Enable the "start busy" interrupt, which will be triggered after the 193 * transaction is done, i.e., the internal start_busy bit, transitions 194 * from 1 to 0. 195 */ 196 writel(1 << IE_M_START_BUSY_SHIFT, iproc_i2c->base + IE_OFFSET); 197 198 /* 199 * Now we can activate the transfer. For a read operation, specify the 200 * number of bytes to read 201 */ 202 val = 1 << M_CMD_START_BUSY_SHIFT; 203 if (msg->flags & I2C_M_RD) { 204 val |= (M_CMD_PROTOCOL_BLK_RD << M_CMD_PROTOCOL_SHIFT) | 205 (msg->len << M_CMD_RD_CNT_SHIFT); 206 } else { 207 val |= (M_CMD_PROTOCOL_BLK_WR << M_CMD_PROTOCOL_SHIFT); 208 } 209 writel(val, iproc_i2c->base + M_CMD_OFFSET); 210 211 time_left = wait_for_completion_timeout(&iproc_i2c->done, time_left); 212 213 /* disable all interrupts */ 214 writel(0, iproc_i2c->base + IE_OFFSET); 215 /* read it back to flush the write */ 216 readl(iproc_i2c->base + IE_OFFSET); 217 218 /* make sure the interrupt handler isn't running */ 219 synchronize_irq(iproc_i2c->irq); 220 221 if (!time_left && !iproc_i2c->xfer_is_done) { 222 dev_err(iproc_i2c->device, "transaction timed out\n"); 223 224 /* flush FIFOs */ 225 val = (1 << M_FIFO_RX_FLUSH_SHIFT) | 226 (1 << M_FIFO_TX_FLUSH_SHIFT); 227 writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); 228 return -ETIMEDOUT; 229 } 230 231 ret = bcm_iproc_i2c_check_status(iproc_i2c, msg); 232 if (ret) { 233 /* flush both TX/RX FIFOs */ 234 val = (1 << M_FIFO_RX_FLUSH_SHIFT) | 235 (1 << M_FIFO_TX_FLUSH_SHIFT); 236 writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); 237 return ret; 238 } 239 240 /* 241 * For a read operation, we now need to load the data from FIFO 242 * into the memory buffer 243 */ 244 if (msg->flags & I2C_M_RD) { 245 for (i = 0; i < msg->len; i++) { 246 msg->buf[i] = (readl(iproc_i2c->base + M_RX_OFFSET) >> 247 M_RX_DATA_SHIFT) & M_RX_DATA_MASK; 248 } 249 } 250 251 return 0; 252} 253 254static int bcm_iproc_i2c_xfer(struct i2c_adapter *adapter, 255 struct i2c_msg msgs[], int num) 256{ 257 struct bcm_iproc_i2c_dev *iproc_i2c = i2c_get_adapdata(adapter); 258 int ret, i; 259 260 /* go through all messages */ 261 for (i = 0; i < num; i++) { 262 ret = bcm_iproc_i2c_xfer_single_msg(iproc_i2c, &msgs[i]); 263 if (ret) { 264 dev_dbg(iproc_i2c->device, "xfer failed\n"); 265 return ret; 266 } 267 } 268 269 return num; 270} 271 272static uint32_t bcm_iproc_i2c_functionality(struct i2c_adapter *adap) 273{ 274 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 275} 276 277static const struct i2c_algorithm bcm_iproc_algo = { 278 .master_xfer = bcm_iproc_i2c_xfer, 279 .functionality = bcm_iproc_i2c_functionality, 280}; 281 282static struct i2c_adapter_quirks bcm_iproc_i2c_quirks = { 283 /* need to reserve one byte in the FIFO for the slave address */ 284 .max_read_len = M_TX_RX_FIFO_SIZE - 1, 285 .max_write_len = M_TX_RX_FIFO_SIZE - 1, 286}; 287 288static int bcm_iproc_i2c_cfg_speed(struct bcm_iproc_i2c_dev *iproc_i2c) 289{ 290 unsigned int bus_speed; 291 u32 val; 292 int ret = of_property_read_u32(iproc_i2c->device->of_node, 293 "clock-frequency", &bus_speed); 294 if (ret < 0) { 295 dev_info(iproc_i2c->device, 296 "unable to interpret clock-frequency DT property\n"); 297 bus_speed = 100000; 298 } 299 300 if (bus_speed < 100000) { 301 dev_err(iproc_i2c->device, "%d Hz bus speed not supported\n", 302 bus_speed); 303 dev_err(iproc_i2c->device, 304 "valid speeds are 100khz and 400khz\n"); 305 return -EINVAL; 306 } else if (bus_speed < 400000) { 307 bus_speed = 100000; 308 } else { 309 bus_speed = 400000; 310 } 311 312 val = readl(iproc_i2c->base + TIM_CFG_OFFSET); 313 val &= ~(1 << TIM_CFG_MODE_400_SHIFT); 314 val |= (bus_speed == 400000) << TIM_CFG_MODE_400_SHIFT; 315 writel(val, iproc_i2c->base + TIM_CFG_OFFSET); 316 317 dev_info(iproc_i2c->device, "bus set to %u Hz\n", bus_speed); 318 319 return 0; 320} 321 322static int bcm_iproc_i2c_init(struct bcm_iproc_i2c_dev *iproc_i2c) 323{ 324 u32 val; 325 326 /* put controller in reset */ 327 val = readl(iproc_i2c->base + CFG_OFFSET); 328 val |= 1 << CFG_RESET_SHIFT; 329 val &= ~(1 << CFG_EN_SHIFT); 330 writel(val, iproc_i2c->base + CFG_OFFSET); 331 332 /* wait 100 usec per spec */ 333 udelay(100); 334 335 /* bring controller out of reset */ 336 val &= ~(1 << CFG_RESET_SHIFT); 337 writel(val, iproc_i2c->base + CFG_OFFSET); 338 339 /* flush TX/RX FIFOs and set RX FIFO threshold to zero */ 340 val = (1 << M_FIFO_RX_FLUSH_SHIFT) | (1 << M_FIFO_TX_FLUSH_SHIFT); 341 writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); 342 343 /* disable all interrupts */ 344 writel(0, iproc_i2c->base + IE_OFFSET); 345 346 /* clear all pending interrupts */ 347 writel(0xffffffff, iproc_i2c->base + IS_OFFSET); 348 349 return 0; 350} 351 352static void bcm_iproc_i2c_enable_disable(struct bcm_iproc_i2c_dev *iproc_i2c, 353 bool enable) 354{ 355 u32 val; 356 357 val = readl(iproc_i2c->base + CFG_OFFSET); 358 if (enable) 359 val |= BIT(CFG_EN_SHIFT); 360 else 361 val &= ~BIT(CFG_EN_SHIFT); 362 writel(val, iproc_i2c->base + CFG_OFFSET); 363} 364 365static int bcm_iproc_i2c_probe(struct platform_device *pdev) 366{ 367 int irq, ret = 0; 368 struct bcm_iproc_i2c_dev *iproc_i2c; 369 struct i2c_adapter *adap; 370 struct resource *res; 371 372 iproc_i2c = devm_kzalloc(&pdev->dev, sizeof(*iproc_i2c), 373 GFP_KERNEL); 374 if (!iproc_i2c) 375 return -ENOMEM; 376 377 platform_set_drvdata(pdev, iproc_i2c); 378 iproc_i2c->device = &pdev->dev; 379 init_completion(&iproc_i2c->done); 380 381 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 382 iproc_i2c->base = devm_ioremap_resource(iproc_i2c->device, res); 383 if (IS_ERR(iproc_i2c->base)) 384 return PTR_ERR(iproc_i2c->base); 385 386 ret = bcm_iproc_i2c_init(iproc_i2c); 387 if (ret) 388 return ret; 389 390 ret = bcm_iproc_i2c_cfg_speed(iproc_i2c); 391 if (ret) 392 return ret; 393 394 irq = platform_get_irq(pdev, 0); 395 if (irq <= 0) { 396 dev_err(iproc_i2c->device, "no irq resource\n"); 397 return irq; 398 } 399 iproc_i2c->irq = irq; 400 401 ret = devm_request_irq(iproc_i2c->device, irq, bcm_iproc_i2c_isr, 0, 402 pdev->name, iproc_i2c); 403 if (ret < 0) { 404 dev_err(iproc_i2c->device, "unable to request irq %i\n", irq); 405 return ret; 406 } 407 408 bcm_iproc_i2c_enable_disable(iproc_i2c, true); 409 410 adap = &iproc_i2c->adapter; 411 i2c_set_adapdata(adap, iproc_i2c); 412 strlcpy(adap->name, "Broadcom iProc I2C adapter", sizeof(adap->name)); 413 adap->algo = &bcm_iproc_algo; 414 adap->quirks = &bcm_iproc_i2c_quirks; 415 adap->dev.parent = &pdev->dev; 416 adap->dev.of_node = pdev->dev.of_node; 417 418 ret = i2c_add_adapter(adap); 419 if (ret) { 420 dev_err(iproc_i2c->device, "failed to add adapter\n"); 421 return ret; 422 } 423 424 return 0; 425} 426 427static int bcm_iproc_i2c_remove(struct platform_device *pdev) 428{ 429 struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev); 430 431 /* make sure there's no pending interrupt when we remove the adapter */ 432 writel(0, iproc_i2c->base + IE_OFFSET); 433 readl(iproc_i2c->base + IE_OFFSET); 434 synchronize_irq(iproc_i2c->irq); 435 436 i2c_del_adapter(&iproc_i2c->adapter); 437 bcm_iproc_i2c_enable_disable(iproc_i2c, false); 438 439 return 0; 440} 441 442static const struct of_device_id bcm_iproc_i2c_of_match[] = { 443 { .compatible = "brcm,iproc-i2c" }, 444 { /* sentinel */ } 445}; 446MODULE_DEVICE_TABLE(of, bcm_iproc_i2c_of_match); 447 448static struct platform_driver bcm_iproc_i2c_driver = { 449 .driver = { 450 .name = "bcm-iproc-i2c", 451 .of_match_table = bcm_iproc_i2c_of_match, 452 }, 453 .probe = bcm_iproc_i2c_probe, 454 .remove = bcm_iproc_i2c_remove, 455}; 456module_platform_driver(bcm_iproc_i2c_driver); 457 458MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>"); 459MODULE_DESCRIPTION("Broadcom iProc I2C Driver"); 460MODULE_LICENSE("GPL v2"); 461