1/* 2 * Copyright (c) 2003-2015 Broadcom Corporation 3 * 4 * This file is licensed under the terms of the GNU General Public 5 * License version 2. This program is licensed "as is" without any 6 * warranty of any kind, whether express or implied. 7 */ 8 9#include <linux/completion.h> 10#include <linux/i2c.h> 11#include <linux/init.h> 12#include <linux/interrupt.h> 13#include <linux/io.h> 14#include <linux/kernel.h> 15#include <linux/module.h> 16#include <linux/platform_device.h> 17 18#define XLP9XX_I2C_DIV 0x0 19#define XLP9XX_I2C_CTRL 0x1 20#define XLP9XX_I2C_CMD 0x2 21#define XLP9XX_I2C_STATUS 0x3 22#define XLP9XX_I2C_MTXFIFO 0x4 23#define XLP9XX_I2C_MRXFIFO 0x5 24#define XLP9XX_I2C_MFIFOCTRL 0x6 25#define XLP9XX_I2C_STXFIFO 0x7 26#define XLP9XX_I2C_SRXFIFO 0x8 27#define XLP9XX_I2C_SFIFOCTRL 0x9 28#define XLP9XX_I2C_SLAVEADDR 0xA 29#define XLP9XX_I2C_OWNADDR 0xB 30#define XLP9XX_I2C_FIFOWCNT 0xC 31#define XLP9XX_I2C_INTEN 0xD 32#define XLP9XX_I2C_INTST 0xE 33#define XLP9XX_I2C_WAITCNT 0xF 34#define XLP9XX_I2C_TIMEOUT 0X10 35#define XLP9XX_I2C_GENCALLADDR 0x11 36 37#define XLP9XX_I2C_CMD_START BIT(7) 38#define XLP9XX_I2C_CMD_STOP BIT(6) 39#define XLP9XX_I2C_CMD_READ BIT(5) 40#define XLP9XX_I2C_CMD_WRITE BIT(4) 41#define XLP9XX_I2C_CMD_ACK BIT(3) 42 43#define XLP9XX_I2C_CTRL_MCTLEN_SHIFT 16 44#define XLP9XX_I2C_CTRL_MCTLEN_MASK 0xffff0000 45#define XLP9XX_I2C_CTRL_RST BIT(8) 46#define XLP9XX_I2C_CTRL_EN BIT(6) 47#define XLP9XX_I2C_CTRL_MASTER BIT(4) 48#define XLP9XX_I2C_CTRL_FIFORD BIT(1) 49#define XLP9XX_I2C_CTRL_ADDMODE BIT(0) 50 51#define XLP9XX_I2C_INTEN_NACKADDR BIT(25) 52#define XLP9XX_I2C_INTEN_SADDR BIT(13) 53#define XLP9XX_I2C_INTEN_DATADONE BIT(12) 54#define XLP9XX_I2C_INTEN_ARLOST BIT(11) 55#define XLP9XX_I2C_INTEN_MFIFOFULL BIT(4) 56#define XLP9XX_I2C_INTEN_MFIFOEMTY BIT(3) 57#define XLP9XX_I2C_INTEN_MFIFOHI BIT(2) 58#define XLP9XX_I2C_INTEN_BUSERR BIT(0) 59 60#define XLP9XX_I2C_MFIFOCTRL_HITH_SHIFT 8 61#define XLP9XX_I2C_MFIFOCTRL_LOTH_SHIFT 0 62#define XLP9XX_I2C_MFIFOCTRL_RST BIT(16) 63 64#define XLP9XX_I2C_SLAVEADDR_RW BIT(0) 65#define XLP9XX_I2C_SLAVEADDR_ADDR_SHIFT 1 66 67#define XLP9XX_I2C_IP_CLK_FREQ 133000000UL 68#define XLP9XX_I2C_DEFAULT_FREQ 100000 69#define XLP9XX_I2C_HIGH_FREQ 400000 70#define XLP9XX_I2C_FIFO_SIZE 0x80U 71#define XLP9XX_I2C_TIMEOUT_MS 1000 72 73#define XLP9XX_I2C_FIFO_WCNT_MASK 0xff 74#define XLP9XX_I2C_STATUS_ERRMASK (XLP9XX_I2C_INTEN_ARLOST | \ 75 XLP9XX_I2C_INTEN_NACKADDR | XLP9XX_I2C_INTEN_BUSERR) 76 77struct xlp9xx_i2c_dev { 78 struct device *dev; 79 struct i2c_adapter adapter; 80 struct completion msg_complete; 81 int irq; 82 bool msg_read; 83 u32 __iomem *base; 84 u32 msg_buf_remaining; 85 u32 msg_len; 86 u32 clk_hz; 87 u32 msg_err; 88 u8 *msg_buf; 89}; 90 91static inline void xlp9xx_write_i2c_reg(struct xlp9xx_i2c_dev *priv, 92 unsigned long reg, u32 val) 93{ 94 writel(val, priv->base + reg); 95} 96 97static inline u32 xlp9xx_read_i2c_reg(struct xlp9xx_i2c_dev *priv, 98 unsigned long reg) 99{ 100 return readl(priv->base + reg); 101} 102 103static void xlp9xx_i2c_mask_irq(struct xlp9xx_i2c_dev *priv, u32 mask) 104{ 105 u32 inten; 106 107 inten = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTEN) & ~mask; 108 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, inten); 109} 110 111static void xlp9xx_i2c_unmask_irq(struct xlp9xx_i2c_dev *priv, u32 mask) 112{ 113 u32 inten; 114 115 inten = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTEN) | mask; 116 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, inten); 117} 118 119static void xlp9xx_i2c_update_rx_fifo_thres(struct xlp9xx_i2c_dev *priv) 120{ 121 u32 thres; 122 123 thres = min(priv->msg_buf_remaining, XLP9XX_I2C_FIFO_SIZE); 124 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL, 125 thres << XLP9XX_I2C_MFIFOCTRL_HITH_SHIFT); 126} 127 128static void xlp9xx_i2c_fill_tx_fifo(struct xlp9xx_i2c_dev *priv) 129{ 130 u32 len, i; 131 u8 *buf = priv->msg_buf; 132 133 len = min(priv->msg_buf_remaining, XLP9XX_I2C_FIFO_SIZE); 134 for (i = 0; i < len; i++) 135 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MTXFIFO, buf[i]); 136 priv->msg_buf_remaining -= len; 137 priv->msg_buf += len; 138} 139 140static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv) 141{ 142 u32 len, i; 143 u8 *buf = priv->msg_buf; 144 145 len = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_FIFOWCNT) & 146 XLP9XX_I2C_FIFO_WCNT_MASK; 147 len = min(priv->msg_buf_remaining, len); 148 for (i = 0; i < len; i++, buf++) 149 *buf = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO); 150 151 priv->msg_buf_remaining -= len; 152 priv->msg_buf = buf; 153 154 if (priv->msg_buf_remaining) 155 xlp9xx_i2c_update_rx_fifo_thres(priv); 156} 157 158static irqreturn_t xlp9xx_i2c_isr(int irq, void *dev_id) 159{ 160 struct xlp9xx_i2c_dev *priv = dev_id; 161 u32 status; 162 163 status = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTST); 164 if (status == 0) 165 return IRQ_NONE; 166 167 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTST, status); 168 if (status & XLP9XX_I2C_STATUS_ERRMASK) { 169 priv->msg_err = status; 170 goto xfer_done; 171 } 172 173 /* SADDR ACK for SMBUS_QUICK */ 174 if ((status & XLP9XX_I2C_INTEN_SADDR) && (priv->msg_len == 0)) 175 goto xfer_done; 176 177 if (!priv->msg_read) { 178 if (status & XLP9XX_I2C_INTEN_MFIFOEMTY) { 179 /* TX FIFO got empty, fill it up again */ 180 if (priv->msg_buf_remaining) 181 xlp9xx_i2c_fill_tx_fifo(priv); 182 else 183 xlp9xx_i2c_mask_irq(priv, 184 XLP9XX_I2C_INTEN_MFIFOEMTY); 185 } 186 } else { 187 if (status & (XLP9XX_I2C_INTEN_DATADONE | 188 XLP9XX_I2C_INTEN_MFIFOHI)) { 189 /* data is in FIFO, read it */ 190 if (priv->msg_buf_remaining) 191 xlp9xx_i2c_drain_rx_fifo(priv); 192 } 193 } 194 195 /* Transfer complete */ 196 if (status & XLP9XX_I2C_INTEN_DATADONE) 197 goto xfer_done; 198 199 return IRQ_HANDLED; 200 201xfer_done: 202 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0); 203 complete(&priv->msg_complete); 204 return IRQ_HANDLED; 205} 206 207static int xlp9xx_i2c_init(struct xlp9xx_i2c_dev *priv) 208{ 209 u32 prescale; 210 211 /* 212 * The controller uses 5 * SCL clock internally. 213 * So prescale value should be divided by 5. 214 */ 215 prescale = DIV_ROUND_UP(XLP9XX_I2C_IP_CLK_FREQ, priv->clk_hz); 216 prescale = ((prescale - 8) / 5) - 1; 217 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, XLP9XX_I2C_CTRL_RST); 218 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, XLP9XX_I2C_CTRL_EN | 219 XLP9XX_I2C_CTRL_MASTER); 220 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_DIV, prescale); 221 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0); 222 223 return 0; 224} 225 226static int xlp9xx_i2c_xfer_msg(struct xlp9xx_i2c_dev *priv, struct i2c_msg *msg, 227 int last_msg) 228{ 229 unsigned long timeleft; 230 u32 intr_mask, cmd, val; 231 232 priv->msg_buf = msg->buf; 233 priv->msg_buf_remaining = priv->msg_len = msg->len; 234 priv->msg_err = 0; 235 priv->msg_read = (msg->flags & I2C_M_RD); 236 reinit_completion(&priv->msg_complete); 237 238 /* Reset FIFO */ 239 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL, 240 XLP9XX_I2C_MFIFOCTRL_RST); 241 242 /* set FIFO threshold if reading */ 243 if (priv->msg_read) 244 xlp9xx_i2c_update_rx_fifo_thres(priv); 245 246 /* set slave addr */ 247 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_SLAVEADDR, 248 (msg->addr << XLP9XX_I2C_SLAVEADDR_ADDR_SHIFT) | 249 (priv->msg_read ? XLP9XX_I2C_SLAVEADDR_RW : 0)); 250 251 /* Build control word for transfer */ 252 val = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_CTRL); 253 if (!priv->msg_read) 254 val &= ~XLP9XX_I2C_CTRL_FIFORD; 255 else 256 val |= XLP9XX_I2C_CTRL_FIFORD; /* read */ 257 258 if (msg->flags & I2C_M_TEN) 259 val |= XLP9XX_I2C_CTRL_ADDMODE; /* 10-bit address mode*/ 260 else 261 val &= ~XLP9XX_I2C_CTRL_ADDMODE; 262 263 /* set data length to be transferred */ 264 val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) | 265 (msg->len << XLP9XX_I2C_CTRL_MCTLEN_SHIFT); 266 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val); 267 268 /* fill fifo during tx */ 269 if (!priv->msg_read) 270 xlp9xx_i2c_fill_tx_fifo(priv); 271 272 /* set interrupt mask */ 273 intr_mask = (XLP9XX_I2C_INTEN_ARLOST | XLP9XX_I2C_INTEN_BUSERR | 274 XLP9XX_I2C_INTEN_NACKADDR | XLP9XX_I2C_INTEN_DATADONE); 275 276 if (priv->msg_read) { 277 intr_mask |= XLP9XX_I2C_INTEN_MFIFOHI; 278 if (msg->len == 0) 279 intr_mask |= XLP9XX_I2C_INTEN_SADDR; 280 } else { 281 if (msg->len == 0) 282 intr_mask |= XLP9XX_I2C_INTEN_SADDR; 283 else 284 intr_mask |= XLP9XX_I2C_INTEN_MFIFOEMTY; 285 } 286 xlp9xx_i2c_unmask_irq(priv, intr_mask); 287 288 /* set cmd reg */ 289 cmd = XLP9XX_I2C_CMD_START; 290 cmd |= (priv->msg_read ? XLP9XX_I2C_CMD_READ : XLP9XX_I2C_CMD_WRITE); 291 if (last_msg) 292 cmd |= XLP9XX_I2C_CMD_STOP; 293 294 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CMD, cmd); 295 296 timeleft = msecs_to_jiffies(XLP9XX_I2C_TIMEOUT_MS); 297 timeleft = wait_for_completion_timeout(&priv->msg_complete, timeleft); 298 299 if (priv->msg_err) { 300 dev_dbg(priv->dev, "transfer error %x!\n", priv->msg_err); 301 if (priv->msg_err & XLP9XX_I2C_INTEN_BUSERR) 302 xlp9xx_i2c_init(priv); 303 return -EIO; 304 } 305 306 if (timeleft == 0) { 307 dev_dbg(priv->dev, "i2c transfer timed out!\n"); 308 xlp9xx_i2c_init(priv); 309 return -ETIMEDOUT; 310 } 311 312 return 0; 313} 314 315static int xlp9xx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, 316 int num) 317{ 318 int i, ret; 319 struct xlp9xx_i2c_dev *priv = i2c_get_adapdata(adap); 320 321 for (i = 0; i < num; i++) { 322 ret = xlp9xx_i2c_xfer_msg(priv, &msgs[i], i == num - 1); 323 if (ret != 0) 324 return ret; 325 } 326 327 return num; 328} 329 330static u32 xlp9xx_i2c_functionality(struct i2c_adapter *adapter) 331{ 332 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | 333 I2C_FUNC_10BIT_ADDR; 334} 335 336static struct i2c_algorithm xlp9xx_i2c_algo = { 337 .master_xfer = xlp9xx_i2c_xfer, 338 .functionality = xlp9xx_i2c_functionality, 339}; 340 341static int xlp9xx_i2c_get_frequency(struct platform_device *pdev, 342 struct xlp9xx_i2c_dev *priv) 343{ 344 struct device_node *np = pdev->dev.of_node; 345 u32 freq; 346 int err; 347 348 err = of_property_read_u32(np, "clock-frequency", &freq); 349 if (err) { 350 freq = XLP9XX_I2C_DEFAULT_FREQ; 351 dev_dbg(&pdev->dev, "using default frequency %u\n", freq); 352 } else if (freq == 0 || freq > XLP9XX_I2C_HIGH_FREQ) { 353 dev_warn(&pdev->dev, "invalid frequency %u, using default\n", 354 freq); 355 freq = XLP9XX_I2C_DEFAULT_FREQ; 356 } 357 priv->clk_hz = freq; 358 359 return 0; 360} 361 362static int xlp9xx_i2c_probe(struct platform_device *pdev) 363{ 364 struct xlp9xx_i2c_dev *priv; 365 struct resource *res; 366 int err = 0; 367 368 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 369 if (!priv) 370 return -ENOMEM; 371 372 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 373 priv->base = devm_ioremap_resource(&pdev->dev, res); 374 if (IS_ERR(priv->base)) 375 return PTR_ERR(priv->base); 376 377 priv->irq = platform_get_irq(pdev, 0); 378 if (priv->irq <= 0) { 379 dev_err(&pdev->dev, "invalid irq!\n"); 380 return priv->irq; 381 } 382 383 xlp9xx_i2c_get_frequency(pdev, priv); 384 xlp9xx_i2c_init(priv); 385 386 err = devm_request_irq(&pdev->dev, priv->irq, xlp9xx_i2c_isr, 0, 387 pdev->name, priv); 388 if (err) { 389 dev_err(&pdev->dev, "IRQ request failed!\n"); 390 return err; 391 } 392 393 init_completion(&priv->msg_complete); 394 priv->adapter.dev.parent = &pdev->dev; 395 priv->adapter.algo = &xlp9xx_i2c_algo; 396 priv->adapter.dev.of_node = pdev->dev.of_node; 397 priv->dev = &pdev->dev; 398 399 snprintf(priv->adapter.name, sizeof(priv->adapter.name), "xlp9xx-i2c"); 400 i2c_set_adapdata(&priv->adapter, priv); 401 402 err = i2c_add_adapter(&priv->adapter); 403 if (err) { 404 dev_err(&pdev->dev, "failed to add I2C adapter!\n"); 405 return err; 406 } 407 408 platform_set_drvdata(pdev, priv); 409 dev_dbg(&pdev->dev, "I2C bus:%d added\n", priv->adapter.nr); 410 411 return 0; 412} 413 414static int xlp9xx_i2c_remove(struct platform_device *pdev) 415{ 416 struct xlp9xx_i2c_dev *priv; 417 418 priv = platform_get_drvdata(pdev); 419 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0); 420 synchronize_irq(priv->irq); 421 i2c_del_adapter(&priv->adapter); 422 xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, 0); 423 424 return 0; 425} 426 427static const struct of_device_id xlp9xx_i2c_of_match[] = { 428 { .compatible = "netlogic,xlp980-i2c", }, 429 { /* sentinel */ }, 430}; 431 432static struct platform_driver xlp9xx_i2c_driver = { 433 .probe = xlp9xx_i2c_probe, 434 .remove = xlp9xx_i2c_remove, 435 .driver = { 436 .name = "xlp9xx-i2c", 437 .of_match_table = xlp9xx_i2c_of_match, 438 }, 439}; 440 441module_platform_driver(xlp9xx_i2c_driver); 442 443MODULE_AUTHOR("Subhendu Sekhar Behera <sbehera@broadcom.com>"); 444MODULE_DESCRIPTION("XLP9XX/5XX I2C Bus Controller Driver"); 445MODULE_LICENSE("GPL v2"); 446