static void parse_hp_out(struct hda_codec *codec) { struct ca0110_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; int i; unsigned int def_conf; hda_nid_t nid, dac; if (!cfg->hp_outs) return; nid = cfg->hp_pins[0]; def_conf = snd_hda_codec_get_pincfg(codec, nid); if (!def_conf) { cfg->hp_outs = 0; return; } if (snd_hda_get_connections(codec, nid, &dac, 1) != 1) return; for (i = 0; i < cfg->line_outs; i++) if (dac == spec->dacs[i]) break; if (i >= cfg->line_outs) { spec->hp_dac = dac; spec->multiout.hp_nid = dac; } }
/* create multi_init table, which is used for multichannel initialization */ static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { struct cmi_spec *spec = codec->spec; hda_nid_t nid; int i, j, k, len; /* clear the table, only one c-media dac assumed here */ memset(spec->multi_init, 0, sizeof(spec->multi_init)); for (j = 0, i = 0; i < cfg->line_outs; i++) { hda_nid_t conn[4]; nid = cfg->line_out_pins[i]; /* set as output */ spec->multi_init[j].nid = nid; spec->multi_init[j].verb = AC_VERB_SET_PIN_WIDGET_CONTROL; spec->multi_init[j].param = PIN_OUT; j++; if (nid > 0x0e) { /* set connection */ spec->multi_init[j].nid = nid; spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL; spec->multi_init[j].param = 0; /* find the index in connect list */ len = snd_hda_get_connections(codec, nid, conn, 4); for (k = 0; k < len; k++) if (conn[k] == spec->dac_nids[i]) { spec->multi_init[j].param = k; break; } j++; } } return 0; }
static void parse_input(struct hda_codec *codec) { struct ca0110_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; hda_nid_t nid, pin; int n, i, j; n = 0; nid = codec->start_nid; for (i = 0; i < codec->num_nodes; i++, nid++) { unsigned int wcaps = get_wcaps(codec, nid); unsigned int type = get_wcaps_type(wcaps); if (type != AC_WID_AUD_IN) continue; if (snd_hda_get_connections(codec, nid, &pin, 1) != 1) continue; if (pin == cfg->dig_in_pin) { spec->dig_in = nid; continue; } for (j = 0; j < cfg->num_inputs; j++) if (cfg->inputs[j].pin == pin) break; if (j >= cfg->num_inputs) continue; spec->input_pins[n] = pin; snd_hda_get_pin_label(codec, pin, cfg, spec->input_labels[n], sizeof(spec->input_labels[n]), NULL); spec->adcs[n] = nid; n++; } spec->num_inputs = n; }
static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin, unsigned int *idxp) { int i; hda_nid_t nid; nid = codec->start_nid; for (i = 0; i < codec->num_nodes; i++, nid++) { hda_nid_t pins[2]; unsigned int type; int j, nums; type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; if (type != AC_WID_AUD_IN) continue; nums = snd_hda_get_connections(codec, nid, pins, ARRAY_SIZE(pins)); if (nums <= 0) continue; for (j = 0; j < nums; j++) { if (pins[j] == pin) { *idxp = j; return nid; } } } return 0; }
static void parse_input(struct hda_codec *codec) { struct ca0110_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; hda_nid_t nid, pin; int n, i, j; n = 0; nid = codec->start_nid; for (i = 0; i < codec->num_nodes; i++, nid++) { unsigned int wcaps = get_wcaps(codec, nid); unsigned int type = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; if (type != AC_WID_AUD_IN) continue; if (snd_hda_get_connections(codec, nid, &pin, 1) != 1) continue; if (pin == cfg->dig_in_pin) { spec->dig_in = nid; continue; } for (j = 0; j < AUTO_PIN_LAST; j++) if (cfg->input_pins[j] == pin) break; if (j >= AUTO_PIN_LAST) continue; spec->input_pins[n] = pin; spec->input_labels[n] = auto_pin_cfg_labels[j]; spec->adcs[n] = nid; n++; } spec->num_inputs = n; }
static hda_nid_t get_dac(struct hda_codec *codec, hda_nid_t pin) { hda_nid_t dac; if (!pin) return 0; if (snd_hda_get_connections(codec, pin, &dac, 1) != 1) return 0; return dac; }
static void parse_digital(struct hda_codec *codec) { struct ca0110_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; if (cfg->dig_outs && snd_hda_get_connections(codec, cfg->dig_out_pins[0], &spec->dig_out, 1) == 1) spec->multiout.dig_out_nid = spec->dig_out; }
static int parse_digital_output(struct hda_codec *codec) { struct cs_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; hda_nid_t nid; if (!cfg->dig_outs) return 0; if (snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) < 1) return 0; spec->multiout.dig_out_nid = nid; spec->multiout.share_spdif = 1; if (cfg->dig_outs > 1 && snd_hda_get_connections(codec, cfg->dig_out_pins[1], &nid, 1) > 0) { spec->slave_dig_outs[0] = nid; codec->slave_dig_outs = spec->slave_dig_outs; } return 0; }
static void parse_line_outs(struct hda_codec *codec) { struct ca0110_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; int i, n; unsigned int def_conf; hda_nid_t nid; n = 0; for (i = 0; i < cfg->line_outs; i++) { nid = cfg->line_out_pins[i]; def_conf = snd_hda_codec_get_pincfg(codec, nid); if (!def_conf) continue; /* invalid pin */ if (snd_hda_get_connections(codec, nid, &spec->dacs[i], 1) != 1) continue; spec->out_pins[n++] = nid; } spec->multiout.dac_nids = spec->dacs; spec->multiout.num_dacs = n; spec->multiout.max_channels = n * 2; }