优质服务商推荐更多服务商>

linuxadc驱动(基于三星通用adcapi)

4083

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

硬件平台: 基于讯为开发板itop4412 scp 1G\

 linuxadc驱动(基于三星通用adcapi)_设计制作_可编程逻辑

驱动说明:

本驱动基于三星提供的通用api函数来实现的,具体adc     寄存器   操作有三星公司实 现,我们要做的是调用三星公司提供的api来实现我们自己的功能。下面对相关的结构体和api函数进行解析

[cpp] view pl     ai   n copy

struct s3c_adc_client {

struct platform_device  *pdev;

struct list_head     pend;

wait_queue_head_t   *wait;

unsigned int         nr_samples;

int          result;

unsigned char        is_ts;

unsigned char        channel;

void    (*select_cb)(struct s3c_adc_client *c, unsigned selec     te   d);

void    (*convert_cb)(struct s3c_adc_client *c,

unsigned val1, unsigned val2,

unsigned *samples_left);

};

一个具体s3c_adc_client结构体来描述一个具体的客户(一个具体的驱动)


2.我们需要在驱动中构建这个驱动,并且注册到linux的内核

[cpp] view plain copy

struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev,

void (*select)(struct s3c_adc_client *client,

unsigned int selected),

void (*conv)(struct s3c_adc_client *client,

unsigned d0, unsigned d1,

unsigned *samples_left),

unsigned int is_ts)


例子:

[cpp] view plain copy

adcdev.client = s3c_adc_register(dev, NULL, NULL, 0);


3.adc开始和停止转换函数

[cpp] view plain copy

int s3c_adc_start(struct s3c_adc_client *client,

unsigned int channel, unsigned int nr_samples)

[csharp] view plain copy

sta     ti   c void s3c_adc_stop(struct s3c_adc_client *client)

4.读取adc转换数据

[cpp] view plain copy

int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)

5.adc配置相关的函数
具体的讲解可以读取博客http://blog.csdn.net/liuhaoyutz/ar  TI cle/details/7461268

平台文件adc设备注册

方法一:在配置文件/home/topeet/     Android   4.0/iTop4412_Kernel_3.0/arch/     arm   /mach-exynos中的mach-iTop4412.添加

[html] view plain copy

struct platform_device s3c_device_adc_ctl = {

.name                   = "adc_ll",

.id                             = -1,

};

方法二:以模块的方式注册到内核

[cpp] view plain copy

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

sta  TI c struct platform_device adc_dev = {

.name         = "adc_ll",

.id       = -1,

};

sta  TI c int __init adc_dev_init(void)

{

platform_device_register(&adc_dev);

return 0;

}

sta  TI c void __exit adc_dev_exit(void)

{

platform_device_unregister(&adc_dev);

}

module_init(adc_dev_init);

module_exit(adc_dev_exit);

MODULE_LICENSE("GPL");


第二部分:基于杂项设备方式的设备驱动

[cpp] view plain copy

/*

* This prog     ram   is free software; you     can   redistribute it and/or modify

* it under the terms of the GNU General Public License ve     rs   ion 2 as

* published by the Free Software Foundation.

*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define DEVICE_NAME     "adc"

#define DRIVER_NAME     "adc_ll"

typedef struct {

struct mutex lock;

struct s3c_adc_client *client;

int channel;

} ADC_DEV;

static ADC_DEV adcdev;

static inline int exynos_adc_read_ch(void) {

int ret;

ret = mutex_lock_interruptible(&adcdev.lock);

if (ret < 0)

return ret;

ret = s3c_adc_read(adcdev.client, adcdev.channel);

mutex_unlock(&adcdev.lock);

return ret;

}

static inline void exynos_adc_set_channel(int channel) {

if (channel < 0 || channel > 3)

return;

adcdev.channel = channel;

}

static ssize_t exynos_adc_read(struct file *filp, char *buffer,

size_t count, loff_t *ppos)

{

char str[20];

int value;

size_t len;

value = exynos_adc_read_ch();

printk("value = 0x%x\n", value);

len = sprintf(str, "%d\n", value);

if (count >= len) {

int r = copy_to_user(buffer, str, len);

return r ? r : len;

} else {

return -EINVAL;

}

}

static long exynos_adc_ioctl(struct file *file,

unsigned int cmd, unsigned long arg)

{

#define ADC_SET_CHANNEL     0xc000fa01

#define ADC_SET_ADCTSC      0xc000fa02

switch (cmd) {

case ADC_SET_CHANNEL:

exynos_adc_set_channel(arg);

break;

case ADC_SET_ADCTSC:

/* do nothing */

