Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* Low-level parallel port routines for the Atari builtin port
0003  *
0004  * Author: Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
0005  *
0006  * Based on parport_amiga.c.
0007  *
0008  * The built-in Atari parallel port provides one port at a fixed address
0009  * with 8 output data lines (D0 - D7), 1 output control line (STROBE)
0010  * and 1 input status line (BUSY) able to cause an interrupt.
0011  */
0012 
0013 #include <linux/module.h>
0014 #include <linux/init.h>
0015 #include <linux/parport.h>
0016 #include <linux/interrupt.h>
0017 #include <asm/setup.h>
0018 #include <asm/atarihw.h>
0019 #include <asm/irq.h>
0020 #include <asm/atariints.h>
0021 
0022 static struct parport *this_port;
0023 
0024 static unsigned char
0025 parport_atari_read_data(struct parport *p)
0026 {
0027     unsigned long flags;
0028     unsigned char data;
0029 
0030     local_irq_save(flags);
0031     sound_ym.rd_data_reg_sel = 15;
0032     data = sound_ym.rd_data_reg_sel;
0033     local_irq_restore(flags);
0034     return data;
0035 }
0036 
0037 static void
0038 parport_atari_write_data(struct parport *p, unsigned char data)
0039 {
0040     unsigned long flags;
0041 
0042     local_irq_save(flags);
0043     sound_ym.rd_data_reg_sel = 15;
0044     sound_ym.wd_data = data;
0045     local_irq_restore(flags);
0046 }
0047 
0048 static unsigned char
0049 parport_atari_read_control(struct parport *p)
0050 {
0051     unsigned long flags;
0052     unsigned char control = 0;
0053 
0054     local_irq_save(flags);
0055     sound_ym.rd_data_reg_sel = 14;
0056     if (!(sound_ym.rd_data_reg_sel & (1 << 5)))
0057         control = PARPORT_CONTROL_STROBE;
0058     local_irq_restore(flags);
0059     return control;
0060 }
0061 
0062 static void
0063 parport_atari_write_control(struct parport *p, unsigned char control)
0064 {
0065     unsigned long flags;
0066 
0067     local_irq_save(flags);
0068     sound_ym.rd_data_reg_sel = 14;
0069     if (control & PARPORT_CONTROL_STROBE)
0070         sound_ym.wd_data = sound_ym.rd_data_reg_sel & ~(1 << 5);
0071     else
0072         sound_ym.wd_data = sound_ym.rd_data_reg_sel | (1 << 5);
0073     local_irq_restore(flags);
0074 }
0075 
0076 static unsigned char
0077 parport_atari_frob_control(struct parport *p, unsigned char mask,
0078                unsigned char val)
0079 {
0080     unsigned char old = parport_atari_read_control(p);
0081     parport_atari_write_control(p, (old & ~mask) ^ val);
0082     return old;
0083 }
0084 
0085 static unsigned char
0086 parport_atari_read_status(struct parport *p)
0087 {
0088     return ((st_mfp.par_dt_reg & 1 ? 0 : PARPORT_STATUS_BUSY) |
0089         PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR);
0090 }
0091 
0092 static void
0093 parport_atari_init_state(struct pardevice *d, struct parport_state *s)
0094 {
0095 }
0096 
0097 static void
0098 parport_atari_save_state(struct parport *p, struct parport_state *s)
0099 {
0100 }
0101 
0102 static void
0103 parport_atari_restore_state(struct parport *p, struct parport_state *s)
0104 {
0105 }
0106 
0107 static void
0108 parport_atari_enable_irq(struct parport *p)
0109 {
0110     enable_irq(IRQ_MFP_BUSY);
0111 }
0112 
0113 static void
0114 parport_atari_disable_irq(struct parport *p)
0115 {
0116     disable_irq(IRQ_MFP_BUSY);
0117 }
0118 
0119 static void
0120 parport_atari_data_forward(struct parport *p)
0121 {
0122     unsigned long flags;
0123 
0124     local_irq_save(flags);
0125     /* Soundchip port B as output. */
0126     sound_ym.rd_data_reg_sel = 7;
0127     sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x40;
0128     local_irq_restore(flags);
0129 }
0130 
0131 static void
0132 parport_atari_data_reverse(struct parport *p)
0133 {
0134 }
0135 
0136 static struct parport_operations parport_atari_ops = {
0137     .write_data = parport_atari_write_data,
0138     .read_data  = parport_atari_read_data,
0139 
0140     .write_control  = parport_atari_write_control,
0141     .read_control   = parport_atari_read_control,
0142     .frob_control   = parport_atari_frob_control,
0143 
0144     .read_status    = parport_atari_read_status,
0145 
0146     .enable_irq = parport_atari_enable_irq,
0147     .disable_irq    = parport_atari_disable_irq,
0148 
0149     .data_forward   = parport_atari_data_forward,
0150     .data_reverse   = parport_atari_data_reverse,
0151 
0152     .init_state = parport_atari_init_state,
0153     .save_state = parport_atari_save_state,
0154     .restore_state  = parport_atari_restore_state,
0155 
0156     .epp_write_data = parport_ieee1284_epp_write_data,
0157     .epp_read_data  = parport_ieee1284_epp_read_data,
0158     .epp_write_addr = parport_ieee1284_epp_write_addr,
0159     .epp_read_addr  = parport_ieee1284_epp_read_addr,
0160 
0161     .ecp_write_data = parport_ieee1284_ecp_write_data,
0162     .ecp_read_data  = parport_ieee1284_ecp_read_data,
0163     .ecp_write_addr = parport_ieee1284_ecp_write_addr,
0164 
0165     .compat_write_data  = parport_ieee1284_write_compat,
0166     .nibble_read_data   = parport_ieee1284_read_nibble,
0167     .byte_read_data     = parport_ieee1284_read_byte,
0168 
0169     .owner      = THIS_MODULE,
0170 };
0171 
0172 
0173 static int __init parport_atari_init(void)
0174 {
0175     struct parport *p;
0176     unsigned long flags;
0177 
0178     if (MACH_IS_ATARI) {
0179         local_irq_save(flags);
0180         /* Soundchip port A/B as output. */
0181         sound_ym.rd_data_reg_sel = 7;
0182         sound_ym.wd_data = (sound_ym.rd_data_reg_sel & 0x3f) | 0xc0;
0183         /* STROBE high. */
0184         sound_ym.rd_data_reg_sel = 14;
0185         sound_ym.wd_data = sound_ym.rd_data_reg_sel | (1 << 5);
0186         local_irq_restore(flags);
0187         /* MFP port I0 as input. */
0188         st_mfp.data_dir &= ~1;
0189         /* MFP port I0 interrupt on high->low edge. */
0190         st_mfp.active_edge &= ~1;
0191         p = parport_register_port((unsigned long)&sound_ym.wd_data,
0192                       IRQ_MFP_BUSY, PARPORT_DMA_NONE,
0193                       &parport_atari_ops);
0194         if (!p)
0195             return -ENODEV;
0196         if (request_irq(IRQ_MFP_BUSY, parport_irq_handler, 0, p->name,
0197                 p)) {
0198             parport_put_port (p);
0199             return -ENODEV;
0200         }
0201 
0202         this_port = p;
0203         pr_info("%s: Atari built-in port using irq\n", p->name);
0204         parport_announce_port (p);
0205 
0206         return 0;
0207     }
0208     return -ENODEV;
0209 }
0210 
0211 static void __exit parport_atari_exit(void)
0212 {
0213     parport_remove_port(this_port);
0214     if (this_port->irq != PARPORT_IRQ_NONE)
0215         free_irq(IRQ_MFP_BUSY, this_port);
0216     parport_put_port(this_port);
0217 }
0218 
0219 MODULE_AUTHOR("Andreas Schwab");
0220 MODULE_DESCRIPTION("Parport Driver for Atari builtin Port");
0221 MODULE_LICENSE("GPL");
0222 
0223 module_init(parport_atari_init)
0224 module_exit(parport_atari_exit)