i2c: nomadik: use bitops helpers
authorThéo Lebrun <theo.lebrun@bootlin.com>
Wed, 6 Mar 2024 17:59:24 +0000 (18:59 +0100)
committerAndi Shyti <andi.shyti@kernel.org>
Tue, 12 Mar 2024 10:50:43 +0000 (11:50 +0100)
Constant register bit fields are declared using hardcoded hex values;
replace them by calls to BIT() and GENMASK(). Replace custom GEN_MASK()
macro by the generic FIELD_PREP(). Replace manual bit manipulations by
the generic FIELD_GET() macro.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
drivers/i2c/busses/i2c-nomadik.c

index 80bdf7e4261306267ee10e9f30d2d461ecf3a53d..63ce70f763a863e37aebfea655b949b5b8c1b006 100644 (file)
@@ -9,6 +9,7 @@
  * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
  * Author: Sachin Verma <sachin.verma@st.com>
  */
+#include <linux/bitfield.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/amba/bus.h>
 #define I2C_ICR                (0x038)
 
 /* Control registers */
-#define I2C_CR_PE              (0x1 << 0)      /* Peripheral Enable */
-#define I2C_CR_OM              (0x3 << 1)      /* Operating mode */
-#define I2C_CR_SAM             (0x1 << 3)      /* Slave addressing mode */
-#define I2C_CR_SM              (0x3 << 4)      /* Speed mode */
-#define I2C_CR_SGCM            (0x1 << 6)      /* Slave general call mode */
-#define I2C_CR_FTX             (0x1 << 7)      /* Flush Transmit */
-#define I2C_CR_FRX             (0x1 << 8)      /* Flush Receive */
-#define I2C_CR_DMA_TX_EN       (0x1 << 9)      /* DMA Tx enable */
-#define I2C_CR_DMA_RX_EN       (0x1 << 10)     /* DMA Rx Enable */
-#define I2C_CR_DMA_SLE         (0x1 << 11)     /* DMA sync. logic enable */
-#define I2C_CR_LM              (0x1 << 12)     /* Loopback mode */
-#define I2C_CR_FON             (0x3 << 13)     /* Filtering on */
-#define I2C_CR_FS              (0x3 << 15)     /* Force stop enable */
+#define I2C_CR_PE              BIT(0)          /* Peripheral Enable */
+#define I2C_CR_OM              GENMASK(2, 1)   /* Operating mode */
+#define I2C_CR_SAM             BIT(3)          /* Slave addressing mode */
+#define I2C_CR_SM              GENMASK(5, 4)   /* Speed mode */
+#define I2C_CR_SGCM            BIT(6)          /* Slave general call mode */
+#define I2C_CR_FTX             BIT(7)          /* Flush Transmit */
+#define I2C_CR_FRX             BIT(8)          /* Flush Receive */
+#define I2C_CR_DMA_TX_EN       BIT(9)          /* DMA Tx enable */
+#define I2C_CR_DMA_RX_EN       BIT(10)         /* DMA Rx Enable */
+#define I2C_CR_DMA_SLE         BIT(11)         /* DMA sync. logic enable */
+#define I2C_CR_LM              BIT(12)         /* Loopback mode */
+#define I2C_CR_FON             GENMASK(14, 13) /* Filtering on */
+#define I2C_CR_FS              GENMASK(16, 15) /* Force stop enable */
+
+/* Slave control register (SCR) */
+#define I2C_SCR_SLSU           GENMASK(31, 16) /* Slave data setup time */
 
 /* Master controller (MCR) register */
