Skip to content

Commit 02113c7

Browse files
committed
usb: typec: tipd: HACK: Use drm oob hotplug event
This is not how dp-altmode support should be implemented but it works for new. Requires a "displayport" property in the connector node with a phandle of the connector. Signed-off-by: Janne Grunau <j@jannau.net>
1 parent 44289ee commit 02113c7

1 file changed

Lines changed: 20 additions & 0 deletions

File tree

drivers/usb/typec/tipd/core.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
77
*/
88

9+
#include <drm/drm_connector.h>
10+
911
#include <linux/i2c.h>
1012
#include <linux/acpi.h>
1113
#include <linux/gpio/consumer.h>
@@ -225,6 +227,8 @@ struct cd321x {
225227
struct cd321x_status update_status;
226228
struct delayed_work update_work;
227229
struct usb_pd_identity cur_partner_identity;
230+
231+
struct fwnode_handle *connector_fwnode;
228232
};
229233

230234
static enum power_supply_property tps6598x_psy_props[] = {
@@ -763,6 +767,9 @@ static void cd321x_update_work(struct work_struct *work)
763767
bool usb_connection = st.data_status &
764768
(TPS_DATA_STATUS_USB2_CONNECTION | TPS_DATA_STATUS_USB3_CONNECTION);
765769

770+
bool dp_hpd = st.data_status & CD321X_DATA_STATUS_HPD_LEVEL;
771+
bool dp_hpd_changed = st.data_status_changed & CD321X_DATA_STATUS_HPD_LEVEL;
772+
766773
enum usb_role old_role = usb_role_switch_get_role(tps->role_sw);
767774
enum usb_role new_role = USB_ROLE_NONE;
768775
enum typec_pwr_opmode pwr_opmode = TYPEC_PWR_MODE_USB;
@@ -791,6 +798,10 @@ static void cd321x_update_work(struct work_struct *work)
791798
if (old_role != USB_ROLE_NONE && (new_role != old_role || was_disconnected))
792799
usb_role_switch_set_role(tps->role_sw, USB_ROLE_NONE);
793800

801+
if (cd321x->connector_fwnode && (!dp_hpd || dp_hpd_changed)) {
802+
drm_connector_oob_hotplug_event(cd321x->connector_fwnode, connector_status_disconnected);
803+
}
804+
794805
/* Process partner disconnection or change */
795806
if (!new_connected || partner_changed) {
796807
if (!IS_ERR(tps->partner))
@@ -845,6 +856,9 @@ static void cd321x_update_work(struct work_struct *work)
845856
/* Launch the USB role switch */
846857
usb_role_switch_set_role(tps->role_sw, new_role);
847858

859+
if (cd321x->connector_fwnode && dp_hpd)
860+
drm_connector_oob_hotplug_event(cd321x->connector_fwnode, connector_status_connected);
861+
848862
power_supply_changed(tps->psy);
849863
}
850864

@@ -1281,6 +1295,7 @@ static int
12811295
cd321x_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode)
12821296
{
12831297
struct cd321x *cd321x = container_of(tps, struct cd321x, tps);
1298+
struct fwnode_handle *connector_fwnode = NULL;
12841299
int ret;
12851300

12861301
INIT_DELAYED_WORK(&cd321x->update_work, cd321x_update_work);
@@ -1299,6 +1314,11 @@ cd321x_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode)
12991314
goto err_unregister_altmodes;
13001315
}
13011316

1317+
if (fwnode_property_present(fwnode, "displayport"))
1318+
connector_fwnode = fwnode_find_reference(fwnode, "displayport", 0);
1319+
if (!IS_ERR_OR_NULL(connector_fwnode))
1320+
cd321x->connector_fwnode = connector_fwnode;
1321+
13021322
cd321x->state.alt = NULL;
13031323
cd321x->state.mode = TYPEC_STATE_SAFE;
13041324
cd321x->state.data = NULL;

0 commit comments

Comments
 (0)