Merge branch 'parisc-4.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
[cascardo/linux.git] / drivers / mfd / stmpe.c
index 94c7cc0..cfdae8a 100644 (file)
@@ -469,6 +469,8 @@ static const struct mfd_cell stmpe_ts_cell = {
 
 static const u8 stmpe811_regs[] = {
        [STMPE_IDX_CHIP_ID]     = STMPE811_REG_CHIP_ID,
+       [STMPE_IDX_SYS_CTRL]    = STMPE811_REG_SYS_CTRL,
+       [STMPE_IDX_SYS_CTRL2]   = STMPE811_REG_SYS_CTRL2,
        [STMPE_IDX_ICR_LSB]     = STMPE811_REG_INT_CTRL,
        [STMPE_IDX_IER_LSB]     = STMPE811_REG_INT_EN,
        [STMPE_IDX_ISR_MSB]     = STMPE811_REG_INT_STA,
@@ -481,7 +483,7 @@ static const u8 stmpe811_regs[] = {
        [STMPE_IDX_GPAFR_U_MSB] = STMPE811_REG_GPIO_AF,
        [STMPE_IDX_IEGPIOR_LSB] = STMPE811_REG_GPIO_INT_EN,
        [STMPE_IDX_ISGPIOR_MSB] = STMPE811_REG_GPIO_INT_STA,
-       [STMPE_IDX_GPEDR_MSB]   = STMPE811_REG_GPIO_ED,
+       [STMPE_IDX_GPEDR_LSB]   = STMPE811_REG_GPIO_ED,
 };
 
 static struct stmpe_variant_block stmpe811_blocks[] = {
@@ -511,7 +513,7 @@ static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks,
        if (blocks & STMPE_BLOCK_TOUCHSCREEN)
                mask |= STMPE811_SYS_CTRL2_TSC_OFF;
 
-       return __stmpe_set_bits(stmpe, STMPE811_REG_SYS_CTRL2, mask,
+       return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], mask,
                                enable ? 0 : mask);
 }
 
@@ -550,26 +552,90 @@ static struct stmpe_variant_info stmpe610 = {
        .get_altfunc    = stmpe811_get_altfunc,
 };
 
+/*
+ * STMPE1600
+ * Compared to all others STMPE variant, LSB and MSB regs are located in this
+ * order :     LSB   addr
+ *             MSB   addr + 1
+ * As there is only 2 * 8bits registers for GPMR/GPSR/IEGPIOPR, CSB index is MSB registers
+ */
+
+static const u8 stmpe1600_regs[] = {
+       [STMPE_IDX_CHIP_ID]     = STMPE1600_REG_CHIP_ID,
+       [STMPE_IDX_SYS_CTRL]    = STMPE1600_REG_SYS_CTRL,
+       [STMPE_IDX_ICR_LSB]     = STMPE1600_REG_SYS_CTRL,
+       [STMPE_IDX_GPMR_LSB]    = STMPE1600_REG_GPMR_LSB,
+       [STMPE_IDX_GPMR_CSB]    = STMPE1600_REG_GPMR_MSB,
+       [STMPE_IDX_GPSR_LSB]    = STMPE1600_REG_GPSR_LSB,
+       [STMPE_IDX_GPSR_CSB]    = STMPE1600_REG_GPSR_MSB,
+       [STMPE_IDX_GPDR_LSB]    = STMPE1600_REG_GPDR_LSB,
+       [STMPE_IDX_GPDR_CSB]    = STMPE1600_REG_GPDR_MSB,
+       [STMPE_IDX_IEGPIOR_LSB] = STMPE1600_REG_IEGPIOR_LSB,
+       [STMPE_IDX_IEGPIOR_CSB] = STMPE1600_REG_IEGPIOR_MSB,
+       [STMPE_IDX_ISGPIOR_LSB] = STMPE1600_REG_ISGPIOR_LSB,
+};
+
+static struct stmpe_variant_block stmpe1600_blocks[] = {
+       {
+               .cell   = &stmpe_gpio_cell,
+               .irq    = 0,
+               .block  = STMPE_BLOCK_GPIO,
+       },
+};
+
+static int stmpe1600_enable(struct stmpe *stmpe, unsigned int blocks,
+                          bool enable)
+{
+       if (blocks & STMPE_BLOCK_GPIO)
+               return 0;
+       else
+               return -EINVAL;
+}
+
+static struct stmpe_variant_info stmpe1600 = {
+       .name           = "stmpe1600",
+       .id_val         = STMPE1600_ID,
+       .id_mask        = 0xffff,
+       .num_gpios      = 16,
+       .af_bits        = 0,
+       .regs           = stmpe1600_regs,
+       .blocks         = stmpe1600_blocks,
+       .num_blocks     = ARRAY_SIZE(stmpe1600_blocks),
+       .num_irqs       = STMPE1600_NR_INTERNAL_IRQS,
+       .enable         = stmpe1600_enable,
+};
+
 /*
  * STMPE1601
  */
 
 static const u8 stmpe1601_regs[] = {
        [STMPE_IDX_CHIP_ID]     = STMPE1601_REG_CHIP_ID,
+       [STMPE_IDX_SYS_CTRL]    = STMPE1601_REG_SYS_CTRL,
+       [STMPE_IDX_SYS_CTRL2]   = STMPE1601_REG_SYS_CTRL2,
        [STMPE_IDX_ICR_LSB]     = STMPE1601_REG_ICR_LSB,
+       [STMPE_IDX_IER_MSB]     = STMPE1601_REG_IER_MSB,
        [STMPE_IDX_IER_LSB]     = STMPE1601_REG_IER_LSB,
        [STMPE_IDX_ISR_MSB]     = STMPE1601_REG_ISR_MSB,
        [STMPE_IDX_GPMR_LSB]    = STMPE1601_REG_GPIO_MP_LSB,
+       [STMPE_IDX_GPMR_CSB]    = STMPE1601_REG_GPIO_MP_MSB,
        [STMPE_IDX_GPSR_LSB]    = STMPE1601_REG_GPIO_SET_LSB,
+       [STMPE_IDX_GPSR_CSB]    = STMPE1601_REG_GPIO_SET_MSB,
        [STMPE_IDX_GPCR_LSB]    = STMPE1601_REG_GPIO_CLR_LSB,
+       [STMPE_IDX_GPCR_CSB]    = STMPE1601_REG_GPIO_CLR_MSB,
        [STMPE_IDX_GPDR_LSB]    = STMPE1601_REG_GPIO_SET_DIR_LSB,
+       [STMPE_IDX_GPDR_CSB]    = STMPE1601_REG_GPIO_SET_DIR_MSB,
+       [STMPE_IDX_GPEDR_LSB]   = STMPE1601_REG_GPIO_ED_LSB,
+       [STMPE_IDX_GPEDR_CSB]   = STMPE1601_REG_GPIO_ED_MSB,
        [STMPE_IDX_GPRER_LSB]   = STMPE1601_REG_GPIO_RE_LSB,
+       [STMPE_IDX_GPRER_CSB]   = STMPE1601_REG_GPIO_RE_MSB,
        [STMPE_IDX_GPFER_LSB]   = STMPE1601_REG_GPIO_FE_LSB,
+       [STMPE_IDX_GPFER_CSB]   = STMPE1601_REG_GPIO_FE_MSB,
        [STMPE_IDX_GPPUR_LSB]   = STMPE1601_REG_GPIO_PU_LSB,
        [STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB,
        [STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB,
+       [STMPE_IDX_IEGPIOR_CSB] = STMPE1601_REG_INT_EN_GPIO_MASK_MSB,
        [STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB,
-       [STMPE_IDX_GPEDR_MSB]   = STMPE1601_REG_GPIO_ED_MSB,
 };
 
 static struct stmpe_variant_block stmpe1601_blocks[] = {
@@ -640,13 +706,13 @@ static int stmpe1601_autosleep(struct stmpe *stmpe,
                return timeout;
        }
 
-       ret = __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2,
+       ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2],
                        STMPE1601_AUTOSLEEP_TIMEOUT_MASK,
                        timeout);
        if (ret < 0)
                return ret;
 
-       return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2,
+       return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2],
                        STPME1601_AUTOSLEEP_ENABLE,
                        STPME1601_AUTOSLEEP_ENABLE);
 }
