⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gc_keyb.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 3 页
字号:
	ulong	ret;	// discard leading 0x00 and command echo 0 (command group value)	while (ReadSSPByte() == 0);	// discard command echo 1 (command code value)	ReadSSPByte();	// data from SMARTIO	// It assumes LSB first.	// NOTE:Some command uses MSB first order	ret = 0;	for (i=0;i<num;i++) {		ret |= ReadSSPByte() << (8*i);	}	return ret;}typedef	struct	t_SMARTIO_CMD {	unchar	Group;	unchar	Code;	unchar  Opt[2];}	SMARTIO_CMD;static	SMARTIO_CMD RD_INT_CMD = { 0x83, 0x01, { 0x00, 0x00 } };static	SMARTIO_CMD RD_KBD_CMD = { 0x83, 0x02, { 0x00, 0x00 } };static	SMARTIO_CMD RD_ADC_CMD = { 0x83, 0x28, { 0x00, 0x00 } };static	SMARTIO_CMD RD_KPD_CMD = { 0x83, 0x04, { 0x00, 0x00 } };static	volatile ushort	adc_value;static	volatile unchar	kpd_value;static	unsigned int	kpd_timeout = 10000;			// 10000 msecstatic  ulong kbd_int, kpd_int, adc_int;static void smartio_interrupt_task(void *data);static struct tq_struct tq_smartio = {		{ NULL,	NULL },		// struct list_head		0,			// unsigned long sync		smartio_interrupt_task,	// void (*routine)(void *)		NULL,			// void *data};DECLARE_WAIT_QUEUE_HEAD(smartio_queue);DECLARE_WAIT_QUEUE_HEAD(smartio_adc_queue);DECLARE_WAIT_QUEUE_HEAD(smartio_kpd_queue);DECLARE_WAIT_QUEUE_HEAD(keyboard_done_queue);DECLARE_WAIT_QUEUE_HEAD(sniffer_queue);static spinlock_t smartio_busy_lock = SPIN_LOCK_UNLOCKED;static atomic_t	smartio_busy = ATOMIC_INIT(0);static int f_five_pressed = 0;static int f_seven_pressed = 0;//static int e_null_counter = 0;//static int f_null_counter = 0;//static int keydown = 0;static unchar previous_code = 0;//static int e0 = 0;static void smartio_interrupt_task(void *arg){	unchar	code;	unsigned long flags;	unchar  dummy;	spin_lock_irqsave(&smartio_busy_lock, flags);	if (atomic_read(&smartio_busy) == 1) {		spin_unlock_irqrestore(&smartio_busy_lock, flags);		queue_task(&tq_smartio, &tq_timer);	}	else {		atomic_set(&smartio_busy, 1);		spin_unlock_irqrestore(&smartio_busy_lock, flags);	}	/* Read SMARTIO Interrupt Status to check which Interrupt is occurred	 * and Clear SMARTIO Interrupt */	send_SSP_msg((unchar *) &RD_INT_CMD, 2);	code = (unchar) (read_SSP_response(1) & 0xFF);#ifdef CONFIG_VT	if (code  & 0x04) {					// Keyboard Interrupt		kbd_int++;		/* Read Scan code */		send_SSP_msg((unchar *) &RD_KBD_CMD, 2);		code = (unchar) (read_SSP_response(1) & 0xFF);		dummy = code & 0x80;		if ((code == 0xE0) || (code == 0xE1) || (code == 0xF0)) {	// combined code			if (code == 0xF0) {				if (!previous_code) {					code = 0xE0;					previous_code = 0xF0;				} else {					code = mf_two_kbdmap[code & 0x7F] | dummy;					previous_code = 0;				}			} else if (code == 0xE0) {				if (previous_code != 0) {					code = mf_two_kbdmap[code & 0x7F] | dummy;					previous_code = 0;				} else previous_code = code;			} else {						// 0xE1				if (!previous_code) {					code = mf_two_kbdmap[code &0x7F] | dummy;					previous_code = 0;				} else {					previous_code = code;				}			}		} else {			if (code == 0x03) {				f_five_pressed = 1;			} else if (code == 0x83) {				if (f_five_pressed != 0) {					f_five_pressed = 0;					code = 0x03;				} else if (f_seven_pressed == 0) {					f_seven_pressed = 1;					code = 2;					dummy = 0;				} else {					f_seven_pressed = 0;					code = 2;				}			}			previous_code = 0;			code &= 0x7F;			code = mf_two_kbdmap[code] | dummy;		}		sniffed_value = (ushort)code;		if (SNIFFER) wake_up_interruptible(&sniffer_queue);		if (SNIFFMODE == PASSIVE) {			handle_scancode( code, (code & 0x80) ? 0 : 1 );			if (code & 0x80) {				wake_up_interruptible(&keyboard_done_queue);				mdelay(10);		// this makes the whole thing a bit more stable							// keyboard handling can be corrupted when hitting							// thousands of keys like crazy. kbd_translate might catch up							// with irq routine? or there is simply a buffer overflow on							// the serial device? somehow it looses some key sequences.							// if a break code is lost or coruppted the keyboard starts							// to autorepeat like crazy and appears to hang.							// this needs further investigations! Thomas				kbd_press_flag = 0;			}			else				kbd_press_flag = 1;		}		code = 0;       // prevent furthermore if ... then to react!	}#endif	// ADC resolution is 10bit (0x000 ~ 0x3FF)	if (code & 0x02) {					// ADC Complete Interrupt		adc_int++;		send_SSP_msg((unchar *) &RD_ADC_CMD, 2);		adc_value = (ushort) (read_SSP_response(2) & 0x3FF);		wake_up_interruptible(&smartio_adc_queue);	}	if (code & 0x08) { 					// Keypad interrupt		kpd_int++;		send_SSP_msg((unchar *) &RD_KPD_CMD, 2);		kpd_value = (unchar) (read_SSP_response(1) & 0xFF);		wake_up_interruptible(&smartio_kpd_queue);	}	spin_lock_irqsave(&smartio_busy_lock, flags);	atomic_set(&smartio_busy, 0);	spin_unlock_irqrestore(&smartio_busy_lock, flags);	enable_irq(ADS_AVR_IRQ);	wake_up_interruptible(&smartio_queue);}static void gc_sio_interrupt(int irq, void *dev_id, struct pt_regs *regs){#ifdef CONFIG_VT	kbd_pt_regs = regs;#endif	// *NOTE*	// ADS SMARTIO interrupt is cleared after reading interrupt status	// from smartio.	// disable SMARTIO IRQ here and re-enable at samrtio_bh.	// 11/13/00 Woojung	disable_irq(ADS_AVR_IRQ);	queue_task(&tq_smartio, &tq_immediate);	mark_bh(IMMEDIATE_BH);}char gc_kbd_unexpected_up(unsigned char keycode){	return 0;}static inline void gc_sio_init(void){	GPDR |= (GPIO_GPIO10 | GPIO_GPIO12 | GPIO_GPIO13); 	// Output	GPDR &= ~GPIO_GPIO11;	// Alternative Function	GAFR |= (GPIO_GPIO10 | GPIO_GPIO11 | GPIO_GPIO12 | GPIO_GPIO13);	Ser4SSCR0 = 0xA707;	Ser4SSSR = SSSR_ROR;	Ser4SSCR1 = 0x0010;	Ser4SSCR0 = 0xA787;	// Reset SMARTIO	ADS_AVR_REG &= 0xFE;	mdelay(300);			// 10 mSec	ADS_AVR_REG |= 0x01;	mdelay(10);			// 10 mSec}void __init gc_kbd_init_hw(void){	printk (KERN_INFO "Graphics Client keyboard driver v1.0\n");	k_setkeycode	= gc_kbd_setkeycode;	k_getkeycode	= gc_kbd_getkeycode;	k_translate	= gc_kbd_translate;	k_unexpected_up	= gc_kbd_unexpected_up;#ifdef CONFIG_MAGIC_SYSRQ	k_sysrq_key	= 0x54;	/* sysrq table??? --rmk */#endif	gc_sio_init();	if (request_irq(ADS_AVR_IRQ,gc_sio_interrupt,0,"smartio", NULL) != 0)		printk("Could not allocate SMARTIO IRQ!\n");	sio_reset_flag = 1;}/* SMARTIO ADC Interface */#define SMARTIO_VERSION				0#define SMARTIO_PORT_A				1#define SMARTIO_PORT_B				2#define SMARTIO_PORT_C				3#define SMARTIO_PORT_D				4#define SMARTIO_SELECT_OPTION			5#define SMARTIO_BACKLITE			6#define SMARTIO_KEYPAD				7#define SMARTIO_ADC				8#define	SMARTIO_VEE_PWM				9#define SMARTIO_SLEEP				11#define SMARTIO_KBD_SNIFFER			12static	SMARTIO_CMD CONV_ADC_CMD = { 0x80, 0x28, { 0x00, 0x00 } };static	SMARTIO_CMD READ_PORT_CMD = { 0x82, 0x00, { 0x00, 0x00 } };static	SMARTIO_CMD READ_DEVVER_CMD = { 0x82, 0x05, { 0x00, 0x00 } };static	SMARTIO_CMD READ_DEVTYPE_CMD = { 0x82, 0x06, { 0x00, 0x00 } };static	SMARTIO_CMD READ_FWLEVEL_CMD = { 0x82, 0x07, { 0x00, 0x00 } };static int lock_smartio(unsigned long *flags){	spin_lock_irqsave(&smartio_busy_lock, *flags);	if (atomic_read(&smartio_busy) == 1) {		spin_unlock_irqrestore(&smartio_busy_lock, *flags);		interruptible_sleep_on(&smartio_queue);	}	else {		atomic_set(&smartio_busy, 1);		spin_unlock_irqrestore(&smartio_busy_lock, *flags);	}	return 1;}static int unlock_smartio(unsigned long *flags){	spin_lock_irqsave(&smartio_busy_lock, *flags);	atomic_set(&smartio_busy, 0);	spin_unlock_irqrestore(&smartio_busy_lock, *flags);	return 1;}static ushort read_sio_adc(int channel){	unsigned long	flags;	if ((channel < 0) || (channel > 7))		return 0xFFFF;	CONV_ADC_CMD.Opt[0] = (unchar) channel;	lock_smartio(&flags);	send_SSP_msg((unchar *) &CONV_ADC_CMD, 3);	unlock_smartio(&flags);	interruptible_sleep_on(&smartio_adc_queue);	return adc_value & 0x3FF;}static ushort read_sio_port(int port){	unsigned long	flags;	ushort			ret;	if ((port < SMARTIO_PORT_B) || (port > SMARTIO_PORT_D))		return 0xFFFF;	READ_PORT_CMD.Code = (unchar) port;	lock_smartio(&flags);	send_SSP_msg((unchar *) &READ_PORT_CMD, 2);	ret = read_SSP_response(1);	unlock_smartio(&flags);	return ret;}static ushort read_sio_kpd(void){	long	timeout;	// kpd_timeout is mSec order	// interrupt_sleep_on_timeout is based on 10msec timer tick	if (kpd_timeout == -1) {		interruptible_sleep_on(&smartio_kpd_queue);	}	else {		timeout = interruptible_sleep_on_timeout(&smartio_kpd_queue,								kpd_timeout/10);		if (timeout == 0) {			// timeout without keypad input			return 0xFFFF;		}	}	return kpd_value;}static ushort read_sio_sniff(void){        long    timeout;        // kpd_timeout is mSec order        // interrupt_sleep_on_timeout is based on 10msec timer tick        if (sniffer_timeout == -1) {                interruptible_sleep_on(&sniffer_queue);        }        else {                timeout = interruptible_sleep_on_timeout(&sniffer_queue,                                                                sniffer_timeout/10);                if (timeout == 0) {                        // timeout without keypad input                        return -1;                }        }        return (ushort)sniffed_value;}static struct sio_ver {	uint	DevVer;	uint	DevType;	uint	FwLevel;};static ushort read_sio_version(struct sio_ver *ptr){	unsigned long	flags;	ushort          ret;	// Read Device Version	lock_smartio(&flags);	send_SSP_msg((unchar *) &READ_DEVVER_CMD, 2);	ret = read_SSP_response(1);	unlock_smartio(&flags);	ptr->DevVer = (uint)ret;	// Read Device Type	lock_smartio(&flags);	send_SSP_msg((unchar *) &READ_DEVTYPE_CMD, 2);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -