lc1120 codec driver

音视频全链路工程:从采集到渲染的低延迟实战指南 音视频开发已超越传统编解码范畴,演进为涵盖信号采集、实时编码、网络传输、低延迟解码与跨端同步的全链路系统工程。其核心原理在于各环节间的数据时序一致性、带宽-延迟-画质的刚性权衡,以及终端能力与协议栈的深度耦合。技术价值体现在商业敏感指标上——如会议场景中300ms音画不同步即导致体验崩盘,直播首屏超2秒流失率陡增。典型应用场景包括在线教育、远程医疗、智能安防与车载DVR等对实时性与兼容性双高要求的领域。本文聚焦真实项目中高频出现的链路失配问题,深入解析采集时序抖动、编码参数物理意义、SRT/WebRTC协议 阅读详情

一. 在/sound/soc/codec/lc1120.c中的初始化代码:

1.init/exit lc1120_i2c_driver:

static const struct i2c_device_id lc1120_i2c_id[] = {
        { "lc1120", 0 },
        { }
    };
    MODULE_DEVICE_TABLE(i2c, lc1120_i2c_id);
    /* machine i2c codec control layer */
    static struct i2c_driver lc1120_i2c_driver = {
        .driver = {
            .name = "lc1120",
            .owner = THIS_MODULE,
        },
        .probe    = lc1120_i2c_probe,   //lc1120_i2c_driver 添加完毕,就会自动运行probe.
        .remove = lc1120_i2c_remove,
        .id_table = lc1120_i2c_id,
    };
    static int __init lc1120_i2c_init(void)
    {
        int ret;
    D_ENTER;
        ret = i2c_add_driver(&lc1120_i2c_driver);   //向I2C总线,添加一个i2c_driver,lc1120_i2c_driver,就是一个i2c_driver.
        if (ret)
        {
            printk(KERN_ERR "%s: error when regsiter i2c, %d\n",
             __func__, ret);
        }
        return ret;
    }
    static void __exit lc1120_i2c_exit(void)
    {
    D_ENTER;
        i2c_del_driver(&lc1120_i2c_driver);
    }
    module_init(lc1120_i2c_init);
    module_exit(lc1120_i2c_exit);
2.lc1120_i2c_probe and lc1120_i2c_remove:
/* codec private data */
    struct lc1120_priv
    {
        struct snd_soc_codec codec;   //只包含了一个codec 和一个原子变量
        atomic_t count;
    };

    /*
     * If the i2c layer weren't so broken, we could pass this kind of data
     * around
     */
    static int lc1120_i2c_probe(struct i2c_client *client,
                 const struct i2c_device_id *id)
    {
        struct snd_soc_codec *codec;
        struct lc1120_priv *lc1120;     //lc1120_priv 是一个自定义的表示lc1120设备的结构体。
    D_ENTER;
        if (device_create_file(&client->dev, &dev_attr_reg))       //在sys中建立reg和val文件,用来与用户控件交互。
            printk(KERN_ERR "%s create sysfs reg failed\n", __func__);
        if (device_create_file(&client->dev, &dev_attr_val))
            printk(KERN_ERR "%s create sysfs val failed\n", __func__);
        lc1120 = kzalloc(sizeof(struct lc1120_priv), GFP_KERNEL);   //给lc1120_priv 申请内存.
        if (lc1120 == NULL) {
            dev_err(&client->dev, "failed to create private data\n");
            return -ENOMEM;
        }
        atomic_set(&lc1120->count, 0);    //初始化原子变量为0。
        codec = &lc1120->codec;          
        codec->dev = &client->dev;     //client设备 指向 codec 设备。
        snd_soc_codec_set_drvdata(codec, lc1120); //把lc1120 指向 codec->drvdata.
        codec->control_data = client;  //client 指向 codec->control_data
        i2c_set_clientdata(client, lc1120);   //把lc1120 指向 client->dev->device_private->driver_data
        return lc1120_register(codec);   //注册codec。
    }
    static int lc1120_i2c_remove(struct i2c_client *client)
    {
        struct lc1120_priv *lc1120 = i2c_get_clientdata(client);
    D_ENTER;
        lc1120_unregister(lc1120);   注销codec
        kfree(lc1120);
        return 0;
    }
