smartcard: add the smartcard driver

PD#138714: add the smartcard driver

1.add smartcard driver
2.add Documentation/devicetree/bindings/amlogic/amlogic-smartcard.txt
3.add CONFIG_AMLOGIC_SMARTCARD to meson64_defconfig

Change-Id: I1855c4df061b6d937f1bda7d603d3f02d6e90ef5
Signed-off-by: Ke Gong <ke.gong@amlogic.com>
This commit is contained in:
Ke Gong
2017-03-15 16:01:16 +08:00
committed by Jianxin Pan
parent 350e8c6ff5
commit 763e1f059d
12 changed files with 3172 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
Device-Tree bindings for smartcard driver
Required properties:
- compatible: Must be "amlogic, smartcard".
- interrupts: Smartcard IRQ.
- smc0_clock_source: Smartcard module's clock source selection.
- reset_level: Reset level.
- smc0_det_invert: Invert the DET level.
- pinctrl: Pinmux setting of the smartcard.
- resets: Clock domain of the smartcard.
If you want to use GPIO to replace the DET and RESET pins, the following properties should be set:
- reset_pin: RESET GPIO.
- detect_pin: DETECT GPIO.
If you want to switch 5v/3v by a GPIO, the following properties should be set:
- enable_5v3v_pin: 5v/3v switch GPIO.
- smc0_5v3v_level: 5v/3v GPIO output.
If you want to disable the CLK output when no card inserted, the following properties should be set:
- smc0_clk_pinmux_reg: CLK pinmux register address.
- smc0_clk_pinmux_bit: CLK pinmux bit.
- smc0_clk_oen_reg: CLK GPIO OEN register.
- smc0_clk_out_reg: CLK GPIO output register.
- smc0_clk_bit: CLK GPIO bit.
- smc0_clk_oebit: CLK GPIO OEN bit.;
- smc0_clk_oubit: BLK GPIO output bit.
Example:
smartcard {
compatible = "amlogic,smartcard";
irq_trigger_type = "GPIO_IRQ_LOW";
reset_pin = <&gpio GPIOX_11 GPIO_ACTIVE_HIGH >; //Reset pin
detect_pin = <&gpio GPIOX_20 GPIO_ACTIVE_HIGH >; //Detect pin
enable_5v3v_pin = <&gpio GPIOX_10 GPIO_ACTIVE_HIGH >; //5V3V pin, can be ignored
interrupts = <0 69 4>; //smc irq
smc0_clock_source = <0>; //Smc clock source, if change this, you must adjust clk and divider in smartcard.c
smc0_irq = <69 >; //smc irq
smc0_det_invert = <0>; //0: high voltage on detect pin indicates card in.
smc0_5v3v_level = <0>;
smc_need_enable_pin = "no"; //Ordinarily, smartcard controller needs a enable pin.
reset_level = <0>; //0: low to reset the smartcard
smc0_clk_pinmux_reg = <0x30>;
smc0_clk_pinmux_bit = <0x80>;
smc0_clk_oen_reg = <0x200f>;
smc0_clk_out_reg = <0x2010>;
smc0_clk_bit = <0x2000>;
smc0_clk_oebit = <0x2000000>;
smc0_clk_oubit = <0x1000000>;
pinctrl-names = "default";
pinctrl-0 = <&smc_pins>;
resets = <&clock GCLK_IDX_SMART_CARD_MPEG_DOMAIN>;
reset-names = "smartcard";
status = "okay";
};
&pinmux {
smc_pins:smc_pins { //Set gpio to 7816-clk 7816-data mode.
amlogic,setmask = <4 0x000000c0>; //Please refer to core-pin mux document
amlogic,clrmask = <3 0x60000280>;
amlogic,pins = "GPIOX_8","GPIOX_9";
};
}

View File

@@ -13617,3 +13617,14 @@ F: arch/arm64/configs/meson64_defconfig
F: drivers/amlogic/media/Kconfig
F: drivers/amlogic/media/Makefile
F: drivers/amlogic/media/vin/
AMLOGIC smartcard
M: Gong Ke <ke.gong@amlogic.com>
F: drivers/amlogic/smartcard/c_stb_regs_define.h
F: drivers/amlogic/smartcard/Kconfig
F: drivers/amlogic/smartcard/Makefile
F: drivers/amlogic/smartcard/smartcard.c
F: drivers/amlogic/smartcard/smartcard.h
F: drivers/amlogic/smartcard/smc_reg.h
F: include/linux/amlogic/amsmc.h
F: Documentation/devicetree/bindings/amlogic/amlogic-smartcard.txt

