GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
ifeq ($(CFG_SDK_EXPORT_FLAG),)
|
||||
ifneq ($(srctree),)
|
||||
KERNEL_DIR := $(srctree)
|
||||
SDK_DIR := $(shell cd $(KERNEL_DIR)/../../.. && /bin/pwd)
|
||||
else
|
||||
SDK_DIR := $(shell cd $(CURDIR)/../../../.. && /bin/pwd)
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(SDK_DIR)/build/base.mk
|
||||
|
||||
MOD_NAME := xm_lsadc
|
||||
|
||||
SRCS := adc.c
|
||||
SRCS += adc_init.c
|
||||
|
||||
SDK_KER_CFLAGS += -I$(GMP_DIR)/include \
|
||||
-I$(GMP_DIR)/drv/osal/include \
|
||||
-I$(GMP_DIR)/drv/include
|
||||
|
||||
SDK_KER_CFLAGS += -DUSER_BIT_32 -DKERNEL_BIT_32 -Wno-date-time -D_GNU_SOURCE
|
||||
|
||||
include $(SDK_DIR)/build/sdk_ko_rules.mk
|
||||
|
||||
|
||||
@@ -0,0 +1,447 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "osal.h"
|
||||
#include <linux/types.h>
|
||||
#include "adc.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((xmedia_void *)0)
|
||||
#endif
|
||||
|
||||
|
||||
#define lsadc_print(fmt, ...) osal_printk("Func:%s, Line:%d, "fmt"\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
|
||||
//#define USE_LSADC_CHANNEL_0
|
||||
//#define ENABLE_ADC_IRQ
|
||||
#define LSADC_IRQ_ID 37
|
||||
#define LSADC_BASE_ADDR 0x120a0000
|
||||
#define LSADC_ADDR_OFFSET(x) (LSADC_BASE_ADDR+(x))
|
||||
|
||||
#define LSADC_CRG_ADDR 0x120101BC
|
||||
|
||||
#define LSADC_CONFIG 0x00
|
||||
#define LSADC_GLITCH 0x04
|
||||
#define LSADC_TIMESCAN 0x08
|
||||
#define LSADC_PD_TD 0x0C
|
||||
#define LSADC_INTEN 0x10
|
||||
#define LSADC_INTSTATUS 0x14
|
||||
#define LSADC_INTCLR 0x18
|
||||
#define LSADC_START 0x1C
|
||||
#define LSADC_STOP 0x20
|
||||
#define LSADC_ACTBIT 0x24
|
||||
#define LSADC_CHNDATA 0x2C
|
||||
#define LSADC_ENABLE 0x3C
|
||||
|
||||
#define LSADC_MAX_CHN_NUM 3
|
||||
#define LSADC_NUM_BITS 10
|
||||
#define LSADC_ALL_CHN_INT_MASK 0xF
|
||||
|
||||
#define LSADC_ACTIVE_BIT (0xfff)
|
||||
#define LSADC_ACTIVE_BIT_MASK (0xFFF)
|
||||
|
||||
#define LSADC_DATA_DELTA (0xc)
|
||||
#define LSADC_DATA_DELTA_MASK (0xF)
|
||||
#define LSADC_GLITCH_SAMPLE (0x30)
|
||||
#define LSADC_TIME_SCAN (0x200)
|
||||
#define LSADC_GLITCH_TIME_US ((LSADC_GLITCH_SAMPLE + 1) * LSADC_TIME_SCAN * 25 / 100)
|
||||
|
||||
volatile xmedia_void* lsadc_reg = NULL;
|
||||
xmedia_s32 lsadc_irq = LSADC_IRQ_ID;
|
||||
|
||||
#ifdef ENABLE_ADC_IRQ
|
||||
#define INVALID_CDC_VALUE (0)
|
||||
typedef struct {
|
||||
xmedia_u32 adc_value;
|
||||
} lsadc_cdc_info;
|
||||
|
||||
lsadc_cdc_info g_cdc_info[LSADC_MAX_CHN_NUM];
|
||||
static osal_spinlock_t g_lsadc_spin_lock;
|
||||
#endif
|
||||
|
||||
#define LSADC_SPIN_LOCK_FLAG xmedia_ulong
|
||||
#define LSADC_VIR_ADDR(x) ((uintptr_t)(lsadc_reg) + ((x)-LSADC_BASE_ADDR))
|
||||
#define lsadc_writel(v, x) osal_writel(v, LSADC_VIR_ADDR(LSADC_ADDR_OFFSET(x)))
|
||||
#define lsadc_readl(x) osal_readl(LSADC_VIR_ADDR(LSADC_ADDR_OFFSET(x)))
|
||||
|
||||
static inline xmedia_void lsadc_reg_write(xmedia_ulong value, xmedia_ulong mask,
|
||||
xmedia_ulong addr)
|
||||
{
|
||||
xmedia_ulong t;
|
||||
|
||||
t = lsadc_readl(addr);
|
||||
t &= ~mask;
|
||||
t |= value & mask;
|
||||
lsadc_writel(t, addr);
|
||||
}
|
||||
|
||||
static xmedia_void write_reg32(xmedia_u32 value, xmedia_u32 mask, const xmedia_void* addr)
|
||||
{
|
||||
xmedia_u32 t;
|
||||
|
||||
t = osal_readl((xmedia_void*)addr);
|
||||
t &= ~mask;
|
||||
t |= value & mask;
|
||||
|
||||
osal_writel(t, (xmedia_void*)addr);
|
||||
}
|
||||
|
||||
static xmedia_void lsadc_enable_clock(xmedia_void)
|
||||
{
|
||||
xmedia_void *lsadc_crg_addr;
|
||||
|
||||
lsadc_crg_addr = osal_ioremap(LSADC_CRG_ADDR, (xmedia_ulong)0x4);
|
||||
|
||||
write_reg32(0x0 << 2, 0x1 << 2, lsadc_crg_addr); // (bit2)ls_adc_srst_req = 0
|
||||
osal_udelay(200);
|
||||
|
||||
write_reg32(0x1 << 3, 0x1 << 3, lsadc_crg_addr); // (bit3)ls_adc_cken = 1
|
||||
osal_udelay(100);
|
||||
|
||||
osal_iounmap((xmedia_void*)lsadc_crg_addr);
|
||||
}
|
||||
|
||||
static xmedia_void lsadc_disable_clock(xmedia_void)
|
||||
{
|
||||
xmedia_void *lsadc_crg_addr;
|
||||
|
||||
lsadc_crg_addr = osal_ioremap(LSADC_CRG_ADDR, (xmedia_ulong)0x4);
|
||||
|
||||
write_reg32(0x0 << 3, 0x1 << 3, lsadc_crg_addr); // (bit3)ls_adc_cken = 0
|
||||
osal_udelay(100);
|
||||
|
||||
write_reg32(0x1 << 2, 0x1 << 2, lsadc_crg_addr); // (bit2)ls_adc_srst_req = 1
|
||||
osal_udelay(100);
|
||||
|
||||
osal_iounmap((xmedia_void*)lsadc_crg_addr);
|
||||
}
|
||||
|
||||
static xmedia_s32 lsadc_open(xmedia_void* private_data)
|
||||
{
|
||||
lsadc_enable_clock();
|
||||
lsadc_reg_write(1 << 15, 1 << 15, LSADC_CONFIG); // exit reset state
|
||||
lsadc_reg_write(1 << 9, 1 << 9 , LSADC_ENABLE); // enable lsadc
|
||||
return 0;
|
||||
}
|
||||
|
||||
static xmedia_s32 lsadc_release(xmedia_void* private_data)
|
||||
{
|
||||
lsadc_reg_write(0 << 15, 1 << 15, LSADC_CONFIG); // enter reset state
|
||||
lsadc_reg_write(0 << 9, 1 << 9 , LSADC_ENABLE); // disable lsadc
|
||||
lsadc_disable_clock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 0: single scanning mode
|
||||
* 1: continuous scanning mode
|
||||
* The filter glitch is already eanble, only the continuous mode has a filter glitch, and the single mode is invalid.
|
||||
*/
|
||||
static xmedia_s32 lsadc_model_select(xmedia_s32 value)
|
||||
{
|
||||
xmedia_u32 val;
|
||||
|
||||
val = (xmedia_u32)value;
|
||||
|
||||
if ((val != 0) && (val != 1)) {
|
||||
lsadc_print("error value:%x\n", val);
|
||||
return -1;
|
||||
}
|
||||
|
||||
lsadc_reg_write(val << 13, 1 << 13, LSADC_CONFIG);
|
||||
|
||||
if (val == 1) {
|
||||
lsadc_reg_write(LSADC_ACTIVE_BIT, LSADC_ACTIVE_BIT_MASK, LSADC_ACTBIT); // [11:0]
|
||||
lsadc_reg_write(LSADC_DATA_DELTA << 20, LSADC_DATA_DELTA_MASK << 20, LSADC_CONFIG); // [23:20]
|
||||
lsadc_writel(LSADC_GLITCH_SAMPLE, LSADC_GLITCH); //glitch_sample, must > 0
|
||||
lsadc_writel(LSADC_TIME_SCAN, LSADC_TIMESCAN); //time_scan, must > 20
|
||||
/* set filter glitch function, 0:enable, 1:bypass, attention to LSADC_CTRL10(0x120a0028),
|
||||
* lsadc will filter the lsadc_zero value in this reg;defaule value is 0
|
||||
*/
|
||||
lsadc_reg_write(0 << 17, 1 << 17, LSADC_CONFIG);
|
||||
} else {
|
||||
lsadc_reg_write(1 << 17, 1 << 17, LSADC_CONFIG); //set glitch bypass
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static xmedia_s32 lsadc_chn_valid(xmedia_s32 chn, xmedia_s32 enable)
|
||||
{
|
||||
xmedia_ulong value;
|
||||
|
||||
value = enable ? 1 : 0;
|
||||
|
||||
switch (chn)
|
||||
{
|
||||
#ifdef USE_LSADC_CHANNEL_0
|
||||
case 0:
|
||||
lsadc_reg_write(value << 8, 1 << 8, LSADC_CONFIG);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 1:
|
||||
lsadc_reg_write(value << 9, 1 << 9, LSADC_CONFIG);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
lsadc_reg_write(value << 10, 1 << 10, LSADC_CONFIG);
|
||||
break;
|
||||
|
||||
default:
|
||||
lsadc_print("error chn:%d\n", chn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static xmedia_s32 lsadc_start(xmedia_void)
|
||||
{
|
||||
#ifdef ENABLE_ADC_IRQ
|
||||
LSADC_SPIN_LOCK_FLAG flag;
|
||||
#endif
|
||||
xmedia_s32 model_sel = 0;
|
||||
xmedia_s32 deglitch_bypass = 0;
|
||||
xmedia_s32 config = lsadc_readl(LSADC_CONFIG);
|
||||
xmedia_s32 chn_num = 0;
|
||||
xmedia_s32 sleep_time_ms = 0;
|
||||
if ( (config & (1 << 13)) != 0 ) {
|
||||
model_sel = 1;
|
||||
}
|
||||
if ( (config & (1 << 17)) != 0 ) {
|
||||
deglitch_bypass = 1;
|
||||
}
|
||||
if (1 == model_sel) {
|
||||
xmedia_s32 lsadc_active_bit = lsadc_readl(LSADC_ACTBIT) & 0xFFF;
|
||||
lsadc_print("config=%#x lsadc_active_bit=%#x\n", config, lsadc_active_bit);
|
||||
#ifdef USE_LSADC_CHANNEL_0
|
||||
if ( (config & (1 << 8)) != 0 ) {
|
||||
chn_num++;
|
||||
}
|
||||
#endif
|
||||
if ( (config & (1 << 9)) != 0 ) {
|
||||
chn_num++;
|
||||
}
|
||||
if ( (config & (1 << 10)) != 0 ) {
|
||||
chn_num++;
|
||||
}
|
||||
if (0 == deglitch_bypass) {
|
||||
xmedia_s32 sleep_time_us = LSADC_GLITCH_TIME_US * chn_num;
|
||||
sleep_time_ms = sleep_time_us / 1000;
|
||||
if (0 != (sleep_time_us % 1000))
|
||||
sleep_time_ms += 1;
|
||||
} else {
|
||||
sleep_time_ms = 1;
|
||||
lsadc_print("bypass in continuous scan mode! sleep_time_ms=%d\n", sleep_time_ms);
|
||||
}
|
||||
} else {
|
||||
sleep_time_ms = 1;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ADC_IRQ
|
||||
osal_memset(g_cdc_info, 0, sizeof(g_cdc_info));
|
||||
osal_spin_lock_irqsave(&g_lsadc_spin_lock, &flag);
|
||||
|
||||
lsadc_reg_write(1, 1, LSADC_INTEN); //inten enable
|
||||
lsadc_reg_write(LSADC_ALL_CHN_INT_MASK, LSADC_ALL_CHN_INT_MASK, LSADC_INTCLR); //clr all intflag
|
||||
osal_spin_unlock_irqrestore(&g_lsadc_spin_lock, &flag);
|
||||
#endif
|
||||
lsadc_reg_write(1, 1, LSADC_START); //start
|
||||
|
||||
osal_msleep(sleep_time_ms); // wait for scan & calculate equ_vaule.
|
||||
return 0;
|
||||
}
|
||||
|
||||
static xmedia_s32 lsadc_stop(xmedia_void)
|
||||
{
|
||||
#ifdef ENABLE_ADC_IRQ
|
||||
LSADC_SPIN_LOCK_FLAG flag;
|
||||
#endif
|
||||
|
||||
lsadc_reg_write(1, 1, LSADC_STOP); //stop
|
||||
|
||||
#ifdef ENABLE_ADC_IRQ
|
||||
osal_spin_lock_irqsave(&g_lsadc_spin_lock, &flag);
|
||||
osal_memset(g_cdc_info, 0, sizeof(g_cdc_info));
|
||||
lsadc_reg_write(0, 1, LSADC_INTEN); //inten disable
|
||||
|
||||
osal_spin_unlock_irqrestore(&g_lsadc_spin_lock, &flag);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static xmedia_s32 lsadc_get_chn_value(xmedia_s32 chn)
|
||||
{
|
||||
xmedia_u32 unchn;
|
||||
#ifdef USE_LSADC_CHANNEL_0
|
||||
if (chn < 0 || chn >= LSADC_MAX_CHN_NUM) {
|
||||
#else
|
||||
if (chn <= 0 || chn >= LSADC_MAX_CHN_NUM) {
|
||||
#endif
|
||||
lsadc_print("error chn:%d\n", chn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unchn = (xmedia_u32)chn;
|
||||
|
||||
#ifdef ENABLE_ADC_IRQ
|
||||
return g_cdc_info[unchn].adc_value;
|
||||
#else
|
||||
return lsadc_readl(LSADC_CHNDATA + (unchn << 2));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ADC_IRQ
|
||||
static xmedia_s32 lsadc_irq_proc(xmedia_s32 irq, xmedia_void* devId)
|
||||
{
|
||||
xmedia_u32 intstate;
|
||||
xmedia_s32 chn_value;
|
||||
xmedia_u32 chn;
|
||||
LSADC_SPIN_LOCK_FLAG flag;
|
||||
xmedia_u32 int_flag;
|
||||
|
||||
osal_spin_lock_irqsave(&g_lsadc_spin_lock, &flag);
|
||||
|
||||
intstate = lsadc_readl(LSADC_INTSTATUS);
|
||||
|
||||
for (chn = 0; chn < LSADC_MAX_CHN_NUM; chn++) {
|
||||
int_flag = 1 << chn;
|
||||
if (intstate & (int_flag)) {
|
||||
chn_value = lsadc_readl(LSADC_CHNDATA + (chn << 2));
|
||||
g_cdc_info[chn].adc_value = chn_value;
|
||||
lsadc_reg_write(int_flag, int_flag, LSADC_INTCLR);//clr intflag
|
||||
}
|
||||
}
|
||||
osal_spin_unlock_irqrestore(&g_lsadc_spin_lock, &flag);
|
||||
return OSAL_IRQ_HANDLED;
|
||||
}
|
||||
#endif
|
||||
|
||||
static xmedia_slong lsadc_ioctl (xmedia_u32 cmd, xmedia_ulong arg, xmedia_void* private_data)
|
||||
{
|
||||
xmedia_s32 ret = -1;
|
||||
xmedia_s32 param = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case LSADC_IOC_MODEL_SEL:
|
||||
{
|
||||
param = *(xmedia_s32*)(uintptr_t)arg;
|
||||
ret = lsadc_model_select(param);
|
||||
break;
|
||||
}
|
||||
|
||||
case LSADC_IOC_CHN_ENABLE:
|
||||
{
|
||||
param = *(xmedia_s32*)(uintptr_t)arg;
|
||||
ret = lsadc_chn_valid(param, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case LSADC_IOC_CHN_DISABLE:
|
||||
{
|
||||
param = *(xmedia_s32*)(uintptr_t)arg;
|
||||
ret = lsadc_chn_valid(param, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case LSADC_IOC_START:
|
||||
{
|
||||
ret = lsadc_start();
|
||||
break;
|
||||
}
|
||||
|
||||
case LSADC_IOC_STOP:
|
||||
{
|
||||
ret = lsadc_stop();
|
||||
break;
|
||||
}
|
||||
|
||||
case LSADC_IOC_GET_CHNVAL:
|
||||
{
|
||||
param = *(xmedia_s32*)(uintptr_t)arg;
|
||||
ret = lsadc_get_chn_value(param);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
lsadc_print("error cmd:%08x\n", cmd);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct osal_fileops g_lsadc_fops =
|
||||
{
|
||||
.open = lsadc_open,
|
||||
.release = lsadc_release,
|
||||
.unlocked_ioctl = lsadc_ioctl,
|
||||
};
|
||||
|
||||
static osal_dev_t* g_lsadc_dev;
|
||||
|
||||
xmedia_s32 lsadc_init(xmedia_void)
|
||||
{
|
||||
xmedia_s32 ret = 0;
|
||||
|
||||
if (!lsadc_reg) {
|
||||
lsadc_reg = (volatile xmedia_void*)osal_ioremap(LSADC_BASE_ADDR, 0x100);
|
||||
|
||||
if (!lsadc_reg) {
|
||||
lsadc_print("lsadc ioremap error.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ADC_IRQ
|
||||
lsadc_print("lsadc_irq=%d.\n", lsadc_irq);
|
||||
if (lsadc_irq <= 0) {
|
||||
lsadc_irq = LSADC_IRQ_ID;
|
||||
lsadc_print("lsadc_irq=LSADC_IRQ_ID(%d).\n", lsadc_irq);
|
||||
}
|
||||
|
||||
osal_spin_lock_init(&g_lsadc_spin_lock);
|
||||
|
||||
ret = osal_request_irq(lsadc_irq, lsadc_irq_proc, XMEDIA_NULL, "lsadc", &g_lsadc_fops);
|
||||
|
||||
if (ret != 0) {
|
||||
lsadc_print("lsadc request irq error.\n");
|
||||
osal_iounmap((xmedia_void*)lsadc_reg);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
g_lsadc_dev = osal_createdev("lsadc");
|
||||
g_lsadc_dev->minor = 255;
|
||||
g_lsadc_dev->fops = &g_lsadc_fops;
|
||||
ret = osal_registerdevice(g_lsadc_dev);
|
||||
|
||||
if (ret != 0) {
|
||||
osal_destroydev(g_lsadc_dev);
|
||||
lsadc_print("lsadc register device error.\n");
|
||||
osal_free_irq(lsadc_irq, &g_lsadc_fops);
|
||||
osal_iounmap((xmedia_void*)lsadc_reg);
|
||||
}
|
||||
|
||||
osal_printk("load xm_adc.ko OK!\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
xmedia_void lsadc_exit(xmedia_void)
|
||||
{
|
||||
#ifdef ENABLE_ADC_IRQ
|
||||
osal_free_irq(lsadc_irq, &g_lsadc_fops);
|
||||
osal_spin_lock_destory(&g_lsadc_spin_lock);
|
||||
#endif
|
||||
|
||||
osal_deregisterdevice(g_lsadc_dev);
|
||||
osal_destroydev(g_lsadc_dev);
|
||||
|
||||
lsadc_disable_clock();
|
||||
|
||||
osal_printk("unload xm_adc.ko OK!\n");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __ADC_H__
|
||||
#define __ADC_H__
|
||||
#include "drv_type_ioctl.h"
|
||||
#include "xmedia_type.h"
|
||||
|
||||
typedef enum IOC_NR_LSADC_E
|
||||
{
|
||||
IOC_NR_LSADC_MODEL_SEL = 0,
|
||||
IOC_NR_LSADC_CHN_ENABLE,
|
||||
IOC_NR_LSADC_CHN_DISABLE,
|
||||
IOC_NR_LSADC_START,
|
||||
IOC_NR_LSADC_STOP,
|
||||
IOC_NR_LSADC_GET_CHNVAL,
|
||||
IOC_NR_LSADC_BUTT
|
||||
}IOC_NR_LSADC_E;
|
||||
|
||||
#define LSADC_IOC_MODEL_SEL _IOWR(IOC_TYPE_LSADC, IOC_NR_LSADC_MODEL_SEL, xmedia_s32)
|
||||
#define LSADC_IOC_CHN_ENABLE _IOW(IOC_TYPE_LSADC, IOC_NR_LSADC_CHN_ENABLE, xmedia_s32)
|
||||
#define LSADC_IOC_CHN_DISABLE _IOW(IOC_TYPE_LSADC, IOC_NR_LSADC_CHN_DISABLE, xmedia_s32)
|
||||
#define LSADC_IOC_START _IO(IOC_TYPE_LSADC, IOC_NR_LSADC_START)
|
||||
#define LSADC_IOC_STOP _IO(IOC_TYPE_LSADC, IOC_NR_LSADC_STOP)
|
||||
#define LSADC_IOC_GET_CHNVAL _IOWR(IOC_TYPE_LSADC, IOC_NR_LSADC_GET_CHNVAL, xmedia_s32)
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __ADC_H__ */
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include "osal.h"
|
||||
|
||||
|
||||
extern unsigned int lsadc_irq;
|
||||
extern volatile void *lsadc_reg;
|
||||
extern int lsadc_init(void);
|
||||
extern void lsadc_exit(void);
|
||||
|
||||
static int adc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *mem;
|
||||
|
||||
lsadc_irq = platform_get_irq(pdev, 0);
|
||||
if (lsadc_irq <= 0)
|
||||
{
|
||||
dev_err(&pdev->dev, "cannot find lsadc IRQ%d. \n", lsadc_irq);
|
||||
}
|
||||
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
lsadc_reg = (volatile void *)devm_ioremap_resource(&pdev->dev, mem);
|
||||
if (IS_ERR((void* )lsadc_reg))
|
||||
{
|
||||
dev_err(&pdev->dev, "lsadc reg map failed. \n");
|
||||
}
|
||||
|
||||
return lsadc_init();
|
||||
}
|
||||
|
||||
static int adc_remove(struct platform_device *pdev)
|
||||
{
|
||||
lsadc_exit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id adc_match[] = {
|
||||
{ .compatible = "lotus,lsadc" },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct platform_driver lsadc_driver = {
|
||||
.probe = adc_probe,
|
||||
.remove = adc_remove,
|
||||
.driver = { .name = "xmedia_lsadc",
|
||||
.of_match_table = adc_match,
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef MODULE
|
||||
|
||||
osal_module_platform_driver(lsadc_driver);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#else
|
||||
|
||||
int __init adc_driver_init(void)
|
||||
{
|
||||
return osal_platform_driver_register(&lsadc_driver);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
ifeq ($(CFG_XMEDIA_EXPORT_FLAG),)
|
||||
SDK_DIR := $(shell cd $(CURDIR)/../../../../.. && /bin/pwd)
|
||||
endif
|
||||
|
||||
include $(SDK_DIR)/build/base.mk
|
||||
|
||||
TARGET := adc_test
|
||||
|
||||
LIBS :=
|
||||
|
||||
INCLUDES := -I$(GMP_DIR)/include \
|
||||
-I$(GMP_DIR)/drv/osal/include \
|
||||
-I$(GMP_DIR)/drv/include \
|
||||
-I$(GMP_DIR)/drv/lsadc
|
||||
|
||||
CFLAGS := $(SDK_USR_CFLAGS) $(LIBS) $(INCLUDES)
|
||||
|
||||
SRCS := $(wildcard ./*.c)
|
||||
|
||||
OBJS := $(patsubst %.c, %.o, $(SRCS))
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(OBJS)
|
||||
$(AT)$(CC) -o $(TARGET) $^ $(CFLAGS)
|
||||
|
||||
%.o : %.c
|
||||
$(AT)$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
clean:
|
||||
$(AT)rm -rf $(OBJS) $(TARGET)
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "adc.h"
|
||||
|
||||
|
||||
#define DEV_FILE "/dev/lsadc"
|
||||
|
||||
#define LSADC_GLITCH_SAMPLE_MS (7)
|
||||
|
||||
typedef enum {
|
||||
LSADC_SCAN_MODE_SINGLE_STEP,
|
||||
LSADC_SCAN_MODE_CONTINUOUS,
|
||||
LSADC_SCAN_MODE_BUTT
|
||||
} lsadc_scan_mode;
|
||||
|
||||
static xmedia_s32 lsadc_check_glitch
|
||||
(xmedia_s32 value_arr[13], xmedia_s32 start_pos, xmedia_s32 end_pos, xmedia_s32 *lsadc_equ_vaule)
|
||||
{
|
||||
xmedia_s32 j;
|
||||
xmedia_s32 last_sum = 0;
|
||||
xmedia_s32 start_value;
|
||||
const xmedia_s32 LSADC_DATA_DELTA = 0xc;
|
||||
xmedia_s32 arr_len = 13;
|
||||
xmedia_s32 len = end_pos - start_pos + 1;
|
||||
if (start_pos < 0 || start_pos >= arr_len || len <= 0 || end_pos >= arr_len || NULL == lsadc_equ_vaule) {
|
||||
fprintf(stderr, "fail to check! start_pos:%d end_pos:%d\n", start_pos, end_pos);
|
||||
return 0;
|
||||
}
|
||||
start_value = value_arr[start_pos];
|
||||
for(j = start_pos; j <= end_pos; j++) {
|
||||
last_sum += value_arr[j];
|
||||
}
|
||||
|
||||
*lsadc_equ_vaule = last_sum / len;
|
||||
if (*lsadc_equ_vaule - start_value > LSADC_DATA_DELTA
|
||||
|| start_value - *lsadc_equ_vaule > LSADC_DATA_DELTA) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
xmedia_s32 sample_lsadc_single_step_scan_mode(lsadc_scan_mode mode, xmedia_s32 chn)
|
||||
{
|
||||
xmedia_s32 i, value;
|
||||
xmedia_s32 fd = open(DEV_FILE, O_RDWR);
|
||||
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "fail to open file:%s\n", DEV_FILE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ioctl(fd, LSADC_IOC_MODEL_SEL, &mode) < 0) {
|
||||
fprintf(stderr, "adc model select error.\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if(ioctl(fd, LSADC_IOC_CHN_ENABLE, &chn) < 0) {
|
||||
fprintf(stderr, "enable chn %d error.\n", chn);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
printf("[%s] LSADC_GLITCH_SAMPLE_MS=%d\n", __FUNCTION__, LSADC_GLITCH_SAMPLE_MS);
|
||||
|
||||
for(i=0; i < 20; i++)
|
||||
{
|
||||
xmedia_s32 j, k;
|
||||
const xmedia_s32 gnum = LSADC_GLITCH_SAMPLE_MS;
|
||||
xmedia_s32 last_value[gnum + 6];
|
||||
xmedia_s32 lsadc_equ_vaule;
|
||||
xmedia_s32 len = sizeof(last_value) / sizeof(last_value[0]);
|
||||
for(j = 0; j < len; j++) {
|
||||
if(ioctl(fd, LSADC_IOC_START) < 0) {
|
||||
fprintf(stderr, "start lsadc error.\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
value = ioctl(fd, LSADC_IOC_GET_CHNVAL, &chn);
|
||||
last_value[j] = value;
|
||||
if (0 == j)
|
||||
printf("[%d][%d] get value:%d,chn[%d]\n", i, j, value, chn);
|
||||
if (j >= (gnum - 1)) {
|
||||
k = j - (gnum - 1);
|
||||
if (lsadc_check_glitch(last_value, k, j, &lsadc_equ_vaule)) {
|
||||
printf("[%d][%d] is glitch, value:%d equ_vaule:%d chn[%d]\n", i, k, last_value[k], lsadc_equ_vaule, chn);
|
||||
}
|
||||
}
|
||||
|
||||
if(ioctl(fd, LSADC_IOC_STOP) <0) {
|
||||
fprintf(stderr, "stop lsadc error.\n");
|
||||
}
|
||||
}
|
||||
usleep(1000*1000);
|
||||
}
|
||||
|
||||
exit:
|
||||
if(ioctl(fd, LSADC_IOC_STOP) < 0) {
|
||||
fprintf(stderr, "stop lsadc error.\n");
|
||||
}
|
||||
|
||||
if(ioctl(fd, LSADC_IOC_CHN_DISABLE, &chn) < 0) {
|
||||
fprintf(stderr, "disable chn %d error.\n", chn);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
xmedia_s32 sample_lsadc_continuous_scan_mode(lsadc_scan_mode mode, xmedia_s32 chn)
|
||||
{
|
||||
xmedia_s32 i, value;
|
||||
xmedia_s32 fd = open(DEV_FILE, O_RDWR);
|
||||
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "fail to open file:%s\n", DEV_FILE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ioctl(fd, LSADC_IOC_MODEL_SEL, &mode) < 0) {
|
||||
fprintf(stderr, "adc model select error.\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if(ioctl(fd, LSADC_IOC_CHN_ENABLE, &chn) < 0) {
|
||||
fprintf(stderr, "enable chn %d error.\n", chn);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if(ioctl(fd, LSADC_IOC_START) < 0) {
|
||||
fprintf(stderr, "start lsadc error.\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for(i = 0; i < 20; i++) {
|
||||
xmedia_s32 j, k;
|
||||
const xmedia_s32 gnum = LSADC_GLITCH_SAMPLE_MS;
|
||||
xmedia_s32 last_value[gnum + 6];
|
||||
xmedia_s32 lsadc_equ_vaule;
|
||||
xmedia_s32 len = sizeof(last_value) / sizeof(last_value[0]);
|
||||
for(j = 0; j < len; j++) {
|
||||
value = ioctl(fd, LSADC_IOC_GET_CHNVAL, &chn);
|
||||
last_value[j] = value;
|
||||
if (0 == j)
|
||||
printf("[%d][%d] get value:%d,chn[%d]\n", i, j, value, chn);
|
||||
if (j >= (gnum - 1)) {
|
||||
k = j - (gnum - 1);
|
||||
if (lsadc_check_glitch(last_value, k, j, &lsadc_equ_vaule)) {
|
||||
printf("[%d][%d] is glitch, value:%d equ_vaule:%d chn[%d]\n", i, k, last_value[k], lsadc_equ_vaule, chn);
|
||||
}
|
||||
}
|
||||
|
||||
usleep(1*1000);
|
||||
}
|
||||
usleep(1000*1000);
|
||||
}
|
||||
|
||||
exit:
|
||||
if(ioctl(fd, LSADC_IOC_STOP) < 0) {
|
||||
fprintf(stderr, "stop lsadc error.\n");
|
||||
}
|
||||
|
||||
if(ioctl(fd, LSADC_IOC_CHN_DISABLE, &chn) < 0) {
|
||||
fprintf(stderr, "disable chn %d error.\n", chn);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __LITEOS__
|
||||
xmedia_s32 app_main(xmedia_s32 argc, char *argv[])
|
||||
#else
|
||||
xmedia_s32 main(xmedia_s32 argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
lsadc_scan_mode mode = LSADC_SCAN_MODE_BUTT;
|
||||
xmedia_s32 chn = 0;
|
||||
|
||||
printf("select scan mode:\n");
|
||||
printf(" - [0] is single step scan mode\n");
|
||||
printf(" - [1] is Continuous scan mode\n");
|
||||
|
||||
mode = getchar() - '0';
|
||||
|
||||
getchar();
|
||||
printf("select ADC CHN:\n");
|
||||
printf(" - [0] is CHN[0]\n");
|
||||
printf(" - [1] is CHN[1]\n");
|
||||
printf(" - [2] is CHN[2]\n");
|
||||
|
||||
chn = getchar() - '0';
|
||||
|
||||
switch (mode) {
|
||||
case LSADC_SCAN_MODE_SINGLE_STEP:
|
||||
sample_lsadc_single_step_scan_mode(mode, chn);
|
||||
break;
|
||||
case LSADC_SCAN_MODE_CONTINUOUS:
|
||||
sample_lsadc_continuous_scan_mode(mode, chn);
|
||||
break;
|
||||
default:
|
||||
printf("error scan mode\n");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user