Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Linux driver for M2Tech hiFace compatible devices
0004  *
0005  * Copyright 2012-2013 (C) M2TECH S.r.l and Amarula Solutions B.V.
0006  *
0007  * Authors:  Michael Trimarchi <michael@amarulasolutions.com>
0008  *           Antonio Ospite <ao2@amarulasolutions.com>
0009  *
0010  * The driver is based on the work done in TerraTec DMX 6Fire USB
0011  */
0012 
0013 #include <linux/module.h>
0014 #include <linux/slab.h>
0015 #include <sound/initval.h>
0016 
0017 #include "chip.h"
0018 #include "pcm.h"
0019 
0020 MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>");
0021 MODULE_AUTHOR("Antonio Ospite <ao2@amarulasolutions.com>");
0022 MODULE_DESCRIPTION("M2Tech hiFace USB-SPDIF audio driver");
0023 MODULE_LICENSE("GPL v2");
0024 
0025 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
0026 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */
0027 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
0028 
0029 #define DRIVER_NAME "snd-usb-hiface"
0030 #define CARD_NAME "hiFace"
0031 
0032 module_param_array(index, int, NULL, 0444);
0033 MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
0034 module_param_array(id, charp, NULL, 0444);
0035 MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
0036 module_param_array(enable, bool, NULL, 0444);
0037 MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
0038 
0039 static DEFINE_MUTEX(register_mutex);
0040 
0041 struct hiface_vendor_quirk {
0042     const char *device_name;
0043     u8 extra_freq;
0044 };
0045 
0046 static int hiface_chip_create(struct usb_interface *intf,
0047                   struct usb_device *device, int idx,
0048                   const struct hiface_vendor_quirk *quirk,
0049                   struct hiface_chip **rchip)
0050 {
0051     struct snd_card *card = NULL;
0052     struct hiface_chip *chip;
0053     int ret;
0054     int len;
0055 
0056     *rchip = NULL;
0057 
0058     /* if we are here, card can be registered in alsa. */
0059     ret = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE,
0060                sizeof(*chip), &card);
0061     if (ret < 0) {
0062         dev_err(&device->dev, "cannot create alsa card.\n");
0063         return ret;
0064     }
0065 
0066     strscpy(card->driver, DRIVER_NAME, sizeof(card->driver));
0067 
0068     if (quirk && quirk->device_name)
0069         strscpy(card->shortname, quirk->device_name, sizeof(card->shortname));
0070     else
0071         strscpy(card->shortname, "M2Tech generic audio", sizeof(card->shortname));
0072 
0073     strlcat(card->longname, card->shortname, sizeof(card->longname));
0074     len = strlcat(card->longname, " at ", sizeof(card->longname));
0075     if (len < sizeof(card->longname))
0076         usb_make_path(device, card->longname + len,
0077                   sizeof(card->longname) - len);
0078 
0079     chip = card->private_data;
0080     chip->dev = device;
0081     chip->card = card;
0082 
0083     *rchip = chip;
0084     return 0;
0085 }
0086 
0087 static int hiface_chip_probe(struct usb_interface *intf,
0088                  const struct usb_device_id *usb_id)
0089 {
0090     const struct hiface_vendor_quirk *quirk = (struct hiface_vendor_quirk *)usb_id->driver_info;
0091     int ret;
0092     int i;
0093     struct hiface_chip *chip;
0094     struct usb_device *device = interface_to_usbdev(intf);
0095 
0096     ret = usb_set_interface(device, 0, 0);
0097     if (ret != 0) {
0098         dev_err(&device->dev, "can't set first interface for " CARD_NAME " device.\n");
0099         return -EIO;
0100     }
0101 
0102     /* check whether the card is already registered */
0103     chip = NULL;
0104     mutex_lock(&register_mutex);
0105 
0106     for (i = 0; i < SNDRV_CARDS; i++)
0107         if (enable[i])
0108             break;
0109 
0110     if (i >= SNDRV_CARDS) {
0111         dev_err(&device->dev, "no available " CARD_NAME " audio device\n");
0112         ret = -ENODEV;
0113         goto err;
0114     }
0115 
0116     ret = hiface_chip_create(intf, device, i, quirk, &chip);
0117     if (ret < 0)
0118         goto err;
0119 
0120     ret = hiface_pcm_init(chip, quirk ? quirk->extra_freq : 0);
0121     if (ret < 0)
0122         goto err_chip_destroy;
0123 
0124     ret = snd_card_register(chip->card);
0125     if (ret < 0) {
0126         dev_err(&device->dev, "cannot register " CARD_NAME " card\n");
0127         goto err_chip_destroy;
0128     }
0129 
0130     mutex_unlock(&register_mutex);
0131 
0132     usb_set_intfdata(intf, chip);
0133     return 0;
0134 
0135 err_chip_destroy:
0136     snd_card_free(chip->card);
0137 err:
0138     mutex_unlock(&register_mutex);
0139     return ret;
0140 }
0141 
0142 static void hiface_chip_disconnect(struct usb_interface *intf)
0143 {
0144     struct hiface_chip *chip;
0145     struct snd_card *card;
0146 
0147     chip = usb_get_intfdata(intf);
0148     if (!chip)
0149         return;
0150 
0151     card = chip->card;
0152 
0153     /* Make sure that the userspace cannot create new request */
0154     snd_card_disconnect(card);
0155 
0156     hiface_pcm_abort(chip);
0157     snd_card_free_when_closed(card);
0158 }
0159 
0160 static const struct usb_device_id device_table[] = {
0161     {
0162         USB_DEVICE(0x04b4, 0x0384),
0163         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0164             .device_name = "Young",
0165             .extra_freq = 1,
0166         }
0167     },
0168     {
0169         USB_DEVICE(0x04b4, 0x930b),
0170         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0171             .device_name = "hiFace",
0172         }
0173     },
0174     {
0175         USB_DEVICE(0x04b4, 0x931b),
0176         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0177             .device_name = "North Star",
0178         }
0179     },
0180     {
0181         USB_DEVICE(0x04b4, 0x931c),
0182         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0183             .device_name = "W4S Young",
0184         }
0185     },
0186     {
0187         USB_DEVICE(0x04b4, 0x931d),
0188         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0189             .device_name = "Corrson",
0190         }
0191     },
0192     {
0193         USB_DEVICE(0x04b4, 0x931e),
0194         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0195             .device_name = "AUDIA",
0196         }
0197     },
0198     {
0199         USB_DEVICE(0x04b4, 0x931f),
0200         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0201             .device_name = "SL Audio",
0202         }
0203     },
0204     {
0205         USB_DEVICE(0x04b4, 0x9320),
0206         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0207             .device_name = "Empirical",
0208         }
0209     },
0210     {
0211         USB_DEVICE(0x04b4, 0x9321),
0212         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0213             .device_name = "Rockna",
0214         }
0215     },
0216     {
0217         USB_DEVICE(0x249c, 0x9001),
0218         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0219             .device_name = "Pathos",
0220         }
0221     },
0222     {
0223         USB_DEVICE(0x249c, 0x9002),
0224         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0225             .device_name = "Metronome",
0226         }
0227     },
0228     {
0229         USB_DEVICE(0x249c, 0x9006),
0230         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0231             .device_name = "CAD",
0232         }
0233     },
0234     {
0235         USB_DEVICE(0x249c, 0x9008),
0236         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0237             .device_name = "Audio Esclusive",
0238         }
0239     },
0240     {
0241         USB_DEVICE(0x249c, 0x931c),
0242         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0243             .device_name = "Rotel",
0244         }
0245     },
0246     {
0247         USB_DEVICE(0x249c, 0x932c),
0248         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0249             .device_name = "Eeaudio",
0250         }
0251     },
0252     {
0253         USB_DEVICE(0x245f, 0x931c),
0254         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0255             .device_name = "CHORD",
0256         }
0257     },
0258     {
0259         USB_DEVICE(0x25c6, 0x9002),
0260         .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
0261             .device_name = "Vitus",
0262         }
0263     },
0264     {}
0265 };
0266 
0267 MODULE_DEVICE_TABLE(usb, device_table);
0268 
0269 static struct usb_driver hiface_usb_driver = {
0270     .name = DRIVER_NAME,
0271     .probe = hiface_chip_probe,
0272     .disconnect = hiface_chip_disconnect,
0273     .id_table = device_table,
0274 };
0275 
0276 module_usb_driver(hiface_usb_driver);