root/drivers/parport/parport_mfc3.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. DPRINTK
  2. mfc3_write_data
  3. mfc3_read_data
  4. control_pc_to_mfc3
  5. control_mfc3_to_pc
  6. mfc3_write_control
  7. mfc3_read_control
  8. mfc3_frob_control
  9. status_mfc3_to_pc
  10. mfc3_read_status
  11. mfc3_interrupt
  12. mfc3_enable_irq
  13. mfc3_disable_irq
  14. mfc3_data_forward
  15. mfc3_data_reverse
  16. mfc3_init_state
  17. mfc3_save_state
  18. mfc3_restore_state
  19. parport_mfc3_init
  20. parport_mfc3_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* Low-level parallel port routines for the Multiface 3 card
   3  *
   4  * Author: Joerg Dorchain <joerg@dorchain.net>
   5  *
   6  * (C) The elitist m68k Users(TM)
   7  *
   8  * based on the existing parport_amiga and lp_mfc
   9  *
  10  *
  11  * From the MFC3 documentation:
  12  * 
  13  * Miscellaneous PIA Details
  14  * -------------------------
  15  * 
  16  *      The two open-drain interrupt outputs /IRQA and /IRQB are routed to
  17  * /INT2 of the Z2 bus.
  18  * 
  19  *      The CPU data bus of the PIA (D0-D7) is connected to D8-D15 on the Z2
  20  * bus. This means that any PIA registers are accessed at even addresses.
  21  * 
  22  * Centronics Pin Connections for the PIA
  23  * --------------------------------------
  24  * 
  25  *      The following table shows the connections between the PIA and the
  26  * Centronics interface connector. These connections implement a single, but
  27  * very complete, Centronics type interface. The Pin column gives the pin
  28  * numbers of the PIA. The Centronics pin numbers can be found in the section
  29  * "Parallel Connectors".
  30  * 
  31  * 
  32  *    Pin | PIA | Dir | Centronics Names
  33  * -------+-----+-----+---------------------------------------------------------
  34  *     19 | CB2 | --> | /STROBE (aka /DRDY)
  35  *  10-17 | PBx | <-> | DATA0 - DATA7
  36  *     18 | CB1 | <-- | /ACK
  37  *     40 | CA1 | <-- | BUSY
  38  *      3 | PA1 | <-- | PAPER-OUT (aka POUT)
  39  *      4 | PA2 | <-- | SELECTED (aka SEL)
  40  *      9 | PA7 | --> | /INIT (aka /RESET or /INPUT-PRIME)
  41  *      6 | PA4 | <-- | /ERROR (aka /FAULT)
  42  *      7 | PA5 | --> | DIR (aka /SELECT-IN)
  43  *      8 | PA6 | --> | /AUTO-FEED-XT
  44  *     39 | CA2 | --> | open
  45  *      5 | PA3 | <-- | /ACK (same as CB1!)
  46  *      2 | PA0 | <-- | BUSY (same as CA1!)
  47  * -------+-----+-----+---------------------------------------------------------
  48  * 
  49  * Should be enough to understand some of the driver.
  50  *
  51  * Per convention for normal use the port registers are visible.
  52  * If you need the data direction registers, restore the value in the
  53  * control register.
  54  */
  55 
  56 #include "multiface.h"
  57 #include <linux/module.h>
  58 #include <linux/init.h>
  59 #include <linux/parport.h>
  60 #include <linux/delay.h>
  61 #include <linux/mc6821.h>
  62 #include <linux/zorro.h>
  63 #include <linux/interrupt.h>
  64 #include <asm/setup.h>
  65 #include <asm/amigahw.h>
  66 #include <asm/irq.h>
  67 #include <asm/amigaints.h>
  68 
  69 /* Maximum Number of Cards supported */
  70 #define MAX_MFC 5
  71 
  72 #undef DEBUG
  73 #ifdef DEBUG
  74 #define DPRINTK printk
  75 #else
  76 static inline int DPRINTK(void *nothing, ...) {return 0;}
  77 #endif
  78 
  79 static struct parport *this_port[MAX_MFC] = {NULL, };
  80 static volatile int dummy; /* for trigger readds */
  81 
  82 #define pia(dev) ((struct pia *)(dev->base))
  83 static struct parport_operations pp_mfc3_ops;
  84 
  85 static void mfc3_write_data(struct parport *p, unsigned char data)
  86 {
  87 DPRINTK(KERN_DEBUG "write_data %c\n",data);
  88 
  89         dummy = pia(p)->pprb; /* clears irq bit */
  90         /* Triggers also /STROBE.*/
  91         pia(p)->pprb = data;
  92 }
  93 
  94 static unsigned char mfc3_read_data(struct parport *p)
  95 {
  96         /* clears interrupt bit. Triggers also /STROBE. */
  97         return pia(p)->pprb;
  98 }
  99 
 100 static unsigned char control_pc_to_mfc3(unsigned char control)
 101 {
 102         unsigned char ret = 32|64;
 103 
 104         if (control & PARPORT_CONTROL_SELECT) /* XXX: What is SELECP? */
 105                 ret &= ~32; /* /SELECT_IN */
 106         if (control & PARPORT_CONTROL_INIT) /* INITP */
 107                 ret |= 128;
 108         if (control & PARPORT_CONTROL_AUTOFD) /* AUTOLF */
 109                 ret &= ~64;
 110         if (control & PARPORT_CONTROL_STROBE) /* Strobe */
 111                 /* Handled directly by hardware */;
 112         return ret;
 113 }
 114 
 115 static unsigned char control_mfc3_to_pc(unsigned char control)
 116 {
 117         unsigned char ret = PARPORT_CONTROL_STROBE 
 118                           | PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_SELECT;
 119 
 120         if (control & 128) /* /INITP */
 121                 ret |= PARPORT_CONTROL_INIT;
 122         if (control & 64) /* /AUTOLF */
 123                 ret &= ~PARPORT_CONTROL_AUTOFD;
 124         if (control & 32) /* /SELECT_IN */
 125                 ret &= ~PARPORT_CONTROL_SELECT;
 126         return ret;
 127 }
 128 
 129 static void mfc3_write_control(struct parport *p, unsigned char control)
 130 {
 131 DPRINTK(KERN_DEBUG "write_control %02x\n",control);
 132         pia(p)->ppra = (pia(p)->ppra & 0x1f) | control_pc_to_mfc3(control);
 133 }
 134         
 135 static unsigned char mfc3_read_control( struct parport *p)
 136 {
 137 DPRINTK(KERN_DEBUG "read_control \n");
 138         return control_mfc3_to_pc(pia(p)->ppra & 0xe0);
 139 }
 140 
 141 static unsigned char mfc3_frob_control( struct parport *p, unsigned char mask, unsigned char val)
 142 {
 143         unsigned char old;
 144 
 145 DPRINTK(KERN_DEBUG "frob_control mask %02x, value %02x\n",mask,val);
 146         old = mfc3_read_control(p);
 147         mfc3_write_control(p, (old & ~mask) ^ val);
 148         return old;
 149 }
 150 
 151 static unsigned char status_mfc3_to_pc(unsigned char status)
 152 {
 153         unsigned char ret = PARPORT_STATUS_BUSY;
 154 
 155         if (status & 1) /* Busy */
 156                 ret &= ~PARPORT_STATUS_BUSY;
 157         if (status & 2) /* PaperOut */
 158                 ret |= PARPORT_STATUS_PAPEROUT;
 159         if (status & 4) /* Selected */
 160                 ret |= PARPORT_STATUS_SELECT;
 161         if (status & 8) /* Ack */
 162                 ret |= PARPORT_STATUS_ACK;
 163         if (status & 16) /* /ERROR */
 164                 ret |= PARPORT_STATUS_ERROR;
 165 
 166         return ret;
 167 }
 168 
 169 static unsigned char mfc3_read_status(struct parport *p)
 170 {
 171         unsigned char status;
 172 
 173         status = status_mfc3_to_pc(pia(p)->ppra & 0x1f);
 174 DPRINTK(KERN_DEBUG "read_status %02x\n", status);
 175         return status;
 176 }
 177 
 178 static int use_cnt;
 179 
 180 static irqreturn_t mfc3_interrupt(int irq, void *dev_id)
 181 {
 182         int i;
 183 
 184         for( i = 0; i < MAX_MFC; i++)
 185                 if (this_port[i] != NULL)
 186                         if (pia(this_port[i])->crb & 128) { /* Board caused interrupt */
 187                                 dummy = pia(this_port[i])->pprb; /* clear irq bit */
 188                                 parport_generic_irq(this_port[i]);
 189                         }
 190         return IRQ_HANDLED;
 191 }
 192 
 193 static void mfc3_enable_irq(struct parport *p)
 194 {
 195         pia(p)->crb |= PIA_C1_ENABLE_IRQ;
 196 }
 197 
 198 static void mfc3_disable_irq(struct parport *p)
 199 {
 200         pia(p)->crb &= ~PIA_C1_ENABLE_IRQ;
 201 }
 202 
 203 static void mfc3_data_forward(struct parport *p)
 204 {
 205         DPRINTK(KERN_DEBUG "forward\n");
 206         pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */
 207         pia(p)->pddrb = 255; /* all pins output */
 208         pia(p)->crb |= PIA_DDR; /* make data register visible - default */
 209 }
 210 
 211 static void mfc3_data_reverse(struct parport *p)
 212 {
 213         DPRINTK(KERN_DEBUG "reverse\n");
 214         pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */
 215         pia(p)->pddrb = 0; /* all pins input */
 216         pia(p)->crb |= PIA_DDR; /* make data register visible - default */
 217 }
 218 
 219 static void mfc3_init_state(struct pardevice *dev, struct parport_state *s)
 220 {
 221         s->u.amiga.data = 0;
 222         s->u.amiga.datadir = 255;
 223         s->u.amiga.status = 0;
 224         s->u.amiga.statusdir = 0xe0;
 225 }
 226 
 227 static void mfc3_save_state(struct parport *p, struct parport_state *s)
 228 {
 229         s->u.amiga.data = pia(p)->pprb;
 230         pia(p)->crb &= ~PIA_DDR;
 231         s->u.amiga.datadir = pia(p)->pddrb;
 232         pia(p)->crb |= PIA_DDR;
 233         s->u.amiga.status = pia(p)->ppra;
 234         pia(p)->cra &= ~PIA_DDR;
 235         s->u.amiga.statusdir = pia(p)->pddrb;
 236         pia(p)->cra |= PIA_DDR;
 237 }
 238 
 239 static void mfc3_restore_state(struct parport *p, struct parport_state *s)
 240 {
 241         pia(p)->pprb = s->u.amiga.data;
 242         pia(p)->crb &= ~PIA_DDR;
 243         pia(p)->pddrb = s->u.amiga.datadir;
 244         pia(p)->crb |= PIA_DDR;
 245         pia(p)->ppra = s->u.amiga.status;
 246         pia(p)->cra &= ~PIA_DDR;
 247         pia(p)->pddrb = s->u.amiga.statusdir;
 248         pia(p)->cra |= PIA_DDR;
 249 }
 250 
 251 static struct parport_operations pp_mfc3_ops = {
 252         .write_data     = mfc3_write_data,
 253         .read_data      = mfc3_read_data,
 254 
 255         .write_control  = mfc3_write_control,
 256         .read_control   = mfc3_read_control,
 257         .frob_control   = mfc3_frob_control,
 258 
 259         .read_status    = mfc3_read_status,
 260 
 261         .enable_irq     = mfc3_enable_irq,
 262         .disable_irq    = mfc3_disable_irq,
 263 
 264         .data_forward   = mfc3_data_forward, 
 265         .data_reverse   = mfc3_data_reverse, 
 266 
 267         .init_state     = mfc3_init_state,
 268         .save_state     = mfc3_save_state,
 269         .restore_state  = mfc3_restore_state,
 270 
 271         .epp_write_data = parport_ieee1284_epp_write_data,
 272         .epp_read_data  = parport_ieee1284_epp_read_data,
 273         .epp_write_addr = parport_ieee1284_epp_write_addr,
 274         .epp_read_addr  = parport_ieee1284_epp_read_addr,
 275 
 276         .ecp_write_data = parport_ieee1284_ecp_write_data,
 277         .ecp_read_data  = parport_ieee1284_ecp_read_data,
 278         .ecp_write_addr = parport_ieee1284_ecp_write_addr,
 279 
 280         .compat_write_data      = parport_ieee1284_write_compat,
 281         .nibble_read_data       = parport_ieee1284_read_nibble,
 282         .byte_read_data         = parport_ieee1284_read_byte,
 283 
 284         .owner          = THIS_MODULE,
 285 };
 286 
 287 /* ----------- Initialisation code --------------------------------- */
 288 
 289 static int __init parport_mfc3_init(void)
 290 {
 291         struct parport *p;
 292         int pias = 0;
 293         struct pia *pp;
 294         struct zorro_dev *z = NULL;
 295 
 296         if (!MACH_IS_AMIGA)
 297                 return -ENODEV;
 298 
 299         while ((z = zorro_find_device(ZORRO_PROD_BSC_MULTIFACE_III, z))) {
 300                 unsigned long piabase = z->resource.start+PIABASE;
 301                 if (!request_mem_region(piabase, sizeof(struct pia), "PIA"))
 302                         continue;
 303 
 304                 pp = ZTWO_VADDR(piabase);
 305                 pp->crb = 0;
 306                 pp->pddrb = 255; /* all data pins output */
 307                 pp->crb = PIA_DDR|32|8;
 308                 dummy = pp->pddrb; /* reading clears interrupt */
 309                 pp->cra = 0;
 310                 pp->pddra = 0xe0; /* /RESET,  /DIR ,/AUTO-FEED output */
 311                 pp->cra = PIA_DDR;
 312                 pp->ppra = 0; /* reset printer */
 313                 udelay(10);
 314                 pp->ppra = 128;
 315                 p = parport_register_port((unsigned long)pp, IRQ_AMIGA_PORTS,
 316                                           PARPORT_DMA_NONE, &pp_mfc3_ops);
 317                 if (!p)
 318                         goto out_port;
 319 
 320                 if (p->irq != PARPORT_IRQ_NONE) {
 321                         if (use_cnt++ == 0)
 322                                 if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, IRQF_SHARED, p->name, &pp_mfc3_ops))
 323                                         goto out_irq;
 324                 }
 325                 p->dev = &z->dev;
 326 
 327                 this_port[pias++] = p;
 328                 printk(KERN_INFO "%s: Multiface III port using irq\n", p->name);
 329                 /* XXX: set operating mode */
 330 
 331                 p->private_data = (void *)piabase;
 332                 parport_announce_port (p);
 333 
 334                 if (pias >= MAX_MFC)
 335                         break;
 336                 continue;
 337 
 338         out_irq:
 339                 parport_put_port(p);
 340         out_port:
 341                 release_mem_region(piabase, sizeof(struct pia));
 342         }
 343 
 344         return pias ? 0 : -ENODEV;
 345 }
 346 
 347 static void __exit parport_mfc3_exit(void)
 348 {
 349         int i;
 350 
 351         for (i = 0; i < MAX_MFC; i++) {
 352                 if (!this_port[i])
 353                         continue;
 354                 parport_remove_port(this_port[i]);
 355                 if (this_port[i]->irq != PARPORT_IRQ_NONE) {
 356                         if (--use_cnt == 0) 
 357                                 free_irq(IRQ_AMIGA_PORTS, &pp_mfc3_ops);
 358                 }
 359                 release_mem_region(ZTWO_PADDR(this_port[i]->private_data), sizeof(struct pia));
 360                 parport_put_port(this_port[i]);
 361         }
 362 }
 363 
 364 
 365 MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
 366 MODULE_DESCRIPTION("Parport Driver for Multiface 3 expansion cards Parallel Port");
 367 MODULE_SUPPORTED_DEVICE("Multiface 3 Parallel Port");
 368 MODULE_LICENSE("GPL");
 369 
 370 module_init(parport_mfc3_init)
 371 module_exit(parport_mfc3_exit)

/* [<][>][^][v][top][bottom][index][help] */