View File

@@ -216,6 +216,7 @@ CONFIG_AMLOGIC_MEDIA_FB_OSD2_ENABLE=y
CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR=y
CONFIG_AMLOGIC_MMC=y
CONFIG_AMLOGIC_VRTC=y
CONFIG_AMLOGIC_SMARTCARD=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y

View File

@@ -54,5 +54,8 @@ source "drivers/amlogic/media/Kconfig"
source "drivers/amlogic/mmc/Kconfig"
source "drivers/amlogic/vrtc/Kconfig"
source "drivers/amlogic/smartcard/Kconfig"
endmenu
endif

View File

@@ -50,3 +50,6 @@ obj-$(CONFIG_AMLOGIC_MEDIA_ENABLE) += media/
obj-$(CONFIG_AMLOGIC_MMC) += mmc/
obj-$(CONFIG_AMLOGIC_VRTC) += vrtc/
obj-$(CONFIG_AMLOGIC_SMARTCARD) += smartcard/

View File

@@ -0,0 +1,7 @@
#
#Smart card driver configuration
#
config AMLOGIC_SMARTCARD
bool "Amlogic Smartcard driver"
default n

View File

@@ -0,0 +1,6 @@
#
#Makefile for the Smart card driver.
#
obj-$(CONFIG_AMLOGIC_SMARTCARD) += amsmc.o
amsmc-objs = smartcard.o

View File

