Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * AdLib FM card driver.
0004  */
0005 
0006 #include <linux/kernel.h>
0007 #include <linux/module.h>
0008 #include <linux/isa.h>
0009 #include <sound/core.h>
0010 #include <sound/initval.h>
0011 #include <sound/opl3.h>
0012 
0013 #define CRD_NAME "AdLib FM"
0014 #define DEV_NAME "adlib"
0015 
0016 MODULE_DESCRIPTION(CRD_NAME);
0017 MODULE_AUTHOR("Rene Herman");
0018 MODULE_LICENSE("GPL");
0019 
0020 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
0021 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
0022 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
0023 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
0024 
0025 module_param_array(index, int, NULL, 0444);
0026 MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
0027 module_param_array(id, charp, NULL, 0444);
0028 MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
0029 module_param_array(enable, bool, NULL, 0444);
0030 MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
0031 module_param_hw_array(port, long, ioport, NULL, 0444);
0032 MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
0033 
0034 static int snd_adlib_match(struct device *dev, unsigned int n)
0035 {
0036     if (!enable[n])
0037         return 0;
0038 
0039     if (port[n] == SNDRV_AUTO_PORT) {
0040         dev_err(dev, "please specify port\n");
0041         return 0;
0042     }
0043     return 1;
0044 }
0045 
0046 static int snd_adlib_probe(struct device *dev, unsigned int n)
0047 {
0048     struct snd_card *card;
0049     struct snd_opl3 *opl3;
0050     int error;
0051 
0052     error = snd_devm_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
0053     if (error < 0) {
0054         dev_err(dev, "could not create card\n");
0055         return error;
0056     }
0057 
0058     card->private_data = devm_request_region(dev, port[n], 4, CRD_NAME);
0059     if (!card->private_data) {
0060         dev_err(dev, "could not grab ports\n");
0061         return -EBUSY;
0062     }
0063 
0064     strcpy(card->driver, DEV_NAME);
0065     strcpy(card->shortname, CRD_NAME);
0066     sprintf(card->longname, CRD_NAME " at %#lx", port[n]);
0067 
0068     error = snd_opl3_create(card, port[n], port[n] + 2, OPL3_HW_AUTO, 1, &opl3);
0069     if (error < 0) {
0070         dev_err(dev, "could not create OPL\n");
0071         return error;
0072     }
0073 
0074     error = snd_opl3_hwdep_new(opl3, 0, 0, NULL);
0075     if (error < 0) {
0076         dev_err(dev, "could not create FM\n");
0077         return error;
0078     }
0079 
0080     error = snd_card_register(card);
0081     if (error < 0) {
0082         dev_err(dev, "could not register card\n");
0083         return error;
0084     }
0085 
0086     dev_set_drvdata(dev, card);
0087     return 0;
0088 }
0089 
0090 static struct isa_driver snd_adlib_driver = {
0091     .match      = snd_adlib_match,
0092     .probe      = snd_adlib_probe,
0093 
0094     .driver     = {
0095         .name   = DEV_NAME
0096     }
0097 };
0098 
0099 module_isa_driver(snd_adlib_driver, SNDRV_CARDS);