linux/sound/isa/adlib.c
<<
>>
Prefs
   1/*
   2 * AdLib FM card driver.
   3 */
   4
   5#include <linux/kernel.h>
   6#include <linux/module.h>
   7#include <linux/isa.h>
   8#include <sound/core.h>
   9#include <sound/initval.h>
  10#include <sound/opl3.h>
  11
  12#define CRD_NAME "AdLib FM"
  13#define DEV_NAME "adlib"
  14
  15MODULE_DESCRIPTION(CRD_NAME);
  16MODULE_AUTHOR("Rene Herman");
  17MODULE_LICENSE("GPL");
  18
  19static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
  20static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
  21static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
  22static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
  23
  24module_param_array(index, int, NULL, 0444);
  25MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
  26module_param_array(id, charp, NULL, 0444);
  27MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
  28module_param_array(enable, bool, NULL, 0444);
  29MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
  30module_param_hw_array(port, long, ioport, NULL, 0444);
  31MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
  32
  33static int snd_adlib_match(struct device *dev, unsigned int n)
  34{
  35        if (!enable[n])
  36                return 0;
  37
  38        if (port[n] == SNDRV_AUTO_PORT) {
  39                dev_err(dev, "please specify port\n");
  40                return 0;
  41        }
  42        return 1;
  43}
  44
  45static void snd_adlib_free(struct snd_card *card)
  46{
  47        release_and_free_resource(card->private_data);
  48}
  49
  50static int snd_adlib_probe(struct device *dev, unsigned int n)
  51{
  52        struct snd_card *card;
  53        struct snd_opl3 *opl3;
  54        int error;
  55
  56        error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
  57        if (error < 0) {
  58                dev_err(dev, "could not create card\n");
  59                return error;
  60        }
  61
  62        card->private_data = request_region(port[n], 4, CRD_NAME);
  63        if (!card->private_data) {
  64                dev_err(dev, "could not grab ports\n");
  65                error = -EBUSY;
  66                goto out;
  67        }
  68        card->private_free = snd_adlib_free;
  69
  70        strcpy(card->driver, DEV_NAME);
  71        strcpy(card->shortname, CRD_NAME);
  72        sprintf(card->longname, CRD_NAME " at %#lx", port[n]);
  73
  74        error = snd_opl3_create(card, port[n], port[n] + 2, OPL3_HW_AUTO, 1, &opl3);
  75        if (error < 0) {
  76                dev_err(dev, "could not create OPL\n");
  77                goto out;
  78        }
  79
  80        error = snd_opl3_hwdep_new(opl3, 0, 0, NULL);
  81        if (error < 0) {
  82                dev_err(dev, "could not create FM\n");
  83                goto out;
  84        }
  85
  86        error = snd_card_register(card);
  87        if (error < 0) {
  88                dev_err(dev, "could not register card\n");
  89                goto out;
  90        }
  91
  92        dev_set_drvdata(dev, card);
  93        return 0;
  94
  95out:    snd_card_free(card);
  96        return error;
  97}
  98
  99static int snd_adlib_remove(struct device *dev, unsigned int n)
 100{
 101        snd_card_free(dev_get_drvdata(dev));
 102        return 0;
 103}
 104
 105static struct isa_driver snd_adlib_driver = {
 106        .match          = snd_adlib_match,
 107        .probe          = snd_adlib_probe,
 108        .remove         = snd_adlib_remove,
 109
 110        .driver         = {
 111                .name   = DEV_NAME
 112        }
 113};
 114
 115module_isa_driver(snd_adlib_driver, SNDRV_CARDS);
 116