📄 dwc_otg_driver.c
字号:
switch (dwc_otg_module_params. otg_cap) {case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:if (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) valid = 0; break; case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE: if ((core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) && (core_if->hwcfg2.b. op_mode != DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) && (core_if->hwcfg2.b. op_mode != DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) && (core_if->hwcfg2.b. op_mode != DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) { valid = 0;}break; case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE: /* always valid */ break;} valid;} ), (((core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) || (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) || (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) || (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ? DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE : DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE)); retval += DWC_OTG_PARAM_CHECK_VALID(dma_enable, "dma_enable", ((dwc_otg_module_params.dma_enable == 1) && (core_if->hwcfg2.b.architecture == 0)) ? 0 : 1, 0); retval += DWC_OTG_PARAM_CHECK_VALID(dma_desc_enable, "dma_desc_enable", ((dwc_otg_module_params.dma_desc_enable == 1) && ((dwc_otg_module_params.dma_enable == 0) || (core_if->hwcfg4.b.desc_dma == 0))) ? 0 : 1, 0); retval += DWC_OTG_PARAM_CHECK_VALID(opt, "opt", 1, 0); DWC_OTG_PARAM_SET_DEFAULT(dma_burst_size); retval += DWC_OTG_PARAM_CHECK_VALID(host_support_fs_ls_low_power, "host_support_fs_ls_low_power", 1, 0); retval += DWC_OTG_PARAM_CHECK_VALID(enable_dynamic_fifo, "enable_dynamic_fifo", ((dwc_otg_module_params.enable_dynamic_fifo == 0) || (core_if->hwcfg2.b.dynamic_fifo == 1)), 0); retval += DWC_OTG_PARAM_CHECK_VALID(data_fifo_size, "data_fifo_size", (dwc_otg_module_params.data_fifo_size <= core_if->hwcfg3.b.dfifo_depth), core_if->hwcfg3.b.dfifo_depth); retval += DWC_OTG_PARAM_CHECK_VALID(dev_rx_fifo_size, "dev_rx_fifo_size", (dwc_otg_module_params.dev_rx_fifo_size <= dwc_read_reg32(&core_if->core_global_regs->grxfsiz)), dwc_read_reg32(&core_if->core_global_regs->grxfsiz)); retval += DWC_OTG_PARAM_CHECK_VALID(dev_nperio_tx_fifo_size, "dev_nperio_tx_fifo_size", (dwc_otg_module_params.dev_nperio_tx_fifo_size <= (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)), (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)); retval += DWC_OTG_PARAM_CHECK_VALID(host_rx_fifo_size, "host_rx_fifo_size", (dwc_otg_module_params.host_rx_fifo_size <= dwc_read_reg32(&core_if->core_global_regs->grxfsiz)), dwc_read_reg32(&core_if->core_global_regs->grxfsiz)); retval += DWC_OTG_PARAM_CHECK_VALID(host_nperio_tx_fifo_size, "host_nperio_tx_fifo_size", (dwc_otg_module_params.host_nperio_tx_fifo_size <= (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)), (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)); retval += DWC_OTG_PARAM_CHECK_VALID(host_perio_tx_fifo_size, "host_perio_tx_fifo_size", (dwc_otg_module_params.host_perio_tx_fifo_size <= ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16))), ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16))); retval += DWC_OTG_PARAM_CHECK_VALID(max_transfer_size, "max_transfer_size", (dwc_otg_module_params.max_transfer_size < (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))), ((1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1)); retval += DWC_OTG_PARAM_CHECK_VALID(max_packet_count, "max_packet_count", (dwc_otg_module_params.max_packet_count < (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))), ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1)); retval += DWC_OTG_PARAM_CHECK_VALID(host_channels, "host_channels", (dwc_otg_module_params.host_channels <= (core_if->hwcfg2.b.num_host_chan + 1)), (core_if->hwcfg2.b.num_host_chan + 1)); retval += DWC_OTG_PARAM_CHECK_VALID(dev_endpoints, "dev_endpoints", (dwc_otg_module_params.dev_endpoints <= (core_if->hwcfg2.b.num_dev_ep)), core_if->hwcfg2.b.num_dev_ep);/* * Define the following to disable the FS PHY Hardware checking. This is for * internal testing only. * * #define NO_FS_PHY_HW_CHECKS */#ifdef NO_FS_PHY_HW_CHECKS retval += DWC_OTG_PARAM_CHECK_VALID(phy_type, "phy_type", 1, 0);#else retval += DWC_OTG_PARAM_CHECK_VALID(phy_type, "phy_type", ( { int valid = 0; if ((dwc_otg_module_params. phy_type == DWC_PHY_TYPE_PARAM_UTMI) && ((core_if->hwcfg2.b. hs_phy_type == 1) || (core_if->hwcfg2.b. hs_phy_type == 3))) { valid = 1;} else if ((dwc_otg_module_params. phy_type == DWC_PHY_TYPE_PARAM_ULPI) && ((core_if->hwcfg2.b. hs_phy_type == 2) || (core_if->hwcfg2.b. hs_phy_type == 3))) { valid = 1;} else if ((dwc_otg_module_params. phy_type == DWC_PHY_TYPE_PARAM_FS) && (core_if->hwcfg2.b. fs_phy_type == 1)) { valid = 1;} valid;} ), ( { int set = DWC_PHY_TYPE_PARAM_FS; if (core_if->hwcfg2.b.hs_phy_type) { if ((core_if->hwcfg2.b.hs_phy_type == 3) || (core_if->hwcfg2.b.hs_phy_type == 1)) { set = DWC_PHY_TYPE_PARAM_UTMI;} else { set = DWC_PHY_TYPE_PARAM_ULPI;} } set;} ));#endif retval += DWC_OTG_PARAM_CHECK_VALID(speed, "speed", (dwc_otg_module_params.speed == 0) && (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1, dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS ? 1 : 0); retval += DWC_OTG_PARAM_CHECK_VALID(host_ls_low_power_phy_clk, "host_ls_low_power_phy_clk", ((dwc_otg_module_params.host_ls_low_power_phy_clk == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ) && (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1), ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ : DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ)); DWC_OTG_PARAM_SET_DEFAULT(phy_ulpi_ddr); DWC_OTG_PARAM_SET_DEFAULT(phy_ulpi_ext_vbus); DWC_OTG_PARAM_SET_DEFAULT(phy_utmi_width); DWC_OTG_PARAM_SET_DEFAULT(ulpi_fs_ls); DWC_OTG_PARAM_SET_DEFAULT(ts_dline);#ifdef NO_FS_PHY_HW_CHECKS retval += DWC_OTG_PARAM_CHECK_VALID(i2c_enable, "i2c_enable", 1, 0);#else retval += DWC_OTG_PARAM_CHECK_VALID(i2c_enable, "i2c_enable", (dwc_otg_module_params.i2c_enable == 1) && (core_if->hwcfg3.b.i2c == 0) ? 0 : 1, 0);#endif for (i = 0; i < 15; i++) { int changed = 1; int error = 0; if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] == -1) { changed = 0; dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_param_dev_perio_tx_fifo_size_default; } if (! (dwc_otg_module_params.dev_perio_tx_fifo_size[i] <= (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i])))) { if (changed) { DWC_ERROR ("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n", dwc_otg_module_params.dev_perio_tx_fifo_size[i], i); error = 1; } dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i]); } retval += error; } retval += DWC_OTG_PARAM_CHECK_VALID(en_multiple_tx_fifo, "en_multiple_tx_fifo", ((dwc_otg_module_params.en_multiple_tx_fifo == 1) && (core_if->hwcfg4.b.ded_fifo_en == 0)) ? 0 : 1, 0); for (i = 0; i < 15; i++) { int changed = 1; int error = 0; if (dwc_otg_module_params.dev_tx_fifo_size[i] == -1) { changed = 0; dwc_otg_module_params.dev_tx_fifo_size[i] = dwc_param_dev_tx_fifo_size_default; } if (! (dwc_otg_module_params.dev_tx_fifo_size[i] <= (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i])))) { if (changed) { DWC_ERROR ("%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n", dwc_otg_module_params.dev_tx_fifo_size[i], i); error = 1; } dwc_otg_module_params.dev_tx_fifo_size[i] = dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i]); } retval += error; } retval += DWC_OTG_PARAM_CHECK_VALID(thr_ctl, "thr_ctl", ((dwc_otg_module_params.thr_ctl != 0) && ((dwc_otg_module_params.dma_enable == 0) || (core_if->hwcfg4.b.ded_fifo_en == 0))) ? 0 : 1, 0); DWC_OTG_PARAM_SET_DEFAULT(tx_thr_length); DWC_OTG_PARAM_SET_DEFAULT(rx_thr_length); return retval;}#define DWC_INT_MSK_COMMON 0xf1000806/** * This function is the top level interrupt handler for the Common * (Device and host modes) interrupts. */static irqreturn_t dwc_otg_common_irq(int _irq, void *_dev){ dwc_otg_device_t *otg_dev = _dev;// irqreturn_t retval = IRQ_NONE; u32 sts, irq, msk; irq = readl(S3C_UDC_OTG_GINTSTS); msk = readl(S3C_UDC_OTG_GINTMSK); sts = ((irq & msk) & DWC_INT_MSK_COMMON); if (!sts) { return IRQ_NONE; }#if 0 retval = dwc_otg_handle_common_intr(otg_dev->core_if, sts); return IRQ_RETVAL(retval);#else return dwc_otg_handle_common_intr(otg_dev->core_if, sts);#endif}/** * This function is called when a lm_device is unregistered with the * dwc_otg_driver. This happens, for example, when the rmmod command is * executed. The device may or may not be electrically present. If it is * present, the driver stops device processing. Any resources used on behalf * of this device are freed. * * @param[in] _lmdev */static int dwc_otg_driver_remove (struct platform_device *dev){ dwc_otg_device_t *otg_dev = platform_get_drvdata(dev); dbg_otg("%s(%p)\n", __func__, dev); if (otg_dev == NULL) { /* Memory allocation for the dwc_otg_device failed. */ DWC_DEBUGPL(DBG_ANY, "%s: otg_dev NULL!\n", __func__); return -1; } /* * Free the IRQ */ if (otg_dev->common_irq_installed) { free_irq(IRQ_OTG, otg_dev); }#ifndef DWC_DEVICE_ONLY if (otg_dev->hcd != NULL) { dwc_otg_hcd_remove(dev); } else { DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->hcd NULL!\n", __func__); return -1; }#endif#ifndef DWC_HOST_ONLY if (otg_dev->pcd != NULL) { dwc_otg_pcd_remove(dev); }#endif if (otg_dev->core_if != NULL) { dwc_otg_cil_remove(otg_dev->core_if); } /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -