Android4.0 声卡配置-高通msm8916移植
一个正常的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_quirk和snd_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(®ister_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(®ister_mutex);
return chip; __error:
if (chip) {
if (!chip->num_interfaces)
snd_card_free(chip->card);
chip->probing = ;
}
mutex_unlock(®ister_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[ ]
Android4.0 声卡配置-高通msm8916移植的更多相关文章
- Android字符设备驱动开发基于高通msm8916【原创 】
本人才疏浅学,写一篇文档总结自己在msm8916平台上移植自己编写的简单的字符设备驱动开发的整个流程.这个小项目的主要功能是开发一个简单的APP,APP通过JNI去调用位于kernel的字符设备驱动. ...
- 红米Note5进入全网通5.0时代,其实是高通已经落后了!
高通早在去年12月份就正式发布了新一代的骁龙845处理器,接下来就是人们对于搭载骁龙845处理器的手机充满期待,可是转眼到了2018年的3月份,目前已经发布的高端旗舰新机却只有三星S9和三星S9+,而 ...
- 高通spi 屏幕 -lk代码分析
lk SPI驱动 1. 初始化时钟 在lk中,我们是从kmain开始执行下来的,而执行顺序则是先初始化时钟,也就是在platform_early_init函数中开始执行的: 在这里我们需要修改这个函数 ...
- 高通 display 驱动【转】
高通display驱动 0. 关键字 MDSS : 高通平台lcd multimedia Display sub system DSI: Display Serial Interface qcom,m ...
- 简谈高通Trustzone的实现【转】
本文转载自:https://blog.csdn.net/hovan/article/details/42520879 从trust zone之我见知道,支持trustzone的芯片会跑在两个世界. 普 ...
- 高通Quick Charge高速充电原理分析
1 QC 2.0 1.1 高通Quick Charge 2.0 高速充电原理分析 高通的QC2.0高速充电须要手机端和充电器都要支持才行. 当将充电器端通过数据线连到手机上时,充电器默认的是将D+和D ...
- 高通 NXP NFC(PN547PN548) 移植流程 android6.0
一.驱动部分 首先向NXP 的 fae要android 6.0 bring up的代码,如:NFC_NCIHALx_AR0F.4.3.0_M_NoSE 结构目录如下: 1. 添加驱动文件 高通平台需使 ...
- 【转】高通平台android 环境配置编译及开发经验总结
原文网址:http://blog.csdn.net/dongwuming/article/details/12784535 1.高通平台android开发总结 1.1 搭建高通平台环境开发环境 在高通 ...
- 高通平台MSM8916LCM模块移植(一)-bootloader部分
此次移植打算分成两个模块来说,bootloader部分和kernel部分.在实际的移植调试过程中也是这么分成了两个部分分别调试. 高通平台中的bootloader叫做LK(Little Kernel, ...
随机推荐
- [UI列表]LoopScrollRect无限滑动不卡顿
应用场景 对于背包界面,排行榜列表,聊天消息,等有大量的UI列表的界面,常规做法是为每一条数据生成一个格子,在数据量越大的情况下,会生成越来越多的Gameobject,引起卡顿. 这篇文章讲述的就是解 ...
- jstl常用语句
1.select框中if选中,下面的语句实现从后台给过来一个category实体,如果category的categoryType为指定的值,则选中. <select class="fo ...
- 在Windows上运行Spark程序
一.下载Saprk程序 https://d3kbcqa49mib13.cloudfront.net/spark-2.1.1-bin-hadoop2.7.tgz 解压到d:\spark-2.1.1-bi ...
- Android打赏功能:支付宝转账
适用于个人开发者开发的APP中,让用户打赏给作者,实质上进行支付宝转账到指定账号的功能. 一.打开'支付宝'APP ,点击'收款'功能 ,将收款码(二维码)图片保存到手机上(进一步移到电脑上). 二. ...
- 合并查询结果集UNION(去重), UNION ALL(不去重),INTERSECT(交集),MINUS(差集,第一个结果集减去第二个结果集,第一个结果集中不在第二个结果集中的记录行),[NOT] EXIST
MINUS配合[NOT] EXIST使用可以查询出包含符合某个条件的多记录的其他记录, 举例: 顾客A买了商品2.4.6 顾客B买了商品1.2.4 顾客C买了商品4.6 顾客D买了商品1.2.4.6 ...
- (转)iOS-Runtime知识点整理
runtime简介 因为Objc是一门动态语言,所以它总是想办法把一些决定工作从编译连接推迟到运行时.也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的 ...
- 【Zookeeper】源码分析之服务器(五)之ObserverZooKeeperServer
一.前言 前面分析了FollowerZooKeeperServer,接着分析ObserverZooKeeperServer. 二.ObserverZooKeeperServer源码分析 2.1 类的继 ...
- Linux中dos2unix批量转换
有时候遇到多层目录下的文件格式需要转换,dos2unix 没有-r之类的递归指令,所以需要与find还有管道结合. find -type f | xargs dos2unix -o
- springboot学习(一)——helloworld
以下内容,如有问题,烦请指出,谢谢 springboot出来也很久了,以前零散地学习了不少,不过很长时间了都没有在实际中使用过了,忘了不少,因此要最近准备抽时间系统的学习积累下springboot,给 ...
- 插值查找C++
和上一篇折半查找很类似,只有四则运算不一样,思想类似. 只是在插值查找的过程中,考虑了查找键的值. #include <iostream> using namespace std; //需 ...