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 ))
@@ -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
12711285cd321x_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