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

📄 sa1111_keyb.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
#if 0static void kbd_write_command_w(int data){	unsigned long flags;	spin_lock_irqsave(&kbd_controller_lock, flags);	kb_wait();	kbd_write_command(data);	spin_unlock_irqrestore(&kbd_controller_lock, flags);}#endifstatic void kbd_write_output_w(int data){	unsigned long flags;	spin_lock_irqsave(&kbd_controller_lock, flags);	kb_wait();	KBDDATA = data & 0xff;	spin_unlock_irqrestore(&kbd_controller_lock, flags);}/* * Test the keyboard interface.  We basically check to make sure that * we can drive each line to the keyboard independently of each other. */static int kbdif_test(void){	int ret = 0;	KBDCR = KBDCR_ENA | KBDCR_FKC;	udelay(2);	if ((KBDSTAT & (KBDSTAT_KBC | KBDSTAT_KBD)) != KBDSTAT_KBD) {		printk("Keyboard interface test failed[1]: %02x\n",		       KBDSTAT);		ret = -ENODEV;	}	KBDCR = KBDCR_ENA;	udelay(2);	if ((KBDSTAT & (KBDSTAT_KBC | KBDSTAT_KBD)) != (KBDSTAT_KBC | KBDSTAT_KBD)) {		printk("Keyboard interface test failed[2]: %02x\n",		       KBDSTAT);		ret = -ENODEV;	}	KBDCR = KBDCR_ENA | KBDCR_FKD;	udelay(2);	if ((KBDSTAT & (KBDSTAT_KBC | KBDSTAT_KBD)) != KBDSTAT_KBC) {		printk("Keyboard interface test failed[3]: %02x\n",		       KBDSTAT);		ret = -ENODEV;	}	return ret;}static char *__init initialize_kbd(void){	int status;	/*	 * Test the keyboard interface.	 */	kbdif_test();	/*	 * Ok, drop the force low bits, and wait a while,	 * and clear the stop bit error flag.	 */	KBDCR = KBDCR_ENA;	udelay(4);	KBDSTAT = KBD_STAT_STP;	/*	 * Ok, we're now ready to talk to the keyboard.  Reset	 * it, just to make sure we're starting in a sane state.	 *	 * Set up to try again if the keyboard asks for RESEND.	 */	do {		KBDDATA = KBD_CMD_RESET;		status = kbd_wait_for_input();		if (status == KBD_REPLY_ACK)			break;		if (status != KBD_REPLY_RESEND)			return "Keyboard reset failed, no ACK";	} while (1);	if (kbd_wait_for_input() != KBD_REPLY_POR)		return "Keyboard reset failed, no POR";	/*	 * Set keyboard controller mode. During this, the keyboard should be	 * in the disabled state.	 *	 * Set up to try again if the keyboard asks for RESEND.	 */	do {		kbd_write_output_w(KBD_CMD_DISABLE);		status = kbd_wait_for_input();		if (status == KBD_REPLY_ACK)			break;		if (status != KBD_REPLY_RESEND)			return "Disable keyboard: no ACK";	} while (1);#if 0				/*@@@ */	kbd_write_command_w(KBD_CCMD_WRITE_MODE);	kbd_write_output_w(KBD_MODE_KBD_INT			   | KBD_MODE_SYS | KBD_MODE_DISABLE_MOUSE |			   KBD_MODE_KCC);	/* ibm powerpc portables need this to use scan-code set 1 -- Cort */	kbd_write_command_w(KBD_CCMD_READ_MODE);	if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {		/*		 * If the controller does not support conversion,		 * Set the keyboard to scan-code set 1.		 */		kbd_write_output_w(0xF0);		kbd_wait_for_input();		kbd_write_output_w(0x01);		kbd_wait_for_input();	}#else	kbd_write_output_w(0xf0);	kbd_wait_for_input();	kbd_write_output_w(0x01);	kbd_wait_for_input();#endif	kbd_write_output_w(KBD_CMD_ENABLE);	if (kbd_wait_for_input() != KBD_REPLY_ACK)		return "Enable keyboard: no ACK";	/*	 * Finally, set the typematic rate to maximum.	 */	kbd_write_output_w(KBD_CMD_SET_RATE);	if (kbd_wait_for_input() != KBD_REPLY_ACK)		return "Set rate: no ACK";	kbd_write_output_w(0x00);	if (kbd_wait_for_input() != KBD_REPLY_ACK)		return "Set rate: no ACK";	return NULL;}int __init sa1111_kbd_init_hw(void){	char *msg;	int ret;	if (!request_mem_region(_KBDCR, 512, "keyboard"))		return -EBUSY;	SKPCR |= SKPCR_PTCLKEN;	KBDCLKDIV = 0;	KBDPRECNT = 127;	/* Flush any pending input. */	kbd_clear_input();	msg = initialize_kbd();	if (msg)		printk(KERN_WARNING "initialize_kbd: %s\n", msg);#if defined CONFIG_PSMOUSE	psaux_init();#endif	k_setkeycode	= sa1111_setkeycode;	k_getkeycode	= sa1111_getkeycode;	k_translate	= sa1111_translate;	k_unexpected_up	= sa1111_unexpected_up;	k_leds		= sa1111_leds;#ifdef CONFIG_MAGIC_SYSRQ	k_sysrq_xlate	= sa1111_sysrq_xlate;	k_sysrq_key	= 0x54;#endif	/* Ok, finally allocate the IRQ, and off we go.. */	ret = request_irq(IRQ_TPRXINT, keyboard_interrupt, 0, "keyboard", NULL);	if (ret)		release_mem_region(_KBDCR, 512);	return ret;}#if defined CONFIG_PSMOUSEstatic inline void handle_mouse_event(unsigned char scancode){	if (mouse_reply_expected) {		if (scancode == AUX_ACK) {			mouse_reply_expected--;			return;		}		mouse_reply_expected = 0;	}	add_mouse_randomness(scancode);	if (aux_count) {		int head = queue->head;		queue->buf[head] = scancode;		head = (head + 1) & (AUX_BUF_SIZE - 1);		if (head != queue->tail) {			queue->head = head;			if (queue->fasync)				kill_fasync(&queue->fasync, SIGIO,					    POLL_IN);			wake_up_interruptible(&queue->proc_list);		}	}}static void handle_mse_event(void){	unsigned int msests = MSESTAT;	unsigned int work = 10000;	unsigned char scancode;	while (msests & MSE_STAT_RXF) {		while (msests & MSE_STAT_RXF) {			scancode = MSEDATA & 0xff;			if (!(msests & MSE_STAT_STP))				handle_mouse_event(scancode);			if (!--work) {				printk(KERN_ERR				       "pc_keyb: mouse controller jammed (0x%02X).\n",				       msests);				return;			 /*XXX*/}			msests = MSESTAT;		}		work = 10000;	}}static void ms_wait(void){	unsigned long timeout = KBC_TIMEOUT;	do {		/*		 * "handle_kbd_event()" will handle any incoming events		 * while we wait - keypresses or mouse movement.		 */		handle_mse_event();		if (MSESTAT & MSE_STAT_TXE)			return;		mdelay(1);		timeout--;	}	while (timeout);#ifdef KBD_REPORT_TIMEOUTS	printk(KERN_WARNING "Mouse timed out[1]\n");#endif}static void mouse_interrupt(int irq, void *dev_id, struct pt_regs *regs){	unsigned long flags;	spin_lock_irqsave(&kbd_controller_lock, flags);	handle_mse_event();	spin_unlock_irqrestore(&kbd_controller_lock, flags);}/* * Check if this is a dual port controller. */static int __init detect_auxiliary_port(void){	unsigned long flags;	int loops = 10;	int retval = 0;	/* Check if the BIOS detected a device on the auxiliary port. */	if (aux_device_present == 0xaa)		return 1;	spin_lock_irqsave(&kbd_controller_lock, flags);	/* Put the value 0x5A in the output buffer using the "Write	 * Auxiliary Device Output Buffer" command (0xD3). Poll the	 * Status Register for a while to see if the value really	 * turns up in the Data Register. If the KBD_STAT_MOUSE_OBF	 * bit is also set to 1 in the Status Register, we assume this	 * controller has an Auxiliary Port (a.k.a. Mouse Port).	 */	// kb_wait();	// kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF);	SKPCR |= SKPCR_PMCLKEN;	MSECLKDIV = 0;	MSEPRECNT = 127;	MSECR = MSECR_ENA;	mdelay(50);	MSEDATA = 0xf4;	mdelay(50);	do {		unsigned int msests = MSESTAT;		if (msests & MSE_STAT_RXF) {			do {				msests = MSEDATA;	/* dummy read */				mdelay(50);				msests = MSESTAT;			}			while (msests & MSE_STAT_RXF);			printk(KERN_INFO "Detected PS/2 Mouse Port.\n");			retval = 1;			break;		}		mdelay(1);	}	while (--loops);	spin_unlock_irqrestore(&kbd_controller_lock, flags);	return retval;}/* * Send a byte to the mouse. */static void aux_write_dev(int val){	unsigned long flags;	spin_lock_irqsave(&kbd_controller_lock, flags);	// kb_wait();	// kbd_write_command(KBD_CCMD_WRITE_MOUSE);	ms_wait();	MSEDATA = val;	spin_unlock_irqrestore(&kbd_controller_lock, flags);}/* * Send a byte to the mouse & handle returned ack */static void aux_write_ack(int val){	unsigned long flags;	spin_lock_irqsave(&kbd_controller_lock, flags);	// kb_wait();	// kbd_write_command(KBD_CCMD_WRITE_MOUSE);	ms_wait();	MSEDATA = val;	/* we expect an ACK in response. */	mouse_reply_expected++;	ms_wait();	spin_unlock_irqrestore(&kbd_controller_lock, flags);}static unsigned char get_from_queue(void){	unsigned char result;	unsigned long flags;	spin_lock_irqsave(&kbd_controller_lock, flags);	result = queue->buf[queue->tail];	queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE - 1);	spin_unlock_irqrestore(&kbd_controller_lock, flags);	return result;}static inline int queue_empty(void){	return queue->head == queue->tail;}static int fasync_aux(int fd, struct file *filp, int on){	int retval;	retval = fasync_helper(fd, filp, on, &queue->fasync);	if (retval < 0)		return retval;	return 0;}/* * Random magic cookie for the aux device */#define AUX_DEV ((void *)queue)static int release_aux(struct inode *inode, struct file *file){	fasync_aux(-1, file, 0);	if (--aux_count)		return 0;	// kbd_write_cmd(AUX_INTS_OFF);                     /* Disable controller ints */	// kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE);	aux_write_ack(AUX_DISABLE_DEV);	/* Disable aux device */	MSECR &= ~MSECR_ENA;	free_irq(IRQ_MSRXINT, AUX_DEV);	return 0;}/* * Install interrupt handler. * Enable auxiliary device. */static int open_aux(struct inode *inode, struct file *file){	if (aux_count++) {		return 0;	}	queue->head = queue->tail = 0;	/* Flush input queue */	/* Don't enable the mouse controller until we've registered IRQ handler */	if (request_irq(IRQ_MSRXINT, mouse_interrupt, SA_SHIRQ, "PS/2 Mouse", AUX_DEV)) {		aux_count--;		return -EBUSY;	}	MSECLKDIV = 0;	MSEPRECNT = 127;	MSECR &= ~MSECR_ENA;	mdelay(50);	MSECR = MSECR_ENA;	mdelay(50);	MSEDATA = 0xf4;	mdelay(50);	if (MSESTAT & 0x0100) {		MSESTAT = 0x0100;	/* clear IRQ status */	}/*  kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); *//* Enable the   auxiliary port on   controller. */	aux_write_ack(AUX_ENABLE_DEV);	/* Enable aux device */	// kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */	// send_data(KBD_CMD_ENABLE);   /* try to workaround toshiba4030cdt problem */	return 0;}/* * Put bytes from input queue to buffer. */static ssize_tread_aux(struct file *file, char *buffer, size_t count, loff_t * ppos){	DECLARE_WAITQUEUE(wait, current);	ssize_t i = count;	unsigned char c;	if (queue_empty()) {		if (file->f_flags & O_NONBLOCK)			return -EAGAIN;		add_wait_queue(&queue->proc_list, &wait);	      repeat:		set_current_state(TASK_INTERRUPTIBLE);		if (queue_empty() && !signal_pending(current)) {			schedule();			goto repeat;		}		current->state = TASK_RUNNING;		remove_wait_queue(&queue->proc_list, &wait);	}	while (i > 0 && !queue_empty()) {		c = get_from_queue();		put_user(c, buffer++);		i--;	}	if (count - i) {		file->f_dentry->d_inode->i_atime = CURRENT_TIME;		return count - i;	}	if (signal_pending(current))		return -ERESTARTSYS;	return 0;}/* * Write to the aux device. */static ssize_twrite_aux(struct file *file, const char *buffer, size_t count,	  loff_t * ppos){	ssize_t retval = 0;	if (count) {		ssize_t written = 0;		if (count > 32)			count = 32;	/* Limit to 32 bytes. */		do {			char c;			get_user(c, buffer++);			aux_write_dev(c);			written++;		}		while (--count);		retval = -EIO;		if (written) {			retval = written;			file->f_dentry->d_inode->i_mtime = CURRENT_TIME;		}	}	return retval;}static unsigned int aux_poll(struct file *file, poll_table * wait){	poll_wait(file, &queue->proc_list, wait);	if (!queue_empty())		return POLLIN | POLLRDNORM;	return 0;}struct file_operations psaux_fops = {	read:		read_aux,	write:		write_aux,	poll:		aux_poll,	open:		open_aux,	release:	release_aux,	fasync:		fasync_aux,};/* * Initialize driver. */static struct miscdevice psaux_mouse = {	PSMOUSE_MINOR, "psaux", &psaux_fops};static int __init psaux_init(void){	int ret;	if (!request_mem_region(_MSECR, 512, "psaux"))		return -EBUSY;	if (!detect_auxiliary_port()) {		ret = -EIO;		goto out;	}	misc_register(&psaux_mouse);	queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);	memset(queue, 0, sizeof(*queue));	queue->head = queue->tail = 0;	init_waitqueue_head(&queue->proc_list);#ifdef CONFIG_PSMOUSE	aux_write_ack(AUX_SET_SAMPLE);	aux_write_ack(100);	/* 100 samples/sec */	aux_write_ack(AUX_SET_RES);	aux_write_ack(3);	/* 8 counts per mm */	aux_write_ack(AUX_SET_SCALE21);	/* 2:1 scaling */#endif	ret = 0; out: 	if (ret) 		release_mem_region(_MSECR, 512);	return ret;}#endif				/* CONFIG_PSMOUSE */

⌨️ 快捷键说明

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