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

📄 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;
	struct pci_dev *pci;
	U32 intr;
	char *name;
	U32 start;
	U32 size;
} UsblinkOtg;

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

/*
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 int __devinit hc_add_ohci (struct pci_dev *dev, int irq,
	void *mem_base, unsigned long flags, const char* name);
struct ohci;
extern void __devexit hc_remove_ohci (struct ohci*);

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;
   /*
info("read  [0x%03x]=0x%08x", offset, value);
*/
   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;
   /*
info("write [0x%03x]=0x%08x", offset, val);
*/
   }


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

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

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

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


#endif

static int __devinit
otg242_probe(U32 addr, U32 intr_no)
{
	unsigned long mem_addr, mem_len;
	void *mem_base;
	int status;
	SctBool rc;
	struct pci_device_id id;

	info("probe: addr=0x%x intr=0x%x", addr, intr_no);

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

	mem_addr = addr;
	mem_len = 0x20000;
	otg.start = mem_addr;
	otg.size = mem_len;
	if (!request_mem_region (mem_addr, mem_len, "TD242")) {
		dbg ("controller already in use");
		return -EBUSY;
	}

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

	otg.driverObject = OTG242_Create(mem_base, intr_no, (U32)(&otg));
	if (otg.driverObject == 0)
	{
		err("Failed to create otg242");
		release_mem_region (mem_addr, mem_len);
		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_addr, mem_len);
		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_addr, mem_len);
		return -EFAULT;
	}

	otg.ohciIntr = 0xff;

	memset(&id, 0, sizeof(id));
	/*
	status = hc_found_ohci (otg.pci, otg.ohciIntr,
			OTG242_GetOHCIRegisterBase(otg.driverObject), &id);
	*/
	status = hc_add_ohci (otg.pci, otg.ohciIntr,
			OTG242_GetOHCIRegisterBase(otg.driverObject), 0, "otg242");
	
	if (status < 0) 
	{
		err("Failed to start ohci driver");
		OTG242_Delete(otg.driverObject);
		otg.driverObject = 0;
		iounmap (mem_base);
		release_mem_region (mem_addr, mem_len);
		return -EFAULT;
	}

	otg.ohci = pci_get_drvdata(otg.pci);
	otg.ohciDriverInitialized = SCC_TRUE;
	
	info(" **OTG242** Start successful, baseAddress %p ohci=%p!", mem_base, otg.ohci);

	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_remove (void)
{
	hc_remove_ohci(otg.ohci);

	OTG242_Delete(otg.driverObject);
	otg.driverObject = 0;
	release_mem_region (otg.start, otg.size);
}

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

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

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

static int __init otg242_hcd_init (void) 
{
	int rc;
	/*
	U32 msc2;

	msc2 = MSC2 & 0x0000FFFF;
	MSC2 = msc2 | 0x4C690000;
	*/

	otg.driverObject = 0;
	otg.ohciIntr = 0;
	otg.ohciDriverInitialized = SCC_FALSE;
	otg.ohciInterruptPending = SCC_FALSE;
	otg.pci = 0;

	GPDR &= ~(GPIO_GPIO(14));
	set_GPIO_IRQ_edge(GPIO_GPIO(14), GPIO_RISING_EDGE);

	otg.pci = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
	if (0 == otg.pci)
	{
		dbg("Failed to allocate memory for ochi device");
		return -EFAULT;
	}

	memcpy(otg.pci->slot_name, "NonePCI", 8);
	memcpy(otg.pci->name, "otg242", 7);
	otg.pci->dma_mask = -1;

	rc = otg242_probe(OTG243_MEM_START, OTG243_INT_LVL);

	return rc;
}

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

static void __exit otg242_hcd_cleanup (void) 
{	
	otg242_remove();
	kfree(otg.pci);
}

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 + -