zoukankan      html  css  js  c++  java
  • Android4.0 声卡配置-高通msm8916移植

    一个正常的UAC设备插入Android 7.0是默认打开UAC配置的,打印的log如下:

    [ 2367.490491] usb 3-3.2: new full-speed USB device number 9 using xhci_hcd
    [ 2367.580010] usb 3-3.2: New USB device found, idVendor=0d8c, idProduct=0132
    [ 2367.580018] usb 3-3.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
    [ 2367.580023] usb 3-3.2: Product: USB PnP Audio Device
    [ 2367.580027] usb 3-3.2: Manufacturer: C-Media Electronics Inc.
    [ 2367.581679] input: C-Media Electronics Inc. USB PnP Audio Device as /devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3.2/3-3.2:1.2/0003:0D8C:0132.0004/input/input18
    [ 2367.581999] hid-generic 0003:0D8C:0132.0004: input,hidraw3: USB HID v1.11 Device [C-Media Electronics Inc. USB PnP Audio Device] on usb-0000:00:14.0-3.2/input2
    [ 2367.913280] usbcore: registered new interface driver snd-usb-audio

    而Android4.0是没有默认打开,是需要进行相应的配置的;这里可以看到其驱动程序为snd-usb-audio,依据这个关键词在内核中查找到如下内容:

    1 root@ubuntu:/home/lh/work/git/ML16/kernel# grep "registered new interface driver" ./ -rn
    2 ./drivers/usb/core/driver.c:914:        pr_info("%s: registered new interface driver %s
    ",

    需要在 /kernel/arch/arm/configs目录下增加msm8916_defconfig和msm8916-perf_defconfig配置;

    在AndroidBoard.mk就已经定义了我们kernel配置文件的属性:

    CONFIG_SND_USB_AUDIO=y就行了,因为sound/usb/中的makefile包含了:

    sound/usb/card.c

    1 static struct usb_driver usb_audio_driver = {
    2     .name =     "snd-usb-audio",
    3     .probe =    usb_audio_probe,
    4     .disconnect =   usb_audio_disconnect,
    5     .suspend =  usb_audio_suspend,
    6     .resume =   usb_audio_resume,
    7     .id_table = usb_audio_ids,
    8     .supports_autosuspend = 1,
    9 };

    根据probe方法snd_usb_audio_probe调用了snd_usb_apply_boot_quirksnd_card_register,查到了:

     1 static int usb_audio_probe(struct usb_interface *intf,
     2                const struct usb_device_id *id)
     3 {
     4     struct snd_usb_audio *chip;
     5     chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
     6     if (chip) {
     7         usb_set_intfdata(intf, chip);
     8         return 0;
     9     } else
    10         return -EIO;
    11 }
    12 
    13 
    14 // linux-3.4.y/sound/usb/quirks.c
    15 int snd_usb_apply_boot_quirk(struct usb_device *dev,
    16                  struct usb_interface *intf,
    17                  const struct snd_usb_audio_quirk *quirk)
    18 {
    19     u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
    20             le16_to_cpu(dev->descriptor.idProduct));
    21 
    22     switch (id) {
    23     case USB_ID(0x041e, 0x3000):
    24         /* SB Extigy needs special boot-up sequence */
    25         /* if more models come, this will go to the quirk list. */
    26         return snd_usb_extigy_boot_quirk(dev, intf);
    27 
    28     case USB_ID(0x041e, 0x3020):
    29         /* SB Audigy 2 NX needs its own boot-up magic, too */
    30         return snd_usb_audigy2nx_boot_quirk(dev);
    31 
    32     case USB_ID(0x10f5, 0x0200):
    33         /* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
    34         return snd_usb_cm106_boot_quirk(dev);
    35 
    36     case USB_ID(0x0d8c, 0x0102):
    37         /* C-Media CM6206 / CM106-Like Sound Device */
    38     case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */
    39         return snd_usb_cm6206_boot_quirk(dev);
    40 
    41     case USB_ID(0x133e, 0x0815):
    42         /* Access Music VirusTI Desktop */
    43         return snd_usb_accessmusic_boot_quirk(dev);
    44 
    45     case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */
    46     case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
    47     case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
    48         return snd_usb_nativeinstruments_boot_quirk(dev);
    49     case USB_ID(0x0763, 0x2012):  /* M-Audio Fast Track Pro USB */
    50         return snd_usb_fasttrackpro_boot_quirk(dev);
    51     }
    52 
    53     return 0;
    54 }

    snd_usb_audio_probe:

      1 /*
      2  * probe the active usb device
      3  *
      4  * note that this can be called multiple times per a device, when it
      5  * includes multiple audio control interfaces.
      6  *
      7  * thus we check the usb device pointer and creates the card instance
      8  * only at the first time.  the successive calls of this function will
      9  * append the pcm interface to the corresponding card.
     10  */
     11 static struct snd_usb_audio *
     12 snd_usb_audio_probe(struct usb_device *dev,
     13             struct usb_interface *intf,
     14             const struct usb_device_id *usb_id)
     15 {
     16     const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
     17     int i, err;
     18     struct snd_usb_audio *chip;
     19     struct usb_host_interface *alts;
     20     int ifnum;
     21     u32 id;
     22 
     23     alts = &intf->altsetting[0];
     24     ifnum = get_iface_desc(alts)->bInterfaceNumber;
     25     id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
     26             le16_to_cpu(dev->descriptor.idProduct));
     27     if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
     28         goto __err_val;
     29 
     30     if (snd_usb_apply_boot_quirk(dev, intf, quirk) < 0)
     31         goto __err_val;
     32 
     33     /*
     34      * found a config.  now register to ALSA
     35      */
     36 
     37     /* check whether it's already registered */
     38     chip = NULL;
     39     mutex_lock(&register_mutex);
     40     for (i = 0; i < SNDRV_CARDS; i++) {
     41         if (usb_chip[i] && usb_chip[i]->dev == dev) {
     42             if (usb_chip[i]->shutdown) {
     43                 snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance
    ");
     44                 goto __error;
     45             }
     46             chip = usb_chip[i];
     47             chip->probing = 1;
     48             break;
     49         }
     50     }
     51     if (! chip) {
     52         /* it's a fresh one.
     53          * now look for an empty slot and create a new card instance
     54          */
     55         for (i = 0; i < SNDRV_CARDS; i++)
     56             if (enable[i] && ! usb_chip[i] &&
     57                 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
     58                 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
     59                 if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
     60                     goto __error;
     61                 }
     62                 snd_card_set_dev(chip->card, &intf->dev);
     63                 chip->pm_intf = intf;
     64                 break;
     65             }
     66         if (!chip) {
     67             printk(KERN_ERR "no available usb audio device
    ");
     68             goto __error;
     69         }
     70     }
     71 
     72     /*
     73      * For devices with more than one control interface, we assume the
     74      * first contains the audio controls. We might need a more specific
     75      * check here in the future.
     76      */
     77     if (!chip->ctrl_intf)
     78         chip->ctrl_intf = alts;
     79 
     80     chip->txfr_quirk = 0;
     81     err = 1; /* continue */
     82     if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {
     83         /* need some special handlings */
     84         if ((err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk)) < 0)
     85             goto __error;
     86     }
     87 
     88     if (err > 0) {
     89         /* create normal USB audio interfaces */
     90         if (snd_usb_create_streams(chip, ifnum) < 0 ||
     91             snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) {
     92             goto __error;
     93         }
     94     }
     95 
     96     /* we are allowed to call snd_card_register() many times */
     97     if (snd_card_register(chip->card) < 0) {
     98         goto __error;
     99     }
    100 
    101     usb_chip[chip->index] = chip;
    102     chip->num_interfaces++;
    103     chip->probing = 0;
    104     mutex_unlock(&register_mutex);
    105     return chip;
    106 
    107  __error:
    108     if (chip) {
    109         if (!chip->num_interfaces)
    110             snd_card_free(chip->card);
    111         chip->probing = 0;
    112     }
    113     mutex_unlock(&register_mutex);
    114  __err_val:
    115     return NULL;
    116 }

    probe依次调用了:

     

    1 snd_usb_apply_boot_quirk
    2 snd_usb_audio_create
    3 snd_usb_create_quirk
    4 snd_usb_create_streams
    5  snd_usb_create_stream
    6   snd_usb_parse_audio_interface 这里根据usb的信息解析成pcm参数(如声道数量,采样率等等)
    7 
    8 snd_usb_create_mixer
    9 snd_card_register

     

    总结:

    UAC设备的参数是通过USB描述符确定的。比如声道bNrChannels位深bBitResolution采样率bSamFreqType。截取其中一段说明:

    bNrChannels             1
    bSubframeSize           2
    bBitResolution         16
    bSamFreqType            7 Discrete
    tSamFreq[ 0]         8000
    tSamFreq[ 1]        11025
    tSamFreq[ 2]        16000
    tSamFreq[ 3]        22050
    tSamFreq[ 4]        32000
    tSamFreq[ 5]        44100
    tSamFreq[ 6]        48000
    声道1,位深16,波特率8000~48000。
     

     

    
    
  • 相关阅读:
    css
    js
    css3
    css
    深浅拷贝
    index-数据结构/算法
    es6知识点
    在vscode中配置sass savepath
    计算机基础
    element-ui使用后手记
  • 原文地址:https://www.cnblogs.com/linhaostudy/p/8183292.html
Copyright © 2011-2022 走看看