aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_sigmatel.c
diff options
context:
space:
mode:
authorVitaliy Kulikov <Vitaliy.Kulikov@idt.com>2011-03-10 14:43:35 -0500
committerTakashi Iwai <tiwai@suse.de>2011-03-14 10:38:57 -0400
commit699d899560cd7e72da39231e584412e7ac8114a4 (patch)
tree71ccc46475ccb77b8669affa8c5aa6b1d412d482 /sound/pci/hda/patch_sigmatel.c
parent094a42452abd5564429045e210281c6d22e67fca (diff)
ALSA: hda - pin-adc-mux-dmic auto-configuration of 92HD8X codecs
This patch replaces use of the harcoded arrays of pins, muxes, digital mics and adcs with the auto-generated ones using codec parsing and auto-discovers all actually connected digital mic pins on 92HD8X-like codecs This patch also adds the support for d-mic on pin 0x20. Signed-off-by: Vitaliy Kulikov <Vitaliy.Kulikov@idt.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r--sound/pci/hda/patch_sigmatel.c222
1 files changed, 149 insertions, 73 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 32f744d47da7..05fcd60cc46f 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -186,6 +186,10 @@ struct sigmatel_mic_route {
186 signed char dmux_idx; 186 signed char dmux_idx;
187}; 187};
188 188
189#define MAX_PINS_NUM 16
190#define MAX_ADCS_NUM 4
191#define MAX_DMICS_NUM 4
192
189struct sigmatel_spec { 193struct sigmatel_spec {
190 struct snd_kcontrol_new *mixers[4]; 194 struct snd_kcontrol_new *mixers[4];
191 unsigned int num_mixers; 195 unsigned int num_mixers;
@@ -300,6 +304,17 @@ struct sigmatel_spec {
300 struct hda_input_mux private_imux; 304 struct hda_input_mux private_imux;
301 struct hda_input_mux private_smux; 305 struct hda_input_mux private_smux;
302 struct hda_input_mux private_mono_mux; 306 struct hda_input_mux private_mono_mux;
307
308 /* auto spec */
309 unsigned auto_pin_cnt;
310 hda_nid_t auto_pin_nids[MAX_PINS_NUM];
311 unsigned auto_adc_cnt;
312 hda_nid_t auto_adc_nids[MAX_ADCS_NUM];
313 hda_nid_t auto_mux_nids[MAX_ADCS_NUM];
314 hda_nid_t auto_dmux_nids[MAX_ADCS_NUM];
315 unsigned long auto_capvols[MAX_ADCS_NUM];
316 unsigned auto_dmic_cnt;
317 hda_nid_t auto_dmic_nids[MAX_DMICS_NUM];
303}; 318};
304 319
305static hda_nid_t stac9200_adc_nids[1] = { 320static hda_nid_t stac9200_adc_nids[1] = {
@@ -355,14 +370,6 @@ static unsigned long stac92hd73xx_capvols[] = {
355 370
356#define STAC92HD83_DAC_COUNT 3 371#define STAC92HD83_DAC_COUNT 3
357 372
358static hda_nid_t stac92hd83xxx_mux_nids[2] = {
359 0x17, 0x18,
360};
361
362static hda_nid_t stac92hd83xxx_adc_nids[2] = {
363 0x15, 0x16,
364};
365
366static hda_nid_t stac92hd83xxx_pwr_nids[4] = { 373static hda_nid_t stac92hd83xxx_pwr_nids[4] = {
367 0xa, 0xb, 0xd, 0xe, 374 0xa, 0xb, 0xd, 0xe,
368}; 375};
@@ -375,25 +382,9 @@ static unsigned int stac92hd83xxx_pwr_mapping[4] = {
375 0x03, 0x0c, 0x20, 0x40, 382 0x03, 0x0c, 0x20, 0x40,
376}; 383};
377 384
378#define STAC92HD83XXX_NUM_DMICS 2 385static hda_nid_t stac92hd83xxx_dmic_nids[] = {
379static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { 386 0x11, 0x20,
380 0x11, 0x20, 0
381};
382
383#define STAC92HD88XXX_NUM_DMICS STAC92HD83XXX_NUM_DMICS
384#define stac92hd88xxx_dmic_nids stac92hd83xxx_dmic_nids
385
386#define STAC92HD87B_NUM_DMICS 1
387static hda_nid_t stac92hd87b_dmic_nids[STAC92HD87B_NUM_DMICS + 1] = {
388 0x11, 0
389};
390
391#define STAC92HD83XXX_NUM_CAPS 2
392static unsigned long stac92hd83xxx_capvols[] = {
393 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
394 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_OUTPUT),
395}; 387};
396#define stac92hd83xxx_capsws stac92hd83xxx_capvols
397 388
398static hda_nid_t stac92hd71bxx_pwr_nids[3] = { 389static hda_nid_t stac92hd71bxx_pwr_nids[3] = {
399 0x0a, 0x0d, 0x0f 390 0x0a, 0x0d, 0x0f
@@ -572,21 +563,6 @@ static hda_nid_t stac92hd73xx_pin_nids[13] = {
572 0x14, 0x22, 0x23 563 0x14, 0x22, 0x23
573}; 564};
574 565
575static hda_nid_t stac92hd83xxx_pin_nids[10] = {
576 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
577 0x0f, 0x10, 0x11, 0x1f, 0x20,
578};
579
580static hda_nid_t stac92hd87xxx_pin_nids[6] = {
581 0x0a, 0x0b, 0x0c, 0x0d,
582 0x0f, 0x11,
583};
584
585static hda_nid_t stac92hd88xxx_pin_nids[8] = {
586 0x0a, 0x0b, 0x0c, 0x0d,
587 0x0f, 0x11, 0x1f, 0x20,
588};
589
590#define STAC92HD71BXX_NUM_PINS 13 566#define STAC92HD71BXX_NUM_PINS 13
591static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { 567static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
592 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 568 0x0a, 0x0b, 0x0c, 0x0d, 0x00,
@@ -3415,6 +3391,17 @@ static const char * const stac92xx_dmic_labels[5] = {
3415 "Digital Mic 3", "Digital Mic 4" 3391 "Digital Mic 3", "Digital Mic 4"
3416}; 3392};
3417 3393
3394static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux,
3395 int idx)
3396{
3397 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3398 int nums;
3399 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3400 if (idx >= 0 && idx < nums)
3401 return conn[idx];
3402 return 0;
3403}
3404
3418static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 3405static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
3419 hda_nid_t nid) 3406 hda_nid_t nid)
3420{ 3407{
@@ -3425,6 +3412,15 @@ static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
3425 for (i = 0; i < nums; i++) 3412 for (i = 0; i < nums; i++)
3426 if (conn[i] == nid) 3413 if (conn[i] == nid)
3427 return i; 3414 return i;
3415
3416 for (i = 0; i < nums; i++) {
3417 unsigned int wid_caps = get_wcaps(codec, conn[i]);
3418 unsigned int wid_type = get_wcaps_type(wid_caps);
3419
3420 if (wid_type != AC_WID_PIN && wid_type != AC_WID_AUD_MIX)
3421 if (get_connection_index(codec, conn[i], nid) >= 0)
3422 return i;
3423 }
3428 return -1; 3424 return -1;
3429} 3425}
3430 3426
@@ -3497,6 +3493,16 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3497 type_idx, HDA_OUTPUT); 3493 type_idx, HDA_OUTPUT);
3498 if (err < 0) 3494 if (err < 0)
3499 return err; 3495 return err;
3496 if (!err) {
3497 nid = get_connected_node(codec,
3498 spec->dmux_nids[0], index);
3499 if (nid)
3500 err = create_elem_capture_vol(codec,
3501 nid, label,
3502 type_idx, HDA_INPUT);
3503 if (err < 0)
3504 return err;
3505 }
3500 } 3506 }
3501 } 3507 }
3502 3508
@@ -5308,6 +5314,105 @@ static int hp_bnb2011_with_dock(struct hda_codec *codec)
5308 return 0; 5314 return 0;
5309} 5315}
5310 5316
5317static void stac92hd8x_add_pin(struct hda_codec *codec, hda_nid_t nid)
5318{
5319 struct sigmatel_spec *spec = codec->spec;
5320 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
5321 int i;
5322
5323 spec->auto_pin_nids[spec->auto_pin_cnt] = nid;
5324 spec->auto_pin_cnt++;
5325
5326 if (get_defcfg_device(def_conf) == AC_JACK_MIC_IN &&
5327 get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) {
5328 for (i = 0; i < ARRAY_SIZE(stac92hd83xxx_dmic_nids); i++) {
5329 if (nid == stac92hd83xxx_dmic_nids[i]) {
5330 spec->auto_dmic_nids[spec->auto_dmic_cnt] = nid;
5331 spec->auto_dmic_cnt++;
5332 }
5333 }
5334 }
5335}
5336
5337static void stac92hd8x_add_adc(struct hda_codec *codec, hda_nid_t nid)
5338{
5339 struct sigmatel_spec *spec = codec->spec;
5340
5341 spec->auto_adc_nids[spec->auto_adc_cnt] = nid;
5342 spec->auto_adc_cnt++;
5343}
5344
5345static void stac92hd8x_add_mux(struct hda_codec *codec, hda_nid_t nid)
5346{
5347 int i, j;
5348 struct sigmatel_spec *spec = codec->spec;
5349
5350 for (i = 0; i < spec->auto_adc_cnt; i++) {
5351 if (get_connection_index(codec,
5352 spec->auto_adc_nids[i], nid) >= 0) {
5353 /* mux and volume for adc_nids[i] */
5354 if (!spec->auto_mux_nids[i]) {
5355 spec->auto_mux_nids[i] = nid;
5356 /* 92hd codecs capture volume is in mux */
5357 spec->auto_capvols[i] = HDA_COMPOSE_AMP_VAL(nid,
5358 3, 0, HDA_OUTPUT);
5359 }
5360 for (j = 0; j < spec->auto_dmic_cnt; j++) {
5361 if (get_connection_index(codec, nid,
5362 spec->auto_dmic_nids[j]) >= 0) {
5363 /* dmux for adc_nids[i] */
5364 if (!spec->auto_dmux_nids[i])
5365 spec->auto_dmux_nids[i] = nid;
5366 break;
5367 }
5368 }
5369 break;
5370 }
5371 }
5372}
5373
5374static void stac92hd8x_fill_auto_spec(struct hda_codec *codec)
5375{
5376 hda_nid_t nid, end_nid;
5377 unsigned int wid_caps, wid_type;
5378 struct sigmatel_spec *spec = codec->spec;
5379
5380 end_nid = codec->start_nid + codec->num_nodes;
5381
5382 for (nid = codec->start_nid; nid < end_nid; nid++) {
5383 wid_caps = get_wcaps(codec, nid);
5384 wid_type = get_wcaps_type(wid_caps);
5385
5386 if (wid_type == AC_WID_PIN)
5387 stac92hd8x_add_pin(codec, nid);
5388
5389 if (wid_type == AC_WID_AUD_IN && !(wid_caps & AC_WCAP_DIGITAL))
5390 stac92hd8x_add_adc(codec, nid);
5391 }
5392
5393 for (nid = codec->start_nid; nid < end_nid; nid++) {
5394 wid_caps = get_wcaps(codec, nid);
5395 wid_type = get_wcaps_type(wid_caps);
5396
5397 if (wid_type == AC_WID_AUD_SEL)
5398 stac92hd8x_add_mux(codec, nid);
5399 }
5400
5401 spec->pin_nids = spec->auto_pin_nids;
5402 spec->num_pins = spec->auto_pin_cnt;
5403 spec->adc_nids = spec->auto_adc_nids;
5404 spec->num_adcs = spec->auto_adc_cnt;
5405 spec->capvols = spec->auto_capvols;
5406 spec->capsws = spec->auto_capvols;
5407 spec->num_caps = spec->auto_adc_cnt;
5408 spec->mux_nids = spec->auto_mux_nids;
5409 spec->num_muxes = spec->auto_adc_cnt;
5410 spec->dmux_nids = spec->auto_dmux_nids;
5411 spec->num_dmuxes = spec->auto_adc_cnt;
5412 spec->dmic_nids = spec->auto_dmic_nids;
5413 spec->num_dmics = spec->auto_dmic_cnt;
5414}
5415
5311static int patch_stac92hd83xxx(struct hda_codec *codec) 5416static int patch_stac92hd83xxx(struct hda_codec *codec)
5312{ 5417{
5313 struct sigmatel_spec *spec; 5418 struct sigmatel_spec *spec;
@@ -5329,26 +5434,17 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5329 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); 5434 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0);
5330 codec->no_trigger_sense = 1; 5435 codec->no_trigger_sense = 1;
5331 codec->spec = spec; 5436 codec->spec = spec;
5437
5438 stac92hd8x_fill_auto_spec(codec);
5439
5332 spec->linear_tone_beep = 0; 5440 spec->linear_tone_beep = 0;
5333 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; 5441 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
5334 spec->digbeep_nid = 0x21; 5442 spec->digbeep_nid = 0x21;
5335 spec->dmic_nids = stac92hd83xxx_dmic_nids;
5336 spec->dmux_nids = stac92hd83xxx_mux_nids;
5337 spec->mux_nids = stac92hd83xxx_mux_nids;
5338 spec->num_muxes = ARRAY_SIZE(stac92hd83xxx_mux_nids);
5339 spec->adc_nids = stac92hd83xxx_adc_nids;
5340 spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids);
5341 spec->pwr_nids = stac92hd83xxx_pwr_nids; 5443 spec->pwr_nids = stac92hd83xxx_pwr_nids;
5342 spec->pwr_mapping = stac92hd83xxx_pwr_mapping; 5444 spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
5343 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); 5445 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
5344 spec->multiout.dac_nids = spec->dac_nids; 5446 spec->multiout.dac_nids = spec->dac_nids;
5345
5346 spec->init = stac92hd83xxx_core_init; 5447 spec->init = stac92hd83xxx_core_init;
5347 spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids);
5348 spec->pin_nids = stac92hd83xxx_pin_nids;
5349 spec->num_caps = STAC92HD83XXX_NUM_CAPS;
5350 spec->capvols = stac92hd83xxx_capvols;
5351 spec->capsws = stac92hd83xxx_capsws;
5352 5448
5353 spec->board_config = snd_hda_check_board_config(codec, 5449 spec->board_config = snd_hda_check_board_config(codec,
5354 STAC_92HD83XXX_MODELS, 5450 STAC_92HD83XXX_MODELS,
@@ -5366,28 +5462,11 @@ again:
5366 case 0x111d76d1: 5462 case 0x111d76d1:
5367 case 0x111d76d9: 5463 case 0x111d76d9:
5368 case 0x111d76e5: 5464 case 0x111d76e5:
5369 spec->dmic_nids = stac92hd87b_dmic_nids;
5370 spec->num_dmics = stac92xx_connected_ports(codec,
5371 stac92hd87b_dmic_nids,
5372 STAC92HD87B_NUM_DMICS);
5373 spec->num_pins = ARRAY_SIZE(stac92hd87xxx_pin_nids);
5374 spec->pin_nids = stac92hd87xxx_pin_nids;
5375 spec->mono_nid = 0;
5376 spec->num_pwrs = 0;
5377 break;
5378 case 0x111d7666: 5465 case 0x111d7666:
5379 case 0x111d7667: 5466 case 0x111d7667:
5380 case 0x111d7668: 5467 case 0x111d7668:
5381 case 0x111d7669: 5468 case 0x111d7669:
5382 case 0x111d76e3: 5469 case 0x111d76e3:
5383 spec->num_dmics = stac92xx_connected_ports(codec,
5384 stac92hd88xxx_dmic_nids,
5385 STAC92HD88XXX_NUM_DMICS);
5386 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
5387 spec->pin_nids = stac92hd88xxx_pin_nids;
5388 spec->mono_nid = 0;
5389 spec->num_pwrs = 0;
5390 break;
5391 case 0x111d7604: 5470 case 0x111d7604:
5392 case 0x111d76d4: 5471 case 0x111d76d4:
5393 case 0x111d7605: 5472 case 0x111d7605:
@@ -5396,9 +5475,6 @@ again:
5396 if (spec->board_config == STAC_92HD83XXX_PWR_REF) 5475 if (spec->board_config == STAC_92HD83XXX_PWR_REF)
5397 break; 5476 break;
5398 spec->num_pwrs = 0; 5477 spec->num_pwrs = 0;
5399 spec->num_dmics = stac92xx_connected_ports(codec,
5400 stac92hd83xxx_dmic_nids,
5401 STAC92HD83XXX_NUM_DMICS);
5402 break; 5478 break;
5403 } 5479 }
5404 5480