SmartAudio/lichee/linux-4.9/drivers/input/sensor/sunxi_gpadc_test.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");