asoc: codecs: Add support for thermal coolong device in wsa

Add support for thermal cooling device in wsa macro to
set and reset the codec attenuation in 0C use cases.

Change-Id: Id00a3cd5666da906588a75961552ea07e24e1434
Signed-off-by: Aditya Bavanari <abavanar@codeaurora.org>
Signed-off-by: Sudheer Papothi <spapothi@codeaurora.org>
Šī revīzija ir iekļauta:
Sudheer Papothi
2020-11-13 13:34:23 +05:30
vecāks 9fc4437cd8
revīzija f067509538

Parādīt failu

@@ -7,6 +7,7 @@
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/thermal.h>
#include <linux/pm_runtime.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
@@ -56,6 +57,7 @@
#define LPASS_CDC_WSA_MACRO_EC_MIX_TX1_MASK 0x18
#define LPASS_CDC_WSA_MACRO_MAX_DMA_CH_PER_PORT 0x2
#define LPASS_CDC_WSA_MACRO_THERMAL_MAX_STATE 11
enum {
LPASS_CDC_WSA_MACRO_RX0 = 0,
@@ -271,6 +273,9 @@ struct lpass_cdc_wsa_macro_priv {
u16 default_clk_id;
u32 pcm_rate_vi;
int wsa_digital_mute_status[LPASS_CDC_WSA_MACRO_RX_MAX];
struct thermal_cooling_device *tcdev;
uint32_t thermal_cur_state;
uint32_t thermal_max_state;
};
static int lpass_cdc_wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
@@ -3024,6 +3029,73 @@ exit:
return ret;
}
/* Thermal Functions */
static int lpass_cdc_wsa_macro_get_max_state(
struct thermal_cooling_device *cdev,
unsigned long *state)
{
struct lpass_cdc_wsa_macro_priv *wsa_priv = cdev->devdata;
if (!wsa_priv) {
pr_err("%s: cdev->devdata is NULL\n", __func__);
return -EINVAL;
}
*state = wsa_priv->thermal_max_state;
return 0;
}
static int lpass_cdc_wsa_macro_get_cur_state(
struct thermal_cooling_device *cdev,
unsigned long *state)
{
struct lpass_cdc_wsa_macro_priv *wsa_priv = cdev->devdata;
if (!wsa_priv) {
pr_err("%s: cdev->devdata is NULL\n", __func__);
return -EINVAL;
}
*state = wsa_priv->thermal_cur_state;
pr_debug("%s: thermal current state:%lu\n", __func__, *state);
return 0;
}
static int lpass_cdc_wsa_macro_set_cur_state(
struct thermal_cooling_device *cdev,
unsigned long state)
{
struct lpass_cdc_wsa_macro_priv *wsa_priv = cdev->devdata;
u8 gain = 0;
if (!wsa_priv) {
pr_err("%s: cdev->devdata is NULL\n", __func__);
return -EINVAL;
}
if (state < wsa_priv->thermal_max_state)
wsa_priv->thermal_cur_state = state;
else
wsa_priv->thermal_cur_state = wsa_priv->thermal_max_state;
gain = (u8)(gain - wsa_priv->thermal_cur_state);
dev_dbg(wsa_priv->dev,
"%s: requested state:%d, actual state: %d, gain: %#x\n",
__func__, state, wsa_priv->thermal_cur_state, gain);
snd_soc_component_update_bits(wsa_priv->component,
LPASS_CDC_WSA_RX0_RX_VOL_CTL, 0xFF, gain);
snd_soc_component_update_bits(wsa_priv->component,
LPASS_CDC_WSA_RX1_RX_VOL_CTL, 0xFF, gain);
return 0;
}
static struct thermal_cooling_device_ops wsa_cooling_ops = {
.get_max_state = lpass_cdc_wsa_macro_get_max_state,
.get_cur_state = lpass_cdc_wsa_macro_get_cur_state,
.set_cur_state = lpass_cdc_wsa_macro_set_cur_state,
};
static int lpass_cdc_wsa_macro_init(struct snd_soc_component *component)
{
struct snd_soc_dapm_context *dapm =
@@ -3222,7 +3294,7 @@ static int lpass_cdc_wsa_macro_probe(struct platform_device *pdev)
{
struct macro_ops ops;
struct lpass_cdc_wsa_macro_priv *wsa_priv;
u32 wsa_base_addr, default_clk_id;
u32 wsa_base_addr, default_clk_id, thermal_max_state;
char __iomem *wsa_io_base;
int ret = 0;
u8 bcl_pmic_params[3];
@@ -3327,6 +3399,32 @@ static int lpass_cdc_wsa_macro_probe(struct platform_device *pdev)
goto reg_macro_fail;
}
schedule_work(&wsa_priv->lpass_cdc_wsa_macro_add_child_devices_work);
if (of_find_property(wsa_priv->dev->of_node, "#cooling-cells", NULL)) {
ret = of_property_read_u32(pdev->dev.of_node,
"qcom,thermal-max-state",
&thermal_max_state);
if (ret) {
dev_info(&pdev->dev, "%s: could not find %s entry in dt\n",
__func__, "qcom,thermal-max-state");
wsa_priv->thermal_max_state =
LPASS_CDC_WSA_MACRO_THERMAL_MAX_STATE;
} else {
wsa_priv->thermal_max_state = thermal_max_state;
}
wsa_priv->tcdev = devm_thermal_of_cooling_device_register(
&pdev->dev,
wsa_priv->dev->of_node,
"wsa", wsa_priv,
&wsa_cooling_ops);
if (IS_ERR(wsa_priv->tcdev)) {
dev_err(&pdev->dev,
"%s: failed to register wsa macro as cooling device\n",
__func__);
wsa_priv->tcdev = NULL;
}
}
pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
@@ -3350,6 +3448,9 @@ static int lpass_cdc_wsa_macro_remove(struct platform_device *pdev)
if (!wsa_priv)
return -EINVAL;
if (wsa_priv->tcdev)
thermal_cooling_device_unregister(wsa_priv->tcdev);
for (count = 0; count < wsa_priv->child_count &&
count < LPASS_CDC_WSA_MACRO_CHILD_DEVICES_MAX; count++)
platform_device_unregister(wsa_priv->pdev_child_devices[count]);