1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for Intel PMC USB mux control
5 * Copyright (C) 2020 Intel Corporation
6 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
9 #include <linux/acpi.h>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/property.h>
13 #include <linux/usb/pd.h>
14 #include <linux/usb/role.h>
15 #include <linux/usb/typec_mux.h>
16 #include <linux/usb/typec_dp.h>
17 #include <linux/usb/typec_tbt.h>
18 #include <linux/debugfs.h>
19 #include <linux/usb.h>
21 #include <asm/intel_scu_ipc.h>
23 #define PMC_USBC_CMD 0xa7
25 /* Response status bits */
26 #define PMC_USB_RESP_STATUS_FAILURE BIT(0)
27 #define PMC_USB_RESP_STATUS_FATAL BIT(1)
29 /* "Usage" OOB Message field values */
38 #define PMC_USB_MSG_USB2_PORT_SHIFT 0
39 #define PMC_USB_MSG_USB3_PORT_SHIFT 4
40 #define PMC_USB_MSG_UFP_SHIFT 4
41 #define PMC_USB_MSG_ORI_HSL_SHIFT 5
42 #define PMC_USB_MSG_ORI_AUX_SHIFT 6
44 /* Alt Mode Request */
53 #define PMC_USB_MODE_TYPE_SHIFT 4
56 PMC_USB_MODE_TYPE_USB
,
58 PMC_USB_MODE_TYPE_TBT
,
61 /* Common Mode Data bits */
62 #define PMC_USB_ALTMODE_RETIMER_CABLE BIT(2)
64 #define PMC_USB_ALTMODE_ORI_SHIFT 1
65 #define PMC_USB_ALTMODE_UFP_SHIFT 3
67 /* DP specific Mode Data bits */
68 #define PMC_USB_ALTMODE_DP_MODE_SHIFT 8
70 /* TBT specific Mode Data bits */
71 #define PMC_USB_ALTMODE_TBT_TYPE BIT(17)
72 #define PMC_USB_ALTMODE_CABLE_TYPE BIT(18)
73 #define PMC_USB_ALTMODE_ACTIVE_LINK BIT(20)
74 #define PMC_USB_ALTMODE_ACTIVE_CABLE BIT(22)
75 #define PMC_USB_ALTMODE_FORCE_LSR BIT(23)
76 #define PMC_USB_ALTMODE_CABLE_SPD(_s_) (((_s_) & GENMASK(2, 0)) << 25)
77 #define PMC_USB_ALTMODE_CABLE_USB31 1
78 #define PMC_USB_ALTMODE_CABLE_10GPS 2
79 #define PMC_USB_ALTMODE_CABLE_20GPS 3
80 #define PMC_USB_ALTMODE_TBT_GEN(_g_) (((_g_) & GENMASK(1, 0)) << 28)
82 /* Display HPD Request bits */
83 #define PMC_USB_DP_HPD_LVL BIT(4)
84 #define PMC_USB_DP_HPD_IRQ BIT(5)
87 * Input Output Manager (IOM) PORT STATUS
89 #define IOM_PORT_STATUS_ACTIVITY_TYPE_MASK GENMASK(9, 6)
90 #define IOM_PORT_STATUS_ACTIVITY_TYPE_SHIFT 6
91 #define IOM_PORT_STATUS_ACTIVITY_TYPE_USB 0x03
92 /* activity type: Safe Mode */
93 #define IOM_PORT_STATUS_ACTIVITY_TYPE_SAFE_MODE 0x04
94 /* activity type: Display Port */
95 #define IOM_PORT_STATUS_ACTIVITY_TYPE_DP 0x05
96 /* activity type: Display Port Multi Function Device */
97 #define IOM_PORT_STATUS_ACTIVITY_TYPE_DP_MFD 0x06
98 /* activity type: Thunderbolt */
99 #define IOM_PORT_STATUS_ACTIVITY_TYPE_TBT 0x07
100 #define IOM_PORT_STATUS_ACTIVITY_TYPE_ALT_MODE_USB 0x0c
101 #define IOM_PORT_STATUS_ACTIVITY_TYPE_ALT_MODE_TBT_USB 0x0d
102 /* Upstream Facing Port Information */
103 #define IOM_PORT_STATUS_UFP BIT(10)
104 /* Display Port Hot Plug Detect status */
105 #define IOM_PORT_STATUS_DHPD_HPD_STATUS_MASK GENMASK(13, 12)
106 #define IOM_PORT_STATUS_DHPD_HPD_STATUS_SHIFT 12
107 #define IOM_PORT_STATUS_DHPD_HPD_STATUS_ASSERT 0x01
108 #define IOM_PORT_STATUS_DHPD_HPD_SOURCE_TBT BIT(14)
109 #define IOM_PORT_STATUS_CONNECTED BIT(31)
111 #define IOM_PORT_ACTIVITY_IS(_status_, _type_) \
112 ((((_status_) & IOM_PORT_STATUS_ACTIVITY_TYPE_MASK) >> \
113 IOM_PORT_STATUS_ACTIVITY_TYPE_SHIFT) == \
114 (IOM_PORT_STATUS_ACTIVITY_TYPE_##_type_))
116 #define IOM_PORT_HPD_ASSERTED(_status_) \
117 ((((_status_) & IOM_PORT_STATUS_DHPD_HPD_STATUS_MASK) >> \
118 IOM_PORT_STATUS_DHPD_HPD_STATUS_SHIFT) & \
119 IOM_PORT_STATUS_DHPD_HPD_STATUS_ASSERT)
121 /* IOM port status register */
122 #define IOM_PORT_STATUS_REGS(_offset_, _size_) ((_offset_) | (_size_))
123 #define IOM_PORT_STATUS_REGS_SZ_MASK BIT(0)
124 #define IOM_PORT_STATUS_REGS_SZ_4 0
125 #define IOM_PORT_STATUS_REGS_SZ_8 1
126 #define IOM_PORT_STATUS_REGS_OFFSET(_d_) \
127 ((_d_) & ~IOM_PORT_STATUS_REGS_SZ_MASK)
128 #define IOM_PORT_STATUS_REGS_SIZE(_d_) \
129 (4 << ((_d_) & IOM_PORT_STATUS_REGS_SZ_MASK))
133 struct pmc_usb_port
{
137 struct typec_mux_dev
*typec_mux
;
138 struct typec_switch_dev
*typec_sw
;
139 struct usb_role_switch
*usb_sw
;
141 enum typec_orientation orientation
;
147 enum typec_orientation sbu_orientation
;
148 enum typec_orientation hsl_orientation
;
154 struct intel_scu_ipc_dev
*ipc
;
155 struct pmc_usb_port
*port
;
156 struct acpi_device
*iom_adev
;
157 void __iomem
*iom_base
;
158 u32 iom_port_status_offset
;
159 u8 iom_port_status_size
;
161 struct dentry
*dentry
;
164 static struct dentry
*pmc_mux_debugfs_root
;
166 static void update_port_status(struct pmc_usb_port
*port
)
170 /* SoC expects the USB Type-C port numbers to start with 0 */
171 port_num
= port
->usb3_port
- 1;
173 port
->iom_status
= readl(port
->pmc
->iom_base
+
174 port
->pmc
->iom_port_status_offset
+
175 port_num
* port
->pmc
->iom_port_status_size
);
178 static int sbu_orientation(struct pmc_usb_port
*port
)
180 if (port
->sbu_orientation
)
181 return port
->sbu_orientation
- 1;
183 return port
->orientation
- 1;
186 static int hsl_orientation(struct pmc_usb_port
*port
)
188 if (port
->hsl_orientation
)
189 return port
->hsl_orientation
- 1;
191 return port
->orientation
- 1;
194 static bool is_pmc_mux_tbt(struct acpi_device
*adev
)
196 return acpi_dev_hid_uid_match(adev
, "INTC1072", NULL
) ||
197 acpi_dev_hid_uid_match(adev
, "INTC1079", NULL
);
200 static int pmc_usb_send_command(struct intel_scu_ipc_dev
*ipc
, u8
*msg
, u32 len
)
207 * Error bit will always be 0 with the USBC command.
208 * Status can be checked from the response message if the
209 * function intel_scu_ipc_dev_command succeeds.
211 ret
= intel_scu_ipc_dev_command(ipc
, PMC_USBC_CMD
, 0, msg
,
212 len
, response
, sizeof(response
));
217 status_res
= (msg
[0] & 0xf) < PMC_USB_SAFE_MODE
?
218 response
[2] : response
[1];
220 if (status_res
& PMC_USB_RESP_STATUS_FAILURE
) {
221 if (status_res
& PMC_USB_RESP_STATUS_FATAL
)
230 static int pmc_usb_command(struct pmc_usb_port
*port
, u8
*msg
, u32 len
)
236 * If PMC is busy then retry the command once again
238 while (retry_count
--) {
239 ret
= pmc_usb_send_command(port
->pmc
->ipc
, msg
, len
);
248 pmc_usb_mux_dp_hpd(struct pmc_usb_port
*port
, struct typec_displayport_data
*dp
)
253 msg
[0] = PMC_USB_DP_HPD
;
254 msg
[0] |= port
->usb3_port
<< PMC_USB_MSG_USB3_PORT_SHIFT
;
256 /* Configure HPD first if HPD,IRQ comes together */
257 if (!IOM_PORT_HPD_ASSERTED(port
->iom_status
) &&
258 dp
->status
& DP_STATUS_IRQ_HPD
&&
259 dp
->status
& DP_STATUS_HPD_STATE
) {
260 msg
[1] = PMC_USB_DP_HPD_LVL
;
261 ret
= pmc_usb_command(port
, msg
, sizeof(msg
));
266 if (dp
->status
& DP_STATUS_IRQ_HPD
)
267 msg
[1] = PMC_USB_DP_HPD_IRQ
;
269 if (dp
->status
& DP_STATUS_HPD_STATE
)
270 msg
[1] |= PMC_USB_DP_HPD_LVL
;
272 return pmc_usb_command(port
, msg
, sizeof(msg
));
276 pmc_usb_mux_dp(struct pmc_usb_port
*port
, struct typec_mux_state
*state
)
278 struct typec_displayport_data
*data
= state
->data
;
279 struct altmode_req req
= { };
282 if (IOM_PORT_ACTIVITY_IS(port
->iom_status
, DP
) ||
283 IOM_PORT_ACTIVITY_IS(port
->iom_status
, DP_MFD
)) {
284 if (IOM_PORT_HPD_ASSERTED(port
->iom_status
) &&
285 (!(data
->status
& DP_STATUS_IRQ_HPD
) &&
286 data
->status
& DP_STATUS_HPD_STATE
))
289 return pmc_usb_mux_dp_hpd(port
, state
->data
);
292 req
.usage
= PMC_USB_ALT_MODE
;
293 req
.usage
|= port
->usb3_port
<< PMC_USB_MSG_USB3_PORT_SHIFT
;
294 req
.mode_type
= PMC_USB_MODE_TYPE_DP
<< PMC_USB_MODE_TYPE_SHIFT
;
296 req
.mode_data
= (port
->orientation
- 1) << PMC_USB_ALTMODE_ORI_SHIFT
;
297 req
.mode_data
|= (port
->role
- 1) << PMC_USB_ALTMODE_UFP_SHIFT
;
299 req
.mode_data
|= (state
->mode
- TYPEC_STATE_MODAL
) <<
300 PMC_USB_ALTMODE_DP_MODE_SHIFT
;
302 if (!is_pmc_mux_tbt(port
->pmc
->iom_adev
)) {
303 u8 cable_speed
= (data
->conf
& DP_CONF_SIGNALLING_MASK
) >>
304 DP_CONF_SIGNALLING_SHIFT
;
306 u8 cable_type
= (data
->conf
& DP_CONF_CABLE_TYPE_MASK
) >>
307 DP_CONF_CABLE_TYPE_SHIFT
;
309 req
.mode_data
|= PMC_USB_ALTMODE_CABLE_SPD(cable_speed
);
311 if (cable_type
== DP_CONF_CABLE_TYPE_OPTICAL
)
312 req
.mode_data
|= PMC_USB_ALTMODE_CABLE_TYPE
;
313 else if (cable_type
== DP_CONF_CABLE_TYPE_RE_TIMER
)
314 req
.mode_data
|= PMC_USB_ALTMODE_ACTIVE_CABLE
|
315 PMC_USB_ALTMODE_RETIMER_CABLE
;
316 else if (cable_type
== DP_CONF_CABLE_TYPE_RE_DRIVER
)
317 req
.mode_data
|= PMC_USB_ALTMODE_ACTIVE_CABLE
;
320 ret
= pmc_usb_command(port
, (void *)&req
, sizeof(req
));
324 if (data
->status
& (DP_STATUS_IRQ_HPD
| DP_STATUS_HPD_STATE
))
325 return pmc_usb_mux_dp_hpd(port
, state
->data
);
331 pmc_usb_mux_tbt(struct pmc_usb_port
*port
, struct typec_mux_state
*state
)
333 struct typec_thunderbolt_data
*data
= state
->data
;
334 u8 cable_rounded
= TBT_CABLE_ROUNDED_SUPPORT(data
->cable_mode
);
335 u8 cable_speed
= TBT_CABLE_SPEED(data
->cable_mode
);
336 struct altmode_req req
= { };
338 if (IOM_PORT_ACTIVITY_IS(port
->iom_status
, TBT
) ||
339 IOM_PORT_ACTIVITY_IS(port
->iom_status
, ALT_MODE_TBT_USB
))
342 req
.usage
= PMC_USB_ALT_MODE
;
343 req
.usage
|= port
->usb3_port
<< PMC_USB_MSG_USB3_PORT_SHIFT
;
344 req
.mode_type
= PMC_USB_MODE_TYPE_TBT
<< PMC_USB_MODE_TYPE_SHIFT
;
346 req
.mode_data
= (port
->orientation
- 1) << PMC_USB_ALTMODE_ORI_SHIFT
;
347 req
.mode_data
|= (port
->role
- 1) << PMC_USB_ALTMODE_UFP_SHIFT
;
349 if (TBT_ADAPTER(data
->device_mode
) == TBT_ADAPTER_TBT3
)
350 req
.mode_data
|= PMC_USB_ALTMODE_TBT_TYPE
;
352 if (data
->cable_mode
& TBT_CABLE_OPTICAL
)
353 req
.mode_data
|= PMC_USB_ALTMODE_CABLE_TYPE
;
355 if (data
->cable_mode
& TBT_CABLE_LINK_TRAINING
)
356 req
.mode_data
|= PMC_USB_ALTMODE_ACTIVE_LINK
;
358 if (acpi_dev_hid_uid_match(port
->pmc
->iom_adev
, "INTC1072", NULL
) ||
359 acpi_dev_hid_uid_match(port
->pmc
->iom_adev
, "INTC1079", NULL
)) {
360 if ((data
->enter_vdo
& TBT_ENTER_MODE_ACTIVE_CABLE
) ||
361 (data
->cable_mode
& TBT_CABLE_RETIMER
))
362 req
.mode_data
|= PMC_USB_ALTMODE_RETIMER_CABLE
;
364 if (data
->enter_vdo
& TBT_ENTER_MODE_ACTIVE_CABLE
)
365 req
.mode_data
|= PMC_USB_ALTMODE_ACTIVE_CABLE
;
367 if (data
->cable_mode
& TBT_CABLE_RETIMER
)
368 req
.mode_data
|= PMC_USB_ALTMODE_RETIMER_CABLE
;
371 req
.mode_data
|= PMC_USB_ALTMODE_CABLE_SPD(cable_speed
);
373 req
.mode_data
|= PMC_USB_ALTMODE_TBT_GEN(cable_rounded
);
375 return pmc_usb_command(port
, (void *)&req
, sizeof(req
));
379 pmc_usb_mux_usb4(struct pmc_usb_port
*port
, struct typec_mux_state
*state
)
381 struct enter_usb_data
*data
= state
->data
;
382 struct altmode_req req
= { };
385 if (IOM_PORT_ACTIVITY_IS(port
->iom_status
, TBT
) ||
386 IOM_PORT_ACTIVITY_IS(port
->iom_status
, ALT_MODE_TBT_USB
))
389 req
.usage
= PMC_USB_ALT_MODE
;
390 req
.usage
|= port
->usb3_port
<< PMC_USB_MSG_USB3_PORT_SHIFT
;
391 req
.mode_type
= PMC_USB_MODE_TYPE_TBT
<< PMC_USB_MODE_TYPE_SHIFT
;
394 req
.mode_data
= PMC_USB_ALTMODE_FORCE_LSR
;
396 if (data
->active_link_training
)
397 req
.mode_data
|= PMC_USB_ALTMODE_ACTIVE_LINK
;
399 req
.mode_data
|= (port
->orientation
- 1) << PMC_USB_ALTMODE_ORI_SHIFT
;
400 req
.mode_data
|= (port
->role
- 1) << PMC_USB_ALTMODE_UFP_SHIFT
;
402 switch ((data
->eudo
& EUDO_CABLE_TYPE_MASK
) >> EUDO_CABLE_TYPE_SHIFT
) {
403 case EUDO_CABLE_TYPE_PASSIVE
:
405 case EUDO_CABLE_TYPE_OPTICAL
:
406 req
.mode_data
|= PMC_USB_ALTMODE_CABLE_TYPE
;
408 case EUDO_CABLE_TYPE_RE_TIMER
:
409 if (!acpi_dev_hid_uid_match(port
->pmc
->iom_adev
, "INTC1072", NULL
) ||
410 !acpi_dev_hid_uid_match(port
->pmc
->iom_adev
, "INTC1079", NULL
))
411 req
.mode_data
|= PMC_USB_ALTMODE_RETIMER_CABLE
;
414 if (acpi_dev_hid_uid_match(port
->pmc
->iom_adev
, "INTC1072", NULL
) ||
415 acpi_dev_hid_uid_match(port
->pmc
->iom_adev
, "INTC1079", NULL
))
416 req
.mode_data
|= PMC_USB_ALTMODE_RETIMER_CABLE
;
418 req
.mode_data
|= PMC_USB_ALTMODE_ACTIVE_CABLE
;
420 /* Configure data rate to rounded in the case of Active TBT3
423 req
.mode_data
|= PMC_USB_ALTMODE_TBT_GEN(1);
427 cable_speed
= (data
->eudo
& EUDO_CABLE_SPEED_MASK
) >> EUDO_CABLE_SPEED_SHIFT
;
428 req
.mode_data
|= PMC_USB_ALTMODE_CABLE_SPD(cable_speed
);
430 return pmc_usb_command(port
, (void *)&req
, sizeof(req
));
433 static int pmc_usb_mux_safe_state(struct pmc_usb_port
*port
,
434 struct typec_mux_state
*state
)
438 if (IOM_PORT_ACTIVITY_IS(port
->iom_status
, SAFE_MODE
))
441 if ((IOM_PORT_ACTIVITY_IS(port
->iom_status
, DP
) ||
442 IOM_PORT_ACTIVITY_IS(port
->iom_status
, DP_MFD
)) &&
443 state
->alt
&& state
->alt
->svid
== USB_TYPEC_DP_SID
)
446 if ((IOM_PORT_ACTIVITY_IS(port
->iom_status
, TBT
) ||
447 IOM_PORT_ACTIVITY_IS(port
->iom_status
, ALT_MODE_TBT_USB
)) &&
448 state
->alt
&& state
->alt
->svid
== USB_TYPEC_TBT_SID
)
451 msg
= PMC_USB_SAFE_MODE
;
452 msg
|= port
->usb3_port
<< PMC_USB_MSG_USB3_PORT_SHIFT
;
454 return pmc_usb_command(port
, &msg
, sizeof(msg
));
457 static int pmc_usb_disconnect(struct pmc_usb_port
*port
)
459 struct typec_displayport_data data
= { };
462 if (!(port
->iom_status
& IOM_PORT_STATUS_CONNECTED
))
465 /* Clear DisplayPort HPD if it's still asserted. */
466 if (IOM_PORT_HPD_ASSERTED(port
->iom_status
))
467 pmc_usb_mux_dp_hpd(port
, &data
);
469 msg
[0] = PMC_USB_DISCONNECT
;
470 msg
[0] |= port
->usb3_port
<< PMC_USB_MSG_USB3_PORT_SHIFT
;
472 msg
[1] = port
->usb2_port
<< PMC_USB_MSG_USB2_PORT_SHIFT
;
474 return pmc_usb_command(port
, msg
, sizeof(msg
));
477 static int pmc_usb_connect(struct pmc_usb_port
*port
, enum usb_role role
)
479 u8 ufp
= role
== USB_ROLE_DEVICE
? 1 : 0;
483 if (port
->orientation
== TYPEC_ORIENTATION_NONE
)
486 if (port
->iom_status
& IOM_PORT_STATUS_CONNECTED
) {
487 if (port
->role
== role
|| port
->role
== USB_ROLE_NONE
)
491 ret
= pmc_usb_disconnect(port
);
496 msg
[0] = PMC_USB_CONNECT
;
497 msg
[0] |= port
->usb3_port
<< PMC_USB_MSG_USB3_PORT_SHIFT
;
499 msg
[1] = port
->usb2_port
<< PMC_USB_MSG_USB2_PORT_SHIFT
;
500 msg
[1] |= ufp
<< PMC_USB_MSG_UFP_SHIFT
;
501 msg
[1] |= hsl_orientation(port
) << PMC_USB_MSG_ORI_HSL_SHIFT
;
502 msg
[1] |= sbu_orientation(port
) << PMC_USB_MSG_ORI_AUX_SHIFT
;
504 return pmc_usb_command(port
, msg
, sizeof(msg
));
508 pmc_usb_mux_set(struct typec_mux_dev
*mux
, struct typec_mux_state
*state
)
510 struct pmc_usb_port
*port
= typec_mux_get_drvdata(mux
);
512 update_port_status(port
);
514 if (port
->orientation
== TYPEC_ORIENTATION_NONE
|| port
->role
== USB_ROLE_NONE
)
517 if (state
->mode
== TYPEC_STATE_SAFE
)
518 return pmc_usb_mux_safe_state(port
, state
);
519 if (state
->mode
== TYPEC_STATE_USB
)
520 return pmc_usb_connect(port
, port
->role
);
523 switch (state
->alt
->svid
) {
524 case USB_TYPEC_TBT_SID
:
525 return pmc_usb_mux_tbt(port
, state
);
526 case USB_TYPEC_DP_SID
:
527 return pmc_usb_mux_dp(port
, state
);
530 switch (state
->mode
) {
531 case TYPEC_MODE_USB2
:
532 /* REVISIT: Try with usb3_port set to 0? */
534 case TYPEC_MODE_USB3
:
535 return pmc_usb_connect(port
, port
->role
);
536 case TYPEC_MODE_USB4
:
537 return pmc_usb_mux_usb4(port
, state
);
544 static int pmc_usb_set_orientation(struct typec_switch_dev
*sw
,
545 enum typec_orientation orientation
)
547 struct pmc_usb_port
*port
= typec_switch_get_drvdata(sw
);
549 update_port_status(port
);
551 port
->orientation
= orientation
;
556 static int pmc_usb_set_role(struct usb_role_switch
*sw
, enum usb_role role
)
558 struct pmc_usb_port
*port
= usb_role_switch_get_drvdata(sw
);
561 update_port_status(port
);
563 if (role
== USB_ROLE_NONE
)
564 ret
= pmc_usb_disconnect(port
);
566 ret
= pmc_usb_connect(port
, role
);
573 static int pmc_usb_register_port(struct pmc_usb
*pmc
, int index
,
574 struct fwnode_handle
*fwnode
)
576 struct pmc_usb_port
*port
= &pmc
->port
[index
];
577 struct usb_role_switch_desc desc
= { };
578 struct typec_switch_desc sw_desc
= { };
579 struct typec_mux_desc mux_desc
= { };
583 ret
= fwnode_property_read_u8(fwnode
, "usb2-port-number", &port
->usb2_port
);
587 ret
= fwnode_property_read_u8(fwnode
, "usb3-port-number", &port
->usb3_port
);
591 ret
= fwnode_property_read_string(fwnode
, "sbu-orientation", &str
);
593 port
->sbu_orientation
= typec_find_orientation(str
);
595 ret
= fwnode_property_read_string(fwnode
, "hsl-orientation", &str
);
597 port
->hsl_orientation
= typec_find_orientation(str
);
602 sw_desc
.fwnode
= fwnode
;
603 sw_desc
.drvdata
= port
;
604 sw_desc
.name
= fwnode_get_name(fwnode
);
605 sw_desc
.set
= pmc_usb_set_orientation
;
607 port
->typec_sw
= typec_switch_register(pmc
->dev
, &sw_desc
);
608 if (IS_ERR(port
->typec_sw
))
609 return PTR_ERR(port
->typec_sw
);
611 mux_desc
.fwnode
= fwnode
;
612 mux_desc
.drvdata
= port
;
613 mux_desc
.name
= fwnode_get_name(fwnode
);
614 mux_desc
.set
= pmc_usb_mux_set
;
616 port
->typec_mux
= typec_mux_register(pmc
->dev
, &mux_desc
);
617 if (IS_ERR(port
->typec_mux
)) {
618 ret
= PTR_ERR(port
->typec_mux
);
619 goto err_unregister_switch
;
622 desc
.fwnode
= fwnode
;
623 desc
.driver_data
= port
;
624 desc
.name
= fwnode_get_name(fwnode
);
625 desc
.set
= pmc_usb_set_role
;
626 desc
.allow_userspace_control
= true;
628 port
->usb_sw
= usb_role_switch_register(pmc
->dev
, &desc
);
629 if (IS_ERR(port
->usb_sw
)) {
630 ret
= PTR_ERR(port
->usb_sw
);
631 goto err_unregister_mux
;
637 typec_mux_unregister(port
->typec_mux
);
639 err_unregister_switch
:
640 typec_switch_unregister(port
->typec_sw
);
645 /* IOM ACPI IDs and IOM_PORT_STATUS_OFFSET */
646 static const struct acpi_device_id iom_acpi_ids
[] = {
648 { "INTC1072", IOM_PORT_STATUS_REGS(0x560, IOM_PORT_STATUS_REGS_SZ_4
) },
651 { "INTC1079", IOM_PORT_STATUS_REGS(0x160, IOM_PORT_STATUS_REGS_SZ_4
) },
654 { "INTC107A", IOM_PORT_STATUS_REGS(0x160, IOM_PORT_STATUS_REGS_SZ_4
) },
657 { "INTC10EA", IOM_PORT_STATUS_REGS(0x150, IOM_PORT_STATUS_REGS_SZ_8
) },
661 static int pmc_usb_probe_iom(struct pmc_usb
*pmc
)
663 struct list_head resource_list
;
664 struct resource_entry
*rentry
;
665 static const struct acpi_device_id
*dev_id
;
666 struct acpi_device
*adev
= NULL
;
669 for (dev_id
= &iom_acpi_ids
[0]; dev_id
->id
[0]; dev_id
++) {
670 adev
= acpi_dev_get_first_match_dev(dev_id
->id
, NULL
, -1);
677 pmc
->iom_port_status_offset
= IOM_PORT_STATUS_REGS_OFFSET(dev_id
->driver_data
);
678 pmc
->iom_port_status_size
= IOM_PORT_STATUS_REGS_SIZE(dev_id
->driver_data
);
680 INIT_LIST_HEAD(&resource_list
);
681 ret
= acpi_dev_get_memory_resources(adev
, &resource_list
);
687 rentry
= list_first_entry_or_null(&resource_list
, struct resource_entry
, node
);
689 pmc
->iom_base
= devm_ioremap_resource(pmc
->dev
, rentry
->res
);
691 acpi_dev_free_resource_list(&resource_list
);
693 if (!pmc
->iom_base
) {
698 if (IS_ERR(pmc
->iom_base
)) {
700 return PTR_ERR(pmc
->iom_base
);
703 pmc
->iom_adev
= adev
;
708 static int port_iom_status_show(struct seq_file
*s
, void *unused
)
710 struct pmc_usb_port
*port
= s
->private;
712 update_port_status(port
);
713 seq_printf(s
, "0x%08x\n", port
->iom_status
);
717 DEFINE_SHOW_ATTRIBUTE(port_iom_status
);
719 static void pmc_mux_port_debugfs_init(struct pmc_usb_port
*port
)
721 struct dentry
*debugfs_dir
;
724 snprintf(name
, sizeof(name
), "port%d", port
->usb3_port
- 1);
726 debugfs_dir
= debugfs_create_dir(name
, port
->pmc
->dentry
);
727 debugfs_create_file("iom_status", 0400, debugfs_dir
, port
,
728 &port_iom_status_fops
);
731 static int pmc_usb_probe(struct platform_device
*pdev
)
733 struct fwnode_handle
*fwnode
= NULL
;
738 pmc
= devm_kzalloc(&pdev
->dev
, sizeof(*pmc
), GFP_KERNEL
);
742 device_for_each_child_node(&pdev
->dev
, fwnode
)
745 /* The IOM microcontroller has a limitation of max 4 ports. */
746 if (pmc
->num_ports
> 4) {
747 dev_err(&pdev
->dev
, "driver limited to 4 ports\n");
751 pmc
->port
= devm_kcalloc(&pdev
->dev
, pmc
->num_ports
,
752 sizeof(struct pmc_usb_port
), GFP_KERNEL
);
756 pmc
->ipc
= devm_intel_scu_ipc_dev_get(&pdev
->dev
);
760 pmc
->dev
= &pdev
->dev
;
762 ret
= pmc_usb_probe_iom(pmc
);
766 pmc
->dentry
= debugfs_create_dir(dev_name(pmc
->dev
), pmc_mux_debugfs_root
);
769 * For every physical USB connector (USB2 and USB3 combo) there is a
770 * child ACPI device node under the PMC mux ACPI device object.
772 for (i
= 0; i
< pmc
->num_ports
; i
++) {
773 fwnode
= device_get_next_child_node(pmc
->dev
, fwnode
);
777 ret
= pmc_usb_register_port(pmc
, i
, fwnode
);
779 fwnode_handle_put(fwnode
);
780 goto err_remove_ports
;
783 pmc_mux_port_debugfs_init(&pmc
->port
[i
]);
786 platform_set_drvdata(pdev
, pmc
);
791 for (i
= 0; i
< pmc
->num_ports
; i
++) {
792 typec_switch_unregister(pmc
->port
[i
].typec_sw
);
793 typec_mux_unregister(pmc
->port
[i
].typec_mux
);
794 usb_role_switch_unregister(pmc
->port
[i
].usb_sw
);
797 acpi_dev_put(pmc
->iom_adev
);
799 debugfs_remove(pmc
->dentry
);
804 static void pmc_usb_remove(struct platform_device
*pdev
)
806 struct pmc_usb
*pmc
= platform_get_drvdata(pdev
);
809 for (i
= 0; i
< pmc
->num_ports
; i
++) {
810 typec_switch_unregister(pmc
->port
[i
].typec_sw
);
811 typec_mux_unregister(pmc
->port
[i
].typec_mux
);
812 usb_role_switch_unregister(pmc
->port
[i
].usb_sw
);
815 acpi_dev_put(pmc
->iom_adev
);
817 debugfs_remove(pmc
->dentry
);
820 static const struct acpi_device_id pmc_usb_acpi_ids
[] = {
824 MODULE_DEVICE_TABLE(acpi
, pmc_usb_acpi_ids
);
826 static struct platform_driver pmc_usb_driver
= {
828 .name
= "intel_pmc_usb",
829 .acpi_match_table
= ACPI_PTR(pmc_usb_acpi_ids
),
831 .probe
= pmc_usb_probe
,
832 .remove_new
= pmc_usb_remove
,
835 static int __init
pmc_usb_init(void)
837 pmc_mux_debugfs_root
= debugfs_create_dir("intel_pmc_mux", usb_debug_root
);
839 return platform_driver_register(&pmc_usb_driver
);
841 module_init(pmc_usb_init
);
843 static void __exit
pmc_usb_exit(void)
845 platform_driver_unregister(&pmc_usb_driver
);
846 debugfs_remove(pmc_mux_debugfs_root
);
848 module_exit(pmc_usb_exit
);
850 MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>");
851 MODULE_LICENSE("GPL v2");
852 MODULE_DESCRIPTION("Intel PMC USB mux control");