Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef2c2342 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/dp: configure AUX switch on connect/disconnect"

parents c9668918 cf4733b0
Loading
Loading
Loading
Loading
+53 −2
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@

#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__

#include <linux/soc/qcom/fsa4480-i2c.h>
#include <linux/usb/usbpd.h>
#include <linux/delay.h>

#include "dp_aux.h"
@@ -29,6 +31,7 @@ struct dp_aux_private {
	struct dp_aux dp_aux;
	struct dp_catalog_aux *catalog;
	struct dp_aux_cfg *cfg;
	struct device_node *aux_switch_node;
	struct mutex mutex;
	struct completion comp;
	struct drm_dp_aux drm_aux;
@@ -703,14 +706,60 @@ static void dp_aux_set_sim_mode(struct dp_aux *dp_aux, bool en,
		aux->drm_aux.transfer = dp_aux_transfer;
}

static int dp_aux_configure_aux_switch(struct dp_aux *dp_aux,
		bool enable, int orientation)
{
	struct dp_aux_private *aux;
	int rc = 0;
	enum fsa_function event = FSA_USBC_DISPLAYPORT_DISCONNECTED;

	if (!dp_aux) {
		pr_err("invalid input\n");
		rc = -EINVAL;
		goto end;
	}

	aux = container_of(dp_aux, struct dp_aux_private, dp_aux);

	if (!aux->aux_switch_node) {
		pr_debug("undefined fsa4480 handle\n");
		rc = -EINVAL;
		goto end;
	}

	if (enable) {
		switch (orientation) {
		case ORIENTATION_CC1:
			event = FSA_USBC_ORIENTATION_CC1;
			break;
		case ORIENTATION_CC2:
			event = FSA_USBC_ORIENTATION_CC2;
			break;
		default:
			pr_err("invalid orientation\n");
			rc = -EINVAL;
			goto end;
		}
	}

	pr_debug("enable=%d, orientation=%d, event=%d\n",
			enable, orientation, event);

	rc = fsa4480_switch_event(aux->aux_switch_node, event);
	if (rc)
		pr_err("failed to configure fsa4480 i2c device (%d)\n", rc);
end:
	return rc;
}

struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
		struct dp_aux_cfg *aux_cfg)
		struct dp_aux_cfg *aux_cfg, struct device_node *aux_switch)
{
	int rc = 0;
	struct dp_aux_private *aux;
	struct dp_aux *dp_aux;

