root/drivers/i2c/busses/i2c-altera.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. altr_i2c_int_enable
  2. altr_i2c_int_clear
  3. altr_i2c_core_disable
  4. altr_i2c_core_enable
  5. altr_i2c_reset
  6. altr_i2c_stop
  7. altr_i2c_init
  8. altr_i2c_transfer
  9. altr_i2c_empty_rx_fifo
  10. altr_i2c_fill_tx_fifo
  11. altr_i2c_isr_quick
  12. altr_i2c_isr
  13. altr_i2c_xfer_msg
  14. altr_i2c_xfer
  15. altr_i2c_func
  16. altr_i2c_probe
  17. altr_i2c_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  Copyright Intel Corporation (C) 2017.
   4  *
   5  * Based on the i2c-axxia.c driver.
   6  */
   7 #include <linux/clk.h>
   8 #include <linux/clkdev.h>
   9 #include <linux/err.h>
  10 #include <linux/i2c.h>
  11 #include <linux/iopoll.h>
  12 #include <linux/interrupt.h>
  13 #include <linux/module.h>
  14 #include <linux/io.h>
  15 #include <linux/kernel.h>
  16 #include <linux/platform_device.h>
  17 
  18 #define ALTR_I2C_TFR_CMD        0x00    /* Transfer Command register */
  19 #define     ALTR_I2C_TFR_CMD_STA        BIT(9)  /* send START before byte */
  20 #define     ALTR_I2C_TFR_CMD_STO        BIT(8)  /* send STOP after byte */
  21 #define     ALTR_I2C_TFR_CMD_RW_D       BIT(0)  /* Direction of transfer */
  22 #define ALTR_I2C_RX_DATA        0x04    /* RX data FIFO register */
  23 #define ALTR_I2C_CTRL           0x08    /* Control register */
  24 #define     ALTR_I2C_CTRL_RXT_SHFT      4       /* RX FIFO Threshold */
  25 #define     ALTR_I2C_CTRL_TCT_SHFT      2       /* TFER CMD FIFO Threshold */
  26 #define     ALTR_I2C_CTRL_BSPEED        BIT(1)  /* Bus Speed (1=Fast) */
  27 #define     ALTR_I2C_CTRL_EN    BIT(0)  /* Enable Core (1=Enable) */
  28 #define ALTR_I2C_ISER           0x0C    /* Interrupt Status Enable register */
  29 #define     ALTR_I2C_ISER_RXOF_EN       BIT(4)  /* Enable RX OVERFLOW IRQ */
  30 #define     ALTR_I2C_ISER_ARB_EN        BIT(3)  /* Enable ARB LOST IRQ */
  31 #define     ALTR_I2C_ISER_NACK_EN       BIT(2)  /* Enable NACK DET IRQ */
  32 #define     ALTR_I2C_ISER_RXRDY_EN      BIT(1)  /* Enable RX Ready IRQ */
  33 #define     ALTR_I2C_ISER_TXRDY_EN      BIT(0)  /* Enable TX Ready IRQ */
  34 #define ALTR_I2C_ISR            0x10    /* Interrupt Status register */
  35 #define     ALTR_I2C_ISR_RXOF           BIT(4)  /* RX OVERFLOW IRQ */
  36 #define     ALTR_I2C_ISR_ARB            BIT(3)  /* ARB LOST IRQ */
  37 #define     ALTR_I2C_ISR_NACK           BIT(2)  /* NACK DET IRQ */
  38 #define     ALTR_I2C_ISR_RXRDY          BIT(1)  /* RX Ready IRQ */
  39 #define     ALTR_I2C_ISR_TXRDY          BIT(0)  /* TX Ready IRQ */
  40 #define ALTR_I2C_STATUS         0x14    /* Status register */
  41 #define     ALTR_I2C_STAT_CORE          BIT(0)  /* Core Status (0=idle) */
  42 #define ALTR_I2C_TC_FIFO_LVL    0x18    /* Transfer FIFO LVL register */
  43 #define ALTR_I2C_RX_FIFO_LVL    0x1C    /* Receive FIFO LVL register */
  44 #define ALTR_I2C_SCL_LOW        0x20    /* SCL low count register */
  45 #define ALTR_I2C_SCL_HIGH       0x24    /* SCL high count register */
  46 #define ALTR_I2C_SDA_HOLD       0x28    /* SDA hold count register */
  47 
  48 #define ALTR_I2C_ALL_IRQ        (ALTR_I2C_ISR_RXOF | ALTR_I2C_ISR_ARB | \
  49                                  ALTR_I2C_ISR_NACK | ALTR_I2C_ISR_RXRDY | \
  50                                  ALTR_I2C_ISR_TXRDY)
  51 
  52 #define ALTR_I2C_THRESHOLD      0       /* IRQ Threshold at 1 element */
  53 #define ALTR_I2C_DFLT_FIFO_SZ   4
  54 #define ALTR_I2C_TIMEOUT        100000  /* 100ms */
  55 #define ALTR_I2C_XFER_TIMEOUT   (msecs_to_jiffies(250))
  56 
  57 /**
  58  * altr_i2c_dev - I2C device context
  59  * @base: pointer to register struct
  60  * @msg: pointer to current message
  61  * @msg_len: number of bytes transferred in msg
  62  * @msg_err: error code for completed message
  63  * @msg_complete: xfer completion object
  64  * @dev: device reference
  65  * @adapter: core i2c abstraction
  66  * @i2c_clk: clock reference for i2c input clock
  67  * @bus_clk_rate: current i2c bus clock rate
  68  * @buf: ptr to msg buffer for easier use.
  69  * @fifo_size: size of the FIFO passed in.
  70  * @isr_mask: cached copy of local ISR enables.
  71  * @isr_status: cached copy of local ISR status.
  72  * @lock: spinlock for IRQ synchronization.
  73  * @isr_mutex: mutex for IRQ thread.
  74  */
  75 struct altr_i2c_dev {
  76         void __iomem *base;
  77         struct i2c_msg *msg;
  78         size_t msg_len;
  79         int msg_err;
  80         struct completion msg_complete;
  81         struct device *dev;
  82         struct i2c_adapter adapter;
  83         struct clk *i2c_clk;
  84         u32 bus_clk_rate;
  85         u8 *buf;
  86         u32 fifo_size;
  87         u32 isr_mask;
  88         u32 isr_status;
  89         spinlock_t lock;        /* IRQ synchronization */
  90         struct mutex isr_mutex;
  91 };
  92 
  93 static void
  94 altr_i2c_int_enable(struct altr_i2c_dev *idev, u32 mask, bool enable)
  95 {
  96         unsigned long flags;
  97         u32 int_en;
  98 
  99         spin_lock_irqsave(&idev->lock, flags);
 100 
 101         int_en = readl(idev->base + ALTR_I2C_ISER);
 102         if (enable)
 103                 idev->isr_mask = int_en | mask;
 104         else
 105                 idev->isr_mask = int_en & ~mask;
 106 
 107         writel(idev->isr_mask, idev->base + ALTR_I2C_ISER);
 108 
 109         spin_unlock_irqrestore(&idev->lock, flags);
 110 }
 111 
 112 static void altr_i2c_int_clear(struct altr_i2c_dev *idev, u32 mask)
 113 {
 114         u32 int_en = readl(idev->base + ALTR_I2C_ISR);
 115 
 116         writel(int_en | mask, idev->base + ALTR_I2C_ISR);
 117 }
 118 
 119 static void altr_i2c_core_disable(struct altr_i2c_dev *idev)
 120 {
 121         u32 tmp = readl(idev->base + ALTR_I2C_CTRL);
 122 
 123         writel(tmp & ~ALTR_I2C_CTRL_EN, idev->base + ALTR_I2C_CTRL);
 124 }
 125 
 126 static void altr_i2c_core_enable(struct altr_i2c_dev *idev)
 127 {
 128         u32 tmp = readl(idev->base + ALTR_I2C_CTRL);
 129 
 130         writel(tmp | ALTR_I2C_CTRL_EN, idev->base + ALTR_I2C_CTRL);
 131 }
 132 
 133 static void altr_i2c_reset(struct altr_i2c_dev *idev)
 134 {
 135         altr_i2c_core_disable(idev);
 136         altr_i2c_core_enable(idev);
 137 }
 138 
 139 static inline void altr_i2c_stop(struct altr_i2c_dev *idev)
 140 {
 141         writel(ALTR_I2C_TFR_CMD_STO, idev->base + ALTR_I2C_TFR_CMD);
 142 }
 143 
 144 static void altr_i2c_init(struct altr_i2c_dev *idev)
 145 {
 146         u32 divisor = clk_get_rate(idev->i2c_clk) / idev->bus_clk_rate;
 147         u32 clk_mhz = clk_get_rate(idev->i2c_clk) / 1000000;
 148         u32 tmp = (ALTR_I2C_THRESHOLD << ALTR_I2C_CTRL_RXT_SHFT) |
 149                   (ALTR_I2C_THRESHOLD << ALTR_I2C_CTRL_TCT_SHFT);
 150         u32 t_high, t_low;
 151 
 152         if (idev->bus_clk_rate <= 100000) {
 153                 tmp &= ~ALTR_I2C_CTRL_BSPEED;
 154                 /* Standard mode SCL 50/50 */
 155                 t_high = divisor * 1 / 2;
 156                 t_low = divisor * 1 / 2;
 157         } else {
 158                 tmp |= ALTR_I2C_CTRL_BSPEED;
 159                 /* Fast mode SCL 33/66 */
 160                 t_high = divisor * 1 / 3;
 161                 t_low = divisor * 2 / 3;
 162         }
 163         writel(tmp, idev->base + ALTR_I2C_CTRL);
 164 
 165         dev_dbg(idev->dev, "rate=%uHz per_clk=%uMHz -> ratio=1:%u\n",
 166                 idev->bus_clk_rate, clk_mhz, divisor);
 167 
 168         /* Reset controller */
 169         altr_i2c_reset(idev);
 170 
 171         /* SCL High Time */
 172         writel(t_high, idev->base + ALTR_I2C_SCL_HIGH);
 173         /* SCL Low Time */
 174         writel(t_low, idev->base + ALTR_I2C_SCL_LOW);
 175         /* SDA Hold Time, 300ns */
 176         writel(3 * clk_mhz / 10, idev->base + ALTR_I2C_SDA_HOLD);
 177 
 178         /* Mask all master interrupt bits */
 179         altr_i2c_int_enable(idev, ALTR_I2C_ALL_IRQ, false);
 180 }
 181 
 182 /**
 183  * altr_i2c_transfer - On the last byte to be transmitted, send
 184  * a Stop bit on the last byte.
 185  */
 186 static void altr_i2c_transfer(struct altr_i2c_dev *idev, u32 data)
 187 {
 188         /* On the last byte to be transmitted, send STOP */
 189         if (idev->msg_len == 1)
 190                 data |= ALTR_I2C_TFR_CMD_STO;
 191         if (idev->msg_len > 0)
 192                 writel(data, idev->base + ALTR_I2C_TFR_CMD);
 193 }
 194 
 195 /**
 196  * altr_i2c_empty_rx_fifo - Fetch data from RX FIFO until end of
 197  * transfer. Send a Stop bit on the last byte.
 198  */
 199 static void altr_i2c_empty_rx_fifo(struct altr_i2c_dev *idev)
 200 {
 201         size_t rx_fifo_avail = readl(idev->base + ALTR_I2C_RX_FIFO_LVL);
 202         int bytes_to_transfer = min(rx_fifo_avail, idev->msg_len);
 203 
 204         while (bytes_to_transfer-- > 0) {
 205                 *idev->buf++ = readl(idev->base + ALTR_I2C_RX_DATA);
 206                 idev->msg_len--;
 207                 altr_i2c_transfer(idev, 0);
 208         }
 209 }
 210 
 211 /**
 212  * altr_i2c_fill_tx_fifo - Fill TX FIFO from current message buffer.
 213  * @return: Number of bytes left to transfer.
 214  */
 215 static int altr_i2c_fill_tx_fifo(struct altr_i2c_dev *idev)
 216 {
 217         size_t tx_fifo_avail = idev->fifo_size - readl(idev->base +
 218                                                        ALTR_I2C_TC_FIFO_LVL);
 219         int bytes_to_transfer = min(tx_fifo_avail, idev->msg_len);
 220         int ret = idev->msg_len - bytes_to_transfer;
 221 
 222         while (bytes_to_transfer-- > 0) {
 223                 altr_i2c_transfer(idev, *idev->buf++);
 224                 idev->msg_len--;
 225         }
 226 
 227         return ret;
 228 }
 229 
 230 static irqreturn_t altr_i2c_isr_quick(int irq, void *_dev)
 231 {
 232         struct altr_i2c_dev *idev = _dev;
 233         irqreturn_t ret = IRQ_HANDLED;
 234 
 235         /* Read IRQ status but only interested in Enabled IRQs. */
 236         idev->isr_status = readl(idev->base + ALTR_I2C_ISR) & idev->isr_mask;
 237         if (idev->isr_status)
 238                 ret = IRQ_WAKE_THREAD;
 239 
 240         return ret;
 241 }
 242 
 243 static irqreturn_t altr_i2c_isr(int irq, void *_dev)
 244 {
 245         int ret;
 246         bool read, finish = false;
 247         struct altr_i2c_dev *idev = _dev;
 248         u32 status = idev->isr_status;
 249 
 250         mutex_lock(&idev->isr_mutex);
 251         if (!idev->msg) {
 252                 dev_warn(idev->dev, "unexpected interrupt\n");
 253                 altr_i2c_int_clear(idev, ALTR_I2C_ALL_IRQ);
 254                 goto out;
 255         }
 256         read = (idev->msg->flags & I2C_M_RD) != 0;
 257 
 258         /* handle Lost Arbitration */
 259         if (unlikely(status & ALTR_I2C_ISR_ARB)) {
 260                 altr_i2c_int_clear(idev, ALTR_I2C_ISR_ARB);
 261                 idev->msg_err = -EAGAIN;
 262                 finish = true;
 263         } else if (unlikely(status & ALTR_I2C_ISR_NACK)) {
 264                 dev_dbg(idev->dev, "Could not get ACK\n");
 265                 idev->msg_err = -ENXIO;
 266                 altr_i2c_int_clear(idev, ALTR_I2C_ISR_NACK);
 267                 altr_i2c_stop(idev);
 268                 finish = true;
 269         } else if (read && unlikely(status & ALTR_I2C_ISR_RXOF)) {
 270                 /* handle RX FIFO Overflow */
 271                 altr_i2c_empty_rx_fifo(idev);
 272                 altr_i2c_int_clear(idev, ALTR_I2C_ISR_RXRDY);
 273                 altr_i2c_stop(idev);
 274                 dev_err(idev->dev, "RX FIFO Overflow\n");
 275                 finish = true;
 276         } else if (read && (status & ALTR_I2C_ISR_RXRDY)) {
 277                 /* RX FIFO needs service? */
 278                 altr_i2c_empty_rx_fifo(idev);
 279                 altr_i2c_int_clear(idev, ALTR_I2C_ISR_RXRDY);
 280                 if (!idev->msg_len)
 281                         finish = true;
 282         } else if (!read && (status & ALTR_I2C_ISR_TXRDY)) {
 283                 /* TX FIFO needs service? */
 284                 altr_i2c_int_clear(idev, ALTR_I2C_ISR_TXRDY);
 285                 if (idev->msg_len > 0)
 286                         altr_i2c_fill_tx_fifo(idev);
 287                 else
 288                         finish = true;
 289         } else {
 290                 dev_warn(idev->dev, "Unexpected interrupt: 0x%x\n", status);
 291                 altr_i2c_int_clear(idev, ALTR_I2C_ALL_IRQ);
 292         }
 293 
 294         if (finish) {
 295                 /* Wait for the Core to finish */
 296                 ret = readl_poll_timeout_atomic(idev->base + ALTR_I2C_STATUS,
 297                                                 status,
 298                                                 !(status & ALTR_I2C_STAT_CORE),
 299                                                 1, ALTR_I2C_TIMEOUT);
 300                 if (ret)
 301                         dev_err(idev->dev, "message timeout\n");
 302                 altr_i2c_int_enable(idev, ALTR_I2C_ALL_IRQ, false);
 303                 altr_i2c_int_clear(idev, ALTR_I2C_ALL_IRQ);
 304                 complete(&idev->msg_complete);
 305                 dev_dbg(idev->dev, "Message Complete\n");
 306         }
 307 out:
 308         mutex_unlock(&idev->isr_mutex);
 309 
 310         return IRQ_HANDLED;
 311 }
 312 
 313 static int altr_i2c_xfer_msg(struct altr_i2c_dev *idev, struct i2c_msg *msg)
 314 {
 315         u32 imask = ALTR_I2C_ISR_RXOF | ALTR_I2C_ISR_ARB | ALTR_I2C_ISR_NACK;
 316         unsigned long time_left;
 317         u32 value;
 318         u8 addr = i2c_8bit_addr_from_msg(msg);
 319 
 320         mutex_lock(&idev->isr_mutex);
 321         idev->msg = msg;
 322         idev->msg_len = msg->len;
 323         idev->buf = msg->buf;
 324         idev->msg_err = 0;
 325         reinit_completion(&idev->msg_complete);
 326         altr_i2c_core_enable(idev);
 327 
 328         /* Make sure RX FIFO is empty */
 329         do {
 330                 readl(idev->base + ALTR_I2C_RX_DATA);
 331         } while (readl(idev->base + ALTR_I2C_RX_FIFO_LVL));
 332 
 333         writel(ALTR_I2C_TFR_CMD_STA | addr, idev->base + ALTR_I2C_TFR_CMD);
 334 
 335         if ((msg->flags & I2C_M_RD) != 0) {
 336                 imask |= ALTR_I2C_ISER_RXOF_EN | ALTR_I2C_ISER_RXRDY_EN;
 337                 altr_i2c_int_enable(idev, imask, true);
 338                 /* write the first byte to start the RX */
 339                 altr_i2c_transfer(idev, 0);
 340         } else {
 341                 imask |= ALTR_I2C_ISR_TXRDY;
 342                 altr_i2c_int_enable(idev, imask, true);
 343                 altr_i2c_fill_tx_fifo(idev);
 344         }
 345         mutex_unlock(&idev->isr_mutex);
 346 
 347         time_left = wait_for_completion_timeout(&idev->msg_complete,
 348                                                 ALTR_I2C_XFER_TIMEOUT);
 349         altr_i2c_int_enable(idev, imask, false);
 350 
 351         value = readl(idev->base + ALTR_I2C_STATUS) & ALTR_I2C_STAT_CORE;
 352         if (value)
 353                 dev_err(idev->dev, "Core Status not IDLE...\n");
 354 
 355         if (time_left == 0) {
 356                 idev->msg_err = -ETIMEDOUT;
 357                 dev_dbg(idev->dev, "Transaction timed out.\n");
 358         }
 359 
 360         altr_i2c_core_disable(idev);
 361 
 362         return idev->msg_err;
 363 }
 364 
 365 static int
 366 altr_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 367 {
 368         struct altr_i2c_dev *idev = i2c_get_adapdata(adap);
 369         int i, ret;
 370 
 371         for (i = 0; i < num; i++) {
 372                 ret = altr_i2c_xfer_msg(idev, msgs++);
 373                 if (ret)
 374                         return ret;
 375         }
 376         return num;
 377 }
 378 
 379 static u32 altr_i2c_func(struct i2c_adapter *adap)
 380 {
 381         return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 382 }
 383 
 384 static const struct i2c_algorithm altr_i2c_algo = {
 385         .master_xfer = altr_i2c_xfer,
 386         .functionality = altr_i2c_func,
 387 };
 388 
 389 static int altr_i2c_probe(struct platform_device *pdev)
 390 {
 391         struct altr_i2c_dev *idev = NULL;
 392         struct resource *res;
 393         int irq, ret;
 394 
 395         idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL);
 396         if (!idev)
 397                 return -ENOMEM;
 398 
 399         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 400         idev->base = devm_ioremap_resource(&pdev->dev, res);
 401         if (IS_ERR(idev->base))
 402                 return PTR_ERR(idev->base);
 403 
 404         irq = platform_get_irq(pdev, 0);
 405         if (irq < 0) {
 406                 dev_err(&pdev->dev, "missing interrupt resource\n");
 407                 return irq;
 408         }
 409 
 410         idev->i2c_clk = devm_clk_get(&pdev->dev, NULL);
 411         if (IS_ERR(idev->i2c_clk)) {
 412                 dev_err(&pdev->dev, "missing clock\n");
 413                 return PTR_ERR(idev->i2c_clk);
 414         }
 415 
 416         idev->dev = &pdev->dev;
 417         init_completion(&idev->msg_complete);
 418         spin_lock_init(&idev->lock);
 419         mutex_init(&idev->isr_mutex);
 420 
 421         ret = device_property_read_u32(idev->dev, "fifo-size",
 422                                        &idev->fifo_size);
 423         if (ret) {
 424                 dev_err(&pdev->dev, "FIFO size set to default of %d\n",
 425                         ALTR_I2C_DFLT_FIFO_SZ);
 426                 idev->fifo_size = ALTR_I2C_DFLT_FIFO_SZ;
 427         }
 428 
 429         ret = device_property_read_u32(idev->dev, "clock-frequency",
 430                                        &idev->bus_clk_rate);
 431         if (ret) {
 432                 dev_err(&pdev->dev, "Default to 100kHz\n");
 433                 idev->bus_clk_rate = 100000;    /* default clock rate */
 434         }
 435 
 436         if (idev->bus_clk_rate > 400000) {
 437                 dev_err(&pdev->dev, "invalid clock-frequency %d\n",
 438                         idev->bus_clk_rate);
 439                 return -EINVAL;
 440         }
 441 
 442         ret = devm_request_threaded_irq(&pdev->dev, irq, altr_i2c_isr_quick,
 443                                         altr_i2c_isr, IRQF_ONESHOT,
 444                                         pdev->name, idev);
 445         if (ret) {
 446                 dev_err(&pdev->dev, "failed to claim IRQ %d\n", irq);
 447                 return ret;
 448         }
 449 
 450         ret = clk_prepare_enable(idev->i2c_clk);
 451         if (ret) {
 452                 dev_err(&pdev->dev, "failed to enable clock\n");
 453                 return ret;
 454         }
 455 
 456         altr_i2c_init(idev);
 457 
 458         i2c_set_adapdata(&idev->adapter, idev);
 459         strlcpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name));
 460         idev->adapter.owner = THIS_MODULE;
 461         idev->adapter.algo = &altr_i2c_algo;
 462         idev->adapter.dev.parent = &pdev->dev;
 463         idev->adapter.dev.of_node = pdev->dev.of_node;
 464 
 465         platform_set_drvdata(pdev, idev);
 466 
 467         ret = i2c_add_adapter(&idev->adapter);
 468         if (ret) {
 469                 clk_disable_unprepare(idev->i2c_clk);
 470                 return ret;
 471         }
 472         dev_info(&pdev->dev, "Altera SoftIP I2C Probe Complete\n");
 473 
 474         return 0;
 475 }
 476 
 477 static int altr_i2c_remove(struct platform_device *pdev)
 478 {
 479         struct altr_i2c_dev *idev = platform_get_drvdata(pdev);
 480 
 481         clk_disable_unprepare(idev->i2c_clk);
 482         i2c_del_adapter(&idev->adapter);
 483 
 484         return 0;
 485 }
 486 
 487 /* Match table for of_platform binding */
 488 static const struct of_device_id altr_i2c_of_match[] = {
 489         { .compatible = "altr,softip-i2c-v1.0" },
 490         {},
 491 };
 492 MODULE_DEVICE_TABLE(of, altr_i2c_of_match);
 493 
 494 static struct platform_driver altr_i2c_driver = {
 495         .probe = altr_i2c_probe,
 496         .remove = altr_i2c_remove,
 497         .driver = {
 498                 .name = "altera-i2c",
 499                 .of_match_table = altr_i2c_of_match,
 500         },
 501 };
 502 
 503 module_platform_driver(altr_i2c_driver);
 504 
 505 MODULE_DESCRIPTION("Altera Soft IP I2C bus driver");
 506 MODULE_AUTHOR("Thor Thayer <thor.thayer@linux.intel.com>");
 507 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */