Unverified Commit 9e3d83c5 authored by Srinivasa Rao Mandadapu's avatar Srinivasa Rao Mandadapu Committed by Mark Brown
Browse files

ASoC: codecs: Add power domains support in digital macro codecs



Add support for enabling required power domains in digital macro codecs.
macro and dcodec power domains are being requested as clocks by HLOS
in ADSP based architectures and ADSP internally handling as powerdomains.
In ADSP bypass case need to handle them as power domains explicitly.

Signed-off-by: default avatarSrinivasa Rao Mandadapu <quic_srivasam@quicinc.com>
Co-developed-by: default avatarVenkata Prasad Potturu <quic_potturu@quicinc.com>
Signed-off-by: default avatarVenkata Prasad Potturu <quic_potturu@quicinc.com>
Reported-by: default avatarkernel test robot <lkp@intel.com>
Link: https://lore.kernel.org/r/1645898959-11231-2-git-send-email-quic_srivasam@quicinc.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 0f907c38
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -244,6 +244,7 @@ config SND_SOC_ALL_CODECS
	imply SND_SOC_WCD9335
	imply SND_SOC_WCD934X
	imply SND_SOC_WCD938X_SDW
	imply SND_SOC_LPASS_MACRO_COMMON
	imply SND_SOC_LPASS_RX_MACRO
	imply SND_SOC_LPASS_TX_MACRO
	imply SND_SOC_WL1273
@@ -2008,6 +2009,9 @@ config SND_SOC_TPA6130A2
	tristate "Texas Instruments TPA6130A2 headphone amplifier"
	depends on I2C

config SND_SOC_LPASS_MACRO_COMMON
        tristate

config SND_SOC_LPASS_WSA_MACRO
	depends on COMMON_CLK
	select REGMAP_MMIO
@@ -2016,16 +2020,19 @@ config SND_SOC_LPASS_WSA_MACRO
config SND_SOC_LPASS_VA_MACRO
	depends on COMMON_CLK
	select REGMAP_MMIO
	select SND_SOC_LPASS_MACRO_COMMON
	tristate "Qualcomm VA Macro in LPASS(Low Power Audio SubSystem)"

config SND_SOC_LPASS_RX_MACRO
	depends on COMMON_CLK
	select REGMAP_MMIO
	select SND_SOC_LPASS_MACRO_COMMON
	tristate "Qualcomm RX Macro in LPASS(Low Power Audio SubSystem)"

config SND_SOC_LPASS_TX_MACRO
	depends on COMMON_CLK
	select REGMAP_MMIO
	select SND_SOC_LPASS_MACRO_COMMON
	tristate "Qualcomm TX Macro in LPASS(Low Power Audio SubSystem)"

endmenu
+2 −0
Original line number Diff line number Diff line
@@ -112,6 +112,7 @@ snd-soc-l3-objs := l3.o
snd-soc-lm4857-objs := lm4857.o
snd-soc-lm49453-objs := lm49453.o
snd-soc-lochnagar-sc-objs := lochnagar-sc.o
snd-soc-lpass-macro-common-objs := lpass-macro-common.o
snd-soc-lpass-rx-macro-objs := lpass-rx-macro.o
snd-soc-lpass-tx-macro-objs := lpass-tx-macro.o
snd-soc-lpass-wsa-macro-objs := lpass-wsa-macro.o
@@ -676,6 +677,7 @@ obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
obj-$(CONFIG_SND_SOC_MAX98504)	+= snd-soc-max98504.o
obj-$(CONFIG_SND_SOC_SIMPLE_AMPLIFIER)	+= snd-soc-simple-amplifier.o
obj-$(CONFIG_SND_SOC_TPA6130A2)	+= snd-soc-tpa6130a2.o
obj-$(CONFIG_SND_SOC_LPASS_MACRO_COMMON)	+= snd-soc-lpass-macro-common.o
obj-$(CONFIG_SND_SOC_LPASS_WSA_MACRO)	+= snd-soc-lpass-wsa-macro.o
obj-$(CONFIG_SND_SOC_LPASS_VA_MACRO)	+= snd-soc-lpass-va-macro.o
obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO)	+= snd-soc-lpass-rx-macro.o
+67 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
// Copyright (c) 2022, The Linux Foundation. All rights reserved.