@@ -671,7 +737,7 @@ static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks,
        else
                mask &= ~STMPE1601_SYS_CTRL_ENABLE_SPWM;
 
-       return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL, mask,
+       return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask,
                                enable ? mask : 0);
 }
 
@@ -710,18 +776,33 @@ static struct stmpe_variant_info stmpe1601 = {
  */
 static const u8 stmpe1801_regs[] = {
        [STMPE_IDX_CHIP_ID]     = STMPE1801_REG_CHIP_ID,
+       [STMPE_IDX_SYS_CTRL]    = STMPE1801_REG_SYS_CTRL,
        [STMPE_IDX_ICR_LSB]     = STMPE1801_REG_INT_CTRL_LOW,
        [STMPE_IDX_IER_LSB]     = STMPE1801_REG_INT_EN_MASK_LOW,
        [STMPE_IDX_ISR_LSB]     = STMPE1801_REG_INT_STA_LOW,
        [STMPE_IDX_GPMR_LSB]    = STMPE1801_REG_GPIO_MP_LOW,
+       [STMPE_IDX_GPMR_CSB]    = STMPE1801_REG_GPIO_MP_MID,
+       [STMPE_IDX_GPMR_MSB]    = STMPE1801_REG_GPIO_MP_HIGH,
        [STMPE_IDX_GPSR_LSB]    = STMPE1801_REG_GPIO_SET_LOW,
+       [STMPE_IDX_GPSR_CSB]    = STMPE1801_REG_GPIO_SET_MID,
+       [STMPE_IDX_GPSR_MSB]    = STMPE1801_REG_GPIO_SET_HIGH,
        [STMPE_IDX_GPCR_LSB]    = STMPE1801_REG_GPIO_CLR_LOW,
+       [STMPE_IDX_GPCR_CSB]    = STMPE1801_REG_GPIO_CLR_MID,
+       [STMPE_IDX_GPCR_MSB]    = STMPE1801_REG_GPIO_CLR_HIGH,
        [STMPE_IDX_GPDR_LSB]    = STMPE1801_REG_GPIO_SET_DIR_LOW,
+       [STMPE_IDX_GPDR_CSB]    = STMPE1801_REG_GPIO_SET_DIR_MID,
+       [STMPE_IDX_GPDR_MSB]    = STMPE1801_REG_GPIO_SET_DIR_HIGH,
        [STMPE_IDX_GPRER_LSB]   = STMPE1801_REG_GPIO_RE_LOW,
+       [STMPE_IDX_GPRER_CSB]   = STMPE1801_REG_GPIO_RE_MID,
+       [STMPE_IDX_GPRER_MSB]   = STMPE1801_REG_GPIO_RE_HIGH,
        [STMPE_IDX_GPFER_LSB]   = STMPE1801_REG_GPIO_FE_LOW,
+       [STMPE_IDX_GPFER_CSB]   = STMPE1801_REG_GPIO_FE_MID,
+       [STMPE_IDX_GPFER_MSB]   = STMPE1801_REG_GPIO_FE_HIGH,
        [STMPE_IDX_GPPUR_LSB]   = STMPE1801_REG_GPIO_PULL_UP_LOW,
        [STMPE_IDX_IEGPIOR_LSB] = STMPE1801_REG_INT_EN_GPIO_MASK_LOW,
-       [STMPE_IDX_ISGPIOR_LSB] = STMPE1801_REG_INT_STA_GPIO_LOW,
+       [STMPE_IDX_IEGPIOR_CSB] = STMPE1801_REG_INT_EN_GPIO_MASK_MID,
+       [STMPE_IDX_IEGPIOR_MSB] = STMPE1801_REG_INT_EN_GPIO_MASK_HIGH,
+       [STMPE_IDX_ISGPIOR_MSB] = STMPE1801_REG_INT_STA_GPIO_HIGH,
 };
 
 static struct stmpe_variant_block stmpe1801_blocks[] = {
@@ -751,22 +832,31 @@ static int stmpe1801_enable(struct stmpe *stmpe, unsigned int blocks,
                                enable ? mask : 0);
 }
 
-static int stmpe1801_reset(struct stmpe *stmpe)
+static int stmpe_reset(struct stmpe *stmpe)
 {
+       u16 id_val = stmpe->variant->id_val;
        unsigned long timeout;
        int ret = 0;
+       u8 reset_bit;
+
+       if (id_val == STMPE811_ID)
+               /* STMPE801 and STMPE610 use bit 1 of SYS_CTRL register */
+               reset_bit = STMPE811_SYS_CTRL_RESET;
+       else
+               /* all other STMPE variant use bit 7 of SYS_CTRL register */
+               reset_bit = STMPE_SYS_CTRL_RESET;
 
-       ret = __stmpe_set_bits(stmpe, STMPE1801_REG_SYS_CTRL,
-               STMPE1801_MSK_SYS_CTRL_RESET, STMPE1801_MSK_SYS_CTRL_RESET);
+       ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL],
+                              reset_bit, reset_bit);
        if (ret < 0)
                return ret;
 
        timeout = jiffies + msecs_to_jiffies(100);
        while (time_before(jiffies, timeout)) {
-               ret = __stmpe_reg_read(stmpe, STMPE1801_REG_SYS_CTRL);
+               ret = __stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL]);
                if (ret < 0)
                        return ret;