-#define I2C_MCR_OP             (0x1 << 0)      /* Operation */
-#define I2C_MCR_A7             (0x7f << 1)     /* 7-bit address */
-#define I2C_MCR_EA10           (0x7 << 8)      /* 10-bit Extended address */
-#define I2C_MCR_SB             (0x1 << 11)     /* Extended address */
-#define I2C_MCR_AM             (0x3 << 12)     /* Address type */
-#define I2C_MCR_STOP           (0x1 << 14)     /* Stop condition */
-#define I2C_MCR_LENGTH         (0x7ff << 15)   /* Transaction length */
+#define I2C_MCR_OP             BIT(0)          /* Operation */
+#define I2C_MCR_A7             GENMASK(7, 1)   /* 7-bit address */
+#define I2C_MCR_EA10           GENMASK(10, 8)  /* 10-bit Extended address */
+#define I2C_MCR_SB             BIT(11)         /* Extended address */
+#define I2C_MCR_AM             GENMASK(13, 12) /* Address type */
+#define I2C_MCR_STOP           BIT(14)         /* Stop condition */
+#define I2C_MCR_LENGTH         GENMASK(25, 15) /* Transaction length */
 
 /* Status register (SR) */
-#define I2C_SR_OP              (0x3 << 0)      /* Operation */
-#define I2C_SR_STATUS          (0x3 << 2)      /* controller status */
-#define I2C_SR_CAUSE           (0x7 << 4)      /* Abort cause */
-#define I2C_SR_TYPE            (0x3 << 7)      /* Receive type */
-#define I2C_SR_LENGTH          (0x7ff << 9)    /* Transfer length */
+#define I2C_SR_OP              GENMASK(1, 0)   /* Operation */
+#define I2C_SR_STATUS          GENMASK(3, 2)   /* controller status */
+#define I2C_SR_CAUSE           GENMASK(6, 4)   /* Abort cause */
+#define I2C_SR_TYPE            GENMASK(8, 7)   /* Receive type */
+#define I2C_SR_LENGTH          GENMASK(19, 9)  /* Transfer length */
+
+/* Baud-rate counter register (BRCR) */
+#define I2C_BRCR_BRCNT1                GENMASK(31, 16) /* Baud-rate counter 1 */
+#define I2C_BRCR_BRCNT2                GENMASK(15, 0)  /* Baud-rate counter 2 */
 
 /* Interrupt mask set/clear (IMSCR) bits */
-#define I2C_IT_TXFE            (0x1 << 0)
-#define I2C_IT_TXFNE           (0x1 << 1)
-#define I2C_IT_TXFF            (0x1 << 2)
-#define I2C_IT_TXFOVR          (0x1 << 3)
-#define I2C_IT_RXFE            (0x1 << 4)
-#define I2C_IT_RXFNF           (0x1 << 5)
-#define I2C_IT_RXFF            (0x1 << 6)
-#define I2C_IT_RFSR            (0x1 << 16)
-#define I2C_IT_RFSE            (0x1 << 17)
-#define I2C_IT_WTSR            (0x1 << 18)
-#define I2C_IT_MTD             (0x1 << 19)
-#define I2C_IT_STD             (0x1 << 20)
-#define I2C_IT_MAL             (0x1 << 24)
-#define I2C_IT_BERR            (0x1 << 25)
-#define I2C_IT_MTDWS           (0x1 << 28)
-
-#define GEN_MASK(val, mask, sb)  (((val) << (sb)) & (mask))
+#define I2C_IT_TXFE            BIT(0)
+#define I2C_IT_TXFNE           BIT(1)
+#define I2C_IT_TXFF            BIT(2)
+#define I2C_IT_TXFOVR          BIT(3)
+#define I2C_IT_RXFE            BIT(4)
+#define I2C_IT_RXFNF           BIT(5)
+#define I2C_IT_RXFF            BIT(6)
+#define I2C_IT_RFSR            BIT(16)
+#define I2C_IT_RFSE            BIT(17)
+#define I2C_IT_WTSR            BIT(18)
+#define I2C_IT_MTD             BIT(19)
+#define I2C_IT_STD             BIT(20)
+#define I2C_IT_MAL             BIT(24)
+#define I2C_IT_BERR            BIT(25)
+#define I2C_IT_MTDWS           BIT(28)
 
 /* some bits in ICR are reserved */
 #define I2C_CLEAR_ALL_INTS     0x131f007f
@@ -128,6 +134,12 @@ enum i2c_operation {
        I2C_READ = 0x01
 };
 
