pinctrl:add interface for drive and vol setting
authorluowei <lw@rock-chips.com>
Sat, 14 Dec 2013 11:14:15 +0000 (19:14 +0800)
committerluowei <lw@rock-chips.com>
Sat, 14 Dec 2013 11:14:15 +0000 (19:14 +0800)
arch/arm/boot/dts/rk3188-pinctrl.dtsi
drivers/pinctrl/pinctrl-rockchip.c
include/dt-bindings/pinctrl/rockchip-rk3188.h

index 3271560a324f40530b70e815dc051d8dbdac8ea6..bf424f697ff4bc5a0a782b93c9f75ea632123a73 100755 (executable)
@@ -78,7 +78,7 @@
                        bias-disable;
                };
 
-               uart0 {
+               gpio1_uart0 {
                        uart0_xfer: uart0-xfer {
                                rockchip,pins = <UART0_SIN>,
                                                <UART0_SOUT>;
                        };
                };
 
-               uart1 {
+               gpio1_uart1 {
                        uart1_xfer: uart1-xfer {
                                rockchip,pins = <UART1_SIN>,
                                                <UART1_SOUT>;
                        };
                };
 
-               uart2 {
+               gpio1_uart2 {
                        uart2_xfer: uart2-xfer {
                                rockchip,pins = <UART2_SIN>,
                                                <UART2_SOUT>;
                        /* no rts / cts for uart2 */
                };
 
-               uart3 {
+               gpio1_uart3 {
                        uart3_xfer: uart3-xfer {
                                rockchip,pins = <UART3_SIN>,
                                                <UART3_SOUT>;
                        };
                };
 
-               i2c0 {
+               gpio1_i2c0 {
                        i2c0_sda:i2c0-sda {
                                rockchip,pins = <I2C0_SDA>;
                                rockchip,pull = <VALUE_PULL_DISABLE>;
                        };
                };
 
-               i2c1 {
+               gpio1_i2c1 {
                        i2c1_sda:i2c1-sda {
                                rockchip,pins = <I2C1_SDA>;
                                rockchip,pull = <VALUE_PULL_DISABLE>;
                        };
                };
 
-               i2c2 {
+               gpio1_i2c2 {
                        i2c2_sda:i2c2-sda {
                                rockchip,pins = <I2C2_SDA>;
                                rockchip,pull = <VALUE_PULL_DISABLE>;
                        };
                };
 
-               i2c3 {
+               gpio1_i2c3 {
                        i2c3_sda:i2c3-sda {
                                rockchip,pins = <I2C3_SDA>;
                                rockchip,pull = <VALUE_PULL_DISABLE>;
                        };
                };
 
-               i2c4 {
+               gpio1_i2c4 {
                        i2c4_sda:i2c4-sda {
                                rockchip,pins = <I2C4_SDA>;
                                rockchip,pull = <VALUE_PULL_DISABLE>;
                        };
                };
 
-               spi0 {
+               gpio1_spi0 {
                        spi0_txd:spi0-txd {
                                rockchip,pins = <SPI0_TXD>;
                                rockchip,pull = <VALUE_PULL_DISABLE>;
 
                };
 
-               spi1 {
+               gpio1_spi1 {
                        spi1_txd:spi1-txd {
                                rockchip,pins = <SPI1_TXD>;
                                rockchip,pull = <VALUE_PULL_DISABLE>;
 
                };
 
-               i2s0 {
+               gpio1_i2s0 {
 
                        i2s0_mclk:i2s0-mclk {
                                rockchip,pins = <I2S0_MCLK>;
                };
 
 
-               pwm {
+               gpio3_pwm {
                        pwm0:pwm0 {
                                rockchip,pins = <PWM0>;
                                rockchip,pull = <VALUE_PULL_DISABLE>;
                };
 
                
-               sd0 {
+               gpio3_sdio {
                        sd0_clk: sd0-clk {
                                rockchip,pins = <MMC0_CLKOUT>;
                                rockchip,pull = <VALUE_PULL_DISABLE>;
                };
 
        
-               sd1 {
+               gpio3_sdmmc {
                        sd1_clk: sd1-clk {
                                rockchip,pins = <MMC1_CLKOUT>;
                                rockchip,pull = <VALUE_PULL_DISABLE>;
                };
 
 
-
                //to add
        };
 };
index b653bee9e8d7dd348b32fc13115d20d4e77685e4..b491400da390b873ff202c3649724793e644aad8 100755 (executable)
@@ -40,6 +40,7 @@
 #include <linux/irqchip/chained_irq.h>
 #include <linux/clk.h>
 #include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/pinctrl/rockchip-rk3188.h>
 
 
 #include <linux/of.h>
@@ -159,7 +160,8 @@ struct rockchip_pin_config {
  * @nconfigs: number of configs for each pin
  */
 struct rockchip_pin_group {
-       const char                      *name;
+       const char                      *name;  
+       const char                      *func_name;
        unsigned int                    npins;
        unsigned int                    *pins;
        struct rockchip_pin_config      *data;
@@ -207,6 +209,24 @@ struct union_mode{
         };
 };
 
+struct func_to_reg_offset {
+       unsigned int reg_type;
+       const char *func_name;
+       unsigned int reg_offset;
+       unsigned int bit_offset;
+       unsigned int bit_mask;
+};
+
+#define FUNC_TO_REG_OFFSET(type, label, reg, bit, mask)        \
+       {                                               \
+               .reg_type       = type,         \
+               .func_name      = label,        \
+               .reg_offset     = reg,          \
+               .bit_offset     = bit,          \
+               .bit_mask       = mask,         \
+       }
+
+
 
 static inline struct rockchip_pin_bank *gc_to_pin_bank(struct gpio_chip *gc)
 {
@@ -362,9 +382,7 @@ static const struct pinctrl_ops rockchip_pctrl_ops = {
        .dt_free_map            = rockchip_dt_free_map,
 };
 
-/*
- * Hardware access
- */
+
 
 /*
  * Set a new mux function for a pin.
@@ -414,14 +432,365 @@ static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 
        spin_unlock_irqrestore(&bank->slock, flags);
 
-       DBG_PINCTRL("%s:GPIO%d-%d mux:0x%x\n", __func__, m.mux.bank, ((m.mux.goff - 0x0A) * 8 + m.mux.off ), mux);
+       DBG_PINCTRL("%s:setting GPIO%d-%d to mux:0x%x\n", __func__, m.mux.bank, ((m.mux.goff - 0x0A) * 8 + m.mux.off ), mux);
                
-       DBG_PINCTRL("%s:setting mux of GPIO%d-%d to %d\n", __func__, bank->bank_num, pin, mux&0x3);
+       //DBG_PINCTRL("%s:setting mux of GPIO%d-%d to %d\n", __func__, bank->bank_num, pin, mux&0x3);
+}
+
+
+/*
+ * Pinmux_ops handling
+ */
+
+static int rockchip_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+       struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+       return info->nfunctions;
+}
+
+static const char *rockchip_pmx_get_func_name(struct pinctrl_dev *pctldev,
+                                         unsigned selector)
+{
+       struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+       return info->functions[selector].name;
+}
+
+static int rockchip_pmx_get_groups(struct pinctrl_dev *pctldev,
+                               unsigned selector, const char * const **groups,
+                               unsigned * const num_groups)
+{
+       struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+       *groups = info->functions[selector].groups;
+       *num_groups = info->functions[selector].ngroups;
+
+       return 0;
+}
+
+static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
+                                                           unsigned group)
+{
+       struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+       const unsigned int *pins = info->groups[group].pins;
+       const struct rockchip_pin_config *data = info->groups[group].data;
+       struct rockchip_pin_bank *bank;
+       int cnt;
+
+       DBG_PINCTRL("%s:enable function %s group %s\n",
+               __func__, info->functions[selector].name, info->groups[group].name);
+
+       /*
+        * for each pin in the pin group selected, program the correspoding pin
+        * pin function number in the config register.
+        */
+       for (cnt = 0; cnt < info->groups[group].npins; cnt++) {
+               bank = pin_to_bank(info, pins[cnt]);
+               rockchip_set_mux(bank, pins[cnt] - bank->pin_base,
+                                data[cnt].func);
+       }
+
+       return 0;
 }
 
-#define RK2928_PULL_OFFSET             0x118
-#define RK2928_PULL_PINS_PER_REG       16
-#define RK2928_PULL_BANK_STRIDE                8
+static void rockchip_pmx_disable(struct pinctrl_dev *pctldev,
+                                       unsigned selector, unsigned group)
+{
+       struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+       const unsigned int *pins = info->groups[group].pins;
+       struct rockchip_pin_bank *bank;
+       int cnt;
+
+       DBG_PINCTRL("%s:disable function %s group %s\n",
+               __func__, info->functions[selector].name, info->groups[group].name);
+
+       for (cnt = 0; cnt < info->groups[group].npins; cnt++) {
+               bank = pin_to_bank(info, pins[cnt]);
+               rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0);
+       }
+}
+
+/*
+ * The calls to gpio_direction_output() and gpio_direction_input()
+ * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
+ * function called from the gpiolib interface).
+ */
+static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
+                                             struct pinctrl_gpio_range *range,
+                                             unsigned offset, bool input)
+{
+       struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+       struct rockchip_pin_bank *bank;
+       struct gpio_chip *chip;
+       int pin;
+       u32 data;
+       u32 mux;
+
+       chip = range->gc;
+       bank = gc_to_pin_bank(chip);
+       pin = offset - chip->base;
+
+       DBG_PINCTRL("%s:gpio_direction for pin %u as %s-%d to %s\n",
+                __func__, offset, range->name, pin, input ? "input" : "output");
+
+       mux = (bank->bank_num << 12) | (((pin / 8) + 0x0A) << 8) | ((pin % 8)<< 4) | RK_FUNC_GPIO;
+
+       rockchip_set_mux(bank, pin, mux);
+
+       data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
+       /* set bit to 1 for output, 0 for input */
+       if (!input)
+               data |= BIT(pin);
+       else
+               data &= ~BIT(pin);
+       writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
+
+       return 0;
+}
+
+static const struct pinmux_ops rockchip_pmx_ops = {
+       .get_functions_count    = rockchip_pmx_get_funcs_count,
+       .get_function_name      = rockchip_pmx_get_func_name,
+       .get_function_groups    = rockchip_pmx_get_groups,
+       .enable                 = rockchip_pmx_enable,
+       .disable                = rockchip_pmx_disable,
+       .gpio_set_direction     = rockchip_pmx_gpio_set_direction,
+};
+
+
+
+/*
+ * Hardware access
+ */
+#define TYPE_PULL_REG          0x01
+#define TYPE_VOL_REG           0x02
+#define TYPE_DRV_REG           0x03
+#define TYPE_TRI_REG           0x04
+
+#define RK3188_GRF_IO_CON0     0xf4
+#define RK3188_GRF_IO_CON1     0xf8
+#define RK3188_GRF_IO_CON2     0xfc
+#define RK3188_GRF_IO_CON3     0x100
+#define RK3188_GRF_IO_CON4     0x104
+
+static struct func_to_reg_offset rk3188_func_to_reg_offset[] = 
+{
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG,  "reserve", RK3188_GRF_IO_CON0, 0 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio0_flash", RK3188_GRF_IO_CON0, 2, 3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio0_flash", RK3188_GRF_IO_CON0, 4 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio0_d", RK3188_GRF_IO_CON0, 6 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio1_uart0", RK3188_GRF_IO_CON0, 8 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio1_uart1", RK3188_GRF_IO_CON0, 10 ,3),     
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio1_spi0", RK3188_GRF_IO_CON0, 10 ,3),      
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio1_uart2", RK3188_GRF_IO_CON0, 12 ,3),     
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio1_uart3", RK3188_GRF_IO_CON0, 14 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio1_spi1", RK3188_GRF_IO_CON0, 14 ,3),
+
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio1_i2s0", RK3188_GRF_IO_CON1, 0 ,3),       
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio1_i2s0", RK3188_GRF_IO_CON1, 2 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio1_c", RK3188_GRF_IO_CON1, 4 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio1_i2c0", RK3188_GRF_IO_CON1, 6 ,3),       
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio1_i2c1", RK3188_GRF_IO_CON1, 8 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio1_i2c2", RK3188_GRF_IO_CON1, 10 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio1_i2c4", RK3188_GRF_IO_CON1, 12 ,3),      
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio2_lcdc1", RK3188_GRF_IO_CON1, 14 ,3),
+
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio2_lcdc1", RK3188_GRF_IO_CON2, 0 ,3),      
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio2_smc", RK3188_GRF_IO_CON2, 2 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "reserve", RK3188_GRF_IO_CON2, 4 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio3_sdmmc", RK3188_GRF_IO_CON2, 6 ,3),      
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio3_sdmmc", RK3188_GRF_IO_CON2, 8 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio3_b", RK3188_GRF_IO_CON2, 10 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio3_cif", RK3188_GRF_IO_CON2, 12 ,3),       
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio3_cif", RK3188_GRF_IO_CON2, 14 ,3),
+
+
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio3_sdio", RK3188_GRF_IO_CON3, 0 ,3),       
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio3_sdio", RK3188_GRF_IO_CON3, 2 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio3_pwm", RK3188_GRF_IO_CON3, 4 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "gpio3_d", RK3188_GRF_IO_CON3, 6 ,3),  
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "flash", RK3188_GRF_IO_CON3, 8 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "flash", RK3188_GRF_IO_CON3, 10 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "cif", RK3188_GRF_IO_CON3, 12 ,3),     
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "lcdc0", RK3188_GRF_IO_CON3, 14 ,3),
+
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "lcdc0", RK3188_GRF_IO_CON4, 0 ,3),    
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "jtag", RK3188_GRF_IO_CON4, 2 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "misc", RK3188_GRF_IO_CON4, 4 ,3),
+       FUNC_TO_REG_OFFSET(TYPE_DRV_REG, "reserve", RK3188_GRF_IO_CON4, 6 ,3),  
+       
+       FUNC_TO_REG_OFFSET(TYPE_VOL_REG, "ap0_io", RK3188_GRF_IO_CON4, 8 ,1),
+       FUNC_TO_REG_OFFSET(TYPE_VOL_REG, "ap1_io", RK3188_GRF_IO_CON4, 9 ,1),
+       FUNC_TO_REG_OFFSET(TYPE_VOL_REG, "cif_io", RK3188_GRF_IO_CON4, 10 ,1),  
+       FUNC_TO_REG_OFFSET(TYPE_VOL_REG, "flash_io", RK3188_GRF_IO_CON4, 11 ,1),        
+       FUNC_TO_REG_OFFSET(TYPE_VOL_REG, "vccio0_io", RK3188_GRF_IO_CON4, 12 ,1),
+       FUNC_TO_REG_OFFSET(TYPE_VOL_REG, "vccio1_io", RK3188_GRF_IO_CON4, 13 ,1),
+       FUNC_TO_REG_OFFSET(TYPE_VOL_REG, "lcdc0_io", RK3188_GRF_IO_CON4, 14 ,1),
+       FUNC_TO_REG_OFFSET(TYPE_VOL_REG, "lcdc1_io", RK3188_GRF_IO_CON4, 15 ,1),
+       
+};
+
+
+static int rockchip_get_pin_config(struct rockchip_pin_bank *bank,
+                                       int pin_num, int param, int config_type)
+{
+       struct rockchip_pinctrl *info = bank->drvdata;  
+       struct rockchip_pin_ctrl *ctrl = info->ctrl;
+       struct func_to_reg_offset reg_offset[4];//same name count should be less four
+       int i = 0, j = 0;       
+       int value = 0;
+       unsigned long flags;    
+       void __iomem *reg;
+       
+       for(i = 0; i < ARRAY_SIZE(rk3188_func_to_reg_offset); i++)
+       {
+               if(!strcmp(info->groups->func_name, rk3188_func_to_reg_offset[i].func_name))
+               {
+                       reg_offset[j++] = rk3188_func_to_reg_offset[i];
+               }
+       }
+
+       if(j <= 0)
+       {
+               printk("%s:could find config register for PIN%d-%d\n",__func__, bank->bank_num, pin_num);
+               return -1;
+       }
+
+
+       switch(ctrl->type)
+       {
+               case RK2928:
+               break;
+               
+               case RK3188:
+
+               switch(config_type)
+               {               
+                       case TYPE_PULL_REG:
+                               
+                       break;
+                       
+                       case TYPE_VOL_REG:
+
+                       break;
+                       
+                       case TYPE_DRV_REG:
+                       for(i=0; i < j; i++)
+                       {
+                               reg = bank->reg_base + reg_offset[i].reg_offset;
+                               value |= ((param & reg_offset[i].bit_mask) << (16 + reg_offset[i].bit_offset));
+                               value |= ((param & reg_offset[i].bit_mask) << reg_offset[i].bit_offset);
+                               spin_lock_irqsave(&bank->slock, flags);
+                               //writel_relaxed(value, reg);
+                               spin_unlock_irqrestore(&bank->slock, flags);
+               
+                               DBG_PINCTRL("%s:reg[%d]=0x%p,value[%d]=0x%x\n",__func__, i, reg, i, value);                     
+                       }
+                       break;
+
+                       case TYPE_TRI_REG:
+                               
+                       break;
+                       default:
+                       break;
+
+               }
+               
+               break;
+
+               default:
+               break;
+       }
+
+       
+       
+       DBG_PINCTRL("%s:GPIO%d-%d,group=%s, function=%s, gpio=%s, type=%d\n", __func__, bank->bank_num, pin_num, info->groups->name, info->groups->func_name, bank->of_node->name, config_type);
+       
+       return 0;
+}
+
+
+
+static int rockchip_set_pin_config(struct rockchip_pin_bank *bank,
+                                       int pin_num, int param, int config_type)
+{
+       struct rockchip_pinctrl *info = bank->drvdata;  
+       struct rockchip_pin_ctrl *ctrl = info->ctrl;
+       struct func_to_reg_offset reg_offset[4];//same name count should be less four
+       int i = 0, j = 0;       
+       int value = 0;
+       unsigned long flags;    
+       void __iomem *reg;
+       
+       for(i = 0; i < ARRAY_SIZE(rk3188_func_to_reg_offset); i++)
+       {
+               if(!strcmp(info->groups->func_name, rk3188_func_to_reg_offset[i].func_name))
+               {
+                       reg_offset[j++] = rk3188_func_to_reg_offset[i];
+               }
+       }
+
+       if(j <= 0)
+       {
+               printk("%s:could find config register for PIN%d-%d\n",__func__, bank->bank_num, pin_num);
+               return -1;
+       }
+
+
+       switch(ctrl->type)
+       {
+               case RK2928:
+               break;
+               
+               case RK3188:
+
+               switch(config_type)
+               {               
+                       case TYPE_PULL_REG:
+                               
+                       break;
+                       
+                       case TYPE_VOL_REG:
+
+                       break;
+                       
+                       case TYPE_DRV_REG:
+                       for(i=0; i < j; i++)
+                       {
+                               reg = bank->reg_base + reg_offset[i].reg_offset;
+                               value |= ((param & reg_offset[i].bit_mask) << (16 + reg_offset[i].bit_offset));
+                               value |= ((param & reg_offset[i].bit_mask) << reg_offset[i].bit_offset);
+                               spin_lock_irqsave(&bank->slock, flags);
+                               //writel_relaxed(value, reg);
+                               spin_unlock_irqrestore(&bank->slock, flags);
+               
+                               DBG_PINCTRL("%s:reg[%d]=0x%p,value[%d]=0x%x\n",__func__, i, reg, i, value);                     
+                       }
+                       break;
+
+                       case TYPE_TRI_REG:
+                               
+                       break;
+                       default:
+                       break;
+
+               }
+               
+               break;
+
+               default:
+               break;
+       }
+
+       
+       
+       DBG_PINCTRL("%s:GPIO%d-%d,group=%s, function=%s, gpio=%s, type=%d\n", __func__, bank->bank_num, pin_num, info->groups[0].name, info->groups[0].func_name, bank->of_node->name, config_type);
+       
+       return 0;
+}
+
+
 
 static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
                                    int pin_num, void __iomem **reg, u8 *bit)
@@ -433,11 +802,10 @@ static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
        *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4;
 
        *bit = pin_num % RK2928_PULL_PINS_PER_REG;
+
+       DBG_PINCTRL("%s:GPIO%d-%d, pull_reg=0x%p, bit=%d\n", __func__, bank->bank_num, pin_num, *reg, *bit);
 };
 
-#define RK3188_PULL_BITS_PER_PIN       2
-#define RK3188_PULL_PINS_PER_REG       8
-#define RK3188_PULL_BANK_STRIDE                16
 
 static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
                                    int pin_num, void __iomem **reg, u8 *bit)
@@ -463,6 +831,8 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
                *bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG);
                *bit *= RK3188_PULL_BITS_PER_PIN;
        }
+
+       DBG_PINCTRL("%s:GPIO%d-%d, pull_reg=0x%p, bit=%d\n", __func__, bank->bank_num, pin_num, *reg, *bit);
 }
 
 static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
@@ -505,6 +875,8 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
                dev_err(info->dev, "unsupported pinctrl type\n");
                return -EINVAL;
        };
+
+       DBG_PINCTRL("%s:GPIO%d-%d pull is 0x%x\n", __func__, bank->bank_num, pin_num, data);
 }
 
 static int rockchip_set_pull(struct rockchip_pin_bank *bank,
@@ -517,8 +889,6 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
        u8 bit;
        u32 data;
 
-       DBG_PINCTRL("%s:setting pull of GPIO%d-%d to %d\n",
-               __func__, bank->bank_num, pin_num, pull);
 
        /* rk3066b does support any pulls */
        if (ctrl->type == RK3066B)
@@ -570,126 +940,12 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
                return -EINVAL;
        }
 
-       return 0;
-}
-
-/*
- * Pinmux_ops handling
- */
-
-static int rockchip_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
-{
-       struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
-       return info->nfunctions;
-}
-
-static const char *rockchip_pmx_get_func_name(struct pinctrl_dev *pctldev,
-                                         unsigned selector)
-{
-       struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
-       return info->functions[selector].name;
-}
-
-static int rockchip_pmx_get_groups(struct pinctrl_dev *pctldev,
-                               unsigned selector, const char * const **groups,
-                               unsigned * const num_groups)
-{
-       struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
-       *groups = info->functions[selector].groups;
-       *num_groups = info->functions[selector].ngroups;
-
-       return 0;
-}
-
-static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
-                                                           unsigned group)
-{
-       struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-       const unsigned int *pins = info->groups[group].pins;
-       const struct rockchip_pin_config *data = info->groups[group].data;
-       struct rockchip_pin_bank *bank;
-       int cnt;
-
-       DBG_PINCTRL("%s:enable function %s group %s\n",
-               __func__, info->functions[selector].name, info->groups[group].name);
-
-       /*
-        * for each pin in the pin group selected, program the correspoding pin
-        * pin function number in the config register.
-        */
-       for (cnt = 0; cnt < info->groups[group].npins; cnt++) {
-               bank = pin_to_bank(info, pins[cnt]);
-               rockchip_set_mux(bank, pins[cnt] - bank->pin_base,
-                                data[cnt].func);
-       }
-
-       return 0;
-}
 
-static void rockchip_pmx_disable(struct pinctrl_dev *pctldev,
-                                       unsigned selector, unsigned group)
-{
-       struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-       const unsigned int *pins = info->groups[group].pins;
-       struct rockchip_pin_bank *bank;
-       int cnt;
-
-       DBG_PINCTRL("%s:disable function %s group %s\n",
-               __func__, info->functions[selector].name, info->groups[group].name);
-
-       for (cnt = 0; cnt < info->groups[group].npins; cnt++) {
-               bank = pin_to_bank(info, pins[cnt]);
-               rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0);
-       }
-}
-
-/*
- * The calls to gpio_direction_output() and gpio_direction_input()
- * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
- * function called from the gpiolib interface).
- */
-static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
-                                             struct pinctrl_gpio_range *range,
-                                             unsigned offset, bool input)
-{
-       struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-       struct rockchip_pin_bank *bank;
-       struct gpio_chip *chip;
-       int pin;
-       u32 data;
-
-       chip = range->gc;
-       bank = gc_to_pin_bank(chip);
-       pin = offset - chip->base;
-
-       DBG_PINCTRL("%s:gpio_direction for pin %u as %s-%d to %s\n",
-                __func__, offset, range->name, pin, input ? "input" : "output");
-
-       rockchip_set_mux(bank, pin, RK_FUNC_GPIO);
-
-       data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
-       /* set bit to 1 for output, 0 for input */
-       if (!input)
-               data |= BIT(pin);
-       else
-               data &= ~BIT(pin);
-       writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
+       DBG_PINCTRL("%s:GPIO%d-%d pull is 0x%x\n", __func__, bank->bank_num, pin_num, data);
 
        return 0;
 }
 
