mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 13:49:24 -04:00
usb: misc: nb7vpq904m: allow USB control connect and disconnect
add redriver_notify_connect() and redriver_notify_disconnect(). Change-Id: I48b2198df2a2257b13946fd8fcd7517f51073d45 Signed-off-by: Linyu Yuan <linyyuan@codeaurora.org>
This commit is contained in:
parent
aa860b5b17
commit
1362aa149f
2 changed files with 113 additions and 7 deletions
|
|
@ -99,6 +99,7 @@ struct ssusb_redriver {
|
|||
u8 flat_gain[CHAN_MODE_NUM][CHANNEL_NUM];
|
||||
|
||||
u8 gen_dev_val;
|
||||
int ucsi_i2c_write_err;
|
||||
|
||||
struct dentry *debug_root;
|
||||
};
|
||||
|
|
@ -132,7 +133,7 @@ static int redriver_i2c_reg_set(struct ssusb_redriver *redriver,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ssusb_redriver_gen_dev_set(struct ssusb_redriver *redriver)
|
||||
static int ssusb_redriver_gen_dev_set(struct ssusb_redriver *redriver)
|
||||
{
|
||||
u8 val = 0;
|
||||
|
||||
|
|
@ -192,7 +193,7 @@ static void ssusb_redriver_gen_dev_set(struct ssusb_redriver *redriver)
|
|||
|
||||
redriver->gen_dev_val = val;
|
||||
|
||||
redriver_i2c_reg_set(redriver, GEN_DEV_SET_REG, val);
|
||||
return redriver_i2c_reg_set(redriver, GEN_DEV_SET_REG, val);
|
||||
}
|
||||
|
||||
static int ssusb_redriver_param_config(struct ssusb_redriver *redriver,
|
||||
|
|
@ -352,7 +353,7 @@ static int ssusb_redriver_channel_update(struct ssusb_redriver *redriver)
|
|||
return 0;
|
||||
|
||||
err:
|
||||
dev_err(redriver->dev, "channel parameters update failure.\n");
|
||||
dev_err(redriver->dev, "channel parameters update failure(%d).\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -458,6 +459,7 @@ static int ssusb_redriver_ucsi_notifier(struct notifier_block *nb,
|
|||
container_of(nb, struct ssusb_redriver, ucsi_nb);
|
||||
struct ucsi_glink_constat_info *info = data;
|
||||
enum operation_mode op_mode;
|
||||
int ret;
|
||||
|
||||
if (info->connect && !info->partner_change)
|
||||
return NOTIFY_DONE;
|
||||
|
|
@ -501,25 +503,115 @@ static int ssusb_redriver_ucsi_notifier(struct notifier_block *nb,
|
|||
"CC1" : "CC2");
|
||||
}
|
||||
|
||||
ssusb_redriver_channel_update(redriver);
|
||||
ret = ssusb_redriver_channel_update(redriver);
|
||||
if (ret) {
|
||||
dev_dbg(redriver->dev, "i2c bus may not resume(%d)\n", ret);
|
||||
redriver->ucsi_i2c_write_err = ret;
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
ssusb_redriver_gen_dev_set(redriver);
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
int redriver_notify_connect(struct device_node *node)
|
||||
{
|
||||
struct ssusb_redriver *redriver;
|
||||
struct i2c_client *client;
|
||||
|
||||
if (!node)
|
||||
return -ENODEV;
|
||||
|
||||
client = of_find_i2c_device_by_node(node);
|
||||
if (!client)
|
||||
return -ENODEV;
|
||||
|
||||
redriver = i2c_get_clientdata(client);
|
||||
if (!redriver)
|
||||
return -EINVAL;
|
||||
|
||||
/* 1. no operation in recovery mode.
|
||||
* 2. needed when usb related mode set.
|
||||
* 3. currently ucsi notification arrive to redriver earlier than usb,
|
||||
* in ucsi notification callback, save mode even i2c write failed,
|
||||
* but add ucsi_i2c_write_err to indicate i2c write error,
|
||||
* this allow usb trigger i2c write again by check it.
|
||||
* !!! if future remove ucsi, ucsi_i2c_write_err can be removed,
|
||||
* and this function also need update !!!.
|
||||
*/
|
||||
if ((redriver->op_mode == OP_MODE_DEFAULT) ||
|
||||
((redriver->op_mode != OP_MODE_USB) &&
|
||||
(redriver->op_mode != OP_MODE_USB_AND_DP)) ||
|
||||
(!redriver->ucsi_i2c_write_err))
|
||||
return 0;
|
||||
|
||||
dev_dbg(redriver->dev, "op mode %s\n",
|
||||
OPMODESTR(redriver->op_mode));
|
||||
|
||||
/* !!! assume i2c resume complete here !!! */
|
||||
ssusb_redriver_channel_update(redriver);
|
||||
ssusb_redriver_gen_dev_set(redriver);
|
||||
|
||||
redriver->ucsi_i2c_write_err = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(redriver_notify_connect);
|
||||
|
||||
int redriver_notify_disconnect(struct device_node *node)
|
||||
{
|
||||
struct ssusb_redriver *redriver;
|
||||
struct i2c_client *client;
|
||||
|
||||
if (!node)
|
||||
return -ENODEV;
|
||||
|
||||
client = of_find_i2c_device_by_node(node);
|
||||
if (!client)
|
||||
return -ENODEV;
|
||||
|
||||
redriver = i2c_get_clientdata(client);
|
||||
if (!redriver)
|
||||
return -EINVAL;
|
||||
|
||||
/* 1. no operation in recovery mode.
|
||||
* 2. there is case for 4 lane display, first report usb mode,
|
||||
* second call usb release super speed lanes,
|
||||
* then stop usb host and call this disconnect,
|
||||
* it should not disable chip.
|
||||
* 3. if already disabled, no need to disable again.
|
||||
*/
|
||||
if ((redriver->op_mode == OP_MODE_DEFAULT) ||
|
||||
(redriver->op_mode == OP_MODE_DP) ||
|
||||
(redriver->op_mode == OP_MODE_NONE))
|
||||
return 0;
|
||||
|
||||
dev_dbg(redriver->dev, "op mode %s -> %s\n",
|
||||
OPMODESTR(redriver->op_mode), OPMODESTR(OP_MODE_NONE));
|
||||
|
||||
redriver->op_mode = OP_MODE_NONE;
|
||||
|
||||
ssusb_redriver_gen_dev_set(redriver);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(redriver_notify_disconnect);
|
||||
|
||||
int redriver_release_usb_lanes(struct device_node *node)
|
||||
{
|
||||
struct ssusb_redriver *redriver;
|
||||
struct i2c_client *client;
|
||||
|
||||
if (!node)
|
||||
return -EINVAL;
|
||||
return -ENODEV;
|
||||
|
||||
client = of_find_i2c_device_by_node(node);
|
||||
if (!client)
|
||||
return -EINVAL;
|
||||
return -ENODEV;
|
||||
|
||||
redriver = i2c_get_clientdata(client);
|
||||
if (!redriver)
|
||||
return -EINVAL;
|
||||
|
||||
if (redriver->op_mode == OP_MODE_DP)
|
||||
return 0;
|
||||
|
|
@ -542,13 +634,15 @@ int redriver_gadget_pullup(struct device_node *node, int is_on)
|
|||
u8 val;
|
||||
|
||||
if (!node)
|
||||
return -EINVAL;
|
||||
return -ENODEV;
|
||||
|
||||
client = of_find_i2c_device_by_node(node);
|
||||
if (!client)
|
||||
return -EINVAL;
|
||||
return -ENODEV;
|
||||
|
||||
redriver = i2c_get_clientdata(client);
|
||||
if (!redriver)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* when redriver connect to a USB hub, and do adb root operation,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
int redriver_release_usb_lanes(struct device_node *node);
|
||||
int redriver_gadget_pullup(struct device_node *node, int is_on);
|
||||
int redriver_notify_connect(struct device_node *node);
|
||||
int redriver_notify_disconnect(struct device_node *node);
|
||||
|
||||
#else
|
||||
|
||||
|
|
@ -23,6 +25,16 @@ static inline int redriver_gadget_pullup(struct device_node *node, int is_on)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int redriver_notify_connect(struct device_node *node)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int redriver_notify_disconnect(struct device_node *node)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /*__LINUX_USB_REDRIVER_H */
|
||||
|
|
|
|||
Loading…
Reference in a new issue