summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/board-whistler-baseband.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/board-whistler-baseband.c')
-rw-r--r--arch/arm/mach-tegra/board-whistler-baseband.c60
1 files changed, 52 insertions, 8 deletions
diff --git a/arch/arm/mach-tegra/board-whistler-baseband.c b/arch/arm/mach-tegra/board-whistler-baseband.c
index eb50fb2f8237..b602cd3f44c1 100644
--- a/arch/arm/mach-tegra/board-whistler-baseband.c
+++ b/arch/arm/mach-tegra/board-whistler-baseband.c
@@ -26,8 +26,9 @@
static void baseband_phy_init(void);
static void baseband_phy_on(void);
-static void baseband_phy_off(void);
-
+static void baseband_pre_phy_off(void);
+static void baseband_post_phy_off(void);
+static bool ap2mdm_ack_gpio_off = false;
static struct wake_lock mdm_wake_lock;
static struct gpio modem_gpios[] = {
@@ -58,13 +59,14 @@ static __initdata struct tegra_pingroup_config whistler_null_ulpi_pinmux[] = {
static struct tegra_usb_phy_platform_ops ulpi_null_plat_ops = {
.init = baseband_phy_init,
- .pre_phy_off = baseband_phy_off,
+ .pre_phy_off = baseband_pre_phy_off,
+ .post_phy_off = baseband_post_phy_off,
.post_phy_on = baseband_phy_on,
};
static struct tegra_usb_platform_data tegra_ehci2_ulpi_null_pdata = {
.port_otg = false,
- .has_hostpc = true,
+ .has_hostpc = false,
.phy_intf = TEGRA_USB_PHY_INTF_ULPI_NULL,
.op_mode = TEGRA_USB_OPMODE_HOST,
.u_data.host = {
@@ -105,6 +107,15 @@ static irqreturn_t mdm_start_thread(int irq, void *data)
return IRQ_HANDLED;
}
+static inline void null_phy_set_tristate(bool enable)
+{
+ int tristate = (enable) ? TEGRA_TRI_TRISTATE : TEGRA_TRI_NORMAL;
+
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, tristate);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, tristate);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, tristate);
+}
+
static void baseband_phy_init(void)
{
static bool phy_init;
@@ -117,18 +128,51 @@ static void baseband_phy_init(void)
pr_info("%s\n", __func__);
}
-static void baseband_phy_off(void)
+static void baseband_pre_phy_off(void)
{
/* set AP2MDM_ACK2 high */
gpio_set_value(AP2MDM_ACK2, 1);
+ ap2mdm_ack_gpio_off = true;
+}
+
+static void baseband_post_phy_off(void)
+{
+ null_phy_set_tristate(true);
}
-static void baseband_phy_on (void)
+static void baseband_phy_on(void)
{
- /* set AP2MDM_ACK2 low */
- gpio_set_value(AP2MDM_ACK2, 0);
+ if (ap2mdm_ack_gpio_off) {
+
+ /* driving linestate using GPIO */
+ gpio_set_value(ULPI_D0, 0);
+ gpio_set_value(ULPI_D1, 0);
+
+ /* driving DIR high */
+ gpio_set_value(ULPI_DIR, 1);
+
+ /* remove ULPI tristate */
+ null_phy_set_tristate(false);
+
+ gpio_set_value(AP2MDM_ACK2, 0);
+
+ if (gpio_is_valid(MDM2AP_ACK2)) {
+ int retry = 20000;
+ while (retry) {
+ /* poll phy_restore_gpio high */
+ if (gpio_get_value(MDM2AP_ACK2))
+ break;
+ retry--;
+ }
+
+ if (retry == 0)
+ pr_info("phy_restore_gpio timeout\n");
+ }
+ ap2mdm_ack_gpio_off = false;
+ }
}
+
static void baseband_start(void)
{
/*