diff options
| author | Mark Kuo <mkuo@nvidia.com> | 2016-04-19 07:14:54 -0400 |
|---|---|---|
| committer | Ashutosh Jha <ajha@nvidia.com> | 2016-08-01 21:18:32 -0400 |
| commit | 9fa385edfb538b87d9bec36bceea7dd952fd5dd0 (patch) | |
| tree | 9401e951dc0a5938343791f1ba8a30f830def8fb /drivers/pinctrl | |
| parent | 19031972b862aeec92d29c208c6249c3034466dd (diff) | |
padctl: t186: add APIs for charger detection
Add a few APIs for doing charger detection on T186.
Bug 200153047
Change-Id: Ifc9ba84e483b1fa1c5923990c2eadbf140ea4a6b
Signed-off-by: Mark Kuo <mkuo@nvidia.com>
Reviewed-on: http://git-master/r/1170316
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Rakesh Babu Bodla <rbodla@nvidia.com>
Reviewed-by: Ashutosh Jha <ajha@nvidia.com>
Diffstat (limited to 'drivers/pinctrl')
| -rw-r--r-- | drivers/pinctrl/pinctrl-tegra186-padctl.c | 377 |
1 files changed, 372 insertions, 5 deletions
diff --git a/drivers/pinctrl/pinctrl-tegra186-padctl.c b/drivers/pinctrl/pinctrl-tegra186-padctl.c index a5258dae8..bd9e8f0c1 100644 --- a/drivers/pinctrl/pinctrl-tegra186-padctl.c +++ b/drivers/pinctrl/pinctrl-tegra186-padctl.c | |||
| @@ -103,10 +103,33 @@ | |||
| 103 | 103 | ||
| 104 | #define USB2_BATTERY_CHRG_OTGPADX_CTL0(x) (0x80 + (x) * 0x40) | 104 | #define USB2_BATTERY_CHRG_OTGPADX_CTL0(x) (0x80 + (x) * 0x40) |
| 105 | #define PD_CHG (1 << 0) | 105 | #define PD_CHG (1 << 0) |
| 106 | #define VDCD_DET_FILTER_EN (1 << 4) | ||
| 107 | #define VDAT_DET (1 << 5) | ||
| 108 | #define VDAT_DET_FILTER_EN (1 << 8) | ||
| 109 | #define OP_SINK_EN (1 << 9) | ||
| 110 | #define OP_SRC_EN (1 << 10) | ||
| 111 | #define ON_SINK_EN (1 << 11) | ||
| 112 | #define ON_SRC_EN (1 << 12) | ||
| 113 | #define OP_I_SRC_EN (1 << 13) | ||
| 114 | #define ZIP_FILTER_EN (1 << 21) | ||
| 115 | #define ZIN_FILTER_EN (1 << 25) | ||
| 116 | #define DCD_DETECTED (1 << 26) | ||
| 117 | #define SRP_DETECT_EN (1 << 28) | ||
| 118 | #define SRP_DETECTED (1 << 29) | ||
| 119 | #define SRP_INTR_EN (1 << 30) | ||
| 120 | #define GENERATE_SRP (1 << 31) | ||
| 106 | 121 | ||
| 107 | #define USB2_BATTERY_CHRG_OTGPADX_CTL1(x) (0x84 + (x) * 0x40) | 122 | #define USB2_BATTERY_CHRG_OTGPADX_CTL1(x) (0x84 + (x) * 0x40) |
| 108 | #define VREG_LEV(x) (((x) & 0x3) << 7) | ||
| 109 | #define VREG_FIX18 (1 << 6) | 123 | #define VREG_FIX18 (1 << 6) |
| 124 | #define VREG_LEV(x) (((x) & 0x3) << 7) | ||
| 125 | #define USBOP_RPD_OVRD (1 << 16) | ||
| 126 | #define USBOP_RPD_OVRD_VAL (1 << 17) | ||
| 127 | #define USBOP_RPU_OVRD (1 << 18) | ||
| 128 | #define USBOP_RPU_OVRD_VAL (1 << 19) | ||
| 129 | #define USBON_RPD_OVRD (1 << 20) | ||
| 130 | #define USBON_RPD_OVRD_VAL (1 << 21) | ||
| 131 | #define USBON_RPU_OVRD (1 << 22) | ||
| 132 | #define USBON_RPU_OVRD_VAL (1 << 23) | ||
| 110 | 133 | ||
| 111 | #define XUSB_PADCTL_USB2_OTG_PADX_CTL0(x) (0x88 + (x) * 0x40) | 134 | #define XUSB_PADCTL_USB2_OTG_PADX_CTL0(x) (0x88 + (x) * 0x40) |
| 112 | #define HS_CURR_LEVEL(x) ((x) & 0x3f) | 135 | #define HS_CURR_LEVEL(x) ((x) & 0x3f) |
| @@ -121,6 +144,9 @@ | |||
| 121 | #define TERM_RANGE_ADJ(x) (((x) & 0xf) << 3) | 144 | #define TERM_RANGE_ADJ(x) (((x) & 0xf) << 3) |
| 122 | #define RPD_CTRL(x) (((x) & 0x1f) << 26) | 145 | #define RPD_CTRL(x) (((x) & 0x1f) << 26) |
| 123 | 146 | ||
| 147 | #define XUSB_PADCTL_USB2_BATTERY_CHRG_TDCD_DBNC_TIMER_0 (0x280) | ||
| 148 | #define IDCD_DBNC(x) (((x) & 0x3ff) << 0) | ||
| 149 | |||
| 124 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0 (0x284) | 150 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0 (0x284) |
| 125 | #define BIAS_PAD_PD (1 << 11) | 151 | #define BIAS_PAD_PD (1 << 11) |
| 126 | #define HS_SQUELCH_LEVEL(x) (((x) & 0x7) << 0) | 152 | #define HS_SQUELCH_LEVEL(x) (((x) & 0x7) << 0) |
| @@ -1428,10 +1454,6 @@ static int tegra186_utmi_phy_power_on(struct phy *phy) | |||
| 1428 | reg |= RPD_CTRL(padctl->calib.rpd_ctrl); | 1454 | reg |= RPD_CTRL(padctl->calib.rpd_ctrl); |
| 1429 | padctl_writel(padctl, reg, XUSB_PADCTL_USB2_OTG_PADX_CTL1(port)); | 1455 | padctl_writel(padctl, reg, XUSB_PADCTL_USB2_OTG_PADX_CTL1(port)); |
| 1430 | 1456 | ||
| 1431 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL1(port)); | ||
| 1432 | reg |= VREG_FIX18; | ||
| 1433 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL1(port)); | ||
| 1434 | |||
| 1435 | mutex_lock(&padctl->lock); | 1457 | mutex_lock(&padctl->lock); |
| 1436 | 1458 | ||
| 1437 | if (padctl->utmi_enable++ > 0) | 1459 | if (padctl->utmi_enable++ > 0) |
| @@ -3042,6 +3064,351 @@ int tegra_phy_xusb_pretend_connected(struct phy *phy) | |||
| 3042 | } | 3064 | } |
| 3043 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_pretend_connected); | 3065 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_pretend_connected); |
| 3044 | 3066 | ||
| 3067 | void tegra_phy_xusb_utmi_pad_chg_power_on(struct phy *phy) | ||
| 3068 | { | ||
| 3069 | struct tegra_padctl *padctl; | ||
| 3070 | int port; | ||
| 3071 | u32 reg; | ||
| 3072 | |||
| 3073 | if (!phy) | ||
| 3074 | return; | ||
| 3075 | |||
| 3076 | padctl = phy_get_drvdata(phy); | ||
| 3077 | port = utmi_phy_to_port(phy); | ||
| 3078 | |||
| 3079 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3080 | reg &= ~PD_CHG; | ||
| 3081 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3082 | } | ||
| 3083 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_chg_power_on); | ||
| 3084 | |||
| 3085 | void tegra_phy_xusb_utmi_pad_chg_power_down(struct phy *phy) | ||
| 3086 | { | ||
| 3087 | struct tegra_padctl *padctl; | ||
| 3088 | int port; | ||
| 3089 | u32 reg; | ||
| 3090 | |||
| 3091 | if (!phy) | ||
| 3092 | return; | ||
| 3093 | |||
| 3094 | padctl = phy_get_drvdata(phy); | ||
| 3095 | port = utmi_phy_to_port(phy); | ||
| 3096 | |||
| 3097 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3098 | reg |= PD_CHG; | ||
| 3099 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3100 | } | ||
| 3101 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_chg_power_down); | ||
| 3102 | |||
| 3103 | void tegra_phy_xusb_utmi_pad_pd2_deassert(struct phy *phy) | ||
| 3104 | { | ||
| 3105 | struct tegra_padctl *padctl; | ||
| 3106 | int port; | ||
| 3107 | u32 reg; | ||
| 3108 | |||
| 3109 | if (!phy) | ||
| 3110 | return; | ||
| 3111 | |||
| 3112 | padctl = phy_get_drvdata(phy); | ||
| 3113 | port = utmi_phy_to_port(phy); | ||
| 3114 | |||
| 3115 | reg = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(port)); | ||
| 3116 | reg &= ~USB2_OTG_PD2_OVRD_EN; | ||
| 3117 | padctl_writel(padctl, reg, XUSB_PADCTL_USB2_OTG_PADX_CTL0(port)); | ||
| 3118 | } | ||
| 3119 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_pd2_deassert); | ||
| 3120 | |||
| 3121 | void tegra_phy_xusb_utmi_pad_pd2_assert(struct phy *phy) | ||
| 3122 | { | ||
| 3123 | struct tegra_padctl *padctl; | ||
| 3124 | int port; | ||
| 3125 | u32 reg; | ||
| 3126 | |||
| 3127 | if (!phy) | ||
| 3128 | return; | ||
| 3129 | |||
| 3130 | padctl = phy_get_drvdata(phy); | ||
| 3131 | port = utmi_phy_to_port(phy); | ||
| 3132 | |||
| 3133 | reg = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(port)); | ||
| 3134 | reg |= (USB2_OTG_PD2 | USB2_OTG_PD2_OVRD_EN); | ||
| 3135 | padctl_writel(padctl, reg, XUSB_PADCTL_USB2_OTG_PADX_CTL0(port)); | ||
| 3136 | } | ||
| 3137 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_pd2_assert); | ||
| 3138 | |||
| 3139 | void tegra_phy_xusb_set_idcd_dbnc(struct phy *phy, u32 val) | ||
| 3140 | { | ||
| 3141 | struct tegra_padctl *padctl; | ||
| 3142 | u32 reg; | ||
| 3143 | |||
| 3144 | if (!phy) | ||
| 3145 | return; | ||
| 3146 | |||
| 3147 | padctl = phy_get_drvdata(phy); | ||
| 3148 | |||
| 3149 | reg = padctl_readl(padctl, | ||
| 3150 | XUSB_PADCTL_USB2_BATTERY_CHRG_TDCD_DBNC_TIMER_0); | ||
| 3151 | reg &= ~IDCD_DBNC(~0); | ||
| 3152 | reg |= IDCD_DBNC(val); | ||
| 3153 | padctl_writel(padctl, reg, | ||
| 3154 | XUSB_PADCTL_USB2_BATTERY_CHRG_TDCD_DBNC_TIMER_0); | ||
| 3155 | } | ||
| 3156 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_set_idcd_dbnc); | ||
| 3157 | |||
| 3158 | void tegra_phy_xusb_utmi_pad_battery_charge_on(struct phy *phy) | ||
| 3159 | { | ||
| 3160 | struct tegra_padctl *padctl; | ||
| 3161 | int port; | ||
| 3162 | u32 reg; | ||
| 3163 | |||
| 3164 | if (!phy) | ||
| 3165 | return; | ||
| 3166 | |||
| 3167 | padctl = phy_get_drvdata(phy); | ||
| 3168 | port = utmi_phy_to_port(phy); | ||
| 3169 | |||
| 3170 | /* Set DP/DN Pull up/down to zero by default */ | ||
| 3171 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL1(port)); | ||
| 3172 | reg &= ~(USBOP_RPD_OVRD_VAL | USBOP_RPU_OVRD_VAL | | ||
| 3173 | USBON_RPD_OVRD_VAL | USBON_RPU_OVRD_VAL); | ||
| 3174 | reg |= (USBOP_RPD_OVRD | USBOP_RPU_OVRD | | ||
| 3175 | USBON_RPD_OVRD | USBON_RPU_OVRD); | ||
| 3176 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL1(port)); | ||
| 3177 | |||
| 3178 | /* Disable DP/DN as src/sink */ | ||
| 3179 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3180 | reg &= ~(OP_SRC_EN | ON_SINK_EN | | ||
| 3181 | ON_SRC_EN | OP_SINK_EN); | ||
| 3182 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3183 | } | ||
| 3184 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_battery_charge_on); | ||
| 3185 | |||
| 3186 | void tegra_phy_xusb_utmi_pad_battery_charge_off(struct phy *phy) | ||
| 3187 | { | ||
| 3188 | struct tegra_padctl *padctl; | ||
| 3189 | int port; | ||
| 3190 | u32 reg; | ||
| 3191 | |||
| 3192 | if (!phy) | ||
| 3193 | return; | ||
| 3194 | |||
| 3195 | padctl = phy_get_drvdata(phy); | ||
| 3196 | port = utmi_phy_to_port(phy); | ||
| 3197 | |||
| 3198 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL1(port)); | ||
| 3199 | reg &= ~(USBOP_RPD_OVRD | USBOP_RPU_OVRD | | ||
| 3200 | USBON_RPD_OVRD | USBON_RPU_OVRD); | ||
| 3201 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL1(port)); | ||
| 3202 | } | ||
| 3203 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_battery_charge_off); | ||
| 3204 | |||
| 3205 | void tegra_phy_xusb_utmi_pad_enable_charger_filters(struct phy *phy) | ||
| 3206 | { | ||
| 3207 | struct tegra_padctl *padctl; | ||
| 3208 | int port; | ||
| 3209 | u32 reg; | ||
| 3210 | |||
| 3211 | if (!phy) | ||
| 3212 | return; | ||
| 3213 | |||
| 3214 | padctl = phy_get_drvdata(phy); | ||
| 3215 | port = utmi_phy_to_port(phy); | ||
| 3216 | |||
| 3217 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3218 | reg |= (VDCD_DET_FILTER_EN | VDAT_DET_FILTER_EN | | ||
| 3219 | ZIP_FILTER_EN | ZIN_FILTER_EN); | ||
| 3220 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3221 | } | ||
| 3222 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_enable_charger_filters); | ||
| 3223 | |||
| 3224 | void tegra_phy_xusb_utmi_pad_disable_charger_filters(struct phy *phy) | ||
| 3225 | { | ||
| 3226 | struct tegra_padctl *padctl; | ||
| 3227 | int port; | ||
| 3228 | u32 reg; | ||
| 3229 | |||
| 3230 | if (!phy) | ||
| 3231 | return; | ||
| 3232 | |||
| 3233 | padctl = phy_get_drvdata(phy); | ||
| 3234 | port = utmi_phy_to_port(phy); | ||
| 3235 | |||
| 3236 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3237 | reg &= ~(VDCD_DET_FILTER_EN | VDAT_DET_FILTER_EN | | ||
| 3238 | ZIP_FILTER_EN | ZIN_FILTER_EN); | ||
| 3239 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3240 | } | ||
| 3241 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_disable_charger_filters); | ||
| 3242 | |||
| 3243 | void tegra_phy_xusb_utmi_pad_set_protection_level(struct phy *phy, int level) | ||
| 3244 | { | ||
| 3245 | struct tegra_padctl *padctl; | ||
| 3246 | int port; | ||
| 3247 | u32 reg; | ||
| 3248 | |||
| 3249 | if (!phy) | ||
| 3250 | return; | ||
| 3251 | |||
| 3252 | padctl = phy_get_drvdata(phy); | ||
| 3253 | port = utmi_phy_to_port(phy); | ||
| 3254 | |||
| 3255 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL1(port)); | ||
| 3256 | if (level < 0) { | ||
| 3257 | /* disable pad protection */ | ||
| 3258 | reg |= VREG_FIX18; | ||
| 3259 | reg &= ~VREG_LEV(~0); | ||
| 3260 | } else { | ||
| 3261 | reg &= ~VREG_FIX18; | ||
| 3262 | reg &= ~VREG_LEV(~0); | ||
| 3263 | reg |= VREG_LEV(level); | ||
| 3264 | } | ||
| 3265 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL1(port)); | ||
| 3266 | } | ||
| 3267 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_set_protection_level); | ||
| 3268 | |||
| 3269 | bool tegra_phy_xusb_utmi_pad_dcd(struct phy *phy) | ||
| 3270 | { | ||
| 3271 | struct tegra_padctl *padctl; | ||
| 3272 | int port; | ||
| 3273 | u32 reg; | ||
| 3274 | int dcd_timeout_ms = 0; | ||
| 3275 | bool ret = false; | ||
| 3276 | |||
| 3277 | if (!phy) | ||
| 3278 | return false; | ||
| 3279 | |||
| 3280 | padctl = phy_get_drvdata(phy); | ||
| 3281 | port = utmi_phy_to_port(phy); | ||
| 3282 | |||
| 3283 | /* data contact detection */ | ||
| 3284 | /* Turn on IDP_SRC */ | ||
| 3285 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3286 | reg |= OP_I_SRC_EN; | ||
| 3287 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3288 | |||
| 3289 | /* Turn on D- pull-down resistor */ | ||
| 3290 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL1(port)); | ||
| 3291 | reg |= USBON_RPD_OVRD_VAL; | ||
| 3292 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL1(port)); | ||
| 3293 | |||
| 3294 | /* Wait for TDCD_DBNC */ | ||
| 3295 | usleep_range(10000, 120000); | ||
| 3296 | |||
| 3297 | while (dcd_timeout_ms < 900) { | ||
| 3298 | reg = padctl_readl(padctl, | ||
| 3299 | USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3300 | if (reg & DCD_DETECTED) { | ||
| 3301 | dev_dbg(padctl->dev, "USB2 port %d DCD successful\n", | ||
| 3302 | port); | ||
| 3303 | ret = true; | ||
| 3304 | break; | ||
| 3305 | } | ||
| 3306 | usleep_range(20000, 22000); | ||
| 3307 | dcd_timeout_ms += 22; | ||
| 3308 | } | ||
| 3309 | |||
| 3310 | /* Turn off IP_SRC, clear DCD DETECTED*/ | ||
| 3311 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3312 | reg &= ~OP_I_SRC_EN; | ||
| 3313 | reg |= DCD_DETECTED; | ||
| 3314 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3315 | |||
| 3316 | /* Turn off D- pull-down resistor */ | ||
| 3317 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL1(port)); | ||
| 3318 | reg &= ~USBON_RPD_OVRD_VAL; | ||
| 3319 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL1(port)); | ||
| 3320 | |||
| 3321 | return ret; | ||
| 3322 | } | ||
| 3323 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_dcd); | ||
| 3324 | |||
| 3325 | bool tegra_phy_xusb_utmi_pad_primary_charger_detect(struct phy *phy) | ||
| 3326 | { | ||
| 3327 | struct tegra_padctl *padctl; | ||
| 3328 | int port; | ||
| 3329 | u32 reg; | ||
| 3330 | bool ret; | ||
| 3331 | |||
| 3332 | if (!phy) | ||
| 3333 | return false; | ||
| 3334 | |||
| 3335 | padctl = phy_get_drvdata(phy); | ||
| 3336 | port = utmi_phy_to_port(phy); | ||
| 3337 | |||
| 3338 | /* Source D+ to D- */ | ||
| 3339 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3340 | reg |= OP_SRC_EN | ON_SINK_EN; | ||
| 3341 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3342 | |||
| 3343 | /* Wait for TVDPSRC_ON */ | ||
| 3344 | msleep(40); | ||
| 3345 | |||
| 3346 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3347 | ret = !!(reg & VDAT_DET); | ||
| 3348 | |||
| 3349 | /* Turn off OP_SRC, ON_SINK, clear VDAT, ZIN status change */ | ||
| 3350 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3351 | reg &= ~(OP_SRC_EN | ON_SINK_EN); | ||
| 3352 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3353 | |||
| 3354 | return ret; | ||
| 3355 | } | ||
| 3356 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_primary_charger_detect); | ||
| 3357 | |||
| 3358 | bool tegra_phy_xusb_utmi_pad_secondary_charger_detect(struct phy *phy) | ||
| 3359 | { | ||
| 3360 | struct tegra_padctl *padctl; | ||
| 3361 | int port; | ||
| 3362 | u32 reg; | ||
| 3363 | bool ret; | ||
| 3364 | |||
| 3365 | if (!phy) | ||
| 3366 | return false; | ||
| 3367 | |||
| 3368 | padctl = phy_get_drvdata(phy); | ||
| 3369 | port = utmi_phy_to_port(phy); | ||
| 3370 | |||
| 3371 | /* Source D- to D+ */ | ||
| 3372 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3373 | reg |= ON_SRC_EN | OP_SINK_EN; | ||
| 3374 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3375 | |||
| 3376 | /* Wait for TVDPSRC_ON */ | ||
| 3377 | msleep(40); | ||
| 3378 | |||
| 3379 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3380 | ret = !(reg & VDAT_DET); | ||
| 3381 | |||
| 3382 | /* Turn off ON_SRC, OP_SINK, clear VDAT, ZIP status change */ | ||
| 3383 | reg = padctl_readl(padctl, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3384 | reg &= ~(ON_SRC_EN | OP_SINK_EN); | ||
| 3385 | padctl_writel(padctl, reg, USB2_BATTERY_CHRG_OTGPADX_CTL0(port)); | ||
| 3386 | |||
| 3387 | return ret; | ||
| 3388 | } | ||
| 3389 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_secondary_charger_detect); | ||
| 3390 | |||
| 3391 | int tegra_phy_xusb_phy_to_port(struct phy *phy) | ||
| 3392 | { | ||
| 3393 | struct tegra_padctl *padctl; | ||
| 3394 | int port = -EINVAL; | ||
| 3395 | |||
| 3396 | if (!phy || IS_ERR(phy)) | ||
| 3397 | return port; | ||
| 3398 | |||
| 3399 | padctl = phy_get_drvdata(phy); | ||
| 3400 | |||
| 3401 | if (is_utmi_phy(phy)) | ||
| 3402 | port = utmi_phy_to_port(phy); | ||
| 3403 | else if (is_hsic_phy(phy)) | ||
| 3404 | port = hsic_phy_to_port(phy); | ||
| 3405 | else if (is_usb3_phy(phy)) | ||
| 3406 | port = usb3_phy_to_port(phy); | ||
| 3407 | |||
| 3408 | return port; | ||
| 3409 | } | ||
| 3410 | EXPORT_SYMBOL_GPL(tegra_phy_xusb_phy_to_port); | ||
| 3411 | |||
| 3045 | MODULE_AUTHOR("JC Kuo <jckuo@nvidia.com>"); | 3412 | MODULE_AUTHOR("JC Kuo <jckuo@nvidia.com>"); |
| 3046 | MODULE_DESCRIPTION("Tegra 186 XUSB PADCTL driver"); | 3413 | MODULE_DESCRIPTION("Tegra 186 XUSB PADCTL driver"); |
| 3047 | MODULE_LICENSE("GPL v2"); | 3414 | MODULE_LICENSE("GPL v2"); |
