1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * SCR24x PCMCIA Smart Card Reader Driver
5 * Copyright (C) 2005-2006 TL Sudheendran
6 * Copyright (C) 2016 Lubomir Rintel
8 * Derived from "scr24x_v4.2.6_Release.tar.gz" driver by TL Sudheendran.
11 #include <linux/device.h>
12 #include <linux/module.h>
13 #include <linux/delay.h>
14 #include <linux/cdev.h>
15 #include <linux/slab.h>
18 #include <linux/uaccess.h>
20 #include <pcmcia/cistpl.h>
21 #include <pcmcia/ds.h>
23 #define CCID_HEADER_SIZE 10
24 #define CCID_LENGTH_OFFSET 1
25 #define CCID_MAX_LEN 271
27 #define SCR24X_DATA(n) (1 + n)
28 #define SCR24X_CMD_STATUS 7
29 #define CMD_START 0x40
30 #define CMD_WRITE_BYTE 0x41
31 #define CMD_READ_BYTE 0x42
32 #define STATUS_BUSY 0x80
37 unsigned char buf
[CCID_MAX_LEN
];
45 static DECLARE_BITMAP(scr24x_minors
, SCR24X_DEVS
);
47 static struct class *scr24x_class
;
48 static dev_t scr24x_devt
;
50 static void scr24x_delete(struct kref
*kref
)
52 struct scr24x_dev
*dev
= container_of(kref
, struct scr24x_dev
,
58 static int scr24x_wait_ready(struct scr24x_dev
*dev
)
64 status
= ioread8(dev
->regs
+ SCR24X_CMD_STATUS
);
65 if (!(status
& STATUS_BUSY
))
74 static int scr24x_open(struct inode
*inode
, struct file
*filp
)
76 struct scr24x_dev
*dev
= container_of(inode
->i_cdev
,
77 struct scr24x_dev
, c_dev
);
79 kref_get(&dev
->refcnt
);
80 filp
->private_data
= dev
;
82 return stream_open(inode
, filp
);
85 static int scr24x_release(struct inode
*inode
, struct file
*filp
)
87 struct scr24x_dev
*dev
= filp
->private_data
;
89 /* We must not take the dev->lock here as scr24x_delete()
90 * might be called to remove the dev structure altogether.
91 * We don't need the lock anyway, since after the reference
92 * acquired in probe() is released in remove() the chrdev
93 * is already unregistered and noone can possibly acquire
94 * a reference via open() anymore. */
95 kref_put(&dev
->refcnt
, scr24x_delete
);
99 static int read_chunk(struct scr24x_dev
*dev
, size_t offset
, size_t limit
)
104 for (i
= offset
; i
< limit
; i
+= 5) {
105 iowrite8(CMD_READ_BYTE
, dev
->regs
+ SCR24X_CMD_STATUS
);
106 ret
= scr24x_wait_ready(dev
);
110 for (y
= 0; y
< 5 && i
+ y
< limit
; y
++)
111 dev
->buf
[i
+ y
] = ioread8(dev
->regs
+ SCR24X_DATA(y
));
117 static ssize_t
scr24x_read(struct file
*filp
, char __user
*buf
, size_t count
,
120 struct scr24x_dev
*dev
= filp
->private_data
;
124 if (count
< CCID_HEADER_SIZE
)
127 if (mutex_lock_interruptible(&dev
->lock
))
135 ret
= scr24x_wait_ready(dev
);
138 len
= CCID_HEADER_SIZE
;
139 ret
= read_chunk(dev
, 0, len
);
143 len
+= le32_to_cpu(*(__le32
*)(&dev
->buf
[CCID_LENGTH_OFFSET
]));
144 if (len
> sizeof(dev
->buf
)) {
148 ret
= read_chunk(dev
, CCID_HEADER_SIZE
, len
);
155 if (copy_to_user(buf
, dev
->buf
, count
)) {
162 mutex_unlock(&dev
->lock
);
166 static ssize_t
scr24x_write(struct file
*filp
, const char __user
*buf
,
167 size_t count
, loff_t
*ppos
)
169 struct scr24x_dev
*dev
= filp
->private_data
;
173 if (mutex_lock_interruptible(&dev
->lock
))
181 if (count
> sizeof(dev
->buf
)) {
186 if (copy_from_user(dev
->buf
, buf
, count
)) {
191 ret
= scr24x_wait_ready(dev
);
195 iowrite8(CMD_START
, dev
->regs
+ SCR24X_CMD_STATUS
);
196 ret
= scr24x_wait_ready(dev
);
200 for (i
= 0; i
< count
; i
+= 5) {
201 for (y
= 0; y
< 5 && i
+ y
< count
; y
++)
202 iowrite8(dev
->buf
[i
+ y
], dev
->regs
+ SCR24X_DATA(y
));
204 iowrite8(CMD_WRITE_BYTE
, dev
->regs
+ SCR24X_CMD_STATUS
);
205 ret
= scr24x_wait_ready(dev
);
212 mutex_unlock(&dev
->lock
);
216 static const struct file_operations scr24x_fops
= {
217 .owner
= THIS_MODULE
,
219 .write
= scr24x_write
,
221 .release
= scr24x_release
,
225 static int scr24x_config_check(struct pcmcia_device
*link
, void *priv_data
)
227 if (resource_size(link
->resource
[PCMCIA_IOPORT_0
]) != 0x11)
229 return pcmcia_request_io(link
);
232 static int scr24x_probe(struct pcmcia_device
*link
)
234 struct scr24x_dev
*dev
;
237 dev
= kzalloc(sizeof(*dev
), GFP_KERNEL
);
241 dev
->devno
= find_first_zero_bit(scr24x_minors
, SCR24X_DEVS
);
242 if (dev
->devno
>= SCR24X_DEVS
) {
247 mutex_init(&dev
->lock
);
248 kref_init(&dev
->refcnt
);
251 link
->config_flags
|= CONF_ENABLE_IRQ
| CONF_AUTO_SET_IO
;
253 ret
= pcmcia_loop_config(link
, scr24x_config_check
, NULL
);
257 dev
->dev
= &link
->dev
;
258 dev
->regs
= devm_ioport_map(&link
->dev
,
259 link
->resource
[PCMCIA_IOPORT_0
]->start
,
260 resource_size(link
->resource
[PCMCIA_IOPORT_0
]));
266 cdev_init(&dev
->c_dev
, &scr24x_fops
);
267 dev
->c_dev
.owner
= THIS_MODULE
;
268 dev
->c_dev
.ops
= &scr24x_fops
;
269 ret
= cdev_add(&dev
->c_dev
, MKDEV(MAJOR(scr24x_devt
), dev
->devno
), 1);
273 ret
= pcmcia_enable_device(link
);
275 pcmcia_disable_device(link
);
279 device_create(scr24x_class
, NULL
, MKDEV(MAJOR(scr24x_devt
), dev
->devno
),
280 NULL
, "scr24x%d", dev
->devno
);
282 dev_info(&link
->dev
, "SCR24x Chip Card Interface\n");
286 if (dev
->devno
< SCR24X_DEVS
)
287 clear_bit(dev
->devno
, scr24x_minors
);
292 static void scr24x_remove(struct pcmcia_device
*link
)
294 struct scr24x_dev
*dev
= (struct scr24x_dev
*)link
->priv
;
296 device_destroy(scr24x_class
, MKDEV(MAJOR(scr24x_devt
), dev
->devno
));
297 mutex_lock(&dev
->lock
);
298 pcmcia_disable_device(link
);
299 cdev_del(&dev
->c_dev
);
300 clear_bit(dev
->devno
, scr24x_minors
);
302 mutex_unlock(&dev
->lock
);
304 kref_put(&dev
->refcnt
, scr24x_delete
);
307 static const struct pcmcia_device_id scr24x_ids
[] = {
308 PCMCIA_DEVICE_PROD_ID12("HP", "PC Card Smart Card Reader",
309 0x53cb94f9, 0xbfdf89a5),
310 PCMCIA_DEVICE_PROD_ID1("SCR241 PCMCIA", 0x6271efa3),
311 PCMCIA_DEVICE_PROD_ID1("SCR243 PCMCIA", 0x2054e8de),
312 PCMCIA_DEVICE_PROD_ID1("SCR24x PCMCIA", 0x54a33665),
315 MODULE_DEVICE_TABLE(pcmcia
, scr24x_ids
);
317 static struct pcmcia_driver scr24x_driver
= {
318 .owner
= THIS_MODULE
,
320 .probe
= scr24x_probe
,
321 .remove
= scr24x_remove
,
322 .id_table
= scr24x_ids
,
325 static int __init
scr24x_init(void)
329 scr24x_class
= class_create(THIS_MODULE
, "scr24x");
330 if (IS_ERR(scr24x_class
))
331 return PTR_ERR(scr24x_class
);
333 ret
= alloc_chrdev_region(&scr24x_devt
, 0, SCR24X_DEVS
, "scr24x");
335 class_destroy(scr24x_class
);
339 ret
= pcmcia_register_driver(&scr24x_driver
);
341 unregister_chrdev_region(scr24x_devt
, SCR24X_DEVS
);
342 class_destroy(scr24x_class
);
348 static void __exit
scr24x_exit(void)
350 pcmcia_unregister_driver(&scr24x_driver
);
351 unregister_chrdev_region(scr24x_devt
, SCR24X_DEVS
);
352 class_destroy(scr24x_class
);
355 module_init(scr24x_init
);
356 module_exit(scr24x_exit
);
358 MODULE_AUTHOR("Lubomir Rintel");
359 MODULE_DESCRIPTION("SCR24x PCMCIA Smart Card Reader Driver");
360 MODULE_LICENSE("GPL");