linux adc驱动(基于三星通用adc api)

linux adc驱动(基于三星通用adc api)
硬件平台: 基于讯为开发板itop4412 scp 1g
驱动说明:
本驱动基于三星提供的通用api函数来实现的,具体adc寄存器操作有三星公司实 现,我们要做的是调用三星公司提供的api来实现我们自己的功能。下面对相关的结构体和api函数进行解析
[cpp]view plaincopy
structs3c_adc_client{
structplatform_device*pdev;
structlist_headpend;
wait_queue_head_t*wait;
unsignedintnr_samples;
intresult;
unsignedcharis_ts;
unsignedcharchannel;
void(*select_cb)(structs3c_adc_client*c,unsignedselected);
void(*convert_cb)(structs3c_adc_client*c,
unsignedval1,unsignedval2,
unsigned*samples_left);
};
一个具体s3c_adc_client结构体来描述一个具体的客户(一个具体的驱动)
2.我们需要在驱动中构建这个驱动,并且注册到linux的内核
[cpp]view plaincopy
structs3c_adc_client*s3c_adc_register(structplatform_device*pdev,
void(*select)(structs3c_adc_client*client,
unsignedintselected),
void(*conv)(structs3c_adc_client*client,
unsignedd0,unsignedd1,
unsigned*samples_left),
unsignedintis_ts)
例子:
[cpp]view plaincopy
adcdev.client=s3c_adc_register(dev,null,null,0);
3.adc开始和停止转换函数
[cpp]view plaincopy
ints3c_adc_start(structs3c_adc_client*client,
unsignedintchannel,unsignedintnr_samples)
[csharp]view plaincopy
staticvoids3c_adc_stop(structs3c_adc_client*client)
4.读取adc转换数据
[cpp]view plaincopy
ints3c_adc_read(structs3c_adc_client*client,unsignedintch)
5.adc配置相关的函数
具体的讲解可以读取博客http://blog.csdn.net/liuhaoyutz/article/details/7461268
平台文件adc设备注册
方法一:在配置文件/home/topeet/android4.0/itop4412_kernel_3.0/arch/arm/mach-exynos中的mach-itop4412.添加
[html]view plaincopy
structplatform_devices3c_device_adc_ctl={
.name=adc_ll,
.id=-1,
};
方法二:以模块的方式注册到内核
[cpp]view plaincopy
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
staticstructplatform_deviceadc_dev={
.name=adc_ll,
.id=-1,
};
staticint__initadc_dev_init(void)
{
platform_device_register(&adc_dev);
return0;
}
staticvoid__exitadc_dev_exit(void)
{
platform_device_unregister(&adc_dev);
}
module_init(adc_dev_init);
module_exit(adc_dev_exit);
module_license(gpl);
第二部分:基于杂项设备方式的设备驱动
[cpp]view plaincopy
/*
*thisprogramisfreesoftware;youcanredistributeitand/ormodify
*itunderthetermsofthegnugeneralpubliclicenseversion2as
*publishedbythefreesoftwarefoundation.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#definedevice_nameadc
#definedriver_nameadc_ll
typedefstruct{
structmutexlock;
structs3c_adc_client*client;
intchannel;
}adc_dev;
staticadc_devadcdev;
staticinlineintexynos_adc_read_ch(void){
intret;
ret=mutex_lock_interruptible(&adcdev.lock);
if(ret=len){
intr=copy_to_user(buffer,str,len);
returnr?r:len;
}else{
return-einval;
}
}
staticlongexynos_adc_ioctl(structfile*file,
unsignedintcmd,unsignedlongarg)
{
#defineadc_set_channel0xc000fa01
#defineadc_set_adctsc0xc000fa02
switch(cmd){
caseadc_set_channel:
exynos_adc_set_channel(arg);
break;
caseadc_set_adctsc:
/*donothing*/
break;
default:
return-einval;
}
return0;
}
staticintexynos_adc_open(structinode*inode,structfile*filp)
{
exynos_adc_set_channel(0);
printk(adcopened);
return0;
}
staticintexynos_adc_release(structinode*inode,structfile*filp)
{
printk(adcclosed);
return0;
}
staticstructfile_operationsadc_dev_fops={
owner:this_module,
open:exynos_adc_open,
read:exynos_adc_read,
unlocked_ioctl:exynos_adc_ioctl,
release:exynos_adc_release,
};
staticstructmiscdevicemisc={
.minor=misc_dynamic_minor,
.name=device_name,
.fops=&adc_dev_fops,
};
staticint__devinitexynos_adc_probe(structplatform_device*dev)
{
intret;
mutex_init(&adcdev.lock);
printk(%s,%d,__function__,__line__);
/*registerwiththecoreadcdriver.*/
#if1
adcdev.client=s3c_adc_register(dev,null,null,0);
if(is_err(adcdev.client)){
printk(itop4412_adc:cannotregisteradc);
ret=ptr_err(adcdev.client);
gotoerr_mem;
}
#endif
printk(%s,%d,__function__,__line__);
ret=misc_register(&misc);
printk(%s,%d,__function__,__line__);
printk(device_name initialized);
err_mem:
returnret;
}
staticint__devexitexynos_adc_remove(structplatform_device*dev)
{
misc_deregister(&misc);
s3c_adc_release(adcdev.client);
return0;
}
staticintitop4412_adc_ctl_suspend(structplatform_device*pdev,pm_message_tstate)
{
printk(itop4412_led_ctlsuspend:poweroff!);
return0;
}
staticintitop4412_adc_ctl_resume(structplatform_device*pdev)
{
printk(itop4412_led_ctlresume:poweron!);
return0;
}
staticstructplatform_driverexynos_adc_driver={
.probe=exynos_adc_probe,
.remove=exynos_adc_remove,
.suspend=itop4412_adc_ctl_suspend,
.resume=itop4412_adc_ctl_resume,
.driver={
.name=driver_name,
.owner=this_module,
},
};
staticint__initexynos_adc_init(void)
{
returnplatform_driver_register(&exynos_adc_driver);
}
staticvoid__exitexynos_adc_exit(void)
{
platform_driver_unregister(&exynos_adc_driver);
}
module_init(exynos_adc_init);
module_exit(exynos_adc_exit);
module_license(gpl);
module_author(topeetinc.);
测试代码
[cpp]view plaincopy
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
//#include
intmain(void){
intfd;
char*adc=/dev/adc;
charbuffer[512];
intlen=0,r=0;
memset(buffer,0,sizeof(buffer));
printf(adcready!);
if((fd=open(adc,o_rdwr|o_noctty|o_ndelay))<0)
printf(openadcerr!);
else{
printf(openadcsuccess!);
len=read(fd,buffer,10);
if(len==0)
printf(returnnull);
else{
r=atoi(buffer);
r=(int)(r*10000/4095);//datastransitiontores
printf(resvalueis%d,r);
}
}
}

研究小组开发了一种被称为FingerTrak的装置
广汽埃安独立运营是为了科创板吗
MAX1452诊断夹电路
海尔率先开启了物联网时代的生态品牌建设
液位控制器电路
linux adc驱动(基于三星通用adc api)
DiscoRobo和SketRobo机器人:会跳舞会画画的机器人
GaN成为打造高功率密度器件的天然之选
电阻触摸屏的校准算法
云计算和AI或成谷歌新的切入点
浪涌保护器SPD防雷模块的作用和原理
畅谈“芯”机遇 共谋“芯”未来丨时擎受邀出席无锡经开区2023集成电路产业恳谈会(上海专场)
小蓝酷骑接连倒闭,共享时代的经济模式究竟是怎样的?
雷神911GT拆解,整机模板极佳,布线也十分精细
多功能电力仪表的接线须知,安全的前提是你有充足的技术知识!
音质最好的入耳式降噪耳机 真无线降噪耳机排名
关于小米9产能的问题,MIUI开启集中整治行动
医用注射器/预灌封注射器滑动性能测试仪
小米6:4月发布 骁龙835是标配 还有陶瓷尊享版!
怎样用好手中的六位半万用表?