139 lines
4.4 KiB
C
139 lines
4.4 KiB
C
/*
|
|
* drivers/input/sensor/sunxi_gpadc_test.c
|
|
*
|
|
* Copyright (C) 2016 Allwinner.
|
|
* fuzhaoke <fuzhaoke@allwinnertech.com>
|
|
*
|
|
* SUNXI GPADC test file
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of
|
|
* the License, or (at your option) any later version.
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/init.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/ioport.h>
|
|
#include <asm/irq.h>
|
|
#include <asm/io.h>
|
|
#include <linux/timer.h>
|
|
#include <linux/irq.h>
|
|
#include <linux/of_irq.h>
|
|
#include "sunxi_gpadc.h"
|
|
|
|
struct sunxi_gpadc *sunxi_gpadc_handler;
|
|
|
|
extern void sunxi_gpadc_sample_rate_set(void __iomem *reg_base, u32 clk_in, u32 round_clk);
|
|
extern void sunxi_gpadc_ctrl_set(void __iomem *reg_base, u32 ctrl_para);
|
|
extern u32 sunxi_gpadc_ch_select(void __iomem *reg_base, enum gp_channel_id id);
|
|
extern u32 sunxi_gpadc_ch_deselect(void __iomem *reg_base, enum gp_channel_id id);
|
|
extern u32 sunxi_gpadc_mode_select(void __iomem *reg_base, enum gp_select_mode mode);
|
|
extern u32 sunxi_gpadc_ch_cmp(void __iomem *reg_base, enum gp_channel_id id, u32 low_uv, u32 hig_uv);
|
|
extern u32 sunxi_gpadc_cmp_select(void __iomem *reg_base, enum gp_channel_id id);
|
|
extern void sunxi_gpadc_en(void __iomem *reg_base, bool onoff);
|
|
extern u32 sunxi_gpadc_int_cfg(void __iomem *reg_base);
|
|
extern void sunxi_gpadc_int_set(void __iomem *reg_base, u32 int_para);
|
|
extern void sunxi_gpadc_int_clr(void __iomem *reg_base, u32 int_para);
|
|
extern u32 sunxi_gpadc_read_ints(void __iomem *reg_base);
|
|
extern void sunxi_gpadc_clr_ints(void __iomem *reg_base, u32 int_para);
|
|
extern u32 sunxi_gpadc_read_data(void __iomem *reg_base, enum gp_channel_id id);
|
|
extern struct sunxi_gpadc *sunxi_gpadc_get_handler(void);
|
|
|
|
|
|
static irqreturn_t sunxi_gpadc_interrupt(int irqno, void *dev_id)
|
|
{
|
|
struct sunxi_gpadc *sunxi_gpadc_handler = (struct sunxi_gpadc *)dev_id;
|
|
u32 reg_val = 0;
|
|
|
|
reg_val = sunxi_gpadc_read_ints(sunxi_gpadc_handler->reg_base);
|
|
reg_val &= sunxi_gpadc_int_cfg(sunxi_gpadc_handler->reg_base);
|
|
|
|
if (reg_val & GP_CH0_LOW_IRQ_PEND)
|
|
printk("channel 0 low pend\n");
|
|
|
|
if (reg_val & GP_CH1_LOW_IRQ_PEND)
|
|
printk("channel 1 low pend\n");
|
|
|
|
if (reg_val & GP_CH0_DATA_IRQ_PEND)
|
|
printk("val_ch0 = %d mv\n", sunxi_gpadc_read_data(sunxi_gpadc_handler->reg_base, GP_CH_0)*561);
|
|
|
|
if (reg_val & GP_CH1_DATA_IRQ_PEND)
|
|
printk("val_ch1 = %d mv\n", sunxi_gpadc_read_data(sunxi_gpadc_handler->reg_base, GP_CH_1)*561);
|
|
|
|
if (reg_val & GP_CH0_HIG_IRQ_PEND)
|
|
printk("channel 0 hight pend\n");
|
|
|
|
if (reg_val & GP_CH1_HIG_IRQ_PEND)
|
|
printk("channel 1 hight pend\n");
|
|
|
|
sunxi_gpadc_clr_ints(sunxi_gpadc_handler->reg_base, reg_val);
|
|
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
|
|
static int __init gp_test_init(void)
|
|
{
|
|
int try_time = 50;
|
|
int val;
|
|
|
|
printk("gp_test_init\n");
|
|
|
|
sunxi_gpadc_handler = sunxi_gpadc_get_handler();
|
|
if (NULL == sunxi_gpadc_handler) {
|
|
pr_err("sunxi_gpadc_handler is null !\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
sunxi_gpadc_sample_rate_set(sunxi_gpadc_handler->reg_base, OSC_24MHZ, 50000);
|
|
sunxi_gpadc_int_clr(sunxi_gpadc_handler->reg_base, ~0);
|
|
|
|
sunxi_gpadc_mode_select(sunxi_gpadc_handler->reg_base, GP_CONTINUOUS_MODE);
|
|
sunxi_gpadc_ch_select(sunxi_gpadc_handler, GP_CH_0);
|
|
|
|
#if 0
|
|
/* config for channle 1, enable low voltage interrupt */
|
|
sunxi_gpadc_ch_select(sunxi_gpadc_handler, GP_CH_1);
|
|
sunxi_gpadc_ch_cmp(sunxi_gpadc_handler->reg_base, GP_CH_1, 1500000, VOL_RANGE);
|
|
sunxi_gpadc_cmp_select(sunxi_gpadc_handler, GP_CH_1);
|
|
if (request_irq(sunxi_gpadc_handler->irq_num, sunxi_gpadc_interrupt,
|
|
IRQF_TRIGGER_NONE, "sunxi-gpadc", sunxi_gpadc_handler)) {
|
|
pr_err("sunxi_gpadc request irq failure\n");
|
|
return -1;
|
|
}
|
|
sunxi_gpadc_int_set(sunxi_gpadc_handler->reg_base, GP_CH1_LOW_IRQ_EN);
|
|
#endif
|
|
|
|
/* enable GPADC */
|
|
sunxi_gpadc_en(sunxi_gpadc_handler, true);
|
|
|
|
/* get the data of channel 0 */
|
|
while (try_time--) {
|
|
val = sunxi_gpadc_read_data(sunxi_gpadc_handler->reg_base, GP_CH_0);
|
|
printk("val = 0x%03x , vol=%d mv\n", val, val*561);
|
|
mdelay(100);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void __exit gp_test_exit(void)
|
|
{
|
|
printk("gp_test_exit\n");
|
|
#if 0
|
|
free_irq(sunxi_gpadc_handler->irq_num, sunxi_gpadc_handler);
|
|
#endif
|
|
sunxi_gpadc_en(sunxi_gpadc_handler, false);
|
|
}
|
|
|
|
module_init(gp_test_init);
|
|
module_exit(gp_test_exit);
|
|
|
|
|
|
MODULE_AUTHOR("Fuzhaoke");
|
|
MODULE_DESCRIPTION("sunxi-gpadc driver test");
|
|
MODULE_LICENSE("GPL");
|