smartcard: modify smartcard driver for 8.1
authorYinming Ding <yinming.ding@amlogic.com>
Fri, 22 Jun 2018 09:36:05 +0000 (17:36 +0800)
committerYixun Lan <yixun.lan@amlogic.com>
Thu, 12 Jul 2018 02:35:48 +0000 (19:35 -0700)
PD#168901: smartcard modify smartcard driver for 8.1

Change-Id: Ib0b81009e434d5f6c513bfc52bbfeef48414ef39
Signed-off-by: Yinming Ding <yinming.ding@amlogic.com>
arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts
arch/arm64/boot/dts/amlogic/mesongxl.dtsi
drivers/amlogic/pinctrl/pinctrl-meson-gxl.c
drivers/amlogic/smartcard/c_stb_regs_define.h
drivers/amlogic/smartcard/smartcard.c
drivers/amlogic/smartcard/smartcard.h

index b720dae4ddab92f73f76c6e4a3eb292e184e9ad8..4cd5978ecbd1b7631d34251f9e15be053ae36354 100644 (file)
                &clkc CLKID_HIU_IFACE>;
                clock-names = "demux", "asyncfifo", "ahbarb0", "uparsertop";
        };
+
+       /* SMC */
+       smartcard{
+               compatible = "amlogic,smartcard";
+               irq_trigger_type = "GPIO_IRQ_LOW";
+
+               reset_pin-gpios = <&gpio GPIODV_21 GPIO_ACTIVE_HIGH>;
+               detect_pin-gpios = <&gpio GPIODV_20 GPIO_ACTIVE_HIGH>;
+               enable_5v3v_pin-gpios = <&gpio GPIODV_19 GPIO_ACTIVE_HIGH>;
+               enable_pin-gpios = <&gpio GPIODV_20 GPIO_ACTIVE_HIGH>;
+
+               interrupts = <0 37 1>;
+               interrupt-names = "smc0_irq";
+               /*
+                *Smc clock source, if change this,
+                *you must adjust clk and divider in smartcard.c
+                */
+               smc0_clock_source = <0>;
+               smc0_irq = <37>;                //smc irq
+               /*0: high voltage on detect pin indicates card in.*/
+               smc0_det_invert = <0>;
+               smc0_5v3v_level = <0>;
+               /*Ordinarily,smartcard controller needs a enable pin.*/
+               smc_need_enable_pin = "no";
+               reset_level = <0>;
+               smc0_enable_level = <0>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&sd_iso7816_pins>;
+               clocks = <&clkc CLKID_SMART_CARD>;
+               clock-names = "smartcard";
+               status = "okay";
+       };
 };
 &efuse {
        status = "ok";
index 472949888ae33a89491e20a5dcbb7697d8f31a86..c342c7fc14174b71ae667d25b1fc8d4409a94a1d 100644 (file)
                };
        };
 
