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

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: sun4i-spdif: Add 24bit support

Merge series from codekipper@gmail.com:

I've tested this patch series on the Allwinner H3, A64, H6 and H313 SoCs
up to 192KHz.
24bit support is working on my H313 board but 16bit plays a bit slow and
I suspect that there is an issue with the clock setups. This is even
present without this patch stack. I would look to address this asap,
but for now can you please review what's here.

+18 -6
+18 -6
sound/soc/sunxi/sun4i-spdif.c
··· 176 176 unsigned int reg_dac_txdata; 177 177 bool has_reset; 178 178 unsigned int val_fctl_ftx; 179 + unsigned int mclk_multiplier; 179 180 }; 180 181 181 182 struct sun4i_spdif_dev { ··· 201 200 /* flush TX FIFO */ 202 201 regmap_update_bits(host->regmap, SUN4I_SPDIF_FCTL, 203 202 quirks->val_fctl_ftx, quirks->val_fctl_ftx); 203 + 204 + /* Valid data at the MSB of TXFIFO Register */ 205 + regmap_update_bits(host->regmap, SUN4I_SPDIF_FCTL, 206 + SUN4I_SPDIF_FCTL_TXIM, 0); 204 207 205 208 /* clear TX counter */ 206 209 regmap_write(host->regmap, SUN4I_SPDIF_TXCNT, 0); ··· 287 282 return -EINVAL; 288 283 } 289 284 285 + host->dma_params_tx.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 290 286 switch (params_format(params)) { 291 287 case SNDRV_PCM_FORMAT_S16_LE: 292 288 fmt |= SUN4I_SPDIF_TXCFG_FMT16BIT; 289 + host->dma_params_tx.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 293 290 break; 294 291 case SNDRV_PCM_FORMAT_S20_3LE: 295 292 fmt |= SUN4I_SPDIF_TXCFG_FMT20BIT; 296 293 break; 297 294 case SNDRV_PCM_FORMAT_S24_LE: 295 + case SNDRV_PCM_FORMAT_S32_LE: 298 296 fmt |= SUN4I_SPDIF_TXCFG_FMT24BIT; 299 297 break; 300 298 default: ··· 321 313 default: 322 314 return -EINVAL; 323 315 } 316 + mclk *= host->quirks->mclk_multiplier; 324 317 325 318 ret = clk_set_rate(host->spdif_clk, mclk); 326 319 if (ret < 0) { ··· 329 320 "Setting SPDIF clock rate for %d Hz failed!\n", mclk); 330 321 return ret; 331 322 } 332 - 333 - regmap_update_bits(host->regmap, SUN4I_SPDIF_FCTL, 334 - SUN4I_SPDIF_FCTL_TXIM, SUN4I_SPDIF_FCTL_TXIM); 335 323 336 324 switch (rate) { 337 325 case 22050: ··· 353 347 default: 354 348 return -EINVAL; 355 349 } 350 + mclk_div *= host->quirks->mclk_multiplier; 356 351 357 352 reg_val = 0; 358 353 reg_val |= SUN4I_SPDIF_TXCFG_ASS; ··· 529 522 530 523 #define SUN4I_RATES SNDRV_PCM_RATE_8000_192000 531 524 532 - #define SUN4I_FORMATS (SNDRV_PCM_FORMAT_S16_LE | \ 533 - SNDRV_PCM_FORMAT_S20_3LE | \ 534 - SNDRV_PCM_FORMAT_S24_LE) 525 + #define SUN4I_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 526 + SNDRV_PCM_FMTBIT_S20_3LE | \ 527 + SNDRV_PCM_FMTBIT_S24_LE | \ 528 + SNDRV_PCM_FMTBIT_S32_LE) 535 529 536 530 static struct snd_soc_dai_driver sun4i_spdif_dai = { 537 531 .playback = { ··· 548 540 static const struct sun4i_spdif_quirks sun4i_a10_spdif_quirks = { 549 541 .reg_dac_txdata = SUN4I_SPDIF_TXFIFO, 550 542 .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, 543 + .mclk_multiplier = 1, 551 544 }; 552 545 553 546 static const struct sun4i_spdif_quirks sun6i_a31_spdif_quirks = { 554 547 .reg_dac_txdata = SUN4I_SPDIF_TXFIFO, 555 548 .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, 556 549 .has_reset = true, 550 + .mclk_multiplier = 1, 557 551 }; 558 552 559 553 static const struct sun4i_spdif_quirks sun8i_h3_spdif_quirks = { 560 554 .reg_dac_txdata = SUN8I_SPDIF_TXFIFO, 561 555 .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, 562 556 .has_reset = true, 557 + .mclk_multiplier = 4, 563 558 }; 564 559 565 560 static const struct sun4i_spdif_quirks sun50i_h6_spdif_quirks = { 566 561 .reg_dac_txdata = SUN8I_SPDIF_TXFIFO, 567 562 .val_fctl_ftx = SUN50I_H6_SPDIF_FCTL_FTX, 568 563 .has_reset = true, 564 + .mclk_multiplier = 1, 569 565 }; 570 566 571 567 static const struct of_device_id sun4i_spdif_of_match[] = {