break;

default:

return -EINVAL;

}

return 0;

}

static int exynos_adc_open(struct inode *inode, struct file *filp)

{

exynos_adc_set_channel(0);

printk("adc opened\n");

return 0;

}

static int exynos_adc_release(struct inode *inode, struct file *filp)

{

printk("adc closed\n");

return 0;

}

static struct file_operations adc_dev_fops = {

owner:  THIS_MODULE,

open:   exynos_adc_open,

read:   exynos_adc_read,

unlocked_ioctl: exynos_adc_ioctl,

release:    exynos_adc_release,

};

static struct     mi   scdevice misc = {

.minor  = MISC_DYNAMIC_MINOR,

.name   = DEVICE_NAME,

.fops   = &adc_dev_fops,

};

static int __devinit exynos_adc_probe(struct platform_device *dev)

{

int ret;

mutex_init(&adcdev.lock);

printk("%s, %d\n", __FUNCTION__, __LINE__);

/* Register with the core ADC driver. */

#if 1

adcdev.client = s3c_adc_register(dev, NULL, NULL, 0);

if (IS_ERR(adcdev.client)) {

printk("itop4412_adc: cannot register adc\n");

ret = PTR_ERR(adcdev.client);

goto err_mem;

}

#endif

printk("%s, %d\n", __FUNCTION__, __LINE__);

ret = misc_register(&misc);

printk("%s, %d\n", __FUNCTION__, __LINE__);

printk(DEVICE_NAME"\tinitialized\n");

err_mem:

return ret;

}

static int __devexit exynos_adc_remove(struct platform_device *dev)

{

misc_deregister(&misc);

s3c_adc_release(adcdev.client);

return 0;

}

static int itop4412_adc_ctl_suspend (struct platform_device *pdev, pm_message_t state)

{

printk("itop4412_led_ctl suspend:power off!\n");

return 0;

}

static int itop4412_adc_ctl_resume (struct platform_device *pdev)

{

printk("itop4412_led_ctl resume:power on!\n");

return 0;

}

static struct platform_driver exynos_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,

},

};

static int __init exynos_adc_init(void)

{

return platform_driver_register(&exynos_adc_driver);

}

static void __exit exynos_adc_exit(void)

{

platform_driver_unregister(&exynos_adc_driver);

}

module_init(exynos_adc_init);

module_exit(exynos_adc_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("TOPEET Inc.");


    测试   代码

[cpp] view plain copy

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

//#include

//#include

int main(void){

int fd;

char *adc = "/dev/adc";

char buffer[512];

int len=0, r=0;

memset(buffer,0,sizeof(buffer));

printf("adc ready!\n");

if((fd = open(adc, O_RDWR|O_NOCTTY|O_NDELAY))<0)

printf("open adc err!\n");

else{

printf("open adc success!\n");

len=read(fd,buffer,10);

if(len == 0)

printf("return null\n");

else{

r = atoi(buffer);

r = (int)(r*10000/4095);    //Datas  transition to Res

printf("res value is %d\n",r);

}

}

}




特别声明:本文仅供交流学习 , 版权归属原作者,并不代表蚂蚜网赞同其观点和对其真实性负责。若文章无意侵犯到您的知识产权,损害了您的利益,烦请与我们联系vmaya_gz@126.com,我们将在24小时内进行修改或删除。

相关推荐: