aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/drivers/serial-u16550.c221
1 files changed, 123 insertions, 98 deletions
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 74028b2..3a86a58 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -117,13 +117,13 @@ MODULE_PARM_DESC(adaptor, "Type of adaptor.");
#define SERIAL_MODE_INPUT_TRIGGERED (1 << 2)
#define SERIAL_MODE_OUTPUT_TRIGGERED (1 << 3)
-typedef struct _snd_uart16550 {
+struct snd_uart16550 {
struct snd_card *card;
struct snd_rawmidi *rmidi;
struct snd_rawmidi_substream *midi_output[SNDRV_SERIAL_MAX_OUTS];
struct snd_rawmidi_substream *midi_input[SNDRV_SERIAL_MAX_INS];
- int filemode; //open status of file
+ int filemode; /* open status of file */
spinlock_t open_lock;
@@ -140,39 +140,39 @@ typedef struct _snd_uart16550 {
unsigned char old_divisor_msb;
unsigned char old_line_ctrl_reg;
- // parameter for using of write loop
- short int fifo_limit; //used in uart16550
- short int fifo_count; //used in uart16550
+ /* parameter for using of write loop */
+ short int fifo_limit; /* used in uart16550 */
+ short int fifo_count; /* used in uart16550 */
- // type of adaptor
+ /* type of adaptor */
int adaptor;
- // inputs
+ /* inputs */
int prev_in;
unsigned char rstatus;
- // outputs
+ /* outputs */
int prev_out;
unsigned char prev_status[SNDRV_SERIAL_MAX_OUTS];
- // write buffer and its writing/reading position
+ /* write buffer and its writing/reading position */
unsigned char tx_buff[TX_BUFF_SIZE];
int buff_in_count;
int buff_in;
int buff_out;
int drop_on_full;
- // wait timer
+ /* wait timer */
unsigned int timer_running:1;
struct timer_list buffer_timer;
-} snd_uart16550_t;
+};
static struct platform_device *devices[SNDRV_CARDS];
-static inline void snd_uart16550_add_timer(snd_uart16550_t *uart)
+static inline void snd_uart16550_add_timer(struct snd_uart16550 *uart)
{
- if (! uart->timer_running) {
+ if (!uart->timer_running) {
/* timer 38600bps * 10bit * 16byte */
uart->buffer_timer.expires = jiffies + (HZ+255)/256;
uart->timer_running = 1;
@@ -180,7 +180,7 @@ static inline void snd_uart16550_add_timer(snd_uart16550_t *uart)
}
}
-static inline void snd_uart16550_del_timer(snd_uart16550_t *uart)
+static inline void snd_uart16550_del_timer(struct snd_uart16550 *uart)
{
if (uart->timer_running) {
del_timer(&uart->buffer_timer);
@@ -189,10 +189,10 @@ static inline void snd_uart16550_del_timer(snd_uart16550_t *uart)
}
/* This macro is only used in snd_uart16550_io_loop */
-static inline void snd_uart16550_buffer_output(snd_uart16550_t *uart)
+static inline void snd_uart16550_buffer_output(struct snd_uart16550 *uart)
{
unsigned short buff_out = uart->buff_out;
- if( uart->buff_in_count > 0 ) {
+ if (uart->buff_in_count > 0) {
outb(uart->tx_buff[buff_out], uart->base + UART_TX);
uart->fifo_count++;
buff_out++;
@@ -206,7 +206,7 @@ static inline void snd_uart16550_buffer_output(snd_uart16550_t *uart)
* We don't want to interrupt this,
* as we're already handling an interrupt
*/
-static void snd_uart16550_io_loop(snd_uart16550_t * uart)
+static void snd_uart16550_io_loop(struct snd_uart16550 * uart)
{
unsigned char c, status;
int substream;
@@ -220,9 +220,8 @@ static void snd_uart16550_io_loop(snd_uart16550_t * uart)
c = inb(uart->base + UART_RX);
/* keep track of last status byte */
- if (c & 0x80) {
+ if (c & 0x80)
uart->rstatus = c;
- }
/* handle stream switch */
if (uart->adaptor == SNDRV_SERIAL_GENERIC) {
@@ -230,14 +229,16 @@ static void snd_uart16550_io_loop(snd_uart16550_t * uart)
if (c <= SNDRV_SERIAL_MAX_INS && c > 0)
substream = c - 1;
if (c != 0xf5)
- uart->rstatus = 0; /* prevent future bytes from being interpreted as streams */
- }
- else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && (uart->midi_input[substream] != NULL)) {
- snd_rawmidi_receive(uart->midi_input[substream], &c, 1);
- }
- } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && (uart->midi_input[substream] != NULL)) {
+ /* prevent future bytes from being
+ interpreted as streams */
+ uart->rstatus = 0;
+ } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN)
+ && uart->midi_input[substream])
+ snd_rawmidi_receive(uart->midi_input[substream],
+ &c, 1);
+ } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) &&
+ uart->midi_input[substream])
snd_rawmidi_receive(uart->midi_input[substream], &c, 1);
- }
if (status & UART_LSR_OE)
snd_printk("%s: Overrun on device at 0x%lx\n",
@@ -250,21 +251,20 @@ static void snd_uart16550_io_loop(snd_uart16550_t * uart)
/* no need of check SERIAL_MODE_OUTPUT_OPEN because if not,
buffer is never filled. */
/* Check write status */
- if (status & UART_LSR_THRE) {
+ if (status & UART_LSR_THRE)
uart->fifo_count = 0;
- }
if (uart->adaptor == SNDRV_SERIAL_MS124W_SA
|| uart->adaptor == SNDRV_SERIAL_GENERIC) {
/* Can't use FIFO, must send only when CTS is true */
status = inb(uart->base + UART_MSR);
- while( (uart->fifo_count == 0) && (status & UART_MSR_CTS) &&
- (uart->buff_in_count > 0) ) {
+ while (uart->fifo_count == 0 && (status & UART_MSR_CTS) &&
+ uart->buff_in_count > 0) {
snd_uart16550_buffer_output(uart);
- status = inb( uart->base + UART_MSR );
+ status = inb(uart->base + UART_MSR);
}
} else {
/* Write loop */
- while (uart->fifo_count < uart->fifo_limit /* Can we write ? */
+ while (uart->fifo_count < uart->fifo_limit /* Can we write ? */
&& uart->buff_in_count > 0) /* Do we want to? */
snd_uart16550_buffer_output(uart);
}
@@ -294,15 +294,16 @@ static void snd_uart16550_io_loop(snd_uart16550_t * uart)
*/
static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id)
{
- snd_uart16550_t *uart;
+ struct snd_uart16550 *uart;
- uart = (snd_uart16550_t *) dev_id;
+ uart = dev_id;
spin_lock(&uart->open_lock);
if (uart->filemode == SERIAL_MODE_NOT_OPENED) {
spin_unlock(&uart->open_lock);
return IRQ_NONE;
}
- inb(uart->base + UART_IIR); /* indicate to the UART that the interrupt has been serviced */
+ /* indicate to the UART that the interrupt has been serviced */
+ inb(uart->base + UART_IIR);
snd_uart16550_io_loop(uart);
spin_unlock(&uart->open_lock);
return IRQ_HANDLED;
@@ -312,9 +313,9 @@ static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id)
static void snd_uart16550_buffer_timer(unsigned long data)
{
unsigned long flags;
- snd_uart16550_t *uart;
+ struct snd_uart16550 *uart;
- uart = (snd_uart16550_t *)data;
+ uart = (struct snd_uart16550 *)data;
spin_lock_irqsave(&uart->open_lock, flags);
snd_uart16550_del_timer(uart);
snd_uart16550_io_loop(uart);
@@ -326,7 +327,7 @@ static void snd_uart16550_buffer_timer(unsigned long data)
* return 0 if found
* return negative error if not found
*/
-static int __init snd_uart16550_detect(snd_uart16550_t *uart)
+static int __init snd_uart16550_detect(struct snd_uart16550 *uart)
{
unsigned long io_base = uart->base;
int ok;
@@ -343,7 +344,8 @@ static int __init snd_uart16550_detect(snd_uart16550_t *uart)
return -EBUSY;
}
- ok = 1; /* uart detected unless one of the following tests should fail */
+ /* uart detected unless one of the following tests should fail */
+ ok = 1;
/* 8 data-bits, 1 stop-bit, parity off, DLAB = 0 */
outb(UART_LCR_WLEN8, io_base + UART_LCR); /* Line Control Register */
c = inb(io_base + UART_IER);
@@ -368,7 +370,7 @@ static int __init snd_uart16550_detect(snd_uart16550_t *uart)
return ok;
}
-static void snd_uart16550_do_open(snd_uart16550_t * uart)
+static void snd_uart16550_do_open(struct snd_uart16550 * uart)
{
char byte;
@@ -460,7 +462,7 @@ static void snd_uart16550_do_open(snd_uart16550_t * uart)
inb(uart->base + UART_RX); /* Clear any pre-existing receive interrupt */
}
-static void snd_uart16550_do_close(snd_uart16550_t * uart)
+static void snd_uart16550_do_close(struct snd_uart16550 * uart)
{
if (uart->irq < 0)
snd_uart16550_del_timer(uart);
@@ -514,7 +516,7 @@ static void snd_uart16550_do_close(snd_uart16550_t * uart)
static int snd_uart16550_input_open(struct snd_rawmidi_substream *substream)
{
unsigned long flags;
- snd_uart16550_t *uart = substream->rmidi->private_data;
+ struct snd_uart16550 *uart = substream->rmidi->private_data;
spin_lock_irqsave(&uart->open_lock, flags);
if (uart->filemode == SERIAL_MODE_NOT_OPENED)
@@ -528,7 +530,7 @@ static int snd_uart16550_input_open(struct snd_rawmidi_substream *substream)
static int snd_uart16550_input_close(struct snd_rawmidi_substream *substream)
{
unsigned long flags;
- snd_uart16550_t *uart = substream->rmidi->private_data;
+ struct snd_uart16550 *uart = substream->rmidi->private_data;
spin_lock_irqsave(&uart->open_lock, flags);
uart->filemode &= ~SERIAL_MODE_INPUT_OPEN;
@@ -539,24 +541,24 @@ static int snd_uart16550_input_close(struct snd_rawmidi_substream *substream)
return 0;
}
-static void snd_uart16550_input_trigger(struct snd_rawmidi_substream *substream, int up)
+static void snd_uart16550_input_trigger(struct snd_rawmidi_substream *substream,
+ int up)
{
unsigned long flags;
- snd_uart16550_t *uart = substream->rmidi->private_data;
+ struct snd_uart16550 *uart = substream->rmidi->private_data;
spin_lock_irqsave(&uart->open_lock, flags);
- if (up) {
+ if (up)
uart->filemode |= SERIAL_MODE_INPUT_TRIGGERED;
- } else {
+ else
uart->filemode &= ~SERIAL_MODE_INPUT_TRIGGERED;
- }
spin_unlock_irqrestore(&uart->open_lock, flags);
}
static int snd_uart16550_output_open(struct snd_rawmidi_substream *substream)
{
unsigned long flags;
- snd_uart16550_t *uart = substream->rmidi->private_data;
+ struct snd_uart16550 *uart = substream->rmidi->private_data;
spin_lock_irqsave(&uart->open_lock, flags);
if (uart->filemode == SERIAL_MODE_NOT_OPENED)
@@ -570,7 +572,7 @@ static int snd_uart16550_output_open(struct snd_rawmidi_substream *substream)
static int snd_uart16550_output_close(struct snd_rawmidi_substream *substream)
{
unsigned long flags;
- snd_uart16550_t *uart = substream->rmidi->private_data;
+ struct snd_uart16550 *uart = substream->rmidi->private_data;
spin_lock_irqsave(&uart->open_lock, flags);
uart->filemode &= ~SERIAL_MODE_OUTPUT_OPEN;
@@ -581,18 +583,20 @@ static int snd_uart16550_output_close(struct snd_rawmidi_substream *substream)
return 0;
};
-static inline int snd_uart16550_buffer_can_write( snd_uart16550_t *uart, int Num )
+static inline int snd_uart16550_buffer_can_write(struct snd_uart16550 *uart,
+ int Num)
{
- if( uart->buff_in_count + Num < TX_BUFF_SIZE )
+ if (uart->buff_in_count + Num < TX_BUFF_SIZE)
return 1;
else
return 0;
}
-static inline int snd_uart16550_write_buffer(snd_uart16550_t *uart, unsigned char byte)
+static inline int snd_uart16550_write_buffer(struct snd_uart16550 *uart,
+ unsigned char byte)
{
unsigned short buff_in = uart->buff_in;
- if( uart->buff_in_count < TX_BUFF_SIZE ) {
+ if (uart->buff_in_count < TX_BUFF_SIZE) {
uart->tx_buff[buff_in] = byte;
buff_in++;
buff_in &= TX_BUFF_MASK;
@@ -605,12 +609,14 @@ static inline int snd_uart16550_write_buffer(snd_uart16550_t *uart, unsigned cha
return 0;
}
-static int snd_uart16550_output_byte(snd_uart16550_t *uart, struct snd_rawmidi_substream *substream, unsigned char midi_byte)
+static int snd_uart16550_output_byte(struct snd_uart16550 *uart,
+ struct snd_rawmidi_substream *substream,
+ unsigned char midi_byte)
{
- if (uart->buff_in_count == 0 /* Buffer empty? */
+ if (uart->buff_in_count == 0 /* Buffer empty? */
&& ((uart->adaptor != SNDRV_SERIAL_MS124W_SA &&
uart->adaptor != SNDRV_SERIAL_GENERIC) ||
- (uart->fifo_count == 0 /* FIFO empty? */
+ (uart->fifo_count == 0 /* FIFO empty? */
&& (inb(uart->base + UART_MSR) & UART_MSR_CTS)))) { /* CTS? */
/* Tx Buffer Empty - try to write immediately */
@@ -623,12 +629,13 @@ static int snd_uart16550_output_byte(snd_uart16550_t *uart, struct snd_rawmidi_s
uart->fifo_count++;
outb(midi_byte, uart->base + UART_TX);
} else {
- /* Cannot write (buffer empty) - put char in buffer */
+ /* Cannot write (buffer empty) -
+ * put char in buffer */
snd_uart16550_write_buffer(uart, midi_byte);
}
}
} else {
- if( !snd_uart16550_write_buffer(uart, midi_byte) ) {
+ if (!snd_uart16550_write_buffer(uart, midi_byte)) {
snd_printk("%s: Buffer overrun on device at 0x%lx\n",
uart->rmidi->name, uart->base);
return 0;
@@ -642,9 +649,9 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream)
{
unsigned long flags;
unsigned char midi_byte, addr_byte;
- snd_uart16550_t *uart = substream->rmidi->private_data;
+ struct snd_uart16550 *uart = substream->rmidi->private_data;
char first;
- static unsigned long lasttime=0;
+ static unsigned long lasttime = 0;
/* Interupts are disabled during the updating of the tx_buff,
* since it is 'bad' to have two processes updating the same
@@ -653,7 +660,7 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream)
spin_lock_irqsave(&uart->open_lock, flags);
- if (uart->irq < 0) //polling
+ if (uart->irq < 0) /* polling */
snd_uart16550_io_loop(uart);
if (uart->adaptor == SNDRV_SERIAL_MS124W_MB) {
@@ -671,7 +678,8 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream)
/* select any combination of the four ports */
addr_byte = (substream->number << 4) | 0x08;
/* ...except none */
- if (addr_byte == 0x08) addr_byte = 0xf8;
+ if (addr_byte == 0x08)
+ addr_byte = 0xf8;
#endif
snd_uart16550_output_byte(uart, substream, addr_byte);
/* send midi byte */
@@ -679,31 +687,42 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream)
}
} else {
first = 0;
- while( 1 == snd_rawmidi_transmit_peek(substream, &midi_byte, 1) ) {
- /* Also send F5 after 3 seconds with no data to handle device disconnect */
- if (first == 0 && (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS ||
- uart->adaptor == SNDRV_SERIAL_GENERIC) &&
- (uart->prev_out != substream->number || jiffies-lasttime > 3*HZ)) {
-
- if( snd_uart16550_buffer_can_write( uart, 3 ) ) {
+ while (snd_rawmidi_transmit_peek(substream, &midi_byte, 1) == 1) {
+ /* Also send F5 after 3 seconds with no data
+ * to handle device disconnect */
+ if (first == 0 &&
+ (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS ||
+ uart->adaptor == SNDRV_SERIAL_GENERIC) &&
+ (uart->prev_out != substream->number ||
+ jiffies-lasttime > 3*HZ)) {
+
+ if (snd_uart16550_buffer_can_write(uart, 3)) {
/* Roland Soundcanvas part selection */
- /* If this substream of the data is different previous
- substream in this uart, send the change part event */
+ /* If this substream of the data is
+ * different previous substream
+ * in this uart, send the change part
+ * event
+ */
uart->prev_out = substream->number;
/* change part */
- snd_uart16550_output_byte(uart, substream, 0xf5);
+ snd_uart16550_output_byte(uart, substream,
+ 0xf5);
/* data */
- snd_uart16550_output_byte(uart, substream, uart->prev_out + 1);
- /* If midi_byte is a data byte, send the previous status byte */
- if ((midi_byte < 0x80) && (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS))
+ snd_uart16550_output_byte(uart, substream,
+ uart->prev_out + 1);
+ /* If midi_byte is a data byte,
+ * send the previous status byte */
+ if (midi_byte < 0x80 &&
+ uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS)
snd_uart16550_output_byte(uart, substream, uart->prev_status[uart->prev_out]);
- } else if( !uart->drop_on_full )
+ } else if (!uart->drop_on_full)
break;
}
/* send midi byte */
- if( !snd_uart16550_output_byte(uart, substream, midi_byte) && !uart->drop_on_full )
+ if (!snd_uart16550_output_byte(uart, substream, midi_byte) &&
+ !uart->drop_on_full )
break;
if (midi_byte >= 0x80 && midi_byte < 0xf0)
@@ -717,17 +736,17 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream)
spin_unlock_irqrestore(&uart->open_lock, flags);
}
-static void snd_uart16550_output_trigger(struct snd_rawmidi_substream *substream, int up)
+static void snd_uart16550_output_trigger(struct snd_rawmidi_substream *substream,
+ int up)
{
unsigned long flags;
- snd_uart16550_t *uart = substream->rmidi->private_data;
+ struct snd_uart16550 *uart = substream->rmidi->private_data;
spin_lock_irqsave(&uart->open_lock, flags);
- if (up) {
+ if (up)
uart->filemode |= SERIAL_MODE_OUTPUT_TRIGGERED;
- } else {
+ else
uart->filemode &= ~SERIAL_MODE_OUTPUT_TRIGGERED;
- }
spin_unlock_irqrestore(&uart->open_lock, flags);
if (up)
snd_uart16550_output_write(substream);
@@ -747,10 +766,10 @@ static struct snd_rawmidi_ops snd_uart16550_input =
.trigger = snd_uart16550_input_trigger,
};
-static int snd_uart16550_free(snd_uart16550_t *uart)
+static int snd_uart16550_free(struct snd_uart16550 *uart)
{
if (uart->irq >= 0)
- free_irq(uart->irq, (void *)uart);
+ free_irq(uart->irq, uart);
release_and_free_resource(uart->res_base);
kfree(uart);
return 0;
@@ -758,7 +777,7 @@ static int snd_uart16550_free(snd_uart16550_t *uart)
static int snd_uart16550_dev_free(struct snd_device *device)
{
- snd_uart16550_t *uart = device->device_data;
+ struct snd_uart16550 *uart = device->device_data;
return snd_uart16550_free(uart);
}
@@ -769,12 +788,12 @@ static int __init snd_uart16550_create(struct snd_card *card,
unsigned int base,
int adaptor,
int droponfull,
- snd_uart16550_t **ruart)
+ struct snd_uart16550 **ruart)
{
static struct snd_device_ops ops = {
.dev_free = snd_uart16550_dev_free,
};
- snd_uart16550_t *uart;
+ struct snd_uart16550 *uart;
int err;
@@ -795,7 +814,7 @@ static int __init snd_uart16550_create(struct snd_card *card,
if (irq >= 0 && irq != SNDRV_AUTO_IRQ) {
if (request_irq(irq, snd_uart16550_interrupt,
- IRQF_DISABLED, "Serial MIDI", (void *) uart)) {
+ IRQF_DISABLED, "Serial MIDI", uart)) {
snd_printk("irq %d busy. Using Polling.\n", irq);
} else {
uart->irq = irq;
@@ -843,23 +862,28 @@ static int __init snd_uart16550_create(struct snd_card *card,
static void __init snd_uart16550_substreams(struct snd_rawmidi_str *stream)
{
- struct list_head *list;
+ struct snd_rawmidi_substream *substream;
- list_for_each(list, &stream->substreams) {
- struct snd_rawmidi_substream *substream = list_entry(list, struct snd_rawmidi_substream, list);
+ list_for_each_entry(substream, &stream->substreams, list) {
sprintf(substream->name, "Serial MIDI %d", substream->number + 1);
}
}
-static int __init snd_uart16550_rmidi(snd_uart16550_t *uart, int device, int outs, int ins, struct snd_rawmidi **rmidi)
+static int __init snd_uart16550_rmidi(struct snd_uart16550 *uart, int device,
+ int outs, int ins,
+ struct snd_rawmidi **rmidi)
{
struct snd_rawmidi *rrawmidi;
int err;
- if ((err = snd_rawmidi_new(uart->card, "UART Serial MIDI", device, outs, ins, &rrawmidi)) < 0)
+ err = snd_rawmidi_new(uart->card, "UART Serial MIDI", device,
+ outs, ins, &rrawmidi);
+ if (err < 0)
return err;
- snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_uart16550_input);
- snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_uart16550_output);
+ snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_INPUT,
+ &snd_uart16550_input);
+ snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
+ &snd_uart16550_output);
strcpy(rrawmidi->name, "Serial MIDI");
snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]);
snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]);
@@ -875,7 +899,7 @@ static int __init snd_uart16550_rmidi(snd_uart16550_t *uart, int device, int out
static int __init snd_serial_probe(struct platform_device *devptr)
{
struct snd_card *card;
- snd_uart16550_t *uart;
+ struct snd_uart16550 *uart;
int err;
int dev = devptr->id;
@@ -929,7 +953,8 @@ static int __init snd_serial_probe(struct platform_device *devptr)
&uart)) < 0)
goto _err;
- if ((err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi)) < 0)
+ err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi);
+ if (err < 0)
goto _err;
sprintf(card->longname, "%s at 0x%lx, irq %d speed %d div %d outs %d ins %d adaptor %s droponfull %d",