当前位置: 首页 > 编程日记 > 正文

linux驱动:i2c驱动(二)

3、驱动源码分析

IPNC_RDK_V3.8.0.1/Source/ti_tools/ipnc_psp_arago/kernel/sound/soc/codecs/tlv320aic3x.c

3.1 注册模块

module_init(aic3x_modinit);

3.2 在初始化函数中添加i2c驱动

static int __init aic3x_modinit(void)

{

intret = 0;

#if defined(CONFIG_I2C) ||defined(CONFIG_I2C_MODULE)

ret= i2c_add_driver(&aic3x_i2c_driver);

if(ret != 0) {

printk(KERN_ERR "Failed to registerTLV320AIC3x I2C driver: %d\n",

ret);

}

#endif

returnret;

}

3.3 【驱动】

static struct i2c_driver aic3x_i2c_driver = {

.driver= {

.name = "tlv320aic3x-codec",

.owner = THIS_MODULE,

},

.probe     = aic3x_i2c_probe,

.remove= aic3x_i2c_remove,

.id_table= aic3x_i2c_id,

};

3.4 probe

static int aic3x_i2c_probe(structi2c_client *i2c,

const struct i2c_device_id *id)

{

structaic3x_pdata *pdata = i2c->dev.platform_data;

structaic3x_priv *aic3x;

intret;

conststruct i2c_device_id *tbl;

aic3x= kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);

if(aic3x == NULL) {

dev_err(&i2c->dev, "failed tocreate private data\n");

return -ENOMEM;

}

aic3x->control_data= i2c;

aic3x->control_type= SND_SOC_I2C;

i2c_set_clientdata(i2c, aic3x);

if(pdata) {

aic3x->gpio_reset =pdata->gpio_reset;

aic3x->setup = pdata->setup;

}else {

aic3x->gpio_reset = -1;

}

for(tbl = aic3x_i2c_id; tbl->name[0]; tbl++) {

if (!strcmp(tbl->name, id->name))

break;

}

aic3x->model= tbl - aic3x_i2c_id;

ret= snd_soc_register_codec(&i2c->dev,

&soc_codec_dev_aic3x,&aic3x_dai, 1);

if(ret < 0)

kfree(aic3x);

returnret;

}

3.5 remove

static int aic3x_i2c_remove(structi2c_client *client)

{

snd_soc_unregister_codec(&client->dev);

kfree(i2c_get_clientdata(client));

return0;

}

3.6 i2c_device_id

static const struct i2c_device_id aic3x_i2c_id[] = {

[AIC3X_MODEL_3X]= { "tlv320aic3x", 0 },

[AIC3X_MODEL_33]= { "tlv320aic33", 0 },

[AIC3X_MODEL_3007]= { "tlv320aic3007", 0 },

[AIC3X_MODEL_3104]= { "tlv320aic3104", 0 },

{}

};

3.7 模块注销

static void __exit aic3x_exit(void)

{

#if defined(CONFIG_I2C) ||defined(CONFIG_I2C_MODULE)

i2c_del_driver(&aic3x_i2c_driver);

#endif

}

module_exit(aic3x_exit);

3、与i2c相关的函数

Include/linux/i2c.h中

4.1 i2c_add_driver

static inline int i2c_add_driver(structi2c_driver *driver)

{

returni2c_register_driver(THIS_MODULE,driver);

}

Drivers/i2c/i2c-core.c中

4.2 i2c_del_driver

/**

*i2c_del_driver - unregister I2C driver

*@driver: the driver being unregistered

*Context: can sleep

*/

void i2c_del_driver(structi2c_driver *driver)

{

mutex_lock(&core_lock);

bus_for_each_dev(&i2c_bus_type,NULL, driver, __process_removed_driver);

mutex_unlock(&core_lock);

driver_unregister(&driver->driver);

pr_debug("i2c-core:driver [%s] unregistered\n", driver->driver.name);

}

Include/linux/i2c.h中

4.3 i2c_set_clientdata