-static const struct pinmux_ops rockchip_pmx_ops = {
-       .get_functions_count    = rockchip_pmx_get_funcs_count,
-       .get_function_name      = rockchip_pmx_get_func_name,
-       .get_function_groups    = rockchip_pmx_get_groups,
-       .enable                 = rockchip_pmx_enable,
-       .disable                = rockchip_pmx_disable,
-       .gpio_set_direction     = rockchip_pmx_gpio_set_direction,
-};
-
 /*
  * Pinconf_ops handling
  */
@@ -748,14 +1004,20 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
                break;
                
        case PIN_CONFIG_POWER_SOURCE:
-               //to do
+               rc = rockchip_set_pin_config(bank, pin - bank->pin_base, param, TYPE_VOL_REG);
+               if (rc)
+               return rc;
                break;
 
        case PIN_CONFIG_DRIVE_STRENGTH:
-               //to do
+               rc = rockchip_set_pin_config(bank, pin - bank->pin_base, param, TYPE_DRV_REG);
+               if (rc)
+               return rc;
                break;
        case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
-               //to do
+               rc = rockchip_set_pin_config(bank, pin - bank->pin_base, param, TYPE_TRI_REG);
+               if (rc)
+               return rc;
                break;
        default:
                return -ENOTSUPP;
