2 * vrc4171_card.c, NEC VRC4171 Card Controller driver for Socket Services.
4 * Copyright (C) 2003-2005 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <linux/init.h>
21 #include <linux/ioport.h>
22 #include <linux/interrupt.h>
23 #include <linux/module.h>
24 #include <linux/spinlock.h>
25 #include <linux/sched.h>
26 #include <linux/types.h>
27 #include <linux/platform_device.h>
31 #include <pcmcia/ss.h>
35 MODULE_DESCRIPTION("NEC VRC4171 Card Controllers driver for Socket Services");
36 MODULE_AUTHOR("Yoichi Yuasa <yuasa@hh.iij4u.or.jp>");
37 MODULE_LICENSE("GPL");
39 #define CARD_MAX_SLOTS 2
42 #define CARD_SLOTB_OFFSET 0x40
44 #define CARD_MEM_START 0x10000000
45 #define CARD_MEM_END 0x13ffffff
46 #define CARD_MAX_MEM_OFFSET 0x3ffffff
47 #define CARD_MAX_MEM_SPEED 1000
49 #define CARD_CONTROLLER_INDEX 0x03e0
50 #define CARD_CONTROLLER_DATA 0x03e1
52 #define VPP_GET_VCC 0x01
53 #define POWER_ENABLE 0x10
54 #define CARD_VOLTAGE_SENSE 0x1f
55 #define VCC_3VORXV_CAPABLE 0x00
56 #define VCC_XV_ONLY 0x01
57 #define VCC_3V_CAPABLE 0x02
58 #define VCC_5V_ONLY 0x03
59 #define CARD_VOLTAGE_SELECT 0x2f
63 #define VCC_STATUS_3V 0x02
64 #define VCC_STATUS_5V 0x01
65 #define VCC_STATUS_XV 0x03
66 #define GLOBAL_CONTROL 0x1e
71 #define INTERRUPT_STATUS 0x05fa
75 #define CONFIGURATION1 0x05fe
76 #define SLOTB_CONFIG 0xc000
77 #define SLOTB_NONE 0x0000
78 #define SLOTB_PCCARD 0x4000
79 #define SLOTB_CF 0x8000
80 #define SLOTB_FLASHROM 0xc000
82 #define CARD_CONTROLLER_START CARD_CONTROLLER_INDEX
83 #define CARD_CONTROLLER_END CARD_CONTROLLER_DATA
86 #define MEM_MAX_MAPS 5
103 typedef struct vrc4171_socket
{
105 struct pcmcia_socket pcmcia_socket
;
111 static vrc4171_socket_t vrc4171_sockets
[CARD_MAX_SLOTS
];
112 static vrc4171_slotb_t vrc4171_slotb
= SLOTB_IS_NONE
;
113 static char vrc4171_card_name
[] = "NEC VRC4171 Card Controller";
114 static unsigned int vrc4171_irq
;
115 static uint16_t vrc4171_irq_mask
= 0xdeb8;
117 static struct resource vrc4171_card_resource
[3] = {
118 { .name
= vrc4171_card_name
,
119 .start
= CARD_CONTROLLER_START
,
120 .end
= CARD_CONTROLLER_END
,
121 .flags
= IORESOURCE_IO
, },
122 { .name
= vrc4171_card_name
,
123 .start
= INTERRUPT_STATUS
,
124 .end
= INTERRUPT_STATUS
,
125 .flags
= IORESOURCE_IO
, },
126 { .name
= vrc4171_card_name
,
127 .start
= CONFIGURATION1
,
128 .end
= CONFIGURATION1
,
129 .flags
= IORESOURCE_IO
, },
132 static struct platform_device vrc4171_card_device
= {
133 .name
= vrc4171_card_name
,
136 .resource
= vrc4171_card_resource
,
139 static inline uint16_t vrc4171_get_irq_status(void)
141 return inw(INTERRUPT_STATUS
);
144 static inline void vrc4171_set_multifunction_pin(vrc4171_slotb_t config
)
148 config1
= inw(CONFIGURATION1
);
149 config1
&= ~SLOTB_CONFIG
;
153 config1
|= SLOTB_NONE
;
155 case SLOTB_IS_PCCARD
:
156 config1
|= SLOTB_PCCARD
;
161 case SLOTB_IS_FLASHROM
:
162 config1
|= SLOTB_FLASHROM
;
168 outw(config1
, CONFIGURATION1
);
171 static inline uint8_t exca_read_byte(int slot
, uint8_t index
)
173 if (slot
== CARD_SLOTB
)
174 index
+= CARD_SLOTB_OFFSET
;
176 outb(index
, CARD_CONTROLLER_INDEX
);
177 return inb(CARD_CONTROLLER_DATA
);
180 static inline uint16_t exca_read_word(int slot
, uint8_t index
)
184 if (slot
== CARD_SLOTB
)
185 index
+= CARD_SLOTB_OFFSET
;
187 outb(index
++, CARD_CONTROLLER_INDEX
);
188 data
= inb(CARD_CONTROLLER_DATA
);
190 outb(index
, CARD_CONTROLLER_INDEX
);
191 data
|= ((uint16_t)inb(CARD_CONTROLLER_DATA
)) << 8;
196 static inline uint8_t exca_write_byte(int slot
, uint8_t index
, uint8_t data
)
198 if (slot
== CARD_SLOTB
)
199 index
+= CARD_SLOTB_OFFSET
;
201 outb(index
, CARD_CONTROLLER_INDEX
);
202 outb(data
, CARD_CONTROLLER_DATA
);
207 static inline uint16_t exca_write_word(int slot
, uint8_t index
, uint16_t data
)
209 if (slot
== CARD_SLOTB
)
210 index
+= CARD_SLOTB_OFFSET
;
212 outb(index
++, CARD_CONTROLLER_INDEX
);
213 outb(data
, CARD_CONTROLLER_DATA
);
215 outb(index
, CARD_CONTROLLER_INDEX
);
216 outb((uint8_t)(data
>> 8), CARD_CONTROLLER_DATA
);
221 static inline int search_nonuse_irq(void)
225 for (i
= 0; i
< 16; i
++) {
226 if (vrc4171_irq_mask
& (1 << i
)) {
227 vrc4171_irq_mask
&= ~(1 << i
);
235 static int pccard_init(struct pcmcia_socket
*sock
)
237 vrc4171_socket_t
*socket
;
240 sock
->features
|= SS_CAP_PCCARD
| SS_CAP_PAGE_REGS
;
242 sock
->map_size
= 0x1000;
243 sock
->pci_irq
= vrc4171_irq
;
246 socket
= &vrc4171_sockets
[slot
];
247 socket
->csc_irq
= search_nonuse_irq();
248 socket
->io_irq
= search_nonuse_irq();
253 static int pccard_get_status(struct pcmcia_socket
*sock
, u_int
*value
)
256 uint8_t status
, sense
;
259 if (sock
== NULL
|| sock
->sock
>= CARD_MAX_SLOTS
|| value
== NULL
)
264 status
= exca_read_byte(slot
, I365_STATUS
);
265 if (exca_read_byte(slot
, I365_INTCTL
) & I365_PC_IOCARD
) {
266 if (status
& I365_CS_STSCHG
)
269 if (!(status
& I365_CS_BVD1
))
271 else if ((status
& (I365_CS_BVD1
| I365_CS_BVD2
)) == I365_CS_BVD1
)
274 if ((status
& I365_CS_DETECT
) == I365_CS_DETECT
)
276 if (status
& I365_CS_WRPROT
)
278 if (status
& I365_CS_READY
)
280 if (status
& I365_CS_POWERON
)
283 sense
= exca_read_byte(slot
, CARD_VOLTAGE_SENSE
);
285 case VCC_3VORXV_CAPABLE
:
286 val
|= SS_3VCARD
| SS_XVCARD
;
304 static inline u_char
get_Vcc_value(uint8_t voltage
)
318 static inline u_char
get_Vpp_value(uint8_t power
, u_char Vcc
)
320 if ((power
& 0x03) == 0x01 || (power
& 0x03) == 0x02)
326 static int pccard_get_socket(struct pcmcia_socket
*sock
, socket_state_t
*state
)
329 uint8_t power
, voltage
, control
, cscint
;
331 if (sock
== NULL
|| sock
->sock
>= CARD_MAX_SLOTS
|| state
== NULL
)
336 power
= exca_read_byte(slot
, I365_POWER
);
337 voltage
= exca_read_byte(slot
, CARD_VOLTAGE_SELECT
);
339 state
->Vcc
= get_Vcc_value(voltage
);
340 state
->Vpp
= get_Vpp_value(power
, state
->Vcc
);
343 if (power
& POWER_ENABLE
)
344 state
->flags
|= SS_PWR_AUTO
;
345 if (power
& I365_PWR_OUT
)
346 state
->flags
|= SS_OUTPUT_ENA
;
348 control
= exca_read_byte(slot
, I365_INTCTL
);
349 if (control
& I365_PC_IOCARD
)
350 state
->flags
|= SS_IOCARD
;
351 if (!(control
& I365_PC_RESET
))
352 state
->flags
|= SS_RESET
;
354 cscint
= exca_read_byte(slot
, I365_CSCINT
);
356 if (state
->flags
& SS_IOCARD
) {
357 if (cscint
& I365_CSC_STSCHG
)
358 state
->flags
|= SS_STSCHG
;
360 if (cscint
& I365_CSC_BVD1
)
361 state
->csc_mask
|= SS_BATDEAD
;
362 if (cscint
& I365_CSC_BVD2
)
363 state
->csc_mask
|= SS_BATWARN
;
365 if (cscint
& I365_CSC_READY
)
366 state
->csc_mask
|= SS_READY
;
367 if (cscint
& I365_CSC_DETECT
)
368 state
->csc_mask
|= SS_DETECT
;
373 static inline uint8_t set_Vcc_value(u_char Vcc
)
382 /* Small voltage is chosen for safety. */
386 static int pccard_set_socket(struct pcmcia_socket
*sock
, socket_state_t
*state
)
388 vrc4171_socket_t
*socket
;
390 uint8_t voltage
, power
, control
, cscint
;
392 if (sock
== NULL
|| sock
->sock
>= CARD_MAX_SLOTS
||
393 (state
->Vpp
!= state
->Vcc
&& state
->Vpp
!= 0) ||
394 (state
->Vcc
!= 50 && state
->Vcc
!= 33 && state
->Vcc
!= 0))
398 socket
= &vrc4171_sockets
[slot
];
400 spin_lock_irq(&sock
->lock
);
402 voltage
= set_Vcc_value(state
->Vcc
);
403 exca_write_byte(slot
, CARD_VOLTAGE_SELECT
, voltage
);
405 power
= POWER_ENABLE
;
406 if (state
->Vpp
== state
->Vcc
)
407 power
|= VPP_GET_VCC
;
408 if (state
->flags
& SS_OUTPUT_ENA
)
409 power
|= I365_PWR_OUT
;
410 exca_write_byte(slot
, I365_POWER
, power
);
413 if (state
->io_irq
!= 0)
414 control
|= socket
->io_irq
;
415 if (state
->flags
& SS_IOCARD
)
416 control
|= I365_PC_IOCARD
;
417 if (state
->flags
& SS_RESET
)
418 control
&= ~I365_PC_RESET
;
420 control
|= I365_PC_RESET
;
421 exca_write_byte(slot
, I365_INTCTL
, control
);
424 exca_write_byte(slot
, I365_CSCINT
, cscint
);
425 exca_read_byte(slot
, I365_CSC
); /* clear CardStatus change */
426 if (state
->csc_mask
!= 0)
427 cscint
|= socket
->csc_irq
<< 8;
428 if (state
->flags
& SS_IOCARD
) {
429 if (state
->csc_mask
& SS_STSCHG
)
430 cscint
|= I365_CSC_STSCHG
;
432 if (state
->csc_mask
& SS_BATDEAD
)
433 cscint
|= I365_CSC_BVD1
;
434 if (state
->csc_mask
& SS_BATWARN
)
435 cscint
|= I365_CSC_BVD2
;
437 if (state
->csc_mask
& SS_READY
)
438 cscint
|= I365_CSC_READY
;
439 if (state
->csc_mask
& SS_DETECT
)
440 cscint
|= I365_CSC_DETECT
;
441 exca_write_byte(slot
, I365_CSCINT
, cscint
);
443 spin_unlock_irq(&sock
->lock
);
448 static int pccard_set_io_map(struct pcmcia_socket
*sock
, struct pccard_io_map
*io
)
451 uint8_t ioctl
, addrwin
;
454 if (sock
== NULL
|| sock
->sock
>= CARD_MAX_SLOTS
||
455 io
== NULL
|| io
->map
>= IO_MAX_MAPS
||
456 io
->start
> 0xffff || io
->stop
> 0xffff || io
->start
> io
->stop
)
462 addrwin
= exca_read_byte(slot
, I365_ADDRWIN
);
463 if (addrwin
& I365_ENA_IO(map
)) {
464 addrwin
&= ~I365_ENA_IO(map
);
465 exca_write_byte(slot
, I365_ADDRWIN
, addrwin
);
468 exca_write_word(slot
, I365_IO(map
)+I365_W_START
, io
->start
);
469 exca_write_word(slot
, I365_IO(map
)+I365_W_STOP
, io
->stop
);
473 ioctl
|= I365_IOCTL_WAIT(map
);
474 if (io
->flags
& MAP_16BIT
)
475 ioctl
|= I365_IOCTL_16BIT(map
);
476 if (io
->flags
& MAP_AUTOSZ
)
477 ioctl
|= I365_IOCTL_IOCS16(map
);
478 if (io
->flags
& MAP_0WS
)
479 ioctl
|= I365_IOCTL_0WS(map
);
480 exca_write_byte(slot
, I365_IOCTL
, ioctl
);
482 if (io
->flags
& MAP_ACTIVE
) {
483 addrwin
|= I365_ENA_IO(map
);
484 exca_write_byte(slot
, I365_ADDRWIN
, addrwin
);
490 static int pccard_set_mem_map(struct pcmcia_socket
*sock
, struct pccard_mem_map
*mem
)
493 uint16_t start
, stop
, offset
;
497 if (sock
== NULL
|| sock
->sock
>= CARD_MAX_SLOTS
||
498 mem
== NULL
|| mem
->map
>= MEM_MAX_MAPS
||
499 mem
->res
->start
< CARD_MEM_START
|| mem
->res
->start
> CARD_MEM_END
||
500 mem
->res
->end
< CARD_MEM_START
|| mem
->res
->end
> CARD_MEM_END
||
501 mem
->res
->start
> mem
->res
->end
||
502 mem
->card_start
> CARD_MAX_MEM_OFFSET
||
503 mem
->speed
> CARD_MAX_MEM_SPEED
)
509 addrwin
= exca_read_byte(slot
, I365_ADDRWIN
);
510 if (addrwin
& I365_ENA_MEM(map
)) {
511 addrwin
&= ~I365_ENA_MEM(map
);
512 exca_write_byte(slot
, I365_ADDRWIN
, addrwin
);
515 start
= (mem
->res
->start
>> 12) & 0x3fff;
516 if (mem
->flags
& MAP_16BIT
)
517 start
|= I365_MEM_16BIT
;
518 exca_write_word(slot
, I365_MEM(map
)+I365_W_START
, start
);
520 stop
= (mem
->res
->end
>> 12) & 0x3fff;
521 switch (mem
->speed
) {
525 stop
|= I365_MEM_WS0
;
528 stop
|= I365_MEM_WS1
;
531 stop
|= I365_MEM_WS0
| I365_MEM_WS1
;
534 exca_write_word(slot
, I365_MEM(map
)+I365_W_STOP
, stop
);
536 offset
= (mem
->card_start
>> 12) & 0x3fff;
537 if (mem
->flags
& MAP_ATTRIB
)
538 offset
|= I365_MEM_REG
;
539 if (mem
->flags
& MAP_WRPROT
)
540 offset
|= I365_MEM_WRPROT
;
541 exca_write_word(slot
, I365_MEM(map
)+I365_W_OFF
, offset
);
543 if (mem
->flags
& MAP_ACTIVE
) {
544 addrwin
|= I365_ENA_MEM(map
);
545 exca_write_byte(slot
, I365_ADDRWIN
, addrwin
);
551 static struct pccard_operations vrc4171_pccard_operations
= {
553 .get_status
= pccard_get_status
,
554 .get_socket
= pccard_get_socket
,
555 .set_socket
= pccard_set_socket
,
556 .set_io_map
= pccard_set_io_map
,
557 .set_mem_map
= pccard_set_mem_map
,
560 static inline unsigned int get_events(int slot
)
562 unsigned int events
= 0;
565 status
= exca_read_byte(slot
, I365_STATUS
);
566 csc
= exca_read_byte(slot
, I365_CSC
);
568 if (exca_read_byte(slot
, I365_INTCTL
) & I365_PC_IOCARD
) {
569 if ((csc
& I365_CSC_STSCHG
) && (status
& I365_CS_STSCHG
))
572 if (csc
& (I365_CSC_BVD1
| I365_CSC_BVD2
)) {
573 if (!(status
& I365_CS_BVD1
))
574 events
|= SS_BATDEAD
;
575 else if ((status
& (I365_CS_BVD1
| I365_CS_BVD2
)) == I365_CS_BVD1
)
576 events
|= SS_BATWARN
;
579 if ((csc
& I365_CSC_READY
) && (status
& I365_CS_READY
))
581 if ((csc
& I365_CSC_DETECT
) && ((status
& I365_CS_DETECT
) == I365_CS_DETECT
))
587 static irqreturn_t
pccard_interrupt(int irq
, void *dev_id
, struct pt_regs
*regs
)
589 vrc4171_socket_t
*socket
;
591 irqreturn_t retval
= IRQ_NONE
;
594 status
= vrc4171_get_irq_status();
595 if (status
& IRQ_A
) {
596 socket
= &vrc4171_sockets
[CARD_SLOTA
];
597 if (socket
->slot
== SLOT_INITIALIZED
) {
598 if (status
& (1 << socket
->csc_irq
)) {
599 events
= get_events(CARD_SLOTA
);
601 pcmcia_parse_events(&socket
->pcmcia_socket
, events
);
602 retval
= IRQ_HANDLED
;
608 if (status
& IRQ_B
) {
609 socket
= &vrc4171_sockets
[CARD_SLOTB
];
610 if (socket
->slot
== SLOT_INITIALIZED
) {
611 if (status
& (1 << socket
->csc_irq
)) {
612 events
= get_events(CARD_SLOTB
);
614 pcmcia_parse_events(&socket
->pcmcia_socket
, events
);
615 retval
= IRQ_HANDLED
;
624 static inline void reserve_using_irq(int slot
)
628 irq
= exca_read_byte(slot
, I365_INTCTL
);
630 vrc4171_irq_mask
&= ~(1 << irq
);
632 irq
= exca_read_byte(slot
, I365_CSCINT
);
633 irq
= (irq
& 0xf0) >> 4;
634 vrc4171_irq_mask
&= ~(1 << irq
);
637 static int __devinit
vrc4171_add_sockets(void)
639 vrc4171_socket_t
*socket
;
642 for (slot
= 0; slot
< CARD_MAX_SLOTS
; slot
++) {
643 if (slot
== CARD_SLOTB
&& vrc4171_slotb
== SLOTB_IS_NONE
)
646 socket
= &vrc4171_sockets
[slot
];
647 if (socket
->slot
!= SLOT_PROBE
) {
650 switch (socket
->slot
) {
651 case SLOT_NOPROBE_MEM
:
652 addrwin
= exca_read_byte(slot
, I365_ADDRWIN
);
654 exca_write_byte(slot
, I365_ADDRWIN
, addrwin
);
656 case SLOT_NOPROBE_IO
:
657 addrwin
= exca_read_byte(slot
, I365_ADDRWIN
);
659 exca_write_byte(slot
, I365_ADDRWIN
, addrwin
);
665 reserve_using_irq(slot
);
669 sprintf(socket
->name
, "NEC VRC4171 Card Slot %1c", 'A' + slot
);
670 socket
->pcmcia_socket
.dev
.dev
= &vrc4171_card_device
.dev
;
671 socket
->pcmcia_socket
.ops
= &vrc4171_pccard_operations
;
672 socket
->pcmcia_socket
.owner
= THIS_MODULE
;
674 retval
= pcmcia_register_socket(&socket
->pcmcia_socket
);
678 exca_write_byte(slot
, I365_ADDRWIN
, 0);
679 exca_write_byte(slot
, GLOBAL_CONTROL
, 0);
681 socket
->slot
= SLOT_INITIALIZED
;
687 static void vrc4171_remove_sockets(void)
689 vrc4171_socket_t
*socket
;
692 for (slot
= 0; slot
< CARD_MAX_SLOTS
; slot
++) {
693 if (slot
== CARD_SLOTB
&& vrc4171_slotb
== SLOTB_IS_NONE
)
696 socket
= &vrc4171_sockets
[slot
];
697 if (socket
->slot
== SLOT_INITIALIZED
)
698 pcmcia_unregister_socket(&socket
->pcmcia_socket
);
700 socket
->slot
= SLOT_PROBE
;
704 static int __devinit
vrc4171_card_setup(char *options
)
706 if (options
== NULL
|| *options
== '\0')
709 if (strncmp(options
, "irq:", 4) == 0) {
712 irq
= simple_strtoul(options
, &options
, 0);
713 if (irq
>= 0 && irq
< NR_IRQS
)
721 if (strncmp(options
, "slota:", 6) == 0) {
723 if (*options
!= '\0') {
724 if (strncmp(options
, "memnoprobe", 10) == 0) {
725 vrc4171_sockets
[CARD_SLOTA
].slot
= SLOT_NOPROBE_MEM
;
727 } else if (strncmp(options
, "ionoprobe", 9) == 0) {
728 vrc4171_sockets
[CARD_SLOTA
].slot
= SLOT_NOPROBE_IO
;
730 } else if ( strncmp(options
, "noprobe", 7) == 0) {
731 vrc4171_sockets
[CARD_SLOTA
].slot
= SLOT_NOPROBE_ALL
;
743 if (strncmp(options
, "slotb:", 6) == 0) {
745 if (*options
!= '\0') {
746 if (strncmp(options
, "pccard", 6) == 0) {
747 vrc4171_slotb
= SLOTB_IS_PCCARD
;
749 } else if (strncmp(options
, "cf", 2) == 0) {
750 vrc4171_slotb
= SLOTB_IS_CF
;
752 } else if (strncmp(options
, "flashrom", 8) == 0) {
753 vrc4171_slotb
= SLOTB_IS_FLASHROM
;
755 } else if (strncmp(options
, "none", 4) == 0) {
756 vrc4171_slotb
= SLOTB_IS_NONE
;
764 if (strncmp(options
, "memnoprobe", 10) == 0)
765 vrc4171_sockets
[CARD_SLOTB
].slot
= SLOT_NOPROBE_MEM
;
766 if (strncmp(options
, "ionoprobe", 9) == 0)
767 vrc4171_sockets
[CARD_SLOTB
].slot
= SLOT_NOPROBE_IO
;
768 if (strncmp(options
, "noprobe", 7) == 0)
769 vrc4171_sockets
[CARD_SLOTB
].slot
= SLOT_NOPROBE_ALL
;
776 __setup("vrc4171_card=", vrc4171_card_setup
);
778 static struct device_driver vrc4171_card_driver
= {
779 .name
= vrc4171_card_name
,
780 .bus
= &platform_bus_type
,
781 .suspend
= pcmcia_socket_dev_suspend
,
782 .resume
= pcmcia_socket_dev_resume
,
785 static int __devinit
vrc4171_card_init(void)
789 retval
= driver_register(&vrc4171_card_driver
);
793 retval
= platform_device_register(&vrc4171_card_device
);
795 driver_unregister(&vrc4171_card_driver
);
799 vrc4171_set_multifunction_pin(vrc4171_slotb
);
801 retval
= vrc4171_add_sockets();
803 retval
= request_irq(vrc4171_irq
, pccard_interrupt
, SA_SHIRQ
,
804 vrc4171_card_name
, vrc4171_sockets
);
807 vrc4171_remove_sockets();
808 platform_device_unregister(&vrc4171_card_device
);
809 driver_unregister(&vrc4171_card_driver
);
813 printk(KERN_INFO
"%s, connected to IRQ %d\n", vrc4171_card_driver
.name
, vrc4171_irq
);
818 static void __devexit
vrc4171_card_exit(void)
820 free_irq(vrc4171_irq
, vrc4171_sockets
);
821 vrc4171_remove_sockets();
822 platform_device_unregister(&vrc4171_card_device
);
823 driver_unregister(&vrc4171_card_driver
);
826 module_init(vrc4171_card_init
);
827 module_exit(vrc4171_card_exit
);