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

📄 init.c

📁 Usb Host/Periphel Control TD1120 codes
💻 C
字号:

#include "usblink.h"

/*
 * Version Information
 */
#define DRIVER_VERSION "v5.3"
#define DRIVER_AUTHOR "Roman Weissgaerber <weissg@vienna.at>, David Brownell"
#define DRIVER_DESC "USB OHCI Host Controller Driver"

typedef struct _UsblinkOtg
{
	U32 driverObject;
	U32 ohciIntr;
	SctBool ohciDriverInitialized;
	SctBool ohciInterruptPending;
	void *ohci;
	U32 intr;
	char *name;
} UsblinkOtg;

static UsblinkOtg otg = {0, 0, SCC_FALSE, SCC_FALSE, 0};

static struct pci_driver ohci_pci_driver;

extern int __devinit hc_found_ohci (struct pci_dev *dev, int irq,
	void *mem_base, const struct pci_device_id *id);
extern void __devexit ohci_pci_remove (struct pci_dev *dev);
extern void hc_interrupt (int irq, void * __ohci, struct pt_regs * r);
extern int ohci_pci_suspend (struct pci_dev *dev, u32 state);
extern int ohci_pci_resume (struct pci_dev *dev);



#ifdef OTG_16_BIT_DATA_BUS


//some tricks here, addr + offset is working because addr
//is declared as U8, sigh...
U32 HW_ReadOtg242Register(volatile U8* addr, U32 offset)
   {
   volatile U16 *Address;
   U32 value;

   Address = (U16 *)(addr + offset);
   value = (U32)(*Address++) & 0xFFFF;
   value |= (*Address & 0xFFFF) << 16;
   return value;
   }

void HW_WriteOtg242Register(volatile U8* addr, U32 offset, U32 val)
   {
   volatile U16 *Address;

	//write the lower 16bits of val
   Address = (U16 *)(addr + offset);
   *Address = val &0xFFFF;


   //write the higher 16bits of val
   Address++;
   *Address = (val>>16) & 0xFFFF;
   }


U16 HW_ReadOtg242Register16(volatile U16* addr, U32 offset)
{
   volatile U16 *Address;
   U16 value;

   Address = (U16 *)((U32)addr + offset);
   value = (U16)((*Address) & 0xFFFF);
   
   return value;
   }

void HW_WriteOtg242Register16(volatile U16* addr, U32 offset, U16 val)
{
	volatile U16 *Address;

   Address = (U16 *)((U32)addr + offset);
   *Address = val;
}


#endif

static int __devinit
otg242_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
	unsigned long mem_resource, mem_len;
	void *mem_base;
	int status;
	SctBool rc;

	info("probe: dev=%p\n", dev);
	
	if (pci_enable_device(dev) < 0)
		return -ENODEV;

        if (!dev->irq) {
        	err("found OHCI device with no IRQ assigned. check BIOS settings!");
		pci_disable_device (dev);
   	        return -ENODEV;
        }
	
	/* we read its hardware registers as memory */
	mem_resource = pci_resource_start(dev, 3);
	mem_len = pci_resource_len(dev, 3);
	
	info("mem=%lx  len=%lx", mem_resource, mem_len);

	if (!request_mem_region (mem_resource, mem_len, ohci_pci_driver.name)) {
		dbg ("controller already in use");
		pci_disable_device (dev);
		return -EBUSY;
	}

	if (otg.driverObject != 0)
	{
		dbg ("controller already in use");
		pci_disable_device (dev);
		return -EBUSY;
	}

	mem_base = ioremap_nocache (mem_resource, mem_len);
	if (!mem_base) {
		err("Error mapping OHCI memory");
		release_mem_region (mem_resource, mem_len);
		pci_disable_device (dev);
		return -EFAULT;
	}

	otg.intr = dev->irq;
	otg.driverObject = OTG242_Create(mem_base, otg.intr, (U32)(&otg));
	if (otg.driverObject == 0)
	{
		err("Failed to create otg242");
		release_mem_region (mem_resource, mem_len);
		pci_disable_device (dev);
		return -EFAULT;
	}

	rc = OTG242_Initialize(otg.driverObject);
	if (rc != SCS_SUCCESS)
	{
		err("Failed to initialize otg242");
		OTG242_Delete(otg.driverObject);
		otg.driverObject = 0;
		release_mem_region (mem_resource, mem_len);
		pci_disable_device (dev);
		return -EFAULT;
	}

	rc = OTG242_Start(otg.driverObject);
	if (rc != SCS_SUCCESS)
	{
		err("Failed to start otg242");
		OTG242_Delete(otg.driverObject);
		otg.driverObject = 0;
		release_mem_region (mem_resource, mem_len);
		pci_disable_device (dev);
		return -EFAULT;
	}

	otg.ohciIntr = 0xff;

	/* controller writes into our memory */
	pci_set_master (dev);

	status = hc_found_ohci (dev, otg.ohciIntr, OTG242_GetOHCIRegisterBase(otg.driverObject), id);

	
	if (status < 0) 
	{
		err("Failed to start ohci driver");
		OTG242_Delete(otg.driverObject);
		otg.driverObject = 0;
		iounmap (mem_base);
		release_mem_region (mem_resource, mem_len);
		pci_disable_device (dev);
		return -EFAULT;
	}

	info(" **OTG242** Start successful, baseAddress %p!", mem_base);
	
	otg.ohci = pci_get_drvdata(dev);
	otg.ohciDriverInitialized = SCC_TRUE;
	
	if (otg.ohciInterruptPending == SCC_TRUE)
	{
		otg.ohciInterruptPending = SCC_FALSE;
		TriggerOhciInterrupt((U32)(&otg));
	}

	return status;
} 