static inline void i2c_set_clientdata(structi2c_client *dev, void *data)

{

dev_set_drvdata(&dev->dev,data);

}

4、【设备】

Arch/arm/mach-omap2/board-ti8148ipnc.c

5.1 static struct i2c_board_info __initdatati814x_i2c_boardinfo[] = {

#ifdef CONFIG_SND_SOC_TLV320AIC3X

{

I2C_BOARD_INFO("tlv320aic3104", 0x18),

.platform_data =&dm8148ipnc_aic3x_data,

},

#endif

{

I2C_BOARD_INFO("tps65911", 0x2D),

.platform_data = &tps65911_pdata,

},

};

static void __init ti814x_evm_i2c_init(void)

{

/*There are 4 instances of I2C in TI814X but currently only one

* instance is being used on the TI8148 EVM

*/

#ifndef CONFIG_TI8148_EVM_OPTIMIZED

omap_register_i2c_bus(1,100, ti814x_i2c_boardinfo,

ARRAY_SIZE(ti814x_i2c_boardinfo));

#else

omap_register_i2c_bus(1,100, ti814x_i2c_boardinfo,

ARRAY_SIZE(ti814x_i2c_boardinfo));

#endif

}

5.2 int __init omap_register_i2c_bus(int bus_id, u32clkrate,

struct i2c_board_info const *info,

unsigned len)

{

interr;

BUG_ON(bus_id< 1 || bus_id > omap_i2c_nr_ports());

if(info) {

err = i2c_register_board_info(bus_id,info, len);

if (err)

returnerr;

}

if(!i2c_pdata[bus_id - 1].clkrate)

i2c_pdata[bus_id - 1].clkrate = clkrate;

i2c_pdata[bus_id- 1].clkrate &= ~OMAP_I2C_CMDLINE_SETUP;

returnomap_i2c_add_bus(bus_id);

}

【TI i2c适配器驱动】

Arch/arm/plat-omap/i2c.c中

1、static int __init omap_i2c_add_bus(intbus_id)

{

if(cpu_class_is_omap1())

return omap1_i2c_add_bus(bus_id);

else

return omap2_i2c_add_bus(bus_id);

}

Arch/arm/plat-omap/i2c.c中

2、static inline int omap2_i2c_add_bus(intbus_id)

{

intl;

structomap_hwmod *oh;

structomap_device *od;

charoh_name[MAX_OMAP_I2C_HWMOD_NAME_LEN];

structomap_i2c_bus_platform_data *pdata;

omap2_i2c_mux_pins(bus_id);

l= snprintf(oh_name, MAX_OMAP_I2C_HWMOD_NAME_LEN, "i2c%d", bus_id);

WARN(l>= MAX_OMAP_I2C_HWMOD_NAME_LEN,

"String buffer overflow in I2C%ddevice setup\n", bus_id);

oh= omap_hwmod_lookup(oh_name);

if(!oh) {

pr_err("Couldnot look up %s\n", oh_name);

return-EEXIST;

}

pdata= &i2c_pdata[bus_id - 1];

/*

* When waiting for completion of a i2ctransfer, we need to

* set a wake up latency constraint for theMPU. This is to

* ensure quick enough wakeup from idle, whentransfer

* completes.

* Only omap3 has support for constraints

*/

if(cpu_is_omap34xx())

pdata->set_mpu_wkup_lat =omap_pm_set_max_mpu_wakeup_lat_compat;

od= omap_device_build(name, bus_id, oh, pdata,

sizeof(structomap_i2c_bus_platform_data),

omap_i2c_latency,ARRAY_SIZE(omap_i2c_latency), 0);

WARN(IS_ERR(od),"Could not build omap_device for %s\n", name);

returnPTR_ERR(od);

}

3、omap_hwmod_lookup(oh_name) 获取之前注册到omap_hwmod_list中的“i2c1”

Arch/arm/plat-omap/omap_device.c中