3. lc1120_register(codec) /lc1120_unregister(codec)
static DEVICE_ATTR(reg, S_IRUGO | S_IWUGO, sys_reg_show, sys_reg_store);
    static DEVICE_ATTR(val, S_IRUGO | S_IWUGO, sys_val_show, sys_val_store);  //在sysfs中建立reg和val变量。
    static int lc1120_register(struct snd_soc_codec *codec)
    {
        int ret;
    D_ENTER;
        lc1120_codec = codec;
        codec->name = "lc1120";
        codec->owner = THIS_MODULE;
        codec->read = lc1120_read;
        codec->write = lc1120_write;
    /* TODO:
        codec->set_bias_level = lc1120_set_bias_level;
    */
        codec->dai = &lc1120_dai;   //dai 就是soc与codec通信的链接。
        codec->num_dai = 1;
        ret = snd_soc_register_codec(codec);  //标准注册codec函数。
        if (ret) {
            dev_err(codec->dev, "Failed to register codec\n");
            return ret;
        }
        ret = snd_soc_register_dai(&lc1120_dai);  //标准注册dai函数。
        if (ret) {
            dev_err(codec->dev, "Failed to register dai\n");
            snd_soc_unregister_codec(codec);
            return ret;
        }
    printk(KERN_ERR "yzt %s exited\n", __func__);
        return 0;
    }
    static int lc1120_unregister(struct lc1120_priv *lc1120)
    {
    D_ENTER;
    //    lc1120_set_bias_level(&lc1120->codec, SND_SOC_BIAS_OFF);
        snd_soc_unregister_dai(&lc1120_dai);      //先注销dai
        snd_soc_unregister_codec(&lc1120->codec);  //在注销codec
        lc1120_codec = NULL;
        return 0;
    }
二.在sound/soc/comip/snd_soc_comip_lc1120.c中的初始化代码:

1.comip_lc1120_init()/comip_lc1120_exit()

static struct clk *codec_mclk;
    static struct platform_device *snd_soc_comip_lc1120_device;  //两个全局变量,下面会用到。

    static int __init comip_lc1120_init(void)
    {
        int ret;
    D_ENTER;
        codec_mclk = snd_soc_codec_set_mclk();   //在soc中配置寄存器,使之输出13M I2S main_clk
        snd_soc_comip_lc1120_device = platform_device_alloc("soc-audio", -1);  //申请platform device 空间。
        if (!snd_soc_comip_lc1120_device) {
            printk(KERN_ERR "Platform device allocation failed\n");
            return -ENOMEM;
        }
        //把snd_soc_device 指向 platform -> dev
        //snd_soc_comip_lc1120_devdata 是snd_soc_device,snd_soc_comip_lc1120_device 是platform
        platform_set_drvdata(snd_soc_comip_lc1120_device, &snd_soc_comip_lc1120_devdata);
        snd_soc_comip_lc1120_devdata.dev = &snd_soc_comip_lc1120_device->dev;
        ret = platform_device_add(snd_soc_comip_lc1120_device);  添加一个platform设备。
        if (ret) {
            printk(KERN_ERR "Soc Audio: Unable to add lc1120\n");
            platform_device_put(snd_soc_comip_lc1120_device);
        }
        return ret;
    }
    module_init(comip_lc1120_init);
    static void __exit comip_lc1120_exit(void)
    {
    D_ENTER;
        if (codec_mclk)
            clk_put(codec_mclk);
        codec_mclk = NULL;   //时钟清零
        platform_device_unregister(snd_soc_comip_lc1120_device);
    }
    module_exit(comip_lc1120_exit);
2. 几个结构体之间的关系:

a.一个platform_device 包含一个device 和一个resource。resource很有用。

struct platform_device {
        const char    * name;
        int        id;
        struct device    dev;
        u32        num_resources;
        struct resource    * resource;
        const struct platform_device_id    *id_entry;
        /* arch specific additions */
        struct pdev_archdata    archdata;
    };
b.一个snd_soc_device 包括一个snd_soc_card 和一个 snd_soc_codec_device.
/* SoC Device - the audio subsystem */
    struct snd_soc_device {
        struct device *dev;
        struct snd_soc_card *card;
        struct snd_soc_codec_device *codec_dev;
        void *codec_data;
    };
具体如下:
/* Audio subsystem */
    static struct snd_soc_device snd_soc_comip_lc1120_devdata =  //snd_soc_device包含了两项
    {
        .card = &snd_soc_comip_lc1120_card_data,   //snd_soc_card.
        .codec_dev = &soc_codec_dev_lc1120,        //snd_soc_codec_device.
    };
c.一个snd_soc_card 包含一个snd_soc_platform 和一个snd_soc_dai_link :
/* Audio machine driver */
    static struct snd_soc_card snd_soc_comip_lc1120_card_data =
    {
        .name = "comip_lc1120",
        .platform = &comip_soc_platform,         //snd_soc_platform,是指Soc端的音频操作
        .dai_link = snd_soc_comip_lc1120_dai_link,  //snd_soc_dai_link,Soc和codec 两个dai的 链接
        .num_links = ARRAY_SIZE(snd_soc_comip_lc1120_dai_link),
    };
d. 一个snd_soc_platform 表示Soc端的pcm码流操作,包含:
struct snd_soc_platform comip_soc_platform = {
        .name        = "comip-audio",
        .pcm_ops     = &comip_pcm_ops,
        .pcm_new    = comip_pcm_new,
        .pcm_free    = comip_pcm_free_dma_buffers,
    };
    EXPORT_SYMBOL_GPL(comip_soc_platform);
e. 一个snd_soc_dai_link 包含两个snd_soc_dai,一个cpu_dai和一个codec_dai;还有一个snd_soc_ops
static struct snd_soc_dai_link snd_soc_comip_lc1120_dai_link[] =
    {
        {
            .name = "comip_i2s_lc1120",
            .stream_name = "comip_i2s_lc1120",
            .cpu_dai = &comip_i2s_dai,
            .codec_dai = &lc1120_dai,
            .ops = &snd_soc_comip_lc1120_ops,
        },
    };
f:snd_soc_ops snd_soc_comip_lc1120_ops,包含如下;音频播放的时候,会调用trigger,startup,hw_param等等。
/* Digital audio interface glue - connects codec <--> CPU */
    static struct snd_soc_ops snd_soc_comip_lc1120_ops =
    {
        .startup = comip_lc1120_startup,  
        .shutdown = comip_lc1120_shutdown,
        .hw_params = comip_lc1120_i2s_hw_params,
        .hw_free = comip_lc1120_hw_free,
        .prepare = comip_lc1120_prepare,
        .trigger = comip_lc1120_trigger,
    };
g. comip_lc1120_i2s_hw_params内容如下,其他基本都是直接return 0;
static int comip_lc1120_i2s_hw_params(struct snd_pcm_substream *substream,
                    struct snd_pcm_hw_params *params)
{
    struct snd_soc_pcm_runtime *rtd = substream->private_data;
    struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
    struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
    int ret = 0;
//    unsigned long rate = params_rate(params);



    D_ENTER;
        ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
                            SND_SOC_DAIFMT_CBM_CFM);
        if (ret < 0)
            return ret;
        ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
                            SND_SOC_DAIFMT_CBM_CFM);
        if (ret < 0)
            return ret;
        return ret;
    }
h. struct snd_soc_codec_device soc_codec_dev_lc1120定义如下:soc_codec_dev_lc1120

struct snd_soc_codec_device soc_codec_dev_lc1120 = {
        .probe = lc1120_probe, //在注册了soc_codec_dev_lc1120之后,就自动运行lc1120_probe
        .remove = lc1120_remove,
        .suspend = lc1120_suspend,
        .resume = lc1120_resume,
    };
    EXPORT_SYMBOL_GPL(soc_codec_dev_lc1120);

三. lc1120 功能部分,注册完了之后,就具备了一系列功能。

1. lc1120_probe():