+enum i2c_operating_mode {
+       I2C_OM_SLAVE,
+       I2C_OM_MASTER,
+       I2C_OM_MASTER_OR_SLAVE,
+};
+
 /**
  * struct i2c_nmk_client - client specific data
  * @slave_adr: 7-bit slave address
@@ -284,7 +296,10 @@ exit:
 }
 
 /* enable peripheral, master mode operation */
-#define DEFAULT_I2C_REG_CR     ((1 << 1) | I2C_CR_PE)
+#define DEFAULT_I2C_REG_CR     (FIELD_PREP(I2C_CR_OM, I2C_OM_MASTER) | I2C_CR_PE)
+
+/* grab top three bits from extended I2C addresses */
+#define ADR_3MSB_BITS          GENMASK(9, 7)
 
 /**
  * load_i2c_mcr_reg() - load the MCR register
@@ -296,41 +311,42 @@ static u32 load_i2c_mcr_reg(struct nmk_i2c_dev *priv, u16 flags)
        u32 mcr = 0;
        unsigned short slave_adr_3msb_bits;
 
-       mcr |= GEN_MASK(priv->cli.slave_adr, I2C_MCR_A7, 1);
+       mcr |= FIELD_PREP(I2C_MCR_A7, priv->cli.slave_adr);
 
        if (unlikely(flags & I2C_M_TEN)) {
                /* 10-bit address transaction */
-               mcr |= GEN_MASK(2, I2C_MCR_AM, 12);
+               mcr |= FIELD_PREP(I2C_MCR_AM, 2);
                /*
                 * Get the top 3 bits.
                 * EA10 represents extended address in MCR. This includes
                 * the extension (MSB bits) of the 7 bit address loaded
                 * in A7
                 */
-               slave_adr_3msb_bits = (priv->cli.slave_adr >> 7) & 0x7;
+               slave_adr_3msb_bits = FIELD_GET(ADR_3MSB_BITS,
+                                               priv->cli.slave_adr);
 
-               mcr |= GEN_MASK(slave_adr_3msb_bits, I2C_MCR_EA10, 8);
+               mcr |= FIELD_PREP(I2C_MCR_EA10, slave_adr_3msb_bits);
        } else {
                /* 7-bit address transaction */
-               mcr |= GEN_MASK(1, I2C_MCR_AM, 12);
+               mcr |= FIELD_PREP(I2C_MCR_AM, 1);
        }
 
        /* start byte procedure not applied */
-       mcr |= GEN_MASK(0, I2C_MCR_SB, 11);
+       mcr |= FIELD_PREP(I2C_MCR_SB, 0);
 
        /* check the operation, master read/write? */
        if (priv->cli.operation == I2C_WRITE)
-               mcr |= GEN_MASK(I2C_WRITE, I2C_MCR_OP, 0);
+               mcr |= FIELD_PREP(I2C_MCR_OP, I2C_WRITE);
        else
-               mcr |= GEN_MASK(I2C_READ, I2C_MCR_OP, 0);
+               mcr |= FIELD_PREP(I2C_MCR_OP, I2C_READ);
 
        /* stop or repeated start? */
        if (priv->stop)
-               mcr |= GEN_MASK(1, I2C_MCR_STOP, 14);
+               mcr |= FIELD_PREP(I2C_MCR_STOP, 1);
        else
-               mcr &= ~(GEN_MASK(1, I2C_MCR_STOP, 14));
+               mcr &= ~FIELD_PREP(I2C_MCR_STOP, 1);
 
-       mcr |= GEN_MASK(priv->cli.count, I2C_MCR_LENGTH, 15);
+       mcr |= FIELD_PREP(I2C_MCR_LENGTH, priv->cli.count);
 
        return mcr;
 }
@@ -383,7 +399,7 @@ static void setup_i2c_controller(struct nmk_i2c_dev *priv)
        slsu += 1;
 
        dev_dbg(&priv->adev->dev, "calculated SLSU = %04x\n", slsu);
