📄 hal_pxa250.c
字号:
*/ for(index=ISP1362_1ST_DEV;index<ISP1362_LAST_DEV;(index++,loc_dev++)) { if(loc_dev->driver && loc_dev->driver->suspend) { loc_dev->driver->suspend(loc_dev); } } return 0;} /* End of isp1362_hal_suspend *//* PCI resume function of ISP1362 * This function is called from PCI Driver. * This functions checks the registerd drivers (HCD, DCD, OTG) and calls * the corresponding resume functions if present. */static int isp1362_hal_resume (){ struct isp1362_dev *loc_dev; int index; func_debug(("isp1362_hal_resume(void)\n")) loc_dev = isp1362_loc_dev; /* For each controller check whether driver is registerd * or not. If registerd call the resume function if it is * present */ for(index=ISP1362_1ST_DEV;index<ISP1362_LAST_DEV;(index++,loc_dev++)) { if(loc_dev->driver && loc_dev->driver->resume) { loc_dev->driver->resume(loc_dev); } } return 0;} /* End of isp1362_hal_resume */#endif /* CONFIG_PM *//*--------------------------------------------------------------* * Top Drivers (HCD, DCD, OTG) interface functions *--------------------------------------------------------------*//*--------------------------------------------------------------* * hardware register initialization *--------------------------------------------------------------*//* This fuction initializes the ISP1362 device hardware configuration * register for PCI interface. */void isp1362_set_hw_config(struct isp1362_dev *dev){ __u32 hw_cnfg; int gpio_irqpin1; int gpio_irqpin2; func_debug(("isp1362_set_hw_config(dev=%p)\n",dev)) switch(dev->index) { case ISP1362_HC: isp1362_reg_read16(dev, HC_HW_CNFG_REG,hw_cnfg); /* Enable HC interrupt Pin * Connect the 15K pulldown registers on port1&2 * Level triggering, Active low polarity */ hw_cnfg |= (HC_CONNECT_PLDN_15K_DS2 | HC_CONNECT_PLDN_15K_DS1); hw_cnfg &= ~(HC_INT_PIN_TRIGGER | HC_INT_OUTPUT_POLARITY); hw_cnfg |= (HC_INT_PIN_ENABLE); /* set up the interrupt level-edge config */ gpio_irqpin1 = IRQ_TO_GPIO_2_80(dev->irq); GPDR(gpio_irqpin1) &= ~GPIO_bit(gpio_irqpin1); set_GPIO_IRQ_edge(gpio_irqpin1, ISP1362_IRQ_1_EDGE); #ifdef CONFIG_USB_PHCD_DMA /* PXA250 Machine specific initialization of the GPIO * inputs used for DREQx */ GPDR(19) &= ~GPIO_bit(19); GPDR(20) &= ~GPIO_bit(20); set_GPIO_mode(GPIO19_DREQ1_MD); set_GPIO_mode(GPIO20_DREQ0_MD); hw_cnfg |= (HC_DREQ_OUT_POLARITY | HC_DATA_BUS_16BIT_WIDTH);#endif /* CONFIG_USB_PHCD_DMA */ isp1362_reg_write16(dev,(HC_HW_CNFG_REG|0x80),hw_cnfg); break; case ISP1362_DC: isp1362_reg_read16(dev, DC_HW_CNFG_REG, hw_cnfg); /* No Clock Division, Clock is always running * Level triggering, Active low polarity */ hw_cnfg &= ~(DC_CLK_DIV); /* No clock division */ hw_cnfg |= (DC_CLK_RUN); /* Clock is always running */ /* set up the system hardware for each external int source */ gpio_irqpin2 = IRQ_TO_GPIO_2_80(dev->irq); GPDR(gpio_irqpin2) &= ~GPIO_bit(gpio_irqpin2); set_GPIO_IRQ_edge(gpio_irqpin2, ISP1362_IRQ_2_EDGE); isp1362_reg_write16(dev,(DC_HW_CNFG_REG&0xFE),hw_cnfg); break; default: break; }} /* End of isp1362_set_hw_config() *//*--------------------------------------------------------------* * IO PORT Management Functions *--------------------------------------------------------------*/int isp1362_check_io_region(struct isp1362_dev *dev){ func_debug(("isp1362_check_io_region(dev=%p)\n",dev)) /* If OTG driver, check the IO resources of HCD */ if(pxa250_hal_data.io_base) return 0; else return -EBUSY;} /* End of isp1362_check_io_region *//* This fuction assigns IO region to the driver * This is a dummy function as the IO resources are * assigned at the time of this driver loading */struct resource* isp1362_request_io_region(struct isp1362_dev *dev){ func_debug(("isp1362_request_io_region(dev=%p)\n",dev)) pxa250_hal_data.io_usage++; /* Store the IO resources */ dev->io_res = &(pxa250_hal_data.resource); return dev->io_res;} /* End of isp1362_request_io_region *//* This fuction releases IO region for the driver * This is a dummy function as the IO region is released * at the time of this driver unloading */void isp1362_release_io_region(struct isp1362_dev *dev){ func_debug(("isp1362_release_io_region(dev=%p)\n",dev)) pxa250_hal_data.io_usage--; dev->io_res = NULL; return;} /* End of isp1362_release_io_region *//*--------------------------------------------------------------* * Interrupt Management Functions *--------------------------------------------------------------*//* This function registers the ISR of driver with this driver. * If there is only one interrupt line, it will be registered only for the * first time with the OS. Otherwise for HC and DC will be registered to the * OS. */int isp1362_request_irq(void (*handler)(struct isp1362_dev *, void *), struct isp1362_dev *dev, void *isr_data) { int result = 0; __u16 intcsr; func_debug(("isp1362_request_irq(handler=%p,dev=%p,isr_data=%p)\n",handler,dev,isr_data)) if(pxa250_hal_data.int_ch1 == pxa250_hal_data.int_ch2) { if(!(pxa250_hal_data.irq_usage)) { /* If this is the first request */ result= request_irq(dev->irq,isp1362_hal_isr, SA_SHIRQ, isp1362_driver_name, (void*)isp1362_loc_dev); } pxa250_hal_data.irq_usage++; } else { result = 0; if(dev->index != ISP1362_OTG) { result= request_irq(dev->irq,isp1362_hal_isr, SA_SHIRQ, isp1362_driver_name, (void*)dev); } } if(result >= 0) { dev->handler = handler; dev->isr_data = isr_data; } return result;} /* End of isp1362_request_irq *//* This function de-registers the ISR of driver with this driver. * If One interrupt line is used for all the drivers, free it when * all the drivers isr is freed. If there are two interrupt lines * free the ISR for DC&HC */void isp1362_free_irq(struct isp1362_dev *dev, void *isr_data){ __u16 intcsr; func_debug(("isp1362_free_irq(dev=%p,isr_data=%p)\n",dev,isr_data)) if(pxa250_hal_data.int_ch1 == pxa250_hal_data.int_ch2) { pxa250_hal_data.irq_usage--; if(pxa250_hal_data.irq_usage) return; free_irq(dev->irq,isp1362_loc_dev); } else if(dev->index != ISP1362_OTG) { free_irq(dev->irq,dev); } } /* isp1362_free_irq *//*--------------------------------------------------------------* * Driver Registration Functions *--------------------------------------------------------------*//* This function is used by top driver (OTG, HCD, DCD) to register * their communication functions (probe, remove, suspend, resume) using * the drv data structure. * This function will call the probe function of the driver if the ISP1362 * corresponding to the driver is enabled */int isp1362_register_driver(struct isp1362_driver *drv) { struct isp1362_dev *dev; int result; func_debug(("isp1362_register_driver(drv=%p)\n",drv)) if(!drv) return -EINVAL; dev = &isp1362_loc_dev[drv->index]; if(dev->active) result = drv->probe(dev); else result = -ENODEV; if(result >= 0 ) { dev->driver = drv; } return result;} /* End of isp1362_register_driver *//* This function is used by top driver (OTG, HCD, DCD) to de-register * their communication functions (probe, remove, suspend, resume) using * the drv data structure. * This function will check whether the driver is registered or not and * call the remove function of the driver if registered */void isp1362_unregister_driver(struct isp1362_driver *drv){ struct isp1362_dev *dev; func_debug(("isp1362_unregister_driver(drv=%p)\n",drv)) dev = &isp1362_loc_dev[drv->index]; if(dev->driver == drv) { /* driver registered is same as the requestig driver */ drv->remove(dev); dev->driver = NULL; return; }} /* End of isp1362_unregister_driver *//*--------------------------------------------------------------* * Module Management Functions *--------------------------------------------------------------*//* This is the module initialization function. It resets the internal * variables and checks for IO resource availability and sets the resource * information and calls the probe function */static int __init isp1362_hal_module_init (void) { int result = 0; __u16 scratch = 0; func_debug(("isp1362_hal_module_init(void)\n")) memset(isp1362_loc_dev,0,sizeof(isp1362_loc_dev)); memset(&pxa250_hal_data, 0, sizeof(struct isp1362_hal)); pxa250_hal_data.io_base = ioremap_nocache(PXA_CS2_PHYS, PAGE_SIZE); if(!pxa250_hal_data.io_base) { detail_debug(("ISP1362 IO resources are busy\n")) return -1; } /* Set up the two CPLD gpio lines used for power modes */ IDP_CPLD_GPIOL_VALUE |= 0x3; IDP_CPLD_GPIOL_DIR |= 0x3; /* cpld gpio0 and 1 to output, set high initially */ IDP_CPLD_GPIOL_VALUE &= ~0x3; /* drive low to wake up ISP */ mdelay(10); IDP_CPLD_GPIOL_VALUE |= 0x3; mdelay(10); /* here as well... */ /* set the IO Resources */ pxa250_hal_data.io_len = 4*sizeof(void*); pxa250_hal_data.int_ch1 = ISP1362_IRQ_1; pxa250_hal_data.int_ch2 = ISP1362_IRQ_2; pxa250_hal_data.resource.start = (unsigned long)pxa250_hal_data.io_base; pxa250_hal_data.resource.end = (unsigned long)pxa250_hal_data.io_base + pxa250_hal_data.io_len; result = isp1362_hal_probe(&pxa250_hal_data); if(result < 0) { iounmap(pxa250_hal_data.io_base); } return ;}/* This is the module eleanup function. It calls the remove function * and resets the internal data structures. */static void __exit isp1362_hal_module_cleanup (void) { func_debug(("isp1362_hal_module_cleanup(void)\n")) isp1362_hal_remove(&pxa250_hal_data); if(pxa250_hal_data.io_base) iounmap(pxa250_hal_data.io_base); memset(isp1362_loc_dev,0,sizeof(isp1362_loc_dev)); memset(&pxa250_hal_data, 0, sizeof(struct isp1362_hal));} module_init (isp1362_hal_module_init);module_exit (isp1362_hal_module_cleanup);MODULE_AUTHOR (DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -