Skip to content

Commit

Permalink
[ALSA] Change an arugment of snd_mpu401_uart_new() to bit flags
Browse files Browse the repository at this point in the history
Change the 5th argument of snd_mpu401_uart_new() to bit flags
instead of a boolean.  The argument takes bits that consist of
MPU401_INFO_XXX flags.
The callers that used the value 1 there are replaced with
MPU401_INFO_INTEGRATED.

Signed-off-by: Takashi Iwai <[email protected]>
  • Loading branch information
tiwai authored and Jaroslav Kysela committed Jun 22, 2006
1 parent 140432f commit 302e4c2
Show file tree
Hide file tree
Showing 19 changed files with 147 additions and 62 deletions.
29 changes: 25 additions & 4 deletions Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4215,7 +4215,7 @@ struct _snd_pcm_runtime {
<programlisting>
<![CDATA[
struct snd_rawmidi *rmidi;
snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, integrated,
snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags,
irq, irq_flags, &rmidi);
]]>
</programlisting>
Expand All @@ -4242,15 +4242,36 @@ struct _snd_pcm_runtime {
</para>

<para>
The 5th argument is bitflags for additional information.
When the i/o port address above is a part of the PCI i/o
region, the MPU401 i/o port might have been already allocated
(reserved) by the driver itself. In such a case, pass non-zero
to the 5th argument
(<parameter>integrated</parameter>). Otherwise, pass 0 to it,
(reserved) by the driver itself. In such a case, pass a bit flag
<constant>MPU401_INFO_INTEGRATED</constant>,
and
the mpu401-uart layer will allocate the i/o ports by itself.
</para>

<para>
When the controller supports only the input or output MIDI stream,
pass <constant>MPU401_INFO_INPUT</constant> or
<constant>MPU401_INFO_OUTPUT</constant> bitflag, respectively.
Then the rawmidi instance is created as a single stream.
</para>

<para>
<constant>MPU401_INFO_MMIO</constant> bitflag is used to change
the access method to MMIO (via readb and writeb) instead of
iob and outb. In this case, you have to pass the iomapped address
to <function>snd_mpu401_uart_new()</function>.
</para>

<para>
When <constant>MPU401_INFO_TX_IRQ</constant> is set, the output
stream isn't checked in the default interrupt handler. The driver
needs to call <function>snd_mpu401_uart_interrupt_tx()</function>
by itself to start processing the output stream in irq handler.
</para>

<para>
Usually, the port address corresponds to the command port and
port + 1 corresponds to the data port. If not, you may change
Expand Down
14 changes: 12 additions & 2 deletions include/sound/mpu401.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@
#define MPU401_HW_PC98II 18 /* Roland PC98II */
#define MPU401_HW_AUREAL 19 /* Aureal Vortex */

#define MPU401_INFO_INPUT (1 << 0) /* input stream */
#define MPU401_INFO_OUTPUT (1 << 1) /* output stream */
#define MPU401_INFO_INTEGRATED (1 << 2) /* integrated h/w port */
#define MPU401_INFO_MMIO (1 << 3) /* MMIO access */
#define MPU401_INFO_TX_IRQ (1 << 4) /* independent TX irq */

#define MPU401_MODE_BIT_INPUT 0
#define MPU401_MODE_BIT_OUTPUT 1
#define MPU401_MODE_BIT_INPUT_TRIGGER 2
Expand All @@ -62,6 +68,7 @@ struct snd_mpu401 {
struct snd_rawmidi *rmidi;

unsigned short hardware; /* MPU401_HW_XXXX */
unsigned int info_flags; /* MPU401_INFO_XXX */
unsigned long port; /* base port of MPU-401 chip */
unsigned long cport; /* port + 1 (usually) */
struct resource *res; /* port resource */
Expand Down Expand Up @@ -99,13 +106,16 @@ struct snd_mpu401 {
*/

irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs);
irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id,
struct pt_regs *regs);
irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id,
struct pt_regs *regs);

