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

Commit 0d0c1f1d authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: apq8084: add callback notifier for Liquid device"

parents 8c9f29c4 0a7ea40d
Loading
Loading
Loading
Loading
+74 −40
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <linux/pm_runtime.h>
#include <linux/slimbus/slimbus.h>
#include <soc/qcom/subsystem_notif.h>
#include <soc/qcom/apq8084_dock.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
@@ -411,6 +412,23 @@ static void apq8084_liquid_ext_spk_power_amp_enable(u32 on)
			on ? "Enable" : "Disable");
}

static void apq8084_liquid_route_aud_dock_dev(void)
{
	struct apq8084_liquid_dock_dev *dock_dev = apq8084_liquid_dock_dev;
	struct snd_soc_dapm_context *dapm = dock_dev->dapm;

	mutex_lock(&dapm->codec->mutex);

	/* Turn off external amp to turn off liquid spkr */
	if ((apq8084_ext_spk_pamp & LO_1_SPK_AMP) &&
		(apq8084_ext_spk_pamp & LO_3_SPK_AMP) &&
		(apq8084_ext_spk_pamp & LO_2_SPK_AMP) &&
		(apq8084_ext_spk_pamp & LO_4_SPK_AMP))
		apq8084_liquid_ext_spk_power_amp_enable(0);

	mutex_unlock(&dapm->codec->mutex);
}

static void apq8084_liquid_docking_irq_work(struct work_struct *work)
{
	struct apq8084_liquid_dock_dev *dock_dev =
@@ -446,66 +464,88 @@ static irqreturn_t apq8084_liquid_docking_irq_handler(int irq, void *dev)
	return IRQ_HANDLED;
}

static int apq8084_liquid_init_docking(struct snd_soc_dapm_context *dapm)
static int apq8084_liquid_dock_notify_handler(struct notifier_block *this,
					unsigned long dock_event,
					void *unused)
{
	int ret = 0;
	int dock_plug_gpio = 0;
	int err = 0;

	/* plug in docking speaker+plug in device OR unplug one of them */
	u32 dock_plug_irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
					IRQF_SHARED;
	dock_plug_gpio = of_get_named_gpio(spdev->dev.of_node,
					   "qcom,dock-plug-det-irq", 0);

	if (dock_plug_gpio >= 0) {
		apq8084_liquid_dock_dev =
		 kzalloc(sizeof(*apq8084_liquid_dock_dev), GFP_KERNEL);
		if (!apq8084_liquid_dock_dev) {
			pr_err("apq8084_liquid_dock_dev alloc fail.\n");
			ret = -ENOMEM;
			goto exit;
		}

		apq8084_liquid_dock_dev->dock_plug_gpio = dock_plug_gpio;

		ret = gpio_request(apq8084_liquid_dock_dev->dock_plug_gpio,
	if (dock_event) {
		err = gpio_request(apq8084_liquid_dock_dev->dock_plug_gpio,
					   "dock-plug-det-irq");
		if (ret) {
			pr_err("%s:failed request apq8084_liquid_dock_plug_gpio.\n",
				__func__);
			ret = -EINVAL;
			goto out;
		if (err) {
			pr_err("%s: fail request dock-plug-det-irq err = %d\n",
				__func__, err);
			goto exit;
		}

		apq8084_liquid_dock_dev->dock_plug_det =
			gpio_get_value(apq8084_liquid_dock_dev->dock_plug_gpio);
		if (apq8084_liquid_dock_dev->dock_plug_det)
			apq8084_liquid_route_aud_dock_dev();
		apq8084_liquid_dock_dev->dock_plug_irq =
			gpio_to_irq(apq8084_liquid_dock_dev->dock_plug_gpio);

		apq8084_liquid_dock_dev->dapm = dapm;

		ret = request_irq(apq8084_liquid_dock_dev->dock_plug_irq,
		err = request_irq(apq8084_liquid_dock_dev->dock_plug_irq,
				  apq8084_liquid_docking_irq_handler,
				  dock_plug_irq_flags,
				  "liquid_dock_plug_irq",
				  apq8084_liquid_dock_dev);
		if (ret < 0) {
		if (err < 0) {
			pr_err("%s: Request Irq Failed err = %d\n",
				__func__, ret);
			goto out2;
				__func__, err);
			goto out;
		}

		INIT_WORK(
			&apq8084_liquid_dock_dev->irq_work,
			apq8084_liquid_docking_irq_work);
	} else {
		if (apq8084_liquid_dock_dev->dock_plug_gpio)
			gpio_free(apq8084_liquid_dock_dev->dock_plug_gpio);

		if (apq8084_liquid_dock_dev->dock_plug_irq)
			free_irq(apq8084_liquid_dock_dev->dock_plug_irq,
				 apq8084_liquid_dock_dev);
	}
	return 0;
	return NOTIFY_OK;

out2:
	gpio_free(apq8084_liquid_dock_dev->dock_plug_gpio);
out:
	kfree(apq8084_liquid_dock_dev);
	apq8084_liquid_dock_dev = NULL;
	gpio_free(apq8084_liquid_dock_dev->dock_plug_gpio);
exit:
	return NOTIFY_DONE;
}

static struct notifier_block apq8084_liquid_docking_notifier = {
	.notifier_call  = apq8084_liquid_dock_notify_handler,
};

static int apq8084_liquid_init_docking(struct snd_soc_dapm_context *dapm)
{
	int ret = 0;
	int dock_plug_gpio = 0;

	dock_plug_gpio = of_get_named_gpio(spdev->dev.of_node,
					   "qcom,dock-plug-det-irq", 0);

	if (dock_plug_gpio >= 0) {
		apq8084_liquid_dock_dev =
		 kzalloc(sizeof(*apq8084_liquid_dock_dev), GFP_KERNEL);
		if (!apq8084_liquid_dock_dev) {
			pr_err("apq8084_liquid_dock_dev alloc fail.\n");
			ret = -ENOMEM;
			goto exit;
		}

		apq8084_liquid_dock_dev->dock_plug_gpio = dock_plug_gpio;
		apq8084_liquid_dock_dev->dapm = dapm;

		register_liquid_dock_notify(&apq8084_liquid_docking_notifier);
	}
exit:
	return ret;
}
@@ -4365,14 +4405,8 @@ static int apq8084_asoc_machine_remove(struct platform_device *pdev)
	if (gpio_is_valid(ext_spk_amp_gpio))
		gpio_free(ext_spk_amp_gpio);

	unregister_liquid_dock_notify(&apq8084_liquid_docking_notifier);
	if (apq8084_liquid_dock_dev != NULL) {
		if (apq8084_liquid_dock_dev->dock_plug_gpio)
			gpio_free(apq8084_liquid_dock_dev->dock_plug_gpio);

		if (apq8084_liquid_dock_dev->dock_plug_irq)
			free_irq(apq8084_liquid_dock_dev->dock_plug_irq,
				 apq8084_liquid_dock_dev);

		kfree(apq8084_liquid_dock_dev);
		apq8084_liquid_dock_dev = NULL;
	}