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

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

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

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

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

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

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

在sound/usb/card.c

 static struct usb_driver usb_audio_driver = {
.name = "snd-usb-audio",
.probe = usb_audio_probe,
.disconnect = usb_audio_disconnect,
.suspend = usb_audio_suspend,
.resume = usb_audio_resume,
.id_table = usb_audio_ids,
.supports_autosuspend = ,
};

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

 static int usb_audio_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct snd_usb_audio *chip;
chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
if (chip) {
usb_set_intfdata(intf, chip);
return ;
} else
return -EIO;
} // linux-3.4.y/sound/usb/quirks.c
int snd_usb_apply_boot_quirk(struct usb_device *dev,
struct usb_interface *intf,
const struct snd_usb_audio_quirk *quirk)
{
u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct)); switch (id) {
case USB_ID(0x041e, 0x3000):
/* SB Extigy needs special boot-up sequence */
/* if more models come, this will go to the quirk list. */
return snd_usb_extigy_boot_quirk(dev, intf); case USB_ID(0x041e, 0x3020):
/* SB Audigy 2 NX needs its own boot-up magic, too */
return snd_usb_audigy2nx_boot_quirk(dev); case USB_ID(0x10f5, 0x0200):
/* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
return snd_usb_cm106_boot_quirk(dev); case USB_ID(0x0d8c, 0x0102):
/* C-Media CM6206 / CM106-Like Sound Device */
case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */
return snd_usb_cm6206_boot_quirk(dev); case USB_ID(0x133e, 0x0815):
/* Access Music VirusTI Desktop */
return snd_usb_accessmusic_boot_quirk(dev); case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */
case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
return snd_usb_nativeinstruments_boot_quirk(dev);
case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */
return snd_usb_fasttrackpro_boot_quirk(dev);
} return ;
}

snd_usb_audio_probe:

 /*
* probe the active usb device
*
* note that this can be called multiple times per a device, when it
* includes multiple audio control interfaces.
*
* thus we check the usb device pointer and creates the card instance
* only at the first time. the successive calls of this function will
* append the pcm interface to the corresponding card.
*/
static struct snd_usb_audio *
snd_usb_audio_probe(struct usb_device *dev,
struct usb_interface *intf,
const struct usb_device_id *usb_id)
{
const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
int i, err;
struct snd_usb_audio *chip;
struct usb_host_interface *alts;
int ifnum;
u32 id; alts = &intf->altsetting[];
ifnum = get_iface_desc(alts)->bInterfaceNumber;
id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
if (quirk && quirk->ifnum >= && ifnum != quirk->ifnum)
goto __err_val; if (snd_usb_apply_boot_quirk(dev, intf, quirk) < )
goto __err_val; /*
* found a config. now register to ALSA
*/ /* check whether it's already registered */
chip = NULL;
mutex_lock(&register_mutex);
for (i = ; i < SNDRV_CARDS; i++) {
if (usb_chip[i] && usb_chip[i]->dev == dev) {
if (usb_chip[i]->shutdown) {
snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance\n");
goto __error;
}
chip = usb_chip[i];
chip->probing = ;
break;
}
}
if (! chip) {
/* it's a fresh one.
* now look for an empty slot and create a new card instance
*/
for (i = ; i < SNDRV_CARDS; i++)
if (enable[i] && ! usb_chip[i] &&
(vid[i] == - || vid[i] == USB_ID_VENDOR(id)) &&
(pid[i] == - || pid[i] == USB_ID_PRODUCT(id))) {
if (snd_usb_audio_create(dev, i, quirk, &chip) < ) {
goto __error;
}
snd_card_set_dev(chip->card, &intf->dev);
chip->pm_intf = intf;
break;
}
if (!chip) {
printk(KERN_ERR "no available usb audio device\n");
goto __error;
}
} /*
* For devices with more than one control interface, we assume the
* first contains the audio controls. We might need a more specific
* check here in the future.
*/
if (!chip->ctrl_intf)
chip->ctrl_intf = alts; chip->txfr_quirk = ;
err = ; /* continue */
if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {
/* need some special handlings */
if ((err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk)) < )
goto __error;
} if (err > ) {
/* create normal USB audio interfaces */
if (snd_usb_create_streams(chip, ifnum) < ||
snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < ) {
goto __error;
}
} /* we are allowed to call snd_card_register() many times */
if (snd_card_register(chip->card) < ) {
goto __error;
} usb_chip[chip->index] = chip;
chip->num_interfaces++;
chip->probing = ;
mutex_unlock(&register_mutex);
return chip; __error:
if (chip) {
if (!chip->num_interfaces)
snd_card_free(chip->card);
chip->probing = ;
}
mutex_unlock(&register_mutex);
__err_val:
return NULL;
}

probe依次调用了:

 snd_usb_apply_boot_quirk
snd_usb_audio_create
snd_usb_create_quirk
snd_usb_create_streams
snd_usb_create_stream
snd_usb_parse_audio_interface 这里根据usb的信息解析成pcm参数(如声道数量,采样率等等) snd_usb_create_mixer
snd_card_register

总结:

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