int snd_mpu401_uart_new(struct snd_card *card,
int device,
unsigned short hardware,
unsigned long port,
int integrated,
unsigned int info_flags,
int irq,
int irq_flags,
struct snd_rawmidi ** rrawmidi);
Expand Down
96 changes: 68 additions & 28 deletions sound/drivers/mpu401/mpu401_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,17 +95,8 @@ static void snd_mpu401_uart_clear_rx(struct snd_mpu401 *mpu)
#endif
}

static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
static void uart_interrupt_tx(struct snd_mpu401 *mpu)
{
spin_lock(&mpu->input_lock);
if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
snd_mpu401_uart_input_read(mpu);
else
snd_mpu401_uart_clear_rx(mpu);
spin_unlock(&mpu->input_lock);
/* ok. for better Tx performance try do some output when
* input is done
*/
if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) &&
test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
spin_lock(&mpu->output_lock);
Expand All @@ -114,6 +105,22 @@ static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
}
}

static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
{
if (mpu->info_flags & MPU401_INFO_INPUT) {
spin_lock(&mpu->input_lock);
if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
snd_mpu401_uart_input_read(mpu);
else
snd_mpu401_uart_clear_rx(mpu);
spin_unlock(&mpu->input_lock);
}
if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
/* ok. for better Tx performance try do some output
when input is done */
uart_interrupt_tx(mpu);
}

/**
* snd_mpu401_uart_interrupt - generic MPU401-UART interrupt handler
* @irq: the irq number
Expand All @@ -135,6 +142,27 @@ irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id,

EXPORT_SYMBOL(snd_mpu401_uart_interrupt);

/**
* snd_mpu401_uart_interrupt_tx - generic MPU401-UART transmit irq handler
* @irq: the irq number
* @dev_id: mpu401 instance
* @regs: the reigster
*
* Processes the interrupt for MPU401-UART output.
*/
irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id,
struct pt_regs *regs)
{
struct snd_mpu401 *mpu = dev_id;

if (mpu == NULL)
return IRQ_NONE;
uart_interrupt_tx(mpu);
return IRQ_HANDLED;
}

EXPORT_SYMBOL(snd_mpu401_uart_interrupt_tx);

/*
* timer callback
* reprogram the timer and call the interrupt job
Expand Down Expand Up @@ -430,14 +458,16 @@ snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up)
* since the output timer might have been removed in
* snd_mpu401_uart_output_write().
*/
snd_mpu401_uart_add_timer(mpu, 0);
if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
snd_mpu401_uart_add_timer(mpu, 0);