@@ -774,7 +1036,8 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
        struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
        struct rockchip_pin_bank *bank = pin_to_bank(info, pin);
        enum pin_config_param param = pinconf_to_config_param(*config);
-
+       int rc;
+       
        switch (param) {
        case PIN_CONFIG_BIAS_DISABLE:
                if (rockchip_get_pull(bank, pin - bank->pin_base) != param)
@@ -796,14 +1059,20 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
                break;
        
        case PIN_CONFIG_POWER_SOURCE:
-               //to do
+               rc = rockchip_get_pin_config(bank, pin - bank->pin_base, param, TYPE_VOL_REG);
+               if (rc)
+               return rc;
                break;
 
        case PIN_CONFIG_DRIVE_STRENGTH:
-               //to do
+               rc = rockchip_get_pin_config(bank, pin - bank->pin_base, param, TYPE_DRV_REG);
+               if (rc)
+               return rc;
                break;
        case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
-               //to do
+               rc = rockchip_get_pin_config(bank, pin - bank->pin_base, param, TYPE_TRI_REG);
+               if (rc)
+               return rc;
                break;
                
        default:
@@ -1023,10 +1292,13 @@ static int rockchip_pinctrl_parse_functions(struct device_node *np,
 
        for_each_child_of_node(np, child) {
                func->groups[i] = child->name;
-               grp = &info->groups[grp_index++];
+               grp = &info->groups[grp_index++];       
+               grp->func_name = np->name;
                ret = rockchip_pinctrl_parse_groups(child, grp, info, i++);
                if (ret)
-                       return ret;
+                       return ret;     
+               
+               DBG_PINCTRL("%s:grp->func_name(%d): %s\n", __func__, grp_index, grp->func_name);
        }
 
        return 0;
@@ -1337,14 +1609,16 @@ static int rockchip_gpio_irq_set_type(struct irq_data *d, unsigned int type)
        u32 mask = BIT(d->hwirq);
        u32 polarity;
        u32 level;
-       u32 data;
-       
+       u32 data;       
+       u32 mux;
        unsigned long flags;
        
        DBG_PINCTRL("%s:type=%d,irq=%d,hwirq=%d\n",__func__,type, d->irq, (int)d->hwirq);
        
        /* make sure the pin is configured as gpio input */
-       rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
+       mux = (bank->bank_num << 12) | (((d->hwirq / 8) + 0x0A) << 8) | ((d->hwirq % 8)<< 4) | RK_FUNC_GPIO;
+       rockchip_set_mux(bank, d->hwirq, mux);
+
        data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
        data &= ~mask;
        writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
@@ -1941,7 +2215,7 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
        int i = 0;
        for(i=1; i<32*4; i++)
        {
-               if(i>23 && i<32)
+               if(i>23 && i<32+16)
                continue;
                gpio_request(i, NULL);  
                gpio_direction_input(i);
index d4207d9c753777bd200533e2b4730d98b84491f3..62207490bb2b58e1def3e0bd0bfe74b23ded1129 100755 (executable)
 #define JTAG_TMS 0x3d62
 #define HOST_DRV_VBUS 0x3d63
 
+
+#define RK2928_PULL_OFFSET             0x118
+#define RK2928_PULL_PINS_PER_REG       16
+#define RK2928_PULL_BANK_STRIDE                8
+
+#define RK3188_PULL_BITS_PER_PIN       2
+#define RK3188_PULL_PINS_PER_REG       8
+#define RK3188_PULL_BANK_STRIDE                16
+
+
 /*warning:don not chang the following value*/
 #define VALUE_PULL_DISABLE     0
 #define VALUE_PULL_UP          1