bNrChannels
bSubframeSize
bBitResolution
bSamFreqType Discrete
tSamFreq[ ]
tSamFreq[ ]
tSamFreq[ ]
tSamFreq[ ]
tSamFreq[ ]
tSamFreq[ ]
tSamFreq[ ]
声道1,位深16,波特率8000~48000。
 
												

Android4.0 声卡配置-高通msm8916移植的更多相关文章

  1. Android字符设备驱动开发基于高通msm8916【原创 】

    本人才疏浅学,写一篇文档总结自己在msm8916平台上移植自己编写的简单的字符设备驱动开发的整个流程.这个小项目的主要功能是开发一个简单的APP,APP通过JNI去调用位于kernel的字符设备驱动. ...

  2. 红米Note5进入全网通5.0时代,其实是高通已经落后了!

    高通早在去年12月份就正式发布了新一代的骁龙845处理器,接下来就是人们对于搭载骁龙845处理器的手机充满期待,可是转眼到了2018年的3月份,目前已经发布的高端旗舰新机却只有三星S9和三星S9+,而 ...

  3. 高通spi 屏幕 -lk代码分析

    lk SPI驱动 1. 初始化时钟 在lk中,我们是从kmain开始执行下来的,而执行顺序则是先初始化时钟,也就是在platform_early_init函数中开始执行的: 在这里我们需要修改这个函数 ...

  4. 高通 display 驱动【转】

    高通display驱动 0. 关键字 MDSS : 高通平台lcd multimedia Display sub system DSI: Display Serial Interface qcom,m ...

  5. 简谈高通Trustzone的实现【转】

    本文转载自:https://blog.csdn.net/hovan/article/details/42520879 从trust zone之我见知道,支持trustzone的芯片会跑在两个世界. 普 ...

  6. 高通Quick Charge高速充电原理分析

    1 QC 2.0 1.1 高通Quick Charge 2.0 高速充电原理分析 高通的QC2.0高速充电须要手机端和充电器都要支持才行. 当将充电器端通过数据线连到手机上时,充电器默认的是将D+和D ...

  7. 高通 NXP NFC(PN547PN548) 移植流程 android6.0

    一.驱动部分 首先向NXP 的 fae要android 6.0 bring up的代码,如:NFC_NCIHALx_AR0F.4.3.0_M_NoSE 结构目录如下: 1. 添加驱动文件 高通平台需使 ...

  8. 【转】高通平台android 环境配置编译及开发经验总结

    原文网址:http://blog.csdn.net/dongwuming/article/details/12784535 1.高通平台android开发总结 1.1 搭建高通平台环境开发环境 在高通 ...

  9. 高通平台MSM8916LCM模块移植(一)-bootloader部分

    此次移植打算分成两个模块来说,bootloader部分和kernel部分.在实际的移植调试过程中也是这么分成了两个部分分别调试. 高通平台中的bootloader叫做LK(Little Kernel, ...

随机推荐

  1. redis参数配置说明

    参数说明redis.conf 配置项说明如下:1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程  daemonize no2. 当Redis以守护进程方式运行 ...

  2. select的限制以及poll的使用

    1.先说select在多路IO中的限制:1)linux中每个程序能够打开的最多文件描述符是有限制的.默认是1024.可以通过ulimit -n进行查看和修改: xcy@xcy-virtual-mach ...

  3. Caused by: org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2

    异常信息 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with na ...

  4. 初识Avro

    Avro是Hadoop生态圈的一部分,由Hadoop的创始人Doug Cutting牵头开发,当前最新版本1.8.2.Avro是一个数据序列化系统,设计用于支持大批量数据交换的应用.它的主要特点有: ...

  5. 细谈最近上线的Vue2.0项目(一)

    8月初离职,来到现在的新东家负责一个新的项目.而我最近开发的两个webapp一直都是以Vue为主,这也是这篇文章的由来. 正文前的胡侃&一点点吐槽 在经历了两个公司不同的项目后,发现都存在一个 ...

  6. shell 踩坑记

    变量赋值时,等号两边不能有空格: 在判断表达式中,不论是 [ -n "$1" ] 还是 [ -f  "$1" ] 都要在变量两侧加上双引号: 在使用与或非判断式 ...

  7. Nodejs密集型CPU解决方案

    首先说一下nodejs单线程的优势: 高性能,与php相比,避免了频繁创建切换线程的开销,执行更加迅速,资源占用小. 线程安全,不用担心同一变量被多线程读写,造成程序崩溃. 单线程的异步和非阻塞,其实 ...

  8. Ansible 系列之 Patterns

    Ansible 之 Patterns 1.Ansible中的Patterns决定了我们要管理哪个主机,意思是与哪些主机进行交互. 我们将在Ad-Hoc(Ad-Hoc 是指 临时执行的命令,要结合着模块 ...

  9. css3毛玻璃模糊效果

    CSS3 blur滤镜实现如下测试代码: .blur { -webkit-filter: blur(10px); /* Chrome, Opera */ -moz-filter: blur(10px) ...

  10. 初识CSS3

    1.CSS规则由两部分构成,即选择器和声明器  声明必须放在{}中并且声明可以是一条或者多条  每条声明由一个属性和值构成,属性和值用冒号分开,每条语句用英文冒号分开 注意:   css的最后一条声明 ...