/* output pending data */
spin_lock_irqsave(&mpu->output_lock, flags);
snd_mpu401_uart_output_write(mpu);
spin_unlock_irqrestore(&mpu->output_lock, flags);
} else {
snd_mpu401_uart_remove_timer(mpu, 0);
if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
snd_mpu401_uart_remove_timer(mpu, 0);
clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode);
}
}
Expand Down Expand Up @@ -475,7 +505,7 @@ static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi)
* @device: the device index, zero-based
* @hardware: the hardware type, MPU401_HW_XXXX
* @port: the base address of MPU401 port
* @integrated: non-zero if the port was already reserved by the chip
* @info_flags: bitflags MPU401_INFO_XXX
* @irq: the irq number, -1 if no interrupt for mpu
* @irq_flags: the irq request flags (SA_XXX), 0 if irq was already reserved.
* @rrawmidi: the pointer to store the new rawmidi instance
Expand All @@ -490,17 +520,24 @@ static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi)
*/
int snd_mpu401_uart_new(struct snd_card *card, int device,
unsigned short hardware,
unsigned long port, int integrated,
unsigned long port,
unsigned int info_flags,
int irq, int irq_flags,
struct snd_rawmidi ** rrawmidi)
{
struct snd_mpu401 *mpu;
struct snd_rawmidi *rmidi;
int in_enable, out_enable;
int err;

if (rrawmidi)
*rrawmidi = NULL;
if ((err = snd_rawmidi_new(card, "MPU-401U", device, 1, 1, &rmidi)) < 0)
if (! (info_flags & (MPU401_INFO_INPUT | MPU401_INFO_OUTPUT)))
info_flags |= MPU401_INFO_INPUT | MPU401_INFO_OUTPUT;
in_enable = (info_flags & MPU401_INFO_INPUT) ? 1 : 0;
out_enable = (info_flags & MPU401_INFO_OUTPUT) ? 1 : 0;
if ((err = snd_rawmidi_new(card, "MPU-401U", device,
out_enable, in_enable, &rmidi)) < 0)
return err;
mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
if (mpu == NULL) {
Expand All @@ -514,7 +551,7 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
spin_lock_init(&mpu->output_lock);
spin_lock_init(&mpu->timer_lock);
mpu->hardware = hardware;
if (!integrated) {
if (! (info_flags & MPU401_INFO_INTEGRATED)) {
int res_size = hardware == MPU401_HW_PC98II ? 4 : 2;
mpu->res = request_region(port, res_size, "MPU401 UART");
if (mpu->res == NULL) {
Expand All @@ -525,15 +562,12 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
return -EBUSY;
}
}
switch (hardware) {
case MPU401_HW_AUREAL:
if (info_flags & MPU401_INFO_MMIO) {
mpu->write = mpu401_write_mmio;
mpu->read = mpu401_read_mmio;
break;
default:
} else {
mpu->write = mpu401_write_port;
mpu->read = mpu401_read_port;
break;
}
mpu->port = port;
if (hardware == MPU401_HW_PC98II)
Expand All @@ -549,20 +583,26 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
return -EBUSY;
}
}
mpu->info_flags = info_flags;
mpu->irq = irq;
mpu->irq_flags = irq_flags;
if (card->shortname[0])
snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI",
card->shortname);
else
sprintf(rmidi->name, "MPU-401 MIDI %d-%d",card->number, device);
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
&snd_mpu401_uart_output);
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
&snd_mpu401_uart_input);
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
SNDRV_RAWMIDI_INFO_INPUT |
SNDRV_RAWMIDI_INFO_DUPLEX;
if (out_enable) {
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
&snd_mpu401_uart_output);
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
}
if (in_enable) {
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
&snd_mpu401_uart_input);
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
if (out_enable)
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
}
mpu->rmidi = rmidi;
if (rrawmidi)
*rrawmidi = rmidi;
Expand Down
3 changes: 1 addition & 2 deletions sound/isa/sscape.c
Original file line number Diff line number Diff line change
Expand Up @@ -897,10 +897,9 @@ static int __devinit create_mpu401(struct snd_card *card, int devnum, unsigned l
struct snd_rawmidi *rawmidi;
int err;

#define MPU401_SHARE_HARDWARE 1
if ((err = snd_mpu401_uart_new(card, devnum,
MPU401_HW_MPU401,
port, MPU401_SHARE_HARDWARE,
port, MPU401_INFO_INTEGRATED,
irq, SA_INTERRUPT,
&rawmidi)) == 0) {
struct snd_mpu401 *mpu = (struct snd_mpu401 *) rawmidi->private_data;
Expand Down
4 changes: 2 additions & 2 deletions sound/pci/als4000.c
Original file line number Diff line number Diff line change
Expand Up @@ -746,8 +746,8 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
card->shortname, chip->alt_port, chip->irq);

if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000,
gcr+0x30, 1, pci->irq, 0,
&chip->rmidi)) < 0) {
gcr+0x30, MPU401_INFO_INTEGRATED,
pci->irq, 0, &chip->rmidi)) < 0) {
printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", gcr+0x30);
goto out_err;
}
Expand Down
3 changes: 2 additions & 1 deletion sound/pci/au88x0/au88x0_mpu401.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ static int __devinit snd_vortex_midi(vortex_t * vortex)
port = (unsigned long)(vortex->mmio + VORTEX_MIDI_DATA);
if ((temp =
snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port,
1, 0, 0, &rmidi)) != 0) {
MPU401_INFO_INTEGRATED | MPU401_INFO_MMIO,
0, 0, &rmidi)) != 0) {
hwwrite(vortex->mmio, VORTEX_CTRL,
(hwread(vortex->mmio, VORTEX_CTRL) &
~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN);
Expand Down
4 changes: 2 additions & 2 deletions sound/pci/azt3328.c
Original file line number Diff line number Diff line change
Expand Up @@ -1806,8 +1806,8 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
card->private_data = chip;

if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401,
chip->mpu_port, 1, pci->irq, 0,
&chip->rmidi)) < 0) {
chip->mpu_port, MPU401_INFO_INTEGRATED,
pci->irq, 0, &chip->rmidi)) < 0) {
snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);
goto out_err;
}
Expand Down
4 changes: 3 additions & 1 deletion sound/pci/cmipci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2981,7 +2981,9 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc

