Android4.0 声卡配置-高通msm8916移植

观书散遗帙,探古穷至妙。这篇文章主要讲述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\\n",

需要在  /kernel/arch/arm/configs目录下增加msm8916_defconfig和msm8916-perf_defconfig配置;
在AndroidBoard.mk就已经定义了我们kernel配置文件的属性:
Android4.0 声卡配置-高通msm8916移植

文章图片

 
CONFIG_SND_USB_AUDIO=y就行了,因为sound/usb/中的makefile包含了:
Android4.0 声卡配置-高通msm8916移植

文章图片

 
 
在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, 2const struct usb_device_id *id) 3 { 4struct snd_usb_audio *chip; 5chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id); 6if (chip) { 7usb_set_intfdata(intf, chip); 8return 0; 9} else 10return -EIO; 11 } 12 13 14 // linux-3.4.y/sound/usb/quirks.c 15 int snd_usb_apply_boot_quirk(struct usb_device *dev, 16struct usb_interface *intf, 17const struct snd_usb_audio_quirk *quirk) 18 { 19u32 id = USB_ID(le16_to_cpu(dev-> descriptor.idVendor), 20le16_to_cpu(dev-> descriptor.idProduct)); 21 22switch (id) { 23case USB_ID(0x041e, 0x3000): 24/* SB Extigy needs special boot-up sequence */ 25/* if more models come, this will go to the quirk list. */ 26return snd_usb_extigy_boot_quirk(dev, intf); 27 28case USB_ID(0x041e, 0x3020): 29/* SB Audigy 2 NX needs its own boot-up magic, too */ 30return snd_usb_audigy2nx_boot_quirk(dev); 31 32case USB_ID(0x10f5, 0x0200): 33/* C-Media CM106 / Turtle Beach Audio Advantage Roadie */ 34return snd_usb_cm106_boot_quirk(dev); 35 36case USB_ID(0x0d8c, 0x0102): 37/* C-Media CM6206 / CM106-Like Sound Device */ 38case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */ 39return snd_usb_cm6206_boot_quirk(dev); 40 41case USB_ID(0x133e, 0x0815): 42/* Access Music VirusTI Desktop */ 43return snd_usb_accessmusic_boot_quirk(dev); 44 45case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */ 46case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */ 47case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */ 48return snd_usb_nativeinstruments_boot_quirk(dev); 49case USB_ID(0x0763, 0x2012):/* M-Audio Fast Track Pro USB */ 50return snd_usb_fasttrackpro_boot_quirk(dev); 51} 52 53return 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, 13struct usb_interface *intf, 14const struct usb_device_id *usb_id) 15 { 16const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id-> driver_info; 17int i, err; 18struct snd_usb_audio *chip; 19struct usb_host_interface *alts; 20int ifnum; 21u32 id; 22 23alts = & intf-> altsetting[0]; 24ifnum = get_iface_desc(alts)-> bInterfaceNumber; 25id = USB_ID(le16_to_cpu(dev-> descriptor.idVendor), 26le16_to_cpu(dev-> descriptor.idProduct)); 27if (quirk & & quirk-> ifnum > = 0 & & ifnum != quirk-> ifnum) 28goto __err_val; 29 30if (snd_usb_apply_boot_quirk(dev, intf, quirk) < 0) 31goto __err_val; 32 33/* 34* found a config.now register to ALSA 35*/ 36 37/* check whether it\'s already registered */ 38chip = NULL; 39mutex_lock(& register_mutex); 40for (i = 0; i < SNDRV_CARDS; i++) { 41if (usb_chip[i] & & usb_chip[i]-> dev == dev) { 42if (usb_chip[i]-> shutdown) { 43snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance\\n"); 44goto __error; 45} 46chip = usb_chip[i]; 47chip-> probing = 1; 48break; 49} 50} 51if (! chip) { 52/* it\'s a fresh one. 53* now look for an empty slot and create a new card instance 54*/ 55for (i = 0; i < SNDRV_CARDS; i++) 56if (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))) { 59if (snd_usb_audio_create(dev, i, quirk, & chip) < 0) { 60goto __error; 61} 62snd_card_set_dev(chip-> card, & intf-> dev); 63chip-> pm_intf = intf; 64break; 65} 66if (!chip) { 67printk(KERN_ERR "no available usb audio device\\n"); 68goto __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*/ 77if (!chip-> ctrl_intf) 78chip-> ctrl_intf = alts; 79 80chip-> txfr_quirk = 0; 81err = 1; /* continue */ 82if (quirk & & quirk-> ifnum != QUIRK_NO_INTERFACE) { 83/* need some special handlings */ 84if ((err = snd_usb_create_quirk(chip, intf, & usb_audio_driver, quirk)) < 0) 85goto __error; 86} 87 88if (err > 0) { 89/* create normal USB audio interfaces */ 90if (snd_usb_create_streams(chip, ifnum) < 0 || 91snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) { 92goto __error; 93} 94} 95 96/* we are allowed to call snd_card_register() many times */ 97if (snd_card_register(chip-> card) < 0) { 98goto __error; 99} 100 101usb_chip[chip-> index] = chip; 102chip-> num_interfaces++; 103chip-> probing = 0; 104mutex_unlock(& register_mutex); 105return chip; 106 107__error: 108if (chip) { 109if (!chip-> num_interfaces) 110snd_card_free(chip-> card); 111chip-> probing = 0; 112} 113mutex_unlock(& register_mutex); 114__err_val: 115return NULL; 116 }

probe依次调用了:
【Android4.0 声卡配置-高通msm8916移植】 
1 snd_usb_apply_boot_quirk 2 snd_usb_audio_create 3 snd_usb_create_quirk 4 snd_usb_create_streams 5snd_usb_create_stream 6snd_usb_parse_audio_interface 这里根据usb的信息解析成pcm参数(如声道数量,采样率等等) 7 8 snd_usb_create_mixer 9 snd_card_register

 
总结:
UAC设备的参数是通过USB描述符确定的。比如声道是bNrChannels,位深是bBitResolution,采样率是bSamFreqType。截取其中一段说明:
bNrChannels1 bSubframeSize2 bBitResolution16 bSamFreqType7 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。   
 
 


    推荐阅读