#include <linux/export.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>

#include "lpass-macro-common.h"

struct lpass_macro *lpass_macro_pds_init(struct device *dev)
{
	struct lpass_macro *l_pds;
	int ret;

	if (!of_find_property(dev->of_node, "power-domains", NULL))
		return NULL;

	l_pds = devm_kzalloc(dev, sizeof(*l_pds), GFP_KERNEL);
	if (!l_pds)
		return ERR_PTR(-ENOMEM);

	l_pds->macro_pd = dev_pm_domain_attach_by_name(dev, "macro");
	if (IS_ERR_OR_NULL(l_pds->macro_pd))
		return NULL;

	ret = pm_runtime_get_sync(l_pds->macro_pd);
	if (ret < 0) {
		pm_runtime_put_noidle(l_pds->macro_pd);
		goto macro_err;
	}

	l_pds->dcodec_pd = dev_pm_domain_attach_by_name(dev, "dcodec");
	if (IS_ERR_OR_NULL(l_pds->dcodec_pd))
		goto dcodec_err;

	ret = pm_runtime_get_sync(l_pds->dcodec_pd);
	if (ret < 0) {
		pm_runtime_put_noidle(l_pds->dcodec_pd);
		goto dcodec_sync_err;
	}
	return l_pds;

dcodec_sync_err:
	dev_pm_domain_detach(l_pds->dcodec_pd, false);
dcodec_err:
	pm_runtime_put(l_pds->macro_pd);
macro_err:
	dev_pm_domain_detach(l_pds->macro_pd, false);
	return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(lpass_macro_pds_init);

void lpass_macro_pds_exit(struct lpass_macro *pds)
{
	pm_runtime_put(pds->macro_pd);
	dev_pm_domain_detach(pds->macro_pd, false);
	pm_runtime_put(pds->dcodec_pd);
	dev_pm_domain_detach(pds->dcodec_pd, false);
}
EXPORT_SYMBOL_GPL(lpass_macro_pds_exit);

MODULE_DESCRIPTION("Common macro driver");
MODULE_LICENSE("GPL");
+17 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2022, The Linux Foundation. All rights reserved.
 */

#ifndef __LPASS_MACRO_COMMON_H__
#define __LPASS_MACRO_COMMON_H__

struct lpass_macro {
	struct device *macro_pd;
	struct device *dcodec_pd;
};

struct lpass_macro *lpass_macro_pds_init(struct device *dev);
void lpass_macro_pds_exit(struct lpass_macro *pds);

#endif /* __LPASS_MACRO_COMMON_H__ */
+9 −1
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
#include <linux/of_clk.h>
#include <linux/clk-provider.h>

#include "lpass-macro-common.h"

#define CDC_RX_TOP_TOP_CFG0		(0x0000)
#define CDC_RX_TOP_SWR_CTRL		(0x0008)
#define CDC_RX_TOP_DEBUG		(0x000C)
@@ -607,7 +609,7 @@ struct rx_macro {
	int is_softclip_on;
	int is_aux_hpf_on;
	int softclip_clk_users;

	struct lpass_macro *pds;
	struct regmap *regmap;
	struct clk *mclk;
	struct clk *npl;
@@ -3555,6 +3557,10 @@ static int rx_macro_probe(struct platform_device *pdev)
	if (IS_ERR(rx->fsgen))
		return PTR_ERR(rx->fsgen);

	rx->pds = lpass_macro_pds_init(dev);
	if (IS_ERR(rx->pds))
		return PTR_ERR(rx->pds);

	base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(base))
		return PTR_ERR(base);
@@ -3635,6 +3641,8 @@ static int rx_macro_remove(struct platform_device *pdev)
	clk_disable_unprepare(rx->macro);
	clk_disable_unprepare(rx->dcodec);

	lpass_macro_pds_exit(rx->pds);

	return 0;
}

Loading