aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-09-07 06:27:25 -0400
committerTakashi Iwai <tiwai@suse.de>2010-09-20 04:02:29 -0400
commit84eb01be18df7012ac31bf678da5aaf1accc6a77 (patch)
treebc02a76d09ce565bb73422b43bce611f7dece82d
parentf68b3b291d39f1e3361b194a95459f9cbdaf31e6 (diff)
ALSA: hda - Merge all HDMI modules into the unified module
This patch merges all three patch_*hdmi variants to the single HDMI parser. There is only one snd-hda-codec-hdmi module now. In this patch, the behavior of each parser isn't changed much. The old ATI parser still doesn't use the dynamic parser yet. In later patches, they'll be cleaned up. Also, this patch gets rid of the individual snd-hda-eld module and builds into snd-hda-codec-hdmi, since this is referred only from the HDMI parser. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/Kconfig39
-rw-r--r--sound/pci/hda/Makefile15
-rw-r--r--sound/pci/hda/hda_eld.c7
-rw-r--r--sound/pci/hda/patch_atihdmi.c224
-rw-r--r--sound/pci/hda/patch_hdmi.c685
-rw-r--r--sound/pci/hda/patch_intelhdmi.c220
-rw-r--r--sound/pci/hda/patch_nvhdmi.c608
7 files changed, 691 insertions, 1107 deletions
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 9194c3c1d04a..0ea5cc60ac78 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -119,47 +119,20 @@ config SND_HDA_CODEC_VIA
119 snd-hda-codec-via. 119 snd-hda-codec-via.
120 This module is automatically loaded at probing. 120 This module is automatically loaded at probing.
121 121
122config SND_HDA_CODEC_ATIHDMI 122config SND_HDA_CODEC_HDMI
123 bool "Build ATI HDMI HD-audio codec support" 123 bool "Build HDMI/DisplayPort HD-audio codec support"
124 default y
125 help
126 Say Y here to include ATI HDMI HD-audio codec support in
127 snd-hda-intel driver, such as ATI RS600 HDMI.
128
129 When the HD-audio driver is built as a module, the codec
130 support code is also built as another module,
131 snd-hda-codec-atihdmi.
132 This module is automatically loaded at probing.
133
134config SND_HDA_CODEC_NVHDMI
135 bool "Build NVIDIA HDMI HD-audio codec support"
136 default y
137 help
138 Say Y here to include NVIDIA HDMI HD-audio codec support in
139 snd-hda-intel driver, such as NVIDIA MCP78 HDMI.
140
141 When the HD-audio driver is built as a module, the codec
142 support code is also built as another module,
143 snd-hda-codec-nvhdmi.
144 This module is automatically loaded at probing.
145
146config SND_HDA_CODEC_INTELHDMI
147 bool "Build INTEL HDMI HD-audio codec support"
148 select SND_DYNAMIC_MINORS 124 select SND_DYNAMIC_MINORS
149 default y 125 default y
150 help 126 help
151 Say Y here to include INTEL HDMI HD-audio codec support in 127 Say Y here to include HDMI and DisplayPort HD-audio codec
152 snd-hda-intel driver, such as Eaglelake integrated HDMI. 128 support in snd-hda-intel driver. This includes all AMD/ATI,
129 Intel and Nvidia HDMI/DisplayPort codecs.
153 130
154 When the HD-audio driver is built as a module, the codec 131 When the HD-audio driver is built as a module, the codec
155 support code is also built as another module, 132 support code is also built as another module,
156 snd-hda-codec-intelhdmi. 133 snd-hda-codec-hdmi.
157 This module is automatically loaded at probing. 134 This module is automatically loaded at probing.
158 135
159config SND_HDA_ELD
160 def_bool y
161 depends on SND_HDA_CODEC_INTELHDMI || SND_HDA_CODEC_NVHDMI
162
163config SND_HDA_CODEC_CIRRUS 136config SND_HDA_CODEC_CIRRUS
164 bool "Build Cirrus Logic codec support" 137 bool "Build Cirrus Logic codec support"
165 depends on SND_HDA_INTEL 138 depends on SND_HDA_INTEL
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 24bc195b02da..17ef3658f34b 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -3,7 +3,6 @@ snd-hda-intel-objs := hda_intel.o
3snd-hda-codec-y := hda_codec.o 3snd-hda-codec-y := hda_codec.o
4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o 4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o 5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
6snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o
7snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o 6snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
8snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o 7snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
9 8
@@ -12,13 +11,11 @@ snd-hda-codec-cmedia-objs := patch_cmedia.o
12snd-hda-codec-analog-objs := patch_analog.o 11snd-hda-codec-analog-objs := patch_analog.o
13snd-hda-codec-idt-objs := patch_sigmatel.o 12snd-hda-codec-idt-objs := patch_sigmatel.o
14snd-hda-codec-si3054-objs := patch_si3054.o 13snd-hda-codec-si3054-objs := patch_si3054.o
15snd-hda-codec-atihdmi-objs := patch_atihdmi.o
16snd-hda-codec-cirrus-objs := patch_cirrus.o 14snd-hda-codec-cirrus-objs := patch_cirrus.o
17snd-hda-codec-ca0110-objs := patch_ca0110.o 15snd-hda-codec-ca0110-objs := patch_ca0110.o
18snd-hda-codec-conexant-objs := patch_conexant.o 16snd-hda-codec-conexant-objs := patch_conexant.o
19snd-hda-codec-via-objs := patch_via.o 17snd-hda-codec-via-objs := patch_via.o
20snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o 18snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o
21snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o
22 19
23# common driver 20# common driver
24obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o 21obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o
@@ -39,9 +36,6 @@ endif
39ifdef CONFIG_SND_HDA_CODEC_SI3054 36ifdef CONFIG_SND_HDA_CODEC_SI3054
40obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-si3054.o 37obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-si3054.o
41endif 38endif
42ifdef CONFIG_SND_HDA_CODEC_ATIHDMI
43obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o
44endif
45ifdef CONFIG_SND_HDA_CODEC_CIRRUS 39ifdef CONFIG_SND_HDA_CODEC_CIRRUS
46obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cirrus.o 40obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cirrus.o
47endif 41endif
@@ -54,11 +48,8 @@ endif
54ifdef CONFIG_SND_HDA_CODEC_VIA 48ifdef CONFIG_SND_HDA_CODEC_VIA
55obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-via.o 49obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-via.o
56endif 50endif
57ifdef CONFIG_SND_HDA_CODEC_NVHDMI 51ifdef CONFIG_SND_HDA_CODEC_HDMI
58obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-nvhdmi.o 52obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-hdmi.o
59endif
60ifdef CONFIG_SND_HDA_CODEC_INTELHDMI
61obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-intelhdmi.o
62endif 53endif
63 54
64# this must be the last entry after codec drivers; 55# this must be the last entry after codec drivers;
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index 26c3ade73583..cb0c23a6b473 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -332,7 +332,6 @@ int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
332 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, 332 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
333 AC_DIPSIZE_ELD_BUF); 333 AC_DIPSIZE_ELD_BUF);
334} 334}
335EXPORT_SYMBOL_HDA(snd_hdmi_get_eld_size);
336 335
337int snd_hdmi_get_eld(struct hdmi_eld *eld, 336int snd_hdmi_get_eld(struct hdmi_eld *eld,
338 struct hda_codec *codec, hda_nid_t nid) 337 struct hda_codec *codec, hda_nid_t nid)
@@ -368,7 +367,6 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
368 kfree(buf); 367 kfree(buf);
369 return ret; 368 return ret;
370} 369}
371EXPORT_SYMBOL_HDA(snd_hdmi_get_eld);
372 370
373static void hdmi_show_short_audio_desc(struct cea_sad *a) 371static void hdmi_show_short_audio_desc(struct cea_sad *a)
374{ 372{
@@ -407,7 +405,6 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
407 } 405 }
408 buf[j] = '\0'; /* necessary when j == 0 */ 406 buf[j] = '\0'; /* necessary when j == 0 */
409} 407}
410EXPORT_SYMBOL_HDA(snd_print_channel_allocation);
411 408
412void snd_hdmi_show_eld(struct hdmi_eld *e) 409void snd_hdmi_show_eld(struct hdmi_eld *e)
413{ 410{
@@ -426,7 +423,6 @@ void snd_hdmi_show_eld(struct hdmi_eld *e)
426 for (i = 0; i < e->sad_count; i++) 423 for (i = 0; i < e->sad_count; i++)
427 hdmi_show_short_audio_desc(e->sad + i); 424 hdmi_show_short_audio_desc(e->sad + i);
428} 425}
429EXPORT_SYMBOL_HDA(snd_hdmi_show_eld);
430 426
431#ifdef CONFIG_PROC_FS 427#ifdef CONFIG_PROC_FS
432 428
@@ -585,7 +581,6 @@ int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
585 581
586 return 0; 582 return 0;
587} 583}
588EXPORT_SYMBOL_HDA(snd_hda_eld_proc_new);
589 584
590void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld) 585void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
591{ 586{
@@ -594,7 +589,6 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
594 eld->proc_entry = NULL; 589 eld->proc_entry = NULL;
595 } 590 }
596} 591}
597EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free);
598 592
599#endif /* CONFIG_PROC_FS */ 593#endif /* CONFIG_PROC_FS */
600 594
@@ -645,4 +639,3 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
645 pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max); 639 pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max);
646 pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); 640 pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps);
647} 641}
648EXPORT_SYMBOL_HDA(hdmi_eld_update_pcm_info);
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
deleted file mode 100644
index fb684f00156b..000000000000
--- a/sound/pci/hda/patch_atihdmi.c
+++ /dev/null
@@ -1,224 +0,0 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ATI HDMI codecs
5 *
6 * Copyright (c) 2006 ATI Technologies Inc.
7 *
8 *
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/slab.h>
27#include <sound/core.h>
28#include "hda_codec.h"
29#include "hda_local.h"
30
31struct atihdmi_spec {
32 struct hda_multi_out multiout;
33
34 struct hda_pcm pcm_rec;
35};
36
37#define CVT_NID 0x02 /* audio converter */
38#define PIN_NID 0x03 /* HDMI output pin */
39
40static struct hda_verb atihdmi_basic_init[] = {
41 /* enable digital output on pin widget */
42 { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
43 {} /* terminator */
44};
45
46/*
47 * Controls
48 */
49static int atihdmi_build_controls(struct hda_codec *codec)
50{
51 struct atihdmi_spec *spec = codec->spec;
52 int err;
53
54 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
55 if (err < 0)
56 return err;
57
58 return 0;
59}
60
61static int atihdmi_init(struct hda_codec *codec)
62{
63 snd_hda_sequence_write(codec, atihdmi_basic_init);
64 /* SI codec requires to unmute the pin */
65 if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP)
66 snd_hda_codec_write(codec, PIN_NID, 0,
67 AC_VERB_SET_AMP_GAIN_MUTE,
68 AMP_OUT_UNMUTE);
69 return 0;
70}
71
72/*
73 * Digital out
74 */
75static int atihdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
76 struct hda_codec *codec,
77 struct snd_pcm_substream *substream)
78{
79 struct atihdmi_spec *spec = codec->spec;
80 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
81}
82
83static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
84 struct hda_codec *codec,
85 struct snd_pcm_substream *substream)
86{
87 struct atihdmi_spec *spec = codec->spec;
88 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
89}
90
91static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
92 struct hda_codec *codec,
93 unsigned int stream_tag,
94 unsigned int format,
95 struct snd_pcm_substream *substream)
96{
97 struct atihdmi_spec *spec = codec->spec;
98 int chans = substream->runtime->channels;
99 int i, err;
100
101 err = snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
102 format, substream);
103 if (err < 0)
104 return err;
105 snd_hda_codec_write(codec, CVT_NID, 0, AC_VERB_SET_CVT_CHAN_COUNT,
106 chans - 1);
107 /* FIXME: XXX */
108 for (i = 0; i < chans; i++) {
109 snd_hda_codec_write(codec, CVT_NID, 0,
110 AC_VERB_SET_HDMI_CHAN_SLOT,
111 (i << 4) | i);
112 }
113 return 0;
114}
115
116static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
117 .substreams = 1,
118 .channels_min = 2,
119 .channels_max = 2,
120 .nid = CVT_NID, /* NID to query formats and rates and setup streams */
121 .ops = {
122 .open = atihdmi_dig_playback_pcm_open,
123 .close = atihdmi_dig_playback_pcm_close,
124 .prepare = atihdmi_dig_playback_pcm_prepare
125 },
126};
127
128static int atihdmi_build_pcms(struct hda_codec *codec)
129{
130 struct atihdmi_spec *spec = codec->spec;
131 struct hda_pcm *info = &spec->pcm_rec;
132 unsigned int chans;
133
134 codec->num_pcms = 1;
135 codec->pcm_info = info;
136
137 info->name = "ATI HDMI";
138 info->pcm_type = HDA_PCM_TYPE_HDMI;
139 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = atihdmi_pcm_digital_playback;
140
141 /* FIXME: we must check ELD and change the PCM parameters dynamically
142 */
143 chans = get_wcaps(codec, CVT_NID);
144 chans = get_wcaps_channels(chans);
145 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
146
147 return 0;
148}
149
150static void atihdmi_free(struct hda_codec *codec)
151{
152 kfree(codec->spec);
153}
154
155static struct hda_codec_ops atihdmi_patch_ops = {
156 .build_controls = atihdmi_build_controls,
157 .build_pcms = atihdmi_build_pcms,
158 .init = atihdmi_init,
159 .free = atihdmi_free,
160};
161
162static int patch_atihdmi(struct hda_codec *codec)
163{
164 struct atihdmi_spec *spec;
165
166 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
167 if (spec == NULL)
168 return -ENOMEM;
169
170 codec->spec = spec;
171
172 spec->multiout.num_dacs = 0; /* no analog */
173 spec->multiout.max_channels = 2;
174 /* NID for copying analog to digital,
175 * seems to be unused in pure-digital
176 * case.
177 */
178 spec->multiout.dig_out_nid = CVT_NID;
179
180 codec->patch_ops = atihdmi_patch_ops;
181
182 return 0;
183}
184
185/*
186 * patch entries
187 */
188static struct hda_codec_preset snd_hda_preset_atihdmi[] = {
189 { .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
190 { .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
191 { .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
192 { .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi },
193 { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi },
194 { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi },
195 {} /* terminator */
196};
197
198MODULE_ALIAS("snd-hda-codec-id:1002793c");
199MODULE_ALIAS("snd-hda-codec-id:10027919");
200MODULE_ALIAS("snd-hda-codec-id:1002791a");
201MODULE_ALIAS("snd-hda-codec-id:1002aa01");
202MODULE_ALIAS("snd-hda-codec-id:10951390");
203MODULE_ALIAS("snd-hda-codec-id:17e80047");
204
205MODULE_LICENSE("GPL");
206MODULE_DESCRIPTION("ATI HDMI HD-audio codec");
207
208static struct hda_codec_preset_list atihdmi_list = {
209 .preset = snd_hda_preset_atihdmi,
210 .owner = THIS_MODULE,
211};
212
213static int __init patch_atihdmi_init(void)
214{
215 return snd_hda_add_codec_preset(&atihdmi_list);
216}
217
218static void __exit patch_atihdmi_exit(void)
219{
220 snd_hda_delete_codec_preset(&atihdmi_list);
221}
222
223module_init(patch_atihdmi_init)
224module_exit(patch_atihdmi_exit)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index afd6022a96a7..cb997ca0fdfa 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -3,6 +3,9 @@
3 * patch_hdmi.c - routines for HDMI/DisplayPort codecs 3 * patch_hdmi.c - routines for HDMI/DisplayPort codecs
4 * 4 *
5 * Copyright(c) 2008-2010 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008-2010 Intel Corporation. All rights reserved.
6 * Copyright (c) 2006 ATI Technologies Inc.
7 * Copyright (c) 2008 NVIDIA Corp. All rights reserved.
8 * Copyright (c) 2008 Wei Ni <wni@nvidia.com>
6 * 9 *
7 * Authors: 10 * Authors:
8 * Wu Fengguang <wfg@linux.intel.com> 11 * Wu Fengguang <wfg@linux.intel.com>
@@ -25,6 +28,22 @@
25 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 28 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */ 29 */
27 30
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/slab.h>
34#include <sound/core.h>
35#include "hda_codec.h"
36#include "hda_local.h"
37
38/*
39 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
40 * could support two independent pipes, each of them can be connected to one or
41 * more ports (DVI, HDMI or DisplayPort).
42 *
43 * The HDA correspondence of pipes/ports are converter/pin nodes.
44 */
45#define MAX_HDMI_CVTS 3
46#define MAX_HDMI_PINS 3
28 47
29struct hdmi_spec { 48struct hdmi_spec {
30 int num_cvts; 49 int num_cvts;
@@ -49,10 +68,10 @@ struct hdmi_spec {
49 struct hda_pcm_stream codec_pcm_pars[MAX_HDMI_CVTS]; 68 struct hda_pcm_stream codec_pcm_pars[MAX_HDMI_CVTS];
50 69
51 /* 70 /*
52 * nvhdmi specific 71 * ati/nvhdmi specific
53 */ 72 */
54 struct hda_multi_out multiout; 73 struct hda_multi_out multiout;
55 unsigned int codec_type; 74 struct hda_pcm_stream *pcm_playback;
56 75
57 /* misc flags */ 76 /* misc flags */
58 /* PD bit indicates only the update, not the current state */ 77 /* PD bit indicates only the update, not the current state */
@@ -791,7 +810,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
791/* 810/*
792 * HDA/HDMI auto parsing 811 * HDA/HDMI auto parsing
793 */ 812 */
794
795static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid) 813static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
796{ 814{
797 struct hdmi_spec *spec = codec->spec; 815 struct hdmi_spec *spec = codec->spec;
@@ -922,3 +940,664 @@ static int hdmi_parse_codec(struct hda_codec *codec)
922 return 0; 940 return 0;
923} 941}
924 942
943/*
944 */
945static char *generic_hdmi_pcm_names[MAX_HDMI_CVTS] = {
946 "HDMI 0",
947 "HDMI 1",
948 "HDMI 2",
949};
950
951/*
952 * HDMI callbacks
953 */
954
955static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
956 struct hda_codec *codec,
957 unsigned int stream_tag,
958 unsigned int format,
959 struct snd_pcm_substream *substream)
960{
961 hdmi_set_channel_count(codec, hinfo->nid,
962 substream->runtime->channels);
963
964 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
965
966 return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
967}
968
969static struct hda_pcm_stream generic_hdmi_pcm_playback = {
970 .substreams = 1,
971 .channels_min = 2,
972 .ops = {
973 .open = hdmi_pcm_open,
974 .prepare = generic_hdmi_playback_pcm_prepare,
975 },
976};
977
978static int generic_hdmi_build_pcms(struct hda_codec *codec)
979{
980 struct hdmi_spec *spec = codec->spec;
981 struct hda_pcm *info = spec->pcm_rec;
982 int i;
983
984 codec->num_pcms = spec->num_cvts;
985 codec->pcm_info = info;
986
987 for (i = 0; i < codec->num_pcms; i++, info++) {
988 unsigned int chans;
989 struct hda_pcm_stream *pstr;
990
991 chans = get_wcaps(codec, spec->cvt[i]);
992 chans = get_wcaps_channels(chans);
993
994 info->name = generic_hdmi_pcm_names[i];
995 info->pcm_type = HDA_PCM_TYPE_HDMI;
996 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
997 if (spec->pcm_playback)
998 *pstr = *spec->pcm_playback;
999 else
1000 *pstr = generic_hdmi_pcm_playback;
1001 pstr->nid = spec->cvt[i];
1002 if (pstr->channels_max <= 2 && chans && chans <= 16)
1003 pstr->channels_max = chans;
1004 }
1005
1006 return 0;
1007}
1008
1009static int generic_hdmi_build_controls(struct hda_codec *codec)
1010{
1011 struct hdmi_spec *spec = codec->spec;
1012 int err;
1013 int i;
1014
1015 for (i = 0; i < codec->num_pcms; i++) {
1016 err = snd_hda_create_spdif_out_ctls(codec, spec->cvt[i]);
1017 if (err < 0)
1018 return err;
1019 }
1020
1021 return 0;
1022}
1023
1024static int generic_hdmi_init(struct hda_codec *codec)
1025{
1026 struct hdmi_spec *spec = codec->spec;
1027 int i;
1028
1029 for (i = 0; spec->pin[i]; i++) {
1030 hdmi_enable_output(codec, spec->pin[i]);
1031 snd_hda_codec_write(codec, spec->pin[i], 0,
1032 AC_VERB_SET_UNSOLICITED_ENABLE,
1033 AC_USRSP_EN | spec->pin[i]);
1034 }
1035 return 0;
1036}
1037
1038static void generic_hdmi_free(struct hda_codec *codec)
1039{
1040 struct hdmi_spec *spec = codec->spec;
1041 int i;
1042
1043 for (i = 0; i < spec->num_pins; i++)
1044 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
1045
1046 kfree(spec);
1047}
1048
1049static struct hda_codec_ops generic_hdmi_patch_ops = {
1050 .init = generic_hdmi_init,
1051 .free = generic_hdmi_free,
1052 .build_pcms = generic_hdmi_build_pcms,
1053 .build_controls = generic_hdmi_build_controls,
1054 .unsol_event = hdmi_unsol_event,
1055};
1056
1057static int patch_generic_hdmi(struct hda_codec *codec)
1058{
1059 struct hdmi_spec *spec;
1060 int i;
1061
1062 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1063 if (spec == NULL)
1064 return -ENOMEM;
1065
1066 codec->spec = spec;
1067 if (hdmi_parse_codec(codec) < 0) {
1068 codec->spec = NULL;
1069 kfree(spec);
1070 return -EINVAL;
1071 }
1072 codec->patch_ops = generic_hdmi_patch_ops;
1073
1074 for (i = 0; i < spec->num_pins; i++)
1075 snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
1076
1077 init_channel_allocations();
1078
1079 return 0;
1080}
1081
1082/*
1083 * Nvidia specific implementations
1084 */
1085
1086#define Nv_VERB_SET_Channel_Allocation 0xF79
1087#define Nv_VERB_SET_Info_Frame_Checksum 0xF7A
1088#define Nv_VERB_SET_Audio_Protection_On 0xF98
1089#define Nv_VERB_SET_Audio_Protection_Off 0xF99
1090
1091#define nvhdmi_master_con_nid_7x 0x04
1092#define nvhdmi_master_pin_nid_7x 0x05
1093
1094static hda_nid_t nvhdmi_con_nids_7x[4] = {
1095 /*front, rear, clfe, rear_surr */
1096 0x6, 0x8, 0xa, 0xc,
1097};
1098
1099static struct hda_verb nvhdmi_basic_init_7x[] = {
1100 /* set audio protect on */
1101 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
1102 /* enable digital output on pin widget */
1103 { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
1104 { 0x7, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
1105 { 0x9, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
1106 { 0xb, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
1107 { 0xd, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
1108 {} /* terminator */
1109};
1110
1111#ifdef LIMITED_RATE_FMT_SUPPORT
1112/* support only the safe format and rate */
1113#define SUPPORTED_RATES SNDRV_PCM_RATE_48000
1114#define SUPPORTED_MAXBPS 16
1115#define SUPPORTED_FORMATS SNDRV_PCM_FMTBIT_S16_LE
1116#else
1117/* support all rates and formats */
1118#define SUPPORTED_RATES \
1119 (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
1120 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
1121 SNDRV_PCM_RATE_192000)
1122#define SUPPORTED_MAXBPS 24
1123#define SUPPORTED_FORMATS \
1124 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
1125#endif
1126
1127static int nvhdmi_7x_init(struct hda_codec *codec)
1128{
1129 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x);
1130 return 0;
1131}
1132
1133static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo,
1134 struct hda_codec *codec,
1135 struct snd_pcm_substream *substream)
1136{
1137 struct hdmi_spec *spec = codec->spec;
1138 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1139}
1140
1141static int simple_playback_pcm_close(struct hda_pcm_stream *hinfo,
1142 struct hda_codec *codec,
1143 struct snd_pcm_substream *substream)
1144{
1145 struct hdmi_spec *spec = codec->spec;
1146 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1147}
1148
1149static int simple_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1150 struct hda_codec *codec,
1151 unsigned int stream_tag,
1152 unsigned int format,
1153 struct snd_pcm_substream *substream)
1154{
1155 struct hdmi_spec *spec = codec->spec;
1156 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1157 stream_tag, format, substream);
1158}
1159
1160static int nvhdmi_8ch_7x_pcm_close(struct hda_pcm_stream *hinfo,
1161 struct hda_codec *codec,
1162 struct snd_pcm_substream *substream)
1163{
1164 struct hdmi_spec *spec = codec->spec;
1165 int i;
1166
1167 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
1168 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
1169 for (i = 0; i < 4; i++) {
1170 /* set the stream id */
1171 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
1172 AC_VERB_SET_CHANNEL_STREAMID, 0);
1173 /* set the stream format */
1174 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
1175 AC_VERB_SET_STREAM_FORMAT, 0);
1176 }
1177
1178 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1179}
1180
1181static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1182 struct hda_codec *codec,
1183 unsigned int stream_tag,
1184 unsigned int format,
1185 struct snd_pcm_substream *substream)
1186{
1187 int chs;
1188 unsigned int dataDCC1, dataDCC2, chan, chanmask, channel_id;
1189 int i;
1190
1191 mutex_lock(&codec->spdif_mutex);
1192
1193 chs = substream->runtime->channels;
1194 chan = chs ? (chs - 1) : 1;
1195
1196 switch (chs) {
1197 default:
1198 case 0:
1199 case 2:
1200 chanmask = 0x00;
1201 break;
1202 case 4:
1203 chanmask = 0x08;
1204 break;
1205 case 6:
1206 chanmask = 0x0b;
1207 break;
1208 case 8:
1209 chanmask = 0x13;
1210 break;
1211 }
1212 dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT;
1213 dataDCC2 = 0x2;
1214
1215 /* set the Audio InforFrame Channel Allocation */
1216 snd_hda_codec_write(codec, 0x1, 0,
1217 Nv_VERB_SET_Channel_Allocation, chanmask);
1218
1219 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
1220 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
1221 snd_hda_codec_write(codec,
1222 nvhdmi_master_con_nid_7x,
1223 0,
1224 AC_VERB_SET_DIGI_CONVERT_1,
1225 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
1226
1227 /* set the stream id */
1228 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
1229 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
1230
1231 /* set the stream format */
1232 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
1233 AC_VERB_SET_STREAM_FORMAT, format);
1234
1235 /* turn on again (if needed) */
1236 /* enable and set the channel status audio/data flag */
1237 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
1238 snd_hda_codec_write(codec,
1239 nvhdmi_master_con_nid_7x,
1240 0,
1241 AC_VERB_SET_DIGI_CONVERT_1,
1242 codec->spdif_ctls & 0xff);
1243 snd_hda_codec_write(codec,
1244 nvhdmi_master_con_nid_7x,
1245 0,
1246 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
1247 }
1248
1249 for (i = 0; i < 4; i++) {
1250 if (chs == 2)
1251 channel_id = 0;
1252 else
1253 channel_id = i * 2;
1254
1255 /* turn off SPDIF once;
1256 *otherwise the IEC958 bits won't be updated
1257 */
1258 if (codec->spdif_status_reset &&
1259 (codec->spdif_ctls & AC_DIG1_ENABLE))
1260 snd_hda_codec_write(codec,
1261 nvhdmi_con_nids_7x[i],
1262 0,
1263 AC_VERB_SET_DIGI_CONVERT_1,
1264 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
1265 /* set the stream id */
1266 snd_hda_codec_write(codec,
1267 nvhdmi_con_nids_7x[i],
1268 0,
1269 AC_VERB_SET_CHANNEL_STREAMID,
1270 (stream_tag << 4) | channel_id);
1271 /* set the stream format */
1272 snd_hda_codec_write(codec,
1273 nvhdmi_con_nids_7x[i],
1274 0,
1275 AC_VERB_SET_STREAM_FORMAT,
1276 format);
1277 /* turn on again (if needed) */
1278 /* enable and set the channel status audio/data flag */
1279 if (codec->spdif_status_reset &&
1280 (codec->spdif_ctls & AC_DIG1_ENABLE)) {
1281 snd_hda_codec_write(codec,
1282 nvhdmi_con_nids_7x[i],
1283 0,
1284 AC_VERB_SET_DIGI_CONVERT_1,
1285 codec->spdif_ctls & 0xff);
1286 snd_hda_codec_write(codec,
1287 nvhdmi_con_nids_7x[i],
1288 0,
1289 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
1290 }
1291 }
1292
1293 /* set the Audio Info Frame Checksum */
1294 snd_hda_codec_write(codec, 0x1, 0,
1295 Nv_VERB_SET_Info_Frame_Checksum,
1296 (0x71 - chan - chanmask));
1297
1298 mutex_unlock(&codec->spdif_mutex);
1299 return 0;
1300}
1301
1302static struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = {
1303 .substreams = 1,
1304 .channels_min = 2,
1305 .channels_max = 8,
1306 .nid = nvhdmi_master_con_nid_7x,
1307 .rates = SUPPORTED_RATES,
1308 .maxbps = SUPPORTED_MAXBPS,
1309 .formats = SUPPORTED_FORMATS,
1310 .ops = {
1311 .open = simple_playback_pcm_open,
1312 .close = nvhdmi_8ch_7x_pcm_close,
1313 .prepare = nvhdmi_8ch_7x_pcm_prepare
1314 },
1315};
1316
1317static struct hda_pcm_stream nvhdmi_pcm_playback_2ch = {
1318 .substreams = 1,
1319 .channels_min = 2,
1320 .channels_max = 2,
1321 .nid = nvhdmi_master_con_nid_7x,
1322 .rates = SUPPORTED_RATES,
1323 .maxbps = SUPPORTED_MAXBPS,
1324 .formats = SUPPORTED_FORMATS,
1325 .ops = {
1326 .open = simple_playback_pcm_open,
1327 .close = simple_playback_pcm_close,
1328 .prepare = simple_playback_pcm_prepare
1329 },
1330};
1331
1332static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
1333 .build_controls = generic_hdmi_build_controls,
1334 .build_pcms = generic_hdmi_build_pcms,
1335 .init = nvhdmi_7x_init,
1336 .free = generic_hdmi_free,
1337};
1338
1339static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
1340 .build_controls = generic_hdmi_build_controls,
1341 .build_pcms = generic_hdmi_build_pcms,
1342 .init = nvhdmi_7x_init,
1343 .free = generic_hdmi_free,
1344};
1345
1346static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
1347{
1348 struct hdmi_spec *spec;
1349 int err = patch_generic_hdmi(codec);
1350
1351 if (err < 0)
1352 return err;
1353 spec = codec->spec;
1354 spec->old_pin_detect = 1;
1355 return 0;
1356}
1357
1358static int patch_nvhdmi_2ch(struct hda_codec *codec)
1359{
1360 struct hdmi_spec *spec;
1361
1362 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1363 if (spec == NULL)
1364 return -ENOMEM;
1365
1366 codec->spec = spec;
1367
1368 spec->multiout.num_dacs = 0; /* no analog */
1369 spec->multiout.max_channels = 2;
1370 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
1371 spec->old_pin_detect = 1;
1372 spec->num_cvts = 1;
1373 spec->cvt[0] = nvhdmi_master_con_nid_7x;
1374 spec->pcm_playback = &nvhdmi_pcm_playback_2ch;
1375
1376 codec->patch_ops = nvhdmi_patch_ops_2ch;
1377
1378 return 0;
1379}
1380
1381static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
1382{
1383 struct hdmi_spec *spec;
1384 int err = patch_nvhdmi_2ch(codec);
1385
1386 if (err < 0)
1387 return err;
1388 spec = codec->spec;
1389 spec->multiout.max_channels = 8;
1390 spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x;
1391 codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
1392 return 0;
1393}
1394
1395/*
1396 * ATI-specific implementations
1397 *
1398 * FIXME: we may omit the whole this and use the generic code once after
1399 * it's confirmed to work.
1400 */
1401
1402#define ATIHDMI_CVT_NID 0x02 /* audio converter */
1403#define ATIHDMI_PIN_NID 0x03 /* HDMI output pin */
1404
1405static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1406 struct hda_codec *codec,
1407 unsigned int stream_tag,
1408 unsigned int format,
1409 struct snd_pcm_substream *substream)
1410{
1411 struct hdmi_spec *spec = codec->spec;
1412 int chans = substream->runtime->channels;
1413 int i, err;
1414
1415 err = simple_playback_pcm_prepare(hinfo, codec, stream_tag, format,
1416 substream);
1417 if (err < 0)
1418 return err;
1419 snd_hda_codec_write(codec, spec->cvt[0], 0, AC_VERB_SET_CVT_CHAN_COUNT,
1420 chans - 1);
1421 /* FIXME: XXX */
1422 for (i = 0; i < chans; i++) {
1423 snd_hda_codec_write(codec, spec->cvt[0], 0,
1424 AC_VERB_SET_HDMI_CHAN_SLOT,
1425 (i << 4) | i);
1426 }
1427 return 0;
1428}
1429
1430static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
1431 .substreams = 1,
1432 .channels_min = 2,
1433 .channels_max = 2,
1434 .nid = ATIHDMI_CVT_NID,
1435 .ops = {
1436 .open = simple_playback_pcm_open,
1437 .close = simple_playback_pcm_close,
1438 .prepare = atihdmi_playback_pcm_prepare
1439 },
1440};
1441
1442static struct hda_verb atihdmi_basic_init[] = {
1443 /* enable digital output on pin widget */
1444 { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1445 {} /* terminator */
1446};
1447
1448static int atihdmi_init(struct hda_codec *codec)
1449{
1450 struct hdmi_spec *spec = codec->spec;
1451
1452 snd_hda_sequence_write(codec, atihdmi_basic_init);
1453 /* SI codec requires to unmute the pin */
1454 if (get_wcaps(codec, spec->pin[0]) & AC_WCAP_OUT_AMP)
1455 snd_hda_codec_write(codec, spec->pin[0], 0,
1456 AC_VERB_SET_AMP_GAIN_MUTE,
1457 AMP_OUT_UNMUTE);
1458 return 0;
1459}
1460
1461static struct hda_codec_ops atihdmi_patch_ops = {
1462 .build_controls = generic_hdmi_build_controls,
1463 .build_pcms = generic_hdmi_build_pcms,
1464 .init = atihdmi_init,
1465 .free = generic_hdmi_free,
1466};
1467
1468
1469static int patch_atihdmi(struct hda_codec *codec)
1470{
1471 struct hdmi_spec *spec;
1472
1473 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1474 if (spec == NULL)
1475 return -ENOMEM;
1476
1477 codec->spec = spec;
1478
1479 spec->multiout.num_dacs = 0; /* no analog */
1480 spec->multiout.max_channels = 2;
1481 spec->multiout.dig_out_nid = ATIHDMI_CVT_NID;
1482 spec->num_cvts = 1;
1483 spec->cvt[0] = ATIHDMI_CVT_NID;
1484 spec->pin[0] = ATIHDMI_PIN_NID;
1485 spec->pcm_playback = &atihdmi_pcm_digital_playback;
1486
1487 codec->patch_ops = atihdmi_patch_ops;
1488
1489 return 0;
1490}
1491
1492
1493/*
1494 * patch entries
1495 */
1496static struct hda_codec_preset snd_hda_preset_hdmi[] = {
1497{ .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
1498{ .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
1499{ .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
1500{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi },
1501{ .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_generic_hdmi },
1502{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_generic_hdmi },
1503{ .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_generic_hdmi },
1504{ .id = 0x10de0002, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
1505{ .id = 0x10de0003, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
1506{ .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
1507{ .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
1508{ .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x },
1509{ .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1510{ .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1511{ .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_nvhdmi_8ch_89 },
1512{ .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1513{ .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1514{ .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1515{ .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1516{ .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1517{ .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1518{ .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1519{ .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1520{ .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1521{ .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1522{ .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1523{ .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1524{ .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1525{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1526{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1527{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
1528{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
1529{ .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
1530{ .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
1531{ .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_generic_hdmi },
1532{ .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_generic_hdmi },
1533{ .id = 0x80862803, .name = "Eaglelake HDMI", .patch = patch_generic_hdmi },
1534{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
1535{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi },
1536{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi },
1537{} /* terminator */
1538};
1539
1540MODULE_ALIAS("snd-hda-codec-id:1002793c");
1541MODULE_ALIAS("snd-hda-codec-id:10027919");
1542MODULE_ALIAS("snd-hda-codec-id:1002791a");
1543MODULE_ALIAS("snd-hda-codec-id:1002aa01");
1544MODULE_ALIAS("snd-hda-codec-id:10951390");
1545MODULE_ALIAS("snd-hda-codec-id:10951392");
1546MODULE_ALIAS("snd-hda-codec-id:10de0002");
1547MODULE_ALIAS("snd-hda-codec-id:10de0003");
1548MODULE_ALIAS("snd-hda-codec-id:10de0005");
1549MODULE_ALIAS("snd-hda-codec-id:10de0006");
1550MODULE_ALIAS("snd-hda-codec-id:10de0007");
1551MODULE_ALIAS("snd-hda-codec-id:10de000a");
1552MODULE_ALIAS("snd-hda-codec-id:10de000b");
1553MODULE_ALIAS("snd-hda-codec-id:10de000c");
1554MODULE_ALIAS("snd-hda-codec-id:10de000d");
1555MODULE_ALIAS("snd-hda-codec-id:10de0010");
1556MODULE_ALIAS("snd-hda-codec-id:10de0011");
1557MODULE_ALIAS("snd-hda-codec-id:10de0012");
1558MODULE_ALIAS("snd-hda-codec-id:10de0013");
1559MODULE_ALIAS("snd-hda-codec-id:10de0014");
1560MODULE_ALIAS("snd-hda-codec-id:10de0018");
1561MODULE_ALIAS("snd-hda-codec-id:10de0019");
1562MODULE_ALIAS("snd-hda-codec-id:10de001a");
1563MODULE_ALIAS("snd-hda-codec-id:10de001b");
1564MODULE_ALIAS("snd-hda-codec-id:10de001c");
1565MODULE_ALIAS("snd-hda-codec-id:10de0040");
1566MODULE_ALIAS("snd-hda-codec-id:10de0041");
1567MODULE_ALIAS("snd-hda-codec-id:10de0042");
1568MODULE_ALIAS("snd-hda-codec-id:10de0043");
1569MODULE_ALIAS("snd-hda-codec-id:10de0044");
1570MODULE_ALIAS("snd-hda-codec-id:10de0067");
1571MODULE_ALIAS("snd-hda-codec-id:10de8001");
1572MODULE_ALIAS("snd-hda-codec-id:17e80047");
1573MODULE_ALIAS("snd-hda-codec-id:80860054");
1574MODULE_ALIAS("snd-hda-codec-id:80862801");
1575MODULE_ALIAS("snd-hda-codec-id:80862802");
1576MODULE_ALIAS("snd-hda-codec-id:80862803");
1577MODULE_ALIAS("snd-hda-codec-id:80862804");
1578MODULE_ALIAS("snd-hda-codec-id:80862805");
1579MODULE_ALIAS("snd-hda-codec-id:808629fb");
1580
1581MODULE_LICENSE("GPL");
1582MODULE_DESCRIPTION("HDMI HD-audio codec");
1583MODULE_ALIAS("snd-hda-codec-intelhdmi");
1584MODULE_ALIAS("snd-hda-codec-nvhdmi");
1585MODULE_ALIAS("snd-hda-codec-atihdmi");
1586
1587static struct hda_codec_preset_list intel_list = {
1588 .preset = snd_hda_preset_hdmi,
1589 .owner = THIS_MODULE,
1590};
1591
1592static int __init patch_hdmi_init(void)
1593{
1594 return snd_hda_add_codec_preset(&intel_list);
1595}
1596
1597static void __exit patch_hdmi_exit(void)
1598{
1599 snd_hda_delete_codec_preset(&intel_list);
1600}
1601
1602module_init(patch_hdmi_init)
1603module_exit(patch_hdmi_exit)
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
deleted file mode 100644
index 36a9b83a6174..000000000000
--- a/sound/pci/hda/patch_intelhdmi.c
+++ /dev/null
@@ -1,220 +0,0 @@
1/*
2 *
3 * patch_intelhdmi.c - Patch for Intel HDMI codecs
4 *
5 * Copyright(c) 2008 Intel Corporation. All rights reserved.
6 *
7 * Authors:
8 * Jiang Zhe <zhe.jiang@intel.com>
9 * Wu Fengguang <wfg@linux.intel.com>
10 *
11 * Maintained by:
12 * Wu Fengguang <wfg@linux.intel.com>
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the Free
16 * Software Foundation; either version 2 of the License, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/slab.h>
32#include <sound/core.h>
33#include "hda_codec.h"
34#include "hda_local.h"
35
36/*
37 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
38 * could support two independent pipes, each of them can be connected to one or
39 * more ports (DVI, HDMI or DisplayPort).
40 *
41 * The HDA correspondence of pipes/ports are converter/pin nodes.
42 */
43#define MAX_HDMI_CVTS 3
44#define MAX_HDMI_PINS 3
45
46#include "patch_hdmi.c"
47
48static char *intel_hdmi_pcm_names[MAX_HDMI_CVTS] = {
49 "INTEL HDMI 0",
50 "INTEL HDMI 1",
51 "INTEL HDMI 2",
52};
53
54/*
55 * HDMI callbacks
56 */
57
58static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
59 struct hda_codec *codec,
60 unsigned int stream_tag,
61 unsigned int format,
62 struct snd_pcm_substream *substream)
63{
64 hdmi_set_channel_count(codec, hinfo->nid,
65 substream->runtime->channels);
66
67 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
68
69 return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
70}
71
72static struct hda_pcm_stream intel_hdmi_pcm_playback = {
73 .substreams = 1,
74 .channels_min = 2,
75 .ops = {
76 .open = hdmi_pcm_open,
77 .prepare = intel_hdmi_playback_pcm_prepare,
78 },
79};
80
81static int intel_hdmi_build_pcms(struct hda_codec *codec)
82{
83 struct hdmi_spec *spec = codec->spec;
84 struct hda_pcm *info = spec->pcm_rec;
85 int i;
86
87 codec->num_pcms = spec->num_cvts;
88 codec->pcm_info = info;
89
90 for (i = 0; i < codec->num_pcms; i++, info++) {
91 unsigned int chans;
92
93 chans = get_wcaps(codec, spec->cvt[i]);
94 chans = get_wcaps_channels(chans);
95
96 info->name = intel_hdmi_pcm_names[i];
97 info->pcm_type = HDA_PCM_TYPE_HDMI;
98 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
99 intel_hdmi_pcm_playback;
100 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
101 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
102 }
103
104 return 0;
105}
106
107static int intel_hdmi_build_controls(struct hda_codec *codec)
108{
109 struct hdmi_spec *spec = codec->spec;
110 int err;
111 int i;
112
113 for (i = 0; i < codec->num_pcms; i++) {
114 err = snd_hda_create_spdif_out_ctls(codec, spec->cvt[i]);
115 if (err < 0)
116 return err;
117 }
118
119 return 0;
120}
121
122static int intel_hdmi_init(struct hda_codec *codec)
123{
124 struct hdmi_spec *spec = codec->spec;
125 int i;
126
127 for (i = 0; spec->pin[i]; i++) {
128 hdmi_enable_output(codec, spec->pin[i]);
129 snd_hda_codec_write(codec, spec->pin[i], 0,
130 AC_VERB_SET_UNSOLICITED_ENABLE,
131 AC_USRSP_EN | spec->pin[i]);
132 }
133 return 0;
134}
135
136static void intel_hdmi_free(struct hda_codec *codec)
137{
138 struct hdmi_spec *spec = codec->spec;
139 int i;
140
141 for (i = 0; i < spec->num_pins; i++)
142 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
143
144 kfree(spec);
145}
146
147static struct hda_codec_ops intel_hdmi_patch_ops = {
148 .init = intel_hdmi_init,
149 .free = intel_hdmi_free,
150 .build_pcms = intel_hdmi_build_pcms,
151 .build_controls = intel_hdmi_build_controls,
152 .unsol_event = hdmi_unsol_event,
153};
154
155static int patch_intel_hdmi(struct hda_codec *codec)
156{
157 struct hdmi_spec *spec;
158 int i;
159
160 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
161 if (spec == NULL)
162 return -ENOMEM;
163
164 codec->spec = spec;
165 if (hdmi_parse_codec(codec) < 0) {
166 codec->spec = NULL;
167 kfree(spec);
168 return -EINVAL;
169 }
170 codec->patch_ops = intel_hdmi_patch_ops;
171
172 for (i = 0; i < spec->num_pins; i++)
173 snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
174
175 init_channel_allocations();
176
177 return 0;
178}
179
180static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
181{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_intel_hdmi },
182{ .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_intel_hdmi },
183{ .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_intel_hdmi },
184{ .id = 0x80862803, .name = "Eaglelake HDMI", .patch = patch_intel_hdmi },
185{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_intel_hdmi },
186{ .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_intel_hdmi },
187{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_intel_hdmi },
188{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
189{} /* terminator */
190};
191
192MODULE_ALIAS("snd-hda-codec-id:808629fb");
193MODULE_ALIAS("snd-hda-codec-id:80862801");
194MODULE_ALIAS("snd-hda-codec-id:80862802");
195MODULE_ALIAS("snd-hda-codec-id:80862803");
196MODULE_ALIAS("snd-hda-codec-id:80862804");
197MODULE_ALIAS("snd-hda-codec-id:80862805");
198MODULE_ALIAS("snd-hda-codec-id:80860054");
199MODULE_ALIAS("snd-hda-codec-id:10951392");
200
201MODULE_LICENSE("GPL");
202MODULE_DESCRIPTION("Intel HDMI HD-audio codec");
203
204static struct hda_codec_preset_list intel_list = {
205 .preset = snd_hda_preset_intelhdmi,
206 .owner = THIS_MODULE,
207};
208
209static int __init patch_intelhdmi_init(void)
210{
211 return snd_hda_add_codec_preset(&intel_list);
212}
213
214static void __exit patch_intelhdmi_exit(void)
215{
216 snd_hda_delete_codec_preset(&intel_list);
217}
218
219module_init(patch_intelhdmi_init)
220module_exit(patch_intelhdmi_exit)
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
deleted file mode 100644
index baa108b9d6aa..000000000000
--- a/sound/pci/hda/patch_nvhdmi.c
+++ /dev/null
@@ -1,608 +0,0 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for NVIDIA HDMI codecs
5 *
6 * Copyright (c) 2008 NVIDIA Corp. All rights reserved.
7 * Copyright (c) 2008 Wei Ni <wni@nvidia.com>
8 *
9 *
10 * This driver is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This driver is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/slab.h>
28#include <sound/core.h>
29#include "hda_codec.h"
30#include "hda_local.h"
31
32#define MAX_HDMI_CVTS 1
33#define MAX_HDMI_PINS 1
34
35#include "patch_hdmi.c"
36
37static char *nvhdmi_pcm_names[MAX_HDMI_CVTS] = {
38 "NVIDIA HDMI",
39};
40
41/* define below to restrict the supported rates and formats */
42/* #define LIMITED_RATE_FMT_SUPPORT */
43
44enum HDACodec {
45 HDA_CODEC_NVIDIA_MCP7X,
46 HDA_CODEC_NVIDIA_MCP89,
47 HDA_CODEC_NVIDIA_GT21X,
48 HDA_CODEC_INVALID
49};
50
51#define Nv_VERB_SET_Channel_Allocation 0xF79
52#define Nv_VERB_SET_Info_Frame_Checksum 0xF7A
53#define Nv_VERB_SET_Audio_Protection_On 0xF98
54#define Nv_VERB_SET_Audio_Protection_Off 0xF99
55
56#define nvhdmi_master_con_nid_7x 0x04
57#define nvhdmi_master_pin_nid_7x 0x05
58
59#define nvhdmi_master_con_nid_89 0x04
60#define nvhdmi_master_pin_nid_89 0x05
61
62static hda_nid_t nvhdmi_con_nids_7x[4] = {
63 /*front, rear, clfe, rear_surr */
64 0x6, 0x8, 0xa, 0xc,
65};
66
67static struct hda_verb nvhdmi_basic_init_7x[] = {
68 /* set audio protect on */
69 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
70 /* enable digital output on pin widget */
71 { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
72 { 0x7, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
73 { 0x9, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
74 { 0xb, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
75 { 0xd, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
76 {} /* terminator */
77};
78
79#ifdef LIMITED_RATE_FMT_SUPPORT
80/* support only the safe format and rate */
81#define SUPPORTED_RATES SNDRV_PCM_RATE_48000
82#define SUPPORTED_MAXBPS 16
83#define SUPPORTED_FORMATS SNDRV_PCM_FMTBIT_S16_LE
84#else
85/* support all rates and formats */
86#define SUPPORTED_RATES \
87 (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
88 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
89 SNDRV_PCM_RATE_192000)
90#define SUPPORTED_MAXBPS 24
91#define SUPPORTED_FORMATS \
92 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
93#endif
94
95/*
96 * Controls
97 */
98static int nvhdmi_build_controls(struct hda_codec *codec)
99{
100 struct hdmi_spec *spec = codec->spec;
101 int err;
102 int i;
103
104 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
105 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
106 for (i = 0; i < codec->num_pcms; i++) {
107 err = snd_hda_create_spdif_out_ctls(codec,
108 spec->cvt[i]);
109 if (err < 0)
110 return err;
111 }
112 } else {
113 err = snd_hda_create_spdif_out_ctls(codec,
114 spec->multiout.dig_out_nid);
115 if (err < 0)
116 return err;
117 }
118
119 return 0;
120}
121
122static int nvhdmi_init(struct hda_codec *codec)
123{
124 struct hdmi_spec *spec = codec->spec;
125 int i;
126 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
127 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
128 for (i = 0; spec->pin[i]; i++) {
129 hdmi_enable_output(codec, spec->pin[i]);
130 snd_hda_codec_write(codec, spec->pin[i], 0,
131 AC_VERB_SET_UNSOLICITED_ENABLE,
132 AC_USRSP_EN | spec->pin[i]);
133 }
134 } else {
135 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x);
136 }
137 return 0;
138}
139
140static void nvhdmi_free(struct hda_codec *codec)
141{
142 struct hdmi_spec *spec = codec->spec;
143 int i;
144
145 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
146 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
147 for (i = 0; i < spec->num_pins; i++)
148 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
149 }
150
151 kfree(spec);
152}
153
154/*
155 * Digital out
156 */
157static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
158 struct hda_codec *codec,
159 struct snd_pcm_substream *substream)
160{
161 struct hdmi_spec *spec = codec->spec;
162 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
163}
164
165static int nvhdmi_dig_playback_pcm_close_8ch_7x(struct hda_pcm_stream *hinfo,
166 struct hda_codec *codec,
167 struct snd_pcm_substream *substream)
168{
169 struct hdmi_spec *spec = codec->spec;
170 int i;
171
172 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
173 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
174 for (i = 0; i < 4; i++) {
175 /* set the stream id */
176 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
177 AC_VERB_SET_CHANNEL_STREAMID, 0);
178 /* set the stream format */
179 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
180 AC_VERB_SET_STREAM_FORMAT, 0);
181 }
182
183 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
184}
185
186static int nvhdmi_dig_playback_pcm_close_2ch(struct hda_pcm_stream *hinfo,
187 struct hda_codec *codec,
188 struct snd_pcm_substream *substream)
189{
190 struct hdmi_spec *spec = codec->spec;
191 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
192}
193
194static int nvhdmi_dig_playback_pcm_prepare_8ch_89(struct hda_pcm_stream *hinfo,
195 struct hda_codec *codec,
196 unsigned int stream_tag,
197 unsigned int format,
198 struct snd_pcm_substream *substream)
199{
200 hdmi_set_channel_count(codec, hinfo->nid,
201 substream->runtime->channels);
202
203 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
204
205 return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
206}
207
208static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
209 struct hda_codec *codec,
210 unsigned int stream_tag,
211 unsigned int format,
212 struct snd_pcm_substream *substream)
213{
214 int chs;
215 unsigned int dataDCC1, dataDCC2, chan, chanmask, channel_id;
216 int i;
217
218 mutex_lock(&codec->spdif_mutex);
219
220 chs = substream->runtime->channels;
221 chan = chs ? (chs - 1) : 1;
222
223 switch (chs) {
224 default:
225 case 0:
226 case 2:
227 chanmask = 0x00;
228 break;
229 case 4:
230 chanmask = 0x08;
231 break;
232 case 6:
233 chanmask = 0x0b;
234 break;
235 case 8:
236 chanmask = 0x13;
237 break;
238 }
239 dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT;
240 dataDCC2 = 0x2;
241
242 /* set the Audio InforFrame Channel Allocation */
243 snd_hda_codec_write(codec, 0x1, 0,
244 Nv_VERB_SET_Channel_Allocation, chanmask);
245
246 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
247 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
248 snd_hda_codec_write(codec,
249 nvhdmi_master_con_nid_7x,
250 0,
251 AC_VERB_SET_DIGI_CONVERT_1,
252 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
253
254 /* set the stream id */
255 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
256 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
257
258 /* set the stream format */
259 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
260 AC_VERB_SET_STREAM_FORMAT, format);
261
262 /* turn on again (if needed) */
263 /* enable and set the channel status audio/data flag */
264 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
265 snd_hda_codec_write(codec,
266 nvhdmi_master_con_nid_7x,
267 0,
268 AC_VERB_SET_DIGI_CONVERT_1,
269 codec->spdif_ctls & 0xff);
270 snd_hda_codec_write(codec,
271 nvhdmi_master_con_nid_7x,
272 0,
273 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
274 }
275
276 for (i = 0; i < 4; i++) {
277 if (chs == 2)
278 channel_id = 0;
279 else
280 channel_id = i * 2;
281
282 /* turn off SPDIF once;
283 *otherwise the IEC958 bits won't be updated
284 */
285 if (codec->spdif_status_reset &&
286 (codec->spdif_ctls & AC_DIG1_ENABLE))
287 snd_hda_codec_write(codec,
288 nvhdmi_con_nids_7x[i],
289 0,
290 AC_VERB_SET_DIGI_CONVERT_1,
291 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
292 /* set the stream id */
293 snd_hda_codec_write(codec,
294 nvhdmi_con_nids_7x[i],
295 0,
296 AC_VERB_SET_CHANNEL_STREAMID,
297 (stream_tag << 4) | channel_id);
298 /* set the stream format */
299 snd_hda_codec_write(codec,
300 nvhdmi_con_nids_7x[i],
301 0,
302 AC_VERB_SET_STREAM_FORMAT,
303 format);
304 /* turn on again (if needed) */
305 /* enable and set the channel status audio/data flag */
306 if (codec->spdif_status_reset &&
307 (codec->spdif_ctls & AC_DIG1_ENABLE)) {
308 snd_hda_codec_write(codec,
309 nvhdmi_con_nids_7x[i],
310 0,
311 AC_VERB_SET_DIGI_CONVERT_1,
312 codec->spdif_ctls & 0xff);
313 snd_hda_codec_write(codec,
314 nvhdmi_con_nids_7x[i],
315 0,
316 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
317 }
318 }
319
320 /* set the Audio Info Frame Checksum */
321 snd_hda_codec_write(codec, 0x1, 0,
322 Nv_VERB_SET_Info_Frame_Checksum,
323 (0x71 - chan - chanmask));
324
325 mutex_unlock(&codec->spdif_mutex);
326 return 0;
327}
328
329static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo,
330 struct hda_codec *codec,
331 unsigned int stream_tag,
332 unsigned int format,
333 struct snd_pcm_substream *substream)
334{
335 struct hdmi_spec *spec = codec->spec;
336 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
337 format, substream);
338}
339
340static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_89 = {
341 .substreams = 1,
342 .channels_min = 2,
343 .ops = {
344 .open = hdmi_pcm_open,
345 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89,
346 },
347};
348
349static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_7x = {
350 .substreams = 1,
351 .channels_min = 2,
352 .channels_max = 8,
353 .nid = nvhdmi_master_con_nid_7x,
354 .rates = SUPPORTED_RATES,
355 .maxbps = SUPPORTED_MAXBPS,
356 .formats = SUPPORTED_FORMATS,
357 .ops = {
358 .open = nvhdmi_dig_playback_pcm_open,
359 .close = nvhdmi_dig_playback_pcm_close_8ch_7x,
360 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch
361 },
362};
363
364static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
365 .substreams = 1,
366 .channels_min = 2,
367 .channels_max = 2,
368 .nid = nvhdmi_master_con_nid_7x,
369 .rates = SUPPORTED_RATES,
370 .maxbps = SUPPORTED_MAXBPS,
371 .formats = SUPPORTED_FORMATS,
372 .ops = {
373 .open = nvhdmi_dig_playback_pcm_open,
374 .close = nvhdmi_dig_playback_pcm_close_2ch,
375 .prepare = nvhdmi_dig_playback_pcm_prepare_2ch
376 },
377};
378
379static int nvhdmi_build_pcms_8ch_89(struct hda_codec *codec)
380{
381 struct hdmi_spec *spec = codec->spec;
382 struct hda_pcm *info = spec->pcm_rec;
383 int i;
384
385 codec->num_pcms = spec->num_cvts;
386 codec->pcm_info = info;
387
388 for (i = 0; i < codec->num_pcms; i++, info++) {
389 unsigned int chans;
390
391 chans = get_wcaps(codec, spec->cvt[i]);
392 chans = get_wcaps_channels(chans);
393
394 info->name = nvhdmi_pcm_names[i];
395 info->pcm_type = HDA_PCM_TYPE_HDMI;
396 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
397 = nvhdmi_pcm_digital_playback_8ch_89;
398 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
399 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
400 }
401
402 return 0;
403}
404
405static int nvhdmi_build_pcms_8ch_7x(struct hda_codec *codec)
406{
407 struct hdmi_spec *spec = codec->spec;
408 struct hda_pcm *info = spec->pcm_rec;
409
410 codec->num_pcms = 1;
411 codec->pcm_info = info;
412
413 info->name = "NVIDIA HDMI";
414 info->pcm_type = HDA_PCM_TYPE_HDMI;
415 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
416 = nvhdmi_pcm_digital_playback_8ch_7x;
417
418 return 0;
419}
420
421static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
422{
423 struct hdmi_spec *spec = codec->spec;
424 struct hda_pcm *info = spec->pcm_rec;
425
426 codec->num_pcms = 1;
427 codec->pcm_info = info;
428
429 info->name = "NVIDIA HDMI";
430 info->pcm_type = HDA_PCM_TYPE_HDMI;
431 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
432 = nvhdmi_pcm_digital_playback_2ch;
433
434 return 0;
435}
436
437static struct hda_codec_ops nvhdmi_patch_ops_8ch_89 = {
438 .build_controls = nvhdmi_build_controls,
439 .build_pcms = nvhdmi_build_pcms_8ch_89,
440 .init = nvhdmi_init,
441 .free = nvhdmi_free,
442 .unsol_event = hdmi_unsol_event,
443};
444
445static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
446 .build_controls = nvhdmi_build_controls,
447 .build_pcms = nvhdmi_build_pcms_8ch_7x,
448 .init = nvhdmi_init,
449 .free = nvhdmi_free,
450};
451
452static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
453 .build_controls = nvhdmi_build_controls,
454 .build_pcms = nvhdmi_build_pcms_2ch,
455 .init = nvhdmi_init,
456 .free = nvhdmi_free,
457};
458
459static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
460{
461 struct hdmi_spec *spec;
462 int i;
463
464 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
465 if (spec == NULL)
466 return -ENOMEM;
467
468 codec->spec = spec;
469 spec->codec_type = HDA_CODEC_NVIDIA_MCP89;
470 spec->old_pin_detect = 1;
471
472 if (hdmi_parse_codec(codec) < 0) {
473 codec->spec = NULL;
474 kfree(spec);
475 return -EINVAL;
476 }
477 codec->patch_ops = nvhdmi_patch_ops_8ch_89;
478
479 for (i = 0; i < spec->num_pins; i++)
480 snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
481
482 init_channel_allocations();
483
484 return 0;
485}
486
487static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
488{
489 struct hdmi_spec *spec;
490
491 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
492 if (spec == NULL)
493 return -ENOMEM;
494
495 codec->spec = spec;
496
497 spec->multiout.num_dacs = 0; /* no analog */
498 spec->multiout.max_channels = 8;
499 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
500 spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
501 spec->old_pin_detect = 1;
502
503 codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
504
505 return 0;
506}
507
508static int patch_nvhdmi_2ch(struct hda_codec *codec)
509{
510 struct hdmi_spec *spec;
511
512 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
513 if (spec == NULL)
514 return -ENOMEM;
515
516 codec->spec = spec;
517
518 spec->multiout.num_dacs = 0; /* no analog */
519 spec->multiout.max_channels = 2;
520 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
521 spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
522 spec->old_pin_detect = 1;
523
524 codec->patch_ops = nvhdmi_patch_ops_2ch;
525
526 return 0;
527}
528
529/*
530 * patch entries
531 */
532static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
533 { .id = 0x10de0002, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
534 { .id = 0x10de0003, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
535 { .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
536 { .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
537 { .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x },
538 { .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
539 { .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
540 { .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_nvhdmi_8ch_89 },
541 { .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
542 { .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
543 { .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
544 { .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
545 { .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
546 { .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
547 { .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
548 { .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
549 { .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
550 { .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
551 { .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
552 { .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
553 { .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
554 { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
555 { .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
556 { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
557 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
558 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
559 {} /* terminator */
560};
561
562MODULE_ALIAS("snd-hda-codec-id:10de0002");
563MODULE_ALIAS("snd-hda-codec-id:10de0003");
564MODULE_ALIAS("snd-hda-codec-id:10de0005");
565MODULE_ALIAS("snd-hda-codec-id:10de0006");
566MODULE_ALIAS("snd-hda-codec-id:10de0007");
567MODULE_ALIAS("snd-hda-codec-id:10de000a");
568MODULE_ALIAS("snd-hda-codec-id:10de000b");
569MODULE_ALIAS("snd-hda-codec-id:10de000c");
570MODULE_ALIAS("snd-hda-codec-id:10de000d");
571MODULE_ALIAS("snd-hda-codec-id:10de0010");
572MODULE_ALIAS("snd-hda-codec-id:10de0011");
573MODULE_ALIAS("snd-hda-codec-id:10de0012");
574MODULE_ALIAS("snd-hda-codec-id:10de0013");
575MODULE_ALIAS("snd-hda-codec-id:10de0014");
576MODULE_ALIAS("snd-hda-codec-id:10de0018");
577MODULE_ALIAS("snd-hda-codec-id:10de0019");
578MODULE_ALIAS("snd-hda-codec-id:10de001a");
579MODULE_ALIAS("snd-hda-codec-id:10de001b");
580MODULE_ALIAS("snd-hda-codec-id:10de001c");
581MODULE_ALIAS("snd-hda-codec-id:10de0040");
582MODULE_ALIAS("snd-hda-codec-id:10de0041");
583MODULE_ALIAS("snd-hda-codec-id:10de0042");
584MODULE_ALIAS("snd-hda-codec-id:10de0043");
585MODULE_ALIAS("snd-hda-codec-id:10de0044");
586MODULE_ALIAS("snd-hda-codec-id:10de0067");
587MODULE_ALIAS("snd-hda-codec-id:10de8001");
588
589MODULE_LICENSE("GPL");
590MODULE_DESCRIPTION("NVIDIA HDMI HD-audio codec");
591
592static struct hda_codec_preset_list nvhdmi_list = {
593 .preset = snd_hda_preset_nvhdmi,
594 .owner = THIS_MODULE,
595};
596
597static int __init patch_nvhdmi_init(void)
598{
599 return snd_hda_add_codec_preset(&nvhdmi_list);
600}
601
602static void __exit patch_nvhdmi_exit(void)
603{
604 snd_hda_delete_codec_preset(&nvhdmi_list);
605}
606
607module_init(patch_nvhdmi_init)
608module_exit(patch_nvhdmi_exit)