Skip to content

Commit d9b201c

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 881fca1 commit d9b201c

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))
@@ -837,6 +848,9 @@ static void cd321x_update_work(struct work_struct *work)
837848
/* Launch the USB role switch */
838849
usb_role_switch_set_role(tps->role_sw, new_role);
839850

851+
if (cd321x->connector_fwnode && dp_hpd)
852+
drm_connector_oob_hotplug_event(cd321x->connector_fwnode, connector_status_connected);
853+
840854
power_supply_changed(tps->psy);
841855
}
842856

@@ -1271,6 +1285,7 @@ static int
12711285
cd321x_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode)
12721286
{
12731287
struct cd321x *cd321x = container_of(tps, struct cd321x, tps);
1288+
struct fwnode_handle *connector_fwnode = NULL;
12741289
int ret;
12751290

12761291
INIT_DELAYED_WORK(&cd321x->update_work, cd321x_update_work);
@@ -1289,6 +1304,11 @@ cd321x_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode)
12891304
goto err_unregister_altmodes;
12901305
}
12911306

1307+
if (fwnode_property_present(fwnode, "displayport"))
1308+
connector_fwnode = fwnode_find_reference(fwnode, "displayport", 0);
1309+
if (!IS_ERR_OR_NULL(connector_fwnode))
1310+
cd321x->connector_fwnode = connector_fwnode;
1311+
12921312
cd321x->state.alt = NULL;
12931313
cd321x->state.mode = TYPEC_STATE_SAFE;
12941314
cd321x->state.data = NULL;

0 commit comments

Comments
 (0)