基于 real 210 的adc的驱动简要解析

ADC是嵌入式产品常用的设备,它的驱动并不是很难,但是如果有多个这类设备的话,就得考虑ADC中断共享的问题了,这样反而是驱动变得较复杂,且不易控制。
在real210 的代码里面  在arch/arm/plat-samsung目录下加入了adc.c这个代码,这是一个通用adc驱动代码。这个代码用来初始化adc设备并构建了一个客户请求列表,用来接受客户请求转换数据。

下面这个结构体用来描述一个客户:

struct s3c_adc_client {
        structplatform_device        *pdev; 
        structlist_head         pend;        //用来构建客户请求列表
        wait_queue_head_t        *wait;        //等待队列头,用来睡眠
        unsignedint         nr_samples;
        int                result;
        unsigned char        is_ts;        //是否是触摸屏
        unsigned char         channel;        //通道

void (*select_cb)(struct s3c_adc_client *c, unsigned selected);
        void (*convert_cb)(struct s3c_adc_client *c,
                unsigned val1, unsigned val2,
                        unsigned *samples_left); //转换回调函数
        };

我们需要在我们的驱动中构建这个结构体,并且向adc通用驱动中注册这个结构体。注册函数为:

struct s3c_adc_client *s3c_adc_register(structplatform_device *pdev,
                        void (*select)(struct s3c_adc_client *client,unsignedint selected),
                        void (*conv)(struct s3c_adc_client *client,unsigned d0, unsigned d1,unsigned *samples_left),
                        unsignedintis_ts)

然后我们就可以读取相应通道的数据了:

s3c_adc_get_adc_data(channel);

现在我们开始写我们的驱动:

1、 构建我们的设备结构体

在arch/arm/plat_samsung/Dev-adc.c中添加如下内容

struct platform_device s3c_device_adc = {
.name = "samsung-adc",
.id = -1,
.num_resources= ARRAY_SIZE(s3c_adc_resource),
.resource = s3c_adc_resource,
};

2、 注册我们的设备

修改arch/arm/mach-S5pv210/mach-smdkc110.c,在结构体数组smdk2410_devices中添加我们的设备:

staticstructplatform_device *smdk2410_devices[] __initdata = {
                ……
         &s3c_device_adc,
                ……
        };

软后在 S5pc110_battery.c   路径是 (kernel\drivers\power)
里面的函数  s3c_bat_get_adc_data(S3C_ADC_TEMPERATURE);
获取 通道S3C_ADC_TEMPERATURE 的adc的值
有兴趣的朋友可以去看看 


还有一种上层获取 adc的值得方法是 通过proc来做的  下面是kernel需要添加的代码
建立proc的文件
  #if 1
        #include <linux/proc_fs.h>
     //lulu add for read batter info 
     #define PROC_NAME "battery"
struct proc_dir_entry *root_entry;
struct proc_dir_entry *entry;
root_entry = proc_mkdir(PROC_NAME, &proc_root);
if(root_entry)
{
entry = create_proc_entry("battery_info" ,0666, root_entry);
if(entry)
{
entry->write_proc = battery_proc_write;
entry->read_proc =  battery_proc_read;
entry->data = (void*)0;
}
}
#endif


#if 1
//lulu add for read write battery info
static int battery_proc_write(struct file *file, const char *buffer, 
                           unsigned long count, void *data) 
{      
printk("\n battery_proc_write\n");
       return 1; 

static int battery_proc_read(char *page, char **start, off_t off, 
  int count, int *eof, void *data) 
{
int value;
int i;
int len;
len = sprintf(page, "\n%s = \n", __func__);
for (i=0; i<5; i++)  {
value = s3c_adc_get_adc_data(0);
len += sprintf(page+len, " %d,", value);
udelay(10);
}
udelay(100);
len += sprintf(page+len, "\n");
for (i=0; i<5; i++)  {
value = s3c_adc_get_adc_data(1); //获取adc 1 通道的数值
len += sprintf(page+len, " %d,", value);
udelay(10);
}
len += sprintf(page+len, "}\n");
return len;
}
#endif


可以在java层 通过读写proc的方式来获取 adc的值  基于上层如何读写proc 我想我在另一篇博客里面有说的 我在这里就不说了啊
Android 如何利用proc有上层想kernel写文件

你可能感兴趣的:(c,struct,File,嵌入式,buffer,resources)