| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * DesignWare HDMI audio driver |
|---|
| 3 | | - * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 5 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 6 | | - * published by the Free Software Foundation. |
|---|
| 7 | 4 | * |
|---|
| 8 | 5 | * Written and tested against the Designware HDMI Tx found in iMX6. |
|---|
| 9 | 6 | */ |
|---|
| .. | .. |
|---|
| 66 | 63 | HDMI_REVISION_ID = 0x0001, |
|---|
| 67 | 64 | HDMI_IH_AHBDMAAUD_STAT0 = 0x0109, |
|---|
| 68 | 65 | HDMI_IH_MUTE_AHBDMAAUD_STAT0 = 0x0189, |
|---|
| 69 | | - HDMI_FC_AUDICONF2 = 0x1027, |
|---|
| 70 | | - HDMI_FC_AUDSCONF = 0x1063, |
|---|
| 71 | | - HDMI_FC_AUDSCONF_LAYOUT1 = 1 << 0, |
|---|
| 72 | | - HDMI_FC_AUDSCONF_LAYOUT0 = 0 << 0, |
|---|
| 73 | 66 | HDMI_AHB_DMA_CONF0 = 0x3600, |
|---|
| 74 | 67 | HDMI_AHB_DMA_START = 0x3601, |
|---|
| 75 | 68 | HDMI_AHB_DMA_STOP = 0x3602, |
|---|
| .. | .. |
|---|
| 298 | 291 | return IRQ_HANDLED; |
|---|
| 299 | 292 | } |
|---|
| 300 | 293 | |
|---|
| 301 | | -static struct snd_pcm_hardware dw_hdmi_hw = { |
|---|
| 294 | +static const struct snd_pcm_hardware dw_hdmi_hw = { |
|---|
| 302 | 295 | .info = SNDRV_PCM_INFO_INTERLEAVED | |
|---|
| 303 | 296 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
|---|
| 304 | 297 | SNDRV_PCM_INFO_MMAP | |
|---|
| .. | .. |
|---|
| 327 | 320 | struct snd_pcm_runtime *runtime = substream->runtime; |
|---|
| 328 | 321 | struct snd_dw_hdmi *dw = substream->private_data; |
|---|
| 329 | 322 | void __iomem *base = dw->data.base; |
|---|
| 323 | + u8 *eld; |
|---|
| 330 | 324 | int ret; |
|---|
| 331 | 325 | |
|---|
| 332 | 326 | runtime->hw = dw_hdmi_hw; |
|---|
| 333 | 327 | |
|---|
| 334 | | - ret = snd_pcm_hw_constraint_eld(runtime, dw->data.eld); |
|---|
| 335 | | - if (ret < 0) |
|---|
| 336 | | - return ret; |
|---|
| 328 | + eld = dw->data.get_eld(dw->data.hdmi); |
|---|
| 329 | + if (eld) { |
|---|
| 330 | + ret = snd_pcm_hw_constraint_eld(runtime, eld); |
|---|
| 331 | + if (ret < 0) |
|---|
| 332 | + return ret; |
|---|
| 333 | + } |
|---|
| 337 | 334 | |
|---|
| 338 | 335 | ret = snd_pcm_limit_hw_rates(runtime); |
|---|
| 339 | 336 | if (ret < 0) |
|---|
| .. | .. |
|---|
| 406 | 403 | { |
|---|
| 407 | 404 | struct snd_pcm_runtime *runtime = substream->runtime; |
|---|
| 408 | 405 | struct snd_dw_hdmi *dw = substream->private_data; |
|---|
| 409 | | - u8 threshold, conf0, conf1, layout, ca; |
|---|
| 406 | + u8 threshold, conf0, conf1, ca; |
|---|
| 410 | 407 | |
|---|
| 411 | 408 | /* Setup as per 3.0.5 FSL 4.1.0 BSP */ |
|---|
| 412 | 409 | switch (dw->revision) { |
|---|
| .. | .. |
|---|
| 437 | 434 | conf1 = default_hdmi_channel_config[runtime->channels - 2].conf1; |
|---|
| 438 | 435 | ca = default_hdmi_channel_config[runtime->channels - 2].ca; |
|---|
| 439 | 436 | |
|---|
| 440 | | - /* |
|---|
| 441 | | - * For >2 channel PCM audio, we need to select layout 1 |
|---|
| 442 | | - * and set an appropriate channel map. |
|---|
| 443 | | - */ |
|---|
| 444 | | - if (runtime->channels > 2) |
|---|
| 445 | | - layout = HDMI_FC_AUDSCONF_LAYOUT1; |
|---|
| 446 | | - else |
|---|
| 447 | | - layout = HDMI_FC_AUDSCONF_LAYOUT0; |
|---|
| 448 | | - |
|---|
| 449 | 437 | writeb_relaxed(threshold, dw->data.base + HDMI_AHB_DMA_THRSLD); |
|---|
| 450 | 438 | writeb_relaxed(conf0, dw->data.base + HDMI_AHB_DMA_CONF0); |
|---|
| 451 | 439 | writeb_relaxed(conf1, dw->data.base + HDMI_AHB_DMA_CONF1); |
|---|
| 452 | | - writeb_relaxed(layout, dw->data.base + HDMI_FC_AUDSCONF); |
|---|
| 453 | | - writeb_relaxed(ca, dw->data.base + HDMI_FC_AUDICONF2); |
|---|
| 440 | + |
|---|
| 441 | + dw_hdmi_set_channel_count(dw->data.hdmi, runtime->channels); |
|---|
| 442 | + dw_hdmi_set_channel_allocation(dw->data.hdmi, ca); |
|---|
| 454 | 443 | |
|---|
| 455 | 444 | switch (runtime->format) { |
|---|
| 456 | 445 | case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE: |
|---|
| .. | .. |
|---|
| 614 | 603 | struct snd_dw_hdmi *dw = dev_get_drvdata(dev); |
|---|
| 615 | 604 | |
|---|
| 616 | 605 | snd_power_change_state(dw->card, SNDRV_CTL_POWER_D3cold); |
|---|
| 617 | | - snd_pcm_suspend_all(dw->pcm); |
|---|
| 618 | 606 | |
|---|
| 619 | 607 | return 0; |
|---|
| 620 | 608 | } |
|---|
| .. | .. |
|---|
| 646 | 634 | |
|---|
| 647 | 635 | module_platform_driver(snd_dw_hdmi_driver); |
|---|
| 648 | 636 | |
|---|
| 649 | | -MODULE_AUTHOR("Russell King <rmk+kernel@arm.linux.org.uk>"); |
|---|
| 637 | +MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>"); |
|---|
| 650 | 638 | MODULE_DESCRIPTION("Synopsis Designware HDMI AHB ALSA interface"); |
|---|
| 651 | 639 | MODULE_LICENSE("GPL v2"); |
|---|
| 652 | 640 | MODULE_ALIAS("platform:" DRIVER_NAME); |
|---|