mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-01 18:52:02 +00:00
USB fixes for 5.18-rc7
Here are some small fixes for reported issues with some USB drivers. They include: - xhci fixes for xhci-mtk platform driver - typec driver fixes for reported problems. - cdc-wdm read-stuck fix - gadget driver fix for reported race condition - new usb-serial driver ids All of these have been in linux-next with no reported problems. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCYoENmA8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ymxrwCeIzUtnkEw80tyjr3r/ciuZgfqM90AoJ50aiIV YqYG8aVcUUrM47qQuYUX =I21N -----END PGP SIGNATURE----- Merge tag 'usb-5.18-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb Pull USB fixes from Greg KH: "Here are some small fixes for reported issues with some USB drivers. They include: - xhci fixes for xhci-mtk platform driver - typec driver fixes for reported problems. - cdc-wdm read-stuck fix - gadget driver fix for reported race condition - new usb-serial driver ids All of these have been in linux-next with no reported problems" * tag 'usb-5.18-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: usb: xhci-mtk: remove bandwidth budget table usb: xhci-mtk: fix fs isoc's transfer error usb: gadget: fix race when gadget driver register via ioctl usb: typec: tcpci_mt6360: Update for BMC PHY setting usb: gadget: uvc: allow for application to cleanly shutdown usb: typec: tcpci: Don't skip cleanup in .remove() on error usb: cdc-wdm: fix reading stuck on device close USB: serial: qcserial: add support for Sierra Wireless EM7590 USB: serial: option: add Fibocom MA510 modem USB: serial: option: add Fibocom L610 modem USB: serial: pl2303: add device id for HP LM930 Display
This commit is contained in:
commit
fc49583cdb
@ -774,6 +774,7 @@ static int wdm_release(struct inode *inode, struct file *file)
|
||||
poison_urbs(desc);
|
||||
spin_lock_irq(&desc->iuspin);
|
||||
desc->resp_count = 0;
|
||||
clear_bit(WDM_RESPONDING, &desc->flags);
|
||||
spin_unlock_irq(&desc->iuspin);
|
||||
desc->manage_power(desc->intf, 0);
|
||||
unpoison_urbs(desc);
|
||||
|
@ -890,13 +890,37 @@ static void uvc_function_unbind(struct usb_configuration *c,
|
||||
{
|
||||
struct usb_composite_dev *cdev = c->cdev;
|
||||
struct uvc_device *uvc = to_uvc(f);
|
||||
long wait_ret = 1;
|
||||
|
||||
uvcg_info(f, "%s()\n", __func__);
|
||||
|
||||
/* If we know we're connected via v4l2, then there should be a cleanup
|
||||
* of the device from userspace either via UVC_EVENT_DISCONNECT or
|
||||
* though the video device removal uevent. Allow some time for the
|
||||
* application to close out before things get deleted.
|
||||
*/
|
||||
if (uvc->func_connected) {
|
||||
uvcg_dbg(f, "waiting for clean disconnect\n");
|
||||
wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue,
|
||||
uvc->func_connected == false, msecs_to_jiffies(500));
|
||||
uvcg_dbg(f, "done waiting with ret: %ld\n", wait_ret);
|
||||
}
|
||||
|
||||
device_remove_file(&uvc->vdev.dev, &dev_attr_function_name);
|
||||
video_unregister_device(&uvc->vdev);
|
||||
v4l2_device_unregister(&uvc->v4l2_dev);
|
||||
|
||||
if (uvc->func_connected) {
|
||||
/* Wait for the release to occur to ensure there are no longer any
|
||||
* pending operations that may cause panics when resources are cleaned
|
||||
* up.
|
||||
*/
|
||||
uvcg_warn(f, "%s no clean disconnect, wait for release\n", __func__);
|
||||
wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue,
|
||||
uvc->func_connected == false, msecs_to_jiffies(1000));
|
||||
uvcg_dbg(f, "done waiting for release with ret: %ld\n", wait_ret);
|
||||
}
|
||||
|
||||
usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
|
||||
kfree(uvc->control_buf);
|
||||
|
||||
@ -915,6 +939,7 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi)
|
||||
|
||||
mutex_init(&uvc->video.mutex);
|
||||
uvc->state = UVC_STATE_DISCONNECTED;
|
||||
init_waitqueue_head(&uvc->func_connected_queue);
|
||||
opts = fi_to_f_uvc_opts(fi);
|
||||
|
||||
mutex_lock(&opts->lock);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/usb/composite.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-dev.h>
|
||||
@ -129,6 +130,7 @@ struct uvc_device {
|
||||
struct usb_function func;
|
||||
struct uvc_video video;
|
||||
bool func_connected;
|
||||
wait_queue_head_t func_connected_queue;
|
||||
|
||||
/* Descriptors */
|
||||
struct {
|
||||
|
@ -253,10 +253,11 @@ uvc_v4l2_subscribe_event(struct v4l2_fh *fh,
|
||||
|
||||
static void uvc_v4l2_disable(struct uvc_device *uvc)
|
||||
{
|
||||
uvc->func_connected = false;
|
||||
uvc_function_disconnect(uvc);
|
||||
uvcg_video_enable(&uvc->video, 0);
|
||||
uvcg_free_buffers(&uvc->video.queue);
|
||||
uvc->func_connected = false;
|
||||
wake_up_interruptible(&uvc->func_connected_queue);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -145,6 +145,7 @@ enum dev_state {
|
||||
STATE_DEV_INVALID = 0,
|
||||
STATE_DEV_OPENED,
|
||||
STATE_DEV_INITIALIZED,
|
||||
STATE_DEV_REGISTERING,
|
||||
STATE_DEV_RUNNING,
|
||||
STATE_DEV_CLOSED,
|
||||
STATE_DEV_FAILED
|
||||
@ -508,6 +509,7 @@ static int raw_ioctl_run(struct raw_dev *dev, unsigned long value)
|
||||
ret = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
dev->state = STATE_DEV_REGISTERING;
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
|
||||
ret = usb_gadget_probe_driver(&dev->driver);
|
||||
|
@ -19,11 +19,6 @@
|
||||
#define HS_BW_BOUNDARY 6144
|
||||
/* usb2 spec section11.18.1: at most 188 FS bytes per microframe */
|
||||
#define FS_PAYLOAD_MAX 188
|
||||
/*
|
||||
* max number of microframes for split transfer,
|
||||
* for fs isoc in : 1 ss + 1 idle + 7 cs
|
||||
*/
|
||||
#define TT_MICROFRAMES_MAX 9
|
||||
|
||||
#define DBG_BUF_EN 64
|
||||
|
||||
@ -242,28 +237,17 @@ static void drop_tt(struct usb_device *udev)
|
||||
|
||||
static struct mu3h_sch_ep_info *
|
||||
create_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx)
|
||||
struct usb_host_endpoint *ep)
|
||||
{
|
||||
struct mu3h_sch_ep_info *sch_ep;
|
||||
struct mu3h_sch_bw_info *bw_info;
|
||||
struct mu3h_sch_tt *tt = NULL;
|
||||
u32 len_bw_budget_table;
|
||||
|
||||
bw_info = get_bw_info(mtk, udev, ep);
|
||||
if (!bw_info)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
if (is_fs_or_ls(udev->speed))
|
||||
len_bw_budget_table = TT_MICROFRAMES_MAX;
|
||||
else if ((udev->speed >= USB_SPEED_SUPER)
|
||||
&& usb_endpoint_xfer_isoc(&ep->desc))
|
||||
len_bw_budget_table = get_esit(ep_ctx);
|
||||
else
|
||||
len_bw_budget_table = 1;
|
||||
|
||||
sch_ep = kzalloc(struct_size(sch_ep, bw_budget_table,
|
||||
len_bw_budget_table),
|
||||
GFP_KERNEL);
|
||||
sch_ep = kzalloc(sizeof(*sch_ep), GFP_KERNEL);
|
||||
if (!sch_ep)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -295,8 +279,6 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
|
||||
u32 mult;
|
||||
u32 esit_pkts;
|
||||
u32 max_esit_payload;
|
||||
u32 *bwb_table = sch_ep->bw_budget_table;
|
||||
int i;
|
||||
|
||||
ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2));
|
||||
maxpkt = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2));
|
||||
@ -332,7 +314,6 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
|
||||
*/
|
||||
sch_ep->pkts = max_burst + 1;
|
||||
sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts;
|
||||
bwb_table[0] = sch_ep->bw_cost_per_microframe;
|
||||
} else if (sch_ep->speed >= USB_SPEED_SUPER) {
|
||||
/* usb3_r1 spec section4.4.7 & 4.4.8 */
|
||||
sch_ep->cs_count = 0;
|
||||
@ -349,7 +330,6 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
|
||||
if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
|
||||
sch_ep->pkts = esit_pkts;
|
||||
sch_ep->num_budget_microframes = 1;
|
||||
bwb_table[0] = maxpkt * sch_ep->pkts;
|
||||
}
|
||||
|
||||
if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) {
|
||||
@ -366,15 +346,8 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
|
||||
DIV_ROUND_UP(esit_pkts, sch_ep->pkts);
|
||||
|
||||
sch_ep->repeat = !!(sch_ep->num_budget_microframes > 1);
|
||||
sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts;
|
||||
|
||||
for (i = 0; i < sch_ep->num_budget_microframes - 1; i++)
|
||||
bwb_table[i] = sch_ep->bw_cost_per_microframe;
|
||||
|
||||
/* last one <= bw_cost_per_microframe */
|
||||
bwb_table[i] = maxpkt * esit_pkts
|
||||
- i * sch_ep->bw_cost_per_microframe;
|
||||
}
|
||||
sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts;
|
||||
} else if (is_fs_or_ls(sch_ep->speed)) {
|
||||
sch_ep->pkts = 1; /* at most one packet for each microframe */
|
||||
|
||||
@ -384,28 +357,7 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
|
||||
*/
|
||||
sch_ep->cs_count = DIV_ROUND_UP(maxpkt, FS_PAYLOAD_MAX);
|
||||
sch_ep->num_budget_microframes = sch_ep->cs_count;
|
||||
sch_ep->bw_cost_per_microframe =
|
||||
(maxpkt < FS_PAYLOAD_MAX) ? maxpkt : FS_PAYLOAD_MAX;
|
||||
|
||||
/* init budget table */
|
||||
if (ep_type == ISOC_OUT_EP) {
|
||||
for (i = 0; i < sch_ep->num_budget_microframes; i++)
|
||||
bwb_table[i] = sch_ep->bw_cost_per_microframe;
|
||||
} else if (ep_type == INT_OUT_EP) {
|
||||
/* only first one consumes bandwidth, others as zero */
|
||||
bwb_table[0] = sch_ep->bw_cost_per_microframe;
|
||||
} else { /* INT_IN_EP or ISOC_IN_EP */
|
||||
bwb_table[0] = 0; /* start split */
|
||||
bwb_table[1] = 0; /* idle */
|
||||
/*
|
||||
* due to cs_count will be updated according to cs
|
||||
* position, assign all remainder budget array
|
||||
* elements as @bw_cost_per_microframe, but only first
|
||||
* @num_budget_microframes elements will be used later
|
||||
*/
|
||||
for (i = 2; i < TT_MICROFRAMES_MAX; i++)
|
||||
bwb_table[i] = sch_ep->bw_cost_per_microframe;
|
||||
}
|
||||
sch_ep->bw_cost_per_microframe = min_t(u32, maxpkt, FS_PAYLOAD_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
@ -422,7 +374,7 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
|
||||
|
||||
for (j = 0; j < sch_ep->num_budget_microframes; j++) {
|
||||
k = XHCI_MTK_BW_INDEX(base + j);
|
||||
bw = sch_bw->bus_bw[k] + sch_ep->bw_budget_table[j];
|
||||
bw = sch_bw->bus_bw[k] + sch_ep->bw_cost_per_microframe;
|
||||
if (bw > max_bw)
|
||||
max_bw = bw;
|
||||
}
|
||||
@ -433,18 +385,16 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
|
||||
static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
|
||||
struct mu3h_sch_ep_info *sch_ep, bool used)
|
||||
{
|
||||
int bw_updated;
|
||||
u32 base;
|
||||
int i, j, k;
|
||||
int i, j;
|
||||
|
||||
bw_updated = sch_ep->bw_cost_per_microframe * (used ? 1 : -1);
|
||||
|
||||
for (i = 0; i < sch_ep->num_esit; i++) {
|
||||
base = sch_ep->offset + i * sch_ep->esit;
|
||||
for (j = 0; j < sch_ep->num_budget_microframes; j++) {
|
||||
k = XHCI_MTK_BW_INDEX(base + j);
|
||||
if (used)
|
||||
sch_bw->bus_bw[k] += sch_ep->bw_budget_table[j];
|
||||
else
|
||||
sch_bw->bus_bw[k] -= sch_ep->bw_budget_table[j];
|
||||
}
|
||||
for (j = 0; j < sch_ep->num_budget_microframes; j++)
|
||||
sch_bw->bus_bw[XHCI_MTK_BW_INDEX(base + j)] += bw_updated;
|
||||
}
|
||||
}
|
||||
|
||||
@ -464,7 +414,7 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
|
||||
*/
|
||||
for (j = 0; j < sch_ep->num_budget_microframes; j++) {
|
||||
k = XHCI_MTK_BW_INDEX(base + j);
|
||||
tmp = tt->fs_bus_bw[k] + sch_ep->bw_budget_table[j];
|
||||
tmp = tt->fs_bus_bw[k] + sch_ep->bw_cost_per_microframe;
|
||||
if (tmp > FS_PAYLOAD_MAX)
|
||||
return -ESCH_BW_OVERFLOW;
|
||||
}
|
||||
@ -538,19 +488,17 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset)
|
||||
static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
|
||||
{
|
||||
struct mu3h_sch_tt *tt = sch_ep->sch_tt;
|
||||
int bw_updated;
|
||||
u32 base;
|
||||
int i, j, k;
|
||||
int i, j;
|
||||
|
||||
bw_updated = sch_ep->bw_cost_per_microframe * (used ? 1 : -1);
|
||||
|
||||
for (i = 0; i < sch_ep->num_esit; i++) {
|
||||
base = sch_ep->offset + i * sch_ep->esit;
|
||||
|
||||
for (j = 0; j < sch_ep->num_budget_microframes; j++) {
|
||||
k = XHCI_MTK_BW_INDEX(base + j);
|
||||
if (used)
|
||||
tt->fs_bus_bw[k] += sch_ep->bw_budget_table[j];
|
||||
else
|
||||
tt->fs_bus_bw[k] -= sch_ep->bw_budget_table[j];
|
||||
}
|
||||
for (j = 0; j < sch_ep->num_budget_microframes; j++)
|
||||
tt->fs_bus_bw[XHCI_MTK_BW_INDEX(base + j)] += bw_updated;
|
||||
}
|
||||
|
||||
if (used)
|
||||
@ -710,7 +658,7 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
|
||||
xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
|
||||
|
||||
sch_ep = create_sch_ep(mtk, udev, ep, ep_ctx);
|
||||
sch_ep = create_sch_ep(mtk, udev, ep);
|
||||
if (IS_ERR_OR_NULL(sch_ep))
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -83,7 +83,6 @@ struct mu3h_sch_bw_info {
|
||||
* times; 1: distribute the (bMaxBurst+1)*(Mult+1) packets
|
||||
* according to @pkts and @repeat. normal mode is used by
|
||||
* default
|
||||
* @bw_budget_table: table to record bandwidth budget per microframe
|
||||
*/
|
||||
struct mu3h_sch_ep_info {
|
||||
u32 esit;
|
||||
@ -109,7 +108,6 @@ struct mu3h_sch_ep_info {
|
||||
u32 pkts;
|
||||
u32 cs_count;
|
||||
u32 burst_mode;
|
||||
u32 bw_budget_table[];
|
||||
};
|
||||
|
||||
#define MU3C_U3_PORT_MAX 4
|
||||
|
@ -2123,10 +2123,14 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = RSVD(3) },
|
||||
{ USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */
|
||||
.driver_info = RSVD(4) | RSVD(5) | RSVD(6) },
|
||||
{ USB_DEVICE(0x1782, 0x4d10) }, /* Fibocom L610 (AT mode) */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x1782, 0x4d11, 0xff) }, /* Fibocom L610 (ECM/RNDIS mode) */
|
||||
{ USB_DEVICE(0x2cb7, 0x0104), /* Fibocom NL678 series */
|
||||
.driver_info = RSVD(4) | RSVD(5) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */
|
||||
.driver_info = RSVD(6) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0106, 0xff) }, /* Fibocom MA510 (ECM mode w/ diag intf.) */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x010a, 0xff) }, /* Fibocom MA510 (ECM mode) */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) }, /* Fibocom FG150 Diag */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) }, /* Fibocom FG150 AT */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */
|
||||
|
@ -106,6 +106,7 @@ static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) },
|
||||
{ USB_DEVICE(HP_VENDOR_ID, HP_LCM960_PRODUCT_ID) },
|
||||
{ USB_DEVICE(HP_VENDOR_ID, HP_LM920_PRODUCT_ID) },
|
||||
{ USB_DEVICE(HP_VENDOR_ID, HP_LM930_PRODUCT_ID) },
|
||||
{ USB_DEVICE(HP_VENDOR_ID, HP_LM940_PRODUCT_ID) },
|
||||
{ USB_DEVICE(HP_VENDOR_ID, HP_TD620_PRODUCT_ID) },
|
||||
{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
|
||||
|
@ -135,6 +135,7 @@
|
||||
#define HP_TD620_PRODUCT_ID 0x0956
|
||||
#define HP_LD960_PRODUCT_ID 0x0b39
|
||||
#define HP_LD381_PRODUCT_ID 0x0f7f
|
||||
#define HP_LM930_PRODUCT_ID 0x0f9b
|
||||
#define HP_LCM220_PRODUCT_ID 0x3139
|
||||
#define HP_LCM960_PRODUCT_ID 0x3239
|
||||
#define HP_LD220_PRODUCT_ID 0x3524
|
||||
|
@ -166,6 +166,8 @@ static const struct usb_device_id id_table[] = {
|
||||
{DEVICE_SWI(0x1199, 0x9090)}, /* Sierra Wireless EM7565 QDL */
|
||||
{DEVICE_SWI(0x1199, 0x9091)}, /* Sierra Wireless EM7565 */
|
||||
{DEVICE_SWI(0x1199, 0x90d2)}, /* Sierra Wireless EM9191 QDL */
|
||||
{DEVICE_SWI(0x1199, 0xc080)}, /* Sierra Wireless EM7590 QDL */
|
||||
{DEVICE_SWI(0x1199, 0xc081)}, /* Sierra Wireless EM7590 */
|
||||
{DEVICE_SWI(0x413c, 0x81a2)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */
|
||||
{DEVICE_SWI(0x413c, 0x81a3)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */
|
||||
{DEVICE_SWI(0x413c, 0x81a4)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
|
||||
|
@ -877,7 +877,7 @@ static int tcpci_remove(struct i2c_client *client)
|
||||
/* Disable chip interrupts before unregistering port */
|
||||
err = tcpci_write16(chip->tcpci, TCPC_ALERT_MASK, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
dev_warn(&client->dev, "Failed to disable irqs (%pe)\n", ERR_PTR(err));
|
||||
|
||||
tcpci_unregister_port(chip->tcpci);
|
||||
|
||||
|
@ -15,6 +15,9 @@
|
||||
|
||||
#include "tcpci.h"
|
||||
|
||||
#define MT6360_REG_PHYCTRL1 0x80
|
||||
#define MT6360_REG_PHYCTRL3 0x82
|
||||
#define MT6360_REG_PHYCTRL7 0x86
|
||||
#define MT6360_REG_VCONNCTRL1 0x8C
|
||||
#define MT6360_REG_MODECTRL2 0x8F
|
||||
#define MT6360_REG_SWRESET 0xA0
|
||||
@ -22,6 +25,8 @@
|
||||
#define MT6360_REG_DRPCTRL1 0xA2
|
||||
#define MT6360_REG_DRPCTRL2 0xA3
|
||||
#define MT6360_REG_I2CTORST 0xBF
|
||||
#define MT6360_REG_PHYCTRL11 0xCA
|
||||
#define MT6360_REG_RXCTRL1 0xCE
|
||||
#define MT6360_REG_RXCTRL2 0xCF
|
||||
#define MT6360_REG_CTDCTRL2 0xEC
|
||||
|
||||
@ -106,6 +111,27 @@ static int mt6360_tcpc_init(struct tcpci *tcpci, struct tcpci_data *tdata)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* BMC PHY */
|
||||
ret = mt6360_tcpc_write16(regmap, MT6360_REG_PHYCTRL1, 0x3A70);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_write(regmap, MT6360_REG_PHYCTRL3, 0x82);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_write(regmap, MT6360_REG_PHYCTRL7, 0x36);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mt6360_tcpc_write16(regmap, MT6360_REG_PHYCTRL11, 0x3C60);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_write(regmap, MT6360_REG_RXCTRL1, 0xE8);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set shipping mode off, AUTOIDLE on */
|
||||
return regmap_write(regmap, MT6360_REG_MODECTRL2, 0x7A);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user