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

ASoC: ak4458: Add DSD support for ak4458 and ak4497

Ak4458 can't support DSD512 format, but ak4497 can, so add
a new enum variable (enum ak4458_type) in ak4458_drvdata to
distinguish these two platforms.

Ak4497 has two kinds of DSD input pin, it can be selected by
the dsd-path property from DT.

In hw_params(), bit clock is calculated according to different
DSD format (DSD64, DSD128, DSD256, DSD512), then registers
are configured.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Link: https://lore.kernel.org/r/1600178220-28973-2-git-send-email-shengjiu.wang@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Shengjiu Wang and committed by
Mark Brown
337d348b fc50e26d

+86 -8
+82 -7
sound/soc/codecs/ak4458.c
··· 28 28 "AVDD", 29 29 }; 30 30 31 + enum ak4458_type { 32 + AK4458 = 0, 33 + AK4497 = 1, 34 + }; 35 + 31 36 struct ak4458_drvdata { 32 37 struct snd_soc_dai_driver *dai_drv; 33 38 const struct snd_soc_component_driver *comp_drv; 39 + enum ak4458_type type; 34 40 }; 35 41 36 42 /* AK4458 Codec Private Data */ 37 43 struct ak4458_priv { 38 44 struct regulator_bulk_data supplies[AK4458_NUM_SUPPLIES]; 45 + const struct ak4458_drvdata *drvdata; 39 46 struct device *dev; 40 47 struct regmap *regmap; 41 48 struct gpio_desc *reset_gpiod; ··· 52 45 int fmt; 53 46 int slots; 54 47 int slot_width; 48 + u32 dsd_path; /* For ak4497 */ 55 49 }; 56 50 57 51 static const struct reg_default ak4458_reg_defaults[] = { ··· 333 325 struct snd_soc_component *component = dai->component; 334 326 struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component); 335 327 int pcm_width = max(params_physical_width(params), ak4458->slot_width); 336 - int nfs1; 337 - u8 format; 328 + u8 format, dsdsel0, dsdsel1; 329 + int nfs1, dsd_bclk; 338 330 339 331 nfs1 = params_rate(params); 340 332 ak4458->fs = nfs1; 333 + 334 + /* calculate bit clock */ 335 + switch (params_format(params)) { 336 + case SNDRV_PCM_FORMAT_DSD_U8: 337 + case SNDRV_PCM_FORMAT_DSD_U16_LE: 338 + case SNDRV_PCM_FORMAT_DSD_U16_BE: 339 + case SNDRV_PCM_FORMAT_DSD_U32_LE: 340 + case SNDRV_PCM_FORMAT_DSD_U32_BE: 341 + dsd_bclk = nfs1 * params_physical_width(params); 342 + switch (dsd_bclk) { 343 + case 2822400: 344 + dsdsel0 = 0; 345 + dsdsel1 = 0; 346 + break; 347 + case 5644800: 348 + dsdsel0 = 1; 349 + dsdsel1 = 0; 350 + break; 351 + case 11289600: 352 + dsdsel0 = 0; 353 + dsdsel1 = 1; 354 + break; 355 + case 22579200: 356 + if (ak4458->drvdata->type == AK4497) { 357 + dsdsel0 = 1; 358 + dsdsel1 = 1; 359 + } else { 360 + dev_err(dai->dev, "DSD512 not supported.\n"); 361 + return -EINVAL; 362 + } 363 + break; 364 + default: 365 + dev_err(dai->dev, "Unsupported dsd bclk.\n"); 366 + return -EINVAL; 367 + } 368 + 369 + snd_soc_component_update_bits(component, AK4458_06_DSD1, 370 + AK4458_DSDSEL_MASK, dsdsel0); 371 + snd_soc_component_update_bits(component, AK4458_09_DSD2, 372 + AK4458_DSDSEL_MASK, dsdsel1); 373 + break; 374 + } 341 375 342 376 /* Master Clock Frequency Auto Setting Mode Enable */ 343 377 snd_soc_component_update_bits(component, AK4458_00_CONTROL1, 0x80, 0x80); ··· 403 353 format = AK4458_DIF_32BIT_LSB; 404 354 break; 405 355 case SND_SOC_DAIFMT_DSP_B: 356 + format = AK4458_DIF_32BIT_MSB; 357 + break; 358 + case SND_SOC_DAIFMT_PDM: 406 359 format = AK4458_DIF_32BIT_MSB; 407 360 break; 408 361 default: ··· 446 393 case SND_SOC_DAIFMT_LEFT_J: 447 394 case SND_SOC_DAIFMT_RIGHT_J: 448 395 case SND_SOC_DAIFMT_DSP_B: 396 + case SND_SOC_DAIFMT_PDM: 449 397 ak4458->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; 450 398 break; 451 399 default: ··· 454 400 fmt & SND_SOC_DAIFMT_FORMAT_MASK); 455 401 return -EINVAL; 456 402 } 403 + 404 + /* DSD mode */ 405 + snd_soc_component_update_bits(component, AK4458_02_CONTROL3, 406 + AK4458_DP_MASK, 407 + ak4458->fmt == SND_SOC_DAIFMT_PDM ? 408 + AK4458_DP_MASK : 0); 457 409 458 410 ak4458_rstn_control(component, 0); 459 411 ak4458_rstn_control(component, 1); ··· 532 472 533 473 #define AK4458_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 534 474 SNDRV_PCM_FMTBIT_S24_LE |\ 535 - SNDRV_PCM_FMTBIT_S32_LE) 475 + SNDRV_PCM_FMTBIT_S32_LE |\ 476 + SNDRV_PCM_FMTBIT_DSD_U8 |\ 477 + SNDRV_PCM_FMTBIT_DSD_U16_LE |\ 478 + SNDRV_PCM_FMTBIT_DSD_U32_LE) 536 479 537 480 static const unsigned int ak4458_rates[] = { 538 481 8000, 11025, 16000, 22050, ··· 626 563 0x80, 0x80); /* ACKS bit = 1; 10000000 */ 627 564 if (ret < 0) 628 565 return ret; 566 + 567 + if (ak4458->drvdata->type == AK4497) { 568 + ret = snd_soc_component_update_bits(component, AK4458_09_DSD2, 569 + 0x4, (ak4458->dsd_path << 2)); 570 + if (ret < 0) 571 + return ret; 572 + } 629 573 630 574 return ak4458_rstn_control(component, 1); 631 575 } ··· 738 668 static const struct ak4458_drvdata ak4458_drvdata = { 739 669 .dai_drv = &ak4458_dai, 740 670 .comp_drv = &soc_codec_dev_ak4458, 671 + .type = AK4458, 741 672 }; 742 673 743 674 static const struct ak4458_drvdata ak4497_drvdata = { 744 675 .dai_drv = &ak4497_dai, 745 676 .comp_drv = &soc_codec_dev_ak4497, 677 + .type = AK4497, 746 678 }; 747 679 748 680 static const struct dev_pm_ops ak4458_pm = { ··· 756 684 static int ak4458_i2c_probe(struct i2c_client *i2c) 757 685 { 758 686 struct ak4458_priv *ak4458; 759 - const struct ak4458_drvdata *drvdata; 760 687 int ret, i; 761 688 762 689 ak4458 = devm_kzalloc(&i2c->dev, sizeof(*ak4458), GFP_KERNEL); ··· 769 698 i2c_set_clientdata(i2c, ak4458); 770 699 ak4458->dev = &i2c->dev; 771 700 772 - drvdata = of_device_get_match_data(&i2c->dev); 701 + ak4458->drvdata = of_device_get_match_data(&i2c->dev); 773 702 774 703 ak4458->reset_gpiod = devm_gpiod_get_optional(ak4458->dev, "reset", 775 704 GPIOD_OUT_LOW); ··· 781 710 if (IS_ERR(ak4458->mute_gpiod)) 782 711 return PTR_ERR(ak4458->mute_gpiod); 783 712 713 + /* Optional property for ak4497 */ 714 + of_property_read_u32(i2c->dev.of_node, "dsd-path", &ak4458->dsd_path); 715 + 784 716 for (i = 0; i < ARRAY_SIZE(ak4458->supplies); i++) 785 717 ak4458->supplies[i].supply = ak4458_supply_names[i]; 786 718 ··· 794 720 return ret; 795 721 } 796 722 797 - ret = devm_snd_soc_register_component(ak4458->dev, drvdata->comp_drv, 798 - drvdata->dai_drv, 1); 723 + ret = devm_snd_soc_register_component(ak4458->dev, 724 + ak4458->drvdata->comp_drv, 725 + ak4458->drvdata->dai_drv, 1); 799 726 if (ret < 0) { 800 727 dev_err(ak4458->dev, "Failed to register CODEC: %d\n", ret); 801 728 return ret;
+4 -1
sound/soc/codecs/ak4458.h
··· 83 83 #define AK4458_ATS_SHIFT 6 84 84 #define AK4458_ATS_MASK GENMASK(7, 6) 85 85 86 - #endif /* _AK4458_H */ 86 + #define AK4458_DSDSEL_MASK (0x1 << 0) 87 + #define AK4458_DP_MASK (0x1 << 7) 88 + 89 + #endif