aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-02-12 12:37:26 -0500
committerTakashi Iwai <tiwai@suse.de>2008-04-24 06:00:10 -0400
commit9a08160bdbe3148a405f72798f76e2a5d30bd243 (patch)
tree33b6785feb1fda1d381a74ef19eb26c983650749 /sound/pci/hda/hda_codec.c
parentf6c7e5461e9046445d50c5c7a9a4587824239623 (diff)
[ALSA] hda-codec - Add "IEC958 Default PCM" switch
Added a new mixer switch to enable/disable the sharing of the default PCM stream with analog and SPDIF outputs. When "IEC958 Default PCM" switch is on, the PCM stream is routed both to analog and SPDIF outputs. This is the behavior in the earlier version. Turning this switch off has a merit for some codecs, though. Some codec chips don't support 24bit formats for SPDIF but only for analog outputs. In this case, you can use 24bit format by disabling this switch. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c73
1 files changed, 69 insertions, 4 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index af2c8943b303..853e5c786c37 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1533,6 +1533,43 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
1533} 1533}
1534 1534
1535/* 1535/*
1536 * SPDIF sharing with analog output
1537 */
1538static int spdif_share_sw_get(struct snd_kcontrol *kcontrol,
1539 struct snd_ctl_elem_value *ucontrol)
1540{
1541 struct hda_multi_out *mout = snd_kcontrol_chip(kcontrol);
1542 ucontrol->value.integer.value[0] = mout->share_spdif;
1543 return 0;
1544}
1545
1546static int spdif_share_sw_put(struct snd_kcontrol *kcontrol,
1547 struct snd_ctl_elem_value *ucontrol)
1548{
1549 struct hda_multi_out *mout = snd_kcontrol_chip(kcontrol);
1550 mout->share_spdif = !!ucontrol->value.integer.value[0];
1551 return 0;
1552}
1553
1554static struct snd_kcontrol_new spdif_share_sw = {
1555 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1556 .name = "IEC958 Default PCM Playback Switch",
1557 .info = snd_ctl_boolean_mono_info,
1558 .get = spdif_share_sw_get,
1559 .put = spdif_share_sw_put,
1560};
1561
1562int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
1563 struct hda_multi_out *mout)
1564{
1565 if (!mout->dig_out_nid)
1566 return 0;
1567 /* ATTENTION: here mout is passed as private_data, instead of codec */
1568 return snd_ctl_add(codec->bus->card,
1569 snd_ctl_new1(&spdif_share_sw, mout));
1570}
1571
1572/*
1536 * SPDIF input 1573 * SPDIF input
1537 */ 1574 */
1538 1575
@@ -2557,9 +2594,36 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec,
2557 */ 2594 */
2558int snd_hda_multi_out_analog_open(struct hda_codec *codec, 2595int snd_hda_multi_out_analog_open(struct hda_codec *codec,
2559 struct hda_multi_out *mout, 2596 struct hda_multi_out *mout,
2560 struct snd_pcm_substream *substream) 2597 struct snd_pcm_substream *substream,
2561{ 2598 struct hda_pcm_stream *hinfo)
2562 substream->runtime->hw.channels_max = mout->max_channels; 2599{
2600 struct snd_pcm_runtime *runtime = substream->runtime;
2601 runtime->hw.channels_max = mout->max_channels;
2602 if (mout->dig_out_nid) {
2603 if (!mout->analog_rates) {
2604 mout->analog_rates = hinfo->rates;
2605 mout->analog_formats = hinfo->formats;
2606 mout->analog_maxbps = hinfo->maxbps;
2607 } else {
2608 runtime->hw.rates = mout->analog_rates;
2609 runtime->hw.formats = mout->analog_formats;
2610 hinfo->maxbps = mout->analog_maxbps;
2611 }
2612 if (!mout->spdif_rates) {
2613 snd_hda_query_supported_pcm(codec, mout->dig_out_nid,
2614 &mout->spdif_rates,
2615 &mout->spdif_formats,
2616 &mout->spdif_maxbps);
2617 }
2618 mutex_lock(&codec->spdif_mutex);
2619 if (mout->share_spdif) {
2620 runtime->hw.rates &= mout->spdif_rates;
2621 runtime->hw.formats &= mout->spdif_formats;
2622 if (mout->spdif_maxbps < hinfo->maxbps)
2623 hinfo->maxbps = mout->spdif_maxbps;
2624 }
2625 }
2626 mutex_unlock(&codec->spdif_mutex);
2563 return snd_pcm_hw_constraint_step(substream->runtime, 0, 2627 return snd_pcm_hw_constraint_step(substream->runtime, 0,
2564 SNDRV_PCM_HW_PARAM_CHANNELS, 2); 2628 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
2565} 2629}
@@ -2579,7 +2643,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
2579 int i; 2643 int i;
2580 2644
2581 mutex_lock(&codec->spdif_mutex); 2645 mutex_lock(&codec->spdif_mutex);
2582 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { 2646 if (mout->dig_out_nid && mout->share_spdif &&
2647 mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
2583 if (chs == 2 && 2648 if (chs == 2 &&
2584 snd_hda_is_supported_format(codec, mout->dig_out_nid, 2649 snd_hda_is_supported_format(codec, mout->dig_out_nid,
2585 format) && 2650 format) &&