X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=drivers%2Fusb%2Fgadget%2Fdwc2_udc_otg.c;h=e3871e381e1493633432162532367e7717c63199;hb=f10643cf8a4ca006d1ad194e930cd292fd869d17;hp=b9c814cf73e22832194c8f75b305a54179d62511;hpb=1f47e2aca42c2e51ff3a7754c717ee13f568c721;p=platform%2Fkernel%2Fu-boot.git diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c index b9c814c..e3871e3 100644 --- a/drivers/usb/gadget/dwc2_udc_otg.c +++ b/drivers/usb/gadget/dwc2_udc_otg.c @@ -21,10 +21,13 @@ #include #include #include +#include #include #include #include #include +#include +#include #include #include @@ -943,8 +946,7 @@ int usb_gadget_handle_interrupts(int index) struct dwc2_priv_data { struct clk_bulk clks; struct reset_ctl_bulk resets; - struct phy *phys; - int num_phys; + struct phy_bulk phys; struct udevice *usb33d_supply; }; @@ -953,128 +955,72 @@ int dm_usb_gadget_handle_interrupts(struct udevice *dev) return dwc2_udc_handle_interrupt(); } -int dwc2_phy_setup(struct udevice *dev, struct phy **array, int *num_phys) +static int dwc2_phy_setup(struct udevice *dev, struct phy_bulk *phys) { - int i, ret, count; - struct phy *usb_phys; - - /* Return if no phy declared */ - if (!dev_read_prop(dev, "phys", NULL)) - return 0; - - count = dev_count_phandle_with_args(dev, "phys", "#phy-cells"); - if (count <= 0) - return count; - - usb_phys = devm_kcalloc(dev, count, sizeof(struct phy), - GFP_KERNEL); - if (!usb_phys) - return -ENOMEM; - - for (i = 0; i < count; i++) { - ret = generic_phy_get_by_index(dev, i, &usb_phys[i]); - if (ret && ret != -ENOENT) { - dev_err(dev, "Failed to get USB PHY%d for %s\n", - i, dev->name); - return ret; - } - } - - for (i = 0; i < count; i++) { - ret = generic_phy_init(&usb_phys[i]); - if (ret) { - dev_err(dev, "Can't init USB PHY%d for %s\n", - i, dev->name); - goto phys_init_err; - } - } - - for (i = 0; i < count; i++) { - ret = generic_phy_power_on(&usb_phys[i]); - if (ret) { - dev_err(dev, "Can't power USB PHY%d for %s\n", - i, dev->name); - goto phys_poweron_err; - } - } - - *array = usb_phys; - *num_phys = count; - - return 0; - -phys_poweron_err: - for (i = count - 1; i >= 0; i--) - generic_phy_power_off(&usb_phys[i]); + int ret; - for (i = 0; i < count; i++) - generic_phy_exit(&usb_phys[i]); + ret = generic_phy_get_bulk(dev, phys); + if (ret) + return ret; - return ret; + ret = generic_phy_init_bulk(phys); + if (ret) + return ret; -phys_init_err: - for (; i >= 0; i--) - generic_phy_exit(&usb_phys[i]); + ret = generic_phy_power_on_bulk(phys); + if (ret) + generic_phy_exit_bulk(phys); return ret; } -void dwc2_phy_shutdown(struct udevice *dev, struct phy *usb_phys, int num_phys) +static void dwc2_phy_shutdown(struct udevice *dev, struct phy_bulk *phys) { - int i, ret; - - for (i = 0; i < num_phys; i++) { - if (!generic_phy_valid(&usb_phys[i])) - continue; - - ret = generic_phy_power_off(&usb_phys[i]); - ret |= generic_phy_exit(&usb_phys[i]); - if (ret) { - dev_err(dev, "Can't shutdown USB PHY%d for %s\n", - i, dev->name); - } - } + generic_phy_power_off_bulk(phys); + generic_phy_exit_bulk(phys); } -static int dwc2_udc_otg_ofdata_to_platdata(struct udevice *dev) +static int dwc2_udc_otg_of_to_plat(struct udevice *dev) { - struct dwc2_plat_otg_data *platdata = dev_get_platdata(dev); + struct dwc2_plat_otg_data *plat = dev_get_plat(dev); ulong drvdata; void (*set_params)(struct dwc2_plat_otg_data *data); int ret; - if (usb_get_dr_mode(dev->node) != USB_DR_MODE_PERIPHERAL && - usb_get_dr_mode(dev->node) != USB_DR_MODE_OTG) { + if (usb_get_dr_mode(dev_ofnode(dev)) != USB_DR_MODE_PERIPHERAL && + usb_get_dr_mode(dev_ofnode(dev)) != USB_DR_MODE_OTG) { dev_dbg(dev, "Invalid mode\n"); return -ENODEV; } - platdata->regs_otg = dev_read_addr(dev); + plat->regs_otg = dev_read_addr(dev); - platdata->rx_fifo_sz = dev_read_u32_default(dev, "g-rx-fifo-size", 0); - platdata->np_tx_fifo_sz = dev_read_u32_default(dev, - "g-np-tx-fifo-size", 0); + plat->rx_fifo_sz = dev_read_u32_default(dev, "g-rx-fifo-size", 0); + plat->np_tx_fifo_sz = dev_read_u32_default(dev, "g-np-tx-fifo-size", 0); - platdata->tx_fifo_sz_nb = + plat->tx_fifo_sz_nb = dev_read_size(dev, "g-tx-fifo-size") / sizeof(u32); - if (platdata->tx_fifo_sz_nb > DWC2_MAX_HW_ENDPOINTS) - platdata->tx_fifo_sz_nb = DWC2_MAX_HW_ENDPOINTS; - if (platdata->tx_fifo_sz_nb) { + if (plat->tx_fifo_sz_nb > DWC2_MAX_HW_ENDPOINTS) + plat->tx_fifo_sz_nb = DWC2_MAX_HW_ENDPOINTS; + if (plat->tx_fifo_sz_nb) { ret = dev_read_u32_array(dev, "g-tx-fifo-size", - platdata->tx_fifo_sz_array, - platdata->tx_fifo_sz_nb); + plat->tx_fifo_sz_array, + plat->tx_fifo_sz_nb); if (ret) return ret; } - platdata->force_b_session_valid = + plat->force_b_session_valid = dev_read_bool(dev, "u-boot,force-b-session-valid"); - /* force platdata according compatible */ + plat->force_vbus_detection = + dev_read_bool(dev, "u-boot,force-vbus-detection"); + + /* force plat according compatible */ drvdata = dev_get_driver_data(dev); if (drvdata) { set_params = (void *)drvdata; - set_params(platdata); + set_params(plat); } return 0; @@ -1101,7 +1047,7 @@ static int dwc2_udc_otg_reset_init(struct udevice *dev, int ret; ret = reset_get_bulk(dev, resets); - if (ret == -ENOTSUPP) + if (ret == -ENOTSUPP || ret == -ENOENT) return 0; if (ret) @@ -1144,10 +1090,10 @@ static int dwc2_udc_otg_clk_init(struct udevice *dev, static int dwc2_udc_otg_probe(struct udevice *dev) { - struct dwc2_plat_otg_data *platdata = dev_get_platdata(dev); + struct dwc2_plat_otg_data *plat = dev_get_plat(dev); struct dwc2_priv_data *priv = dev_get_priv(dev); struct dwc2_usbotg_reg *usbotg_reg = - (struct dwc2_usbotg_reg *)platdata->regs_otg; + (struct dwc2_usbotg_reg *)plat->regs_otg; int ret; ret = dwc2_udc_otg_clk_init(dev, &priv->clks); @@ -1158,36 +1104,50 @@ static int dwc2_udc_otg_probe(struct udevice *dev) if (ret) return ret; - ret = dwc2_phy_setup(dev, &priv->phys, &priv->num_phys); + ret = dwc2_phy_setup(dev, &priv->phys); if (ret) return ret; - if (CONFIG_IS_ENABLED(DM_REGULATOR) && - platdata->activate_stm_id_vb_detection && - !platdata->force_b_session_valid) { - ret = device_get_supply_regulator(dev, "usb33d-supply", - &priv->usb33d_supply); - if (ret) { - dev_err(dev, "can't get voltage level detector supply\n"); - return ret; + if (plat->activate_stm_id_vb_detection) { + if (CONFIG_IS_ENABLED(DM_REGULATOR) && + (!plat->force_b_session_valid || + plat->force_vbus_detection)) { + ret = device_get_supply_regulator(dev, "usb33d-supply", + &priv->usb33d_supply); + if (ret) { + dev_err(dev, "can't get voltage level detector supply\n"); + return ret; + } + ret = regulator_set_enable(priv->usb33d_supply, true); + if (ret) { + dev_err(dev, "can't enable voltage level detector supply\n"); + return ret; + } } - ret = regulator_set_enable(priv->usb33d_supply, true); - if (ret) { - dev_err(dev, "can't enable voltage level detector supply\n"); - return ret; + + if (plat->force_b_session_valid && + !plat->force_vbus_detection) { + /* Override VBUS detection: enable then value*/ + setbits_le32(&usbotg_reg->gotgctl, VB_VALOEN); + setbits_le32(&usbotg_reg->gotgctl, VB_VALOVAL); + } else { + /* Enable VBUS sensing */ + setbits_le32(&usbotg_reg->ggpio, + GGPIO_STM32_OTG_GCCFG_VBDEN); + } + if (plat->force_b_session_valid) { + /* Override B session bits: enable then value */ + setbits_le32(&usbotg_reg->gotgctl, A_VALOEN | B_VALOEN); + setbits_le32(&usbotg_reg->gotgctl, + A_VALOVAL | B_VALOVAL); + } else { + /* Enable ID detection */ + setbits_le32(&usbotg_reg->ggpio, + GGPIO_STM32_OTG_GCCFG_IDEN); } - /* Enable vbus sensing */ - setbits_le32(&usbotg_reg->ggpio, - GGPIO_STM32_OTG_GCCFG_VBDEN | - GGPIO_STM32_OTG_GCCFG_IDEN); } - if (platdata->force_b_session_valid) - /* Override B session bits : value and enable */ - setbits_le32(&usbotg_reg->gotgctl, - A_VALOEN | A_VALOVAL | B_VALOEN | B_VALOVAL); - - ret = dwc2_udc_probe(platdata); + ret = dwc2_udc_probe(plat); if (ret) return ret; @@ -1208,7 +1168,7 @@ static int dwc2_udc_otg_remove(struct udevice *dev) clk_release_bulk(&priv->clks); - dwc2_phy_shutdown(dev, priv->phys, priv->num_phys); + dwc2_phy_shutdown(dev, &priv->phys); return dm_scan_fdt_dev(dev); } @@ -1225,18 +1185,18 @@ U_BOOT_DRIVER(dwc2_udc_otg) = { .name = "dwc2-udc-otg", .id = UCLASS_USB_GADGET_GENERIC, .of_match = dwc2_udc_otg_ids, - .ofdata_to_platdata = dwc2_udc_otg_ofdata_to_platdata, + .of_to_plat = dwc2_udc_otg_of_to_plat, .probe = dwc2_udc_otg_probe, .remove = dwc2_udc_otg_remove, - .platdata_auto_alloc_size = sizeof(struct dwc2_plat_otg_data), - .priv_auto_alloc_size = sizeof(struct dwc2_priv_data), + .plat_auto = sizeof(struct dwc2_plat_otg_data), + .priv_auto = sizeof(struct dwc2_priv_data), }; int dwc2_udc_B_session_valid(struct udevice *dev) { - struct dwc2_plat_otg_data *platdata = dev_get_platdata(dev); + struct dwc2_plat_otg_data *plat = dev_get_plat(dev); struct dwc2_usbotg_reg *usbotg_reg = - (struct dwc2_usbotg_reg *)platdata->regs_otg; + (struct dwc2_usbotg_reg *)plat->regs_otg; return readl(&usbotg_reg->gotgctl) & B_SESSION_VALID; }