aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/hda_codec.c41
-rw-r--r--sound/pci/hda/hda_codec.h21
-rw-r--r--sound/pci/hda/patch_hdmi.c9
3 files changed, 50 insertions, 21 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index bd8d7a63d7fe..05e8995f9aec 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -3013,26 +3013,31 @@ struct hda_rate_tbl {
3013 unsigned int hda_fmt; 3013 unsigned int hda_fmt;
3014}; 3014};
3015 3015
3016/* rate = base * mult / div */
3017#define HDA_RATE(base, mult, div) \
3018 (AC_FMT_BASE_##base##K | (((mult) - 1) << AC_FMT_MULT_SHIFT) | \
3019 (((div) - 1) << AC_FMT_DIV_SHIFT))
3020
3016static struct hda_rate_tbl rate_bits[] = { 3021static struct hda_rate_tbl rate_bits[] = {
3017 /* rate in Hz, ALSA rate bitmask, HDA format value */ 3022 /* rate in Hz, ALSA rate bitmask, HDA format value */
3018 3023
3019 /* autodetected value used in snd_hda_query_supported_pcm */ 3024 /* autodetected value used in snd_hda_query_supported_pcm */
3020 { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */ 3025 { 8000, SNDRV_PCM_RATE_8000, HDA_RATE(48, 1, 6) },
3021 { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */ 3026 { 11025, SNDRV_PCM_RATE_11025, HDA_RATE(44, 1, 4) },
3022 { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */ 3027 { 16000, SNDRV_PCM_RATE_16000, HDA_RATE(48, 1, 3) },
3023 { 22050, SNDRV_PCM_RATE_22050, 0x4100 }, /* 1/2 x 44 */ 3028 { 22050, SNDRV_PCM_RATE_22050, HDA_RATE(44, 1, 2) },
3024 { 32000, SNDRV_PCM_RATE_32000, 0x0a00 }, /* 2/3 x 48 */ 3029 { 32000, SNDRV_PCM_RATE_32000, HDA_RATE(48, 2, 3) },
3025 { 44100, SNDRV_PCM_RATE_44100, 0x4000 }, /* 44 */ 3030 { 44100, SNDRV_PCM_RATE_44100, HDA_RATE(44, 1, 1) },
3026 { 48000, SNDRV_PCM_RATE_48000, 0x0000 }, /* 48 */ 3031 { 48000, SNDRV_PCM_RATE_48000, HDA_RATE(48, 1, 1) },
3027 { 88200, SNDRV_PCM_RATE_88200, 0x4800 }, /* 2 x 44 */ 3032 { 88200, SNDRV_PCM_RATE_88200, HDA_RATE(44, 2, 1) },
3028 { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ 3033 { 96000, SNDRV_PCM_RATE_96000, HDA_RATE(48, 2, 1) },
3029 { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ 3034 { 176400, SNDRV_PCM_RATE_176400, HDA_RATE(44, 4, 1) },
3030 { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ 3035 { 192000, SNDRV_PCM_RATE_192000, HDA_RATE(48, 4, 1) },
3031#define AC_PAR_PCM_RATE_BITS 11 3036#define AC_PAR_PCM_RATE_BITS 11
3032 /* up to bits 10, 384kHZ isn't supported properly */ 3037 /* up to bits 10, 384kHZ isn't supported properly */
3033 3038
3034 /* not autodetected value */ 3039 /* not autodetected value */
3035 { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */ 3040 { 9600, SNDRV_PCM_RATE_KNOT, HDA_RATE(48, 1, 5) },
3036 3041
3037 { 0 } /* terminator */ 3042 { 0 } /* terminator */
3038}; 3043};
@@ -3075,20 +3080,20 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
3075 3080
3076 switch (snd_pcm_format_width(format)) { 3081 switch (snd_pcm_format_width(format)) {
3077 case 8: 3082 case 8:
3078 val |= 0x00; 3083 val |= AC_FMT_BITS_8;
3079 break; 3084 break;
3080 case 16: 3085 case 16:
3081 val |= 0x10; 3086 val |= AC_FMT_BITS_16;
3082 break; 3087 break;
3083 case 20: 3088 case 20:
3084 case 24: 3089 case 24:
3085 case 32: 3090 case 32:
3086 if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE) 3091 if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
3087 val |= 0x40; 3092 val |= AC_FMT_BITS_32;
3088 else if (maxbps >= 24) 3093 else if (maxbps >= 24)
3089 val |= 0x30; 3094 val |= AC_FMT_BITS_24;
3090 else 3095 else
3091 val |= 0x20; 3096 val |= AC_FMT_BITS_20;
3092 break; 3097 break;
3093 default: 3098 default:
3094 snd_printdd("invalid format width %d\n", 3099 snd_printdd("invalid format width %d\n",
@@ -3097,7 +3102,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
3097 } 3102 }
3098 3103
3099 if (spdif_ctls & AC_DIG1_NONAUDIO) 3104 if (spdif_ctls & AC_DIG1_NONAUDIO)
3100 val |= 0x8000; 3105 val |= AC_FMT_TYPE_NON_PCM;
3101 3106
3102 return val; 3107 return val;
3103} 3108}
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 48b33671e727..46f75bccf0d3 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -224,6 +224,27 @@ enum {
224/* Input converter SDI select */ 224/* Input converter SDI select */
225#define AC_SDI_SELECT (0xf<<0) 225#define AC_SDI_SELECT (0xf<<0)
226 226
227/* stream format id */
228#define AC_FMT_CHAN_SHIFT 0
229#define AC_FMT_CHAN_MASK (0x0f << 0)
230#define AC_FMT_BITS_SHIFT 4
231#define AC_FMT_BITS_MASK (7 << 4)
232#define AC_FMT_BITS_8 (0 << 4)
233#define AC_FMT_BITS_16 (1 << 4)
234#define AC_FMT_BITS_20 (2 << 4)
235#define AC_FMT_BITS_24 (3 << 4)
236#define AC_FMT_BITS_32 (4 << 4)
237#define AC_FMT_DIV_SHIFT 8
238#define AC_FMT_DIV_MASK (7 << 8)
239#define AC_FMT_MULT_SHIFT 11
240#define AC_FMT_MULT_MASK (7 << 11)
241#define AC_FMT_BASE_SHIFT 14
242#define AC_FMT_BASE_48K (0 << 14)
243#define AC_FMT_BASE_44K (1 << 14)
244#define AC_FMT_TYPE_SHIFT 15
245#define AC_FMT_TYPE_PCM (0 << 15)
246#define AC_FMT_TYPE_NON_PCM (1 << 15)
247
227/* Unsolicited response control */ 248/* Unsolicited response control */
228#define AC_UNSOL_TAG (0x3f<<0) 249#define AC_UNSOL_TAG (0x3f<<0)
229#define AC_UNSOL_ENABLED (1<<7) 250#define AC_UNSOL_ENABLED (1<<7)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 8534792591fc..522e0748ee99 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -698,6 +698,10 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
698 * Callbacks 698 * Callbacks
699 */ 699 */
700 700
701/* HBR should be Non-PCM, 8 channels */
702#define is_hbr_format(format) \
703 ((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7)
704
701static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, 705static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
702 u32 stream_tag, int format) 706 u32 stream_tag, int format)
703{ 707{
@@ -718,8 +722,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
718 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 722 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
719 723
720 new_pinctl = pinctl & ~AC_PINCTL_EPT; 724 new_pinctl = pinctl & ~AC_PINCTL_EPT;
721 /* Non-PCM, 8 channels */ 725 if (is_hbr_format(format))
722 if ((format & 0x8000) && (format & 0x0f) == 7)
723 new_pinctl |= AC_PINCTL_EPT_HBR; 726 new_pinctl |= AC_PINCTL_EPT_HBR;
724 else 727 else
725 new_pinctl |= AC_PINCTL_EPT_NATIVE; 728 new_pinctl |= AC_PINCTL_EPT_NATIVE;
@@ -736,7 +739,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
736 new_pinctl); 739 new_pinctl);
737 } 740 }
738 741
739 if ((format & 0x8000) && (format & 0x0f) == 7 && !new_pinctl) { 742 if (is_hbr_format(format) && !new_pinctl) {
740 snd_printdd("hdmi_setup_stream: HBR is not supported\n"); 743 snd_printdd("hdmi_setup_stream: HBR is not supported\n");
741 return -EINVAL; 744 return -EINVAL;
742 } 745 }