#define EXYNOS_4x12_URSTCON_OTG_PHYLINK BIT(2)
#define EXYNOS_4x12_URSTCON_HOST_PHY BIT(3)
#define EXYNOS_4x12_URSTCON_PHY1 BIT(4)
-#define EXYNOS_4x12_URSTCON_HSIC0 BIT(5)
-#define EXYNOS_4x12_URSTCON_HSIC1 BIT(6)
+/*
+ * According to Exynos 4x12 reference manual the values for
+ * EXYNOS_4x12_URSTCON_HSIC are:
+ * URSTCON_HSIC0 = BIT(5)
+ * URSTCON_HSIC1 = BIT(6)
+ * but from experiments with real hardware the above 2 bitfields
+ * seems to be swapped, so define them to match the actual
+ * hardware */
+#define EXYNOS_4x12_URSTCON_HSIC1 BIT(5)
+#define EXYNOS_4x12_URSTCON_HSIC0 BIT(6)
#define EXYNOS_4x12_URSTCON_HOST_LINK_ALL BIT(7)
#define EXYNOS_4x12_URSTCON_HOST_LINK_P0 BIT(8)
#define EXYNOS_4x12_URSTCON_HOST_LINK_P1 BIT(9)
break;
case EXYNOS4x12_HSIC0:
phypwr = EXYNOS_4x12_UPHYPWR_HSIC0;
- rstbits = EXYNOS_4x12_URSTCON_HSIC1 |
+ rstbits = EXYNOS_4x12_URSTCON_HSIC0 |
EXYNOS_4x12_URSTCON_HOST_LINK_P0 |
EXYNOS_4x12_URSTCON_HOST_PHY;
break;
case EXYNOS4x12_HSIC1:
phypwr = EXYNOS_4x12_UPHYPWR_HSIC1;
rstbits = EXYNOS_4x12_URSTCON_HSIC1 |
- EXYNOS_4x12_URSTCON_HOST_LINK_P1;
+ EXYNOS_4x12_URSTCON_HOST_LINK_P1 |
+ EXYNOS_4x12_URSTCON_HOST_PHY;
break;
};
static int exynos4x12_power_on(struct samsung_usb2_phy_instance *inst)
{
struct samsung_usb2_phy_driver *drv = inst->drv;
+ struct samsung_usb2_phy_instance *device =
+ &drv->instances[EXYNOS4x12_DEVICE];
- inst->enabled = 1;
+ inst->enabled++;
exynos4x12_setup_clk(inst);
exynos4x12_phy_pwr(inst, 1);
exynos4x12_isol(inst, 0);
/* Power on the device, as it is necessary for HSIC to work */
- if (inst->cfg->id == EXYNOS4x12_HSIC0) {
- struct samsung_usb2_phy_instance *device =
- &drv->instances[EXYNOS4x12_DEVICE];
- exynos4x12_phy_pwr(device, 1);
- exynos4x12_isol(device, 0);
+ if (inst->cfg->id == EXYNOS4x12_HSIC0 ||
+ inst->cfg->id == EXYNOS4x12_HSIC1) {
+ if (!device->enabled) {
+ exynos4x12_phy_pwr(device, 1);
+ exynos4x12_isol(device, 0);
+ }
+ device->enabled++;
}
return 0;
struct samsung_usb2_phy_instance *device =
&drv->instances[EXYNOS4x12_DEVICE];
- inst->enabled = 0;
+ inst->enabled--;
+ if (inst->enabled)
+ return 0;
+
exynos4x12_isol(inst, 1);
exynos4x12_phy_pwr(inst, 0);
- if (inst->cfg->id == EXYNOS4x12_HSIC0 && !device->enabled) {
- exynos4x12_isol(device, 1);
- exynos4x12_phy_pwr(device, 0);
+ if (inst->cfg->id == EXYNOS4x12_HSIC0 ||
+ inst->cfg->id == EXYNOS4x12_HSIC1) {
+ device->enabled--;
+ if (!device->enabled) {
+ exynos4x12_isol(device, 1);
+ exynos4x12_phy_pwr(device, 0);
+ }
}
return 0;