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

网友投稿 412 2022-10-23

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

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

驱动说明:

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 selected);

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

4.读取adc转换数据

[cpp] view plain copy

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

平台文件adc设备注册

[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

.name         = "adc_ll",

.id       = -1,

};

{

platform_device_register(&adc_dev);

return 0;

}

static 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

/*

* it under the terms of the GNU General Public License version 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);

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", value);

len = sprintf(str, "%d", 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");

return 0;

}

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

{

printk("adc closed");

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,

};

.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", __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");

ret = PTR_ERR(adcdev.client);

goto err_mem;

}

#endif

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

ret = misc_register(&misc);

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

printk(DEVICE_NAME" initialized");

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)

{

return 0;

}

static int itop4412_adc_ctl_resume (struct platform_device *pdev)

{

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

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!");

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

printf("open adc err!");

else{

printf("open adc success!");

len=read(fd,buffer,10);

if(len == 0)

printf("return null");

else{

r = atoi(buffer);

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

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

}

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:#yyds干货盘点# Kubernetes 管理业务配置方式有哪些?(08)
下一篇:Redis工具类封装RedisUtils的使用示例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~