smartcard: modify smartcard driver for 8.1

PD#168901: smartcard modify smartcard driver for 8.1

Change-Id: Ib0b81009e434d5f6c513bfc52bbfeef48414ef39
Signed-off-by: Yinming Ding <yinming.ding@amlogic.com>
This commit is contained in:
Yinming Ding
2018-06-22 17:36:05 +08:00
committed by Yixun Lan
parent 7a67df5813
commit a3f21fe9fb
6 changed files with 126 additions and 98 deletions

View File

@@ -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";

View File

@@ -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",

View 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),

View File

@@ -19,22 +19,23 @@
#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

View 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)
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;

View 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