-               if (!(ret & STMPE1801_MSK_SYS_CTRL_RESET))
+               if (!(ret & reset_bit))
                        return 0;
                usleep_range(100, 200);
        }
@@ -794,20 +884,39 @@ static struct stmpe_variant_info stmpe1801 = {
 
 static const u8 stmpe24xx_regs[] = {
        [STMPE_IDX_CHIP_ID]     = STMPE24XX_REG_CHIP_ID,
+       [STMPE_IDX_SYS_CTRL]    = STMPE24XX_REG_SYS_CTRL,
+       [STMPE_IDX_SYS_CTRL2]   = STMPE24XX_REG_SYS_CTRL2,
        [STMPE_IDX_ICR_LSB]     = STMPE24XX_REG_ICR_LSB,
+       [STMPE_IDX_IER_MSB]     = STMPE24XX_REG_IER_MSB,
        [STMPE_IDX_IER_LSB]     = STMPE24XX_REG_IER_LSB,
        [STMPE_IDX_ISR_MSB]     = STMPE24XX_REG_ISR_MSB,
        [STMPE_IDX_GPMR_LSB]    = STMPE24XX_REG_GPMR_LSB,
+       [STMPE_IDX_GPMR_CSB]    = STMPE24XX_REG_GPMR_CSB,
+       [STMPE_IDX_GPMR_MSB]    = STMPE24XX_REG_GPMR_MSB,
        [STMPE_IDX_GPSR_LSB]    = STMPE24XX_REG_GPSR_LSB,
+       [STMPE_IDX_GPSR_CSB]    = STMPE24XX_REG_GPSR_CSB,
+       [STMPE_IDX_GPSR_MSB]    = STMPE24XX_REG_GPSR_MSB,
        [STMPE_IDX_GPCR_LSB]    = STMPE24XX_REG_GPCR_LSB,
+       [STMPE_IDX_GPCR_CSB]    = STMPE24XX_REG_GPCR_CSB,
+       [STMPE_IDX_GPCR_MSB]    = STMPE24XX_REG_GPCR_MSB,
        [STMPE_IDX_GPDR_LSB]    = STMPE24XX_REG_GPDR_LSB,
+       [STMPE_IDX_GPDR_CSB]    = STMPE24XX_REG_GPDR_CSB,
+       [STMPE_IDX_GPDR_MSB]    = STMPE24XX_REG_GPDR_MSB,
        [STMPE_IDX_GPRER_LSB]   = STMPE24XX_REG_GPRER_LSB,
+       [STMPE_IDX_GPRER_CSB]   = STMPE24XX_REG_GPRER_CSB,
+       [STMPE_IDX_GPRER_MSB]   = STMPE24XX_REG_GPRER_MSB,
        [STMPE_IDX_GPFER_LSB]   = STMPE24XX_REG_GPFER_LSB,
+       [STMPE_IDX_GPFER_CSB]   = STMPE24XX_REG_GPFER_CSB,
+       [STMPE_IDX_GPFER_MSB]   = STMPE24XX_REG_GPFER_MSB,
        [STMPE_IDX_GPPUR_LSB]   = STMPE24XX_REG_GPPUR_LSB,
        [STMPE_IDX_GPPDR_LSB]   = STMPE24XX_REG_GPPDR_LSB,
        [STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB,
        [STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB,
+       [STMPE_IDX_IEGPIOR_CSB] = STMPE24XX_REG_IEGPIOR_CSB,
+       [STMPE_IDX_IEGPIOR_MSB] = STMPE24XX_REG_IEGPIOR_MSB,
        [STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB,
+       [STMPE_IDX_GPEDR_LSB]   = STMPE24XX_REG_GPEDR_LSB,
+       [STMPE_IDX_GPEDR_CSB]   = STMPE24XX_REG_GPEDR_CSB,
        [STMPE_IDX_GPEDR_MSB]   = STMPE24XX_REG_GPEDR_MSB,
 };
 
@@ -840,7 +949,7 @@ static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks,
        if (blocks & STMPE_BLOCK_KEYPAD)
                mask |= STMPE24XX_SYS_CTRL_ENABLE_KPC;
 
-       return __stmpe_set_bits(stmpe, STMPE24XX_REG_SYS_CTRL, mask,
+       return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask,
                                enable ? mask : 0);
 }
 
@@ -893,6 +1002,7 @@ static struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = {
        [STMPE610]      = &stmpe610,
        [STMPE801]      = &stmpe801,
        [STMPE811]      = &stmpe811,
+       [STMPE1600]     = &stmpe1600,
        [STMPE1601]     = &stmpe1601,
        [STMPE1801]     = &stmpe1801,
        [STMPE2401]     = &stmpe2401,
@@ -919,7 +1029,8 @@ static irqreturn_t stmpe_irq(int irq, void *data)
        int ret;
        int i;
 
-       if (variant->id_val == STMPE801_ID) {
+       if (variant->id_val == STMPE801_ID ||
+           variant->id_val == STMPE1600_ID) {
                int base = irq_create_mapping(stmpe->domain, 0);
 
                handle_nested_irq(base);
@@ -982,7 +1093,7 @@ static void stmpe_irq_sync_unlock(struct irq_data *data)
                        continue;
 
                stmpe->oldier[i] = new;
-               stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB] - i, new);
+               stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB + i], new);
        }
 
        mutex_unlock(&stmpe->irq_lock);
@@ -1088,20 +1199,18 @@ static int stmpe_chip_init(struct stmpe *stmpe)
        if (ret)
                return ret;
 
-       if (id == STMPE1801_ID) {
-               ret =  stmpe1801_reset(stmpe);
-               if (ret < 0)
-                       return ret;
-       }
+       ret =  stmpe_reset(stmpe);
+       if (ret < 0)
+               return ret;
 
        if (stmpe->irq >= 0) {
-               if (id == STMPE801_ID)
-                       icr = STMPE801_REG_SYS_CTRL_INT_EN;
+               if (id == STMPE801_ID || id == STMPE1600_ID)
+                       icr = STMPE_SYS_CTRL_INT_EN;
                else
                        icr = STMPE_ICR_LSB_GIM;
 
-               /* STMPE801 doesn't support Edge interrupts */
-               if (id != STMPE801_ID) {
+               /* STMPE801 and STMPE1600 don't support Edge interrupts */
+               if (id != STMPE801_ID && id != STMPE1600_ID) {
                        if (irq_trigger == IRQF_TRIGGER_FALLING ||
                                        irq_trigger == IRQF_TRIGGER_RISING)
                                icr |= STMPE_ICR_LSB_EDGE;
@@ -1109,8 +1218,8 @@ static int stmpe_chip_init(struct stmpe *stmpe)
 
                if (irq_trigger == IRQF_TRIGGER_RISING ||
                                irq_trigger == IRQF_TRIGGER_HIGH) {
-                       if (id == STMPE801_ID)
-                               icr |= STMPE801_REG_SYS_CTRL_INT_HI;
+                       if (id == STMPE801_ID || id == STMPE1600_ID)
+                               icr |= STMPE_SYS_CTRL_INT_HI;
                        else
                                icr |= STMPE_ICR_LSB_HIGH;
                }