+       sd_iso7816_pins:sd_iso7816_pins {
+               mux {
+                       groups = "iso7816_clk_dv",
+                               "iso7816_data_dv";
+                       function = "iso7816";
+                       input-enable;
+                       bias-pull-down;
+               };
+       };
+
        nand_pulldown: nand_pulldown {
                mux {
                        groups = "emmc_nand_d07",
index 1c46b28afbcb21c693d90205562683bddf755cde..720f11249435a4f5a272f7adf400de4e79c6fe75 100644 (file)
@@ -405,8 +405,8 @@ static const unsigned int dvp_d2_9_pins[] = {
 };
 
 /*iso7816*/
-static const unsigned int iso7816_clk_pins[] = { GPIOZ_6 };
-static const unsigned int iso7816_data_pins[] = { GPIOZ_7 };
+static const unsigned int iso7816_clk_dv_pins[] = { GPIODV_22 };
+static const unsigned int iso7816_data_dv_pins[] = { GPIODV_23 };
 
 static struct meson_pmx_group meson_gxl_periphs_groups[] = {
        GPIO_GROUP(GPIOZ_0),
@@ -588,7 +588,6 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
        GROUP(tsin_fail_b_z4,           3,      15),    /*z4*/
        GROUP(dvp_d2_9,                 3,      11),    /*z4*/
        GROUP(i2sout_ch23_z5,           3,      26),    /*z5*/
-       GROUP(iso7816_clk,              4,      9),     /*z6*/
        GROUP(i2sout_ch45_z6,           3,      25),    /*z6*/
        GROUP(i2sout_ch67_z7,           3,      24),    /*z7*/
        GROUP(spi_sclk_0,               4,      4),     /*z11*/
@@ -643,6 +642,8 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
        GROUP(i2c_scl_c_dv19,           1,      16),    /*dv19*/
        GROUP(pwm_b,                    2,      11),    /*dv29*/
        GROUP(pwm_d,                    2,      12),    /*dv28*/
+       GROUP(iso7816_clk_dv,           2,      18), /*dv22*/
+       GROUP(iso7816_data_dv,          2,      17), /*dv23*/
 
        /* Bank BOOT */
        GROUP(emmc_nand_d07,            7,      31),
@@ -997,6 +998,11 @@ static const char *const dmic_groups[] = {
        "dmic_in_z8", "dmic_clk_z9",
 };
 
+static const char * const iso7816_groups[] = {
+       "iso7816_clk_dv", "iso7816_data_dv",
+};
+
+
 static struct meson_pmx_func meson_gxl_periphs_functions[] = {
        FUNCTION(gpio_periphs),
        FUNCTION(emmc),
@@ -1004,6 +1010,7 @@ static struct meson_pmx_func meson_gxl_periphs_functions[] = {
        FUNCTION(uart_a),
        FUNCTION(uart_b),
        FUNCTION(uart_c),
+       FUNCTION(iso7816),
        FUNCTION(eth),
        FUNCTION(jtag),
        FUNCTION(pwm_a),
index 30390ae64080fbacefae27493405c62a7889e4e0..2b92601183b891b70ede8b85d32f6d84b2f01ebe 100644 (file)
 #define __MACH_MESON8_REG_ADDR_H_
 #include <linux/amlogic/iomap.h>
 #define CBUS_REG_ADDR(_r) aml_read_cbus(_r)
-#define SMARTCARD_REG0 0x2110
+#define SMARTCARD_REG_BASE     smc_get_reg_base()
+#define SMARTCARD_REG0 (SMARTCARD_REG_BASE + 0x0)
 #define P_SMARTCARD_REG0                CBUS_REG_ADDR(SMARTCARD_REG0)
-#define SMARTCARD_REG1 0x2111
+#define SMARTCARD_REG1 (SMARTCARD_REG_BASE + 0x1)
 #define P_SMARTCARD_REG1                CBUS_REG_ADDR(SMARTCARD_REG1)
-#define SMARTCARD_REG2 0x2112
+#define SMARTCARD_REG2 (SMARTCARD_REG_BASE + 0x2)
 #define P_SMARTCARD_REG2                CBUS_REG_ADDR(SMARTCARD_REG2)
-#define SMARTCARD_STATUS 0x2113
+#define SMARTCARD_STATUS (SMARTCARD_REG_BASE + 0x3)
 #define P_SMARTCARD_STATUS              CBUS_REG_ADDR(SMARTCARD_STATUS)
-#define SMARTCARD_INTR 0x2114
+#define SMARTCARD_INTR (SMARTCARD_REG_BASE + 0x4)
 #define P_SMARTCARD_INTR                CBUS_REG_ADDR(SMARTCARD_INTR)
-#define SMARTCARD_REG5 0x2115
+#define SMARTCARD_REG5 (SMARTCARD_REG_BASE + 0x5)
 #define P_SMARTCARD_REG5                CBUS_REG_ADDR(SMARTCARD_REG5)
-#define SMARTCARD_REG6 0x2116
+#define SMARTCARD_REG6 (SMARTCARD_REG_BASE + 0x6)
 #define P_SMARTCARD_REG6                CBUS_REG_ADDR(SMARTCARD_REG6)
-#define SMARTCARD_FIFO 0x2117
+#define SMARTCARD_FIFO (SMARTCARD_REG_BASE + 0x7)
 #define P_SMARTCARD_FIFO                CBUS_REG_ADDR(SMARTCARD_FIFO)
-#define SMARTCARD_REG8 0x2118
+#define SMARTCARD_REG8 (SMARTCARD_REG_BASE + 0x8)
 #define P_SMARTCARD_REG8                CBUS_REG_ADDR(SMARTCARD_REG8)
 #endif
index bcf5327a8256eeacde87b2be7b747f9099dea050..8330b97a5cbf9fe65bccdca01ee35cde6e13aa0a 100644 (file)
@@ -156,10 +156,14 @@ while (0)
 static struct file *debug_filp;
 static loff_t debug_file_pos;
 static int smc_debug;
+#ifdef MEM_DEBUG
 static char *dbuf;
 static int dread, dwrite;
 static int dcnt;
-static struct reset_control *aml_smartcard_reset_ctrl;
+#endif
+/*no used reset ctl,need use clk in 4.9 kernel*/
+static struct clk *aml_smartcard_clk;
+
 #define REG_READ 0
 #define REG_WRITE 1
 void operate_reg(unsigned int reg, int read_write, unsigned int *value)
@@ -191,6 +195,8 @@ void debug_write(const char __user *buf, size_t count)
 
        set_fs(old_fs);
 }
+
+#ifdef MEM_DEBUG
 static void open_debug(void)
 {
        debug_filp = filp_open(DEBUG_FILE_NAME, O_WRONLY, 0);
@@ -222,6 +228,7 @@ static size_t print_time(u64 ts, char *buf)
        return sprintf(buf, "[%5lu.%06lu] ",
                        (unsigned long)ts, rem_nsec / 1000);
 }
+#endif
 
 #ifdef CONFIG_OF
 static const struct of_device_id smc_dt_match[] = {
@@ -386,6 +393,7 @@ static struct mutex smc_lock;
 static int              smc_major;
 static struct smc_dev  smc_dev[SMC_DEV_COUNT];
 static int ENA_GPIO_PULL = 1;
+static int DIV_SMC = 3;
 
 #ifdef SW_INVERT
 static const unsigned char inv_table[256] = {
@@ -530,6 +538,30 @@ static ssize_t store_freq(struct class *class,
        return count;
 }
 
+static ssize_t show_div_smc(struct class *class,
+       struct class_attribute *attr,
+       char *buf)
+{
+       return sprintf(buf, "div -> %d\n", DIV_SMC);
+}
+
+static ssize_t store_div_smc(struct class *class,
+       struct class_attribute *attr,
+       const char *buf,
+       size_t count)
+{
+       int div = 0;
+
+       if (kstrtoint(buf, 0, &div))
+               return -EINVAL;
+
+       if (div)
+               DIV_SMC = div;
+
+       pr_dbg("div -> %d\n", DIV_SMC);
+       return count;
+}
+
 #ifdef MEM_DEBUG
 static ssize_t show_debug(struct class *class,
        struct class_attribute *attr,
@@ -598,6 +630,7 @@ static struct class_attribute smc_class_attrs[] = {
        __ATTR(smc_gpio_pull, 0644, show_gpio_pull, set_gpio_pull),
        __ATTR(ctrl_5v3v, 0644, show_5v3v, store_5v3v),
        __ATTR(freq, 0644, show_freq, store_freq),
+       __ATTR(div_smc, 0644, show_div_smc, store_div_smc),
 #ifdef MEM_DEBUG
        __ATTR(debug, 0644, show_debug, store_debug),
 #endif
@@ -609,76 +642,17 @@ static struct class smc_class = {
        .class_attrs = smc_class_attrs,
 };
 
-static unsigned long get_clk(char *name)
-{
-       struct clk *clk = NULL;
 
-       clk = clk_get_sys(name, NULL);
-       if (clk)
-               return clk_get_rate(clk);
-       return 0;
-}
 
-static unsigned long get_module_clk(int sel)
+long smc_get_reg_base(void)
 {
-#ifdef CONFIG_ARCH_ARC700
-       return get_mpeg_clk();
-#else
+       int newbase = 0;
 
-       unsigned long clk = 0;
-#ifdef CONFIG_ARCH_MESON6/*M6*/
-       /*sel = [0:clk81, 1:ddr-pll, 2:fclk-div5, 3:XTAL]*/
-       switch (sel) {
-       case 0:
-               clk = get_clk("clk81");
-               break;
-       case 1:
-               clk = get_clk("pll_ddr");
-               break;
-       case 2:
-               clk = get_clk("fixed")/5;
-               break;
-       case 3:
-               clk = get_clk("xtal");
-               break;
-       }
-#else
-       /*
-        * sel = [0:fclk-div2/fclk-div4(M8 and further),
-        * 1:fclk-div3, 2:fclk-div5, 3:XTAL]
-        */
-       switch (sel) {
-#if defined(MESON_CPU_TYPE_MESON8) && (MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8)
-       case 0:
-               clk = get_clk("pll_fixed") / 4;
-               break;
-#else/*M6TV/TVD/TVLITE*/
-       case 0:
-               clk = 1000000000;
-               break;
-                       /*
-                        * case 0: clk = get_clk("fixed")/2;
-                        * break;
-                        */
-#endif
-       case 1:
-               clk = get_clk("pll_fixed") / 3;
-               break;
-       case 2:
-               clk = get_clk("pll_fixed") / 5;
-               break;
-       case 3:
-               clk = get_clk("xtal");
-               break;
+       if (get_cpu_type() > MESON_CPU_MAJOR_ID_TXL &&
+               get_cpu_type() != MESON_CPU_MAJOR_ID_GXLX) {
+               newbase = 1;
        }
-#endif /*M6*/
-
-       if (!clk)
-               pr_error("fail: unknown clk source");
-
-       return clk;
-
-#endif
+       return (newbase) ? 0x9400 : 0x2110;
 }
 
 #ifndef CONFIG_OF
@@ -767,9 +741,7 @@ static int smc_hw_set_param(struct smc_dev *smc)
         * SMC_ANSWER_TO_RST *reg1;
         * SMC_INTERRUPT_Reg *reg_int;
         */
-       unsigned int sys_clk_rate = get_module_clk(clock_source);
-       unsigned long freq_cpu =
-           sys_clk_rate / 1000 * 22; /**10 adjust freq temporarily*/
+       unsigned long freq_cpu = clk_get_rate(aml_smartcard_clk)/1000*DIV_SMC;
 
        pr_error("hw set param\n");
 
@@ -813,6 +785,7 @@ static int smc_hw_set_param(struct smc_dev *smc)
        pr_error("xmit_par:%d\n", smc->param.xmit_parity);
        pr_error("xmit_rep:%d\n", smc->param.xmit_repeat_dis);
        pr_error("xmit_try:%d\n", smc->param.xmit_retries);
+       pr_error("clk_tcnt:%d freq_cpu:%ld\n", reg2->clk_tcnt, freq_cpu);
 
        v = SMC_READ_REG(REG5);
        reg5 = (struct SMCCARD_HW_Reg5 *)&v;
@@ -870,10 +843,7 @@ static int smc_hw_setup(struct smc_dev *smc)
        struct SMCCARD_HW_Reg5 *reg5;
        struct SMCCARD_HW_Reg6 *reg6;
 
-       unsigned int sys_clk_rate = get_module_clk(clock_source);
-
-       unsigned long freq_cpu = sys_clk_rate
-           / 1000 * 22; /**10 adjust freq temporarily*/
+       unsigned long freq_cpu = clk_get_rate(aml_smartcard_clk)/1000*DIV_SMC;
 
        pr_error("SMC CLK SOURCE - %luKHz\n", freq_cpu);
 
@@ -938,6 +908,7 @@ static int smc_hw_setup(struct smc_dev *smc)
        pr_error("xmit_par:%d\n", smc->param.xmit_parity);
        pr_error("xmit_rep:%d\n", smc->param.xmit_repeat_dis);
        pr_error("xmit_try:%d\n", smc->param.xmit_retries);
+       pr_error("clk_tcnt:%d freq_cpu:%ld\n", reg2->clk_tcnt, freq_cpu);
 
        v = SMC_READ_REG(INTR);
        reg_int = (struct SMC_INTERRUPT_Reg *)&v;
@@ -1088,7 +1059,7 @@ static int smc_hw_deactive(struct smc_dev *smc)
                } else {
                        if (smc->use_enable_pin)
                                _gpio_out(smc->enable_pin,
-                                       !smc->enable_level,
+                                       smc->enable_level,
                                        SMC_ENABLE_PIN_NAME);
                }
                if (ENA_GPIO_PULL > 0) {
@@ -1800,7 +1771,7 @@ static void smc_dev_deinit(struct smc_dev *smc)
        }
        if (smc->use_enable_pin)
                _gpio_free(smc->enable_pin, SMC_ENABLE_PIN_NAME);
-       reset_control_assert(aml_smartcard_reset_ctrl);
+       clk_disable_unprepare(aml_smartcard_clk);
 #if 0
        if (smc->pin_clk_pin != -1)
                _gpio_free(smc->pin_clk_pin, SMC_CLK_PIN_NAME);
@@ -1846,7 +1817,7 @@ static int _set_gpio(struct smc_dev *smc, struct gpio_desc **gpiod,
        } else if (input_output == INPUT)       {
                *gpiod = gpiod_get(&smc->pdev->dev, str, GPIOD_IN);
                ret = gpiod_direction_input(*gpiod);
-               //ret |= gpiod_set_pullup(*gpiod, 1);
+               ret |= gpiod_set_pull(*gpiod, GPIOD_PULL_UP);
        } else
                pr_dbg("SMC Request gpio direction invalid\n");
 
@@ -1861,6 +1832,7 @@ static int smc_dev_init(struct smc_dev *smc, int id)
        u32 value;
        char buf[32];
        const char *dts_str;
+       struct resource *res;
 #endif
 
 #if defined(MESON_CPU_TYPE_MESON8) && (MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8)
@@ -1910,7 +1882,7 @@ static int smc_dev_init(struct smc_dev *smc, int id)
                                pr_error("%s: %d\n", buf, smc->enable_level);
                                if (smc->enable_pin != NULL) {
                                        _gpio_out(smc->enable_pin,
-                                               !smc->enable_level,
+                                               smc->enable_level,
                                                SMC_ENABLE_PIN_NAME);
                                        pr_error("enable_pin: -->(%d)\n",
                                                (!smc->enable_level)?1:0);
@@ -1953,7 +1925,7 @@ static int smc_dev_init(struct smc_dev *smc, int id)
        smc->irq_num = smc0_irq;
        if (smc->irq_num == -1) {
                snprintf(buf, sizeof(buf), "smc%d_irq", id);
-#ifdef CONFIG_OF
+#if 0
                ret = of_property_read_u32(smc->pdev->dev.of_node, buf, &value);
                if (!ret) {
                        smc->irq_num = value;
@@ -2183,7 +2155,7 @@ static int smc_dev_init(struct smc_dev *smc, int id)
        }
 #endif
 
-#if 0
+#if 1
        smc->enable_5v3v_level = 0;
        if (1) {
                snprintf(buf, sizeof(buf), "smc%d_5v3v_level", id);
@@ -2192,7 +2164,7 @@ static int smc_dev_init(struct smc_dev *smc, int id)
                if (!ret) {
                        smc->enable_5v3v_level = value;
                        pr_error("%s: %d\n", buf, smc->enable_5v3v_level);
-                       if (smc->enable_5v3v_pin != -1) {
+                       if (smc->enable_5v3v_pin != NULL) {
                                _gpio_out(smc->enable_5v3v_pin,
                                        smc->enable_5v3v_level,
                                        SMC_ENABLE_5V3V_PIN_NAME);
@@ -2236,7 +2208,7 @@ static int smc_dev_init(struct smc_dev *smc, int id)
 #else
        smc->irq_num = request_irq(smc->irq_num,
                        (irq_handler_t)smc_irq_handler,
-                       IRQF_SHARED, "smc", smc);
+                       IRQF_SHARED|IRQF_TRIGGER_RISING, "smc", smc);
        if (smc->irq_num < 0) {
                pr_error("request irq error!\n");
                smc_dev_deinit(smc);
@@ -2586,9 +2558,13 @@ static int smc_probe(struct platform_device *pdev)
                        break;
                }
        }
-       aml_smartcard_reset_ctrl =
-               devm_reset_control_get(&pdev->dev, "smartcard");
-       reset_control_deassert(aml_smartcard_reset_ctrl);
+       aml_smartcard_clk =
+               devm_clk_get(&pdev->dev, "smartcard");
+       if (IS_ERR_OR_NULL(aml_smartcard_clk)) {
+               dev_err(&pdev->dev, "get smartcard clk fail\n");
+               return -1;
+       }
+       clk_prepare_enable(aml_smartcard_clk);
        if (smc) {
                smc->init = 1;
                smc->pdev = pdev;
index bb1280ca70ddfe82a35522ca4d9df080c4906a74..784561359795b138e255bcfa1d058cee5ce5b7e6 100644 (file)
@@ -22,4 +22,5 @@ extern int amlogic_gpio_direction_output(unsigned int pin, int value,
        const char *owner);
 extern int amlogic_gpio_request(unsigned int pin, const char *label);
 extern unsigned long get_mpeg_clk(void);
+extern long smc_get_reg_base(void);
 #endif