static struct snd_soc_codec *lc1120_codec;    //定义了一个全局变量

    static int lc1120_probe(struct platform_device *pdev)
    {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
        struct snd_soc_codec *codec;
        int ret = 0;
    D_ENTER;
        codec = lc1120_codec;
        if (!codec) {
            dev_err(&pdev->dev, "Codec not registered\n");
            return -ENODEV;
        }
        if (lc1120_write_regs(codec, lc1120_init_data,   //初始化一系列寄存器
                ARRAY_SIZE(lc1120_init_data)))
        {
            printk(KERN_ERR "%s: initialize lc1120 failed\n", __func__);
            return -ENODEV;
        }
        socdev->card->codec = codec;
        /* register pcms */
        mutex_init(&codec->mutex);
        ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);   //create new sound card and pcms。
        if (ret < 0) {
            printk(KERN_ERR "%s: snd_soc_new_pcms failed for %d\n",
                __func__, ret);
            goto pcm_err;
        }
        ret = snd_soc_add_controls(codec, lc1120_snd_controls,  //add an array of controls to a codec.
                 ARRAY_SIZE(lc1120_snd_controls));
        if (ret < 0)
        {
            printk(KERN_ERR "%s: snd_soc_add controls failed for %d\n",
                __func__, ret);
            goto pcm_err;
        }
        INIT_LIST_HEAD(&codec->dapm_widgets);
        INIT_LIST_HEAD(&codec->dapm_paths);
        ret = snd_soc_dapm_new_controls(codec, lc1120_dapm_widgets,  //create new dapm controls
                    ARRAY_SIZE(lc1120_dapm_widgets));
        if (ret < 0)
        {
            printk(KERN_ERR "%s: snd_soc_dapm_new_controls failed for %d\n",
                __func__, ret);
            goto pcm_err;
        }
        ret = snd_soc_dapm_add_routes(codec, lc1120_route,     //Add routes between DAPM widgets
                    ARRAY_SIZE(lc1120_route));
        if (ret < 0)
        {
            printk(KERN_ERR "%s: snd_soc_dapm_add_routes failed for %d\n",
                __func__, ret);
            goto pcm_err;
        }
        ret = snd_soc_dapm_new_widgets(codec);       //add new dapm widgets
        if (ret < 0)
        {
            printk(KERN_ERR "%s: snd_soc_dapm_new_widgets failed for %d\n",
                __func__, ret);
            goto pcm_err;
        }
    printk(KERN_ERR "yzt: %s exited\n", __func__);
    pcm_err:
        return ret;
    }


AIC3104_音频驱动 这两周一直在调AIC3104的驱动,这是个音频codec芯片,可以实现语音对讲功能。 AIC3104是通过I2C方式与CPU通信,来设置寄存器,另外是IIS接口进行语音的Mic_in和Line_out功能。   下面是aic3104的驱动源代码: /* extdrv/peripheral/vda/adv7179.c * * * Copyright (c) 2006 Hisilic 阅读详情

相关推荐

IIS总线

IIS(Integrate Interface of Sound)即集成音频接口,在上个世纪80年代首先被Philips公司用于消费产品的音频设备。   LRCLK(Left/Right CLOCK)信号机制中经过多路转换,将两路音频信号合成单一的数据队列。当LRCLK为高时,左声道数据被传输;LRCLK为低时,右声道数据被传输(也可以反过来,高低与左右声音的对应可以自定义)。   对于多

1271

LC.1120. Maximum Average Subtree

class Solution(object): def maximumAverageSubtree(self, root): """ DFS,每个节点返回两个值,一个值是以该节点为根的树的节点的个数, 另一个值是以该节点为根的树的所有节点的和 """ self.res = -float('inf') ...

很吵请安静 879

I2S 调试

1. Main clk : 一般都是13M。   今天用示波器量了下音频Main clock时钟频率,很逗。开始量出来166Hz,后来觉得不对,把周期调小了下,才量出来12.99MHz。我说怎么可能这么低频率。   I2S总线的 PCLK 和 LRCLK 都是Main clk中分频出去的,频率才会低很多。如果Main clk只有166Hz, 还怎么分频。汗。。。还是挺幼稚呀。。 函数如下

1269

lc1120 jack detect switch

/* switch data register*/ struct lc1120_priv *data = container_of(codec, struct lc1120_priv, codec); //从元素codec,得到lc1120_priv地址 data->sdev.name = "h2w"; //switch设备只需要给个名字就能注册了。

801

I2S 总线介绍

I2S是数字音频的接口,这里不用多说,请读者自己查阅相关资料。 提示,I2S总线的接口信号如下: 1、LRCLK:左右声道控制,高电平时,SDATA上为左声道数据,低电平时,SDATA上为右声道数据。(也有相反的情况,请参考不同的音频芯片的手册) 2、BCLK:跟SDATA上数据对应的时钟,上升沿采数据,也可能在下降沿采数据,请注意对应音频芯片手册上的说明。 3、SDATA:串行数据,一个

968

fibplus-8.0.0.zip

