mirror of https://gitee.com/openkylin/linux.git
ALSA: hda - Make common input-jack helper functions
Since multiple codec drivers already use the input-jack stuff, let's make common helper functions to reduce the duplicated codes. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
d207df2df0
commit
cd372fb3be
|
@ -29,6 +29,7 @@
|
|||
#include <sound/asoundef.h>
|
||||
#include <sound/tlv.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/jack.h>
|
||||
#include "hda_local.h"
|
||||
#include "hda_beep.h"
|
||||
#include <sound/hda_hwdep.h>
|
||||
|
@ -4959,5 +4960,109 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen)
|
|||
}
|
||||
EXPORT_SYMBOL_HDA(snd_print_pcm_bits);
|
||||
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
/*
|
||||
* Input-jack notification support
|
||||
*/
|
||||
struct hda_jack_item {
|
||||
hda_nid_t nid;
|
||||
int type;
|
||||
struct snd_jack *jack;
|
||||
};
|
||||
|
||||
static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid,
|
||||
int type)
|
||||
{
|
||||
switch (type) {
|
||||
case SND_JACK_HEADPHONE:
|
||||
return "Headphone";
|
||||
case SND_JACK_MICROPHONE:
|
||||
return "Mic";
|
||||
case SND_JACK_LINEOUT:
|
||||
return "Line-out";
|
||||
case SND_JACK_HEADSET:
|
||||
return "Headset";
|
||||
default:
|
||||
return "Misc";
|
||||
}
|
||||
}
|
||||
|
||||
static void hda_free_jack_priv(struct snd_jack *jack)
|
||||
{
|
||||
struct hda_jack_item *jacks = jack->private_data;
|
||||
jacks->nid = 0;
|
||||
jacks->jack = NULL;
|
||||
}
|
||||
|
||||
int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type,
|
||||
const char *name)
|
||||
{
|
||||
struct hda_jack_item *jack;
|
||||
int err;
|
||||
|
||||
snd_array_init(&codec->jacks, sizeof(*jack), 32);
|
||||
jack = snd_array_new(&codec->jacks);
|
||||
if (!jack)
|
||||
return -ENOMEM;
|
||||
|
||||
jack->nid = nid;
|
||||
jack->type = type;
|
||||
if (!name)
|
||||
name = get_jack_default_name(codec, nid, type);
|
||||
err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
|
||||
if (err < 0) {
|
||||
jack->nid = 0;
|
||||
return err;
|
||||
}
|
||||
jack->jack->private_data = jack;
|
||||
jack->jack->private_free = hda_free_jack_priv;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_input_jack_add);
|
||||
|
||||
void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
struct hda_jack_item *jacks = codec->jacks.list;
|
||||
int i;
|
||||
|
||||
if (!jacks)
|
||||
return;
|
||||
|
||||
for (i = 0; i < codec->jacks.used; i++, jacks++) {
|
||||
unsigned int pin_ctl;
|
||||
unsigned int present;
|
||||
int type;
|
||||
|
||||
if (jacks->nid != nid)
|
||||
continue;
|
||||
present = snd_hda_jack_detect(codec, nid);
|
||||
type = jacks->type;
|
||||
if (type == (SND_JACK_HEADPHONE | SND_JACK_LINEOUT)) {
|
||||
pin_ctl = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
type = (pin_ctl & AC_PINCTL_HP_EN) ?
|
||||
SND_JACK_HEADPHONE : SND_JACK_LINEOUT;
|
||||
}
|
||||
snd_jack_report(jacks->jack, present ? type : 0);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_input_jack_report);
|
||||
|
||||
/* free jack instances manually when clearing/reconfiguring */
|
||||
void snd_hda_input_jack_free(struct hda_codec *codec)
|
||||
{
|
||||
if (!codec->bus->shutdown && codec->jacks.list) {
|
||||
struct hda_jack_item *jacks = codec->jacks.list;
|
||||
int i;
|
||||
for (i = 0; i < codec->jacks.used; i++, jacks++) {
|
||||
if (jacks->jack)
|
||||
snd_device_free(codec->bus->card, jacks->jack);
|
||||
}
|
||||
}
|
||||
snd_array_free(&codec->jacks);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_input_jack_free);
|
||||
#endif /* CONFIG_SND_HDA_INPUT_JACK */
|
||||
|
||||
MODULE_DESCRIPTION("HDA codec core");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -866,6 +866,11 @@ struct hda_codec {
|
|||
/* codec-specific additional proc output */
|
||||
void (*proc_widget_hook)(struct snd_info_buffer *buffer,
|
||||
struct hda_codec *codec, hda_nid_t nid);
|
||||
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
/* jack detection */
|
||||
struct snd_array jacks;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* direction */
|
||||
|
|
|
@ -656,4 +656,28 @@ static inline void snd_hda_eld_proc_free(struct hda_codec *codec,
|
|||
#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
|
||||
void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
|
||||
|
||||
/*
|
||||
* Input-jack notification support
|
||||
*/
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type,
|
||||
const char *name);
|
||||
void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid);
|
||||
void snd_hda_input_jack_free(struct hda_codec *codec);
|
||||
#else /* CONFIG_SND_HDA_INPUT_JACK */
|
||||
static inline int snd_hda_input_jack_add(struct hda_codec *codec,
|
||||
hda_nid_t nid, int type,
|
||||
const char *name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void snd_hda_input_jack_report(struct hda_codec *codec,
|
||||
hda_nid_t nid)
|
||||
{
|
||||
}
|
||||
static inline void snd_hda_input_jack_free(struct hda_codec *codec)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_SND_HDA_INPUT_JACK */
|
||||
|
||||
#endif /* __SOUND_HDA_LOCAL_H */
|
||||
|
|
|
@ -49,14 +49,6 @@
|
|||
#define AUTO_MIC_PORTB (1 << 1)
|
||||
#define AUTO_MIC_PORTC (1 << 2)
|
||||
|
||||
struct conexant_jack {
|
||||
|
||||
hda_nid_t nid;
|
||||
int type;
|
||||
struct snd_jack *jack;
|
||||
|
||||
};
|
||||
|
||||
struct pin_dac_pair {
|
||||
hda_nid_t pin;
|
||||
hda_nid_t dac;
|
||||
|
@ -111,9 +103,6 @@ struct conexant_spec {
|
|||
|
||||
unsigned int spdif_route;
|
||||
|
||||
/* jack detection */
|
||||
struct snd_array jacks;
|
||||
|
||||
/* dynamic controls, init_verbs and input_mux */
|
||||
struct auto_pin_cfg autocfg;
|
||||
struct hda_input_mux private_imux;
|
||||
|
@ -393,71 +382,9 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
|
|||
&spec->cur_mux[adc_idx]);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
static void conexant_free_jack_priv(struct snd_jack *jack)
|
||||
{
|
||||
struct conexant_jack *jacks = jack->private_data;
|
||||
jacks->nid = 0;
|
||||
jacks->jack = NULL;
|
||||
}
|
||||
|
||||
static int conexant_add_jack(struct hda_codec *codec,
|
||||
hda_nid_t nid, int type)
|
||||
{
|
||||
struct conexant_spec *spec;
|
||||
struct conexant_jack *jack;
|
||||
const char *name;
|
||||
int i, err;
|
||||
|
||||
spec = codec->spec;
|
||||
snd_array_init(&spec->jacks, sizeof(*jack), 32);
|
||||
|
||||
jack = spec->jacks.list;
|
||||
for (i = 0; i < spec->jacks.used; i++, jack++)
|
||||
if (jack->nid == nid)
|
||||
return 0 ; /* already present */
|
||||
|
||||
jack = snd_array_new(&spec->jacks);
|
||||
name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
|
||||
|
||||
if (!jack)
|
||||
return -ENOMEM;
|
||||
|
||||
jack->nid = nid;
|
||||
jack->type = type;
|
||||
|
||||
err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
|
||||
if (err < 0)
|
||||
return err;
|
||||
jack->jack->private_data = jack;
|
||||
jack->jack->private_free = conexant_free_jack_priv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
struct conexant_jack *jacks = spec->jacks.list;
|
||||
|
||||
if (jacks) {
|
||||
int i;
|
||||
for (i = 0; i < spec->jacks.used; i++) {
|
||||
if (jacks->nid == nid) {
|
||||
unsigned int present;
|
||||
present = snd_hda_jack_detect(codec, nid);
|
||||
|
||||
present = (present) ? jacks->type : 0 ;
|
||||
|
||||
snd_jack_report(jacks->jack,
|
||||
present);
|
||||
}
|
||||
jacks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int conexant_init_jacks(struct hda_codec *codec)
|
||||
{
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
int i;
|
||||
|
||||
|
@ -469,15 +396,15 @@ static int conexant_init_jacks(struct hda_codec *codec)
|
|||
int err = 0;
|
||||
switch (hv->param ^ AC_USRSP_EN) {
|
||||
case CONEXANT_HP_EVENT:
|
||||
err = conexant_add_jack(codec, hv->nid,
|
||||
SND_JACK_HEADPHONE);
|
||||
conexant_report_jack(codec, hv->nid);
|
||||
err = snd_hda_input_jack_add(codec, hv->nid,
|
||||
SND_JACK_HEADPHONE, NULL);
|
||||
snd_hda_input_jack_report(codec, hv->nid);
|
||||
break;
|
||||
case CXT5051_PORTC_EVENT:
|
||||
case CONEXANT_MIC_EVENT:
|
||||
err = conexant_add_jack(codec, hv->nid,
|
||||
SND_JACK_MICROPHONE);
|
||||
conexant_report_jack(codec, hv->nid);
|
||||
err = snd_hda_input_jack_add(codec, hv->nid,
|
||||
SND_JACK_MICROPHONE, NULL);
|
||||
snd_hda_input_jack_report(codec, hv->nid);
|
||||
break;
|
||||
}
|
||||
if (err < 0)
|
||||
|
@ -485,19 +412,9 @@ static int conexant_init_jacks(struct hda_codec *codec)
|
|||
++hv;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
#else
|
||||
static inline void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int conexant_init_jacks(struct hda_codec *codec)
|
||||
{
|
||||
#endif /* CONFIG_SND_HDA_INPUT_JACK */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int conexant_init(struct hda_codec *codec)
|
||||
{
|
||||
|
@ -511,18 +428,7 @@ static int conexant_init(struct hda_codec *codec)
|
|||
|
||||
static void conexant_free(struct hda_codec *codec)
|
||||
{
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
if (spec->jacks.list) {
|
||||
struct conexant_jack *jacks = spec->jacks.list;
|
||||
int i;
|
||||
for (i = 0; i < spec->jacks.used; i++, jacks++) {
|
||||
if (jacks->jack)
|
||||
snd_device_free(codec->bus->card, jacks->jack);
|
||||
}
|
||||
snd_array_free(&spec->jacks);
|
||||
}
|
||||
#endif
|
||||
snd_hda_input_jack_free(codec);
|
||||
snd_hda_detach_beep_device(codec);
|
||||
kfree(codec->spec);
|
||||
}
|
||||
|
@ -1787,7 +1693,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
|
|||
cxt5051_portc_automic(codec);
|
||||
break;
|
||||
}
|
||||
conexant_report_jack(codec, nid);
|
||||
snd_hda_input_jack_report(codec, nid);
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new cxt5051_playback_mixers[] = {
|
||||
|
@ -1959,10 +1865,8 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
|
|||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_UNSOLICITED_ENABLE,
|
||||
AC_USRSP_EN | event);
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
conexant_add_jack(codec, nid, SND_JACK_MICROPHONE);
|
||||
conexant_report_jack(codec, nid);
|
||||
#endif
|
||||
snd_hda_input_jack_add(codec, nid, SND_JACK_MICROPHONE, NULL);
|
||||
snd_hda_input_jack_report(codec, nid);
|
||||
}
|
||||
|
||||
static struct hda_verb cxt5051_ideapad_init_verbs[] = {
|
||||
|
@ -3477,11 +3381,11 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
|
|||
switch (res >> 26) {
|
||||
case CONEXANT_HP_EVENT:
|
||||
cx_auto_hp_automute(codec);
|
||||
conexant_report_jack(codec, nid);
|
||||
snd_hda_input_jack_report(codec, nid);
|
||||
break;
|
||||
case CONEXANT_MIC_EVENT:
|
||||
cx_auto_automic(codec);
|
||||
conexant_report_jack(codec, nid);
|
||||
snd_hda_input_jack_report(codec, nid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -282,12 +282,6 @@ struct alc_mic_route {
|
|||
unsigned char amix_idx;
|
||||
};
|
||||
|
||||
struct alc_jack {
|
||||
hda_nid_t nid;
|
||||
int type;
|
||||
struct snd_jack *jack;
|
||||
};
|
||||
|
||||
#define MUX_IDX_UNDEF ((unsigned char)-1)
|
||||
|
||||
struct alc_customize_define {
|
||||
|
@ -366,9 +360,6 @@ struct alc_spec {
|
|||
/* PCM information */
|
||||
struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
|
||||
|
||||
/* jack detection */
|
||||
struct snd_array jacks;
|
||||
|
||||
/* dynamic controls, init_verbs and input_mux */
|
||||
struct auto_pin_cfg autocfg;
|
||||
struct alc_customize_define cdefine;
|
||||
|
@ -1032,94 +1023,32 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
|
|||
alc_fix_pll(codec);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
static void alc_free_jack_priv(struct snd_jack *jack)
|
||||
{
|
||||
struct alc_jack *jacks = jack->private_data;
|
||||
jacks->nid = 0;
|
||||
jacks->jack = NULL;
|
||||
}
|
||||
|
||||
static int alc_add_jack(struct hda_codec *codec,
|
||||
hda_nid_t nid, int type)
|
||||
{
|
||||
struct alc_spec *spec;
|
||||
struct alc_jack *jack;
|
||||
const char *name;
|
||||
int err;
|
||||
|
||||
spec = codec->spec;
|
||||
snd_array_init(&spec->jacks, sizeof(*jack), 32);
|
||||
jack = snd_array_new(&spec->jacks);
|
||||
if (!jack)
|
||||
return -ENOMEM;
|
||||
|
||||
jack->nid = nid;
|
||||
jack->type = type;
|
||||
name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
|
||||
|
||||
err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
|
||||
if (err < 0)
|
||||
return err;
|
||||
jack->jack->private_data = jack;
|
||||
jack->jack->private_free = alc_free_jack_priv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
struct alc_jack *jacks = spec->jacks.list;
|
||||
|
||||
if (jacks) {
|
||||
int i;
|
||||
for (i = 0; i < spec->jacks.used; i++) {
|
||||
if (jacks->nid == nid) {
|
||||
unsigned int present;
|
||||
present = snd_hda_jack_detect(codec, nid);
|
||||
|
||||
present = (present) ? jacks->type : 0;
|
||||
|
||||
snd_jack_report(jacks->jack, present);
|
||||
}
|
||||
jacks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int alc_init_jacks(struct hda_codec *codec)
|
||||
{
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
struct alc_spec *spec = codec->spec;
|
||||
int err;
|
||||
unsigned int hp_nid = spec->autocfg.hp_pins[0];
|
||||
unsigned int mic_nid = spec->ext_mic.pin;
|
||||
|
||||
if (hp_nid) {
|
||||
err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE);
|
||||
err = snd_hda_input_jack_add(codec, hp_nid,
|
||||
SND_JACK_HEADPHONE, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
alc_report_jack(codec, hp_nid);
|
||||
snd_hda_input_jack_report(codec, hp_nid);
|
||||
}
|
||||
|
||||
if (mic_nid) {
|
||||
err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE);
|
||||
err = snd_hda_input_jack_add(codec, mic_nid,
|
||||
SND_JACK_MICROPHONE, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
alc_report_jack(codec, mic_nid);
|
||||
snd_hda_input_jack_report(codec, mic_nid);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SND_HDA_INPUT_JACK */
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int alc_init_jacks(struct hda_codec *codec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
|
||||
{
|
||||
|
@ -1133,7 +1062,7 @@ static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
|
|||
nid = spec->autocfg.hp_pins[i];
|
||||
if (!nid)
|
||||
break;
|
||||
alc_report_jack(codec, nid);
|
||||
snd_hda_input_jack_report(codec, nid);
|
||||
spec->jack_present |= snd_hda_jack_detect(codec, nid);
|
||||
}
|
||||
|
||||
|
@ -1240,7 +1169,7 @@ static void alc_mic_automute(struct hda_codec *codec)
|
|||
AC_VERB_SET_CONNECT_SEL,
|
||||
alive->mux_idx);
|
||||
}
|
||||
alc_report_jack(codec, spec->ext_mic.pin);
|
||||
snd_hda_input_jack_report(codec, spec->ext_mic.pin);
|
||||
|
||||
/* FIXME: analog mixer */
|
||||
}
|
||||
|
@ -4283,6 +4212,7 @@ static void alc_free(struct hda_codec *codec)
|
|||
return;
|
||||
|
||||
alc_shutup(codec);
|
||||
snd_hda_input_jack_free(codec);
|
||||
alc_free_kctls(codec);
|
||||
kfree(spec);
|
||||
snd_hda_detach_beep_device(codec);
|
||||
|
@ -14494,7 +14424,7 @@ static void alc269_speaker_automute(struct hda_codec *codec)
|
|||
HDA_AMP_MUTE, bits);
|
||||
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
|
||||
HDA_AMP_MUTE, bits);
|
||||
alc_report_jack(codec, nid);
|
||||
snd_hda_input_jack_report(codec, nid);
|
||||
}
|
||||
|
||||
/* unsolicited event for HP jack sensing */
|
||||
|
|
|
@ -180,12 +180,6 @@ struct sigmatel_event {
|
|||
int data;
|
||||
};
|
||||
|
||||
struct sigmatel_jack {
|
||||
hda_nid_t nid;
|
||||
int type;
|
||||
struct snd_jack *jack;
|
||||
};
|
||||
|
||||
struct sigmatel_mic_route {
|
||||
hda_nid_t pin;
|
||||
signed char mux_idx;
|
||||
|
@ -229,9 +223,6 @@ struct sigmatel_spec {
|
|||
hda_nid_t *pwr_nids;
|
||||
hda_nid_t *dac_list;
|
||||
|
||||
/* jack detection */
|
||||
struct snd_array jacks;
|
||||
|
||||
/* events */
|
||||
struct snd_array events;
|
||||
|
||||
|
@ -4054,21 +4045,10 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
|
|||
AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
static void stac92xx_free_jack_priv(struct snd_jack *jack)
|
||||
{
|
||||
struct sigmatel_jack *jacks = jack->private_data;
|
||||
jacks->nid = 0;
|
||||
jacks->jack = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int stac92xx_add_jack(struct hda_codec *codec,
|
||||
hda_nid_t nid, int type)
|
||||
{
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
struct sigmatel_jack *jack;
|
||||
int def_conf = snd_hda_codec_get_pincfg(codec, nid);
|
||||
int connectivity = get_defcfg_connect(def_conf);
|
||||
char name[32];
|
||||
|
@ -4077,26 +4057,15 @@ static int stac92xx_add_jack(struct hda_codec *codec,
|
|||
if (connectivity && connectivity != AC_JACK_PORT_FIXED)
|
||||
return 0;
|
||||
|
||||
snd_array_init(&spec->jacks, sizeof(*jack), 32);
|
||||
jack = snd_array_new(&spec->jacks);
|
||||
if (!jack)
|
||||
return -ENOMEM;
|
||||
jack->nid = nid;
|
||||
jack->type = type;
|
||||
|
||||
snprintf(name, sizeof(name), "%s at %s %s Jack",
|
||||
snd_hda_get_jack_type(def_conf),
|
||||
snd_hda_get_jack_connectivity(def_conf),
|
||||
snd_hda_get_jack_location(def_conf));
|
||||
|
||||
err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
|
||||
if (err < 0) {
|
||||
jack->nid = 0;
|
||||
err = snd_hda_input_jack_add(codec, nid, type, name);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
jack->jack->private_data = jack;
|
||||
jack->jack->private_free = stac92xx_free_jack_priv;
|
||||
#endif
|
||||
#endif /* CONFIG_SND_HDA_INPUT_JACK */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4399,23 +4368,6 @@ static int stac92xx_init(struct hda_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void stac92xx_free_jacks(struct hda_codec *codec)
|
||||
{
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
/* free jack instances manually when clearing/reconfiguring */
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
if (!codec->bus->shutdown && spec->jacks.list) {
|
||||
struct sigmatel_jack *jacks = spec->jacks.list;
|
||||
int i;
|
||||
for (i = 0; i < spec->jacks.used; i++, jacks++) {
|
||||
if (jacks->jack)
|
||||
snd_device_free(codec->bus->card, jacks->jack);
|
||||
}
|
||||
}
|
||||
snd_array_free(&spec->jacks);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void stac92xx_free_kctls(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
|
@ -4449,7 +4401,7 @@ static void stac92xx_free(struct hda_codec *codec)
|
|||
return;
|
||||
|
||||
stac92xx_shutup(codec);
|
||||
stac92xx_free_jacks(codec);
|
||||
snd_hda_input_jack_free(codec);
|
||||
snd_array_free(&spec->events);
|
||||
|
||||
kfree(spec);
|
||||
|
@ -4667,33 +4619,6 @@ static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
|
|||
stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid));
|
||||
}
|
||||
|
||||
static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
struct sigmatel_jack *jacks = spec->jacks.list;
|
||||
|
||||
if (jacks) {
|
||||
int i;
|
||||
for (i = 0; i < spec->jacks.used; i++) {
|
||||
if (jacks->nid == nid) {
|
||||
unsigned int pin_ctl =
|
||||
snd_hda_codec_read(codec, nid,
|
||||
0, AC_VERB_GET_PIN_WIDGET_CONTROL,
|
||||
0x00);
|
||||
int type = jacks->type;
|
||||
if (type == (SND_JACK_LINEOUT
|
||||
| SND_JACK_HEADPHONE))
|
||||
type = (pin_ctl & AC_PINCTL_HP_EN)
|
||||
? SND_JACK_HEADPHONE : SND_JACK_LINEOUT;
|
||||
snd_jack_report(jacks->jack,
|
||||
get_pin_presence(codec, nid)
|
||||
? type : 0);
|
||||
}
|
||||
jacks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get the pin connection (fixed, none, etc) */
|
||||
static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx)
|
||||
{
|
||||
|
@ -4782,7 +4707,7 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
|
|||
case STAC_PWR_EVENT:
|
||||
if (spec->num_pwrs > 0)
|
||||
stac92xx_pin_sense(codec, event->nid);
|
||||
stac92xx_report_jack(codec, event->nid);
|
||||
snd_hda_input_jack_report(codec, event->nid);
|
||||
|
||||
switch (codec->subsystem_id) {
|
||||
case 0x103c308f:
|
||||
|
|
Loading…
Reference in New Issue