4、struct omap_device *omap_device_build(constchar *pdev_name, int pdev_id,

struct omap_hwmod *oh, void *pdata,

int pdata_len,

struct omap_device_pm_latency *pm_lats,

int pm_lats_cnt, int is_early_device)

{

structomap_hwmod *ohs[] = { oh };

if(!oh)

return ERR_PTR(-EINVAL);

returnomap_device_build_ss(pdev_name,pdev_id, ohs, 1, pdata,

pdata_len, pm_lats, pm_lats_cnt,

is_early_device);

}

5、struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,

struct omap_hwmod **ohs, int oh_cnt,

void *pdata, int pdata_len,

struct omap_device_pm_latency *pm_lats,

int pm_lats_cnt, int is_early_device)

{。。。。。。

ret = omap_device_register(od);

。。。。。。}

6、int omap_device_register(structomap_device *od)

{

pr_debug("omap_device:%s: registering\n", od->pdev.name);

od->pdev.dev.parent= &omap_device_parent;

returnplatform_device_register(&od->pdev);

}

7、int platform_device_register(structplatform_device *pdev)

{

device_initialize(&pdev->dev);

returnplatform_device_add(pdev);

}

8、int platform_device_add(struct platform_device *pdev)

{。。。。。。

ret = device_add(&pdev->dev);

。。。。。。}

相关文章:

01 使用AFN3 0上传图片时间慢的问题

##iOS中修改图片的大小&#xff1a;修改分辨率和裁剪 ###第一步:裁剪图片 // 裁剪// 要裁剪的图片区域&#xff0c;按照原图的像素大小来&#xff0c;超过原图大小的边自动适配CGSize size CGSizeMake(1000, 1000);UIImage *img [self imageWithImageSimple:image scaledToS…

配置telnet

配置telnet<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />允许root账号能够登录telnet&#xff0c;但是拒绝某一台主机登录且只允许在9&#xff1a;00-14&#xff1a;00 14&#xff1a;00-18&#xff1a;00能够访问&#xff0…

04 pod setup 慢的问题

解决方式一: 可以直接从别人的电脑中拷贝解决方式二转载于:https://juejin.im/post/5a3c5a985188257d391d3a39

linux驱动:i2c驱动(三)流程图之注册设备

一、设备注册过程 1、将i2c设备信息保存到i2c_board_info结构体中&#xff1b; 2、在注册i2c_board_info时&#xff08;i2c_register_board_info&#xff09;将它加入一个全局列表__i2c_board_list中&#xff0c; 3、在注册I2c adapter适配器驱动后&#xff0c;再从全局列表…

AI找Bug,一键快速预测

作者 | Jane出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;在程序开发中&#xff0c;程序员每天都要和 Bug 打交道&#xff0c;对新手程序员而言&#xff0c;debug 是一件非常让人头疼的事情。好不容易写完一段代码&#xff0c;一运行&#xff0c;全是红色&#xff…

专业研究HP procurve网络、阿姆瑞特和系统集成的论坛

一个专业研究HP procurve网络、阿姆瑞特防火墙和系统集成的论坛http://www.vlan2.com确实不错。转载于:https://blog.51cto.com/showrouter/284235

到底是什么特征影响着CNN的性能?

作者 | 刘畅 编辑 | Jane出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;开门见山。最近阅读了一篇论文&#xff0c;加上看了一些之前的工作。记录一下&#xff0c;CNN 到底学到了什么东西&#xff0c;或者换句话讲。到底是什么样的特征在影响着CNN 的性能&#xff1…

Java数据结构与算法(八)-二叉树

一、为什么要使用树 有序数组插入、删除数据慢。链表查找数据慢树可以解决这两个问题二、相关术语 树的结点&#xff1a;包含一个数据元素及若干指向子树的分支&#xff1b;孩子结点&#xff1a;结点的子树的根称为该结点的孩子&#xff1b;双亲结点&#xff1a;B 结点是A 结点…

linux驱动:i2c驱动(四)流程图之注册驱动

