OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [sound/] [uart6850.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * sound/uart6850.c
3
 */
4
/*
5
 * Copyright (C) by Hannu Savolainen 1993-1996
6
 *
7
 * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
8
 * Version 2 (June 1991). See the "COPYING" file distributed with this software
9
 * for more info.
10
 */
11
#include <linux/config.h>
12
 
13
/* Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl:
14
 *      added 6850 support, used with COVOX SoundMaster II and custom cards.
15
 */
16
 
17
#include "sound_config.h"
18
 
19
#if defined(CONFIG_UART6850) && defined(CONFIG_MIDI)
20
 
21
static int      uart6850_base = 0x330;
22
 
23
static int     *uart6850_osp;
24
 
25
#define DATAPORT   (uart6850_base)
26
#define COMDPORT   (uart6850_base+1)
27
#define STATPORT   (uart6850_base+1)
28
 
29
static int
30
uart6850_status (void)
31
{
32
  return inb (STATPORT);
33
}
34
#define input_avail()           (uart6850_status()&INPUT_AVAIL)
35
#define output_ready()          (uart6850_status()&OUTPUT_READY)
36
static void
37
uart6850_cmd (unsigned char cmd)
38
{
39
  outb (cmd, COMDPORT);
40
}
41
static int
42
uart6850_read (void)
43
{
44
  return inb (DATAPORT);
45
}
46
static void
47
uart6850_write (unsigned char byte)
48
{
49
  outb (byte, DATAPORT);
50
}
51
 
52
#define OUTPUT_READY    0x02    /* Mask for data ready Bit */
53
#define INPUT_AVAIL     0x01    /* Mask for Data Send Ready Bit */
54
 
55
#define UART_RESET      0x95
56
#define UART_MODE_ON    0x03
57
 
58
static int      uart6850_opened = 0;
59
static int      uart6850_irq;
60
static int      uart6850_detected = 0;
61
static int      my_dev;
62
 
63
static int      reset_uart6850 (void);
64
static void     (*midi_input_intr) (int dev, unsigned char data);
65
static void     poll_uart6850 (unsigned long dummy);
66
 
67
 
68
static struct timer_list uart6850_timer =
69
{NULL, NULL, 0, 0, poll_uart6850};
70
 
71
static void
72
uart6850_input_loop (void)
73
{
74
  int             count;
75
 
76
  count = 10;
77
 
78
  while (count)                 /*
79
                                 * Not timed out
80
                                 */
81
    if (input_avail ())
82
      {
83
        unsigned char   c = uart6850_read ();
84
 
85
        count = 100;
86
 
87
        if (uart6850_opened & OPEN_READ)
88
          midi_input_intr (my_dev, c);
89
      }
90
    else
91
      while (!input_avail () && count)
92
        count--;
93
}
94
 
95
void
96
m6850intr (int irq, void *dev_id, struct pt_regs *dummy)
97
{
98
  if (input_avail ())
99
    uart6850_input_loop ();
100
}
101
 
102
/*
103
 * It looks like there is no input interrupts in the UART mode. Let's try
104
 * polling.
105
 */
106
 
107
static void
108
poll_uart6850 (unsigned long dummy)
109
{
110
  unsigned long   flags;
111
 
112
  if (!(uart6850_opened & OPEN_READ))
113
    return;                     /* Device has been closed */
114
 
115
  save_flags (flags);
116
  cli ();
117
 
118
  if (input_avail ())
119
    uart6850_input_loop ();
120
 
121
 
122
  {
123
    uart6850_timer.expires = (1) + jiffies;
124
    add_timer (&uart6850_timer);
125
  };                            /*
126
                                   * Come back later
127
                                 */
128
 
129
  restore_flags (flags);
130
}
131
 
132
static int
133
uart6850_open (int dev, int mode,
134
               void            (*input) (int dev, unsigned char data),
135
               void            (*output) (int dev)
136
)
137
{
138
  if (uart6850_opened)
139
    {
140
      printk ("Midi6850: Midi busy\n");
141
      return -(EBUSY);
142
    }
143
 
144
  ;
145
  uart6850_cmd (UART_RESET);
146
 
147
  uart6850_input_loop ();
148
 
149
  midi_input_intr = input;
150
  uart6850_opened = mode;
151
  poll_uart6850 (0);             /*
152
                                 * Enable input polling
153
                                 */
154
 
155
  return 0;
156
}
157
 
158
static void
159
uart6850_close (int dev)
160
{
161
  uart6850_cmd (UART_MODE_ON);
162
 
163
  del_timer (&uart6850_timer);;
164
  uart6850_opened = 0;
165
}
166
 
167
static int
168
uart6850_out (int dev, unsigned char midi_byte)
169
{
170
  int             timeout;
171
  unsigned long   flags;
172
 
173
  /*
174
   * Test for input since pending input seems to block the output.
175
   */
176
 
177
  save_flags (flags);
178
  cli ();
179
 
180
  if (input_avail ())
181
    uart6850_input_loop ();
182
 
183
  restore_flags (flags);
184
 
185
  /*
186
   * Sometimes it takes about 13000 loops before the output becomes ready
187
   * (After reset). Normally it takes just about 10 loops.
188
   */
189
 
190
  for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);     /*
191
                                                                         * Wait
192
                                                                         */
193
 
194
  if (!output_ready ())
195
    {
196
      printk ("Midi6850: Timeout\n");
197
      return 0;
198
    }
199
 
200
  uart6850_write (midi_byte);
201
  return 1;
202
}
203
 
