Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
0004  */
0005 
0006 #include <linux/clk.h>
0007 #include <linux/i2c.h>
0008 #include <linux/interrupt.h>
0009 #include <linux/io.h>
0010 #include <linux/module.h>
0011 #include <linux/platform_device.h>
0012 
0013 #define UNIPHIER_I2C_DTRM   0x00    /* TX register */
0014 #define     UNIPHIER_I2C_DTRM_IRQEN BIT(11) /* enable interrupt */
0015 #define     UNIPHIER_I2C_DTRM_STA   BIT(10) /* start condition */
0016 #define     UNIPHIER_I2C_DTRM_STO   BIT(9)  /* stop condition */
0017 #define     UNIPHIER_I2C_DTRM_NACK  BIT(8)  /* do not return ACK */
0018 #define     UNIPHIER_I2C_DTRM_RD    BIT(0)  /* read transaction */
0019 #define UNIPHIER_I2C_DREC   0x04    /* RX register */
0020 #define     UNIPHIER_I2C_DREC_MST   BIT(14) /* 1 = master, 0 = slave */
0021 #define     UNIPHIER_I2C_DREC_TX    BIT(13) /* 1 = transmit, 0 = receive */
0022 #define     UNIPHIER_I2C_DREC_STS   BIT(12) /* stop condition detected */
0023 #define     UNIPHIER_I2C_DREC_LRB   BIT(11) /* no ACK */
0024 #define     UNIPHIER_I2C_DREC_LAB   BIT(9)  /* arbitration lost */
0025 #define     UNIPHIER_I2C_DREC_BBN   BIT(8)  /* bus not busy */
0026 #define UNIPHIER_I2C_MYAD   0x08    /* slave address */
0027 #define UNIPHIER_I2C_CLK    0x0c    /* clock frequency control */
0028 #define UNIPHIER_I2C_BRST   0x10    /* bus reset */
0029 #define     UNIPHIER_I2C_BRST_FOEN  BIT(1)  /* normal operation */
0030 #define     UNIPHIER_I2C_BRST_RSCL  BIT(0)  /* release SCL */
0031 #define UNIPHIER_I2C_HOLD   0x14    /* hold time control */
0032 #define UNIPHIER_I2C_BSTS   0x18    /* bus status monitor */
0033 #define     UNIPHIER_I2C_BSTS_SDA   BIT(1)  /* readback of SDA line */
0034 #define     UNIPHIER_I2C_BSTS_SCL   BIT(0)  /* readback of SCL line */
0035 #define UNIPHIER_I2C_NOISE  0x1c    /* noise filter control */
0036 #define UNIPHIER_I2C_SETUP  0x20    /* setup time control */
0037 
0038 struct uniphier_i2c_priv {
0039     struct completion comp;
0040     struct i2c_adapter adap;
0041     void __iomem *membase;
0042     struct clk *clk;
0043     unsigned int busy_cnt;
0044     unsigned int clk_cycle;
0045 };
0046 
0047 static irqreturn_t uniphier_i2c_interrupt(int irq, void *dev_id)
0048 {
0049     struct uniphier_i2c_priv *priv = dev_id;
0050 
0051     /*
0052      * This hardware uses edge triggered interrupt.  Do not touch the
0053      * hardware registers in this handler to make sure to catch the next
0054      * interrupt edge.  Just send a complete signal and return.
0055      */
0056     complete(&priv->comp);
0057 
0058     return IRQ_HANDLED;
0059 }
0060 
0061 static int uniphier_i2c_xfer_byte(struct i2c_adapter *adap, u32 txdata,
0062                   u32 *rxdatap)
0063 {
0064     struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);
0065     unsigned long time_left;
0066     u32 rxdata;
0067 
0068     reinit_completion(&priv->comp);
0069 
0070     txdata |= UNIPHIER_I2C_DTRM_IRQEN;
0071     writel(txdata, priv->membase + UNIPHIER_I2C_DTRM);
0072 
0073     time_left = wait_for_completion_timeout(&priv->comp, adap->timeout);
0074     if (unlikely(!time_left)) {
0075         dev_err(&adap->dev, "transaction timeout\n");
0076         return -ETIMEDOUT;
0077     }
0078 
0079     rxdata = readl(priv->membase + UNIPHIER_I2C_DREC);
0080     if (rxdatap)
0081         *rxdatap = rxdata;
0082 
0083     return 0;
0084 }
0085 
0086 static int uniphier_i2c_send_byte(struct i2c_adapter *adap, u32 txdata)
0087 {
0088     u32 rxdata;
0089     int ret;
0090 
0091     ret = uniphier_i2c_xfer_byte(adap, txdata, &rxdata);
0092     if (ret)
0093         return ret;
0094 
0095     if (unlikely(rxdata & UNIPHIER_I2C_DREC_LAB))
0096         return -EAGAIN;
0097 
0098     if (unlikely(rxdata & UNIPHIER_I2C_DREC_LRB))
0099         return -ENXIO;
0100 
0101     return 0;
0102 }
0103 
0104 static int uniphier_i2c_tx(struct i2c_adapter *adap, u16 addr, u16 len,
0105                const u8 *buf)
0106 {
0107     int ret;
0108 
0109     ret = uniphier_i2c_send_byte(adap, addr << 1 |
0110                      UNIPHIER_I2C_DTRM_STA |
0111                      UNIPHIER_I2C_DTRM_NACK);
0112     if (ret)
0113         return ret;
0114 
0115     while (len--) {
0116         ret = uniphier_i2c_send_byte(adap,
0117                          UNIPHIER_I2C_DTRM_NACK | *buf++);
0118         if (ret)
0119             return ret;
0120     }
0121 
0122     return 0;
0123 }
0124 
0125 static int uniphier_i2c_rx(struct i2c_adapter *adap, u16 addr, u16 len,
0126                u8 *buf)
0127 {
0128     int ret;
0129 
0130     ret = uniphier_i2c_send_byte(adap, addr << 1 |
0131                      UNIPHIER_I2C_DTRM_STA |
0132                      UNIPHIER_I2C_DTRM_NACK |
0133                      UNIPHIER_I2C_DTRM_RD);
0134     if (ret)
0135         return ret;
0136 
0137     while (len--) {
0138         u32 rxdata;
0139 
0140         ret = uniphier_i2c_xfer_byte(adap,
0141                          len ? 0 : UNIPHIER_I2C_DTRM_NACK,
0142                          &rxdata);
0143         if (ret)
0144             return ret;
0145         *buf++ = rxdata;
0146     }
0147 
0148     return 0;
0149 }
0150 
0151 static int uniphier_i2c_stop(struct i2c_adapter *adap)
0152 {
0153     return uniphier_i2c_send_byte(adap, UNIPHIER_I2C_DTRM_STO |
0154                       UNIPHIER_I2C_DTRM_NACK);
0155 }
0156 
0157 static int uniphier_i2c_master_xfer_one(struct i2c_adapter *adap,
0158                     struct i2c_msg *msg, bool stop)
0159 {
0160     bool is_read = msg->flags & I2C_M_RD;
0161     bool recovery = false;
0162     int ret;
0163 
0164     if (is_read)
0165         ret = uniphier_i2c_rx(adap, msg->addr, msg->len, msg->buf);
0166     else
0167         ret = uniphier_i2c_tx(adap, msg->addr, msg->len, msg->buf);
0168 
0169     if (ret == -EAGAIN) /* could not acquire bus. bail out without STOP */
0170         return ret;
0171 
0172     if (ret == -ETIMEDOUT) {
0173         /* This error is fatal.  Needs recovery. */
0174         stop = false;
0175         recovery = true;
0176     }
0177 
0178     if (stop) {
0179         int ret2 = uniphier_i2c_stop(adap);
0180 
0181         if (ret2) {
0182             /* Failed to issue STOP.  The bus needs recovery. */
0183             recovery = true;
0184             ret = ret ?: ret2;
0185         }
0186     }
0187 
0188     if (recovery)
0189         i2c_recover_bus(adap);
0190 
0191     return ret;
0192 }
0193 
0194 static int uniphier_i2c_check_bus_busy(struct i2c_adapter *adap)
0195 {
0196     struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);
0197 
0198     if (!(readl(priv->membase + UNIPHIER_I2C_DREC) &
0199                         UNIPHIER_I2C_DREC_BBN)) {
0200         if (priv->busy_cnt++ > 3) {
0201             /*
0202              * If bus busy continues too long, it is probably
0203              * in a wrong state.  Try bus recovery.
0204              */
0205             i2c_recover_bus(adap);
0206             priv->busy_cnt = 0;
0207         }
0208 
0209         return -EAGAIN;
0210     }
0211 
0212     priv->busy_cnt = 0;
0213     return 0;
0214 }
0215 
0216 static int uniphier_i2c_master_xfer(struct i2c_adapter *adap,
0217                     struct i2c_msg *msgs, int num)
0218 {
0219     struct i2c_msg *msg, *emsg = msgs + num;
0220     int ret;
0221 
0222     ret = uniphier_i2c_check_bus_busy(adap);
0223     if (ret)
0224         return ret;
0225 
0226     for (msg = msgs; msg < emsg; msg++) {
0227         /* Emit STOP if it is the last message or I2C_M_STOP is set. */
0228         bool stop = (msg + 1 == emsg) || (msg->flags & I2C_M_STOP);
0229 
0230         ret = uniphier_i2c_master_xfer_one(adap, msg, stop);
0231         if (ret)
0232             return ret;
0233     }
0234 
0235     return num;
0236 }
0237 
0238 static u32 uniphier_i2c_functionality(struct i2c_adapter *adap)
0239 {
0240     return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
0241 }
0242 
0243 static const struct i2c_algorithm uniphier_i2c_algo = {
0244     .master_xfer = uniphier_i2c_master_xfer,
0245     .functionality = uniphier_i2c_functionality,
0246 };
0247 
0248 static void uniphier_i2c_reset(struct uniphier_i2c_priv *priv, bool reset_on)
0249 {
0250     u32 val = UNIPHIER_I2C_BRST_RSCL;
0251 
0252     val |= reset_on ? 0 : UNIPHIER_I2C_BRST_FOEN;
0253     writel(val, priv->membase + UNIPHIER_I2C_BRST);
0254 }
0255 
0256 static int uniphier_i2c_get_scl(struct i2c_adapter *adap)
0257 {
0258     struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);
0259 
0260     return !!(readl(priv->membase + UNIPHIER_I2C_BSTS) &
0261                             UNIPHIER_I2C_BSTS_SCL);
0262 }
0263 
0264 static void uniphier_i2c_set_scl(struct i2c_adapter *adap, int val)
0265 {
0266     struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);
0267 
0268     writel(val ? UNIPHIER_I2C_BRST_RSCL : 0,
0269            priv->membase + UNIPHIER_I2C_BRST);
0270 }
0271 
0272 static int uniphier_i2c_get_sda(struct i2c_adapter *adap)
0273 {
0274     struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);
0275 
0276     return !!(readl(priv->membase + UNIPHIER_I2C_BSTS) &
0277                             UNIPHIER_I2C_BSTS_SDA);
0278 }
0279 
0280 static void uniphier_i2c_unprepare_recovery(struct i2c_adapter *adap)
0281 {
0282     uniphier_i2c_reset(i2c_get_adapdata(adap), false);
0283 }
0284 
0285 static struct i2c_bus_recovery_info uniphier_i2c_bus_recovery_info = {
0286     .recover_bus = i2c_generic_scl_recovery,
0287     .get_scl = uniphier_i2c_get_scl,
0288     .set_scl = uniphier_i2c_set_scl,
0289     .get_sda = uniphier_i2c_get_sda,
0290     .unprepare_recovery = uniphier_i2c_unprepare_recovery,
0291 };
0292 
0293 static void uniphier_i2c_hw_init(struct uniphier_i2c_priv *priv)
0294 {
0295     unsigned int cyc = priv->clk_cycle;
0296 
0297     uniphier_i2c_reset(priv, true);
0298 
0299     /*
0300      * Bit30-16: clock cycles of tLOW.
0301      *  Standard-mode: tLOW = 4.7 us, tHIGH = 4.0 us
0302      *  Fast-mode:     tLOW = 1.3 us, tHIGH = 0.6 us
0303      * "tLow/tHIGH = 5/4" meets both.
0304      */
0305     writel((cyc * 5 / 9 << 16) | cyc, priv->membase + UNIPHIER_I2C_CLK);
0306 
0307     uniphier_i2c_reset(priv, false);
0308 }
0309 
0310 static int uniphier_i2c_probe(struct platform_device *pdev)
0311 {
0312     struct device *dev = &pdev->dev;
0313     struct uniphier_i2c_priv *priv;
0314     u32 bus_speed;
0315     unsigned long clk_rate;
0316     int irq, ret;
0317 
0318     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0319     if (!priv)
0320         return -ENOMEM;
0321 
0322     priv->membase = devm_platform_ioremap_resource(pdev, 0);
0323     if (IS_ERR(priv->membase))
0324         return PTR_ERR(priv->membase);
0325 
0326     irq = platform_get_irq(pdev, 0);
0327     if (irq < 0)
0328         return irq;
0329 
0330     if (of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed))
0331         bus_speed = I2C_MAX_STANDARD_MODE_FREQ;
0332 
0333     if (!bus_speed || bus_speed > I2C_MAX_FAST_MODE_FREQ) {
0334         dev_err(dev, "invalid clock-frequency %d\n", bus_speed);
0335         return -EINVAL;
0336     }
0337 
0338     priv->clk = devm_clk_get(dev, NULL);
0339     if (IS_ERR(priv->clk)) {
0340         dev_err(dev, "failed to get clock\n");
0341         return PTR_ERR(priv->clk);
0342     }
0343 
0344     ret = clk_prepare_enable(priv->clk);
0345     if (ret)
0346         return ret;
0347 
0348     clk_rate = clk_get_rate(priv->clk);
0349     if (!clk_rate) {
0350         dev_err(dev, "input clock rate should not be zero\n");
0351         ret = -EINVAL;
0352         goto disable_clk;
0353     }
0354 
0355     priv->clk_cycle = clk_rate / bus_speed;
0356     init_completion(&priv->comp);
0357     priv->adap.owner = THIS_MODULE;
0358     priv->adap.algo = &uniphier_i2c_algo;
0359     priv->adap.dev.parent = dev;
0360     priv->adap.dev.of_node = dev->of_node;
0361     strscpy(priv->adap.name, "UniPhier I2C", sizeof(priv->adap.name));
0362     priv->adap.bus_recovery_info = &uniphier_i2c_bus_recovery_info;
0363     i2c_set_adapdata(&priv->adap, priv);
0364     platform_set_drvdata(pdev, priv);
0365 
0366     uniphier_i2c_hw_init(priv);
0367 
0368     ret = devm_request_irq(dev, irq, uniphier_i2c_interrupt, 0, pdev->name,
0369                    priv);
0370     if (ret) {
0371         dev_err(dev, "failed to request irq %d\n", irq);
0372         goto disable_clk;
0373     }
0374 
0375     ret = i2c_add_adapter(&priv->adap);
0376 disable_clk:
0377     if (ret)
0378         clk_disable_unprepare(priv->clk);
0379 
0380     return ret;
0381 }
0382 
0383 static int uniphier_i2c_remove(struct platform_device *pdev)
0384 {
0385     struct uniphier_i2c_priv *priv = platform_get_drvdata(pdev);
0386 
0387     i2c_del_adapter(&priv->adap);
0388     clk_disable_unprepare(priv->clk);
0389 
0390     return 0;
0391 }
0392 
0393 static int __maybe_unused uniphier_i2c_suspend(struct device *dev)
0394 {
0395     struct uniphier_i2c_priv *priv = dev_get_drvdata(dev);
0396 
0397     clk_disable_unprepare(priv->clk);
0398 
0399     return 0;
0400 }
0401 
0402 static int __maybe_unused uniphier_i2c_resume(struct device *dev)
0403 {
0404     struct uniphier_i2c_priv *priv = dev_get_drvdata(dev);
0405     int ret;
0406 
0407     ret = clk_prepare_enable(priv->clk);
0408     if (ret)
0409         return ret;
0410 
0411     uniphier_i2c_hw_init(priv);
0412 
0413     return 0;
0414 }
0415 
0416 static const struct dev_pm_ops uniphier_i2c_pm_ops = {
0417     SET_SYSTEM_SLEEP_PM_OPS(uniphier_i2c_suspend, uniphier_i2c_resume)
0418 };
0419 
0420 static const struct of_device_id uniphier_i2c_match[] = {
0421     { .compatible = "socionext,uniphier-i2c" },
0422     { /* sentinel */ }
0423 };
0424 MODULE_DEVICE_TABLE(of, uniphier_i2c_match);
0425 
0426 static struct platform_driver uniphier_i2c_drv = {
0427     .probe  = uniphier_i2c_probe,
0428     .remove = uniphier_i2c_remove,
0429     .driver = {
0430         .name  = "uniphier-i2c",
0431         .of_match_table = uniphier_i2c_match,
0432         .pm = &uniphier_i2c_pm_ops,
0433     },
0434 };
0435 module_platform_driver(uniphier_i2c_drv);
0436 
0437 MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
0438 MODULE_DESCRIPTION("UniPhier I2C bus driver");
0439 MODULE_LICENSE("GPL");