From 248698c9d44d67dcc3d96c29e809eaad6f86ef64 Mon Sep 17 00:00:00 2001 From: Mayank Rana Date: Thu, 19 Apr 2012 00:03:16 +0530 Subject: [PATCH] msm_hsusb: Vote for corner of VDD CX instead of voltage of VDD CX New platform uses RBCPR hardware feature, with that voting for absolute voltage of VDD CX is not required. Hence vote for corner of VDD CX which uses nominal corner voltage on VDD CX. CRs-Fixed: 355399 Change-ID: I22a73c5a439c98195b907ff3d032eb675a557612 Signed-off-by: Mayank Rana --- arch/arm/mach-msm/board-8930-regulator.c | 2 +- drivers/usb/otg/msm_otg.c | 112 +++++++++++------------ include/linux/usb/msm_hsusb.h | 12 +++ 3 files changed, 64 insertions(+), 62 deletions(-) diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c index f760e7bd4e7..fc89a11bfcb 100644 --- a/arch/arm/mach-msm/board-8930-regulator.c +++ b/arch/arm/mach-msm/board-8930-regulator.c @@ -148,7 +148,6 @@ VREG_CONSUMERS(L27) = { }; VREG_CONSUMERS(S1) = { REGULATOR_SUPPLY("8038_s1", NULL), - REGULATOR_SUPPLY("HSUSB_VDDCX", "msm_otg"), REGULATOR_SUPPLY("riva_vddcx", "wcnss_wlan.0"), }; VREG_CONSUMERS(S2) = { @@ -192,6 +191,7 @@ VREG_CONSUMERS(EXT_OTG_SW) = { }; VREG_CONSUMERS(VDD_DIG_CORNER) = { REGULATOR_SUPPLY("vdd_dig_corner", NULL), + REGULATOR_SUPPLY("hsusb_vdd_dig", "msm_otg"), }; #define PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, _modes, _ops, \ diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c index b428bd2c5f6..2f7e250639d 100644 --- a/drivers/usb/otg/msm_otg.c +++ b/drivers/usb/otg/msm_otg.c @@ -45,6 +45,7 @@ #include #include #include +#include #define MSM_USB_BASE (motg->regs) #define DRIVER_NAME "msm_otg" @@ -61,6 +62,7 @@ #define USB_PHY_1P8_HPM_LOAD 50000 /* uA */ #define USB_PHY_1P8_LPM_LOAD 4000 /* uA */ +#define USB_PHY_VDD_DIG_VOL_NONE 0 /*uV */ #define USB_PHY_VDD_DIG_VOL_MIN 1045000 /* uV */ #define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */ @@ -104,53 +106,25 @@ static inline bool aca_enabled(void) #endif } -static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) -{ - int ret = 0; +enum usb_vdd_value { + VDD_NONE = 0, + VDD_MIN, + VDD_MAX, + VDD_VAL_MAX, +}; - if (init) { - hsusb_vddcx = devm_regulator_get(motg->otg.dev, "HSUSB_VDDCX"); - if (IS_ERR(hsusb_vddcx)) { - dev_err(motg->otg.dev, "unable to get hsusb vddcx\n"); - return PTR_ERR(hsusb_vddcx); - } - - ret = regulator_set_voltage(hsusb_vddcx, - USB_PHY_VDD_DIG_VOL_MIN, - USB_PHY_VDD_DIG_VOL_MAX); - if (ret) { - dev_err(motg->otg.dev, "unable to set the voltage " - "for hsusb vddcx\n"); - return ret; - } - - ret = regulator_enable(hsusb_vddcx); - if (ret) { - regulator_set_voltage(hsusb_vddcx, 0, - USB_PHY_VDD_DIG_VOL_MIN); - dev_err(motg->otg.dev, "unable to enable the hsusb vddcx\n"); - return ret; - } - - } else { - - ret = regulator_disable(hsusb_vddcx); - if (ret) { - dev_err(motg->otg.dev, "unable to disable hsusb vddcx\n"); - return ret; - } - - ret = regulator_set_voltage(hsusb_vddcx, 0, - USB_PHY_VDD_DIG_VOL_MIN); - if (ret) { - dev_err(motg->otg.dev, "unable to set the voltage" - "for hsusb vddcx\n"); - return ret; - } - } - - return ret; -} +static const int vdd_val[VDD_TYPE_MAX][VDD_VAL_MAX] = { + { /* VDD_CX CORNER Voting */ + [VDD_NONE] = RPM_VREG_CORNER_NONE, + [VDD_MIN] = RPM_VREG_CORNER_NOMINAL, + [VDD_MAX] = RPM_VREG_CORNER_HIGH, + }, + { /* VDD_CX Voltage Voting */ + [VDD_NONE] = USB_PHY_VDD_DIG_VOL_NONE, + [VDD_MIN] = USB_PHY_VDD_DIG_VOL_MIN, + [VDD_MAX] = USB_PHY_VDD_DIG_VOL_MAX, + }, +}; static int msm_hsusb_ldo_init(struct msm_otg *motg, int init) { @@ -198,15 +172,13 @@ put_3p3_lpm: #define USB_PHY_SUSP_DIG_VOL 500000 static int msm_hsusb_config_vddcx(int high) { - int max_vol = USB_PHY_VDD_DIG_VOL_MAX; + struct msm_otg *motg = the_msm_otg; + enum usb_vdd_type vdd_type = motg->vdd_type; + int max_vol = vdd_val[vdd_type][VDD_MAX]; int min_vol; int ret; - if (high) - min_vol = USB_PHY_VDD_DIG_VOL_MIN; - else - min_vol = USB_PHY_SUSP_DIG_VOL; - + min_vol = vdd_val[vdd_type][!!high]; ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol); if (ret) { pr_err("%s: unable to set the voltage for regulator " @@ -3321,22 +3293,33 @@ static int __init msm_otg_probe(struct platform_device *pdev) clk_prepare_enable(motg->pclk); - ret = msm_hsusb_init_vddcx(motg, 1); - if (ret) { - dev_err(&pdev->dev, "hsusb vddcx init failed\n"); - goto devote_xo_handle; + motg->vdd_type = VDDCX_CORNER; + hsusb_vddcx = devm_regulator_get(motg->otg.dev, "hsusb_vdd_dig"); + if (IS_ERR(hsusb_vddcx)) { + hsusb_vddcx = devm_regulator_get(motg->otg.dev, "HSUSB_VDDCX"); + if (IS_ERR(hsusb_vddcx)) { + dev_err(motg->otg.dev, "unable to get hsusb vddcx\n"); + goto devote_xo_handle; + } + motg->vdd_type = VDDCX; } ret = msm_hsusb_config_vddcx(1); if (ret) { dev_err(&pdev->dev, "hsusb vddcx configuration failed\n"); - goto free_init_vddcx; + goto devote_xo_handle; + } + + ret = regulator_enable(hsusb_vddcx); + if (ret) { + dev_err(&pdev->dev, "unable to enable the hsusb vddcx\n"); + goto free_config_vddcx; } ret = msm_hsusb_ldo_init(motg, 1); if (ret) { dev_err(&pdev->dev, "hsusb vreg configuration failed\n"); - goto free_init_vddcx; + goto free_hsusb_vddcx; } if (pdata->mhl_enable) { @@ -3460,8 +3443,12 @@ destroy_wlock: msm_hsusb_ldo_enable(motg, 0); free_ldo_init: msm_hsusb_ldo_init(motg, 0); -free_init_vddcx: - msm_hsusb_init_vddcx(motg, 0); +free_hsusb_vddcx: + regulator_disable(hsusb_vddcx); +free_config_vddcx: + regulator_set_voltage(hsusb_vddcx, + vdd_val[motg->vdd_type][VDD_NONE], + vdd_val[motg->vdd_type][VDD_MAX]); devote_xo_handle: clk_disable_unprepare(motg->pclk); msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_OFF); @@ -3535,7 +3522,10 @@ static int __devexit msm_otg_remove(struct platform_device *pdev) msm_xo_put(motg->xo_handle); msm_hsusb_ldo_enable(motg, 0); msm_hsusb_ldo_init(motg, 0); - msm_hsusb_init_vddcx(motg, 0); + regulator_disable(hsusb_vddcx); + regulator_set_voltage(hsusb_vddcx, + vdd_val[motg->vdd_type][VDD_NONE], + vdd_val[motg->vdd_type][VDD_MAX]); iounmap(motg->regs); pm_runtime_set_suspended(&pdev->dev); diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h index a731774cbde..e84884c36bf 100644 --- a/include/linux/usb/msm_hsusb.h +++ b/include/linux/usb/msm_hsusb.h @@ -148,6 +148,17 @@ enum usb_chg_type { USB_ACA_DOCK_CHARGER, }; +/** + * Used different VDDCX voltage voting mechnism + * VDDCX_CORNER Vote for VDDCX Corner voltage + * VDDCX Vote for VDDCX Absolute voltage + */ +enum usb_vdd_type { + VDDCX_CORNER = 0, + VDDCX, + VDD_TYPE_MAX, +}; + /** * SPS Pipes direction. * @@ -342,6 +353,7 @@ struct msm_otg { unsigned long tmouts; u8 active_tmout; struct hrtimer timer; + enum usb_vdd_type vdd_type; }; struct msm_hsic_host_platform_data {