/*-------------------------------------------------------------------------*/

/* may be called from interrupt context [interface spec] */
/* may be called without controller present */
/* may be called with controller, bus, and devices active */

static void __devexit
otg242_pci_remove (struct pci_dev *dev)
{
	ohci_pci_remove(dev);

	info("Removing otg242 driver");
	OTG242_Delete(otg.driverObject);
	otg.driverObject = 0;
	release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0));
	pci_disable_device (dev);
}

void TriggerOhciInterrupt(U32 context)
{
	if (otg.ohciDriverInitialized == SCC_FALSE)
	{
		otg.ohciInterruptPending = SCC_TRUE;
		return;
	}

	hc_interrupt(otg.ohciIntr, otg.ohci, NULL);
}

#ifdef	CONFIG_PM
static int
otg242_pci_suspend(struct pci_dev *dev, u32 state)
{
    ohci_pci_suspend(dev, state);
}

static int
otg242_pci_resume(struct pci_dev *dev)
{
    ohci_pci_resume(dev);
}

#endif	/* PM */

/*-------------------------------------------------------------------------*/

static const struct pci_device_id __devinitdata ohci_pci_ids [] = {
    {

	/* handle any USB OHCI controller */
	class: 		((PCI_CLASS_BRIDGE_OTHER << 8) | 0x10),
	class_mask: 	~0xFF,

	/* no matter who makes it */
	vendor:		0x10B5,
	device:		0x9030,
	subvendor:	PCI_ANY_ID,
	subdevice:	PCI_ANY_ID,

	}, { /* end: all zeroes */ }
};

MODULE_DEVICE_TABLE (pci, ohci_pci_ids);

static struct pci_driver ohci_pci_driver = {
	name:		"otg242",
	id_table:	&ohci_pci_ids [0],

	probe:		otg242_pci_probe,
	remove:		__devexit_p(otg242_pci_remove),

#ifdef	CONFIG_PM
	suspend:	otg242_pci_suspend,
	resume:		otg242_pci_resume,
#endif	/* PM */
};

 
/*-------------------------------------------------------------------------*/

static int __init otg242_hcd_init (void) 
{
	int rc;

	otg.driverObject = 0;
	otg.ohciIntr = 0;
	otg.ohciDriverInitialized = SCC_FALSE;
	otg.ohciInterruptPending = SCC_FALSE;
	otg.ohci = 0;
	rc = pci_module_init (&ohci_pci_driver);

	return rc;
}

/*-------------------------------------------------------------------------*/

static void __exit otg242_hcd_cleanup (void) 
{	
	pci_unregister_driver (&ohci_pci_driver);
}

module_init (otg242_hcd_init);
module_exit (otg242_hcd_cleanup);


MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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