二、i2c设备的驱动部分 1、i2c驱动i2c_driver 2、通过i2c_add_driver注册 2、注册过程中 比较i2c_device_id数组中各成员的id与i2c_client中的名字&#xff0c;找到设备 3、执行i2c_driver驱动中的probe

Expression Blend实例中文教程(2) - 界面快速入门

上一篇主要介绍Expression系列产品&#xff0c;另外概述了Blend的强大功能&#xff0c;本篇将用Blend 3创建一个新Silverlight项目&#xff0c;通过创建的过程&#xff0c;对Blend进行快速入门学习。 在开始使用Blend前&#xff0c;首先需要进行Silverlight的开发环境搭建&…

Lua基本语法-书写规范以及自带常用函数

Lua基本语法-书写规范和常用函数本文提供全流程&#xff0c;中文翻译。Chinar坚持将简单的生活方式&#xff0c;带给世人&#xff01;&#xff08;拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例&#xff09; 1String Operation —— 字符串操作2Table ——…

linux驱动:音频驱动(一)ALSA

一、【基础知识】 1、J2 《--HPR_OUTHPL_OUT 《-- U13&#xff08;TLV320AIC3104IRHBR&#xff09;的HPROUTHPLOUT 2、驱动源码 IPNC_RDK_V3.8.0.1/Source/ti_tools/ipnc_psp_arago/kernel/sound/soc/codecs/tlv320aic3x.c 3、依赖于I2C驱动 4、声卡驱动框架&#xff1a;…

秘籍 | 机器学习数据集网址大全

作者 | Will Badr译者 | Linstancy整理 | Jane出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;要找到一定特定的数据集可以解决各种机器学习问题&#xff0c;是一件很难的事情。越来越多企业或研究机构将自己的数据集公开&#xff0c;已经成为全球的趋势&#xff0c;…

为asa防火墙配置ssh登陆

由于最近事情超多&#xff0c;单位下发某些令人恶心的制度&#xff0c;今天突然说北京分公司和总公司之间要做***的连接&#xff0c;虽然俺是个CCNP&#xff0c;但是对于***来说接触的少之又少&#xff0c;并且工作繁忙&#xff0c;每天头大&#xff0c;北京分公司的安全ie同事…

70.nodejs操作mongodb

转自&#xff1a;https://www.cnblogs.com/whoamme/p/3467374.html 首先安装nodejs mongodb npm install mongodb var mongodb require(mongodb); var server new mongodb.Server(localhost, 27017, {auto_reconnect:true}); var db new mongodb.Db(mydb, server, {saf…

明晚8点公开课 | 用AI给旧时光上色!详解GAN在黑白照片上色中的应用

在改革开放40周年之际&#xff0c;百度联合新华社推出了一个刷屏级的H5应用——用AI技术为黑白老照片上色&#xff0c;浓浓的怀旧风勾起了心底快被遗忘的时光。想了解如何给老照片上色&#xff1f;本次公开课中&#xff0c;我们邀请到了百度高级研发工程师李超&#xff0c;他的…

linux驱动:音频驱动(二)ASoc

五、【ASoC声卡驱动框架】 1、ASoC将嵌入式设备的音频系统从软件层面划分为3个组件 1.1 codec驱动&#xff1a;音频编解码器驱动&#xff0c;与平台无关&#xff0c;实现音频控制项添加、音频接口实现、DAPM&#xff08;动态音频电源管理&#xff09;、音频编解码器的IO功能 …

把32位的SharePoint服务器场迁移到64位, 应该怎么做?