	if (!catalog || !aux_cfg) {
	if (!catalog || !aux_cfg || !aux_switch) {
		pr_err("invalid input\n");
		rc = -ENODEV;
		goto error;
@@ -729,6 +778,7 @@ struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
	aux->dev = dev;
	aux->catalog = catalog;
	aux->cfg = aux_cfg;
	aux->aux_switch_node = aux_switch;
	dp_aux = &aux->dp_aux;
	aux->retry_cnt = 0;
	aux->dp_aux.reg = 0xFFFF;
@@ -742,6 +792,7 @@ struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
	dp_aux->abort = dp_aux_abort_transaction;
	dp_aux->dpcd_updated = dp_aux_dpcd_updated;
	dp_aux->set_sim_mode = dp_aux_set_sim_mode;
	dp_aux->aux_switch = dp_aux_configure_aux_switch;

	return dp_aux;
error:
+2 −1
Original line number Diff line number Diff line
@@ -55,10 +55,11 @@ struct dp_aux {
	void (*abort)(struct dp_aux *aux);
	void (*dpcd_updated)(struct dp_aux *aux);
	void (*set_sim_mode)(struct dp_aux *aux, bool en, u8 *edid, u8 *dpcd);
	int (*aux_switch)(struct dp_aux *aux, bool enable, int orientation);
};

struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
		struct dp_aux_cfg *aux_cfg);
		struct dp_aux_cfg *aux_cfg, struct device_node *aux_switch);
void dp_aux_put(struct dp_aux *aux);

#endif /*__DP_AUX_H_*/
+9 −3
Original line number Diff line number Diff line
@@ -262,7 +262,10 @@ static ssize_t dp_debug_write_hpd(struct file *file,
	struct dp_debug_private *debug = file->private_data;
	char buf[SZ_8];
	size_t len = 0;
	int hpd;
	int const orientation_mask = 0x4;
	int const hpd_data_mask = 0x7;
	int hpd = 0;
	int orientation = 0;

	if (!debug)
		return -ENODEV;
@@ -280,11 +283,14 @@ static ssize_t dp_debug_write_hpd(struct file *file,
	if (kstrtoint(buf, 10, &hpd) != 0)
		goto end;

	hpd &= 0x3;
	hpd &= hpd_data_mask;
	orientation = hpd & orientation_mask ?
		ORIENTATION_CC2 : ORIENTATION_CC1;

	debug->dp_debug.psm_enabled = !!(hpd & BIT(1));

	debug->usbpd->simulate_connect(debug->usbpd, !!(hpd & BIT(0)));
	debug->usbpd->simulate_connect(debug->usbpd, !!(hpd & BIT(0)),
			orientation);
end:
	return len;
}
+11 −34
Original line number Diff line number Diff line
@@ -653,36 +653,6 @@ static int dp_display_process_hpd_low(struct dp_display_private *dp)
	return rc;
}

static int dp_display_configure_aux_switch(struct dp_display_private *dp)
{
	int rc = 0;
	enum fsa_function event = FSA_EVENT_MAX;

	if (!dp->aux_switch_node) {
		pr_debug("undefined fsa4480 handle\n");
		goto end;
	}

	switch (dp->usbpd->orientation) {
	case ORIENTATION_CC1:
		event = FSA_USBC_ORIENTATION_CC1;
		break;
	case ORIENTATION_CC2:
		event = FSA_USBC_ORIENTATION_CC2;
		break;
	default:
		pr_err("invalid orientation\n");
		rc = -EINVAL;
		goto end;
	}

	rc = fsa4480_switch_event(dp->aux_switch_node, event);
	if (rc)
		pr_err("failed to configure fsa4480 i2c device (%d)\n", rc);
end:
	return rc;
}

static int dp_display_usbpd_configure_cb(struct device *dev)
{
	int rc = 0;
@@ -701,9 +671,11 @@ static int dp_display_usbpd_configure_cb(struct device *dev)
		goto end;
	}

	rc = dp_display_configure_aux_switch(dp);
	if (!dp->debug->sim_mode) {
		rc = dp->aux->aux_switch(dp->aux, true, dp->usbpd->orientation);
		if (rc)
			goto end;
	}

	dp_display_host_init(dp);

@@ -792,6 +764,10 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev)
	flush_workqueue(dp->wq);

	dp_display_handle_disconnect(dp);

	if (!dp->debug->sim_mode)
		dp->aux->aux_switch(dp->aux, false, ORIENTATION_NONE);

	atomic_set(&dp->aborted, 0);
end:
	return rc;
@@ -1028,7 +1004,8 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
		goto error_aux;
	}

	dp->aux = dp_aux_get(dev, &dp->catalog->aux, dp->parser->aux_cfg);
	dp->aux = dp_aux_get(dev, &dp->catalog->aux, dp->parser->aux_cfg,
			dp->aux_switch_node);
	if (IS_ERR(dp->aux)) {
		rc = PTR_ERR(dp->aux);
		pr_err("failed to initialize aux, rc = %d\n", rc);
+6 −1
Original line number Diff line number Diff line
@@ -401,7 +401,8 @@ static void dp_usbpd_response_cb(struct usbpd_svid_handler *hdlr, u8 cmd,
	}
}

static int dp_usbpd_simulate_connect(struct dp_usbpd *dp_usbpd, bool hpd)
static int dp_usbpd_simulate_connect(struct dp_usbpd *dp_usbpd, bool hpd,
		int orientation)
{
	int rc = 0;
	struct dp_usbpd_private *pd;
@@ -416,7 +417,11 @@ static int dp_usbpd_simulate_connect(struct dp_usbpd *dp_usbpd, bool hpd)

	dp_usbpd->hpd_high = hpd;
	pd->forced_disconnect = !hpd;
	pd->dp_usbpd.orientation = orientation;

	pr_debug("hpd_high=%d, forced_disconnect=%d, orientation=%d\n",
			dp_usbpd->hpd_high, pd->forced_disconnect,
			pd->dp_usbpd.orientation);
	if (hpd)
		pd->dp_cb->configure(pd->dev);
	else
Loading