lkml.org 
[lkml]   [2006]   [Mar]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [ALSA] AdLib FM card driver
    Takashi Iwai wrote:

    >> then the ID is used as is and everything seems fine. I assume that
    >> either the space check could go or that a passed in ID should be
    >> subjected to it as well? (that function also deletes all !isalnum's from
    >> the shortname such as <underscore> which, again, is fine when passed in
    >> manually).
    >
    > The space check is there to retrieve the second word from the
    > shortname, because the length of id string is much shorter. In most
    > cases, you likely have names like "Vendor DeviceXXXX". Then only
    > DeviceXXX is extracted. If it matters, pass a string without space in
    > the shortname field.

    Okay I guess. No, "FM" is fine by me...

    >> +static int __devinit snd_adlib_probe(struct platform_device *device)
    > (snip)
    >> + card->private_data = request_region(port[i], 4, CRD_NAME);
    >> + if (!card->private_data) {
    >> + snd_printk(KERN_ERR DRV_NAME ": could not grab ports\n");
    >> + snd_card_free(card);
    >> + return -EINVAL;
    >> + }
    >
    > -EBUSY would be more suitable (although it's ignored later).

    Yes.

    >> + card->private_free = snd_adlib_free;
    >> +
    >> + if (snd_opl3_create(card, port[i], port[i] + 2, OPL3_HW_AUTO, 1, &opl3) < 0) {
    >> + snd_printk(KERN_ERR DRV_NAME ": could not create OPL\n");
    >> + snd_card_free(card);
    >> + return -EINVAL;
    >> + }
    >
    > Better to keep the original error value?

    This is a problem unfortunately. I haven't yet regenerated the patch to
    continue on IS_ERR that I sent a few days ago against -mm as you asked
    due to the issue of driver_probe_device() specifically ignoring -ENODEV
    and -ENXIO. I've looked, and both of these are values ALSA internals can
    and do return so if we just propagate the value up, we might propagate
    an -ENODEV or -ENXIO; platform_driver_register_simple() would then
    return success and let the driver load.

    From the perspective of these ISA drivers, deleting the -ENODEV |
    -ENXIO check from driver_probe_device() would be best. And I guess
    making it dependent on hotpluggability of a bus is best all around, but
    this is waiting for comment from greg.

    > Ditto. Maybe better to have a single error exit with snd_card_free()?

    Attached is a version that simply jumps to a return -EINVAL, which would
    also be the easiest way to fixup the others, at least for -stable. If
    you disagree though, in the next message I'll sent a version that does
    register the error, but for now just turns them into -EINVAL before
    returning.

    Given that the specific error is ignored anyway I prefer this first one
    myself but both are fine by me. I'll use the method you prefer with the
    others as well.

    Rene

    Index: local/sound/isa/adlib.c
    ===================================================================
    --- /dev/null 1970-01-01 00:00:00.000000000 +0000
    +++ local/sound/isa/adlib.c 2006-03-27 17:03:08.000000000 +0200
    @@ -0,0 +1,153 @@
    +/*
    + * AdLib FM card driver.
    + */
    +
    +#include <sound/driver.h>
    +#include <linux/kernel.h>
    +#include <linux/module.h>
    +#include <linux/platform_device.h>
    +#include <sound/core.h>
    +#include <sound/initval.h>
    +#include <sound/opl3.h>
    +
    +#define CRD_NAME "AdLib FM"
    +#define DRV_NAME "snd_adlib"
    +
    +MODULE_DESCRIPTION(CRD_NAME);
    +MODULE_AUTHOR("Rene Herman");
    +MODULE_LICENSE("GPL");
    +
    +static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
    +static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
    +static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
    +static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
    +
    +module_param_array(index, int, NULL, 0444);
    +MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
    +module_param_array(id, charp, NULL, 0444);
    +MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
    +module_param_array(enable, bool, NULL, 0444);
    +MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
    +module_param_array(port, long, NULL, 0444);
    +MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
    +
    +static struct platform_device *devices[SNDRV_CARDS];
    +
    +static void snd_adlib_free(struct snd_card *card)
    +{
    + release_and_free_resource(card->private_data);
    +}
    +
    +static int __devinit snd_adlib_probe(struct platform_device *device)
    +{
    + struct snd_card *card;
    + struct snd_opl3 *opl3;
    +
    + int i = device->id;
    +
    + if (port[i] == SNDRV_AUTO_PORT) {
    + snd_printk(KERN_ERR DRV_NAME ": please specify port\n");
    + goto out0;
    + }
    +
    + card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
    + if (!card) {
    + snd_printk(KERN_ERR DRV_NAME ": could not create card\n");
    + goto out0;
    + }
    +
    + card->private_data = request_region(port[i], 4, CRD_NAME);
    + if (!card->private_data) {
    + snd_printk(KERN_ERR DRV_NAME ": could not grab ports\n");
    + goto out1;
    + }
    + card->private_free = snd_adlib_free;
    +
    + if (snd_opl3_create(card, port[i], port[i] + 2, OPL3_HW_AUTO, 1, &opl3) < 0) {
    + snd_printk(KERN_ERR DRV_NAME ": could not create OPL\n");
    + goto out1;
    + }
    +
    + if (snd_opl3_hwdep_new(opl3, 0, 0, NULL) < 0) {
    + snd_printk(KERN_ERR DRV_NAME ": could not create FM\n");
    + goto out1;
    + }
    +
    + strcpy(card->driver, DRV_NAME);
    + strcpy(card->shortname, CRD_NAME);
    + sprintf(card->longname, CRD_NAME " at %#lx", port[i]);
    +
    + snd_card_set_dev(card, &device->dev);
    +
    + if (snd_card_register(card) < 0) {
    + snd_printk(KERN_ERR DRV_NAME ": could not register card\n");
    + goto out1;
    + }
    +
    + platform_set_drvdata(device, card);
    + return 0;
    +
    +out1: snd_card_free(card);
    +out0: return -EINVAL;
    +}
    +
    +static int __devexit snd_adlib_remove(struct platform_device *device)
    +{
    + snd_card_free(platform_get_drvdata(device));
    + platform_set_drvdata(device, NULL);
    + return 0;
    +}
    +
    +static struct platform_driver snd_adlib_driver = {
    + .probe = snd_adlib_probe,
    + .remove = __devexit_p(snd_adlib_remove),
    +
    + .driver = {
    + .name = DRV_NAME
    + }
    +};
    +
    +static int __init alsa_card_adlib_init(void)
    +{
    + int i, cards;
    +
    + if (platform_driver_register(&snd_adlib_driver) < 0) {
    + snd_printk(KERN_ERR DRV_NAME ": could not register driver\n");
    + return -ENODEV;
    + }
    +
    + for (cards = 0, i = 0; i < SNDRV_CARDS; i++) {
    + struct platform_device *device;
    +
    + if (!enable[i])
    + continue;
    +
    + device = platform_device_register_simple(DRV_NAME, i, NULL, 0);
    + if (IS_ERR(device))
    + continue;
    +
    + devices[i] = device;
    + cards++;
    + }
    +
    + if (!cards) {
    +#ifdef MODULE
    + printk(KERN_ERR CRD_NAME " soundcard not found or device busy\n");
    +#endif
    + platform_driver_unregister(&snd_adlib_driver);
    + return -ENODEV;
    + }
    + return 0;
    +}
    +
    +static void __exit alsa_card_adlib_exit(void)
    +{
    + int i;
    +
    + for (i = 0; i < SNDRV_CARDS; i++)
    + platform_device_unregister(devices[i]);
    + platform_driver_unregister(&snd_adlib_driver);
    +}
    +
    +module_init(alsa_card_adlib_init);
    +module_exit(alsa_card_adlib_exit);
    Index: local/sound/isa/Kconfig
    ===================================================================
    --- local.orig/sound/isa/Kconfig 2006-03-27 16:53:56.000000000 +0200
    +++ local/sound/isa/Kconfig 2006-03-27 16:54:25.000000000 +0200
    @@ -11,6 +11,15 @@ config SND_CS4231_LIB
    tristate
    select SND_PCM

    +config SND_ADLIB
    + tristate "AdLib FM card"
    + select SND_OPL3_LIB
    + help
    + Say Y here to include support for AdLib FM cards.
    +
    + To compile this driver as a module, choose M here: the module
    + will be called snd-adlib.
    +
    config SND_AD1816A
    tristate "Analog Devices SoundPort AD1816A"
    depends on SND && PNP && ISA
    Index: local/sound/isa/Makefile
    ===================================================================
    --- local.orig/sound/isa/Makefile 2006-03-27 16:53:56.000000000 +0200
    +++ local/sound/isa/Makefile 2006-03-27 16:54:25.000000000 +0200
    @@ -3,6 +3,7 @@
    # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
    #

    +snd-adlib-objs := adlib.o
    snd-als100-objs := als100.o
    snd-azt2320-objs := azt2320.o
    snd-cmi8330-objs := cmi8330.o
    @@ -13,6 +14,7 @@ snd-sgalaxy-objs := sgalaxy.o
    snd-sscape-objs := sscape.o

    # Toplevel Module Dependency
    +obj-$(CONFIG_SND_ADLIB) += snd-adlib.o
    obj-$(CONFIG_SND_ALS100) += snd-als100.o
    obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o
    obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o
    Index: local/Documentation/sound/alsa/ALSA-Configuration.txt
    ===================================================================
    --- local.orig/Documentation/sound/alsa/ALSA-Configuration.txt 2006-03-27 16:53:56.000000000 +0200
    +++ local/Documentation/sound/alsa/ALSA-Configuration.txt 2006-03-27 16:54:25.000000000 +0200
    @@ -120,6 +120,34 @@ Prior to version 0.9.0rc4 options had a
    enable - enable card
    - Default: enabled, for PCI and ISA PnP cards

    + Module snd-adlib
    + ----------------
    +
    + Module for AdLib FM cards.
    +
    + port - port # for OPL chip
    +
    + This module supports multiple cards. It does not support autoprobe, so
    + the port must be specified. For actual AdLib FM cards it will be 0x388.
    + Note that this card does not have PCM support and no mixer; only FM
    + synthesis.
    +
    + Make sure you have "sbiload" from the alsa-tools package available and,
    + after loading the module, find out the assigned ALSA sequencer port
    + number through "sbiload -l". Example output:
    +
    + Port Client name Port name
    + 64:0 OPL2 FM synth OPL2 FM Port
    +
    + Load the std.sb and drums.sb patches also supplied by sbiload:
    +
    + sbiload -p 64:0 std.sb drums.sb
    +
    + If you use this driver to drive an OPL3, you can use std.o3 and drums.o3
    + instead. To have the card produce sound, use aplaymidi from alsa-utils:
    +
    + aplaymidi -p 64:0 foo.mid
    +
    Module snd-ad1816a
    ------------------
    \
     
     \ /
      Last update: 2006-03-27 18:26    [W:3.324 / U:0.128 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site