Skip to content

Commit 5691e0b

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 5f2a3f1 commit 5691e0b

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>
@@ -217,6 +219,8 @@ struct cd321x {
217219
struct cd321x_status update_status;
218220
struct delayed_work update_work;
219221
struct usb_pd_identity cur_partner_identity;
222+
223+
struct fwnode_handle *connector_fwnode;
220224
};
221225

222226
static enum power_supply_property tps6598x_psy_props[] = {
@@ -755,6 +759,9 @@ static void cd321x_update_work(struct work_struct *work)
755759
bool usb_connection = st.data_status &
756760
(TPS_DATA_STATUS_USB2_CONNECTION | TPS_DATA_STATUS_USB3_CONNECTION);
757761

762+
bool dp_hpd = st.data_status & CD321X_DATA_STATUS_HPD_LEVEL;
763+
bool dp_hpd_changed = st.data_status_changed & CD321X_DATA_STATUS_HPD_LEVEL;
764+
758765
enum usb_role old_role = usb_role_switch_get_role(tps->role_sw);
759766
enum usb_role new_role = USB_ROLE_NONE;
760767
enum typec_pwr_opmode pwr_opmode = TYPEC_PWR_MODE_USB;
@@ -783,6 +790,10 @@ static void cd321x_update_work(struct work_struct *work)
783790
if (old_role != USB_ROLE_NONE && (new_role != old_role || was_disconnected))
784791
usb_role_switch_set_role(tps->role_sw, USB_ROLE_NONE);
785792

793+
if (cd321x->connector_fwnode && (!dp_hpd || dp_hpd_changed)) {
794+
drm_connector_oob_hotplug_event(cd321x->connector_fwnode, connector_status_disconnected);
795+
}
796+
786797
/* Process partner disconnection or change */
787798
if (!new_connected || partner_changed) {
788799
if (!IS_ERR(tps->partner))
@@ -839,6 +850,9 @@ static void cd321x_update_work(struct work_struct *work)
839850
/* Launch the USB role switch */
840851
usb_role_switch_set_role(tps->role_sw, new_role);
841852

853+
if (cd321x->connector_fwnode && dp_hpd)
854+
drm_connector_oob_hotplug_event(cd321x->connector_fwnode, connector_status_connected);
855+
842856
power_supply_changed(tps->psy);
843857
}
844858

@@ -1273,6 +1287,7 @@ static int
12731287
cd321x_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode)
12741288
{
12751289
struct cd321x *cd321x = container_of(tps, struct cd321x, tps);
1290+
struct fwnode_handle *connector_fwnode = NULL;
12761291
int ret;
12771292

12781293
INIT_DELAYED_WORK(&cd321x->update_work, cd321x_update_work);
@@ -1291,6 +1306,11 @@ cd321x_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode)
12911306
goto err_unregister_altmodes;
12921307
}
12931308

1309+
if (fwnode_property_present(fwnode, "displayport"))
1310+
connector_fwnode = fwnode_find_reference(fwnode, "displayport", 0);
1311+
if (!IS_ERR_OR_NULL(connector_fwnode))
1312+
cd321x->connector_fwnode = connector_fwnode;
1313+
12941314
cd321x->state.alt = NULL;
12951315
cd321x->state.mode = TYPEC_STATE_SAFE;
12961316
cd321x->state.data = NULL;

0 commit comments

Comments
 (0)