FIBPlus 是一套面向 Delphi / C++Builder 的 Firebird、InterBase 数据库访问组件,特点是直接走原生客户端 API,不经 BDE/ODBC,速度快且可控性强。8.0.0 版本主要适配 Delphi 2009 及以后的版本(Delphi 6–2007 需用 7.9.x),核心组件包括 TpFIBDatabase、TpFIBTransaction、TpFIBDataSet 等,支持精细事务管理、本地缓存、BLOB 处理和备份恢复等数据库服务。该库原为 Devrace 的商业组件,现由社区在 GitHub 的 madorin/fibplus 项目开源维护,建议从官方仓库获取源码而非第三方网盘压缩包。安装时解压后用对应版本的工程组(10.4+ 统一为 `FIB.groupproj`)Build 全部包,再 Install `dclFIB` 并在 Library 路径加入 Source 目录即可。新项目中若需官方技术支持,也可考虑 FireDAC、IBDAC 等更现代的替代方案。

PCM总线定义

PCM总线协定分析(数字多媒体) 【 产品规格 】 通道名称 SCLK、FS、DR、DT 频率 64kbps ~ 2.048Mbps 电压 5V 应用领域 主要应用于数字音讯控制。 孕龙逻辑分析仪支持分析PCM串行协议分析,PCM (Pulse Code Modula

1705

基于K8S + apisix/istio 实现云原生模块化微服务.自带代码生成器,能够生成对表的增删改查的逻辑代码

基于K8S + apisix/istio 实现云原生模块化微服务.自带代码生成器,能够生成对表的增删改查的逻辑代码.是标准Maven项目,只依赖springboot,没有hibernate,struts,ibatis,数据库调优可以使用druid输出慢sql,比分析xml中的语句更直观,springrain所有的sql语句都使用Finder封装管理,只要查看Finder的引用即可.

Android启动错误“Waiting for sevice media.audio_flinger”的解决方案

Android启动错误“Waiting for sevice media.audio_flinger”的解决方案 最近Android启动遇到卡死在声卡服务的问题,现象如下: W/AudioSystem(   49): AudioFlinger not published, waiting... I/ServiceManager(   49): Waiting for sevice m

1564

Linux 使用rm -rf /*命令后,恢复系统方法

Linux 使用rm -rf /*命令后,恢复系统方法 个人学习记录 这里实验环境采用的是radhel7.1的版本: 个人认为核心就是缺失什么组件,就从别的地方复制什么组件过来,先把系统拉起来,再慢慢恢复配置 进入救援模式 1、将/dev/sda两个分区分别挂载看看,里面的内容,有内容的就是根存在的分区 2、ifconfig eno16777777 192.168.8.2 3、从另外一台一样系统的根 。用 tar打包,一个个文件夹拷贝过来 4、到坏系统,scp另外一个系统的etc.tar.gz 5

weixin_43603476的博客 1万+

IAR9.30以上版本安装、注册、新建工程和配置过程详细介绍

IAR 一般是指一款嵌入式软件的集成开发环境,类似于 MDK-Keil 这款软件。IAR 对于不同的内核处理器,是对应不同的 IAR 软件的,IAR 到目前为止支持大部分的MCU,比如8051系列、ARM架构系列、MSP430系列、AVR系列等等这些常用的芯片架构。对于 ARM 架构的芯片,有对应的 IAR Embedded Workbench for ARM 软件平台,因为我主要是使用 ARM 架构芯片,下面安装、注册和使用都是基于这个版本进行介绍的。

luobeihai的博客 6万+

alsa-lib, alsa-utils安装方法

ALSA 驱动安装方法 ALSA 驱动下载: 去http://www.alsa-project.org/main/index.php/Main_Page 下载:        alsa-driver-xxxxxx        alsa-lib-xxxxxx        alsa-ultis-xxxxxx 即driver, lib, ultis包,后面的xxxxxx是具体的版本号,我

1499

数据分析面试八股文--技能软件类

数据分析的“三板斧"指的是三个在 Python 数据分析领域广泛使用的库:NumPy,Pandas,和 Matplotlib。这三个库提供了处理和分析数据的强大工具。NumPyNumPy(Numerical Python)是一个开源 Python 库,用于支持大型多维数组和矩阵运算。此外,NumPy 还提供了大量的数学函数来操作这些数组。np.array():创建数组np.arange():返回一个有终点和起点的固定步长的排列。

zfyzfw的博客 4376

ALSA 和 SOC+codec 整体架构

一、简介 整个Alsa体系分为用户空间和内核空间两部分,实现了很多强大的功能。从驱动开发的角度来看,基本只需要把注意力集中在跟硬件相关的部分就可以了。其它内容是Alsa体系维护者的事情。 在内核中,Alsa为不同的类型的硬件分别提供了不同的封装形式,这里仅介绍主框架(不同类型硬件的实现就是对主框架的封装)和SOC框架。 二、主框架 1、基本概念 帧(frame):全部声道采样一次所得

1417

SVA学习笔记(1)——property基本语法及巧用define与property

巧用define与property,让代码更加灵活

craftsman2018ship的博客 1574

Open3D 机载点云电力线提取【2025最新版】

传统方法实现的机载点云电力线分割提取。博客长期更新,本文最新更新时间为:2025年3月23日。

点云侠的博客 4468

音频测试内容

音频测试 声音测试,有好几个步骤: 1. 播放: speaker 播放音乐。 插上耳机,能自动侦测,自动转到耳机播放。 耳机播放。 拔掉耳机,能自动转到speaker播放。 2.录音 mic 录音 插上耳机mic,能自动侦测耳机mic,转用耳机mic录音 拔掉耳机,又回转到mic录音。

1375

TIA protal与SCL从入门到精通(1)——SCL编程入门

SCL语言是由Pascal而生的结构化程序语言,与梯形图相(LAD)比,SCL语言的灵活程度更高,易于编写控制算法。 本教程基于的平台如下 软件:TIA 15.1 CPU 1516 (1)直接创建纯SCL的程序块儿; (2)在LAD/FBD中在插入SCL程序段。 在程序段中直接右击插入即可,但是插入的程序段并不能完全使用SCL语法,GOTO等跳转指令就不能使用。在SCL中一般不能使用绝对地址进...

苦走一口田 7万+

multimedia 各种server 在frameworks层的起始处

multimedia, 包含了audio的AudioFlinger, video的mediaservice 和 camera的cameraservice. 他们在frameworks层最上面起始调用位于: frameworks/base/media/mediaserver/main_mediaserver.cp 代码如下: /* ** ** Copyright 2008, T

1274

Python基础语法与最佳实践【python基础篇】

本文全面介绍了Python基础语法与最佳实践,涵盖变量与数据类型、控制流、函数、模块与包等核心概念。通过实际代码示例展示了条件语句、循环结构、函数定义及模块导入的基本用法。在最佳实践部分,重点讲解了PEP 8代码风格规范、异常处理技巧、列表推导式、上下文管理器、文档字符串编写以及enumerate和zip的高效使用。这些内容既适合Python初学者掌握基础语法,也能帮助有经验的开发者编写更规范、高效、可维护的代码。文章强调遵循Python官方推荐实践,通过合理运用语言特性提升代码质量。

博客 1975

23种设计模式-享元(Flyweight)设计模式

软考中级-软件设计师 享元设计模式

片言可决讼,半纸能缚龙 3223

AIC3104音频codec电路

它包括了: IIS语音通信接口:同来收发语音信号。 IIC通信接口:用来配置寄存器 MIC_in接口: line_out接口: reset脚。

1130

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

comip-lm49350 Soc音频模块和codec

comip-lm49350.c 是CPU的音频模块+ codec lm49350 统一成一个整体的设备结构。他会先注册成一个platform device。 代码分析如下: 1. init/exit static int __init comip_soc_init(void) { int ret; printk(KERN_INFO "COMIP

992

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

audio 的各种功能分类

1. Speaker: 就是声音很大的那个扩音器。   SPK_OUT_P SPK_OUT_N   2. Receiver: 也叫earphone, 就是耳朵贴近手机时的,那个听筒。   3. headphone out :就是耳机输出   HPL_OUT HPR_OUT   4 .Mic ---有3种   a. Main_mic, 就是手机贴近嘴时的那个mic

948

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

android耳机监测

最近在做Marvell的项目,碰到个耳机热插拔的问题,所以顺便看了下相关代码,这里来贡献一下给大家。 我们这里以PXA的代码为例,整个框架比较的简单清晰,上层是分别是HeadsetObserver.java以及HookSwitchObserver.java, 它们会直接读取/sys/class/switch/中某一特定的设备的state,比如"/sys/class/switch/h2w/sta

889
上一篇: audio 调试命令
下一篇: audio 的各种功能分类
lamdoc
博客等级 码龄18年 155粉丝 655原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值