@@ -0,0 +1,40 @@
/*
* drivers/amlogic/smartcard/c_stb_regs_define.h
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#ifndef __MACH_MESON8_REG_ADDR_H_
#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 P_SMARTCARD_REG0 CBUS_REG_ADDR(SMARTCARD_REG0)
#define SMARTCARD_REG1 0x2111
#define P_SMARTCARD_REG1 CBUS_REG_ADDR(SMARTCARD_REG1)
#define SMARTCARD_REG2 0x2112
#define P_SMARTCARD_REG2 CBUS_REG_ADDR(SMARTCARD_REG2)
#define SMARTCARD_STATUS 0x2113
#define P_SMARTCARD_STATUS CBUS_REG_ADDR(SMARTCARD_STATUS)
#define SMARTCARD_INTR 0x2114
#define P_SMARTCARD_INTR CBUS_REG_ADDR(SMARTCARD_INTR)
#define SMARTCARD_REG5 0x2115
#define P_SMARTCARD_REG5 CBUS_REG_ADDR(SMARTCARD_REG5)
#define SMARTCARD_REG6 0x2116
#define P_SMARTCARD_REG6 CBUS_REG_ADDR(SMARTCARD_REG6)
#define SMARTCARD_FIFO 0x2117
#define P_SMARTCARD_FIFO CBUS_REG_ADDR(SMARTCARD_FIFO)
#define SMARTCARD_REG8 0x2118
#define P_SMARTCARD_REG8 CBUS_REG_ADDR(SMARTCARD_REG8)
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
/*
* drivers/amlogic/smartcard/smartcard.h
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#ifndef _AML_SMC_H_
#define _AML_SMC_H_
extern int amlogic_gpio_name_map_num(const char *name);
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);
#endif

View File

@@ -0,0 +1,265 @@
/*
* drivers/amlogic/smartcard/smc_reg.h
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#ifndef _SMC_REG_H
#define _SMC_REG_H
#include <asm/byteorder.h>
#ifdef __LITTLE_ENDIAN
#ifndef __LITTLE_ENDIAN__
#define __LITTLE_ENDIAN__
#endif
#endif
#define F_DEFAULT 372
#define D_DEFAULT 1
#define FREQ_DEFAULT 4000 /*KHz*/
#define FIFO_THRESHOLD_DEFAULT 1
#define ETU_DIVIDER_CLOCK_HZ 24000 /* KHz*/
#define ETU_CLK_SEL 0
#define ATR_HOLDOFF_EN 1
#define ATR_CLK_MUX_DEFAULT 4
#define ATR_HOLDOFF_TCNT_DEFAULT 255
#define ATR_FINAL_TCNT_DEFAULT 40000
#define DET_FILTER_SEL_DEFAULT 3
#define IO_FILTER_SEL_DEFAULT 3
#define BWT_BASE_DEFAULT 999
#define N_DEFAULT 0
#define CWI_DEFAULT 13
#define BWI_DEFAULT 4
#define BGT_DEFAULT 22
struct SMCCARD_HW_Reg0 {
#ifdef __LITTLE_ENDIAN__
unsigned etu_divider:16; /* Bit 15:0*/
unsigned first_etu_offset:3; /* Bit 18:16*/
unsigned enable:1; /* Bit 19*/
unsigned recv_fifo_threshold:4; /* Bit 23:20*/
unsigned clk_en:1; /* Bit 24*/
unsigned clk_oen:1; /* Bit 25*/
unsigned rst_level:1; /* Bit 26*/
unsigned start_atr:1; /* Bit 27*/
unsigned unused:1; /* Bit 28*/
unsigned io_level:1; /* Bit 29*/
unsigned card_detect:1; /* Bit 30*/
unsigned start_atr_en:1; /* Bit 31*/
#else
unsigned start_atr_en:1; /* Bit 31*/
unsigned card_detect:1; /* Bit 30*/
unsigned io_level:1; /* Bit 29*/
unsigned unused:1; /* Bit 28*/
unsigned start_atr:1; /* Bit 27*/
unsigned rst_level:1; /* Bit 26*/
unsigned clk_oen:1; /* Bit 25*/
unsigned clk_en:1; /* Bit 24*/
unsigned recv_fifo_threshold:4; /* Bit 23:20*/
unsigned enable:1; /* Bit 19*/
unsigned first_etu_offset:3; /* Bit 18:16*/
unsigned etu_divider:16; /* Bit 15:0*/
#endif
};
struct SMC_ANSWER_TO_RST {
#ifdef __LITTLE_ENDIAN__
unsigned atr_final_tcnt:16; /* Bit 15:0*/
unsigned atr_holdoff_tcnt:8; /* Bit 23:16*/
unsigned atr_clk_mux:3; /* Bit 26:24*/
unsigned atr_holdoff_en:1; /* Bit 27*/
unsigned etu_clk_sel:2; /* Bit 29:28*/
unsigned unused:2; /* Bit 31:30*/
#else
unsigned unused:2; /* Bit 31:30*/
unsigned etu_clk_sel:2; /* Bit 29:28*/
unsigned atr_holdoff_en:1; /* Bit 27*/
unsigned atr_clk_mux:3; /* Bit 26:24*/
unsigned atr_holdoff_tcnt:8; /* Bit 23:16*/
unsigned atr_final_tcnt:16; /* Bit 15:0*/
#endif
};
struct SMCCARD_HW_Reg2 {
#ifdef __LITTLE_ENDIAN__
unsigned xmit_invert:1; /* Bit 0*/
unsigned xmit_lsb_msb:1; /* Bit 1*/
unsigned xmit_parity:1; /* Bit 2*/
unsigned xmit_retries:3; /* Bit 5:3*/
unsigned xmit_repeat_dis:1; /* Bit 6*/
unsigned recv_invert:1; /* Bit 7*/
unsigned recv_lsb_msb:1; /* Bit 8*/
unsigned recv_parity:1; /* Bit 9*/
unsigned recv_no_parity:1; /* Bit 10*/
unsigned pulse_irq:1; /* Bit 11*/
unsigned clk_tcnt:8; /* Bit 19:12*/
unsigned det_filter_sel:3; /* Bit 22:20*/
unsigned io_filter_sel:3; /* Bit 25:23*/
unsigned recv_retry_cnt:3; /* Bit 28:26*/
unsigned reserved:1; /* Bit 29*/
unsigned clk_sel:2; /* Bit 31:30*/
#else
unsigned clk_sel:2; /* Bit 31:30*/
unsigned reserved:1; /* Bit 29*/
unsigned recv_retry_cnt:3; /* Bit 28:26*/
unsigned io_filter_sel:3; /* Bit 25:23*/
unsigned det_filter_sel:3; /* Bit 22:20*/
unsigned clk_tcnt:8; /* Bit 19:12*/
unsigned pulse_irq:1; /* Bit 11*/
unsigned recv_no_parity:1; /* Bit 10*/
unsigned recv_parity:1; /* Bit 9*/
unsigned recv_lsb_msb:1; /* Bit 8*/
unsigned recv_invert:1; /* Bit 7*/
unsigned xmit_repeat_dis:1; /* Bit 6*/
unsigned xmit_retries:3; /* Bit 5:3*/
unsigned xmit_parity:1; /* Bit 2*/
unsigned xmit_lsb_msb:1; /* Bit 1*/
unsigned xmit_invert:1; /* Bit 0*/
#endif
};
struct SMC_STATUS_Reg {
#ifdef __LITTLE_ENDIAN__
unsigned recv_fifo_threshold_status:1; /* Bit 0*/
unsigned send_fifo_last_byte_status:1; /* Bit 1*/
unsigned cwt_expeired_status:1; /* Bit 2*/
unsigned bwt_expeired_status:1; /* Bit 3*/
unsigned write_full_send_fifo_status:1; /* Bit 4*/
unsigned send_and_recv_confilt_status:1; /* Bit 5*/
unsigned recv_error_status:1; /* Bit 6*/
unsigned send_error_status:1; /* Bit 7*/
unsigned rst_expired_status:1; /* Bit 8*/
unsigned card_detect_status:1; /* Bit 9*/
unsigned unused:6; /* Bit 15:10*/
unsigned recv_fifo_bytes_number:4; /* Bit 19:16*/
unsigned recv_fifo_empty_status:1; /* Bit 20*/
unsigned recv_fifo_full_status:1; /* Bit 21*/
unsigned send_fifo_bytes_number:4; /* Bit 25:22*/
unsigned send_fifo_empty_status:1; /* Bit 26*/
unsigned send_fifo_full_status:1; /* Bit 27*/
unsigned recv_data_from_card_status:1; /* Bit 28*/
unsigned recv_module_enable_status:1; /* Bit 29*/
unsigned send_module_enable_status:1; /* Bit 30*/
unsigned wait_for_atr_status:1; /* Bit 31*/
#else
unsigned wait_for_atr_status:1; /* Bit 31*/
unsigned send_module_enable_status:1; /* Bit 30*/
unsigned recv_module_enable_status:1; /* Bit 29*/
unsigned recv_data_from_card_status:1; /* Bit 28*/
unsigned send_fifo_full_status:1; /* Bit 27*/
unsigned send_fifo_empty_status:1; /* Bit 26*/
unsigned send_fifo_bytes_number:4; /* Bit 25:22*/
unsigned recv_fifo_full_status:1; /* Bit 21*/
unsigned recv_fifo_empty_status:1; /* Bit 20*/
unsigned recv_fifo_bytes_number:4; /* Bit 19:16*/
unsigned unused:6; /* Bit 15:10*/
unsigned card_detect_status:1; /* Bit 9*/
unsigned rst_expired_status:1; /* Bit 8*/
unsigned send_error_status:1; /* Bit 7*/
unsigned recv_error_status:1; /* Bit 6*/
unsigned send_and_recv_confilt_status:1; /* Bit 5*/
unsigned write_full_send_fifo_status:1; /* Bit 4*/
unsigned bwt_expeired_status:1; /* Bit 3*/
unsigned cwt_expeired_status:1; /* Bit 2*/
unsigned send_fifo_last_byte_status:1; /* Bit 1*/
unsigned recv_fifo_threshold_status:1; /* Bit 0*/
#endif
};
struct SMC_INTERRUPT_Reg {
#ifdef __LITTLE_ENDIAN__
unsigned recv_fifo_bytes_threshold_int:1; /* Bit 0*/
unsigned send_fifo_last_byte_int:1; /* Bit 1*/
unsigned cwt_expeired_int:1; /* Bit 2*/
unsigned bwt_expeired_int:1; /* Bit 3*/
unsigned write_full_fifo_int:1; /* Bit 4*/
unsigned send_and_recv_confilt_int:1; /* Bit 5*/
unsigned recv_error_int:1; /* Bit 6*/
unsigned send_error_int:1; /* Bit 7*/
unsigned rst_expired_int:1; /* Bit 8*/
unsigned card_detect_int:1; /* Bit 9*/
unsigned unused1:6; /* Bit 15:10*/
unsigned recv_fifo_bytes_threshold_int_mask:1; /* Bit 16*/
unsigned send_fifo_last_byte_int_mask:1; /* Bit 17*/
unsigned cwt_expeired_int_mask:1; /* Bit 18*/
unsigned bwt_expeired_int_mask:1; /* Bit 19*/
unsigned write_full_fifo_int_mask:1; /* Bit 20*/
unsigned send_and_recv_confilt_int_mask:1; /* Bit 21*/
unsigned recv_error_int_mask:1; /* Bit 22*/
unsigned send_error_int_mask:1; /* Bit 23*/
unsigned rst_expired_int_mask:1; /* Bit 24*/
unsigned card_detect_int_mask:1; /* Bit 25*/
unsigned unused2:6; /* Bit 31:26*/
#else
unsigned unused2:6; /* Bit 31:26*/
unsigned card_detect_int_mask:1; /* Bit 25*/
unsigned rst_expired_int_mask:1; /* Bit 24*/
unsigned send_error_int_mask:1; /* Bit 23*/
unsigned recv_error_int_mask:1; /* Bit 22*/
unsigned send_and_recv_confilt_int_mask:1; /* Bit 21*/
unsigned write_full_fifo_int_mask:1; /* Bit 20*/
unsigned bwt_expeired_int_mask:1; /* Bit 19*/
unsigned cwt_expeired_int_mask:1; /* Bit 18*/
unsigned send_fifo_last_byte_int_mask:1; /* Bit 17*/
unsigned recv_fifo_bytes_threshold_int_mask:1; /* Bit 16*/
unsigned unused1:6; /* Bit 15:10*/
unsigned card_detect_int:1; /* Bit 9*/
unsigned rst_expired_int:1; /* Bit 8*/
unsigned send_error_int:1; /* Bit 7*/
unsigned recv_error_int:1; /* Bit 6*/
unsigned send_and_recv_confilt_int:1; /* Bit 5*/
unsigned write_full_fifo_int:1; /* Bit 4*/
unsigned bwt_expeired_int:1; /* Bit 3*/
unsigned cwt_expeired_int:1; /* Bit 2*/
unsigned send_fifo_last_byte_int:1; /* Bit 1*/
unsigned recv_fifo_bytes_threshold_int:1; /* Bit 0*/
#endif
};
struct SMCCARD_HW_Reg5 {
#ifdef __LITTLE_ENDIAN__
unsigned bwt_base_time_gnt:16; /* Bit 15:0*/
unsigned btw_detect_en:1; /* Bit 16*/
unsigned cwt_detect_en:1; /* Bit 17*/
unsigned etu_msr_en:1; /* Bit 18*/
unsigned unused:1; /* Bit 19*/
unsigned etu_msr_cnt:12; /* Bit 31:20*/
#else
unsigned etu_msr_cnt:12; /* Bit 31:20*/
unsigned unused:1; /* Bit 19*/
unsigned etu_msr_en:1; /* Bit 18*/
unsigned cwt_detect_en:1; /* Bit 17*/
unsigned btw_detect_en:1; /* Bit 16*/
unsigned bwt_base_time_gnt:16; /* Bit 15:0*/
#endif
};
struct SMCCARD_HW_Reg6 {
#ifdef __LITTLE_ENDIAN__
unsigned N_parameter:8; /* Bit 7:0*/
unsigned cwi_value:4; /* Bit 11:8*/
unsigned bgt:8; /* Bit 19:12*/
unsigned bwi:4; /* Bit 23:20*/
unsigned unused:8; /* Bit 31:24*/
#else
unsigned unused:8; /* Bit 31:24*/
unsigned bwi:4; /* Bit 23:20*/
unsigned bgt:8; /* Bit 19:12*/
unsigned cwi_value:4; /* Bit 11:8*/
unsigned N_parameter:8; /* Bit 7:0*/
#endif
};
#endif

