summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorMark Kuo <mkuo@nvidia.com>2016-04-19 07:14:54 -0400
committerAshutosh Jha <ajha@nvidia.com>2016-08-01 21:18:32 -0400
commit9fa385edfb538b87d9bec36bceea7dd952fd5dd0 (patch)
tree9401e951dc0a5938343791f1ba8a30f830def8fb /drivers/pinctrl
parent19031972b862aeec92d29c208c6249c3034466dd (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.c377
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}
3043EXPORT_SYMBOL_GPL(tegra_phy_xusb_pretend_connected); 3065EXPORT_SYMBOL_GPL(tegra_phy_xusb_pretend_connected);
3044 3066
3067void 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}
3083EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_chg_power_on);
3084
3085void 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}
3101EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_chg_power_down);
3102
3103void 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}
3119EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_pd2_deassert);
3120
3121void 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}
3137EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_pd2_assert);
3138
3139void 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}
3156EXPORT_SYMBOL_GPL(tegra_phy_xusb_set_idcd_dbnc);
3157
3158void 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}
3184EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_battery_charge_on);
3185
3186void 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}
3203EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_battery_charge_off);
3204
3205void 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}
3222EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_enable_charger_filters);
3223
3224void 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}
3241EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_disable_charger_filters);
3242
3243void 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}
3267EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_set_protection_level);
3268
3269bool 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}
3323EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_dcd);
3324
3325bool 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}
3356EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_primary_charger_detect);
3357
3358bool 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}
3389EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_pad_secondary_charger_detect);
3390
3391int 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}
3410EXPORT_SYMBOL_GPL(tegra_phy_xusb_phy_to_port);
3411
3045MODULE_AUTHOR("JC Kuo <jckuo@nvidia.com>"); 3412MODULE_AUTHOR("JC Kuo <jckuo@nvidia.com>");
3046MODULE_DESCRIPTION("Tegra 186 XUSB PADCTL driver"); 3413MODULE_DESCRIPTION("Tegra 186 XUSB PADCTL driver");
3047MODULE_LICENSE("GPL v2"); 3414MODULE_LICENSE("GPL v2");