xref: /openbmc/linux/Documentation/driver-api/serial/serial-iso7816.rst (revision 0898782247ae533d1f4e47a06bc5d4870931b284)
1*65388dadSMauro Carvalho Chehab=============================
2*65388dadSMauro Carvalho ChehabISO7816 Serial Communications
3*65388dadSMauro Carvalho Chehab=============================
4*65388dadSMauro Carvalho Chehab
5*65388dadSMauro Carvalho Chehab1. Introduction
6*65388dadSMauro Carvalho Chehab===============
7*65388dadSMauro Carvalho Chehab
8*65388dadSMauro Carvalho Chehab  ISO/IEC7816 is a series of standards specifying integrated circuit cards (ICC)
9*65388dadSMauro Carvalho Chehab  also known as smart cards.
10*65388dadSMauro Carvalho Chehab
11*65388dadSMauro Carvalho Chehab2. Hardware-related considerations
12*65388dadSMauro Carvalho Chehab==================================
13*65388dadSMauro Carvalho Chehab
14*65388dadSMauro Carvalho Chehab  Some CPUs/UARTs (e.g., Microchip AT91) contain a built-in mode capable of
15*65388dadSMauro Carvalho Chehab  handling communication with a smart card.
16*65388dadSMauro Carvalho Chehab
17*65388dadSMauro Carvalho Chehab  For these microcontrollers, the Linux driver should be made capable of
18*65388dadSMauro Carvalho Chehab  working in both modes, and proper ioctls (see later) should be made
19*65388dadSMauro Carvalho Chehab  available at user-level to allow switching from one mode to the other, and
20*65388dadSMauro Carvalho Chehab  vice versa.
21*65388dadSMauro Carvalho Chehab
22*65388dadSMauro Carvalho Chehab3. Data Structures Already Available in the Kernel
23*65388dadSMauro Carvalho Chehab==================================================
24*65388dadSMauro Carvalho Chehab
25*65388dadSMauro Carvalho Chehab  The Linux kernel provides the serial_iso7816 structure (see [1]) to handle
26*65388dadSMauro Carvalho Chehab  ISO7816 communications. This data structure is used to set and configure
27*65388dadSMauro Carvalho Chehab  ISO7816 parameters in ioctls.
28*65388dadSMauro Carvalho Chehab
29*65388dadSMauro Carvalho Chehab  Any driver for devices capable of working both as RS232 and ISO7816 should
30*65388dadSMauro Carvalho Chehab  implement the iso7816_config callback in the uart_port structure. The
31*65388dadSMauro Carvalho Chehab  serial_core calls iso7816_config to do the device specific part in response
32*65388dadSMauro Carvalho Chehab  to TIOCGISO7816 and TIOCSISO7816 ioctls (see below). The iso7816_config
33*65388dadSMauro Carvalho Chehab  callback receives a pointer to struct serial_iso7816.
34*65388dadSMauro Carvalho Chehab
35*65388dadSMauro Carvalho Chehab4. Usage from user-level
36*65388dadSMauro Carvalho Chehab========================
37*65388dadSMauro Carvalho Chehab
38*65388dadSMauro Carvalho Chehab  From user-level, ISO7816 configuration can be get/set using the previous
39*65388dadSMauro Carvalho Chehab  ioctls. For instance, to set ISO7816 you can use the following code::
40*65388dadSMauro Carvalho Chehab
41*65388dadSMauro Carvalho Chehab	#include <linux/serial.h>
42*65388dadSMauro Carvalho Chehab
43*65388dadSMauro Carvalho Chehab	/* Include definition for ISO7816 ioctls: TIOCSISO7816 and TIOCGISO7816 */
44*65388dadSMauro Carvalho Chehab	#include <sys/ioctl.h>
45*65388dadSMauro Carvalho Chehab
46*65388dadSMauro Carvalho Chehab	/* Open your specific device (e.g., /dev/mydevice): */
47*65388dadSMauro Carvalho Chehab	int fd = open ("/dev/mydevice", O_RDWR);
48*65388dadSMauro Carvalho Chehab	if (fd < 0) {
49*65388dadSMauro Carvalho Chehab		/* Error handling. See errno. */
50*65388dadSMauro Carvalho Chehab	}
51*65388dadSMauro Carvalho Chehab
52*65388dadSMauro Carvalho Chehab	struct serial_iso7816 iso7816conf;
53*65388dadSMauro Carvalho Chehab
54*65388dadSMauro Carvalho Chehab	/* Reserved fields as to be zeroed */
55*65388dadSMauro Carvalho Chehab	memset(&iso7816conf, 0, sizeof(iso7816conf));
56*65388dadSMauro Carvalho Chehab
57*65388dadSMauro Carvalho Chehab	/* Enable ISO7816 mode: */
58*65388dadSMauro Carvalho Chehab	iso7816conf.flags |= SER_ISO7816_ENABLED;
59*65388dadSMauro Carvalho Chehab
60*65388dadSMauro Carvalho Chehab	/* Select the protocol: */
61*65388dadSMauro Carvalho Chehab	/* T=0 */
62*65388dadSMauro Carvalho Chehab	iso7816conf.flags |= SER_ISO7816_T(0);
63*65388dadSMauro Carvalho Chehab	/* or T=1 */
64*65388dadSMauro Carvalho Chehab	iso7816conf.flags |= SER_ISO7816_T(1);
65*65388dadSMauro Carvalho Chehab
66*65388dadSMauro Carvalho Chehab	/* Set the guard time: */
67*65388dadSMauro Carvalho Chehab	iso7816conf.tg = 2;
68*65388dadSMauro Carvalho Chehab
69*65388dadSMauro Carvalho Chehab	/* Set the clock frequency*/
70*65388dadSMauro Carvalho Chehab	iso7816conf.clk = 3571200;
71*65388dadSMauro Carvalho Chehab
72*65388dadSMauro Carvalho Chehab	/* Set transmission factors: */
73*65388dadSMauro Carvalho Chehab	iso7816conf.sc_fi = 372;
74*65388dadSMauro Carvalho Chehab	iso7816conf.sc_di = 1;
75*65388dadSMauro Carvalho Chehab
76*65388dadSMauro Carvalho Chehab	if (ioctl(fd_usart, TIOCSISO7816, &iso7816conf) < 0) {
77*65388dadSMauro Carvalho Chehab		/* Error handling. See errno. */
78*65388dadSMauro Carvalho Chehab	}
79*65388dadSMauro Carvalho Chehab
80*65388dadSMauro Carvalho Chehab	/* Use read() and write() syscalls here... */
81*65388dadSMauro Carvalho Chehab
82*65388dadSMauro Carvalho Chehab	/* Close the device when finished: */
83*65388dadSMauro Carvalho Chehab	if (close (fd) < 0) {
84*65388dadSMauro Carvalho Chehab		/* Error handling. See errno. */
85*65388dadSMauro Carvalho Chehab	}
86*65388dadSMauro Carvalho Chehab
87*65388dadSMauro Carvalho Chehab5. References
88*65388dadSMauro Carvalho Chehab=============
89*65388dadSMauro Carvalho Chehab
90*65388dadSMauro Carvalho Chehab [1]    include/uapi/linux/serial.h
91