提交 f1cf9a66 编写于 作者: T Takashi Iwai

Merge branch 'topic/hda' into for-linus

...@@ -157,7 +157,7 @@ config SND_HDA_CODEC_INTELHDMI ...@@ -157,7 +157,7 @@ config SND_HDA_CODEC_INTELHDMI
config SND_HDA_ELD config SND_HDA_ELD
def_bool y def_bool y
depends on SND_HDA_CODEC_INTELHDMI depends on SND_HDA_CODEC_INTELHDMI || SND_HDA_CODEC_NVHDMI
config SND_HDA_CODEC_CIRRUS config SND_HDA_CODEC_CIRRUS
bool "Build Cirrus Logic codec support" bool "Build Cirrus Logic codec support"
......
...@@ -3,7 +3,7 @@ snd-hda-intel-objs := hda_intel.o ...@@ -3,7 +3,7 @@ snd-hda-intel-objs := hda_intel.o
snd-hda-codec-y := hda_codec.o snd-hda-codec-y := hda_codec.o
snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
# snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o
snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
...@@ -18,7 +18,7 @@ snd-hda-codec-ca0110-objs := patch_ca0110.o ...@@ -18,7 +18,7 @@ snd-hda-codec-ca0110-objs := patch_ca0110.o
snd-hda-codec-conexant-objs := patch_conexant.o snd-hda-codec-conexant-objs := patch_conexant.o
snd-hda-codec-via-objs := patch_via.o snd-hda-codec-via-objs := patch_via.o
snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o
snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o hda_eld.o snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o
# common driver # common driver
obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o
......
...@@ -978,8 +978,9 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, ...@@ -978,8 +978,9 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
* *
* Returns 0 if successful, or a negative error code. * Returns 0 if successful, or a negative error code.
*/ */
int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
struct hda_codec **codecp) unsigned int codec_addr,
struct hda_codec **codecp)
{ {
struct hda_codec *codec; struct hda_codec *codec;
char component[31]; char component[31];
...@@ -1186,7 +1187,7 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream); ...@@ -1186,7 +1187,7 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
*/ */
/* FIXME: more better hash key? */ /* FIXME: more better hash key? */
#define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24)) #define HDA_HASH_KEY(nid, dir, idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24)) #define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24))
#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24)) #define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24))
#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24)) #define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24))
...@@ -1356,7 +1357,8 @@ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) ...@@ -1356,7 +1357,8 @@ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
if (!codec->no_trigger_sense) { if (!codec->no_trigger_sense) {
pincap = snd_hda_query_pin_caps(codec, nid); pincap = snd_hda_query_pin_caps(codec, nid);
if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); snd_hda_codec_read(codec, nid, 0,
AC_VERB_SET_PIN_SENSE, 0);
} }
return snd_hda_codec_read(codec, nid, 0, return snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_PIN_SENSE, 0); AC_VERB_GET_PIN_SENSE, 0);
...@@ -1372,8 +1374,8 @@ EXPORT_SYMBOL_HDA(snd_hda_pin_sense); ...@@ -1372,8 +1374,8 @@ EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
*/ */
int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
{ {
u32 sense = snd_hda_pin_sense(codec, nid); u32 sense = snd_hda_pin_sense(codec, nid);
return !!(sense & AC_PINSENSE_PRESENCE); return !!(sense & AC_PINSENSE_PRESENCE);
} }
EXPORT_SYMBOL_HDA(snd_hda_jack_detect); EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
...@@ -1952,7 +1954,7 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, ...@@ -1952,7 +1954,7 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
err = snd_hda_ctl_add(codec, 0, kctl); err = snd_hda_ctl_add(codec, 0, kctl);
if (err < 0) if (err < 0)
return err; return err;
for (s = slaves; *s; s++) { for (s = slaves; *s; s++) {
struct snd_kcontrol *sctl; struct snd_kcontrol *sctl;
int i = 0; int i = 0;
...@@ -2439,27 +2441,27 @@ static struct snd_kcontrol_new dig_mixes[] = { ...@@ -2439,27 +2441,27 @@ static struct snd_kcontrol_new dig_mixes[] = {
{ {
.access = SNDRV_CTL_ELEM_ACCESS_READ, .access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
.info = snd_hda_spdif_mask_info, .info = snd_hda_spdif_mask_info,
.get = snd_hda_spdif_cmask_get, .get = snd_hda_spdif_cmask_get,
}, },
{ {
.access = SNDRV_CTL_ELEM_ACCESS_READ, .access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
.info = snd_hda_spdif_mask_info, .info = snd_hda_spdif_mask_info,
.get = snd_hda_spdif_pmask_get, .get = snd_hda_spdif_pmask_get,
}, },
{ {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
.info = snd_hda_spdif_mask_info, .info = snd_hda_spdif_mask_info,
.get = snd_hda_spdif_default_get, .get = snd_hda_spdif_default_get,
.put = snd_hda_spdif_default_put, .put = snd_hda_spdif_default_put,
}, },
{ {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
.info = snd_hda_spdif_out_switch_info, .info = snd_hda_spdif_out_switch_info,
.get = snd_hda_spdif_out_switch_get, .get = snd_hda_spdif_out_switch_get,
.put = snd_hda_spdif_out_switch_put, .put = snd_hda_spdif_out_switch_put,
...@@ -2610,7 +2612,7 @@ static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol, ...@@ -2610,7 +2612,7 @@ static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
static struct snd_kcontrol_new dig_in_ctls[] = { static struct snd_kcontrol_new dig_in_ctls[] = {
{ {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
.info = snd_hda_spdif_in_switch_info, .info = snd_hda_spdif_in_switch_info,
.get = snd_hda_spdif_in_switch_get, .get = snd_hda_spdif_in_switch_get,
.put = snd_hda_spdif_in_switch_put, .put = snd_hda_spdif_in_switch_put,
...@@ -2618,7 +2620,7 @@ static struct snd_kcontrol_new dig_in_ctls[] = { ...@@ -2618,7 +2620,7 @@ static struct snd_kcontrol_new dig_in_ctls[] = {
{ {
.access = SNDRV_CTL_ELEM_ACCESS_READ, .access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT), .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
.info = snd_hda_spdif_mask_info, .info = snd_hda_spdif_mask_info,
.get = snd_hda_spdif_in_status_get, .get = snd_hda_spdif_in_status_get,
}, },
...@@ -2883,7 +2885,7 @@ int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus) ...@@ -2883,7 +2885,7 @@ int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus)
int err = snd_hda_codec_build_controls(codec); int err = snd_hda_codec_build_controls(codec);
if (err < 0) { if (err < 0) {
printk(KERN_ERR "hda_codec: cannot build controls" printk(KERN_ERR "hda_codec: cannot build controls"
"for #%d (error %d)\n", codec->addr, err); "for #%d (error %d)\n", codec->addr, err);
err = snd_hda_codec_reset(codec); err = snd_hda_codec_reset(codec);
if (err < 0) { if (err < 0) {
printk(KERN_ERR printk(KERN_ERR
...@@ -2979,8 +2981,12 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, ...@@ -2979,8 +2981,12 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
val |= channels - 1; val |= channels - 1;
switch (snd_pcm_format_width(format)) { switch (snd_pcm_format_width(format)) {
case 8: val |= 0x00; break; case 8:
case 16: val |= 0x10; break; val |= 0x00;
break;
case 16:
val |= 0x10;
break;
case 20: case 20:
case 24: case 24:
case 32: case 32:
...@@ -3298,7 +3304,8 @@ static int get_empty_pcm_device(struct hda_bus *bus, int type) ...@@ -3298,7 +3304,8 @@ static int get_empty_pcm_device(struct hda_bus *bus, int type)
if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits)) if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
return audio_idx[type][i]; return audio_idx[type][i];
snd_printk(KERN_WARNING "Too many %s devices\n", snd_hda_pcm_type_name[type]); snd_printk(KERN_WARNING "Too many %s devices\n",
snd_hda_pcm_type_name[type]);
return -EAGAIN; return -EAGAIN;
} }
...@@ -3336,7 +3343,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec) ...@@ -3336,7 +3343,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
err = codec->patch_ops.build_pcms(codec); err = codec->patch_ops.build_pcms(codec);
if (err < 0) { if (err < 0) {
printk(KERN_ERR "hda_codec: cannot build PCMs" printk(KERN_ERR "hda_codec: cannot build PCMs"
"for #%d (error %d)\n", codec->addr, err); "for #%d (error %d)\n", codec->addr, err);
err = snd_hda_codec_reset(codec); err = snd_hda_codec_reset(codec);
if (err < 0) { if (err < 0) {
printk(KERN_ERR printk(KERN_ERR
...@@ -3466,8 +3473,8 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_config); ...@@ -3466,8 +3473,8 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
/** /**
* snd_hda_check_board_codec_sid_config - compare the current codec * snd_hda_check_board_codec_sid_config - compare the current codec
subsystem ID with the subsystem ID with the
config table config table
This is important for Gateway notebooks with SB450 HDA Audio This is important for Gateway notebooks with SB450 HDA Audio
where the vendor ID of the PCI device is: where the vendor ID of the PCI device is:
...@@ -3607,7 +3614,7 @@ void snd_hda_update_power_acct(struct hda_codec *codec) ...@@ -3607,7 +3614,7 @@ void snd_hda_update_power_acct(struct hda_codec *codec)
* *
* Increment the power-up counter and power up the hardware really when * Increment the power-up counter and power up the hardware really when
* not turned on yet. * not turned on yet.
*/ */
void snd_hda_power_up(struct hda_codec *codec) void snd_hda_power_up(struct hda_codec *codec)
{ {
struct hda_bus *bus = codec->bus; struct hda_bus *bus = codec->bus;
...@@ -3636,7 +3643,7 @@ EXPORT_SYMBOL_HDA(snd_hda_power_up); ...@@ -3636,7 +3643,7 @@ EXPORT_SYMBOL_HDA(snd_hda_power_up);
* *
* Decrement the power-up counter and schedules the power-off work if * Decrement the power-up counter and schedules the power-off work if
* the counter rearches to zero. * the counter rearches to zero.
*/ */
void snd_hda_power_down(struct hda_codec *codec) void snd_hda_power_down(struct hda_codec *codec)
{ {
--codec->power_count; --codec->power_count;
...@@ -3662,7 +3669,7 @@ EXPORT_SYMBOL_HDA(snd_hda_power_down); ...@@ -3662,7 +3669,7 @@ EXPORT_SYMBOL_HDA(snd_hda_power_down);
* *
* This function is supposed to be set or called from the check_power_status * This function is supposed to be set or called from the check_power_status
* patch ops. * patch ops.
*/ */
int snd_hda_check_amp_list_power(struct hda_codec *codec, int snd_hda_check_amp_list_power(struct hda_codec *codec,
struct hda_loopback_check *check, struct hda_loopback_check *check,
hda_nid_t nid) hda_nid_t nid)
...@@ -3830,7 +3837,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, ...@@ -3830,7 +3837,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
{ {
/* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
set_dig_out_convert(codec, nid, set_dig_out_convert(codec, nid,
codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff, codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff,
-1); -1);
snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
...@@ -4089,13 +4096,13 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) ...@@ -4089,13 +4096,13 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
/* /*
* Sort an associated group of pins according to their sequence numbers. * Sort an associated group of pins according to their sequence numbers.
*/ */
static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences, static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences,
int num_pins) int num_pins)
{ {
int i, j; int i, j;
short seq; short seq;
hda_nid_t nid; hda_nid_t nid;
for (i = 0; i < num_pins; i++) { for (i = 0; i < num_pins; i++) {
for (j = i + 1; j < num_pins; j++) { for (j = i + 1; j < num_pins; j++) {
if (sequences[i] > sequences[j]) { if (sequences[i] > sequences[j]) {
...@@ -4123,7 +4130,7 @@ static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences, ...@@ -4123,7 +4130,7 @@ static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences,
* is detected, one of speaker of HP pins is assigned as the primary * is detected, one of speaker of HP pins is assigned as the primary
* output, i.e. to line_out_pins[0]. So, line_outs is always positive * output, i.e. to line_out_pins[0]. So, line_outs is always positive
* if any analog output exists. * if any analog output exists.
* *
* The analog input pins are assigned to input_pins array. * The analog input pins are assigned to input_pins array.
* The digital input/output pins are assigned to dig_in_pin and dig_out_pin, * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
* respectively. * respectively.
...@@ -4186,9 +4193,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, ...@@ -4186,9 +4193,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
case AC_JACK_SPEAKER: case AC_JACK_SPEAKER:
seq = get_defcfg_sequence(def_conf); seq = get_defcfg_sequence(def_conf);
assoc = get_defcfg_association(def_conf); assoc = get_defcfg_association(def_conf);
if (! assoc) if (!assoc)
continue; continue;
if (! assoc_speaker) if (!assoc_speaker)
assoc_speaker = assoc; assoc_speaker = assoc;
else if (assoc_speaker != assoc) else if (assoc_speaker != assoc)
continue; continue;
...@@ -4286,7 +4293,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, ...@@ -4286,7 +4293,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
cfg->speaker_outs); cfg->speaker_outs);
sort_pins_by_sequence(cfg->hp_pins, sequences_hp, sort_pins_by_sequence(cfg->hp_pins, sequences_hp,
cfg->hp_outs); cfg->hp_outs);
/* if we have only one mic, make it AUTO_PIN_MIC */ /* if we have only one mic, make it AUTO_PIN_MIC */
if (!cfg->input_pins[AUTO_PIN_MIC] && if (!cfg->input_pins[AUTO_PIN_MIC] &&
cfg->input_pins[AUTO_PIN_FRONT_MIC]) { cfg->input_pins[AUTO_PIN_FRONT_MIC]) {
...@@ -4436,7 +4443,7 @@ EXPORT_SYMBOL_HDA(snd_hda_resume); ...@@ -4436,7 +4443,7 @@ EXPORT_SYMBOL_HDA(snd_hda_resume);
/** /**
* snd_array_new - get a new element from the given array * snd_array_new - get a new element from the given array
* @array: the array object * @array: the array object
* *
* Get a new element from the given array. If it exceeds the * Get a new element from the given array. If it exceeds the
* pre-allocated array size, re-allocate the array. * pre-allocated array size, re-allocate the array.
* *
......
...@@ -331,6 +331,7 @@ int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid) ...@@ -331,6 +331,7 @@ int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
AC_DIPSIZE_ELD_BUF); AC_DIPSIZE_ELD_BUF);
} }
EXPORT_SYMBOL_HDA(snd_hdmi_get_eld_size);
int snd_hdmi_get_eld(struct hdmi_eld *eld, int snd_hdmi_get_eld(struct hdmi_eld *eld,
struct hda_codec *codec, hda_nid_t nid) struct hda_codec *codec, hda_nid_t nid)
...@@ -366,6 +367,7 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, ...@@ -366,6 +367,7 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
kfree(buf); kfree(buf);
return ret; return ret;
} }
EXPORT_SYMBOL_HDA(snd_hdmi_get_eld);
static void hdmi_show_short_audio_desc(struct cea_sad *a) static void hdmi_show_short_audio_desc(struct cea_sad *a)
{ {
...@@ -404,6 +406,7 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen) ...@@ -404,6 +406,7 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
} }
buf[j] = '\0'; /* necessary when j == 0 */ buf[j] = '\0'; /* necessary when j == 0 */
} }
EXPORT_SYMBOL_HDA(snd_print_channel_allocation);
void snd_hdmi_show_eld(struct hdmi_eld *e) void snd_hdmi_show_eld(struct hdmi_eld *e)
{ {
...@@ -422,6 +425,7 @@ void snd_hdmi_show_eld(struct hdmi_eld *e) ...@@ -422,6 +425,7 @@ void snd_hdmi_show_eld(struct hdmi_eld *e)
for (i = 0; i < e->sad_count; i++) for (i = 0; i < e->sad_count; i++)
hdmi_show_short_audio_desc(e->sad + i); hdmi_show_short_audio_desc(e->sad + i);
} }
EXPORT_SYMBOL_HDA(snd_hdmi_show_eld);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
...@@ -580,6 +584,7 @@ int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld, ...@@ -580,6 +584,7 @@ int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
return 0; return 0;
} }
EXPORT_SYMBOL_HDA(snd_hda_eld_proc_new);
void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld) void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
{ {
...@@ -588,5 +593,6 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld) ...@@ -588,5 +593,6 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
eld->proc_entry = NULL; eld->proc_entry = NULL;
} }
} }
EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free);
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
...@@ -267,7 +267,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; ...@@ -267,7 +267,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define RIRB_INT_MASK 0x05 #define RIRB_INT_MASK 0x05
/* STATESTS int mask: S3,SD2,SD1,SD0 */ /* STATESTS int mask: S3,SD2,SD1,SD0 */
#define AZX_MAX_CODECS 4 #define AZX_MAX_CODECS 8
#define AZX_DEFAULT_CODECS 4
#define STATESTS_INT_MASK ((1 << AZX_MAX_CODECS) - 1) #define STATESTS_INT_MASK ((1 << AZX_MAX_CODECS) - 1)
/* SD_CTL bits */ /* SD_CTL bits */
...@@ -1367,6 +1368,7 @@ static void azx_bus_reset(struct hda_bus *bus) ...@@ -1367,6 +1368,7 @@ static void azx_bus_reset(struct hda_bus *bus)
/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */ /* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = { static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
[AZX_DRIVER_NVIDIA] = 8,
[AZX_DRIVER_TERA] = 1, [AZX_DRIVER_TERA] = 1,
}; };
...@@ -1399,7 +1401,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) ...@@ -1399,7 +1401,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
codecs = 0; codecs = 0;
max_slots = azx_max_codecs[chip->driver_type]; max_slots = azx_max_codecs[chip->driver_type];
if (!max_slots) if (!max_slots)
max_slots = AZX_MAX_CODECS; max_slots = AZX_DEFAULT_CODECS;
/* First try to probe all given codec slots */ /* First try to probe all given codec slots */
for (c = 0; c < max_slots; c++) { for (c = 0; c < max_slots; c++) {
...@@ -2263,10 +2265,12 @@ static int azx_dev_free(struct snd_device *device) ...@@ -2263,10 +2265,12 @@ static int azx_dev_free(struct snd_device *device)
static struct snd_pci_quirk position_fix_list[] __devinitdata = { static struct snd_pci_quirk position_fix_list[] __devinitdata = {
SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
{} {}
}; };
...@@ -2354,6 +2358,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev) ...@@ -2354,6 +2358,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
static struct snd_pci_quirk msi_black_list[] __devinitdata = { static struct snd_pci_quirk msi_black_list[] __devinitdata = {
SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
{} {}
}; };
......
此差异已折叠。
此差异已折叠。
...@@ -29,13 +29,23 @@ ...@@ -29,13 +29,23 @@
#include "hda_codec.h" #include "hda_codec.h"
#include "hda_local.h" #include "hda_local.h"
#define MAX_HDMI_CVTS 1
#define MAX_HDMI_PINS 1
#include "patch_hdmi.c"
static char *nvhdmi_pcm_names[MAX_HDMI_CVTS] = {
"NVIDIA HDMI",
};
/* define below to restrict the supported rates and formats */ /* define below to restrict the supported rates and formats */
/* #define LIMITED_RATE_FMT_SUPPORT */ /* #define LIMITED_RATE_FMT_SUPPORT */
struct nvhdmi_spec { enum HDACodec {
struct hda_multi_out multiout; HDA_CODEC_NVIDIA_MCP7X,
HDA_CODEC_NVIDIA_MCP89,
struct hda_pcm pcm_rec; HDA_CODEC_NVIDIA_GT21X,
HDA_CODEC_INVALID
}; };
#define Nv_VERB_SET_Channel_Allocation 0xF79 #define Nv_VERB_SET_Channel_Allocation 0xF79
...@@ -43,15 +53,18 @@ struct nvhdmi_spec { ...@@ -43,15 +53,18 @@ struct nvhdmi_spec {
#define Nv_VERB_SET_Audio_Protection_On 0xF98 #define Nv_VERB_SET_Audio_Protection_On 0xF98
#define Nv_VERB_SET_Audio_Protection_Off 0xF99 #define Nv_VERB_SET_Audio_Protection_Off 0xF99
#define Nv_Master_Convert_nid 0x04 #define nvhdmi_master_con_nid_7x 0x04
#define Nv_Master_Pin_nid 0x05 #define nvhdmi_master_pin_nid_7x 0x05
static hda_nid_t nvhdmi_convert_nids[4] = { #define nvhdmi_master_con_nid_89 0x04
#define nvhdmi_master_pin_nid_89 0x05
static hda_nid_t nvhdmi_con_nids_7x[4] = {
/*front, rear, clfe, rear_surr */ /*front, rear, clfe, rear_surr */
0x6, 0x8, 0xa, 0xc, 0x6, 0x8, 0xa, 0xc,
}; };
static struct hda_verb nvhdmi_basic_init[] = { static struct hda_verb nvhdmi_basic_init_7x[] = {
/* set audio protect on */ /* set audio protect on */
{ 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
/* enable digital output on pin widget */ /* enable digital output on pin widget */
...@@ -84,22 +97,60 @@ static struct hda_verb nvhdmi_basic_init[] = { ...@@ -84,22 +97,60 @@ static struct hda_verb nvhdmi_basic_init[] = {
*/ */
static int nvhdmi_build_controls(struct hda_codec *codec) static int nvhdmi_build_controls(struct hda_codec *codec)
{ {
struct nvhdmi_spec *spec = codec->spec; struct hdmi_spec *spec = codec->spec;
int err; int err;
int i;
err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
if (err < 0) || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
return err; for (i = 0; i < codec->num_pcms; i++) {
err = snd_hda_create_spdif_out_ctls(codec,
spec->cvt[i]);
if (err < 0)
return err;
}
} else {
err = snd_hda_create_spdif_out_ctls(codec,
spec->multiout.dig_out_nid);
if (err < 0)
return err;
}
return 0; return 0;
} }
static int nvhdmi_init(struct hda_codec *codec) static int nvhdmi_init(struct hda_codec *codec)
{ {
snd_hda_sequence_write(codec, nvhdmi_basic_init); struct hdmi_spec *spec = codec->spec;
int i;
if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
|| (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
for (i = 0; spec->pin[i]; i++) {
hdmi_enable_output(codec, spec->pin[i]);
snd_hda_codec_write(codec, spec->pin[i], 0,
AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | spec->pin[i]);
}
} else {
snd_hda_sequence_write(codec, nvhdmi_basic_init_7x);
}
return 0; return 0;
} }
static void nvhdmi_free(struct hda_codec *codec)
{
struct hdmi_spec *spec = codec->spec;
int i;
if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
|| (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
for (i = 0; i < spec->num_pins; i++)
snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
}
kfree(spec);
}
/* /*
* Digital out * Digital out
*/ */
...@@ -107,25 +158,25 @@ static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, ...@@ -107,25 +158,25 @@ static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
struct hda_codec *codec, struct hda_codec *codec,
struct snd_pcm_substream *substream) struct snd_pcm_substream *substream)
{ {
struct nvhdmi_spec *spec = codec->spec; struct hdmi_spec *spec = codec->spec;
return snd_hda_multi_out_dig_open(codec, &spec->multiout); return snd_hda_multi_out_dig_open(codec, &spec->multiout);
} }
static int nvhdmi_dig_playback_pcm_close_8ch(struct hda_pcm_stream *hinfo, static int nvhdmi_dig_playback_pcm_close_8ch_7x(struct hda_pcm_stream *hinfo,
struct hda_codec *codec, struct hda_codec *codec,
struct snd_pcm_substream *substream) struct snd_pcm_substream *substream)
{ {
struct nvhdmi_spec *spec = codec->spec; struct hdmi_spec *spec = codec->spec;
int i; int i;
snd_hda_codec_write(codec, Nv_Master_Convert_nid, snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
0, AC_VERB_SET_CHANNEL_STREAMID, 0); 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
/* set the stream id */ /* set the stream id */
snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0, snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
AC_VERB_SET_CHANNEL_STREAMID, 0); AC_VERB_SET_CHANNEL_STREAMID, 0);
/* set the stream format */ /* set the stream format */
snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0, snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
AC_VERB_SET_STREAM_FORMAT, 0); AC_VERB_SET_STREAM_FORMAT, 0);
} }
...@@ -136,10 +187,25 @@ static int nvhdmi_dig_playback_pcm_close_2ch(struct hda_pcm_stream *hinfo, ...@@ -136,10 +187,25 @@ static int nvhdmi_dig_playback_pcm_close_2ch(struct hda_pcm_stream *hinfo,
struct hda_codec *codec, struct hda_codec *codec,
struct snd_pcm_substream *substream) struct snd_pcm_substream *substream)
{ {
struct nvhdmi_spec *spec = codec->spec; struct hdmi_spec *spec = codec->spec;
return snd_hda_multi_out_dig_close(codec, &spec->multiout); return snd_hda_multi_out_dig_close(codec, &spec->multiout);
} }
static int nvhdmi_dig_playback_pcm_prepare_8ch_89(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
unsigned int stream_tag,
unsigned int format,
struct snd_pcm_substream *substream)
{
hdmi_set_channel_count(codec, hinfo->nid,
substream->runtime->channels);
hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
return 0;
}
static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
struct hda_codec *codec, struct hda_codec *codec,
unsigned int stream_tag, unsigned int stream_tag,
...@@ -181,29 +247,29 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, ...@@ -181,29 +247,29 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
/* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
snd_hda_codec_write(codec, snd_hda_codec_write(codec,
Nv_Master_Convert_nid, nvhdmi_master_con_nid_7x,
0, 0,
AC_VERB_SET_DIGI_CONVERT_1, AC_VERB_SET_DIGI_CONVERT_1,
codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
/* set the stream id */ /* set the stream id */
snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0, snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0); AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
/* set the stream format */ /* set the stream format */
snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0, snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
AC_VERB_SET_STREAM_FORMAT, format); AC_VERB_SET_STREAM_FORMAT, format);
/* turn on again (if needed) */ /* turn on again (if needed) */
/* enable and set the channel status audio/data flag */ /* enable and set the channel status audio/data flag */
if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) { if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
snd_hda_codec_write(codec, snd_hda_codec_write(codec,
Nv_Master_Convert_nid, nvhdmi_master_con_nid_7x,
0, 0,
AC_VERB_SET_DIGI_CONVERT_1, AC_VERB_SET_DIGI_CONVERT_1,
codec->spdif_ctls & 0xff); codec->spdif_ctls & 0xff);
snd_hda_codec_write(codec, snd_hda_codec_write(codec,
Nv_Master_Convert_nid, nvhdmi_master_con_nid_7x,
0, 0,
AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
} }
...@@ -220,19 +286,19 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, ...@@ -220,19 +286,19 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
if (codec->spdif_status_reset && if (codec->spdif_status_reset &&
(codec->spdif_ctls & AC_DIG1_ENABLE)) (codec->spdif_ctls & AC_DIG1_ENABLE))
snd_hda_codec_write(codec, snd_hda_codec_write(codec,
nvhdmi_convert_nids[i], nvhdmi_con_nids_7x[i],
0, 0,
AC_VERB_SET_DIGI_CONVERT_1, AC_VERB_SET_DIGI_CONVERT_1,
codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
/* set the stream id */ /* set the stream id */
snd_hda_codec_write(codec, snd_hda_codec_write(codec,
nvhdmi_convert_nids[i], nvhdmi_con_nids_7x[i],
0, 0,
AC_VERB_SET_CHANNEL_STREAMID, AC_VERB_SET_CHANNEL_STREAMID,
(stream_tag << 4) | channel_id); (stream_tag << 4) | channel_id);
/* set the stream format */ /* set the stream format */
snd_hda_codec_write(codec, snd_hda_codec_write(codec,
nvhdmi_convert_nids[i], nvhdmi_con_nids_7x[i],
0, 0,
AC_VERB_SET_STREAM_FORMAT, AC_VERB_SET_STREAM_FORMAT,
format); format);
...@@ -241,12 +307,12 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, ...@@ -241,12 +307,12 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
if (codec->spdif_status_reset && if (codec->spdif_status_reset &&
(codec->spdif_ctls & AC_DIG1_ENABLE)) { (codec->spdif_ctls & AC_DIG1_ENABLE)) {
snd_hda_codec_write(codec, snd_hda_codec_write(codec,
nvhdmi_convert_nids[i], nvhdmi_con_nids_7x[i],
0, 0,
AC_VERB_SET_DIGI_CONVERT_1, AC_VERB_SET_DIGI_CONVERT_1,
codec->spdif_ctls & 0xff); codec->spdif_ctls & 0xff);
snd_hda_codec_write(codec, snd_hda_codec_write(codec,
nvhdmi_convert_nids[i], nvhdmi_con_nids_7x[i],
0, 0,
AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
} }
...@@ -261,28 +327,47 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, ...@@ -261,28 +327,47 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
return 0; return 0;
} }
static int nvhdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
return 0;
}
static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo, static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo,
struct hda_codec *codec, struct hda_codec *codec,
unsigned int stream_tag, unsigned int stream_tag,
unsigned int format, unsigned int format,
struct snd_pcm_substream *substream) struct snd_pcm_substream *substream)
{ {
struct nvhdmi_spec *spec = codec->spec; struct hdmi_spec *spec = codec->spec;
return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
format, substream); format, substream);
} }
static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch = { static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_89 = {
.substreams = 1,
.channels_min = 2,
.rates = SUPPORTED_RATES,
.maxbps = SUPPORTED_MAXBPS,
.formats = SUPPORTED_FORMATS,
.ops = {
.prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89,
.cleanup = nvhdmi_playback_pcm_cleanup,
},
};
static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_7x = {
.substreams = 1, .substreams = 1,
.channels_min = 2, .channels_min = 2,
.channels_max = 8, .channels_max = 8,
.nid = Nv_Master_Convert_nid, .nid = nvhdmi_master_con_nid_7x,
.rates = SUPPORTED_RATES, .rates = SUPPORTED_RATES,
.maxbps = SUPPORTED_MAXBPS, .maxbps = SUPPORTED_MAXBPS,
.formats = SUPPORTED_FORMATS, .formats = SUPPORTED_FORMATS,
.ops = { .ops = {
.open = nvhdmi_dig_playback_pcm_open, .open = nvhdmi_dig_playback_pcm_open,
.close = nvhdmi_dig_playback_pcm_close_8ch, .close = nvhdmi_dig_playback_pcm_close_8ch_7x,
.prepare = nvhdmi_dig_playback_pcm_prepare_8ch .prepare = nvhdmi_dig_playback_pcm_prepare_8ch
}, },
}; };
...@@ -291,7 +376,7 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = { ...@@ -291,7 +376,7 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
.substreams = 1, .substreams = 1,
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 2,
.nid = Nv_Master_Convert_nid, .nid = nvhdmi_master_con_nid_7x,
.rates = SUPPORTED_RATES, .rates = SUPPORTED_RATES,
.maxbps = SUPPORTED_MAXBPS, .maxbps = SUPPORTED_MAXBPS,
.formats = SUPPORTED_FORMATS, .formats = SUPPORTED_FORMATS,
...@@ -302,10 +387,36 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = { ...@@ -302,10 +387,36 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
}, },
}; };
static int nvhdmi_build_pcms_8ch(struct hda_codec *codec) static int nvhdmi_build_pcms_8ch_89(struct hda_codec *codec)
{
struct hdmi_spec *spec = codec->spec;
struct hda_pcm *info = spec->pcm_rec;
int i;
codec->num_pcms = spec->num_cvts;
codec->pcm_info = info;
for (i = 0; i < codec->num_pcms; i++, info++) {
unsigned int chans;
chans = get_wcaps(codec, spec->cvt[i]);
chans = get_wcaps_channels(chans);
info->name = nvhdmi_pcm_names[i];
info->pcm_type = HDA_PCM_TYPE_HDMI;
info->stream[SNDRV_PCM_STREAM_PLAYBACK]
= nvhdmi_pcm_digital_playback_8ch_89;
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
}
return 0;
}
static int nvhdmi_build_pcms_8ch_7x(struct hda_codec *codec)
{ {
struct nvhdmi_spec *spec = codec->spec; struct hdmi_spec *spec = codec->spec;
struct hda_pcm *info = &spec->pcm_rec; struct hda_pcm *info = spec->pcm_rec;
codec->num_pcms = 1; codec->num_pcms = 1;
codec->pcm_info = info; codec->pcm_info = info;
...@@ -313,15 +424,15 @@ static int nvhdmi_build_pcms_8ch(struct hda_codec *codec) ...@@ -313,15 +424,15 @@ static int nvhdmi_build_pcms_8ch(struct hda_codec *codec)
info->name = "NVIDIA HDMI"; info->name = "NVIDIA HDMI";
info->pcm_type = HDA_PCM_TYPE_HDMI; info->pcm_type = HDA_PCM_TYPE_HDMI;
info->stream[SNDRV_PCM_STREAM_PLAYBACK] info->stream[SNDRV_PCM_STREAM_PLAYBACK]
= nvhdmi_pcm_digital_playback_8ch; = nvhdmi_pcm_digital_playback_8ch_7x;
return 0; return 0;
} }
static int nvhdmi_build_pcms_2ch(struct hda_codec *codec) static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
{ {
struct nvhdmi_spec *spec = codec->spec; struct hdmi_spec *spec = codec->spec;
struct hda_pcm *info = &spec->pcm_rec; struct hda_pcm *info = spec->pcm_rec;
codec->num_pcms = 1; codec->num_pcms = 1;
codec->pcm_info = info; codec->pcm_info = info;
...@@ -334,14 +445,17 @@ static int nvhdmi_build_pcms_2ch(struct hda_codec *codec) ...@@ -334,14 +445,17 @@ static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
return 0; return 0;
} }
static void nvhdmi_free(struct hda_codec *codec) static struct hda_codec_ops nvhdmi_patch_ops_8ch_89 = {
{ .build_controls = nvhdmi_build_controls,
kfree(codec->spec); .build_pcms = nvhdmi_build_pcms_8ch_89,
} .init = nvhdmi_init,
.free = nvhdmi_free,
.unsol_event = hdmi_unsol_event,
};
static struct hda_codec_ops nvhdmi_patch_ops_8ch = { static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
.build_controls = nvhdmi_build_controls, .build_controls = nvhdmi_build_controls,
.build_pcms = nvhdmi_build_pcms_8ch, .build_pcms = nvhdmi_build_pcms_8ch_7x,
.init = nvhdmi_init, .init = nvhdmi_init,
.free = nvhdmi_free, .free = nvhdmi_free,
}; };
...@@ -353,9 +467,36 @@ static struct hda_codec_ops nvhdmi_patch_ops_2ch = { ...@@ -353,9 +467,36 @@ static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
.free = nvhdmi_free, .free = nvhdmi_free,
}; };
static int patch_nvhdmi_8ch(struct hda_codec *codec) static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
{
struct hdmi_spec *spec;
int i;
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
codec->spec = spec;
spec->codec_type = HDA_CODEC_NVIDIA_MCP89;
if (hdmi_parse_codec(codec) < 0) {
codec->spec = NULL;
kfree(spec);
return -EINVAL;
}
codec->patch_ops = nvhdmi_patch_ops_8ch_89;
for (i = 0; i < spec->num_pins; i++)
snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
init_channel_allocations();
return 0;
}
static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
{ {
struct nvhdmi_spec *spec; struct hdmi_spec *spec;
spec = kzalloc(sizeof(*spec), GFP_KERNEL); spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL) if (spec == NULL)
...@@ -365,16 +506,17 @@ static int patch_nvhdmi_8ch(struct hda_codec *codec) ...@@ -365,16 +506,17 @@ static int patch_nvhdmi_8ch(struct hda_codec *codec)
spec->multiout.num_dacs = 0; /* no analog */ spec->multiout.num_dacs = 0; /* no analog */
spec->multiout.max_channels = 8; spec->multiout.max_channels = 8;
spec->multiout.dig_out_nid = Nv_Master_Convert_nid; spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
codec->patch_ops = nvhdmi_patch_ops_8ch; codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
return 0; return 0;
} }
static int patch_nvhdmi_2ch(struct hda_codec *codec) static int patch_nvhdmi_2ch(struct hda_codec *codec)
{ {
struct nvhdmi_spec *spec; struct hdmi_spec *spec;
spec = kzalloc(sizeof(*spec), GFP_KERNEL); spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL) if (spec == NULL)
...@@ -384,7 +526,8 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) ...@@ -384,7 +526,8 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
spec->multiout.num_dacs = 0; /* no analog */ spec->multiout.num_dacs = 0; /* no analog */
spec->multiout.max_channels = 2; spec->multiout.max_channels = 2;
spec->multiout.dig_out_nid = Nv_Master_Convert_nid; spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
codec->patch_ops = nvhdmi_patch_ops_2ch; codec->patch_ops = nvhdmi_patch_ops_2ch;
...@@ -395,13 +538,24 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) ...@@ -395,13 +538,24 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
* patch entries * patch entries
*/ */
static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
{ .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
{ .id = 0x10de0003, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
{ .id = 0x10de0005, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
{ .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
{ .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch },
{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
{ .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
{ .id = 0x10de0002, .name = "MCP77/78 HDMI",
.patch = patch_nvhdmi_8ch_7x },
{ .id = 0x10de0003, .name = "MCP77/78 HDMI",
.patch = patch_nvhdmi_8ch_7x },
{ .id = 0x10de0005, .name = "MCP77/78 HDMI",
.patch = patch_nvhdmi_8ch_7x },
{ .id = 0x10de0006, .name = "MCP77/78 HDMI",
.patch = patch_nvhdmi_8ch_7x },
{ .id = 0x10de0007, .name = "MCP79/7A HDMI",
.patch = patch_nvhdmi_8ch_7x },
{ .id = 0x10de000c, .name = "MCP89 HDMI",
.patch = patch_nvhdmi_8ch_89 },
{ .id = 0x10de000b, .name = "GT21x HDMI",
.patch = patch_nvhdmi_8ch_89 },
{ .id = 0x10de000d, .name = "GT240 HDMI",
.patch = patch_nvhdmi_8ch_89 },
{} /* terminator */ {} /* terminator */
}; };
...@@ -412,9 +566,12 @@ MODULE_ALIAS("snd-hda-codec-id:10de0006"); ...@@ -412,9 +566,12 @@ MODULE_ALIAS("snd-hda-codec-id:10de0006");
MODULE_ALIAS("snd-hda-codec-id:10de0007"); MODULE_ALIAS("snd-hda-codec-id:10de0007");
MODULE_ALIAS("snd-hda-codec-id:10de0067"); MODULE_ALIAS("snd-hda-codec-id:10de0067");
MODULE_ALIAS("snd-hda-codec-id:10de8001"); MODULE_ALIAS("snd-hda-codec-id:10de8001");
MODULE_ALIAS("snd-hda-codec-id:10de000c");
MODULE_ALIAS("snd-hda-codec-id:10de000b");
MODULE_ALIAS("snd-hda-codec-id:10de000d");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Nvidia HDMI HD-audio codec"); MODULE_DESCRIPTION("NVIDIA HDMI HD-audio codec");
static struct hda_codec_preset_list nvhdmi_list = { static struct hda_codec_preset_list nvhdmi_list = {
.preset = snd_hda_preset_nvhdmi, .preset = snd_hda_preset_nvhdmi,
......
...@@ -4915,7 +4915,7 @@ static void fixup_automic_adc(struct hda_codec *codec) ...@@ -4915,7 +4915,7 @@ static void fixup_automic_adc(struct hda_codec *codec)
static void fixup_single_adc(struct hda_codec *codec) static void fixup_single_adc(struct hda_codec *codec)
{ {
struct alc_spec *spec = codec->spec; struct alc_spec *spec = codec->spec;
hda_nid_t pin; hda_nid_t pin = 0;
int i; int i;
/* search for the input pin; there must be only one */ /* search for the input pin; there must be only one */
...@@ -13561,6 +13561,8 @@ static void alc269_lifebook_unsol_event(struct hda_codec *codec, ...@@ -13561,6 +13561,8 @@ static void alc269_lifebook_unsol_event(struct hda_codec *codec,
static void alc269_quanta_fl1_setup(struct hda_codec *codec) static void alc269_quanta_fl1_setup(struct hda_codec *codec)
{ {
struct alc_spec *spec = codec->spec; struct alc_spec *spec = codec->spec;
spec->autocfg.hp_pins[0] = 0x15;
spec->autocfg.speaker_pins[0] = 0x14;
spec->ext_mic.pin = 0x18; spec->ext_mic.pin = 0x18;
spec->ext_mic.mux_idx = 0; spec->ext_mic.mux_idx = 0;
spec->int_mic.pin = 0x19; spec->int_mic.pin = 0x19;
...@@ -13656,6 +13658,8 @@ static void alc269_laptop_unsol_event(struct hda_codec *codec, ...@@ -13656,6 +13658,8 @@ static void alc269_laptop_unsol_event(struct hda_codec *codec,
static void alc269_laptop_dmic_setup(struct hda_codec *codec) static void alc269_laptop_dmic_setup(struct hda_codec *codec)
{ {
struct alc_spec *spec = codec->spec; struct alc_spec *spec = codec->spec;
spec->autocfg.hp_pins[0] = 0x15;
spec->autocfg.speaker_pins[0] = 0x14;
spec->ext_mic.pin = 0x18; spec->ext_mic.pin = 0x18;
spec->ext_mic.mux_idx = 0; spec->ext_mic.mux_idx = 0;
spec->int_mic.pin = 0x12; spec->int_mic.pin = 0x12;
...@@ -13666,6 +13670,8 @@ static void alc269_laptop_dmic_setup(struct hda_codec *codec) ...@@ -13666,6 +13670,8 @@ static void alc269_laptop_dmic_setup(struct hda_codec *codec)
static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
{ {
struct alc_spec *spec = codec->spec; struct alc_spec *spec = codec->spec;
spec->autocfg.hp_pins[0] = 0x15;
spec->autocfg.speaker_pins[0] = 0x14;
spec->ext_mic.pin = 0x18; spec->ext_mic.pin = 0x18;
spec->ext_mic.mux_idx = 0; spec->ext_mic.mux_idx = 0;
spec->int_mic.pin = 0x12; spec->int_mic.pin = 0x12;
...@@ -13676,6 +13682,8 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) ...@@ -13676,6 +13682,8 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
static void alc269_laptop_amic_setup(struct hda_codec *codec) static void alc269_laptop_amic_setup(struct hda_codec *codec)
{ {
struct alc_spec *spec = codec->spec; struct alc_spec *spec = codec->spec;
spec->autocfg.hp_pins[0] = 0x15;
spec->autocfg.speaker_pins[0] = 0x14;
spec->ext_mic.pin = 0x18; spec->ext_mic.pin = 0x18;
spec->ext_mic.mux_idx = 0; spec->ext_mic.mux_idx = 0;
spec->int_mic.pin = 0x19; spec->int_mic.pin = 0x19;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册