From b0f27cd9f094f11c23fc543abad0e8be4c8c9e8a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 6 Sep 2018 12:17:11 +0530 Subject: [PATCH 1/2] soc: swr-mstr: add changes to support native playback For MCLK frequency switching to 11.2896 for native playback support, frameshape also needs to be changed accordingly. Add changes to support frameshape switch based on mclk frequency for given master. Change-Id: I0c4dd69b743f83b45eeed73f27ad10e878b9244b Signed-off-by: Laxminath Kasam --- include/soc/swr-wcd.h | 4 ++++ soc/swr-mstr-ctrl.c | 21 ++++++++++++++++++++- soc/swr-mstr-ctrl.h | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h index 360815043709..75d0e6512267 100644 --- a/include/soc/swr-wcd.h +++ b/include/soc/swr-wcd.h @@ -23,6 +23,7 @@ enum { SWR_DEVICE_UP, SWR_SUBSYS_RESTART, SWR_SET_NUM_RX_CH, + SWR_CLK_FREQ, }; struct swr_mstr_port { @@ -30,6 +31,9 @@ struct swr_mstr_port { u8 *port; }; +#define MCLK_FREQ 9600000 +#define MCLK_FREQ_NATIVE 11289600 + #if (IS_ENABLED(CONFIG_SOUNDWIRE_WCD_CTRL) || \ IS_ENABLED(CONFIG_SOUNDWIRE_MSTR_CTRL)) extern int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data); diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 26cc1f45d9f5..d3fb08769850 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -956,7 +956,15 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) n_col = SWR_MAX_COL; } /* Use default 50 * x, frame shape. Change based on mclk */ - n_row = SWR_ROW_50; + if (swrm->mclk_freq == MCLK_FREQ_NATIVE) { + dev_dbg(swrm->dev, "setting 64 x %d frameshape\n", + n_col ? 16 : 2); + n_row = SWR_ROW_64; + } else { + dev_dbg(swrm->dev, "setting 50 x %d frameshape\n", + n_col ? 16 : 2); + n_row = SWR_ROW_50; + } value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank)); value &= (~mask); value |= ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | @@ -1630,6 +1638,7 @@ static int swrm_probe(struct platform_device *pdev) swrm->slave_status = 0; swrm->num_rx_chs = 0; swrm->clk_ref_count = 0; + swrm->mclk_freq = MCLK_FREQ; swrm->state = SWR_MSTR_RESUME; init_completion(&swrm->reset); init_completion(&swrm->broadcast); @@ -1940,6 +1949,16 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) mstr = &swrm->master; switch (id) { + case SWR_CLK_FREQ: + if (!data) { + dev_err(swrm->dev, "%s: data is NULL\n", __func__); + ret = -EINVAL; + } else { + mutex_lock(&swrm->mlock); + swrm->mclk_freq = *(int *)data; + mutex_unlock(&swrm->mlock); + } + break; case SWR_DEVICE_DOWN: dev_dbg(swrm->dev, "%s: swr master down called\n", __func__); mutex_lock(&swrm->mlock); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index fd133928593c..b3dfd7d3a3d1 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -129,6 +129,7 @@ struct swr_mstr_ctrl { void *data), void *swr_handle, int type); int irq; int version; + int mclk_freq; u32 num_dev; int slave_status; struct swrm_mports mport_cfg[SWR_MAX_MSTR_PORT_NUM]; From ac396d57341557943e4cf8a6dee4303d1e1147f1 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 6 Sep 2018 12:53:26 +0530 Subject: [PATCH 2/2] asoc: bolero: add support for native playback On bolero rx macro, add support to switch mclk frequency based on native usecase active. Change-Id: I2f915475dcfdadf1027507b7ed83a4a852ece1c7 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 76 +++++++++++++++++------------------ 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index fbacdc028375..006f863bd0aa 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -44,6 +44,11 @@ SNDRV_PCM_FMTBIT_S24_LE |\ SNDRV_PCM_FMTBIT_S24_3LE) +#define SAMPLING_RATE_44P1KHZ 44100 +#define SAMPLING_RATE_88P2KHZ 88200 +#define SAMPLING_RATE_176P4KHZ 176400 +#define SAMPLING_RATE_352P8KHZ 352800 + #define RX_MACRO_MAX_OFFSET 0x1000 #define RX_MACRO_MAX_DMA_CH_PER_PORT 2 @@ -312,10 +317,6 @@ static const char *const rx_macro_mux_text[] = { "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB" }; -static const char *const rx_macro_native_text[] = {"OFF", "ON"}; -static const struct soc_enum rx_macro_native_enum = - SOC_ENUM_SINGLE_EXT(2, rx_macro_native_text); - static const char *const rx_macro_ear_mode_text[] = {"OFF", "ON"}; static const struct soc_enum rx_macro_ear_mode_enum = SOC_ENUM_SINGLE_EXT(2, rx_macro_ear_mode_text); @@ -642,16 +643,40 @@ static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, return 0; } +static bool rx_macro_is_fractional_sample_rate(u32 sample_rate) +{ + switch (sample_rate) { + case SAMPLING_RATE_44P1KHZ: + case SAMPLING_RATE_88P2KHZ: + case SAMPLING_RATE_176P4KHZ: + case SAMPLING_RATE_352P8KHZ: + return true; + default: + return false; + } + return false; +} + static int rx_macro_set_interpolator_rate(struct snd_soc_dai *dai, u32 sample_rate) { struct snd_soc_codec *codec = dai->codec; int rate_val = 0; int i = 0, ret = 0; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) { if (sample_rate == sr_val_tbl[i].sample_rate) { rate_val = sr_val_tbl[i].rate_val; + if (rx_macro_is_fractional_sample_rate(sample_rate)) + rx_priv->is_native_on = true; + else + rx_priv->is_native_on = false; break; } } @@ -748,7 +773,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, dev_dbg(rx_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", __func__, mclk_enable, dapm, rx_priv->rx_mclk_users); - if(rx_priv->is_native_on) + if (rx_priv->is_native_on) mclk_mux = MCLK_MUX1; mutex_lock(&rx_priv->mclk_lock); if (mclk_enable) { @@ -809,6 +834,7 @@ static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, int ret = 0; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; + int mclk_freq = MCLK_FREQ; if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) return -EINVAL; @@ -820,13 +846,18 @@ static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, if (rx_priv->swr_clk_users > 0) { if ((rx_priv->mclk_mux == MCLK_MUX0 && rx_priv->is_native_on) || - (rx_priv->mclk_mux == MCLK_MUX1 && + (rx_priv->mclk_mux == MCLK_MUX1 && !rx_priv->is_native_on)) { swrm_wcd_notify( rx_priv->swr_ctrl_data[0].rx_swr_pdev, SWR_DEVICE_DOWN, NULL); } } + if (rx_priv->is_native_on) + mclk_freq = MCLK_FREQ_NATIVE; + swrm_wcd_notify( + rx_priv->swr_ctrl_data[0].rx_swr_pdev, + SWR_CLK_FREQ, &mclk_freq); ret = rx_macro_mclk_enable(rx_priv, 1, true); break; case SND_SOC_DAPM_POST_PMD: @@ -1331,36 +1362,6 @@ err: return -EINVAL; } -static int rx_macro_get_native(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct device *rx_dev = NULL; - struct rx_macro_priv *rx_priv = NULL; - - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) - return -EINVAL; - - ucontrol->value.integer.value[0] = - (rx_priv->is_native_on == true ? 1 : 0); - return 0; -} - -static int rx_macro_put_native(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct device *rx_dev = NULL; - struct rx_macro_priv *rx_priv = NULL; - - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) - return -EINVAL; - - rx_priv->is_native_on = - (!ucontrol->value.integer.value[0] ? false : true); - return 0; -} - static int rx_macro_get_ear_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1877,9 +1878,6 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_SINGLE_EXT("RX_COMP2 Switch", SND_SOC_NOPM, RX_MACRO_COMP2, 1, 0, rx_macro_get_compander, rx_macro_set_compander), - SOC_ENUM_EXT("RX_Native", rx_macro_native_enum, rx_macro_get_native, - rx_macro_put_native), - SOC_ENUM_EXT("RX_EAR Mode", rx_macro_ear_mode_enum, rx_macro_get_ear_mode, rx_macro_put_ear_mode),