📄 mc68328digi.c
字号:
/*----------------------------------------------------------------------------*//* mc68328digi.c,v 1.2 2001/02/12 11:14:10 pney Exp * * linux/drivers/char/mc68328digi.c - Touch screen driver. * * Author: Philippe Ney <philippe.ney@smartdata.ch> * Copyright (C) 2001 SMARTDATA <www.smartdata.ch> * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Thanks to: * Kenneth Albanowski for is first work on a touch screen driver. * Alessandro Rubini for is "Linux device drivers" book. * Ori Pomerantz for is "Linux Kernel Module Programming" guide. * * Updates: * 2001-03-07 Pascal bauermeister <pascal.bauermeister@smartdata.ch> * - Adapted to work ok on xcopilot; yet untested on real Palm. * - Added check for version in ioctl() * * 2001-03-21 Pascal bauermeister <pascal.bauermeister@smartdata.ch> * - bypass real hw uninits for xcopilot. Now xcopilot is * happy. It even no longer generates pen irq while this * irq is disabled (I'd like to understand why, so that * I can do the same in mc68328digi_init() !). * * 2001-10-23 Daniel Potts <danielp@cse.unsw.edu.au> * - support for uCdimm/68VZ328. I use SPI 2 which maps to the * same addresses as for 68EZ328 and requries less changes to * the code. For CS I use PF_A22; CSD0/CAS0 is not made * available off the uCdimm. * PF1 (/IRQ5) is already used on uCdimm by the ethernet * controller. We use /IRQ6 instead (PD7). * - kill_fasync and request_irq fixes for 2.4.x (only) support. * * * Hardware: Motorola MC68EZ328 DragonBall-EZ * Burr-Brown ADS7843 Touch Screen Controller * Rikei REW-A1 Touch Screen * * OS: uClinux version 2.0.38.1pre3 * * Connectivity: Burr-Brown DragonBall * PENIRQ ----> PD7 & PD4 (with a 100k resistor) * // BUSY ----> PF5 //changed by duwei 06/02/2003 * // CS ----> PB4 //changed by duwei 06/02/2003 * DIN ----> PE0 * DOUT ----> PE1 * DCLK ----> PE2 * There are some changed in the current platform: by duwei 03/20/2003 * ADS7843: /PENIRQ ----+----[100k resistor]---- : VCC * | * +----------------------- VZ328: /IRQ6(PD7) * States graph: * * ELAPSED & PEN_UP * (re-init) +------+ * +------------------------>| IDLE |<------+ * | +------+ | * | | | ELAPSED * | +------------------------+ | (re-init) * | | PEN_IRQ | * | | (disable pen_irq) | * | | (enable & set timer) | * | | | * | \/ | * +------+ | * | WAIT | | * +------+ | * /\ | | * | | +---------------+-------+------+---------------+ * | | | | | | * | | | | | | * | | +--------+ +-------+ +--------+ +--------+ * | +------->| ASK X | | ASK Y | | READ X | | READ Y | * | ELAPSED & +--------+ +-------+ +--------+ +--------+ * | PEN_DOWN | /\ | /\ | /\ | * | (init SPIM) +-----------' +---------' +---------' | * | (set timer) XCH_COMPLETE XCH_COMPLETE XCH_COMPLETE | * | | * | | * | | * +-------------------------------------------------------------------+ * XCH_COMPLETE * (release SPIM) * (set timer) * * * Remarks: I added some stuff for port on 2.2 and 2.4 kernels but currently * this version works only on 2.0 because not tested on 2.4 yet. * Someone interested? * *//*----------------------------------------------------------------------------*/#include <linux/kernel.h> /* We're doing kernel work */#include <linux/module.h> /* Specifically, a module */#include <linux/interrupt.h> /* We want interrupts */#include <linux/miscdevice.h> /* for misc_register() and misc_deregister() */#include <linux/fs.h> /* for struct 'file_operations' */#include <linux/timer.h> /* for timeout interrupts */#include <linux/param.h> /* for HZ. HZ = 100 and the timer step is 1/100 */#include <linux/sched.h> /* for jiffies definition. jiffies is incremented * once for each clock tick; thus it's incremented * HZ times per secondes.*/#include <linux/mm.h> /* for verify_area *///#include <linux/malloc.h> /* for kmalloc *///changed by duwei 03/19/2003#include <linux/slab.h> /* for kmalloc */#include <linux/init.h>#include <asm/irq.h> /* For IRQ_MACHSPEC *//*----------------------------------------------------------------------------*//*----------------------------define------------------------------------------*/#define CONFIG_M68VZ328 1#define CONFIG_UCDIMM 1 //added by duwei 03/21/2003/*----------------------------------------------------------------------------*/#if defined(CONFIG_M68328)/* These are missing in MC68328.h. I took them from MC68EZ328.h temporarily, * but did not dare modifying MC68328.h yet (don't want to break things and * have no time now to do regression testings) * - Pascal Bauermeister */#define ICR_ADDR 0xfffff302#define ICR_POL5 0x0080 /* Polarity Control for IRQ5 */#define IMR_MIRQ5 (1 << IRQ5_IRQ_NUM) /* Mask IRQ5 */#define IRQ5_IRQ_NUM 20 /* IRQ5 */#define PBPUEN BYTE_REF(PBPUEN_ADDR)#define PBPUEN_ADDR 0xfffff40a /* Port B Pull-Up enable reg */#define PB_CSD0_CAS0 0x10 /* Use CSD0/CAS0 as PB[4] */#define PDSEL BYTE_REF(PDSEL_ADDR)#define PDSEL_ADDR 0xfffff41b /* Port D Select Register */#define PD_IRQ1 0x10 /* Use IRQ1 as PD[4] */#define PF_A22 0x20 /* Use A22 as PF[5] */#define PF_IRQ5 0x02 /* Use IRQ5 as PF[1] */#define SPIMCONT WORD_REF(SPIMCONT_ADDR)#define SPIMCONT_ADDR 0xfffff802#define SPIMCONT_SPIMEN SPIMCONT_RSPIMEN#elif defined(CONFIG_M68EZ328)# include <asm/MC68EZ328.h> /* bus, port and irq definition of DragonBall EZ */#elif defined(CONFIG_M68VZ328)# include <asm/MC68VZ328.h>#else# error "mc68328digi: a known machine not defined."#endif//#include <linux/mc68328digi.h>#include "mc68328digi.h" //added by duwei 03/19/2003/*----------------------------------------------------------------------------*//* Debug */#if 0#if 0# define DPRINTK printk("%0: [%03d,%03d] ", __file__, \ current_pos.x, current_pos.y); \ printk#else# define DPRINTK __dummy__ static void __dummy__(const char* fmt, ...) {}#endif#endif/*----------------------------------------------------------------------------*/static const char* __file__ = __FILE__;/*----------------------------------------------------------------------------*//* * Kernel compatibility. * Kernel > 2.2.3, include/linux/version.h contain a macro for KERNEL_VERSION */#include <linux/version.h>#ifndef KERNEL_VERSION#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))#endif/* * Conditional compilation. LINUX_VERSION_CODE is the code of this version * (as per KERNEL_VERSION) */#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0))#include <asm/uaccess.h> /* for put_user */#include <linux/poll.h> /* for polling fnct */#endif/* * time limit * Used for a whole conversion (x & y) and to clock the Burr-Brown to fall the * BUSY signal down (otherwise, pen cannot generate irq anymore). * If this limit run out, an error is generated. In the first case, the driver * could recover his normal state. In the second, the BUSY signal cannot be * fallen down and the device have to be reseted. * This limit is defined as approximatively the double of the deglitch one. */#define CONV_TIME_LIMIT 50 /* ms *//* * Length of the data structure */#define DATA_LENGTH sizeof(struct ts_pen_info)/* * Size of the buffer for the event queue */#define TS_BUF_SIZE 32*DATA_LENGTH/* * Minor number for the touch screen device. Major is 10 because of the misc * type of the driver. */#define MC68328DIGI_MINOR 9/* * SPIMCONT fields for this app (not defined in asm/MC68EZ328.h). */#define SPIMCONT_DATARATE ( 7 <<SPIMCONT_DATA_RATE_SHIFT)/* SPICLK = CLK / 512 */#define SPIMCONT_BITCOUNT (15<< 0) /* 16 bits transfert *//* * SPIMCONT used values. */#define SPIMCONT_INIT (SPIMCONT_DATARATE | \ SPIMCONT_ENABLE | \ SPIMCONT_XCH *0 | \ SPIMCONT_IRQ *0 | \ SPIMCONT_IRQEN | \ SPIMCONT_PHA | \ SPIMCONT_POL | \ SPIMCONT_BITCOUNT )/* * ADS7843 fields (BURR-BROWN Touch Screen Controller). */#define ADS7843_START_BIT (1<<7)#define ADS7843_A2 (1<<6)#define ADS7843_A1 (1<<5)#define ADS7843_A0 (1<<4)#define ADS7843_MODE (1<<3) /* HIGH = 8, LOW = 12 bits conversion */#define ADS7843_SER_DFR (1<<2) /* LOW = differential mode */#define ADS7843_PD1 (1<<1) /* PD1,PD0 = 11 PENIRQ disable */#define ADS7843_PD0 (1<<0) /* PD1,PD0 = 00 PENIRQ enable *//* * SPIMDATA used values. *//* * Ask for X conversion. Disable PENIRQ. */#define SPIMDATA_ASKX (ADS7843_START_BIT | \ ADS7843_A2 | \ ADS7843_A1 *0| \ ADS7843_A0 | \ ADS7843_MODE *0| \ ADS7843_SER_DFR *0| \ ADS7843_PD1 | \ ADS7843_PD0 )/* * Ask for Y conversion. Disable PENIRQ. */#define SPIMDATA_ASKY (ADS7843_START_BIT | \ ADS7843_A2 *0| \ ADS7843_A1 *0| \ ADS7843_A0 | \ ADS7843_MODE *0| \ ADS7843_SER_DFR *0| \ ADS7843_PD1 | \ ADS7843_PD0 )/* * Enable PENIRQ. */#define SPIMDATA_NOP (ADS7843_START_BIT | \ ADS7843_A2 *0| \ ADS7843_A1 *0| \ ADS7843_A0 *0| \ ADS7843_MODE *0| \ ADS7843_SER_DFR *0| \ ADS7843_PD1 *0| \ ADS7843_PD0 *0 )/* * Generate clock to fall pull BUSY signal. * No start bit to avoid generating a BUSY at end of the transfert. */#define SPIMDATA_NULL 0/* * Useful masks. */#if defined (CONFIG_UCDIMM)#define PEN_MASK PD_IRQ6 /* pen irq signal from the Burr-Brown is */#define PEN_MASK_2 PD_IRQ1 /* connected to 2 pins of the DragonBall */ /* (bit 2 port F and bit 4 port D) *///#define BUSY_MASK PF_A22//#define CS_MASK PF_CSA1#define BUSY_MASK PB_TIN_TOUT /* use PB6 as the BUSY signal channel */#define CS_MASK PG_EMUIRQ /* use PG2 as the CS signal channel.added bu duwei 03/21/2003 *///#define CS_MASK PF_CLKO /* use PF2 as the CS signal channel.added by liusen 07/08/2004 *///#define CS_MASK PG_EMUCS /*use PG4 as the CS signal channel.added bu duwei 03/21/2003 */#define PESEL_MASK 0x07#define CONV_MASK 0x0FFF /* 12 bit conversion */#define PEN_IRQ_NUM IRQ6_IRQ_NUM/*#define CS_DATA PFDATA#define CS_PUEN PFPUEN#define CS_DIR PFDIR#define CS_SEL PFSEL*///changed by duwei 03/21/2003#define CS_DATA PGDATA#define CS_PUEN PGPUEN#define CS_DIR PGDIR#define CS_SEL PGSEL//changed by liusen 07/09/2004//#define CS_DATA PFDATA//#define CS_PUEN PFPUEN//#define CS_DIR PFDIR//#define CS_SEL PFSEL#define PENIRQ_DATA PDDATA#define PENIRQ_PUEN PDPUEN#define PENIRQ_DIR PDDIR#define PENIRQ_SEL PDSEL#define ICR_PENPOL ICR_POL6#define IMR_MPEN IMR_MIRQ6#else#error "unexpected"#define USE_PENIRQ_PULUP#define PEN_MASK PF_IRQ5 /* pen irq signal from the Burr-Brown is */#define PEN_MASK_2 PD_IRQ1 /* connected to 2 pins of the DragonBall */ /* (bit 2 port F and bit 4 port D) */#define BUSY_MASK PF_A22#define CS_MASK PB_CSD0_CAS0#define PESEL_MASK 0x07#define CONV_MASK 0x0FFF /* 12 bit conversion */#define PEN_IRQ_NUM IRQ5_IRQ_NUM/* chip select register offset */#define CS_DATA PBDATA#define CS_PUEN PBPUEN#define CS_DIR PBDIR#define CS_SEL PBSEL/* pen irq register offsets and data */#define PENIRQ_DATA PFDATA#define PENIRQ_PUEN PFPUEN#define PENIRQ_DIR PFDIR#define PENIRQ_SEL PFSEL#define ICR_PENPOL ICR_POL5#define IMR_MPEN IMR_MIRQ5#endif/* * Touch screen driver states. */#define TS_DRV_ERROR -1#define TS_DRV_IDLE 0#define TS_DRV_WAIT 1#define TS_DRV_ASKX 2#define TS_DRV_ASKY 3#define TS_DRV_READX 4#define TS_DRV_READY 5/* * Conversion status. */#define CONV_ERROR -1 /* error during conversion flow */ #define CONV_END 0 /* conversion ended (= pen is up) */#define CONV_LOOP 1 /* conversion continue (= pen is down) *//*----------------------------------------------------------------------------*//* macros --------------------------------------------------------------------*/#define TICKS(nbms) ((HZ*(nbms))/1000)/*----------------------------------------------------------------------------*//* * Look in the PF register if it is on interrupt state. */#ifdef CONFIG_XCOPILOT_BUGS# define IS_PEN_DOWN ((IPR&IPR_PEN)!=0)#else# define IS_PEN_DOWN ((PENIRQ_DATA & PEN_MASK)==ST_PEN_DOWN)#endif/* * State of the BUSY signal of the SPIM. *///#define IS_BUSY_ENDED ((PFDATA & BUSY_MASK)==0)//#define IS_BUSY_ENDED ((PGDATA & BUSY_MASK)==0) //changed by duwei 03/21/2003#define IS_BUSY_ENDED ((PBDATA & BUSY_MASK)==0) //changed by duwei 07/2/2003
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -