Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: ak4458: enable daisy chain

Enable Daisy Chain if in TDM mode and the number of played
channels is bigger than the maximum supported number of channels.

Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Link: https://lore.kernel.org/r/1618915453-29445-1-git-send-email-shengjiu.wang@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Viorel Suman and committed by
Mark Brown
7342db3c ec1af6c6

+32 -16
+31 -16
sound/soc/codecs/ak4458.c
··· 306 306 307 307 }; 308 308 309 + static int ak4458_get_tdm_mode(struct ak4458_priv *ak4458) 310 + { 311 + switch (ak4458->slots * ak4458->slot_width) { 312 + case 128: 313 + return 1; 314 + case 256: 315 + return 2; 316 + case 512: 317 + return 3; 318 + default: 319 + return 0; 320 + } 321 + } 322 + 309 323 static int ak4458_rstn_control(struct snd_soc_component *component, int bit) 310 324 { 311 325 int ret; ··· 347 333 struct snd_soc_component *component = dai->component; 348 334 struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component); 349 335 int pcm_width = max(params_physical_width(params), ak4458->slot_width); 350 - u8 format, dsdsel0, dsdsel1; 351 - int nfs1, dsd_bclk, ret; 336 + u8 format, dsdsel0, dsdsel1, dchn; 337 + int nfs1, dsd_bclk, ret, channels, channels_max; 352 338 353 339 nfs1 = params_rate(params); 354 340 ak4458->fs = nfs1; 355 341 356 342 /* calculate bit clock */ 343 + channels = params_channels(params); 344 + channels_max = dai->driver->playback.channels_max; 345 + 357 346 switch (params_format(params)) { 358 347 case SNDRV_PCM_FORMAT_DSD_U8: 359 348 case SNDRV_PCM_FORMAT_DSD_U16_LE: ··· 435 418 436 419 snd_soc_component_update_bits(component, AK4458_00_CONTROL1, 437 420 AK4458_DIF_MASK, format); 421 + 422 + /* 423 + * Enable/disable Daisy Chain if in TDM mode and the number of played 424 + * channels is bigger than the maximum supported number of channels 425 + */ 426 + dchn = ak4458_get_tdm_mode(ak4458) && 427 + (ak4458->fmt == SND_SOC_DAIFMT_DSP_B) && 428 + (channels > channels_max) ? AK4458_DCHAIN_MASK : 0; 429 + 430 + snd_soc_component_update_bits(component, AK4458_0B_CONTROL7, 431 + AK4458_DCHAIN_MASK, dchn); 438 432 439 433 ret = ak4458_rstn_control(component, 0); 440 434 if (ret) ··· 547 519 ak4458->slots = slots; 548 520 ak4458->slot_width = slot_width; 549 521 550 - switch (slots * slot_width) { 551 - case 128: 552 - mode = AK4458_MODE_TDM128; 553 - break; 554 - case 256: 555 - mode = AK4458_MODE_TDM256; 556 - break; 557 - case 512: 558 - mode = AK4458_MODE_TDM512; 559 - break; 560 - default: 561 - mode = AK4458_MODE_NORMAL; 562 - break; 563 - } 522 + mode = ak4458_get_tdm_mode(ak4458) << AK4458_MODE_SHIFT; 564 523 565 524 snd_soc_component_update_bits(component, AK4458_0A_CONTROL6, 566 525 AK4458_MODE_MASK,
+1
sound/soc/codecs/ak4458.h
··· 82 82 * */ 83 83 #define AK4458_ATS_SHIFT 6 84 84 #define AK4458_ATS_MASK GENMASK(7, 6) 85 + #define AK4458_DCHAIN_MASK (0x1 << 1) 85 86 86 87 #define AK4458_DSDSEL_MASK (0x1 << 0) 87 88 #define AK4458_DP_MASK (0x1 << 7)