]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Takashi Iwai <tiwai@suse.de> |
2 | Subject: ALSA: hda - Nvidia HDMI codec support | |
3 | Patch-mainline: 2.6.28-rc1 | |
4 | References: | |
5 | ||
6 | Add the minimal support of Nvidia HDMI codec. | |
7 | ||
8 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | |
9 | ||
10 | --- | |
11 | --- | |
12 | sound/pci/Kconfig | 8 ++ | |
13 | sound/pci/hda/Makefile | 1 | |
14 | sound/pci/hda/hda_codec.c | 3 | |
15 | sound/pci/hda/hda_patch.h | 2 | |
16 | sound/pci/hda/patch_nvhdmi.c | 165 +++++++++++++++++++++++++++++++++++++++++++ | |
17 | 5 files changed, 179 insertions(+) | |
18 | ||
19 | --- a/sound/pci/hda/hda_codec.c | |
20 | +++ b/sound/pci/hda/hda_codec.c | |
21 | @@ -94,6 +94,9 @@ static const struct hda_codec_preset *hd | |
22 | #ifdef CONFIG_SND_HDA_CODEC_VIA | |
23 | snd_hda_preset_via, | |
24 | #endif | |
25 | +#ifdef CONFIG_SND_HDA_CODEC_NVHDMI | |
26 | + snd_hda_preset_nvhdmi, | |
27 | +#endif | |
28 | NULL | |
29 | }; | |
30 | ||
31 | --- a/sound/pci/hda/hda_patch.h | |
32 | +++ b/sound/pci/hda/hda_patch.h | |
33 | @@ -18,3 +18,5 @@ extern struct hda_codec_preset snd_hda_p | |
34 | extern struct hda_codec_preset snd_hda_preset_conexant[]; | |
35 | /* VIA codecs */ | |
36 | extern struct hda_codec_preset snd_hda_preset_via[]; | |
37 | +/* NVIDIA HDMI codecs */ | |
38 | +extern struct hda_codec_preset snd_hda_preset_nvhdmi[]; | |
39 | --- a/sound/pci/hda/Makefile | |
40 | +++ b/sound/pci/hda/Makefile | |
41 | @@ -15,5 +15,6 @@ snd-hda-intel-$(CONFIG_SND_HDA_CODEC_SI3 | |
42 | snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ATIHDMI) += patch_atihdmi.o | |
43 | snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CONEXANT) += patch_conexant.o | |
44 | snd-hda-intel-$(CONFIG_SND_HDA_CODEC_VIA) += patch_via.o | |
45 | +snd-hda-intel-$(CONFIG_SND_HDA_CODEC_NVHDMI) += patch_nvhdmi.o | |
46 | ||
47 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o | |
48 | --- /dev/null | |
49 | +++ b/sound/pci/hda/patch_nvhdmi.c | |
50 | @@ -0,0 +1,165 @@ | |
51 | +/* | |
52 | + * Universal Interface for Intel High Definition Audio Codec | |
53 | + * | |
54 | + * HD audio interface patch for NVIDIA HDMI codecs | |
55 | + * | |
56 | + * Copyright (c) 2008 NVIDIA Corp. All rights reserved. | |
57 | + * Copyright (c) 2008 Wei Ni <wni@nvidia.com> | |
58 | + * | |
59 | + * | |
60 | + * This driver is free software; you can redistribute it and/or modify | |
61 | + * it under the terms of the GNU General Public License as published by | |
62 | + * the Free Software Foundation; either version 2 of the License, or | |
63 | + * (at your option) any later version. | |
64 | + * | |
65 | + * This driver is distributed in the hope that it will be useful, | |
66 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
67 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
68 | + * GNU General Public License for more details. | |
69 | + * | |
70 | + * You should have received a copy of the GNU General Public License | |
71 | + * along with this program; if not, write to the Free Software | |
72 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
73 | + */ | |
74 | + | |
75 | +#include <linux/init.h> | |
76 | +#include <linux/delay.h> | |
77 | +#include <linux/slab.h> | |
78 | +#include <sound/core.h> | |
79 | +#include "hda_codec.h" | |
80 | +#include "hda_local.h" | |
81 | + | |
82 | +struct nvhdmi_spec { | |
83 | + struct hda_multi_out multiout; | |
84 | + | |
85 | + struct hda_pcm pcm_rec; | |
86 | +}; | |
87 | + | |
88 | +static struct hda_verb nvhdmi_basic_init[] = { | |
89 | + /* enable digital output on pin widget */ | |
90 | + { 0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | |
91 | + {} /* terminator */ | |
92 | +}; | |
93 | + | |
94 | +/* | |
95 | + * Controls | |
96 | + */ | |
97 | +static int nvhdmi_build_controls(struct hda_codec *codec) | |
98 | +{ | |
99 | + struct nvhdmi_spec *spec = codec->spec; | |
100 | + int err; | |
101 | + | |
102 | + err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); | |
103 | + if (err < 0) | |
104 | + return err; | |
105 | + | |
106 | + return 0; | |
107 | +} | |
108 | + | |
109 | +static int nvhdmi_init(struct hda_codec *codec) | |
110 | +{ | |
111 | + snd_hda_sequence_write(codec, nvhdmi_basic_init); | |
112 | + return 0; | |
113 | +} | |
114 | + | |
115 | +/* | |
116 | + * Digital out | |
117 | + */ | |
118 | +static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | |
119 | + struct hda_codec *codec, | |
120 | + struct snd_pcm_substream *substream) | |
121 | +{ | |
122 | + struct nvhdmi_spec *spec = codec->spec; | |
123 | + return snd_hda_multi_out_dig_open(codec, &spec->multiout); | |
124 | +} | |
125 | + | |
126 | +static int nvhdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |
127 | + struct hda_codec *codec, | |
128 | + struct snd_pcm_substream *substream) | |
129 | +{ | |
130 | + struct nvhdmi_spec *spec = codec->spec; | |
131 | + return snd_hda_multi_out_dig_close(codec, &spec->multiout); | |
132 | +} | |
133 | + | |
134 | +static int nvhdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |
135 | + struct hda_codec *codec, | |
136 | + unsigned int stream_tag, | |
137 | + unsigned int format, | |
138 | + struct snd_pcm_substream *substream) | |
139 | +{ | |
140 | + struct nvhdmi_spec *spec = codec->spec; | |
141 | + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, | |
142 | + format, substream); | |
143 | +} | |
144 | + | |
145 | +static struct hda_pcm_stream nvhdmi_pcm_digital_playback = { | |
146 | + .substreams = 1, | |
147 | + .channels_min = 2, | |
148 | + .channels_max = 2, | |
149 | + .nid = 0x4, /* NID to query formats and rates and setup streams */ | |
150 | + .rates = SNDRV_PCM_RATE_48000, | |
151 | + .maxbps = 16, | |
152 | + .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
153 | + .ops = { | |
154 | + .open = nvhdmi_dig_playback_pcm_open, | |
155 | + .close = nvhdmi_dig_playback_pcm_close, | |
156 | + .prepare = nvhdmi_dig_playback_pcm_prepare | |
157 | + }, | |
158 | +}; | |
159 | + | |
160 | +static int nvhdmi_build_pcms(struct hda_codec *codec) | |
161 | +{ | |
162 | + struct nvhdmi_spec *spec = codec->spec; | |
163 | + struct hda_pcm *info = &spec->pcm_rec; | |
164 | + | |
165 | + codec->num_pcms = 1; | |
166 | + codec->pcm_info = info; | |
167 | + | |
168 | + info->name = "NVIDIA HDMI"; | |
169 | + info->pcm_type = HDA_PCM_TYPE_HDMI; | |
170 | + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = nvhdmi_pcm_digital_playback; | |
171 | + | |
172 | + return 0; | |
173 | +} | |
174 | + | |
175 | +static void nvhdmi_free(struct hda_codec *codec) | |
176 | +{ | |
177 | + kfree(codec->spec); | |
178 | +} | |
179 | + | |
180 | +static struct hda_codec_ops nvhdmi_patch_ops = { | |
181 | + .build_controls = nvhdmi_build_controls, | |
182 | + .build_pcms = nvhdmi_build_pcms, | |
183 | + .init = nvhdmi_init, | |
184 | + .free = nvhdmi_free, | |
185 | +}; | |
186 | + | |
187 | +static int patch_nvhdmi(struct hda_codec *codec) | |
188 | +{ | |
189 | + struct nvhdmi_spec *spec; | |
190 | + | |
191 | + spec = kzalloc(sizeof(*spec), GFP_KERNEL); | |
192 | + if (spec == NULL) | |
193 | + return -ENOMEM; | |
194 | + | |
195 | + codec->spec = spec; | |
196 | + | |
197 | + spec->multiout.num_dacs = 0; /* no analog */ | |
198 | + spec->multiout.max_channels = 2; | |
199 | + spec->multiout.dig_out_nid = 0x4; /* NID for copying analog to digital, | |
200 | + * seems to be unused in pure-digital | |
201 | + * case. */ | |
202 | + | |
203 | + codec->patch_ops = nvhdmi_patch_ops; | |
204 | + | |
205 | + return 0; | |
206 | +} | |
207 | + | |
208 | +/* | |
209 | + * patch entries | |
210 | + */ | |
211 | +struct hda_codec_preset snd_hda_preset_nvhdmi[] = { | |
212 | + { .id = 0x10de0002, .name = "NVIDIA MCP78 HDMI", .patch = patch_nvhdmi }, | |
213 | + { .id = 0x10de0007, .name = "NVIDIA MCP7A HDMI", .patch = patch_nvhdmi }, | |
214 | + {} /* terminator */ | |
215 | +}; | |
216 | --- a/sound/pci/Kconfig | |
217 | +++ b/sound/pci/Kconfig | |
218 | @@ -565,6 +565,14 @@ config SND_HDA_CODEC_ATIHDMI | |
219 | Say Y here to include ATI HDMI HD-audio codec support in | |
220 | snd-hda-intel driver, such as ATI RS600 HDMI. | |
221 | ||
222 | +config SND_HDA_CODEC_NVHDMI | |
223 | + bool "Build NVIDIA HDMI HD-audio codec support" | |
224 | + depends on SND_HDA_INTEL | |
225 | + default y | |
226 | + help | |
227 | + Say Y here to include NVIDIA HDMI HD-audio codec support in | |
228 | + snd-hda-intel driver, such as NVIDIA MCP78 HDMI. | |
229 | + | |
230 | config SND_HDA_CODEC_CONEXANT | |
231 | bool "Build Conexant HD-audio codec support" | |
232 | depends on SND_HDA_INTEL |