Skip to content

Commit

Permalink
ALSA: hda - set up HDMI channels
Browse files Browse the repository at this point in the history
Set up channel information for HDMI widgets.  This will allow LPCM
with multiple channels supported on some HDMI devices.

TODO: It still doesn't check ELD and doesn't change PCM parameters
dynamically.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
  • Loading branch information
Takashi Iwai authored and Jaroslav Kysela committed Aug 25, 2008
1 parent c492060 commit 862f76f
Showing 1 changed file with 37 additions and 8 deletions.
45 changes: 37 additions & 8 deletions sound/pci/hda/patch_atihdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ struct atihdmi_spec {
struct hda_pcm pcm_rec;
};

#define CVT_NID 0x02 /* audio converter */
#define PIN_NID 0x03 /* HDMI output pin */

static struct hda_verb atihdmi_basic_init[] = {
/* enable digital output on pin widget */
{ 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
Expand All @@ -60,8 +63,9 @@ static int atihdmi_init(struct hda_codec *codec)
{
snd_hda_sequence_write(codec, atihdmi_basic_init);
/* SI codec requires to unmute the pin */
if (get_wcaps(codec, 0x03) & AC_WCAP_OUT_AMP)
snd_hda_codec_write(codec, 0x03, 0, AC_VERB_SET_AMP_GAIN_MUTE,
if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP)
snd_hda_codec_write(codec, PIN_NID, 0,
AC_VERB_SET_AMP_GAIN_MUTE,
AMP_OUT_UNMUTE);
return 0;
}
Expand Down Expand Up @@ -92,15 +96,29 @@ static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
struct snd_pcm_substream *substream)
{
struct atihdmi_spec *spec = codec->spec;
return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
format, substream);
int chans = substream->runtime->channels;
int i, err;

err = snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
format, substream);
if (err < 0)
return err;
snd_hda_codec_write(codec, CVT_NID, 0, AC_VERB_SET_CVT_CHAN_COUNT,
chans - 1);
/* FIXME: XXX */
for (i = 0; i < chans; i++) {
snd_hda_codec_write(codec, CVT_NID, 0,
AC_VERB_SET_HDMI_CHAN_SLOT,
(i << 4) | i);
}
return 0;
}

static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
.nid = 0x2, /* NID to query formats and rates and setup streams */
.nid = CVT_NID, /* NID to query formats and rates and setup streams */
.ops = {
.open = atihdmi_dig_playback_pcm_open,
.close = atihdmi_dig_playback_pcm_close,
Expand All @@ -112,6 +130,7 @@ static int atihdmi_build_pcms(struct hda_codec *codec)
{
struct atihdmi_spec *spec = codec->spec;
struct hda_pcm *info = &spec->pcm_rec;
unsigned int chans;

codec->num_pcms = 1;
codec->pcm_info = info;
Expand All @@ -120,6 +139,13 @@ static int atihdmi_build_pcms(struct hda_codec *codec)
info->pcm_type = HDA_PCM_TYPE_HDMI;
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = atihdmi_pcm_digital_playback;

/* FIXME: we must check ELD and change the PCM parameters dynamically
*/
chans = get_wcaps(codec, CVT_NID);
chans = (chans & AC_WCAP_CHAN_CNT_EXT) >> 13;
chans = ((chans << 1) | 1) + 1;
info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;

return 0;
}

Expand Down Expand Up @@ -147,9 +173,11 @@ static int patch_atihdmi(struct hda_codec *codec)

spec->multiout.num_dacs = 0; /* no analog */
spec->multiout.max_channels = 2;
spec->multiout.dig_out_nid = 0x2; /* NID for copying analog to digital,
* seems to be unused in pure-digital
* case. */
/* NID for copying analog to digital,
* seems to be unused in pure-digital
* case.
*/
spec->multiout.dig_out_nid = CVT_NID;

codec->patch_ops = atihdmi_patch_ops;

Expand All @@ -164,6 +192,7 @@ struct hda_codec_preset snd_hda_preset_atihdmi[] = {
{ .id = 0x10027919, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
{ .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi },
{ .id = 0x1002aa01, .name = "ATI R6xx HDMI", .patch = patch_atihdmi },
{ .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi },
{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_atihdmi },
{ .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi },
{} /* terminator */
Expand Down

0 comments on commit 862f76f

Please sign in to comment.