aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_hdmi.c
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 /sound/pci/hda/patch_hdmi.c
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>
Diffstat (limited to 'sound/pci/hda/patch_hdmi.c')
-rw-r--r--sound/pci/hda/patch_hdmi.c685
1 files changed, 682 insertions, 3 deletions
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)