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

📄 hal_pxa250.c

📁 linux下的usb开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************ * Philips ISP1362 hardware access layer driver for  * Intel PXA250 based Accelent IDP platform * * (c) 2002 Koninklijke Philips Electronics N.V., All rights reserved *  * This  source code and any compilation or derivative thereof is the * proprietary information of Koninklijke Philips Electronics N.V. * and is confidential in nature. * Under no circumstances is this software to be exposed to or placed * under an Open Source License of any type without the expressed * written permission of Koninklijke Philips Electronics N.V. * * File Name:	hal_pxa250.c * * History:	 * *	Version	Date		Author		Comments * ------------------------------------------------- * 	1.0		09/23/02	SYARRA		Initial Creation * * Note: use tab space 4 ************************************************************************/#include <linux/config.h>#define MODULE#include <linux/module.h>#include <linux/kernel.h>#include <linux/delay.h>#include <linux/ioport.h>#include <linux/sched.h>#include <linux/slab.h>#include <linux/smp_lock.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/timer.h>#include <linux/list.h>#include <linux/interrupt.h>  /* for in_interrupt() */#undef DEBUG#include <linux/usb.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/system.h>#include <asm/unaligned.h>#include <asm/dma.h>#include "hal_intf.h"/*--------------------------------------------------------------* *               Local variable Definitions *--------------------------------------------------------------*/struct isp1362_dev 		isp1362_loc_dev[ISP1362_LAST_DEV];static	struct isp1362_hal	pxa250_hal_data;/*--------------------------------------------------------------* *               Local # Definitions *--------------------------------------------------------------*/#define		isp1362_driver_name	"1362-hal"#define		DRIVER_AUTHOR		"Philips Semiconductors"#define		DRIVER_DESC			"ISP1362 bus driver"/*--------------------------------------------------------------* *               Local Function Declerations *--------------------------------------------------------------*/static void isp1362_hal_remove (struct isp1362_hal *info);static int isp1362_hal_probe (struct isp1362_hal *info);#ifdef CONFIG_PMstatic int isp1362_hal_suspend (__u32 state);static int isp1362_hal_resume (void);#endif /* CONFIG_PM */static void isp1362_hal_isr (int irq, void *__data, struct pt_regs *r);/*--------------------------------------------------------------* *               ISP1362 Interrupt Service Routine *--------------------------------------------------------------*//* Interrupt Service Routine of isp1362	                                   * Reads the source of interrupt and calls the corresponding driver's ISR. * Before calling the driver's ISR clears the source of interrupt. * The drivers can get the source of interrupt from the dev->int_reg field */void 	isp1362_hal_isr(int 	irq, void *__data, struct pt_regs *r) {	__u32		irq_mask;	__u32		hc_int_reg;	__u32		intrenable;	__u8		repeat_flag = 0;	struct isp1362_dev	*dev;	func_debug(("isp1362_hal_isr(irq = %d,__data=%p,r=%p)\n",irq,__data,r))		do{			repeat_flag = 0;		/* Process the Host Controller Driver          */		dev = &isp1362_loc_dev[ISP1362_HC];		/* Get the source of interrupts for Host Controller          */		isp1362_reg_read16(dev, HC_MP_INT_REG,(dev->int_reg));		isp1362_reg_read16(dev, HC_MP_INT_EN_REG,irq_mask);		isp1362_reg_read32(dev, HC_INT_STS_REG,(dev->alt_int_reg) );		isp1362_reg_read32(dev, HC_INT_EN_REG,intrenable );			/* Clear the source of interrupts for Host Controller          */		isp1362_reg_write16(dev,(HC_MP_INT_REG|0x80), (dev->int_reg));		isp1362_reg_write32(dev,(HC_INT_STS_REG|0x80), (dev->alt_int_reg));		dev->int_reg &= irq_mask;		hc_int_reg = dev->int_reg;		dev->alt_int_reg &= intrenable;		/* call the Host Isr if any valid interrupt is present          */		if(dev->int_reg) {			repeat_flag = 1;			dev->handler(dev,dev->isr_data);		}		/* Process OTG controller Driver 		 * Since OTG is part of  HC interrupt register, the interrupt source         * will be HC interrupt Register         */		dev = &isp1362_loc_dev[ISP1362_OTG];		if(hc_int_reg & HC_OTG_INT) {			/* Read the source of  OTG_INT and clear the                 * interrupt source                  */			isp1362_reg_read16(dev, OTG_INT_REG,(dev->int_reg));			isp1362_reg_write16(dev, (OTG_INT_REG|0x80),OTG_INT_MASK);				if(dev->int_reg) {				dev->handler(dev, dev->isr_data);				repeat_flag = 1;			}		}		/* Process the Device Controller         */		dev = &isp1362_loc_dev[ISP1362_DC];		/* Get the source of interrupts for Device Controller 		 * Device Controller interrupts are cleared by the driver         * during processing         */		isp1362_reg_read32(dev, DC_INT_REG,(dev->int_reg));		isp1362_reg_read32(dev, DC_INT_EN_REG,irq_mask);		dev->int_reg &= irq_mask;		if(dev->int_reg) {			dev->handler(dev, dev->isr_data);			repeat_flag = 1;		}		/* If there is any interrupt generated at the time of clearing the interrupts		(because it consumes time to clear the interrupt), we might miss some of		them. (Accelent PXA250 board will detect interrupts on falling edge only.		and hardware is configured for Level triggering. The problem with configuring		hardware for Edge triggering is limited by ISP1362 Edge pulse of <200nsec		and CPU needs at least 1usec pulse to detect it */	} while(repeat_flag);	return;} /* End of isp1362_hal_isr *//* probe function of ISP1362 * This function is called when the module is loaded This function  * initializes the information for the 3 Controllers with the assigned  * resources and tests the register access to these controllers and do a  * software reset and makes them ready for the drivers to play with them. */static int __devinitisp1362_hal_probe (struct isp1362_hal *info){	__u32	reg_data = 0;	struct isp1362_dev	*loc_dev;	func_debug(("isp1362_hal_probe(info=%p)\n",info))	    if ((info->int_ch1 == 0) || (info->int_ch2 ==0)) {    	detail_debug(("found ISP1362 device with no IRQ assigned. check BIOS settings!"))   	    return -ENODEV;	}		/* Get the Host Controller IO and INT resources	 */	loc_dev = &(isp1362_loc_dev[ISP1362_HC]);	loc_dev->irq = info->int_ch1;	loc_dev->io_base = (unsigned long)info->io_base;	loc_dev->io_data = loc_dev->io_base;	loc_dev->io_cmd = loc_dev->io_base + sizeof(void*);	loc_dev->io_len = 2*sizeof(void*);	loc_dev->index = ISP1362_HC;	detail_debug(("isp1362 HC IO Base= %x irq = %x\n", loc_dev->io_base,loc_dev->irq))	/* Get the Device Controller IO and INT resources	 * Device controller also uses the same INT channel for PCI	 * but the IO is different	 */	loc_dev = &(isp1362_loc_dev[ISP1362_DC]);	loc_dev->irq = info->int_ch2;	loc_dev->io_base = (unsigned long)info->io_base + 2*sizeof(void*);	loc_dev->io_data = loc_dev->io_base;	loc_dev->io_cmd = loc_dev->io_base + sizeof(void*);	loc_dev->io_len = 2*sizeof(void*);	loc_dev->index = ISP1362_DC;	detail_debug(("isp1362 DC IO Base= %x irq = %x\n", loc_dev->io_base,loc_dev->irq))	/* Get the OTG Controller IO and INT resources	 * OTG controller resources are same as Host Controller resources	 */	loc_dev = &(isp1362_loc_dev[ISP1362_OTG]);	loc_dev->irq = info->int_ch1;	loc_dev->io_base = (unsigned long)info->io_base;	loc_dev->io_data = loc_dev->io_base;	loc_dev->io_cmd = loc_dev->io_base + sizeof(void*);	loc_dev->io_len = 2*sizeof(void*);	loc_dev->index = ISP1362_OTG;	detail_debug(("isp1362 OTG IO Base= %x irq = %x\n", loc_dev->io_base,loc_dev->irq))	loc_dev = &(isp1362_loc_dev[ISP1362_HC]);	/* Try to check whether we can access Scratch Register of         * Host Controller or not. The initial PCI access is retried until          * local init for the PCI bridge is completed          */	isp1362_reg_write16(loc_dev, (HC_SCRATCH_REG|0x80), 0xFACE);	isp1362_reg_read16(loc_dev, HC_SCRATCH_REG,reg_data);	/* Host Controller presence is detected by writing to scratch register	 * and reading back and checking the contents are same or not         */	if(reg_data != 0xFACE) {		detail_debug(("%s unable to access HC Scratch Register",isp1362_driver_name))		return -ENODEV;	}	/* Reset the Host controller (reset requires some time .....     * is 100 msec ok??     */	loc_dev->active = 1;	isp1362_reg_write16(loc_dev, (HC_SW_RESET_REG|0x80), 0x00F6);	isp1362_mdelay(100);	isp1362_reg_read16(loc_dev, HC_CHIP_ID_REG,(loc_dev->chip_id));		detail_debug(("%s: found HC Chip Id = %x\n",isp1362_driver_name, loc_dev->chip_id))	/* Update the local and store the PCI data         */	info->io_usage = 0;	info->irq_usage = 0;	/* Now Process the Device Controller 	 */	loc_dev = &(isp1362_loc_dev[ISP1362_DC]);	reg_data = 0;	isp1362_reg_write16(loc_dev, (DC_SCRATCH_REG&0xFE), 0xFACE);	isp1362_reg_read16(loc_dev, DC_SCRATCH_REG,reg_data);	if(reg_data != 0xFACE) {		detail_debug(("%s unable to access DC Scratch Register",isp1362_driver_name))		return -ENODEV;	}	loc_dev->active = 1;	isp1362_reg_read16(loc_dev, DC_CHIP_ID_REG,(loc_dev->chip_id));	detail_debug(("%s: found DC Chip Id = %x\n",isp1362_driver_name, loc_dev->chip_id))	/* Rest the DC. Assume 10 msec are fairly enough for DC to reset	 */	isp1362_command(DC_SW_RESET_REG,loc_dev);	isp1362_mdelay(10);	/* Now Process the OTG Controller 	 * OTG resources are same as HC resource nothing to be done here	 */	loc_dev = &(isp1362_loc_dev[ISP1362_OTG]);	loc_dev->active = 1;	return 0;} /* End of isp1362_hal_probe *//* hal cleanup function of ISP1362 * This function is called when module is unloaded or a de-registration of  * driver. * This functions checks the registerd drivers (HCD, DCD, OTG) and calls * the corresponding removal functions. Also initializes the local variables * to zero. */static void __devexitisp1362_hal_remove (struct isp1362_hal *info){	struct isp1362_dev	*loc_dev;	int			index;	func_debug(("isp1362_hal_remove(info=%p)\n",info))	/* For each controller check whether driver is registerd         * or not. If registerd call the removal function if it is	 * present	 */	for(index=ISP1362_1ST_DEV;index<ISP1362_LAST_DEV;index++) {		loc_dev = &isp1362_loc_dev[index];		if(loc_dev->driver) {			loc_dev->driver->remove(loc_dev);			loc_dev->driver = NULL;			return;		}	}	/* Clear the local variables	 */	pxa250_hal_data.io_usage = 0;	pxa250_hal_data.irq_usage = 0;	return;} /* End of isp1362_hal_remove */#ifdef CONFIG_PM/* PCI suspend function of ISP1362 * This function is called from PCI Driver. * This functions checks the registerd drivers (HCD, DCD, OTG) and calls * the corresponding suspend functions if present.  */static int isp1362_hal_suspend (__u32 state) {	struct isp1362_dev	*loc_dev;	int			index;	func_debug(("isp1362_hal_suspend(state = %x)\n",state))	loc_dev = isp1362_loc_dev;	/* For each controller check whether driver is registerd         * or not. If registerd call the suspend function if it is	 * present

⌨️ 快捷键说明

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