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
222226static 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
12731287cd321x_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