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

Commit 9109f814 authored by Karthikeyan Mani's avatar Karthikeyan Mani Committed by Gerrit - the friendly Code Review server
Browse files

drivers: soc: qcom: notify drivers registering first time



Send usbc mode at register function so that all drivers
registering first time will get the notification of
current usb connection type, if any.

Change-Id: Ifac7af1ff546a17bc6f382246ae0aeec5194ca9f
Signed-off-by: default avatarKarthikeyan Mani <kmani@codeaurora.org>
parent 6a56d6a5
Loading
Loading
Loading
Loading
+52 −34
Original line number Original line Diff line number Diff line
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -15,6 +15,7 @@
#include <linux/power_supply.h>
#include <linux/power_supply.h>
#include <linux/regmap.h>
#include <linux/regmap.h>
#include <linux/i2c.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <linux/soc/qcom/fsa4480-i2c.h>
#include <linux/soc/qcom/fsa4480-i2c.h>


#define FSA4480_I2C_NAME	"fsa4480-driver"
#define FSA4480_I2C_NAME	"fsa4480-driver"
@@ -41,6 +42,7 @@ struct fsa4480_priv {
	atomic_t usbc_mode;
	atomic_t usbc_mode;
	struct work_struct usbc_analog_work;
	struct work_struct usbc_analog_work;
	struct blocking_notifier_head fsa4480_notifier;
	struct blocking_notifier_head fsa4480_notifier;
	struct mutex notification_lock;
};
};


struct fsa4480_reg_val {
struct fsa4480_reg_val {
@@ -132,6 +134,51 @@ static int fsa4480_usbc_event_changed(struct notifier_block *nb,
	return ret;
	return ret;
}
}


static int fsa4480_usbc_analog_setup_switches(struct fsa4480_priv *fsa_priv)
{
	int rc = 0;
	union power_supply_propval mode;
	struct device *dev;

	if (!fsa_priv)
		return -EINVAL;
	dev = fsa_priv->dev;
	if (!dev)
		return -EINVAL;

	mutex_lock(&fsa_priv->notification_lock);
	/* get latest mode again within locked context */
	rc = power_supply_get_property(fsa_priv->usb_psy,
			POWER_SUPPLY_PROP_TYPEC_MODE, &mode);
	if (rc) {
		dev_err(dev, "%s: Unable to read USB TYPEC_MODE: %d\n",
			__func__, rc);
		goto done;
	}
	dev_dbg(dev, "%s: setting GPIOs active = %d\n",
		__func__, mode.intval != POWER_SUPPLY_TYPEC_NONE);

	if (mode.intval != POWER_SUPPLY_TYPEC_NONE) {
		/* activate switches */
		fsa4480_usbc_update_settings(fsa_priv, 0x00, 0x9F);

		/* notify call chain on event */
		blocking_notifier_call_chain(&fsa_priv->fsa4480_notifier,
		POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER, NULL);
	} else {
		/* notify call chain on event */
		blocking_notifier_call_chain(&fsa_priv->fsa4480_notifier,
				POWER_SUPPLY_TYPEC_NONE, NULL);

		/* deactivate switches */
		fsa4480_usbc_update_settings(fsa_priv, 0x18, 0x98);
	}

done:
	mutex_unlock(&fsa_priv->notification_lock);
	return rc;
}

/*
/*
 * fsa4480_reg_notifier - register notifier block with fsa driver
 * fsa4480_reg_notifier - register notifier block with fsa driver
 *
 *
@@ -165,9 +212,7 @@ int fsa4480_reg_notifier(struct notifier_block *nb,
	 */
	 */
	dev_dbg(fsa_priv->dev, "%s: verify if USB adapter is already inserted\n",
	dev_dbg(fsa_priv->dev, "%s: verify if USB adapter is already inserted\n",
		__func__);
		__func__);
	rc = fsa4480_usbc_event_changed(&fsa_priv->psy_nb,
	rc = fsa4480_usbc_analog_setup_switches(fsa_priv);
					     PSY_EVENT_PROP_CHANGED,
					     fsa_priv->usb_psy);


	return rc;
	return rc;
}
}
@@ -194,7 +239,6 @@ int fsa4480_unreg_notifier(struct notifier_block *nb,
	if (!fsa_priv)
	if (!fsa_priv)
		return -EINVAL;
		return -EINVAL;


	atomic_set(&(fsa_priv->usbc_mode), 0);
	fsa4480_usbc_update_settings(fsa_priv, 0x18, 0x98);
	fsa4480_usbc_update_settings(fsa_priv, 0x18, 0x98);
	return blocking_notifier_chain_unregister
	return blocking_notifier_chain_unregister
					(&fsa_priv->fsa4480_notifier, nb);
					(&fsa_priv->fsa4480_notifier, nb);
@@ -266,33 +310,6 @@ int fsa4480_switch_event(struct device_node *node,
}
}
EXPORT_SYMBOL(fsa4480_switch_event);
EXPORT_SYMBOL(fsa4480_switch_event);


static int fsa4480_usbc_analog_setup_switches
			(struct fsa4480_priv *fsa_priv, bool active)
{
	int rc = 0;

	dev_dbg(fsa_priv->dev, "%s: setting GPIOs active = %d\n",
		__func__, active);

	if (active) {
		/* activate switches */
		fsa4480_usbc_update_settings(fsa_priv, 0x00, 0x9F);

		/* notify call chain on event */
		blocking_notifier_call_chain(&fsa_priv->fsa4480_notifier,
		POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER, NULL);
	} else {
		/* notify call chain on event */
		blocking_notifier_call_chain(&fsa_priv->fsa4480_notifier,
				POWER_SUPPLY_TYPEC_NONE, NULL);

		/* deactivate switches */
		fsa4480_usbc_update_settings(fsa_priv, 0x18, 0x98);
	}

	return rc;
}

static void fsa4480_usbc_analog_work_fn(struct work_struct *work)
static void fsa4480_usbc_analog_work_fn(struct work_struct *work)
{
{
	struct fsa4480_priv *fsa_priv =
	struct fsa4480_priv *fsa_priv =
@@ -302,8 +319,7 @@ static void fsa4480_usbc_analog_work_fn(struct work_struct *work)
		pr_err("%s: fsa container invalid\n", __func__);
		pr_err("%s: fsa container invalid\n", __func__);
		return;
		return;
	}
	}
	fsa4480_usbc_analog_setup_switches(fsa_priv,
	fsa4480_usbc_analog_setup_switches(fsa_priv);
		atomic_read(&(fsa_priv->usbc_mode)) != POWER_SUPPLY_TYPEC_NONE);
	pm_relax(fsa_priv->dev);
	pm_relax(fsa_priv->dev);
}
}


@@ -361,6 +377,7 @@ static int fsa4480_probe(struct i2c_client *i2c,
		goto err_supply;
		goto err_supply;
	}
	}


	mutex_init(&fsa_priv->notification_lock);
	i2c_set_clientdata(i2c, fsa_priv);
	i2c_set_clientdata(i2c, fsa_priv);


	INIT_WORK(&fsa_priv->usbc_analog_work,
	INIT_WORK(&fsa_priv->usbc_analog_work,
@@ -394,6 +411,7 @@ static int fsa4480_remove(struct i2c_client *i2c)
	/* deregister from PMI */
	/* deregister from PMI */
	power_supply_unreg_notifier(&fsa_priv->psy_nb);
	power_supply_unreg_notifier(&fsa_priv->psy_nb);
	power_supply_put(fsa_priv->usb_psy);
	power_supply_put(fsa_priv->usb_psy);
	mutex_destroy(&fsa_priv->notification_lock);
	dev_set_drvdata(&i2c->dev, NULL);
	dev_set_drvdata(&i2c->dev, NULL);


	return 0;
	return 0;