if (iomidi > 0) {
if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
iomidi, integrated_midi,
iomidi,
(integrated_midi ?
MPU401_INFO_INTEGRATED : 0),
cm->irq, 0, &cm->rmidi)) < 0) {
printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi);
}
Expand Down
21 changes: 12 additions & 9 deletions sound/pci/cs5535audio/cs5535audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,16 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
{}
};

static int index = SNDRV_DEFAULT_IDX1;
static char *id = SNDRV_DEFAULT_STR1;
/* for backward compatibility */
static int enable;
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;

module_param(index, int, 0444);
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for " DRIVER_NAME);
module_param(id, charp, 0444);
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for " DRIVER_NAME);
module_param(enable, bool, 0444);
MODULE_PARM_DESC(enable, "Enable for " DRIVER_NAME);
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable " DRIVER_NAME);

static struct pci_device_id snd_cs5535audio_ids[] __devinitdata = {
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO) },
Expand Down Expand Up @@ -358,8 +357,12 @@ static int __devinit snd_cs5535audio_probe(struct pci_dev *pci,

if (dev >= SNDRV_CARDS)
return -ENODEV;
if (!enable[dev]) {
dev++;
return -ENOENT;
}

card = snd_card_new(index, id, THIS_MODULE, 0);
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;

Expand Down
3 changes: 2 additions & 1 deletion sound/pci/es1938.c
Original file line number Diff line number Diff line change
Expand Up @@ -1756,7 +1756,8 @@ static int __devinit snd_es1938_probe(struct pci_dev *pci,
}
}
if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
chip->mpu_port, 1, chip->irq, 0, &chip->rmidi) < 0) {
chip->mpu_port, MPU401_INFO_INTEGRATED,
chip->irq, 0, &chip->rmidi) < 0) {
printk(KERN_ERR "es1938: unable to initialize MPU-401\n");
} else {
// this line is vital for MIDI interrupt handling on ess-solo1
Expand Down
3 changes: 2 additions & 1 deletion sound/pci/es1968.c
Original file line number Diff line number Diff line change
Expand Up @@ -2727,7 +2727,8 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci,
}
if (enable_mpu[dev]) {
if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
chip->io_port + ESM_MPU401_PORT, 1,
chip->io_port + ESM_MPU401_PORT,
MPU401_INFO_INTEGRATED,
chip->irq, 0, &chip->rmidi)) < 0) {
printk(KERN_WARNING "es1968: skipping MPU-401 MIDI support..\n");
}
Expand Down
3 changes: 2 additions & 1 deletion sound/pci/fm801.c
Original file line number Diff line number Diff line change
Expand Up @@ -1448,7 +1448,8 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
return err;
}
if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801,
FM801_REG(chip, MPU401_DATA), 1,
FM801_REG(chip, MPU401_DATA),
MPU401_INFO_INTEGRATED,
chip->irq, 0, &chip->rmidi)) < 0) {
snd_card_free(card);
return err;
Expand Down
Loading

0 comments on commit 302e4c2

Please sign in to comment.