204
static int
205
uart6850_command (int dev, unsigned char *midi_byte)
206
{
207
  return 1;
208
}
209
 
210
static int
211
uart6850_start_read (int dev)
212
{
213
  return 0;
214
}
215
 
216
static int
217
uart6850_end_read (int dev)
218
{
219
  return 0;
220
}
221
 
222
static int
223
uart6850_ioctl (int dev, unsigned cmd, caddr_t arg)
224
{
225
  return -(EINVAL);
226
}
227
 
228
static void
229
uart6850_kick (int dev)
230
{
231
}
232
 
233
static int
234
uart6850_buffer_status (int dev)
235
{
236
  return 0;                      /*
237
                                 * No data in buffers
238
                                 */
239
}
240
 
241
#define MIDI_SYNTH_NAME "6850 UART Midi"
242
#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
243
#include "midi_synth.h"
244
 
245
static struct midi_operations uart6850_operations =
246
{
247
  {"6850 UART", 0, 0, SNDCARD_UART6850},
248
  &std_midi_synth,
249
  {0},
250
  uart6850_open,
251
  uart6850_close,
252
  uart6850_ioctl,
253
  uart6850_out,
254
  uart6850_start_read,
255
  uart6850_end_read,
256
  uart6850_kick,
257
  uart6850_command,
258
  uart6850_buffer_status
259
};
260
 
261
 
262
void
263
attach_uart6850 (struct address_info *hw_config)
264
{
265
  int             ok, timeout;
266
  unsigned long   flags;
267
 
268
  if (num_midis >= MAX_MIDI_DEV)
269
    {
270
      printk ("Sound: Too many midi devices detected\n");
271
      return;
272
    }
273
 
274
  uart6850_base = hw_config->io_base;
275
  uart6850_osp = hw_config->osp;
276
  uart6850_irq = hw_config->irq;
277
 
278
  if (!uart6850_detected)
279
    return;
280
 
281
  save_flags (flags);
282
  cli ();
283
 
284
  for (timeout = 30000; timeout < 0 && !output_ready (); timeout--);     /*
285
                                                                         * Wait
286
                                                                         */
287
  uart6850_cmd (UART_MODE_ON);
288
 
289
  ok = 1;
290
 
291
  restore_flags (flags);
292
 
293
  conf_printf ("6850 Midi Interface", hw_config);
294
 
295
  std_midi_synth.midi_dev = my_dev = num_midis;
296
  midi_devs[num_midis++] = &uart6850_operations;
297
}
298
 
299
static int
300
reset_uart6850 (void)
301
{
302
  uart6850_read ();
303
  return 1;                     /*
304
                                 * OK
305
                                 */
306
}
307
 
308
 
309
int
310
probe_uart6850 (struct address_info *hw_config)
311
{
312
  int             ok = 0;
313
 
314
  uart6850_osp = hw_config->osp;
315
  uart6850_base = hw_config->io_base;
316
  uart6850_irq = hw_config->irq;
317
 
318
  if (snd_set_irq_handler (uart6850_irq, m6850intr, "MIDI6850", uart6850_osp) < 0)
319
    return 0;
320
 
321
  ok = reset_uart6850 ();
322
 
323
  uart6850_detected = ok;
324
  return ok;
325
}
326
 
327
void
328
unload_uart6850 (struct address_info *hw_config)
329
{
330
  snd_release_irq (hw_config->irq);
331
}
332
 
333
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.