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

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

DEFINITIONS

This source file includes following definitions.
  1. uniphier_i2c_interrupt
  2. uniphier_i2c_xfer_byte
  3. uniphier_i2c_send_byte
  4. uniphier_i2c_tx
  5. uniphier_i2c_rx
  6. uniphier_i2c_stop
  7. uniphier_i2c_master_xfer_one
  8. uniphier_i2c_check_bus_busy
  9. uniphier_i2c_master_xfer
  10. uniphier_i2c_functionality
  11. uniphier_i2c_reset
  12. uniphier_i2c_get_scl
  13. uniphier_i2c_set_scl
  14. uniphier_i2c_get_sda
  15. uniphier_i2c_unprepare_recovery
  16. uniphier_i2c_hw_init
  17. uniphier_i2c_probe
  18. uniphier_i2c_remove
  19. uniphier_i2c_suspend
  20. uniphier_i2c_resume

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
   4  */
   5 
   6 #include <linux/clk.h>
   7 #include <linux/i2c.h>
   8 #include <linux/interrupt.h>
   9 #include <linux/io.h>
  10 #include <linux/module.h>
  11 #include <linux/platform_device.h>
  12 
  13 #define UNIPHIER_I2C_DTRM       0x00    /* TX register */
  14 #define     UNIPHIER_I2C_DTRM_IRQEN     BIT(11) /* enable interrupt */
  15 #define     UNIPHIER_I2C_DTRM_STA       BIT(10) /* start condition */
  16 #define     UNIPHIER_I2C_DTRM_STO       BIT(9)  /* stop condition */
  17 #define     UNIPHIER_I2C_DTRM_NACK      BIT(8)  /* do not return ACK */
  18 #define     UNIPHIER_I2C_DTRM_RD        BIT(0)  /* read transaction */
  19 #define UNIPHIER_I2C_DREC       0x04    /* RX register */
  20 #define     UNIPHIER_I2C_DREC_MST       BIT(14) /* 1 = master, 0 = slave */
  21 #define     UNIPHIER_I2C_DREC_TX        BIT(13) /* 1 = transmit, 0 = receive */
  22 #define     UNIPHIER_I2C_DREC_STS       BIT(12) /* stop condition detected */
  23 #define     UNIPHIER_I2C_DREC_LRB       BIT(11) /* no ACK */
  24 #define     UNIPHIER_I2C_DREC_LAB       BIT(9)  /* arbitration lost */
  25 #define     UNIPHIER_I2C_DREC_BBN       BIT(8)  /* bus not busy */
  26 #define UNIPHIER_I2C_MYAD       0x08    /* slave address */
  27 #define UNIPHIER_I2C_CLK        0x0c    /* clock frequency control */
  28 #define UNIPHIER_I2C_BRST       0x10    /* bus reset */
  29 #define     UNIPHIER_I2C_BRST_FOEN      BIT(1)  /* normal operation */
  30 #define     UNIPHIER_I2C_BRST_RSCL      BIT(0)  /* release SCL */
  31 #define UNIPHIER_I2C_HOLD       0x14    /* hold time control */
  32 #define UNIPHIER_I2C_BSTS       0x18    /* bus status monitor */
  33 #define     UNIPHIER_I2C_BSTS_SDA       BIT(1)  /* readback of SDA line */
  34 #define     UNIPHIER_I2C_BSTS_SCL       BIT(0)  /* readback of SCL line */
  35 #define UNIPHIER_I2C_NOISE      0x1c    /* noise filter control */
  36 #define UNIPHIER_I2C_SETUP      0x20    /* setup time control */
  37 
  38 #define UNIPHIER_I2C_DEFAULT_SPEED      100000
  39 #define UNIPHIER_I2C_MAX_SPEED          400000
  40 
  41 struct uniphier_i2c_priv {
  42         struct completion comp;
  43         struct i2c_adapter adap;
  44         void __iomem *membase;
  45         struct clk *clk;
  46         unsigned int busy_cnt;
  47         unsigned int clk_cycle;
  48 };
  49 
  50 static irqreturn_t uniphier_i2c_interrupt(int irq, void *dev_id)
  51 {
  52         struct uniphier_i2c_priv *priv = dev_id;
  53 
  54         /*
  55          * This hardware uses edge triggered interrupt.  Do not touch the
  56          * hardware registers in this handler to make sure to catch the next
  57          * interrupt edge.  Just send a complete signal and return.
  58          */
  59         complete(&priv->comp);
  60 
  61         return IRQ_HANDLED;
  62 }
  63 
  64 static int uniphier_i2c_xfer_byte(struct i2c_adapter *adap, u32 txdata,
  65                                   u32 *rxdatap)
  66 {
  67         struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);
  68         unsigned long time_left;
  69         u32 rxdata;
  70 
  71         reinit_completion(&priv->comp);
  72 
  73         txdata |= UNIPHIER_I2C_DTRM_IRQEN;
  74         writel(txdata, priv->membase + UNIPHIER_I2C_DTRM);
  75 
  76         time_left = wait_for_completion_timeout(&priv->comp, adap->timeout);
  77         if (unlikely(!time_left)) {
  78                 dev_err(&adap->dev, "transaction timeout\n");
  79                 return -ETIMEDOUT;
  80         }
  81 
  82         rxdata = readl(priv->membase + UNIPHIER_I2C_DREC);
  83         if (rxdatap)
  84                 *rxdatap = rxdata;
  85 
  86         return 0;
  87 }
  88 
  89 static int uniphier_i2c_send_byte(struct i2c_adapter *adap, u32 txdata)
  90 {
  91         u32 rxdata;
  92         int ret;
  93 
  94         ret = uniphier_i2c_xfer_byte(adap, txdata, &rxdata);
  95         if (ret)
  96                 return ret;
  97 
  98         if (unlikely(rxdata & UNIPHIER_I2C_DREC_LAB))
  99                 return -EAGAIN;
 100 
 101         if (unlikely(rxdata & UNIPHIER_I2C_DREC_LRB))
 102                 return -ENXIO;
 103 
 104         return 0;
 105 }
 106 
 107 static int uniphier_i2c_tx(struct i2c_adapter *adap, u16 addr, u16 len,
 108                            const u8 *buf)
 109 {
 110         int ret;
 111 
 112         ret = uniphier_i2c_send_byte(adap, addr << 1 |
 113                                      UNIPHIER_I2C_DTRM_STA |
 114                                      UNIPHIER_I2C_DTRM_NACK);
 115         if (ret)
 116                 return ret;
 117 
 118         while (len--) {
 119                 ret = uniphier_i2c_send_byte(adap,
 120                                              UNIPHIER_I2C_DTRM_NACK | *buf++);
 121                 if (ret)
 122                         return ret;
 123         }
 124 
 125         return 0;
 126 }
 127 
 128 static int uniphier_i2c_rx(struct i2c_adapter *adap, u16 addr, u16 len,
 129                            u8 *buf)
 130 {
 131         int ret;
 132 
 133         ret = uniphier_i2c_send_byte(adap, addr << 1 |
 134                                      UNIPHIER_I2C_DTRM_STA |
 135                                      UNIPHIER_I2C_DTRM_NACK |
 136                                      UNIPHIER_I2C_DTRM_RD);
 137         if (ret)
 138                 return ret;
 139 
 140         while (len--) {
 141                 u32 rxdata;
 142 
 143                 ret = uniphier_i2c_xfer_byte(adap,
 144                                              len ? 0 : UNIPHIER_I2C_DTRM_NACK,
 145                                              &rxdata);
 146                 if (ret)
 147                         return ret;
 148                 *buf++ = rxdata;
 149         }
 150 
 151         return 0;
 152 }
 153 
 154 static int uniphier_i2c_stop(struct i2c_adapter *adap)
 155 {
 156         return uniphier_i2c_send_byte(adap, UNIPHIER_I2C_DTRM_STO |
 157                                       UNIPHIER_I2C_DTRM_NACK);
 158 }
 159 
 160 static int uniphier_i2c_master_xfer_one(struct i2c_adapter *adap,
 161                                         struct i2c_msg *msg, bool stop)
 162 {
 163         bool is_read = msg->flags & I2C_M_RD;
 164         bool recovery = false;
 165         int ret;
 166 
 167         if (is_read)
 168                 ret = uniphier_i2c_rx(adap, msg->addr, msg->len, msg->buf);
 169         else
 170                 ret = uniphier_i2c_tx(adap, msg->addr, msg->len, msg->buf);
 171 
 172         if (ret == -EAGAIN) /* could not acquire bus. bail out without STOP */
 173                 return ret;
 174 
 175         if (ret == -ETIMEDOUT) {
 176                 /* This error is fatal.  Needs recovery. */
 177                 stop = false;
 178                 recovery = true;
 179         }
 180 
 181         if (stop) {
 182                 int ret2 = uniphier_i2c_stop(adap);
 183 
 184                 if (ret2) {
 185                         /* Failed to issue STOP.  The bus needs recovery. */
 186                         recovery = true;
 187                         ret = ret ?: ret2;
 188                 }
 189         }
 190 
 191         if (recovery)
 192                 i2c_recover_bus(adap);
 193 
 194         return ret;
 195 }
 196 
 197 static int uniphier_i2c_check_bus_busy(struct i2c_adapter *adap)
 198 {
 199         struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);
 200 
 201         if (!(readl(priv->membase + UNIPHIER_I2C_DREC) &
 202                                                 UNIPHIER_I2C_DREC_BBN)) {
 203                 if (priv->busy_cnt++ > 3) {
 204                         /*
 205                          * If bus busy continues too long, it is probably
 206                          * in a wrong state.  Try bus recovery.
 207                          */
 208                         i2c_recover_bus(adap);
 209                         priv->busy_cnt = 0;
 210                 }
 211 
 212                 return -EAGAIN;
 213         }
 214 
 215         priv->busy_cnt = 0;
 216         return 0;
 217 }
 218 
 219 static int uniphier_i2c_master_xfer(struct i2c_adapter *adap,
 220                                     struct i2c_msg *msgs, int num)
 221 {
 222         struct i2c_msg *msg, *emsg = msgs + num;
 223         int ret;
 224 
 225         ret = uniphier_i2c_check_bus_busy(adap);
 226         if (ret)
 227                 return ret;
 228 
 229         for (msg = msgs; msg < emsg; msg++) {
 230                 /* Emit STOP if it is the last message or I2C_M_STOP is set. */
 231                 bool stop = (msg + 1 == emsg) || (msg->flags & I2C_M_STOP);
 232 
 233                 ret = uniphier_i2c_master_xfer_one(adap, msg, stop);
 234                 if (ret)
 235                         return ret;
 236         }
 237 
 238         return num;
 239 }
 240 
 241 static u32 uniphier_i2c_functionality(struct i2c_adapter *adap)
 242 {
 243         return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 244 }
 245 
 246 static const struct i2c_algorithm uniphier_i2c_algo = {
 247         .master_xfer = uniphier_i2c_master_xfer,
 248         .functionality = uniphier_i2c_functionality,
 249 };
 250 
 251 static void uniphier_i2c_reset(struct uniphier_i2c_priv *priv, bool reset_on)
 252 {
 253         u32 val = UNIPHIER_I2C_BRST_RSCL;
 254 
 255         val |= reset_on ? 0 : UNIPHIER_I2C_BRST_FOEN;
 256         writel(val, priv->membase + UNIPHIER_I2C_BRST);
 257 }
 258 
 259 static int uniphier_i2c_get_scl(struct i2c_adapter *adap)
 260 {
 261         struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);
 262 
 263         return !!(readl(priv->membase + UNIPHIER_I2C_BSTS) &
 264                                                         UNIPHIER_I2C_BSTS_SCL);
 265 }
 266 
 267 static void uniphier_i2c_set_scl(struct i2c_adapter *adap, int val)
 268 {
 269         struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);
 270 
 271         writel(val ? UNIPHIER_I2C_BRST_RSCL : 0,
 272                priv->membase + UNIPHIER_I2C_BRST);
 273 }
 274 
 275 static int uniphier_i2c_get_sda(struct i2c_adapter *adap)
 276 {
 277         struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);
 278 
 279         return !!(readl(priv->membase + UNIPHIER_I2C_BSTS) &
 280                                                         UNIPHIER_I2C_BSTS_SDA);
 281 }
 282 
 283 static void uniphier_i2c_unprepare_recovery(struct i2c_adapter *adap)
 284 {
 285         uniphier_i2c_reset(i2c_get_adapdata(adap), false);
 286 }
 287 
 288 static struct i2c_bus_recovery_info uniphier_i2c_bus_recovery_info = {
 289         .recover_bus = i2c_generic_scl_recovery,
 290         .get_scl = uniphier_i2c_get_scl,
 291         .set_scl = uniphier_i2c_set_scl,
 292         .get_sda = uniphier_i2c_get_sda,
 293         .unprepare_recovery = uniphier_i2c_unprepare_recovery,
 294 };
 295 
 296 static void uniphier_i2c_hw_init(struct uniphier_i2c_priv *priv)
 297 {
 298         unsigned int cyc = priv->clk_cycle;
 299 
 300         uniphier_i2c_reset(priv, true);
 301 
 302         /*
 303          * Bit30-16: clock cycles of tLOW.
 304          *  Standard-mode: tLOW = 4.7 us, tHIGH = 4.0 us
 305          *  Fast-mode:     tLOW = 1.3 us, tHIGH = 0.6 us
 306          * "tLow/tHIGH = 5/4" meets both.
 307          */
 308         writel((cyc * 5 / 9 << 16) | cyc, priv->membase + UNIPHIER_I2C_CLK);
 309 
 310         uniphier_i2c_reset(priv, false);
 311 }
 312 
 313 static int uniphier_i2c_probe(struct platform_device *pdev)
 314 {
 315         struct device *dev = &pdev->dev;
 316         struct uniphier_i2c_priv *priv;
 317         u32 bus_speed;
 318         unsigned long clk_rate;
 319         int irq, ret;
 320 
 321         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 322         if (!priv)
 323                 return -ENOMEM;
 324 
 325         priv->membase = devm_platform_ioremap_resource(pdev, 0);
 326         if (IS_ERR(priv->membase))
 327                 return PTR_ERR(priv->membase);
 328 
 329         irq = platform_get_irq(pdev, 0);
 330         if (irq < 0) {
 331                 dev_err(dev, "failed to get IRQ number\n");
 332                 return irq;
 333         }
 334 
 335         if (of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed))
 336                 bus_speed = UNIPHIER_I2C_DEFAULT_SPEED;
 337 
 338         if (!bus_speed || bus_speed > UNIPHIER_I2C_MAX_SPEED) {
 339                 dev_err(dev, "invalid clock-frequency %d\n", bus_speed);
 340                 return -EINVAL;
 341         }
 342 
 343         priv->clk = devm_clk_get(dev, NULL);
 344         if (IS_ERR(priv->clk)) {
 345                 dev_err(dev, "failed to get clock\n");
 346                 return PTR_ERR(priv->clk);
 347         }
 348 
 349         ret = clk_prepare_enable(priv->clk);
 350         if (ret)
 351                 return ret;
 352 
 353         clk_rate = clk_get_rate(priv->clk);
 354         if (!clk_rate) {
 355                 dev_err(dev, "input clock rate should not be zero\n");
 356                 ret = -EINVAL;
 357                 goto disable_clk;
 358         }
 359 
 360         priv->clk_cycle = clk_rate / bus_speed;
 361         init_completion(&priv->comp);
 362         priv->adap.owner = THIS_MODULE;
 363         priv->adap.algo = &uniphier_i2c_algo;
 364         priv->adap.dev.parent = dev;
 365         priv->adap.dev.of_node = dev->of_node;
 366         strlcpy(priv->adap.name, "UniPhier I2C", sizeof(priv->adap.name));
 367         priv->adap.bus_recovery_info = &uniphier_i2c_bus_recovery_info;
 368         i2c_set_adapdata(&priv->adap, priv);
 369         platform_set_drvdata(pdev, priv);
 370 
 371         uniphier_i2c_hw_init(priv);
 372 
 373         ret = devm_request_irq(dev, irq, uniphier_i2c_interrupt, 0, pdev->name,
 374                                priv);
 375         if (ret) {
 376                 dev_err(dev, "failed to request irq %d\n", irq);
 377                 goto disable_clk;
 378         }
 379 
 380         ret = i2c_add_adapter(&priv->adap);
 381 disable_clk:
 382         if (ret)
 383                 clk_disable_unprepare(priv->clk);
 384 
 385         return ret;
 386 }
 387 
 388 static int uniphier_i2c_remove(struct platform_device *pdev)
 389 {
 390         struct uniphier_i2c_priv *priv = platform_get_drvdata(pdev);
 391 
 392         i2c_del_adapter(&priv->adap);
 393         clk_disable_unprepare(priv->clk);
 394 
 395         return 0;
 396 }
 397 
 398 static int __maybe_unused uniphier_i2c_suspend(struct device *dev)
 399 {
 400         struct uniphier_i2c_priv *priv = dev_get_drvdata(dev);
 401 
 402         clk_disable_unprepare(priv->clk);
 403 
 404         return 0;
 405 }
 406 
 407 static int __maybe_unused uniphier_i2c_resume(struct device *dev)
 408 {
 409         struct uniphier_i2c_priv *priv = dev_get_drvdata(dev);
 410         int ret;
 411 
 412         ret = clk_prepare_enable(priv->clk);
 413         if (ret)
 414                 return ret;
 415 
 416         uniphier_i2c_hw_init(priv);
 417 
 418         return 0;
 419 }
 420 
 421 static const struct dev_pm_ops uniphier_i2c_pm_ops = {
 422         SET_SYSTEM_SLEEP_PM_OPS(uniphier_i2c_suspend, uniphier_i2c_resume)
 423 };
 424 
 425 static const struct of_device_id uniphier_i2c_match[] = {
 426         { .compatible = "socionext,uniphier-i2c" },
 427         { /* sentinel */ }
 428 };
 429 MODULE_DEVICE_TABLE(of, uniphier_i2c_match);
 430 
 431 static struct platform_driver uniphier_i2c_drv = {
 432         .probe  = uniphier_i2c_probe,
 433         .remove = uniphier_i2c_remove,
 434         .driver = {
 435                 .name  = "uniphier-i2c",
 436                 .of_match_table = uniphier_i2c_match,
 437                 .pm = &uniphier_i2c_pm_ops,
 438         },
 439 };
 440 module_platform_driver(uniphier_i2c_drv);
 441 
 442 MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
 443 MODULE_DESCRIPTION("UniPhier I2C bus driver");
 444 MODULE_LICENSE("GPL");

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