ADC被用于按钮识别,在\linux-3.4\drivers\input\keyboard\sunxi-keyboard.c中被调用。
由于ADC被占用,如果想用于其他功能,就要在内核配置中去掉sunxi keyboard选项。配置选项在这里:
Device Driver -> Input device support -> Keyboards -> softwinnner KEY BOARD support
注意:打开配置文件的命令是 sudo make ARCH=arm menuconfig 。这里“ARCH=arm”这个选项一定要加,否则内核配置选项会自动被按x86架构修改。那就全乱了。
可以参考的例子有:
1)\linux-3.4\drivers\input\keyboard\sunxi-keyboard.c 用ADC实现的按钮动作驱动。
2)\linux-3.4\drivers\char\sunxi_ir_cut\ir-cut.c 用ADC读出ir cut的位置。
ADC的驱动编写很简单,配置完参数后就可以直接读取了。
以下是驱动的代码。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEVICE_NAME "v3s_adc"
#define KEY_BASSADDRESS (0xf1c22800)
#define LRADC_DATA0 (0x0c)
#define LRADC_CTRL (0x00)
static u32 sunxi_keyboard_read_data(unsigned long addr)
{
u32 reg_val;
reg_val = readl((const volatile void __iomem *)(addr));
return reg_val;
}
static int adc_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
{
int key_val = 100;
int err;
// 直接在内存中读出AD转换结果
key_val = sunxi_keyboard_read_data(KEY_BASSADDRESS+LRADC_DATA0);
err = copy_to_user(buff,(const void *)&key_val, sizeof(key_val));
if(err)
printk("copy to user err\n");
return 1;
}
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.read = adc_read,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
static int sunxi_Adc_init(void)
{
int ret;
unsigned int reg_value = 0;
// ADC的参数配置,主要配置了 LRADC_ADC0_DATA_EN | LRADC_HOLD_EN | ADC_CHAN_SELECT(ch0)
reg_value = (1<<0)|(0<<2)|(0<<4)|(1<<6)|(0<<22) ;
writel(reg_value, KEY_BASSADDRESS + LRADC_CTRL);
ret = misc_register(&misc);
return ret;
}
static void __exit sunxi_Adc_exit(void)
{
misc_deregister(&misc);
}
module_init(sunxi_Adc_init);
module_exit(sunxi_Adc_exit);
MODULE_AUTHOR(" <@>");
MODULE_DESCRIPTION("sunxi-adc driver");
MODULE_LICENSE("GPL");
为了方便测试,将ADC驱动编译成动态驱动。
驱动文件名sunxi_adc.c。放在\linux-3.4\drivers\input\keyboard\路径下。
然后修改该路径下的Makefile,和Kconfig文件
在Makefile文件最下方添加以下代码:
obj-$(CONFIG_SUNXI_ADC) += sunxi_adc.o
在Kconfig最下方添加以下代码:
config SUNXI_ADC
tristate "sunxi adc function test"
default n
help
Say Y here to enable the sunxi adc funtion.
based on verify board.
这样menuconfig内就有了sunxi_adc选项。选择成M模式编译
保存退出,然后编译内核,就得到了sunxi_adc.ko。同在\linux-3.4\drivers\input\keyboard\路径下。
将驱动复制到板子上。运行 Insmod sunxi_adc.ko加载驱动。
要读取ADC值,在代码中加入
// 样例代码,可放在不同的函数中。用完记得close
// 打开驱动设备
if ((adc_fd = open("/dev/v3s_adc", O_RDWR)) == -1)
{
printf("open error\r\n");
return;
} else {
printf("v3s_adc device open success\r\n");
}
// 读取ADC值的函数
int adc;
if(read(adc_fd, &adc, sizeof(adc))<0)
{
printf("read adc value error\r\n");
}
printf("adc value = %d \r\n", adc);