-       writel(slsu << 16, priv->virtbase + I2C_SCR);
+       writel(FIELD_PREP(I2C_SCR_SLSU, slsu), priv->virtbase + I2C_SCR);
 
        /*
         * The spec says, in case of std. mode the divider is
@@ -399,8 +415,8 @@ static void setup_i2c_controller(struct nmk_i2c_dev *priv)
         * plus operation. Currently we do not supprt high speed mode
         * so set brcr1 to 0.
         */
-       brcr1 = 0 << 16;
-       brcr2 = (i2c_clk / (priv->clk_freq * div)) & 0xffff;
+       brcr1 = FIELD_PREP(I2C_BRCR_BRCNT1, 0);
+       brcr2 = FIELD_PREP(I2C_BRCR_BRCNT2, i2c_clk / (priv->clk_freq * div));
 
        /* set the baud rate counter register */
        writel((brcr1 | brcr2), priv->virtbase + I2C_BRCR);
@@ -414,12 +430,13 @@ static void setup_i2c_controller(struct nmk_i2c_dev *priv)
        if (priv->sm > I2C_FREQ_MODE_FAST) {
                dev_err(&priv->adev->dev,
                        "do not support this mode defaulting to std. mode\n");
-               brcr2 = i2c_clk / (I2C_MAX_STANDARD_MODE_FREQ * 2) & 0xffff;
+               brcr2 = FIELD_PREP(I2C_BRCR_BRCNT2,
+                                  i2c_clk / (I2C_MAX_STANDARD_MODE_FREQ * 2));
                writel((brcr1 | brcr2), priv->virtbase + I2C_BRCR);
-               writel(I2C_FREQ_MODE_STANDARD << 4,
-                               priv->virtbase + I2C_CR);
+               writel(FIELD_PREP(I2C_CR_SM, I2C_FREQ_MODE_STANDARD),
+                      priv->virtbase + I2C_CR);
        }
-       writel(priv->sm << 4, priv->virtbase + I2C_CR);
+       writel(FIELD_PREP(I2C_CR_SM, priv->sm), priv->virtbase + I2C_CR);
 
        /* set the Tx and Rx FIFO threshold */
        writel(priv->tft, priv->virtbase + I2C_TFTR);
@@ -583,13 +600,8 @@ static int nmk_i2c_xfer_one(struct nmk_i2c_dev *priv, u16 flags)
                u32 cause;
 
                i2c_sr = readl(priv->virtbase + I2C_SR);
-               /*
-                * Check if the controller I2C operation status
-                * is set to ABORT(11b).
-                */
-               if (((i2c_sr >> 2) & 0x3) == 0x3) {
-                       /* get the abort cause */
-                       cause = (i2c_sr >> 4) & 0x7;
+               if (FIELD_GET(I2C_SR_STATUS, i2c_sr) == I2C_ABORT) {
+                       cause = FIELD_GET(I2C_SR_CAUSE, i2c_sr);
                        dev_err(&priv->adev->dev, "%s\n",
                                cause >= ARRAY_SIZE(abort_causes) ?
                                "unknown reason" :
@@ -730,7 +742,7 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
        misr = readl(priv->virtbase + I2C_MISR);
 
        src = __ffs(misr);
-       switch ((1 << src)) {
+       switch (BIT(src)) {
 
        /* Transmit FIFO nearly empty interrupt */
        case I2C_IT_TXFNE:
@@ -824,15 +836,18 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
         * during the transaction.
         */
        case I2C_IT_BERR:
+       {
+               u32 sr;
+
+               sr = readl(priv->virtbase + I2C_SR);
                priv->result = -EIO;
-               /* get the status */
-               if (((readl(priv->virtbase + I2C_SR) >> 2) & 0x3) == I2C_ABORT)
+               if (FIELD_GET(I2C_SR_STATUS, sr) == I2C_ABORT)
                        init_hw(priv);
 
                i2c_set_bit(priv->virtbase + I2C_ICR, I2C_IT_BERR);
                complete(&priv->xfer_complete);
-
-               break;
+       }
+       break;
 
        /*
         * Tx FIFO overrun interrupt.