View File

@@ -0,0 +1,64 @@
/*
* include/linux/amlogic/amsmc.h
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#ifndef _AMSMC_H
#define _AMSMC_H
/* #include <asm/types.h> */
#include <linux/types.h>
#define AMSMC_MAX_ATR_LEN 33
enum {
AMSMC_CARDOUT = 0,
AMSMC_CARDIN = 1
};
struct am_smc_atr {
char atr[AMSMC_MAX_ATR_LEN];
int atr_len;
};
struct am_smc_param {
int f;
int d;
int n;
int bwi;
int cwi;
int bgt;
int freq;
int recv_invert;
int recv_lsb_msb;
int recv_no_parity;
int recv_parity;
int xmit_invert;
int xmit_lsb_msb;
int xmit_retries;
int xmit_repeat_dis;
int xmit_parity;
};
#define AMSMC_IOC_MAGIC 'C'
#define AMSMC_IOC_RESET _IOR(AMSMC_IOC_MAGIC, 0x00, struct am_smc_atr)
#define AMSMC_IOC_GET_STATUS _IOR(AMSMC_IOC_MAGIC, 0x01, int)
#define AMSMC_IOC_ACTIVE _IO(AMSMC_IOC_MAGIC, 0x02)
#define AMSMC_IOC_DEACTIVE _IO(AMSMC_IOC_MAGIC, 0x03)
#define AMSMC_IOC_GET_PARAM _IOR(AMSMC_IOC_MAGIC, 0x04, struct am_smc_param)
#define AMSMC_IOC_SET_PARAM _IOW(AMSMC_IOC_MAGIC, 0x05, struct am_smc_param)
#endif