mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 07:37:31 -04:00
asoc: bolero: add SSR changes support on bolero codec
Add changes for audio SSR and PDR on bolero codec and respective macro drivers. Change-Id: I146de15022cebb788ccb52ed6b8ab85b7cba2ba0 Signed-off-by: Vaishnavi Kommaraju <vkommara@codeaurora.org> Signed-off-by: Rohit kumar <rohitkr@codeaurora.org> Signed-off-by: Laxminath Kasam <lkasam@codeaurora.org>
This commit is contained in:
parent
27b1bbc54b
commit
fb0d683b37
7 changed files with 195 additions and 5 deletions
|
|
@ -18,7 +18,7 @@
|
|||
#include <linux/printk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <soc/snd_event.h>
|
||||
#include "bolero-cdc.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
|
@ -62,6 +62,11 @@ static int __bolero_reg_read(struct bolero_priv *priv,
|
|||
u16 current_mclk_mux_macro;
|
||||
|
||||
mutex_lock(&priv->clk_lock);
|
||||
if (!priv->dev_up) {
|
||||
dev_dbg_ratelimited(priv->dev,
|
||||
"%s: SSR in progress, exit\n", __func__);
|
||||
goto err;
|
||||
}
|
||||
current_mclk_mux_macro =
|
||||
priv->current_mclk_mux_macro[macro_id];
|
||||
if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) {
|
||||
|
|
@ -94,6 +99,11 @@ static int __bolero_reg_write(struct bolero_priv *priv,
|
|||
u16 current_mclk_mux_macro;
|
||||
|
||||
mutex_lock(&priv->clk_lock);
|
||||
if (!priv->dev_up) {
|
||||
dev_dbg_ratelimited(priv->dev,
|
||||
"%s: SSR in progress, exit\n", __func__);
|
||||
goto err;
|
||||
}
|
||||
current_mclk_mux_macro =
|
||||
priv->current_mclk_mux_macro[macro_id];
|
||||
if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) {
|
||||
|
|
@ -529,10 +539,64 @@ static ssize_t bolero_version_read(struct snd_info_entry *entry,
|
|||
return simple_read_from_buffer(buf, count, &pos, buffer, len);
|
||||
}
|
||||
|
||||
static int bolero_ssr_enable(struct device *dev, void *data)
|
||||
{
|
||||
struct bolero_priv *priv = data;
|
||||
int macro_idx;
|
||||
|
||||
if (priv->initial_boot) {
|
||||
priv->initial_boot = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (priv->macro_params[VA_MACRO].event_handler)
|
||||
priv->macro_params[VA_MACRO].event_handler(priv->codec,
|
||||
BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET, 0x0);
|
||||
|
||||
regcache_cache_only(priv->regmap, false);
|
||||
/* call ssr event for supported macros */
|
||||
for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) {
|
||||
if (!priv->macro_params[macro_idx].event_handler)
|
||||
continue;
|
||||
priv->macro_params[macro_idx].event_handler(priv->codec,
|
||||
BOLERO_MACRO_EVT_SSR_UP, 0x0);
|
||||
}
|
||||
mutex_lock(&priv->clk_lock);
|
||||
priv->dev_up = true;
|
||||
mutex_unlock(&priv->clk_lock);
|
||||
bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_SSR_UP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bolero_ssr_disable(struct device *dev, void *data)
|
||||
{
|
||||
struct bolero_priv *priv = data;
|
||||
int macro_idx;
|
||||
|
||||
regcache_cache_only(priv->regmap, true);
|
||||
|
||||
mutex_lock(&priv->clk_lock);
|
||||
priv->dev_up = false;
|
||||
mutex_unlock(&priv->clk_lock);
|
||||
/* call ssr event for supported macros */
|
||||
for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) {
|
||||
if (!priv->macro_params[macro_idx].event_handler)
|
||||
continue;
|
||||
priv->macro_params[macro_idx].event_handler(priv->codec,
|
||||
BOLERO_MACRO_EVT_SSR_DOWN, 0x0);
|
||||
}
|
||||
bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_SSR_DOWN);
|
||||
}
|
||||
|
||||
static struct snd_info_entry_ops bolero_info_ops = {
|
||||
.read = bolero_version_read,
|
||||
};
|
||||
|
||||
static const struct snd_event_ops bolero_ssr_ops = {
|
||||
.enable = bolero_ssr_enable,
|
||||
.disable = bolero_ssr_disable,
|
||||
};
|
||||
|
||||
/*
|
||||
* bolero_info_create_codec_entry - creates bolero module
|
||||
* @codec_root: The parent directory
|
||||
|
|
@ -623,6 +687,16 @@ static int bolero_soc_codec_probe(struct snd_soc_codec *codec)
|
|||
else if (priv->num_macros_registered > 2)
|
||||
priv->version = BOLERO_VERSION_1_2;
|
||||
|
||||
ret = snd_event_client_register(priv->dev, &bolero_ssr_ops, priv);
|
||||
if (!ret) {
|
||||
snd_event_notify(priv->dev, SND_EVENT_UP);
|
||||
} else {
|
||||
dev_err(codec->dev,
|
||||
"%s: Registration with SND event FWK failed ret = %d\n",
|
||||
__func__, ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
dev_dbg(codec->dev, "%s: bolero soc codec probe success\n", __func__);
|
||||
err:
|
||||
return ret;
|
||||
|
|
@ -633,6 +707,7 @@ static int bolero_soc_codec_remove(struct snd_soc_codec *codec)
|
|||
struct bolero_priv *priv = dev_get_drvdata(codec->dev);
|
||||
int macro_idx;
|
||||
|
||||
snd_event_client_deregister(priv->dev);
|
||||
/* call exit for supported macros */
|
||||
for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++)
|
||||
if (priv->macro_params[macro_idx].exit)
|
||||
|
|
@ -756,6 +831,8 @@ static int bolero_probe(struct platform_device *pdev)
|
|||
bolero_reg_access[VA_MACRO] = bolero_va_top_reg_access;
|
||||
|
||||
priv->dev = &pdev->dev;
|
||||
priv->dev_up = true;
|
||||
priv->initial_boot = true;
|
||||
priv->regmap = bolero_regmap_init(priv->dev,
|
||||
&bolero_regmap_config);
|
||||
if (IS_ERR_OR_NULL((void *)(priv->regmap))) {
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@ enum {
|
|||
BOLERO_MACRO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
|
||||
BOLERO_MACRO_EVT_IMPED_TRUE, /* for imped true */
|
||||
BOLERO_MACRO_EVT_IMPED_FALSE, /* for imped false */
|
||||
BOLERO_MACRO_EVT_SSR_DOWN,
|
||||
BOLERO_MACRO_EVT_SSR_UP,
|
||||
BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET
|
||||
};
|
||||
|
||||
struct macro_ops {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
/* from bolero to WCD events */
|
||||
enum {
|
||||
BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
|
||||
BOLERO_WCD_EVT_SSR_DOWN,
|
||||
BOLERO_WCD_EVT_SSR_UP,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
@ -52,6 +54,8 @@ struct bolero_priv {
|
|||
struct mutex clk_lock;
|
||||
bool va_without_decimation;
|
||||
bool macros_supported[MAX_MACRO];
|
||||
bool dev_up;
|
||||
bool initial_boot;
|
||||
struct macro_ops macro_params[MAX_MACRO];
|
||||
struct snd_soc_dai_driver *bolero_dais;
|
||||
u16 num_dais;
|
||||
|
|
|
|||
|
|
@ -1130,6 +1130,19 @@ static int rx_macro_event_handler(struct snd_soc_codec *codec, u16 event,
|
|||
case BOLERO_MACRO_EVT_IMPED_FALSE:
|
||||
rx_macro_wcd_clsh_imped_config(codec, data, false);
|
||||
break;
|
||||
case BOLERO_MACRO_EVT_SSR_DOWN:
|
||||
swrm_wcd_notify(
|
||||
rx_priv->swr_ctrl_data[0].rx_swr_pdev,
|
||||
SWR_DEVICE_SSR_DOWN, NULL);
|
||||
swrm_wcd_notify(
|
||||
rx_priv->swr_ctrl_data[0].rx_swr_pdev,
|
||||
SWR_DEVICE_DOWN, NULL);
|
||||
break;
|
||||
case BOLERO_MACRO_EVT_SSR_UP:
|
||||
swrm_wcd_notify(
|
||||
rx_priv->swr_ctrl_data[0].rx_swr_pdev,
|
||||
SWR_DEVICE_SSR_UP, NULL);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include <sound/soc.h>
|
||||
#include <sound/soc-dapm.h>
|
||||
#include <sound/tlv.h>
|
||||
#include <soc/swr-wcd.h>
|
||||
#include "bolero-cdc.h"
|
||||
#include "bolero-cdc-registers.h"
|
||||
#include "../msm-cdc-pinctrl.h"
|
||||
|
|
@ -303,6 +304,33 @@ exit:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int tx_macro_event_handler(struct snd_soc_codec *codec, u16 event,
|
||||
u32 data)
|
||||
{
|
||||
struct device *tx_dev = NULL;
|
||||
struct tx_macro_priv *tx_priv = NULL;
|
||||
|
||||
if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
switch (event) {
|
||||
case BOLERO_MACRO_EVT_SSR_DOWN:
|
||||
swrm_wcd_notify(
|
||||
tx_priv->swr_ctrl_data[0].tx_swr_pdev,
|
||||
SWR_DEVICE_SSR_DOWN, NULL);
|
||||
swrm_wcd_notify(
|
||||
tx_priv->swr_ctrl_data[0].tx_swr_pdev,
|
||||
SWR_DEVICE_DOWN, NULL);
|
||||
break;
|
||||
case BOLERO_MACRO_EVT_SSR_UP:
|
||||
swrm_wcd_notify(
|
||||
tx_priv->swr_ctrl_data[0].tx_swr_pdev,
|
||||
SWR_DEVICE_SSR_UP, NULL);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
|
||||
{
|
||||
struct delayed_work *hpf_delayed_work = NULL;
|
||||
|
|
@ -1640,6 +1668,7 @@ static void tx_macro_init_ops(struct macro_ops *ops,
|
|||
ops->dai_ptr = tx_macro_dai;
|
||||
ops->num_dais = ARRAY_SIZE(tx_macro_dai);
|
||||
ops->mclk_fn = tx_macro_mclk_ctrl;
|
||||
ops->event_handler = tx_macro_event_handler;
|
||||
}
|
||||
|
||||
static int tx_macro_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01
|
||||
|
||||
#define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40
|
||||
#define MAX_RETRY_ATTEMPTS 50
|
||||
|
||||
static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
|
||||
static int va_tx_unmute_delay = BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS;
|
||||
|
|
@ -178,8 +179,7 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv,
|
|||
0x02, 0x02);
|
||||
}
|
||||
} else {
|
||||
va_priv->va_mclk_users--;
|
||||
if (va_priv->va_mclk_users == 0) {
|
||||
if (va_priv->va_mclk_users == 1) {
|
||||
regmap_update_bits(regmap,
|
||||
BOLERO_CDC_VA_TOP_CSR_TOP_CFG0,
|
||||
0x02, 0x00);
|
||||
|
|
@ -192,12 +192,47 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv,
|
|||
bolero_request_clock(va_priv->dev,
|
||||
VA_MACRO, MCLK_MUX0, false);
|
||||
}
|
||||
va_priv->va_mclk_users--;
|
||||
}
|
||||
exit:
|
||||
mutex_unlock(&va_priv->mclk_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int va_macro_event_handler(struct snd_soc_codec *codec, u16 event,
|
||||
u32 data)
|
||||
{
|
||||
struct device *va_dev = NULL;
|
||||
struct va_macro_priv *va_priv = NULL;
|
||||
int retry_cnt = MAX_RETRY_ATTEMPTS;
|
||||
|
||||
if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
switch (event) {
|
||||
case BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET:
|
||||
while ((va_priv->va_mclk_users != 0) && (retry_cnt != 0)) {
|
||||
dev_dbg(va_dev, "%s:retry_cnt: %d\n",
|
||||
__func__, retry_cnt);
|
||||
/*
|
||||
* loop and check every 20ms for va_mclk user count
|
||||
* to get reset to 0 which ensures userspace teardown
|
||||
* is done and SSR powerup seq can proceed.
|
||||
*/
|
||||
msleep(20);
|
||||
retry_cnt--;
|
||||
}
|
||||
if (retry_cnt == 0)
|
||||
dev_err(va_dev,
|
||||
"%s: va_mclk_users is non-zero still, audio SSR fail!!\n",
|
||||
__func__);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int va_macro_mclk_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
|
|
@ -1054,13 +1089,13 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
|
||||
|
||||
SND_SOC_DAPM_SUPPLY_S("VA_MCLK", 0, SND_SOC_NOPM, 0, 0,
|
||||
SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0,
|
||||
va_macro_mclk_event,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget va_macro_wod_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_SUPPLY_S("VA_MCLK", 0, SND_SOC_NOPM, 0, 0,
|
||||
SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0,
|
||||
va_macro_mclk_event,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
};
|
||||
|
|
@ -1465,6 +1500,7 @@ static void va_macro_init_ops(struct macro_ops *ops,
|
|||
ops->exit = va_macro_deinit;
|
||||
ops->io_base = va_io_base;
|
||||
ops->mclk_fn = va_macro_mclk_ctrl;
|
||||
ops->event_handler = va_macro_event_handler;
|
||||
}
|
||||
|
||||
static int va_macro_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -859,6 +859,33 @@ exit:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int wsa_macro_event_handler(struct snd_soc_codec *codec, u16 event,
|
||||
u32 data)
|
||||
{
|
||||
struct device *wsa_dev = NULL;
|
||||
struct wsa_macro_priv *wsa_priv = NULL;
|
||||
|
||||
if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
switch (event) {
|
||||
case BOLERO_MACRO_EVT_SSR_DOWN:
|
||||
swrm_wcd_notify(
|
||||
wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
|
||||
SWR_DEVICE_SSR_DOWN, NULL);
|
||||
swrm_wcd_notify(
|
||||
wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
|
||||
SWR_DEVICE_DOWN, NULL);
|
||||
break;
|
||||
case BOLERO_MACRO_EVT_SSR_UP:
|
||||
swrm_wcd_notify(
|
||||
wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
|
||||
SWR_DEVICE_SSR_UP, NULL);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
|
|
@ -2617,6 +2644,7 @@ static void wsa_macro_init_ops(struct macro_ops *ops,
|
|||
ops->dai_ptr = wsa_macro_dai;
|
||||
ops->num_dais = ARRAY_SIZE(wsa_macro_dai);
|
||||
ops->mclk_fn = wsa_macro_mclk_ctrl;
|
||||
ops->event_handler = wsa_macro_event_handler;
|
||||
}
|
||||
|
||||
static int wsa_macro_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
Loading…
Reference in a new issue