diff options
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/fsl_xcvr.c | 25 | ||||
-rw-r--r-- | sound/soc/fsl/imx-card.c | 40 |
2 files changed, 63 insertions, 2 deletions
diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index e3111dd80be4..5d804860f7d8 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -1395,7 +1395,7 @@ static irqreturn_t irq0_isr(int irq, void *devid) if (isr & FSL_XCVR_IRQ_NEW_CS) { dev_dbg(dev, "Received new CS block\n"); isr_clr |= FSL_XCVR_IRQ_NEW_CS; - if (!xcvr->soc_data->spdif_only) { + if (xcvr->soc_data->fw_name) { /* Data RAM is 4KiB, last two pages: 8 and 9. Select page 8. */ regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, FSL_XCVR_EXT_CTRL_PAGE_MASK, @@ -1423,6 +1423,26 @@ static irqreturn_t irq0_isr(int irq, void *devid) /* clear CS control register */ memset_io(reg_ctrl, 0, sizeof(val)); } + } else { + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_0, + (u32 *)&xcvr->rx_iec958.status[0]); + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_1, + (u32 *)&xcvr->rx_iec958.status[4]); + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_2, + (u32 *)&xcvr->rx_iec958.status[8]); + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_3, + (u32 *)&xcvr->rx_iec958.status[12]); + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_4, + (u32 *)&xcvr->rx_iec958.status[16]); + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_5, + (u32 *)&xcvr->rx_iec958.status[20]); + for (i = 0; i < 6; i++) { + val = *(u32 *)(xcvr->rx_iec958.status + i * 4); + *(u32 *)(xcvr->rx_iec958.status + i * 4) = + bitrev32(val); + } + regmap_set_bits(xcvr->regmap, FSL_XCVR_RX_DPTH_CTRL, + FSL_XCVR_RX_DPTH_CTRL_CSA); } } if (isr & FSL_XCVR_IRQ_NEW_UD) { @@ -1497,6 +1517,7 @@ static const struct fsl_xcvr_soc_data fsl_xcvr_imx93_data = { }; static const struct fsl_xcvr_soc_data fsl_xcvr_imx95_data = { + .fw_name = "imx/xcvr/xcvr-imx95.bin", .spdif_only = true, .use_phy = true, .use_edma = true, @@ -1786,7 +1807,7 @@ static int fsl_xcvr_runtime_resume(struct device *dev) } } - if (xcvr->mode == FSL_XCVR_MODE_EARC) { + if (xcvr->soc_data->fw_name) { ret = fsl_xcvr_load_firmware(xcvr); if (ret) { dev_err(dev, "failed to load firmware.\n"); diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c index ea5dbb54b584..28699d7b75ca 100644 --- a/sound/soc/fsl/imx-card.c +++ b/sound/soc/fsl/imx-card.c @@ -26,6 +26,7 @@ enum codec_type { CODEC_AK4497, CODEC_AK5552, CODEC_CS42888, + CODEC_WM8524, }; /* @@ -196,6 +197,13 @@ static struct imx_akcodec_tdm_fs_mul cs42888_tdm_fs_mul[] = { { .min = 256, .max = 256, .mul = 256 }, }; +static struct imx_akcodec_fs_mul wm8524_fs_mul[] = { + { .rmin = 8000, .rmax = 32000, .wmin = 256, .wmax = 1152, }, + { .rmin = 44100, .rmax = 48000, .wmin = 256, .wmax = 768, }, + { .rmin = 88200, .rmax = 96000, .wmin = 128, .wmax = 384, }, + { .rmin = 176400, .rmax = 192000, .wmin = 128, .wmax = 192, }, +}; + static const u32 akcodec_rates[] = { 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000, @@ -229,6 +237,10 @@ static const u32 cs42888_tdm_channels[] = { 1, 2, 3, 4, 5, 6, 7, 8, }; +static const u32 wm8524_channels[] = { + 2, +}; + static bool format_is_dsd(struct snd_pcm_hw_params *params) { snd_pcm_format_t format = params_format(params); @@ -261,6 +273,7 @@ static bool codec_is_akcodec(unsigned int type) case CODEC_AK5558: case CODEC_AK5552: case CODEC_CS42888: + case CODEC_WM8524: return true; default: break; @@ -477,9 +490,24 @@ static int imx_aif_startup(struct snd_pcm_substream *substream) return ret; } +static void imx_aif_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *cpu_dai; + struct snd_soc_dai *codec_dai; + int i; + + for_each_rtd_cpu_dais(rtd, i, cpu_dai) + snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_OUT); + + for_each_rtd_codec_dais(rtd, i, codec_dai) + snd_soc_dai_set_sysclk(codec_dai, 0, 0, SND_SOC_CLOCK_IN); +} + static const struct snd_soc_ops imx_aif_ops = { .hw_params = imx_aif_hw_params, .startup = imx_aif_startup, + .shutdown = imx_aif_shutdown, }; static const struct snd_soc_ops imx_aif_ops_be = { @@ -632,6 +660,8 @@ static int imx_card_parse_of(struct imx_card_data *data) plat_data->type = CODEC_AK5552; else if (!strcmp(link->codecs->dai_name, "cs42888")) plat_data->type = CODEC_CS42888; + else if (!strcmp(link->codecs->dai_name, "wm8524-hifi")) + plat_data->type = CODEC_WM8524; } else { link->codecs = &snd_soc_dummy_dlc; @@ -805,6 +835,10 @@ static int imx_card_probe(struct platform_device *pdev) data->dapm_routes[1].sink = "CPU-Capture"; data->dapm_routes[1].source = "Capture"; break; + case CODEC_WM8524: + data->dapm_routes[0].sink = "Playback"; + data->dapm_routes[0].source = "CPU-Playback"; + break; default: break; } @@ -854,6 +888,12 @@ static int imx_card_probe(struct platform_device *pdev) plat_data->support_tdm_channels = cs42888_tdm_channels; plat_data->num_tdm_channels = ARRAY_SIZE(cs42888_tdm_channels); break; + case CODEC_WM8524: + plat_data->fs_mul = wm8524_fs_mul; + plat_data->num_fs_mul = ARRAY_SIZE(wm8524_fs_mul); + plat_data->support_channels = wm8524_channels; + plat_data->num_channels = ARRAY_SIZE(wm8524_channels); + break; default: break; } |