搞了搞ADC,突然发现像是再用库函数对32编程一样,API如下
struct iio_channel *iio_channel_get(struct device *dev, const char *consumer_channel);
功能:获取 iio 通道描述
参数:
dev: 使用该通道的设备描述指针
consumer_channel: 该设备所使用的 IIO 通道描述指针
void iio_channel_release(struct iio_channel *chan);
功能:释放 iio_channel_get 函数获取到的通道
参数:
chan:要被释放的通道描述指针
int iio_read_channel_raw(struct iio_channel *chan, int *val);
功能:读取 chan 通道 AD 采集的原始数据。
参数:
chan:要读取的采集通道指针
val:存放读取结果的指针
驱动代码:
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/moduleparam.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_platform.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/adc.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/iio/iio.h>
#include <linux/iio/machine.h>
#include <linux/iio/driver.h>
#include <linux/iio/consumer.h>
#define GPIO_LOW 0
#define GPIO_HIGH 1
int major;
int count;
static struct class *cls;
static int arg1=0;
module_param(arg1,int,S_IRUSR);
struct iio_channel *chan;
static int adc_open(struct inode *inode, struct file *file)
{
printk(KERN_EMERG "%s-%d: enter\n",__FUNCTION__,__LINE__);
return 0;
}
static struct file_operations adc_fops = {
.owner = THIS_MODULE,
.open = adc_open,
};
static int adc_probe(struct platform_device *pdev)
{
int i=0;
int ret,raw;
int result = -1;
printk(KERN_EMERG "%s-%d: enter\n",__FUNCTION__,__LINE__);
major = register_chrdev(0, "adc", &adc_fops);
cls = class_create(THIS_MODULE, "adc");
device_create(cls, NULL, MKDEV(major, 0), NULL, "adc_test");
chan = iio_channel_get(&(pdev->dev), NULL);
if (IS_ERR(chan))
{
chan = NULL;
printk("%s() have not set adc chan\n", __FUNCTION__);
return -1;
}
while(i<arg1)
{
ret = iio_read_channel_raw(chan, &raw);
if (ret < 0) {
printk("read hook adc channel() error: %d\n", ret);
return -1;
}
result = (1800*raw)/1023;
printk(KERN_INFO "i = %d raw= %d Voltage=%dmV\n",i,raw,result);
i++;
mdelay(500);
}
printk(KERN_INFO "%s-%d: exit\n",__FUNCTION__,__LINE__);
return 0;
}
static int adc_remove(struct platform_device *pdev)
{
printk(KERN_INFO "Enter %s\n", __FUNCTION__);
iio_channel_release(chan);
device_destroy(cls, MKDEV(major, 0));
class_destroy(cls);
unregister_chrdev(major, "adc");
return 0;
}
static const struct of_device_id of_adc_match[] = {
{ .compatible = "adc_test" },
{ /* Sentinel */ }
};
static struct platform_driver adc_driver = {
.probe = adc_probe,
.remove = adc_remove,
.driver = {
.name = "adc",
.owner = THIS_MODULE,
.of_match_table = of_adc_match,
},
};
static int __init adc_init(void)
{
printk(KERN_INFO "Enter %s\n", __FUNCTION__);
return platform_driver_register(&adc_driver);
return 0;
}
static void __exit adc_exit(void)
{
platform_driver_unregister(&adc_driver);
printk(KERN_INFO "Exit Hello world\n");
}
module_init(adc_init);
module_exit(adc_exit);
MODULE_LICENSE("GPL");
然后,dts文件新增内容:
adc_demo{
status = "okay";
compatible = "adc_test";
io-channels = <&saradc 3>;//通道三
};
加载模块使用命令:insmod adc.ko arg1=10,这里传递的参数是打印的次数,防止死循环,由于不知道是什么原因,测试程序无法在开发板上面跑,就把读取的操作放在了prob函数里面,为了防止出现死循环,传了个参数
有什么问题可以先去看看wiki的教程