rk3399下adc驅動
阿新 • • 發佈:2018-11-09
搞了搞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的教程