cleanup
[linux-2.4.21-pre4.git] / drivers / parport / parport_atari.c
1 /* Low-level parallel port routines for the Atari builtin port
2  *
3  * Author: Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
4  *
5  * Based on parport_amiga.c.
6  *
7  * The built-in Atari parallel port provides one port at a fixed address
8  * with 8 output data lines (D0 - D7), 1 output control line (STROBE)
9  * and 1 input status line (BUSY) able to cause an interrupt.
10  */
11
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/parport.h>
15 #include <asm/setup.h>
16 #include <asm/atarihw.h>
17 #include <asm/irq.h>
18 #include <asm/atariints.h>
19
20 static struct parport *this_port = NULL;
21
22 static unsigned char
23 parport_atari_read_data(struct parport *p)
24 {
25         unsigned long flags;
26         unsigned char data;
27
28         save_flags(flags);
29         cli();
30         sound_ym.rd_data_reg_sel = 15;
31         data = sound_ym.rd_data_reg_sel;
32         restore_flags(flags);
33         return data;
34 }
35
36 static void
37 parport_atari_write_data(struct parport *p, unsigned char data)
38 {
39         unsigned long flags;
40
41         save_flags(flags);
42         cli();
43         sound_ym.rd_data_reg_sel = 15;
44         sound_ym.wd_data = data;
45         restore_flags(flags);
46 }
47
48 static unsigned char
49 parport_atari_read_control(struct parport *p)
50 {
51         unsigned long flags;
52         unsigned char control = 0;
53
54         save_flags(flags);
55         cli();
56         sound_ym.rd_data_reg_sel = 14;
57         if (!(sound_ym.rd_data_reg_sel & (1 << 5)))
58                 control = PARPORT_CONTROL_STROBE;
59         restore_flags(flags);
60         return control;
61 }
62
63 static void
64 parport_atari_write_control(struct parport *p, unsigned char control)
65 {
66         unsigned long flags;
67
68         save_flags(flags);
69         cli();
70         sound_ym.rd_data_reg_sel = 14;
71         if (control & PARPORT_CONTROL_STROBE)
72                 sound_ym.wd_data = sound_ym.rd_data_reg_sel & ~(1 << 5);
73         else
74                 sound_ym.wd_data = sound_ym.rd_data_reg_sel | (1 << 5);
75         restore_flags(flags);
76 }
77
78 static unsigned char
79 parport_atari_frob_control(struct parport *p, unsigned char mask,
80                            unsigned char val)
81 {
82         unsigned char old = parport_atari_read_control(p);
83         parport_atari_write_control(p, (old & ~mask) ^ val);
84         return old;
85 }
86
87 static unsigned char
88 parport_atari_read_status(struct parport *p)
89 {
90         return ((mfp.par_dt_reg & 1 ? 0 : PARPORT_STATUS_BUSY) |
91                 PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR);
92 }
93
94 static void
95 parport_atari_init_state(struct pardevice *d, struct parport_state *s)
96 {
97 }
98
99 static void
100 parport_atari_save_state(struct parport *p, struct parport_state *s)
101 {
102 }
103
104 static void
105 parport_atari_restore_state(struct parport *p, struct parport_state *s)
106 {
107 }
108
109 static void
110 parport_atari_interrupt(int irq, void *dev_id, struct pt_regs *regs)
111 {
112         parport_generic_irq(irq, (struct parport *) dev_id, regs);
113 }
114
115 static void
116 parport_atari_enable_irq(struct parport *p)
117 {
118         enable_irq(IRQ_MFP_BUSY);
119 }
120
121 static void
122 parport_atari_disable_irq(struct parport *p)
123 {
124         disable_irq(IRQ_MFP_BUSY);
125 }
126
127 static void
128 parport_atari_data_forward(struct parport *p)
129 {
130         unsigned long flags;
131
132         save_flags(flags);
133         cli();
134         /* Soundchip port B as output. */
135         sound_ym.rd_data_reg_sel = 7;
136         sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x40;
137         restore_flags(flags);
138 }
139
140 static void
141 parport_atari_data_reverse(struct parport *p)
142 {
143 #if 0 /* too dangerous, can kill sound chip */
144         unsigned long flags;
145
146         save_flags(flags);
147         cli();
148         /* Soundchip port B as input. */
149         sound_ym.rd_data_reg_sel = 7;
150         sound_ym.wd_data = sound_ym.rd_data_reg_sel & ~0x40;
151         restore_flags(flags);
152 #endif
153 }
154
155 static void
156 parport_atari_inc_use_count(void)
157 {
158         MOD_INC_USE_COUNT;
159 }
160
161 static void
162 parport_atari_dec_use_count(void)
163 {
164         MOD_DEC_USE_COUNT;
165 }
166
167 static struct parport_operations parport_atari_ops = {
168         parport_atari_write_data,
169         parport_atari_read_data,
170
171         parport_atari_write_control,
172         parport_atari_read_control,
173         parport_atari_frob_control,
174
175         parport_atari_read_status,
176
177         parport_atari_enable_irq,
178         parport_atari_disable_irq,
179
180         parport_atari_data_forward,
181         parport_atari_data_reverse,
182
183         parport_atari_init_state,
184         parport_atari_save_state,
185         parport_atari_restore_state,
186
187         parport_atari_inc_use_count,
188         parport_atari_dec_use_count,
189
190         parport_ieee1284_epp_write_data,
191         parport_ieee1284_epp_read_data,
192         parport_ieee1284_epp_write_addr,
193         parport_ieee1284_epp_read_addr,
194
195         parport_ieee1284_ecp_write_data,
196         parport_ieee1284_ecp_read_data,
197         parport_ieee1284_ecp_write_addr,
198
199         parport_ieee1284_write_compat,
200         parport_ieee1284_read_nibble,
201         parport_ieee1284_read_byte,
202 };
203
204
205 int __init
206 parport_atari_init(void)
207 {
208         struct parport *p;
209         unsigned long flags;
210
211         if (MACH_IS_ATARI) {
212                 save_flags(flags);
213                 cli();
214                 /* Soundchip port A/B as output. */
215                 sound_ym.rd_data_reg_sel = 7;
216                 sound_ym.wd_data = (sound_ym.rd_data_reg_sel & 0x3f) | 0xc0;
217                 /* STROBE high. */
218                 sound_ym.rd_data_reg_sel = 14;
219                 sound_ym.wd_data = sound_ym.rd_data_reg_sel | (1 << 5);
220                 restore_flags(flags);
221                 /* MFP port I0 as input. */
222                 mfp.data_dir &= ~1;
223                 /* MFP port I0 interrupt on high->low edge. */
224                 mfp.active_edge &= ~1;
225                 p = parport_register_port((unsigned long)&sound_ym.wd_data,
226                                           IRQ_MFP_BUSY, PARPORT_DMA_NONE,
227                                           &parport_atari_ops);
228                 if (!p)
229                         return 0;
230                 if (request_irq(IRQ_MFP_BUSY, parport_atari_interrupt,
231                                 IRQ_TYPE_SLOW, p->name, p)) {
232                         parport_unregister_port (p);
233                         return 0;
234                 }
235
236                 this_port = p;
237                 printk(KERN_INFO "%s: Atari built-in port using irq\n", p->name);
238                 parport_proc_register(p);
239
240                 parport_announce_port (p);
241
242                 return 1;
243         }
244         return 0;
245 }
246
247 #ifdef MODULE
248
249 MODULE_AUTHOR("Andreas Schwab");
250 MODULE_DESCRIPTION("Parport Driver for Atari builtin Port");
251 MODULE_SUPPORTED_DEVICE("Atari builtin Parallel Port");
252 MODULE_LICENSE("GPL");
253
254 int
255 init_module(void)
256 {
257         return parport_atari_init() ? 0 : -ENODEV;
258 }
259
260 void
261 cleanup_module(void)
262 {
263         if (this_port->irq != PARPORT_IRQ_NONE)
264                 free_irq(IRQ_MFP_BUSY, this_port);
265         parport_proc_unregister(this_port);
266         parport_unregister_port(this_port);
267 }
268 #endif