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

📄 hx4700_navpt.c

📁 pocket pc hx4700 linux driver
💻 C
字号:
/* * Synaptics NavPoint(tm) support in the hx470x. * * Copyright (c) 2005 SDG Systems, LLC * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file COPYING in the main directory of this archive for * more details. * * 10-Feb-2005          Todd Blumer <todd@sdgsystems.com> */#include <linux/module.h>#include <linux/version.h>#include <linux/config.h>#include <linux/errno.h>#include <linux/kthread.h>#include <linux/wait.h>#include <linux/platform_device.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/navpoint.h>#include <linux/input.h>#include <asm/hardware.h>#include <asm/irq.h>#include <asm/mach/irq.h>#include <asm/arch/pxa-regs.h>#include <asm/arch/hx4700-gpio.h>#include <asm/arch/ssp.h>/* * The iPAQ hx4700 uses several subsystems for input: PXA GPIOs for 2 keys,  * ASIC3 GPIOs for 3 other keys, NavPoint(tm) for input. We'll have each of * these tie into the kernel input system. That seems to be the most straight- * forward thing to do. * * Components that make up this driver: PXA SSP1 (SPI), input subsystem. */#define HX4700_NAVPT_SSP_PORT		1#define HX4700_NAVPT_SSP_TIMEOUT	0x17777		/* from WinCE *//* * must be power of 2 */#define SSP_QSIZE		512static struct ssp_dev ssp_dev;static struct navpoint_dev navpt_dev;static struct completion thread_comp;static volatile int must_die;static struct hx4700_navpoint {	struct task_struct *kthread;	wait_queue_head_t kthread_wait;	volatile unsigned int read_ndx;	volatile unsigned int write_ndx;	u_int8_t dataq[SSP_QSIZE];} hx4700_np;#define SSP_QMASK		(SSP_QSIZE-1)static voidrx_qinsert( u_int8_t octet ){	unsigned int nextw = (hx4700_np.write_ndx+1) & SSP_QMASK;	if (nextw == hx4700_np.read_ndx) {		printk( KERN_ERR "hx4700 navpoint queue full\n" );	}	else {		hx4700_np.dataq[nextw] = octet;		hx4700_np.write_ndx = nextw;	}}static voidrx_threshold_irq( void *priv, int count ){	int i;	int word;	for (i=0; i<count; i++) {		word = ssp_read_word( &ssp_dev );		/*		 * ssp mode is 16-bit words, extract and send to		 * navpoint driver		 */		rx_qinsert( (u_int8_t)((word >> 8) & 0xff) );		rx_qinsert( (u_int8_t)word );	}	wake_up_interruptible( &hx4700_np.kthread_wait );}inthx4700_navptd( void *notused ){	printk( "hx4700_navptd: receive thread started.\n" );	daemonize( "hx4700_navptd" );	while (!kthread_should_stop()) {		if (must_die)			break;		interruptible_sleep_on(&hx4700_np.kthread_wait);		/*wait_event_interruptible( hx4700_np.kthread_wait,			kthread_should_stop()			|| hx4700_np.read_ndx != hx4700_np.write_ndx );*/		try_to_freeze();		if (must_die)			break;		while (hx4700_np.read_ndx != hx4700_np.write_ndx) {			u_int8_t octet = hx4700_np.dataq[hx4700_np.read_ndx++];			hx4700_np.read_ndx &= SSP_QMASK;			navpoint_rx( &navpt_dev, octet, hx4700_np.write_ndx - hx4700_np.read_ndx);		}	}	complete_and_exit( &thread_comp, 0 );}static inthx4700_navpt_write( u_int8_t *data, int count ){	int odd, i;	u_int32_t word;	/*	 * SPI bus is in 16-bit word mode. If odd, we must still	 * shift in a zero byte to fill the word	 */	odd = count & 1;	for (i=0; i<count-odd; i+=2) {		word = (u_int32_t)data[i] << 8 | data[i+1];		// printk( "ssp write: 0x%x\n", word );		(void) ssp_write_word( &ssp_dev, word );	}	if (odd) {		word = (u_int32_t)data[count-1] << 8;		// printk( "ssp write odd: 0x%x\n", word );		(void) ssp_write_word( &ssp_dev, word );	}	return 0;}static struct ssp_ops hx4700_ssp_ops = {	.rx_thresh = rx_threshold_irq,	.priv = &ssp_dev,};// module_param(qsize, uint, 1024);static voidhx4700_ssp_init( void ){	ssp_dev.ops = &hx4700_ssp_ops;	ssp_init( &ssp_dev, HX4700_NAVPT_SSP_PORT, 0 );	ssp_config( &ssp_dev, SSCR0_Motorola | SSCR0_DataSize(16),		SSCR1_SCFR | SSCR1_SCLKDIR | SSCR1_SFRMDIR			| SSCR1_RWOT | SSCR1_TINTE | SSCR1_PINTE			| SSCR1_SPH | SSCR1_RIE			| SSCR1_TxTresh(1) | SSCR1_RxTresh(1),		0, SSCR0_SerClkDiv(2) );	SSTO_P(HX4700_NAVPT_SSP_PORT) = HX4700_NAVPT_SSP_TIMEOUT;}static inthx4700_navpt_probe( struct device *dev ){	pxa_gpio_mode( GPIO_NR_HX4700_SYNAPTICS_SPI_CLK_MD );	pxa_gpio_mode( GPIO_NR_HX4700_SYNAPTICS_SPI_CS_N_MD );	pxa_gpio_mode( GPIO_NR_HX4700_SYNAPTICS_SPI_DO_MD );	pxa_gpio_mode( GPIO_NR_HX4700_SYNAPTICS_SPI_DI_MD );	init_waitqueue_head( &hx4700_np.kthread_wait );	hx4700_ssp_init();	SET_HX4700_GPIO( SYNAPTICS_POWER_ON, 1 );	/*	 * start receiver thread for navpoint data	 */        must_die = 0;	init_completion( &thread_comp );	hx4700_np.kthread = kthread_run( &hx4700_navptd, NULL, "hx4700_navpt" );	if (IS_ERR(hx4700_np.kthread)) {		printk( KERN_ERR "iPAQ hx470x NavPoint start failure.\n" );		return -EIO;	}	navpt_dev.unit = 0;	navpt_dev.tx_func = hx4700_navpt_write;	navpoint_init( &navpt_dev );	ssp_enable( &ssp_dev );	// navpoint_reset( &navpt_dev );	return 0;}#ifdef CONFIG_PMstatic inthx4700_navpt_suspend( struct device *dev, pm_message_t state ){	SET_HX4700_GPIO( SYNAPTICS_POWER_ON, 0 );	ssp_exit( &ssp_dev );	return 0;}static inthx4700_navpt_resume( struct device *dev ){	hx4700_ssp_init();	SET_HX4700_GPIO( SYNAPTICS_POWER_ON, 1 );	ssp_enable( &ssp_dev );	navpoint_reset( &navpt_dev );	return 0;}#else#define hx4700_navpt_resume	NULL#define hx4700_navpt_suspend	NULL#endifstatic inthx4700_navpt_remove( struct device *dev ){	navpoint_exit( &navpt_dev );	ssp_disable( &ssp_dev );	SET_HX4700_GPIO( SYNAPTICS_POWER_ON, 0 );        must_die = 1;	wake_up_interruptible( &hx4700_np.kthread_wait );	wait_for_completion( &thread_comp );	ssp_exit( &ssp_dev );	return 0;}struct device_driver hx4700_navpt_driver = {	.name     = "hx4700-navpoint",	.bus	  = &platform_bus_type,	.probe    = hx4700_navpt_probe,	.suspend  = hx4700_navpt_suspend,	.resume   = hx4700_navpt_resume,	.remove   = hx4700_navpt_remove,};static int __inithx4700_navpt_init( void ){	printk( "hx4700 NavPoint Driver\n" );	return driver_register( &hx4700_navpt_driver );}static void __exithx4700_navpt_exit( void ){	driver_unregister( &hx4700_navpt_driver );}module_init( hx4700_navpt_init );module_exit( hx4700_navpt_exit );MODULE_AUTHOR( "Todd Blumer <todd@sdgsystems.com>" );MODULE_DESCRIPTION( "PXA27x NavPoint(tm) driver for iPAQ hx470x" );MODULE_LICENSE( "GPL" );/* vim600: set noexpandtab sw=8 ts=8 :*/

⌨️ 快捷键说明

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