总体步骤如下: 1. 迁移已经存在了的数据库服务器到新的数据库服务器. 先迁移这一层的目的是避免可能发生的一些由64位系统对32位系统执行查询或写入操作所引起的性能问题. 2. 迁移WFE服务器到64位环境下. 准备工作: 1. 重新编译已经存在的32位的应用程序和自定义的程序集(web p…

testem方便的web tdd 测试框架使用

备注&#xff1a;单元测试&#xff0c;对于日常的开发是比较重要的&#xff0c;testem 简化了我们的代码编写&#xff0c;以及运行。主要特性&#xff1a;a. 支持的测试框架有&#xff1a;jasmine quint mocha buster.js &#xff0c;同时也包含一些其他的适配器&#xff0c;支…

程序员老在改Bug,就不能一次改好吗?

作者丨伍杏玲来源 | 程序人生&#xff08;ID&#xff1a;coder_life&#xff09;程序员的日常三件事&#xff1a;写Bug、改Bug、背锅。连程序员都自我调侃道&#xff0c;为什么每天都在加班&#xff1f;因为我的眼里常含Bug。但是真的有这么多Bug要改吗&#xff1f;就不能一次改…

一场库文件的远程修复

一场库文件的远程修复系统环境RHEL 4.7一、原因&#xff1a;发现每天早上7点1分备份的数据库文件时间不对&#xff0c;登录上去后date下发现时间是正确。二、尝试解决&#xff1a;1&#xff09;setup->Timezone configuration-> Asia/Shanghai保存后&#xff0c;发现由原…

linux驱动:音频驱动(四)ASoc之machine设备

linux驱动&#xff1a;音频驱动&#xff08;四&#xff09;ASoc之machine设备

Sql server Insert执行的秘密(下) 带外键的INSERT分析

2019独角兽企业重金招聘Python工程师标准>>> 这一篇分析一下带外键表的INSERT的例子。 本文所用的数据表结构如上图所示&#xff1b;其中Blog表上BlogID是自增的主键&#xff0c;并在CreateUserID和CreateTime列上分别建有两个非唯一索引。 我们要往Blog表中插入一…

熬夜写代码,不如换女装入GitHub获上千Star?

作者 | 琥珀出品 | AI科技大本营&#xff08;ID: rgznai100&#xff09;程序员如何以合规手段快速获得 GitHub 上千 Star&#xff1f;新年刚过&#xff0c;GitHub Trending 上一个名为“Dress”的开源项目迅速蹿红&#xff0c;并成功掀起了不少程序员及吃瓜群众的热议。项目地址…

CCNp笔记(EIGRP)

EIGRP<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />特性1属于混合路由协议具有距离矢量路由协议的特性&#xff0c;又有链路状态路由协议的特性。2属于高级距离矢量路由协议3快速收敛4保证100%无环路5增量更新6支持默认4条最多…

linux驱动:音频驱动(五)ASoc之codec驱动

linux驱动&#xff1a;音频驱动&#xff08;五&#xff09;ASoc之codec驱动

科大讯飞市值腰斩背后,AI产业集体思考如何落地?

作者丨郭敏本文经授权转载自钛媒体&#xff08;ID&#xff1a;taimeiti&#xff09;【导语】在过去的一年里&#xff0c;科大讯飞受到了多方质疑&#xff0c;质疑的声音不外乎盈利疲软、靠政府补助、技术优势逐渐变弱等&#xff0c;种种质疑背后&#xff0c;其实整个 AI 产业从…

zabbix系列之邮件告警(三)

设置邮件告警有两种方式&#xff1a;1&#xff09;、通过Linux自带的mail发送告警邮件2&#xff09;、通过第三方邮箱发送&#xff08;如QQ邮箱、163邮箱等&#xff09;告警邮件1、修改 zabbx_server.conf 文件,指定脚本路径&#xff0c;没有则添加[rootcentos1 ~]# vim /usr/l…

Python告诉你:为何年终奖多发一元,到手却少两千多?

作者 | shenzhongqiang来源 | Python数据与分析&#xff08;ID&#xff1a;ML_Python&#xff09;年终奖多发一元&#xff0c;到手却要少两千多&#xff0c;甚至更多。听到这个消息的时候&#xff0c;大家是不是觉得有点意外&#xff0c;意外之余还有点淡淡的忧伤&#xff1f;上…