root/drivers/parport/parport_amiga.c

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

DEFINITIONS

This source file includes following definitions.
  1. amiga_write_data
  2. amiga_read_data
  3. control_amiga_to_pc
  4. amiga_write_control
  5. amiga_read_control
  6. amiga_frob_control
  7. status_amiga_to_pc
  8. amiga_read_status
  9. amiga_enable_irq
  10. amiga_disable_irq
  11. amiga_data_forward
  12. amiga_data_reverse
  13. amiga_init_state
  14. amiga_save_state
  15. amiga_restore_state
  16. amiga_parallel_probe
  17. amiga_parallel_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* Low-level parallel port routines for the Amiga built-in port
   3  *
   4  * Author: Joerg Dorchain <joerg@dorchain.net>
   5  *
   6  * This is a complete rewrite of the code, but based heaviy upon the old
   7  * lp_intern. code.
   8  *
   9  * The built-in Amiga parallel port provides one port at a fixed address
  10  * with 8 bidirectional data lines (D0 - D7) and 3 bidirectional status
  11  * lines (BUSY, POUT, SEL), 1 output control line /STROBE (raised automatically
  12  * in hardware when the data register is accessed), and 1 input control line
  13  * /ACK, able to cause an interrupt, but both not directly settable by
  14  * software.
  15  */
  16 
  17 #include <linux/module.h>
  18 #include <linux/init.h>
  19 #include <linux/parport.h>
  20 #include <linux/ioport.h>
  21 #include <linux/interrupt.h>
  22 #include <linux/platform_device.h>
  23 
  24 #include <asm/setup.h>
  25 #include <asm/amigahw.h>
  26 #include <asm/irq.h>
  27 #include <asm/io.h>
  28 #include <asm/amigaints.h>
  29 
  30 #undef DEBUG
  31 #ifdef DEBUG
  32 #define DPRINTK printk
  33 #else
  34 #define DPRINTK(x...)   do { } while (0)
  35 #endif
  36 
  37 
  38 static void amiga_write_data(struct parport *p, unsigned char data)
  39 {
  40         DPRINTK(KERN_DEBUG "write_data %c\n",data);
  41         /* Triggers also /STROBE. This behavior cannot be changed */
  42         ciaa.prb = data;
  43         mb();
  44 }
  45 
  46 static unsigned char amiga_read_data(struct parport *p)
  47 {
  48         /* Triggers also /STROBE. This behavior cannot be changed */
  49         return ciaa.prb;
  50 }
  51 
  52 static unsigned char control_amiga_to_pc(unsigned char control)
  53 {
  54         return PARPORT_CONTROL_SELECT |
  55               PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_STROBE;
  56         /* fake value: interrupt enable, select in, no reset,
  57         no autolf, no strobe - seems to be closest the wiring diagram */
  58 }
  59 
  60 static void amiga_write_control(struct parport *p, unsigned char control)
  61 {
  62         DPRINTK(KERN_DEBUG "write_control %02x\n",control);
  63         /* No implementation possible */
  64 }
  65         
  66 static unsigned char amiga_read_control( struct parport *p)
  67 {
  68         DPRINTK(KERN_DEBUG "read_control \n");
  69         return control_amiga_to_pc(0);
  70 }
  71 
  72 static unsigned char amiga_frob_control( struct parport *p, unsigned char mask, unsigned char val)
  73 {
  74         unsigned char old;
  75 
  76         DPRINTK(KERN_DEBUG "frob_control mask %02x, value %02x\n",mask,val);
  77         old = amiga_read_control(p);
  78         amiga_write_control(p, (old & ~mask) ^ val);
  79         return old;
  80 }
  81 
  82 static unsigned char status_amiga_to_pc(unsigned char status)
  83 {
  84         unsigned char ret = PARPORT_STATUS_BUSY | PARPORT_STATUS_ACK | PARPORT_STATUS_ERROR;
  85 
  86         if (status & 1) /* Busy */
  87                 ret &= ~PARPORT_STATUS_BUSY;
  88         if (status & 2) /* PaperOut */
  89                 ret |= PARPORT_STATUS_PAPEROUT;
  90         if (status & 4) /* Selected */
  91                 ret |= PARPORT_STATUS_SELECT;
  92         /* the rest is not connected or handled autonomously in hardware */
  93 
  94         return ret;
  95 }
  96 
  97 static unsigned char amiga_read_status(struct parport *p)
  98 {
  99         unsigned char status;
 100 
 101         status = status_amiga_to_pc(ciab.pra & 7);
 102         DPRINTK(KERN_DEBUG "read_status %02x\n", status);
 103         return status;
 104 }
 105 
 106 static void amiga_enable_irq(struct parport *p)
 107 {
 108         enable_irq(IRQ_AMIGA_CIAA_FLG);
 109 }
 110 
 111 static void amiga_disable_irq(struct parport *p)
 112 {
 113         disable_irq(IRQ_AMIGA_CIAA_FLG);
 114 }
 115 
 116 static void amiga_data_forward(struct parport *p)
 117 {
 118         DPRINTK(KERN_DEBUG "forward\n");
 119         ciaa.ddrb = 0xff; /* all pins output */
 120         mb();
 121 }
 122 
 123 static void amiga_data_reverse(struct parport *p)
 124 {
 125         DPRINTK(KERN_DEBUG "reverse\n");
 126         ciaa.ddrb = 0; /* all pins input */
 127         mb();
 128 }
 129 
 130 static void amiga_init_state(struct pardevice *dev, struct parport_state *s)
 131 {
 132         s->u.amiga.data = 0;
 133         s->u.amiga.datadir = 255;
 134         s->u.amiga.status = 0;
 135         s->u.amiga.statusdir = 0;
 136 }
 137 
 138 static void amiga_save_state(struct parport *p, struct parport_state *s)
 139 {
 140         mb();
 141         s->u.amiga.data = ciaa.prb;
 142         s->u.amiga.datadir = ciaa.ddrb;
 143         s->u.amiga.status = ciab.pra & 7;
 144         s->u.amiga.statusdir = ciab.ddra & 7;
 145         mb();
 146 }
 147 
 148 static void amiga_restore_state(struct parport *p, struct parport_state *s)
 149 {
 150         mb();
 151         ciaa.prb = s->u.amiga.data;
 152         ciaa.ddrb = s->u.amiga.datadir;
 153         ciab.pra |= (ciab.pra & 0xf8) | s->u.amiga.status;
 154         ciab.ddra |= (ciab.ddra & 0xf8) | s->u.amiga.statusdir;
 155         mb();
 156 }
 157 
 158 static struct parport_operations pp_amiga_ops = {
 159         .write_data     = amiga_write_data,
 160         .read_data      = amiga_read_data,
 161 
 162         .write_control  = amiga_write_control,
 163         .read_control   = amiga_read_control,
 164         .frob_control   = amiga_frob_control,
 165 
 166         .read_status    = amiga_read_status,
 167 
 168         .enable_irq     = amiga_enable_irq,
 169         .disable_irq    = amiga_disable_irq,
 170 
 171         .data_forward   = amiga_data_forward,
 172         .data_reverse   = amiga_data_reverse,
 173 
 174         .init_state     = amiga_init_state,
 175         .save_state     = amiga_save_state,
 176         .restore_state  = amiga_restore_state,
 177 
 178         .epp_write_data = parport_ieee1284_epp_write_data,
 179         .epp_read_data  = parport_ieee1284_epp_read_data,
 180         .epp_write_addr = parport_ieee1284_epp_write_addr,
 181         .epp_read_addr  = parport_ieee1284_epp_read_addr,
 182 
 183         .ecp_write_data = parport_ieee1284_ecp_write_data,
 184         .ecp_read_data  = parport_ieee1284_ecp_read_data,
 185         .ecp_write_addr = parport_ieee1284_ecp_write_addr,
 186 
 187         .compat_write_data      = parport_ieee1284_write_compat,
 188         .nibble_read_data       = parport_ieee1284_read_nibble,
 189         .byte_read_data         = parport_ieee1284_read_byte,
 190 
 191         .owner          = THIS_MODULE,
 192 };
 193 
 194 /* ----------- Initialisation code --------------------------------- */
 195 
 196 static int __init amiga_parallel_probe(struct platform_device *pdev)
 197 {
 198         struct parport *p;
 199         int err;
 200 
 201         ciaa.ddrb = 0xff;
 202         ciab.ddra &= 0xf8;
 203         mb();
 204 
 205         p = parport_register_port((unsigned long)&ciaa.prb, IRQ_AMIGA_CIAA_FLG,
 206                                    PARPORT_DMA_NONE, &pp_amiga_ops);
 207         if (!p)
 208                 return -EBUSY;
 209 
 210         err = request_irq(IRQ_AMIGA_CIAA_FLG, parport_irq_handler, 0, p->name,
 211                           p);
 212         if (err)
 213                 goto out_irq;
 214 
 215         printk(KERN_INFO "%s: Amiga built-in port using irq\n", p->name);
 216         /* XXX: set operating mode */
 217         parport_announce_port(p);
 218 
 219         platform_set_drvdata(pdev, p);
 220 
 221         return 0;
 222 
 223 out_irq:
 224         parport_put_port(p);
 225         return err;
 226 }
 227 
 228 static int __exit amiga_parallel_remove(struct platform_device *pdev)
 229 {
 230         struct parport *port = platform_get_drvdata(pdev);
 231 
 232         parport_remove_port(port);
 233         if (port->irq != PARPORT_IRQ_NONE)
 234                 free_irq(IRQ_AMIGA_CIAA_FLG, port);
 235         parport_put_port(port);
 236         return 0;
 237 }
 238 
 239 static struct platform_driver amiga_parallel_driver = {
 240         .remove = __exit_p(amiga_parallel_remove),
 241         .driver   = {
 242                 .name   = "amiga-parallel",
 243         },
 244 };
 245 
 246 module_platform_driver_probe(amiga_parallel_driver, amiga_parallel_probe);
 247 
 248 MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
 249 MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port");
 250 MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port");
 251 MODULE_LICENSE("GPL");
 252 MODULE_ALIAS("platform:amiga-parallel");

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