usb: dwc3: msm: add orientation gpio support

As dwc3 msm support override orientation and super speed phy lane flag,
it is better support orientation gpio here.

Change-Id: I2460286d8538bae3f2e768eb380e11f11faf97fc
Signed-off-by: Linyu Yuan <quic_linyyuan@quicinc.com>
This commit is contained in:
Linyu Yuan 2022-11-11 14:29:36 +08:00 committed by Gerrit - the friendly Code Review server
parent e22de8882b
commit 1f40435ba0
4 changed files with 31 additions and 85 deletions

View File

@ -598,6 +598,9 @@ struct dwc3_msm {
bool cached_dis_u2_entry_quirk;
int refcnt_dp_usb;
enum dp_lane dp_state;
int orientation_gpio;
bool has_orientation_gpio;
};
#define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */
@ -3630,6 +3633,28 @@ static void dwc3_set_phy_speed_flags(struct dwc3_msm *mdwc)
}
}
static void dwc3_msm_orientation_gpio_init(struct dwc3_msm *mdwc)
{
struct device *dev = mdwc->dev;
int rc;
mdwc->orientation_gpio = of_get_gpio(dev->of_node, 0);
if (!gpio_is_valid(mdwc->orientation_gpio)) {
dev_err(dev, "Failed to get gpio\n");
return;
}
rc = devm_gpio_request_one(dev, mdwc->orientation_gpio,
GPIOF_IN, "dwc3-msm-orientation");
if (rc < 0) {
dev_err(dev, "Failed to request gpio\n");
mdwc->orientation_gpio = -EINVAL;
return;
}
mdwc->has_orientation_gpio = true;
}
static void dwc3_set_ssphy_orientation_flag(struct dwc3_msm *mdwc)
{
union extcon_property_value val;
@ -3641,9 +3666,9 @@ static void dwc3_set_ssphy_orientation_flag(struct dwc3_msm *mdwc)
if (mdwc->orientation_override) {
mdwc->ss_phy->flags |= mdwc->orientation_override;
} else if (usb_redriver_has_orientation(mdwc->redriver)) {
orientation = usb_redriver_get_orientation(mdwc->redriver);
if (orientation == ORIENTATION_CC1)
} else if (mdwc->has_orientation_gpio) {
orientation = gpio_get_value(mdwc->orientation_gpio);
if (orientation == 0)
mdwc->ss_phy->flags |= PHY_LANE_A;
else
mdwc->ss_phy->flags |= PHY_LANE_B;
@ -5720,6 +5745,8 @@ static int dwc3_msm_probe(struct platform_device *pdev)
goto err;
}
dwc3_msm_orientation_gpio_init(mdwc);
/* Get all clks and gdsc reference */
ret = dwc3_msm_get_clk_gdsc(mdwc);
if (ret) {

View File

@ -96,7 +96,6 @@ struct nb7vpq904m_redriver {
struct i2c_client *client;
struct regulator *vdd;
int orientation_gpio;
int typec_orientation;
enum operation_mode op_mode;
@ -466,17 +465,6 @@ static int nb7vpq904m_read_configuration(struct nb7vpq904m_redriver *redriver)
return ret;
}
static int nb7vpq904m_get_orientation(struct usb_redriver *r)
{
struct nb7vpq904m_redriver *redriver =
container_of(r, struct nb7vpq904m_redriver, r);
dev_dbg(redriver->dev, "%s: mode %s\n", __func__,
OPMODESTR(redriver->op_mode));
return gpio_get_value(redriver->orientation_gpio);
}
static inline void orientation_set(struct nb7vpq904m_redriver *redriver, int ort)
{
redriver->typec_orientation = ort;
@ -647,28 +635,6 @@ static int nb7vpq904m_host_powercycle(struct usb_redriver *r)
return 0;
}
static void nb7vpq904m_orientation_gpio_init(
struct nb7vpq904m_redriver *redriver)
{
struct device *dev = redriver->dev;
int rc;
redriver->orientation_gpio = of_get_gpio(dev->of_node, 0);
if (!gpio_is_valid(redriver->orientation_gpio)) {
dev_err(dev, "Failed to get gpio\n");
return;
}
rc = devm_gpio_request_one(dev, redriver->orientation_gpio, GPIOF_IN, "redriver");
if (rc < 0) {
dev_err(dev, "Failed to request gpio\n");
redriver->orientation_gpio = -EINVAL;
return;
}
redriver->r.has_orientation = true;
}
static const struct regmap_config redriver_regmap = {
.max_register = REDRIVER_REG_MAX,
.reg_bits = 8,
@ -738,15 +704,12 @@ static int nb7vpq904m_probe(struct i2c_client *client,
*/
nb7vpq904m_vdd_enable(redriver, false);
nb7vpq904m_orientation_gpio_init(redriver);
nb7vpq904m_debugfs_entries(redriver);
redriver->r.of_node = redriver->dev->of_node;
redriver->r.release_usb_lanes = nb7vpq904m_release_usb_lanes;
redriver->r.notify_connect = nb7vpq904m_notify_connect;
redriver->r.notify_disconnect = nb7vpq904m_notify_disconnect;
redriver->r.get_orientation = nb7vpq904m_get_orientation;
redriver->r.gadget_pullup_enter = nb7vpq904m_gadget_pullup_enter;
redriver->r.gadget_pullup_exit = nb7vpq904m_gadget_pullup_exit;
redriver->r.host_powercycle = nb7vpq904m_host_powercycle;
@ -1007,19 +970,6 @@ static const struct file_operations loss_match_ops = {
.write = loss_match_write,
};
static int orientation_gpio_read(void *data, u64 *val)
{
struct nb7vpq904m_redriver *redriver = data;
*val = nb7vpq904m_get_orientation(&redriver->r);
dev_dbg(redriver->dev, "orientation %llu\n", *val);
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(orientation_gpio_ops,
orientation_gpio_read, NULL, "%llu\n");
static void nb7vpq904m_debugfs_entries(
struct nb7vpq904m_redriver *redriver)
{
@ -1041,9 +991,6 @@ static void nb7vpq904m_debugfs_entries(
debugfs_create_file("loss_match", 0600,
redriver->debug_root, redriver, &loss_match_ops);
debugfs_create_file("orientation-gpio", 0444,
redriver->debug_root, redriver, &orientation_gpio_ops);
debugfs_create_bool("lane-channel-swap", 0644,
redriver->debug_root, &redriver->lane_channel_swap);
}

View File

@ -24,8 +24,7 @@ int usb_add_redriver(struct usb_redriver *redriver)
{
struct usb_redriver *iter;
if (!redriver->of_node || redriver->bounded ||
(redriver->has_orientation && !redriver->get_orientation))
if (!redriver->of_node || redriver->bounded)
return -EINVAL;
spin_lock(&usb_rediver_lock);
@ -168,15 +167,6 @@ void usb_redriver_notify_disconnect(struct usb_redriver *ur)
}
EXPORT_SYMBOL(usb_redriver_notify_disconnect);
int usb_redriver_get_orientation(struct usb_redriver *ur)
{
if (ur && ur->has_orientation)
return ur->get_orientation(ur);
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(usb_redriver_get_orientation);
void usb_redriver_gadget_pullup_enter(struct usb_redriver *ur,
int is_on)
{

View File

@ -40,12 +40,10 @@
* @release_usb_lanes: put redriver into 2/4 lanes display mode
* @notify_connect: cable connect
* @notify_disconnect: cable disconnect
* @get_orientation: report orientation to user if orientation source shared
* @gadget_pullup_enter: operation when enter gadget pullup function
* @gadget_pullup_exit: operation when exit gadget pullup function
* @host_powercycle: workaround for host otg case
* @unbind, change to default state when user unbind it
* @has_orientation, provide orientation from chip driver or not
* @bounded, bound to user or not
*/
struct usb_redriver {
@ -55,13 +53,11 @@ struct usb_redriver {
int (*release_usb_lanes)(struct usb_redriver *ur, int ort, int num);
int (*notify_connect)(struct usb_redriver *ur, int ort);
int (*notify_disconnect)(struct usb_redriver *ur);
int (*get_orientation)(struct usb_redriver *ur);
int (*gadget_pullup_enter)(struct usb_redriver *ur, int is_on);
int (*gadget_pullup_exit)(struct usb_redriver *ur, int is_on);
int (*host_powercycle)(struct usb_redriver *ur);
void (*unbind)(struct usb_redriver *ur);
bool has_orientation;
bool bounded;
};
@ -76,7 +72,6 @@ void usb_put_redriver(struct usb_redriver *ur);
void usb_redriver_release_lanes(struct usb_redriver *ur, int ort, int num);
void usb_redriver_notify_connect(struct usb_redriver *ur, int ort);
void usb_redriver_notify_disconnect(struct usb_redriver *ur);
int usb_redriver_get_orientation(struct usb_redriver *ur);
void usb_redriver_gadget_pullup_enter(struct usb_redriver *ur, int is_on);
void usb_redriver_gadget_pullup_exit(struct usb_redriver *ur, int is_on);
void usb_redriver_host_powercycle(struct usb_redriver *ur);
@ -100,11 +95,6 @@ static inline int usb_remove_redriver(struct usb_redriver *ur)
return 0;
}
static inline int usb_redriver_get_orientation(struct usb_redriver *ur)
{
return -EOPNOTSUPP;
}
#define usb_put_redriver(ur) do {} while (0)
#define usb_redriver_release_lanes(ur, ort, num) do {} while (0)
@ -116,12 +106,4 @@ static inline int usb_redriver_get_orientation(struct usb_redriver *ur)
#endif
static inline bool usb_redriver_has_orientation(struct usb_redriver *ur)
{
if (ur && ur->has_orientation)
return true;
return false;
}
#endif /*__LINUX_USB_REDRIVER_H */