Merge "asoc: sm6150: Add SND event FWK support for talos"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
e5b3489f2f
@@ -18,7 +18,7 @@
|
|||||||
#include <linux/printk.h>
|
#include <linux/printk.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <soc/snd_event.h>
|
||||||
#include "bolero-cdc.h"
|
#include "bolero-cdc.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@@ -62,6 +62,11 @@ static int __bolero_reg_read(struct bolero_priv *priv,
|
|||||||
u16 current_mclk_mux_macro;
|
u16 current_mclk_mux_macro;
|
||||||
|
|
||||||
mutex_lock(&priv->clk_lock);
|
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 =
|
current_mclk_mux_macro =
|
||||||
priv->current_mclk_mux_macro[macro_id];
|
priv->current_mclk_mux_macro[macro_id];
|
||||||
if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) {
|
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;
|
u16 current_mclk_mux_macro;
|
||||||
|
|
||||||
mutex_lock(&priv->clk_lock);
|
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 =
|
current_mclk_mux_macro =
|
||||||
priv->current_mclk_mux_macro[macro_id];
|
priv->current_mclk_mux_macro[macro_id];
|
||||||
if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) {
|
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);
|
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 = {
|
static struct snd_info_entry_ops bolero_info_ops = {
|
||||||
.read = bolero_version_read,
|
.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
|
* bolero_info_create_codec_entry - creates bolero module
|
||||||
* @codec_root: The parent directory
|
* @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)
|
else if (priv->num_macros_registered > 2)
|
||||||
priv->version = BOLERO_VERSION_1_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__);
|
dev_dbg(codec->dev, "%s: bolero soc codec probe success\n", __func__);
|
||||||
err:
|
err:
|
||||||
return ret;
|
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);
|
struct bolero_priv *priv = dev_get_drvdata(codec->dev);
|
||||||
int macro_idx;
|
int macro_idx;
|
||||||
|
|
||||||
|
snd_event_client_deregister(priv->dev);
|
||||||
/* call exit for supported macros */
|
/* call exit for supported macros */
|
||||||
for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++)
|
for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++)
|
||||||
if (priv->macro_params[macro_idx].exit)
|
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;
|
bolero_reg_access[VA_MACRO] = bolero_va_top_reg_access;
|
||||||
|
|
||||||
priv->dev = &pdev->dev;
|
priv->dev = &pdev->dev;
|
||||||
|
priv->dev_up = true;
|
||||||
|
priv->initial_boot = true;
|
||||||
priv->regmap = bolero_regmap_init(priv->dev,
|
priv->regmap = bolero_regmap_init(priv->dev,
|
||||||
&bolero_regmap_config);
|
&bolero_regmap_config);
|
||||||
if (IS_ERR_OR_NULL((void *)(priv->regmap))) {
|
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_RX_MUTE = 1, /* for RX mute/unmute */
|
||||||
BOLERO_MACRO_EVT_IMPED_TRUE, /* for imped true */
|
BOLERO_MACRO_EVT_IMPED_TRUE, /* for imped true */
|
||||||
BOLERO_MACRO_EVT_IMPED_FALSE, /* for imped false */
|
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 {
|
struct macro_ops {
|
||||||
|
@@ -20,6 +20,8 @@
|
|||||||
/* from bolero to WCD events */
|
/* from bolero to WCD events */
|
||||||
enum {
|
enum {
|
||||||
BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
|
BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
|
||||||
|
BOLERO_WCD_EVT_SSR_DOWN,
|
||||||
|
BOLERO_WCD_EVT_SSR_UP,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -52,6 +54,8 @@ struct bolero_priv {
|
|||||||
struct mutex clk_lock;
|
struct mutex clk_lock;
|
||||||
bool va_without_decimation;
|
bool va_without_decimation;
|
||||||
bool macros_supported[MAX_MACRO];
|
bool macros_supported[MAX_MACRO];
|
||||||
|
bool dev_up;
|
||||||
|
bool initial_boot;
|
||||||
struct macro_ops macro_params[MAX_MACRO];
|
struct macro_ops macro_params[MAX_MACRO];
|
||||||
struct snd_soc_dai_driver *bolero_dais;
|
struct snd_soc_dai_driver *bolero_dais;
|
||||||
u16 num_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:
|
case BOLERO_MACRO_EVT_IMPED_FALSE:
|
||||||
rx_macro_wcd_clsh_imped_config(codec, data, false);
|
rx_macro_wcd_clsh_imped_config(codec, data, false);
|
||||||
break;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include <sound/soc.h>
|
#include <sound/soc.h>
|
||||||
#include <sound/soc-dapm.h>
|
#include <sound/soc-dapm.h>
|
||||||
#include <sound/tlv.h>
|
#include <sound/tlv.h>
|
||||||
|
#include <soc/swr-wcd.h>
|
||||||
#include "bolero-cdc.h"
|
#include "bolero-cdc.h"
|
||||||
#include "bolero-cdc-registers.h"
|
#include "bolero-cdc-registers.h"
|
||||||
#include "../msm-cdc-pinctrl.h"
|
#include "../msm-cdc-pinctrl.h"
|
||||||
@@ -303,6 +304,33 @@ exit:
|
|||||||
return ret;
|
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)
|
static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct delayed_work *hpf_delayed_work = NULL;
|
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->dai_ptr = tx_macro_dai;
|
||||||
ops->num_dais = ARRAY_SIZE(tx_macro_dai);
|
ops->num_dais = ARRAY_SIZE(tx_macro_dai);
|
||||||
ops->mclk_fn = tx_macro_mclk_ctrl;
|
ops->mclk_fn = tx_macro_mclk_ctrl;
|
||||||
|
ops->event_handler = tx_macro_event_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tx_macro_probe(struct platform_device *pdev)
|
static int tx_macro_probe(struct platform_device *pdev)
|
||||||
|
@@ -46,6 +46,7 @@
|
|||||||
#define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01
|
#define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01
|
||||||
|
|
||||||
#define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40
|
#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 const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
|
||||||
static int va_tx_unmute_delay = BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS;
|
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);
|
0x02, 0x02);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
va_priv->va_mclk_users--;
|
if (va_priv->va_mclk_users == 1) {
|
||||||
if (va_priv->va_mclk_users == 0) {
|
|
||||||
regmap_update_bits(regmap,
|
regmap_update_bits(regmap,
|
||||||
BOLERO_CDC_VA_TOP_CSR_TOP_CFG0,
|
BOLERO_CDC_VA_TOP_CSR_TOP_CFG0,
|
||||||
0x02, 0x00);
|
0x02, 0x00);
|
||||||
@@ -192,12 +192,47 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv,
|
|||||||
bolero_request_clock(va_priv->dev,
|
bolero_request_clock(va_priv->dev,
|
||||||
VA_MACRO, MCLK_MUX0, false);
|
VA_MACRO, MCLK_MUX0, false);
|
||||||
}
|
}
|
||||||
|
va_priv->va_mclk_users--;
|
||||||
}
|
}
|
||||||
exit:
|
exit:
|
||||||
mutex_unlock(&va_priv->mclk_lock);
|
mutex_unlock(&va_priv->mclk_lock);
|
||||||
return ret;
|
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,
|
static int va_macro_mclk_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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_PMU | SND_SOC_DAPM_POST_PMU |
|
||||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
|
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,
|
va_macro_mclk_event,
|
||||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_soc_dapm_widget va_macro_wod_dapm_widgets[] = {
|
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,
|
va_macro_mclk_event,
|
||||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
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->exit = va_macro_deinit;
|
||||||
ops->io_base = va_io_base;
|
ops->io_base = va_io_base;
|
||||||
ops->mclk_fn = va_macro_mclk_ctrl;
|
ops->mclk_fn = va_macro_mclk_ctrl;
|
||||||
|
ops->event_handler = va_macro_event_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int va_macro_probe(struct platform_device *pdev)
|
static int va_macro_probe(struct platform_device *pdev)
|
||||||
|
@@ -859,6 +859,33 @@ exit:
|
|||||||
return ret;
|
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,
|
static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol,
|
struct snd_kcontrol *kcontrol,
|
||||||
int event)
|
int event)
|
||||||
@@ -2617,6 +2644,7 @@ static void wsa_macro_init_ops(struct macro_ops *ops,
|
|||||||
ops->dai_ptr = wsa_macro_dai;
|
ops->dai_ptr = wsa_macro_dai;
|
||||||
ops->num_dais = ARRAY_SIZE(wsa_macro_dai);
|
ops->num_dais = ARRAY_SIZE(wsa_macro_dai);
|
||||||
ops->mclk_fn = wsa_macro_mclk_ctrl;
|
ops->mclk_fn = wsa_macro_mclk_ctrl;
|
||||||
|
ops->event_handler = wsa_macro_event_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wsa_macro_probe(struct platform_device *pdev)
|
static int wsa_macro_probe(struct platform_device *pdev)
|
||||||
|
@@ -123,6 +123,8 @@ enum {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
|
BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
|
||||||
|
BOLERO_WCD_EVT_SSR_DOWN,
|
||||||
|
BOLERO_WCD_EVT_SSR_UP,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@@ -974,6 +974,7 @@ int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wcd937x_mbhc_hs_detect_exit(codec);
|
||||||
wcd_mbhc_deinit(wcd_mbhc);
|
wcd_mbhc_deinit(wcd_mbhc);
|
||||||
ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids,
|
ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids,
|
||||||
wcd_mbhc_registers, WCD937X_ZDET_SUPPORTED);
|
wcd_mbhc_registers, WCD937X_ZDET_SUPPORTED);
|
||||||
|
@@ -450,8 +450,10 @@ static bool wcd937x_volatile_register(struct device *dev, unsigned int reg)
|
|||||||
{
|
{
|
||||||
if(reg <= WCD937X_BASE_ADDRESS)
|
if(reg <= WCD937X_BASE_ADDRESS)
|
||||||
return 0;
|
return 0;
|
||||||
return (wcd937x_reg_access[WCD937X_REG(reg)] & RD_REG)
|
if ((wcd937x_reg_access[WCD937X_REG(reg)] & RD_REG)
|
||||||
& ~(wcd937x_reg_access[WCD937X_REG(reg)] & WR_REG);
|
&& !(wcd937x_reg_access[WCD937X_REG(reg)] & WR_REG))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct regmap_config wcd937x_regmap_config = {
|
struct regmap_config wcd937x_regmap_config = {
|
||||||
|
@@ -48,6 +48,8 @@ static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
|
|||||||
static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
|
static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
|
||||||
|
|
||||||
static int wcd937x_handle_post_irq(void *data);
|
static int wcd937x_handle_post_irq(void *data);
|
||||||
|
static int wcd937x_reset(struct device *dev);
|
||||||
|
static int wcd937x_reset_low(struct device *dev);
|
||||||
|
|
||||||
static const struct regmap_irq wcd937x_irqs[WCD937X_NUM_IRQS] = {
|
static const struct regmap_irq wcd937x_irqs[WCD937X_NUM_IRQS] = {
|
||||||
REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01),
|
REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01),
|
||||||
@@ -1216,6 +1218,23 @@ int wcd937x_micbias_control(struct snd_soc_codec *codec,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(wcd937x_micbias_control);
|
EXPORT_SYMBOL(wcd937x_micbias_control);
|
||||||
|
|
||||||
|
static int wcd937x_get_logical_addr(struct swr_device *swr_dev)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
uint8_t devnum = 0;
|
||||||
|
|
||||||
|
ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&swr_dev->dev,
|
||||||
|
"%s get devnum %d for dev addr %lx failed\n",
|
||||||
|
__func__, devnum, swr_dev->addr);
|
||||||
|
swr_remove_device(swr_dev);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
swr_dev->dev_num = devnum;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int wcd937x_event_notify(struct notifier_block *block,
|
static int wcd937x_event_notify(struct notifier_block *block,
|
||||||
unsigned long val,
|
unsigned long val,
|
||||||
void *data)
|
void *data)
|
||||||
@@ -1223,8 +1242,10 @@ static int wcd937x_event_notify(struct notifier_block *block,
|
|||||||
u16 event = (val & 0xffff);
|
u16 event = (val & 0xffff);
|
||||||
u16 amic = (val >> 0x10);
|
u16 amic = (val >> 0x10);
|
||||||
u16 mask = 0x40, reg = 0x0;
|
u16 mask = 0x40, reg = 0x0;
|
||||||
|
int ret = 0;
|
||||||
struct wcd937x_priv *wcd937x = dev_get_drvdata((struct device *)data);
|
struct wcd937x_priv *wcd937x = dev_get_drvdata((struct device *)data);
|
||||||
struct snd_soc_codec *codec = wcd937x->codec;
|
struct snd_soc_codec *codec = wcd937x->codec;
|
||||||
|
struct wcd_mbhc *mbhc;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR:
|
case BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR:
|
||||||
@@ -1238,6 +1259,25 @@ static int wcd937x_event_notify(struct notifier_block *block,
|
|||||||
mask = 0x20;
|
mask = 0x20;
|
||||||
snd_soc_update_bits(codec, reg, mask, 0x00);
|
snd_soc_update_bits(codec, reg, mask, 0x00);
|
||||||
break;
|
break;
|
||||||
|
case BOLERO_WCD_EVT_SSR_DOWN:
|
||||||
|
wcd937x_reset_low(wcd937x->dev);
|
||||||
|
break;
|
||||||
|
case BOLERO_WCD_EVT_SSR_UP:
|
||||||
|
wcd937x_reset(wcd937x->dev);
|
||||||
|
wcd937x_get_logical_addr(wcd937x->tx_swr_dev);
|
||||||
|
wcd937x_get_logical_addr(wcd937x->rx_swr_dev);
|
||||||
|
regcache_mark_dirty(wcd937x->regmap);
|
||||||
|
regcache_sync(wcd937x->regmap);
|
||||||
|
/* Initialize MBHC module */
|
||||||
|
mbhc = &wcd937x->mbhc->wcd_mbhc;
|
||||||
|
ret = wcd937x_mbhc_post_ssr_init(wcd937x->mbhc, codec);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(codec->dev, "%s: mbhc initialization failed\n",
|
||||||
|
__func__);
|
||||||
|
} else {
|
||||||
|
wcd937x_mbhc_hs_detect(codec, mbhc->mbhc_cfg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(codec->dev, "%s: invalid event %d\n", __func__, event);
|
dev_err(codec->dev, "%s: invalid event %d\n", __func__, event);
|
||||||
break;
|
break;
|
||||||
@@ -1923,7 +1963,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wcd937x = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
int wcd937x_reset(struct device *dev)
|
static int wcd937x_reset(struct device *dev)
|
||||||
{
|
{
|
||||||
struct wcd937x_priv *wcd937x = NULL;
|
struct wcd937x_priv *wcd937x = NULL;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -2026,6 +2066,36 @@ static void wcd937x_dt_parse_micbias_info(struct device *dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wcd937x_reset_low(struct device *dev)
|
||||||
|
{
|
||||||
|
struct wcd937x_priv *wcd937x = NULL;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!dev)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
wcd937x = dev_get_drvdata(dev);
|
||||||
|
if (!wcd937x)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!wcd937x->rst_np) {
|
||||||
|
dev_err(dev, "%s: reset gpio device node not specified\n",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = msm_cdc_pinctrl_select_sleep_state(wcd937x->rst_np);
|
||||||
|
if (rc) {
|
||||||
|
dev_err(dev, "%s: wcd sleep state request fail!\n",
|
||||||
|
__func__);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
/* 20ms sleep required after pulling the reset gpio to LOW */
|
||||||
|
usleep_range(20, 30);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
struct wcd937x_pdata *wcd937x_populate_dt_data(struct device *dev)
|
struct wcd937x_pdata *wcd937x_populate_dt_data(struct device *dev)
|
||||||
{
|
{
|
||||||
struct wcd937x_pdata *pdata = NULL;
|
struct wcd937x_pdata *pdata = NULL;
|
||||||
|
@@ -85,6 +85,21 @@ static const struct component_ops wcd937x_slave_comp_ops = {
|
|||||||
.unbind = wcd937x_slave_unbind,
|
.unbind = wcd937x_slave_unbind,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int wcd937x_swr_up(struct swr_device *pdev)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wcd937x_swr_down(struct swr_device *pdev)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wcd937x_swr_reset(struct swr_device *pdev)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int wcd937x_swr_probe(struct swr_device *pdev)
|
static int wcd937x_swr_probe(struct swr_device *pdev)
|
||||||
{
|
{
|
||||||
return component_add(&pdev->dev, &wcd937x_slave_comp_ops);
|
return component_add(&pdev->dev, &wcd937x_slave_comp_ops);
|
||||||
@@ -105,6 +120,9 @@ static struct swr_driver wcd937x_slave_driver = {
|
|||||||
.probe = wcd937x_swr_probe,
|
.probe = wcd937x_swr_probe,
|
||||||
.remove = wcd937x_swr_remove,
|
.remove = wcd937x_swr_remove,
|
||||||
.id_table = wcd937x_swr_id,
|
.id_table = wcd937x_swr_id,
|
||||||
|
.device_up = wcd937x_swr_up,
|
||||||
|
.device_down = wcd937x_swr_down,
|
||||||
|
.reset_device = wcd937x_swr_reset,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init wcd937x_slave_init(void)
|
static int __init wcd937x_slave_init(void)
|
||||||
|
245
asoc/sm6150.c
245
asoc/sm6150.c
@@ -28,7 +28,7 @@
|
|||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
#include <sound/pcm_params.h>
|
#include <sound/pcm_params.h>
|
||||||
#include <sound/info.h>
|
#include <sound/info.h>
|
||||||
#include <dsp/audio_notifier.h>
|
#include <soc/snd_event.h>
|
||||||
#include <dsp/q6afe-v2.h>
|
#include <dsp/q6afe-v2.h>
|
||||||
#include <dsp/q6core.h>
|
#include <dsp/q6core.h>
|
||||||
#include "device_event.h"
|
#include "device_event.h"
|
||||||
@@ -201,6 +201,7 @@ struct msm_asoc_mach_data {
|
|||||||
struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */
|
struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */
|
||||||
struct device_node *hph_en1_gpio_p; /* used by pinctrl API */
|
struct device_node *hph_en1_gpio_p; /* used by pinctrl API */
|
||||||
struct device_node *hph_en0_gpio_p; /* used by pinctrl API */
|
struct device_node *hph_en0_gpio_p; /* used by pinctrl API */
|
||||||
|
bool is_afe_config_done;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msm_asoc_wcd93xx_codec {
|
struct msm_asoc_wcd93xx_codec {
|
||||||
@@ -628,10 +629,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_sample_rate,
|
|||||||
static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_sample_rate,
|
static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_sample_rate,
|
||||||
cdc_dma_sample_rate_text);
|
cdc_dma_sample_rate_text);
|
||||||
|
|
||||||
static struct platform_device *spdev;
|
|
||||||
|
|
||||||
static int msm_hifi_control;
|
static int msm_hifi_control;
|
||||||
static bool is_initial_boot;
|
|
||||||
static bool codec_reg_done;
|
static bool codec_reg_done;
|
||||||
static struct snd_soc_aux_dev *msm_aux_dev;
|
static struct snd_soc_aux_dev *msm_aux_dev;
|
||||||
static struct snd_soc_codec_conf *msm_codec_conf;
|
static struct snd_soc_codec_conf *msm_codec_conf;
|
||||||
@@ -4643,121 +4641,6 @@ static void msm_afe_clear_config(void)
|
|||||||
afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG);
|
afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int msm_adsp_power_up_config(struct snd_soc_codec *codec,
|
|
||||||
struct snd_card *card)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
unsigned long timeout;
|
|
||||||
int adsp_ready = 0;
|
|
||||||
bool snd_card_online = 0;
|
|
||||||
|
|
||||||
timeout = jiffies +
|
|
||||||
msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (!snd_card_online) {
|
|
||||||
snd_card_online = snd_card_is_online_state(card);
|
|
||||||
pr_debug("%s: Sound card is %s\n", __func__,
|
|
||||||
snd_card_online ? "Online" : "Offline");
|
|
||||||
}
|
|
||||||
if (!adsp_ready) {
|
|
||||||
adsp_ready = q6core_is_adsp_ready();
|
|
||||||
pr_debug("%s: ADSP Audio is %s\n", __func__,
|
|
||||||
adsp_ready ? "ready" : "not ready");
|
|
||||||
}
|
|
||||||
if (snd_card_online && adsp_ready)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sound card/ADSP will be coming up after subsystem restart and
|
|
||||||
* it might not be fully up when the control reaches
|
|
||||||
* here. So, wait for 50msec before checking ADSP state
|
|
||||||
*/
|
|
||||||
msleep(50);
|
|
||||||
} while (time_after(timeout, jiffies));
|
|
||||||
|
|
||||||
if (!snd_card_online || !adsp_ready) {
|
|
||||||
pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n",
|
|
||||||
__func__,
|
|
||||||
snd_card_online ? "Online" : "Offline",
|
|
||||||
adsp_ready ? "ready" : "not ready");
|
|
||||||
ret = -ETIMEDOUT;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = msm_afe_set_config(codec);
|
|
||||||
if (ret)
|
|
||||||
pr_err("%s: Failed to set AFE config. err %d\n",
|
|
||||||
__func__, ret);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sm6150_notifier_service_cb(struct notifier_block *this,
|
|
||||||
unsigned long opcode, void *ptr)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct snd_soc_card *card = NULL;
|
|
||||||
const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
|
|
||||||
struct snd_soc_pcm_runtime *rtd;
|
|
||||||
struct snd_soc_codec *codec;
|
|
||||||
|
|
||||||
pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode);
|
|
||||||
|
|
||||||
switch (opcode) {
|
|
||||||
case AUDIO_NOTIFIER_SERVICE_DOWN:
|
|
||||||
/*
|
|
||||||
* Use flag to ignore initial boot notifications
|
|
||||||
* On initial boot msm_adsp_power_up_config is
|
|
||||||
* called on init. There is no need to clear
|
|
||||||
* and set the config again on initial boot.
|
|
||||||
*/
|
|
||||||
if (is_initial_boot)
|
|
||||||
break;
|
|
||||||
msm_afe_clear_config();
|
|
||||||
break;
|
|
||||||
case AUDIO_NOTIFIER_SERVICE_UP:
|
|
||||||
if (is_initial_boot) {
|
|
||||||
is_initial_boot = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!spdev)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
card = platform_get_drvdata(spdev);
|
|
||||||
rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
|
|
||||||
if (!rtd) {
|
|
||||||
dev_err(card->dev,
|
|
||||||
"%s: snd_soc_get_pcm_runtime for %s failed!\n",
|
|
||||||
__func__, be_dl_name);
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
codec = rtd->codec;
|
|
||||||
|
|
||||||
ret = msm_adsp_power_up_config(codec, card->snd_card);
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_err(card->dev,
|
|
||||||
"%s: msm_adsp_power_up_config failed ret = %d!\n",
|
|
||||||
__func__, ret);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
err:
|
|
||||||
return NOTIFY_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct notifier_block service_nb = {
|
|
||||||
.notifier_call = sm6150_notifier_service_cb,
|
|
||||||
.priority = -INT_MAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd)
|
static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -4845,11 +4728,12 @@ static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd)
|
|||||||
|
|
||||||
msm_codec_fn.get_afe_config_fn = tavil_get_afe_config;
|
msm_codec_fn.get_afe_config_fn = tavil_get_afe_config;
|
||||||
|
|
||||||
ret = msm_adsp_power_up_config(codec, rtd->card->snd_card);
|
ret = msm_afe_set_config(codec);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("%s: Failed to set AFE config %d\n", __func__, ret);
|
pr_err("%s: Failed to set AFE config %d\n", __func__, ret);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
pdata->is_afe_config_done = true;
|
||||||
|
|
||||||
config_data = msm_codec_fn.get_afe_config_fn(codec,
|
config_data = msm_codec_fn.get_afe_config_fn(codec,
|
||||||
AFE_AANC_VERSION);
|
AFE_AANC_VERSION);
|
||||||
@@ -8357,6 +8241,108 @@ static void msm_i2s_auxpcm_deinit(void)
|
|||||||
mi2s_intf_conf[count].msm_is_mi2s_master = 0;
|
mi2s_intf_conf[count].msm_is_mi2s_master = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sm6150_ssr_enable(struct device *dev, void *data)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
struct snd_soc_card *card = platform_get_drvdata(pdev);
|
||||||
|
struct msm_asoc_mach_data *pdata;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!card) {
|
||||||
|
dev_err(dev, "%s: card is NULL\n", __func__);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(card->name, "sm6150-tavil-snd-card")) {
|
||||||
|
pdata = snd_soc_card_get_drvdata(card);
|
||||||
|
if (!pdata->is_afe_config_done) {
|
||||||
|
const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
|
||||||
|
struct snd_soc_pcm_runtime *rtd;
|
||||||
|
|
||||||
|
rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
|
||||||
|
if (!rtd) {
|
||||||
|
dev_err(dev,
|
||||||
|
"%s: snd_soc_get_pcm_runtime for %s failed!\n",
|
||||||
|
__func__, be_dl_name);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
ret = msm_afe_set_config(rtd->codec);
|
||||||
|
if (ret)
|
||||||
|
dev_err(dev, "%s: Failed to set AFE config. err %d\n",
|
||||||
|
__func__, ret);
|
||||||
|
else
|
||||||
|
pdata->is_afe_config_done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snd_soc_card_change_online_state(card, 1);
|
||||||
|
dev_dbg(dev, "%s: setting snd_card to ONLINE\n", __func__);
|
||||||
|
|
||||||
|
err:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sm6150_ssr_disable(struct device *dev, void *data)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
struct snd_soc_card *card = platform_get_drvdata(pdev);
|
||||||
|
struct msm_asoc_mach_data *pdata;
|
||||||
|
|
||||||
|
if (!card) {
|
||||||
|
dev_err(dev, "%s: card is NULL\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_dbg(dev, "%s: setting snd_card to OFFLINE\n", __func__);
|
||||||
|
snd_soc_card_change_online_state(card, 0);
|
||||||
|
|
||||||
|
if (!strcmp(card->name, "sm6150-tavil-snd-card")) {
|
||||||
|
pdata = snd_soc_card_get_drvdata(card);
|
||||||
|
msm_afe_clear_config();
|
||||||
|
pdata->is_afe_config_done = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct snd_event_ops sm6150_ssr_ops = {
|
||||||
|
.enable = sm6150_ssr_enable,
|
||||||
|
.disable = sm6150_ssr_disable,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int msm_audio_ssr_compare(struct device *dev, void *data)
|
||||||
|
{
|
||||||
|
struct device_node *node = data;
|
||||||
|
|
||||||
|
dev_dbg(dev, "%s: dev->of_node = 0x%p, node = 0x%p\n",
|
||||||
|
__func__, dev->of_node, node);
|
||||||
|
return (dev->of_node && dev->of_node == node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int msm_audio_ssr_register(struct device *dev)
|
||||||
|
{
|
||||||
|
struct device_node *np = dev->of_node;
|
||||||
|
struct snd_event_clients *ssr_clients = NULL;
|
||||||
|
struct device_node *node;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; ; i++) {
|
||||||
|
node = of_parse_phandle(np, "qcom,msm_audio_ssr_devs", i);
|
||||||
|
if (!node)
|
||||||
|
break;
|
||||||
|
snd_event_mstr_add_client(&ssr_clients,
|
||||||
|
msm_audio_ssr_compare, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snd_event_master_register(dev, &sm6150_ssr_ops,
|
||||||
|
ssr_clients, NULL);
|
||||||
|
if (!ret)
|
||||||
|
snd_event_notify(dev, SND_EVENT_UP);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int msm_asoc_machine_probe(struct platform_device *pdev)
|
static int msm_asoc_machine_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct snd_soc_card *card;
|
struct snd_soc_card *card;
|
||||||
@@ -8419,7 +8405,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
dev_info(&pdev->dev, "Sound card %s registered\n", card->name);
|
dev_info(&pdev->dev, "Sound card %s registered\n", card->name);
|
||||||
spdev = pdev;
|
|
||||||
|
|
||||||
pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node,
|
pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node,
|
||||||
"qcom,hph-en1-gpio", 0);
|
"qcom,hph-en1-gpio", 0);
|
||||||
@@ -8486,15 +8471,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
msm_i2s_auxpcm_init(pdev);
|
msm_i2s_auxpcm_init(pdev);
|
||||||
if (!strcmp(card->name, "sm6150-tavil-snd-card")) {
|
if (strcmp(card->name, "sm6150-tavil-snd-card")) {
|
||||||
is_initial_boot = true;
|
|
||||||
ret = audio_notifier_register("sm6150",
|
|
||||||
AUDIO_NOTIFIER_ADSP_DOMAIN,
|
|
||||||
&service_nb);
|
|
||||||
if (ret < 0)
|
|
||||||
pr_err("%s: Audio notifier register failed ret = %d\n",
|
|
||||||
__func__, ret);
|
|
||||||
} else {
|
|
||||||
pdata->dmic01_gpio_p = of_parse_phandle(pdev->dev.of_node,
|
pdata->dmic01_gpio_p = of_parse_phandle(pdev->dev.of_node,
|
||||||
"qcom,cdc-dmic01-gpios",
|
"qcom,cdc-dmic01-gpios",
|
||||||
0);
|
0);
|
||||||
@@ -8502,13 +8479,19 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|||||||
"qcom,cdc-dmic23-gpios",
|
"qcom,cdc-dmic23-gpios",
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = msm_audio_ssr_register(&pdev->dev);
|
||||||
|
if (ret)
|
||||||
|
pr_err("%s: Registration with SND event FWK failed ret = %d\n",
|
||||||
|
__func__, ret);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int msm_asoc_machine_remove(struct platform_device *pdev)
|
static int msm_asoc_machine_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
audio_notifier_deregister("sm6150");
|
snd_event_master_deregister(&pdev->dev);
|
||||||
msm_i2s_auxpcm_deinit();
|
msm_i2s_auxpcm_deinit();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <soc/snd_event.h>
|
||||||
#include <dsp/audio_notifier.h>
|
#include <dsp/audio_notifier.h>
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
@@ -59,6 +60,7 @@
|
|||||||
#define LPI_GPIO_FUNC_FUNC5 "func5"
|
#define LPI_GPIO_FUNC_FUNC5 "func5"
|
||||||
|
|
||||||
static bool lpi_dev_up;
|
static bool lpi_dev_up;
|
||||||
|
static struct device *lpi_dev;
|
||||||
|
|
||||||
/* The index of each function in lpi_gpio_functions[] array */
|
/* The index of each function in lpi_gpio_functions[] array */
|
||||||
enum lpi_gpio_func_index {
|
enum lpi_gpio_func_index {
|
||||||
@@ -384,12 +386,14 @@ static int lpi_notifier_service_cb(struct notifier_block *this,
|
|||||||
initial_boot = false;
|
initial_boot = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
snd_event_notify(lpi_dev, SND_EVENT_DOWN);
|
||||||
lpi_dev_up = false;
|
lpi_dev_up = false;
|
||||||
break;
|
break;
|
||||||
case AUDIO_NOTIFIER_SERVICE_UP:
|
case AUDIO_NOTIFIER_SERVICE_UP:
|
||||||
if (initial_boot)
|
if (initial_boot)
|
||||||
initial_boot = false;
|
initial_boot = false;
|
||||||
lpi_dev_up = true;
|
lpi_dev_up = true;
|
||||||
|
snd_event_notify(lpi_dev, SND_EVENT_UP);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -402,6 +406,15 @@ static struct notifier_block service_nb = {
|
|||||||
.priority = -INT_MAX,
|
.priority = -INT_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void lpi_pinctrl_ssr_disable(struct device *dev, void *data)
|
||||||
|
{
|
||||||
|
lpi_dev_up = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct snd_event_ops lpi_pinctrl_ssr_ops = {
|
||||||
|
.disable = lpi_pinctrl_ssr_disable,
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
|
||||||
@@ -576,6 +589,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev)
|
|||||||
goto err_range;
|
goto err_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lpi_dev = &pdev->dev;
|
||||||
lpi_dev_up = true;
|
lpi_dev_up = true;
|
||||||
ret = audio_notifier_register("lpi_tlmm", AUDIO_NOTIFIER_ADSP_DOMAIN,
|
ret = audio_notifier_register("lpi_tlmm", AUDIO_NOTIFIER_ADSP_DOMAIN,
|
||||||
&service_nb);
|
&service_nb);
|
||||||
@@ -585,8 +599,19 @@ static int lpi_pinctrl_probe(struct platform_device *pdev)
|
|||||||
goto err_range;
|
goto err_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = snd_event_client_register(dev, &lpi_pinctrl_ssr_ops, NULL);
|
||||||
|
if (!ret) {
|
||||||
|
snd_event_notify(dev, SND_EVENT_UP);
|
||||||
|
} else {
|
||||||
|
dev_err(dev, "%s: snd_event registration failed, ret [%d]\n",
|
||||||
|
__func__, ret);
|
||||||
|
goto err_snd_evt;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_snd_evt:
|
||||||
|
audio_notifier_deregister("lpi_tlmm");
|
||||||
err_range:
|
err_range:
|
||||||
gpiochip_remove(&state->chip);
|
gpiochip_remove(&state->chip);
|
||||||
err_chip:
|
err_chip:
|
||||||
@@ -597,6 +622,7 @@ static int lpi_pinctrl_remove(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct lpi_gpio_state *state = platform_get_drvdata(pdev);
|
struct lpi_gpio_state *state = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
snd_event_client_deregister(&pdev->dev);
|
||||||
audio_notifier_deregister("lpi_tlmm");
|
audio_notifier_deregister("lpi_tlmm");
|
||||||
gpiochip_remove(&state->chip);
|
gpiochip_remove(&state->chip);
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user