📄 digi.c
字号:
/*************************************************************************Title: Filename: $Header:$Hardware: MX21Summay:License: The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/Author: Company: Motorola Suzhou Design Center====================Change Log========================$Log:$********************************************************************************////@file digi.c///@brief This is the digi driver source code///@author Karen Kang///@bug///@verstion $Version$#ifndef __KERNEL__# define __KERNEL__#endif#ifndef MODULE# define MODULE#endif#include <linux/config.h>#include <linux/module.h>#include <linux/version.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/delay.h>#include <linux/poll.h>#include <asm/uaccess.h> #include <linux/miscdevice.h>#include <linux/string.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/fcntl.h>#include <linux/interrupt.h>#include <linux/ptrace.h>#include <linux/ioport.h>#include <linux/in.h>#include <linux/slab.h>#include <linux/vmalloc.h>#include <linux/string.h>#include <linux/init.h>#include <asm/bitops.h>#include <asm/io.h>#include <linux/errno.h>#include <linux/tqueue.h>#include <linux/wait.h>#include <asm/irq.h>#include <asm/arch/hardware.h>#include <asm/arch/irqs.h>#include <linux/pm.h>#include "digi.h"#define CONFIG_ARCH_MX2ADS 1#ifdef CONFIG_ARCH_MX2ADS#include <asm/arch/mx2.h>#endiftypedef unsigned int U32; /* unsigned 32 bit data */typedef U32 * P_U32; /* unsigned 32 bit data */#define CSPI1_BASE_ADDR 0xE400E000 #define CSPI1_RXDATAREG1 (CSPI1_BASE_ADDR+0x00) // 32bit cspi1 receive data reg#define CSPI1_TXDATAREG1 (CSPI1_BASE_ADDR+0x04) // 32bit cspi1 transmit data reg#define CSPI1_CONTROLREG1 (CSPI1_BASE_ADDR+0x08) // 32bit cspi1 control reg#define CSPI1_INTREG1 (CSPI1_BASE_ADDR+0x0C) // 32bit cspi1 interrupt stat/ctr reg#define CSPI1_TESTREG1 (CSPI1_BASE_ADDR+0x10) // 32bit cspi1 test reg#define CSPI1_PERIODREG1 (CSPI1_BASE_ADDR+0x14) // 32bit cspi1 sample period ctrl reg#define CSPI1_DMAREG1 (CSPI1_BASE_ADDR+0x18) // 32bit cspi1 dma ctrl reg#define CSPI1_RESETREG1 (CSPI1_BASE_ADDR+0x1C) // 32bit cspi1 soft reset reg#define MODULE_NAME "digi"//#define DBMX_DEBUG 1#ifdef DBMX_DEBUG#define TRACE(fmt, args...) \ { \ printk("\n %s:%d:%s:",__FILE__, __LINE__,__FUNCTION__); \ printk(fmt, ## args);\ }#else#define TRACE(fmt, args...)#endif#define FAILED(fmt, args...) \ { \ printk("\n %s:%d:%s:",__FILE__, __LINE__,__FUNCTION__); \ printk(fmt, ## args);\ }#define INFO(fmt, args...) \ { \ printk("\n"); \ printk(fmt, ## args);\ }//>>>>>> Private Macro//<<<<<Private Function Declearationstatic int digi_open(struct inode * inode, struct file * filp);static int digi_release(struct inode * inode, struct file * filp);static int digi_fasync(int fd, struct file *filp, int mode);static int digi_ioctl(struct inode * inode,struct file *filp,unsigned int cmd,unsigned long arg);static ssize_t digi_read(struct file * filp, char * buf, size_t count, loff_t * l);static unsigned int digi_poll(struct file * filp, struct poll_table_struct * wait);static int check_device(struct inode *pInode);static ts_event_t* get_data(void);static void spi_tx_data(u16 data);static int get_block(ts_event_t* * block, int size);static void digi_sam_callback(unsigned long data);static void add_x_y(unsigned x, unsigned y, unsigned flag);static int init_buf(void);static void spi_flush_fifo(void);#ifdef CONFIG_ARCH_MX2ADSstatic int spi_tx_fifo_empty(void);static int spi_rx_fifo_data_ready(void);static unsigned int spi_exchange_data(unsigned int dataTx);#endif//>>>>>Private Function Declearation//<<<<<< Global Variablestatic int g_digi_major=0;//static struct proc_dir_entry * g_proc_dir;static devfs_handle_t g_devfs_handle;static wait_queue_head_t digi_wait;struct fasync_struct *ts_fasync;static u16 rptr, wptr;static struct timer_list pen_timer; u8 pen_timer_status; spinlock_t pen_lock;static struct tasklet_struct digi_tasklet; struct pm_dev *g_digi_pm;static int g_Digi_Status;#define DIGI_OPEN_STATUS 0x0001#define DIGI_SUSPEND_STATUS 0x0002struct file_operations g_digi_fops = { open: digi_open, release: digi_release, read: digi_read, poll: digi_poll, ioctl: digi_ioctl, fasync: digi_fasync, }; //>>>>>> Global Variable#define CSPI1_BASE_ADDR 0xE400E000 #define CSPI1_RXDATAREG1 (CSPI1_BASE_ADDR+0x00) // 32bit cspi1 receive data reg#define CSPI1_TXDATAREG1 (CSPI1_BASE_ADDR+0x04) // 32bit cspi1 transmit data reg#define CSPI1_CONTROLREG1 (CSPI1_BASE_ADDR+0x08) // 32bit cspi1 control reg#define CSPI1_INTREG1 (CSPI1_BASE_ADDR+0x0C) // 32bit cspi1 interrupt stat/ctr reg#define NODATA() (rptr==wptr)/***Misc functions for touch pannel*/static void touch_pan_enable(void){#ifdef CONFIG_ARCH_MX2ADS //set cspi1_ss0 to be low effective //cspi1_ss0 --pd28, it connect with pen_cs_b _reg_GPIO_DR(GPIOD) &= (~0x10000000);#endif#ifdef CONFIG_ARCH_MX1ADS REG_PC_DR &= (~0x00008000); #endif }static void touch_pan_disable(void){#ifdef CONFIG_ARCH_MX2ADS //set the cspi1_ss0 to be high _reg_GPIO_DR(GPIOD) |= 0x10000000;#endif#ifdef CONFIG_ARCH_MX1ADS //set the output [15] to be high REG_PC_DR |= 0x00008000;#endif }static void touch_pan_set_inter(void){ int temp;#ifdef CONFIG_ARCH_MX2ADS //pc14, tout pin connect to penIrq _reg_GPIO_GIUS(GPIOC) |= 0x00004000; _reg_GPIO_OCR1(GPIOC) |= 0x30000000; //new _reg_GPIO_IMR(GPIOC) &= ~(0x00004000); _reg_GPIO_DDIR(GPIOC) &= ~(0x00004000); temp = _reg_GPIO_SSR(GPIOC);#endif#ifdef CONFIG_ARCH_MX1ADS //PenIrq is connected to PD31, //first set bit31 of PortD GPIO GIUS_D REG_PD_GIUS |= 0x80000000; //mask the Pen interrupt in PD[31] REG_PD_IMR &= TOUCH_INT_MASK; //set it to be input REG_PD_DDIR &= 0x7fffffff; REG_PD_ICR2 &= 0x3fffffff; temp = REG_PD_SSR;#endif }static void touch_pan_enable_inter(void){#ifdef CONFIG_ARCH_MX2ADS _reg_GPIO_IMR(GPIOC) |= 0x00004000; #endif#ifdef CONFIG_ARCH_MX1ADS //unmask the Pen interrupt in PD[31] REG_PD_IMR |= ~TOUCH_INT_MASK;#endif }static void touch_pan_disable_inter(void){#ifdef CONFIG_ARCH_MX2ADS _reg_GPIO_IMR(GPIOC) &= ~(0x00004000);#endif#ifdef CONFIG_ARCH_MX1ADS //mask the Pen interrupt in PD[31] REG_PD_IMR &= TOUCH_INT_MASK; #endif }static void touch_pan_clear_inter(void){#ifdef CONFIG_ARCH_MX2ADS _reg_GPIO_ISR(GPIOC) = 0x00004000;#endif#ifdef CONFIG_ARCH_MX1ADS REG_PD_ISR = ~TOUCH_INT_MASK;#endif }static void touch_pan_set_pos_inter(void){#ifdef CONFIG_ARCH_MX2ADS _reg_GPIO_ICR1(GPIOC) &= 0xcfffffff;#endif#ifdef CONFIG_ARCH_MX1ADS //here set it to be positive edge sensitive REG_PD_ICR2 &= 0x3fffffff;#endif }//here set it to be Negative level sensitivestatic void touch_pan_set_neg_inter(void){#ifdef CONFIG_ARCH_MX2ADS _reg_GPIO_ICR1(GPIOC) &= 0xcfffffff; _reg_GPIO_ICR1(GPIOC) |= 0x10000000;#endif#ifdef CONFIG_ARCH_MX1ADS REG_PD_ICR2 &= 0x7fffffff; REG_PD_ICR2 |= 0x40000000; //to be 01#endif}//here check if it is positive level sensitivestatic u8 touch_pan_check_int_pol(void){#ifdef CONFIG_ARCH_MX2ADS if((_reg_GPIO_ICR1(GPIOC) & 0x30000000) == 0x10000000) return 0; else return 1;#endif#ifdef CONFIG_ARCH_MX1ADS if((REG_PD_ICR2 & 0xC0000000) == TOUCH_INT_NEG_POLARITY) return 0; else return 1;#endif}void touch_pan_init(void)//chip select for ADC{#ifdef CONFIG_ARCH_MX2ADS //cspi1_ss0 --pd28, it connect with pen_cs_b _reg_GPIO_GIUS(GPIOD) |= 0x10000000; _reg_GPIO_OCR2(GPIOD) |= 0x03000000; _reg_GPIO_DR(GPIOD) |= 0x10000000; _reg_GPIO_DDIR(GPIOD) |= 0x10000000;#endif#ifdef CONFIG_ARCH_MX1ADS //Here should also configure the Touch pannel select pin //Port C 15, it should be configured to be GPIO function //first set GIUS to be 1 to select GPIO signal REG_PC_GIUS |= 0x00008000; //then set the OCR1 to be 11 to use data register REG_PC_OCR1 |= 0xc0000000; //SPI1_SS to be output bit 15 REG_PC_DDIR |= 0x00008000; //se//t PUEN to be 1 to set the pin is pulled high REG_PC_PUEN |= 0x00008000; //set the output [15] to be high disable REG_PC_DR |= 0x00008000; #endif}//read data from Touch Pannelvoid touch_pan_read_dev(u32* x, u32* y){ unsigned long x_upper, x_lower, y_upper, y_lower; unsigned long temp,i;#ifdef CONFIG_ARCH_MX2ADS temp = _reg_GPIO_ISR(GPIOC);#endif#ifdef CONFIG_ARCH_MX1ADS temp = REG_PD_ISR;#endif touch_pan_disable_inter(); touch_pan_enable(); x_upper = spi_exchange_data(0xD3); // this is dummy data x_upper = spi_exchange_data(0x00); x_lower = spi_exchange_data(0x00); //for(i=0;i<10000;i++); x_upper = spi_exchange_data(0xD3); // this is dummy data x_upper = spi_exchange_data(0x00); x_lower = spi_exchange_data(0x00); //for(i=0;i<10000;i++); y_upper = spi_exchange_data(0x93); // this is dummy data y_upper = spi_exchange_data(0x00); y_lower = spi_exchange_data(0x00); // for(i=0;i<10000;i++); y_upper = spi_exchange_data(0x90); // this is dummy data y_upper = spi_exchange_data(0x00); y_lower = spi_exchange_data(0x00); *x=( ((x_upper<<5) & 0xFFE0) | ((x_lower>>3) & 0x1F) ); *y=( ((y_upper<<5) & 0xFFE0) | ((y_lower>>3) & 0x1F) ); touch_pan_disable(); //printk("x=%d ,y=%d \n",*x,*y);#ifdef CONFIG_ARCH_MX2ADS _reg_GPIO_ISR(GPIOC) = temp;#endif }void touch_pan_read_data(u32* x,u32* y){#define NUM_OF_SAMPLE (4)#define MAX_POS_DIFF (4) u32 xPos[NUM_OF_SAMPLE], yPos[NUM_OF_SAMPLE]; touch_pan_read_dev(&xPos[0], &yPos[0]); if ((xPos[0]<100)||(xPos[0]>5000) || (yPos[0]<100)||(yPos[0]>5000)) { *x = TPNL_PEN_UPVALUE; *y = TPNL_PEN_UPVALUE; return; } touch_pan_read_dev(&xPos[1], &yPos[1]); if ((xPos[1]<100)||(xPos[1]>5000) || (yPos[1]<100)||(yPos[1]>5000)) { *x = TPNL_PEN_UPVALUE; *y = TPNL_PEN_UPVALUE; return; } touch_pan_read_dev(&xPos[2], &yPos[2]); if ((xPos[2]<100)||(xPos[2]>5000) || (yPos[2]<100)||(yPos[2]>5000)) { *x = TPNL_PEN_UPVALUE; *y = TPNL_PEN_UPVALUE; return; } touch_pan_read_dev(&xPos[3], &yPos[3]); if ((xPos[3]<100)||(xPos[3]>5000) || (yPos[3]<100)||(yPos[3]>5000)) { *x = TPNL_PEN_UPVALUE; *y = TPNL_PEN_UPVALUE; return; } *x = (xPos[0] + xPos[1] + xPos[2] + xPos[3])>>2; *y = (yPos[0] + yPos[1] + yPos[2] + yPos[3])>>2; return;}/** * Function Name: digi_isr * * Input: filp : * wait : * Value Returned: *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -