109c434b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 21da177e4SLinus Torvalds /* Low-level parallel port routines for the Multiface 3 card 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Author: Joerg Dorchain <joerg@dorchain.net> 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * (C) The elitist m68k Users(TM) 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * based on the existing parport_amiga and lp_mfc 91da177e4SLinus Torvalds * 101da177e4SLinus Torvalds * 111da177e4SLinus Torvalds * From the MFC3 documentation: 121da177e4SLinus Torvalds * 131da177e4SLinus Torvalds * Miscellaneous PIA Details 141da177e4SLinus Torvalds * ------------------------- 151da177e4SLinus Torvalds * 161da177e4SLinus Torvalds * The two open-drain interrupt outputs /IRQA and /IRQB are routed to 171da177e4SLinus Torvalds * /INT2 of the Z2 bus. 181da177e4SLinus Torvalds * 191da177e4SLinus Torvalds * The CPU data bus of the PIA (D0-D7) is connected to D8-D15 on the Z2 201da177e4SLinus Torvalds * bus. This means that any PIA registers are accessed at even addresses. 211da177e4SLinus Torvalds * 221da177e4SLinus Torvalds * Centronics Pin Connections for the PIA 231da177e4SLinus Torvalds * -------------------------------------- 241da177e4SLinus Torvalds * 251da177e4SLinus Torvalds * The following table shows the connections between the PIA and the 261da177e4SLinus Torvalds * Centronics interface connector. These connections implement a single, but 271da177e4SLinus Torvalds * very complete, Centronics type interface. The Pin column gives the pin 281da177e4SLinus Torvalds * numbers of the PIA. The Centronics pin numbers can be found in the section 291da177e4SLinus Torvalds * "Parallel Connectors". 301da177e4SLinus Torvalds * 311da177e4SLinus Torvalds * 321da177e4SLinus Torvalds * Pin | PIA | Dir | Centronics Names 331da177e4SLinus Torvalds * -------+-----+-----+--------------------------------------------------------- 341da177e4SLinus Torvalds * 19 | CB2 | --> | /STROBE (aka /DRDY) 351da177e4SLinus Torvalds * 10-17 | PBx | <-> | DATA0 - DATA7 361da177e4SLinus Torvalds * 18 | CB1 | <-- | /ACK 371da177e4SLinus Torvalds * 40 | CA1 | <-- | BUSY 381da177e4SLinus Torvalds * 3 | PA1 | <-- | PAPER-OUT (aka POUT) 391da177e4SLinus Torvalds * 4 | PA2 | <-- | SELECTED (aka SEL) 401da177e4SLinus Torvalds * 9 | PA7 | --> | /INIT (aka /RESET or /INPUT-PRIME) 411da177e4SLinus Torvalds * 6 | PA4 | <-- | /ERROR (aka /FAULT) 421da177e4SLinus Torvalds * 7 | PA5 | --> | DIR (aka /SELECT-IN) 431da177e4SLinus Torvalds * 8 | PA6 | --> | /AUTO-FEED-XT 441da177e4SLinus Torvalds * 39 | CA2 | --> | open 451da177e4SLinus Torvalds * 5 | PA3 | <-- | /ACK (same as CB1!) 461da177e4SLinus Torvalds * 2 | PA0 | <-- | BUSY (same as CA1!) 471da177e4SLinus Torvalds * -------+-----+-----+--------------------------------------------------------- 481da177e4SLinus Torvalds * 491da177e4SLinus Torvalds * Should be enough to understand some of the driver. 501da177e4SLinus Torvalds * 511da177e4SLinus Torvalds * Per convention for normal use the port registers are visible. 521da177e4SLinus Torvalds * If you need the data direction registers, restore the value in the 531da177e4SLinus Torvalds * control register. 541da177e4SLinus Torvalds */ 551da177e4SLinus Torvalds 561da177e4SLinus Torvalds #include "multiface.h" 571da177e4SLinus Torvalds #include <linux/module.h> 581da177e4SLinus Torvalds #include <linux/init.h> 591da177e4SLinus Torvalds #include <linux/parport.h> 601da177e4SLinus Torvalds #include <linux/delay.h> 611da177e4SLinus Torvalds #include <linux/mc6821.h> 621da177e4SLinus Torvalds #include <linux/zorro.h> 631da177e4SLinus Torvalds #include <linux/interrupt.h> 641da177e4SLinus Torvalds #include <asm/setup.h> 651da177e4SLinus Torvalds #include <asm/amigahw.h> 661da177e4SLinus Torvalds #include <asm/irq.h> 671da177e4SLinus Torvalds #include <asm/amigaints.h> 681da177e4SLinus Torvalds 691da177e4SLinus Torvalds /* Maximum Number of Cards supported */ 701da177e4SLinus Torvalds #define MAX_MFC 5 711da177e4SLinus Torvalds 721da177e4SLinus Torvalds #undef DEBUG 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds static struct parport *this_port[MAX_MFC] = {NULL, }; 751da177e4SLinus Torvalds static volatile int dummy; /* for trigger readds */ 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds #define pia(dev) ((struct pia *)(dev->base)) 781da177e4SLinus Torvalds static struct parport_operations pp_mfc3_ops; 791da177e4SLinus Torvalds 801da177e4SLinus Torvalds static void mfc3_write_data(struct parport *p, unsigned char data) 811da177e4SLinus Torvalds { 8246aea0d4SJoe Perches pr_debug("write_data %c\n", data); 831da177e4SLinus Torvalds 841da177e4SLinus Torvalds dummy = pia(p)->pprb; /* clears irq bit */ 851da177e4SLinus Torvalds /* Triggers also /STROBE.*/ 861da177e4SLinus Torvalds pia(p)->pprb = data; 871da177e4SLinus Torvalds } 881da177e4SLinus Torvalds 891da177e4SLinus Torvalds static unsigned char mfc3_read_data(struct parport *p) 901da177e4SLinus Torvalds { 911da177e4SLinus Torvalds /* clears interrupt bit. Triggers also /STROBE. */ 921da177e4SLinus Torvalds return pia(p)->pprb; 931da177e4SLinus Torvalds } 941da177e4SLinus Torvalds 951da177e4SLinus Torvalds static unsigned char control_pc_to_mfc3(unsigned char control) 961da177e4SLinus Torvalds { 971da177e4SLinus Torvalds unsigned char ret = 32|64; 981da177e4SLinus Torvalds 991da177e4SLinus Torvalds if (control & PARPORT_CONTROL_SELECT) /* XXX: What is SELECP? */ 1001da177e4SLinus Torvalds ret &= ~32; /* /SELECT_IN */ 1011da177e4SLinus Torvalds if (control & PARPORT_CONTROL_INIT) /* INITP */ 1021da177e4SLinus Torvalds ret |= 128; 1031da177e4SLinus Torvalds if (control & PARPORT_CONTROL_AUTOFD) /* AUTOLF */ 1041da177e4SLinus Torvalds ret &= ~64; 1051da177e4SLinus Torvalds if (control & PARPORT_CONTROL_STROBE) /* Strobe */ 1061da177e4SLinus Torvalds /* Handled directly by hardware */; 1071da177e4SLinus Torvalds return ret; 1081da177e4SLinus Torvalds } 1091da177e4SLinus Torvalds 1101da177e4SLinus Torvalds static unsigned char control_mfc3_to_pc(unsigned char control) 1111da177e4SLinus Torvalds { 1121da177e4SLinus Torvalds unsigned char ret = PARPORT_CONTROL_STROBE 1131da177e4SLinus Torvalds | PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_SELECT; 1141da177e4SLinus Torvalds 1151da177e4SLinus Torvalds if (control & 128) /* /INITP */ 1161da177e4SLinus Torvalds ret |= PARPORT_CONTROL_INIT; 1171da177e4SLinus Torvalds if (control & 64) /* /AUTOLF */ 1181da177e4SLinus Torvalds ret &= ~PARPORT_CONTROL_AUTOFD; 1191da177e4SLinus Torvalds if (control & 32) /* /SELECT_IN */ 1201da177e4SLinus Torvalds ret &= ~PARPORT_CONTROL_SELECT; 1211da177e4SLinus Torvalds return ret; 1221da177e4SLinus Torvalds } 1231da177e4SLinus Torvalds 1241da177e4SLinus Torvalds static void mfc3_write_control(struct parport *p, unsigned char control) 1251da177e4SLinus Torvalds { 12646aea0d4SJoe Perches pr_debug("write_control %02x\n", control); 1271da177e4SLinus Torvalds pia(p)->ppra = (pia(p)->ppra & 0x1f) | control_pc_to_mfc3(control); 1281da177e4SLinus Torvalds } 1291da177e4SLinus Torvalds 1301da177e4SLinus Torvalds static unsigned char mfc3_read_control( struct parport *p) 1311da177e4SLinus Torvalds { 13246aea0d4SJoe Perches pr_debug("read_control\n"); 1331da177e4SLinus Torvalds return control_mfc3_to_pc(pia(p)->ppra & 0xe0); 1341da177e4SLinus Torvalds } 1351da177e4SLinus Torvalds 1361da177e4SLinus Torvalds static unsigned char mfc3_frob_control( struct parport *p, unsigned char mask, unsigned char val) 1371da177e4SLinus Torvalds { 1381da177e4SLinus Torvalds unsigned char old; 1391da177e4SLinus Torvalds 14046aea0d4SJoe Perches pr_debug("frob_control mask %02x, value %02x\n", mask, val); 1411da177e4SLinus Torvalds old = mfc3_read_control(p); 1421da177e4SLinus Torvalds mfc3_write_control(p, (old & ~mask) ^ val); 1431da177e4SLinus Torvalds return old; 1441da177e4SLinus Torvalds } 1451da177e4SLinus Torvalds 1461da177e4SLinus Torvalds static unsigned char status_mfc3_to_pc(unsigned char status) 1471da177e4SLinus Torvalds { 1481da177e4SLinus Torvalds unsigned char ret = PARPORT_STATUS_BUSY; 1491da177e4SLinus Torvalds 1501da177e4SLinus Torvalds if (status & 1) /* Busy */ 1511da177e4SLinus Torvalds ret &= ~PARPORT_STATUS_BUSY; 1521da177e4SLinus Torvalds if (status & 2) /* PaperOut */ 1531da177e4SLinus Torvalds ret |= PARPORT_STATUS_PAPEROUT; 1541da177e4SLinus Torvalds if (status & 4) /* Selected */ 1551da177e4SLinus Torvalds ret |= PARPORT_STATUS_SELECT; 1561da177e4SLinus Torvalds if (status & 8) /* Ack */ 1571da177e4SLinus Torvalds ret |= PARPORT_STATUS_ACK; 1581da177e4SLinus Torvalds if (status & 16) /* /ERROR */ 1591da177e4SLinus Torvalds ret |= PARPORT_STATUS_ERROR; 1601da177e4SLinus Torvalds 1611da177e4SLinus Torvalds return ret; 1621da177e4SLinus Torvalds } 1631da177e4SLinus Torvalds 1641da177e4SLinus Torvalds static unsigned char mfc3_read_status(struct parport *p) 1651da177e4SLinus Torvalds { 1661da177e4SLinus Torvalds unsigned char status; 1671da177e4SLinus Torvalds 1681da177e4SLinus Torvalds status = status_mfc3_to_pc(pia(p)->ppra & 0x1f); 16946aea0d4SJoe Perches pr_debug("read_status %02x\n", status); 1701da177e4SLinus Torvalds return status; 1711da177e4SLinus Torvalds } 1721da177e4SLinus Torvalds 173df4c756eSCarlos Palminha static int use_cnt; 1741da177e4SLinus Torvalds 1757d12e780SDavid Howells static irqreturn_t mfc3_interrupt(int irq, void *dev_id) 1761da177e4SLinus Torvalds { 1771da177e4SLinus Torvalds int i; 1781da177e4SLinus Torvalds 1791da177e4SLinus Torvalds for( i = 0; i < MAX_MFC; i++) 1801da177e4SLinus Torvalds if (this_port[i] != NULL) 1811da177e4SLinus Torvalds if (pia(this_port[i])->crb & 128) { /* Board caused interrupt */ 1821da177e4SLinus Torvalds dummy = pia(this_port[i])->pprb; /* clear irq bit */ 183f230d101SJeff Garzik parport_generic_irq(this_port[i]); 1841da177e4SLinus Torvalds } 1851da177e4SLinus Torvalds return IRQ_HANDLED; 1861da177e4SLinus Torvalds } 1871da177e4SLinus Torvalds 1881da177e4SLinus Torvalds static void mfc3_enable_irq(struct parport *p) 1891da177e4SLinus Torvalds { 1901da177e4SLinus Torvalds pia(p)->crb |= PIA_C1_ENABLE_IRQ; 1911da177e4SLinus Torvalds } 1921da177e4SLinus Torvalds 1931da177e4SLinus Torvalds static void mfc3_disable_irq(struct parport *p) 1941da177e4SLinus Torvalds { 1951da177e4SLinus Torvalds pia(p)->crb &= ~PIA_C1_ENABLE_IRQ; 1961da177e4SLinus Torvalds } 1971da177e4SLinus Torvalds 1981da177e4SLinus Torvalds static void mfc3_data_forward(struct parport *p) 1991da177e4SLinus Torvalds { 20046aea0d4SJoe Perches pr_debug("forward\n"); 2011da177e4SLinus Torvalds pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */ 2021da177e4SLinus Torvalds pia(p)->pddrb = 255; /* all pins output */ 2031da177e4SLinus Torvalds pia(p)->crb |= PIA_DDR; /* make data register visible - default */ 2041da177e4SLinus Torvalds } 2051da177e4SLinus Torvalds 2061da177e4SLinus Torvalds static void mfc3_data_reverse(struct parport *p) 2071da177e4SLinus Torvalds { 20846aea0d4SJoe Perches pr_debug("reverse\n"); 2091da177e4SLinus Torvalds pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */ 2101da177e4SLinus Torvalds pia(p)->pddrb = 0; /* all pins input */ 2111da177e4SLinus Torvalds pia(p)->crb |= PIA_DDR; /* make data register visible - default */ 2121da177e4SLinus Torvalds } 2131da177e4SLinus Torvalds 2141da177e4SLinus Torvalds static void mfc3_init_state(struct pardevice *dev, struct parport_state *s) 2151da177e4SLinus Torvalds { 2161da177e4SLinus Torvalds s->u.amiga.data = 0; 2171da177e4SLinus Torvalds s->u.amiga.datadir = 255; 2181da177e4SLinus Torvalds s->u.amiga.status = 0; 2191da177e4SLinus Torvalds s->u.amiga.statusdir = 0xe0; 2201da177e4SLinus Torvalds } 2211da177e4SLinus Torvalds 2221da177e4SLinus Torvalds static void mfc3_save_state(struct parport *p, struct parport_state *s) 2231da177e4SLinus Torvalds { 2241da177e4SLinus Torvalds s->u.amiga.data = pia(p)->pprb; 2251da177e4SLinus Torvalds pia(p)->crb &= ~PIA_DDR; 2261da177e4SLinus Torvalds s->u.amiga.datadir = pia(p)->pddrb; 2271da177e4SLinus Torvalds pia(p)->crb |= PIA_DDR; 2281da177e4SLinus Torvalds s->u.amiga.status = pia(p)->ppra; 2291da177e4SLinus Torvalds pia(p)->cra &= ~PIA_DDR; 2301da177e4SLinus Torvalds s->u.amiga.statusdir = pia(p)->pddrb; 2311da177e4SLinus Torvalds pia(p)->cra |= PIA_DDR; 2321da177e4SLinus Torvalds } 2331da177e4SLinus Torvalds 2341da177e4SLinus Torvalds static void mfc3_restore_state(struct parport *p, struct parport_state *s) 2351da177e4SLinus Torvalds { 2361da177e4SLinus Torvalds pia(p)->pprb = s->u.amiga.data; 2371da177e4SLinus Torvalds pia(p)->crb &= ~PIA_DDR; 2381da177e4SLinus Torvalds pia(p)->pddrb = s->u.amiga.datadir; 2391da177e4SLinus Torvalds pia(p)->crb |= PIA_DDR; 2401da177e4SLinus Torvalds pia(p)->ppra = s->u.amiga.status; 2411da177e4SLinus Torvalds pia(p)->cra &= ~PIA_DDR; 2421da177e4SLinus Torvalds pia(p)->pddrb = s->u.amiga.statusdir; 2431da177e4SLinus Torvalds pia(p)->cra |= PIA_DDR; 2441da177e4SLinus Torvalds } 2451da177e4SLinus Torvalds 2461da177e4SLinus Torvalds static struct parport_operations pp_mfc3_ops = { 2471da177e4SLinus Torvalds .write_data = mfc3_write_data, 2481da177e4SLinus Torvalds .read_data = mfc3_read_data, 2491da177e4SLinus Torvalds 2501da177e4SLinus Torvalds .write_control = mfc3_write_control, 2511da177e4SLinus Torvalds .read_control = mfc3_read_control, 2521da177e4SLinus Torvalds .frob_control = mfc3_frob_control, 2531da177e4SLinus Torvalds 2541da177e4SLinus Torvalds .read_status = mfc3_read_status, 2551da177e4SLinus Torvalds 2561da177e4SLinus Torvalds .enable_irq = mfc3_enable_irq, 2571da177e4SLinus Torvalds .disable_irq = mfc3_disable_irq, 2581da177e4SLinus Torvalds 2591da177e4SLinus Torvalds .data_forward = mfc3_data_forward, 2601da177e4SLinus Torvalds .data_reverse = mfc3_data_reverse, 2611da177e4SLinus Torvalds 2621da177e4SLinus Torvalds .init_state = mfc3_init_state, 2631da177e4SLinus Torvalds .save_state = mfc3_save_state, 2641da177e4SLinus Torvalds .restore_state = mfc3_restore_state, 2651da177e4SLinus Torvalds 2661da177e4SLinus Torvalds .epp_write_data = parport_ieee1284_epp_write_data, 2671da177e4SLinus Torvalds .epp_read_data = parport_ieee1284_epp_read_data, 2681da177e4SLinus Torvalds .epp_write_addr = parport_ieee1284_epp_write_addr, 2691da177e4SLinus Torvalds .epp_read_addr = parport_ieee1284_epp_read_addr, 2701da177e4SLinus Torvalds 2711da177e4SLinus Torvalds .ecp_write_data = parport_ieee1284_ecp_write_data, 2721da177e4SLinus Torvalds .ecp_read_data = parport_ieee1284_ecp_read_data, 2731da177e4SLinus Torvalds .ecp_write_addr = parport_ieee1284_ecp_write_addr, 2741da177e4SLinus Torvalds 2751da177e4SLinus Torvalds .compat_write_data = parport_ieee1284_write_compat, 2761da177e4SLinus Torvalds .nibble_read_data = parport_ieee1284_read_nibble, 2771da177e4SLinus Torvalds .byte_read_data = parport_ieee1284_read_byte, 2781da177e4SLinus Torvalds 2791da177e4SLinus Torvalds .owner = THIS_MODULE, 2801da177e4SLinus Torvalds }; 2811da177e4SLinus Torvalds 2821da177e4SLinus Torvalds /* ----------- Initialisation code --------------------------------- */ 2831da177e4SLinus Torvalds 2841da177e4SLinus Torvalds static int __init parport_mfc3_init(void) 2851da177e4SLinus Torvalds { 2861da177e4SLinus Torvalds struct parport *p; 2871da177e4SLinus Torvalds int pias = 0; 2881da177e4SLinus Torvalds struct pia *pp; 2891da177e4SLinus Torvalds struct zorro_dev *z = NULL; 2901da177e4SLinus Torvalds 2911da177e4SLinus Torvalds if (!MACH_IS_AMIGA) 2921da177e4SLinus Torvalds return -ENODEV; 2931da177e4SLinus Torvalds 2941da177e4SLinus Torvalds while ((z = zorro_find_device(ZORRO_PROD_BSC_MULTIFACE_III, z))) { 2951da177e4SLinus Torvalds unsigned long piabase = z->resource.start+PIABASE; 2961da177e4SLinus Torvalds if (!request_mem_region(piabase, sizeof(struct pia), "PIA")) 2971da177e4SLinus Torvalds continue; 2981da177e4SLinus Torvalds 2996112ea08SGeert Uytterhoeven pp = ZTWO_VADDR(piabase); 3001da177e4SLinus Torvalds pp->crb = 0; 3011da177e4SLinus Torvalds pp->pddrb = 255; /* all data pins output */ 3021da177e4SLinus Torvalds pp->crb = PIA_DDR|32|8; 3031da177e4SLinus Torvalds dummy = pp->pddrb; /* reading clears interrupt */ 3041da177e4SLinus Torvalds pp->cra = 0; 3051da177e4SLinus Torvalds pp->pddra = 0xe0; /* /RESET, /DIR ,/AUTO-FEED output */ 3061da177e4SLinus Torvalds pp->cra = PIA_DDR; 3071da177e4SLinus Torvalds pp->ppra = 0; /* reset printer */ 3081da177e4SLinus Torvalds udelay(10); 3091da177e4SLinus Torvalds pp->ppra = 128; 3101da177e4SLinus Torvalds p = parport_register_port((unsigned long)pp, IRQ_AMIGA_PORTS, 3111da177e4SLinus Torvalds PARPORT_DMA_NONE, &pp_mfc3_ops); 3121da177e4SLinus Torvalds if (!p) 3131da177e4SLinus Torvalds goto out_port; 3141da177e4SLinus Torvalds 3151da177e4SLinus Torvalds if (p->irq != PARPORT_IRQ_NONE) { 3161da177e4SLinus Torvalds if (use_cnt++ == 0) 317dace1453SThomas Gleixner if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, IRQF_SHARED, p->name, &pp_mfc3_ops)) 3181da177e4SLinus Torvalds goto out_irq; 3191da177e4SLinus Torvalds } 320c15a3837SDavid Brownell p->dev = &z->dev; 3211da177e4SLinus Torvalds 3221da177e4SLinus Torvalds this_port[pias++] = p; 323decf26f6SJoe Perches pr_info("%s: Multiface III port using irq\n", p->name); 3241da177e4SLinus Torvalds /* XXX: set operating mode */ 3251da177e4SLinus Torvalds 3261da177e4SLinus Torvalds p->private_data = (void *)piabase; 3271da177e4SLinus Torvalds parport_announce_port (p); 3281da177e4SLinus Torvalds 3291da177e4SLinus Torvalds if (pias >= MAX_MFC) 3301da177e4SLinus Torvalds break; 3311da177e4SLinus Torvalds continue; 3321da177e4SLinus Torvalds 3331da177e4SLinus Torvalds out_irq: 3341da177e4SLinus Torvalds parport_put_port(p); 3351da177e4SLinus Torvalds out_port: 3361da177e4SLinus Torvalds release_mem_region(piabase, sizeof(struct pia)); 3371da177e4SLinus Torvalds } 3381da177e4SLinus Torvalds 3391da177e4SLinus Torvalds return pias ? 0 : -ENODEV; 3401da177e4SLinus Torvalds } 3411da177e4SLinus Torvalds 3421da177e4SLinus Torvalds static void __exit parport_mfc3_exit(void) 3431da177e4SLinus Torvalds { 3441da177e4SLinus Torvalds int i; 3451da177e4SLinus Torvalds 3461da177e4SLinus Torvalds for (i = 0; i < MAX_MFC; i++) { 3471da177e4SLinus Torvalds if (!this_port[i]) 3481da177e4SLinus Torvalds continue; 3491da177e4SLinus Torvalds parport_remove_port(this_port[i]); 35049966baeSRoel Kluin if (this_port[i]->irq != PARPORT_IRQ_NONE) { 3511da177e4SLinus Torvalds if (--use_cnt == 0) 3521da177e4SLinus Torvalds free_irq(IRQ_AMIGA_PORTS, &pp_mfc3_ops); 3531da177e4SLinus Torvalds } 3541da177e4SLinus Torvalds release_mem_region(ZTWO_PADDR(this_port[i]->private_data), sizeof(struct pia)); 3551da177e4SLinus Torvalds parport_put_port(this_port[i]); 3561da177e4SLinus Torvalds } 3571da177e4SLinus Torvalds } 3581da177e4SLinus Torvalds 3591da177e4SLinus Torvalds 3601da177e4SLinus Torvalds MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>"); 36142b2aa86SJustin P. Mattock MODULE_DESCRIPTION("Parport Driver for Multiface 3 expansion cards Parallel Port"); 3621da177e4SLinus Torvalds MODULE_SUPPORTED_DEVICE("Multiface 3 Parallel Port"); 3631da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 3641da177e4SLinus Torvalds 3651da177e4SLinus Torvalds module_init(parport_mfc3_init) 3661da177e4SLinus Torvalds module_exit(parport_mfc3_exit) 367