From a3f21fe9fbfdd58ba364db633cc6405f29ffaa4d Mon Sep 17 00:00:00 2001 From: Yinming Ding Date: Fri, 22 Jun 2018 17:36:05 +0800 Subject: [PATCH] smartcard: modify smartcard driver for 8.1 PD#168901: smartcard modify smartcard driver for 8.1 Change-Id: Ib0b81009e434d5f6c513bfc52bbfeef48414ef39 Signed-off-by: Yinming Ding --- arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts | 33 ++++ arch/arm64/boot/dts/amlogic/mesongxl.dtsi | 10 ++ drivers/amlogic/pinctrl/pinctrl-meson-gxl.c | 13 +- drivers/amlogic/smartcard/c_stb_regs_define.h | 19 +-- drivers/amlogic/smartcard/smartcard.c | 148 ++++++++---------- drivers/amlogic/smartcard/smartcard.h | 1 + 6 files changed, 126 insertions(+), 98 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts b/arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts index b720dae4ddab..4cd5978ecbd1 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts @@ -1263,6 +1263,39 @@ &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"; diff --git a/arch/arm64/boot/dts/amlogic/mesongxl.dtsi b/arch/arm64/boot/dts/amlogic/mesongxl.dtsi index 472949888ae3..c342c7fc1417 100644 --- a/arch/arm64/boot/dts/amlogic/mesongxl.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesongxl.dtsi @@ -825,6 +825,16 @@ }; }; + 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", diff --git a/drivers/amlogic/pinctrl/pinctrl-meson-gxl.c b/drivers/amlogic/pinctrl/pinctrl-meson-gxl.c index 1c46b28afbcb..720f11249435 100644 --- a/drivers/amlogic/pinctrl/pinctrl-meson-gxl.c +++ b/drivers/amlogic/pinctrl/pinctrl-meson-gxl.c @@ -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), diff --git a/drivers/amlogic/smartcard/c_stb_regs_define.h b/drivers/amlogic/smartcard/c_stb_regs_define.h index 30390ae64080..2b92601183b8 100644 --- a/drivers/amlogic/smartcard/c_stb_regs_define.h +++ b/drivers/amlogic/smartcard/c_stb_regs_define.h @@ -19,22 +19,23 @@ #define __MACH_MESON8_REG_ADDR_H_ #include #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 diff --git a/drivers/amlogic/smartcard/smartcard.c b/drivers/amlogic/smartcard/smartcard.c index bcf5327a8256..8330b97a5cbf 100644 --- a/drivers/amlogic/smartcard/smartcard.c +++ b/drivers/amlogic/smartcard/smartcard.c @@ -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) + + +long smc_get_reg_base(void) { - struct clk *clk = NULL; + int newbase = 0; - clk = clk_get_sys(name, NULL); - if (clk) - return clk_get_rate(clk); - return 0; -} - -static unsigned long get_module_clk(int sel) -{ -#ifdef CONFIG_ARCH_ARC700 - return get_mpeg_clk(); -#else - - 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; + if (get_cpu_type() > MESON_CPU_MAJOR_ID_TXL && + get_cpu_type() != MESON_CPU_MAJOR_ID_GXLX) { + newbase = 1; } -#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; - } -#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; diff --git a/drivers/amlogic/smartcard/smartcard.h b/drivers/amlogic/smartcard/smartcard.h index bb1280ca70dd..784561359795 100644 --- a/drivers/amlogic/smartcard/smartcard.h +++ b/drivers/amlogic/smartcard/smartcard.h @@ -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