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中修改图片的大小:修改分辨率和裁剪 ###第一步:裁剪图片 // 裁剪// 要裁剪的图片区域,按照原图的像素大小来,超过原图大小的边自动适配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,但是拒绝某一台主机登录且只允许在9:00-14:00 14:00-18:00能够访问࿰…

04 pod setup 慢的问题
解决方式一: 可以直接从别人的电脑中拷贝解决方式二转载于:https://juejin.im/post/5a3c5a985188257d391d3a39
linux驱动:i2c驱动(三)流程图之注册设备
一、设备注册过程 1、将i2c设备信息保存到i2c_board_info结构体中; 2、在注册i2c_board_info时(i2c_register_board_info)将它加入一个全局列表__i2c_board_list中, 3、在注册I2c adapter适配器驱动后,再从全局列表…

AI找Bug,一键快速预测
作者 | Jane出品 | AI科技大本营(ID:rgznai100)在程序开发中,程序员每天都要和 Bug 打交道,对新手程序员而言,debug 是一件非常让人头疼的事情。好不容易写完一段代码,一运行,全是红色ÿ…

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

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

Java数据结构与算法(八)-二叉树
一、为什么要使用树 有序数组插入、删除数据慢。链表查找数据慢树可以解决这两个问题二、相关术语 树的结点:包含一个数据元素及若干指向子树的分支;孩子结点:结点的子树的根称为该结点的孩子;双亲结点:B 结点是A 结点…
linux驱动:i2c驱动(四)流程图之注册驱动
二、i2c设备的驱动部分 1、i2c驱动i2c_driver 2、通过i2c_add_driver注册 2、注册过程中 比较i2c_device_id数组中各成员的id与i2c_client中的名字,找到设备 3、执行i2c_driver驱动中的probe

Expression Blend实例中文教程(2) - 界面快速入门
上一篇主要介绍Expression系列产品,另外概述了Blend的强大功能,本篇将用Blend 3创建一个新Silverlight项目,通过创建的过程,对Blend进行快速入门学习。 在开始使用Blend前,首先需要进行Silverlight的开发环境搭建&…
Lua基本语法-书写规范以及自带常用函数
Lua基本语法-书写规范和常用函数本文提供全流程,中文翻译。Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例) 1String Operation —— 字符串操作2Table ——…

linux驱动:音频驱动(一)ALSA
一、【基础知识】 1、J2 《--HPR_OUTHPL_OUT 《-- U13(TLV320AIC3104IRHBR)的HPROUTHPLOUT 2、驱动源码 IPNC_RDK_V3.8.0.1/Source/ti_tools/ipnc_psp_arago/kernel/sound/soc/codecs/tlv320aic3x.c 3、依赖于I2C驱动 4、声卡驱动框架:…

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

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

70.nodejs操作mongodb
转自: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周年之际,百度联合新华社推出了一个刷屏级的H5应用——用AI技术为黑白老照片上色,浓浓的怀旧风勾起了心底快被遗忘的时光。想了解如何给老照片上色?本次公开课中,我们邀请到了百度高级研发工程师李超,他的…

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

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

testem方便的web tdd 测试框架使用
备注:单元测试,对于日常的开发是比较重要的,testem 简化了我们的代码编写,以及运行。主要特性:a. 支持的测试框架有:jasmine quint mocha buster.js ,同时也包含一些其他的适配器,支…
linux驱动:音频驱动(三)ASoc之machine驱动及card初始化
一、machine驱动及card初始化

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

一场库文件的远程修复
一场库文件的远程修复系统环境RHEL 4.7一、原因:发现每天早上7点1分备份的数据库文件时间不对,登录上去后date下发现时间是正确。二、尝试解决:1)setup->Timezone configuration-> Asia/Shanghai保存后,发现由原…
linux驱动:音频驱动(四)ASoc之machine设备
linux驱动:音频驱动(四)ASoc之machine设备

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

熬夜写代码,不如换女装入GitHub获上千Star?
作者 | 琥珀出品 | AI科技大本营(ID: rgznai100)程序员如何以合规手段快速获得 GitHub 上千 Star?新年刚过,GitHub Trending 上一个名为“Dress”的开源项目迅速蹿红,并成功掀起了不少程序员及吃瓜群众的热议。项目地址…

CCNp笔记(EIGRP)
EIGRP<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />特性1属于混合路由协议具有距离矢量路由协议的特性,又有链路状态路由协议的特性。2属于高级距离矢量路由协议3快速收敛4保证100%无环路5增量更新6支持默认4条最多…
linux驱动:音频驱动(五)ASoc之codec驱动
linux驱动:音频驱动(五)ASoc之codec驱动

科大讯飞市值腰斩背后,AI产业集体思考如何落地?
作者丨郭敏本文经授权转载自钛媒体(ID:taimeiti)【导语】在过去的一年里,科大讯飞受到了多方质疑,质疑的声音不外乎盈利疲软、靠政府补助、技术优势逐渐变弱等,种种质疑背后,其实整个 AI 产业从…

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

Python告诉你:为何年终奖多发一元,到手却少两千多?
作者 | shenzhongqiang来源 | Python数据与分析(ID:ML_Python)年终奖多发一元,到手却要少两千多,甚至更多。听到这个消息的时候,大家是不是觉得有点意外,意外之余还有点淡淡的忧伤?上…