aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /sound/pci
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/Kconfig71
-rw-r--r--sound/pci/Makefile1
-rw-r--r--sound/pci/ac97/ac97_codec.c98
-rw-r--r--sound/pci/ac97/ac97_patch.c114
-rw-r--r--sound/pci/ad1889.c2
-rw-r--r--sound/pci/asihpi/asihpi.c1054
-rw-r--r--sound/pci/asihpi/hpi.h1216
-rw-r--r--sound/pci/asihpi/hpi6000.c332
-rw-r--r--sound/pci/asihpi/hpi6205.c696
-rw-r--r--sound/pci/asihpi/hpi6205.h7
-rw-r--r--sound/pci/asihpi/hpi_internal.h1127
-rw-r--r--sound/pci/asihpi/hpicmn.c496
-rw-r--r--sound/pci/asihpi/hpicmn.h26
-rw-r--r--sound/pci/asihpi/hpidebug.c157
-rw-r--r--sound/pci/asihpi/hpidebug.h323
-rw-r--r--sound/pci/asihpi/hpidspcd.c39
-rw-r--r--sound/pci/asihpi/hpidspcd.h2
-rw-r--r--sound/pci/asihpi/hpifunc.c2517
-rw-r--r--sound/pci/asihpi/hpimsginit.c18
-rw-r--r--sound/pci/asihpi/hpimsginit.h12
-rw-r--r--sound/pci/asihpi/hpimsgx.c218
-rw-r--r--sound/pci/asihpi/hpioctl.c147
-rw-r--r--sound/pci/asihpi/hpios.h10
-rw-r--r--sound/pci/atiixp.c2
-rw-r--r--sound/pci/atiixp_modem.c2
-rw-r--r--sound/pci/au88x0/au8810.h2
-rw-r--r--sound/pci/au88x0/au8820.h2
-rw-r--r--sound/pci/au88x0/au8830.h2
-rw-r--r--sound/pci/au88x0/au88x0.h6
-rw-r--r--sound/pci/au88x0/au88x0_a3d.c4
-rw-r--r--sound/pci/au88x0/au88x0_core.c18
-rw-r--r--sound/pci/au88x0/au88x0_eq.c3
-rw-r--r--sound/pci/au88x0/au88x0_mixer.c2
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c46
-rw-r--r--sound/pci/azt3328.c870
-rw-r--r--sound/pci/bt87x.c10
-rw-r--r--sound/pci/ca0106/ca0106.h13
-rw-r--r--sound/pci/ca0106/ca0106_main.c140
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c95
-rw-r--r--sound/pci/ca0106/ca0106_proc.c2
-rw-r--r--sound/pci/cmipci.c33
-rw-r--r--sound/pci/cs46xx/dsp_spos.c33
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c4
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pm.c7
-rw-r--r--sound/pci/ctxfi/ctatc.c4
-rw-r--r--sound/pci/ctxfi/ctdaio.c2
-rw-r--r--sound/pci/ctxfi/cthw20k1.c2
-rw-r--r--sound/pci/ctxfi/cthw20k2.c28
-rw-r--r--sound/pci/ctxfi/ctmixer.c19
-rw-r--r--sound/pci/ctxfi/ctpcm.c16
-rw-r--r--sound/pci/ctxfi/ctvmem.c3
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c10
-rw-r--r--sound/pci/emu10k1/emu10k1x.c2
-rw-r--r--sound/pci/emu10k1/emufx.c5
-rw-r--r--sound/pci/emu10k1/emumixer.c10
-rw-r--r--sound/pci/emu10k1/emumpu401.c2
-rw-r--r--sound/pci/emu10k1/memory.c2
-rw-r--r--sound/pci/emu10k1/p16v.c2
-rw-r--r--sound/pci/emu10k1/p16v.h6
-rw-r--r--sound/pci/ens1370.c25
-rw-r--r--sound/pci/es1968.c80
-rw-r--r--sound/pci/fm801.c378
-rw-r--r--sound/pci/hda/Kconfig39
-rw-r--r--sound/pci/hda/Makefile15
-rw-r--r--sound/pci/hda/hda_beep.h9
-rw-r--r--sound/pci/hda/hda_codec.c549
-rw-r--r--sound/pci/hda/hda_codec.h22
-rw-r--r--sound/pci/hda/hda_eld.c56
-rw-r--r--sound/pci/hda/hda_generic.c48
-rw-r--r--sound/pci/hda/hda_intel.c294
-rw-r--r--sound/pci/hda/hda_local.h97
-rw-r--r--sound/pci/hda/hda_proc.c2
-rw-r--r--sound/pci/hda/patch_analog.c662
-rw-r--r--sound/pci/hda/patch_atihdmi.c224
-rw-r--r--sound/pci/hda/patch_ca0110.c26
-rw-r--r--sound/pci/hda/patch_cirrus.c151
-rw-r--r--sound/pci/hda/patch_cmedia.c42
-rw-r--r--sound/pci/hda/patch_conexant.c1835
-rw-r--r--sound/pci/hda/patch_hdmi.c987
-rw-r--r--sound/pci/hda/patch_intelhdmi.c220
-rw-r--r--sound/pci/hda/patch_nvhdmi.c608
-rw-r--r--sound/pci/hda/patch_realtek.c5558
-rw-r--r--sound/pci/hda/patch_si3054.c11
-rw-r--r--sound/pci/hda/patch_sigmatel.c1165
-rw-r--r--sound/pci/hda/patch_via.c2230
-rw-r--r--sound/pci/ice1712/aureon.c4
-rw-r--r--sound/pci/ice1712/delta.c66
-rw-r--r--sound/pci/ice1712/delta.h15
-rw-r--r--sound/pci/ice1712/ice1712.c4
-rw-r--r--sound/pci/ice1712/pontis.c8
-rw-r--r--sound/pci/ice1712/prodigy192.c2
-rw-r--r--sound/pci/ice1712/prodigy_hifi.c4
-rw-r--r--sound/pci/intel8x0.c10
-rw-r--r--sound/pci/intel8x0m.c113
-rw-r--r--sound/pci/lola/Makefile4
-rw-r--r--sound/pci/lola/lola.c791
-rw-r--r--sound/pci/lola/lola.h527
-rw-r--r--sound/pci/lola/lola_clock.c323
-rw-r--r--sound/pci/lola/lola_mixer.c839
-rw-r--r--sound/pci/lola/lola_pcm.c706
-rw-r--r--sound/pci/lola/lola_proc.c222
-rw-r--r--sound/pci/lx6464es/lx6464es.c4
-rw-r--r--sound/pci/lx6464es/lx6464es.h2
-rw-r--r--sound/pci/lx6464es/lx_core.c2
-rw-r--r--sound/pci/mixart/mixart_core.c4
-rw-r--r--sound/pci/mixart/mixart_hwdep.h10
-rw-r--r--sound/pci/oxygen/Makefile4
-rw-r--r--sound/pci/oxygen/cs4245.h107
-rw-r--r--sound/pci/oxygen/hifier.c239
-rw-r--r--sound/pci/oxygen/oxygen.c358
-rw-r--r--sound/pci/oxygen/oxygen.h22
-rw-r--r--sound/pci/oxygen/oxygen_io.c4
-rw-r--r--sound/pci/oxygen/oxygen_lib.c126
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c117
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c67
-rw-r--r--sound/pci/oxygen/oxygen_regs.h26
-rw-r--r--sound/pci/oxygen/virtuoso.c5
-rw-r--r--sound/pci/oxygen/xonar.h2
-rw-r--r--sound/pci/oxygen/xonar_cs43xx.c92
-rw-r--r--sound/pci/oxygen/xonar_dg.c608
-rw-r--r--sound/pci/oxygen/xonar_dg.h8
-rw-r--r--sound/pci/oxygen/xonar_hdmi.c2
-rw-r--r--sound/pci/oxygen/xonar_lib.c6
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c478
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c412
-rw-r--r--sound/pci/pcxhr/pcxhr_core.c12
-rw-r--r--sound/pci/rme96.c10
-rw-r--r--sound/pci/rme9652/hdsp.c546
-rw-r--r--sound/pci/rme9652/hdspm.c4474
-rw-r--r--sound/pci/sis7019.c6
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c12
131 files changed, 22418 insertions, 14410 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index e7a8cd058efb..e90d103e177e 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -152,10 +152,16 @@ config SND_AZT3328
152 select SND_MPU401_UART 152 select SND_MPU401_UART
153 select SND_PCM 153 select SND_PCM
154 select SND_RAWMIDI 154 select SND_RAWMIDI
155 select SND_AC97_CODEC
155 help 156 help
156 Say Y here to include support for Aztech AZF3328 (PCI168) 157 Say Y here to include support for Aztech AZF3328 (PCI168)
157 soundcards. 158 soundcards.
158 159
160 Supported features: AC97-"conformant" mixer, MPU401/OPL3, analog I/O
161 (16bit/8bit, many sample rates [<= 66.2kHz], NO hardware mixing),
162 Digital Enhanced Game Port, 1.024MHz multimedia sequencer timer,
163 ext. codec (I2S port), onboard amp (4W/4Ohms/ch), suspend/resume.
164
159 To compile this driver as a module, choose M here: the module 165 To compile this driver as a module, choose M here: the module
160 will be called snd-azt3328. 166 will be called snd-azt3328.
161 167
@@ -207,23 +213,28 @@ config SND_CMIPCI
207 213
208config SND_OXYGEN_LIB 214config SND_OXYGEN_LIB
209 tristate 215 tristate
210 select SND_PCM
211 select SND_MPU401_UART
212 216
213config SND_OXYGEN 217config SND_OXYGEN
214 tristate "C-Media 8788 (Oxygen)" 218 tristate "C-Media 8786, 8787, 8788 (Oxygen)"
215 select SND_OXYGEN_LIB 219 select SND_OXYGEN_LIB
220 select SND_PCM
221 select SND_MPU401_UART
216 help 222 help
217 Say Y here to include support for sound cards based on the 223 Say Y here to include support for sound cards based on the
218 C-Media CMI8788 (Oxygen HD Audio) chip: 224 C-Media CMI8788 (Oxygen HD Audio) chip:
219 * Asound A-8788 225 * Asound A-8788
226 * Asus Xonar DG
220 * AuzenTech X-Meridian 227 * AuzenTech X-Meridian
228 * AuzenTech X-Meridian 2G
221 * Bgears b-Enspirer 229 * Bgears b-Enspirer
222 * Club3D Theatron DTS 230 * Club3D Theatron DTS
223 * HT-Omega Claro (plus) 231 * HT-Omega Claro (plus)
224 * HT-Omega Claro halo (XT) 232 * HT-Omega Claro halo (XT)
233 * Kuroutoshikou CMI8787-HG2PCI
225 * Razer Barracuda AC-1 234 * Razer Barracuda AC-1
226 * Sondigo Inferno 235 * Sondigo Inferno
236 * TempoTec/MediaTek HiFier Fantasia
237 * TempoTec/MediaTek HiFier Serenade
227 238
228 To compile this driver as a module, choose M here: the module 239 To compile this driver as a module, choose M here: the module
229 will be called snd-oxygen. 240 will be called snd-oxygen.
@@ -523,6 +534,14 @@ config SND_ES1968_INPUT
523 If you say N the buttons will directly control the master volume. 534 If you say N the buttons will directly control the master volume.
524 It is recommended to say Y. 535 It is recommended to say Y.
525 536
537config SND_ES1968_RADIO
538 bool "Enable TEA5757 radio tuner support for es1968"
539 depends on SND_ES1968
540 depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_ES1968
541 help
542 Say Y here to include support for TEA5757 radio tuner integrated on
543 some MediaForte cards (e.g. SF64-PCE2).
544
526config SND_FM801 545config SND_FM801
527 tristate "ForteMedia FM801" 546 tristate "ForteMedia FM801"
528 select SND_OPL3_LIB 547 select SND_OPL3_LIB
@@ -541,13 +560,13 @@ config SND_FM801_TEA575X_BOOL
541 depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801 560 depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801
542 help 561 help
543 Say Y here to include support for soundcards based on the ForteMedia 562 Say Y here to include support for soundcards based on the ForteMedia
544 FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media 563 FM801 chip with a TEA5757 tuner (MediaForte SF256-PCS, SF256-PCP and
545 Forte SF256-PCS-02) into the snd-fm801 driver. 564 SF64-PCR) into the snd-fm801 driver.
546 565
547config SND_FM801_TEA575X 566config SND_TEA575X
548 tristate 567 tristate
549 depends on SND_FM801_TEA575X_BOOL 568 depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO
550 default SND_FM801 569 default SND_FM801 || SND_ES1968
551 570
552source "sound/pci/hda/Kconfig" 571source "sound/pci/hda/Kconfig"
553 572
@@ -567,27 +586,17 @@ comment "Don't forget to add built-in firmwares for HDSP driver"
567 depends on SND_HDSP=y 586 depends on SND_HDSP=y
568 587
569config SND_HDSPM 588config SND_HDSPM
570 tristate "RME Hammerfall DSP MADI" 589 tristate "RME Hammerfall DSP MADI/RayDAT/AIO"
571 select SND_HWDEP 590 select SND_HWDEP
572 select SND_RAWMIDI 591 select SND_RAWMIDI
573 select SND_PCM 592 select SND_PCM
574 help 593 help
575 Say Y here to include support for RME Hammerfall DSP MADI 594 Say Y here to include support for RME Hammerfall DSP MADI,
576 soundcards. 595 RayDAT and AIO soundcards.
577 596
578 To compile this driver as a module, choose M here: the module 597 To compile this driver as a module, choose M here: the module
579 will be called snd-hdspm. 598 will be called snd-hdspm.
580 599
581config SND_HIFIER
582 tristate "TempoTec HiFier Fantasia"
583 select SND_OXYGEN_LIB
584 help
585 Say Y here to include support for the MediaTek/TempoTec HiFier
586 Fantasia sound card.
587
588 To compile this driver as a module, choose M here: the module
589 will be called snd-hifier.
590
591config SND_ICE1712 600config SND_ICE1712
592 tristate "ICEnsemble ICE1712 (Envy24)" 601 tristate "ICEnsemble ICE1712 (Envy24)"
593 select SND_MPU401_UART 602 select SND_MPU401_UART
@@ -657,6 +666,15 @@ config SND_KORG1212
657 To compile this driver as a module, choose M here: the module 666 To compile this driver as a module, choose M here: the module
658 will be called snd-korg1212. 667 will be called snd-korg1212.
659 668
669config SND_LOLA
670 tristate "Digigram Lola"
671 select SND_PCM
672 help
673 Say Y to include support for Digigram Lola boards.
674
675 To compile this driver as a module, choose M here: the module
676 will be called snd-lola.
677
660config SND_LX6464ES 678config SND_LX6464ES
661 tristate "Digigram LX6464ES" 679 tristate "Digigram LX6464ES"
662 select SND_PCM 680 select SND_PCM
@@ -815,14 +833,17 @@ config SND_VIA82XX_MODEM
815 will be called snd-via82xx-modem. 833 will be called snd-via82xx-modem.
816 834
817config SND_VIRTUOSO 835config SND_VIRTUOSO
818 tristate "Asus Virtuoso 100/200 (Xonar)" 836 tristate "Asus Virtuoso 66/100/200 (Xonar)"
819 select SND_OXYGEN_LIB 837 select SND_OXYGEN_LIB
838 select SND_PCM
839 select SND_MPU401_UART
840 select SND_JACK if INPUT=y || INPUT=SND
820 help 841 help
821 Say Y here to include support for sound cards based on the 842 Say Y here to include support for sound cards based on the
822 Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, 843 Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS,
823 Essence ST (Deluxe), and Essence STX. 844 Essence ST (Deluxe), and Essence STX.
824 Support for the DS is experimental. 845 Support for the HDAV1.3 (Deluxe) and HDAV1.3 Slim is experimental;
825 Support for the HDAV1.3 (Deluxe) is very experimental. 846 for the Xense, missing.
826 847
827 To compile this driver as a module, choose M here: the module 848 To compile this driver as a module, choose M here: the module
828 will be called snd-virtuoso. 849 will be called snd-virtuoso.
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index 9cf4348ec137..54fe325e3aa5 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_SND) += \
64 ca0106/ \ 64 ca0106/ \
65 cs46xx/ \ 65 cs46xx/ \
66 cs5535audio/ \ 66 cs5535audio/ \
67 lola/ \
67 lx6464es/ \ 68 lx6464es/ \
68 echoaudio/ \ 69 echoaudio/ \
69 emu10k1/ \ 70 emu10k1/ \
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index a7630e9edf8a..7f4d619f4ddb 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -71,6 +71,12 @@ static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = {
71{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL }, 71{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL },
72{ 0x414c4300, 0xffffff00, "Realtek", NULL, NULL }, 72{ 0x414c4300, 0xffffff00, "Realtek", NULL, NULL },
73{ 0x414c4700, 0xffffff00, "Realtek", NULL, NULL }, 73{ 0x414c4700, 0xffffff00, "Realtek", NULL, NULL },
74/*
75 * This is an _inofficial_ Aztech Labs entry
76 * (value might differ from unknown official Aztech ID),
77 * currently used by the AC97 emulation of the almost-AC97 PCI168 card.
78 */
79{ 0x415a5400, 0xffffff00, "Aztech Labs (emulated)", NULL, NULL },
74{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL }, 80{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL },
75{ 0x43525900, 0xffffff00, "Cirrus Logic", NULL, NULL }, 81{ 0x43525900, 0xffffff00, "Cirrus Logic", NULL, NULL },
76{ 0x43585400, 0xffffff00, "Conexant", NULL, NULL }, 82{ 0x43585400, 0xffffff00, "Conexant", NULL, NULL },
@@ -127,6 +133,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
127{ 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */ 133{ 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */
128{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL }, 134{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL },
129{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL }, 135{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL },
136{ 0x415a5401, 0xffffffff, "AZF3328", patch_aztech_azf3328, NULL },
130{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL }, 137{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL },
131{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL }, 138{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL },
132{ 0x434d4969, 0xffffffff, "CMI9780", patch_cm9780, NULL }, 139{ 0x434d4969, 0xffffffff, "CMI9780", patch_cm9780, NULL },
@@ -590,9 +597,9 @@ static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
590 snd_ac97_page_restore(ac97, page_save); 597 snd_ac97_page_restore(ac97, page_save);
591#ifdef CONFIG_SND_AC97_POWER_SAVE 598#ifdef CONFIG_SND_AC97_POWER_SAVE
592 /* check analog mixer power-down */ 599 /* check analog mixer power-down */
593 if ((val_mask & 0x8000) && 600 if ((val_mask & AC97_PD_EAPD) &&
594 (kcontrol->private_value & (1<<30))) { 601 (kcontrol->private_value & (1<<30))) {
595 if (val & 0x8000) 602 if (val & AC97_PD_EAPD)
596 ac97->power_up &= ~(1 << (reg>>1)); 603 ac97->power_up &= ~(1 << (reg>>1));
597 else 604 else
598 ac97->power_up |= 1 << (reg>>1); 605 ac97->power_up |= 1 << (reg>>1);
@@ -1014,8 +1021,7 @@ static int snd_ac97_free(struct snd_ac97 *ac97)
1014{ 1021{
1015 if (ac97) { 1022 if (ac97) {
1016#ifdef CONFIG_SND_AC97_POWER_SAVE 1023#ifdef CONFIG_SND_AC97_POWER_SAVE
1017 cancel_delayed_work(&ac97->power_work); 1024 cancel_delayed_work_sync(&ac97->power_work);
1018 flush_scheduled_work();
1019#endif 1025#endif
1020 snd_ac97_proc_done(ac97); 1026 snd_ac97_proc_done(ac97);
1021 if (ac97->bus) 1027 if (ac97->bus)
@@ -1036,20 +1042,20 @@ static int snd_ac97_dev_free(struct snd_device *device)
1036 1042
1037static int snd_ac97_try_volume_mix(struct snd_ac97 * ac97, int reg) 1043static int snd_ac97_try_volume_mix(struct snd_ac97 * ac97, int reg)
1038{ 1044{
1039 unsigned short val, mask = 0x8000; 1045 unsigned short val, mask = AC97_MUTE_MASK_MONO;
1040 1046
1041 if (! snd_ac97_valid_reg(ac97, reg)) 1047 if (! snd_ac97_valid_reg(ac97, reg))
1042 return 0; 1048 return 0;
1043 1049
1044 switch (reg) { 1050 switch (reg) {
1045 case AC97_MASTER_TONE: 1051 case AC97_MASTER_TONE:
1046 return ac97->caps & 0x04 ? 1 : 0; 1052 return ac97->caps & AC97_BC_BASS_TREBLE ? 1 : 0;
1047 case AC97_HEADPHONE: 1053 case AC97_HEADPHONE:
1048 return ac97->caps & 0x10 ? 1 : 0; 1054 return ac97->caps & AC97_BC_HEADPHONE ? 1 : 0;
1049 case AC97_REC_GAIN_MIC: 1055 case AC97_REC_GAIN_MIC:
1050 return ac97->caps & 0x01 ? 1 : 0; 1056 return ac97->caps & AC97_BC_DEDICATED_MIC ? 1 : 0;
1051 case AC97_3D_CONTROL: 1057 case AC97_3D_CONTROL:
1052 if (ac97->caps & 0x7c00) { 1058 if (ac97->caps & AC97_BC_3D_TECH_ID_MASK) {
1053 val = snd_ac97_read(ac97, reg); 1059 val = snd_ac97_read(ac97, reg);
1054 /* if nonzero - fixed and we can't set it */ 1060 /* if nonzero - fixed and we can't set it */
1055 return val == 0; 1061 return val == 0;
@@ -1105,7 +1111,10 @@ static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned cha
1105 *lo_max = *hi_max = 0; 1111 *lo_max = *hi_max = 0;
1106 for (i = 0 ; i < ARRAY_SIZE(cbit); i++) { 1112 for (i = 0 ; i < ARRAY_SIZE(cbit); i++) {
1107 unsigned short val; 1113 unsigned short val;
1108 snd_ac97_write(ac97, reg, 0x8080 | cbit[i] | (cbit[i] << 8)); 1114 snd_ac97_write(
1115 ac97, reg,
1116 AC97_MUTE_MASK_STEREO | cbit[i] | (cbit[i] << 8)
1117 );
1109 /* Do the read twice due to buffers on some ac97 codecs. 1118 /* Do the read twice due to buffers on some ac97 codecs.
1110 * e.g. The STAC9704 returns exactly what you wrote to the register 1119 * e.g. The STAC9704 returns exactly what you wrote to the register
1111 * if you read it immediately. This causes the detect routine to fail. 1120 * if you read it immediately. This causes the detect routine to fail.
@@ -1140,14 +1149,14 @@ static void snd_ac97_change_volume_params2(struct snd_ac97 * ac97, int reg, int
1140 unsigned short val, val1; 1149 unsigned short val, val1;
1141 1150
1142 *max = 63; 1151 *max = 63;
1143 val = 0x8080 | (0x20 << shift); 1152 val = AC97_MUTE_MASK_STEREO | (0x20 << shift);
1144 snd_ac97_write(ac97, reg, val); 1153 snd_ac97_write(ac97, reg, val);
1145 val1 = snd_ac97_read(ac97, reg); 1154 val1 = snd_ac97_read(ac97, reg);
1146 if (val != val1) { 1155 if (val != val1) {
1147 *max = 31; 1156 *max = 31;
1148 } 1157 }
1149 /* reset volume to zero */ 1158 /* reset volume to zero */
1150 snd_ac97_write_cache(ac97, reg, 0x8080); 1159 snd_ac97_write_cache(ac97, reg, AC97_MUTE_MASK_STEREO);
1151} 1160}
1152 1161
1153static inline int printable(unsigned int x) 1162static inline int printable(unsigned int x)
@@ -1184,16 +1193,16 @@ static int snd_ac97_cmute_new_stereo(struct snd_card *card, char *name, int reg,
1184 if (! snd_ac97_valid_reg(ac97, reg)) 1193 if (! snd_ac97_valid_reg(ac97, reg))
1185 return 0; 1194 return 0;
1186 1195
1187 mute_mask = 0x8000; 1196 mute_mask = AC97_MUTE_MASK_MONO;
1188 val = snd_ac97_read(ac97, reg); 1197 val = snd_ac97_read(ac97, reg);
1189 if (check_stereo || (ac97->flags & AC97_STEREO_MUTES)) { 1198 if (check_stereo || (ac97->flags & AC97_STEREO_MUTES)) {
1190 /* check whether both mute bits work */ 1199 /* check whether both mute bits work */
1191 val1 = val | 0x8080; 1200 val1 = val | AC97_MUTE_MASK_STEREO;
1192 snd_ac97_write(ac97, reg, val1); 1201 snd_ac97_write(ac97, reg, val1);
1193 if (val1 == snd_ac97_read(ac97, reg)) 1202 if (val1 == snd_ac97_read(ac97, reg))
1194 mute_mask = 0x8080; 1203 mute_mask = AC97_MUTE_MASK_STEREO;
1195 } 1204 }
1196 if (mute_mask == 0x8080) { 1205 if (mute_mask == AC97_MUTE_MASK_STEREO) {
1197 struct snd_kcontrol_new tmp = AC97_DOUBLE(name, reg, 15, 7, 1, 1); 1206 struct snd_kcontrol_new tmp = AC97_DOUBLE(name, reg, 15, 7, 1, 1);
1198 if (check_amix) 1207 if (check_amix)
1199 tmp.private_value |= (1 << 30); 1208 tmp.private_value |= (1 << 30);
@@ -1269,9 +1278,11 @@ static int snd_ac97_cvol_new(struct snd_card *card, char *name, int reg, unsigne
1269 err = snd_ctl_add(card, kctl); 1278 err = snd_ctl_add(card, kctl);
1270 if (err < 0) 1279 if (err < 0)
1271 return err; 1280 return err;
1272 snd_ac97_write_cache(ac97, reg, 1281 snd_ac97_write_cache(
1273 (snd_ac97_read(ac97, reg) & 0x8080) | 1282 ac97, reg,
1274 lo_max | (hi_max << 8)); 1283 (snd_ac97_read(ac97, reg) & AC97_MUTE_MASK_STEREO)
1284 | lo_max | (hi_max << 8)
1285 );
1275 return 0; 1286 return 0;
1276} 1287}
1277 1288
@@ -1333,7 +1344,7 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1333 return err; 1344 return err;
1334 } 1345 }
1335 1346
1336 ac97->regs[AC97_CENTER_LFE_MASTER] = 0x8080; 1347 ac97->regs[AC97_CENTER_LFE_MASTER] = AC97_MUTE_MASK_STEREO;
1337 1348
1338 /* build center controls */ 1349 /* build center controls */
1339 if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER)) 1350 if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER))
@@ -1411,8 +1422,12 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1411 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_pc_beep[idx], ac97))) < 0) 1422 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_pc_beep[idx], ac97))) < 0)
1412 return err; 1423 return err;
1413 set_tlv_db_scale(kctl, db_scale_4bit); 1424 set_tlv_db_scale(kctl, db_scale_4bit);
1414 snd_ac97_write_cache(ac97, AC97_PC_BEEP, 1425 snd_ac97_write_cache(
1415 snd_ac97_read(ac97, AC97_PC_BEEP) | 0x801e); 1426 ac97,
1427 AC97_PC_BEEP,
1428 (snd_ac97_read(ac97, AC97_PC_BEEP)
1429 | AC97_MUTE_MASK_MONO | 0x001e)
1430 );
1416 } 1431 }
1417 1432
1418 /* build Phone controls */ 1433 /* build Phone controls */
@@ -1546,7 +1561,7 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1546 } 1561 }
1547 1562
1548 /* build Simulated Stereo Enhancement control */ 1563 /* build Simulated Stereo Enhancement control */
1549 if (ac97->caps & 0x0008) { 1564 if (ac97->caps & AC97_BC_SIM_STEREO) {
1550 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_STEREO_ENHANCEMENT], ac97))) < 0) 1565 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_STEREO_ENHANCEMENT], ac97))) < 0)
1551 return err; 1566 return err;
1552 } 1567 }
@@ -1558,7 +1573,7 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1558 } 1573 }
1559 1574
1560 /* build Loudness control */ 1575 /* build Loudness control */
1561 if (ac97->caps & 0x0020) { 1576 if (ac97->caps & AC97_BC_LOUDNESS) {
1562 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_LOUDNESS], ac97))) < 0) 1577 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_LOUDNESS], ac97))) < 0)
1563 return err; 1578 return err;
1564 } 1579 }
@@ -1962,7 +1977,7 @@ static int snd_ac97_dev_disconnect(struct snd_device *device)
1962} 1977}
1963 1978
1964/* build_ops to do nothing */ 1979/* build_ops to do nothing */
1965static struct snd_ac97_build_ops null_build_ops; 1980static const struct snd_ac97_build_ops null_build_ops;
1966 1981
1967#ifdef CONFIG_SND_AC97_POWER_SAVE 1982#ifdef CONFIG_SND_AC97_POWER_SAVE
1968static void do_update_power(struct work_struct *work) 1983static void do_update_power(struct work_struct *work)
@@ -2456,8 +2471,7 @@ void snd_ac97_suspend(struct snd_ac97 *ac97)
2456 if (ac97->build_ops->suspend) 2471 if (ac97->build_ops->suspend)
2457 ac97->build_ops->suspend(ac97); 2472 ac97->build_ops->suspend(ac97);
2458#ifdef CONFIG_SND_AC97_POWER_SAVE 2473#ifdef CONFIG_SND_AC97_POWER_SAVE
2459 cancel_delayed_work(&ac97->power_work); 2474 cancel_delayed_work_sync(&ac97->power_work);
2460 flush_scheduled_work();
2461#endif 2475#endif
2462 snd_ac97_powerdown(ac97); 2476 snd_ac97_powerdown(ac97);
2463} 2477}
@@ -2544,8 +2558,8 @@ void snd_ac97_resume(struct snd_ac97 *ac97)
2544 schedule_timeout_uninterruptible(1); 2558 schedule_timeout_uninterruptible(1);
2545 } while (time_after_eq(end_time, jiffies)); 2559 } while (time_after_eq(end_time, jiffies));
2546 /* FIXME: extra delay */ 2560 /* FIXME: extra delay */
2547 ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000); 2561 ac97->bus->ops->write(ac97, AC97_MASTER, AC97_MUTE_MASK_MONO);
2548 if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) 2562 if (snd_ac97_read(ac97, AC97_MASTER) != AC97_MUTE_MASK_MONO)
2549 msleep(250); 2563 msleep(250);
2550 } else { 2564 } else {
2551 end_time = jiffies + msecs_to_jiffies(100); 2565 end_time = jiffies + msecs_to_jiffies(100);
@@ -2749,12 +2763,12 @@ static int master_mute_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
2749 int rshift = (kcontrol->private_value >> 12) & 0x0f; 2763 int rshift = (kcontrol->private_value >> 12) & 0x0f;
2750 unsigned short mask; 2764 unsigned short mask;
2751 if (shift != rshift) 2765 if (shift != rshift)
2752 mask = 0x8080; 2766 mask = AC97_MUTE_MASK_STEREO;
2753 else 2767 else
2754 mask = 0x8000; 2768 mask = AC97_MUTE_MASK_MONO;
2755 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 2769 snd_ac97_update_bits(ac97, AC97_POWERDOWN, AC97_PD_EAPD,
2756 (ac97->regs[AC97_MASTER] & mask) == mask ? 2770 (ac97->regs[AC97_MASTER] & mask) == mask ?
2757 0x8000 : 0); 2771 AC97_PD_EAPD : 0);
2758 } 2772 }
2759 return err; 2773 return err;
2760} 2774}
@@ -2767,7 +2781,10 @@ static int tune_mute_led(struct snd_ac97 *ac97)
2767 return -ENOENT; 2781 return -ENOENT;
2768 msw->put = master_mute_sw_put; 2782 msw->put = master_mute_sw_put;
2769 snd_ac97_remove_ctl(ac97, "External Amplifier", NULL); 2783 snd_ac97_remove_ctl(ac97, "External Amplifier", NULL);
2770 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 0x8000); /* mute LED on */ 2784 snd_ac97_update_bits(
2785 ac97, AC97_POWERDOWN,
2786 AC97_PD_EAPD, AC97_PD_EAPD /* mute LED on */
2787 );
2771 ac97->scaps |= AC97_SCAP_EAPD_LED; 2788 ac97->scaps |= AC97_SCAP_EAPD_LED;
2772 return 0; 2789 return 0;
2773} 2790}
@@ -2782,12 +2799,12 @@ static int hp_master_mute_sw_put(struct snd_kcontrol *kcontrol,
2782 int rshift = (kcontrol->private_value >> 12) & 0x0f; 2799 int rshift = (kcontrol->private_value >> 12) & 0x0f;
2783 unsigned short mask; 2800 unsigned short mask;
2784 if (shift != rshift) 2801 if (shift != rshift)
2785 mask = 0x8080; 2802 mask = AC97_MUTE_MASK_STEREO;
2786 else 2803 else
2787 mask = 0x8000; 2804 mask = AC97_MUTE_MASK_MONO;
2788 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 2805 snd_ac97_update_bits(ac97, AC97_POWERDOWN, AC97_PD_EAPD,
2789 (ac97->regs[AC97_MASTER] & mask) == mask ? 2806 (ac97->regs[AC97_MASTER] & mask) == mask ?
2790 0x8000 : 0); 2807 AC97_PD_EAPD : 0);
2791 } 2808 }
2792 return err; 2809 return err;
2793} 2810}
@@ -2803,7 +2820,10 @@ static int tune_hp_mute_led(struct snd_ac97 *ac97)
2803 snd_ac97_remove_ctl(ac97, "External Amplifier", NULL); 2820 snd_ac97_remove_ctl(ac97, "External Amplifier", NULL);
2804 snd_ac97_remove_ctl(ac97, "Headphone Playback", "Switch"); 2821 snd_ac97_remove_ctl(ac97, "Headphone Playback", "Switch");
2805 snd_ac97_remove_ctl(ac97, "Headphone Playback", "Volume"); 2822 snd_ac97_remove_ctl(ac97, "Headphone Playback", "Volume");
2806 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 0x8000); /* mute LED on */ 2823 snd_ac97_update_bits(
2824 ac97, AC97_POWERDOWN,
2825 AC97_PD_EAPD, AC97_PD_EAPD /* mute LED on */
2826 );
2807 return 0; 2827 return 0;
2808} 2828}
2809 2829
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index e68c98ef4041..200c9a1d48b7 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -27,6 +27,15 @@
27#include "ac97_patch.h" 27#include "ac97_patch.h"
28 28
29/* 29/*
30 * Forward declarations
31 */
32
33static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97,
34 const char *name);
35static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name,
36 const unsigned int *tlv, const char **slaves);
37
38/*
30 * Chip specific initialization 39 * Chip specific initialization
31 */ 40 */
32 41
@@ -371,7 +380,7 @@ static int patch_yamaha_ymf743_build_spdif(struct snd_ac97 *ac97)
371 return 0; 380 return 0;
372} 381}
373 382
374static struct snd_ac97_build_ops patch_yamaha_ymf743_ops = { 383static const struct snd_ac97_build_ops patch_yamaha_ymf743_ops = {
375 .build_spdif = patch_yamaha_ymf743_build_spdif, 384 .build_spdif = patch_yamaha_ymf743_build_spdif,
376 .build_3d = patch_yamaha_ymf7x3_3d, 385 .build_3d = patch_yamaha_ymf7x3_3d,
377}; 386};
@@ -455,7 +464,7 @@ static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97)
455 return 0; 464 return 0;
456} 465}
457 466
458static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { 467static const struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
459 .build_3d = patch_yamaha_ymf7x3_3d, 468 .build_3d = patch_yamaha_ymf7x3_3d,
460 .build_post_spdif = patch_yamaha_ymf753_post_spdif 469 .build_post_spdif = patch_yamaha_ymf753_post_spdif
461}; 470};
@@ -502,7 +511,7 @@ static int patch_wolfson_wm9703_specific(struct snd_ac97 * ac97)
502 return 0; 511 return 0;
503} 512}
504 513
505static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = { 514static const struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
506 .build_specific = patch_wolfson_wm9703_specific, 515 .build_specific = patch_wolfson_wm9703_specific,
507}; 516};
508 517
@@ -533,7 +542,7 @@ static int patch_wolfson_wm9704_specific(struct snd_ac97 * ac97)
533 return 0; 542 return 0;
534} 543}
535 544
536static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = { 545static const struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
537 .build_specific = patch_wolfson_wm9704_specific, 546 .build_specific = patch_wolfson_wm9704_specific,
538}; 547};
539 548
@@ -677,7 +686,7 @@ static int patch_wolfson_wm9711_specific(struct snd_ac97 * ac97)
677 return 0; 686 return 0;
678} 687}
679 688
680static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = { 689static const struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
681 .build_specific = patch_wolfson_wm9711_specific, 690 .build_specific = patch_wolfson_wm9711_specific,
682}; 691};
683 692
@@ -871,7 +880,7 @@ static void patch_wolfson_wm9713_resume (struct snd_ac97 * ac97)
871} 880}
872#endif 881#endif
873 882
874static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { 883static const struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
875 .build_specific = patch_wolfson_wm9713_specific, 884 .build_specific = patch_wolfson_wm9713_specific,
876 .build_3d = patch_wolfson_wm9713_3d, 885 .build_3d = patch_wolfson_wm9713_3d,
877#ifdef CONFIG_PM 886#ifdef CONFIG_PM
@@ -976,7 +985,7 @@ static int patch_sigmatel_stac97xx_specific(struct snd_ac97 * ac97)
976 return 0; 985 return 0;
977} 986}
978 987
979static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = { 988static const struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
980 .build_3d = patch_sigmatel_stac9700_3d, 989 .build_3d = patch_sigmatel_stac9700_3d,
981 .build_specific = patch_sigmatel_stac97xx_specific 990 .build_specific = patch_sigmatel_stac97xx_specific
982}; 991};
@@ -1023,7 +1032,7 @@ static int patch_sigmatel_stac9708_specific(struct snd_ac97 *ac97)
1023 return patch_sigmatel_stac97xx_specific(ac97); 1032 return patch_sigmatel_stac97xx_specific(ac97);
1024} 1033}
1025 1034
1026static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = { 1035static const struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
1027 .build_3d = patch_sigmatel_stac9708_3d, 1036 .build_3d = patch_sigmatel_stac9708_3d,
1028 .build_specific = patch_sigmatel_stac9708_specific 1037 .build_specific = patch_sigmatel_stac9708_specific
1029}; 1038};
@@ -1252,7 +1261,7 @@ static int patch_sigmatel_stac9758_specific(struct snd_ac97 *ac97)
1252 return 0; 1261 return 0;
1253} 1262}
1254 1263
1255static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = { 1264static const struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
1256 .build_3d = patch_sigmatel_stac9700_3d, 1265 .build_3d = patch_sigmatel_stac9700_3d,
1257 .build_specific = patch_sigmatel_stac9758_specific 1266 .build_specific = patch_sigmatel_stac9758_specific
1258}; 1267};
@@ -1327,7 +1336,7 @@ static int patch_cirrus_build_spdif(struct snd_ac97 * ac97)
1327 return 0; 1336 return 0;
1328} 1337}
1329 1338
1330static struct snd_ac97_build_ops patch_cirrus_ops = { 1339static const struct snd_ac97_build_ops patch_cirrus_ops = {
1331 .build_spdif = patch_cirrus_build_spdif 1340 .build_spdif = patch_cirrus_build_spdif
1332}; 1341};
1333 1342
@@ -1384,7 +1393,7 @@ static int patch_conexant_build_spdif(struct snd_ac97 * ac97)
1384 return 0; 1393 return 0;
1385} 1394}
1386 1395
1387static struct snd_ac97_build_ops patch_conexant_ops = { 1396static const struct snd_ac97_build_ops patch_conexant_ops = {
1388 .build_spdif = patch_conexant_build_spdif 1397 .build_spdif = patch_conexant_build_spdif
1389}; 1398};
1390 1399
@@ -1560,7 +1569,7 @@ static void patch_ad1881_chained(struct snd_ac97 * ac97, int unchained_idx, int
1560 } 1569 }
1561} 1570}
1562 1571
1563static struct snd_ac97_build_ops patch_ad1881_build_ops = { 1572static const struct snd_ac97_build_ops patch_ad1881_build_ops = {
1564#ifdef CONFIG_PM 1573#ifdef CONFIG_PM
1565 .resume = ad18xx_resume 1574 .resume = ad18xx_resume
1566#endif 1575#endif
@@ -1647,7 +1656,7 @@ static int patch_ad1885_specific(struct snd_ac97 * ac97)
1647 return 0; 1656 return 0;
1648} 1657}
1649 1658
1650static struct snd_ac97_build_ops patch_ad1885_build_ops = { 1659static const struct snd_ac97_build_ops patch_ad1885_build_ops = {
1651 .build_specific = &patch_ad1885_specific, 1660 .build_specific = &patch_ad1885_specific,
1652#ifdef CONFIG_PM 1661#ifdef CONFIG_PM
1653 .resume = ad18xx_resume 1662 .resume = ad18xx_resume
@@ -1674,7 +1683,7 @@ static int patch_ad1886_specific(struct snd_ac97 * ac97)
1674 return 0; 1683 return 0;
1675} 1684}
1676 1685
1677static struct snd_ac97_build_ops patch_ad1886_build_ops = { 1686static const struct snd_ac97_build_ops patch_ad1886_build_ops = {
1678 .build_specific = &patch_ad1886_specific, 1687 .build_specific = &patch_ad1886_specific,
1679#ifdef CONFIG_PM 1688#ifdef CONFIG_PM
1680 .resume = ad18xx_resume 1689 .resume = ad18xx_resume
@@ -1881,7 +1890,7 @@ static int patch_ad1981a_specific(struct snd_ac97 * ac97)
1881 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense)); 1890 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
1882} 1891}
1883 1892
1884static struct snd_ac97_build_ops patch_ad1981a_build_ops = { 1893static const struct snd_ac97_build_ops patch_ad1981a_build_ops = {
1885 .build_post_spdif = patch_ad198x_post_spdif, 1894 .build_post_spdif = patch_ad198x_post_spdif,
1886 .build_specific = patch_ad1981a_specific, 1895 .build_specific = patch_ad1981a_specific,
1887#ifdef CONFIG_PM 1896#ifdef CONFIG_PM
@@ -1936,7 +1945,7 @@ static int patch_ad1981b_specific(struct snd_ac97 *ac97)
1936 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense)); 1945 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
1937} 1946}
1938 1947
1939static struct snd_ac97_build_ops patch_ad1981b_build_ops = { 1948static const struct snd_ac97_build_ops patch_ad1981b_build_ops = {
1940 .build_post_spdif = patch_ad198x_post_spdif, 1949 .build_post_spdif = patch_ad198x_post_spdif,
1941 .build_specific = patch_ad1981b_specific, 1950 .build_specific = patch_ad1981b_specific,
1942#ifdef CONFIG_PM 1951#ifdef CONFIG_PM
@@ -2075,7 +2084,7 @@ static int patch_ad1888_specific(struct snd_ac97 *ac97)
2075 return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls)); 2084 return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls));
2076} 2085}
2077 2086
2078static struct snd_ac97_build_ops patch_ad1888_build_ops = { 2087static const struct snd_ac97_build_ops patch_ad1888_build_ops = {
2079 .build_post_spdif = patch_ad198x_post_spdif, 2088 .build_post_spdif = patch_ad198x_post_spdif,
2080 .build_specific = patch_ad1888_specific, 2089 .build_specific = patch_ad1888_specific,
2081#ifdef CONFIG_PM 2090#ifdef CONFIG_PM
@@ -2124,7 +2133,7 @@ static int patch_ad1980_specific(struct snd_ac97 *ac97)
2124 return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1); 2133 return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
2125} 2134}
2126 2135
2127static struct snd_ac97_build_ops patch_ad1980_build_ops = { 2136static const struct snd_ac97_build_ops patch_ad1980_build_ops = {
2128 .build_post_spdif = patch_ad198x_post_spdif, 2137 .build_post_spdif = patch_ad198x_post_spdif,
2129 .build_specific = patch_ad1980_specific, 2138 .build_specific = patch_ad1980_specific,
2130#ifdef CONFIG_PM 2139#ifdef CONFIG_PM
@@ -2239,7 +2248,7 @@ static int patch_ad1985_specific(struct snd_ac97 *ac97)
2239 ARRAY_SIZE(snd_ac97_ad1985_controls)); 2248 ARRAY_SIZE(snd_ac97_ad1985_controls));
2240} 2249}
2241 2250
2242static struct snd_ac97_build_ops patch_ad1985_build_ops = { 2251static const struct snd_ac97_build_ops patch_ad1985_build_ops = {
2243 .build_post_spdif = patch_ad198x_post_spdif, 2252 .build_post_spdif = patch_ad198x_post_spdif,
2244 .build_specific = patch_ad1985_specific, 2253 .build_specific = patch_ad1985_specific,
2245#ifdef CONFIG_PM 2254#ifdef CONFIG_PM
@@ -2531,7 +2540,7 @@ static int patch_ad1986_specific(struct snd_ac97 *ac97)
2531 ARRAY_SIZE(snd_ac97_ad1985_controls)); 2540 ARRAY_SIZE(snd_ac97_ad1985_controls));
2532} 2541}
2533 2542
2534static struct snd_ac97_build_ops patch_ad1986_build_ops = { 2543static const struct snd_ac97_build_ops patch_ad1986_build_ops = {
2535 .build_post_spdif = patch_ad198x_post_spdif, 2544 .build_post_spdif = patch_ad198x_post_spdif,
2536 .build_specific = patch_ad1986_specific, 2545 .build_specific = patch_ad1986_specific,
2537#ifdef CONFIG_PM 2546#ifdef CONFIG_PM
@@ -2636,7 +2645,7 @@ static int patch_alc650_specific(struct snd_ac97 * ac97)
2636 return 0; 2645 return 0;
2637} 2646}
2638 2647
2639static struct snd_ac97_build_ops patch_alc650_ops = { 2648static const struct snd_ac97_build_ops patch_alc650_ops = {
2640 .build_specific = patch_alc650_specific, 2649 .build_specific = patch_alc650_specific,
2641 .update_jacks = alc650_update_jacks 2650 .update_jacks = alc650_update_jacks
2642}; 2651};
@@ -2788,7 +2797,7 @@ static int patch_alc655_specific(struct snd_ac97 * ac97)
2788 return 0; 2797 return 0;
2789} 2798}
2790 2799
2791static struct snd_ac97_build_ops patch_alc655_ops = { 2800static const struct snd_ac97_build_ops patch_alc655_ops = {
2792 .build_specific = patch_alc655_specific, 2801 .build_specific = patch_alc655_specific,
2793 .update_jacks = alc655_update_jacks 2802 .update_jacks = alc655_update_jacks
2794}; 2803};
@@ -2900,7 +2909,7 @@ static int patch_alc850_specific(struct snd_ac97 *ac97)
2900 return 0; 2909 return 0;
2901} 2910}
2902 2911
2903static struct snd_ac97_build_ops patch_alc850_ops = { 2912static const struct snd_ac97_build_ops patch_alc850_ops = {
2904 .build_specific = patch_alc850_specific, 2913 .build_specific = patch_alc850_specific,
2905 .update_jacks = alc850_update_jacks 2914 .update_jacks = alc850_update_jacks
2906}; 2915};
@@ -2940,6 +2949,49 @@ static int patch_alc850(struct snd_ac97 *ac97)
2940 return 0; 2949 return 0;
2941} 2950}
2942 2951
2952static int patch_aztech_azf3328_specific(struct snd_ac97 *ac97)
2953{
2954 struct snd_kcontrol *kctl_3d_center =
2955 snd_ac97_find_mixer_ctl(ac97, "3D Control - Center");
2956 struct snd_kcontrol *kctl_3d_depth =
2957 snd_ac97_find_mixer_ctl(ac97, "3D Control - Depth");
2958
2959 /*
2960 * 3D register is different from AC97 standard layout
2961 * (also do some renaming, to resemble Windows driver naming)
2962 */
2963 if (kctl_3d_center) {
2964 kctl_3d_center->private_value =
2965 AC97_SINGLE_VALUE(AC97_3D_CONTROL, 1, 0x07, 0);
2966 snd_ac97_rename_vol_ctl(ac97,
2967 "3D Control - Center", "3D Control - Width"
2968 );
2969 }
2970 if (kctl_3d_depth)
2971 kctl_3d_depth->private_value =
2972 AC97_SINGLE_VALUE(AC97_3D_CONTROL, 8, 0x03, 0);
2973
2974 /* Aztech Windows driver calls the
2975 equivalent control "Modem Playback", thus rename it: */
2976 snd_ac97_rename_vol_ctl(ac97,
2977 "Master Mono Playback", "Modem Playback"
2978 );
2979 snd_ac97_rename_vol_ctl(ac97,
2980 "Headphone Playback", "FM Synth Playback"
2981 );
2982
2983 return 0;
2984}
2985
2986static const struct snd_ac97_build_ops patch_aztech_azf3328_ops = {
2987 .build_specific = patch_aztech_azf3328_specific
2988};
2989
2990static int patch_aztech_azf3328(struct snd_ac97 *ac97)
2991{
2992 ac97->build_ops = &patch_aztech_azf3328_ops;
2993 return 0;
2994}
2943 2995
2944/* 2996/*
2945 * C-Media CM97xx codecs 2997 * C-Media CM97xx codecs
@@ -2962,7 +3014,7 @@ static int patch_cm9738_specific(struct snd_ac97 * ac97)
2962 return patch_build_controls(ac97, snd_ac97_cm9738_controls, ARRAY_SIZE(snd_ac97_cm9738_controls)); 3014 return patch_build_controls(ac97, snd_ac97_cm9738_controls, ARRAY_SIZE(snd_ac97_cm9738_controls));
2963} 3015}
2964 3016
2965static struct snd_ac97_build_ops patch_cm9738_ops = { 3017static const struct snd_ac97_build_ops patch_cm9738_ops = {
2966 .build_specific = patch_cm9738_specific, 3018 .build_specific = patch_cm9738_specific,
2967 .update_jacks = cm9738_update_jacks 3019 .update_jacks = cm9738_update_jacks
2968}; 3020};
@@ -3053,7 +3105,7 @@ static int patch_cm9739_post_spdif(struct snd_ac97 * ac97)
3053 return patch_build_controls(ac97, snd_ac97_cm9739_controls_spdif, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif)); 3105 return patch_build_controls(ac97, snd_ac97_cm9739_controls_spdif, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif));
3054} 3106}
3055 3107
3056static struct snd_ac97_build_ops patch_cm9739_ops = { 3108static const struct snd_ac97_build_ops patch_cm9739_ops = {
3057 .build_specific = patch_cm9739_specific, 3109 .build_specific = patch_cm9739_specific,
3058 .build_post_spdif = patch_cm9739_post_spdif, 3110 .build_post_spdif = patch_cm9739_post_spdif,
3059 .update_jacks = cm9739_update_jacks 3111 .update_jacks = cm9739_update_jacks
@@ -3227,7 +3279,7 @@ static int patch_cm9761_specific(struct snd_ac97 * ac97)
3227 return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls)); 3279 return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls));
3228} 3280}
3229 3281
3230static struct snd_ac97_build_ops patch_cm9761_ops = { 3282static const struct snd_ac97_build_ops patch_cm9761_ops = {
3231 .build_specific = patch_cm9761_specific, 3283 .build_specific = patch_cm9761_specific,
3232 .build_post_spdif = patch_cm9761_post_spdif, 3284 .build_post_spdif = patch_cm9761_post_spdif,
3233 .update_jacks = cm9761_update_jacks 3285 .update_jacks = cm9761_update_jacks
@@ -3323,7 +3375,7 @@ static int patch_cm9780_specific(struct snd_ac97 *ac97)
3323 return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls)); 3375 return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls));
3324} 3376}
3325 3377
3326static struct snd_ac97_build_ops patch_cm9780_ops = { 3378static const struct snd_ac97_build_ops patch_cm9780_ops = {
3327 .build_specific = patch_cm9780_specific, 3379 .build_specific = patch_cm9780_specific,
3328 .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */ 3380 .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */
3329}; 3381};
@@ -3443,7 +3495,7 @@ static int patch_vt1616_specific(struct snd_ac97 * ac97)
3443 return 0; 3495 return 0;
3444} 3496}
3445 3497
3446static struct snd_ac97_build_ops patch_vt1616_ops = { 3498static const struct snd_ac97_build_ops patch_vt1616_ops = {
3447 .build_specific = patch_vt1616_specific 3499 .build_specific = patch_vt1616_specific
3448}; 3500};
3449 3501
@@ -3797,7 +3849,7 @@ static int patch_it2646_specific(struct snd_ac97 * ac97)
3797 return 0; 3849 return 0;
3798} 3850}
3799 3851
3800static struct snd_ac97_build_ops patch_it2646_ops = { 3852static const struct snd_ac97_build_ops patch_it2646_ops = {
3801 .build_specific = patch_it2646_specific, 3853 .build_specific = patch_it2646_specific,
3802 .update_jacks = it2646_update_jacks 3854 .update_jacks = it2646_update_jacks
3803}; 3855};
@@ -3831,7 +3883,7 @@ static int patch_si3036_specific(struct snd_ac97 * ac97)
3831 return 0; 3883 return 0;
3832} 3884}
3833 3885
3834static struct snd_ac97_build_ops patch_si3036_ops = { 3886static const struct snd_ac97_build_ops patch_si3036_ops = {
3835 .build_specific = patch_si3036_specific, 3887 .build_specific = patch_si3036_specific,
3836}; 3888};
3837 3889
@@ -3898,7 +3950,7 @@ static int patch_ucb1400_specific(struct snd_ac97 * ac97)
3898 return 0; 3950 return 0;
3899} 3951}
3900 3952
3901static struct snd_ac97_build_ops patch_ucb1400_ops = { 3953static const struct snd_ac97_build_ops patch_ucb1400_ops = {
3902 .build_specific = patch_ucb1400_specific, 3954 .build_specific = patch_ucb1400_specific,
3903}; 3955};
3904 3956
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index 4382d0fa6b9a..d8f6fd65ebbb 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -29,7 +29,7 @@
29 * PM support 29 * PM support
30 * MIDI support 30 * MIDI support
31 * Game Port support 31 * Game Port support
32 * SG DMA support (this will need *alot* of work) 32 * SG DMA support (this will need *a lot* of work)
33 */ 33 */
34 34
35#include <linux/init.h> 35#include <linux/init.h>
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index c80b0b863c54..e3569bdd3b64 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -21,25 +21,6 @@
21 * would appreciate it if you grant us the right to use those modifications 21 * would appreciate it if you grant us the right to use those modifications
22 * for any purpose including commercial applications. 22 * for any purpose including commercial applications.
23 */ 23 */
24/* >0: print Hw params, timer vars. >1: print stream write/copy sizes */
25#define REALLY_VERBOSE_LOGGING 0
26
27#if REALLY_VERBOSE_LOGGING
28#define VPRINTK1 snd_printd
29#else
30#define VPRINTK1(...)
31#endif
32
33#if REALLY_VERBOSE_LOGGING > 1
34#define VPRINTK2 snd_printd
35#else
36#define VPRINTK2(...)
37#endif
38
39#ifndef ASI_STYLE_NAMES
40/* not sure how ALSA style name should look */
41#define ASI_STYLE_NAMES 1
42#endif
43 24
44#include "hpi_internal.h" 25#include "hpi_internal.h"
45#include "hpimsginit.h" 26#include "hpimsginit.h"
@@ -65,6 +46,39 @@ MODULE_LICENSE("GPL");
65MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); 46MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
66MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); 47MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
67 48
49#if defined CONFIG_SND_DEBUG
50/* copied from pcm_lib.c, hope later patch will make that version public
51and this copy can be removed */
52static void pcm_debug_name(struct snd_pcm_substream *substream,
53 char *name, size_t len)
54{
55 snprintf(name, len, "pcmC%dD%d%c:%d",
56 substream->pcm->card->number,
57 substream->pcm->device,
58 substream->stream ? 'c' : 'p',
59 substream->number);
60}
61#define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name))
62#else
63#define pcm_debug_name(s, n, l) do { } while (0)
64#define DEBUG_NAME(name, substream) do { } while (0)
65#endif
66
67#if defined CONFIG_SND_DEBUG_VERBOSE
68/**
69 * snd_printddd - very verbose debug printk
70 * @format: format string
71 *
72 * Works like snd_printk() for debugging purposes.
73 * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set.
74 * Must set snd module debug parameter to 3 to enable at runtime.
75 */
76#define snd_printddd(format, args...) \
77 __snd_printk(3, __FILE__, __LINE__, format, ##args)
78#else
79#define snd_printddd(format, args...) do { } while (0)
80#endif
81
68static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ 82static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
69static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 83static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
70static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 84static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
@@ -85,11 +99,11 @@ MODULE_PARM_DESC(enable_hpi_hwdep,
85 99
86/* identify driver */ 100/* identify driver */
87#ifdef KERNEL_ALSA_BUILD 101#ifdef KERNEL_ALSA_BUILD
88static char *build_info = "built using headers from kernel source"; 102static char *build_info = "Built using headers from kernel source";
89module_param(build_info, charp, S_IRUGO); 103module_param(build_info, charp, S_IRUGO);
90MODULE_PARM_DESC(build_info, "built using headers from kernel source"); 104MODULE_PARM_DESC(build_info, "built using headers from kernel source");
91#else 105#else
92static char *build_info = "built within ALSA source"; 106static char *build_info = "Built within ALSA source";
93module_param(build_info, charp, S_IRUGO); 107module_param(build_info, charp, S_IRUGO);
94MODULE_PARM_DESC(build_info, "built within ALSA source"); 108MODULE_PARM_DESC(build_info, "built within ALSA source");
95#endif 109#endif
@@ -100,17 +114,11 @@ static const int mixer_dump;
100#define DEFAULT_SAMPLERATE 44100 114#define DEFAULT_SAMPLERATE 44100
101static int adapter_fs = DEFAULT_SAMPLERATE; 115static int adapter_fs = DEFAULT_SAMPLERATE;
102 116
103static struct hpi_hsubsys *ss; /* handle to HPI audio subsystem */
104
105/* defaults */ 117/* defaults */
106#define PERIODS_MIN 2 118#define PERIODS_MIN 2
107#define PERIOD_BYTES_MIN 2304 119#define PERIOD_BYTES_MIN 2048
108#define BUFFER_BYTES_MAX (512 * 1024) 120#define BUFFER_BYTES_MAX (512 * 1024)
109 121
110/*#define TIMER_MILLISECONDS 20
111#define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000)
112*/
113
114#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7) 122#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
115 123
116struct clk_source { 124struct clk_source {
@@ -139,7 +147,7 @@ struct snd_card_asihpi {
139 u32 h_mixer; 147 u32 h_mixer;
140 struct clk_cache cc; 148 struct clk_cache cc;
141 149
142 u16 support_mmap; 150 u16 can_dma;
143 u16 support_grouping; 151 u16 support_grouping;
144 u16 support_mrx; 152 u16 support_mrx;
145 u16 update_interval_frames; 153 u16 update_interval_frames;
@@ -152,11 +160,13 @@ struct snd_card_asihpi_pcm {
152 struct timer_list timer; 160 struct timer_list timer;
153 unsigned int respawn_timer; 161 unsigned int respawn_timer;
154 unsigned int hpi_buffer_attached; 162 unsigned int hpi_buffer_attached;
155 unsigned int pcm_size; 163 unsigned int buffer_bytes;
156 unsigned int pcm_count; 164 unsigned int period_bytes;
157 unsigned int bytes_per_sec; 165 unsigned int bytes_per_sec;
158 unsigned int pcm_irq_pos; /* IRQ position */ 166 unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */
159 unsigned int pcm_buf_pos; /* position in buffer */ 167 unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */
168 unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */
169 unsigned int drained_count;
160 struct snd_pcm_substream *substream; 170 struct snd_pcm_substream *substream;
161 u32 h_stream; 171 u32 h_stream;
162 struct hpi_format format; 172 struct hpi_format format;
@@ -167,7 +177,6 @@ struct snd_card_asihpi_pcm {
167/* Functions to allow driver to give a buffer to HPI for busmastering */ 177/* Functions to allow driver to give a buffer to HPI for busmastering */
168 178
169static u16 hpi_stream_host_buffer_attach( 179static u16 hpi_stream_host_buffer_attach(
170 struct hpi_hsubsys *hS,
171 u32 h_stream, /* handle to outstream. */ 180 u32 h_stream, /* handle to outstream. */
172 u32 size_in_bytes, /* size in bytes of bus mastering buffer */ 181 u32 size_in_bytes, /* size in bytes of bus mastering buffer */
173 u32 pci_address 182 u32 pci_address
@@ -194,10 +203,7 @@ static u16 hpi_stream_host_buffer_attach(
194 return hr.error; 203 return hr.error;
195} 204}
196 205
197static u16 hpi_stream_host_buffer_detach( 206static u16 hpi_stream_host_buffer_detach(u32 h_stream)
198 struct hpi_hsubsys *hS,
199 u32 h_stream
200)
201{ 207{
202 struct hpi_message hm; 208 struct hpi_message hm;
203 struct hpi_response hr; 209 struct hpi_response hr;
@@ -218,24 +224,23 @@ static u16 hpi_stream_host_buffer_detach(
218 return hr.error; 224 return hr.error;
219} 225}
220 226
221static inline u16 hpi_stream_start(struct hpi_hsubsys *hS, u32 h_stream) 227static inline u16 hpi_stream_start(u32 h_stream)
222{ 228{
223 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) 229 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
224 return hpi_outstream_start(hS, h_stream); 230 return hpi_outstream_start(h_stream);
225 else 231 else
226 return hpi_instream_start(hS, h_stream); 232 return hpi_instream_start(h_stream);
227} 233}
228 234
229static inline u16 hpi_stream_stop(struct hpi_hsubsys *hS, u32 h_stream) 235static inline u16 hpi_stream_stop(u32 h_stream)
230{ 236{
231 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) 237 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
232 return hpi_outstream_stop(hS, h_stream); 238 return hpi_outstream_stop(h_stream);
233 else 239 else
234 return hpi_instream_stop(hS, h_stream); 240 return hpi_instream_stop(h_stream);
235} 241}
236 242
237static inline u16 hpi_stream_get_info_ex( 243static inline u16 hpi_stream_get_info_ex(
238 struct hpi_hsubsys *hS,
239 u32 h_stream, 244 u32 h_stream,
240 u16 *pw_state, 245 u16 *pw_state,
241 u32 *pbuffer_size, 246 u32 *pbuffer_size,
@@ -244,42 +249,43 @@ static inline u16 hpi_stream_get_info_ex(
244 u32 *pauxiliary_data 249 u32 *pauxiliary_data
245) 250)
246{ 251{
252 u16 e;
247 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) 253 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
248 return hpi_outstream_get_info_ex(hS, h_stream, pw_state, 254 e = hpi_outstream_get_info_ex(h_stream, pw_state,
249 pbuffer_size, pdata_in_buffer, 255 pbuffer_size, pdata_in_buffer,
250 psample_count, pauxiliary_data); 256 psample_count, pauxiliary_data);
251 else 257 else
252 return hpi_instream_get_info_ex(hS, h_stream, pw_state, 258 e = hpi_instream_get_info_ex(h_stream, pw_state,
253 pbuffer_size, pdata_in_buffer, 259 pbuffer_size, pdata_in_buffer,
254 psample_count, pauxiliary_data); 260 psample_count, pauxiliary_data);
261 return e;
255} 262}
256 263
257static inline u16 hpi_stream_group_add(struct hpi_hsubsys *hS, 264static inline u16 hpi_stream_group_add(
258 u32 h_master, 265 u32 h_master,
259 u32 h_stream) 266 u32 h_stream)
260{ 267{
261 if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM) 268 if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM)
262 return hpi_outstream_group_add(hS, h_master, h_stream); 269 return hpi_outstream_group_add(h_master, h_stream);
263 else 270 else
264 return hpi_instream_group_add(hS, h_master, h_stream); 271 return hpi_instream_group_add(h_master, h_stream);
265} 272}
266 273
267static inline u16 hpi_stream_group_reset(struct hpi_hsubsys *hS, 274static inline u16 hpi_stream_group_reset(u32 h_stream)
268 u32 h_stream)
269{ 275{
270 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) 276 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
271 return hpi_outstream_group_reset(hS, h_stream); 277 return hpi_outstream_group_reset(h_stream);
272 else 278 else
273 return hpi_instream_group_reset(hS, h_stream); 279 return hpi_instream_group_reset(h_stream);
274} 280}
275 281
276static inline u16 hpi_stream_group_get_map(struct hpi_hsubsys *hS, 282static inline u16 hpi_stream_group_get_map(
277 u32 h_stream, u32 *mo, u32 *mi) 283 u32 h_stream, u32 *mo, u32 *mi)
278{ 284{
279 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) 285 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
280 return hpi_outstream_group_get_map(hS, h_stream, mo, mi); 286 return hpi_outstream_group_get_map(h_stream, mo, mi);
281 else 287 else
282 return hpi_instream_group_get_map(hS, h_stream, mo, mi); 288 return hpi_instream_group_get_map(h_stream, mo, mi);
283} 289}
284 290
285static u16 handle_error(u16 err, int line, char *filename) 291static u16 handle_error(u16 err, int line, char *filename)
@@ -294,24 +300,27 @@ static u16 handle_error(u16 err, int line, char *filename)
294#define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__) 300#define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
295 301
296/***************************** GENERAL PCM ****************/ 302/***************************** GENERAL PCM ****************/
297#if REALLY_VERBOSE_LOGGING 303
298static void print_hwparams(struct snd_pcm_hw_params *p) 304static void print_hwparams(struct snd_pcm_substream *substream,
299{ 305 struct snd_pcm_hw_params *p)
300 snd_printd("HWPARAMS \n"); 306{
301 snd_printd("samplerate %d \n", params_rate(p)); 307 DEBUG_NAME(substream, name);
302 snd_printd("channels %d \n", params_channels(p)); 308 snd_printd("%s HWPARAMS\n", name);
303 snd_printd("format %d \n", params_format(p)); 309 snd_printd(" samplerate %d Hz\n", params_rate(p));
304 snd_printd("subformat %d \n", params_subformat(p)); 310 snd_printd(" channels %d\n", params_channels(p));
305 snd_printd("buffer bytes %d \n", params_buffer_bytes(p)); 311 snd_printd(" format %d\n", params_format(p));
306 snd_printd("period bytes %d \n", params_period_bytes(p)); 312 snd_printd(" subformat %d\n", params_subformat(p));
307 snd_printd("access %d \n", params_access(p)); 313 snd_printd(" buffer %d B\n", params_buffer_bytes(p));
308 snd_printd("period_size %d \n", params_period_size(p)); 314 snd_printd(" period %d B\n", params_period_bytes(p));
309 snd_printd("periods %d \n", params_periods(p)); 315 snd_printd(" access %d\n", params_access(p));
310 snd_printd("buffer_size %d \n", params_buffer_size(p)); 316 snd_printd(" period_size %d\n", params_period_size(p));
317 snd_printd(" periods %d\n", params_periods(p));
318 snd_printd(" buffer_size %d\n", params_buffer_size(p));
319 snd_printd(" %d B/s\n", params_rate(p) *
320 params_channels(p) *
321 snd_pcm_format_width(params_format(p)) / 8);
322
311} 323}
312#else
313#define print_hwparams(x)
314#endif
315 324
316static snd_pcm_format_t hpi_to_alsa_formats[] = { 325static snd_pcm_format_t hpi_to_alsa_formats[] = {
317 -1, /* INVALID */ 326 -1, /* INVALID */
@@ -335,7 +344,7 @@ static snd_pcm_format_t hpi_to_alsa_formats[] = {
335 */ 344 */
336 -1 345 -1
337#else 346#else
338 /* SNDRV_PCM_FORMAT_S24_3LE */ /* { HPI_FORMAT_PCM24_SIGNED 15 */ 347 /* SNDRV_PCM_FORMAT_S24_3LE */ /* HPI_FORMAT_PCM24_SIGNED 15 */
339#endif 348#endif
340}; 349};
341 350
@@ -378,21 +387,21 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
378 } else { 387 } else {
379 /* on cards without SRC, 388 /* on cards without SRC,
380 valid rates are determined by sampleclock */ 389 valid rates are determined by sampleclock */
381 err = hpi_mixer_get_control(ss, asihpi->h_mixer, 390 err = hpi_mixer_get_control(asihpi->h_mixer,
382 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, 391 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
383 HPI_CONTROL_SAMPLECLOCK, &h_control); 392 HPI_CONTROL_SAMPLECLOCK, &h_control);
384 if (err) { 393 if (err) {
385 snd_printk(KERN_ERR 394 snd_printk(KERN_ERR
386 "no local sampleclock, err %d\n", err); 395 "No local sampleclock, err %d\n", err);
387 } 396 }
388 397
389 for (idx = 0; idx < 100; idx++) { 398 for (idx = -1; idx < 100; idx++) {
390 if (hpi_sample_clock_query_local_rate(ss, 399 if (idx == -1) {
391 h_control, idx, &sample_rate)) { 400 if (hpi_sample_clock_get_sample_rate(h_control,
392 if (!idx) 401 &sample_rate))
393 snd_printk(KERN_ERR 402 continue;
394 "local rate query failed\n"); 403 } else if (hpi_sample_clock_query_local_rate(h_control,
395 404 idx, &sample_rate)) {
396 break; 405 break;
397 } 406 }
398 407
@@ -445,8 +454,6 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
445 } 454 }
446 } 455 }
447 456
448 /* printk(KERN_INFO "Supported rates %X %d %d\n",
449 rates, rate_min, rate_max); */
450 pcmhw->rates = rates; 457 pcmhw->rates = rates;
451 pcmhw->rate_min = rate_min; 458 pcmhw->rate_min = rate_min;
452 pcmhw->rate_max = rate_max; 459 pcmhw->rate_max = rate_max;
@@ -463,7 +470,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
463 int width; 470 int width;
464 unsigned int bytes_per_sec; 471 unsigned int bytes_per_sec;
465 472
466 print_hwparams(params); 473 print_hwparams(substream, params);
467 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); 474 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
468 if (err < 0) 475 if (err < 0)
469 return err; 476 return err;
@@ -471,45 +478,39 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
471 if (err) 478 if (err)
472 return err; 479 return err;
473 480
474 VPRINTK1(KERN_INFO "format %d, %d chans, %d_hz\n",
475 format, params_channels(params),
476 params_rate(params));
477
478 hpi_handle_error(hpi_format_create(&dpcm->format, 481 hpi_handle_error(hpi_format_create(&dpcm->format,
479 params_channels(params), 482 params_channels(params),
480 format, params_rate(params), 0, 0)); 483 format, params_rate(params), 0, 0));
481 484
482 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 485 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
483 if (hpi_instream_reset(ss, dpcm->h_stream) != 0) 486 if (hpi_instream_reset(dpcm->h_stream) != 0)
484 return -EINVAL; 487 return -EINVAL;
485 488
486 if (hpi_instream_set_format(ss, 489 if (hpi_instream_set_format(
487 dpcm->h_stream, &dpcm->format) != 0) 490 dpcm->h_stream, &dpcm->format) != 0)
488 return -EINVAL; 491 return -EINVAL;
489 } 492 }
490 493
491 dpcm->hpi_buffer_attached = 0; 494 dpcm->hpi_buffer_attached = 0;
492 if (card->support_mmap) { 495 if (card->can_dma) {
493 496 err = hpi_stream_host_buffer_attach(dpcm->h_stream,
494 err = hpi_stream_host_buffer_attach(ss, dpcm->h_stream,
495 params_buffer_bytes(params), runtime->dma_addr); 497 params_buffer_bytes(params), runtime->dma_addr);
496 if (err == 0) { 498 if (err == 0) {
497 snd_printd(KERN_INFO 499 snd_printdd(
498 "stream_host_buffer_attach succeeded %u %lu\n", 500 "stream_host_buffer_attach succeeded %u %lu\n",
499 params_buffer_bytes(params), 501 params_buffer_bytes(params),
500 (unsigned long)runtime->dma_addr); 502 (unsigned long)runtime->dma_addr);
501 } else { 503 } else {
502 snd_printd(KERN_INFO 504 snd_printd("stream_host_buffer_attach error %d\n",
503 "stream_host_buffer_attach error %d\n",
504 err); 505 err);
505 return -ENOMEM; 506 return -ENOMEM;
506 } 507 }
507 508
508 err = hpi_stream_get_info_ex(ss, dpcm->h_stream, NULL, 509 err = hpi_stream_get_info_ex(dpcm->h_stream, NULL,
509 &dpcm->hpi_buffer_attached, 510 &dpcm->hpi_buffer_attached,
510 NULL, NULL, NULL); 511 NULL, NULL, NULL);
511 512
512 snd_printd(KERN_INFO "stream_host_buffer_attach status 0x%x\n", 513 snd_printdd("stream_host_buffer_attach status 0x%x\n",
513 dpcm->hpi_buffer_attached); 514 dpcm->hpi_buffer_attached);
514 } 515 }
515 bytes_per_sec = params_rate(params) * params_channels(params); 516 bytes_per_sec = params_rate(params) * params_channels(params);
@@ -520,16 +521,30 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
520 return -EINVAL; 521 return -EINVAL;
521 522
522 dpcm->bytes_per_sec = bytes_per_sec; 523 dpcm->bytes_per_sec = bytes_per_sec;
523 dpcm->pcm_size = params_buffer_bytes(params); 524 dpcm->buffer_bytes = params_buffer_bytes(params);
524 dpcm->pcm_count = params_period_bytes(params); 525 dpcm->period_bytes = params_period_bytes(params);
525 snd_printd(KERN_INFO "pcm_size=%d, pcm_count=%d, bps=%d\n",
526 dpcm->pcm_size, dpcm->pcm_count, bytes_per_sec);
527 526
528 dpcm->pcm_irq_pos = 0;
529 dpcm->pcm_buf_pos = 0;
530 return 0; 527 return 0;
531} 528}
532 529
530static int
531snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
532{
533 struct snd_pcm_runtime *runtime = substream->runtime;
534 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
535 if (dpcm->hpi_buffer_attached)
536 hpi_stream_host_buffer_detach(dpcm->h_stream);
537
538 snd_pcm_lib_free_pages(substream);
539 return 0;
540}
541
542static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
543{
544 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
545 kfree(dpcm);
546}
547
533static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream * 548static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
534 substream) 549 substream)
535{ 550{
@@ -537,9 +552,9 @@ static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
537 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 552 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
538 int expiry; 553 int expiry;
539 554
540 expiry = (dpcm->pcm_count * HZ / dpcm->bytes_per_sec); 555 expiry = HZ / 200;
541 /* wait longer the first time, for samples to propagate */ 556 /*? (dpcm->period_bytes * HZ / dpcm->bytes_per_sec); */
542 expiry = max(expiry, 20); 557 expiry = max(expiry, 1); /* don't let it be zero! */
543 dpcm->timer.expires = jiffies + expiry; 558 dpcm->timer.expires = jiffies + expiry;
544 dpcm->respawn_timer = 1; 559 dpcm->respawn_timer = 1;
545 add_timer(&dpcm->timer); 560 add_timer(&dpcm->timer);
@@ -561,38 +576,44 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
561 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); 576 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
562 struct snd_pcm_substream *s; 577 struct snd_pcm_substream *s;
563 u16 e; 578 u16 e;
579 DEBUG_NAME(substream, name);
580
581 snd_printdd("%s trigger\n", name);
564 582
565 snd_printd("trigger %dstream %d\n",
566 substream->stream, substream->number);
567 switch (cmd) { 583 switch (cmd) {
568 case SNDRV_PCM_TRIGGER_START: 584 case SNDRV_PCM_TRIGGER_START:
569 snd_pcm_group_for_each_entry(s, substream) { 585 snd_pcm_group_for_each_entry(s, substream) {
570 struct snd_card_asihpi_pcm *ds; 586 struct snd_pcm_runtime *runtime = s->runtime;
571 ds = s->runtime->private_data; 587 struct snd_card_asihpi_pcm *ds = runtime->private_data;
572 588
573 if (snd_pcm_substream_chip(s) != card) 589 if (snd_pcm_substream_chip(s) != card)
574 continue; 590 continue;
575 591
576 if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && 592 /* don't link Cap and Play */
577 (card->support_mmap)) { 593 if (substream->stream != s->stream)
594 continue;
595
596 ds->drained_count = 0;
597 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
578 /* How do I know how much valid data is present 598 /* How do I know how much valid data is present
579 * in buffer? Just guessing 2 periods, but if 599 * in buffer? Must be at least one period!
600 * Guessing 2 periods, but if
580 * buffer is bigger it may contain even more 601 * buffer is bigger it may contain even more
581 * data?? 602 * data??
582 */ 603 */
583 unsigned int preload = ds->pcm_count * 2; 604 unsigned int preload = ds->period_bytes * 1;
584 VPRINTK2("preload %d\n", preload); 605 snd_printddd("%d preload x%x\n", s->number, preload);
585 hpi_handle_error(hpi_outstream_write_buf( 606 hpi_handle_error(hpi_outstream_write_buf(
586 ss, ds->h_stream, 607 ds->h_stream,
587 &s->runtime->dma_area[0], 608 &runtime->dma_area[0],
588 preload, 609 preload,
589 &ds->format)); 610 &ds->format));
611 ds->pcm_buf_host_rw_ofs = preload;
590 } 612 }
591 613
592 if (card->support_grouping) { 614 if (card->support_grouping) {
593 VPRINTK1("\t_group %dstream %d\n", s->stream, 615 snd_printdd("%d group\n", s->number);
594 s->number); 616 e = hpi_stream_group_add(
595 e = hpi_stream_group_add(ss,
596 dpcm->h_stream, 617 dpcm->h_stream,
597 ds->h_stream); 618 ds->h_stream);
598 if (!e) { 619 if (!e) {
@@ -604,10 +625,12 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
604 } else 625 } else
605 break; 626 break;
606 } 627 }
607 snd_printd("start\n"); 628 snd_printdd("start\n");
608 /* start the master stream */ 629 /* start the master stream */
609 snd_card_asihpi_pcm_timer_start(substream); 630 snd_card_asihpi_pcm_timer_start(substream);
610 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream)); 631 if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ||
632 !card->can_dma)
633 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
611 break; 634 break;
612 635
613 case SNDRV_PCM_TRIGGER_STOP: 636 case SNDRV_PCM_TRIGGER_STOP:
@@ -615,88 +638,71 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
615 snd_pcm_group_for_each_entry(s, substream) { 638 snd_pcm_group_for_each_entry(s, substream) {
616 if (snd_pcm_substream_chip(s) != card) 639 if (snd_pcm_substream_chip(s) != card)
617 continue; 640 continue;
641 /* don't link Cap and Play */
642 if (substream->stream != s->stream)
643 continue;
618 644
619 /*? workaround linked streams don't 645 /*? workaround linked streams don't
620 transition to SETUP 20070706*/ 646 transition to SETUP 20070706*/
621 s->runtime->status->state = SNDRV_PCM_STATE_SETUP; 647 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
622 648
623 if (card->support_grouping) { 649 if (card->support_grouping) {
624 VPRINTK1("\t_group %dstream %d\n", s->stream, 650 snd_printdd("%d group\n", s->number);
625 s->number);
626 snd_pcm_trigger_done(s, substream); 651 snd_pcm_trigger_done(s, substream);
627 } else 652 } else
628 break; 653 break;
629 } 654 }
630 snd_printd("stop\n"); 655 snd_printdd("stop\n");
631 656
632 /* _prepare and _hwparams reset the stream */ 657 /* _prepare and _hwparams reset the stream */
633 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream)); 658 hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
634 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 659 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
635 hpi_handle_error( 660 hpi_handle_error(
636 hpi_outstream_reset(ss, dpcm->h_stream)); 661 hpi_outstream_reset(dpcm->h_stream));
637 662
638 if (card->support_grouping) 663 if (card->support_grouping)
639 hpi_handle_error(hpi_stream_group_reset(ss, 664 hpi_handle_error(hpi_stream_group_reset(dpcm->h_stream));
640 dpcm->h_stream));
641 break; 665 break;
642 666
643 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 667 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
644 snd_printd("pause release\n"); 668 snd_printdd("pause release\n");
645 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream)); 669 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
646 snd_card_asihpi_pcm_timer_start(substream); 670 snd_card_asihpi_pcm_timer_start(substream);
647 break; 671 break;
648 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 672 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
649 snd_printd("pause\n"); 673 snd_printdd("pause\n");
650 snd_card_asihpi_pcm_timer_stop(substream); 674 snd_card_asihpi_pcm_timer_stop(substream);
651 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream)); 675 hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
652 break; 676 break;
653 default: 677 default:
654 snd_printd("\tINVALID\n"); 678 snd_printd(KERN_ERR "\tINVALID\n");
655 return -EINVAL; 679 return -EINVAL;
656 } 680 }
657 681
658 return 0; 682 return 0;
659} 683}
660 684
661static int
662snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
663{
664 struct snd_pcm_runtime *runtime = substream->runtime;
665 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
666 if (dpcm->hpi_buffer_attached)
667 hpi_stream_host_buffer_detach(ss, dpcm->h_stream);
668
669 snd_pcm_lib_free_pages(substream);
670 return 0;
671}
672
673static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
674{
675 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
676 kfree(dpcm);
677}
678
679/*algorithm outline 685/*algorithm outline
680 Without linking degenerates to getting single stream pos etc 686 Without linking degenerates to getting single stream pos etc
681 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed 687 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
682*/ 688*/
683/* 689/*
684buf_pos=get_buf_pos(s); 690pcm_buf_dma_ofs=get_buf_pos(s);
685for_each_linked_stream(s) { 691for_each_linked_stream(s) {
686 buf_pos=get_buf_pos(s); 692 pcm_buf_dma_ofs=get_buf_pos(s);
687 min_buf_pos = modulo_min(min_buf_pos, buf_pos, pcm_size) 693 min_buf_pos = modulo_min(min_buf_pos, pcm_buf_dma_ofs, buffer_bytes)
688 new_data = min(new_data, calc_new_data(buf_pos,irq_pos) 694 new_data = min(new_data, calc_new_data(pcm_buf_dma_ofs,irq_pos)
689} 695}
690timer.expires = jiffies + predict_next_period_ready(min_buf_pos); 696timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
691for_each_linked_stream(s) { 697for_each_linked_stream(s) {
692 s->buf_pos = min_buf_pos; 698 s->pcm_buf_dma_ofs = min_buf_pos;
693 if (new_data > pcm_count) { 699 if (new_data > period_bytes) {
694 if (mmap) { 700 if (mmap) {
695 irq_pos = (irq_pos + pcm_count) % pcm_size; 701 irq_pos = (irq_pos + period_bytes) % buffer_bytes;
696 if (playback) { 702 if (playback) {
697 write(pcm_count); 703 write(period_bytes);
698 } else { 704 } else {
699 read(pcm_count); 705 read(period_bytes);
700 } 706 }
701 } 707 }
702 snd_pcm_period_elapsed(s); 708 snd_pcm_period_elapsed(s);
@@ -724,105 +730,180 @@ static inline unsigned int modulo_min(unsigned int a, unsigned int b,
724static void snd_card_asihpi_timer_function(unsigned long data) 730static void snd_card_asihpi_timer_function(unsigned long data)
725{ 731{
726 struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data; 732 struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data;
727 struct snd_card_asihpi *card = snd_pcm_substream_chip(dpcm->substream); 733 struct snd_pcm_substream *substream = dpcm->substream;
734 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
728 struct snd_pcm_runtime *runtime; 735 struct snd_pcm_runtime *runtime;
729 struct snd_pcm_substream *s; 736 struct snd_pcm_substream *s;
730 unsigned int newdata = 0; 737 unsigned int newdata = 0;
731 unsigned int buf_pos, min_buf_pos = 0; 738 unsigned int pcm_buf_dma_ofs, min_buf_pos = 0;
732 unsigned int remdata, xfercount, next_jiffies; 739 unsigned int remdata, xfercount, next_jiffies;
733 int first = 1; 740 int first = 1;
741 int loops = 0;
734 u16 state; 742 u16 state;
735 u32 buffer_size, data_avail, samples_played, aux; 743 u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
744 DEBUG_NAME(substream, name);
745
746 snd_printdd("%s snd_card_asihpi_timer_function\n", name);
736 747
737 /* find minimum newdata and buffer pos in group */ 748 /* find minimum newdata and buffer pos in group */
738 snd_pcm_group_for_each_entry(s, dpcm->substream) { 749 snd_pcm_group_for_each_entry(s, substream) {
739 struct snd_card_asihpi_pcm *ds = s->runtime->private_data; 750 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
740 runtime = s->runtime; 751 runtime = s->runtime;
741 752
742 if (snd_pcm_substream_chip(s) != card) 753 if (snd_pcm_substream_chip(s) != card)
743 continue; 754 continue;
744 755
745 hpi_handle_error(hpi_stream_get_info_ex(ss, 756 /* don't link Cap and Play */
757 if (substream->stream != s->stream)
758 continue;
759
760 hpi_handle_error(hpi_stream_get_info_ex(
746 ds->h_stream, &state, 761 ds->h_stream, &state,
747 &buffer_size, &data_avail, 762 &buffer_size, &bytes_avail,
748 &samples_played, &aux)); 763 &samples_played, &on_card_bytes));
749 764
750 /* number of bytes in on-card buffer */ 765 /* number of bytes in on-card buffer */
751 runtime->delay = aux; 766 runtime->delay = on_card_bytes;
752 767
753 if (state == HPI_STATE_DRAINED) { 768 if (!card->can_dma)
754 snd_printd(KERN_WARNING "outstream %d drained\n", 769 on_card_bytes = bytes_avail;
755 s->number);
756 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
757 return;
758 }
759 770
760 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { 771 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
761 buf_pos = frames_to_bytes(runtime, samples_played); 772 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
762 } else { 773 if (state == HPI_STATE_STOPPED) {
763 buf_pos = data_avail + ds->pcm_irq_pos; 774 if ((bytes_avail == 0) &&
764 } 775 (on_card_bytes < ds->pcm_buf_host_rw_ofs)) {
776 hpi_handle_error(hpi_stream_start(ds->h_stream));
777 snd_printdd("P%d start\n", s->number);
778 ds->drained_count = 0;
779 }
780 } else if (state == HPI_STATE_DRAINED) {
781 snd_printd(KERN_WARNING "P%d drained\n",
782 s->number);
783 ds->drained_count++;
784 if (ds->drained_count > 2) {
785 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
786 continue;
787 }
788 } else {
789 ds->drained_count = 0;
790 }
791 } else
792 pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
765 793
766 if (first) { 794 if (first) {
767 /* can't statically init min when wrap is involved */ 795 /* can't statically init min when wrap is involved */
768 min_buf_pos = buf_pos; 796 min_buf_pos = pcm_buf_dma_ofs;
769 newdata = (buf_pos - ds->pcm_irq_pos) % ds->pcm_size; 797 newdata = (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes;
770 first = 0; 798 first = 0;
771 } else { 799 } else {
772 min_buf_pos = 800 min_buf_pos =
773 modulo_min(min_buf_pos, buf_pos, UINT_MAX+1L); 801 modulo_min(min_buf_pos, pcm_buf_dma_ofs, UINT_MAX+1L);
774 newdata = min( 802 newdata = min(
775 (buf_pos - ds->pcm_irq_pos) % ds->pcm_size, 803 (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes,
776 newdata); 804 newdata);
777 } 805 }
778 806
779 VPRINTK1("PB timer hw_ptr x%04lX, appl_ptr x%04lX\n", 807 snd_printdd("hw_ptr 0x%04lX, appl_ptr 0x%04lX\n",
780 (unsigned long)frames_to_bytes(runtime, 808 (unsigned long)frames_to_bytes(runtime,
781 runtime->status->hw_ptr), 809 runtime->status->hw_ptr),
782 (unsigned long)frames_to_bytes(runtime, 810 (unsigned long)frames_to_bytes(runtime,
783 runtime->control->appl_ptr)); 811 runtime->control->appl_ptr));
784 VPRINTK1("%d S=%d, irq=%04X, pos=x%04X, left=x%04X," 812
785 " aux=x%04X space=x%04X\n", s->number, 813 snd_printdd("%d S=%d, "
786 state, ds->pcm_irq_pos, buf_pos, (int)data_avail, 814 "rw=0x%04X, dma=0x%04X, left=0x%04X, "
787 (int)aux, buffer_size-data_avail); 815 "aux=0x%04X space=0x%04X\n",
816 s->number, state,
817 ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs,
818 (int)bytes_avail,
819 (int)on_card_bytes, buffer_size-bytes_avail);
820 loops++;
788 } 821 }
822 pcm_buf_dma_ofs = min_buf_pos;
823
824 remdata = newdata % dpcm->period_bytes;
825 xfercount = newdata - remdata; /* a multiple of period_bytes */
826 /* come back when on_card_bytes has decreased enough to allow
827 write to happen, or when data has been consumed to make another
828 period
829 */
830 if (xfercount && (on_card_bytes > dpcm->period_bytes))
831 next_jiffies = ((on_card_bytes - dpcm->period_bytes) * HZ / dpcm->bytes_per_sec);
832 else
833 next_jiffies = ((dpcm->period_bytes - remdata) * HZ / dpcm->bytes_per_sec);
789 834
790 remdata = newdata % dpcm->pcm_count; 835 next_jiffies = max(next_jiffies, 1U);
791 xfercount = newdata - remdata; /* a multiple of pcm_count */
792 next_jiffies = ((dpcm->pcm_count-remdata) * HZ / dpcm->bytes_per_sec)+1;
793 next_jiffies = max(next_jiffies, 2U * HZ / 1000U);
794 dpcm->timer.expires = jiffies + next_jiffies; 836 dpcm->timer.expires = jiffies + next_jiffies;
795 VPRINTK1("jif %d buf pos x%04X newdata x%04X xc x%04X\n", 837 snd_printdd("jif %d buf pos 0x%04X newdata 0x%04X xfer 0x%04X\n",
796 next_jiffies, min_buf_pos, newdata, xfercount); 838 next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
797 839
798 snd_pcm_group_for_each_entry(s, dpcm->substream) { 840 snd_pcm_group_for_each_entry(s, substream) {
799 struct snd_card_asihpi_pcm *ds = s->runtime->private_data; 841 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
800 ds->pcm_buf_pos = min_buf_pos;
801 842
802 if (xfercount) { 843 /* don't link Cap and Play */
803 if (card->support_mmap) { 844 if (substream->stream != s->stream)
804 ds->pcm_irq_pos = ds->pcm_irq_pos + xfercount; 845 continue;
805 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { 846
806 VPRINTK2("write OS%d x%04x\n", 847 ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
848
849 if (xfercount &&
850 /* Limit use of on card fifo for playback */
851 ((on_card_bytes <= ds->period_bytes) ||
852 (s->stream == SNDRV_PCM_STREAM_CAPTURE)))
853
854 {
855
856 unsigned int buf_ofs = ds->pcm_buf_host_rw_ofs % ds->buffer_bytes;
857 unsigned int xfer1, xfer2;
858 char *pd = &s->runtime->dma_area[buf_ofs];
859
860 if (card->can_dma) { /* buffer wrap is handled at lower level */
861 xfer1 = xfercount;
862 xfer2 = 0;
863 } else {
864 xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs);
865 xfer2 = xfercount - xfer1;
866 }
867
868 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
869 snd_printddd("P%d write1 0x%04X 0x%04X\n",
870 s->number, xfer1, buf_ofs);
871 hpi_handle_error(
872 hpi_outstream_write_buf(
873 ds->h_stream, pd, xfer1,
874 &ds->format));
875
876 if (xfer2) {
877 pd = s->runtime->dma_area;
878
879 snd_printddd("P%d write2 0x%04X 0x%04X\n",
807 s->number, 880 s->number,
808 ds->pcm_count); 881 xfercount - xfer1, buf_ofs);
809 hpi_handle_error( 882 hpi_handle_error(
810 hpi_outstream_write_buf( 883 hpi_outstream_write_buf(
811 ss, ds->h_stream, 884 ds->h_stream, pd,
812 &s->runtime-> 885 xfercount - xfer1,
813 dma_area[0],
814 xfercount,
815 &ds->format)); 886 &ds->format));
816 } else { 887 }
817 VPRINTK2("read IS%d x%04x\n", 888 } else {
818 s->number, 889 snd_printddd("C%d read1 0x%04x\n",
819 dpcm->pcm_count); 890 s->number, xfer1);
891 hpi_handle_error(
892 hpi_instream_read_buf(
893 ds->h_stream,
894 pd, xfer1));
895 if (xfer2) {
896 pd = s->runtime->dma_area;
897 snd_printddd("C%d read2 0x%04x\n",
898 s->number, xfer2);
820 hpi_handle_error( 899 hpi_handle_error(
821 hpi_instream_read_buf( 900 hpi_instream_read_buf(
822 ss, ds->h_stream, 901 ds->h_stream,
823 NULL, xfercount)); 902 pd, xfer2));
824 } 903 }
825 } /* else R/W will be handled by read/write callbacks */ 904 }
905 ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount;
906 ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs;
826 snd_pcm_period_elapsed(s); 907 snd_pcm_period_elapsed(s);
827 } 908 }
828 } 909 }
@@ -835,7 +916,7 @@ static void snd_card_asihpi_timer_function(unsigned long data)
835static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, 916static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
836 unsigned int cmd, void *arg) 917 unsigned int cmd, void *arg)
837{ 918{
838 /* snd_printd(KERN_INFO "Playback ioctl %d\n", cmd); */ 919 snd_printddd(KERN_INFO "P%d ioctl %d\n", substream->number, cmd);
839 return snd_pcm_lib_ioctl(substream, cmd, arg); 920 return snd_pcm_lib_ioctl(substream, cmd, arg);
840} 921}
841 922
@@ -845,12 +926,12 @@ static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
845 struct snd_pcm_runtime *runtime = substream->runtime; 926 struct snd_pcm_runtime *runtime = substream->runtime;
846 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 927 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
847 928
848 snd_printd(KERN_INFO "playback prepare %d\n", substream->number); 929 snd_printdd("P%d prepare\n", substream->number);
849
850 hpi_handle_error(hpi_outstream_reset(ss, dpcm->h_stream));
851 dpcm->pcm_irq_pos = 0;
852 dpcm->pcm_buf_pos = 0;
853 930
931 hpi_handle_error(hpi_outstream_reset(dpcm->h_stream));
932 dpcm->pcm_buf_host_rw_ofs = 0;
933 dpcm->pcm_buf_dma_ofs = 0;
934 dpcm->pcm_buf_elapsed_dma_ofs = 0;
854 return 0; 935 return 0;
855} 936}
856 937
@@ -861,27 +942,8 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
861 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 942 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
862 snd_pcm_uframes_t ptr; 943 snd_pcm_uframes_t ptr;
863 944
864 u32 samples_played; 945 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
865 u16 err; 946 snd_printddd("P%d pointer = 0x%04lx\n", substream->number, (unsigned long)ptr);
866
867 if (!snd_pcm_stream_linked(substream)) {
868 /* NOTE, can use samples played for playback position here and
869 * in timer fn because it LAGS the actual read pointer, and is a
870 * better representation of actual playout position
871 */
872 err = hpi_outstream_get_info_ex(ss, dpcm->h_stream, NULL,
873 NULL, NULL,
874 &samples_played, NULL);
875 hpi_handle_error(err);
876
877 dpcm->pcm_buf_pos = frames_to_bytes(runtime, samples_played);
878 }
879 /* else must return most conservative value found in timer func
880 * by looping over all streams
881 */
882
883 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size);
884 VPRINTK2("playback_pointer=%04ld\n", (unsigned long)ptr);
885 return ptr; 947 return ptr;
886} 948}
887 949
@@ -898,12 +960,12 @@ static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
898 /* on cards without SRC, must query at valid rate, 960 /* on cards without SRC, must query at valid rate,
899 * maybe set by external sync 961 * maybe set by external sync
900 */ 962 */
901 err = hpi_mixer_get_control(ss, asihpi->h_mixer, 963 err = hpi_mixer_get_control(asihpi->h_mixer,
902 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, 964 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
903 HPI_CONTROL_SAMPLECLOCK, &h_control); 965 HPI_CONTROL_SAMPLECLOCK, &h_control);
904 966
905 if (!err) 967 if (!err)
906 err = hpi_sample_clock_get_sample_rate(ss, h_control, 968 err = hpi_sample_clock_get_sample_rate(h_control,
907 &sample_rate); 969 &sample_rate);
908 970
909 for (format = HPI_FORMAT_PCM8_UNSIGNED; 971 for (format = HPI_FORMAT_PCM8_UNSIGNED;
@@ -911,7 +973,7 @@ static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
911 err = hpi_format_create(&hpi_format, 973 err = hpi_format_create(&hpi_format,
912 2, format, sample_rate, 128000, 0); 974 2, format, sample_rate, 128000, 0);
913 if (!err) 975 if (!err)
914 err = hpi_outstream_query_format(ss, h_stream, 976 err = hpi_outstream_query_format(h_stream,
915 &hpi_format); 977 &hpi_format);
916 if (!err && (hpi_to_alsa_formats[format] != -1)) 978 if (!err && (hpi_to_alsa_formats[format] != -1))
917 pcmhw->formats |= 979 pcmhw->formats |=
@@ -942,7 +1004,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
942 return -ENOMEM; 1004 return -ENOMEM;
943 1005
944 err = 1006 err =
945 hpi_outstream_open(ss, card->adapter_index, 1007 hpi_outstream_open(card->adapter_index,
946 substream->number, &dpcm->h_stream); 1008 substream->number, &dpcm->h_stream);
947 hpi_handle_error(err); 1009 hpi_handle_error(err);
948 if (err) 1010 if (err)
@@ -954,7 +1016,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
954 1016
955 /*? also check ASI5000 samplerate source 1017 /*? also check ASI5000 samplerate source
956 If external, only support external rate. 1018 If external, only support external rate.
957 If internal and other stream playing, cant switch 1019 If internal and other stream playing, can't switch
958 */ 1020 */
959 1021
960 init_timer(&dpcm->timer); 1022 init_timer(&dpcm->timer);
@@ -977,11 +1039,9 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
977 SNDRV_PCM_INFO_DOUBLE | 1039 SNDRV_PCM_INFO_DOUBLE |
978 SNDRV_PCM_INFO_BATCH | 1040 SNDRV_PCM_INFO_BATCH |
979 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1041 SNDRV_PCM_INFO_BLOCK_TRANSFER |
980 SNDRV_PCM_INFO_PAUSE; 1042 SNDRV_PCM_INFO_PAUSE |
981 1043 SNDRV_PCM_INFO_MMAP |
982 if (card->support_mmap) 1044 SNDRV_PCM_INFO_MMAP_VALID;
983 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP |
984 SNDRV_PCM_INFO_MMAP_VALID;
985 1045
986 if (card->support_grouping) 1046 if (card->support_grouping)
987 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START; 1047 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
@@ -989,7 +1049,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
989 /* struct is copied, so can create initializer dynamically */ 1049 /* struct is copied, so can create initializer dynamically */
990 runtime->hw = snd_card_asihpi_playback; 1050 runtime->hw = snd_card_asihpi_playback;
991 1051
992 if (card->support_mmap) 1052 if (card->can_dma)
993 err = snd_pcm_hw_constraint_pow2(runtime, 0, 1053 err = snd_pcm_hw_constraint_pow2(runtime, 0,
994 SNDRV_PCM_HW_PARAM_BUFFER_BYTES); 1054 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
995 if (err < 0) 1055 if (err < 0)
@@ -997,12 +1057,13 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
997 1057
998 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 1058 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
999 card->update_interval_frames); 1059 card->update_interval_frames);
1060
1000 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 1061 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1001 card->update_interval_frames * 4, UINT_MAX); 1062 card->update_interval_frames * 2, UINT_MAX);
1002 1063
1003 snd_pcm_set_sync(substream); 1064 snd_pcm_set_sync(substream);
1004 1065
1005 snd_printd(KERN_INFO "playback open\n"); 1066 snd_printdd("playback open\n");
1006 1067
1007 return 0; 1068 return 0;
1008} 1069}
@@ -1012,67 +1073,12 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1012 struct snd_pcm_runtime *runtime = substream->runtime; 1073 struct snd_pcm_runtime *runtime = substream->runtime;
1013 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 1074 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1014 1075
1015 hpi_handle_error(hpi_outstream_close(ss, dpcm->h_stream)); 1076 hpi_handle_error(hpi_outstream_close(dpcm->h_stream));
1016 snd_printd(KERN_INFO "playback close\n"); 1077 snd_printdd("playback close\n");
1017
1018 return 0;
1019}
1020
1021static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,
1022 int channel,
1023 snd_pcm_uframes_t pos,
1024 void __user *src,
1025 snd_pcm_uframes_t count)
1026{
1027 struct snd_pcm_runtime *runtime = substream->runtime;
1028 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1029 unsigned int len;
1030
1031 len = frames_to_bytes(runtime, count);
1032
1033 if (copy_from_user(runtime->dma_area, src, len))
1034 return -EFAULT;
1035
1036 VPRINTK2(KERN_DEBUG "playback copy%d %u bytes\n",
1037 substream->number, len);
1038
1039 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1040 runtime->dma_area, len, &dpcm->format));
1041
1042 return 0;
1043}
1044
1045static int snd_card_asihpi_playback_silence(struct snd_pcm_substream *
1046 substream, int channel,
1047 snd_pcm_uframes_t pos,
1048 snd_pcm_uframes_t count)
1049{
1050 unsigned int len;
1051 struct snd_pcm_runtime *runtime = substream->runtime;
1052 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1053
1054 len = frames_to_bytes(runtime, count);
1055 snd_printd(KERN_INFO "playback silence %u bytes\n", len);
1056 1078
1057 memset(runtime->dma_area, 0, len);
1058 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1059 runtime->dma_area, len, &dpcm->format));
1060 return 0; 1079 return 0;
1061} 1080}
1062 1081
1063static struct snd_pcm_ops snd_card_asihpi_playback_ops = {
1064 .open = snd_card_asihpi_playback_open,
1065 .close = snd_card_asihpi_playback_close,
1066 .ioctl = snd_card_asihpi_playback_ioctl,
1067 .hw_params = snd_card_asihpi_pcm_hw_params,
1068 .hw_free = snd_card_asihpi_hw_free,
1069 .prepare = snd_card_asihpi_playback_prepare,
1070 .trigger = snd_card_asihpi_trigger,
1071 .pointer = snd_card_asihpi_playback_pointer,
1072 .copy = snd_card_asihpi_playback_copy,
1073 .silence = snd_card_asihpi_playback_silence,
1074};
1075
1076static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = { 1082static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
1077 .open = snd_card_asihpi_playback_open, 1083 .open = snd_card_asihpi_playback_open,
1078 .close = snd_card_asihpi_playback_close, 1084 .close = snd_card_asihpi_playback_close,
@@ -1091,13 +1097,13 @@ snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
1091 struct snd_pcm_runtime *runtime = substream->runtime; 1097 struct snd_pcm_runtime *runtime = substream->runtime;
1092 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 1098 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1093 1099
1094 VPRINTK2("capture pointer %d=%d\n", 1100 snd_printddd("capture pointer %d=%d\n",
1095 substream->number, dpcm->pcm_buf_pos); 1101 substream->number, dpcm->pcm_buf_dma_ofs);
1096 /* NOTE Unlike playback can't use actual dwSamplesPlayed 1102 /* NOTE Unlike playback can't use actual samples_played
1097 for the capture position, because those samples aren't yet in 1103 for the capture position, because those samples aren't yet in
1098 the local buffer available for reading. 1104 the local buffer available for reading.
1099 */ 1105 */
1100 return bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size); 1106 return bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
1101} 1107}
1102 1108
1103static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream, 1109static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream,
@@ -1111,11 +1117,12 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
1111 struct snd_pcm_runtime *runtime = substream->runtime; 1117 struct snd_pcm_runtime *runtime = substream->runtime;
1112 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 1118 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1113 1119
1114 hpi_handle_error(hpi_instream_reset(ss, dpcm->h_stream)); 1120 hpi_handle_error(hpi_instream_reset(dpcm->h_stream));
1115 dpcm->pcm_irq_pos = 0; 1121 dpcm->pcm_buf_host_rw_ofs = 0;
1116 dpcm->pcm_buf_pos = 0; 1122 dpcm->pcm_buf_dma_ofs = 0;
1123 dpcm->pcm_buf_elapsed_dma_ofs = 0;
1117 1124
1118 snd_printd("capture prepare %d\n", substream->number); 1125 snd_printdd("Capture Prepare %d\n", substream->number);
1119 return 0; 1126 return 0;
1120} 1127}
1121 1128
@@ -1133,12 +1140,12 @@ static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
1133 1140
1134 /* on cards without SRC, must query at valid rate, 1141 /* on cards without SRC, must query at valid rate,
1135 maybe set by external sync */ 1142 maybe set by external sync */
1136 err = hpi_mixer_get_control(ss, asihpi->h_mixer, 1143 err = hpi_mixer_get_control(asihpi->h_mixer,
1137 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, 1144 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
1138 HPI_CONTROL_SAMPLECLOCK, &h_control); 1145 HPI_CONTROL_SAMPLECLOCK, &h_control);
1139 1146
1140 if (!err) 1147 if (!err)
1141 err = hpi_sample_clock_get_sample_rate(ss, h_control, 1148 err = hpi_sample_clock_get_sample_rate(h_control,
1142 &sample_rate); 1149 &sample_rate);
1143 1150
1144 for (format = HPI_FORMAT_PCM8_UNSIGNED; 1151 for (format = HPI_FORMAT_PCM8_UNSIGNED;
@@ -1147,7 +1154,7 @@ static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
1147 err = hpi_format_create(&hpi_format, 2, format, 1154 err = hpi_format_create(&hpi_format, 2, format,
1148 sample_rate, 128000, 0); 1155 sample_rate, 128000, 0);
1149 if (!err) 1156 if (!err)
1150 err = hpi_instream_query_format(ss, h_stream, 1157 err = hpi_instream_query_format(h_stream,
1151 &hpi_format); 1158 &hpi_format);
1152 if (!err) 1159 if (!err)
1153 pcmhw->formats |= 1160 pcmhw->formats |=
@@ -1178,11 +1185,11 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1178 if (dpcm == NULL) 1185 if (dpcm == NULL)
1179 return -ENOMEM; 1186 return -ENOMEM;
1180 1187
1181 snd_printd("hpi_instream_open adapter %d stream %d\n", 1188 snd_printdd("capture open adapter %d stream %d\n",
1182 card->adapter_index, substream->number); 1189 card->adapter_index, substream->number);
1183 1190
1184 err = hpi_handle_error( 1191 err = hpi_handle_error(
1185 hpi_instream_open(ss, card->adapter_index, 1192 hpi_instream_open(card->adapter_index,
1186 substream->number, &dpcm->h_stream)); 1193 substream->number, &dpcm->h_stream));
1187 if (err) 1194 if (err)
1188 kfree(dpcm); 1195 kfree(dpcm);
@@ -1203,15 +1210,16 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1203 snd_card_asihpi_capture_format(card, dpcm->h_stream, 1210 snd_card_asihpi_capture_format(card, dpcm->h_stream,
1204 &snd_card_asihpi_capture); 1211 &snd_card_asihpi_capture);
1205 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture); 1212 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
1206 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED; 1213 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED |
1214 SNDRV_PCM_INFO_MMAP |
1215 SNDRV_PCM_INFO_MMAP_VALID;
1207 1216
1208 if (card->support_mmap) 1217 if (card->support_grouping)
1209 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP | 1218 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
1210 SNDRV_PCM_INFO_MMAP_VALID;
1211 1219
1212 runtime->hw = snd_card_asihpi_capture; 1220 runtime->hw = snd_card_asihpi_capture;
1213 1221
1214 if (card->support_mmap) 1222 if (card->can_dma)
1215 err = snd_pcm_hw_constraint_pow2(runtime, 0, 1223 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1216 SNDRV_PCM_HW_PARAM_BUFFER_BYTES); 1224 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1217 if (err < 0) 1225 if (err < 0)
@@ -1231,30 +1239,7 @@ static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1231{ 1239{
1232 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data; 1240 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
1233 1241
1234 hpi_handle_error(hpi_instream_close(ss, dpcm->h_stream)); 1242 hpi_handle_error(hpi_instream_close(dpcm->h_stream));
1235 return 0;
1236}
1237
1238static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream,
1239 int channel, snd_pcm_uframes_t pos,
1240 void __user *dst, snd_pcm_uframes_t count)
1241{
1242 struct snd_pcm_runtime *runtime = substream->runtime;
1243 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1244 u32 data_size;
1245
1246 data_size = frames_to_bytes(runtime, count);
1247
1248 VPRINTK2("capture copy%d %d bytes\n", substream->number, data_size);
1249 hpi_handle_error(hpi_instream_read_buf(ss, dpcm->h_stream,
1250 runtime->dma_area, data_size));
1251
1252 /* Used by capture_pointer */
1253 dpcm->pcm_irq_pos = dpcm->pcm_irq_pos + data_size;
1254
1255 if (copy_to_user(dst, runtime->dma_area, data_size))
1256 return -EFAULT;
1257
1258 return 0; 1243 return 0;
1259} 1244}
1260 1245
@@ -1269,45 +1254,26 @@ static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1269 .pointer = snd_card_asihpi_capture_pointer, 1254 .pointer = snd_card_asihpi_capture_pointer,
1270}; 1255};
1271 1256
1272static struct snd_pcm_ops snd_card_asihpi_capture_ops = {
1273 .open = snd_card_asihpi_capture_open,
1274 .close = snd_card_asihpi_capture_close,
1275 .ioctl = snd_card_asihpi_capture_ioctl,
1276 .hw_params = snd_card_asihpi_pcm_hw_params,
1277 .hw_free = snd_card_asihpi_hw_free,
1278 .prepare = snd_card_asihpi_capture_prepare,
1279 .trigger = snd_card_asihpi_trigger,
1280 .pointer = snd_card_asihpi_capture_pointer,
1281 .copy = snd_card_asihpi_capture_copy
1282};
1283
1284static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, 1257static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1285 int device, int substreams) 1258 int device, int substreams)
1286{ 1259{
1287 struct snd_pcm *pcm; 1260 struct snd_pcm *pcm;
1288 int err; 1261 int err;
1289 1262
1290 err = snd_pcm_new(asihpi->card, "asihpi PCM", device, 1263 err = snd_pcm_new(asihpi->card, "Asihpi PCM", device,
1291 asihpi->num_outstreams, asihpi->num_instreams, 1264 asihpi->num_outstreams, asihpi->num_instreams,
1292 &pcm); 1265 &pcm);
1293 if (err < 0) 1266 if (err < 0)
1294 return err; 1267 return err;
1295 /* pointer to ops struct is stored, dont change ops afterwards! */ 1268 /* pointer to ops struct is stored, dont change ops afterwards! */
1296 if (asihpi->support_mmap) {
1297 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, 1269 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1298 &snd_card_asihpi_playback_mmap_ops); 1270 &snd_card_asihpi_playback_mmap_ops);
1299 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 1271 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1300 &snd_card_asihpi_capture_mmap_ops); 1272 &snd_card_asihpi_capture_mmap_ops);
1301 } else {
1302 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1303 &snd_card_asihpi_playback_ops);
1304 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1305 &snd_card_asihpi_capture_ops);
1306 }
1307 1273
1308 pcm->private_data = asihpi; 1274 pcm->private_data = asihpi;
1309 pcm->info_flags = 0; 1275 pcm->info_flags = 0;
1310 strcpy(pcm->name, "asihpi PCM"); 1276 strcpy(pcm->name, "Asihpi PCM");
1311 1277
1312 /*? do we want to emulate MMAP for non-BBM cards? 1278 /*? do we want to emulate MMAP for non-BBM cards?
1313 Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */ 1279 Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */
@@ -1330,8 +1296,7 @@ struct hpi_control {
1330 char name[44]; /* copied to snd_ctl_elem_id.name[44]; */ 1296 char name[44]; /* copied to snd_ctl_elem_id.name[44]; */
1331}; 1297};
1332 1298
1333static char *asihpi_tuner_band_names[] = 1299static const char * const asihpi_tuner_band_names[] = {
1334{
1335 "invalid", 1300 "invalid",
1336 "AM", 1301 "AM",
1337 "FM mono", 1302 "FM mono",
@@ -1349,70 +1314,36 @@ compile_time_assert(
1349 (HPI_TUNER_BAND_LAST+1)), 1314 (HPI_TUNER_BAND_LAST+1)),
1350 assert_tuner_band_names_size); 1315 assert_tuner_band_names_size);
1351 1316
1352#if ASI_STYLE_NAMES 1317static const char * const asihpi_src_names[] = {
1353static char *asihpi_src_names[] =
1354{
1355 "no source",
1356 "outstream",
1357 "line_in",
1358 "aes_in",
1359 "tuner",
1360 "RF",
1361 "clock",
1362 "bitstr",
1363 "mic",
1364 "cobranet",
1365 "analog_in",
1366 "adapter",
1367};
1368#else
1369static char *asihpi_src_names[] =
1370{
1371 "no source", 1318 "no source",
1372 "PCM playback", 1319 "PCM",
1373 "line in", 1320 "Line",
1374 "digital in", 1321 "Digital",
1375 "tuner", 1322 "Tuner",
1376 "RF", 1323 "RF",
1377 "clock", 1324 "Clock",
1378 "bitstream", 1325 "Bitstream",
1379 "mic", 1326 "Microphone",
1380 "cobranet in", 1327 "Cobranet",
1381 "analog in", 1328 "Analog",
1382 "adapter", 1329 "Adapter",
1383}; 1330};
1384#endif
1385 1331
1386compile_time_assert( 1332compile_time_assert(
1387 (ARRAY_SIZE(asihpi_src_names) == 1333 (ARRAY_SIZE(asihpi_src_names) ==
1388 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)), 1334 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)),
1389 assert_src_names_size); 1335 assert_src_names_size);
1390 1336
1391#if ASI_STYLE_NAMES 1337static const char * const asihpi_dst_names[] = {
1392static char *asihpi_dst_names[] =
1393{
1394 "no destination", 1338 "no destination",
1395 "instream", 1339 "PCM",
1396 "line_out", 1340 "Line",
1397 "aes_out", 1341 "Digital",
1398 "RF", 1342 "RF",
1399 "speaker" , 1343 "Speaker",
1400 "cobranet", 1344 "Cobranet Out",
1401 "analog_out", 1345 "Analog"
1402}; 1346};
1403#else
1404static char *asihpi_dst_names[] =
1405{
1406 "no destination",
1407 "PCM capture",
1408 "line out",
1409 "digital out",
1410 "RF",
1411 "speaker",
1412 "cobranet out",
1413 "analog out"
1414};
1415#endif
1416 1347
1417compile_time_assert( 1348compile_time_assert(
1418 (ARRAY_SIZE(asihpi_dst_names) == 1349 (ARRAY_SIZE(asihpi_dst_names) ==
@@ -1438,30 +1369,47 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1438 struct hpi_control *hpi_ctl, 1369 struct hpi_control *hpi_ctl,
1439 char *name) 1370 char *name)
1440{ 1371{
1372 char *dir;
1441 memset(snd_control, 0, sizeof(*snd_control)); 1373 memset(snd_control, 0, sizeof(*snd_control));
1442 snd_control->name = hpi_ctl->name; 1374 snd_control->name = hpi_ctl->name;
1443 snd_control->private_value = hpi_ctl->h_control; 1375 snd_control->private_value = hpi_ctl->h_control;
1444 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1376 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1445 snd_control->index = 0; 1377 snd_control->index = 0;
1446 1378
1379 if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE)
1380 dir = ""; /* clock is neither capture nor playback */
1381 else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
1382 dir = "Capture "; /* On or towards a PCM capture destination*/
1383 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1384 (!hpi_ctl->dst_node_type))
1385 dir = "Capture "; /* On a source node that is not PCM playback */
1386 else if (hpi_ctl->src_node_type &&
1387 (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1388 (hpi_ctl->dst_node_type))
1389 dir = "Monitor Playback "; /* Between an input and an output */
1390 else
1391 dir = "Playback "; /* PCM Playback source, or output node */
1392
1447 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type) 1393 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1448 sprintf(hpi_ctl->name, "%s%d to %s%d %s", 1394 sprintf(hpi_ctl->name, "%s %d %s %d %s%s",
1449 asihpi_src_names[hpi_ctl->src_node_type], 1395 asihpi_src_names[hpi_ctl->src_node_type],
1450 hpi_ctl->src_node_index, 1396 hpi_ctl->src_node_index,
1451 asihpi_dst_names[hpi_ctl->dst_node_type], 1397 asihpi_dst_names[hpi_ctl->dst_node_type],
1452 hpi_ctl->dst_node_index, 1398 hpi_ctl->dst_node_index,
1453 name); 1399 dir, name);
1454 else if (hpi_ctl->dst_node_type) { 1400 else if (hpi_ctl->dst_node_type) {
1455 sprintf(hpi_ctl->name, "%s%d %s", 1401 sprintf(hpi_ctl->name, "%s %d %s%s",
1456 asihpi_dst_names[hpi_ctl->dst_node_type], 1402 asihpi_dst_names[hpi_ctl->dst_node_type],
1457 hpi_ctl->dst_node_index, 1403 hpi_ctl->dst_node_index,
1458 name); 1404 dir, name);
1459 } else { 1405 } else {
1460 sprintf(hpi_ctl->name, "%s%d %s", 1406 sprintf(hpi_ctl->name, "%s %d %s%s",
1461 asihpi_src_names[hpi_ctl->src_node_type], 1407 asihpi_src_names[hpi_ctl->src_node_type],
1462 hpi_ctl->src_node_index, 1408 hpi_ctl->src_node_index,
1463 name); 1409 dir, name);
1464 } 1410 }
1411 /* printk(KERN_INFO "Adding %s %d to %d ", hpi_ctl->name,
1412 hpi_ctl->wSrcNodeType, hpi_ctl->wDstNodeType); */
1465} 1413}
1466 1414
1467/*------------------------------------------------------------ 1415/*------------------------------------------------------------
@@ -1478,7 +1426,7 @@ static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1478 short max_gain_mB; 1426 short max_gain_mB;
1479 short step_gain_mB; 1427 short step_gain_mB;
1480 1428
1481 err = hpi_volume_query_range(ss, h_control, 1429 err = hpi_volume_query_range(h_control,
1482 &min_gain_mB, &max_gain_mB, &step_gain_mB); 1430 &min_gain_mB, &max_gain_mB, &step_gain_mB);
1483 if (err) { 1431 if (err) {
1484 max_gain_mB = 0; 1432 max_gain_mB = 0;
@@ -1500,7 +1448,7 @@ static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
1500 u32 h_control = kcontrol->private_value; 1448 u32 h_control = kcontrol->private_value;
1501 short an_gain_mB[HPI_MAX_CHANNELS]; 1449 short an_gain_mB[HPI_MAX_CHANNELS];
1502 1450
1503 hpi_handle_error(hpi_volume_get_gain(ss, h_control, an_gain_mB)); 1451 hpi_handle_error(hpi_volume_get_gain(h_control, an_gain_mB));
1504 ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB; 1452 ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB;
1505 ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB; 1453 ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB;
1506 1454
@@ -1522,7 +1470,7 @@ static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
1522 asihpi->mixer_volume[addr][1] != right; 1470 asihpi->mixer_volume[addr][1] != right;
1523 */ 1471 */
1524 change = 1; 1472 change = 1;
1525 hpi_handle_error(hpi_volume_set_gain(ss, h_control, an_gain_mB)); 1473 hpi_handle_error(hpi_volume_set_gain(h_control, an_gain_mB));
1526 return change; 1474 return change;
1527} 1475}
1528 1476
@@ -1534,7 +1482,7 @@ static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1534 struct snd_card *card = asihpi->card; 1482 struct snd_card *card = asihpi->card;
1535 struct snd_kcontrol_new snd_control; 1483 struct snd_kcontrol_new snd_control;
1536 1484
1537 asihpi_ctl_init(&snd_control, hpi_ctl, "volume"); 1485 asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
1538 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 1486 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1539 SNDRV_CTL_ELEM_ACCESS_TLV_READ; 1487 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1540 snd_control.info = snd_asihpi_volume_info; 1488 snd_control.info = snd_asihpi_volume_info;
@@ -1558,7 +1506,7 @@ static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
1558 short step_gain_mB; 1506 short step_gain_mB;
1559 1507
1560 err = 1508 err =
1561 hpi_level_query_range(ss, h_control, &min_gain_mB, 1509 hpi_level_query_range(h_control, &min_gain_mB,
1562 &max_gain_mB, &step_gain_mB); 1510 &max_gain_mB, &step_gain_mB);
1563 if (err) { 1511 if (err) {
1564 max_gain_mB = 2400; 1512 max_gain_mB = 2400;
@@ -1580,7 +1528,7 @@ static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
1580 u32 h_control = kcontrol->private_value; 1528 u32 h_control = kcontrol->private_value;
1581 short an_gain_mB[HPI_MAX_CHANNELS]; 1529 short an_gain_mB[HPI_MAX_CHANNELS];
1582 1530
1583 hpi_handle_error(hpi_level_get_gain(ss, h_control, an_gain_mB)); 1531 hpi_handle_error(hpi_level_get_gain(h_control, an_gain_mB));
1584 ucontrol->value.integer.value[0] = 1532 ucontrol->value.integer.value[0] =
1585 an_gain_mB[0] / HPI_UNITS_PER_dB; 1533 an_gain_mB[0] / HPI_UNITS_PER_dB;
1586 ucontrol->value.integer.value[1] = 1534 ucontrol->value.integer.value[1] =
@@ -1604,7 +1552,7 @@ static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
1604 asihpi->mixer_level[addr][1] != right; 1552 asihpi->mixer_level[addr][1] != right;
1605 */ 1553 */
1606 change = 1; 1554 change = 1;
1607 hpi_handle_error(hpi_level_set_gain(ss, h_control, an_gain_mB)); 1555 hpi_handle_error(hpi_level_set_gain(h_control, an_gain_mB));
1608 return change; 1556 return change;
1609} 1557}
1610 1558
@@ -1617,7 +1565,7 @@ static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1617 struct snd_kcontrol_new snd_control; 1565 struct snd_kcontrol_new snd_control;
1618 1566
1619 /* can't use 'volume' cos some nodes have volume as well */ 1567 /* can't use 'volume' cos some nodes have volume as well */
1620 asihpi_ctl_init(&snd_control, hpi_ctl, "level"); 1568 asihpi_ctl_init(&snd_control, hpi_ctl, "Level");
1621 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 1569 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1622 SNDRV_CTL_ELEM_ACCESS_TLV_READ; 1570 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1623 snd_control.info = snd_asihpi_level_info; 1571 snd_control.info = snd_asihpi_level_info;
@@ -1633,12 +1581,8 @@ static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1633 ------------------------------------------------------------*/ 1581 ------------------------------------------------------------*/
1634 1582
1635/* AESEBU format */ 1583/* AESEBU format */
1636static char *asihpi_aesebu_format_names[] = 1584static const char * const asihpi_aesebu_format_names[] = {
1637{ 1585 "N/A", "S/PDIF", "AES/EBU" };
1638 "N/A",
1639 "S/PDIF",
1640 "AES/EBU",
1641};
1642 1586
1643static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol, 1587static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1644 struct snd_ctl_elem_info *uinfo) 1588 struct snd_ctl_elem_info *uinfo)
@@ -1659,12 +1603,12 @@ static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1659 1603
1660static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol, 1604static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1661 struct snd_ctl_elem_value *ucontrol, 1605 struct snd_ctl_elem_value *ucontrol,
1662 u16 (*func)(const struct hpi_hsubsys *, u32, u16 *)) 1606 u16 (*func)(u32, u16 *))
1663{ 1607{
1664 u32 h_control = kcontrol->private_value; 1608 u32 h_control = kcontrol->private_value;
1665 u16 source, err; 1609 u16 source, err;
1666 1610
1667 err = func(ss, h_control, &source); 1611 err = func(h_control, &source);
1668 1612
1669 /* default to N/A */ 1613 /* default to N/A */
1670 ucontrol->value.enumerated.item[0] = 0; 1614 ucontrol->value.enumerated.item[0] = 0;
@@ -1681,7 +1625,7 @@ static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1681 1625
1682static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol, 1626static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1683 struct snd_ctl_elem_value *ucontrol, 1627 struct snd_ctl_elem_value *ucontrol,
1684 u16 (*func)(const struct hpi_hsubsys *, u32, u16)) 1628 u16 (*func)(u32, u16))
1685{ 1629{
1686 u32 h_control = kcontrol->private_value; 1630 u32 h_control = kcontrol->private_value;
1687 1631
@@ -1693,7 +1637,7 @@ static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1693 if (ucontrol->value.enumerated.item[0] == 2) 1637 if (ucontrol->value.enumerated.item[0] == 2)
1694 source = HPI_AESEBU_FORMAT_AESEBU; 1638 source = HPI_AESEBU_FORMAT_AESEBU;
1695 1639
1696 if (func(ss, h_control, source) != 0) 1640 if (func(h_control, source) != 0)
1697 return -EINVAL; 1641 return -EINVAL;
1698 1642
1699 return 1; 1643 return 1;
@@ -1702,13 +1646,13 @@ static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1702static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol, 1646static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
1703 struct snd_ctl_elem_value *ucontrol) { 1647 struct snd_ctl_elem_value *ucontrol) {
1704 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol, 1648 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1705 HPI_AESEBU__receiver_get_format); 1649 hpi_aesebu_receiver_get_format);
1706} 1650}
1707 1651
1708static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol, 1652static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
1709 struct snd_ctl_elem_value *ucontrol) { 1653 struct snd_ctl_elem_value *ucontrol) {
1710 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol, 1654 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1711 HPI_AESEBU__receiver_set_format); 1655 hpi_aesebu_receiver_set_format);
1712} 1656}
1713 1657
1714static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol, 1658static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
@@ -1730,8 +1674,8 @@ static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
1730 u32 h_control = kcontrol->private_value; 1674 u32 h_control = kcontrol->private_value;
1731 u16 status; 1675 u16 status;
1732 1676
1733 hpi_handle_error(HPI_AESEBU__receiver_get_error_status( 1677 hpi_handle_error(hpi_aesebu_receiver_get_error_status(
1734 ss, h_control, &status)); 1678 h_control, &status));
1735 ucontrol->value.integer.value[0] = status; 1679 ucontrol->value.integer.value[0] = status;
1736 return 0; 1680 return 0;
1737} 1681}
@@ -1742,7 +1686,7 @@ static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1742 struct snd_card *card = asihpi->card; 1686 struct snd_card *card = asihpi->card;
1743 struct snd_kcontrol_new snd_control; 1687 struct snd_kcontrol_new snd_control;
1744 1688
1745 asihpi_ctl_init(&snd_control, hpi_ctl, "format"); 1689 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
1746 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 1690 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1747 snd_control.info = snd_asihpi_aesebu_format_info; 1691 snd_control.info = snd_asihpi_aesebu_format_info;
1748 snd_control.get = snd_asihpi_aesebu_rx_format_get; 1692 snd_control.get = snd_asihpi_aesebu_rx_format_get;
@@ -1752,7 +1696,7 @@ static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1752 if (ctl_add(card, &snd_control, asihpi) < 0) 1696 if (ctl_add(card, &snd_control, asihpi) < 0)
1753 return -EINVAL; 1697 return -EINVAL;
1754 1698
1755 asihpi_ctl_init(&snd_control, hpi_ctl, "status"); 1699 asihpi_ctl_init(&snd_control, hpi_ctl, "Status");
1756 snd_control.access = 1700 snd_control.access =
1757 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; 1701 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
1758 snd_control.info = snd_asihpi_aesebu_rxstatus_info; 1702 snd_control.info = snd_asihpi_aesebu_rxstatus_info;
@@ -1764,13 +1708,13 @@ static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1764static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol, 1708static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
1765 struct snd_ctl_elem_value *ucontrol) { 1709 struct snd_ctl_elem_value *ucontrol) {
1766 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol, 1710 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1767 HPI_AESEBU__transmitter_get_format); 1711 hpi_aesebu_transmitter_get_format);
1768} 1712}
1769 1713
1770static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol, 1714static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
1771 struct snd_ctl_elem_value *ucontrol) { 1715 struct snd_ctl_elem_value *ucontrol) {
1772 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol, 1716 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1773 HPI_AESEBU__transmitter_set_format); 1717 hpi_aesebu_transmitter_set_format);
1774} 1718}
1775 1719
1776 1720
@@ -1780,7 +1724,7 @@ static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1780 struct snd_card *card = asihpi->card; 1724 struct snd_card *card = asihpi->card;
1781 struct snd_kcontrol_new snd_control; 1725 struct snd_kcontrol_new snd_control;
1782 1726
1783 asihpi_ctl_init(&snd_control, hpi_ctl, "format"); 1727 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
1784 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 1728 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1785 snd_control.info = snd_asihpi_aesebu_format_info; 1729 snd_control.info = snd_asihpi_aesebu_format_info;
1786 snd_control.get = snd_asihpi_aesebu_tx_format_get; 1730 snd_control.get = snd_asihpi_aesebu_tx_format_get;
@@ -1804,7 +1748,7 @@ static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
1804 u16 gain_range[3]; 1748 u16 gain_range[3];
1805 1749
1806 for (idx = 0; idx < 3; idx++) { 1750 for (idx = 0; idx < 3; idx++) {
1807 err = hpi_tuner_query_gain(ss, h_control, 1751 err = hpi_tuner_query_gain(h_control,
1808 idx, &gain_range[idx]); 1752 idx, &gain_range[idx]);
1809 if (err != 0) 1753 if (err != 0)
1810 return err; 1754 return err;
@@ -1827,7 +1771,7 @@ static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1827 u32 h_control = kcontrol->private_value; 1771 u32 h_control = kcontrol->private_value;
1828 short gain; 1772 short gain;
1829 1773
1830 hpi_handle_error(hpi_tuner_get_gain(ss, h_control, &gain)); 1774 hpi_handle_error(hpi_tuner_get_gain(h_control, &gain));
1831 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB; 1775 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
1832 1776
1833 return 0; 1777 return 0;
@@ -1843,7 +1787,7 @@ static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1843 short gain; 1787 short gain;
1844 1788
1845 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB; 1789 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1846 hpi_handle_error(hpi_tuner_set_gain(ss, h_control, gain)); 1790 hpi_handle_error(hpi_tuner_set_gain(h_control, gain));
1847 1791
1848 return 1; 1792 return 1;
1849} 1793}
@@ -1857,7 +1801,7 @@ static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
1857 u32 i; 1801 u32 i;
1858 1802
1859 for (i = 0; i < len; i++) { 1803 for (i = 0; i < len; i++) {
1860 err = hpi_tuner_query_band(ss, 1804 err = hpi_tuner_query_band(
1861 h_control, i, &band_list[i]); 1805 h_control, i, &band_list[i]);
1862 if (err != 0) 1806 if (err != 0)
1863 break; 1807 break;
@@ -1913,7 +1857,7 @@ static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
1913 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands, 1857 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1914 HPI_TUNER_BAND_LAST); 1858 HPI_TUNER_BAND_LAST);
1915 1859
1916 hpi_handle_error(hpi_tuner_get_band(ss, h_control, &band)); 1860 hpi_handle_error(hpi_tuner_get_band(h_control, &band));
1917 1861
1918 ucontrol->value.enumerated.item[0] = -1; 1862 ucontrol->value.enumerated.item[0] = -1;
1919 for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++) 1863 for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
@@ -1940,7 +1884,7 @@ static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1940 HPI_TUNER_BAND_LAST); 1884 HPI_TUNER_BAND_LAST);
1941 1885
1942 band = tuner_bands[ucontrol->value.enumerated.item[0]]; 1886 band = tuner_bands[ucontrol->value.enumerated.item[0]];
1943 hpi_handle_error(hpi_tuner_set_band(ss, h_control, band)); 1887 hpi_handle_error(hpi_tuner_set_band(h_control, band));
1944 1888
1945 return 1; 1889 return 1;
1946} 1890}
@@ -1965,7 +1909,7 @@ static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
1965 1909
1966 for (band_iter = 0; band_iter < num_bands; band_iter++) { 1910 for (band_iter = 0; band_iter < num_bands; band_iter++) {
1967 for (idx = 0; idx < 3; idx++) { 1911 for (idx = 0; idx < 3; idx++) {
1968 err = hpi_tuner_query_frequency(ss, h_control, 1912 err = hpi_tuner_query_frequency(h_control,
1969 idx, tuner_bands[band_iter], 1913 idx, tuner_bands[band_iter],
1970 &temp_freq_range[idx]); 1914 &temp_freq_range[idx]);
1971 if (err != 0) 1915 if (err != 0)
@@ -1998,7 +1942,7 @@ static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
1998 u32 h_control = kcontrol->private_value; 1942 u32 h_control = kcontrol->private_value;
1999 u32 freq; 1943 u32 freq;
2000 1944
2001 hpi_handle_error(hpi_tuner_get_frequency(ss, h_control, &freq)); 1945 hpi_handle_error(hpi_tuner_get_frequency(h_control, &freq));
2002 ucontrol->value.integer.value[0] = freq; 1946 ucontrol->value.integer.value[0] = freq;
2003 1947
2004 return 0; 1948 return 0;
@@ -2011,7 +1955,7 @@ static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
2011 u32 freq; 1955 u32 freq;
2012 1956
2013 freq = ucontrol->value.integer.value[0]; 1957 freq = ucontrol->value.integer.value[0];
2014 hpi_handle_error(hpi_tuner_set_frequency(ss, h_control, freq)); 1958 hpi_handle_error(hpi_tuner_set_frequency(h_control, freq));
2015 1959
2016 return 1; 1960 return 1;
2017} 1961}
@@ -2026,8 +1970,8 @@ static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2026 snd_control.private_value = hpi_ctl->h_control; 1970 snd_control.private_value = hpi_ctl->h_control;
2027 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 1971 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2028 1972
2029 if (!hpi_tuner_get_gain(ss, hpi_ctl->h_control, NULL)) { 1973 if (!hpi_tuner_get_gain(hpi_ctl->h_control, NULL)) {
2030 asihpi_ctl_init(&snd_control, hpi_ctl, "gain"); 1974 asihpi_ctl_init(&snd_control, hpi_ctl, "Gain");
2031 snd_control.info = snd_asihpi_tuner_gain_info; 1975 snd_control.info = snd_asihpi_tuner_gain_info;
2032 snd_control.get = snd_asihpi_tuner_gain_get; 1976 snd_control.get = snd_asihpi_tuner_gain_get;
2033 snd_control.put = snd_asihpi_tuner_gain_put; 1977 snd_control.put = snd_asihpi_tuner_gain_put;
@@ -2036,7 +1980,7 @@ static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2036 return -EINVAL; 1980 return -EINVAL;
2037 } 1981 }
2038 1982
2039 asihpi_ctl_init(&snd_control, hpi_ctl, "band"); 1983 asihpi_ctl_init(&snd_control, hpi_ctl, "Band");
2040 snd_control.info = snd_asihpi_tuner_band_info; 1984 snd_control.info = snd_asihpi_tuner_band_info;
2041 snd_control.get = snd_asihpi_tuner_band_get; 1985 snd_control.get = snd_asihpi_tuner_band_get;
2042 snd_control.put = snd_asihpi_tuner_band_put; 1986 snd_control.put = snd_asihpi_tuner_band_put;
@@ -2044,7 +1988,7 @@ static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2044 if (ctl_add(card, &snd_control, asihpi) < 0) 1988 if (ctl_add(card, &snd_control, asihpi) < 0)
2045 return -EINVAL; 1989 return -EINVAL;
2046 1990
2047 asihpi_ctl_init(&snd_control, hpi_ctl, "freq"); 1991 asihpi_ctl_init(&snd_control, hpi_ctl, "Freq");
2048 snd_control.info = snd_asihpi_tuner_freq_info; 1992 snd_control.info = snd_asihpi_tuner_freq_info;
2049 snd_control.get = snd_asihpi_tuner_freq_get; 1993 snd_control.get = snd_asihpi_tuner_freq_get;
2050 snd_control.put = snd_asihpi_tuner_freq_put; 1994 snd_control.put = snd_asihpi_tuner_freq_put;
@@ -2095,7 +2039,7 @@ static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
2095 short an_gain_mB[HPI_MAX_CHANNELS], i; 2039 short an_gain_mB[HPI_MAX_CHANNELS], i;
2096 u16 err; 2040 u16 err;
2097 2041
2098 err = hpi_meter_get_peak(ss, h_control, an_gain_mB); 2042 err = hpi_meter_get_peak(h_control, an_gain_mB);
2099 2043
2100 for (i = 0; i < HPI_MAX_CHANNELS; i++) { 2044 for (i = 0; i < HPI_MAX_CHANNELS; i++) {
2101 if (err) { 2045 if (err) {
@@ -2120,7 +2064,7 @@ static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2120 struct snd_card *card = asihpi->card; 2064 struct snd_card *card = asihpi->card;
2121 struct snd_kcontrol_new snd_control; 2065 struct snd_kcontrol_new snd_control;
2122 2066
2123 asihpi_ctl_init(&snd_control, hpi_ctl, "meter"); 2067 asihpi_ctl_init(&snd_control, hpi_ctl, "Meter");
2124 snd_control.access = 2068 snd_control.access =
2125 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; 2069 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2126 snd_control.info = snd_asihpi_meter_info; 2070 snd_control.info = snd_asihpi_meter_info;
@@ -2140,7 +2084,7 @@ static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
2140 struct hpi_control hpi_ctl; 2084 struct hpi_control hpi_ctl;
2141 int s, err; 2085 int s, err;
2142 for (s = 0; s < 32; s++) { 2086 for (s = 0; s < 32; s++) {
2143 err = hpi_multiplexer_query_source(ss, h_control, s, 2087 err = hpi_multiplexer_query_source(h_control, s,
2144 &hpi_ctl. 2088 &hpi_ctl.
2145 src_node_type, 2089 src_node_type,
2146 &hpi_ctl. 2090 &hpi_ctl.
@@ -2168,7 +2112,7 @@ static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2168 uinfo->value.enumerated.items - 1; 2112 uinfo->value.enumerated.items - 1;
2169 2113
2170 err = 2114 err =
2171 hpi_multiplexer_query_source(ss, h_control, 2115 hpi_multiplexer_query_source(h_control,
2172 uinfo->value.enumerated.item, 2116 uinfo->value.enumerated.item,
2173 &src_node_type, &src_node_index); 2117 &src_node_type, &src_node_index);
2174 2118
@@ -2186,11 +2130,11 @@ static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2186 u16 src_node_type, src_node_index; 2130 u16 src_node_type, src_node_index;
2187 int s; 2131 int s;
2188 2132
2189 hpi_handle_error(hpi_multiplexer_get_source(ss, h_control, 2133 hpi_handle_error(hpi_multiplexer_get_source(h_control,
2190 &source_type, &source_index)); 2134 &source_type, &source_index));
2191 /* Should cache this search result! */ 2135 /* Should cache this search result! */
2192 for (s = 0; s < 256; s++) { 2136 for (s = 0; s < 256; s++) {
2193 if (hpi_multiplexer_query_source(ss, h_control, s, 2137 if (hpi_multiplexer_query_source(h_control, s,
2194 &src_node_type, &src_node_index)) 2138 &src_node_type, &src_node_index))
2195 break; 2139 break;
2196 2140
@@ -2201,7 +2145,7 @@ static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2201 } 2145 }
2202 } 2146 }
2203 snd_printd(KERN_WARNING 2147 snd_printd(KERN_WARNING
2204 "control %x failed to match mux source %hu %hu\n", 2148 "Control %x failed to match mux source %hu %hu\n",
2205 h_control, source_type, source_index); 2149 h_control, source_type, source_index);
2206 ucontrol->value.enumerated.item[0] = 0; 2150 ucontrol->value.enumerated.item[0] = 0;
2207 return 0; 2151 return 0;
@@ -2217,12 +2161,12 @@ static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
2217 2161
2218 change = 1; 2162 change = 1;
2219 2163
2220 e = hpi_multiplexer_query_source(ss, h_control, 2164 e = hpi_multiplexer_query_source(h_control,
2221 ucontrol->value.enumerated.item[0], 2165 ucontrol->value.enumerated.item[0],
2222 &source_type, &source_index); 2166 &source_type, &source_index);
2223 if (!e) 2167 if (!e)
2224 hpi_handle_error( 2168 hpi_handle_error(
2225 hpi_multiplexer_set_source(ss, h_control, 2169 hpi_multiplexer_set_source(h_control,
2226 source_type, source_index)); 2170 source_type, source_index));
2227 return change; 2171 return change;
2228} 2172}
@@ -2234,11 +2178,7 @@ static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2234 struct snd_card *card = asihpi->card; 2178 struct snd_card *card = asihpi->card;
2235 struct snd_kcontrol_new snd_control; 2179 struct snd_kcontrol_new snd_control;
2236 2180
2237#if ASI_STYLE_NAMES 2181 asihpi_ctl_init(&snd_control, hpi_ctl, "Route");
2238 asihpi_ctl_init(&snd_control, hpi_ctl, "multiplexer");
2239#else
2240 asihpi_ctl_init(&snd_control, hpi_ctl, "route");
2241#endif
2242 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 2182 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2243 snd_control.info = snd_asihpi_mux_info; 2183 snd_control.info = snd_asihpi_mux_info;
2244 snd_control.get = snd_asihpi_mux_get; 2184 snd_control.get = snd_asihpi_mux_get;
@@ -2254,33 +2194,38 @@ static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2254static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol, 2194static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2255 struct snd_ctl_elem_info *uinfo) 2195 struct snd_ctl_elem_info *uinfo)
2256{ 2196{
2257 static char *mode_names[HPI_CHANNEL_MODE_LAST] = { 2197 static const char * const mode_names[HPI_CHANNEL_MODE_LAST + 1] = {
2258 "normal", "swap", 2198 "invalid",
2259 "from_left", "from_right", 2199 "Normal", "Swap",
2260 "to_left", "to_right" 2200 "From Left", "From Right",
2201 "To Left", "To Right"
2261 }; 2202 };
2262 2203
2263 u32 h_control = kcontrol->private_value; 2204 u32 h_control = kcontrol->private_value;
2264 u16 mode; 2205 u16 mode;
2265 int i; 2206 int i;
2207 u16 mode_map[6];
2208 int valid_modes = 0;
2266 2209
2267 /* HPI channel mode values can be from 1 to 6 2210 /* HPI channel mode values can be from 1 to 6
2268 Some adapters only support a contiguous subset 2211 Some adapters only support a contiguous subset
2269 */ 2212 */
2270 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++) 2213 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
2271 if (hpi_channel_mode_query_mode( 2214 if (!hpi_channel_mode_query_mode(
2272 ss, h_control, i, &mode)) 2215 h_control, i, &mode)) {
2273 break; 2216 mode_map[valid_modes] = mode;
2217 valid_modes++;
2218 }
2274 2219
2275 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2220 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2276 uinfo->count = 1; 2221 uinfo->count = 1;
2277 uinfo->value.enumerated.items = i; 2222 uinfo->value.enumerated.items = valid_modes;
2278 2223
2279 if (uinfo->value.enumerated.item >= i) 2224 if (uinfo->value.enumerated.item >= valid_modes)
2280 uinfo->value.enumerated.item = i - 1; 2225 uinfo->value.enumerated.item = valid_modes - 1;
2281 2226
2282 strcpy(uinfo->value.enumerated.name, 2227 strcpy(uinfo->value.enumerated.name,
2283 mode_names[uinfo->value.enumerated.item]); 2228 mode_names[mode_map[uinfo->value.enumerated.item]]);
2284 2229
2285 return 0; 2230 return 0;
2286} 2231}
@@ -2291,7 +2236,7 @@ static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
2291 u32 h_control = kcontrol->private_value; 2236 u32 h_control = kcontrol->private_value;
2292 u16 mode; 2237 u16 mode;
2293 2238
2294 if (hpi_channel_mode_get(ss, h_control, &mode)) 2239 if (hpi_channel_mode_get(h_control, &mode))
2295 mode = 1; 2240 mode = 1;
2296 2241
2297 ucontrol->value.enumerated.item[0] = mode - 1; 2242 ucontrol->value.enumerated.item[0] = mode - 1;
@@ -2307,7 +2252,7 @@ static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
2307 2252
2308 change = 1; 2253 change = 1;
2309 2254
2310 hpi_handle_error(hpi_channel_mode_set(ss, h_control, 2255 hpi_handle_error(hpi_channel_mode_set(h_control,
2311 ucontrol->value.enumerated.item[0] + 1)); 2256 ucontrol->value.enumerated.item[0] + 1));
2312 return change; 2257 return change;
2313} 2258}
@@ -2319,7 +2264,7 @@ static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2319 struct snd_card *card = asihpi->card; 2264 struct snd_card *card = asihpi->card;
2320 struct snd_kcontrol_new snd_control; 2265 struct snd_kcontrol_new snd_control;
2321 2266
2322 asihpi_ctl_init(&snd_control, hpi_ctl, "channel mode"); 2267 asihpi_ctl_init(&snd_control, hpi_ctl, "Mode");
2323 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 2268 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2324 snd_control.info = snd_asihpi_cmode_info; 2269 snd_control.info = snd_asihpi_cmode_info;
2325 snd_control.get = snd_asihpi_cmode_get; 2270 snd_control.get = snd_asihpi_cmode_get;
@@ -2331,15 +2276,12 @@ static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2331/*------------------------------------------------------------ 2276/*------------------------------------------------------------
2332 Sampleclock source controls 2277 Sampleclock source controls
2333 ------------------------------------------------------------*/ 2278 ------------------------------------------------------------*/
2334 2279static char *sampleclock_sources[MAX_CLOCKSOURCES] = {
2335static char *sampleclock_sources[MAX_CLOCKSOURCES] = 2280 "N/A", "Local PLL", "Digital Sync", "Word External", "Word Header",
2336 { "N/A", "local PLL", "AES/EBU sync", "word external", "word header", 2281 "SMPTE", "Digital1", "Auto", "Network", "Invalid",
2337 "SMPTE", "AES/EBU in1", "auto", "network", "invalid", 2282 "Prev Module",
2338 "prev module", 2283 "Digital2", "Digital3", "Digital4", "Digital5",
2339 "AES/EBU in2", "AES/EBU in3", "AES/EBU in4", "AES/EBU in5", 2284 "Digital6", "Digital7", "Digital8"};
2340 "AES/EBU in6", "AES/EBU in7", "AES/EBU in8"};
2341
2342
2343 2285
2344static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol, 2286static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2345 struct snd_ctl_elem_info *uinfo) 2287 struct snd_ctl_elem_info *uinfo)
@@ -2371,11 +2313,11 @@ static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
2371 int i; 2313 int i;
2372 2314
2373 ucontrol->value.enumerated.item[0] = 0; 2315 ucontrol->value.enumerated.item[0] = 0;
2374 if (hpi_sample_clock_get_source(ss, h_control, &source)) 2316 if (hpi_sample_clock_get_source(h_control, &source))
2375 source = 0; 2317 source = 0;
2376 2318
2377 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT) 2319 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2378 if (hpi_sample_clock_get_source_index(ss, h_control, &srcindex)) 2320 if (hpi_sample_clock_get_source_index(h_control, &srcindex))
2379 srcindex = 0; 2321 srcindex = 0;
2380 2322
2381 for (i = 0; i < clkcache->count; i++) 2323 for (i = 0; i < clkcache->count; i++)
@@ -2402,11 +2344,11 @@ static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
2402 if (item >= clkcache->count) 2344 if (item >= clkcache->count)
2403 item = clkcache->count-1; 2345 item = clkcache->count-1;
2404 2346
2405 hpi_handle_error(hpi_sample_clock_set_source(ss, 2347 hpi_handle_error(hpi_sample_clock_set_source(
2406 h_control, clkcache->s[item].source)); 2348 h_control, clkcache->s[item].source));
2407 2349
2408 if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT) 2350 if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2409 hpi_handle_error(hpi_sample_clock_set_source_index(ss, 2351 hpi_handle_error(hpi_sample_clock_set_source_index(
2410 h_control, clkcache->s[item].index)); 2352 h_control, clkcache->s[item].index));
2411 return change; 2353 return change;
2412} 2354}
@@ -2434,7 +2376,7 @@ static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
2434 u32 rate; 2376 u32 rate;
2435 u16 e; 2377 u16 e;
2436 2378
2437 e = hpi_sample_clock_get_local_rate(ss, h_control, &rate); 2379 e = hpi_sample_clock_get_local_rate(h_control, &rate);
2438 if (!e) 2380 if (!e)
2439 ucontrol->value.integer.value[0] = rate; 2381 ucontrol->value.integer.value[0] = rate;
2440 else 2382 else
@@ -2452,7 +2394,7 @@ static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
2452 asihpi->mixer_clkrate[addr][1] != right; 2394 asihpi->mixer_clkrate[addr][1] != right;
2453 */ 2395 */
2454 change = 1; 2396 change = 1;
2455 hpi_handle_error(hpi_sample_clock_set_local_rate(ss, h_control, 2397 hpi_handle_error(hpi_sample_clock_set_local_rate(h_control,
2456 ucontrol->value.integer.value[0])); 2398 ucontrol->value.integer.value[0]));
2457 return change; 2399 return change;
2458} 2400}
@@ -2476,7 +2418,7 @@ static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
2476 u32 rate; 2418 u32 rate;
2477 u16 e; 2419 u16 e;
2478 2420
2479 e = hpi_sample_clock_get_sample_rate(ss, h_control, &rate); 2421 e = hpi_sample_clock_get_sample_rate(h_control, &rate);
2480 if (!e) 2422 if (!e)
2481 ucontrol->value.integer.value[0] = rate; 2423 ucontrol->value.integer.value[0] = rate;
2482 else 2424 else
@@ -2501,7 +2443,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2501 clkcache->has_local = 0; 2443 clkcache->has_local = 0;
2502 2444
2503 for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) { 2445 for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
2504 if (hpi_sample_clock_query_source(ss, hSC, 2446 if (hpi_sample_clock_query_source(hSC,
2505 i, &source)) 2447 i, &source))
2506 break; 2448 break;
2507 clkcache->s[i].source = source; 2449 clkcache->s[i].source = source;
@@ -2515,7 +2457,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2515 if (has_aes_in) 2457 if (has_aes_in)
2516 /* already will have picked up index 0 above */ 2458 /* already will have picked up index 0 above */
2517 for (j = 1; j < 8; j++) { 2459 for (j = 1; j < 8; j++) {
2518 if (hpi_sample_clock_query_source_index(ss, hSC, 2460 if (hpi_sample_clock_query_source_index(hSC,
2519 j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT, 2461 j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
2520 &source)) 2462 &source))
2521 break; 2463 break;
@@ -2528,7 +2470,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2528 } 2470 }
2529 clkcache->count = i; 2471 clkcache->count = i;
2530 2472
2531 asihpi_ctl_init(&snd_control, hpi_ctl, "source"); 2473 asihpi_ctl_init(&snd_control, hpi_ctl, "Source");
2532 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ; 2474 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2533 snd_control.info = snd_asihpi_clksrc_info; 2475 snd_control.info = snd_asihpi_clksrc_info;
2534 snd_control.get = snd_asihpi_clksrc_get; 2476 snd_control.get = snd_asihpi_clksrc_get;
@@ -2538,7 +2480,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2538 2480
2539 2481
2540 if (clkcache->has_local) { 2482 if (clkcache->has_local) {
2541 asihpi_ctl_init(&snd_control, hpi_ctl, "local_rate"); 2483 asihpi_ctl_init(&snd_control, hpi_ctl, "Localrate");
2542 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ; 2484 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2543 snd_control.info = snd_asihpi_clklocal_info; 2485 snd_control.info = snd_asihpi_clklocal_info;
2544 snd_control.get = snd_asihpi_clklocal_get; 2486 snd_control.get = snd_asihpi_clklocal_get;
@@ -2549,7 +2491,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2549 return -EINVAL; 2491 return -EINVAL;
2550 } 2492 }
2551 2493
2552 asihpi_ctl_init(&snd_control, hpi_ctl, "rate"); 2494 asihpi_ctl_init(&snd_control, hpi_ctl, "Rate");
2553 snd_control.access = 2495 snd_control.access =
2554 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; 2496 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2555 snd_control.info = snd_asihpi_clkrate_info; 2497 snd_control.info = snd_asihpi_clkrate_info;
@@ -2571,10 +2513,10 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2571 2513
2572 if (snd_BUG_ON(!asihpi)) 2514 if (snd_BUG_ON(!asihpi))
2573 return -EINVAL; 2515 return -EINVAL;
2574 strcpy(card->mixername, "asihpi mixer"); 2516 strcpy(card->mixername, "Asihpi Mixer");
2575 2517
2576 err = 2518 err =
2577 hpi_mixer_open(ss, asihpi->adapter_index, 2519 hpi_mixer_open(asihpi->adapter_index,
2578 &asihpi->h_mixer); 2520 &asihpi->h_mixer);
2579 hpi_handle_error(err); 2521 hpi_handle_error(err);
2580 if (err) 2522 if (err)
@@ -2585,7 +2527,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2585 2527
2586 for (idx = 0; idx < 2000; idx++) { 2528 for (idx = 0; idx < 2000; idx++) {
2587 err = hpi_mixer_get_control_by_index( 2529 err = hpi_mixer_get_control_by_index(
2588 ss, asihpi->h_mixer, 2530 asihpi->h_mixer,
2589 idx, 2531 idx,
2590 &hpi_ctl.src_node_type, 2532 &hpi_ctl.src_node_type,
2591 &hpi_ctl.src_node_index, 2533 &hpi_ctl.src_node_index,
@@ -2597,7 +2539,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2597 if (err == HPI_ERROR_CONTROL_DISABLED) { 2539 if (err == HPI_ERROR_CONTROL_DISABLED) {
2598 if (mixer_dump) 2540 if (mixer_dump)
2599 snd_printk(KERN_INFO 2541 snd_printk(KERN_INFO
2600 "disabled HPI control(%d)\n", 2542 "Disabled HPI Control(%d)\n",
2601 idx); 2543 idx);
2602 continue; 2544 continue;
2603 } else 2545 } else
@@ -2662,7 +2604,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2662 default: 2604 default:
2663 if (mixer_dump) 2605 if (mixer_dump)
2664 snd_printk(KERN_INFO 2606 snd_printk(KERN_INFO
2665 "untranslated HPI control" 2607 "Untranslated HPI Control"
2666 "(%d) %d %d %d %d %d\n", 2608 "(%d) %d %d %d %d %d\n",
2667 idx, 2609 idx,
2668 hpi_ctl.control_type, 2610 hpi_ctl.control_type,
@@ -2712,14 +2654,14 @@ snd_asihpi_proc_read(struct snd_info_entry *entry,
2712 version & 0x7, 2654 version & 0x7,
2713 ((version >> 13) * 100) + ((version >> 7) & 0x3f)); 2655 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2714 2656
2715 err = hpi_mixer_get_control(ss, asihpi->h_mixer, 2657 err = hpi_mixer_get_control(asihpi->h_mixer,
2716 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, 2658 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2717 HPI_CONTROL_SAMPLECLOCK, &h_control); 2659 HPI_CONTROL_SAMPLECLOCK, &h_control);
2718 2660
2719 if (!err) { 2661 if (!err) {
2720 err = hpi_sample_clock_get_sample_rate(ss, 2662 err = hpi_sample_clock_get_sample_rate(
2721 h_control, &rate); 2663 h_control, &rate);
2722 err += hpi_sample_clock_get_source(ss, h_control, &source); 2664 err += hpi_sample_clock_get_source(h_control, &source);
2723 2665
2724 if (!err) 2666 if (!err)
2725 snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n", 2667 snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n",
@@ -2841,15 +2783,17 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2841 if (err < 0) 2783 if (err < 0)
2842 return err; 2784 return err;
2843 snd_printk(KERN_WARNING 2785 snd_printk(KERN_WARNING
2844 "**** WARNING **** adapter index %d->ALSA index %d\n", 2786 "**** WARNING **** Adapter index %d->ALSA index %d\n",
2845 hpi_card->index, card->number); 2787 hpi_card->index, card->number);
2846 } 2788 }
2847 2789
2790 snd_card_set_dev(card, &pci_dev->dev);
2791
2848 asihpi = (struct snd_card_asihpi *) card->private_data; 2792 asihpi = (struct snd_card_asihpi *) card->private_data;
2849 asihpi->card = card; 2793 asihpi->card = card;
2850 asihpi->pci = hpi_card->pci; 2794 asihpi->pci = pci_dev;
2851 asihpi->adapter_index = hpi_card->index; 2795 asihpi->adapter_index = hpi_card->index;
2852 hpi_handle_error(hpi_adapter_get_info(ss, 2796 hpi_handle_error(hpi_adapter_get_info(
2853 asihpi->adapter_index, 2797 asihpi->adapter_index,
2854 &asihpi->num_outstreams, 2798 &asihpi->num_outstreams,
2855 &asihpi->num_instreams, 2799 &asihpi->num_instreams,
@@ -2859,7 +2803,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2859 version = asihpi->version; 2803 version = asihpi->version;
2860 snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d " 2804 snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d "
2861 "num_instreams=%d S/N=%d\n" 2805 "num_instreams=%d S/N=%d\n"
2862 "hw version %c%d DSP code version %03d\n", 2806 "Hw Version %c%d DSP code version %03d\n",
2863 asihpi->type, asihpi->adapter_index, 2807 asihpi->type, asihpi->adapter_index,
2864 asihpi->num_outstreams, 2808 asihpi->num_outstreams,
2865 asihpi->num_instreams, asihpi->serial_number, 2809 asihpi->num_instreams, asihpi->serial_number,
@@ -2871,33 +2815,36 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2871 if (pcm_substreams < asihpi->num_instreams) 2815 if (pcm_substreams < asihpi->num_instreams)
2872 pcm_substreams = asihpi->num_instreams; 2816 pcm_substreams = asihpi->num_instreams;
2873 2817
2874 err = hpi_adapter_get_property(ss, asihpi->adapter_index, 2818 err = hpi_adapter_get_property(asihpi->adapter_index,
2875 HPI_ADAPTER_PROPERTY_CAPS1, 2819 HPI_ADAPTER_PROPERTY_CAPS1,
2876 NULL, &asihpi->support_grouping); 2820 NULL, &asihpi->support_grouping);
2877 if (err) 2821 if (err)
2878 asihpi->support_grouping = 0; 2822 asihpi->support_grouping = 0;
2879 2823
2880 err = hpi_adapter_get_property(ss, asihpi->adapter_index, 2824 err = hpi_adapter_get_property(asihpi->adapter_index,
2881 HPI_ADAPTER_PROPERTY_CAPS2, 2825 HPI_ADAPTER_PROPERTY_CAPS2,
2882 &asihpi->support_mrx, NULL); 2826 &asihpi->support_mrx, NULL);
2883 if (err) 2827 if (err)
2884 asihpi->support_mrx = 0; 2828 asihpi->support_mrx = 0;
2885 2829
2886 err = hpi_adapter_get_property(ss, asihpi->adapter_index, 2830 err = hpi_adapter_get_property(asihpi->adapter_index,
2887 HPI_ADAPTER_PROPERTY_INTERVAL, 2831 HPI_ADAPTER_PROPERTY_INTERVAL,
2888 NULL, &asihpi->update_interval_frames); 2832 NULL, &asihpi->update_interval_frames);
2889 if (err) 2833 if (err)
2890 asihpi->update_interval_frames = 512; 2834 asihpi->update_interval_frames = 512;
2891 2835
2892 hpi_handle_error(hpi_instream_open(ss, asihpi->adapter_index, 2836 if (!asihpi->can_dma)
2837 asihpi->update_interval_frames *= 2;
2838
2839 hpi_handle_error(hpi_instream_open(asihpi->adapter_index,
2893 0, &h_stream)); 2840 0, &h_stream));
2894 2841
2895 err = hpi_instream_host_buffer_free(ss, h_stream); 2842 err = hpi_instream_host_buffer_free(h_stream);
2896 asihpi->support_mmap = (!err); 2843 asihpi->can_dma = (!err);
2897 2844
2898 hpi_handle_error(hpi_instream_close(ss, h_stream)); 2845 hpi_handle_error(hpi_instream_close(h_stream));
2899 2846
2900 err = hpi_adapter_get_property(ss, asihpi->adapter_index, 2847 err = hpi_adapter_get_property(asihpi->adapter_index,
2901 HPI_ADAPTER_PROPERTY_CURCHANNELS, 2848 HPI_ADAPTER_PROPERTY_CURCHANNELS,
2902 &asihpi->in_max_chans, &asihpi->out_max_chans); 2849 &asihpi->in_max_chans, &asihpi->out_max_chans);
2903 if (err) { 2850 if (err) {
@@ -2905,13 +2852,12 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2905 asihpi->out_max_chans = 2; 2852 asihpi->out_max_chans = 2;
2906 } 2853 }
2907 2854
2908 snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n", 2855 snd_printk(KERN_INFO "has dma:%d, grouping:%d, mrx:%d\n",
2909 asihpi->support_mmap, 2856 asihpi->can_dma,
2910 asihpi->support_grouping, 2857 asihpi->support_grouping,
2911 asihpi->support_mrx 2858 asihpi->support_mrx
2912 ); 2859 );
2913 2860
2914
2915 err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams); 2861 err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams);
2916 if (err < 0) { 2862 if (err < 0) {
2917 snd_printk(KERN_ERR "pcm_new failed\n"); 2863 snd_printk(KERN_ERR "pcm_new failed\n");
@@ -2923,13 +2869,13 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2923 goto __nodev; 2869 goto __nodev;
2924 } 2870 }
2925 2871
2926 err = hpi_mixer_get_control(ss, asihpi->h_mixer, 2872 err = hpi_mixer_get_control(asihpi->h_mixer,
2927 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, 2873 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2928 HPI_CONTROL_SAMPLECLOCK, &h_control); 2874 HPI_CONTROL_SAMPLECLOCK, &h_control);
2929 2875
2930 if (!err) 2876 if (!err)
2931 err = hpi_sample_clock_set_local_rate( 2877 err = hpi_sample_clock_set_local_rate(
2932 ss, h_control, adapter_fs); 2878 h_control, adapter_fs);
2933 2879
2934 snd_asihpi_proc_init(asihpi); 2880 snd_asihpi_proc_init(asihpi);
2935 2881
@@ -2937,15 +2883,13 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2937 by enable_hwdep module param*/ 2883 by enable_hwdep module param*/
2938 snd_asihpi_hpi_new(asihpi, 0, NULL); 2884 snd_asihpi_hpi_new(asihpi, 0, NULL);
2939 2885
2940 if (asihpi->support_mmap) 2886 strcpy(card->driver, "ASIHPI");
2941 strcpy(card->driver, "ASIHPI-MMAP");
2942 else
2943 strcpy(card->driver, "ASIHPI");
2944 2887
2945 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type); 2888 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
2946 sprintf(card->longname, "%s %i", 2889 sprintf(card->longname, "%s %i",
2947 card->shortname, asihpi->adapter_index); 2890 card->shortname, asihpi->adapter_index);
2948 err = snd_card_register(card); 2891 err = snd_card_register(card);
2892
2949 if (!err) { 2893 if (!err) {
2950 hpi_card->snd_card_asihpi = card; 2894 hpi_card->snd_card_asihpi = card;
2951 dev++; 2895 dev++;
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h
index 23399d02f666..255429c32c1c 100644
--- a/sound/pci/asihpi/hpi.h
+++ b/sound/pci/asihpi/hpi.h
@@ -24,17 +24,10 @@
24 24
25 The HPI is a low-level hardware abstraction layer to all 25 The HPI is a low-level hardware abstraction layer to all
26 AudioScience digital audio adapters 26 AudioScience digital audio adapters
27*/
28/*
29 You must define one operating system that the HPI is to be compiled under
30 HPI_OS_WIN32_USER 32bit Windows
31 HPI_OS_DSP_C6000 DSP TI C6000 (automatically set)
32 HPI_OS_WDM Windows WDM kernel driver
33 HPI_OS_LINUX Linux userspace
34 HPI_OS_LINUX_KERNEL Linux kernel (automatically set)
35 27
36(C) Copyright AudioScience Inc. 1998-2010 28(C) Copyright AudioScience Inc. 1998-2010
37******************************************************************************/ 29*/
30
38#ifndef _HPI_H_ 31#ifndef _HPI_H_
39#define _HPI_H_ 32#define _HPI_H_
40/* HPI Version 33/* HPI Version
@@ -50,20 +43,20 @@ i.e 3.05.02 is a development version
50#define HPI_VER_RELEASE(v) ((int)(v & 0xFF)) 43#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
51 44
52/* Use single digits for versions less that 10 to avoid octal. */ 45/* Use single digits for versions less that 10 to avoid octal. */
53#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 4, 1) 46#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 6, 0)
54#define HPI_VER_STRING "4.04.01" 47#define HPI_VER_STRING "4.06.00"
55 48
56/* Library version as documented in hpi-api-versions.txt */ 49/* Library version as documented in hpi-api-versions.txt */
57#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0) 50#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0)
58 51
59#include <linux/types.h> 52#include <linux/types.h>
60#define HPI_EXCLUDE_DEPRECATED 53#define HPI_BUILD_EXCLUDE_DEPRECATED
54#define HPI_BUILD_KERNEL_MODE
61 55
62/******************************************************************************/ 56/******************************************************************************/
63/******************************************************************************/
64/******** HPI API DEFINITIONS *****/ 57/******** HPI API DEFINITIONS *****/
65/******************************************************************************/ 58/******************************************************************************/
66/******************************************************************************/ 59
67/*******************************************/ 60/*******************************************/
68/** Audio format types 61/** Audio format types
69\ingroup stream 62\ingroup stream
@@ -174,7 +167,6 @@ The range is +1.0 to -1.0, which corresponds to digital fullscale.
174 HPI_FORMAT_UNDEFINED = 0xffff 167 HPI_FORMAT_UNDEFINED = 0xffff
175}; 168};
176 169
177/******************************************* in/out Stream states */
178/*******************************************/ 170/*******************************************/
179/** Stream States 171/** Stream States
180\ingroup stream 172\ingroup stream
@@ -194,7 +186,7 @@ enum HPI_STREAM_STATES {
194 cards to be ready. */ 186 cards to be ready. */
195 HPI_STATE_WAIT = 6 187 HPI_STATE_WAIT = 6
196}; 188};
197/******************************************* mixer source node types */ 189/*******************************************/
198/** Source node types 190/** Source node types
199\ingroup mixer 191\ingroup mixer
200*/ 192*/
@@ -224,7 +216,7 @@ enum HPI_SOURCENODES {
224 /* AX6 max sourcenode types = 15 */ 216 /* AX6 max sourcenode types = 15 */
225}; 217};
226 218
227/******************************************* mixer dest node types */ 219/*******************************************/
228/** Destination node types 220/** Destination node types
229\ingroup mixer 221\ingroup mixer
230*/ 222*/
@@ -262,11 +254,11 @@ enum HPI_CONTROLS {
262 HPI_CONTROL_MUTE = 4, /*mute control - not used at present. */ 254 HPI_CONTROL_MUTE = 4, /*mute control - not used at present. */
263 HPI_CONTROL_MULTIPLEXER = 5, /**< multiplexer control. */ 255 HPI_CONTROL_MULTIPLEXER = 5, /**< multiplexer control. */
264 256
265 HPI_CONTROL_AESEBU_TRANSMITTER = 6, /**< AES/EBU transmitter control. */ 257 HPI_CONTROL_AESEBU_TRANSMITTER = 6, /**< AES/EBU transmitter control */
266 HPI_CONTROL_AESEBUTX = HPI_CONTROL_AESEBU_TRANSMITTER, 258 HPI_CONTROL_AESEBUTX = 6, /* HPI_CONTROL_AESEBU_TRANSMITTER */
267 259
268 HPI_CONTROL_AESEBU_RECEIVER = 7, /**< AES/EBU receiver control. */ 260 HPI_CONTROL_AESEBU_RECEIVER = 7, /**< AES/EBU receiver control. */
269 HPI_CONTROL_AESEBURX = HPI_CONTROL_AESEBU_RECEIVER, 261 HPI_CONTROL_AESEBURX = 7, /* HPI_CONTROL_AESEBU_RECEIVER */
270 262
271 HPI_CONTROL_LEVEL = 8, /**< level/trim control - works in d_bu. */ 263 HPI_CONTROL_LEVEL = 8, /**< level/trim control - works in d_bu. */
272 HPI_CONTROL_TUNER = 9, /**< tuner control. */ 264 HPI_CONTROL_TUNER = 9, /**< tuner control. */
@@ -281,7 +273,7 @@ enum HPI_CONTROLS {
281 HPI_CONTROL_SAMPLECLOCK = 17, /**< sample clock control. */ 273 HPI_CONTROL_SAMPLECLOCK = 17, /**< sample clock control. */
282 HPI_CONTROL_MICROPHONE = 18, /**< microphone control. */ 274 HPI_CONTROL_MICROPHONE = 18, /**< microphone control. */
283 HPI_CONTROL_PARAMETRIC_EQ = 19, /**< parametric EQ control. */ 275 HPI_CONTROL_PARAMETRIC_EQ = 19, /**< parametric EQ control. */
284 HPI_CONTROL_EQUALIZER = HPI_CONTROL_PARAMETRIC_EQ, 276 HPI_CONTROL_EQUALIZER = 19, /*HPI_CONTROL_PARAMETRIC_EQ */
285 277
286 HPI_CONTROL_COMPANDER = 20, /**< compander control. */ 278 HPI_CONTROL_COMPANDER = 20, /**< compander control. */
287 HPI_CONTROL_COBRANET = 21, /**< cobranet control. */ 279 HPI_CONTROL_COBRANET = 21, /**< cobranet control. */
@@ -296,10 +288,7 @@ enum HPI_CONTROLS {
296/* WARNING types 256 or greater impact bit packing in all AX6 DSP code */ 288/* WARNING types 256 or greater impact bit packing in all AX6 DSP code */
297}; 289};
298 290
299/* Shorthand names that match attribute names */ 291/*******************************************/
300
301/******************************************* ADAPTER ATTRIBUTES ****/
302
303/** Adapter properties 292/** Adapter properties
304These are used in HPI_AdapterSetProperty() and HPI_AdapterGetProperty() 293These are used in HPI_AdapterSetProperty() and HPI_AdapterGetProperty()
305\ingroup adapter 294\ingroup adapter
@@ -330,12 +319,21 @@ by the driver and is not passed on to the DSP at all.
330Indicates the state of the adapter's SSX2 setting. This setting is stored in 319Indicates the state of the adapter's SSX2 setting. This setting is stored in
331non-volatile memory on the adapter. A typical call sequence would be to use 320non-volatile memory on the adapter. A typical call sequence would be to use
332HPI_ADAPTER_PROPERTY_SSX2_SETTING to set SSX2 on the adapter and then to reload 321HPI_ADAPTER_PROPERTY_SSX2_SETTING to set SSX2 on the adapter and then to reload
333the driver. The driver would query HPI_ADAPTER_PROPERTY_SSX2_SETTING during startup 322the driver. The driver would query HPI_ADAPTER_PROPERTY_SSX2_SETTING during
334and if SSX2 is set, it would then call HPI_ADAPTER_PROPERTY_ENABLE_SSX2 to enable 323startup and if SSX2 is set, it would then call HPI_ADAPTER_PROPERTY_ENABLE_SSX2
335SSX2 stream mapping within the kernel level of the driver. 324to enable SSX2 stream mapping within the kernel level of the driver.
336*/ 325*/
337 HPI_ADAPTER_PROPERTY_SSX2_SETTING = 4, 326 HPI_ADAPTER_PROPERTY_SSX2_SETTING = 4,
338 327
328/** Enables/disables PCI(e) IRQ.
329A setting of 0 indicates that no interrupts are being generated. A DSP boot
330this property is set to 0. Setting to a non-zero value specifies the number
331of frames of audio that should be processed between interrupts. This property
332should be set to multiple of the mixer interval as read back from the
333HPI_ADAPTER_PROPERTY_INTERVAL property.
334*/
335 HPI_ADAPTER_PROPERTY_IRQ_RATE = 5,
336
339/** Base number for readonly properties */ 337/** Base number for readonly properties */
340 HPI_ADAPTER_PROPERTY_READONLYBASE = 256, 338 HPI_ADAPTER_PROPERTY_READONLYBASE = 256,
341 339
@@ -440,21 +438,30 @@ return value is true (1) or false (0). If the current adapter
440mode is MONO SSX2 is disabled, even though this property will 438mode is MONO SSX2 is disabled, even though this property will
441return true. 439return true.
442*/ 440*/
443 HPI_ADAPTER_PROPERTY_SUPPORTS_SSX2 = 271 441 HPI_ADAPTER_PROPERTY_SUPPORTS_SSX2 = 271,
442/** Readonly supports PCI(e) IRQ.
443Indicates that the adapter in it's current mode supports interrupts
444across the host bus. Note, this does not imply that interrupts are
445enabled. Instead it indicates that they can be enabled.
446*/
447 HPI_ADAPTER_PROPERTY_SUPPORTS_IRQ = 272
444}; 448};
445 449
446/** Adapter mode commands 450/** Adapter mode commands
447 451
448Used in wQueryOrSet field of HPI_AdapterSetModeEx(). 452Used in wQueryOrSet parameter of HPI_AdapterSetModeEx().
449\ingroup adapter 453\ingroup adapter
450*/ 454*/
451enum HPI_ADAPTER_MODE_CMDS { 455enum HPI_ADAPTER_MODE_CMDS {
456 /** Set the mode to the given parameter */
452 HPI_ADAPTER_MODE_SET = 0, 457 HPI_ADAPTER_MODE_SET = 0,
458 /** Return 0 or error depending whether mode is valid,
459 but don't set the mode */
453 HPI_ADAPTER_MODE_QUERY = 1 460 HPI_ADAPTER_MODE_QUERY = 1
454}; 461};
455 462
456/** Adapter Modes 463/** Adapter Modes
457 These are used by HPI_AdapterSetModeEx() 464 These are used by HPI_AdapterSetModeEx()
458 465
459\warning - more than 16 possible modes breaks 466\warning - more than 16 possible modes breaks
460a bitmask in the Windows WAVE DLL 467a bitmask in the Windows WAVE DLL
@@ -629,10 +636,13 @@ enum HPI_MIXER_STORE_COMMAND {
629 HPI_MIXER_STORE_SAVE_SINGLE = 6 636 HPI_MIXER_STORE_SAVE_SINGLE = 6
630}; 637};
631 638
632/************************************* CONTROL ATTRIBUTE VALUES ****/ 639/****************************/
640/* CONTROL ATTRIBUTE VALUES */
641/****************************/
642
633/** Used by mixer plugin enable functions 643/** Used by mixer plugin enable functions
634 644
635E.g. HPI_ParametricEQ_SetState() 645E.g. HPI_ParametricEq_SetState()
636\ingroup mixer 646\ingroup mixer
637*/ 647*/
638enum HPI_SWITCH_STATES { 648enum HPI_SWITCH_STATES {
@@ -641,6 +651,7 @@ enum HPI_SWITCH_STATES {
641}; 651};
642 652
643/* Volume control special gain values */ 653/* Volume control special gain values */
654
644/** volumes units are 100ths of a dB 655/** volumes units are 100ths of a dB
645\ingroup volume 656\ingroup volume
646*/ 657*/
@@ -650,6 +661,11 @@ enum HPI_SWITCH_STATES {
650*/ 661*/
651#define HPI_GAIN_OFF (-100 * HPI_UNITS_PER_dB) 662#define HPI_GAIN_OFF (-100 * HPI_UNITS_PER_dB)
652 663
664/** channel mask specifying all channels
665\ingroup volume
666*/
667#define HPI_BITMASK_ALL_CHANNELS (0xFFFFFFFF)
668
653/** value returned for no signal 669/** value returned for no signal
654\ingroup meter 670\ingroup meter
655*/ 671*/
@@ -667,7 +683,7 @@ enum HPI_VOLUME_AUTOFADES {
667 683
668/** The physical encoding format of the AESEBU I/O. 684/** The physical encoding format of the AESEBU I/O.
669 685
670Used in HPI_AESEBU_Transmitter_SetFormat(), HPI_AESEBU_Receiver_SetFormat() 686Used in HPI_Aesebu_Transmitter_SetFormat(), HPI_Aesebu_Receiver_SetFormat()
671along with related Get and Query functions 687along with related Get and Query functions
672\ingroup aestx 688\ingroup aestx
673*/ 689*/
@@ -680,7 +696,7 @@ enum HPI_AESEBU_FORMATS {
680 696
681/** AES/EBU error status bits 697/** AES/EBU error status bits
682 698
683Returned by HPI_AESEBU_Receiver_GetErrorStatus() 699Returned by HPI_Aesebu_Receiver_GetErrorStatus()
684\ingroup aesrx 700\ingroup aesrx
685*/ 701*/
686enum HPI_AESEBU_ERRORS { 702enum HPI_AESEBU_ERRORS {
@@ -709,7 +725,7 @@ enum HPI_AESEBU_ERRORS {
709#define HPI_PAD_TITLE_LEN 64 725#define HPI_PAD_TITLE_LEN 64
710/** The text string containing the comment. */ 726/** The text string containing the comment. */
711#define HPI_PAD_COMMENT_LEN 256 727#define HPI_PAD_COMMENT_LEN 256
712/** The PTY when the tuner has not recieved any PTY. */ 728/** The PTY when the tuner has not received any PTY. */
713#define HPI_PAD_PROGRAM_TYPE_INVALID 0xffff 729#define HPI_PAD_PROGRAM_TYPE_INVALID 0xffff
714/** \} */ 730/** \} */
715 731
@@ -767,14 +783,6 @@ enum HPI_TUNER_MODE_VALUES {
767 HPI_TUNER_MODE_RDS_RBDS = 2 /**< RDS - RBDS mode */ 783 HPI_TUNER_MODE_RDS_RBDS = 2 /**< RDS - RBDS mode */
768}; 784};
769 785
770/** Tuner Level settings
771\ingroup tuner
772*/
773enum HPI_TUNER_LEVEL {
774 HPI_TUNER_LEVEL_AVERAGE = 0,
775 HPI_TUNER_LEVEL_RAW = 1
776};
777
778/** Tuner Status Bits 786/** Tuner Status Bits
779 787
780These bitfield values are returned by a call to HPI_Tuner_GetStatus(). 788These bitfield values are returned by a call to HPI_Tuner_GetStatus().
@@ -783,13 +791,13 @@ Multiple fields are returned from a single call.
783*/ 791*/
784enum HPI_TUNER_STATUS_BITS { 792enum HPI_TUNER_STATUS_BITS {
785 HPI_TUNER_VIDEO_COLOR_PRESENT = 0x0001, /**< video color is present. */ 793 HPI_TUNER_VIDEO_COLOR_PRESENT = 0x0001, /**< video color is present. */
786 HPI_TUNER_VIDEO_IS_60HZ = 0x0020, /**< 60 hz video detected. */ 794 HPI_TUNER_VIDEO_IS_60HZ = 0x0020, /**< 60 hz video detected. */
787 HPI_TUNER_VIDEO_HORZ_SYNC_MISSING = 0x0040, /**< video HSYNC is missing. */ 795 HPI_TUNER_VIDEO_HORZ_SYNC_MISSING = 0x0040, /**< video HSYNC is missing. */
788 HPI_TUNER_VIDEO_STATUS_VALID = 0x0100, /**< video status is valid. */ 796 HPI_TUNER_VIDEO_STATUS_VALID = 0x0100, /**< video status is valid. */
789 HPI_TUNER_PLL_LOCKED = 0x1000, /**< the tuner's PLL is locked. */ 797 HPI_TUNER_DIGITAL = 0x0200, /**< tuner reports digital programming. */
790 HPI_TUNER_FM_STEREO = 0x2000, /**< tuner reports back FM stereo. */ 798 HPI_TUNER_MULTIPROGRAM = 0x0400, /**< tuner reports multiple programs. */
791 HPI_TUNER_DIGITAL = 0x0200, /**< tuner reports digital programming. */ 799 HPI_TUNER_PLL_LOCKED = 0x1000, /**< the tuner's PLL is locked. */
792 HPI_TUNER_MULTIPROGRAM = 0x0400 /**< tuner reports multiple programs. */ 800 HPI_TUNER_FM_STEREO = 0x2000 /**< tuner reports back FM stereo. */
793}; 801};
794 802
795/** Channel Modes 803/** Channel Modes
@@ -839,7 +847,7 @@ enum HPI_SAMPLECLOCK_SOURCES {
839 HPI_SAMPLECLOCK_SOURCE_LAST = 10 847 HPI_SAMPLECLOCK_SOURCE_LAST = 10
840}; 848};
841 849
842/** Equalizer filter types. Used by HPI_ParametricEQ_SetBand() 850/** Equalizer filter types. Used by HPI_ParametricEq_SetBand()
843\ingroup parmeq 851\ingroup parmeq
844*/ 852*/
845enum HPI_FILTER_TYPE { 853enum HPI_FILTER_TYPE {
@@ -882,7 +890,7 @@ enum HPI_ERROR_CODES {
882 HPI_ERROR_INVALID_OBJ = 101, 890 HPI_ERROR_INVALID_OBJ = 101,
883 /** Function does not exist. */ 891 /** Function does not exist. */
884 HPI_ERROR_INVALID_FUNC = 102, 892 HPI_ERROR_INVALID_FUNC = 102,
885 /** The specified object (adapter/Stream) does not exist. */ 893 /** The specified object does not exist. */
886 HPI_ERROR_INVALID_OBJ_INDEX = 103, 894 HPI_ERROR_INVALID_OBJ_INDEX = 103,
887 /** Trying to access an object that has not been opened yet. */ 895 /** Trying to access an object that has not been opened yet. */
888 HPI_ERROR_OBJ_NOT_OPEN = 104, 896 HPI_ERROR_OBJ_NOT_OPEN = 104,
@@ -890,8 +898,7 @@ enum HPI_ERROR_CODES {
890 HPI_ERROR_OBJ_ALREADY_OPEN = 105, 898 HPI_ERROR_OBJ_ALREADY_OPEN = 105,
891 /** PCI, ISA resource not valid. */ 899 /** PCI, ISA resource not valid. */
892 HPI_ERROR_INVALID_RESOURCE = 106, 900 HPI_ERROR_INVALID_RESOURCE = 106,
893 /** GetInfo call from SubSysFindAdapters failed. */ 901 /* HPI_ERROR_SUBSYSFINDADAPTERS_GETINFO= 107 */
894 HPI_ERROR_SUBSYSFINDADAPTERS_GETINFO = 107,
895 /** Default response was never updated with actual error code. */ 902 /** Default response was never updated with actual error code. */
896 HPI_ERROR_INVALID_RESPONSE = 108, 903 HPI_ERROR_INVALID_RESPONSE = 108,
897 /** wSize field of response was not updated, 904 /** wSize field of response was not updated,
@@ -899,38 +906,44 @@ enum HPI_ERROR_CODES {
899 HPI_ERROR_PROCESSING_MESSAGE = 109, 906 HPI_ERROR_PROCESSING_MESSAGE = 109,
900 /** The network did not respond in a timely manner. */ 907 /** The network did not respond in a timely manner. */
901 HPI_ERROR_NETWORK_TIMEOUT = 110, 908 HPI_ERROR_NETWORK_TIMEOUT = 110,
902 /** An HPI handle is invalid (uninitialised?). */ 909 /* An HPI handle is invalid (uninitialised?). */
903 HPI_ERROR_INVALID_HANDLE = 111, 910 HPI_ERROR_INVALID_HANDLE = 111,
904 /** A function or attribute has not been implemented yet. */ 911 /** A function or attribute has not been implemented yet. */
905 HPI_ERROR_UNIMPLEMENTED = 112, 912 HPI_ERROR_UNIMPLEMENTED = 112,
906 /** There are too many clients attempting to access a network resource. */ 913 /** There are too many clients attempting
914 to access a network resource. */
907 HPI_ERROR_NETWORK_TOO_MANY_CLIENTS = 113, 915 HPI_ERROR_NETWORK_TOO_MANY_CLIENTS = 113,
908 /** Response buffer passed to HPI_Message was smaller than returned response */ 916 /** Response buffer passed to HPI_Message
917 was smaller than returned response.
918 wSpecificError field of hpi response contains the required size.
919 */
909 HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL = 114, 920 HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL = 114,
910 /** The returned response did not match the sent message */ 921 /** The returned response did not match the sent message */
911 HPI_ERROR_RESPONSE_MISMATCH = 115, 922 HPI_ERROR_RESPONSE_MISMATCH = 115,
923 /** A control setting that should have been cached was not. */
924 HPI_ERROR_CONTROL_CACHING = 116,
925 /** A message buffer in the path to the adapter was smaller
926 than the message size.
927 wSpecificError field of hpi response contains the actual size.
928 */
929 HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL = 117,
912 930
913 /** Too many adapters.*/ 931 /* HPI_ERROR_TOO_MANY_ADAPTERS= 200 */
914 HPI_ERROR_TOO_MANY_ADAPTERS = 200,
915 /** Bad adpater. */ 932 /** Bad adpater. */
916 HPI_ERROR_BAD_ADAPTER = 201, 933 HPI_ERROR_BAD_ADAPTER = 201,
917 /** Adapter number out of range or not set properly. */ 934 /** Adapter number out of range or not set properly. */
918 HPI_ERROR_BAD_ADAPTER_NUMBER = 202, 935 HPI_ERROR_BAD_ADAPTER_NUMBER = 202,
919 /** 2 adapters with the same adapter number. */ 936 /** 2 adapters with the same adapter number. */
920 HPI_DUPLICATE_ADAPTER_NUMBER = 203, 937 HPI_ERROR_DUPLICATE_ADAPTER_NUMBER = 203,
921 /** DSP code failed to bootload. */ 938 /** DSP code failed to bootload. (unused?) */
922 HPI_ERROR_DSP_BOOTLOAD = 204, 939 HPI_ERROR_DSP_BOOTLOAD = 204,
923 /** Adapter failed DSP code self test. */
924 HPI_ERROR_DSP_SELFTEST = 205,
925 /** Couldn't find or open the DSP code file. */ 940 /** Couldn't find or open the DSP code file. */
926 HPI_ERROR_DSP_FILE_NOT_FOUND = 206, 941 HPI_ERROR_DSP_FILE_NOT_FOUND = 206,
927 /** Internal DSP hardware error. */ 942 /** Internal DSP hardware error. */
928 HPI_ERROR_DSP_HARDWARE = 207, 943 HPI_ERROR_DSP_HARDWARE = 207,
929 /** Could not allocate memory in DOS. */
930 HPI_ERROR_DOS_MEMORY_ALLOC = 208,
931 /** Could not allocate memory */ 944 /** Could not allocate memory */
932 HPI_ERROR_MEMORY_ALLOC = 208, 945 HPI_ERROR_MEMORY_ALLOC = 208,
933 /** Failed to correctly load/config PLD .*/ 946 /** Failed to correctly load/config PLD. (unused) */
934 HPI_ERROR_PLD_LOAD = 209, 947 HPI_ERROR_PLD_LOAD = 209,
935 /** Unexpected end of file, block length too big etc. */ 948 /** Unexpected end of file, block length too big etc. */
936 HPI_ERROR_DSP_FILE_FORMAT = 210, 949 HPI_ERROR_DSP_FILE_FORMAT = 210,
@@ -939,8 +952,7 @@ enum HPI_ERROR_CODES {
939 HPI_ERROR_DSP_FILE_ACCESS_DENIED = 211, 952 HPI_ERROR_DSP_FILE_ACCESS_DENIED = 211,
940 /** First DSP code section header not found in DSP file. */ 953 /** First DSP code section header not found in DSP file. */
941 HPI_ERROR_DSP_FILE_NO_HEADER = 212, 954 HPI_ERROR_DSP_FILE_NO_HEADER = 212,
942 /** File read operation on DSP code file failed. */ 955 /* HPI_ERROR_DSP_FILE_READ_ERROR= 213, */
943 HPI_ERROR_DSP_FILE_READ_ERROR = 213,
944 /** DSP code for adapter family not found. */ 956 /** DSP code for adapter family not found. */
945 HPI_ERROR_DSP_SECTION_NOT_FOUND = 214, 957 HPI_ERROR_DSP_SECTION_NOT_FOUND = 214,
946 /** Other OS specific error opening DSP file. */ 958 /** Other OS specific error opening DSP file. */
@@ -950,23 +962,21 @@ enum HPI_ERROR_CODES {
950 /** DSP code section header had size == 0. */ 962 /** DSP code section header had size == 0. */
951 HPI_ERROR_DSP_FILE_NULL_HEADER = 217, 963 HPI_ERROR_DSP_FILE_NULL_HEADER = 217,
952 964
953 /** Base number for flash errors. */ 965 /* HPI_ERROR_FLASH = 220, */
954 HPI_ERROR_FLASH = 220,
955 966
956 /** Flash has bad checksum */ 967 /** Flash has bad checksum */
957 HPI_ERROR_BAD_CHECKSUM = (HPI_ERROR_FLASH + 1), 968 HPI_ERROR_BAD_CHECKSUM = 221,
958 HPI_ERROR_BAD_SEQUENCE = (HPI_ERROR_FLASH + 2), 969 HPI_ERROR_BAD_SEQUENCE = 222,
959 HPI_ERROR_FLASH_ERASE = (HPI_ERROR_FLASH + 3), 970 HPI_ERROR_FLASH_ERASE = 223,
960 HPI_ERROR_FLASH_PROGRAM = (HPI_ERROR_FLASH + 4), 971 HPI_ERROR_FLASH_PROGRAM = 224,
961 HPI_ERROR_FLASH_VERIFY = (HPI_ERROR_FLASH + 5), 972 HPI_ERROR_FLASH_VERIFY = 225,
962 HPI_ERROR_FLASH_TYPE = (HPI_ERROR_FLASH + 6), 973 HPI_ERROR_FLASH_TYPE = 226,
963 HPI_ERROR_FLASH_START = (HPI_ERROR_FLASH + 7), 974 HPI_ERROR_FLASH_START = 227,
964 975
965 /** Reserved for OEMs. */ 976 /** Reserved for OEMs. */
966 HPI_ERROR_RESERVED_1 = 290, 977 HPI_ERROR_RESERVED_1 = 290,
967 978
968 /** Stream does not exist. */ 979 /* HPI_ERROR_INVALID_STREAM = 300 use HPI_ERROR_INVALID_OBJ_INDEX */
969 HPI_ERROR_INVALID_STREAM = 300,
970 /** Invalid compression format. */ 980 /** Invalid compression format. */
971 HPI_ERROR_INVALID_FORMAT = 301, 981 HPI_ERROR_INVALID_FORMAT = 301,
972 /** Invalid format samplerate */ 982 /** Invalid format samplerate */
@@ -977,21 +987,19 @@ enum HPI_ERROR_CODES {
977 HPI_ERROR_INVALID_BITRATE = 304, 987 HPI_ERROR_INVALID_BITRATE = 304,
978 /** Invalid datasize used for stream read/write. */ 988 /** Invalid datasize used for stream read/write. */
979 HPI_ERROR_INVALID_DATASIZE = 305, 989 HPI_ERROR_INVALID_DATASIZE = 305,
980 /** Stream buffer is full during stream write. */ 990 /* HPI_ERROR_BUFFER_FULL = 306 use HPI_ERROR_INVALID_DATASIZE */
981 HPI_ERROR_BUFFER_FULL = 306, 991 /* HPI_ERROR_BUFFER_EMPTY = 307 use HPI_ERROR_INVALID_DATASIZE */
982 /** Stream buffer is empty during stream read. */ 992 /** Null data pointer used for stream read/write. */
983 HPI_ERROR_BUFFER_EMPTY = 307, 993 HPI_ERROR_INVALID_DATA_POINTER = 308,
984 /** Invalid datasize used for stream read/write. */
985 HPI_ERROR_INVALID_DATA_TRANSFER = 308,
986 /** Packet ordering error for stream read/write. */ 994 /** Packet ordering error for stream read/write. */
987 HPI_ERROR_INVALID_PACKET_ORDER = 309, 995 HPI_ERROR_INVALID_PACKET_ORDER = 309,
988 996
989 /** Object can't do requested operation in its current 997 /** Object can't do requested operation in its current
990 state, eg set format, change rec mux state while recording.*/ 998 state, eg set format, change rec mux state while recording.*/
991 HPI_ERROR_INVALID_OPERATION = 310, 999 HPI_ERROR_INVALID_OPERATION = 310,
992 1000
993 /** Where an SRG is shared amongst streams, an incompatible samplerate is one 1001 /** Where a SRG is shared amongst streams, an incompatible samplerate
994 that is different to any currently playing or recording stream. */ 1002 is one that is different to any currently active stream. */
995 HPI_ERROR_INCOMPATIBLE_SAMPLERATE = 311, 1003 HPI_ERROR_INCOMPATIBLE_SAMPLERATE = 311,
996 /** Adapter mode is illegal.*/ 1004 /** Adapter mode is illegal.*/
997 HPI_ERROR_BAD_ADAPTER_MODE = 312, 1005 HPI_ERROR_BAD_ADAPTER_MODE = 312,
@@ -1004,6 +1012,8 @@ enum HPI_ERROR_CODES {
1004 HPI_ERROR_NO_INTERADAPTER_GROUPS = 314, 1012 HPI_ERROR_NO_INTERADAPTER_GROUPS = 314,
1005 /** Streams on different DSPs cannot be grouped. */ 1013 /** Streams on different DSPs cannot be grouped. */
1006 HPI_ERROR_NO_INTERDSP_GROUPS = 315, 1014 HPI_ERROR_NO_INTERDSP_GROUPS = 315,
1015 /** Stream wait cancelled before threshold reached. */
1016 HPI_ERROR_WAIT_CANCELLED = 316,
1007 1017
1008 /** Invalid mixer node for this adapter. */ 1018 /** Invalid mixer node for this adapter. */
1009 HPI_ERROR_INVALID_NODE = 400, 1019 HPI_ERROR_INVALID_NODE = 400,
@@ -1017,6 +1027,7 @@ enum HPI_ERROR_CODES {
1017 HPI_ERROR_CONTROL_DISABLED = 404, 1027 HPI_ERROR_CONTROL_DISABLED = 404,
1018 /** I2C transaction failed due to a missing ACK. */ 1028 /** I2C transaction failed due to a missing ACK. */
1019 HPI_ERROR_CONTROL_I2C_MISSING_ACK = 405, 1029 HPI_ERROR_CONTROL_I2C_MISSING_ACK = 405,
1030 HPI_ERROR_I2C_MISSING_ACK = 405,
1020 /** Control is busy, or coming out of 1031 /** Control is busy, or coming out of
1021 reset and cannot be accessed at this time. */ 1032 reset and cannot be accessed at this time. */
1022 HPI_ERROR_CONTROL_NOT_READY = 407, 1033 HPI_ERROR_CONTROL_NOT_READY = 407,
@@ -1027,7 +1038,6 @@ enum HPI_ERROR_CODES {
1027 HPI_ERROR_NVMEM_FAIL = 452, 1038 HPI_ERROR_NVMEM_FAIL = 452,
1028 1039
1029 /** I2C */ 1040 /** I2C */
1030 HPI_ERROR_I2C_MISSING_ACK = HPI_ERROR_CONTROL_I2C_MISSING_ACK,
1031 HPI_ERROR_I2C_BAD_ADR = 460, 1041 HPI_ERROR_I2C_BAD_ADR = 460,
1032 1042
1033 /** Entity errors */ 1043 /** Entity errors */
@@ -1035,6 +1045,7 @@ enum HPI_ERROR_CODES {
1035 HPI_ERROR_ENTITY_ITEM_COUNT = 471, 1045 HPI_ERROR_ENTITY_ITEM_COUNT = 471,
1036 HPI_ERROR_ENTITY_TYPE_INVALID = 472, 1046 HPI_ERROR_ENTITY_TYPE_INVALID = 472,
1037 HPI_ERROR_ENTITY_ROLE_INVALID = 473, 1047 HPI_ERROR_ENTITY_ROLE_INVALID = 473,
1048 HPI_ERROR_ENTITY_SIZE_MISMATCH = 474,
1038 1049
1039 /* AES18 specific errors were 500..507 */ 1050 /* AES18 specific errors were 500..507 */
1040 1051
@@ -1044,11 +1055,18 @@ enum HPI_ERROR_CODES {
1044 /** hpioct32.c can't obtain mutex */ 1055 /** hpioct32.c can't obtain mutex */
1045 HPI_ERROR_MUTEX_TIMEOUT = 700, 1056 HPI_ERROR_MUTEX_TIMEOUT = 700,
1046 1057
1047 /** errors from HPI backends have values >= this */ 1058 /** Backend errors used to be greater than this.
1059 \deprecated Now, all backends return only errors defined here in hpi.h
1060 */
1048 HPI_ERROR_BACKEND_BASE = 900, 1061 HPI_ERROR_BACKEND_BASE = 900,
1049 1062
1050 /** indicates a cached u16 value is invalid. */ 1063 /** Communication with DSP failed */
1051 HPI_ERROR_ILLEGAL_CACHE_VALUE = 0xffff 1064 HPI_ERROR_DSP_COMMUNICATION = 900
1065 /* Note that the dsp communication error is set to this value so that
1066 it remains compatible with any software that expects such errors
1067 to be backend errors i.e. >= 900.
1068 Do not define any new error codes with values > 900.
1069 */
1052}; 1070};
1053 1071
1054/** \defgroup maximums HPI maximum values 1072/** \defgroup maximums HPI maximum values
@@ -1075,7 +1093,7 @@ enum HPI_ERROR_CODES {
1075 1093
1076/**\}*/ 1094/**\}*/
1077 1095
1078/* ////////////////////////////////////////////////////////////////////// */ 1096/**************/
1079/* STRUCTURES */ 1097/* STRUCTURES */
1080#ifndef DISABLE_PRAGMA_PACK1 1098#ifndef DISABLE_PRAGMA_PACK1
1081#pragma pack(push, 1) 1099#pragma pack(push, 1)
@@ -1092,7 +1110,7 @@ struct hpi_format {
1092 /**< Stereo/JointStereo/Mono */ 1110 /**< Stereo/JointStereo/Mono */
1093 u16 mode_legacy; 1111 u16 mode_legacy;
1094 /**< Legacy ancillary mode or idle bit */ 1112 /**< Legacy ancillary mode or idle bit */
1095 u16 unused; /**< unused */ 1113 u16 unused; /**< Unused */
1096 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */ 1114 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
1097 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */ 1115 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */
1098}; 1116};
@@ -1106,930 +1124,594 @@ struct hpi_anc_frame {
1106*/ 1124*/
1107struct hpi_async_event { 1125struct hpi_async_event {
1108 u16 event_type; /**< type of event. \sa async_event */ 1126 u16 event_type; /**< type of event. \sa async_event */
1109 u16 sequence; /**< sequence number, allows lost event detection */ 1127 u16 sequence; /**< Sequence number, allows lost event detection */
1110 u32 state; /**< new state */ 1128 u32 state; /**< New state */
1111 u32 h_object; /**< handle to the object returning the event. */ 1129 u32 h_object; /**< handle to the object returning the event. */
1112 union { 1130 union {
1113 struct { 1131 struct {
1114 u16 index; /**< GPIO bit index. */ 1132 u16 index; /**< GPIO bit index. */
1115 } gpio; 1133 } gpio;
1116 struct { 1134 struct {
1117 u16 node_index; /**< what node is the control on ? */ 1135 u16 node_index; /**< what node is the control on ? */
1118 u16 node_type; /**< what type of node is the control on ? */ 1136 u16 node_type; /**< what type of node is the control on ? */
1119 } control; 1137 } control;
1120 } u; 1138 } u;
1121}; 1139};
1122 1140
1123/*/////////////////////////////////////////////////////////////////////////// */
1124/* Public HPI Entity related definitions */
1125
1126struct hpi_entity;
1127
1128enum e_entity_type {
1129 entity_type_null,
1130 entity_type_sequence, /* sequence of potentially heterogeneous TLV entities */
1131
1132 entity_type_reference, /* refers to a TLV entity or NULL */
1133
1134 entity_type_int, /* 32 bit */
1135 entity_type_float, /* ieee754 binary 32 bit encoding */
1136 entity_type_double,
1137
1138 entity_type_cstring,
1139 entity_type_octet,
1140 entity_type_ip4_address,
1141 entity_type_ip6_address,
1142 entity_type_mac_address,
1143
1144 LAST_ENTITY_TYPE
1145};
1146
1147enum e_entity_role {
1148 entity_role_null,
1149 entity_role_value,
1150 entity_role_classname,
1151
1152 entity_role_units,
1153 entity_role_flags,
1154 entity_role_range,
1155
1156 entity_role_mapping,
1157 entity_role_enum,
1158
1159 entity_role_instance_of,
1160 entity_role_depends_on,
1161 entity_role_member_of_group,
1162 entity_role_value_constraint,
1163 entity_role_parameter_port,
1164
1165 entity_role_block,
1166 entity_role_node_group,
1167 entity_role_audio_port,
1168 entity_role_clock_port,
1169 LAST_ENTITY_ROLE
1170};
1171
1172/* skip host side function declarations for 1141/* skip host side function declarations for
1173 DSP compile and documentation extraction */ 1142 DSP compile and documentation extraction */
1174 1143
1175struct hpi_hsubsys {
1176 int not_really_used;
1177};
1178
1179#ifndef DISABLE_PRAGMA_PACK1 1144#ifndef DISABLE_PRAGMA_PACK1
1180#pragma pack(pop) 1145#pragma pack(pop)
1181#endif 1146#endif
1182 1147
1183/*////////////////////////////////////////////////////////////////////////// */ 1148/*****************/
1184/* HPI FUNCTIONS */ 1149/* HPI FUNCTIONS */
1150/*****************/
1185 1151
1186/*/////////////////////////// */ 1152/* Stream */
1187/* DATA and FORMAT and STREAM */
1188
1189u16 hpi_stream_estimate_buffer_size(struct hpi_format *pF, 1153u16 hpi_stream_estimate_buffer_size(struct hpi_format *pF,
1190 u32 host_polling_rate_in_milli_seconds, u32 *recommended_buffer_size); 1154 u32 host_polling_rate_in_milli_seconds, u32 *recommended_buffer_size);
1191 1155
1192/*/////////// */ 1156/*************/
1193/* SUB SYSTEM */ 1157/* SubSystem */
1194struct hpi_hsubsys *hpi_subsys_create(void 1158/*************/
1195 );
1196
1197void hpi_subsys_free(const struct hpi_hsubsys *ph_subsys);
1198
1199u16 hpi_subsys_get_version(const struct hpi_hsubsys *ph_subsys,
1200 u32 *pversion);
1201
1202u16 hpi_subsys_get_version_ex(const struct hpi_hsubsys *ph_subsys,
1203 u32 *pversion_ex);
1204
1205u16 hpi_subsys_get_info(const struct hpi_hsubsys *ph_subsys, u32 *pversion,
1206 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length);
1207
1208u16 hpi_subsys_find_adapters(const struct hpi_hsubsys *ph_subsys,
1209 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length);
1210
1211u16 hpi_subsys_get_num_adapters(const struct hpi_hsubsys *ph_subsys,
1212 int *pn_num_adapters);
1213
1214u16 hpi_subsys_get_adapter(const struct hpi_hsubsys *ph_subsys, int iterator,
1215 u32 *padapter_index, u16 *pw_adapter_type);
1216
1217u16 hpi_subsys_ssx2_bypass(const struct hpi_hsubsys *ph_subsys, u16 bypass);
1218 1159
1219u16 hpi_subsys_set_host_network_interface(const struct hpi_hsubsys *ph_subsys, 1160u16 hpi_subsys_get_version_ex(u32 *pversion_ex);
1220 const char *sz_interface);
1221 1161
1222/*///////// */ 1162u16 hpi_subsys_get_num_adapters(int *pn_num_adapters);
1223/* ADAPTER */
1224 1163
1225u16 hpi_adapter_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index); 1164u16 hpi_subsys_get_adapter(int iterator, u32 *padapter_index,
1165 u16 *pw_adapter_type);
1226 1166
1227u16 hpi_adapter_close(const struct hpi_hsubsys *ph_subsys, u16 adapter_index); 1167/***********/
1168/* Adapter */
1169/***********/
1228 1170
1229u16 hpi_adapter_get_info(const struct hpi_hsubsys *ph_subsys, 1171u16 hpi_adapter_open(u16 adapter_index);
1230 u16 adapter_index, u16 *pw_num_outstreams, u16 *pw_num_instreams,
1231 u16 *pw_version, u32 *pserial_number, u16 *pw_adapter_type);
1232 1172
1233u16 hpi_adapter_get_module_by_index(const struct hpi_hsubsys *ph_subsys, 1173u16 hpi_adapter_close(u16 adapter_index);
1234 u16 adapter_index, u16 module_index, u16 *pw_num_outputs,
1235 u16 *pw_num_inputs, u16 *pw_version, u32 *pserial_number,
1236 u16 *pw_module_type, u32 *ph_module);
1237 1174
1238u16 hpi_adapter_set_mode(const struct hpi_hsubsys *ph_subsys, 1175u16 hpi_adapter_get_info(u16 adapter_index, u16 *pw_num_outstreams,
1239 u16 adapter_index, u32 adapter_mode); 1176 u16 *pw_num_instreams, u16 *pw_version, u32 *pserial_number,
1177 u16 *pw_adapter_type);
1240 1178
1241u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys, 1179u16 hpi_adapter_get_module_by_index(u16 adapter_index, u16 module_index,
1242 u16 adapter_index, u32 adapter_mode, u16 query_or_set); 1180 u16 *pw_num_outputs, u16 *pw_num_inputs, u16 *pw_version,
1243 1181 u32 *pserial_number, u16 *pw_module_type, u32 *ph_module);
1244u16 hpi_adapter_get_mode(const struct hpi_hsubsys *ph_subsys,
1245 u16 adapter_index, u32 *padapter_mode);
1246
1247u16 hpi_adapter_get_assert(const struct hpi_hsubsys *ph_subsys,
1248 u16 adapter_index, u16 *assert_present, char *psz_assert,
1249 u16 *pw_line_number);
1250
1251u16 hpi_adapter_get_assert_ex(const struct hpi_hsubsys *ph_subsys,
1252 u16 adapter_index, u16 *assert_present, char *psz_assert,
1253 u32 *pline_number, u16 *pw_assert_on_dsp);
1254
1255u16 hpi_adapter_test_assert(const struct hpi_hsubsys *ph_subsys,
1256 u16 adapter_index, u16 assert_id);
1257
1258u16 hpi_adapter_enable_capability(const struct hpi_hsubsys *ph_subsys,
1259 u16 adapter_index, u16 capability, u32 key);
1260
1261u16 hpi_adapter_self_test(const struct hpi_hsubsys *ph_subsys,
1262 u16 adapter_index);
1263
1264u16 hpi_adapter_debug_read(const struct hpi_hsubsys *ph_subsys,
1265 u16 adapter_index, u32 dsp_address, char *p_bytes, int *count_bytes);
1266
1267u16 hpi_adapter_set_property(const struct hpi_hsubsys *ph_subsys,
1268 u16 adapter_index, u16 property, u16 paramter1, u16 paramter2);
1269
1270u16 hpi_adapter_get_property(const struct hpi_hsubsys *ph_subsys,
1271 u16 adapter_index, u16 property, u16 *pw_paramter1,
1272 u16 *pw_paramter2);
1273
1274u16 hpi_adapter_enumerate_property(const struct hpi_hsubsys *ph_subsys,
1275 u16 adapter_index, u16 index, u16 what_to_enumerate,
1276 u16 property_index, u32 *psetting);
1277
1278/*////////////// */
1279/* NonVol Memory */
1280u16 hpi_nv_memory_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1281 u32 *ph_nv_memory, u16 *pw_size_in_bytes);
1282
1283u16 hpi_nv_memory_read_byte(const struct hpi_hsubsys *ph_subsys,
1284 u32 h_nv_memory, u16 index, u16 *pw_data);
1285
1286u16 hpi_nv_memory_write_byte(const struct hpi_hsubsys *ph_subsys,
1287 u32 h_nv_memory, u16 index, u16 data);
1288
1289/*////////////// */
1290/* Digital I/O */
1291u16 hpi_gpio_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1292 u32 *ph_gpio, u16 *pw_number_input_bits, u16 *pw_number_output_bits);
1293
1294u16 hpi_gpio_read_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1295 u16 bit_index, u16 *pw_bit_data);
1296
1297u16 hpi_gpio_read_all_bits(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1298 u16 aw_all_bit_data[4]
1299 );
1300 1182
1301u16 hpi_gpio_write_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio, 1183u16 hpi_adapter_set_mode(u16 adapter_index, u32 adapter_mode);
1302 u16 bit_index, u16 bit_data);
1303 1184
1304u16 hpi_gpio_write_status(const struct hpi_hsubsys *ph_subsys, u32 h_gpio, 1185u16 hpi_adapter_set_mode_ex(u16 adapter_index, u32 adapter_mode,
1305 u16 aw_all_bit_data[4] 1186 u16 query_or_set);
1306 );
1307 1187
1308/**********************/ 1188u16 hpi_adapter_get_mode(u16 adapter_index, u32 *padapter_mode);
1309/* Async Event Object */
1310/**********************/
1311u16 hpi_async_event_open(const struct hpi_hsubsys *ph_subsys,
1312 u16 adapter_index, u32 *ph_async);
1313 1189
1314u16 hpi_async_event_close(const struct hpi_hsubsys *ph_subsys, u32 h_async); 1190u16 hpi_adapter_get_assert2(u16 adapter_index, u16 *p_assert_count,
1191 char *psz_assert, u32 *p_param1, u32 *p_param2,
1192 u32 *p_dsp_string_addr, u16 *p_processor_id);
1315 1193
1316u16 hpi_async_event_wait(const struct hpi_hsubsys *ph_subsys, u32 h_async, 1194u16 hpi_adapter_test_assert(u16 adapter_index, u16 assert_id);
1317 u16 maximum_events, struct hpi_async_event *p_events,
1318 u16 *pw_number_returned);
1319 1195
1320u16 hpi_async_event_get_count(const struct hpi_hsubsys *ph_subsys, 1196u16 hpi_adapter_enable_capability(u16 adapter_index, u16 capability, u32 key);
1321 u32 h_async, u16 *pw_count);
1322 1197
1323u16 hpi_async_event_get(const struct hpi_hsubsys *ph_subsys, u32 h_async, 1198u16 hpi_adapter_self_test(u16 adapter_index);
1324 u16 maximum_events, struct hpi_async_event *p_events,
1325 u16 *pw_number_returned);
1326 1199
1327/*/////////// */ 1200u16 hpi_adapter_debug_read(u16 adapter_index, u32 dsp_address, char *p_bytes,
1328/* WATCH-DOG */ 1201 int *count_bytes);
1329u16 hpi_watchdog_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1330 u32 *ph_watchdog);
1331 1202
1332u16 hpi_watchdog_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog, 1203u16 hpi_adapter_set_property(u16 adapter_index, u16 property, u16 paramter1,
1333 u32 time_millisec); 1204 u16 paramter2);
1334 1205
1335u16 hpi_watchdog_ping(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog); 1206u16 hpi_adapter_get_property(u16 adapter_index, u16 property,
1207 u16 *pw_paramter1, u16 *pw_paramter2);
1336 1208
1337/**************/ 1209u16 hpi_adapter_enumerate_property(u16 adapter_index, u16 index,
1338/* OUT STREAM */ 1210 u16 what_to_enumerate, u16 property_index, u32 *psetting);
1339/**************/ 1211/*************/
1340u16 hpi_outstream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index, 1212/* OutStream */
1341 u16 outstream_index, u32 *ph_outstream); 1213/*************/
1214u16 hpi_outstream_open(u16 adapter_index, u16 outstream_index,
1215 u32 *ph_outstream);
1342 1216
1343u16 hpi_outstream_close(const struct hpi_hsubsys *ph_subsys, u32 h_outstream); 1217u16 hpi_outstream_close(u32 h_outstream);
1344 1218
1345u16 hpi_outstream_get_info_ex(const struct hpi_hsubsys *ph_subsys, 1219u16 hpi_outstream_get_info_ex(u32 h_outstream, u16 *pw_state,
1346 u32 h_outstream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_to_play, 1220 u32 *pbuffer_size, u32 *pdata_to_play, u32 *psamples_played,
1347 u32 *psamples_played, u32 *pauxiliary_data_to_play); 1221 u32 *pauxiliary_data_to_play);
1348 1222
1349u16 hpi_outstream_write_buf(const struct hpi_hsubsys *ph_subsys, 1223u16 hpi_outstream_write_buf(u32 h_outstream, const u8 *pb_write_buf,
1350 u32 h_outstream, const u8 *pb_write_buf, u32 bytes_to_write, 1224 u32 bytes_to_write, const struct hpi_format *p_format);
1351 const struct hpi_format *p_format);
1352 1225
1353u16 hpi_outstream_start(const struct hpi_hsubsys *ph_subsys, u32 h_outstream); 1226u16 hpi_outstream_start(u32 h_outstream);
1354 1227
1355u16 hpi_outstream_wait_start(const struct hpi_hsubsys *ph_subsys, 1228u16 hpi_outstream_wait_start(u32 h_outstream);
1356 u32 h_outstream);
1357 1229
1358u16 hpi_outstream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_outstream); 1230u16 hpi_outstream_stop(u32 h_outstream);
1359 1231
1360u16 hpi_outstream_sinegen(const struct hpi_hsubsys *ph_subsys, 1232u16 hpi_outstream_sinegen(u32 h_outstream);
1361 u32 h_outstream);
1362 1233
1363u16 hpi_outstream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_outstream); 1234u16 hpi_outstream_reset(u32 h_outstream);
1364 1235
1365u16 hpi_outstream_query_format(const struct hpi_hsubsys *ph_subsys, 1236u16 hpi_outstream_query_format(u32 h_outstream, struct hpi_format *p_format);
1366 u32 h_outstream, struct hpi_format *p_format);
1367 1237
1368u16 hpi_outstream_set_format(const struct hpi_hsubsys *ph_subsys, 1238u16 hpi_outstream_set_format(u32 h_outstream, struct hpi_format *p_format);
1369 u32 h_outstream, struct hpi_format *p_format);
1370 1239
1371u16 hpi_outstream_set_punch_in_out(const struct hpi_hsubsys *ph_subsys, 1240u16 hpi_outstream_set_punch_in_out(u32 h_outstream, u32 punch_in_sample,
1372 u32 h_outstream, u32 punch_in_sample, u32 punch_out_sample); 1241 u32 punch_out_sample);
1373 1242
1374u16 hpi_outstream_set_velocity(const struct hpi_hsubsys *ph_subsys, 1243u16 hpi_outstream_set_velocity(u32 h_outstream, short velocity);
1375 u32 h_outstream, short velocity);
1376 1244
1377u16 hpi_outstream_ancillary_reset(const struct hpi_hsubsys *ph_subsys, 1245u16 hpi_outstream_ancillary_reset(u32 h_outstream, u16 mode);
1378 u32 h_outstream, u16 mode);
1379 1246
1380u16 hpi_outstream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys, 1247u16 hpi_outstream_ancillary_get_info(u32 h_outstream, u32 *pframes_available);
1381 u32 h_outstream, u32 *pframes_available);
1382 1248
1383u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys, 1249u16 hpi_outstream_ancillary_read(u32 h_outstream,
1384 u32 h_outstream, struct hpi_anc_frame *p_anc_frame_buffer, 1250 struct hpi_anc_frame *p_anc_frame_buffer,
1385 u32 anc_frame_buffer_size_in_bytes, 1251 u32 anc_frame_buffer_size_in_bytes,
1386 u32 number_of_ancillary_frames_to_read); 1252 u32 number_of_ancillary_frames_to_read);
1387 1253
1388u16 hpi_outstream_set_time_scale(const struct hpi_hsubsys *ph_subsys, 1254u16 hpi_outstream_set_time_scale(u32 h_outstream, u32 time_scaleX10000);
1389 u32 h_outstream, u32 time_scaleX10000);
1390 1255
1391u16 hpi_outstream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys, 1256u16 hpi_outstream_host_buffer_allocate(u32 h_outstream, u32 size_in_bytes);
1392 u32 h_outstream, u32 size_in_bytes);
1393 1257
1394u16 hpi_outstream_host_buffer_free(const struct hpi_hsubsys *ph_subsys, 1258u16 hpi_outstream_host_buffer_free(u32 h_outstream);
1395 u32 h_outstream);
1396 1259
1397u16 hpi_outstream_group_add(const struct hpi_hsubsys *ph_subsys, 1260u16 hpi_outstream_group_add(u32 h_outstream, u32 h_stream);
1398 u32 h_outstream, u32 h_stream);
1399 1261
1400u16 hpi_outstream_group_get_map(const struct hpi_hsubsys *ph_subsys, 1262u16 hpi_outstream_group_get_map(u32 h_outstream, u32 *poutstream_map,
1401 u32 h_outstream, u32 *poutstream_map, u32 *pinstream_map); 1263 u32 *pinstream_map);
1402 1264
1403u16 hpi_outstream_group_reset(const struct hpi_hsubsys *ph_subsys, 1265u16 hpi_outstream_group_reset(u32 h_outstream);
1404 u32 h_outstream);
1405 1266
1406/*////////// */ 1267/************/
1407/* IN_STREAM */ 1268/* InStream */
1408u16 hpi_instream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index, 1269/************/
1409 u16 instream_index, u32 *ph_instream); 1270u16 hpi_instream_open(u16 adapter_index, u16 instream_index,
1271 u32 *ph_instream);
1410 1272
1411u16 hpi_instream_close(const struct hpi_hsubsys *ph_subsys, u32 h_instream); 1273u16 hpi_instream_close(u32 h_instream);
1412 1274
1413u16 hpi_instream_query_format(const struct hpi_hsubsys *ph_subsys, 1275u16 hpi_instream_query_format(u32 h_instream,
1414 u32 h_instream, const struct hpi_format *p_format); 1276 const struct hpi_format *p_format);
1415 1277
1416u16 hpi_instream_set_format(const struct hpi_hsubsys *ph_subsys, 1278u16 hpi_instream_set_format(u32 h_instream,
1417 u32 h_instream, const struct hpi_format *p_format); 1279 const struct hpi_format *p_format);
1418 1280
1419u16 hpi_instream_read_buf(const struct hpi_hsubsys *ph_subsys, u32 h_instream, 1281u16 hpi_instream_read_buf(u32 h_instream, u8 *pb_read_buf, u32 bytes_to_read);
1420 u8 *pb_read_buf, u32 bytes_to_read);
1421 1282
1422u16 hpi_instream_start(const struct hpi_hsubsys *ph_subsys, u32 h_instream); 1283u16 hpi_instream_start(u32 h_instream);
1423 1284
1424u16 hpi_instream_wait_start(const struct hpi_hsubsys *ph_subsys, 1285u16 hpi_instream_wait_start(u32 h_instream);
1425 u32 h_instream);
1426 1286
1427u16 hpi_instream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_instream); 1287u16 hpi_instream_stop(u32 h_instream);
1428 1288
1429u16 hpi_instream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_instream); 1289u16 hpi_instream_reset(u32 h_instream);
1430 1290
1431u16 hpi_instream_get_info_ex(const struct hpi_hsubsys *ph_subsys, 1291u16 hpi_instream_get_info_ex(u32 h_instream, u16 *pw_state, u32 *pbuffer_size,
1432 u32 h_instream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_recorded, 1292 u32 *pdata_recorded, u32 *psamples_recorded,
1433 u32 *psamples_recorded, u32 *pauxiliary_data_recorded); 1293 u32 *pauxiliary_data_recorded);
1434 1294
1435u16 hpi_instream_ancillary_reset(const struct hpi_hsubsys *ph_subsys, 1295u16 hpi_instream_ancillary_reset(u32 h_instream, u16 bytes_per_frame,
1436 u32 h_instream, u16 bytes_per_frame, u16 mode, u16 alignment, 1296 u16 mode, u16 alignment, u16 idle_bit);
1437 u16 idle_bit);
1438 1297
1439u16 hpi_instream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys, 1298u16 hpi_instream_ancillary_get_info(u32 h_instream, u32 *pframe_space);
1440 u32 h_instream, u32 *pframe_space);
1441 1299
1442u16 hpi_instream_ancillary_write(const struct hpi_hsubsys *ph_subsys, 1300u16 hpi_instream_ancillary_write(u32 h_instream,
1443 u32 h_instream, const struct hpi_anc_frame *p_anc_frame_buffer, 1301 const struct hpi_anc_frame *p_anc_frame_buffer,
1444 u32 anc_frame_buffer_size_in_bytes, 1302 u32 anc_frame_buffer_size_in_bytes,
1445 u32 number_of_ancillary_frames_to_write); 1303 u32 number_of_ancillary_frames_to_write);
1446 1304
1447u16 hpi_instream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys, 1305u16 hpi_instream_host_buffer_allocate(u32 h_instream, u32 size_in_bytes);
1448 u32 h_instream, u32 size_in_bytes);
1449 1306
1450u16 hpi_instream_host_buffer_free(const struct hpi_hsubsys *ph_subsys, 1307u16 hpi_instream_host_buffer_free(u32 h_instream);
1451 u32 h_instream);
1452 1308
1453u16 hpi_instream_group_add(const struct hpi_hsubsys *ph_subsys, 1309u16 hpi_instream_group_add(u32 h_instream, u32 h_stream);
1454 u32 h_instream, u32 h_stream);
1455 1310
1456u16 hpi_instream_group_get_map(const struct hpi_hsubsys *ph_subsys, 1311u16 hpi_instream_group_get_map(u32 h_instream, u32 *poutstream_map,
1457 u32 h_instream, u32 *poutstream_map, u32 *pinstream_map); 1312 u32 *pinstream_map);
1458 1313
1459u16 hpi_instream_group_reset(const struct hpi_hsubsys *ph_subsys, 1314u16 hpi_instream_group_reset(u32 h_instream);
1460 u32 h_instream);
1461 1315
1462/*********/ 1316/*********/
1463/* MIXER */ 1317/* Mixer */
1464/*********/ 1318/*********/
1465u16 hpi_mixer_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index, 1319u16 hpi_mixer_open(u16 adapter_index, u32 *ph_mixer);
1466 u32 *ph_mixer); 1320
1467 1321u16 hpi_mixer_close(u32 h_mixer);
1468u16 hpi_mixer_close(const struct hpi_hsubsys *ph_subsys, u32 h_mixer); 1322
1469 1323u16 hpi_mixer_get_control(u32 h_mixer, u16 src_node_type,
1470u16 hpi_mixer_get_control(const struct hpi_hsubsys *ph_subsys, u32 h_mixer, 1324 u16 src_node_type_index, u16 dst_node_type, u16 dst_node_type_index,
1471 u16 src_node_type, u16 src_node_type_index, u16 dst_node_type, 1325 u16 control_type, u32 *ph_control);
1472 u16 dst_node_type_index, u16 control_type, u32 *ph_control); 1326
1473 1327u16 hpi_mixer_get_control_by_index(u32 h_mixer, u16 control_index,
1474u16 hpi_mixer_get_control_by_index(const struct hpi_hsubsys *ph_subsys, 1328 u16 *pw_src_node_type, u16 *pw_src_node_index, u16 *pw_dst_node_type,
1475 u32 h_mixer, u16 control_index, u16 *pw_src_node_type, 1329 u16 *pw_dst_node_index, u16 *pw_control_type, u32 *ph_control);
1476 u16 *pw_src_node_index, u16 *pw_dst_node_type, u16 *pw_dst_node_index, 1330
1477 u16 *pw_control_type, u32 *ph_control); 1331u16 hpi_mixer_store(u32 h_mixer, enum HPI_MIXER_STORE_COMMAND command,
1478 1332 u16 index);
1479u16 hpi_mixer_store(const struct hpi_hsubsys *ph_subsys, u32 h_mixer, 1333/************/
1480 enum HPI_MIXER_STORE_COMMAND command, u16 index); 1334/* Controls */
1481/*************************/ 1335/************/
1482/* mixer CONTROLS */ 1336/******************/
1483/*************************/ 1337/* Volume control */
1484/*************************/ 1338/******************/
1485/* volume control */ 1339u16 hpi_volume_set_gain(u32 h_control, short an_gain0_01dB[HPI_MAX_CHANNELS]
1486/*************************/
1487u16 hpi_volume_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1488 short an_gain0_01dB[HPI_MAX_CHANNELS]
1489 ); 1340 );
1490 1341
1491u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1342u16 hpi_volume_get_gain(u32 h_control,
1492 short an_gain0_01dB_out[HPI_MAX_CHANNELS] 1343 short an_gain0_01dB_out[HPI_MAX_CHANNELS]
1493 ); 1344 );
1494 1345
1346u16 hpi_volume_set_mute(u32 h_control, u32 mute);
1347
1348u16 hpi_volume_get_mute(u32 h_control, u32 *mute);
1349
1495#define hpi_volume_get_range hpi_volume_query_range 1350#define hpi_volume_get_range hpi_volume_query_range
1496u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1351u16 hpi_volume_query_range(u32 h_control, short *min_gain_01dB,
1497 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB); 1352 short *max_gain_01dB, short *step_gain_01dB);
1498 1353
1499u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys, 1354u16 hpi_volume_query_channels(const u32 h_volume, u32 *p_channels);
1500 const u32 h_volume, u32 *p_channels);
1501 1355
1502u16 hpi_volume_auto_fade(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1356u16 hpi_volume_auto_fade(u32 h_control,
1503 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms); 1357 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms);
1504 1358
1505u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys, 1359u16 hpi_volume_auto_fade_profile(u32 h_control,
1506 u32 h_control, short an_stop_gain0_01dB[HPI_MAX_CHANNELS], 1360 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms,
1507 u32 duration_ms, u16 profile); 1361 u16 profile);
1508 1362
1509/*************************/ 1363/*****************/
1510/* level control */ 1364/* Level control */
1511/*************************/ 1365/*****************/
1512u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1366u16 hpi_level_query_range(u32 h_control, short *min_gain_01dB,
1513 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB); 1367 short *max_gain_01dB, short *step_gain_01dB);
1514 1368
1515u16 hpi_level_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1369u16 hpi_level_set_gain(u32 h_control, short an_gain0_01dB[HPI_MAX_CHANNELS]
1516 short an_gain0_01dB[HPI_MAX_CHANNELS]
1517 ); 1370 );
1518 1371
1519u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1372u16 hpi_level_get_gain(u32 h_control,
1520 short an_gain0_01dB_out[HPI_MAX_CHANNELS] 1373 short an_gain0_01dB_out[HPI_MAX_CHANNELS]
1521 ); 1374 );
1522 1375
1523/*************************/ 1376/*****************/
1524/* meter control */ 1377/* Meter control */
1525/*************************/ 1378/*****************/
1526u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys, 1379u16 hpi_meter_query_channels(const u32 h_meter, u32 *p_channels);
1527 const u32 h_meter, u32 *p_channels);
1528 1380
1529u16 hpi_meter_get_peak(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1381u16 hpi_meter_get_peak(u32 h_control,
1530 short an_peak0_01dB_out[HPI_MAX_CHANNELS] 1382 short an_peak0_01dB_out[HPI_MAX_CHANNELS]
1531 ); 1383 );
1532 1384
1533u16 hpi_meter_get_rms(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1385u16 hpi_meter_get_rms(u32 h_control, short an_peak0_01dB_out[HPI_MAX_CHANNELS]
1534 short an_peak0_01dB_out[HPI_MAX_CHANNELS]
1535 ); 1386 );
1536 1387
1537u16 hpi_meter_set_peak_ballistics(const struct hpi_hsubsys *ph_subsys, 1388u16 hpi_meter_set_peak_ballistics(u32 h_control, u16 attack, u16 decay);
1538 u32 h_control, u16 attack, u16 decay);
1539 1389
1540u16 hpi_meter_set_rms_ballistics(const struct hpi_hsubsys *ph_subsys, 1390u16 hpi_meter_set_rms_ballistics(u32 h_control, u16 attack, u16 decay);
1541 u32 h_control, u16 attack, u16 decay);
1542 1391
1543u16 hpi_meter_get_peak_ballistics(const struct hpi_hsubsys *ph_subsys, 1392u16 hpi_meter_get_peak_ballistics(u32 h_control, u16 *attack, u16 *decay);
1544 u32 h_control, u16 *attack, u16 *decay);
1545 1393
1546u16 hpi_meter_get_rms_ballistics(const struct hpi_hsubsys *ph_subsys, 1394u16 hpi_meter_get_rms_ballistics(u32 h_control, u16 *attack, u16 *decay);
1547 u32 h_control, u16 *attack, u16 *decay);
1548 1395
1549/*************************/ 1396/************************/
1550/* channel mode control */ 1397/* ChannelMode control */
1551/*************************/ 1398/************************/
1552u16 hpi_channel_mode_query_mode(const struct hpi_hsubsys *ph_subsys, 1399u16 hpi_channel_mode_query_mode(const u32 h_mode, const u32 index,
1553 const u32 h_mode, const u32 index, u16 *pw_mode); 1400 u16 *pw_mode);
1554 1401
1555u16 hpi_channel_mode_set(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1402u16 hpi_channel_mode_set(u32 h_control, u16 mode);
1556 u16 mode);
1557 1403
1558u16 hpi_channel_mode_get(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1404u16 hpi_channel_mode_get(u32 h_control, u16 *mode);
1559 u16 *mode);
1560 1405
1561/*************************/ 1406/*****************/
1562/* Tuner control */ 1407/* Tuner control */
1563/*************************/ 1408/*****************/
1564u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys, 1409u16 hpi_tuner_query_band(const u32 h_tuner, const u32 index, u16 *pw_band);
1565 const u32 h_tuner, const u32 index, u16 *pw_band);
1566 1410
1567u16 hpi_tuner_set_band(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1411u16 hpi_tuner_set_band(u32 h_control, u16 band);
1568 u16 band);
1569 1412
1570u16 hpi_tuner_get_band(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1413u16 hpi_tuner_get_band(u32 h_control, u16 *pw_band);
1571 u16 *pw_band);
1572 1414
1573u16 hpi_tuner_query_frequency(const struct hpi_hsubsys *ph_subsys, 1415u16 hpi_tuner_query_frequency(const u32 h_tuner, const u32 index,
1574 const u32 h_tuner, const u32 index, const u16 band, u32 *pfreq); 1416 const u16 band, u32 *pfreq);
1575 1417
1576u16 hpi_tuner_set_frequency(const struct hpi_hsubsys *ph_subsys, 1418u16 hpi_tuner_set_frequency(u32 h_control, u32 freq_ink_hz);
1577 u32 h_control, u32 freq_ink_hz);
1578 1419
1579u16 hpi_tuner_get_frequency(const struct hpi_hsubsys *ph_subsys, 1420u16 hpi_tuner_get_frequency(u32 h_control, u32 *pw_freq_ink_hz);
1580 u32 h_control, u32 *pw_freq_ink_hz);
1581 1421
1582u16 hpi_tuner_getRF_level(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1422u16 hpi_tuner_get_rf_level(u32 h_control, short *pw_level);
1583 short *pw_level);
1584 1423
1585u16 hpi_tuner_get_rawRF_level(const struct hpi_hsubsys *ph_subsys, 1424u16 hpi_tuner_get_raw_rf_level(u32 h_control, short *pw_level);
1586 u32 h_control, short *pw_level);
1587 1425
1588u16 hpi_tuner_query_gain(const struct hpi_hsubsys *ph_subsys, 1426u16 hpi_tuner_query_gain(const u32 h_tuner, const u32 index, u16 *pw_gain);
1589 const u32 h_tuner, const u32 index, u16 *pw_gain);
1590 1427
1591u16 hpi_tuner_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1428u16 hpi_tuner_set_gain(u32 h_control, short gain);
1592 short gain);
1593 1429
1594u16 hpi_tuner_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1430u16 hpi_tuner_get_gain(u32 h_control, short *pn_gain);
1595 short *pn_gain);
1596 1431
1597u16 hpi_tuner_get_status(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1432u16 hpi_tuner_get_status(u32 h_control, u16 *pw_status_mask, u16 *pw_status);
1598 u16 *pw_status_mask, u16 *pw_status);
1599 1433
1600u16 hpi_tuner_set_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1434u16 hpi_tuner_set_mode(u32 h_control, u32 mode, u32 value);
1601 u32 mode, u32 value);
1602 1435
1603u16 hpi_tuner_get_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1436u16 hpi_tuner_get_mode(u32 h_control, u32 mode, u32 *pn_value);
1604 u32 mode, u32 *pn_value);
1605 1437
1606u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1438u16 hpi_tuner_get_rds(u32 h_control, char *p_rds_data);
1607 char *p_rds_data);
1608 1439
1609u16 hpi_tuner_query_deemphasis(const struct hpi_hsubsys *ph_subsys, 1440u16 hpi_tuner_query_deemphasis(const u32 h_tuner, const u32 index,
1610 const u32 h_tuner, const u32 index, const u16 band, u32 *pdeemphasis); 1441 const u16 band, u32 *pdeemphasis);
1611 1442
1612u16 hpi_tuner_set_deemphasis(const struct hpi_hsubsys *ph_subsys, 1443u16 hpi_tuner_set_deemphasis(u32 h_control, u32 deemphasis);
1613 u32 h_control, u32 deemphasis); 1444u16 hpi_tuner_get_deemphasis(u32 h_control, u32 *pdeemphasis);
1614u16 hpi_tuner_get_deemphasis(const struct hpi_hsubsys *ph_subsys,
1615 u32 h_control, u32 *pdeemphasis);
1616 1445
1617u16 hpi_tuner_query_program(const struct hpi_hsubsys *ph_subsys, 1446u16 hpi_tuner_query_program(const u32 h_tuner, u32 *pbitmap_program);
1618 const u32 h_tuner, u32 *pbitmap_program);
1619 1447
1620u16 hpi_tuner_set_program(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1448u16 hpi_tuner_set_program(u32 h_control, u32 program);
1621 u32 program);
1622 1449
1623u16 hpi_tuner_get_program(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1450u16 hpi_tuner_get_program(u32 h_control, u32 *pprogram);
1624 u32 *pprogram);
1625 1451
1626u16 hpi_tuner_get_hd_radio_dsp_version(const struct hpi_hsubsys *ph_subsys, 1452u16 hpi_tuner_get_hd_radio_dsp_version(u32 h_control, char *psz_dsp_version,
1627 u32 h_control, char *psz_dsp_version, const u32 string_size); 1453 const u32 string_size);
1628 1454
1629u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys, 1455u16 hpi_tuner_get_hd_radio_sdk_version(u32 h_control, char *psz_sdk_version,
1630 u32 h_control, char *psz_sdk_version, const u32 string_size); 1456 const u32 string_size);
1631 1457
1632u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys, 1458u16 hpi_tuner_get_hd_radio_signal_quality(u32 h_control, u32 *pquality);
1633 u32 h_control, u32 *pquality);
1634 1459
1635u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, 1460u16 hpi_tuner_get_hd_radio_signal_blend(u32 h_control, u32 *pblend);
1636 u32 h_control, u32 *pblend);
1637 1461
1638u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, 1462u16 hpi_tuner_set_hd_radio_signal_blend(u32 h_control, const u32 blend);
1639 u32 h_control, const u32 blend);
1640 1463
1641/****************************/ 1464/***************/
1642/* PADs control */ 1465/* PAD control */
1643/****************************/ 1466/***************/
1644 1467
1645u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys, 1468u16 hpi_pad_get_channel_name(u32 h_control, char *psz_string,
1646 u32 h_control, char *psz_string, const u32 string_length); 1469 const u32 string_length);
1647 1470
1648u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1471u16 hpi_pad_get_artist(u32 h_control, char *psz_string,
1649 char *psz_string, const u32 string_length); 1472 const u32 string_length);
1650 1473
1651u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1474u16 hpi_pad_get_title(u32 h_control, char *psz_string,
1652 char *psz_string, const u32 string_length); 1475 const u32 string_length);
1653 1476
1654u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1477u16 hpi_pad_get_comment(u32 h_control, char *psz_string,
1655 char *psz_string, const u32 string_length); 1478 const u32 string_length);
1656 1479
1657u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys, 1480u16 hpi_pad_get_program_type(u32 h_control, u32 *ppTY);
1658 u32 h_control, u32 *ppTY);
1659 1481
1660u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1482u16 hpi_pad_get_rdsPI(u32 h_control, u32 *ppI);
1661 u32 *ppI);
1662 1483
1663u16 HPI_PAD__get_program_type_string(const struct hpi_hsubsys *ph_subsys, 1484u16 hpi_pad_get_program_type_string(u32 h_control, const u32 data_type,
1664 u32 h_control, const u32 data_type, const u32 pTY, char *psz_string, 1485 const u32 pTY, char *psz_string, const u32 string_length);
1665 const u32 string_length);
1666 1486
1667/****************************/ 1487/****************************/
1668/* AES/EBU Receiver control */ 1488/* AES/EBU Receiver control */
1669/****************************/ 1489/****************************/
1670u16 HPI_AESEBU__receiver_query_format(const struct hpi_hsubsys *ph_subsys, 1490u16 hpi_aesebu_receiver_query_format(const u32 h_aes_rx, const u32 index,
1671 const u32 h_aes_rx, const u32 index, u16 *pw_format); 1491 u16 *pw_format);
1672 1492
1673u16 HPI_AESEBU__receiver_set_format(const struct hpi_hsubsys *ph_subsys, 1493u16 hpi_aesebu_receiver_set_format(u32 h_control, u16 source);
1674 u32 h_control, u16 source);
1675 1494
1676u16 HPI_AESEBU__receiver_get_format(const struct hpi_hsubsys *ph_subsys, 1495u16 hpi_aesebu_receiver_get_format(u32 h_control, u16 *pw_source);
1677 u32 h_control, u16 *pw_source);
1678 1496
1679u16 HPI_AESEBU__receiver_get_sample_rate(const struct hpi_hsubsys *ph_subsys, 1497u16 hpi_aesebu_receiver_get_sample_rate(u32 h_control, u32 *psample_rate);
1680 u32 h_control, u32 *psample_rate);
1681 1498
1682u16 HPI_AESEBU__receiver_get_user_data(const struct hpi_hsubsys *ph_subsys, 1499u16 hpi_aesebu_receiver_get_user_data(u32 h_control, u16 index, u16 *pw_data);
1683 u32 h_control, u16 index, u16 *pw_data);
1684 1500
1685u16 HPI_AESEBU__receiver_get_channel_status(const struct hpi_hsubsys 1501u16 hpi_aesebu_receiver_get_channel_status(u32 h_control, u16 index,
1686 *ph_subsys, u32 h_control, u16 index, u16 *pw_data); 1502 u16 *pw_data);
1687 1503
1688u16 HPI_AESEBU__receiver_get_error_status(const struct hpi_hsubsys *ph_subsys, 1504u16 hpi_aesebu_receiver_get_error_status(u32 h_control, u16 *pw_error_data);
1689 u32 h_control, u16 *pw_error_data);
1690 1505
1691/*******************************/ 1506/*******************************/
1692/* AES/EBU Transmitter control */ 1507/* AES/EBU Transmitter control */
1693/*******************************/ 1508/*******************************/
1694u16 HPI_AESEBU__transmitter_set_sample_rate(const struct hpi_hsubsys 1509u16 hpi_aesebu_transmitter_set_sample_rate(u32 h_control, u32 sample_rate);
1695 *ph_subsys, u32 h_control, u32 sample_rate);
1696 1510
1697u16 HPI_AESEBU__transmitter_set_user_data(const struct hpi_hsubsys *ph_subsys, 1511u16 hpi_aesebu_transmitter_set_user_data(u32 h_control, u16 index, u16 data);
1698 u32 h_control, u16 index, u16 data);
1699 1512
1700u16 HPI_AESEBU__transmitter_set_channel_status(const struct hpi_hsubsys 1513u16 hpi_aesebu_transmitter_set_channel_status(u32 h_control, u16 index,
1701 *ph_subsys, u32 h_control, u16 index, u16 data); 1514 u16 data);
1702 1515
1703u16 HPI_AESEBU__transmitter_get_channel_status(const struct hpi_hsubsys 1516u16 hpi_aesebu_transmitter_get_channel_status(u32 h_control, u16 index,
1704 *ph_subsys, u32 h_control, u16 index, u16 *pw_data); 1517 u16 *pw_data);
1705 1518
1706u16 HPI_AESEBU__transmitter_query_format(const struct hpi_hsubsys *ph_subsys, 1519u16 hpi_aesebu_transmitter_query_format(const u32 h_aes_tx, const u32 index,
1707 const u32 h_aes_tx, const u32 index, u16 *pw_format); 1520 u16 *pw_format);
1708 1521
1709u16 HPI_AESEBU__transmitter_set_format(const struct hpi_hsubsys *ph_subsys, 1522u16 hpi_aesebu_transmitter_set_format(u32 h_control, u16 output_format);
1710 u32 h_control, u16 output_format);
1711 1523
1712u16 HPI_AESEBU__transmitter_get_format(const struct hpi_hsubsys *ph_subsys, 1524u16 hpi_aesebu_transmitter_get_format(u32 h_control, u16 *pw_output_format);
1713 u32 h_control, u16 *pw_output_format);
1714 1525
1715/***********************/ 1526/***********************/
1716/* multiplexer control */ 1527/* Multiplexer control */
1717/***********************/ 1528/***********************/
1718u16 hpi_multiplexer_set_source(const struct hpi_hsubsys *ph_subsys, 1529u16 hpi_multiplexer_set_source(u32 h_control, u16 source_node_type,
1719 u32 h_control, u16 source_node_type, u16 source_node_index); 1530 u16 source_node_index);
1720
1721u16 hpi_multiplexer_get_source(const struct hpi_hsubsys *ph_subsys,
1722 u32 h_control, u16 *source_node_type, u16 *source_node_index);
1723 1531
1724u16 hpi_multiplexer_query_source(const struct hpi_hsubsys *ph_subsys, 1532u16 hpi_multiplexer_get_source(u32 h_control, u16 *source_node_type,
1725 u32 h_control, u16 index, u16 *source_node_type,
1726 u16 *source_node_index); 1533 u16 *source_node_index);
1727 1534
1535u16 hpi_multiplexer_query_source(u32 h_control, u16 index,
1536 u16 *source_node_type, u16 *source_node_index);
1537
1728/***************/ 1538/***************/
1729/* VOX control */ 1539/* Vox control */
1730/***************/ 1540/***************/
1731u16 hpi_vox_set_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1541u16 hpi_vox_set_threshold(u32 h_control, short an_gain0_01dB);
1732 short an_gain0_01dB);
1733 1542
1734u16 hpi_vox_get_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1543u16 hpi_vox_get_threshold(u32 h_control, short *an_gain0_01dB);
1735 short *an_gain0_01dB);
1736 1544
1737/*********************/ 1545/*********************/
1738/* Bitstream control */ 1546/* Bitstream control */
1739/*********************/ 1547/*********************/
1740u16 hpi_bitstream_set_clock_edge(const struct hpi_hsubsys *ph_subsys, 1548u16 hpi_bitstream_set_clock_edge(u32 h_control, u16 edge_type);
1741 u32 h_control, u16 edge_type);
1742 1549
1743u16 hpi_bitstream_set_data_polarity(const struct hpi_hsubsys *ph_subsys, 1550u16 hpi_bitstream_set_data_polarity(u32 h_control, u16 polarity);
1744 u32 h_control, u16 polarity);
1745 1551
1746u16 hpi_bitstream_get_activity(const struct hpi_hsubsys *ph_subsys, 1552u16 hpi_bitstream_get_activity(u32 h_control, u16 *pw_clk_activity,
1747 u32 h_control, u16 *pw_clk_activity, u16 *pw_data_activity); 1553 u16 *pw_data_activity);
1748 1554
1749/***********************/ 1555/***********************/
1750/* SampleClock control */ 1556/* SampleClock control */
1751/***********************/ 1557/***********************/
1752 1558
1753u16 hpi_sample_clock_query_source(const struct hpi_hsubsys *ph_subsys, 1559u16 hpi_sample_clock_query_source(const u32 h_clock, const u32 index,
1754 const u32 h_clock, const u32 index, u16 *pw_source); 1560 u16 *pw_source);
1755 1561
1756u16 hpi_sample_clock_set_source(const struct hpi_hsubsys *ph_subsys, 1562u16 hpi_sample_clock_set_source(u32 h_control, u16 source);
1757 u32 h_control, u16 source);
1758 1563
1759u16 hpi_sample_clock_get_source(const struct hpi_hsubsys *ph_subsys, 1564u16 hpi_sample_clock_get_source(u32 h_control, u16 *pw_source);
1760 u32 h_control, u16 *pw_source);
1761 1565
1762u16 hpi_sample_clock_query_source_index(const struct hpi_hsubsys *ph_subsys, 1566u16 hpi_sample_clock_query_source_index(const u32 h_clock, const u32 index,
1763 const u32 h_clock, const u32 index, const u32 source, 1567 const u32 source, u16 *pw_source_index);
1764 u16 *pw_source_index);
1765 1568
1766u16 hpi_sample_clock_set_source_index(const struct hpi_hsubsys *ph_subsys, 1569u16 hpi_sample_clock_set_source_index(u32 h_control, u16 source_index);
1767 u32 h_control, u16 source_index);
1768 1570
1769u16 hpi_sample_clock_get_source_index(const struct hpi_hsubsys *ph_subsys, 1571u16 hpi_sample_clock_get_source_index(u32 h_control, u16 *pw_source_index);
1770 u32 h_control, u16 *pw_source_index);
1771 1572
1772u16 hpi_sample_clock_get_sample_rate(const struct hpi_hsubsys *ph_subsys, 1573u16 hpi_sample_clock_get_sample_rate(u32 h_control, u32 *psample_rate);
1773 u32 h_control, u32 *psample_rate);
1774 1574
1775u16 hpi_sample_clock_query_local_rate(const struct hpi_hsubsys *ph_subsys, 1575u16 hpi_sample_clock_query_local_rate(const u32 h_clock, const u32 index,
1776 const u32 h_clock, const u32 index, u32 *psource); 1576 u32 *psource);
1777 1577
1778u16 hpi_sample_clock_set_local_rate(const struct hpi_hsubsys *ph_subsys, 1578u16 hpi_sample_clock_set_local_rate(u32 h_control, u32 sample_rate);
1779 u32 h_control, u32 sample_rate);
1780 1579
1781u16 hpi_sample_clock_get_local_rate(const struct hpi_hsubsys *ph_subsys, 1580u16 hpi_sample_clock_get_local_rate(u32 h_control, u32 *psample_rate);
1782 u32 h_control, u32 *psample_rate);
1783 1581
1784u16 hpi_sample_clock_set_auto(const struct hpi_hsubsys *ph_subsys, 1582u16 hpi_sample_clock_set_auto(u32 h_control, u32 enable);
1785 u32 h_control, u32 enable);
1786 1583
1787u16 hpi_sample_clock_get_auto(const struct hpi_hsubsys *ph_subsys, 1584u16 hpi_sample_clock_get_auto(u32 h_control, u32 *penable);
1788 u32 h_control, u32 *penable);
1789 1585
1790u16 hpi_sample_clock_set_local_rate_lock(const struct hpi_hsubsys *ph_subsys, 1586u16 hpi_sample_clock_set_local_rate_lock(u32 h_control, u32 lock);
1791 u32 h_control, u32 lock);
1792 1587
1793u16 hpi_sample_clock_get_local_rate_lock(const struct hpi_hsubsys *ph_subsys, 1588u16 hpi_sample_clock_get_local_rate_lock(u32 h_control, u32 *plock);
1794 u32 h_control, u32 *plock);
1795 1589
1796/***********************/ 1590/***********************/
1797/* Microphone control */ 1591/* Microphone control */
1798/***********************/ 1592/***********************/
1799u16 hpi_microphone_set_phantom_power(const struct hpi_hsubsys *ph_subsys, 1593u16 hpi_microphone_set_phantom_power(u32 h_control, u16 on_off);
1800 u32 h_control, u16 on_off);
1801 1594
1802u16 hpi_microphone_get_phantom_power(const struct hpi_hsubsys *ph_subsys, 1595u16 hpi_microphone_get_phantom_power(u32 h_control, u16 *pw_on_off);
1803 u32 h_control, u16 *pw_on_off);
1804 1596
1805/******************************* 1597/********************************/
1806 Parametric Equalizer control 1598/* Parametric Equalizer control */
1807*******************************/ 1599/********************************/
1808u16 hpi_parametricEQ__get_info(const struct hpi_hsubsys *ph_subsys, 1600u16 hpi_parametric_eq_get_info(u32 h_control, u16 *pw_number_of_bands,
1809 u32 h_control, u16 *pw_number_of_bands, u16 *pw_enabled); 1601 u16 *pw_enabled);
1810 1602
1811u16 hpi_parametricEQ__set_state(const struct hpi_hsubsys *ph_subsys, 1603u16 hpi_parametric_eq_set_state(u32 h_control, u16 on_off);
1812 u32 h_control, u16 on_off);
1813 1604
1814u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys, 1605u16 hpi_parametric_eq_set_band(u32 h_control, u16 index, u16 type,
1815 u32 h_control, u16 index, u16 type, u32 frequency_hz, short q100, 1606 u32 frequency_hz, short q100, short gain0_01dB);
1816 short gain0_01dB);
1817 1607
1818u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys, 1608u16 hpi_parametric_eq_get_band(u32 h_control, u16 index, u16 *pn_type,
1819 u32 h_control, u16 index, u16 *pn_type, u32 *pfrequency_hz, 1609 u32 *pfrequency_hz, short *pnQ100, short *pn_gain0_01dB);
1820 short *pnQ100, short *pn_gain0_01dB);
1821 1610
1822u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys, 1611u16 hpi_parametric_eq_get_coeffs(u32 h_control, u16 index, short coeffs[5]
1823 u32 h_control, u16 index, short coeffs[5]
1824 ); 1612 );
1825 1613
1826/******************************* 1614/*******************************/
1827 Compressor Expander control 1615/* Compressor Expander control */
1828*******************************/ 1616/*******************************/
1829
1830u16 hpi_compander_set_enable(const struct hpi_hsubsys *ph_subsys,
1831 u32 h_control, u32 on);
1832
1833u16 hpi_compander_get_enable(const struct hpi_hsubsys *ph_subsys,
1834 u32 h_control, u32 *pon);
1835
1836u16 hpi_compander_set_makeup_gain(const struct hpi_hsubsys *ph_subsys,
1837 u32 h_control, short makeup_gain0_01dB);
1838
1839u16 hpi_compander_get_makeup_gain(const struct hpi_hsubsys *ph_subsys,
1840 u32 h_control, short *pn_makeup_gain0_01dB);
1841
1842u16 hpi_compander_set_attack_time_constant(const struct hpi_hsubsys
1843 *ph_subsys, u32 h_control, u32 index, u32 attack);
1844
1845u16 hpi_compander_get_attack_time_constant(const struct hpi_hsubsys
1846 *ph_subsys, u32 h_control, u32 index, u32 *pw_attack);
1847
1848u16 hpi_compander_set_decay_time_constant(const struct hpi_hsubsys *ph_subsys,
1849 u32 h_control, u32 index, u32 decay);
1850
1851u16 hpi_compander_get_decay_time_constant(const struct hpi_hsubsys *ph_subsys,
1852 u32 h_control, u32 index, u32 *pw_decay);
1853
1854u16 hpi_compander_set_threshold(const struct hpi_hsubsys *ph_subsys,
1855 u32 h_control, u32 index, short threshold0_01dB);
1856
1857u16 hpi_compander_get_threshold(const struct hpi_hsubsys *ph_subsys,
1858 u32 h_control, u32 index, short *pn_threshold0_01dB);
1859
1860u16 hpi_compander_set_ratio(const struct hpi_hsubsys *ph_subsys,
1861 u32 h_control, u32 index, u32 ratio100);
1862
1863u16 hpi_compander_get_ratio(const struct hpi_hsubsys *ph_subsys,
1864 u32 h_control, u32 index, u32 *pw_ratio100);
1865
1866/*******************************
1867 Cobranet HMI control
1868*******************************/
1869u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1870 u32 hmi_address, u32 byte_count, u8 *pb_data);
1871
1872u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1873 u32 hmi_address, u32 max_byte_count, u32 *pbyte_count, u8 *pb_data);
1874
1875u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys,
1876 u32 h_control, u32 *pstatus, u32 *preadable_size,
1877 u32 *pwriteable_size);
1878
1879/*Read the current IP address
1880*/
1881u16 hpi_cobranet_getI_paddress(const struct hpi_hsubsys *ph_subsys,
1882 u32 h_control, u32 *pi_paddress);
1883
1884/* Write the current IP address
1885*/
1886u16 hpi_cobranet_setI_paddress(const struct hpi_hsubsys *ph_subsys,
1887 u32 h_control, u32 i_paddress);
1888
1889/* Read the static IP address
1890*/
1891u16 hpi_cobranet_get_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
1892 u32 h_control, u32 *pi_paddress);
1893 1617
1894/* Write the static IP address 1618u16 hpi_compander_set_enable(u32 h_control, u32 on);
1895*/
1896u16 hpi_cobranet_set_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
1897 u32 h_control, u32 i_paddress);
1898 1619
1899/* Read the MAC address 1620u16 hpi_compander_get_enable(u32 h_control, u32 *pon);
1900*/
1901u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys,
1902 u32 h_control, u32 *pmAC_MS_bs, u32 *pmAC_LS_bs);
1903 1621
1904/******************************* 1622u16 hpi_compander_set_makeup_gain(u32 h_control, short makeup_gain0_01dB);
1905 Tone Detector control
1906*******************************/
1907u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys, u32 hC,
1908 u32 *state);
1909 1623
1910u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys, u32 hC, 1624u16 hpi_compander_get_makeup_gain(u32 h_control, short *pn_makeup_gain0_01dB);
1911 u32 enable);
1912 1625
1913u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys, u32 hC, 1626u16 hpi_compander_set_attack_time_constant(u32 h_control, u32 index,
1914 u32 *enable); 1627 u32 attack);
1915 1628
1916u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, 1629u16 hpi_compander_get_attack_time_constant(u32 h_control, u32 index,
1917 u32 hC, u32 event_enable); 1630 u32 *pw_attack);
1918 1631
1919u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys, 1632u16 hpi_compander_set_decay_time_constant(u32 h_control, u32 index,
1920 u32 hC, u32 *event_enable); 1633 u32 decay);
1921 1634
1922u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, 1635u16 hpi_compander_get_decay_time_constant(u32 h_control, u32 index,
1923 u32 hC, int threshold); 1636 u32 *pw_decay);
1924 1637
1925u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys, 1638u16 hpi_compander_set_threshold(u32 h_control, u32 index,
1926 u32 hC, int *threshold); 1639 short threshold0_01dB);
1927 1640
1928u16 hpi_tone_detector_get_frequency(const struct hpi_hsubsys *ph_subsys, 1641u16 hpi_compander_get_threshold(u32 h_control, u32 index,
1929 u32 hC, u32 index, u32 *frequency); 1642 short *pn_threshold0_01dB);
1930 1643
1931/******************************* 1644u16 hpi_compander_set_ratio(u32 h_control, u32 index, u32 ratio100);
1932 Silence Detector control
1933*******************************/
1934u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys,
1935 u32 hC, u32 *state);
1936 1645
1937u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys, 1646u16 hpi_compander_get_ratio(u32 h_control, u32 index, u32 *pw_ratio100);
1938 u32 hC, u32 enable);
1939 1647
1940u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys, 1648/********************/
1941 u32 hC, u32 *enable); 1649/* Cobranet control */
1650/********************/
1651u16 hpi_cobranet_hmi_write(u32 h_control, u32 hmi_address, u32 byte_count,
1652 u8 *pb_data);
1942 1653
1943u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, 1654u16 hpi_cobranet_hmi_read(u32 h_control, u32 hmi_address, u32 max_byte_count,
1944 u32 hC, u32 event_enable); 1655 u32 *pbyte_count, u8 *pb_data);
1945 1656
1946u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys, 1657u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
1947 u32 hC, u32 *event_enable); 1658 u32 *preadable_size, u32 *pwriteable_size);
1948 1659
1949u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys, 1660u16 hpi_cobranet_get_ip_address(u32 h_control, u32 *pdw_ip_address);
1950 u32 hC, u32 delay);
1951 1661
1952u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys, 1662u16 hpi_cobranet_set_ip_address(u32 h_control, u32 dw_ip_address);
1953 u32 hC, u32 *delay);
1954 1663
1955u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, 1664u16 hpi_cobranet_get_static_ip_address(u32 h_control, u32 *pdw_ip_address);
1956 u32 hC, int threshold);
1957 1665
1958u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys, 1666u16 hpi_cobranet_set_static_ip_address(u32 h_control, u32 dw_ip_address);
1959 u32 hC, int *threshold);
1960 1667
1961/******************************* 1668u16 hpi_cobranet_get_macaddress(u32 h_control, u32 *p_mac_msbs,
1962 Universal control 1669 u32 *p_mac_lsbs);
1963*******************************/
1964u16 hpi_entity_find_next(struct hpi_entity *container_entity,
1965 enum e_entity_type type, enum e_entity_role role, int recursive_flag,
1966 struct hpi_entity **current_match);
1967 1670
1968u16 hpi_entity_copy_value_from(struct hpi_entity *entity, 1671/*************************/
1969 enum e_entity_type type, size_t item_count, void *value_dst_p); 1672/* Tone Detector control */
1673/*************************/
1674u16 hpi_tone_detector_get_state(u32 hC, u32 *state);
1970 1675
1971u16 hpi_entity_unpack(struct hpi_entity *entity, enum e_entity_type *type, 1676u16 hpi_tone_detector_set_enable(u32 hC, u32 enable);
1972 size_t *items, enum e_entity_role *role, void **value);
1973 1677
1974u16 hpi_entity_alloc_and_pack(const enum e_entity_type type, 1678u16 hpi_tone_detector_get_enable(u32 hC, u32 *enable);
1975 const size_t item_count, const enum e_entity_role role, void *value,
1976 struct hpi_entity **entity);
1977 1679
1978void hpi_entity_free(struct hpi_entity *entity); 1680u16 hpi_tone_detector_set_event_enable(u32 hC, u32 event_enable);
1979 1681
1980u16 hpi_universal_info(const struct hpi_hsubsys *ph_subsys, u32 hC, 1682u16 hpi_tone_detector_get_event_enable(u32 hC, u32 *event_enable);
1981 struct hpi_entity **info);
1982 1683
1983u16 hpi_universal_get(const struct hpi_hsubsys *ph_subsys, u32 hC, 1684u16 hpi_tone_detector_set_threshold(u32 hC, int threshold);
1984 struct hpi_entity **value);
1985 1685
1986u16 hpi_universal_set(const struct hpi_hsubsys *ph_subsys, u32 hC, 1686u16 hpi_tone_detector_get_threshold(u32 hC, int *threshold);
1987 struct hpi_entity *value);
1988 1687
1989/*/////////// */ 1688u16 hpi_tone_detector_get_frequency(u32 hC, u32 index, u32 *frequency);
1990/* DSP CLOCK */
1991/*/////////// */
1992u16 hpi_clock_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1993 u32 *ph_dsp_clock);
1994 1689
1995u16 hpi_clock_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_clock, 1690/****************************/
1996 u16 hour, u16 minute, u16 second, u16 milli_second); 1691/* Silence Detector control */
1692/****************************/
1693u16 hpi_silence_detector_get_state(u32 hC, u32 *state);
1997 1694
1998u16 hpi_clock_get_time(const struct hpi_hsubsys *ph_subsys, u32 h_clock, 1695u16 hpi_silence_detector_set_enable(u32 hC, u32 enable);
1999 u16 *pw_hour, u16 *pw_minute, u16 *pw_second, u16 *pw_milli_second);
2000 1696
2001/*/////////// */ 1697u16 hpi_silence_detector_get_enable(u32 hC, u32 *enable);
2002/* PROFILE */
2003/*/////////// */
2004u16 hpi_profile_open_all(const struct hpi_hsubsys *ph_subsys,
2005 u16 adapter_index, u16 profile_index, u32 *ph_profile,
2006 u16 *pw_max_profiles);
2007 1698
2008u16 hpi_profile_get(const struct hpi_hsubsys *ph_subsys, u32 h_profile, 1699u16 hpi_silence_detector_set_event_enable(u32 hC, u32 event_enable);
2009 u16 index, u16 *pw_seconds, u32 *pmicro_seconds, u32 *pcall_count,
2010 u32 *pmax_micro_seconds, u32 *pmin_micro_seconds);
2011 1700
2012u16 hpi_profile_start_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile); 1701u16 hpi_silence_detector_get_event_enable(u32 hC, u32 *event_enable);
2013 1702
2014u16 hpi_profile_stop_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile); 1703u16 hpi_silence_detector_set_delay(u32 hC, u32 delay);
2015 1704
2016u16 hpi_profile_get_name(const struct hpi_hsubsys *ph_subsys, u32 h_profile, 1705u16 hpi_silence_detector_get_delay(u32 hC, u32 *delay);
2017 u16 index, char *sz_profile_name, u16 profile_name_length);
2018 1706
2019u16 hpi_profile_get_utilization(const struct hpi_hsubsys *ph_subsys, 1707u16 hpi_silence_detector_set_threshold(u32 hC, int threshold);
2020 u32 h_profile, u32 *putilization);
2021 1708
2022/*//////////////////// */ 1709u16 hpi_silence_detector_get_threshold(u32 hC, int *threshold);
2023/* UTILITY functions */ 1710/*********************/
1711/* Utility functions */
1712/*********************/
2024 1713
2025u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format, 1714u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
2026 u32 sample_rate, u32 bit_rate, u32 attributes); 1715 u32 sample_rate, u32 bit_rate, u32 attributes);
2027 1716
2028/* Until it's verified, this function is for Windows OSs only */ 1717#endif /*_HPI_H_ */
2029
2030#endif /*_H_HPI_ */
2031/*
2032///////////////////////////////////////////////////////////////////////////////
2033// See CVS for history. Last complete set in rev 1.146
2034////////////////////////////////////////////////////////////////////////////////
2035*/
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
index f7e374ec4414..df4aed5295dd 100644
--- a/sound/pci/asihpi/hpi6000.c
+++ b/sound/pci/asihpi/hpi6000.c
@@ -43,16 +43,17 @@
43#define HPI_HIF_ERROR_MASK 0x4000 43#define HPI_HIF_ERROR_MASK 0x4000
44 44
45/* HPI6000 specific error codes */ 45/* HPI6000 specific error codes */
46#define HPI6000_ERROR_BASE 900 /* not actually used anywhere */
46 47
47#define HPI6000_ERROR_BASE 900 48/* operational/messaging errors */
48#define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901 49#define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901
49#define HPI6000_ERROR_MSG_RESP_SEND_MSG_ACK 902 50
50#define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903 51#define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903
51#define HPI6000_ERROR_MSG_GET_ADR 904 52#define HPI6000_ERROR_MSG_GET_ADR 904
52#define HPI6000_ERROR_RESP_GET_ADR 905 53#define HPI6000_ERROR_RESP_GET_ADR 905
53#define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906 54#define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906
54#define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907 55#define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907
55#define HPI6000_ERROR_MSG_INVALID_DSP_INDEX 908 56
56#define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909 57#define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909
57 58
58#define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911 59#define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911
@@ -62,7 +63,6 @@
62#define HPI6000_ERROR_SEND_DATA_CMD 915 63#define HPI6000_ERROR_SEND_DATA_CMD 915
63#define HPI6000_ERROR_SEND_DATA_WRITE 916 64#define HPI6000_ERROR_SEND_DATA_WRITE 916
64#define HPI6000_ERROR_SEND_DATA_IDLECMD 917 65#define HPI6000_ERROR_SEND_DATA_IDLECMD 917
65#define HPI6000_ERROR_SEND_DATA_VERIFY 918
66 66
67#define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921 67#define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921
68#define HPI6000_ERROR_GET_DATA_ACK 922 68#define HPI6000_ERROR_GET_DATA_ACK 922
@@ -76,9 +76,8 @@
76 76
77#define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961 77#define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961
78#define HPI6000_ERROR_MSG_RESP_IDLECMD 962 78#define HPI6000_ERROR_MSG_RESP_IDLECMD 962
79#define HPI6000_ERROR_MSG_RESP_BLOCKVERIFY32 963
80 79
81/* adapter init errors */ 80/* Initialisation/bootload errors */
82#define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930 81#define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930
83 82
84/* can't access PCI2040 */ 83/* can't access PCI2040 */
@@ -201,8 +200,8 @@ static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
201static void subsys_create_adapter(struct hpi_message *phm, 200static void subsys_create_adapter(struct hpi_message *phm,
202 struct hpi_response *phr); 201 struct hpi_response *phr);
203 202
204static void subsys_delete_adapter(struct hpi_message *phm, 203static void adapter_delete(struct hpi_adapter_obj *pao,
205 struct hpi_response *phr); 204 struct hpi_message *phm, struct hpi_response *phr);
206 205
207static void adapter_get_asserts(struct hpi_adapter_obj *pao, 206static void adapter_get_asserts(struct hpi_adapter_obj *pao,
208 struct hpi_message *phm, struct hpi_response *phr); 207 struct hpi_message *phm, struct hpi_response *phr);
@@ -210,6 +209,8 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao,
210static short create_adapter_obj(struct hpi_adapter_obj *pao, 209static short create_adapter_obj(struct hpi_adapter_obj *pao,
211 u32 *pos_error_code); 210 u32 *pos_error_code);
212 211
212static void delete_adapter_obj(struct hpi_adapter_obj *pao);
213
213/* local globals */ 214/* local globals */
214 215
215static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */ 216static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */
@@ -217,23 +218,10 @@ static u16 gw_pci_write_asserts; /* used to count PCI2040 errors */
217 218
218static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) 219static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
219{ 220{
220
221 switch (phm->function) { 221 switch (phm->function) {
222 case HPI_SUBSYS_OPEN:
223 case HPI_SUBSYS_CLOSE:
224 case HPI_SUBSYS_GET_INFO:
225 case HPI_SUBSYS_DRIVER_UNLOAD:
226 case HPI_SUBSYS_DRIVER_LOAD:
227 case HPI_SUBSYS_FIND_ADAPTERS:
228 /* messages that should not get here */
229 phr->error = HPI_ERROR_UNIMPLEMENTED;
230 break;
231 case HPI_SUBSYS_CREATE_ADAPTER: 222 case HPI_SUBSYS_CREATE_ADAPTER:
232 subsys_create_adapter(phm, phr); 223 subsys_create_adapter(phm, phr);
233 break; 224 break;
234 case HPI_SUBSYS_DELETE_ADAPTER:
235 subsys_delete_adapter(phm, phr);
236 break;
237 default: 225 default:
238 phr->error = HPI_ERROR_INVALID_FUNC; 226 phr->error = HPI_ERROR_INVALID_FUNC;
239 break; 227 break;
@@ -243,7 +231,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
243static void control_message(struct hpi_adapter_obj *pao, 231static void control_message(struct hpi_adapter_obj *pao,
244 struct hpi_message *phm, struct hpi_response *phr) 232 struct hpi_message *phm, struct hpi_response *phr)
245{ 233{
246
247 switch (phm->function) { 234 switch (phm->function) {
248 case HPI_CONTROL_GET_STATE: 235 case HPI_CONTROL_GET_STATE:
249 if (pao->has_control_cache) { 236 if (pao->has_control_cache) {
@@ -251,7 +238,13 @@ static void control_message(struct hpi_adapter_obj *pao,
251 err = hpi6000_update_control_cache(pao, phm); 238 err = hpi6000_update_control_cache(pao, phm);
252 239
253 if (err) { 240 if (err) {
254 phr->error = err; 241 if (err >= HPI_ERROR_BACKEND_BASE) {
242 phr->error =
243 HPI_ERROR_CONTROL_CACHING;
244 phr->specific_error = err;
245 } else {
246 phr->error = err;
247 }
255 break; 248 break;
256 } 249 }
257 250
@@ -262,16 +255,15 @@ static void control_message(struct hpi_adapter_obj *pao,
262 } 255 }
263 hw_message(pao, phm, phr); 256 hw_message(pao, phm, phr);
264 break; 257 break;
265 case HPI_CONTROL_GET_INFO:
266 hw_message(pao, phm, phr);
267 break;
268 case HPI_CONTROL_SET_STATE: 258 case HPI_CONTROL_SET_STATE:
269 hw_message(pao, phm, phr); 259 hw_message(pao, phm, phr);
270 hpi_sync_control_cache(((struct hpi_hw_obj *)pao->priv)-> 260 hpi_cmn_control_cache_sync_to_msg(((struct hpi_hw_obj *)pao->
271 p_cache, phm, phr); 261 priv)->p_cache, phm, phr);
272 break; 262 break;
263
264 case HPI_CONTROL_GET_INFO:
273 default: 265 default:
274 phr->error = HPI_ERROR_INVALID_FUNC; 266 hw_message(pao, phm, phr);
275 break; 267 break;
276 } 268 }
277} 269}
@@ -280,26 +272,16 @@ static void adapter_message(struct hpi_adapter_obj *pao,
280 struct hpi_message *phm, struct hpi_response *phr) 272 struct hpi_message *phm, struct hpi_response *phr)
281{ 273{
282 switch (phm->function) { 274 switch (phm->function) {
283 case HPI_ADAPTER_GET_INFO:
284 hw_message(pao, phm, phr);
285 break;
286 case HPI_ADAPTER_GET_ASSERT: 275 case HPI_ADAPTER_GET_ASSERT:
287 adapter_get_asserts(pao, phm, phr); 276 adapter_get_asserts(pao, phm, phr);
288 break; 277 break;
289 case HPI_ADAPTER_OPEN: 278
290 case HPI_ADAPTER_CLOSE: 279 case HPI_ADAPTER_DELETE:
291 case HPI_ADAPTER_TEST_ASSERT: 280 adapter_delete(pao, phm, phr);
292 case HPI_ADAPTER_SELFTEST:
293 case HPI_ADAPTER_GET_MODE:
294 case HPI_ADAPTER_SET_MODE:
295 case HPI_ADAPTER_FIND_OBJECT:
296 case HPI_ADAPTER_GET_PROPERTY:
297 case HPI_ADAPTER_SET_PROPERTY:
298 case HPI_ADAPTER_ENUM_PROPERTY:
299 hw_message(pao, phm, phr);
300 break; 281 break;
282
301 default: 283 default:
302 phr->error = HPI_ERROR_INVALID_FUNC; 284 hw_message(pao, phm, phr);
303 break; 285 break;
304 } 286 }
305} 287}
@@ -311,7 +293,7 @@ static void outstream_message(struct hpi_adapter_obj *pao,
311 case HPI_OSTREAM_HOSTBUFFER_ALLOC: 293 case HPI_OSTREAM_HOSTBUFFER_ALLOC:
312 case HPI_OSTREAM_HOSTBUFFER_FREE: 294 case HPI_OSTREAM_HOSTBUFFER_FREE:
313 /* Don't let these messages go to the HW function because 295 /* Don't let these messages go to the HW function because
314 * they're called without allocating the spinlock. 296 * they're called without locking the spinlock.
315 * For the HPI6000 adapters the HW would return 297 * For the HPI6000 adapters the HW would return
316 * HPI_ERROR_INVALID_FUNC anyway. 298 * HPI_ERROR_INVALID_FUNC anyway.
317 */ 299 */
@@ -331,7 +313,7 @@ static void instream_message(struct hpi_adapter_obj *pao,
331 case HPI_ISTREAM_HOSTBUFFER_ALLOC: 313 case HPI_ISTREAM_HOSTBUFFER_ALLOC:
332 case HPI_ISTREAM_HOSTBUFFER_FREE: 314 case HPI_ISTREAM_HOSTBUFFER_FREE:
333 /* Don't let these messages go to the HW function because 315 /* Don't let these messages go to the HW function because
334 * they're called without allocating the spinlock. 316 * they're called without locking the spinlock.
335 * For the HPI6000 adapters the HW would return 317 * For the HPI6000 adapters the HW would return
336 * HPI_ERROR_INVALID_FUNC anyway. 318 * HPI_ERROR_INVALID_FUNC anyway.
337 */ 319 */
@@ -352,26 +334,22 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
352{ 334{
353 struct hpi_adapter_obj *pao = NULL; 335 struct hpi_adapter_obj *pao = NULL;
354 336
355 /* subsytem messages get executed by every HPI. */
356 /* All other messages are ignored unless the adapter index matches */
357 /* an adapter in the HPI */
358 HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->object, phm->function);
359
360 /* if Dsp has crashed then do not communicate with it any more */
361 if (phm->object != HPI_OBJ_SUBSYSTEM) { 337 if (phm->object != HPI_OBJ_SUBSYSTEM) {
362 pao = hpi_find_adapter(phm->adapter_index); 338 pao = hpi_find_adapter(phm->adapter_index);
363 if (!pao) { 339 if (!pao) {
364 HPI_DEBUG_LOG(DEBUG, 340 hpi_init_response(phr, phm->object, phm->function,
365 " %d,%d refused, for another HPI?\n", 341 HPI_ERROR_BAD_ADAPTER_NUMBER);
366 phm->object, phm->function); 342 HPI_DEBUG_LOG(DEBUG, "invalid adapter index: %d \n",
343 phm->adapter_index);
367 return; 344 return;
368 } 345 }
369 346
347 /* Don't even try to communicate with crashed DSP */
370 if (pao->dsp_crashed >= 10) { 348 if (pao->dsp_crashed >= 10) {
371 hpi_init_response(phr, phm->object, phm->function, 349 hpi_init_response(phr, phm->object, phm->function,
372 HPI_ERROR_DSP_HARDWARE); 350 HPI_ERROR_DSP_HARDWARE);
373 HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n", 351 HPI_DEBUG_LOG(DEBUG, "adapter %d dsp crashed\n",
374 phm->object, phm->function); 352 phm->adapter_index);
375 return; 353 return;
376 } 354 }
377 } 355 }
@@ -433,39 +411,34 @@ static void subsys_create_adapter(struct hpi_message *phm,
433 struct hpi_adapter_obj ao; 411 struct hpi_adapter_obj ao;
434 struct hpi_adapter_obj *pao; 412 struct hpi_adapter_obj *pao;
435 u32 os_error_code; 413 u32 os_error_code;
436 short error = 0; 414 u16 err = 0;
437 u32 dsp_index = 0; 415 u32 dsp_index = 0;
438 416
439 HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n"); 417 HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n");
440 418
441 memset(&ao, 0, sizeof(ao)); 419 memset(&ao, 0, sizeof(ao));
442 420
443 /* this HPI only creates adapters for TI/PCI2040 based devices */
444 if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
445 return;
446 if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
447 return;
448 if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_PCI2040)
449 return;
450
451 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); 421 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
452 if (!ao.priv) { 422 if (!ao.priv) {
453 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); 423 HPI_DEBUG_LOG(ERROR, "can't get mem for adapter object\n");
454 phr->error = HPI_ERROR_MEMORY_ALLOC; 424 phr->error = HPI_ERROR_MEMORY_ALLOC;
455 return; 425 return;
456 } 426 }
457 427
458 /* create the adapter object based on the resource information */ 428 /* create the adapter object based on the resource information */
459 /*? memcpy(&ao.Pci,&phm->u.s.Resource.r.Pci,sizeof(ao.Pci)); */
460 ao.pci = *phm->u.s.resource.r.pci; 429 ao.pci = *phm->u.s.resource.r.pci;
461 430
462 error = create_adapter_obj(&ao, &os_error_code); 431 err = create_adapter_obj(&ao, &os_error_code);
463 if (!error) 432 if (err) {
464 error = hpi_add_adapter(&ao); 433 delete_adapter_obj(&ao);
465 if (error) { 434 if (err >= HPI_ERROR_BACKEND_BASE) {
435 phr->error = HPI_ERROR_DSP_BOOTLOAD;
436 phr->specific_error = err;
437 } else {
438 phr->error = err;
439 }
440
466 phr->u.s.data = os_error_code; 441 phr->u.s.data = os_error_code;
467 kfree(ao.priv);
468 phr->error = error;
469 return; 442 return;
470 } 443 }
471 /* need to update paParentAdapter */ 444 /* need to update paParentAdapter */
@@ -473,7 +446,7 @@ static void subsys_create_adapter(struct hpi_message *phm,
473 if (!pao) { 446 if (!pao) {
474 /* We just added this adapter, why can't we find it!? */ 447 /* We just added this adapter, why can't we find it!? */
475 HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n"); 448 HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n");
476 phr->error = 950; 449 phr->error = HPI_ERROR_BAD_ADAPTER;
477 return; 450 return;
478 } 451 }
479 452
@@ -482,30 +455,16 @@ static void subsys_create_adapter(struct hpi_message *phm,
482 phw->ado[dsp_index].pa_parent_adapter = pao; 455 phw->ado[dsp_index].pa_parent_adapter = pao;
483 } 456 }
484 457
485 phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type; 458 phr->u.s.adapter_type = ao.adapter_type;
486 phr->u.s.adapter_index = ao.index; 459 phr->u.s.adapter_index = ao.index;
487 phr->u.s.num_adapters++;
488 phr->error = 0; 460 phr->error = 0;
489} 461}
490 462
491static void subsys_delete_adapter(struct hpi_message *phm, 463static void adapter_delete(struct hpi_adapter_obj *pao,
492 struct hpi_response *phr) 464 struct hpi_message *phm, struct hpi_response *phr)
493{ 465{
494 struct hpi_adapter_obj *pao = NULL; 466 delete_adapter_obj(pao);
495 struct hpi_hw_obj *phw;
496
497 pao = hpi_find_adapter(phm->adapter_index);
498 if (!pao)
499 return;
500
501 phw = (struct hpi_hw_obj *)pao->priv;
502
503 if (pao->has_control_cache)
504 hpi_free_control_cache(phw->p_cache);
505
506 hpi_delete_adapter(pao); 467 hpi_delete_adapter(pao);
507 kfree(phw);
508
509 phr->error = 0; 468 phr->error = 0;
510} 469}
511 470
@@ -519,9 +478,6 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
519 u32 control_cache_count = 0; 478 u32 control_cache_count = 0;
520 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 479 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
521 480
522 /* init error reporting */
523 pao->dsp_crashed = 0;
524
525 /* The PCI2040 has the following address map */ 481 /* The PCI2040 has the following address map */
526 /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */ 482 /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */
527 /* BAR1 - 32K = HPI registers on DSP */ 483 /* BAR1 - 32K = HPI registers on DSP */
@@ -575,36 +531,36 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
575 /* get info about the adapter by asking the adapter */ 531 /* get info about the adapter by asking the adapter */
576 /* send a HPI_ADAPTER_GET_INFO message */ 532 /* send a HPI_ADAPTER_GET_INFO message */
577 { 533 {
578 struct hpi_message hM; 534 struct hpi_message hm;
579 struct hpi_response hR0; /* response from DSP 0 */ 535 struct hpi_response hr0; /* response from DSP 0 */
580 struct hpi_response hR1; /* response from DSP 1 */ 536 struct hpi_response hr1; /* response from DSP 1 */
581 u16 error = 0; 537 u16 error = 0;
582 538
583 HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n"); 539 HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n");
584 memset(&hM, 0, sizeof(hM)); 540 memset(&hm, 0, sizeof(hm));
585 hM.type = HPI_TYPE_MESSAGE; 541 hm.type = HPI_TYPE_MESSAGE;
586 hM.size = sizeof(struct hpi_message); 542 hm.size = sizeof(struct hpi_message);
587 hM.object = HPI_OBJ_ADAPTER; 543 hm.object = HPI_OBJ_ADAPTER;
588 hM.function = HPI_ADAPTER_GET_INFO; 544 hm.function = HPI_ADAPTER_GET_INFO;
589 hM.adapter_index = 0; 545 hm.adapter_index = 0;
590 memset(&hR0, 0, sizeof(hR0)); 546 memset(&hr0, 0, sizeof(hr0));
591 memset(&hR1, 0, sizeof(hR1)); 547 memset(&hr1, 0, sizeof(hr1));
592 hR0.size = sizeof(hR0); 548 hr0.size = sizeof(hr0);
593 hR1.size = sizeof(hR1); 549 hr1.size = sizeof(hr1);
594 550
595 error = hpi6000_message_response_sequence(pao, 0, &hM, &hR0); 551 error = hpi6000_message_response_sequence(pao, 0, &hm, &hr0);
596 if (hR0.error) { 552 if (hr0.error) {
597 HPI_DEBUG_LOG(DEBUG, "message error %d\n", hR0.error); 553 HPI_DEBUG_LOG(DEBUG, "message error %d\n", hr0.error);
598 return hR0.error; 554 return hr0.error;
599 } 555 }
600 if (phw->num_dsp == 2) { 556 if (phw->num_dsp == 2) {
601 error = hpi6000_message_response_sequence(pao, 1, &hM, 557 error = hpi6000_message_response_sequence(pao, 1, &hm,
602 &hR1); 558 &hr1);
603 if (error) 559 if (error)
604 return error; 560 return error;
605 } 561 }
606 pao->adapter_type = hR0.u.a.adapter_type; 562 pao->adapter_type = hr0.u.ax.info.adapter_type;
607 pao->index = hR0.u.a.adapter_index; 563 pao->index = hr0.u.ax.info.adapter_index;
608 } 564 }
609 565
610 memset(&phw->control_cache[0], 0, 566 memset(&phw->control_cache[0], 0,
@@ -618,20 +574,37 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
618 control_cache_count = 574 control_cache_count =
619 hpi_read_word(&phw->ado[0], 575 hpi_read_word(&phw->ado[0],
620 HPI_HIF_ADDR(control_cache_count)); 576 HPI_HIF_ADDR(control_cache_count));
621 pao->has_control_cache = 1;
622 577
623 phw->p_cache = 578 phw->p_cache =
624 hpi_alloc_control_cache(control_cache_count, 579 hpi_alloc_control_cache(control_cache_count,
625 control_cache_size, (struct hpi_control_cache_info *) 580 control_cache_size, (unsigned char *)
626 &phw->control_cache[0] 581 &phw->control_cache[0]
627 ); 582 );
628 } else 583 if (phw->p_cache)
629 pao->has_control_cache = 0; 584 pao->has_control_cache = 1;
585 }
630 586
631 HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", 587 HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n",
632 pao->adapter_type, pao->index); 588 pao->adapter_type, pao->index);
633 pao->open = 0; /* upon creation the adapter is closed */ 589 pao->open = 0; /* upon creation the adapter is closed */
634 return 0; 590
591 if (phw->p_cache)
592 phw->p_cache->adap_idx = pao->index;
593
594 return hpi_add_adapter(pao);
595}
596
597static void delete_adapter_obj(struct hpi_adapter_obj *pao)
598{
599 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
600
601 if (pao->has_control_cache)
602 hpi_free_control_cache(phw->p_cache);
603
604 /* reset DSPs on adapter */
605 iowrite32(0x0003000F, phw->dw2040_HPICSR + HPI_RESET);
606
607 kfree(phw);
635} 608}
636 609
637/************************************************************************/ 610/************************************************************************/
@@ -643,11 +616,13 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao,
643#ifndef HIDE_PCI_ASSERTS 616#ifndef HIDE_PCI_ASSERTS
644 /* if we have PCI2040 asserts then collect them */ 617 /* if we have PCI2040 asserts then collect them */
645 if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) { 618 if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) {
646 phr->u.a.serial_number = 619 phr->u.ax.assert.p1 =
647 gw_pci_read_asserts * 100 + gw_pci_write_asserts; 620 gw_pci_read_asserts * 100 + gw_pci_write_asserts;
648 phr->u.a.adapter_index = 1; /* assert count */ 621 phr->u.ax.assert.p2 = 0;
649 phr->u.a.adapter_type = -1; /* "dsp index" */ 622 phr->u.ax.assert.count = 1; /* assert count */
650 strcpy(phr->u.a.sz_adapter_assert, "PCI2040 error"); 623 phr->u.ax.assert.dsp_index = -1; /* "dsp index" */
624 strcpy(phr->u.ax.assert.sz_message, "PCI2040 error");
625 phr->u.ax.assert.dsp_msg_addr = 0;
651 gw_pci_read_asserts = 0; 626 gw_pci_read_asserts = 0;
652 gw_pci_write_asserts = 0; 627 gw_pci_write_asserts = 0;
653 phr->error = 0; 628 phr->error = 0;
@@ -684,10 +659,10 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
684 659
685 /* NOTE don't use wAdapterType in this routine. It is not setup yet */ 660 /* NOTE don't use wAdapterType in this routine. It is not setup yet */
686 661
687 switch (pao->pci.subsys_device_id) { 662 switch (pao->pci.pci_dev->subsystem_device) {
688 case 0x5100: 663 case 0x5100:
689 case 0x5110: /* ASI5100 revB or higher with C6711D */ 664 case 0x5110: /* ASI5100 revB or higher with C6711D */
690 case 0x5200: /* ASI5200 PC_ie version of ASI5100 */ 665 case 0x5200: /* ASI5200 PCIe version of ASI5100 */
691 case 0x6100: 666 case 0x6100:
692 case 0x6200: 667 case 0x6200:
693 boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); 668 boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200);
@@ -707,8 +682,9 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
707 * note that bits 4..15 are read-only and so should always return zero, 682 * note that bits 4..15 are read-only and so should always return zero,
708 * even though we wrote 1 to them 683 * even though we wrote 1 to them
709 */ 684 */
710 for (i = 0; i < 1000; i++) 685 hpios_delay_micro_seconds(1000);
711 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); 686 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
687
712 if (delay != dw2040_reset) { 688 if (delay != dw2040_reset) {
713 HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset, 689 HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset,
714 delay); 690 delay);
@@ -741,8 +717,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
741 dw2040_reset = dw2040_reset & (~0x00000008); 717 dw2040_reset = dw2040_reset & (~0x00000008);
742 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET); 718 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
743 /*delay to allow DSP to get going */ 719 /*delay to allow DSP to get going */
744 for (i = 0; i < 100; i++) 720 hpios_delay_micro_seconds(100);
745 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
746 721
747 /* loop through all DSPs, downloading DSP code */ 722 /* loop through all DSPs, downloading DSP code */
748 for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) { 723 for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) {
@@ -781,27 +756,27 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
781 */ 756 */
782 /* bypass PLL */ 757 /* bypass PLL */
783 hpi_write_word(pdo, 0x01B7C100, 0x0000); 758 hpi_write_word(pdo, 0x01B7C100, 0x0000);
784 for (i = 0; i < 100; i++) 759 hpios_delay_micro_seconds(100);
785 delay = ioread32(phw->dw2040_HPICSR +
786 HPI_RESET);
787 760
788 /* ** use default of PLL x7 ** */ 761 /* ** use default of PLL x7 ** */
789 /* EMIF = 225/3=75MHz */ 762 /* EMIF = 225/3=75MHz */
790 hpi_write_word(pdo, 0x01B7C120, 0x8002); 763 hpi_write_word(pdo, 0x01B7C120, 0x8002);
764 hpios_delay_micro_seconds(100);
765
791 /* peri = 225/2 */ 766 /* peri = 225/2 */
792 hpi_write_word(pdo, 0x01B7C11C, 0x8001); 767 hpi_write_word(pdo, 0x01B7C11C, 0x8001);
768 hpios_delay_micro_seconds(100);
769
793 /* cpu = 225/1 */ 770 /* cpu = 225/1 */
794 hpi_write_word(pdo, 0x01B7C118, 0x8000); 771 hpi_write_word(pdo, 0x01B7C118, 0x8000);
795 /* ~200us delay */ 772
796 for (i = 0; i < 2000; i++) 773 /* ~2ms delay */
797 delay = ioread32(phw->dw2040_HPICSR + 774 hpios_delay_micro_seconds(2000);
798 HPI_RESET); 775
799 /* PLL not bypassed */ 776 /* PLL not bypassed */
800 hpi_write_word(pdo, 0x01B7C100, 0x0001); 777 hpi_write_word(pdo, 0x01B7C100, 0x0001);
801 /* ~200us delay */ 778 /* ~2ms delay */
802 for (i = 0; i < 2000; i++) 779 hpios_delay_micro_seconds(2000);
803 delay = ioread32(phw->dw2040_HPICSR +
804 HPI_RESET);
805 } 780 }
806 781
807 /* test r/w to internal DSP memory 782 /* test r/w to internal DSP memory
@@ -925,9 +900,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
925 } 900 }
926 901
927 /* delay a little to allow SDRAM and DSP to "get going" */ 902 /* delay a little to allow SDRAM and DSP to "get going" */
928 903 hpios_delay_micro_seconds(1000);
929 for (i = 0; i < 1000; i++)
930 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
931 904
932 /* test access to SDRAM */ 905 /* test access to SDRAM */
933 { 906 {
@@ -974,7 +947,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
974 947
975 /* write the DSP code down into the DSPs memory */ 948 /* write the DSP code down into the DSPs memory */
976 /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */ 949 /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */
977 dsp_code.ps_dev = pao->pci.p_os_data; 950 dsp_code.ps_dev = pao->pci.pci_dev;
978 951
979 error = hpi_dsp_code_open(boot_load_family, &dsp_code, 952 error = hpi_dsp_code_open(boot_load_family, &dsp_code,
980 pos_error_code); 953 pos_error_code);
@@ -1071,8 +1044,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1071 1044
1072 /* step 3. Start code by sending interrupt */ 1045 /* step 3. Start code by sending interrupt */
1073 iowrite32(0x00030003, pdo->prHPI_control); 1046 iowrite32(0x00030003, pdo->prHPI_control);
1074 for (i = 0; i < 10000; i++) 1047 hpios_delay_micro_seconds(10000);
1075 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
1076 1048
1077 /* wait for a non-zero value in hostcmd - 1049 /* wait for a non-zero value in hostcmd -
1078 * indicating initialization is complete 1050 * indicating initialization is complete
@@ -1099,7 +1071,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1099 * locks up with a bluescreen (NOT GPF or pagefault). 1071 * locks up with a bluescreen (NOT GPF or pagefault).
1100 */ 1072 */
1101 else 1073 else
1102 hpios_delay_micro_seconds(1000); 1074 hpios_delay_micro_seconds(10000);
1103 } 1075 }
1104 if (timeout == 0) 1076 if (timeout == 0)
1105 return HPI6000_ERROR_INIT_NOACK; 1077 return HPI6000_ERROR_INIT_NOACK;
@@ -1130,14 +1102,14 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1130 mask = 0xFFFFFF00L; 1102 mask = 0xFFFFFF00L;
1131 /* ASI5100 uses AX6 code, */ 1103 /* ASI5100 uses AX6 code, */
1132 /* but has no PLD r/w register to test */ 1104 /* but has no PLD r/w register to test */
1133 if (HPI_ADAPTER_FAMILY_ASI(pao->pci. 1105 if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev->
1134 subsys_device_id) == 1106 subsystem_device) ==
1135 HPI_ADAPTER_FAMILY_ASI(0x5100)) 1107 HPI_ADAPTER_FAMILY_ASI(0x5100))
1136 mask = 0x00000000L; 1108 mask = 0x00000000L;
1137 /* ASI5200 uses AX6 code, */ 1109 /* ASI5200 uses AX6 code, */
1138 /* but has no PLD r/w register to test */ 1110 /* but has no PLD r/w register to test */
1139 if (HPI_ADAPTER_FAMILY_ASI(pao->pci. 1111 if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev->
1140 subsys_device_id) == 1112 subsystem_device) ==
1141 HPI_ADAPTER_FAMILY_ASI(0x5200)) 1113 HPI_ADAPTER_FAMILY_ASI(0x5200))
1142 mask = 0x00000000L; 1114 mask = 0x00000000L;
1143 break; 1115 break;
@@ -1202,7 +1174,7 @@ static u32 hpi_read_word(struct dsp_obj *pdo, u32 address)
1202 u32 data = 0; 1174 u32 data = 0;
1203 1175
1204 if (hpi_set_address(pdo, address)) 1176 if (hpi_set_address(pdo, address))
1205 return 0; /*? no way to return error */ 1177 return 0; /*? No way to return error */
1206 1178
1207 /* take care of errata in revB DSP (2.0.1) */ 1179 /* take care of errata in revB DSP (2.0.1) */
1208 data = ioread32(pdo->prHPI_data); 1180 data = ioread32(pdo->prHPI_data);
@@ -1338,10 +1310,6 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1338 u32 *p_data; 1310 u32 *p_data;
1339 u16 error = 0; 1311 u16 error = 0;
1340 1312
1341 /* does the DSP we are referencing exist? */
1342 if (dsp_index >= phw->num_dsp)
1343 return HPI6000_ERROR_MSG_INVALID_DSP_INDEX;
1344
1345 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE); 1313 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1346 if (ack & HPI_HIF_ERROR_MASK) { 1314 if (ack & HPI_HIF_ERROR_MASK) {
1347 pao->dsp_crashed++; 1315 pao->dsp_crashed++;
@@ -1349,9 +1317,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1349 } 1317 }
1350 pao->dsp_crashed = 0; 1318 pao->dsp_crashed = 0;
1351 1319
1352 /* send the message */ 1320 /* get the message address and size */
1353
1354 /* get the address and size */
1355 if (phw->message_buffer_address_on_dsp == 0) { 1321 if (phw->message_buffer_address_on_dsp == 0) {
1356 timeout = TIMEOUT; 1322 timeout = TIMEOUT;
1357 do { 1323 do {
@@ -1366,10 +1332,9 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1366 } else 1332 } else
1367 address = phw->message_buffer_address_on_dsp; 1333 address = phw->message_buffer_address_on_dsp;
1368 1334
1369 /* dwLength = sizeof(struct hpi_message); */
1370 length = phm->size; 1335 length = phm->size;
1371 1336
1372 /* send it */ 1337 /* send the message */
1373 p_data = (u32 *)phm; 1338 p_data = (u32 *)phm;
1374 if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data, 1339 if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data,
1375 (u16)length / 4)) 1340 (u16)length / 4))
@@ -1383,7 +1348,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1383 if (ack & HPI_HIF_ERROR_MASK) 1348 if (ack & HPI_HIF_ERROR_MASK)
1384 return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK; 1349 return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK;
1385 1350
1386 /* get the address and size */ 1351 /* get the response address */
1387 if (phw->response_buffer_address_on_dsp == 0) { 1352 if (phw->response_buffer_address_on_dsp == 0) {
1388 timeout = TIMEOUT; 1353 timeout = TIMEOUT;
1389 do { 1354 do {
@@ -1407,7 +1372,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1407 if (!timeout) 1372 if (!timeout)
1408 length = sizeof(struct hpi_response); 1373 length = sizeof(struct hpi_response);
1409 1374
1410 /* get it */ 1375 /* get the response */
1411 p_data = (u32 *)phr; 1376 p_data = (u32 *)phr;
1412 if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data, 1377 if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data,
1413 (u16)length / 4)) 1378 (u16)length / 4))
@@ -1803,17 +1768,11 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
1803 hpios_dsplock_lock(pao); 1768 hpios_dsplock_lock(pao);
1804 error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr); 1769 error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr);
1805 1770
1806 /* maybe an error response */ 1771 if (error) /* something failed in the HPI/DSP interface */
1807 if (error) {
1808 /* something failed in the HPI/DSP interface */
1809 phr->error = error;
1810 /* just the header of the response is valid */
1811 phr->size = sizeof(struct hpi_response_header);
1812 goto err; 1772 goto err;
1813 }
1814 1773
1815 if (phr->error != 0) /* something failed in the DSP */ 1774 if (phr->error) /* something failed in the DSP */
1816 goto err; 1775 goto out;
1817 1776
1818 switch (phm->function) { 1777 switch (phm->function) {
1819 case HPI_OSTREAM_WRITE: 1778 case HPI_OSTREAM_WRITE:
@@ -1825,21 +1784,30 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
1825 error = hpi6000_get_data(pao, dsp_index, phm, phr); 1784 error = hpi6000_get_data(pao, dsp_index, phm, phr);
1826 break; 1785 break;
1827 case HPI_ADAPTER_GET_ASSERT: 1786 case HPI_ADAPTER_GET_ASSERT:
1828 phr->u.a.adapter_index = 0; /* dsp 0 default */ 1787 phr->u.ax.assert.dsp_index = 0; /* dsp 0 default */
1829 if (num_dsp == 2) { 1788 if (num_dsp == 2) {
1830 if (!phr->u.a.adapter_type) { 1789 if (!phr->u.ax.assert.count) {
1831 /* no assert from dsp 0, check dsp 1 */ 1790 /* no assert from dsp 0, check dsp 1 */
1832 error = hpi6000_message_response_sequence(pao, 1791 error = hpi6000_message_response_sequence(pao,
1833 1, phm, phr); 1792 1, phm, phr);
1834 phr->u.a.adapter_index = 1; 1793 phr->u.ax.assert.dsp_index = 1;
1835 } 1794 }
1836 } 1795 }
1837 } 1796 }
1838 1797
1839 if (error)
1840 phr->error = error;
1841
1842err: 1798err:
1799 if (error) {
1800 if (error >= HPI_ERROR_BACKEND_BASE) {
1801 phr->error = HPI_ERROR_DSP_COMMUNICATION;
1802 phr->specific_error = error;
1803 } else {
1804 phr->error = error;
1805 }
1806
1807 /* just the header of the response is valid */
1808 phr->size = sizeof(struct hpi_response_header);
1809 }
1810out:
1843 hpios_dsplock_unlock(pao); 1811 hpios_dsplock_unlock(pao);
1844 return; 1812 return;
1845} 1813}
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
index 22c5fc625533..9d5df54a6b46 100644
--- a/sound/pci/asihpi/hpi6205.c
+++ b/sound/pci/asihpi/hpi6205.c
@@ -38,27 +38,26 @@
38 38
39/*****************************************************************************/ 39/*****************************************************************************/
40/* HPI6205 specific error codes */ 40/* HPI6205 specific error codes */
41#define HPI6205_ERROR_BASE 1000 41#define HPI6205_ERROR_BASE 1000 /* not actually used anywhere */
42/*#define HPI6205_ERROR_MEM_ALLOC 1001 */ 42
43/* operational/messaging errors */
44#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015
45#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
46
47/* initialization/bootload errors */
43#define HPI6205_ERROR_6205_NO_IRQ 1002 48#define HPI6205_ERROR_6205_NO_IRQ 1002
44#define HPI6205_ERROR_6205_INIT_FAILED 1003 49#define HPI6205_ERROR_6205_INIT_FAILED 1003
45/*#define HPI6205_ERROR_MISSING_DSPCODE 1004 */
46#define HPI6205_ERROR_UNKNOWN_PCI_DEVICE 1005
47#define HPI6205_ERROR_6205_REG 1006 50#define HPI6205_ERROR_6205_REG 1006
48#define HPI6205_ERROR_6205_DSPPAGE 1007 51#define HPI6205_ERROR_6205_DSPPAGE 1007
49#define HPI6205_ERROR_BAD_DSPINDEX 1008
50#define HPI6205_ERROR_C6713_HPIC 1009 52#define HPI6205_ERROR_C6713_HPIC 1009
51#define HPI6205_ERROR_C6713_HPIA 1010 53#define HPI6205_ERROR_C6713_HPIA 1010
52#define HPI6205_ERROR_C6713_PLL 1011 54#define HPI6205_ERROR_C6713_PLL 1011
53#define HPI6205_ERROR_DSP_INTMEM 1012 55#define HPI6205_ERROR_DSP_INTMEM 1012
54#define HPI6205_ERROR_DSP_EXTMEM 1013 56#define HPI6205_ERROR_DSP_EXTMEM 1013
55#define HPI6205_ERROR_DSP_PLD 1014 57#define HPI6205_ERROR_DSP_PLD 1014
56#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015
57#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
58#define HPI6205_ERROR_6205_EEPROM 1017 58#define HPI6205_ERROR_6205_EEPROM 1017
59#define HPI6205_ERROR_DSP_EMIF 1018 59#define HPI6205_ERROR_DSP_EMIF 1018
60 60
61#define hpi6205_error(dsp_index, err) (err)
62/*****************************************************************************/ 61/*****************************************************************************/
63/* for C6205 PCI i/f */ 62/* for C6205 PCI i/f */
64/* Host Status Register (HSR) bitfields */ 63/* Host Status Register (HSR) bitfields */
@@ -128,9 +127,6 @@ struct hpi_hw_obj {
128 u32 outstream_host_buffer_size[HPI_MAX_STREAMS]; 127 u32 outstream_host_buffer_size[HPI_MAX_STREAMS];
129 128
130 struct consistent_dma_area h_control_cache; 129 struct consistent_dma_area h_control_cache;
131 struct consistent_dma_area h_async_event_buffer;
132/* struct hpi_control_cache_single *pControlCache; */
133 struct hpi_async_event *p_async_event_buffer;
134 struct hpi_control_cache *p_cache; 130 struct hpi_control_cache *p_cache;
135}; 131};
136 132
@@ -156,8 +152,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
156 152
157static void subsys_create_adapter(struct hpi_message *phm, 153static void subsys_create_adapter(struct hpi_message *phm,
158 struct hpi_response *phr); 154 struct hpi_response *phr);
159static void subsys_delete_adapter(struct hpi_message *phm, 155static void adapter_delete(struct hpi_adapter_obj *pao,
160 struct hpi_response *phr); 156 struct hpi_message *phm, struct hpi_response *phr);
161 157
162static u16 create_adapter_obj(struct hpi_adapter_obj *pao, 158static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
163 u32 *pos_error_code); 159 u32 *pos_error_code);
@@ -208,8 +204,8 @@ static void instream_start(struct hpi_adapter_obj *pao,
208static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index, 204static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
209 u32 address); 205 u32 address);
210 206
211static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index, 207static void boot_loader_write_mem32(struct hpi_adapter_obj *pao,
212 u32 address, u32 data); 208 int dsp_index, u32 address, u32 data);
213 209
214static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, 210static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao,
215 int dsp_index); 211 int dsp_index);
@@ -227,25 +223,13 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
227 223
228/*****************************************************************************/ 224/*****************************************************************************/
229 225
230static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) 226static void subsys_message(struct hpi_adapter_obj *pao,
227 struct hpi_message *phm, struct hpi_response *phr)
231{ 228{
232
233 switch (phm->function) { 229 switch (phm->function) {
234 case HPI_SUBSYS_OPEN:
235 case HPI_SUBSYS_CLOSE:
236 case HPI_SUBSYS_GET_INFO:
237 case HPI_SUBSYS_DRIVER_UNLOAD:
238 case HPI_SUBSYS_DRIVER_LOAD:
239 case HPI_SUBSYS_FIND_ADAPTERS:
240 /* messages that should not get here */
241 phr->error = HPI_ERROR_UNIMPLEMENTED;
242 break;
243 case HPI_SUBSYS_CREATE_ADAPTER: 230 case HPI_SUBSYS_CREATE_ADAPTER:
244 subsys_create_adapter(phm, phr); 231 subsys_create_adapter(phm, phr);
245 break; 232 break;
246 case HPI_SUBSYS_DELETE_ADAPTER:
247 subsys_delete_adapter(phm, phr);
248 break;
249 default: 233 default:
250 phr->error = HPI_ERROR_INVALID_FUNC; 234 phr->error = HPI_ERROR_INVALID_FUNC;
251 break; 235 break;
@@ -257,15 +241,22 @@ static void control_message(struct hpi_adapter_obj *pao,
257{ 241{
258 242
259 struct hpi_hw_obj *phw = pao->priv; 243 struct hpi_hw_obj *phw = pao->priv;
244 u16 pending_cache_error = 0;
260 245
261 switch (phm->function) { 246 switch (phm->function) {
262 case HPI_CONTROL_GET_STATE: 247 case HPI_CONTROL_GET_STATE:
263 if (pao->has_control_cache) { 248 if (pao->has_control_cache) {
264 rmb(); /* make sure we see updates DM_aed from DSP */ 249 rmb(); /* make sure we see updates DMAed from DSP */
265 if (hpi_check_control_cache(phw->p_cache, phm, phr)) 250 if (hpi_check_control_cache(phw->p_cache, phm, phr)) {
266 break; 251 break;
252 } else if (phm->u.c.attribute == HPI_METER_PEAK) {
253 pending_cache_error =
254 HPI_ERROR_CONTROL_CACHING;
255 }
267 } 256 }
268 hw_message(pao, phm, phr); 257 hw_message(pao, phm, phr);
258 if (pending_cache_error && !phr->error)
259 phr->error = pending_cache_error;
269 break; 260 break;
270 case HPI_CONTROL_GET_INFO: 261 case HPI_CONTROL_GET_INFO:
271 hw_message(pao, phm, phr); 262 hw_message(pao, phm, phr);
@@ -273,7 +264,8 @@ static void control_message(struct hpi_adapter_obj *pao,
273 case HPI_CONTROL_SET_STATE: 264 case HPI_CONTROL_SET_STATE:
274 hw_message(pao, phm, phr); 265 hw_message(pao, phm, phr);
275 if (pao->has_control_cache) 266 if (pao->has_control_cache)
276 hpi_sync_control_cache(phw->p_cache, phm, phr); 267 hpi_cmn_control_cache_sync_to_msg(phw->p_cache, phm,
268 phr);
277 break; 269 break;
278 default: 270 default:
279 phr->error = HPI_ERROR_INVALID_FUNC; 271 phr->error = HPI_ERROR_INVALID_FUNC;
@@ -285,6 +277,10 @@ static void adapter_message(struct hpi_adapter_obj *pao,
285 struct hpi_message *phm, struct hpi_response *phr) 277 struct hpi_message *phm, struct hpi_response *phr)
286{ 278{
287 switch (phm->function) { 279 switch (phm->function) {
280 case HPI_ADAPTER_DELETE:
281 adapter_delete(pao, phm, phr);
282 break;
283
288 default: 284 default:
289 hw_message(pao, phm, phr); 285 hw_message(pao, phm, phr);
290 break; 286 break;
@@ -296,9 +292,9 @@ static void outstream_message(struct hpi_adapter_obj *pao,
296{ 292{
297 293
298 if (phm->obj_index >= HPI_MAX_STREAMS) { 294 if (phm->obj_index >= HPI_MAX_STREAMS) {
299 phr->error = HPI_ERROR_INVALID_STREAM; 295 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
300 HPI_DEBUG_LOG(WARNING, 296 HPI_DEBUG_LOG(WARNING,
301 "message referencing invalid stream %d " 297 "Message referencing invalid stream %d "
302 "on adapter index %d\n", phm->obj_index, 298 "on adapter index %d\n", phm->obj_index,
303 phm->adapter_index); 299 phm->adapter_index);
304 return; 300 return;
@@ -340,9 +336,9 @@ static void instream_message(struct hpi_adapter_obj *pao,
340{ 336{
341 337
342 if (phm->obj_index >= HPI_MAX_STREAMS) { 338 if (phm->obj_index >= HPI_MAX_STREAMS) {
343 phr->error = HPI_ERROR_INVALID_STREAM; 339 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
344 HPI_DEBUG_LOG(WARNING, 340 HPI_DEBUG_LOG(WARNING,
345 "message referencing invalid stream %d " 341 "Message referencing invalid stream %d "
346 "on adapter index %d\n", phm->obj_index, 342 "on adapter index %d\n", phm->obj_index,
347 phm->adapter_index); 343 phm->adapter_index);
348 return; 344 return;
@@ -377,55 +373,32 @@ static void instream_message(struct hpi_adapter_obj *pao,
377/** Entry point to this HPI backend 373/** Entry point to this HPI backend
378 * All calls to the HPI start here 374 * All calls to the HPI start here
379 */ 375 */
380void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) 376void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
377 struct hpi_response *phr)
381{ 378{
382 struct hpi_adapter_obj *pao = NULL; 379 if (pao && (pao->dsp_crashed >= 10)
383 380 && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
384 /* subsytem messages are processed by every HPI. 381 /* allow last resort debug read even after crash */
385 * All other messages are ignored unless the adapter index matches 382 hpi_init_response(phr, phm->object, phm->function,
386 * an adapter in the HPI 383 HPI_ERROR_DSP_HARDWARE);
387 */ 384 HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", phm->object,
388 HPI_DEBUG_LOG(DEBUG, "HPI obj=%d, func=%d\n", phm->object, 385 phm->function);
389 phm->function); 386 return;
390
391 /* if Dsp has crashed then do not communicate with it any more */
392 if (phm->object != HPI_OBJ_SUBSYSTEM) {
393 pao = hpi_find_adapter(phm->adapter_index);
394 if (!pao) {
395 HPI_DEBUG_LOG(DEBUG,
396 " %d,%d refused, for another HPI?\n",
397 phm->object, phm->function);
398 return;
399 }
400
401 if ((pao->dsp_crashed >= 10)
402 && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
403 /* allow last resort debug read even after crash */
404 hpi_init_response(phr, phm->object, phm->function,
405 HPI_ERROR_DSP_HARDWARE);
406 HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n",
407 phm->object, phm->function);
408 return;
409 }
410 } 387 }
411 388
412 /* Init default response */ 389 /* Init default response */
413 if (phm->function != HPI_SUBSYS_CREATE_ADAPTER) 390 if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
414 hpi_init_response(phr, phm->object, phm->function, 391 phr->error = HPI_ERROR_PROCESSING_MESSAGE;
415 HPI_ERROR_PROCESSING_MESSAGE);
416 392
417 HPI_DEBUG_LOG(VERBOSE, "start of switch\n"); 393 HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
418 switch (phm->type) { 394 switch (phm->type) {
419 case HPI_TYPE_MESSAGE: 395 case HPI_TYPE_MESSAGE:
420 switch (phm->object) { 396 switch (phm->object) {
421 case HPI_OBJ_SUBSYSTEM: 397 case HPI_OBJ_SUBSYSTEM:
422 subsys_message(phm, phr); 398 subsys_message(pao, phm, phr);
423 break; 399 break;
424 400
425 case HPI_OBJ_ADAPTER: 401 case HPI_OBJ_ADAPTER:
426 phr->size =
427 sizeof(struct hpi_response_header) +
428 sizeof(struct hpi_adapter_res);
429 adapter_message(pao, phm, phr); 402 adapter_message(pao, phm, phr);
430 break; 403 break;
431 404
@@ -454,6 +427,26 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
454 } 427 }
455} 428}
456 429
430void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
431{
432 struct hpi_adapter_obj *pao = NULL;
433
434 if (phm->object != HPI_OBJ_SUBSYSTEM) {
435 /* normal messages must have valid adapter index */
436 pao = hpi_find_adapter(phm->adapter_index);
437 } else {
438 /* subsys messages don't address an adapter */
439 _HPI_6205(NULL, phm, phr);
440 return;
441 }
442
443 if (pao)
444 _HPI_6205(pao, phm, phr);
445 else
446 hpi_init_response(phr, phm->object, phm->function,
447 HPI_ERROR_BAD_ADAPTER_NUMBER);
448}
449
457/*****************************************************************************/ 450/*****************************************************************************/
458/* SUBSYSTEM */ 451/* SUBSYSTEM */
459 452
@@ -474,46 +467,38 @@ static void subsys_create_adapter(struct hpi_message *phm,
474 467
475 memset(&ao, 0, sizeof(ao)); 468 memset(&ao, 0, sizeof(ao));
476 469
477 /* this HPI only creates adapters for TI/PCI devices */
478 if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
479 return;
480 if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
481 return;
482 if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_DSP6205)
483 return;
484
485 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); 470 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
486 if (!ao.priv) { 471 if (!ao.priv) {
487 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); 472 HPI_DEBUG_LOG(ERROR, "can't get mem for adapter object\n");
488 phr->error = HPI_ERROR_MEMORY_ALLOC; 473 phr->error = HPI_ERROR_MEMORY_ALLOC;
489 return; 474 return;
490 } 475 }
491 476
492 ao.pci = *phm->u.s.resource.r.pci; 477 ao.pci = *phm->u.s.resource.r.pci;
493 err = create_adapter_obj(&ao, &os_error_code); 478 err = create_adapter_obj(&ao, &os_error_code);
494 if (!err)
495 err = hpi_add_adapter(&ao);
496 if (err) { 479 if (err) {
497 phr->u.s.data = os_error_code;
498 delete_adapter_obj(&ao); 480 delete_adapter_obj(&ao);
499 phr->error = err; 481 if (err >= HPI_ERROR_BACKEND_BASE) {
482 phr->error = HPI_ERROR_DSP_BOOTLOAD;
483 phr->specific_error = err;
484 } else {
485 phr->error = err;
486 }
487 phr->u.s.data = os_error_code;
500 return; 488 return;
501 } 489 }
502 490
503 phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type; 491 phr->u.s.adapter_type = ao.adapter_type;
504 phr->u.s.adapter_index = ao.index; 492 phr->u.s.adapter_index = ao.index;
505 phr->u.s.num_adapters++;
506 phr->error = 0; 493 phr->error = 0;
507} 494}
508 495
509/** delete an adapter - required by WDM driver */ 496/** delete an adapter - required by WDM driver */
510static void subsys_delete_adapter(struct hpi_message *phm, 497static void adapter_delete(struct hpi_adapter_obj *pao,
511 struct hpi_response *phr) 498 struct hpi_message *phm, struct hpi_response *phr)
512{ 499{
513 struct hpi_adapter_obj *pao;
514 struct hpi_hw_obj *phw; 500 struct hpi_hw_obj *phw;
515 501
516 pao = hpi_find_adapter(phm->adapter_index);
517 if (!pao) { 502 if (!pao) {
518 phr->error = HPI_ERROR_INVALID_OBJ_INDEX; 503 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
519 return; 504 return;
@@ -526,6 +511,7 @@ static void subsys_delete_adapter(struct hpi_message *phm,
526 iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR); 511 iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR);
527 512
528 delete_adapter_obj(pao); 513 delete_adapter_obj(pao);
514 hpi_delete_adapter(pao);
529 phr->error = 0; 515 phr->error = 0;
530} 516}
531 517
@@ -538,10 +524,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
538 struct hpi_hw_obj *phw = pao->priv; 524 struct hpi_hw_obj *phw = pao->priv;
539 struct bus_master_interface *interface; 525 struct bus_master_interface *interface;
540 u32 phys_addr; 526 u32 phys_addr;
541#ifndef HPI6205_NO_HSR_POLL
542 u32 time_out = HPI6205_TIMEOUT;
543 u32 temp1;
544#endif
545 int i; 527 int i;
546 u16 err; 528 u16 err;
547 529
@@ -566,7 +548,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
566 548
567 if (hpios_locked_mem_alloc(&phw->h_locked_mem, 549 if (hpios_locked_mem_alloc(&phw->h_locked_mem,
568 sizeof(struct bus_master_interface), 550 sizeof(struct bus_master_interface),
569 pao->pci.p_os_data)) 551 pao->pci.pci_dev))
570 phw->p_interface_buffer = NULL; 552 phw->p_interface_buffer = NULL;
571 else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem, 553 else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem,
572 (void *)&phw->p_interface_buffer)) 554 (void *)&phw->p_interface_buffer))
@@ -582,58 +564,39 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
582 } 564 }
583 565
584 err = adapter_boot_load_dsp(pao, pos_error_code); 566 err = adapter_boot_load_dsp(pao, pos_error_code);
585 if (err) 567 if (err) {
568 HPI_DEBUG_LOG(ERROR, "DSP code load failed\n");
586 /* no need to clean up as SubSysCreateAdapter */ 569 /* no need to clean up as SubSysCreateAdapter */
587 /* calls DeleteAdapter on error. */ 570 /* calls DeleteAdapter on error. */
588 return err; 571 return err;
589 572 }
590 HPI_DEBUG_LOG(INFO, "load DSP code OK\n"); 573 HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
591 574
592 /* allow boot load even if mem alloc wont work */ 575 /* allow boot load even if mem alloc wont work */
593 if (!phw->p_interface_buffer) 576 if (!phw->p_interface_buffer)
594 return hpi6205_error(0, HPI_ERROR_MEMORY_ALLOC); 577 return HPI_ERROR_MEMORY_ALLOC;
595 578
596 interface = phw->p_interface_buffer; 579 interface = phw->p_interface_buffer;
597 580
598#ifndef HPI6205_NO_HSR_POLL
599 /* wait for first interrupt indicating the DSP init is done */
600 time_out = HPI6205_TIMEOUT * 10;
601 temp1 = 0;
602 while (((temp1 & C6205_HSR_INTSRC) == 0) && --time_out)
603 temp1 = ioread32(phw->prHSR);
604
605 if (temp1 & C6205_HSR_INTSRC)
606 HPI_DEBUG_LOG(INFO,
607 "interrupt confirming DSP code running OK\n");
608 else {
609 HPI_DEBUG_LOG(ERROR,
610 "timed out waiting for interrupt "
611 "confirming DSP code running\n");
612 return hpi6205_error(0, HPI6205_ERROR_6205_NO_IRQ);
613 }
614
615 /* reset the interrupt */
616 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
617#endif
618
619 /* make sure the DSP has started ok */ 581 /* make sure the DSP has started ok */
620 if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) { 582 if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) {
621 HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n"); 583 HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n");
622 return hpi6205_error(0, HPI6205_ERROR_6205_INIT_FAILED); 584 return HPI6205_ERROR_6205_INIT_FAILED;
623 } 585 }
624 /* Note that *pao, *phw are zeroed after allocation, 586 /* Note that *pao, *phw are zeroed after allocation,
625 * so pointers and flags are NULL by default. 587 * so pointers and flags are NULL by default.
626 * Allocate bus mastering control cache buffer and tell the DSP about it 588 * Allocate bus mastering control cache buffer and tell the DSP about it
627 */ 589 */
628 if (interface->control_cache.number_of_controls) { 590 if (interface->control_cache.number_of_controls) {
629 void *p_control_cache_virtual; 591 u8 *p_control_cache_virtual;
630 592
631 err = hpios_locked_mem_alloc(&phw->h_control_cache, 593 err = hpios_locked_mem_alloc(&phw->h_control_cache,
632 interface->control_cache.size_in_bytes, 594 interface->control_cache.size_in_bytes,
633 pao->pci.p_os_data); 595 pao->pci.pci_dev);
634 if (!err) 596 if (!err)
635 err = hpios_locked_mem_get_virt_addr(&phw-> 597 err = hpios_locked_mem_get_virt_addr(&phw->
636 h_control_cache, &p_control_cache_virtual); 598 h_control_cache,
599 (void *)&p_control_cache_virtual);
637 if (!err) { 600 if (!err) {
638 memset(p_control_cache_virtual, 0, 601 memset(p_control_cache_virtual, 0,
639 interface->control_cache.size_in_bytes); 602 interface->control_cache.size_in_bytes);
@@ -642,8 +605,10 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
642 hpi_alloc_control_cache(interface-> 605 hpi_alloc_control_cache(interface->
643 control_cache.number_of_controls, 606 control_cache.number_of_controls,
644 interface->control_cache.size_in_bytes, 607 interface->control_cache.size_in_bytes,
645 (struct hpi_control_cache_info *)
646 p_control_cache_virtual); 608 p_control_cache_virtual);
609
610 if (!phw->p_cache)
611 err = HPI_ERROR_MEMORY_ALLOC;
647 } 612 }
648 if (!err) { 613 if (!err) {
649 err = hpios_locked_mem_get_phys_addr(&phw-> 614 err = hpios_locked_mem_get_phys_addr(&phw->
@@ -660,96 +625,67 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
660 pao->has_control_cache = 0; 625 pao->has_control_cache = 0;
661 } 626 }
662 } 627 }
663 /* allocate bus mastering async buffer and tell the DSP about it */
664 if (interface->async_buffer.b.size) {
665 err = hpios_locked_mem_alloc(&phw->h_async_event_buffer,
666 interface->async_buffer.b.size *
667 sizeof(struct hpi_async_event), pao->pci.p_os_data);
668 if (!err)
669 err = hpios_locked_mem_get_virt_addr
670 (&phw->h_async_event_buffer, (void *)
671 &phw->p_async_event_buffer);
672 if (!err)
673 memset((void *)phw->p_async_event_buffer, 0,
674 interface->async_buffer.b.size *
675 sizeof(struct hpi_async_event));
676 if (!err) {
677 err = hpios_locked_mem_get_phys_addr
678 (&phw->h_async_event_buffer, &phys_addr);
679 interface->async_buffer.physical_address32 =
680 phys_addr;
681 }
682 if (err) {
683 if (hpios_locked_mem_valid(&phw->
684 h_async_event_buffer)) {
685 hpios_locked_mem_free
686 (&phw->h_async_event_buffer);
687 phw->p_async_event_buffer = NULL;
688 }
689 }
690 }
691 send_dsp_command(phw, H620_HIF_IDLE); 628 send_dsp_command(phw, H620_HIF_IDLE);
692 629
693 { 630 {
694 struct hpi_message hM; 631 struct hpi_message hm;
695 struct hpi_response hR; 632 struct hpi_response hr;
696 u32 max_streams; 633 u32 max_streams;
697 634
698 HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n"); 635 HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
699 memset(&hM, 0, sizeof(hM)); 636 memset(&hm, 0, sizeof(hm));
700 hM.type = HPI_TYPE_MESSAGE; 637 hm.type = HPI_TYPE_MESSAGE;
701 hM.size = sizeof(hM); 638 hm.size = sizeof(hm);
702 hM.object = HPI_OBJ_ADAPTER; 639 hm.object = HPI_OBJ_ADAPTER;
703 hM.function = HPI_ADAPTER_GET_INFO; 640 hm.function = HPI_ADAPTER_GET_INFO;
704 hM.adapter_index = 0; 641 hm.adapter_index = 0;
705 memset(&hR, 0, sizeof(hR)); 642 memset(&hr, 0, sizeof(hr));
706 hR.size = sizeof(hR); 643 hr.size = sizeof(hr);
707 644
708 err = message_response_sequence(pao, &hM, &hR); 645 err = message_response_sequence(pao, &hm, &hr);
709 if (err) { 646 if (err) {
710 HPI_DEBUG_LOG(ERROR, "message transport error %d\n", 647 HPI_DEBUG_LOG(ERROR, "message transport error %d\n",
711 err); 648 err);
712 return err; 649 return err;
713 } 650 }
714 if (hR.error) 651 if (hr.error)
715 return hR.error; 652 return hr.error;
716 653
717 pao->adapter_type = hR.u.a.adapter_type; 654 pao->adapter_type = hr.u.ax.info.adapter_type;
718 pao->index = hR.u.a.adapter_index; 655 pao->index = hr.u.ax.info.adapter_index;
719 656
720 max_streams = hR.u.a.num_outstreams + hR.u.a.num_instreams; 657 max_streams =
658 hr.u.ax.info.num_outstreams +
659 hr.u.ax.info.num_instreams;
721 660
722 hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams, 661 hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
723 65536, pao->pci.p_os_data); 662 65536, pao->pci.pci_dev);
724 663
725 HPI_DEBUG_LOG(VERBOSE, 664 HPI_DEBUG_LOG(VERBOSE,
726 "got adapter info type %x index %d serial %d\n", 665 "got adapter info type %x index %d serial %d\n",
727 hR.u.a.adapter_type, hR.u.a.adapter_index, 666 hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index,
728 hR.u.a.serial_number); 667 hr.u.ax.info.serial_number);
729 } 668 }
730 669
731 pao->open = 0; /* upon creation the adapter is closed */ 670 pao->open = 0; /* upon creation the adapter is closed */
732 671
672 if (phw->p_cache)
673 phw->p_cache->adap_idx = pao->index;
674
733 HPI_DEBUG_LOG(INFO, "bootload DSP OK\n"); 675 HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
734 return 0; 676
677 return hpi_add_adapter(pao);
735} 678}
736 679
737/** Free memory areas allocated by adapter 680/** Free memory areas allocated by adapter
738 * this routine is called from SubSysDeleteAdapter, 681 * this routine is called from AdapterDelete,
739 * and SubSysCreateAdapter if duplicate index 682 * and SubSysCreateAdapter if duplicate index
740*/ 683*/
741static void delete_adapter_obj(struct hpi_adapter_obj *pao) 684static void delete_adapter_obj(struct hpi_adapter_obj *pao)
742{ 685{
743 struct hpi_hw_obj *phw; 686 struct hpi_hw_obj *phw = pao->priv;
744 int i; 687 int i;
745 688
746 phw = pao->priv;
747
748 if (hpios_locked_mem_valid(&phw->h_async_event_buffer)) {
749 hpios_locked_mem_free(&phw->h_async_event_buffer);
750 phw->p_async_event_buffer = NULL;
751 }
752
753 if (hpios_locked_mem_valid(&phw->h_control_cache)) { 689 if (hpios_locked_mem_valid(&phw->h_control_cache)) {
754 hpios_locked_mem_free(&phw->h_control_cache); 690 hpios_locked_mem_free(&phw->h_control_cache);
755 hpi_free_control_cache(phw->p_cache); 691 hpi_free_control_cache(phw->p_cache);
@@ -774,13 +710,15 @@ static void delete_adapter_obj(struct hpi_adapter_obj *pao)
774 phw->outstream_host_buffer_size[i] = 0; 710 phw->outstream_host_buffer_size[i] = 0;
775 } 711 }
776 712
777 hpios_locked_mem_unprepare(pao->pci.p_os_data); 713 hpios_locked_mem_unprepare(pao->pci.pci_dev);
778 714
779 hpi_delete_adapter(pao);
780 kfree(phw); 715 kfree(phw);
781} 716}
782 717
783/*****************************************************************************/ 718/*****************************************************************************/
719/* Adapter functions */
720
721/*****************************************************************************/
784/* OutStream Host buffer functions */ 722/* OutStream Host buffer functions */
785 723
786/** Allocate or attach buffer for busmastering 724/** Allocate or attach buffer for busmastering
@@ -822,7 +760,7 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
822 760
823 err = hpios_locked_mem_alloc(&phw->outstream_host_buffers 761 err = hpios_locked_mem_alloc(&phw->outstream_host_buffers
824 [phm->obj_index], phm->u.d.u.buffer.buffer_size, 762 [phm->obj_index], phm->u.d.u.buffer.buffer_size,
825 pao->pci.p_os_data); 763 pao->pci.pci_dev);
826 764
827 if (err) { 765 if (err) {
828 phr->error = HPI_ERROR_INVALID_DATASIZE; 766 phr->error = HPI_ERROR_INVALID_DATASIZE;
@@ -859,7 +797,7 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
859 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer. 797 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
860 buffer_size - 1)) { 798 buffer_size - 1)) {
861 HPI_DEBUG_LOG(ERROR, 799 HPI_DEBUG_LOG(ERROR,
862 "buffer size must be 2^N not %d\n", 800 "Buffer size must be 2^N not %d\n",
863 phm->u.d.u.buffer.buffer_size); 801 phm->u.d.u.buffer.buffer_size);
864 phr->error = HPI_ERROR_INVALID_DATASIZE; 802 phr->error = HPI_ERROR_INVALID_DATASIZE;
865 return; 803 return;
@@ -873,6 +811,7 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
873 status->dSP_index = 0; 811 status->dSP_index = 0;
874 status->host_index = status->dSP_index; 812 status->host_index = status->dSP_index;
875 status->size_in_bytes = phm->u.d.u.buffer.buffer_size; 813 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
814 status->auxiliary_data_available = 0;
876 815
877 hw_message(pao, phm, phr); 816 hw_message(pao, phm, phr);
878 817
@@ -964,51 +903,6 @@ static void outstream_write(struct hpi_adapter_obj *pao,
964 hpi_init_response(phr, phm->object, phm->function, 0); 903 hpi_init_response(phr, phm->object, phm->function, 0);
965 status = &interface->outstream_host_buffer_status[phm->obj_index]; 904 status = &interface->outstream_host_buffer_status[phm->obj_index];
966 905
967 if (phw->flag_outstream_just_reset[phm->obj_index]) {
968 /* First OutStremWrite() call following reset will write data to the
969 adapter's buffers, reducing delay before stream can start. The DSP
970 takes care of setting the stream data format using format information
971 embedded in phm.
972 */
973 int partial_write = 0;
974 unsigned int original_size = 0;
975
976 phw->flag_outstream_just_reset[phm->obj_index] = 0;
977
978 /* Send the first buffer to the DSP the old way. */
979 /* Limit size of first transfer - */
980 /* expect that this will not usually be triggered. */
981 if (phm->u.d.u.data.data_size > HPI6205_SIZEOF_DATA) {
982 partial_write = 1;
983 original_size = phm->u.d.u.data.data_size;
984 phm->u.d.u.data.data_size = HPI6205_SIZEOF_DATA;
985 }
986 /* write it */
987 phm->function = HPI_OSTREAM_WRITE;
988 hw_message(pao, phm, phr);
989
990 if (phr->error)
991 return;
992
993 /* update status information that the DSP would typically
994 * update (and will update next time the DSP
995 * buffer update task reads data from the host BBM buffer)
996 */
997 status->auxiliary_data_available = phm->u.d.u.data.data_size;
998 status->host_index += phm->u.d.u.data.data_size;
999 status->dSP_index += phm->u.d.u.data.data_size;
1000
1001 /* if we did a full write, we can return from here. */
1002 if (!partial_write)
1003 return;
1004
1005 /* tweak buffer parameters and let the rest of the */
1006 /* buffer land in internal BBM buffer */
1007 phm->u.d.u.data.data_size =
1008 original_size - HPI6205_SIZEOF_DATA;
1009 phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA;
1010 }
1011
1012 space_available = outstream_get_space_available(status); 906 space_available = outstream_get_space_available(status);
1013 if (space_available < phm->u.d.u.data.data_size) { 907 if (space_available < phm->u.d.u.data.data_size) {
1014 phr->error = HPI_ERROR_INVALID_DATASIZE; 908 phr->error = HPI_ERROR_INVALID_DATASIZE;
@@ -1045,6 +939,24 @@ static void outstream_write(struct hpi_adapter_obj *pao,
1045 memcpy(p_bbm_data, p_app_data + l_first_write, 939 memcpy(p_bbm_data, p_app_data + l_first_write,
1046 phm->u.d.u.data.data_size - l_first_write); 940 phm->u.d.u.data.data_size - l_first_write);
1047 } 941 }
942
943 /*
944 * This version relies on the DSP code triggering an OStream buffer
945 * update immediately following a SET_FORMAT call. The host has
946 * already written data into the BBM buffer, but the DSP won't know
947 * about it until dwHostIndex is adjusted.
948 */
949 if (phw->flag_outstream_just_reset[phm->obj_index]) {
950 /* Format can only change after reset. Must tell DSP. */
951 u16 function = phm->function;
952 phw->flag_outstream_just_reset[phm->obj_index] = 0;
953 phm->function = HPI_OSTREAM_SET_FORMAT;
954 hw_message(pao, phm, phr); /* send the format to the DSP */
955 phm->function = function;
956 if (phr->error)
957 return;
958 }
959
1048 status->host_index += phm->u.d.u.data.data_size; 960 status->host_index += phm->u.d.u.data.data_size;
1049} 961}
1050 962
@@ -1130,7 +1042,7 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1130 1042
1131 err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm-> 1043 err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm->
1132 obj_index], phm->u.d.u.buffer.buffer_size, 1044 obj_index], phm->u.d.u.buffer.buffer_size,
1133 pao->pci.p_os_data); 1045 pao->pci.pci_dev);
1134 1046
1135 if (err) { 1047 if (err) {
1136 phr->error = HPI_ERROR_INVALID_DATASIZE; 1048 phr->error = HPI_ERROR_INVALID_DATASIZE;
@@ -1161,7 +1073,7 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1161 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer. 1073 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
1162 buffer_size - 1)) { 1074 buffer_size - 1)) {
1163 HPI_DEBUG_LOG(ERROR, 1075 HPI_DEBUG_LOG(ERROR,
1164 "buffer size must be 2^N not %d\n", 1076 "Buffer size must be 2^N not %d\n",
1165 phm->u.d.u.buffer.buffer_size); 1077 phm->u.d.u.buffer.buffer_size);
1166 phr->error = HPI_ERROR_INVALID_DATASIZE; 1078 phr->error = HPI_ERROR_INVALID_DATASIZE;
1167 return; 1079 return;
@@ -1176,8 +1088,10 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1176 status->dSP_index = 0; 1088 status->dSP_index = 0;
1177 status->host_index = status->dSP_index; 1089 status->host_index = status->dSP_index;
1178 status->size_in_bytes = phm->u.d.u.buffer.buffer_size; 1090 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
1091 status->auxiliary_data_available = 0;
1179 1092
1180 hw_message(pao, phm, phr); 1093 hw_message(pao, phm, phr);
1094
1181 if (phr->error 1095 if (phr->error
1182 && hpios_locked_mem_valid(&phw-> 1096 && hpios_locked_mem_valid(&phw->
1183 instream_host_buffers[phm->obj_index])) { 1097 instream_host_buffers[phm->obj_index])) {
@@ -1342,33 +1256,37 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1342 struct hpi_hw_obj *phw = pao->priv; 1256 struct hpi_hw_obj *phw = pao->priv;
1343 struct dsp_code dsp_code; 1257 struct dsp_code dsp_code;
1344 u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD]; 1258 u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD];
1345 u16 firmware_id = pao->pci.subsys_device_id;
1346 u32 temp; 1259 u32 temp;
1347 int dsp = 0, i = 0; 1260 int dsp = 0, i = 0;
1348 u16 err = 0; 1261 u16 err = 0;
1349 1262
1350 boot_code_id[0] = HPI_ADAPTER_ASI(0x6205); 1263 boot_code_id[0] = HPI_ADAPTER_ASI(0x6205);
1351 1264
1352 /* special cases where firmware_id != subsys ID */ 1265 boot_code_id[1] = pao->pci.pci_dev->subsystem_device;
1353 switch (firmware_id) { 1266 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(boot_code_id[1]);
1267
1268 /* fix up cases where bootcode id[1] != subsys id */
1269 switch (boot_code_id[1]) {
1354 case HPI_ADAPTER_FAMILY_ASI(0x5000): 1270 case HPI_ADAPTER_FAMILY_ASI(0x5000):
1355 boot_code_id[0] = firmware_id; 1271 boot_code_id[0] = boot_code_id[1];
1356 firmware_id = 0; 1272 boot_code_id[1] = 0;
1357 break; 1273 break;
1358 case HPI_ADAPTER_FAMILY_ASI(0x5300): 1274 case HPI_ADAPTER_FAMILY_ASI(0x5300):
1359 case HPI_ADAPTER_FAMILY_ASI(0x5400): 1275 case HPI_ADAPTER_FAMILY_ASI(0x5400):
1360 case HPI_ADAPTER_FAMILY_ASI(0x6300): 1276 case HPI_ADAPTER_FAMILY_ASI(0x6300):
1361 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6400); 1277 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400);
1362 break; 1278 break;
1279 case HPI_ADAPTER_FAMILY_ASI(0x5500):
1363 case HPI_ADAPTER_FAMILY_ASI(0x5600): 1280 case HPI_ADAPTER_FAMILY_ASI(0x5600):
1364 case HPI_ADAPTER_FAMILY_ASI(0x6500): 1281 case HPI_ADAPTER_FAMILY_ASI(0x6500):
1365 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600); 1282 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600);
1366 break; 1283 break;
1367 case HPI_ADAPTER_FAMILY_ASI(0x8800): 1284 case HPI_ADAPTER_FAMILY_ASI(0x8800):
1368 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x8900); 1285 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x8900);
1286 break;
1287 default:
1369 break; 1288 break;
1370 } 1289 }
1371 boot_code_id[1] = firmware_id;
1372 1290
1373 /* reset DSP by writing a 1 to the WARMRESET bit */ 1291 /* reset DSP by writing a 1 to the WARMRESET bit */
1374 temp = C6205_HDCR_WARMRESET; 1292 temp = C6205_HDCR_WARMRESET;
@@ -1379,7 +1297,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1379 temp = ioread32(phw->prHSR); 1297 temp = ioread32(phw->prHSR);
1380 if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) != 1298 if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) !=
1381 C6205_HSR_EEREAD) 1299 C6205_HSR_EEREAD)
1382 return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM); 1300 return HPI6205_ERROR_6205_EEPROM;
1383 temp |= 0x04; 1301 temp |= 0x04;
1384 /* disable PINTA interrupt */ 1302 /* disable PINTA interrupt */
1385 iowrite32(temp, phw->prHSR); 1303 iowrite32(temp, phw->prHSR);
@@ -1387,27 +1305,27 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1387 /* check control register reports PCI boot mode */ 1305 /* check control register reports PCI boot mode */
1388 temp = ioread32(phw->prHDCR); 1306 temp = ioread32(phw->prHDCR);
1389 if (!(temp & C6205_HDCR_PCIBOOT)) 1307 if (!(temp & C6205_HDCR_PCIBOOT))
1390 return hpi6205_error(0, HPI6205_ERROR_6205_REG); 1308 return HPI6205_ERROR_6205_REG;
1391 1309
1392 /* try writing a couple of numbers to the DSP page register */ 1310 /* try writing a few numbers to the DSP page register */
1393 /* and reading them back. */ 1311 /* and reading them back. */
1394 temp = 1; 1312 temp = 3;
1395 iowrite32(temp, phw->prDSPP); 1313 iowrite32(temp, phw->prDSPP);
1396 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) 1314 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1397 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); 1315 return HPI6205_ERROR_6205_DSPPAGE;
1398 temp = 2; 1316 temp = 2;
1399 iowrite32(temp, phw->prDSPP); 1317 iowrite32(temp, phw->prDSPP);
1400 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) 1318 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1401 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); 1319 return HPI6205_ERROR_6205_DSPPAGE;
1402 temp = 3; 1320 temp = 1;
1403 iowrite32(temp, phw->prDSPP); 1321 iowrite32(temp, phw->prDSPP);
1404 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) 1322 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1405 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); 1323 return HPI6205_ERROR_6205_DSPPAGE;
1406 /* reset DSP page to the correct number */ 1324 /* reset DSP page to the correct number */
1407 temp = 0; 1325 temp = 0;
1408 iowrite32(temp, phw->prDSPP); 1326 iowrite32(temp, phw->prDSPP);
1409 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) 1327 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1410 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); 1328 return HPI6205_ERROR_6205_DSPPAGE;
1411 phw->dsp_page = 0; 1329 phw->dsp_page = 0;
1412 1330
1413 /* release 6713 from reset before 6205 is bootloaded. 1331 /* release 6713 from reset before 6205 is bootloaded.
@@ -1453,7 +1371,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1453 return err; 1371 return err;
1454 1372
1455 /* write the DSP code down into the DSPs memory */ 1373 /* write the DSP code down into the DSPs memory */
1456 dsp_code.ps_dev = pao->pci.p_os_data; 1374 dsp_code.ps_dev = pao->pci.pci_dev;
1457 err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code, 1375 err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
1458 pos_error_code); 1376 pos_error_code);
1459 if (err) 1377 if (err)
@@ -1482,10 +1400,8 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1482 if (err) 1400 if (err)
1483 break; 1401 break;
1484 for (i = 0; i < (int)length; i++) { 1402 for (i = 0; i < (int)length; i++) {
1485 err = boot_loader_write_mem32(pao, dsp, 1403 boot_loader_write_mem32(pao, dsp, address,
1486 address, *pcode); 1404 *pcode);
1487 if (err)
1488 break;
1489 /* dummy read every 4 words */ 1405 /* dummy read every 4 words */
1490 /* for 6205 advisory 1.4.4 */ 1406 /* for 6205 advisory 1.4.4 */
1491 if (i % 4 == 0) 1407 if (i % 4 == 0)
@@ -1559,7 +1475,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1559 host_mailbox_address_on_dsp = 0x80000000; 1475 host_mailbox_address_on_dsp = 0x80000000;
1560 while ((physicalPC_iaddress != physicalPC_iaddress_verify) 1476 while ((physicalPC_iaddress != physicalPC_iaddress_verify)
1561 && time_out--) { 1477 && time_out--) {
1562 err = boot_loader_write_mem32(pao, 0, 1478 boot_loader_write_mem32(pao, 0,
1563 host_mailbox_address_on_dsp, 1479 host_mailbox_address_on_dsp,
1564 physicalPC_iaddress); 1480 physicalPC_iaddress);
1565 physicalPC_iaddress_verify = 1481 physicalPC_iaddress_verify =
@@ -1629,11 +1545,10 @@ static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1629 return data; 1545 return data;
1630} 1546}
1631 1547
1632static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index, 1548static void boot_loader_write_mem32(struct hpi_adapter_obj *pao,
1633 u32 address, u32 data) 1549 int dsp_index, u32 address, u32 data)
1634{ 1550{
1635 struct hpi_hw_obj *phw = pao->priv; 1551 struct hpi_hw_obj *phw = pao->priv;
1636 u16 err = 0;
1637 __iomem u32 *p_data; 1552 __iomem u32 *p_data;
1638 /* u32 dwVerifyData=0; */ 1553 /* u32 dwVerifyData=0; */
1639 1554
@@ -1673,15 +1588,11 @@ static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1673 1588
1674 /* dummy read every 4 words for 6205 advisory 1.4.4 */ 1589 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1675 boot_loader_read_mem32(pao, 0, 0); 1590 boot_loader_read_mem32(pao, 0, 0);
1676 } else 1591 }
1677 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1678 return err;
1679} 1592}
1680 1593
1681static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) 1594static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1682{ 1595{
1683 u16 err = 0;
1684
1685 if (dsp_index == 0) { 1596 if (dsp_index == 0) {
1686 u32 setting; 1597 u32 setting;
1687 1598
@@ -1709,8 +1620,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1709 boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting); 1620 boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
1710 if (setting != boot_loader_read_mem32(pao, dsp_index, 1621 if (setting != boot_loader_read_mem32(pao, dsp_index,
1711 0x01800008)) 1622 0x01800008))
1712 return hpi6205_error(dsp_index, 1623 return HPI6205_ERROR_DSP_EMIF;
1713 HPI6205_ERROR_DSP_EMIF);
1714 1624
1715 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */ 1625 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
1716 /* which occupies D15..0. 6713 starts at 27MHz, so need */ 1626 /* which occupies D15..0. 6713 starts at 27MHz, so need */
@@ -1723,8 +1633,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1723 boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting); 1633 boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
1724 if (setting != boot_loader_read_mem32(pao, dsp_index, 1634 if (setting != boot_loader_read_mem32(pao, dsp_index,
1725 0x01800004)) 1635 0x01800004))
1726 return hpi6205_error(dsp_index, 1636 return HPI6205_ERROR_DSP_EMIF;
1727 HPI6205_ERROR_DSP_EMIF);
1728 1637
1729 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */ 1638 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
1730 /* which occupies D15..0. 6713 starts at 27MHz, so need */ 1639 /* which occupies D15..0. 6713 starts at 27MHz, so need */
@@ -1736,8 +1645,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1736 boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting); 1645 boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
1737 if (setting != boot_loader_read_mem32(pao, dsp_index, 1646 if (setting != boot_loader_read_mem32(pao, dsp_index,
1738 0x01800010)) 1647 0x01800010))
1739 return hpi6205_error(dsp_index, 1648 return HPI6205_ERROR_DSP_EMIF;
1740 HPI6205_ERROR_DSP_EMIF);
1741 1649
1742 /* EMIF CE3 setup - 32 bit async. */ 1650 /* EMIF CE3 setup - 32 bit async. */
1743 /* This is the PLD on the ASI5000 cards only */ 1651 /* This is the PLD on the ASI5000 cards only */
@@ -1748,8 +1656,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1748 boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting); 1656 boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
1749 if (setting != boot_loader_read_mem32(pao, dsp_index, 1657 if (setting != boot_loader_read_mem32(pao, dsp_index,
1750 0x01800014)) 1658 0x01800014))
1751 return hpi6205_error(dsp_index, 1659 return HPI6205_ERROR_DSP_EMIF;
1752 HPI6205_ERROR_DSP_EMIF);
1753 1660
1754 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */ 1661 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
1755 /* need to use this else DSP code crashes? */ 1662 /* need to use this else DSP code crashes? */
@@ -1773,12 +1680,9 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1773 read_data = 1680 read_data =
1774 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR); 1681 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR);
1775 if (write_data != read_data) { 1682 if (write_data != read_data) {
1776 err = hpi6205_error(dsp_index,
1777 HPI6205_ERROR_C6713_HPIC);
1778 HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data, 1683 HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data,
1779 read_data); 1684 read_data);
1780 1685 return HPI6205_ERROR_C6713_HPIC;
1781 return err;
1782 } 1686 }
1783 /* HPIA - walking ones test */ 1687 /* HPIA - walking ones test */
1784 write_data = 1; 1688 write_data = 1;
@@ -1796,11 +1700,9 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1796 HPIAH_ADDR)) 1700 HPIAH_ADDR))
1797 << 16); 1701 << 16);
1798 if (read_data != write_data) { 1702 if (read_data != write_data) {
1799 err = hpi6205_error(dsp_index,
1800 HPI6205_ERROR_C6713_HPIA);
1801 HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n", 1703 HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n",
1802 write_data, read_data); 1704 write_data, read_data);
1803 return err; 1705 return HPI6205_ERROR_C6713_HPIA;
1804 } 1706 }
1805 write_data = write_data << 1; 1707 write_data = write_data << 1;
1806 } 1708 }
@@ -1845,30 +1747,81 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1845 /* PLL should not be bypassed! */ 1747 /* PLL should not be bypassed! */
1846 if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF) 1748 if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF)
1847 != 0x0001) { 1749 != 0x0001) {
1848 err = hpi6205_error(dsp_index, 1750 return HPI6205_ERROR_C6713_PLL;
1849 HPI6205_ERROR_C6713_PLL);
1850 return err;
1851 } 1751 }
1852 /* setup C67x EMIF (note this is the only use of 1752 /* setup C67x EMIF (note this is the only use of
1853 BAR1 via BootLoader_WriteMem32) */ 1753 BAR1 via BootLoader_WriteMem32) */
1854 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL, 1754 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL,
1855 0x000034A8); 1755 0x000034A8);
1756
1757 /* EMIF CE0 setup - 2Mx32 Sync DRAM
1758 31..28 Wr setup
1759 27..22 Wr strobe
1760 21..20 Wr hold
1761 19..16 Rd setup
1762 15..14 -
1763 13..8 Rd strobe
1764 7..4 MTYPE 0011 Sync DRAM 32bits
1765 3 Wr hold MSB
1766 2..0 Rd hold
1767 */
1856 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0, 1768 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0,
1857 0x00000030); 1769 0x00000030);
1770
1771 /* EMIF SDRAM Extension
1772 0x00
1773 31-21 0000b 0000b 000b
1774 20 WR2RD = 2cycles-1 = 1b
1775
1776 19-18 WR2DEAC = 3cycle-1 = 10b
1777 17 WR2WR = 2cycle-1 = 1b
1778 16-15 R2WDQM = 4cycle-1 = 11b
1779 14-12 RD2WR = 6cycles-1 = 101b
1780
1781 11-10 RD2DEAC = 4cycle-1 = 11b
1782 9 RD2RD = 2cycle-1 = 1b
1783 8-7 THZP = 3cycle-1 = 10b
1784 6-5 TWR = 2cycle-1 = 01b (tWR = 17ns)
1785 4 TRRD = 2cycle = 0b (tRRD = 14ns)
1786 3-1 TRAS = 5cycle-1 = 100b (Tras=42ns)
1787 1 CAS latency = 3cyc = 1b
1788 (for Micron 2M32-7 operating at 100MHz)
1789 */
1858 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT, 1790 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT,
1859 0x001BDF29); 1791 0x001BDF29);
1792
1793 /* EMIF SDRAM control - set up for a 2Mx32 SDRAM (512x32x4 bank)
1794 31 - 0b -
1795 30 SDBSZ 1b 4 bank
1796 29..28 SDRSZ 00b 11 row address pins
1797
1798 27..26 SDCSZ 01b 8 column address pins
1799 25 RFEN 1b refersh enabled
1800 24 INIT 1b init SDRAM!
1801
1802 23..20 TRCD 0001b (Trcd/Tcyc)-1 = (20/10)-1 = 1
1803
1804 19..16 TRP 0001b (Trp/Tcyc)-1 = (20/10)-1 = 1
1805
1806 15..12 TRC 0110b (Trc/Tcyc)-1 = (70/10)-1 = 6
1807
1808 11..0 - 0000b 0000b 0000b
1809 */
1860 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL, 1810 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL,
1861 0x47117000); 1811 0x47116000);
1812
1813 /* SDRAM refresh timing
1814 Need 4,096 refresh cycles every 64ms = 15.625us = 1562cycles of 100MHz = 0x61A
1815 */
1862 boot_loader_write_mem32(pao, dsp_index, 1816 boot_loader_write_mem32(pao, dsp_index,
1863 C6713_EMIF_SDRAMTIMING, 0x00000410); 1817 C6713_EMIF_SDRAMTIMING, 0x00000410);
1864 1818
1865 hpios_delay_micro_seconds(1000); 1819 hpios_delay_micro_seconds(1000);
1866 } else if (dsp_index == 2) { 1820 } else if (dsp_index == 2) {
1867 /* DSP 2 is a C6713 */ 1821 /* DSP 2 is a C6713 */
1822 }
1868 1823
1869 } else 1824 return 0;
1870 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1871 return err;
1872} 1825}
1873 1826
1874static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index, 1827static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
@@ -1894,7 +1847,7 @@ static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
1894 test_addr); 1847 test_addr);
1895 if (data != test_data) { 1848 if (data != test_data) {
1896 HPI_DEBUG_LOG(VERBOSE, 1849 HPI_DEBUG_LOG(VERBOSE,
1897 "memtest error details " 1850 "Memtest error details "
1898 "%08x %08x %08x %i\n", test_addr, 1851 "%08x %08x %08x %i\n", test_addr,
1899 test_data, data, dsp_index); 1852 test_data, data, dsp_index);
1900 return 1; /* error */ 1853 return 1; /* error */
@@ -1914,7 +1867,7 @@ static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
1914 data = boot_loader_read_mem32(pao, dsp_index, test_addr); 1867 data = boot_loader_read_mem32(pao, dsp_index, test_addr);
1915 if (data != test_data) { 1868 if (data != test_data) {
1916 HPI_DEBUG_LOG(VERBOSE, 1869 HPI_DEBUG_LOG(VERBOSE,
1917 "memtest error details " 1870 "Memtest error details "
1918 "%08x %08x %08x %i\n", test_addr, test_data, 1871 "%08x %08x %08x %i\n", test_addr, test_data,
1919 data, dsp_index); 1872 data, dsp_index);
1920 return 1; /* error */ 1873 return 1; /* error */
@@ -1944,8 +1897,8 @@ static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
1944 /* 64K data mem */ 1897 /* 64K data mem */
1945 err = boot_loader_test_memory(pao, dsp_index, 1898 err = boot_loader_test_memory(pao, dsp_index,
1946 0x80000000, 0x10000); 1899 0x80000000, 0x10000);
1947 } else if ((dsp_index == 1) || (dsp_index == 2)) { 1900 } else if (dsp_index == 1) {
1948 /* DSP 1&2 are a C6713 */ 1901 /* DSP 1 is a C6713 */
1949 /* 192K internal mem */ 1902 /* 192K internal mem */
1950 err = boot_loader_test_memory(pao, dsp_index, 0x00000000, 1903 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1951 0x30000); 1904 0x30000);
@@ -1953,11 +1906,10 @@ static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
1953 /* 64K internal mem / L2 cache */ 1906 /* 64K internal mem / L2 cache */
1954 err = boot_loader_test_memory(pao, dsp_index, 1907 err = boot_loader_test_memory(pao, dsp_index,
1955 0x00030000, 0x10000); 1908 0x00030000, 0x10000);
1956 } else 1909 }
1957 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1958 1910
1959 if (err) 1911 if (err)
1960 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM); 1912 return HPI6205_ERROR_DSP_INTMEM;
1961 else 1913 else
1962 return 0; 1914 return 0;
1963} 1915}
@@ -1970,24 +1922,23 @@ static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
1970 1922
1971 if (dsp_index == 0) { 1923 if (dsp_index == 0) {
1972 /* only test for SDRAM if an ASI5000 card */ 1924 /* only test for SDRAM if an ASI5000 card */
1973 if (pao->pci.subsys_device_id == 0x5000) { 1925 if (pao->pci.pci_dev->subsystem_device == 0x5000) {
1974 /* DSP 0 is always C6205 */ 1926 /* DSP 0 is always C6205 */
1975 dRAM_start_address = 0x00400000; 1927 dRAM_start_address = 0x00400000;
1976 dRAM_size = 0x200000; 1928 dRAM_size = 0x200000;
1977 /*dwDRAMinc=1024; */ 1929 /*dwDRAMinc=1024; */
1978 } else 1930 } else
1979 return 0; 1931 return 0;
1980 } else if ((dsp_index == 1) || (dsp_index == 2)) { 1932 } else if (dsp_index == 1) {
1981 /* DSP 1 is a C6713 */ 1933 /* DSP 1 is a C6713 */
1982 dRAM_start_address = 0x80000000; 1934 dRAM_start_address = 0x80000000;
1983 dRAM_size = 0x200000; 1935 dRAM_size = 0x200000;
1984 /*dwDRAMinc=1024; */ 1936 /*dwDRAMinc=1024; */
1985 } else 1937 }
1986 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1987 1938
1988 if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address, 1939 if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address,
1989 dRAM_size)) 1940 dRAM_size))
1990 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_EXTMEM); 1941 return HPI6205_ERROR_DSP_EXTMEM;
1991 return 0; 1942 return 0;
1992} 1943}
1993 1944
@@ -1996,28 +1947,25 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index)
1996 u32 data = 0; 1947 u32 data = 0;
1997 if (dsp_index == 0) { 1948 if (dsp_index == 0) {
1998 /* only test for DSP0 PLD on ASI5000 card */ 1949 /* only test for DSP0 PLD on ASI5000 card */
1999 if (pao->pci.subsys_device_id == 0x5000) { 1950 if (pao->pci.pci_dev->subsystem_device == 0x5000) {
2000 /* PLD is located at CE3=0x03000000 */ 1951 /* PLD is located at CE3=0x03000000 */
2001 data = boot_loader_read_mem32(pao, dsp_index, 1952 data = boot_loader_read_mem32(pao, dsp_index,
2002 0x03000008); 1953 0x03000008);
2003 if ((data & 0xF) != 0x5) 1954 if ((data & 0xF) != 0x5)
2004 return hpi6205_error(dsp_index, 1955 return HPI6205_ERROR_DSP_PLD;
2005 HPI6205_ERROR_DSP_PLD);
2006 data = boot_loader_read_mem32(pao, dsp_index, 1956 data = boot_loader_read_mem32(pao, dsp_index,
2007 0x0300000C); 1957 0x0300000C);
2008 if ((data & 0xF) != 0xA) 1958 if ((data & 0xF) != 0xA)
2009 return hpi6205_error(dsp_index, 1959 return HPI6205_ERROR_DSP_PLD;
2010 HPI6205_ERROR_DSP_PLD);
2011 } 1960 }
2012 } else if (dsp_index == 1) { 1961 } else if (dsp_index == 1) {
2013 /* DSP 1 is a C6713 */ 1962 /* DSP 1 is a C6713 */
2014 if (pao->pci.subsys_device_id == 0x8700) { 1963 if (pao->pci.pci_dev->subsystem_device == 0x8700) {
2015 /* PLD is located at CE1=0x90000000 */ 1964 /* PLD is located at CE1=0x90000000 */
2016 data = boot_loader_read_mem32(pao, dsp_index, 1965 data = boot_loader_read_mem32(pao, dsp_index,
2017 0x90000010); 1966 0x90000010);
2018 if ((data & 0xFF) != 0xAA) 1967 if ((data & 0xFF) != 0xAA)
2019 return hpi6205_error(dsp_index, 1968 return HPI6205_ERROR_DSP_PLD;
2020 HPI6205_ERROR_DSP_PLD);
2021 /* 8713 - LED on */ 1969 /* 8713 - LED on */
2022 boot_loader_write_mem32(pao, dsp_index, 0x90000000, 1970 boot_loader_write_mem32(pao, dsp_index, 0x90000000,
2023 0x02); 1971 0x02);
@@ -2035,14 +1983,11 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2035 struct hpi_hw_obj *phw = pao->priv; 1983 struct hpi_hw_obj *phw = pao->priv;
2036 u32 data_transferred = 0; 1984 u32 data_transferred = 0;
2037 u16 err = 0; 1985 u16 err = 0;
2038#ifndef HPI6205_NO_HSR_POLL
2039 u32 time_out;
2040#endif
2041 u32 temp2; 1986 u32 temp2;
2042 struct bus_master_interface *interface = phw->p_interface_buffer; 1987 struct bus_master_interface *interface = phw->p_interface_buffer;
2043 1988
2044 if (!p_data) 1989 if (!p_data)
2045 return HPI_ERROR_INVALID_DATA_TRANSFER; 1990 return HPI_ERROR_INVALID_DATA_POINTER;
2046 1991
2047 data_size &= ~3L; /* round data_size down to nearest 4 bytes */ 1992 data_size &= ~3L; /* round data_size down to nearest 4 bytes */
2048 1993
@@ -2062,14 +2007,10 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2062 2007
2063 interface->transfer_size_in_bytes = this_copy; 2008 interface->transfer_size_in_bytes = this_copy;
2064 2009
2065#ifdef HPI6205_NO_HSR_POLL
2066 /* DSP must change this back to nOperation */ 2010 /* DSP must change this back to nOperation */
2067 interface->dsp_ack = H620_HIF_IDLE; 2011 interface->dsp_ack = H620_HIF_IDLE;
2068#endif
2069
2070 send_dsp_command(phw, operation); 2012 send_dsp_command(phw, operation);
2071 2013
2072#ifdef HPI6205_NO_HSR_POLL
2073 temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT); 2014 temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT);
2074 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n", 2015 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2075 HPI6205_TIMEOUT - temp2, this_copy); 2016 HPI6205_TIMEOUT - temp2, this_copy);
@@ -2077,45 +2018,11 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2077 if (!temp2) { 2018 if (!temp2) {
2078 /* timed out */ 2019 /* timed out */
2079 HPI_DEBUG_LOG(ERROR, 2020 HPI_DEBUG_LOG(ERROR,
2080 "timed out waiting for " "state %d got %d\n", 2021 "Timed out waiting for " "state %d got %d\n",
2081 operation, interface->dsp_ack); 2022 operation, interface->dsp_ack);
2082 2023
2083 break; 2024 break;
2084 } 2025 }
2085#else
2086 /* spin waiting on the result */
2087 time_out = HPI6205_TIMEOUT;
2088 temp2 = 0;
2089 while ((temp2 == 0) && time_out--) {
2090 /* give 16k bus mastering transfer time to happen */
2091 /*(16k / 132Mbytes/s = 122usec) */
2092 hpios_delay_micro_seconds(20);
2093 temp2 = ioread32(phw->prHSR);
2094 temp2 &= C6205_HSR_INTSRC;
2095 }
2096 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2097 HPI6205_TIMEOUT - time_out, this_copy);
2098 if (temp2 == C6205_HSR_INTSRC) {
2099 HPI_DEBUG_LOG(VERBOSE,
2100 "interrupt from HIF <data> OK\n");
2101 /*
2102 if(interface->dwDspAck != nOperation) {
2103 HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d,
2104 expected %d \n",
2105 interface->dwDspAck,nOperation);
2106 }
2107 */
2108 }
2109/* need to handle this differently... */
2110 else {
2111 HPI_DEBUG_LOG(ERROR,
2112 "interrupt from HIF <data> BAD\n");
2113 err = HPI_ERROR_DSP_HARDWARE;
2114 }
2115
2116 /* reset the interrupt from the DSP */
2117 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2118#endif
2119 if (operation == H620_HIF_GET_DATA) 2026 if (operation == H620_HIF_GET_DATA)
2120 memcpy(&p_data[data_transferred], 2027 memcpy(&p_data[data_transferred],
2121 (void *)&interface->u.b_data[0], this_copy); 2028 (void *)&interface->u.b_data[0], this_copy);
@@ -2154,7 +2061,6 @@ static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
2154static void send_dsp_command(struct hpi_hw_obj *phw, int cmd) 2061static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
2155{ 2062{
2156 struct bus_master_interface *interface = phw->p_interface_buffer; 2063 struct bus_master_interface *interface = phw->p_interface_buffer;
2157
2158 u32 r; 2064 u32 r;
2159 2065
2160 interface->host_cmd = cmd; 2066 interface->host_cmd = cmd;
@@ -2172,31 +2078,39 @@ static unsigned int message_count;
2172static u16 message_response_sequence(struct hpi_adapter_obj *pao, 2078static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2173 struct hpi_message *phm, struct hpi_response *phr) 2079 struct hpi_message *phm, struct hpi_response *phr)
2174{ 2080{
2175#ifndef HPI6205_NO_HSR_POLL
2176 u32 temp2;
2177#endif
2178 u32 time_out, time_out2; 2081 u32 time_out, time_out2;
2179 struct hpi_hw_obj *phw = pao->priv; 2082 struct hpi_hw_obj *phw = pao->priv;
2180 struct bus_master_interface *interface = phw->p_interface_buffer; 2083 struct bus_master_interface *interface = phw->p_interface_buffer;
2181 u16 err = 0; 2084 u16 err = 0;
2182 2085
2183 message_count++; 2086 message_count++;
2087 if (phm->size > sizeof(interface->u)) {
2088 phr->error = HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL;
2089 phr->specific_error = sizeof(interface->u);
2090 phr->size = sizeof(struct hpi_response_header);
2091 HPI_DEBUG_LOG(ERROR,
2092 "message len %d too big for buffer %zd \n", phm->size,
2093 sizeof(interface->u));
2094 return 0;
2095 }
2096
2184 /* Assume buffer of type struct bus_master_interface 2097 /* Assume buffer of type struct bus_master_interface
2185 is allocated "noncacheable" */ 2098 is allocated "noncacheable" */
2186 2099
2187 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { 2100 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2188 HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n"); 2101 HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n");
2189 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT); 2102 return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT;
2190 } 2103 }
2191 interface->u.message_buffer = *phm; 2104
2105 memcpy(&interface->u.message_buffer, phm, phm->size);
2192 /* signal we want a response */ 2106 /* signal we want a response */
2193 send_dsp_command(phw, H620_HIF_GET_RESP); 2107 send_dsp_command(phw, H620_HIF_GET_RESP);
2194 2108
2195 time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT); 2109 time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
2196 2110
2197 if (time_out2 == 0) { 2111 if (!time_out2) {
2198 HPI_DEBUG_LOG(ERROR, 2112 HPI_DEBUG_LOG(ERROR,
2199 "(%u) timed out waiting for " "GET_RESP state [%x]\n", 2113 "(%u) Timed out waiting for " "GET_RESP state [%x]\n",
2200 message_count, interface->dsp_ack); 2114 message_count, interface->dsp_ack);
2201 } else { 2115 } else {
2202 HPI_DEBUG_LOG(VERBOSE, 2116 HPI_DEBUG_LOG(VERBOSE,
@@ -2206,58 +2120,38 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2206 /* spin waiting on HIF interrupt flag (end of msg process) */ 2120 /* spin waiting on HIF interrupt flag (end of msg process) */
2207 time_out = HPI6205_TIMEOUT; 2121 time_out = HPI6205_TIMEOUT;
2208 2122
2209#ifndef HPI6205_NO_HSR_POLL 2123 /* read the result */
2210 temp2 = 0; 2124 if (time_out) {
2211 while ((temp2 == 0) && --time_out) { 2125 if (interface->u.response_buffer.size <= phr->size)
2212 temp2 = ioread32(phw->prHSR); 2126 memcpy(phr, &interface->u.response_buffer,
2213 temp2 &= C6205_HSR_INTSRC; 2127 interface->u.response_buffer.size);
2214 hpios_delay_micro_seconds(1); 2128 else {
2215 } 2129 HPI_DEBUG_LOG(ERROR,
2216 if (temp2 == C6205_HSR_INTSRC) { 2130 "response len %d too big for buffer %d\n",
2217 rmb(); /* ensure we see latest value for dsp_ack */ 2131 interface->u.response_buffer.size, phr->size);
2218 if ((interface->dsp_ack != H620_HIF_GET_RESP)) { 2132 memcpy(phr, &interface->u.response_buffer,
2219 HPI_DEBUG_LOG(DEBUG, 2133 sizeof(struct hpi_response_header));
2220 "(%u)interface->dsp_ack(0x%x) != " 2134 phr->error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
2221 "H620_HIF_GET_RESP, t=%u\n", message_count, 2135 phr->specific_error =
2222 interface->dsp_ack, 2136 interface->u.response_buffer.size;
2223 HPI6205_TIMEOUT - time_out); 2137 phr->size = sizeof(struct hpi_response_header);
2224 } else {
2225 HPI_DEBUG_LOG(VERBOSE,
2226 "(%u)int with GET_RESP after %u\n",
2227 message_count, HPI6205_TIMEOUT - time_out);
2228 } 2138 }
2229
2230 } else {
2231 /* can we do anything else in response to the error ? */
2232 HPI_DEBUG_LOG(ERROR,
2233 "interrupt from HIF module BAD (function %x)\n",
2234 phm->function);
2235 } 2139 }
2236
2237 /* reset the interrupt from the DSP */
2238 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2239#endif
2240
2241 /* read the result */
2242 if (time_out != 0)
2243 *phr = interface->u.response_buffer;
2244
2245 /* set interface back to idle */ 2140 /* set interface back to idle */
2246 send_dsp_command(phw, H620_HIF_IDLE); 2141 send_dsp_command(phw, H620_HIF_IDLE);
2247 2142
2248 if ((time_out == 0) || (time_out2 == 0)) { 2143 if (!time_out || !time_out2) {
2249 HPI_DEBUG_LOG(DEBUG, "something timed out!\n"); 2144 HPI_DEBUG_LOG(DEBUG, "something timed out!\n");
2250 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT); 2145 return HPI6205_ERROR_MSG_RESP_TIMEOUT;
2251 } 2146 }
2252 /* special case for adapter close - */ 2147 /* special case for adapter close - */
2253 /* wait for the DSP to indicate it is idle */ 2148 /* wait for the DSP to indicate it is idle */
2254 if (phm->function == HPI_ADAPTER_CLOSE) { 2149 if (phm->function == HPI_ADAPTER_CLOSE) {
2255 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { 2150 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2256 HPI_DEBUG_LOG(DEBUG, 2151 HPI_DEBUG_LOG(DEBUG,
2257 "timeout waiting for idle " 2152 "Timeout waiting for idle "
2258 "(on adapter_close)\n"); 2153 "(on adapter_close)\n");
2259 return hpi6205_error(0, 2154 return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT;
2260 HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2261 } 2155 }
2262 } 2156 }
2263 err = hpi_validate_response(phm, phr); 2157 err = hpi_validate_response(phm, phr);
@@ -2277,7 +2171,13 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
2277 /* maybe an error response */ 2171 /* maybe an error response */
2278 if (err) { 2172 if (err) {
2279 /* something failed in the HPI/DSP interface */ 2173 /* something failed in the HPI/DSP interface */
2280 phr->error = err; 2174 if (err >= HPI_ERROR_BACKEND_BASE) {
2175 phr->error = HPI_ERROR_DSP_COMMUNICATION;
2176 phr->specific_error = err;
2177 } else {
2178 phr->error = err;
2179 }
2180
2281 pao->dsp_crashed++; 2181 pao->dsp_crashed++;
2282 2182
2283 /* just the header of the response is valid */ 2183 /* just the header of the response is valid */
diff --git a/sound/pci/asihpi/hpi6205.h b/sound/pci/asihpi/hpi6205.h
index 1adae0857cda..df2f02c0c7b4 100644
--- a/sound/pci/asihpi/hpi6205.h
+++ b/sound/pci/asihpi/hpi6205.h
@@ -25,9 +25,6 @@ Copyright AudioScience, Inc., 2003
25#ifndef _HPI6205_H_ 25#ifndef _HPI6205_H_
26#define _HPI6205_H_ 26#define _HPI6205_H_
27 27
28/* transitional conditional compile shared between host and DSP */
29/* #define HPI6205_NO_HSR_POLL */
30
31#include "hpi_internal.h" 28#include "hpi_internal.h"
32 29
33/*********************************************************** 30/***********************************************************
@@ -78,8 +75,8 @@ struct bus_master_interface {
78 u32 dsp_ack; 75 u32 dsp_ack;
79 u32 transfer_size_in_bytes; 76 u32 transfer_size_in_bytes;
80 union { 77 union {
81 struct hpi_message message_buffer; 78 struct hpi_message_header message_buffer;
82 struct hpi_response response_buffer; 79 struct hpi_response_header response_buffer;
83 u8 b_data[HPI6205_SIZEOF_DATA]; 80 u8 b_data[HPI6205_SIZEOF_DATA];
84 } u; 81 } u;
85 struct controlcache_6205 control_cache; 82 struct controlcache_6205 control_cache;
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
index 16f502d459de..bf5eced76bac 100644
--- a/sound/pci/asihpi/hpi_internal.h
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -28,7 +28,7 @@ HPI internal definitions
28/** maximum number of memory regions mapped to an adapter */ 28/** maximum number of memory regions mapped to an adapter */
29#define HPI_MAX_ADAPTER_MEM_SPACES (2) 29#define HPI_MAX_ADAPTER_MEM_SPACES (2)
30 30
31/* Each OS needs its own hpios.h, or specific define as above */ 31/* Each OS needs its own hpios.h */
32#include "hpios.h" 32#include "hpios.h"
33 33
34/* physical memory allocation */ 34/* physical memory allocation */
@@ -49,7 +49,7 @@ HpiOs_LockedMem_GetPyhsAddr() will always succed on the returned handle.
49*/ 49*/
50u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_locked_mem_handle, 50u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_locked_mem_handle,
51 /**< memory handle */ 51 /**< memory handle */
52 u32 size, /**< size in bytes to allocate */ 52 u32 size, /**< Size in bytes to allocate */
53 struct pci_dev *p_os_reference 53 struct pci_dev *p_os_reference
54 /**< OS specific data required for memory allocation */ 54 /**< OS specific data required for memory allocation */
55 ); 55 );
@@ -96,41 +96,6 @@ typedef void hpi_handler_func(struct hpi_message *, struct hpi_response *);
96#define compile_time_assert(cond, msg) \ 96#define compile_time_assert(cond, msg) \
97 typedef char ASSERT_##msg[(cond) ? 1 : -1] 97 typedef char ASSERT_##msg[(cond) ? 1 : -1]
98 98
99/*/////////////////////////////////////////////////////////////////////////// */
100/* Private HPI Entity related definitions */
101
102#define STR_SIZE_FIELD_MAX 65535U
103#define STR_TYPE_FIELD_MAX 255U
104#define STR_ROLE_FIELD_MAX 255U
105
106struct hpi_entity_str {
107 u16 size;
108 u8 type;
109 u8 role;
110};
111
112#if defined(_MSC_VER)
113#pragma warning(push)
114#pragma warning(disable : 4200)
115#endif
116
117struct hpi_entity {
118 struct hpi_entity_str header;
119#if ! defined(HPI_OS_DSP_C6000) || (defined(HPI_OS_DSP_C6000) && (__TI_COMPILER_VERSION__ > 6000008))
120 /* DSP C6000 compiler v6.0.8 and lower
121 do not support flexible array member */
122 u8 value[];
123#else
124 /* NOTE! Using sizeof(struct hpi_entity) will give erroneous results */
125#define HPI_INTERNAL_WARN_ABOUT_ENTITY_VALUE
126 u8 value[1];
127#endif
128};
129
130#if defined(_MSC_VER)
131#pragma warning(pop)
132#endif
133
134/******************************************* bus types */ 99/******************************************* bus types */
135enum HPI_BUSES { 100enum HPI_BUSES {
136 HPI_BUS_ISAPNP = 1, 101 HPI_BUS_ISAPNP = 1,
@@ -139,206 +104,155 @@ enum HPI_BUSES {
139 HPI_BUS_NET = 4 104 HPI_BUS_NET = 4
140}; 105};
141 106
107enum HPI_SUBSYS_OPTIONS {
108 /* 0, 256 are invalid, 1..255 reserved for global options */
109 HPI_SUBSYS_OPT_NET_ENABLE = 257,
110 HPI_SUBSYS_OPT_NET_BROADCAST = 258,
111 HPI_SUBSYS_OPT_NET_UNICAST = 259,
112 HPI_SUBSYS_OPT_NET_ADDR = 260,
113 HPI_SUBSYS_OPT_NET_MASK = 261,
114 HPI_SUBSYS_OPT_NET_ADAPTER_ADDRESS_ADD = 262
115};
116
117/** Volume flags
118*/
119enum HPI_VOLUME_FLAGS {
120 /** Set if the volume control is muted */
121 HPI_VOLUME_FLAG_MUTED = (1 << 0),
122 /** Set if the volume control has a mute function */
123 HPI_VOLUME_FLAG_HAS_MUTE = (1 << 1),
124 /** Set if volume control can do autofading */
125 HPI_VOLUME_FLAG_HAS_AUTOFADE = (1 << 2)
126 /* Note Flags >= (1<<8) are for DSP internal use only */
127};
128
142/******************************************* CONTROL ATTRIBUTES ****/ 129/******************************************* CONTROL ATTRIBUTES ****/
143/* (in order of control type ID */ 130/* (in order of control type ID */
144 131
145/* This allows for 255 control types, 256 unique attributes each */ 132/* This allows for 255 control types, 256 unique attributes each */
146#define HPI_CTL_ATTR(ctl, ai) (HPI_CONTROL_##ctl * 0x100 + ai) 133#define HPI_CTL_ATTR(ctl, ai) ((HPI_CONTROL_##ctl << 8) + ai)
147 134
148/* Get the sub-index of the attribute for a control type */ 135/* Get the sub-index of the attribute for a control type */
149#define HPI_CTL_ATTR_INDEX(i) (i&0xff) 136#define HPI_CTL_ATTR_INDEX(i) (i & 0xff)
150 137
151/* Extract the control from the control attribute */ 138/* Extract the control from the control attribute */
152#define HPI_CTL_ATTR_CONTROL(i) (i>>8) 139#define HPI_CTL_ATTR_CONTROL(i) (i >> 8)
153
154/* Generic control attributes. */
155
156/** Enable a control.
1570=disable, 1=enable
158\note generic to all mixer plugins?
159*/
160#define HPI_GENERIC_ENABLE HPI_CTL_ATTR(GENERIC, 1)
161 140
162/** Enable event generation for a control. 141/** Enable event generation for a control.
1630=disable, 1=enable 1420=disable, 1=enable
164\note generic to all controls that can generate events 143\note generic to all controls that can generate events
165*/ 144*/
166#define HPI_GENERIC_EVENT_ENABLE HPI_CTL_ATTR(GENERIC, 2) 145
167 146/** Unique identifiers for every control attribute
168/* Volume Control attributes */
169#define HPI_VOLUME_GAIN HPI_CTL_ATTR(VOLUME, 1)
170#define HPI_VOLUME_AUTOFADE HPI_CTL_ATTR(VOLUME, 2)
171
172/** For HPI_ControlQuery() to get the number of channels of a volume control*/
173#define HPI_VOLUME_NUM_CHANNELS HPI_CTL_ATTR(VOLUME, 6)
174#define HPI_VOLUME_RANGE HPI_CTL_ATTR(VOLUME, 10)
175
176/** Level Control attributes */
177#define HPI_LEVEL_GAIN HPI_CTL_ATTR(LEVEL, 1)
178#define HPI_LEVEL_RANGE HPI_CTL_ATTR(LEVEL, 10)
179
180/* Meter Control attributes */
181/** return RMS signal level */
182#define HPI_METER_RMS HPI_CTL_ATTR(METER, 1)
183/** return peak signal level */
184#define HPI_METER_PEAK HPI_CTL_ATTR(METER, 2)
185/** ballistics for ALL rms meters on adapter */
186#define HPI_METER_RMS_BALLISTICS HPI_CTL_ATTR(METER, 3)
187/** ballistics for ALL peak meters on adapter */
188#define HPI_METER_PEAK_BALLISTICS HPI_CTL_ATTR(METER, 4)
189
190/** For HPI_ControlQuery() to get the number of channels of a meter control*/
191#define HPI_METER_NUM_CHANNELS HPI_CTL_ATTR(METER, 5)
192
193/* Multiplexer control attributes */
194#define HPI_MULTIPLEXER_SOURCE HPI_CTL_ATTR(MULTIPLEXER, 1)
195#define HPI_MULTIPLEXER_QUERYSOURCE HPI_CTL_ATTR(MULTIPLEXER, 2)
196
197/** AES/EBU transmitter control attributes */
198/** AESEBU or SPDIF */
199#define HPI_AESEBUTX_FORMAT HPI_CTL_ATTR(AESEBUTX, 1)
200#define HPI_AESEBUTX_SAMPLERATE HPI_CTL_ATTR(AESEBUTX, 3)
201#define HPI_AESEBUTX_CHANNELSTATUS HPI_CTL_ATTR(AESEBUTX, 4)
202#define HPI_AESEBUTX_USERDATA HPI_CTL_ATTR(AESEBUTX, 5)
203
204/** AES/EBU receiver control attributes */
205#define HPI_AESEBURX_FORMAT HPI_CTL_ATTR(AESEBURX, 1)
206#define HPI_AESEBURX_ERRORSTATUS HPI_CTL_ATTR(AESEBURX, 2)
207#define HPI_AESEBURX_SAMPLERATE HPI_CTL_ATTR(AESEBURX, 3)
208#define HPI_AESEBURX_CHANNELSTATUS HPI_CTL_ATTR(AESEBURX, 4)
209#define HPI_AESEBURX_USERDATA HPI_CTL_ATTR(AESEBURX, 5)
210
211/** \defgroup tuner_defs Tuners
212\{
213*/
214/** \defgroup tuner_attrs Tuner control attributes
215\{
216*/
217#define HPI_TUNER_BAND HPI_CTL_ATTR(TUNER, 1)
218#define HPI_TUNER_FREQ HPI_CTL_ATTR(TUNER, 2)
219#define HPI_TUNER_LEVEL HPI_CTL_ATTR(TUNER, 3)
220#define HPI_TUNER_AUDIOMUTE HPI_CTL_ATTR(TUNER, 4)
221/* use TUNER_STATUS instead */
222#define HPI_TUNER_VIDEO_STATUS HPI_CTL_ATTR(TUNER, 5)
223#define HPI_TUNER_GAIN HPI_CTL_ATTR(TUNER, 6)
224#define HPI_TUNER_STATUS HPI_CTL_ATTR(TUNER, 7)
225#define HPI_TUNER_MODE HPI_CTL_ATTR(TUNER, 8)
226/** RDS data. */
227#define HPI_TUNER_RDS HPI_CTL_ATTR(TUNER, 9)
228/** Audio pre-emphasis. */
229#define HPI_TUNER_DEEMPHASIS HPI_CTL_ATTR(TUNER, 10)
230/** HD Radio tuner program control. */
231#define HPI_TUNER_PROGRAM HPI_CTL_ATTR(TUNER, 11)
232/** HD Radio tuner digital signal quality. */
233#define HPI_TUNER_HDRADIO_SIGNAL_QUALITY HPI_CTL_ATTR(TUNER, 12)
234/** HD Radio SDK firmware version. */
235#define HPI_TUNER_HDRADIO_SDK_VERSION HPI_CTL_ATTR(TUNER, 13)
236/** HD Radio DSP firmware version. */
237#define HPI_TUNER_HDRADIO_DSP_VERSION HPI_CTL_ATTR(TUNER, 14)
238/** HD Radio signal blend (force analog, or automatic). */
239#define HPI_TUNER_HDRADIO_BLEND HPI_CTL_ATTR(TUNER, 15)
240
241/** \} */
242
243/** \defgroup pads_attrs Tuner PADs control attributes
244\{
245*/
246/** The text string containing the station/channel combination. */
247#define HPI_PAD_CHANNEL_NAME HPI_CTL_ATTR(PAD, 1)
248/** The text string containing the artist. */
249#define HPI_PAD_ARTIST HPI_CTL_ATTR(PAD, 2)
250/** The text string containing the title. */
251#define HPI_PAD_TITLE HPI_CTL_ATTR(PAD, 3)
252/** The text string containing the comment. */
253#define HPI_PAD_COMMENT HPI_CTL_ATTR(PAD, 4)
254/** The integer containing the PTY code. */
255#define HPI_PAD_PROGRAM_TYPE HPI_CTL_ATTR(PAD, 5)
256/** The integer containing the program identification. */
257#define HPI_PAD_PROGRAM_ID HPI_CTL_ATTR(PAD, 6)
258/** The integer containing whether traffic information is supported.
259Contains either 1 or 0. */
260#define HPI_PAD_TA_SUPPORT HPI_CTL_ATTR(PAD, 7)
261/** The integer containing whether traffic announcement is in progress.
262Contains either 1 or 0. */
263#define HPI_PAD_TA_ACTIVE HPI_CTL_ATTR(PAD, 8)
264/** \} */
265/** \} */
266
267/* VOX control attributes */
268#define HPI_VOX_THRESHOLD HPI_CTL_ATTR(VOX, 1)
269
270/*?? channel mode used hpi_multiplexer_source attribute == 1 */
271#define HPI_CHANNEL_MODE_MODE HPI_CTL_ATTR(CHANNEL_MODE, 1)
272
273/** \defgroup channel_modes Channel Modes
274Used for HPI_ChannelModeSet/Get()
275\{
276*/ 147*/
277/** Left channel out = left channel in, Right channel out = right channel in. */ 148enum HPI_CONTROL_ATTRIBUTES {
278#define HPI_CHANNEL_MODE_NORMAL 1 149 HPI_GENERIC_ENABLE = HPI_CTL_ATTR(GENERIC, 1),
279/** Left channel out = right channel in, Right channel out = left channel in. */ 150 HPI_GENERIC_EVENT_ENABLE = HPI_CTL_ATTR(GENERIC, 2),
280#define HPI_CHANNEL_MODE_SWAP 2 151
281/** Left channel out = left channel in, Right channel out = left channel in. */ 152 HPI_VOLUME_GAIN = HPI_CTL_ATTR(VOLUME, 1),
282#define HPI_CHANNEL_MODE_LEFT_TO_STEREO 3 153 HPI_VOLUME_AUTOFADE = HPI_CTL_ATTR(VOLUME, 2),
283/** Left channel out = right channel in, Right channel out = right channel in.*/ 154 HPI_VOLUME_MUTE = HPI_CTL_ATTR(VOLUME, 3),
284#define HPI_CHANNEL_MODE_RIGHT_TO_STEREO 4 155 HPI_VOLUME_GAIN_AND_FLAGS = HPI_CTL_ATTR(VOLUME, 4),
285/** Left channel out = (left channel in + right channel in)/2, 156 HPI_VOLUME_NUM_CHANNELS = HPI_CTL_ATTR(VOLUME, 6),
286 Right channel out = mute. */ 157 HPI_VOLUME_RANGE = HPI_CTL_ATTR(VOLUME, 10),
287#define HPI_CHANNEL_MODE_STEREO_TO_LEFT 5 158
288/** Left channel out = mute, 159 HPI_METER_RMS = HPI_CTL_ATTR(METER, 1),
289 Right channel out = (right channel in + left channel in)/2. */ 160 HPI_METER_PEAK = HPI_CTL_ATTR(METER, 2),
290#define HPI_CHANNEL_MODE_STEREO_TO_RIGHT 6 161 HPI_METER_RMS_BALLISTICS = HPI_CTL_ATTR(METER, 3),
291#define HPI_CHANNEL_MODE_LAST 6 162 HPI_METER_PEAK_BALLISTICS = HPI_CTL_ATTR(METER, 4),
292/** \} */ 163 HPI_METER_NUM_CHANNELS = HPI_CTL_ATTR(METER, 5),
293 164
294/* Bitstream control set attributes */ 165 HPI_MULTIPLEXER_SOURCE = HPI_CTL_ATTR(MULTIPLEXER, 1),
295#define HPI_BITSTREAM_DATA_POLARITY HPI_CTL_ATTR(BITSTREAM, 1) 166 HPI_MULTIPLEXER_QUERYSOURCE = HPI_CTL_ATTR(MULTIPLEXER, 2),
296#define HPI_BITSTREAM_CLOCK_EDGE HPI_CTL_ATTR(BITSTREAM, 2) 167
297#define HPI_BITSTREAM_CLOCK_SOURCE HPI_CTL_ATTR(BITSTREAM, 3) 168 HPI_AESEBUTX_FORMAT = HPI_CTL_ATTR(AESEBUTX, 1),
169 HPI_AESEBUTX_SAMPLERATE = HPI_CTL_ATTR(AESEBUTX, 3),
170 HPI_AESEBUTX_CHANNELSTATUS = HPI_CTL_ATTR(AESEBUTX, 4),
171 HPI_AESEBUTX_USERDATA = HPI_CTL_ATTR(AESEBUTX, 5),
172
173 HPI_AESEBURX_FORMAT = HPI_CTL_ATTR(AESEBURX, 1),
174 HPI_AESEBURX_ERRORSTATUS = HPI_CTL_ATTR(AESEBURX, 2),
175 HPI_AESEBURX_SAMPLERATE = HPI_CTL_ATTR(AESEBURX, 3),
176 HPI_AESEBURX_CHANNELSTATUS = HPI_CTL_ATTR(AESEBURX, 4),
177 HPI_AESEBURX_USERDATA = HPI_CTL_ATTR(AESEBURX, 5),
178
179 HPI_LEVEL_GAIN = HPI_CTL_ATTR(LEVEL, 1),
180 HPI_LEVEL_RANGE = HPI_CTL_ATTR(LEVEL, 10),
181
182 HPI_TUNER_BAND = HPI_CTL_ATTR(TUNER, 1),
183 HPI_TUNER_FREQ = HPI_CTL_ATTR(TUNER, 2),
184 HPI_TUNER_LEVEL_AVG = HPI_CTL_ATTR(TUNER, 3),
185 HPI_TUNER_LEVEL_RAW = HPI_CTL_ATTR(TUNER, 4),
186 HPI_TUNER_SNR = HPI_CTL_ATTR(TUNER, 5),
187 HPI_TUNER_GAIN = HPI_CTL_ATTR(TUNER, 6),
188 HPI_TUNER_STATUS = HPI_CTL_ATTR(TUNER, 7),
189 HPI_TUNER_MODE = HPI_CTL_ATTR(TUNER, 8),
190 HPI_TUNER_RDS = HPI_CTL_ATTR(TUNER, 9),
191 HPI_TUNER_DEEMPHASIS = HPI_CTL_ATTR(TUNER, 10),
192 HPI_TUNER_PROGRAM = HPI_CTL_ATTR(TUNER, 11),
193 HPI_TUNER_HDRADIO_SIGNAL_QUALITY = HPI_CTL_ATTR(TUNER, 12),
194 HPI_TUNER_HDRADIO_SDK_VERSION = HPI_CTL_ATTR(TUNER, 13),
195 HPI_TUNER_HDRADIO_DSP_VERSION = HPI_CTL_ATTR(TUNER, 14),
196 HPI_TUNER_HDRADIO_BLEND = HPI_CTL_ATTR(TUNER, 15),
197
198 HPI_VOX_THRESHOLD = HPI_CTL_ATTR(VOX, 1),
199
200 HPI_CHANNEL_MODE_MODE = HPI_CTL_ATTR(CHANNEL_MODE, 1),
201
202 HPI_BITSTREAM_DATA_POLARITY = HPI_CTL_ATTR(BITSTREAM, 1),
203 HPI_BITSTREAM_CLOCK_EDGE = HPI_CTL_ATTR(BITSTREAM, 2),
204 HPI_BITSTREAM_CLOCK_SOURCE = HPI_CTL_ATTR(BITSTREAM, 3),
205 HPI_BITSTREAM_ACTIVITY = HPI_CTL_ATTR(BITSTREAM, 4),
206
207 HPI_SAMPLECLOCK_SOURCE = HPI_CTL_ATTR(SAMPLECLOCK, 1),
208 HPI_SAMPLECLOCK_SAMPLERATE = HPI_CTL_ATTR(SAMPLECLOCK, 2),
209 HPI_SAMPLECLOCK_SOURCE_INDEX = HPI_CTL_ATTR(SAMPLECLOCK, 3),
210 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE = HPI_CTL_ATTR(SAMPLECLOCK, 4),
211 HPI_SAMPLECLOCK_AUTO = HPI_CTL_ATTR(SAMPLECLOCK, 5),
212 HPI_SAMPLECLOCK_LOCAL_LOCK = HPI_CTL_ATTR(SAMPLECLOCK, 6),
213
214 HPI_MICROPHONE_PHANTOM_POWER = HPI_CTL_ATTR(MICROPHONE, 1),
215
216 HPI_EQUALIZER_NUM_FILTERS = HPI_CTL_ATTR(EQUALIZER, 1),
217 HPI_EQUALIZER_FILTER = HPI_CTL_ATTR(EQUALIZER, 2),
218 HPI_EQUALIZER_COEFFICIENTS = HPI_CTL_ATTR(EQUALIZER, 3),
219
220 HPI_COMPANDER_PARAMS = HPI_CTL_ATTR(COMPANDER, 1),
221 HPI_COMPANDER_MAKEUPGAIN = HPI_CTL_ATTR(COMPANDER, 2),
222 HPI_COMPANDER_THRESHOLD = HPI_CTL_ATTR(COMPANDER, 3),
223 HPI_COMPANDER_RATIO = HPI_CTL_ATTR(COMPANDER, 4),
224 HPI_COMPANDER_ATTACK = HPI_CTL_ATTR(COMPANDER, 5),
225 HPI_COMPANDER_DECAY = HPI_CTL_ATTR(COMPANDER, 6),
226
227 HPI_COBRANET_SET = HPI_CTL_ATTR(COBRANET, 1),
228 HPI_COBRANET_GET = HPI_CTL_ATTR(COBRANET, 2),
229 HPI_COBRANET_SET_DATA = HPI_CTL_ATTR(COBRANET, 3),
230 HPI_COBRANET_GET_DATA = HPI_CTL_ATTR(COBRANET, 4),
231 HPI_COBRANET_GET_STATUS = HPI_CTL_ATTR(COBRANET, 5),
232 HPI_COBRANET_SEND_PACKET = HPI_CTL_ATTR(COBRANET, 6),
233 HPI_COBRANET_GET_PACKET = HPI_CTL_ATTR(COBRANET, 7),
234
235 HPI_TONEDETECTOR_THRESHOLD = HPI_CTL_ATTR(TONEDETECTOR, 1),
236 HPI_TONEDETECTOR_STATE = HPI_CTL_ATTR(TONEDETECTOR, 2),
237 HPI_TONEDETECTOR_FREQUENCY = HPI_CTL_ATTR(TONEDETECTOR, 3),
238
239 HPI_SILENCEDETECTOR_THRESHOLD = HPI_CTL_ATTR(SILENCEDETECTOR, 1),
240 HPI_SILENCEDETECTOR_STATE = HPI_CTL_ATTR(SILENCEDETECTOR, 2),
241 HPI_SILENCEDETECTOR_DELAY = HPI_CTL_ATTR(SILENCEDETECTOR, 3),
242
243 HPI_PAD_CHANNEL_NAME = HPI_CTL_ATTR(PAD, 1),
244 HPI_PAD_ARTIST = HPI_CTL_ATTR(PAD, 2),
245 HPI_PAD_TITLE = HPI_CTL_ATTR(PAD, 3),
246 HPI_PAD_COMMENT = HPI_CTL_ATTR(PAD, 4),
247 HPI_PAD_PROGRAM_TYPE = HPI_CTL_ATTR(PAD, 5),
248 HPI_PAD_PROGRAM_ID = HPI_CTL_ATTR(PAD, 6),
249 HPI_PAD_TA_SUPPORT = HPI_CTL_ATTR(PAD, 7),
250 HPI_PAD_TA_ACTIVE = HPI_CTL_ATTR(PAD, 8)
251};
298 252
299#define HPI_POLARITY_POSITIVE 0 253#define HPI_POLARITY_POSITIVE 0
300#define HPI_POLARITY_NEGATIVE 1 254#define HPI_POLARITY_NEGATIVE 1
301 255
302/* Bitstream control get attributes */
303#define HPI_BITSTREAM_ACTIVITY 1
304
305/* SampleClock control attributes */
306#define HPI_SAMPLECLOCK_SOURCE HPI_CTL_ATTR(SAMPLECLOCK, 1)
307#define HPI_SAMPLECLOCK_SAMPLERATE HPI_CTL_ATTR(SAMPLECLOCK, 2)
308#define HPI_SAMPLECLOCK_SOURCE_INDEX HPI_CTL_ATTR(SAMPLECLOCK, 3)
309#define HPI_SAMPLECLOCK_LOCAL_SAMPLERATE\
310 HPI_CTL_ATTR(SAMPLECLOCK, 4)
311#define HPI_SAMPLECLOCK_AUTO HPI_CTL_ATTR(SAMPLECLOCK, 5)
312#define HPI_SAMPLECLOCK_LOCAL_LOCK HPI_CTL_ATTR(SAMPLECLOCK, 6)
313
314/* Microphone control attributes */
315#define HPI_MICROPHONE_PHANTOM_POWER HPI_CTL_ATTR(MICROPHONE, 1)
316
317/** Equalizer control attributes */
318/** Used to get number of filters in an EQ. (Can't set) */
319#define HPI_EQUALIZER_NUM_FILTERS HPI_CTL_ATTR(EQUALIZER, 1)
320/** Set/get the filter by type, freq, Q, gain */
321#define HPI_EQUALIZER_FILTER HPI_CTL_ATTR(EQUALIZER, 2)
322/** Get the biquad coefficients */
323#define HPI_EQUALIZER_COEFFICIENTS HPI_CTL_ATTR(EQUALIZER, 3)
324
325/* Note compander also uses HPI_GENERIC_ENABLE */
326#define HPI_COMPANDER_PARAMS HPI_CTL_ATTR(COMPANDER, 1)
327#define HPI_COMPANDER_MAKEUPGAIN HPI_CTL_ATTR(COMPANDER, 2)
328#define HPI_COMPANDER_THRESHOLD HPI_CTL_ATTR(COMPANDER, 3)
329#define HPI_COMPANDER_RATIO HPI_CTL_ATTR(COMPANDER, 4)
330#define HPI_COMPANDER_ATTACK HPI_CTL_ATTR(COMPANDER, 5)
331#define HPI_COMPANDER_DECAY HPI_CTL_ATTR(COMPANDER, 6)
332
333/* Cobranet control attributes. */
334#define HPI_COBRANET_SET HPI_CTL_ATTR(COBRANET, 1)
335#define HPI_COBRANET_GET HPI_CTL_ATTR(COBRANET, 2)
336#define HPI_COBRANET_SET_DATA HPI_CTL_ATTR(COBRANET, 3)
337#define HPI_COBRANET_GET_DATA HPI_CTL_ATTR(COBRANET, 4)
338#define HPI_COBRANET_GET_STATUS HPI_CTL_ATTR(COBRANET, 5)
339#define HPI_COBRANET_SEND_PACKET HPI_CTL_ATTR(COBRANET, 6)
340#define HPI_COBRANET_GET_PACKET HPI_CTL_ATTR(COBRANET, 7)
341
342/*------------------------------------------------------------ 256/*------------------------------------------------------------
343 Cobranet Chip Bridge - copied from HMI.H 257 Cobranet Chip Bridge - copied from HMI.H
344------------------------------------------------------------*/ 258------------------------------------------------------------*/
@@ -380,7 +294,7 @@ Used for HPI_ChannelModeSet/Get()
380 294
381/* These defines are used to fill in protocol information for an Ethernet packet 295/* These defines are used to fill in protocol information for an Ethernet packet
382 sent using HMI on CS18102 */ 296 sent using HMI on CS18102 */
383/** ID supplied by Cirrius for ASI packets. */ 297/** ID supplied by Cirrus for ASI packets. */
384#define HPI_ETHERNET_PACKET_ID 0x85 298#define HPI_ETHERNET_PACKET_ID 0x85
385/** Simple packet - no special routing required */ 299/** Simple packet - no special routing required */
386#define HPI_ETHERNET_PACKET_V1 0x01 300#define HPI_ETHERNET_PACKET_V1 0x01
@@ -393,71 +307,24 @@ Used for HPI_ChannelModeSet/Get()
393/** This packet must make its way to the host across the HPI interface */ 307/** This packet must make its way to the host across the HPI interface */
394#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41 308#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41
395 309
396#define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */ 310#define HPI_ETHERNET_UDP_PORT 44600 /**< HPI UDP service */
397
398/** Base network time out is set to 100 milli-seconds. */
399#define HPI_ETHERNET_TIMEOUT_MS (100)
400
401/** \defgroup tonedet_attr Tonedetector attributes
402\{
403Used by HPI_ToneDetector_Set() and HPI_ToneDetector_Get()
404*/
405
406/** Set the threshold level of a tonedetector,
407Threshold is a -ve number in units of dB/100,
408*/
409#define HPI_TONEDETECTOR_THRESHOLD HPI_CTL_ATTR(TONEDETECTOR, 1)
410
411/** Get the current state of tonedetection
412The result is a bitmap of detected tones. pairs of bits represent the left
413and right channels, with left channel in LSB.
414The lowest frequency detector state is in the LSB
415*/
416#define HPI_TONEDETECTOR_STATE HPI_CTL_ATTR(TONEDETECTOR, 2)
417
418/** Get the frequency of a tonedetector band.
419*/
420#define HPI_TONEDETECTOR_FREQUENCY HPI_CTL_ATTR(TONEDETECTOR, 3)
421 311
422/**\}*/ 312/** Default network timeout in milli-seconds. */
313#define HPI_ETHERNET_TIMEOUT_MS 500
423 314
424/** \defgroup silencedet_attr SilenceDetector attributes 315/** Locked memory buffer alloc/free phases */
425\{ 316enum HPI_BUFFER_CMDS {
426*/ 317 /** use one message to allocate or free physical memory */
427 318 HPI_BUFFER_CMD_EXTERNAL = 0,
428/** Get the current state of tonedetection 319 /** alloc physical memory */
429The result is a bitmap with 1s for silent channels. Left channel is in LSB 320 HPI_BUFFER_CMD_INTERNAL_ALLOC = 1,
430*/ 321 /** send physical memory address to adapter */
431#define HPI_SILENCEDETECTOR_STATE \ 322 HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER = 2,
432 HPI_CTL_ATTR(SILENCEDETECTOR, 2) 323 /** notify adapter to stop using physical buffer */
433 324 HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER = 3,
434/** Set the threshold level of a SilenceDetector, 325 /** free physical buffer */
435Threshold is a -ve number in units of dB/100, 326 HPI_BUFFER_CMD_INTERNAL_FREE = 4
436*/ 327};
437#define HPI_SILENCEDETECTOR_THRESHOLD \
438 HPI_CTL_ATTR(SILENCEDETECTOR, 1)
439
440/** get/set the silence time before the detector triggers
441*/
442#define HPI_SILENCEDETECTOR_DELAY \
443 HPI_CTL_ATTR(SILENCEDETECTOR, 3)
444
445/**\}*/
446
447/* Locked memory buffer alloc/free phases */
448/** use one message to allocate or free physical memory */
449#define HPI_BUFFER_CMD_EXTERNAL 0
450/** alloc physical memory */
451#define HPI_BUFFER_CMD_INTERNAL_ALLOC 1
452/** send physical memory address to adapter */
453#define HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER 2
454/** notify adapter to stop using physical buffer */
455#define HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER 3
456/** free physical buffer */
457#define HPI_BUFFER_CMD_INTERNAL_FREE 4
458
459/******************************************* CONTROLX ATTRIBUTES ****/
460/* NOTE: All controlx attributes must be unique, unlike control attributes */
461 328
462/*****************************************************************************/ 329/*****************************************************************************/
463/*****************************************************************************/ 330/*****************************************************************************/
@@ -482,6 +349,12 @@ Threshold is a -ve number in units of dB/100,
482#define HPI_USB_W2K_TAG 0x57495341 /* "ASIW" */ 349#define HPI_USB_W2K_TAG 0x57495341 /* "ASIW" */
483#define HPI_USB_LINUX_TAG 0x4C495341 /* "ASIL" */ 350#define HPI_USB_LINUX_TAG 0x4C495341 /* "ASIL" */
484 351
352/** Invalid Adapter index
353Used in HPI messages that are not addressed to a specific adapter
354Used in DLL to indicate device not present
355*/
356#define HPI_ADAPTER_INDEX_INVALID 0xFFFF
357
485/** First 2 hex digits define the adapter family */ 358/** First 2 hex digits define the adapter family */
486#define HPI_ADAPTER_FAMILY_MASK 0xff00 359#define HPI_ADAPTER_FAMILY_MASK 0xff00
487#define HPI_MODULE_FAMILY_MASK 0xfff0 360#define HPI_MODULE_FAMILY_MASK 0xfff0
@@ -490,178 +363,186 @@ Threshold is a -ve number in units of dB/100,
490#define HPI_MODULE_FAMILY_ASI(f) (f & HPI_MODULE_FAMILY_MASK) 363#define HPI_MODULE_FAMILY_ASI(f) (f & HPI_MODULE_FAMILY_MASK)
491#define HPI_ADAPTER_ASI(f) (f) 364#define HPI_ADAPTER_ASI(f) (f)
492 365
493/******************************************* message types */ 366enum HPI_MESSAGE_TYPES {
494#define HPI_TYPE_MESSAGE 1 367 HPI_TYPE_MESSAGE = 1,
495#define HPI_TYPE_RESPONSE 2 368 HPI_TYPE_RESPONSE = 2,
496#define HPI_TYPE_DATA 3 369 HPI_TYPE_DATA = 3,
497#define HPI_TYPE_SSX2BYPASS_MESSAGE 4 370 HPI_TYPE_SSX2BYPASS_MESSAGE = 4
498 371};
499/******************************************* object types */ 372
500#define HPI_OBJ_SUBSYSTEM 1 373enum HPI_OBJECT_TYPES {
501#define HPI_OBJ_ADAPTER 2 374 HPI_OBJ_SUBSYSTEM = 1,
502#define HPI_OBJ_OSTREAM 3 375 HPI_OBJ_ADAPTER = 2,
503#define HPI_OBJ_ISTREAM 4 376 HPI_OBJ_OSTREAM = 3,
504#define HPI_OBJ_MIXER 5 377 HPI_OBJ_ISTREAM = 4,
505#define HPI_OBJ_NODE 6 378 HPI_OBJ_MIXER = 5,
506#define HPI_OBJ_CONTROL 7 379 HPI_OBJ_NODE = 6,
507#define HPI_OBJ_NVMEMORY 8 380 HPI_OBJ_CONTROL = 7,
508#define HPI_OBJ_GPIO 9 381 HPI_OBJ_NVMEMORY = 8,
509#define HPI_OBJ_WATCHDOG 10 382 HPI_OBJ_GPIO = 9,
510#define HPI_OBJ_CLOCK 11 383 HPI_OBJ_WATCHDOG = 10,
511#define HPI_OBJ_PROFILE 12 384 HPI_OBJ_CLOCK = 11,
512#define HPI_OBJ_CONTROLEX 13 385 HPI_OBJ_PROFILE = 12,
513#define HPI_OBJ_ASYNCEVENT 14 386 HPI_OBJ_CONTROLEX = 13,
514 387 HPI_OBJ_ASYNCEVENT = 14
515#define HPI_OBJ_MAXINDEX 14 388#define HPI_OBJ_MAXINDEX 14
516 389};
517/******************************************* methods/functions */ 390
518 391#define HPI_OBJ_FUNCTION_SPACING 0x100
519#define HPI_OBJ_FUNCTION_SPACING 0x100 392#define HPI_FUNC_ID(obj, i) (HPI_OBJ_##obj * HPI_OBJ_FUNCTION_SPACING + i)
520#define HPI_MAKE_INDEX(obj, index) (obj * HPI_OBJ_FUNCTION_SPACING + index) 393
521#define HPI_EXTRACT_INDEX(fn) (fn & 0xff) 394#define HPI_EXTRACT_INDEX(fn) (fn & 0xff)
522 395
523/* SUB-SYSTEM */ 396enum HPI_FUNCTION_IDS {
524#define HPI_SUBSYS_OPEN HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 1) 397 HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1),
525#define HPI_SUBSYS_GET_VERSION HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 2) 398 HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2),
526#define HPI_SUBSYS_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 3) 399 HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3),
527#define HPI_SUBSYS_FIND_ADAPTERS HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 4) 400 /* HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), */
528#define HPI_SUBSYS_CREATE_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 5) 401 HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5),
529#define HPI_SUBSYS_CLOSE HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 6) 402 HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6),
530#define HPI_SUBSYS_DELETE_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 7) 403 /* HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), */
531#define HPI_SUBSYS_DRIVER_LOAD HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 8) 404 HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8),
532#define HPI_SUBSYS_DRIVER_UNLOAD HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 9) 405 HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9),
533#define HPI_SUBSYS_READ_PORT_8 HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 10) 406 /* HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), */
534#define HPI_SUBSYS_WRITE_PORT_8 HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 11) 407 /* HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), */
535#define HPI_SUBSYS_GET_NUM_ADAPTERS HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 12) 408 HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12),
536#define HPI_SUBSYS_GET_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 13) 409 HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13),
537#define HPI_SUBSYS_SET_NETWORK_INTERFACE HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 14) 410 HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14),
538#define HPI_SUBSYS_FUNCTION_COUNT 14 411 HPI_SUBSYS_OPTION_INFO = HPI_FUNC_ID(SUBSYSTEM, 15),
539/* ADAPTER */ 412 HPI_SUBSYS_OPTION_GET = HPI_FUNC_ID(SUBSYSTEM, 16),
540#define HPI_ADAPTER_OPEN HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 1) 413 HPI_SUBSYS_OPTION_SET = HPI_FUNC_ID(SUBSYSTEM, 17),
541#define HPI_ADAPTER_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 2) 414#define HPI_SUBSYS_FUNCTION_COUNT 17
542#define HPI_ADAPTER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 3) 415
543#define HPI_ADAPTER_GET_ASSERT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 4) 416 HPI_ADAPTER_OPEN = HPI_FUNC_ID(ADAPTER, 1),
544#define HPI_ADAPTER_TEST_ASSERT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 5) 417 HPI_ADAPTER_CLOSE = HPI_FUNC_ID(ADAPTER, 2),
545#define HPI_ADAPTER_SET_MODE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 6) 418 HPI_ADAPTER_GET_INFO = HPI_FUNC_ID(ADAPTER, 3),
546#define HPI_ADAPTER_GET_MODE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 7) 419 HPI_ADAPTER_GET_ASSERT = HPI_FUNC_ID(ADAPTER, 4),
547#define HPI_ADAPTER_ENABLE_CAPABILITY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 8) 420 HPI_ADAPTER_TEST_ASSERT = HPI_FUNC_ID(ADAPTER, 5),
548#define HPI_ADAPTER_SELFTEST HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 9) 421 HPI_ADAPTER_SET_MODE = HPI_FUNC_ID(ADAPTER, 6),
549#define HPI_ADAPTER_FIND_OBJECT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 10) 422 HPI_ADAPTER_GET_MODE = HPI_FUNC_ID(ADAPTER, 7),
550#define HPI_ADAPTER_QUERY_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 11) 423 HPI_ADAPTER_ENABLE_CAPABILITY = HPI_FUNC_ID(ADAPTER, 8),
551#define HPI_ADAPTER_START_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 12) 424 HPI_ADAPTER_SELFTEST = HPI_FUNC_ID(ADAPTER, 9),
552#define HPI_ADAPTER_PROGRAM_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 13) 425 HPI_ADAPTER_FIND_OBJECT = HPI_FUNC_ID(ADAPTER, 10),
553#define HPI_ADAPTER_SET_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 14) 426 HPI_ADAPTER_QUERY_FLASH = HPI_FUNC_ID(ADAPTER, 11),
554#define HPI_ADAPTER_GET_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 15) 427 HPI_ADAPTER_START_FLASH = HPI_FUNC_ID(ADAPTER, 12),
555#define HPI_ADAPTER_ENUM_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 16) 428 HPI_ADAPTER_PROGRAM_FLASH = HPI_FUNC_ID(ADAPTER, 13),
556#define HPI_ADAPTER_MODULE_INFO HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 17) 429 HPI_ADAPTER_SET_PROPERTY = HPI_FUNC_ID(ADAPTER, 14),
557#define HPI_ADAPTER_DEBUG_READ HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 18) 430 HPI_ADAPTER_GET_PROPERTY = HPI_FUNC_ID(ADAPTER, 15),
558#define HPI_ADAPTER_FUNCTION_COUNT 18 431 HPI_ADAPTER_ENUM_PROPERTY = HPI_FUNC_ID(ADAPTER, 16),
559/* OUTPUT STREAM */ 432 HPI_ADAPTER_MODULE_INFO = HPI_FUNC_ID(ADAPTER, 17),
560#define HPI_OSTREAM_OPEN HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 1) 433 HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18),
561#define HPI_OSTREAM_CLOSE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 2) 434 HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19),
562#define HPI_OSTREAM_WRITE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 3) 435 HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20),
563#define HPI_OSTREAM_START HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 4) 436 HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21),
564#define HPI_OSTREAM_STOP HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 5) 437#define HPI_ADAPTER_FUNCTION_COUNT 21
565#define HPI_OSTREAM_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 6) 438
566#define HPI_OSTREAM_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 7) 439 HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1),
567#define HPI_OSTREAM_QUERY_FORMAT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 8) 440 HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2),
568#define HPI_OSTREAM_DATA HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 9) 441 HPI_OSTREAM_WRITE = HPI_FUNC_ID(OSTREAM, 3),
569#define HPI_OSTREAM_SET_VELOCITY HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 10) 442 HPI_OSTREAM_START = HPI_FUNC_ID(OSTREAM, 4),
570#define HPI_OSTREAM_SET_PUNCHINOUT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 11) 443 HPI_OSTREAM_STOP = HPI_FUNC_ID(OSTREAM, 5),
571#define HPI_OSTREAM_SINEGEN HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 12) 444 HPI_OSTREAM_RESET = HPI_FUNC_ID(OSTREAM, 6),
572#define HPI_OSTREAM_ANC_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 13) 445 HPI_OSTREAM_GET_INFO = HPI_FUNC_ID(OSTREAM, 7),
573#define HPI_OSTREAM_ANC_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 14) 446 HPI_OSTREAM_QUERY_FORMAT = HPI_FUNC_ID(OSTREAM, 8),
574#define HPI_OSTREAM_ANC_READ HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 15) 447 HPI_OSTREAM_DATA = HPI_FUNC_ID(OSTREAM, 9),
575#define HPI_OSTREAM_SET_TIMESCALE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 16) 448 HPI_OSTREAM_SET_VELOCITY = HPI_FUNC_ID(OSTREAM, 10),
576#define HPI_OSTREAM_SET_FORMAT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 17) 449 HPI_OSTREAM_SET_PUNCHINOUT = HPI_FUNC_ID(OSTREAM, 11),
577#define HPI_OSTREAM_HOSTBUFFER_ALLOC HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 18) 450 HPI_OSTREAM_SINEGEN = HPI_FUNC_ID(OSTREAM, 12),
578#define HPI_OSTREAM_HOSTBUFFER_FREE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 19) 451 HPI_OSTREAM_ANC_RESET = HPI_FUNC_ID(OSTREAM, 13),
579#define HPI_OSTREAM_GROUP_ADD HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 20) 452 HPI_OSTREAM_ANC_GET_INFO = HPI_FUNC_ID(OSTREAM, 14),
580#define HPI_OSTREAM_GROUP_GETMAP HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 21) 453 HPI_OSTREAM_ANC_READ = HPI_FUNC_ID(OSTREAM, 15),
581#define HPI_OSTREAM_GROUP_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 22) 454 HPI_OSTREAM_SET_TIMESCALE = HPI_FUNC_ID(OSTREAM, 16),
582#define HPI_OSTREAM_HOSTBUFFER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 23) 455 HPI_OSTREAM_SET_FORMAT = HPI_FUNC_ID(OSTREAM, 17),
583#define HPI_OSTREAM_WAIT_START HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 24) 456 HPI_OSTREAM_HOSTBUFFER_ALLOC = HPI_FUNC_ID(OSTREAM, 18),
584#define HPI_OSTREAM_FUNCTION_COUNT 24 457 HPI_OSTREAM_HOSTBUFFER_FREE = HPI_FUNC_ID(OSTREAM, 19),
585/* INPUT STREAM */ 458 HPI_OSTREAM_GROUP_ADD = HPI_FUNC_ID(OSTREAM, 20),
586#define HPI_ISTREAM_OPEN HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 1) 459 HPI_OSTREAM_GROUP_GETMAP = HPI_FUNC_ID(OSTREAM, 21),
587#define HPI_ISTREAM_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 2) 460 HPI_OSTREAM_GROUP_RESET = HPI_FUNC_ID(OSTREAM, 22),
588#define HPI_ISTREAM_SET_FORMAT HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 3) 461 HPI_OSTREAM_HOSTBUFFER_GET_INFO = HPI_FUNC_ID(OSTREAM, 23),
589#define HPI_ISTREAM_READ HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 4) 462 HPI_OSTREAM_WAIT_START = HPI_FUNC_ID(OSTREAM, 24),
590#define HPI_ISTREAM_START HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 5) 463 HPI_OSTREAM_WAIT = HPI_FUNC_ID(OSTREAM, 25),
591#define HPI_ISTREAM_STOP HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 6) 464#define HPI_OSTREAM_FUNCTION_COUNT 25
592#define HPI_ISTREAM_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 7) 465
593#define HPI_ISTREAM_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 8) 466 HPI_ISTREAM_OPEN = HPI_FUNC_ID(ISTREAM, 1),
594#define HPI_ISTREAM_QUERY_FORMAT HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 9) 467 HPI_ISTREAM_CLOSE = HPI_FUNC_ID(ISTREAM, 2),
595#define HPI_ISTREAM_ANC_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 10) 468 HPI_ISTREAM_SET_FORMAT = HPI_FUNC_ID(ISTREAM, 3),
596#define HPI_ISTREAM_ANC_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 11) 469 HPI_ISTREAM_READ = HPI_FUNC_ID(ISTREAM, 4),
597#define HPI_ISTREAM_ANC_WRITE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 12) 470 HPI_ISTREAM_START = HPI_FUNC_ID(ISTREAM, 5),
598#define HPI_ISTREAM_HOSTBUFFER_ALLOC HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 13) 471 HPI_ISTREAM_STOP = HPI_FUNC_ID(ISTREAM, 6),
599#define HPI_ISTREAM_HOSTBUFFER_FREE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 14) 472 HPI_ISTREAM_RESET = HPI_FUNC_ID(ISTREAM, 7),
600#define HPI_ISTREAM_GROUP_ADD HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 15) 473 HPI_ISTREAM_GET_INFO = HPI_FUNC_ID(ISTREAM, 8),
601#define HPI_ISTREAM_GROUP_GETMAP HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 16) 474 HPI_ISTREAM_QUERY_FORMAT = HPI_FUNC_ID(ISTREAM, 9),
602#define HPI_ISTREAM_GROUP_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 17) 475 HPI_ISTREAM_ANC_RESET = HPI_FUNC_ID(ISTREAM, 10),
603#define HPI_ISTREAM_HOSTBUFFER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 18) 476 HPI_ISTREAM_ANC_GET_INFO = HPI_FUNC_ID(ISTREAM, 11),
604#define HPI_ISTREAM_WAIT_START HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 19) 477 HPI_ISTREAM_ANC_WRITE = HPI_FUNC_ID(ISTREAM, 12),
605#define HPI_ISTREAM_FUNCTION_COUNT 19 478 HPI_ISTREAM_HOSTBUFFER_ALLOC = HPI_FUNC_ID(ISTREAM, 13),
606/* MIXER */ 479 HPI_ISTREAM_HOSTBUFFER_FREE = HPI_FUNC_ID(ISTREAM, 14),
480 HPI_ISTREAM_GROUP_ADD = HPI_FUNC_ID(ISTREAM, 15),
481 HPI_ISTREAM_GROUP_GETMAP = HPI_FUNC_ID(ISTREAM, 16),
482 HPI_ISTREAM_GROUP_RESET = HPI_FUNC_ID(ISTREAM, 17),
483 HPI_ISTREAM_HOSTBUFFER_GET_INFO = HPI_FUNC_ID(ISTREAM, 18),
484 HPI_ISTREAM_WAIT_START = HPI_FUNC_ID(ISTREAM, 19),
485 HPI_ISTREAM_WAIT = HPI_FUNC_ID(ISTREAM, 20),
486#define HPI_ISTREAM_FUNCTION_COUNT 20
487
607/* NOTE: 488/* NOTE:
608 GET_NODE_INFO, SET_CONNECTION, GET_CONNECTIONS are not currently used */ 489 GET_NODE_INFO, SET_CONNECTION, GET_CONNECTIONS are not currently used */
609#define HPI_MIXER_OPEN HPI_MAKE_INDEX(HPI_OBJ_MIXER, 1) 490 HPI_MIXER_OPEN = HPI_FUNC_ID(MIXER, 1),
610#define HPI_MIXER_CLOSE HPI_MAKE_INDEX(HPI_OBJ_MIXER, 2) 491 HPI_MIXER_CLOSE = HPI_FUNC_ID(MIXER, 2),
611#define HPI_MIXER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_MIXER, 3) 492 HPI_MIXER_GET_INFO = HPI_FUNC_ID(MIXER, 3),
612#define HPI_MIXER_GET_NODE_INFO HPI_MAKE_INDEX(HPI_OBJ_MIXER, 4) 493 HPI_MIXER_GET_NODE_INFO = HPI_FUNC_ID(MIXER, 4),
613#define HPI_MIXER_GET_CONTROL HPI_MAKE_INDEX(HPI_OBJ_MIXER, 5) 494 HPI_MIXER_GET_CONTROL = HPI_FUNC_ID(MIXER, 5),
614#define HPI_MIXER_SET_CONNECTION HPI_MAKE_INDEX(HPI_OBJ_MIXER, 6) 495 HPI_MIXER_SET_CONNECTION = HPI_FUNC_ID(MIXER, 6),
615#define HPI_MIXER_GET_CONNECTIONS HPI_MAKE_INDEX(HPI_OBJ_MIXER, 7) 496 HPI_MIXER_GET_CONNECTIONS = HPI_FUNC_ID(MIXER, 7),
616#define HPI_MIXER_GET_CONTROL_BY_INDEX HPI_MAKE_INDEX(HPI_OBJ_MIXER, 8) 497 HPI_MIXER_GET_CONTROL_BY_INDEX = HPI_FUNC_ID(MIXER, 8),
617#define HPI_MIXER_GET_CONTROL_ARRAY_BY_INDEX HPI_MAKE_INDEX(HPI_OBJ_MIXER, 9) 498 HPI_MIXER_GET_CONTROL_ARRAY_BY_INDEX = HPI_FUNC_ID(MIXER, 9),
618#define HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES HPI_MAKE_INDEX(HPI_OBJ_MIXER, 10) 499 HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES = HPI_FUNC_ID(MIXER, 10),
619#define HPI_MIXER_STORE HPI_MAKE_INDEX(HPI_OBJ_MIXER, 11) 500 HPI_MIXER_STORE = HPI_FUNC_ID(MIXER, 11),
620#define HPI_MIXER_FUNCTION_COUNT 11 501 HPI_MIXER_GET_CACHE_INFO = HPI_FUNC_ID(MIXER, 12),
621/* MIXER CONTROLS */ 502#define HPI_MIXER_FUNCTION_COUNT 12
622#define HPI_CONTROL_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 1) 503
623#define HPI_CONTROL_GET_STATE HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 2) 504 HPI_CONTROL_GET_INFO = HPI_FUNC_ID(CONTROL, 1),
624#define HPI_CONTROL_SET_STATE HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 3) 505 HPI_CONTROL_GET_STATE = HPI_FUNC_ID(CONTROL, 2),
506 HPI_CONTROL_SET_STATE = HPI_FUNC_ID(CONTROL, 3),
625#define HPI_CONTROL_FUNCTION_COUNT 3 507#define HPI_CONTROL_FUNCTION_COUNT 3
626/* NONVOL MEMORY */ 508
627#define HPI_NVMEMORY_OPEN HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 1) 509 HPI_NVMEMORY_OPEN = HPI_FUNC_ID(NVMEMORY, 1),
628#define HPI_NVMEMORY_READ_BYTE HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 2) 510 HPI_NVMEMORY_READ_BYTE = HPI_FUNC_ID(NVMEMORY, 2),
629#define HPI_NVMEMORY_WRITE_BYTE HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 3) 511 HPI_NVMEMORY_WRITE_BYTE = HPI_FUNC_ID(NVMEMORY, 3),
630#define HPI_NVMEMORY_FUNCTION_COUNT 3 512#define HPI_NVMEMORY_FUNCTION_COUNT 3
631/* GPIO */ 513
632#define HPI_GPIO_OPEN HPI_MAKE_INDEX(HPI_OBJ_GPIO, 1) 514 HPI_GPIO_OPEN = HPI_FUNC_ID(GPIO, 1),
633#define HPI_GPIO_READ_BIT HPI_MAKE_INDEX(HPI_OBJ_GPIO, 2) 515 HPI_GPIO_READ_BIT = HPI_FUNC_ID(GPIO, 2),
634#define HPI_GPIO_WRITE_BIT HPI_MAKE_INDEX(HPI_OBJ_GPIO, 3) 516 HPI_GPIO_WRITE_BIT = HPI_FUNC_ID(GPIO, 3),
635#define HPI_GPIO_READ_ALL HPI_MAKE_INDEX(HPI_OBJ_GPIO, 4) 517 HPI_GPIO_READ_ALL = HPI_FUNC_ID(GPIO, 4),
636#define HPI_GPIO_WRITE_STATUS HPI_MAKE_INDEX(HPI_OBJ_GPIO, 5) 518 HPI_GPIO_WRITE_STATUS = HPI_FUNC_ID(GPIO, 5),
637#define HPI_GPIO_FUNCTION_COUNT 5 519#define HPI_GPIO_FUNCTION_COUNT 5
638/* ASYNC EVENT */ 520
639#define HPI_ASYNCEVENT_OPEN HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 1) 521 HPI_ASYNCEVENT_OPEN = HPI_FUNC_ID(ASYNCEVENT, 1),
640#define HPI_ASYNCEVENT_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 2) 522 HPI_ASYNCEVENT_CLOSE = HPI_FUNC_ID(ASYNCEVENT, 2),
641#define HPI_ASYNCEVENT_WAIT HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 3) 523 HPI_ASYNCEVENT_WAIT = HPI_FUNC_ID(ASYNCEVENT, 3),
642#define HPI_ASYNCEVENT_GETCOUNT HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 4) 524 HPI_ASYNCEVENT_GETCOUNT = HPI_FUNC_ID(ASYNCEVENT, 4),
643#define HPI_ASYNCEVENT_GET HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 5) 525 HPI_ASYNCEVENT_GET = HPI_FUNC_ID(ASYNCEVENT, 5),
644#define HPI_ASYNCEVENT_SENDEVENTS HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 6) 526 HPI_ASYNCEVENT_SENDEVENTS = HPI_FUNC_ID(ASYNCEVENT, 6),
645#define HPI_ASYNCEVENT_FUNCTION_COUNT 6 527#define HPI_ASYNCEVENT_FUNCTION_COUNT 6
646/* WATCH-DOG */ 528
647#define HPI_WATCHDOG_OPEN HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 1) 529 HPI_WATCHDOG_OPEN = HPI_FUNC_ID(WATCHDOG, 1),
648#define HPI_WATCHDOG_SET_TIME HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 2) 530 HPI_WATCHDOG_SET_TIME = HPI_FUNC_ID(WATCHDOG, 2),
649#define HPI_WATCHDOG_PING HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 3) 531 HPI_WATCHDOG_PING = HPI_FUNC_ID(WATCHDOG, 3),
650/* CLOCK */ 532
651#define HPI_CLOCK_OPEN HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 1) 533 HPI_CLOCK_OPEN = HPI_FUNC_ID(CLOCK, 1),
652#define HPI_CLOCK_SET_TIME HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 2) 534 HPI_CLOCK_SET_TIME = HPI_FUNC_ID(CLOCK, 2),
653#define HPI_CLOCK_GET_TIME HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 3) 535 HPI_CLOCK_GET_TIME = HPI_FUNC_ID(CLOCK, 3),
654/* PROFILE */ 536
655#define HPI_PROFILE_OPEN_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 1) 537 HPI_PROFILE_OPEN_ALL = HPI_FUNC_ID(PROFILE, 1),
656#define HPI_PROFILE_START_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 2) 538 HPI_PROFILE_START_ALL = HPI_FUNC_ID(PROFILE, 2),
657#define HPI_PROFILE_STOP_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 3) 539 HPI_PROFILE_STOP_ALL = HPI_FUNC_ID(PROFILE, 3),
658#define HPI_PROFILE_GET HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 4) 540 HPI_PROFILE_GET = HPI_FUNC_ID(PROFILE, 4),
659#define HPI_PROFILE_GET_IDLECOUNT HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 5) 541 HPI_PROFILE_GET_IDLECOUNT = HPI_FUNC_ID(PROFILE, 5),
660#define HPI_PROFILE_GET_NAME HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 6) 542 HPI_PROFILE_GET_NAME = HPI_FUNC_ID(PROFILE, 6),
661#define HPI_PROFILE_GET_UTILIZATION HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 7) 543 HPI_PROFILE_GET_UTILIZATION = HPI_FUNC_ID(PROFILE, 7)
662#define HPI_PROFILE_FUNCTION_COUNT 7 544#define HPI_PROFILE_FUNCTION_COUNT 7
663/* ////////////////////////////////////////////////////////////////////// */ 545};
664/* PRIVATE ATTRIBUTES */
665 546
666/* ////////////////////////////////////////////////////////////////////// */ 547/* ////////////////////////////////////////////////////////////////////// */
667/* STRUCTURES */ 548/* STRUCTURES */
@@ -672,18 +553,7 @@ Threshold is a -ve number in units of dB/100,
672/** PCI bus resource */ 553/** PCI bus resource */
673struct hpi_pci { 554struct hpi_pci {
674 u32 __iomem *ap_mem_base[HPI_MAX_ADAPTER_MEM_SPACES]; 555 u32 __iomem *ap_mem_base[HPI_MAX_ADAPTER_MEM_SPACES];
675 struct pci_dev *p_os_data; 556 struct pci_dev *pci_dev;
676
677#ifndef HPI64BIT /* keep structure size constant */
678 u32 padding[HPI_MAX_ADAPTER_MEM_SPACES + 1];
679#endif
680 u16 vendor_id;
681 u16 device_id;
682 u16 subsys_vendor_id;
683 u16 subsys_device_id;
684 u16 bus_number;
685 u16 device_number;
686 u32 interrupt;
687}; 557};
688 558
689struct hpi_resource { 559struct hpi_resource {
@@ -702,12 +572,10 @@ struct hpi_resource {
702/** Format info used inside struct hpi_message 572/** Format info used inside struct hpi_message
703 Not the same as public API struct hpi_format */ 573 Not the same as public API struct hpi_format */
704struct hpi_msg_format { 574struct hpi_msg_format {
705 u32 sample_rate; 575 u32 sample_rate; /**< 11025, 32000, 44100 etc. */
706 /**< 11025, 32000, 44100 ... */ 576 u32 bit_rate; /**< for MPEG */
707 u32 bit_rate; /**< for MPEG */ 577 u32 attributes; /**< stereo/joint_stereo/mono */
708 u32 attributes; 578 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
709 /**< Stereo/JointStereo/Mono */
710 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
711 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see \ref HPI_FORMATS. */ 579 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see \ref HPI_FORMATS. */
712}; 580};
713 581
@@ -740,9 +608,9 @@ struct hpi_data_compat32 {
740#endif 608#endif
741 609
742struct hpi_buffer { 610struct hpi_buffer {
743 /** placehoder for backward compatability (see dwBufferSize) */ 611 /** placehoder for backward compatibility (see dwBufferSize) */
744 struct hpi_msg_format reserved; 612 struct hpi_msg_format reserved;
745 u32 command; /**< HPI_BUFFER_CMD_xxx*/ 613 u32 command; /**< HPI_BUFFER_CMD_xxx*/
746 u32 pci_address; /**< PCI physical address of buffer for DSP DMA */ 614 u32 pci_address; /**< PCI physical address of buffer for DSP DMA */
747 u32 buffer_size; /**< must line up with data_size of HPI_DATA*/ 615 u32 buffer_size; /**< must line up with data_size of HPI_DATA*/
748}; 616};
@@ -777,30 +645,25 @@ struct hpi_subsys_msg {
777 645
778struct hpi_subsys_res { 646struct hpi_subsys_res {
779 u32 version; 647 u32 version;
780 u32 data; /* used to return extended version */ 648 u32 data; /* extended version */
781 u16 num_adapters; /* number of adapters */ 649 u16 num_adapters;
782 u16 adapter_index; 650 u16 adapter_index;
783 u16 aw_adapter_list[HPI_MAX_ADAPTERS]; 651 u16 adapter_type;
784}; 652 u16 pad16;
785
786struct hpi_adapter_msg {
787 u32 adapter_mode; /* adapter mode */
788 u16 assert_id; /* assert number for "test assert" call
789 object_index for find object call
790 query_or_set for hpi_adapter_set_mode_ex() */
791 u16 object_type; /* for adapter find object call */
792}; 653};
793 654
794union hpi_adapterx_msg { 655union hpi_adapterx_msg {
795 struct hpi_adapter_msg adapter;
796 struct { 656 struct {
797 u32 offset; 657 u32 dsp_address;
798 } query_flash; 658 u32 count_bytes;
659 } debug_read;
799 struct { 660 struct {
800 u32 offset; 661 u32 adapter_mode;
801 u32 length; 662 u16 query_or_set;
802 u32 key; 663 } mode;
803 } start_flash; 664 struct {
665 u16 index;
666 } module_info;
804 struct { 667 struct {
805 u32 checksum; 668 u32 checksum;
806 u16 sequence; 669 u16 sequence;
@@ -809,28 +672,41 @@ union hpi_adapterx_msg {
809 u16 unused; 672 u16 unused;
810 } program_flash; 673 } program_flash;
811 struct { 674 struct {
675 u16 index;
676 u16 what;
677 u16 property_index;
678 } property_enum;
679 struct {
812 u16 property; 680 u16 property;
813 u16 parameter1; 681 u16 parameter1;
814 u16 parameter2; 682 u16 parameter2;
815 } property_set; 683 } property_set;
816 struct { 684 struct {
817 u16 index; 685 u32 offset;
818 u16 what; 686 } query_flash;
819 u16 property_index;
820 } property_enum;
821 struct { 687 struct {
822 u16 index; 688 u32 pad32;
823 } module_info; 689 u16 key1;
690 u16 key2;
691 } restart;
824 struct { 692 struct {
825 u32 dsp_address; 693 u32 offset;
826 u32 count_bytes; 694 u32 length;
827 } debug_read; 695 u32 key;
696 } start_flash;
697 struct {
698 u32 pad32;
699 u16 value;
700 } test_assert;
701 struct {
702 u32 yes;
703 } irq_query;
828}; 704};
829 705
830struct hpi_adapter_res { 706struct hpi_adapter_res {
831 u32 serial_number; 707 u32 serial_number;
832 u16 adapter_type; 708 u16 adapter_type;
833 u16 adapter_index; /* is this needed? also used for dsp_index */ 709 u16 adapter_index;
834 u16 num_instreams; 710 u16 num_instreams;
835 u16 num_outstreams; 711 u16 num_outstreams;
836 u16 num_mixers; 712 u16 num_mixers;
@@ -839,12 +715,18 @@ struct hpi_adapter_res {
839}; 715};
840 716
841union hpi_adapterx_res { 717union hpi_adapterx_res {
842 struct hpi_adapter_res adapter; 718 struct hpi_adapter_res info;
843 struct { 719 struct {
844 u32 checksum; 720 u32 p1;
845 u32 length; 721 u16 count;
846 u32 version; 722 u16 dsp_index;
847 } query_flash; 723 u32 p2;
724 u32 dsp_msg_addr;
725 char sz_message[HPI_STRING_LEN];
726 } assert;
727 struct {
728 u32 adapter_mode;
729 } mode;
848 struct { 730 struct {
849 u16 sequence; 731 u16 sequence;
850 } program_flash; 732 } program_flash;
@@ -852,6 +734,14 @@ union hpi_adapterx_res {
852 u16 parameter1; 734 u16 parameter1;
853 u16 parameter2; 735 u16 parameter2;
854 } property_get; 736 } property_get;
737 struct {
738 u32 checksum;
739 u32 length;
740 u32 version;
741 } query_flash;
742 struct {
743 u32 yes;
744 } irq_query;
855}; 745};
856 746
857struct hpi_stream_msg { 747struct hpi_stream_msg {
@@ -863,6 +753,7 @@ struct hpi_stream_msg {
863 u32 time_scale; 753 u32 time_scale;
864 struct hpi_buffer buffer; 754 struct hpi_buffer buffer;
865 struct hpi_streamid stream; 755 struct hpi_streamid stream;
756 u32 threshold_bytes;
866 } u; 757 } u;
867}; 758};
868 759
@@ -911,7 +802,7 @@ struct hpi_stream_res {
911struct hpi_mixer_msg { 802struct hpi_mixer_msg {
912 u16 control_index; 803 u16 control_index;
913 u16 control_type; /* = HPI_CONTROL_METER _VOLUME etc */ 804 u16 control_type; /* = HPI_CONTROL_METER _VOLUME etc */
914 u16 padding1; /* maintain alignment of subsequent fields */ 805 u16 padding1; /* Maintain alignment of subsequent fields */
915 u16 node_type1; /* = HPI_SOURCENODE_LINEIN etc */ 806 u16 node_type1; /* = HPI_SOURCENODE_LINEIN etc */
916 u16 node_index1; /* = 0..N */ 807 u16 node_index1; /* = 0..N */
917 u16 node_type2; 808 u16 node_type2;
@@ -949,6 +840,11 @@ union hpi_mixerx_res {
949 u32 p_data; /* pointer to data array */ 840 u32 p_data; /* pointer to data array */
950 u16 more_to_do; /* indicates if there is more to do */ 841 u16 more_to_do; /* indicates if there is more to do */
951 } gcabi; 842 } gcabi;
843 struct {
844 u32 total_controls; /* count of controls in the mixer */
845 u32 cache_controls; /* count of controls in the cac */
846 u32 cache_bytes; /* size of cache */
847 } cache_info;
952}; 848};
953 849
954struct hpi_control_msg { 850struct hpi_control_msg {
@@ -1000,12 +896,16 @@ union hpi_control_union_res {
1000 u32 band; 896 u32 band;
1001 u32 frequency; 897 u32 frequency;
1002 u32 gain; 898 u32 gain;
1003 u32 level;
1004 u32 deemphasis; 899 u32 deemphasis;
1005 struct { 900 struct {
1006 u32 data[2]; 901 u32 data[2];
1007 u32 bLER; 902 u32 bLER;
1008 } rds; 903 } rds;
904 short s_level;
905 struct {
906 u16 value;
907 u16 mask;
908 } status;
1009 } tuner; 909 } tuner;
1010 struct { 910 struct {
1011 char sz_data[8]; 911 char sz_data[8];
@@ -1178,11 +1078,11 @@ struct hpi_profile_res_open {
1178}; 1078};
1179 1079
1180struct hpi_profile_res_time { 1080struct hpi_profile_res_time {
1181 u32 micro_seconds; 1081 u32 total_tick_count;
1182 u32 call_count; 1082 u32 call_count;
1183 u32 max_micro_seconds; 1083 u32 max_tick_count;
1184 u32 min_micro_seconds; 1084 u32 ticks_per_millisecond;
1185 u16 seconds; 1085 u16 profile_interval;
1186}; 1086};
1187 1087
1188struct hpi_profile_res_name { 1088struct hpi_profile_res_name {
@@ -1218,7 +1118,6 @@ struct hpi_message {
1218 u16 obj_index; /* */ 1118 u16 obj_index; /* */
1219 union { 1119 union {
1220 struct hpi_subsys_msg s; 1120 struct hpi_subsys_msg s;
1221 struct hpi_adapter_msg a;
1222 union hpi_adapterx_msg ax; 1121 union hpi_adapterx_msg ax;
1223 struct hpi_stream_msg d; 1122 struct hpi_stream_msg d;
1224 struct hpi_mixer_msg m; 1123 struct hpi_mixer_msg m;
@@ -1239,7 +1138,7 @@ struct hpi_message {
1239}; 1138};
1240 1139
1241#define HPI_MESSAGE_SIZE_BY_OBJECT { \ 1140#define HPI_MESSAGE_SIZE_BY_OBJECT { \
1242 sizeof(struct hpi_message_header) , /* default, no object type 0 */ \ 1141 sizeof(struct hpi_message_header) , /* Default, no object type 0 */ \
1243 sizeof(struct hpi_message_header) + sizeof(struct hpi_subsys_msg),\ 1142 sizeof(struct hpi_message_header) + sizeof(struct hpi_subsys_msg),\
1244 sizeof(struct hpi_message_header) + sizeof(union hpi_adapterx_msg),\ 1143 sizeof(struct hpi_message_header) + sizeof(union hpi_adapterx_msg),\
1245 sizeof(struct hpi_message_header) + sizeof(struct hpi_stream_msg),\ 1144 sizeof(struct hpi_message_header) + sizeof(struct hpi_stream_msg),\
@@ -1256,6 +1155,11 @@ struct hpi_message {
1256 sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \ 1155 sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \
1257} 1156}
1258 1157
1158/*
1159Note that the wSpecificError error field should be inspected and potentially
1160reported whenever HPI_ERROR_DSP_COMMUNICATION or HPI_ERROR_DSP_BOOTLOAD is
1161returned in wError.
1162*/
1259struct hpi_response_header { 1163struct hpi_response_header {
1260 u16 size; 1164 u16 size;
1261 u8 type; /* HPI_TYPE_RESPONSE */ 1165 u8 type; /* HPI_TYPE_RESPONSE */
@@ -1277,7 +1181,6 @@ struct hpi_response {
1277 u16 specific_error; /* adapter specific error */ 1181 u16 specific_error; /* adapter specific error */
1278 union { 1182 union {
1279 struct hpi_subsys_res s; 1183 struct hpi_subsys_res s;
1280 struct hpi_adapter_res a;
1281 union hpi_adapterx_res ax; 1184 union hpi_adapterx_res ax;
1282 struct hpi_stream_res d; 1185 struct hpi_stream_res d;
1283 struct hpi_mixer_res m; 1186 struct hpi_mixer_res m;
@@ -1297,7 +1200,7 @@ struct hpi_response {
1297}; 1200};
1298 1201
1299#define HPI_RESPONSE_SIZE_BY_OBJECT { \ 1202#define HPI_RESPONSE_SIZE_BY_OBJECT { \
1300 sizeof(struct hpi_response_header) ,/* default, no object type 0 */ \ 1203 sizeof(struct hpi_response_header) ,/* Default, no object type 0 */ \
1301 sizeof(struct hpi_response_header) + sizeof(struct hpi_subsys_res),\ 1204 sizeof(struct hpi_response_header) + sizeof(struct hpi_subsys_res),\
1302 sizeof(struct hpi_response_header) + sizeof(union hpi_adapterx_res),\ 1205 sizeof(struct hpi_response_header) + sizeof(union hpi_adapterx_res),\
1303 sizeof(struct hpi_response_header) + sizeof(struct hpi_stream_res),\ 1206 sizeof(struct hpi_response_header) + sizeof(struct hpi_stream_res),\
@@ -1314,7 +1217,7 @@ struct hpi_response {
1314 sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \ 1217 sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \
1315} 1218}
1316 1219
1317/*********************** version 1 message/response *****************************/ 1220/*********************** version 1 message/response **************************/
1318#define HPINET_ETHERNET_DATA_SIZE (1500) 1221#define HPINET_ETHERNET_DATA_SIZE (1500)
1319#define HPINET_IP_HDR_SIZE (20) 1222#define HPINET_IP_HDR_SIZE (20)
1320#define HPINET_IP_DATA_SIZE (HPINET_ETHERNET_DATA_SIZE - HPINET_IP_HDR_SIZE) 1223#define HPINET_IP_DATA_SIZE (HPINET_ETHERNET_DATA_SIZE - HPINET_IP_HDR_SIZE)
@@ -1394,6 +1297,17 @@ struct hpi_res_adapter_program_flash {
1394 sizeof(struct hpi_response_header) - sizeof(u16)]; 1297 sizeof(struct hpi_response_header) - sizeof(u16)];
1395}; 1298};
1396 1299
1300struct hpi_msg_adapter_debug_read {
1301 struct hpi_message_header h;
1302 u32 dsp_address;
1303 u32 count_bytes;
1304};
1305
1306struct hpi_res_adapter_debug_read {
1307 struct hpi_response_header h;
1308 u8 bytes[256];
1309};
1310
1397#if 1 1311#if 1
1398#define hpi_message_header_v1 hpi_message_header 1312#define hpi_message_header_v1 hpi_message_header
1399#define hpi_response_header_v1 hpi_response_header 1313#define hpi_response_header_v1 hpi_response_header
@@ -1414,23 +1328,10 @@ struct hpi_response_header_v1 {
1414}; 1328};
1415#endif 1329#endif
1416 1330
1417/* STRV HPI Packet */
1418struct hpi_msg_strv {
1419 struct hpi_message_header h;
1420 struct hpi_entity strv;
1421};
1422
1423struct hpi_res_strv {
1424 struct hpi_response_header h;
1425 struct hpi_entity strv;
1426};
1427#define MIN_STRV_PACKET_SIZE sizeof(struct hpi_res_strv)
1428
1429struct hpi_msg_payload_v0 { 1331struct hpi_msg_payload_v0 {
1430 struct hpi_message_header h; 1332 struct hpi_message_header h;
1431 union { 1333 union {
1432 struct hpi_subsys_msg s; 1334 struct hpi_subsys_msg s;
1433 struct hpi_adapter_msg a;
1434 union hpi_adapterx_msg ax; 1335 union hpi_adapterx_msg ax;
1435 struct hpi_stream_msg d; 1336 struct hpi_stream_msg d;
1436 struct hpi_mixer_msg m; 1337 struct hpi_mixer_msg m;
@@ -1451,7 +1352,6 @@ struct hpi_res_payload_v0 {
1451 struct hpi_response_header h; 1352 struct hpi_response_header h;
1452 union { 1353 union {
1453 struct hpi_subsys_res s; 1354 struct hpi_subsys_res s;
1454 struct hpi_adapter_res a;
1455 union hpi_adapterx_res ax; 1355 union hpi_adapterx_res ax;
1456 struct hpi_stream_res d; 1356 struct hpi_stream_res d;
1457 struct hpi_mixer_res m; 1357 struct hpi_mixer_res m;
@@ -1471,13 +1371,13 @@ struct hpi_res_payload_v0 {
1471union hpi_message_buffer_v1 { 1371union hpi_message_buffer_v1 {
1472 struct hpi_message m0; /* version 0 */ 1372 struct hpi_message m0; /* version 0 */
1473 struct hpi_message_header_v1 h; 1373 struct hpi_message_header_v1 h;
1474 unsigned char buf[HPI_MAX_PAYLOAD_SIZE]; 1374 u8 buf[HPI_MAX_PAYLOAD_SIZE];
1475}; 1375};
1476 1376
1477union hpi_response_buffer_v1 { 1377union hpi_response_buffer_v1 {
1478 struct hpi_response r0; /* version 0 */ 1378 struct hpi_response r0; /* version 0 */
1479 struct hpi_response_header_v1 h; 1379 struct hpi_response_header_v1 h;
1480 unsigned char buf[HPI_MAX_PAYLOAD_SIZE]; 1380 u8 buf[HPI_MAX_PAYLOAD_SIZE];
1481}; 1381};
1482 1382
1483compile_time_assert((sizeof(union hpi_message_buffer_v1) <= 1383compile_time_assert((sizeof(union hpi_message_buffer_v1) <=
@@ -1499,6 +1399,11 @@ struct hpi_control_defn {
1499/*////////////////////////////////////////////////////////////////////////// */ 1399/*////////////////////////////////////////////////////////////////////////// */
1500/* declarations for control caching (internal to HPI<->DSP interaction) */ 1400/* declarations for control caching (internal to HPI<->DSP interaction) */
1501 1401
1402/** indicates a cached u16 value is invalid. */
1403#define HPI_CACHE_INVALID_UINT16 0xFFFF
1404/** indicates a cached short value is invalid. */
1405#define HPI_CACHE_INVALID_SHORT -32768
1406
1502/** A compact representation of (part of) a controls state. 1407/** A compact representation of (part of) a controls state.
1503Used for efficient transfer of the control state 1408Used for efficient transfer of the control state
1504between DSP and host or across a network 1409between DSP and host or across a network
@@ -1512,58 +1417,104 @@ struct hpi_control_cache_info {
1512 u16 control_index; 1417 u16 control_index;
1513}; 1418};
1514 1419
1515struct hpi_control_cache_single { 1420struct hpi_control_cache_vol {
1516 struct hpi_control_cache_info i; 1421 struct hpi_control_cache_info i;
1422 short an_log[2];
1423 unsigned short flags;
1424 char padding[2];
1425};
1426
1427struct hpi_control_cache_meter {
1428 struct hpi_control_cache_info i;
1429 short an_log_peak[2];
1430 short an_logRMS[2];
1431};
1432
1433struct hpi_control_cache_channelmode {
1434 struct hpi_control_cache_info i;
1435 u16 mode;
1436 char temp_padding[6];
1437};
1438
1439struct hpi_control_cache_mux {
1440 struct hpi_control_cache_info i;
1441 u16 source_node_type;
1442 u16 source_node_index;
1443 char temp_padding[4];
1444};
1445
1446struct hpi_control_cache_level {
1447 struct hpi_control_cache_info i;
1448 short an_log[2];
1449 char temp_padding[4];
1450};
1451
1452struct hpi_control_cache_tuner {
1453 struct hpi_control_cache_info i;
1454 u32 freq_ink_hz;
1455 u16 band;
1456 short s_level_avg;
1457};
1458
1459struct hpi_control_cache_aes3rx {
1460 struct hpi_control_cache_info i;
1461 u32 error_status;
1462 u32 format;
1463};
1464
1465struct hpi_control_cache_aes3tx {
1466 struct hpi_control_cache_info i;
1467 u32 format;
1468 char temp_padding[4];
1469};
1470
1471struct hpi_control_cache_tonedetector {
1472 struct hpi_control_cache_info i;
1473 u16 state;
1474 char temp_padding[6];
1475};
1476
1477struct hpi_control_cache_silencedetector {
1478 struct hpi_control_cache_info i;
1479 u32 state;
1480 char temp_padding[4];
1481};
1482
1483struct hpi_control_cache_sampleclock {
1484 struct hpi_control_cache_info i;
1485 u16 source;
1486 u16 source_index;
1487 u32 sample_rate;
1488};
1489
1490struct hpi_control_cache_microphone {
1491 struct hpi_control_cache_info i;
1492 u16 phantom_state;
1493 char temp_padding[6];
1494};
1495
1496struct hpi_control_cache_generic {
1497 struct hpi_control_cache_info i;
1498 u32 dw1;
1499 u32 dw2;
1500};
1501
1502struct hpi_control_cache_single {
1517 union { 1503 union {
1518 struct { /* volume */ 1504 struct hpi_control_cache_info i;
1519 short an_log[2]; 1505 struct hpi_control_cache_vol vol;
1520 } v; 1506 struct hpi_control_cache_meter meter;
1521 struct { /* peak meter */ 1507 struct hpi_control_cache_channelmode mode;
1522 short an_log_peak[2]; 1508 struct hpi_control_cache_mux mux;
1523 short an_logRMS[2]; 1509 struct hpi_control_cache_level level;
1524 } p; 1510 struct hpi_control_cache_tuner tuner;
1525 struct { /* channel mode */ 1511 struct hpi_control_cache_aes3rx aes3rx;
1526 u16 mode; 1512 struct hpi_control_cache_aes3tx aes3tx;
1527 } m; 1513 struct hpi_control_cache_tonedetector tone;
1528 struct { /* multiplexer */ 1514 struct hpi_control_cache_silencedetector silence;
1529 u16 source_node_type; 1515 struct hpi_control_cache_sampleclock clk;
1530 u16 source_node_index; 1516 struct hpi_control_cache_microphone microphone;
1531 } x; 1517 struct hpi_control_cache_generic generic;
1532 struct { /* level/trim */
1533 short an_log[2];
1534 } l;
1535 struct { /* tuner - partial caching.
1536 some attributes go to the DSP. */
1537 u32 freq_ink_hz;
1538 u16 band;
1539 u16 level;
1540 } t;
1541 struct { /* AESEBU rx status */
1542 u32 error_status;
1543 u32 source;
1544 } aes3rx;
1545 struct { /* AESEBU tx */
1546 u32 format;
1547 } aes3tx;
1548 struct { /* tone detector */
1549 u16 state;
1550 } tone;
1551 struct { /* silence detector */
1552 u32 state;
1553 u32 count;
1554 } silence;
1555 struct { /* sample clock */
1556 u16 source;
1557 u16 source_index;
1558 u32 sample_rate;
1559 } clk;
1560 struct { /* microphone control */
1561 u16 state;
1562 } phantom_power;
1563 struct { /* generic control */
1564 u32 dw1;
1565 u32 dw2;
1566 } g;
1567 } u; 1518 } u;
1568}; 1519};
1569 1520
@@ -1580,8 +1531,7 @@ struct hpi_control_cache_pad {
1580 u32 traffic_anouncement; 1531 u32 traffic_anouncement;
1581}; 1532};
1582 1533
1583/*/////////////////////////////////////////////////////////////////////////// */ 1534/* 2^N sized FIFO buffer (internal to HPI<->DSP interaction) */
1584/* declarations for 2^N sized FIFO buffer (internal to HPI<->DSP interaction) */
1585struct hpi_fifo_buffer { 1535struct hpi_fifo_buffer {
1586 u32 size; 1536 u32 size;
1587 u32 dSP_index; 1537 u32 dSP_index;
@@ -1606,25 +1556,16 @@ u32 hpi_indexes_to_handle(const char c_object, const u16 adapter_index,
1606/*////////////////////////////////////////////////////////////////////////// */ 1556/*////////////////////////////////////////////////////////////////////////// */
1607 1557
1608/* main HPI entry point */ 1558/* main HPI entry point */
1609hpi_handler_func hpi_send_recv; 1559void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr);
1610
1611/* UDP message */
1612void hpi_send_recvUDP(struct hpi_message *phm, struct hpi_response *phr,
1613 const unsigned int timeout);
1614 1560
1615/* used in PnP OS/driver */ 1561/* used in PnP OS/driver */
1616u16 hpi_subsys_create_adapter(const struct hpi_hsubsys *ph_subsys, 1562u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource,
1617 const struct hpi_resource *p_resource, u16 *pw_adapter_index); 1563 u16 *pw_adapter_index);
1618
1619u16 hpi_subsys_delete_adapter(const struct hpi_hsubsys *ph_subsys,
1620 u16 adapter_index);
1621 1564
1622u16 hpi_outstream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys, 1565u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer,
1623 u32 h_outstream, u8 **pp_buffer,
1624 struct hpi_hostbuffer_status **pp_status); 1566 struct hpi_hostbuffer_status **pp_status);
1625 1567
1626u16 hpi_instream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys, 1568u16 hpi_instream_host_buffer_get_info(u32 h_instream, u8 **pp_buffer,
1627 u32 h_instream, u8 **pp_buffer,
1628 struct hpi_hostbuffer_status **pp_status); 1569 struct hpi_hostbuffer_status **pp_status);
1629 1570
1630u16 hpi_adapter_restart(u16 adapter_index); 1571u16 hpi_adapter_restart(u16 adapter_index);
@@ -1642,9 +1583,7 @@ void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR);
1642 1583
1643/*////////////////////////////////////////////////////////////////////////// */ 1584/*////////////////////////////////////////////////////////////////////////// */
1644/* declarations for individual HPI entry points */ 1585/* declarations for individual HPI entry points */
1645hpi_handler_func HPI_1000;
1646hpi_handler_func HPI_6000; 1586hpi_handler_func HPI_6000;
1647hpi_handler_func HPI_6205; 1587hpi_handler_func HPI_6205;
1648hpi_handler_func HPI_COMMON;
1649 1588
1650#endif /* _HPI_INTERNAL_H_ */ 1589#endif /* _HPI_INTERNAL_H_ */
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
index dda4f1c6f658..b15a02e91f82 100644
--- a/sound/pci/asihpi/hpicmn.c
+++ b/sound/pci/asihpi/hpicmn.c
@@ -26,6 +26,8 @@
26 26
27#include "hpi_internal.h" 27#include "hpi_internal.h"
28#include "hpidebug.h" 28#include "hpidebug.h"
29#include "hpimsginit.h"
30
29#include "hpicmn.h" 31#include "hpicmn.h"
30 32
31struct hpi_adapters_list { 33struct hpi_adapters_list {
@@ -43,14 +45,24 @@ static struct hpi_adapters_list adapters;
43**/ 45**/
44u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr) 46u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
45{ 47{
46 u16 error = 0; 48 if (phr->type != HPI_TYPE_RESPONSE) {
49 HPI_DEBUG_LOG(ERROR, "header type %d invalid\n", phr->type);
50 return HPI_ERROR_INVALID_RESPONSE;
51 }
52
53 if (phr->object != phm->object) {
54 HPI_DEBUG_LOG(ERROR, "header object %d invalid\n",
55 phr->object);
56 return HPI_ERROR_INVALID_RESPONSE;
57 }
47 58
48 if ((phr->type != HPI_TYPE_RESPONSE) 59 if (phr->function != phm->function) {
49 || (phr->object != phm->object) 60 HPI_DEBUG_LOG(ERROR, "header type %d invalid\n",
50 || (phr->function != phm->function)) 61 phr->function);
51 error = HPI_ERROR_INVALID_RESPONSE; 62 return HPI_ERROR_INVALID_RESPONSE;
63 }
52 64
53 return error; 65 return 0;
54} 66}
55 67
56u16 hpi_add_adapter(struct hpi_adapter_obj *pao) 68u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
@@ -66,8 +78,18 @@ u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
66 } 78 }
67 79
68 if (adapters.adapter[pao->index].adapter_type) { 80 if (adapters.adapter[pao->index].adapter_type) {
69 { 81 int a;
70 retval = HPI_DUPLICATE_ADAPTER_NUMBER; 82 for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) {
83 if (!adapters.adapter[a].adapter_type) {
84 HPI_DEBUG_LOG(WARNING,
85 "ASI%X duplicate index %d moved to %d\n",
86 pao->adapter_type, pao->index, a);
87 pao->index = a;
88 break;
89 }
90 }
91 if (a < 0) {
92 retval = HPI_ERROR_DUPLICATE_ADAPTER_NUMBER;
71 goto unlock; 93 goto unlock;
72 } 94 }
73 } 95 }
@@ -76,17 +98,22 @@ u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
76 adapters.gw_num_adapters++; 98 adapters.gw_num_adapters++;
77 99
78unlock: 100unlock:
79 hpios_alistlock_un_lock(&adapters); 101 hpios_alistlock_unlock(&adapters);
80 return retval; 102 return retval;
81} 103}
82 104
83void hpi_delete_adapter(struct hpi_adapter_obj *pao) 105void hpi_delete_adapter(struct hpi_adapter_obj *pao)
84{ 106{
85 memset(pao, 0, sizeof(struct hpi_adapter_obj)); 107 if (!pao->adapter_type) {
108 HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
109 return;
110 }
86 111
87 hpios_alistlock_lock(&adapters); 112 hpios_alistlock_lock(&adapters);
88 adapters.gw_num_adapters--; /* dec the number of adapters */ 113 if (adapters.adapter[pao->index].adapter_type)
89 hpios_alistlock_un_lock(&adapters); 114 adapters.gw_num_adapters--;
115 memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
116 hpios_alistlock_unlock(&adapters);
90} 117}
91 118
92/** 119/**
@@ -99,7 +126,7 @@ struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
99 struct hpi_adapter_obj *pao = NULL; 126 struct hpi_adapter_obj *pao = NULL;
100 127
101 if (adapter_index >= HPI_MAX_ADAPTERS) { 128 if (adapter_index >= HPI_MAX_ADAPTERS) {
102 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d ", 129 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d\n",
103 adapter_index); 130 adapter_index);
104 return NULL; 131 return NULL;
105 } 132 }
@@ -125,51 +152,34 @@ struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
125* wipe an HPI_ADAPTERS_LIST structure. 152* wipe an HPI_ADAPTERS_LIST structure.
126* 153*
127**/ 154**/
128static void wipe_adapter_list(void 155static void wipe_adapter_list(void)
129 )
130{ 156{
131 memset(&adapters, 0, sizeof(adapters)); 157 memset(&adapters, 0, sizeof(adapters));
132} 158}
133 159
134/** 160static void subsys_get_adapter(struct hpi_message *phm,
135* SubSysGetAdapters fills awAdapterList in an struct hpi_response structure 161 struct hpi_response *phr)
136* with all adapters in the given HPI_ADAPTERS_LIST.
137*
138*/
139static void subsys_get_adapters(struct hpi_response *phr)
140{ 162{
141 /* fill in the response adapter array with the position */ 163 int count = phm->obj_index;
142 /* identified by the adapter number/index of the adapters in */ 164 u16 index = 0;
143 /* this HPI */
144 /* i.e. if we have an A120 with it's jumper set to */
145 /* Adapter Number 2 then put an Adapter type A120 in the */
146 /* array in position 1 */
147 /* NOTE: AdapterNumber is 1..N, Index is 0..N-1 */
148
149 /* input: NONE */
150 /* output: wNumAdapters */
151 /* awAdapter[] */
152 /* */
153
154 short i;
155 struct hpi_adapter_obj *pao = NULL;
156
157 HPI_DEBUG_LOG(VERBOSE, "subsys_get_adapters\n");
158 165
159 /* for each adapter, place it's type in the position of the array */ 166 /* find the nCount'th nonzero adapter in array */
160 /* corresponding to it's adapter number */ 167 for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
161 for (i = 0; i < adapters.gw_num_adapters; i++) { 168 if (adapters.adapter[index].adapter_type) {
162 pao = &adapters.adapter[i]; 169 if (!count)
163 if (phr->u.s.aw_adapter_list[pao->index] != 0) { 170 break;
164 phr->error = HPI_DUPLICATE_ADAPTER_NUMBER; 171 count--;
165 phr->specific_error = pao->index;
166 return;
167 } 172 }
168 phr->u.s.aw_adapter_list[pao->index] = pao->adapter_type;
169 } 173 }
170 174
171 phr->u.s.num_adapters = adapters.gw_num_adapters; 175 if (index < HPI_MAX_ADAPTERS) {
172 phr->error = 0; /* the function completed OK; */ 176 phr->u.s.adapter_index = adapters.adapter[index].index;
177 phr->u.s.adapter_type = adapters.adapter[index].adapter_type;
178 } else {
179 phr->u.s.adapter_index = 0;
180 phr->u.s.adapter_type = 0;
181 phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
182 }
173} 183}
174 184
175static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC) 185static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
@@ -178,67 +188,99 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
178 int cached = 0; 188 int cached = 0;
179 if (!pC) 189 if (!pC)
180 return 0; 190 return 0;
181 if ((!pC->init) && (pC->p_cache != NULL) && (pC->control_count) 191
182 && (pC->cache_size_in_bytes) 192 if (pC->init)
183 ) { 193 return pC->init;
184 u32 *p_master_cache; 194
185 pC->init = 1; 195 if (!pC->p_cache)
186 196 return 0;
187 p_master_cache = (u32 *)pC->p_cache; 197
188 HPI_DEBUG_LOG(VERBOSE, "check %d controls\n", 198 if (pC->control_count && pC->cache_size_in_bytes) {
199 char *p_master_cache;
200 unsigned int byte_count = 0;
201
202 p_master_cache = (char *)pC->p_cache;
203 HPI_DEBUG_LOG(DEBUG, "check %d controls\n",
189 pC->control_count); 204 pC->control_count);
190 for (i = 0; i < pC->control_count; i++) { 205 for (i = 0; i < pC->control_count; i++) {
191 struct hpi_control_cache_info *info = 206 struct hpi_control_cache_info *info =
192 (struct hpi_control_cache_info *) 207 (struct hpi_control_cache_info *)
193 p_master_cache; 208 &p_master_cache[byte_count];
209
210 if (!info->size_in32bit_words) {
211 if (!i) {
212 HPI_DEBUG_LOG(INFO,
213 "adap %d cache not ready?\n",
214 pC->adap_idx);
215 return 0;
216 }
217 /* The cache is invalid.
218 * Minimum valid entry size is
219 * sizeof(struct hpi_control_cache_info)
220 */
221 HPI_DEBUG_LOG(ERROR,
222 "adap %d zero size cache entry %d\n",
223 pC->adap_idx, i);
224 break;
225 }
194 226
195 if (info->control_type) { 227 if (info->control_type) {
196 pC->p_info[i] = info; 228 pC->p_info[info->control_index] = info;
197 cached++; 229 cached++;
198 } else 230 } else { /* dummy cache entry */
199 pC->p_info[i] = NULL; 231 pC->p_info[info->control_index] = NULL;
232 }
200 233
201 if (info->size_in32bit_words) 234 byte_count += info->size_in32bit_words * 4;
202 p_master_cache += info->size_in32bit_words;
203 else
204 p_master_cache +=
205 sizeof(struct
206 hpi_control_cache_single) /
207 sizeof(u32);
208 235
209 HPI_DEBUG_LOG(VERBOSE, 236 HPI_DEBUG_LOG(VERBOSE,
210 "cached %d, pinfo %p index %d type %d\n", 237 "cached %d, pinfo %p index %d type %d size %d\n",
211 cached, pC->p_info[i], info->control_index, 238 cached, pC->p_info[info->control_index],
212 info->control_type); 239 info->control_index, info->control_type,
240 info->size_in32bit_words);
241
242 /* quit loop early if whole cache has been scanned.
243 * dwControlCount is the maximum possible entries
244 * but some may be absent from the cache
245 */
246 if (byte_count >= pC->cache_size_in_bytes)
247 break;
248 /* have seen last control index */
249 if (info->control_index == pC->control_count - 1)
250 break;
213 } 251 }
214 /* 252
215 We didn't find anything to cache, so try again later ! 253 if (byte_count != pC->cache_size_in_bytes)
216 */ 254 HPI_DEBUG_LOG(WARNING,
217 if (!cached) 255 "adap %d bytecount %d != cache size %d\n",
218 pC->init = 0; 256 pC->adap_idx, byte_count,
257 pC->cache_size_in_bytes);
258 else
259 HPI_DEBUG_LOG(DEBUG,
260 "adap %d cache good, bytecount == cache size = %d\n",
261 pC->adap_idx, byte_count);
262
263 pC->init = (u16)cached;
219 } 264 }
220 return pC->init; 265 return pC->init;
221} 266}
222 267
223/** Find a control. 268/** Find a control.
224*/ 269*/
225static short find_control(struct hpi_message *phm, 270static short find_control(u16 control_index,
226 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI, 271 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
227 u16 *pw_control_index)
228{ 272{
229 *pw_control_index = phm->obj_index;
230
231 if (!control_cache_alloc_check(p_cache)) { 273 if (!control_cache_alloc_check(p_cache)) {
232 HPI_DEBUG_LOG(VERBOSE, 274 HPI_DEBUG_LOG(VERBOSE,
233 "control_cache_alloc_check() failed. adap%d ci%d\n", 275 "control_cache_alloc_check() failed %d\n",
234 phm->adapter_index, *pw_control_index); 276 control_index);
235 return 0; 277 return 0;
236 } 278 }
237 279
238 *pI = p_cache->p_info[*pw_control_index]; 280 *pI = p_cache->p_info[control_index];
239 if (!*pI) { 281 if (!*pI) {
240 HPI_DEBUG_LOG(VERBOSE, "uncached adap %d, control %d\n", 282 HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
241 phm->adapter_index, *pw_control_index); 283 control_index);
242 return 0; 284 return 0;
243 } else { 285 } else {
244 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n", 286 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
@@ -247,25 +289,6 @@ static short find_control(struct hpi_message *phm,
247 return 1; 289 return 1;
248} 290}
249 291
250/** Used by the kernel driver to figure out if a buffer needs mapping.
251 */
252short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
253 struct hpi_message *phm, void **p, unsigned int *pN)
254{
255 *pN = 0;
256 *p = NULL;
257 if ((phm->function == HPI_CONTROL_GET_STATE)
258 && (phm->object == HPI_OBJ_CONTROLEX)
259 ) {
260 u16 control_index;
261 struct hpi_control_cache_info *pI;
262
263 if (!find_control(phm, p_cache, &pI, &control_index))
264 return 0;
265 }
266 return 0;
267}
268
269/* allow unified treatment of several string fields within struct */ 292/* allow unified treatment of several string fields within struct */
270#define HPICMN_PAD_OFS_AND_SIZE(m) {\ 293#define HPICMN_PAD_OFS_AND_SIZE(m) {\
271 offsetof(struct hpi_control_cache_pad, m), \ 294 offsetof(struct hpi_control_cache_pad, m), \
@@ -276,7 +299,7 @@ struct pad_ofs_size {
276 unsigned int field_size; 299 unsigned int field_size;
277}; 300};
278 301
279static struct pad_ofs_size pad_desc[] = { 302static const struct pad_ofs_size pad_desc[] = {
280 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */ 303 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
281 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */ 304 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */
282 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */ 305 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */
@@ -290,13 +313,16 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
290 struct hpi_message *phm, struct hpi_response *phr) 313 struct hpi_message *phm, struct hpi_response *phr)
291{ 314{
292 short found = 1; 315 short found = 1;
293 u16 control_index;
294 struct hpi_control_cache_info *pI; 316 struct hpi_control_cache_info *pI;
295 struct hpi_control_cache_single *pC; 317 struct hpi_control_cache_single *pC;
296 struct hpi_control_cache_pad *p_pad; 318 struct hpi_control_cache_pad *p_pad;
297 319
298 if (!find_control(phm, p_cache, &pI, &control_index)) 320 if (!find_control(phm->obj_index, p_cache, &pI)) {
321 HPI_DEBUG_LOG(VERBOSE,
322 "HPICMN find_control() failed for adap %d\n",
323 phm->adapter_index);
299 return 0; 324 return 0;
325 }
300 326
301 phr->error = 0; 327 phr->error = 0;
302 328
@@ -310,55 +336,79 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
310 336
311 case HPI_CONTROL_METER: 337 case HPI_CONTROL_METER:
312 if (phm->u.c.attribute == HPI_METER_PEAK) { 338 if (phm->u.c.attribute == HPI_METER_PEAK) {
313 phr->u.c.an_log_value[0] = pC->u.p.an_log_peak[0]; 339 phr->u.c.an_log_value[0] = pC->u.meter.an_log_peak[0];
314 phr->u.c.an_log_value[1] = pC->u.p.an_log_peak[1]; 340 phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1];
315 } else if (phm->u.c.attribute == HPI_METER_RMS) { 341 } else if (phm->u.c.attribute == HPI_METER_RMS) {
316 phr->u.c.an_log_value[0] = pC->u.p.an_logRMS[0]; 342 if (pC->u.meter.an_logRMS[0] ==
317 phr->u.c.an_log_value[1] = pC->u.p.an_logRMS[1]; 343 HPI_CACHE_INVALID_SHORT) {
344 phr->error =
345 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
346 phr->u.c.an_log_value[0] = HPI_METER_MINIMUM;
347 phr->u.c.an_log_value[1] = HPI_METER_MINIMUM;
348 } else {
349 phr->u.c.an_log_value[0] =
350 pC->u.meter.an_logRMS[0];
351 phr->u.c.an_log_value[1] =
352 pC->u.meter.an_logRMS[1];
353 }
318 } else 354 } else
319 found = 0; 355 found = 0;
320 break; 356 break;
321 case HPI_CONTROL_VOLUME: 357 case HPI_CONTROL_VOLUME:
322 if (phm->u.c.attribute == HPI_VOLUME_GAIN) { 358 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
323 phr->u.c.an_log_value[0] = pC->u.v.an_log[0]; 359 phr->u.c.an_log_value[0] = pC->u.vol.an_log[0];
324 phr->u.c.an_log_value[1] = pC->u.v.an_log[1]; 360 phr->u.c.an_log_value[1] = pC->u.vol.an_log[1];
325 } else 361 } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
362 if (pC->u.vol.flags & HPI_VOLUME_FLAG_HAS_MUTE) {
363 if (pC->u.vol.flags & HPI_VOLUME_FLAG_MUTED)
364 phr->u.c.param1 =
365 HPI_BITMASK_ALL_CHANNELS;
366 else
367 phr->u.c.param1 = 0;
368 } else {
369 phr->error =
370 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
371 phr->u.c.param1 = 0;
372 }
373 } else {
326 found = 0; 374 found = 0;
375 }
327 break; 376 break;
328 case HPI_CONTROL_MULTIPLEXER: 377 case HPI_CONTROL_MULTIPLEXER:
329 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { 378 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
330 phr->u.c.param1 = pC->u.x.source_node_type; 379 phr->u.c.param1 = pC->u.mux.source_node_type;
331 phr->u.c.param2 = pC->u.x.source_node_index; 380 phr->u.c.param2 = pC->u.mux.source_node_index;
332 } else { 381 } else {
333 found = 0; 382 found = 0;
334 } 383 }
335 break; 384 break;
336 case HPI_CONTROL_CHANNEL_MODE: 385 case HPI_CONTROL_CHANNEL_MODE:
337 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) 386 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
338 phr->u.c.param1 = pC->u.m.mode; 387 phr->u.c.param1 = pC->u.mode.mode;
339 else 388 else
340 found = 0; 389 found = 0;
341 break; 390 break;
342 case HPI_CONTROL_LEVEL: 391 case HPI_CONTROL_LEVEL:
343 if (phm->u.c.attribute == HPI_LEVEL_GAIN) { 392 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
344 phr->u.c.an_log_value[0] = pC->u.l.an_log[0]; 393 phr->u.c.an_log_value[0] = pC->u.level.an_log[0];
345 phr->u.c.an_log_value[1] = pC->u.l.an_log[1]; 394 phr->u.c.an_log_value[1] = pC->u.level.an_log[1];
346 } else 395 } else
347 found = 0; 396 found = 0;
348 break; 397 break;
349 case HPI_CONTROL_TUNER: 398 case HPI_CONTROL_TUNER:
350 if (phm->u.c.attribute == HPI_TUNER_FREQ) 399 if (phm->u.c.attribute == HPI_TUNER_FREQ)
351 phr->u.c.param1 = pC->u.t.freq_ink_hz; 400 phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
352 else if (phm->u.c.attribute == HPI_TUNER_BAND) 401 else if (phm->u.c.attribute == HPI_TUNER_BAND)
353 phr->u.c.param1 = pC->u.t.band; 402 phr->u.c.param1 = pC->u.tuner.band;
354 else if ((phm->u.c.attribute == HPI_TUNER_LEVEL) 403 else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG)
355 && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE)) 404 if (pC->u.tuner.s_level_avg ==
356 if (pC->u.t.level == HPI_ERROR_ILLEGAL_CACHE_VALUE) { 405 HPI_CACHE_INVALID_SHORT) {
357 phr->u.c.param1 = 0; 406 phr->u.cu.tuner.s_level = 0;
358 phr->error = 407 phr->error =
359 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; 408 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
360 } else 409 } else
361 phr->u.c.param1 = pC->u.t.level; 410 phr->u.cu.tuner.s_level =
411 pC->u.tuner.s_level_avg;
362 else 412 else
363 found = 0; 413 found = 0;
364 break; 414 break;
@@ -366,7 +416,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
366 if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS) 416 if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
367 phr->u.c.param1 = pC->u.aes3rx.error_status; 417 phr->u.c.param1 = pC->u.aes3rx.error_status;
368 else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) 418 else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
369 phr->u.c.param1 = pC->u.aes3rx.source; 419 phr->u.c.param1 = pC->u.aes3rx.format;
370 else 420 else
371 found = 0; 421 found = 0;
372 break; 422 break;
@@ -385,13 +435,12 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
385 case HPI_CONTROL_SILENCEDETECTOR: 435 case HPI_CONTROL_SILENCEDETECTOR:
386 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) { 436 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
387 phr->u.c.param1 = pC->u.silence.state; 437 phr->u.c.param1 = pC->u.silence.state;
388 phr->u.c.param2 = pC->u.silence.count;
389 } else 438 } else
390 found = 0; 439 found = 0;
391 break; 440 break;
392 case HPI_CONTROL_MICROPHONE: 441 case HPI_CONTROL_MICROPHONE:
393 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER) 442 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
394 phr->u.c.param1 = pC->u.phantom_power.state; 443 phr->u.c.param1 = pC->u.microphone.phantom_state;
395 else 444 else
396 found = 0; 445 found = 0;
397 break; 446 break;
@@ -400,7 +449,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
400 phr->u.c.param1 = pC->u.clk.source; 449 phr->u.c.param1 = pC->u.clk.source;
401 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) { 450 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
402 if (pC->u.clk.source_index == 451 if (pC->u.clk.source_index ==
403 HPI_ERROR_ILLEGAL_CACHE_VALUE) { 452 HPI_CACHE_INVALID_UINT16) {
404 phr->u.c.param1 = 0; 453 phr->u.c.param1 = 0;
405 phr->error = 454 phr->error =
406 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; 455 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
@@ -411,60 +460,63 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
411 else 460 else
412 found = 0; 461 found = 0;
413 break; 462 break;
414 case HPI_CONTROL_PAD: 463 case HPI_CONTROL_PAD:{
415 464 struct hpi_control_cache_pad *p_pad;
416 if (!(p_pad->field_valid_flags & (1 << 465 p_pad = (struct hpi_control_cache_pad *)pI;
417 HPI_CTL_ATTR_INDEX(phm->u.c.
418 attribute)))) {
419 phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
420 break;
421 }
422 466
423 if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID) 467 if (!(p_pad->field_valid_flags & (1 <<
424 phr->u.c.param1 = p_pad->pI; 468 HPI_CTL_ATTR_INDEX(phm->u.c.
425 else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE) 469 attribute)))) {
426 phr->u.c.param1 = p_pad->pTY;
427 else {
428 unsigned int index =
429 HPI_CTL_ATTR_INDEX(phm->u.c.attribute) - 1;
430 unsigned int offset = phm->u.c.param1;
431 unsigned int pad_string_len, field_size;
432 char *pad_string;
433 unsigned int tocopy;
434
435 HPI_DEBUG_LOG(VERBOSE, "PADS HPI_PADS_ %d\n",
436 phm->u.c.attribute);
437
438 if (index > ARRAY_SIZE(pad_desc) - 1) {
439 phr->error = 470 phr->error =
440 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; 471 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
441 break; 472 break;
442 } 473 }
443 474
444 pad_string = ((char *)p_pad) + pad_desc[index].offset; 475 if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
445 field_size = pad_desc[index].field_size; 476 phr->u.c.param1 = p_pad->pI;
446 /* Ensure null terminator */ 477 else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
447 pad_string[field_size - 1] = 0; 478 phr->u.c.param1 = p_pad->pTY;
448 479 else {
449 pad_string_len = strlen(pad_string) + 1; 480 unsigned int index =
450 481 HPI_CTL_ATTR_INDEX(phm->u.c.
451 if (offset > pad_string_len) { 482 attribute) - 1;
452 phr->error = HPI_ERROR_INVALID_CONTROL_VALUE; 483 unsigned int offset = phm->u.c.param1;
453 break; 484 unsigned int pad_string_len, field_size;
485 char *pad_string;
486 unsigned int tocopy;
487
488 if (index > ARRAY_SIZE(pad_desc) - 1) {
489 phr->error =
490 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
491 break;
492 }
493
494 pad_string =
495 ((char *)p_pad) +
496 pad_desc[index].offset;
497 field_size = pad_desc[index].field_size;
498 /* Ensure null terminator */
499 pad_string[field_size - 1] = 0;
500
501 pad_string_len = strlen(pad_string) + 1;
502
503 if (offset > pad_string_len) {
504 phr->error =
505 HPI_ERROR_INVALID_CONTROL_VALUE;
506 break;
507 }
508
509 tocopy = pad_string_len - offset;
510 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
511 tocopy = sizeof(phr->u.cu.chars8.
512 sz_data);
513
514 memcpy(phr->u.cu.chars8.sz_data,
515 &pad_string[offset], tocopy);
516
517 phr->u.cu.chars8.remaining_chars =
518 pad_string_len - offset - tocopy;
454 } 519 }
455
456 tocopy = pad_string_len - offset;
457 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
458 tocopy = sizeof(phr->u.cu.chars8.sz_data);
459
460 HPI_DEBUG_LOG(VERBOSE,
461 "PADS memcpy(%d), offset %d \n", tocopy,
462 offset);
463 memcpy(phr->u.cu.chars8.sz_data, &pad_string[offset],
464 tocopy);
465
466 phr->u.cu.chars8.remaining_chars =
467 pad_string_len - offset - tocopy;
468 } 520 }
469 break; 521 break;
470 default: 522 default:
@@ -472,16 +524,9 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
472 break; 524 break;
473 } 525 }
474 526
475 if (found) 527 HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
476 HPI_DEBUG_LOG(VERBOSE, 528 found ? "Cached" : "Uncached", phm->adapter_index,
477 "cached adap %d, ctl %d, type %d, attr %d\n", 529 pI->control_index, pI->control_type, phm->u.c.attribute);
478 phm->adapter_index, pI->control_index,
479 pI->control_type, phm->u.c.attribute);
480 else
481 HPI_DEBUG_LOG(VERBOSE,
482 "uncached adap %d, ctl %d, ctl type %d\n",
483 phm->adapter_index, pI->control_index,
484 pI->control_type);
485 530
486 if (found) 531 if (found)
487 phr->size = 532 phr->size =
@@ -497,18 +542,21 @@ Only update if no error.
497Volume and Level return the limited values in the response, so use these 542Volume and Level return the limited values in the response, so use these
498Multiplexer does so use sent values 543Multiplexer does so use sent values
499*/ 544*/
500void hpi_sync_control_cache(struct hpi_control_cache *p_cache, 545void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
501 struct hpi_message *phm, struct hpi_response *phr) 546 struct hpi_message *phm, struct hpi_response *phr)
502{ 547{
503 u16 control_index;
504 struct hpi_control_cache_single *pC; 548 struct hpi_control_cache_single *pC;
505 struct hpi_control_cache_info *pI; 549 struct hpi_control_cache_info *pI;
506 550
507 if (phr->error) 551 if (phr->error)
508 return; 552 return;
509 553
510 if (!find_control(phm, p_cache, &pI, &control_index)) 554 if (!find_control(phm->obj_index, p_cache, &pI)) {
555 HPI_DEBUG_LOG(VERBOSE,
556 "HPICMN find_control() failed for adap %d\n",
557 phm->adapter_index);
511 return; 558 return;
559 }
512 560
513 /* pC is the default cached control strucure. 561 /* pC is the default cached control strucure.
514 May be cast to something else in the following switch statement. 562 May be cast to something else in the following switch statement.
@@ -518,31 +566,36 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
518 switch (pI->control_type) { 566 switch (pI->control_type) {
519 case HPI_CONTROL_VOLUME: 567 case HPI_CONTROL_VOLUME:
520 if (phm->u.c.attribute == HPI_VOLUME_GAIN) { 568 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
521 pC->u.v.an_log[0] = phr->u.c.an_log_value[0]; 569 pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
522 pC->u.v.an_log[1] = phr->u.c.an_log_value[1]; 570 pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
571 } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
572 if (phm->u.c.param1)
573 pC->u.vol.flags |= HPI_VOLUME_FLAG_MUTED;
574 else
575 pC->u.vol.flags &= ~HPI_VOLUME_FLAG_MUTED;
523 } 576 }
524 break; 577 break;
525 case HPI_CONTROL_MULTIPLEXER: 578 case HPI_CONTROL_MULTIPLEXER:
526 /* mux does not return its setting on Set command. */ 579 /* mux does not return its setting on Set command. */
527 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { 580 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
528 pC->u.x.source_node_type = (u16)phm->u.c.param1; 581 pC->u.mux.source_node_type = (u16)phm->u.c.param1;
529 pC->u.x.source_node_index = (u16)phm->u.c.param2; 582 pC->u.mux.source_node_index = (u16)phm->u.c.param2;
530 } 583 }
531 break; 584 break;
532 case HPI_CONTROL_CHANNEL_MODE: 585 case HPI_CONTROL_CHANNEL_MODE:
533 /* mode does not return its setting on Set command. */ 586 /* mode does not return its setting on Set command. */
534 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) 587 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
535 pC->u.m.mode = (u16)phm->u.c.param1; 588 pC->u.mode.mode = (u16)phm->u.c.param1;
536 break; 589 break;
537 case HPI_CONTROL_LEVEL: 590 case HPI_CONTROL_LEVEL:
538 if (phm->u.c.attribute == HPI_LEVEL_GAIN) { 591 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
539 pC->u.v.an_log[0] = phr->u.c.an_log_value[0]; 592 pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
540 pC->u.v.an_log[1] = phr->u.c.an_log_value[1]; 593 pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
541 } 594 }
542 break; 595 break;
543 case HPI_CONTROL_MICROPHONE: 596 case HPI_CONTROL_MICROPHONE:
544 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER) 597 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
545 pC->u.phantom_power.state = (u16)phm->u.c.param1; 598 pC->u.microphone.phantom_state = (u16)phm->u.c.param1;
546 break; 599 break;
547 case HPI_CONTROL_AESEBU_TRANSMITTER: 600 case HPI_CONTROL_AESEBU_TRANSMITTER:
548 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT) 601 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
@@ -550,7 +603,7 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
550 break; 603 break;
551 case HPI_CONTROL_AESEBU_RECEIVER: 604 case HPI_CONTROL_AESEBU_RECEIVER:
552 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) 605 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
553 pC->u.aes3rx.source = phm->u.c.param1; 606 pC->u.aes3rx.format = phm->u.c.param1;
554 break; 607 break;
555 case HPI_CONTROL_SAMPLECLOCK: 608 case HPI_CONTROL_SAMPLECLOCK:
556 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE) 609 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
@@ -565,53 +618,60 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
565 } 618 }
566} 619}
567 620
568struct hpi_control_cache *hpi_alloc_control_cache(const u32 621/** Allocate control cache.
569 number_of_controls, const u32 size_in_bytes, 622
570 struct hpi_control_cache_info *pDSP_control_buffer) 623\return Cache pointer, or NULL if allocation fails.
624*/
625struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
626 const u32 size_in_bytes, u8 *p_dsp_control_buffer)
571{ 627{
572 struct hpi_control_cache *p_cache = 628 struct hpi_control_cache *p_cache =
573 kmalloc(sizeof(*p_cache), GFP_KERNEL); 629 kmalloc(sizeof(*p_cache), GFP_KERNEL);
630 if (!p_cache)
631 return NULL;
632
633 p_cache->p_info =
634 kmalloc(sizeof(*p_cache->p_info) * control_count, GFP_KERNEL);
635 if (!p_cache->p_info) {
636 kfree(p_cache);
637 return NULL;
638 }
639 memset(p_cache->p_info, 0, sizeof(*p_cache->p_info) * control_count);
574 p_cache->cache_size_in_bytes = size_in_bytes; 640 p_cache->cache_size_in_bytes = size_in_bytes;
575 p_cache->control_count = number_of_controls; 641 p_cache->control_count = control_count;
576 p_cache->p_cache = 642 p_cache->p_cache = p_dsp_control_buffer;
577 (struct hpi_control_cache_single *)pDSP_control_buffer;
578 p_cache->init = 0; 643 p_cache->init = 0;
579 p_cache->p_info =
580 kmalloc(sizeof(*p_cache->p_info) * p_cache->control_count,
581 GFP_KERNEL);
582 return p_cache; 644 return p_cache;
583} 645}
584 646
585void hpi_free_control_cache(struct hpi_control_cache *p_cache) 647void hpi_free_control_cache(struct hpi_control_cache *p_cache)
586{ 648{
587 if (p_cache->init) { 649 if (p_cache) {
588 kfree(p_cache->p_info); 650 kfree(p_cache->p_info);
589 p_cache->p_info = NULL;
590 p_cache->init = 0;
591 kfree(p_cache); 651 kfree(p_cache);
592 } 652 }
593} 653}
594 654
595static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) 655static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
596{ 656{
657 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
597 658
598 switch (phm->function) { 659 switch (phm->function) {
599 case HPI_SUBSYS_OPEN: 660 case HPI_SUBSYS_OPEN:
600 case HPI_SUBSYS_CLOSE: 661 case HPI_SUBSYS_CLOSE:
601 case HPI_SUBSYS_DRIVER_UNLOAD: 662 case HPI_SUBSYS_DRIVER_UNLOAD:
602 phr->error = 0;
603 break; 663 break;
604 case HPI_SUBSYS_DRIVER_LOAD: 664 case HPI_SUBSYS_DRIVER_LOAD:
605 wipe_adapter_list(); 665 wipe_adapter_list();
606 hpios_alistlock_init(&adapters); 666 hpios_alistlock_init(&adapters);
607 phr->error = 0;
608 break; 667 break;
609 case HPI_SUBSYS_GET_INFO: 668 case HPI_SUBSYS_GET_ADAPTER:
610 subsys_get_adapters(phr); 669 subsys_get_adapter(phm, phr);
670 break;
671 case HPI_SUBSYS_GET_NUM_ADAPTERS:
672 phr->u.s.num_adapters = adapters.gw_num_adapters;
611 break; 673 break;
612 case HPI_SUBSYS_CREATE_ADAPTER: 674 case HPI_SUBSYS_CREATE_ADAPTER:
613 case HPI_SUBSYS_DELETE_ADAPTER:
614 phr->error = 0;
615 break; 675 break;
616 default: 676 default:
617 phr->error = HPI_ERROR_INVALID_FUNC; 677 phr->error = HPI_ERROR_INVALID_FUNC;
diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h
index 6229022f56cb..d53cdf6e535f 100644
--- a/sound/pci/asihpi/hpicmn.h
+++ b/sound/pci/asihpi/hpicmn.h
@@ -33,18 +33,19 @@ struct hpi_adapter_obj {
33}; 33};
34 34
35struct hpi_control_cache { 35struct hpi_control_cache {
36 u32 init; /**< indicates whether the 36 /** indicates whether the structures are initialized */
37 structures are initialized */ 37 u16 init;
38 u16 adap_idx;
38 u32 control_count; 39 u32 control_count;
39 u32 cache_size_in_bytes; 40 u32 cache_size_in_bytes;
40 struct hpi_control_cache_info 41 /** pointer to allocated memory of lookup pointers. */
41 **p_info; /**< pointer to allocated memory of 42 struct hpi_control_cache_info **p_info;
42 lookup pointers. */ 43 /** pointer to DSP's control cache. */
43 struct hpi_control_cache_single 44 u8 *p_cache;
44 *p_cache; /**< pointer to DSP's control cache. */
45}; 45};
46 46
47struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index); 47struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index);
48
48u16 hpi_add_adapter(struct hpi_adapter_obj *pao); 49u16 hpi_add_adapter(struct hpi_adapter_obj *pao);
49 50
50void hpi_delete_adapter(struct hpi_adapter_obj *pao); 51void hpi_delete_adapter(struct hpi_adapter_obj *pao);
@@ -52,13 +53,12 @@ void hpi_delete_adapter(struct hpi_adapter_obj *pao);
52short hpi_check_control_cache(struct hpi_control_cache *pC, 53short hpi_check_control_cache(struct hpi_control_cache *pC,
53 struct hpi_message *phm, struct hpi_response *phr); 54 struct hpi_message *phm, struct hpi_response *phr);
54struct hpi_control_cache *hpi_alloc_control_cache(const u32 55struct hpi_control_cache *hpi_alloc_control_cache(const u32
55 number_of_controls, const u32 size_in_bytes, 56 number_of_controls, const u32 size_in_bytes, u8 *pDSP_control_buffer);
56 struct hpi_control_cache_info
57 *pDSP_control_buffer);
58void hpi_free_control_cache(struct hpi_control_cache *p_cache); 57void hpi_free_control_cache(struct hpi_control_cache *p_cache);
59 58
60void hpi_sync_control_cache(struct hpi_control_cache *pC, 59void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *pC,
61 struct hpi_message *phm, struct hpi_response *phr); 60 struct hpi_message *phm, struct hpi_response *phr);
61
62u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr); 62u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr);
63short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache, 63
64 struct hpi_message *phm, void **p, unsigned int *pN); 64hpi_handler_func HPI_COMMON;
diff --git a/sound/pci/asihpi/hpidebug.c b/sound/pci/asihpi/hpidebug.c
index 949836ec913a..b52baf62791e 100644
--- a/sound/pci/asihpi/hpidebug.c
+++ b/sound/pci/asihpi/hpidebug.c
@@ -45,161 +45,14 @@ int hpi_debug_level_get(void)
45 return hpi_debug_level; 45 return hpi_debug_level;
46} 46}
47 47
48#ifdef HPIOS_DEBUG_PRINT
49/* implies OS has no printf-like function */
50#include <stdarg.h>
51
52void hpi_debug_printf(char *fmt, ...)
53{
54 va_list arglist;
55 char buffer[128];
56
57 va_start(arglist, fmt);
58
59 if (buffer[0])
60 HPIOS_DEBUG_PRINT(buffer);
61 va_end(arglist);
62}
63#endif
64
65struct treenode {
66 void *array;
67 unsigned int num_elements;
68};
69
70#define make_treenode_from_array(nodename, array) \
71static void *tmp_strarray_##nodename[] = array; \
72static struct treenode nodename = { \
73 &tmp_strarray_##nodename, \
74 ARRAY_SIZE(tmp_strarray_##nodename) \
75};
76
77#define get_treenode_elem(node_ptr, idx, type) \
78 (&(*((type *)(node_ptr)->array)[idx]))
79
80make_treenode_from_array(hpi_control_type_strings, HPI_CONTROL_TYPE_STRINGS)
81
82 make_treenode_from_array(hpi_subsys_strings, HPI_SUBSYS_STRINGS)
83 make_treenode_from_array(hpi_adapter_strings, HPI_ADAPTER_STRINGS)
84 make_treenode_from_array(hpi_istream_strings, HPI_ISTREAM_STRINGS)
85 make_treenode_from_array(hpi_ostream_strings, HPI_OSTREAM_STRINGS)
86 make_treenode_from_array(hpi_mixer_strings, HPI_MIXER_STRINGS)
87 make_treenode_from_array(hpi_node_strings,
88 {
89 "NODE is invalid object"})
90
91 make_treenode_from_array(hpi_control_strings, HPI_CONTROL_STRINGS)
92 make_treenode_from_array(hpi_nvmemory_strings, HPI_OBJ_STRINGS)
93 make_treenode_from_array(hpi_digitalio_strings, HPI_DIGITALIO_STRINGS)
94 make_treenode_from_array(hpi_watchdog_strings, HPI_WATCHDOG_STRINGS)
95 make_treenode_from_array(hpi_clock_strings, HPI_CLOCK_STRINGS)
96 make_treenode_from_array(hpi_profile_strings, HPI_PROFILE_STRINGS)
97 make_treenode_from_array(hpi_asyncevent_strings, HPI_ASYNCEVENT_STRINGS)
98#define HPI_FUNCTION_STRINGS \
99{ \
100 &hpi_subsys_strings,\
101 &hpi_adapter_strings,\
102 &hpi_ostream_strings,\
103 &hpi_istream_strings,\
104 &hpi_mixer_strings,\
105 &hpi_node_strings,\
106 &hpi_control_strings,\
107 &hpi_nvmemory_strings,\
108 &hpi_digitalio_strings,\
109 &hpi_watchdog_strings,\
110 &hpi_clock_strings,\
111 &hpi_profile_strings,\
112 &hpi_control_strings, \
113 &hpi_asyncevent_strings \
114}
115 make_treenode_from_array(hpi_function_strings, HPI_FUNCTION_STRINGS)
116
117 compile_time_assert(HPI_OBJ_MAXINDEX == 14, obj_list_doesnt_match);
118
119static char *hpi_function_string(unsigned int function)
120{
121 unsigned int object;
122 struct treenode *tmp;
123
124 object = function / HPI_OBJ_FUNCTION_SPACING;
125 function = function - object * HPI_OBJ_FUNCTION_SPACING;
126
127 if (object == 0 || object == HPI_OBJ_NODE
128 || object > hpi_function_strings.num_elements)
129 return "invalid object";
130
131 tmp = get_treenode_elem(&hpi_function_strings, object - 1,
132 struct treenode *);
133
134 if (function == 0 || function > tmp->num_elements)
135 return "invalid function";
136
137 return get_treenode_elem(tmp, function - 1, char *);
138}
139
140void hpi_debug_message(struct hpi_message *phm, char *sz_fileline) 48void hpi_debug_message(struct hpi_message *phm, char *sz_fileline)
141{ 49{
142 if (phm) { 50 if (phm) {
143 if ((phm->object <= HPI_OBJ_MAXINDEX) && phm->object) { 51 printk(KERN_DEBUG "HPI_MSG%d,%d,%d,%d,%d\n", phm->version,
144 u16 index = 0; 52 phm->adapter_index, phm->obj_index, phm->function,
145 u16 attrib = 0; 53 phm->u.c.attribute);
146 int is_control = 0; 54 }
147 55
148 index = phm->obj_index;
149 switch (phm->object) {
150 case HPI_OBJ_ADAPTER:
151 case HPI_OBJ_PROFILE:
152 break;
153 case HPI_OBJ_MIXER:
154 if (phm->function ==
155 HPI_MIXER_GET_CONTROL_BY_INDEX)
156 index = phm->u.m.control_index;
157 break;
158 case HPI_OBJ_OSTREAM:
159 case HPI_OBJ_ISTREAM:
160 break;
161
162 case HPI_OBJ_CONTROLEX:
163 case HPI_OBJ_CONTROL:
164 if (phm->version == 1)
165 attrib = HPI_CTL_ATTR(UNIVERSAL, 1);
166 else
167 attrib = phm->u.c.attribute;
168 is_control = 1;
169 break;
170 default:
171 break;
172 }
173
174 if (is_control && (attrib & 0xFF00)) {
175 int control_type = (attrib & 0xFF00) >> 8;
176 int attr_index = HPI_CTL_ATTR_INDEX(attrib);
177 /* note the KERN facility level
178 is in szFileline already */
179 printk("%s adapter %d %s "
180 "ctrl_index x%04x %s %d\n",
181 sz_fileline, phm->adapter_index,
182 hpi_function_string(phm->function),
183 index,
184 get_treenode_elem
185 (&hpi_control_type_strings,
186 control_type, char *),
187 attr_index);
188
189 } else
190 printk("%s adapter %d %s "
191 "idx x%04x attr x%04x \n",
192 sz_fileline, phm->adapter_index,
193 hpi_function_string(phm->function),
194 index, attrib);
195 } else {
196 printk("adap=%d, invalid obj=%d, func=0x%x\n",
197 phm->adapter_index, phm->object,
198 phm->function);
199 }
200 } else
201 printk(KERN_ERR
202 "NULL message pointer to hpi_debug_message!\n");
203} 56}
204 57
205void hpi_debug_data(u16 *pdata, u32 len) 58void hpi_debug_data(u16 *pdata, u32 len)
diff --git a/sound/pci/asihpi/hpidebug.h b/sound/pci/asihpi/hpidebug.h
index a2f0952a99f0..940f54c3c538 100644
--- a/sound/pci/asihpi/hpidebug.h
+++ b/sound/pci/asihpi/hpidebug.h
@@ -37,7 +37,7 @@ enum { HPI_DEBUG_LEVEL_ERROR = 0, /* always log errors */
37#define HPI_DEBUG_LEVEL_DEFAULT HPI_DEBUG_LEVEL_NOTICE 37#define HPI_DEBUG_LEVEL_DEFAULT HPI_DEBUG_LEVEL_NOTICE
38 38
39/* an OS can define an extra flag string that is appended to 39/* an OS can define an extra flag string that is appended to
40 the start of each message, eg see hpios_linux.h */ 40 the start of each message, eg see linux kernel hpios.h */
41 41
42#ifdef SOURCEFILE_NAME 42#ifdef SOURCEFILE_NAME
43#define FILE_LINE SOURCEFILE_NAME ":" __stringify(__LINE__) " " 43#define FILE_LINE SOURCEFILE_NAME ":" __stringify(__LINE__) " "
@@ -45,18 +45,11 @@ enum { HPI_DEBUG_LEVEL_ERROR = 0, /* always log errors */
45#define FILE_LINE __FILE__ ":" __stringify(__LINE__) " " 45#define FILE_LINE __FILE__ ":" __stringify(__LINE__) " "
46#endif 46#endif
47 47
48#if defined(HPI_DEBUG) && defined(_WINDOWS)
49#define HPI_DEBUGBREAK() debug_break()
50#else
51#define HPI_DEBUGBREAK()
52#endif
53
54#define HPI_DEBUG_ASSERT(expression) \ 48#define HPI_DEBUG_ASSERT(expression) \
55 do { \ 49 do { \
56 if (!(expression)) {\ 50 if (!(expression)) { \
57 printk(KERN_ERR FILE_LINE\ 51 printk(KERN_ERR FILE_LINE \
58 "ASSERT " __stringify(expression));\ 52 "ASSERT " __stringify(expression)); \
59 HPI_DEBUGBREAK();\
60 } \ 53 } \
61 } while (0) 54 } while (0)
62 55
@@ -78,28 +71,27 @@ void hpi_debug_message(struct hpi_message *phm, char *sz_fileline);
78 71
79void hpi_debug_data(u16 *pdata, u32 len); 72void hpi_debug_data(u16 *pdata, u32 len);
80 73
81#define HPI_DEBUG_DATA(pdata, len) \ 74#define HPI_DEBUG_DATA(pdata, len) \
82 do { \ 75 do { \
83 if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE) \ 76 if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE) \
84 hpi_debug_data(pdata, len); \ 77 hpi_debug_data(pdata, len); \
85 } while (0) 78 } while (0)
86 79
87#define HPI_DEBUG_MESSAGE(level, phm) \ 80#define HPI_DEBUG_MESSAGE(level, phm) \
88 do { \ 81 do { \
89 if (hpi_debug_level >= HPI_DEBUG_LEVEL_##level) { \ 82 if (hpi_debug_level >= HPI_DEBUG_LEVEL_##level) { \
90 hpi_debug_message(phm,HPI_DEBUG_FLAG_##level \ 83 hpi_debug_message(phm, HPI_DEBUG_FLAG_##level \
91 FILE_LINE __stringify(level));\ 84 FILE_LINE __stringify(level)); \
92 } \ 85 } \
93 } while (0) 86 } while (0)
94 87
95#define HPI_DEBUG_RESPONSE(phr) \ 88#define HPI_DEBUG_RESPONSE(phr) \
96 do { \ 89 do { \
97 if ((hpi_debug_level >= HPI_DEBUG_LEVEL_DEBUG) && (phr->error))\ 90 if (((hpi_debug_level >= HPI_DEBUG_LEVEL_DEBUG) && \
98 HPI_DEBUG_LOG(ERROR, \ 91 (phr->error)) ||\
99 "HPI response - error# %d\n", \ 92 (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE)) \
100 phr->error); \ 93 printk(KERN_DEBUG "HPI_RES%d,%d,%d\n", \
101 else if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE) \ 94 phr->version, phr->error, phr->specific_error); \
102 HPI_DEBUG_LOG(VERBOSE, "HPI response OK\n");\
103 } while (0) 95 } while (0)
104 96
105#ifndef compile_time_assert 97#ifndef compile_time_assert
@@ -107,279 +99,4 @@ void hpi_debug_data(u16 *pdata, u32 len);
107 typedef char msg[(cond) ? 1 : -1] 99 typedef char msg[(cond) ? 1 : -1]
108#endif 100#endif
109 101
110 /* check that size is exactly some number */ 102#endif /* _HPIDEBUG_H_ */
111#define function_count_check(sym, size) \
112 compile_time_assert((sym##_FUNCTION_COUNT) == (size),\
113 strings_match_defs_##sym)
114
115/* These strings should be generated using a macro which defines
116 the corresponding symbol values. */
117#define HPI_OBJ_STRINGS \
118{ \
119 "HPI_OBJ_SUBSYSTEM", \
120 "HPI_OBJ_ADAPTER", \
121 "HPI_OBJ_OSTREAM", \
122 "HPI_OBJ_ISTREAM", \
123 "HPI_OBJ_MIXER", \
124 "HPI_OBJ_NODE", \
125 "HPI_OBJ_CONTROL", \
126 "HPI_OBJ_NVMEMORY", \
127 "HPI_OBJ_DIGITALIO", \
128 "HPI_OBJ_WATCHDOG", \
129 "HPI_OBJ_CLOCK", \
130 "HPI_OBJ_PROFILE", \
131 "HPI_OBJ_CONTROLEX" \
132}
133
134#define HPI_SUBSYS_STRINGS \
135{ \
136 "HPI_SUBSYS_OPEN", \
137 "HPI_SUBSYS_GET_VERSION", \
138 "HPI_SUBSYS_GET_INFO", \
139 "HPI_SUBSYS_FIND_ADAPTERS", \
140 "HPI_SUBSYS_CREATE_ADAPTER",\
141 "HPI_SUBSYS_CLOSE", \
142 "HPI_SUBSYS_DELETE_ADAPTER", \
143 "HPI_SUBSYS_DRIVER_LOAD", \
144 "HPI_SUBSYS_DRIVER_UNLOAD", \
145 "HPI_SUBSYS_READ_PORT_8", \
146 "HPI_SUBSYS_WRITE_PORT_8", \
147 "HPI_SUBSYS_GET_NUM_ADAPTERS",\
148 "HPI_SUBSYS_GET_ADAPTER", \
149 "HPI_SUBSYS_SET_NETWORK_INTERFACE"\
150}
151function_count_check(HPI_SUBSYS, 14);
152
153#define HPI_ADAPTER_STRINGS \
154{ \
155 "HPI_ADAPTER_OPEN", \
156 "HPI_ADAPTER_CLOSE", \
157 "HPI_ADAPTER_GET_INFO", \
158 "HPI_ADAPTER_GET_ASSERT", \
159 "HPI_ADAPTER_TEST_ASSERT", \
160 "HPI_ADAPTER_SET_MODE", \
161 "HPI_ADAPTER_GET_MODE", \
162 "HPI_ADAPTER_ENABLE_CAPABILITY",\
163 "HPI_ADAPTER_SELFTEST", \
164 "HPI_ADAPTER_FIND_OBJECT", \
165 "HPI_ADAPTER_QUERY_FLASH", \
166 "HPI_ADAPTER_START_FLASH", \
167 "HPI_ADAPTER_PROGRAM_FLASH", \
168 "HPI_ADAPTER_SET_PROPERTY", \
169 "HPI_ADAPTER_GET_PROPERTY", \
170 "HPI_ADAPTER_ENUM_PROPERTY", \
171 "HPI_ADAPTER_MODULE_INFO", \
172 "HPI_ADAPTER_DEBUG_READ" \
173}
174
175function_count_check(HPI_ADAPTER, 18);
176
177#define HPI_OSTREAM_STRINGS \
178{ \
179 "HPI_OSTREAM_OPEN", \
180 "HPI_OSTREAM_CLOSE", \
181 "HPI_OSTREAM_WRITE", \
182 "HPI_OSTREAM_START", \
183 "HPI_OSTREAM_STOP", \
184 "HPI_OSTREAM_RESET", \
185 "HPI_OSTREAM_GET_INFO", \
186 "HPI_OSTREAM_QUERY_FORMAT", \
187 "HPI_OSTREAM_DATA", \
188 "HPI_OSTREAM_SET_VELOCITY", \
189 "HPI_OSTREAM_SET_PUNCHINOUT", \
190 "HPI_OSTREAM_SINEGEN", \
191 "HPI_OSTREAM_ANC_RESET", \
192 "HPI_OSTREAM_ANC_GET_INFO", \
193 "HPI_OSTREAM_ANC_READ", \
194 "HPI_OSTREAM_SET_TIMESCALE",\
195 "HPI_OSTREAM_SET_FORMAT", \
196 "HPI_OSTREAM_HOSTBUFFER_ALLOC", \
197 "HPI_OSTREAM_HOSTBUFFER_FREE", \
198 "HPI_OSTREAM_GROUP_ADD",\
199 "HPI_OSTREAM_GROUP_GETMAP", \
200 "HPI_OSTREAM_GROUP_RESET", \
201 "HPI_OSTREAM_HOSTBUFFER_GET_INFO", \
202 "HPI_OSTREAM_WAIT_START", \
203}
204function_count_check(HPI_OSTREAM, 24);
205
206#define HPI_ISTREAM_STRINGS \
207{ \
208 "HPI_ISTREAM_OPEN", \
209 "HPI_ISTREAM_CLOSE", \
210 "HPI_ISTREAM_SET_FORMAT", \
211 "HPI_ISTREAM_READ", \
212 "HPI_ISTREAM_START", \
213 "HPI_ISTREAM_STOP", \
214 "HPI_ISTREAM_RESET", \
215 "HPI_ISTREAM_GET_INFO", \
216 "HPI_ISTREAM_QUERY_FORMAT", \
217 "HPI_ISTREAM_ANC_RESET", \
218 "HPI_ISTREAM_ANC_GET_INFO", \
219 "HPI_ISTREAM_ANC_WRITE", \
220 "HPI_ISTREAM_HOSTBUFFER_ALLOC",\
221 "HPI_ISTREAM_HOSTBUFFER_FREE", \
222 "HPI_ISTREAM_GROUP_ADD", \
223 "HPI_ISTREAM_GROUP_GETMAP", \
224 "HPI_ISTREAM_GROUP_RESET", \
225 "HPI_ISTREAM_HOSTBUFFER_GET_INFO", \
226 "HPI_ISTREAM_WAIT_START", \
227}
228function_count_check(HPI_ISTREAM, 19);
229
230#define HPI_MIXER_STRINGS \
231{ \
232 "HPI_MIXER_OPEN", \
233 "HPI_MIXER_CLOSE", \
234 "HPI_MIXER_GET_INFO", \
235 "HPI_MIXER_GET_NODE_INFO", \
236 "HPI_MIXER_GET_CONTROL", \
237 "HPI_MIXER_SET_CONNECTION", \
238 "HPI_MIXER_GET_CONNECTIONS", \
239 "HPI_MIXER_GET_CONTROL_BY_INDEX", \
240 "HPI_MIXER_GET_CONTROL_ARRAY_BY_INDEX", \
241 "HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES", \
242 "HPI_MIXER_STORE", \
243}
244function_count_check(HPI_MIXER, 11);
245
246#define HPI_CONTROL_STRINGS \
247{ \
248 "HPI_CONTROL_GET_INFO", \
249 "HPI_CONTROL_GET_STATE", \
250 "HPI_CONTROL_SET_STATE" \
251}
252function_count_check(HPI_CONTROL, 3);
253
254#define HPI_NVMEMORY_STRINGS \
255{ \
256 "HPI_NVMEMORY_OPEN", \
257 "HPI_NVMEMORY_READ_BYTE", \
258 "HPI_NVMEMORY_WRITE_BYTE" \
259}
260function_count_check(HPI_NVMEMORY, 3);
261
262#define HPI_DIGITALIO_STRINGS \
263{ \
264 "HPI_GPIO_OPEN", \
265 "HPI_GPIO_READ_BIT", \
266 "HPI_GPIO_WRITE_BIT", \
267 "HPI_GPIO_READ_ALL", \
268 "HPI_GPIO_WRITE_STATUS"\
269}
270function_count_check(HPI_GPIO, 5);
271
272#define HPI_WATCHDOG_STRINGS \
273{ \
274 "HPI_WATCHDOG_OPEN", \
275 "HPI_WATCHDOG_SET_TIME", \
276 "HPI_WATCHDOG_PING" \
277}
278
279#define HPI_CLOCK_STRINGS \
280{ \
281 "HPI_CLOCK_OPEN", \
282 "HPI_CLOCK_SET_TIME", \
283 "HPI_CLOCK_GET_TIME" \
284}
285
286#define HPI_PROFILE_STRINGS \
287{ \
288 "HPI_PROFILE_OPEN_ALL", \
289 "HPI_PROFILE_START_ALL", \
290 "HPI_PROFILE_STOP_ALL", \
291 "HPI_PROFILE_GET", \
292 "HPI_PROFILE_GET_IDLECOUNT", \
293 "HPI_PROFILE_GET_NAME", \
294 "HPI_PROFILE_GET_UTILIZATION" \
295}
296function_count_check(HPI_PROFILE, 7);
297
298#define HPI_ASYNCEVENT_STRINGS \
299{ \
300 "HPI_ASYNCEVENT_OPEN",\
301 "HPI_ASYNCEVENT_CLOSE ",\
302 "HPI_ASYNCEVENT_WAIT",\
303 "HPI_ASYNCEVENT_GETCOUNT",\
304 "HPI_ASYNCEVENT_GET",\
305 "HPI_ASYNCEVENT_SENDEVENTS"\
306}
307function_count_check(HPI_ASYNCEVENT, 6);
308
309#define HPI_CONTROL_TYPE_STRINGS \
310{ \
311 "null control", \
312 "HPI_CONTROL_CONNECTION", \
313 "HPI_CONTROL_VOLUME", \
314 "HPI_CONTROL_METER", \
315 "HPI_CONTROL_MUTE", \
316 "HPI_CONTROL_MULTIPLEXER", \
317 "HPI_CONTROL_AESEBU_TRANSMITTER", \
318 "HPI_CONTROL_AESEBU_RECEIVER", \
319 "HPI_CONTROL_LEVEL", \
320 "HPI_CONTROL_TUNER", \
321 "HPI_CONTROL_ONOFFSWITCH", \
322 "HPI_CONTROL_VOX", \
323 "HPI_CONTROL_AES18_TRANSMITTER", \
324 "HPI_CONTROL_AES18_RECEIVER", \
325 "HPI_CONTROL_AES18_BLOCKGENERATOR", \
326 "HPI_CONTROL_CHANNEL_MODE", \
327 "HPI_CONTROL_BITSTREAM", \
328 "HPI_CONTROL_SAMPLECLOCK", \
329 "HPI_CONTROL_MICROPHONE", \
330 "HPI_CONTROL_PARAMETRIC_EQ", \
331 "HPI_CONTROL_COMPANDER", \
332 "HPI_CONTROL_COBRANET", \
333 "HPI_CONTROL_TONE_DETECT", \
334 "HPI_CONTROL_SILENCE_DETECT", \
335 "HPI_CONTROL_PAD", \
336 "HPI_CONTROL_SRC" ,\
337 "HPI_CONTROL_UNIVERSAL" \
338}
339
340compile_time_assert((HPI_CONTROL_LAST_INDEX + 1 == 27),
341 controltype_strings_match_defs);
342
343#define HPI_SOURCENODE_STRINGS \
344{ \
345 "no source", \
346 "HPI_SOURCENODE_OSTREAM", \
347 "HPI_SOURCENODE_LINEIN", \
348 "HPI_SOURCENODE_AESEBU_IN", \
349 "HPI_SOURCENODE_TUNER", \
350 "HPI_SOURCENODE_RF", \
351 "HPI_SOURCENODE_CLOCK_SOURCE", \
352 "HPI_SOURCENODE_RAW_BITSTREAM", \
353 "HPI_SOURCENODE_MICROPHONE", \
354 "HPI_SOURCENODE_COBRANET", \
355 "HPI_SOURCENODE_ANALOG", \
356 "HPI_SOURCENODE_ADAPTER" \
357}
358
359compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_NONE + 1) ==
360 (12), sourcenode_strings_match_defs);
361
362#define HPI_DESTNODE_STRINGS \
363{ \
364 "no destination", \
365 "HPI_DESTNODE_ISTREAM", \
366 "HPI_DESTNODE_LINEOUT", \
367 "HPI_DESTNODE_AESEBU_OUT", \
368 "HPI_DESTNODE_RF", \
369 "HPI_DESTNODE_SPEAKER", \
370 "HPI_DESTNODE_COBRANET", \
371 "HPI_DESTNODE_ANALOG" \
372}
373compile_time_assert((HPI_DESTNODE_LAST_INDEX - HPI_DESTNODE_NONE + 1) == (8),
374 destnode_strings_match_defs);
375
376#define HPI_CONTROL_CHANNEL_MODE_STRINGS \
377{ \
378 "XXX HPI_CHANNEL_MODE_ERROR XXX", \
379 "HPI_CHANNEL_MODE_NORMAL", \
380 "HPI_CHANNEL_MODE_SWAP", \
381 "HPI_CHANNEL_MODE_LEFT_ONLY", \
382 "HPI_CHANNEL_MODE_RIGHT_ONLY" \
383}
384
385#endif /* _HPIDEBUG_H */
diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c
index 9b10d9a5c255..5c6ea113d219 100644
--- a/sound/pci/asihpi/hpidspcd.c
+++ b/sound/pci/asihpi/hpidspcd.c
@@ -60,7 +60,7 @@ struct code_header {
60 HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER))) 60 HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
61 61
62/***********************************************************************/ 62/***********************************************************************/
63#include "linux/pci.h" 63#include <linux/pci.h>
64/*-------------------------------------------------------------------*/ 64/*-------------------------------------------------------------------*/
65short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code, 65short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
66 u32 *pos_error_code) 66 u32 *pos_error_code)
@@ -71,47 +71,50 @@ short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
71 int err; 71 int err;
72 72
73 sprintf(fw_name, "asihpi/dsp%04x.bin", adapter); 73 sprintf(fw_name, "asihpi/dsp%04x.bin", adapter);
74 HPI_DEBUG_LOG(INFO, "requesting firmware for %s\n", fw_name);
75 74
76 err = request_firmware(&ps_firmware, fw_name, 75 err = request_firmware(&ps_firmware, fw_name,
77 &ps_dsp_code->ps_dev->dev); 76 &ps_dsp_code->ps_dev->dev);
77
78 if (err != 0) { 78 if (err != 0) {
79 HPI_DEBUG_LOG(ERROR, "%d, request_firmware failed for %s\n", 79 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
80 err, fw_name); 80 "%d, request_firmware failed for %s\n", err,
81 fw_name);
81 goto error1; 82 goto error1;
82 } 83 }
83 if (ps_firmware->size < sizeof(header)) { 84 if (ps_firmware->size < sizeof(header)) {
84 HPI_DEBUG_LOG(ERROR, "header size too small %s\n", fw_name); 85 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
86 "Header size too small %s\n", fw_name);
85 goto error2; 87 goto error2;
86 } 88 }
87 memcpy(&header, ps_firmware->data, sizeof(header)); 89 memcpy(&header, ps_firmware->data, sizeof(header));
88 if (header.adapter != adapter) { 90 if (header.adapter != adapter) {
89 HPI_DEBUG_LOG(ERROR, "adapter type incorrect %4x != %4x\n", 91 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
90 header.adapter, adapter); 92 "Adapter type incorrect %4x != %4x\n", header.adapter,
93 adapter);
91 goto error2; 94 goto error2;
92 } 95 }
93 if (header.size != ps_firmware->size) { 96 if (header.size != ps_firmware->size) {
94 HPI_DEBUG_LOG(ERROR, "code size wrong %d != %ld\n", 97 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
95 header.size, (unsigned long)ps_firmware->size); 98 "Code size wrong %d != %ld\n", header.size,
99 (unsigned long)ps_firmware->size);
96 goto error2; 100 goto error2;
97 } 101 }
98 102
99 if (header.version / 10000 != HPI_VER_DECIMAL / 10000) { 103 if (header.version / 100 != HPI_VER_DECIMAL / 100) {
100 HPI_DEBUG_LOG(ERROR, 104 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
101 "firmware major version mismatch " 105 "Incompatible firmware version "
102 "DSP image %d != driver %d\n", header.version, 106 "DSP image %d != Driver %d\n", header.version,
103 HPI_VER_DECIMAL); 107 HPI_VER_DECIMAL);
104 goto error2; 108 goto error2;
105 } 109 }
106 110
107 if (header.version != HPI_VER_DECIMAL) { 111 if (header.version != HPI_VER_DECIMAL) {
108 HPI_DEBUG_LOG(WARNING, 112 dev_printk(KERN_WARNING, &ps_dsp_code->ps_dev->dev,
109 "version mismatch DSP image %d != driver %d\n", 113 "Firmware: release version mismatch DSP image %d != Driver %d\n",
110 header.version, HPI_VER_DECIMAL); 114 header.version, HPI_VER_DECIMAL);
111 /* goto error2; still allow driver to load */
112 } 115 }
113 116
114 HPI_DEBUG_LOG(INFO, "dsp code %s opened\n", fw_name); 117 HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
115 ps_dsp_code->ps_firmware = ps_firmware; 118 ps_dsp_code->ps_firmware = ps_firmware;
116 ps_dsp_code->block_length = header.size / sizeof(u32); 119 ps_dsp_code->block_length = header.size / sizeof(u32);
117 ps_dsp_code->word_count = sizeof(header) / sizeof(u32); 120 ps_dsp_code->word_count = sizeof(header) / sizeof(u32);
@@ -148,7 +151,7 @@ void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code)
148short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, u32 *pword) 151short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, u32 *pword)
149{ 152{
150 if (ps_dsp_code->word_count + 1 > ps_dsp_code->block_length) 153 if (ps_dsp_code->word_count + 1 > ps_dsp_code->block_length)
151 return (HPI_ERROR_DSP_FILE_FORMAT); 154 return HPI_ERROR_DSP_FILE_FORMAT;
152 155
153 *pword = ((u32 *)(ps_dsp_code->ps_firmware->data))[ps_dsp_code-> 156 *pword = ((u32 *)(ps_dsp_code->ps_firmware->data))[ps_dsp_code->
154 word_count]; 157 word_count];
diff --git a/sound/pci/asihpi/hpidspcd.h b/sound/pci/asihpi/hpidspcd.h
index d7c240398225..65f0ca732704 100644
--- a/sound/pci/asihpi/hpidspcd.h
+++ b/sound/pci/asihpi/hpidspcd.h
@@ -87,7 +87,7 @@ void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code);
87*/ 87*/
88short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, 88short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code,
89 /**< DSP code descriptor */ 89 /**< DSP code descriptor */
90 u32 *pword /**< where to store the read word */ 90 u32 *pword /**< Where to store the read word */
91 ); 91 );
92 92
93/** Get a block of dsp code into an internal buffer, and provide a pointer to 93/** Get a block of dsp code into an internal buffer, and provide a pointer to
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
index 1e92eb6dd509..7397b169b89f 100644
--- a/sound/pci/asihpi/hpifunc.c
+++ b/sound/pci/asihpi/hpifunc.c
@@ -30,16 +30,25 @@ u32 hpi_indexes_to_handle(const char c_object, const u16 adapter_index,
30 return handle.w; 30 return handle.w;
31} 31}
32 32
33void hpi_handle_to_indexes(const u32 handle, u16 *pw_adapter_index, 33static u16 hpi_handle_indexes(const u32 h, u16 *p1, u16 *p2)
34 u16 *pw_object_index)
35{ 34{
36 union handle_word uhandle; 35 union handle_word uhandle;
37 uhandle.w = handle; 36 if (!h)
37 return HPI_ERROR_INVALID_HANDLE;
38
39 uhandle.w = h;
40
41 *p1 = (u16)uhandle.h.adapter_index;
42 if (p2)
43 *p2 = (u16)uhandle.h.obj_index;
38 44
39 if (pw_adapter_index) 45 return 0;
40 *pw_adapter_index = (u16)uhandle.h.adapter_index; 46}
41 if (pw_object_index) 47
42 *pw_object_index = (u16)uhandle.h.obj_index; 48void hpi_handle_to_indexes(const u32 handle, u16 *pw_adapter_index,
49 u16 *pw_object_index)
50{
51 hpi_handle_indexes(handle, pw_adapter_index, pw_object_index);
43} 52}
44 53
45char hpi_handle_object(const u32 handle) 54char hpi_handle_object(const u32 handle)
@@ -49,22 +58,6 @@ char hpi_handle_object(const u32 handle)
49 return (char)uhandle.h.obj_type; 58 return (char)uhandle.h.obj_type;
50} 59}
51 60
52#define u32TOINDEX(h, i1) \
53do {\
54 if (h == 0) \
55 return HPI_ERROR_INVALID_OBJ; \
56 else \
57 hpi_handle_to_indexes(h, i1, NULL); \
58} while (0)
59
60#define u32TOINDEXES(h, i1, i2) \
61do {\
62 if (h == 0) \
63 return HPI_ERROR_INVALID_OBJ; \
64 else \
65 hpi_handle_to_indexes(h, i1, i2);\
66} while (0)
67
68void hpi_format_to_msg(struct hpi_msg_format *pMF, 61void hpi_format_to_msg(struct hpi_msg_format *pMF,
69 const struct hpi_format *pF) 62 const struct hpi_format *pF)
70{ 63{
@@ -94,52 +87,13 @@ void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR)
94 pSR->u.legacy_stream_info.state = pSR->u.stream_info.state; 87 pSR->u.legacy_stream_info.state = pSR->u.stream_info.state;
95} 88}
96 89
97static struct hpi_hsubsys gh_subsys; 90static inline void hpi_send_recvV1(struct hpi_message_header *m,
98 91 struct hpi_response_header *r)
99struct hpi_hsubsys *hpi_subsys_create(void)
100{
101 struct hpi_message hm;
102 struct hpi_response hr;
103
104 memset(&gh_subsys, 0, sizeof(struct hpi_hsubsys));
105
106 {
107 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
108 HPI_SUBSYS_OPEN);
109 hpi_send_recv(&hm, &hr);
110
111 if (hr.error == 0)
112 return &gh_subsys;
113
114 }
115 return NULL;
116}
117
118void hpi_subsys_free(const struct hpi_hsubsys *ph_subsys)
119{ 92{
120 struct hpi_message hm; 93 hpi_send_recv((struct hpi_message *)m, (struct hpi_response *)r);
121 struct hpi_response hr;
122
123 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
124 HPI_SUBSYS_CLOSE);
125 hpi_send_recv(&hm, &hr);
126
127}
128
129u16 hpi_subsys_get_version(const struct hpi_hsubsys *ph_subsys, u32 *pversion)
130{
131 struct hpi_message hm;
132 struct hpi_response hr;
133
134 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
135 HPI_SUBSYS_GET_VERSION);
136 hpi_send_recv(&hm, &hr);
137 *pversion = hr.u.s.version;
138 return hr.error;
139} 94}
140 95
141u16 hpi_subsys_get_version_ex(const struct hpi_hsubsys *ph_subsys, 96u16 hpi_subsys_get_version_ex(u32 *pversion_ex)
142 u32 *pversion_ex)
143{ 97{
144 struct hpi_message hm; 98 struct hpi_message hm;
145 struct hpi_response hr; 99 struct hpi_response hr;
@@ -151,79 +105,7 @@ u16 hpi_subsys_get_version_ex(const struct hpi_hsubsys *ph_subsys,
151 return hr.error; 105 return hr.error;
152} 106}
153 107
154u16 hpi_subsys_get_info(const struct hpi_hsubsys *ph_subsys, u32 *pversion, 108u16 hpi_subsys_get_num_adapters(int *pn_num_adapters)
155 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length)
156{
157 struct hpi_message hm;
158 struct hpi_response hr;
159 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
160 HPI_SUBSYS_GET_INFO);
161
162 hpi_send_recv(&hm, &hr);
163
164 *pversion = hr.u.s.version;
165 if (list_length > HPI_MAX_ADAPTERS)
166 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
167 HPI_MAX_ADAPTERS);
168 else
169 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list, list_length);
170 *pw_num_adapters = hr.u.s.num_adapters;
171 return hr.error;
172}
173
174u16 hpi_subsys_find_adapters(const struct hpi_hsubsys *ph_subsys,
175 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length)
176{
177 struct hpi_message hm;
178 struct hpi_response hr;
179 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
180 HPI_SUBSYS_FIND_ADAPTERS);
181
182 hpi_send_recv(&hm, &hr);
183
184 if (list_length > HPI_MAX_ADAPTERS) {
185 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
186 HPI_MAX_ADAPTERS * sizeof(u16));
187 memset(&aw_adapter_list[HPI_MAX_ADAPTERS], 0,
188 (list_length - HPI_MAX_ADAPTERS) * sizeof(u16));
189 } else
190 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
191 list_length * sizeof(u16));
192 *pw_num_adapters = hr.u.s.num_adapters;
193
194 return hr.error;
195}
196
197u16 hpi_subsys_create_adapter(const struct hpi_hsubsys *ph_subsys,
198 const struct hpi_resource *p_resource, u16 *pw_adapter_index)
199{
200 struct hpi_message hm;
201 struct hpi_response hr;
202
203 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
204 HPI_SUBSYS_CREATE_ADAPTER);
205 hm.u.s.resource = *p_resource;
206
207 hpi_send_recv(&hm, &hr);
208
209 *pw_adapter_index = hr.u.s.adapter_index;
210 return hr.error;
211}
212
213u16 hpi_subsys_delete_adapter(const struct hpi_hsubsys *ph_subsys,
214 u16 adapter_index)
215{
216 struct hpi_message hm;
217 struct hpi_response hr;
218 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
219 HPI_SUBSYS_DELETE_ADAPTER);
220 hm.adapter_index = adapter_index;
221 hpi_send_recv(&hm, &hr);
222 return hr.error;
223}
224
225u16 hpi_subsys_get_num_adapters(const struct hpi_hsubsys *ph_subsys,
226 int *pn_num_adapters)
227{ 109{
228 struct hpi_message hm; 110 struct hpi_message hm;
229 struct hpi_response hr; 111 struct hpi_response hr;
@@ -234,35 +116,22 @@ u16 hpi_subsys_get_num_adapters(const struct hpi_hsubsys *ph_subsys,
234 return hr.error; 116 return hr.error;
235} 117}
236 118
237u16 hpi_subsys_get_adapter(const struct hpi_hsubsys *ph_subsys, int iterator, 119u16 hpi_subsys_get_adapter(int iterator, u32 *padapter_index,
238 u32 *padapter_index, u16 *pw_adapter_type) 120 u16 *pw_adapter_type)
239{ 121{
240 struct hpi_message hm; 122 struct hpi_message hm;
241 struct hpi_response hr; 123 struct hpi_response hr;
242 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, 124 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
243 HPI_SUBSYS_GET_ADAPTER); 125 HPI_SUBSYS_GET_ADAPTER);
244 hm.adapter_index = (u16)iterator; 126 hm.obj_index = (u16)iterator;
245 hpi_send_recv(&hm, &hr); 127 hpi_send_recv(&hm, &hr);
246 *padapter_index = (int)hr.u.s.adapter_index; 128 *padapter_index = (int)hr.u.s.adapter_index;
247 *pw_adapter_type = hr.u.s.aw_adapter_list[0]; 129 *pw_adapter_type = hr.u.s.adapter_type;
248 return hr.error;
249}
250 130
251u16 hpi_subsys_set_host_network_interface(const struct hpi_hsubsys *ph_subsys,
252 const char *sz_interface)
253{
254 struct hpi_message hm;
255 struct hpi_response hr;
256 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
257 HPI_SUBSYS_SET_NETWORK_INTERFACE);
258 if (sz_interface == NULL)
259 return HPI_ERROR_INVALID_RESOURCE;
260 hm.u.s.resource.r.net_if = sz_interface;
261 hpi_send_recv(&hm, &hr);
262 return hr.error; 131 return hr.error;
263} 132}
264 133
265u16 hpi_adapter_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index) 134u16 hpi_adapter_open(u16 adapter_index)
266{ 135{
267 struct hpi_message hm; 136 struct hpi_message hm;
268 struct hpi_response hr; 137 struct hpi_response hr;
@@ -276,7 +145,7 @@ u16 hpi_adapter_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index)
276 145
277} 146}
278 147
279u16 hpi_adapter_close(const struct hpi_hsubsys *ph_subsys, u16 adapter_index) 148u16 hpi_adapter_close(u16 adapter_index)
280{ 149{
281 struct hpi_message hm; 150 struct hpi_message hm;
282 struct hpi_response hr; 151 struct hpi_response hr;
@@ -289,15 +158,14 @@ u16 hpi_adapter_close(const struct hpi_hsubsys *ph_subsys, u16 adapter_index)
289 return hr.error; 158 return hr.error;
290} 159}
291 160
292u16 hpi_adapter_set_mode(const struct hpi_hsubsys *ph_subsys, 161u16 hpi_adapter_set_mode(u16 adapter_index, u32 adapter_mode)
293 u16 adapter_index, u32 adapter_mode)
294{ 162{
295 return hpi_adapter_set_mode_ex(ph_subsys, adapter_index, adapter_mode, 163 return hpi_adapter_set_mode_ex(adapter_index, adapter_mode,
296 HPI_ADAPTER_MODE_SET); 164 HPI_ADAPTER_MODE_SET);
297} 165}
298 166
299u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys, 167u16 hpi_adapter_set_mode_ex(u16 adapter_index, u32 adapter_mode,
300 u16 adapter_index, u32 adapter_mode, u16 query_or_set) 168 u16 query_or_set)
301{ 169{
302 struct hpi_message hm; 170 struct hpi_message hm;
303 struct hpi_response hr; 171 struct hpi_response hr;
@@ -305,14 +173,13 @@ u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys,
305 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, 173 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
306 HPI_ADAPTER_SET_MODE); 174 HPI_ADAPTER_SET_MODE);
307 hm.adapter_index = adapter_index; 175 hm.adapter_index = adapter_index;
308 hm.u.a.adapter_mode = adapter_mode; 176 hm.u.ax.mode.adapter_mode = adapter_mode;
309 hm.u.a.assert_id = query_or_set; 177 hm.u.ax.mode.query_or_set = query_or_set;
310 hpi_send_recv(&hm, &hr); 178 hpi_send_recv(&hm, &hr);
311 return hr.error; 179 return hr.error;
312} 180}
313 181
314u16 hpi_adapter_get_mode(const struct hpi_hsubsys *ph_subsys, 182u16 hpi_adapter_get_mode(u16 adapter_index, u32 *padapter_mode)
315 u16 adapter_index, u32 *padapter_mode)
316{ 183{
317 struct hpi_message hm; 184 struct hpi_message hm;
318 struct hpi_response hr; 185 struct hpi_response hr;
@@ -321,13 +188,13 @@ u16 hpi_adapter_get_mode(const struct hpi_hsubsys *ph_subsys,
321 hm.adapter_index = adapter_index; 188 hm.adapter_index = adapter_index;
322 hpi_send_recv(&hm, &hr); 189 hpi_send_recv(&hm, &hr);
323 if (padapter_mode) 190 if (padapter_mode)
324 *padapter_mode = hr.u.a.serial_number; 191 *padapter_mode = hr.u.ax.mode.adapter_mode;
325 return hr.error; 192 return hr.error;
326} 193}
327 194
328u16 hpi_adapter_get_info(const struct hpi_hsubsys *ph_subsys, 195u16 hpi_adapter_get_info(u16 adapter_index, u16 *pw_num_outstreams,
329 u16 adapter_index, u16 *pw_num_outstreams, u16 *pw_num_instreams, 196 u16 *pw_num_instreams, u16 *pw_version, u32 *pserial_number,
330 u16 *pw_version, u32 *pserial_number, u16 *pw_adapter_type) 197 u16 *pw_adapter_type)
331{ 198{
332 struct hpi_message hm; 199 struct hpi_message hm;
333 struct hpi_response hr; 200 struct hpi_response hr;
@@ -337,18 +204,17 @@ u16 hpi_adapter_get_info(const struct hpi_hsubsys *ph_subsys,
337 204
338 hpi_send_recv(&hm, &hr); 205 hpi_send_recv(&hm, &hr);
339 206
340 *pw_adapter_type = hr.u.a.adapter_type; 207 *pw_adapter_type = hr.u.ax.info.adapter_type;
341 *pw_num_outstreams = hr.u.a.num_outstreams; 208 *pw_num_outstreams = hr.u.ax.info.num_outstreams;
342 *pw_num_instreams = hr.u.a.num_instreams; 209 *pw_num_instreams = hr.u.ax.info.num_instreams;
343 *pw_version = hr.u.a.version; 210 *pw_version = hr.u.ax.info.version;
344 *pserial_number = hr.u.a.serial_number; 211 *pserial_number = hr.u.ax.info.serial_number;
345 return hr.error; 212 return hr.error;
346} 213}
347 214
348u16 hpi_adapter_get_module_by_index(const struct hpi_hsubsys *ph_subsys, 215u16 hpi_adapter_get_module_by_index(u16 adapter_index, u16 module_index,
349 u16 adapter_index, u16 module_index, u16 *pw_num_outputs, 216 u16 *pw_num_outputs, u16 *pw_num_inputs, u16 *pw_version,
350 u16 *pw_num_inputs, u16 *pw_version, u32 *pserial_number, 217 u32 *pserial_number, u16 *pw_module_type, u32 *ph_module)
351 u16 *pw_module_type, u32 *ph_module)
352{ 218{
353 struct hpi_message hm; 219 struct hpi_message hm;
354 struct hpi_response hr; 220 struct hpi_response hr;
@@ -360,173 +226,18 @@ u16 hpi_adapter_get_module_by_index(const struct hpi_hsubsys *ph_subsys,
360 226
361 hpi_send_recv(&hm, &hr); 227 hpi_send_recv(&hm, &hr);
362 228
363 *pw_module_type = hr.u.a.adapter_type; 229 *pw_module_type = hr.u.ax.info.adapter_type;
364 *pw_num_outputs = hr.u.a.num_outstreams; 230 *pw_num_outputs = hr.u.ax.info.num_outstreams;
365 *pw_num_inputs = hr.u.a.num_instreams; 231 *pw_num_inputs = hr.u.ax.info.num_instreams;
366 *pw_version = hr.u.a.version; 232 *pw_version = hr.u.ax.info.version;
367 *pserial_number = hr.u.a.serial_number; 233 *pserial_number = hr.u.ax.info.serial_number;
368 *ph_module = 0; 234 *ph_module = 0;
369 235
370 return hr.error; 236 return hr.error;
371} 237}
372 238
373u16 hpi_adapter_get_assert(const struct hpi_hsubsys *ph_subsys, 239u16 hpi_adapter_set_property(u16 adapter_index, u16 property, u16 parameter1,
374 u16 adapter_index, u16 *assert_present, char *psz_assert, 240 u16 parameter2)
375 u16 *pw_line_number)
376{
377 struct hpi_message hm;
378 struct hpi_response hr;
379 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
380 HPI_ADAPTER_GET_ASSERT);
381 hm.adapter_index = adapter_index;
382 hpi_send_recv(&hm, &hr);
383
384 *assert_present = 0;
385
386 if (!hr.error) {
387
388 *pw_line_number = (u16)hr.u.a.serial_number;
389 if (*pw_line_number) {
390
391 int i;
392 char *src = (char *)hr.u.a.sz_adapter_assert;
393 char *dst = psz_assert;
394
395 *assert_present = 1;
396
397 for (i = 0; i < HPI_STRING_LEN; i++) {
398 char c;
399 c = *src++;
400 *dst++ = c;
401 if (c == 0)
402 break;
403 }
404
405 }
406 }
407 return hr.error;
408}
409
410u16 hpi_adapter_get_assert_ex(const struct hpi_hsubsys *ph_subsys,
411 u16 adapter_index, u16 *assert_present, char *psz_assert,
412 u32 *pline_number, u16 *pw_assert_on_dsp)
413{
414 struct hpi_message hm;
415 struct hpi_response hr;
416 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
417 HPI_ADAPTER_GET_ASSERT);
418 hm.adapter_index = adapter_index;
419
420 hpi_send_recv(&hm, &hr);
421
422 *assert_present = 0;
423
424 if (!hr.error) {
425
426 *pline_number = hr.u.a.serial_number;
427
428 *assert_present = hr.u.a.adapter_type;
429
430 *pw_assert_on_dsp = hr.u.a.adapter_index;
431
432 if (!*assert_present && *pline_number)
433
434 *assert_present = 1;
435
436 if (*assert_present) {
437
438 int i;
439 char *src = (char *)hr.u.a.sz_adapter_assert;
440 char *dst = psz_assert;
441
442 for (i = 0; i < HPI_STRING_LEN; i++) {
443 char c;
444 c = *src++;
445 *dst++ = c;
446 if (c == 0)
447 break;
448 }
449
450 } else {
451 *psz_assert = 0;
452 }
453 }
454 return hr.error;
455}
456
457u16 hpi_adapter_test_assert(const struct hpi_hsubsys *ph_subsys,
458 u16 adapter_index, u16 assert_id)
459{
460 struct hpi_message hm;
461 struct hpi_response hr;
462 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
463 HPI_ADAPTER_TEST_ASSERT);
464 hm.adapter_index = adapter_index;
465 hm.u.a.assert_id = assert_id;
466
467 hpi_send_recv(&hm, &hr);
468
469 return hr.error;
470}
471
472u16 hpi_adapter_enable_capability(const struct hpi_hsubsys *ph_subsys,
473 u16 adapter_index, u16 capability, u32 key)
474{
475 struct hpi_message hm;
476 struct hpi_response hr;
477 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
478 HPI_ADAPTER_ENABLE_CAPABILITY);
479 hm.adapter_index = adapter_index;
480 hm.u.a.assert_id = capability;
481 hm.u.a.adapter_mode = key;
482
483 hpi_send_recv(&hm, &hr);
484
485 return hr.error;
486}
487
488u16 hpi_adapter_self_test(const struct hpi_hsubsys *ph_subsys,
489 u16 adapter_index)
490{
491 struct hpi_message hm;
492 struct hpi_response hr;
493 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
494 HPI_ADAPTER_SELFTEST);
495 hm.adapter_index = adapter_index;
496 hpi_send_recv(&hm, &hr);
497 return hr.error;
498}
499
500u16 hpi_adapter_debug_read(const struct hpi_hsubsys *ph_subsys,
501 u16 adapter_index, u32 dsp_address, char *p_buffer, int *count_bytes)
502{
503 struct hpi_message hm;
504 struct hpi_response hr;
505 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
506 HPI_ADAPTER_DEBUG_READ);
507
508 hr.size = sizeof(hr);
509
510 hm.adapter_index = adapter_index;
511 hm.u.ax.debug_read.dsp_address = dsp_address;
512
513 if (*count_bytes > (int)sizeof(hr.u.bytes))
514 *count_bytes = sizeof(hr.u.bytes);
515
516 hm.u.ax.debug_read.count_bytes = *count_bytes;
517
518 hpi_send_recv(&hm, &hr);
519
520 if (!hr.error) {
521 *count_bytes = hr.size - 12;
522 memcpy(p_buffer, &hr.u.bytes, *count_bytes);
523 } else
524 *count_bytes = 0;
525 return hr.error;
526}
527
528u16 hpi_adapter_set_property(const struct hpi_hsubsys *ph_subsys,
529 u16 adapter_index, u16 property, u16 parameter1, u16 parameter2)
530{ 241{
531 struct hpi_message hm; 242 struct hpi_message hm;
532 struct hpi_response hr; 243 struct hpi_response hr;
@@ -542,9 +253,8 @@ u16 hpi_adapter_set_property(const struct hpi_hsubsys *ph_subsys,
542 return hr.error; 253 return hr.error;
543} 254}
544 255
545u16 hpi_adapter_get_property(const struct hpi_hsubsys *ph_subsys, 256u16 hpi_adapter_get_property(u16 adapter_index, u16 property,
546 u16 adapter_index, u16 property, u16 *pw_parameter1, 257 u16 *pw_parameter1, u16 *pw_parameter2)
547 u16 *pw_parameter2)
548{ 258{
549 struct hpi_message hm; 259 struct hpi_message hm;
550 struct hpi_response hr; 260 struct hpi_response hr;
@@ -564,9 +274,8 @@ u16 hpi_adapter_get_property(const struct hpi_hsubsys *ph_subsys,
564 return hr.error; 274 return hr.error;
565} 275}
566 276
567u16 hpi_adapter_enumerate_property(const struct hpi_hsubsys *ph_subsys, 277u16 hpi_adapter_enumerate_property(u16 adapter_index, u16 index,
568 u16 adapter_index, u16 index, u16 what_to_enumerate, 278 u16 what_to_enumerate, u16 property_index, u32 *psetting)
569 u16 property_index, u32 *psetting)
570{ 279{
571 return 0; 280 return 0;
572} 281}
@@ -574,7 +283,7 @@ u16 hpi_adapter_enumerate_property(const struct hpi_hsubsys *ph_subsys,
574u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format, 283u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
575 u32 sample_rate, u32 bit_rate, u32 attributes) 284 u32 sample_rate, u32 bit_rate, u32 attributes)
576{ 285{
577 u16 error = 0; 286 u16 err = 0;
578 struct hpi_msg_format fmt; 287 struct hpi_msg_format fmt;
579 288
580 switch (channels) { 289 switch (channels) {
@@ -586,8 +295,8 @@ u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
586 case 16: 295 case 16:
587 break; 296 break;
588 default: 297 default:
589 error = HPI_ERROR_INVALID_CHANNELS; 298 err = HPI_ERROR_INVALID_CHANNELS;
590 return error; 299 return err;
591 } 300 }
592 fmt.channels = channels; 301 fmt.channels = channels;
593 302
@@ -610,17 +319,17 @@ u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
610 case HPI_FORMAT_OEM2: 319 case HPI_FORMAT_OEM2:
611 break; 320 break;
612 default: 321 default:
613 error = HPI_ERROR_INVALID_FORMAT; 322 err = HPI_ERROR_INVALID_FORMAT;
614 return error; 323 return err;
615 } 324 }
616 fmt.format = format; 325 fmt.format = format;
617 326
618 if (sample_rate < 8000L) { 327 if (sample_rate < 8000L) {
619 error = HPI_ERROR_INCOMPATIBLE_SAMPLERATE; 328 err = HPI_ERROR_INCOMPATIBLE_SAMPLERATE;
620 sample_rate = 8000L; 329 sample_rate = 8000L;
621 } 330 }
622 if (sample_rate > 200000L) { 331 if (sample_rate > 200000L) {
623 error = HPI_ERROR_INCOMPATIBLE_SAMPLERATE; 332 err = HPI_ERROR_INCOMPATIBLE_SAMPLERATE;
624 sample_rate = 200000L; 333 sample_rate = 200000L;
625 } 334 }
626 fmt.sample_rate = sample_rate; 335 fmt.sample_rate = sample_rate;
@@ -651,10 +360,10 @@ u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
651 if ((channels == 1) 360 if ((channels == 1)
652 && (attributes != HPI_MPEG_MODE_DEFAULT)) { 361 && (attributes != HPI_MPEG_MODE_DEFAULT)) {
653 attributes = HPI_MPEG_MODE_DEFAULT; 362 attributes = HPI_MPEG_MODE_DEFAULT;
654 error = HPI_ERROR_INVALID_FORMAT; 363 err = HPI_ERROR_INVALID_FORMAT;
655 } else if (attributes > HPI_MPEG_MODE_DUALCHANNEL) { 364 } else if (attributes > HPI_MPEG_MODE_DUALCHANNEL) {
656 attributes = HPI_MPEG_MODE_DEFAULT; 365 attributes = HPI_MPEG_MODE_DEFAULT;
657 error = HPI_ERROR_INVALID_FORMAT; 366 err = HPI_ERROR_INVALID_FORMAT;
658 } 367 }
659 fmt.attributes = attributes; 368 fmt.attributes = attributes;
660 break; 369 break;
@@ -663,7 +372,7 @@ u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
663 } 372 }
664 373
665 hpi_msg_to_format(p_format, &fmt); 374 hpi_msg_to_format(p_format, &fmt);
666 return error; 375 return err;
667} 376}
668 377
669u16 hpi_stream_estimate_buffer_size(struct hpi_format *p_format, 378u16 hpi_stream_estimate_buffer_size(struct hpi_format *p_format,
@@ -712,8 +421,8 @@ u16 hpi_stream_estimate_buffer_size(struct hpi_format *p_format,
712 return 0; 421 return 0;
713} 422}
714 423
715u16 hpi_outstream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index, 424u16 hpi_outstream_open(u16 adapter_index, u16 outstream_index,
716 u16 outstream_index, u32 *ph_outstream) 425 u32 *ph_outstream)
717{ 426{
718 struct hpi_message hm; 427 struct hpi_message hm;
719 struct hpi_response hr; 428 struct hpi_response hr;
@@ -733,38 +442,41 @@ u16 hpi_outstream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
733 return hr.error; 442 return hr.error;
734} 443}
735 444
736u16 hpi_outstream_close(const struct hpi_hsubsys *ph_subsys, u32 h_outstream) 445u16 hpi_outstream_close(u32 h_outstream)
737{ 446{
738 struct hpi_message hm; 447 struct hpi_message hm;
739 struct hpi_response hr; 448 struct hpi_response hr;
740 449
741 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 450 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
742 HPI_OSTREAM_HOSTBUFFER_FREE); 451 HPI_OSTREAM_HOSTBUFFER_FREE);
743 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 452 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
453 return HPI_ERROR_INVALID_HANDLE;
454
744 hpi_send_recv(&hm, &hr); 455 hpi_send_recv(&hm, &hr);
745 456
746 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 457 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
747 HPI_OSTREAM_GROUP_RESET); 458 HPI_OSTREAM_GROUP_RESET);
748 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 459 hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index);
749 hpi_send_recv(&hm, &hr); 460 hpi_send_recv(&hm, &hr);
750 461
751 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 462 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
752 HPI_OSTREAM_CLOSE); 463 HPI_OSTREAM_CLOSE);
753 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 464 hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index);
754 hpi_send_recv(&hm, &hr); 465 hpi_send_recv(&hm, &hr);
755 466
756 return hr.error; 467 return hr.error;
757} 468}
758 469
759u16 hpi_outstream_get_info_ex(const struct hpi_hsubsys *ph_subsys, 470u16 hpi_outstream_get_info_ex(u32 h_outstream, u16 *pw_state,
760 u32 h_outstream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_to_play, 471 u32 *pbuffer_size, u32 *pdata_to_play, u32 *psamples_played,
761 u32 *psamples_played, u32 *pauxiliary_data_to_play) 472 u32 *pauxiliary_data_to_play)
762{ 473{
763 struct hpi_message hm; 474 struct hpi_message hm;
764 struct hpi_response hr; 475 struct hpi_response hr;
765 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 476 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
766 HPI_OSTREAM_GET_INFO); 477 HPI_OSTREAM_GET_INFO);
767 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 478 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
479 return HPI_ERROR_INVALID_HANDLE;
768 480
769 hpi_send_recv(&hm, &hr); 481 hpi_send_recv(&hm, &hr);
770 482
@@ -782,15 +494,15 @@ u16 hpi_outstream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
782 return hr.error; 494 return hr.error;
783} 495}
784 496
785u16 hpi_outstream_write_buf(const struct hpi_hsubsys *ph_subsys, 497u16 hpi_outstream_write_buf(u32 h_outstream, const u8 *pb_data,
786 u32 h_outstream, const u8 *pb_data, u32 bytes_to_write, 498 u32 bytes_to_write, const struct hpi_format *p_format)
787 const struct hpi_format *p_format)
788{ 499{
789 struct hpi_message hm; 500 struct hpi_message hm;
790 struct hpi_response hr; 501 struct hpi_response hr;
791 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 502 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
792 HPI_OSTREAM_WRITE); 503 HPI_OSTREAM_WRITE);
793 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 504 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
505 return HPI_ERROR_INVALID_HANDLE;
794 hm.u.d.u.data.pb_data = (u8 *)pb_data; 506 hm.u.d.u.data.pb_data = (u8 *)pb_data;
795 hm.u.d.u.data.data_size = bytes_to_write; 507 hm.u.d.u.data.data_size = bytes_to_write;
796 508
@@ -801,82 +513,85 @@ u16 hpi_outstream_write_buf(const struct hpi_hsubsys *ph_subsys,
801 return hr.error; 513 return hr.error;
802} 514}
803 515
804u16 hpi_outstream_start(const struct hpi_hsubsys *ph_subsys, u32 h_outstream) 516u16 hpi_outstream_start(u32 h_outstream)
805{ 517{
806 struct hpi_message hm; 518 struct hpi_message hm;
807 struct hpi_response hr; 519 struct hpi_response hr;
808 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 520 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
809 HPI_OSTREAM_START); 521 HPI_OSTREAM_START);
810 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 522 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
523 return HPI_ERROR_INVALID_HANDLE;
811 524
812 hpi_send_recv(&hm, &hr); 525 hpi_send_recv(&hm, &hr);
813 526
814 return hr.error; 527 return hr.error;
815} 528}
816 529
817u16 hpi_outstream_wait_start(const struct hpi_hsubsys *ph_subsys, 530u16 hpi_outstream_wait_start(u32 h_outstream)
818 u32 h_outstream)
819{ 531{
820 struct hpi_message hm; 532 struct hpi_message hm;
821 struct hpi_response hr; 533 struct hpi_response hr;
822 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 534 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
823 HPI_OSTREAM_WAIT_START); 535 HPI_OSTREAM_WAIT_START);
824 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 536 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
537 return HPI_ERROR_INVALID_HANDLE;
825 538
826 hpi_send_recv(&hm, &hr); 539 hpi_send_recv(&hm, &hr);
827 540
828 return hr.error; 541 return hr.error;
829} 542}
830 543
831u16 hpi_outstream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_outstream) 544u16 hpi_outstream_stop(u32 h_outstream)
832{ 545{
833 struct hpi_message hm; 546 struct hpi_message hm;
834 struct hpi_response hr; 547 struct hpi_response hr;
835 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 548 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
836 HPI_OSTREAM_STOP); 549 HPI_OSTREAM_STOP);
837 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 550 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
551 return HPI_ERROR_INVALID_HANDLE;
838 552
839 hpi_send_recv(&hm, &hr); 553 hpi_send_recv(&hm, &hr);
840 554
841 return hr.error; 555 return hr.error;
842} 556}
843 557
844u16 hpi_outstream_sinegen(const struct hpi_hsubsys *ph_subsys, 558u16 hpi_outstream_sinegen(u32 h_outstream)
845 u32 h_outstream)
846{ 559{
847 struct hpi_message hm; 560 struct hpi_message hm;
848 struct hpi_response hr; 561 struct hpi_response hr;
849 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 562 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
850 HPI_OSTREAM_SINEGEN); 563 HPI_OSTREAM_SINEGEN);
851 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 564 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
565 return HPI_ERROR_INVALID_HANDLE;
852 566
853 hpi_send_recv(&hm, &hr); 567 hpi_send_recv(&hm, &hr);
854 568
855 return hr.error; 569 return hr.error;
856} 570}
857 571
858u16 hpi_outstream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_outstream) 572u16 hpi_outstream_reset(u32 h_outstream)
859{ 573{
860 struct hpi_message hm; 574 struct hpi_message hm;
861 struct hpi_response hr; 575 struct hpi_response hr;
862 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 576 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
863 HPI_OSTREAM_RESET); 577 HPI_OSTREAM_RESET);
864 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 578 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
579 return HPI_ERROR_INVALID_HANDLE;
865 580
866 hpi_send_recv(&hm, &hr); 581 hpi_send_recv(&hm, &hr);
867 582
868 return hr.error; 583 return hr.error;
869} 584}
870 585
871u16 hpi_outstream_query_format(const struct hpi_hsubsys *ph_subsys, 586u16 hpi_outstream_query_format(u32 h_outstream, struct hpi_format *p_format)
872 u32 h_outstream, struct hpi_format *p_format)
873{ 587{
874 struct hpi_message hm; 588 struct hpi_message hm;
875 struct hpi_response hr; 589 struct hpi_response hr;
876 590
877 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 591 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
878 HPI_OSTREAM_QUERY_FORMAT); 592 HPI_OSTREAM_QUERY_FORMAT);
879 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 593 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
594 return HPI_ERROR_INVALID_HANDLE;
880 595
881 hpi_format_to_msg(&hm.u.d.u.data.format, p_format); 596 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
882 597
@@ -885,15 +600,15 @@ u16 hpi_outstream_query_format(const struct hpi_hsubsys *ph_subsys,
885 return hr.error; 600 return hr.error;
886} 601}
887 602
888u16 hpi_outstream_set_format(const struct hpi_hsubsys *ph_subsys, 603u16 hpi_outstream_set_format(u32 h_outstream, struct hpi_format *p_format)
889 u32 h_outstream, struct hpi_format *p_format)
890{ 604{
891 struct hpi_message hm; 605 struct hpi_message hm;
892 struct hpi_response hr; 606 struct hpi_response hr;
893 607
894 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 608 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
895 HPI_OSTREAM_SET_FORMAT); 609 HPI_OSTREAM_SET_FORMAT);
896 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 610 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
611 return HPI_ERROR_INVALID_HANDLE;
897 612
898 hpi_format_to_msg(&hm.u.d.u.data.format, p_format); 613 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
899 614
@@ -902,15 +617,15 @@ u16 hpi_outstream_set_format(const struct hpi_hsubsys *ph_subsys,
902 return hr.error; 617 return hr.error;
903} 618}
904 619
905u16 hpi_outstream_set_velocity(const struct hpi_hsubsys *ph_subsys, 620u16 hpi_outstream_set_velocity(u32 h_outstream, short velocity)
906 u32 h_outstream, short velocity)
907{ 621{
908 struct hpi_message hm; 622 struct hpi_message hm;
909 struct hpi_response hr; 623 struct hpi_response hr;
910 624
911 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 625 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
912 HPI_OSTREAM_SET_VELOCITY); 626 HPI_OSTREAM_SET_VELOCITY);
913 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 627 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
628 return HPI_ERROR_INVALID_HANDLE;
914 hm.u.d.u.velocity = velocity; 629 hm.u.d.u.velocity = velocity;
915 630
916 hpi_send_recv(&hm, &hr); 631 hpi_send_recv(&hm, &hr);
@@ -918,15 +633,16 @@ u16 hpi_outstream_set_velocity(const struct hpi_hsubsys *ph_subsys,
918 return hr.error; 633 return hr.error;
919} 634}
920 635
921u16 hpi_outstream_set_punch_in_out(const struct hpi_hsubsys *ph_subsys, 636u16 hpi_outstream_set_punch_in_out(u32 h_outstream, u32 punch_in_sample,
922 u32 h_outstream, u32 punch_in_sample, u32 punch_out_sample) 637 u32 punch_out_sample)
923{ 638{
924 struct hpi_message hm; 639 struct hpi_message hm;
925 struct hpi_response hr; 640 struct hpi_response hr;
926 641
927 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 642 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
928 HPI_OSTREAM_SET_PUNCHINOUT); 643 HPI_OSTREAM_SET_PUNCHINOUT);
929 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 644 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
645 return HPI_ERROR_INVALID_HANDLE;
930 646
931 hm.u.d.u.pio.punch_in_sample = punch_in_sample; 647 hm.u.d.u.pio.punch_in_sample = punch_in_sample;
932 hm.u.d.u.pio.punch_out_sample = punch_out_sample; 648 hm.u.d.u.pio.punch_out_sample = punch_out_sample;
@@ -936,29 +652,29 @@ u16 hpi_outstream_set_punch_in_out(const struct hpi_hsubsys *ph_subsys,
936 return hr.error; 652 return hr.error;
937} 653}
938 654
939u16 hpi_outstream_ancillary_reset(const struct hpi_hsubsys *ph_subsys, 655u16 hpi_outstream_ancillary_reset(u32 h_outstream, u16 mode)
940 u32 h_outstream, u16 mode)
941{ 656{
942 struct hpi_message hm; 657 struct hpi_message hm;
943 struct hpi_response hr; 658 struct hpi_response hr;
944 659
945 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 660 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
946 HPI_OSTREAM_ANC_RESET); 661 HPI_OSTREAM_ANC_RESET);
947 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 662 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
663 return HPI_ERROR_INVALID_HANDLE;
948 hm.u.d.u.data.format.channels = mode; 664 hm.u.d.u.data.format.channels = mode;
949 hpi_send_recv(&hm, &hr); 665 hpi_send_recv(&hm, &hr);
950 return hr.error; 666 return hr.error;
951} 667}
952 668
953u16 hpi_outstream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys, 669u16 hpi_outstream_ancillary_get_info(u32 h_outstream, u32 *pframes_available)
954 u32 h_outstream, u32 *pframes_available)
955{ 670{
956 struct hpi_message hm; 671 struct hpi_message hm;
957 struct hpi_response hr; 672 struct hpi_response hr;
958 673
959 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 674 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
960 HPI_OSTREAM_ANC_GET_INFO); 675 HPI_OSTREAM_ANC_GET_INFO);
961 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 676 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
677 return HPI_ERROR_INVALID_HANDLE;
962 hpi_send_recv(&hm, &hr); 678 hpi_send_recv(&hm, &hr);
963 if (hr.error == 0) { 679 if (hr.error == 0) {
964 if (pframes_available) 680 if (pframes_available)
@@ -969,8 +685,8 @@ u16 hpi_outstream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
969 return hr.error; 685 return hr.error;
970} 686}
971 687
972u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys, 688u16 hpi_outstream_ancillary_read(u32 h_outstream,
973 u32 h_outstream, struct hpi_anc_frame *p_anc_frame_buffer, 689 struct hpi_anc_frame *p_anc_frame_buffer,
974 u32 anc_frame_buffer_size_in_bytes, 690 u32 anc_frame_buffer_size_in_bytes,
975 u32 number_of_ancillary_frames_to_read) 691 u32 number_of_ancillary_frames_to_read)
976{ 692{
@@ -979,7 +695,8 @@ u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys,
979 695
980 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 696 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
981 HPI_OSTREAM_ANC_READ); 697 HPI_OSTREAM_ANC_READ);
982 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 698 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
699 return HPI_ERROR_INVALID_HANDLE;
983 hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer; 700 hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer;
984 hm.u.d.u.data.data_size = 701 hm.u.d.u.data.data_size =
985 number_of_ancillary_frames_to_read * 702 number_of_ancillary_frames_to_read *
@@ -987,19 +704,19 @@ u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys,
987 if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes) 704 if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes)
988 hpi_send_recv(&hm, &hr); 705 hpi_send_recv(&hm, &hr);
989 else 706 else
990 hr.error = HPI_ERROR_INVALID_DATA_TRANSFER; 707 hr.error = HPI_ERROR_INVALID_DATASIZE;
991 return hr.error; 708 return hr.error;
992} 709}
993 710
994u16 hpi_outstream_set_time_scale(const struct hpi_hsubsys *ph_subsys, 711u16 hpi_outstream_set_time_scale(u32 h_outstream, u32 time_scale)
995 u32 h_outstream, u32 time_scale)
996{ 712{
997 struct hpi_message hm; 713 struct hpi_message hm;
998 struct hpi_response hr; 714 struct hpi_response hr;
999 715
1000 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 716 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1001 HPI_OSTREAM_SET_TIMESCALE); 717 HPI_OSTREAM_SET_TIMESCALE);
1002 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 718 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
719 return HPI_ERROR_INVALID_HANDLE;
1003 720
1004 hm.u.d.u.time_scale = time_scale; 721 hm.u.d.u.time_scale = time_scale;
1005 722
@@ -1008,22 +725,21 @@ u16 hpi_outstream_set_time_scale(const struct hpi_hsubsys *ph_subsys,
1008 return hr.error; 725 return hr.error;
1009} 726}
1010 727
1011u16 hpi_outstream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys, 728u16 hpi_outstream_host_buffer_allocate(u32 h_outstream, u32 size_in_bytes)
1012 u32 h_outstream, u32 size_in_bytes)
1013{ 729{
1014 struct hpi_message hm; 730 struct hpi_message hm;
1015 struct hpi_response hr; 731 struct hpi_response hr;
1016 732
1017 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 733 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1018 HPI_OSTREAM_HOSTBUFFER_ALLOC); 734 HPI_OSTREAM_HOSTBUFFER_ALLOC);
1019 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 735 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
736 return HPI_ERROR_INVALID_HANDLE;
1020 hm.u.d.u.data.data_size = size_in_bytes; 737 hm.u.d.u.data.data_size = size_in_bytes;
1021 hpi_send_recv(&hm, &hr); 738 hpi_send_recv(&hm, &hr);
1022 return hr.error; 739 return hr.error;
1023} 740}
1024 741
1025u16 hpi_outstream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys, 742u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer,
1026 u32 h_outstream, u8 **pp_buffer,
1027 struct hpi_hostbuffer_status **pp_status) 743 struct hpi_hostbuffer_status **pp_status)
1028{ 744{
1029 struct hpi_message hm; 745 struct hpi_message hm;
@@ -1031,7 +747,8 @@ u16 hpi_outstream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1031 747
1032 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 748 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1033 HPI_OSTREAM_HOSTBUFFER_GET_INFO); 749 HPI_OSTREAM_HOSTBUFFER_GET_INFO);
1034 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 750 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
751 return HPI_ERROR_INVALID_HANDLE;
1035 hpi_send_recv(&hm, &hr); 752 hpi_send_recv(&hm, &hr);
1036 753
1037 if (hr.error == 0) { 754 if (hr.error == 0) {
@@ -1043,21 +760,20 @@ u16 hpi_outstream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1043 return hr.error; 760 return hr.error;
1044} 761}
1045 762
1046u16 hpi_outstream_host_buffer_free(const struct hpi_hsubsys *ph_subsys, 763u16 hpi_outstream_host_buffer_free(u32 h_outstream)
1047 u32 h_outstream)
1048{ 764{
1049 struct hpi_message hm; 765 struct hpi_message hm;
1050 struct hpi_response hr; 766 struct hpi_response hr;
1051 767
1052 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 768 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1053 HPI_OSTREAM_HOSTBUFFER_FREE); 769 HPI_OSTREAM_HOSTBUFFER_FREE);
1054 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 770 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
771 return HPI_ERROR_INVALID_HANDLE;
1055 hpi_send_recv(&hm, &hr); 772 hpi_send_recv(&hm, &hr);
1056 return hr.error; 773 return hr.error;
1057} 774}
1058 775
1059u16 hpi_outstream_group_add(const struct hpi_hsubsys *ph_subsys, 776u16 hpi_outstream_group_add(u32 h_outstream, u32 h_stream)
1060 u32 h_outstream, u32 h_stream)
1061{ 777{
1062 struct hpi_message hm; 778 struct hpi_message hm;
1063 struct hpi_response hr; 779 struct hpi_response hr;
@@ -1066,22 +782,22 @@ u16 hpi_outstream_group_add(const struct hpi_hsubsys *ph_subsys,
1066 782
1067 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 783 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1068 HPI_OSTREAM_GROUP_ADD); 784 HPI_OSTREAM_GROUP_ADD);
1069 hr.error = 0; 785
1070 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 786 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
787 return HPI_ERROR_INVALID_HANDLE;
788
789 if (hpi_handle_indexes(h_stream, &adapter,
790 &hm.u.d.u.stream.stream_index))
791 return HPI_ERROR_INVALID_HANDLE;
792
1071 c_obj_type = hpi_handle_object(h_stream); 793 c_obj_type = hpi_handle_object(h_stream);
1072 switch (c_obj_type) { 794 switch (c_obj_type) {
1073 case HPI_OBJ_OSTREAM: 795 case HPI_OBJ_OSTREAM:
1074 hm.u.d.u.stream.object_type = HPI_OBJ_OSTREAM;
1075 u32TOINDEXES(h_stream, &adapter,
1076 &hm.u.d.u.stream.stream_index);
1077 break;
1078 case HPI_OBJ_ISTREAM: 796 case HPI_OBJ_ISTREAM:
1079 hm.u.d.u.stream.object_type = HPI_OBJ_ISTREAM; 797 hm.u.d.u.stream.object_type = c_obj_type;
1080 u32TOINDEXES(h_stream, &adapter,
1081 &hm.u.d.u.stream.stream_index);
1082 break; 798 break;
1083 default: 799 default:
1084 return HPI_ERROR_INVALID_STREAM; 800 return HPI_ERROR_INVALID_OBJ;
1085 } 801 }
1086 if (adapter != hm.adapter_index) 802 if (adapter != hm.adapter_index)
1087 return HPI_ERROR_NO_INTERADAPTER_GROUPS; 803 return HPI_ERROR_NO_INTERADAPTER_GROUPS;
@@ -1090,15 +806,16 @@ u16 hpi_outstream_group_add(const struct hpi_hsubsys *ph_subsys,
1090 return hr.error; 806 return hr.error;
1091} 807}
1092 808
1093u16 hpi_outstream_group_get_map(const struct hpi_hsubsys *ph_subsys, 809u16 hpi_outstream_group_get_map(u32 h_outstream, u32 *poutstream_map,
1094 u32 h_outstream, u32 *poutstream_map, u32 *pinstream_map) 810 u32 *pinstream_map)
1095{ 811{
1096 struct hpi_message hm; 812 struct hpi_message hm;
1097 struct hpi_response hr; 813 struct hpi_response hr;
1098 814
1099 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 815 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1100 HPI_OSTREAM_GROUP_GETMAP); 816 HPI_OSTREAM_GROUP_GETMAP);
1101 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 817 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
818 return HPI_ERROR_INVALID_HANDLE;
1102 hpi_send_recv(&hm, &hr); 819 hpi_send_recv(&hm, &hr);
1103 820
1104 if (poutstream_map) 821 if (poutstream_map)
@@ -1109,21 +826,20 @@ u16 hpi_outstream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1109 return hr.error; 826 return hr.error;
1110} 827}
1111 828
1112u16 hpi_outstream_group_reset(const struct hpi_hsubsys *ph_subsys, 829u16 hpi_outstream_group_reset(u32 h_outstream)
1113 u32 h_outstream)
1114{ 830{
1115 struct hpi_message hm; 831 struct hpi_message hm;
1116 struct hpi_response hr; 832 struct hpi_response hr;
1117 833
1118 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 834 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1119 HPI_OSTREAM_GROUP_RESET); 835 HPI_OSTREAM_GROUP_RESET);
1120 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 836 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
837 return HPI_ERROR_INVALID_HANDLE;
1121 hpi_send_recv(&hm, &hr); 838 hpi_send_recv(&hm, &hr);
1122 return hr.error; 839 return hr.error;
1123} 840}
1124 841
1125u16 hpi_instream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index, 842u16 hpi_instream_open(u16 adapter_index, u16 instream_index, u32 *ph_instream)
1126 u16 instream_index, u32 *ph_instream)
1127{ 843{
1128 struct hpi_message hm; 844 struct hpi_message hm;
1129 struct hpi_response hr; 845 struct hpi_response hr;
@@ -1145,38 +861,40 @@ u16 hpi_instream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1145 return hr.error; 861 return hr.error;
1146} 862}
1147 863
1148u16 hpi_instream_close(const struct hpi_hsubsys *ph_subsys, u32 h_instream) 864u16 hpi_instream_close(u32 h_instream)
1149{ 865{
1150 struct hpi_message hm; 866 struct hpi_message hm;
1151 struct hpi_response hr; 867 struct hpi_response hr;
1152 868
1153 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 869 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1154 HPI_ISTREAM_HOSTBUFFER_FREE); 870 HPI_ISTREAM_HOSTBUFFER_FREE);
1155 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 871 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
872 return HPI_ERROR_INVALID_HANDLE;
1156 hpi_send_recv(&hm, &hr); 873 hpi_send_recv(&hm, &hr);
1157 874
1158 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 875 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1159 HPI_ISTREAM_GROUP_RESET); 876 HPI_ISTREAM_GROUP_RESET);
1160 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 877 hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index);
1161 hpi_send_recv(&hm, &hr); 878 hpi_send_recv(&hm, &hr);
1162 879
1163 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 880 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1164 HPI_ISTREAM_CLOSE); 881 HPI_ISTREAM_CLOSE);
1165 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 882 hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index);
1166 hpi_send_recv(&hm, &hr); 883 hpi_send_recv(&hm, &hr);
1167 884
1168 return hr.error; 885 return hr.error;
1169} 886}
1170 887
1171u16 hpi_instream_query_format(const struct hpi_hsubsys *ph_subsys, 888u16 hpi_instream_query_format(u32 h_instream,
1172 u32 h_instream, const struct hpi_format *p_format) 889 const struct hpi_format *p_format)
1173{ 890{
1174 struct hpi_message hm; 891 struct hpi_message hm;
1175 struct hpi_response hr; 892 struct hpi_response hr;
1176 893
1177 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 894 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1178 HPI_ISTREAM_QUERY_FORMAT); 895 HPI_ISTREAM_QUERY_FORMAT);
1179 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 896 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
897 return HPI_ERROR_INVALID_HANDLE;
1180 hpi_format_to_msg(&hm.u.d.u.data.format, p_format); 898 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
1181 899
1182 hpi_send_recv(&hm, &hr); 900 hpi_send_recv(&hm, &hr);
@@ -1184,15 +902,15 @@ u16 hpi_instream_query_format(const struct hpi_hsubsys *ph_subsys,
1184 return hr.error; 902 return hr.error;
1185} 903}
1186 904
1187u16 hpi_instream_set_format(const struct hpi_hsubsys *ph_subsys, 905u16 hpi_instream_set_format(u32 h_instream, const struct hpi_format *p_format)
1188 u32 h_instream, const struct hpi_format *p_format)
1189{ 906{
1190 struct hpi_message hm; 907 struct hpi_message hm;
1191 struct hpi_response hr; 908 struct hpi_response hr;
1192 909
1193 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 910 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1194 HPI_ISTREAM_SET_FORMAT); 911 HPI_ISTREAM_SET_FORMAT);
1195 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 912 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
913 return HPI_ERROR_INVALID_HANDLE;
1196 hpi_format_to_msg(&hm.u.d.u.data.format, p_format); 914 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
1197 915
1198 hpi_send_recv(&hm, &hr); 916 hpi_send_recv(&hm, &hr);
@@ -1200,15 +918,15 @@ u16 hpi_instream_set_format(const struct hpi_hsubsys *ph_subsys,
1200 return hr.error; 918 return hr.error;
1201} 919}
1202 920
1203u16 hpi_instream_read_buf(const struct hpi_hsubsys *ph_subsys, u32 h_instream, 921u16 hpi_instream_read_buf(u32 h_instream, u8 *pb_data, u32 bytes_to_read)
1204 u8 *pb_data, u32 bytes_to_read)
1205{ 922{
1206 struct hpi_message hm; 923 struct hpi_message hm;
1207 struct hpi_response hr; 924 struct hpi_response hr;
1208 925
1209 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 926 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1210 HPI_ISTREAM_READ); 927 HPI_ISTREAM_READ);
1211 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 928 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
929 return HPI_ERROR_INVALID_HANDLE;
1212 hm.u.d.u.data.data_size = bytes_to_read; 930 hm.u.d.u.data.data_size = bytes_to_read;
1213 hm.u.d.u.data.pb_data = pb_data; 931 hm.u.d.u.data.pb_data = pb_data;
1214 932
@@ -1217,72 +935,76 @@ u16 hpi_instream_read_buf(const struct hpi_hsubsys *ph_subsys, u32 h_instream,
1217 return hr.error; 935 return hr.error;
1218} 936}
1219 937
1220u16 hpi_instream_start(const struct hpi_hsubsys *ph_subsys, u32 h_instream) 938u16 hpi_instream_start(u32 h_instream)
1221{ 939{
1222 struct hpi_message hm; 940 struct hpi_message hm;
1223 struct hpi_response hr; 941 struct hpi_response hr;
1224 942
1225 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 943 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1226 HPI_ISTREAM_START); 944 HPI_ISTREAM_START);
1227 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 945 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
946 return HPI_ERROR_INVALID_HANDLE;
1228 947
1229 hpi_send_recv(&hm, &hr); 948 hpi_send_recv(&hm, &hr);
1230 949
1231 return hr.error; 950 return hr.error;
1232} 951}
1233 952
1234u16 hpi_instream_wait_start(const struct hpi_hsubsys *ph_subsys, 953u16 hpi_instream_wait_start(u32 h_instream)
1235 u32 h_instream)
1236{ 954{
1237 struct hpi_message hm; 955 struct hpi_message hm;
1238 struct hpi_response hr; 956 struct hpi_response hr;
1239 957
1240 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 958 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1241 HPI_ISTREAM_WAIT_START); 959 HPI_ISTREAM_WAIT_START);
1242 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 960 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
961 return HPI_ERROR_INVALID_HANDLE;
1243 962
1244 hpi_send_recv(&hm, &hr); 963 hpi_send_recv(&hm, &hr);
1245 964
1246 return hr.error; 965 return hr.error;
1247} 966}
1248 967
1249u16 hpi_instream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_instream) 968u16 hpi_instream_stop(u32 h_instream)
1250{ 969{
1251 struct hpi_message hm; 970 struct hpi_message hm;
1252 struct hpi_response hr; 971 struct hpi_response hr;
1253 972
1254 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 973 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1255 HPI_ISTREAM_STOP); 974 HPI_ISTREAM_STOP);
1256 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 975 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
976 return HPI_ERROR_INVALID_HANDLE;
1257 977
1258 hpi_send_recv(&hm, &hr); 978 hpi_send_recv(&hm, &hr);
1259 979
1260 return hr.error; 980 return hr.error;
1261} 981}
1262 982
1263u16 hpi_instream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_instream) 983u16 hpi_instream_reset(u32 h_instream)
1264{ 984{
1265 struct hpi_message hm; 985 struct hpi_message hm;
1266 struct hpi_response hr; 986 struct hpi_response hr;
1267 987
1268 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 988 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1269 HPI_ISTREAM_RESET); 989 HPI_ISTREAM_RESET);
1270 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 990 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
991 return HPI_ERROR_INVALID_HANDLE;
1271 992
1272 hpi_send_recv(&hm, &hr); 993 hpi_send_recv(&hm, &hr);
1273 994
1274 return hr.error; 995 return hr.error;
1275} 996}
1276 997
1277u16 hpi_instream_get_info_ex(const struct hpi_hsubsys *ph_subsys, 998u16 hpi_instream_get_info_ex(u32 h_instream, u16 *pw_state, u32 *pbuffer_size,
1278 u32 h_instream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_recorded, 999 u32 *pdata_recorded, u32 *psamples_recorded,
1279 u32 *psamples_recorded, u32 *pauxiliary_data_recorded) 1000 u32 *pauxiliary_data_recorded)
1280{ 1001{
1281 struct hpi_message hm; 1002 struct hpi_message hm;
1282 struct hpi_response hr; 1003 struct hpi_response hr;
1283 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1004 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1284 HPI_ISTREAM_GET_INFO); 1005 HPI_ISTREAM_GET_INFO);
1285 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1006 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1007 return HPI_ERROR_INVALID_HANDLE;
1286 1008
1287 hpi_send_recv(&hm, &hr); 1009 hpi_send_recv(&hm, &hr);
1288 1010
@@ -1300,15 +1022,15 @@ u16 hpi_instream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
1300 return hr.error; 1022 return hr.error;
1301} 1023}
1302 1024
1303u16 hpi_instream_ancillary_reset(const struct hpi_hsubsys *ph_subsys, 1025u16 hpi_instream_ancillary_reset(u32 h_instream, u16 bytes_per_frame,
1304 u32 h_instream, u16 bytes_per_frame, u16 mode, u16 alignment, 1026 u16 mode, u16 alignment, u16 idle_bit)
1305 u16 idle_bit)
1306{ 1027{
1307 struct hpi_message hm; 1028 struct hpi_message hm;
1308 struct hpi_response hr; 1029 struct hpi_response hr;
1309 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1030 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1310 HPI_ISTREAM_ANC_RESET); 1031 HPI_ISTREAM_ANC_RESET);
1311 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1032 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1033 return HPI_ERROR_INVALID_HANDLE;
1312 hm.u.d.u.data.format.attributes = bytes_per_frame; 1034 hm.u.d.u.data.format.attributes = bytes_per_frame;
1313 hm.u.d.u.data.format.format = (mode << 8) | (alignment & 0xff); 1035 hm.u.d.u.data.format.format = (mode << 8) | (alignment & 0xff);
1314 hm.u.d.u.data.format.channels = idle_bit; 1036 hm.u.d.u.data.format.channels = idle_bit;
@@ -1316,14 +1038,14 @@ u16 hpi_instream_ancillary_reset(const struct hpi_hsubsys *ph_subsys,
1316 return hr.error; 1038 return hr.error;
1317} 1039}
1318 1040
1319u16 hpi_instream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys, 1041u16 hpi_instream_ancillary_get_info(u32 h_instream, u32 *pframe_space)
1320 u32 h_instream, u32 *pframe_space)
1321{ 1042{
1322 struct hpi_message hm; 1043 struct hpi_message hm;
1323 struct hpi_response hr; 1044 struct hpi_response hr;
1324 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1045 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1325 HPI_ISTREAM_ANC_GET_INFO); 1046 HPI_ISTREAM_ANC_GET_INFO);
1326 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1047 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1048 return HPI_ERROR_INVALID_HANDLE;
1327 hpi_send_recv(&hm, &hr); 1049 hpi_send_recv(&hm, &hr);
1328 if (pframe_space) 1050 if (pframe_space)
1329 *pframe_space = 1051 *pframe_space =
@@ -1333,8 +1055,8 @@ u16 hpi_instream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
1333 return hr.error; 1055 return hr.error;
1334} 1056}
1335 1057
1336u16 hpi_instream_ancillary_write(const struct hpi_hsubsys *ph_subsys, 1058u16 hpi_instream_ancillary_write(u32 h_instream,
1337 u32 h_instream, const struct hpi_anc_frame *p_anc_frame_buffer, 1059 const struct hpi_anc_frame *p_anc_frame_buffer,
1338 u32 anc_frame_buffer_size_in_bytes, 1060 u32 anc_frame_buffer_size_in_bytes,
1339 u32 number_of_ancillary_frames_to_write) 1061 u32 number_of_ancillary_frames_to_write)
1340{ 1062{
@@ -1343,7 +1065,8 @@ u16 hpi_instream_ancillary_write(const struct hpi_hsubsys *ph_subsys,
1343 1065
1344 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1066 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1345 HPI_ISTREAM_ANC_WRITE); 1067 HPI_ISTREAM_ANC_WRITE);
1346 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1068 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1069 return HPI_ERROR_INVALID_HANDLE;
1347 hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer; 1070 hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer;
1348 hm.u.d.u.data.data_size = 1071 hm.u.d.u.data.data_size =
1349 number_of_ancillary_frames_to_write * 1072 number_of_ancillary_frames_to_write *
@@ -1351,12 +1074,11 @@ u16 hpi_instream_ancillary_write(const struct hpi_hsubsys *ph_subsys,
1351 if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes) 1074 if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes)
1352 hpi_send_recv(&hm, &hr); 1075 hpi_send_recv(&hm, &hr);
1353 else 1076 else
1354 hr.error = HPI_ERROR_INVALID_DATA_TRANSFER; 1077 hr.error = HPI_ERROR_INVALID_DATASIZE;
1355 return hr.error; 1078 return hr.error;
1356} 1079}
1357 1080
1358u16 hpi_instream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys, 1081u16 hpi_instream_host_buffer_allocate(u32 h_instream, u32 size_in_bytes)
1359 u32 h_instream, u32 size_in_bytes)
1360{ 1082{
1361 1083
1362 struct hpi_message hm; 1084 struct hpi_message hm;
@@ -1364,14 +1086,14 @@ u16 hpi_instream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys,
1364 1086
1365 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1087 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1366 HPI_ISTREAM_HOSTBUFFER_ALLOC); 1088 HPI_ISTREAM_HOSTBUFFER_ALLOC);
1367 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1089 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1090 return HPI_ERROR_INVALID_HANDLE;
1368 hm.u.d.u.data.data_size = size_in_bytes; 1091 hm.u.d.u.data.data_size = size_in_bytes;
1369 hpi_send_recv(&hm, &hr); 1092 hpi_send_recv(&hm, &hr);
1370 return hr.error; 1093 return hr.error;
1371} 1094}
1372 1095
1373u16 hpi_instream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys, 1096u16 hpi_instream_host_buffer_get_info(u32 h_instream, u8 **pp_buffer,
1374 u32 h_instream, u8 **pp_buffer,
1375 struct hpi_hostbuffer_status **pp_status) 1097 struct hpi_hostbuffer_status **pp_status)
1376{ 1098{
1377 struct hpi_message hm; 1099 struct hpi_message hm;
@@ -1379,7 +1101,8 @@ u16 hpi_instream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1379 1101
1380 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1102 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1381 HPI_ISTREAM_HOSTBUFFER_GET_INFO); 1103 HPI_ISTREAM_HOSTBUFFER_GET_INFO);
1382 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1104 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1105 return HPI_ERROR_INVALID_HANDLE;
1383 hpi_send_recv(&hm, &hr); 1106 hpi_send_recv(&hm, &hr);
1384 1107
1385 if (hr.error == 0) { 1108 if (hr.error == 0) {
@@ -1391,8 +1114,7 @@ u16 hpi_instream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1391 return hr.error; 1114 return hr.error;
1392} 1115}
1393 1116
1394u16 hpi_instream_host_buffer_free(const struct hpi_hsubsys *ph_subsys, 1117u16 hpi_instream_host_buffer_free(u32 h_instream)
1395 u32 h_instream)
1396{ 1118{
1397 1119
1398 struct hpi_message hm; 1120 struct hpi_message hm;
@@ -1400,13 +1122,13 @@ u16 hpi_instream_host_buffer_free(const struct hpi_hsubsys *ph_subsys,
1400 1122
1401 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1123 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1402 HPI_ISTREAM_HOSTBUFFER_FREE); 1124 HPI_ISTREAM_HOSTBUFFER_FREE);
1403 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1125 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1126 return HPI_ERROR_INVALID_HANDLE;
1404 hpi_send_recv(&hm, &hr); 1127 hpi_send_recv(&hm, &hr);
1405 return hr.error; 1128 return hr.error;
1406} 1129}
1407 1130
1408u16 hpi_instream_group_add(const struct hpi_hsubsys *ph_subsys, 1131u16 hpi_instream_group_add(u32 h_instream, u32 h_stream)
1409 u32 h_instream, u32 h_stream)
1410{ 1132{
1411 struct hpi_message hm; 1133 struct hpi_message hm;
1412 struct hpi_response hr; 1134 struct hpi_response hr;
@@ -1416,22 +1138,23 @@ u16 hpi_instream_group_add(const struct hpi_hsubsys *ph_subsys,
1416 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1138 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1417 HPI_ISTREAM_GROUP_ADD); 1139 HPI_ISTREAM_GROUP_ADD);
1418 hr.error = 0; 1140 hr.error = 0;
1419 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1141
1142 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1143 return HPI_ERROR_INVALID_HANDLE;
1144
1145 if (hpi_handle_indexes(h_stream, &adapter,
1146 &hm.u.d.u.stream.stream_index))
1147 return HPI_ERROR_INVALID_HANDLE;
1148
1420 c_obj_type = hpi_handle_object(h_stream); 1149 c_obj_type = hpi_handle_object(h_stream);
1421 1150
1422 switch (c_obj_type) { 1151 switch (c_obj_type) {
1423 case HPI_OBJ_OSTREAM: 1152 case HPI_OBJ_OSTREAM:
1424 hm.u.d.u.stream.object_type = HPI_OBJ_OSTREAM;
1425 u32TOINDEXES(h_stream, &adapter,
1426 &hm.u.d.u.stream.stream_index);
1427 break;
1428 case HPI_OBJ_ISTREAM: 1153 case HPI_OBJ_ISTREAM:
1429 hm.u.d.u.stream.object_type = HPI_OBJ_ISTREAM; 1154 hm.u.d.u.stream.object_type = c_obj_type;
1430 u32TOINDEXES(h_stream, &adapter,
1431 &hm.u.d.u.stream.stream_index);
1432 break; 1155 break;
1433 default: 1156 default:
1434 return HPI_ERROR_INVALID_STREAM; 1157 return HPI_ERROR_INVALID_OBJ;
1435 } 1158 }
1436 1159
1437 if (adapter != hm.adapter_index) 1160 if (adapter != hm.adapter_index)
@@ -1441,15 +1164,16 @@ u16 hpi_instream_group_add(const struct hpi_hsubsys *ph_subsys,
1441 return hr.error; 1164 return hr.error;
1442} 1165}
1443 1166
1444u16 hpi_instream_group_get_map(const struct hpi_hsubsys *ph_subsys, 1167u16 hpi_instream_group_get_map(u32 h_instream, u32 *poutstream_map,
1445 u32 h_instream, u32 *poutstream_map, u32 *pinstream_map) 1168 u32 *pinstream_map)
1446{ 1169{
1447 struct hpi_message hm; 1170 struct hpi_message hm;
1448 struct hpi_response hr; 1171 struct hpi_response hr;
1449 1172
1450 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1173 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1451 HPI_ISTREAM_HOSTBUFFER_FREE); 1174 HPI_ISTREAM_HOSTBUFFER_FREE);
1452 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1175 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1176 return HPI_ERROR_INVALID_HANDLE;
1453 hpi_send_recv(&hm, &hr); 1177 hpi_send_recv(&hm, &hr);
1454 1178
1455 if (poutstream_map) 1179 if (poutstream_map)
@@ -1460,21 +1184,20 @@ u16 hpi_instream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1460 return hr.error; 1184 return hr.error;
1461} 1185}
1462 1186
1463u16 hpi_instream_group_reset(const struct hpi_hsubsys *ph_subsys, 1187u16 hpi_instream_group_reset(u32 h_instream)
1464 u32 h_instream)
1465{ 1188{
1466 struct hpi_message hm; 1189 struct hpi_message hm;
1467 struct hpi_response hr; 1190 struct hpi_response hr;
1468 1191
1469 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1192 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1470 HPI_ISTREAM_GROUP_RESET); 1193 HPI_ISTREAM_GROUP_RESET);
1471 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1194 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1195 return HPI_ERROR_INVALID_HANDLE;
1472 hpi_send_recv(&hm, &hr); 1196 hpi_send_recv(&hm, &hr);
1473 return hr.error; 1197 return hr.error;
1474} 1198}
1475 1199
1476u16 hpi_mixer_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index, 1200u16 hpi_mixer_open(u16 adapter_index, u32 *ph_mixer)
1477 u32 *ph_mixer)
1478{ 1201{
1479 struct hpi_message hm; 1202 struct hpi_message hm;
1480 struct hpi_response hr; 1203 struct hpi_response hr;
@@ -1492,25 +1215,29 @@ u16 hpi_mixer_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1492 return hr.error; 1215 return hr.error;
1493} 1216}
1494 1217
1495u16 hpi_mixer_close(const struct hpi_hsubsys *ph_subsys, u32 h_mixer) 1218u16 hpi_mixer_close(u32 h_mixer)
1496{ 1219{
1497 struct hpi_message hm; 1220 struct hpi_message hm;
1498 struct hpi_response hr; 1221 struct hpi_response hr;
1222
1499 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE); 1223 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE);
1500 u32TOINDEX(h_mixer, &hm.adapter_index); 1224 if (hpi_handle_indexes(h_mixer, &hm.adapter_index, NULL))
1225 return HPI_ERROR_INVALID_HANDLE;
1226
1501 hpi_send_recv(&hm, &hr); 1227 hpi_send_recv(&hm, &hr);
1502 return hr.error; 1228 return hr.error;
1503} 1229}
1504 1230
1505u16 hpi_mixer_get_control(const struct hpi_hsubsys *ph_subsys, u32 h_mixer, 1231u16 hpi_mixer_get_control(u32 h_mixer, u16 src_node_type,
1506 u16 src_node_type, u16 src_node_type_index, u16 dst_node_type, 1232 u16 src_node_type_index, u16 dst_node_type, u16 dst_node_type_index,
1507 u16 dst_node_type_index, u16 control_type, u32 *ph_control) 1233 u16 control_type, u32 *ph_control)
1508{ 1234{
1509 struct hpi_message hm; 1235 struct hpi_message hm;
1510 struct hpi_response hr; 1236 struct hpi_response hr;
1511 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, 1237 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER,
1512 HPI_MIXER_GET_CONTROL); 1238 HPI_MIXER_GET_CONTROL);
1513 u32TOINDEX(h_mixer, &hm.adapter_index); 1239 if (hpi_handle_indexes(h_mixer, &hm.adapter_index, NULL))
1240 return HPI_ERROR_INVALID_HANDLE;
1514 hm.u.m.node_type1 = src_node_type; 1241 hm.u.m.node_type1 = src_node_type;
1515 hm.u.m.node_index1 = src_node_type_index; 1242 hm.u.m.node_index1 = src_node_type_index;
1516 hm.u.m.node_type2 = dst_node_type; 1243 hm.u.m.node_type2 = dst_node_type;
@@ -1528,16 +1255,16 @@ u16 hpi_mixer_get_control(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1528 return hr.error; 1255 return hr.error;
1529} 1256}
1530 1257
1531u16 hpi_mixer_get_control_by_index(const struct hpi_hsubsys *ph_subsys, 1258u16 hpi_mixer_get_control_by_index(u32 h_mixer, u16 control_index,
1532 u32 h_mixer, u16 control_index, u16 *pw_src_node_type, 1259 u16 *pw_src_node_type, u16 *pw_src_node_index, u16 *pw_dst_node_type,
1533 u16 *pw_src_node_index, u16 *pw_dst_node_type, u16 *pw_dst_node_index, 1260 u16 *pw_dst_node_index, u16 *pw_control_type, u32 *ph_control)
1534 u16 *pw_control_type, u32 *ph_control)
1535{ 1261{
1536 struct hpi_message hm; 1262 struct hpi_message hm;
1537 struct hpi_response hr; 1263 struct hpi_response hr;
1538 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, 1264 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER,
1539 HPI_MIXER_GET_CONTROL_BY_INDEX); 1265 HPI_MIXER_GET_CONTROL_BY_INDEX);
1540 u32TOINDEX(h_mixer, &hm.adapter_index); 1266 if (hpi_handle_indexes(h_mixer, &hm.adapter_index, NULL))
1267 return HPI_ERROR_INVALID_HANDLE;
1541 hm.u.m.control_index = control_index; 1268 hm.u.m.control_index = control_index;
1542 hpi_send_recv(&hm, &hr); 1269 hpi_send_recv(&hm, &hr);
1543 1270
@@ -1562,13 +1289,14 @@ u16 hpi_mixer_get_control_by_index(const struct hpi_hsubsys *ph_subsys,
1562 return hr.error; 1289 return hr.error;
1563} 1290}
1564 1291
1565u16 hpi_mixer_store(const struct hpi_hsubsys *ph_subsys, u32 h_mixer, 1292u16 hpi_mixer_store(u32 h_mixer, enum HPI_MIXER_STORE_COMMAND command,
1566 enum HPI_MIXER_STORE_COMMAND command, u16 index) 1293 u16 index)
1567{ 1294{
1568 struct hpi_message hm; 1295 struct hpi_message hm;
1569 struct hpi_response hr; 1296 struct hpi_response hr;
1570 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_STORE); 1297 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_STORE);
1571 u32TOINDEX(h_mixer, &hm.adapter_index); 1298 if (hpi_handle_indexes(h_mixer, &hm.adapter_index, NULL))
1299 return HPI_ERROR_INVALID_HANDLE;
1572 hm.u.mx.store.command = command; 1300 hm.u.mx.store.command = command;
1573 hm.u.mx.store.index = index; 1301 hm.u.mx.store.index = index;
1574 hpi_send_recv(&hm, &hr); 1302 hpi_send_recv(&hm, &hr);
@@ -1576,16 +1304,16 @@ u16 hpi_mixer_store(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1576} 1304}
1577 1305
1578static 1306static
1579u16 hpi_control_param_set(const struct hpi_hsubsys *ph_subsys, 1307u16 hpi_control_param_set(const u32 h_control, const u16 attrib,
1580 const u32 h_control, const u16 attrib, const u32 param1, 1308 const u32 param1, const u32 param2)
1581 const u32 param2)
1582{ 1309{
1583 struct hpi_message hm; 1310 struct hpi_message hm;
1584 struct hpi_response hr; 1311 struct hpi_response hr;
1585 1312
1586 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1313 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1587 HPI_CONTROL_SET_STATE); 1314 HPI_CONTROL_SET_STATE);
1588 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1315 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1316 return HPI_ERROR_INVALID_HANDLE;
1589 hm.u.c.attribute = attrib; 1317 hm.u.c.attribute = attrib;
1590 hm.u.c.param1 = param1; 1318 hm.u.c.param1 = param1;
1591 hm.u.c.param2 = param2; 1319 hm.u.c.param2 = param2;
@@ -1601,7 +1329,8 @@ static u16 hpi_control_log_set2(u32 h_control, u16 attrib, short sv0,
1601 1329
1602 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1330 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1603 HPI_CONTROL_SET_STATE); 1331 HPI_CONTROL_SET_STATE);
1604 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1332 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1333 return HPI_ERROR_INVALID_HANDLE;
1605 hm.u.c.attribute = attrib; 1334 hm.u.c.attribute = attrib;
1606 hm.u.c.an_log_value[0] = sv0; 1335 hm.u.c.an_log_value[0] = sv0;
1607 hm.u.c.an_log_value[1] = sv1; 1336 hm.u.c.an_log_value[1] = sv1;
@@ -1610,16 +1339,16 @@ static u16 hpi_control_log_set2(u32 h_control, u16 attrib, short sv0,
1610} 1339}
1611 1340
1612static 1341static
1613u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys, 1342u16 hpi_control_param_get(const u32 h_control, const u16 attrib, u32 param1,
1614 const u32 h_control, const u16 attrib, u32 param1, u32 param2, 1343 u32 param2, u32 *pparam1, u32 *pparam2)
1615 u32 *pparam1, u32 *pparam2)
1616{ 1344{
1617 struct hpi_message hm; 1345 struct hpi_message hm;
1618 struct hpi_response hr; 1346 struct hpi_response hr;
1619 1347
1620 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1348 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1621 HPI_CONTROL_GET_STATE); 1349 HPI_CONTROL_GET_STATE);
1622 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1350 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1351 return HPI_ERROR_INVALID_HANDLE;
1623 hm.u.c.attribute = attrib; 1352 hm.u.c.attribute = attrib;
1624 hm.u.c.param1 = param1; 1353 hm.u.c.param1 = param1;
1625 hm.u.c.param2 = param2; 1354 hm.u.c.param2 = param2;
@@ -1632,19 +1361,20 @@ u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys,
1632 return hr.error; 1361 return hr.error;
1633} 1362}
1634 1363
1635#define hpi_control_param1_get(s, h, a, p1) \ 1364#define hpi_control_param1_get(h, a, p1) \
1636 hpi_control_param_get(s, h, a, 0, 0, p1, NULL) 1365 hpi_control_param_get(h, a, 0, 0, p1, NULL)
1637#define hpi_control_param2_get(s, h, a, p1, p2) \ 1366#define hpi_control_param2_get(h, a, p1, p2) \
1638 hpi_control_param_get(s, h, a, 0, 0, p1, p2) 1367 hpi_control_param_get(h, a, 0, 0, p1, p2)
1639 1368
1640static u16 hpi_control_log_get2(const struct hpi_hsubsys *ph_subsys, 1369static u16 hpi_control_log_get2(u32 h_control, u16 attrib, short *sv0,
1641 u32 h_control, u16 attrib, short *sv0, short *sv1) 1370 short *sv1)
1642{ 1371{
1643 struct hpi_message hm; 1372 struct hpi_message hm;
1644 struct hpi_response hr; 1373 struct hpi_response hr;
1645 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1374 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1646 HPI_CONTROL_GET_STATE); 1375 HPI_CONTROL_GET_STATE);
1647 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1376 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1377 return HPI_ERROR_INVALID_HANDLE;
1648 hm.u.c.attribute = attrib; 1378 hm.u.c.attribute = attrib;
1649 1379
1650 hpi_send_recv(&hm, &hr); 1380 hpi_send_recv(&hm, &hr);
@@ -1655,8 +1385,7 @@ static u16 hpi_control_log_get2(const struct hpi_hsubsys *ph_subsys,
1655} 1385}
1656 1386
1657static 1387static
1658u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys, 1388u16 hpi_control_query(const u32 h_control, const u16 attrib, const u32 index,
1659 const u32 h_control, const u16 attrib, const u32 index,
1660 const u32 param, u32 *psetting) 1389 const u32 param, u32 *psetting)
1661{ 1390{
1662 struct hpi_message hm; 1391 struct hpi_message hm;
@@ -1664,7 +1393,8 @@ u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys,
1664 1393
1665 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1394 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1666 HPI_CONTROL_GET_INFO); 1395 HPI_CONTROL_GET_INFO);
1667 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1396 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1397 return HPI_ERROR_INVALID_HANDLE;
1668 1398
1669 hm.u.c.attribute = attrib; 1399 hm.u.c.attribute = attrib;
1670 hm.u.c.param1 = index; 1400 hm.u.c.param1 = index;
@@ -1682,7 +1412,7 @@ static u16 hpi_control_get_string(const u32 h_control, const u16 attribute,
1682 unsigned int sub_string_index = 0, j = 0; 1412 unsigned int sub_string_index = 0, j = 0;
1683 char c = 0; 1413 char c = 0;
1684 unsigned int n = 0; 1414 unsigned int n = 0;
1685 u16 hE = 0; 1415 u16 err = 0;
1686 1416
1687 if ((string_length < 1) || (string_length > 256)) 1417 if ((string_length < 1) || (string_length > 256))
1688 return HPI_ERROR_INVALID_CONTROL_VALUE; 1418 return HPI_ERROR_INVALID_CONTROL_VALUE;
@@ -1693,7 +1423,9 @@ static u16 hpi_control_get_string(const u32 h_control, const u16 attribute,
1693 1423
1694 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1424 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1695 HPI_CONTROL_GET_STATE); 1425 HPI_CONTROL_GET_STATE);
1696 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1426 if (hpi_handle_indexes(h_control, &hm.adapter_index,
1427 &hm.obj_index))
1428 return HPI_ERROR_INVALID_HANDLE;
1697 hm.u.c.attribute = attribute; 1429 hm.u.c.attribute = attribute;
1698 hm.u.c.param1 = sub_string_index; 1430 hm.u.c.param1 = sub_string_index;
1699 hm.u.c.param2 = 0; 1431 hm.u.c.param2 = 0;
@@ -1705,7 +1437,7 @@ static u16 hpi_control_get_string(const u32 h_control, const u16 attribute,
1705 return HPI_ERROR_INVALID_CONTROL_VALUE; 1437 return HPI_ERROR_INVALID_CONTROL_VALUE;
1706 1438
1707 if (hr.error) { 1439 if (hr.error) {
1708 hE = hr.error; 1440 err = hr.error;
1709 break; 1441 break;
1710 } 1442 }
1711 for (j = 0; j < 8; j++) { 1443 for (j = 0; j < 8; j++) {
@@ -1714,7 +1446,7 @@ static u16 hpi_control_get_string(const u32 h_control, const u16 attribute,
1714 n++; 1446 n++;
1715 if (n >= string_length) { 1447 if (n >= string_length) {
1716 psz_string[string_length - 1] = 0; 1448 psz_string[string_length - 1] = 0;
1717 hE = HPI_ERROR_INVALID_CONTROL_VALUE; 1449 err = HPI_ERROR_INVALID_CONTROL_VALUE;
1718 break; 1450 break;
1719 } 1451 }
1720 if (c == 0) 1452 if (c == 0)
@@ -1730,57 +1462,52 @@ static u16 hpi_control_get_string(const u32 h_control, const u16 attribute,
1730 if (c == 0) 1462 if (c == 0)
1731 break; 1463 break;
1732 } 1464 }
1733 return hE; 1465 return err;
1734} 1466}
1735 1467
1736u16 HPI_AESEBU__receiver_query_format(const struct hpi_hsubsys *ph_subsys, 1468u16 hpi_aesebu_receiver_query_format(const u32 h_aes_rx, const u32 index,
1737 const u32 h_aes_rx, const u32 index, u16 *pw_format) 1469 u16 *pw_format)
1738{ 1470{
1739 u32 qr; 1471 u32 qr;
1740 u16 err; 1472 u16 err;
1741 1473
1742 err = hpi_control_query(ph_subsys, h_aes_rx, HPI_AESEBURX_FORMAT, 1474 err = hpi_control_query(h_aes_rx, HPI_AESEBURX_FORMAT, index, 0, &qr);
1743 index, 0, &qr);
1744 *pw_format = (u16)qr; 1475 *pw_format = (u16)qr;
1745 return err; 1476 return err;
1746} 1477}
1747 1478
1748u16 HPI_AESEBU__receiver_set_format(const struct hpi_hsubsys *ph_subsys, 1479u16 hpi_aesebu_receiver_set_format(u32 h_control, u16 format)
1749 u32 h_control, u16 format)
1750{ 1480{
1751 return hpi_control_param_set(ph_subsys, h_control, 1481 return hpi_control_param_set(h_control, HPI_AESEBURX_FORMAT, format,
1752 HPI_AESEBURX_FORMAT, format, 0); 1482 0);
1753} 1483}
1754 1484
1755u16 HPI_AESEBU__receiver_get_format(const struct hpi_hsubsys *ph_subsys, 1485u16 hpi_aesebu_receiver_get_format(u32 h_control, u16 *pw_format)
1756 u32 h_control, u16 *pw_format)
1757{ 1486{
1758 u16 err; 1487 u16 err;
1759 u32 param; 1488 u32 param;
1760 1489
1761 err = hpi_control_param1_get(ph_subsys, h_control, 1490 err = hpi_control_param1_get(h_control, HPI_AESEBURX_FORMAT, &param);
1762 HPI_AESEBURX_FORMAT, &param);
1763 if (!err && pw_format) 1491 if (!err && pw_format)
1764 *pw_format = (u16)param; 1492 *pw_format = (u16)param;
1765 1493
1766 return err; 1494 return err;
1767} 1495}
1768 1496
1769u16 HPI_AESEBU__receiver_get_sample_rate(const struct hpi_hsubsys *ph_subsys, 1497u16 hpi_aesebu_receiver_get_sample_rate(u32 h_control, u32 *psample_rate)
1770 u32 h_control, u32 *psample_rate)
1771{ 1498{
1772 return hpi_control_param1_get(ph_subsys, h_control, 1499 return hpi_control_param1_get(h_control, HPI_AESEBURX_SAMPLERATE,
1773 HPI_AESEBURX_SAMPLERATE, psample_rate); 1500 psample_rate);
1774} 1501}
1775 1502
1776u16 HPI_AESEBU__receiver_get_user_data(const struct hpi_hsubsys *ph_subsys, 1503u16 hpi_aesebu_receiver_get_user_data(u32 h_control, u16 index, u16 *pw_data)
1777 u32 h_control, u16 index, u16 *pw_data)
1778{ 1504{
1779 struct hpi_message hm; 1505 struct hpi_message hm;
1780 struct hpi_response hr; 1506 struct hpi_response hr;
1781 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1507 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1782 HPI_CONTROL_GET_STATE); 1508 HPI_CONTROL_GET_STATE);
1783 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1509 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1510 return HPI_ERROR_INVALID_HANDLE;
1784 hm.u.c.attribute = HPI_AESEBURX_USERDATA; 1511 hm.u.c.attribute = HPI_AESEBURX_USERDATA;
1785 hm.u.c.param1 = index; 1512 hm.u.c.param1 = index;
1786 1513
@@ -1791,14 +1518,15 @@ u16 HPI_AESEBU__receiver_get_user_data(const struct hpi_hsubsys *ph_subsys,
1791 return hr.error; 1518 return hr.error;
1792} 1519}
1793 1520
1794u16 HPI_AESEBU__receiver_get_channel_status(const struct hpi_hsubsys 1521u16 hpi_aesebu_receiver_get_channel_status(u32 h_control, u16 index,
1795 *ph_subsys, u32 h_control, u16 index, u16 *pw_data) 1522 u16 *pw_data)
1796{ 1523{
1797 struct hpi_message hm; 1524 struct hpi_message hm;
1798 struct hpi_response hr; 1525 struct hpi_response hr;
1799 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1526 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1800 HPI_CONTROL_GET_STATE); 1527 HPI_CONTROL_GET_STATE);
1801 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1528 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1529 return HPI_ERROR_INVALID_HANDLE;
1802 hm.u.c.attribute = HPI_AESEBURX_CHANNELSTATUS; 1530 hm.u.c.attribute = HPI_AESEBURX_CHANNELSTATUS;
1803 hm.u.c.param1 = index; 1531 hm.u.c.param1 = index;
1804 1532
@@ -1809,101 +1537,93 @@ u16 HPI_AESEBU__receiver_get_channel_status(const struct hpi_hsubsys
1809 return hr.error; 1537 return hr.error;
1810} 1538}
1811 1539
1812u16 HPI_AESEBU__receiver_get_error_status(const struct hpi_hsubsys *ph_subsys, 1540u16 hpi_aesebu_receiver_get_error_status(u32 h_control, u16 *pw_error_data)
1813 u32 h_control, u16 *pw_error_data)
1814{ 1541{
1815 u32 error_data = 0; 1542 u32 error_data = 0;
1816 u16 error = 0; 1543 u16 err = 0;
1817 1544
1818 error = hpi_control_param1_get(ph_subsys, h_control, 1545 err = hpi_control_param1_get(h_control, HPI_AESEBURX_ERRORSTATUS,
1819 HPI_AESEBURX_ERRORSTATUS, &error_data); 1546 &error_data);
1820 if (pw_error_data) 1547 if (pw_error_data)
1821 *pw_error_data = (u16)error_data; 1548 *pw_error_data = (u16)error_data;
1822 return error; 1549 return err;
1823} 1550}
1824 1551
1825u16 HPI_AESEBU__transmitter_set_sample_rate(const struct hpi_hsubsys 1552u16 hpi_aesebu_transmitter_set_sample_rate(u32 h_control, u32 sample_rate)
1826 *ph_subsys, u32 h_control, u32 sample_rate)
1827{ 1553{
1828 return hpi_control_param_set(ph_subsys, h_control, 1554 return hpi_control_param_set(h_control, HPI_AESEBUTX_SAMPLERATE,
1829 HPI_AESEBUTX_SAMPLERATE, sample_rate, 0); 1555 sample_rate, 0);
1830} 1556}
1831 1557
1832u16 HPI_AESEBU__transmitter_set_user_data(const struct hpi_hsubsys *ph_subsys, 1558u16 hpi_aesebu_transmitter_set_user_data(u32 h_control, u16 index, u16 data)
1833 u32 h_control, u16 index, u16 data)
1834{ 1559{
1835 return hpi_control_param_set(ph_subsys, h_control, 1560 return hpi_control_param_set(h_control, HPI_AESEBUTX_USERDATA, index,
1836 HPI_AESEBUTX_USERDATA, index, data); 1561 data);
1837} 1562}
1838 1563
1839u16 HPI_AESEBU__transmitter_set_channel_status(const struct hpi_hsubsys 1564u16 hpi_aesebu_transmitter_set_channel_status(u32 h_control, u16 index,
1840 *ph_subsys, u32 h_control, u16 index, u16 data) 1565 u16 data)
1841{ 1566{
1842 return hpi_control_param_set(ph_subsys, h_control, 1567 return hpi_control_param_set(h_control, HPI_AESEBUTX_CHANNELSTATUS,
1843 HPI_AESEBUTX_CHANNELSTATUS, index, data); 1568 index, data);
1844} 1569}
1845 1570
1846u16 HPI_AESEBU__transmitter_get_channel_status(const struct hpi_hsubsys 1571u16 hpi_aesebu_transmitter_get_channel_status(u32 h_control, u16 index,
1847 *ph_subsys, u32 h_control, u16 index, u16 *pw_data) 1572 u16 *pw_data)
1848{ 1573{
1849 return HPI_ERROR_INVALID_OPERATION; 1574 return HPI_ERROR_INVALID_OPERATION;
1850} 1575}
1851 1576
1852u16 HPI_AESEBU__transmitter_query_format(const struct hpi_hsubsys *ph_subsys, 1577u16 hpi_aesebu_transmitter_query_format(const u32 h_aes_tx, const u32 index,
1853 const u32 h_aes_tx, const u32 index, u16 *pw_format) 1578 u16 *pw_format)
1854{ 1579{
1855 u32 qr; 1580 u32 qr;
1856 u16 err; 1581 u16 err;
1857 1582
1858 err = hpi_control_query(ph_subsys, h_aes_tx, HPI_AESEBUTX_FORMAT, 1583 err = hpi_control_query(h_aes_tx, HPI_AESEBUTX_FORMAT, index, 0, &qr);
1859 index, 0, &qr);
1860 *pw_format = (u16)qr; 1584 *pw_format = (u16)qr;
1861 return err; 1585 return err;
1862} 1586}
1863 1587
1864u16 HPI_AESEBU__transmitter_set_format(const struct hpi_hsubsys *ph_subsys, 1588u16 hpi_aesebu_transmitter_set_format(u32 h_control, u16 output_format)
1865 u32 h_control, u16 output_format)
1866{ 1589{
1867 return hpi_control_param_set(ph_subsys, h_control, 1590 return hpi_control_param_set(h_control, HPI_AESEBUTX_FORMAT,
1868 HPI_AESEBUTX_FORMAT, output_format, 0); 1591 output_format, 0);
1869} 1592}
1870 1593
1871u16 HPI_AESEBU__transmitter_get_format(const struct hpi_hsubsys *ph_subsys, 1594u16 hpi_aesebu_transmitter_get_format(u32 h_control, u16 *pw_output_format)
1872 u32 h_control, u16 *pw_output_format)
1873{ 1595{
1874 u16 err; 1596 u16 err;
1875 u32 param; 1597 u32 param;
1876 1598
1877 err = hpi_control_param1_get(ph_subsys, h_control, 1599 err = hpi_control_param1_get(h_control, HPI_AESEBUTX_FORMAT, &param);
1878 HPI_AESEBUTX_FORMAT, &param);
1879 if (!err && pw_output_format) 1600 if (!err && pw_output_format)
1880 *pw_output_format = (u16)param; 1601 *pw_output_format = (u16)param;
1881 1602
1882 return err; 1603 return err;
1883} 1604}
1884 1605
1885u16 hpi_bitstream_set_clock_edge(const struct hpi_hsubsys *ph_subsys, 1606u16 hpi_bitstream_set_clock_edge(u32 h_control, u16 edge_type)
1886 u32 h_control, u16 edge_type)
1887{ 1607{
1888 return hpi_control_param_set(ph_subsys, h_control, 1608 return hpi_control_param_set(h_control, HPI_BITSTREAM_CLOCK_EDGE,
1889 HPI_BITSTREAM_CLOCK_EDGE, edge_type, 0); 1609 edge_type, 0);
1890} 1610}
1891 1611
1892u16 hpi_bitstream_set_data_polarity(const struct hpi_hsubsys *ph_subsys, 1612u16 hpi_bitstream_set_data_polarity(u32 h_control, u16 polarity)
1893 u32 h_control, u16 polarity)
1894{ 1613{
1895 return hpi_control_param_set(ph_subsys, h_control, 1614 return hpi_control_param_set(h_control, HPI_BITSTREAM_DATA_POLARITY,
1896 HPI_BITSTREAM_DATA_POLARITY, polarity, 0); 1615 polarity, 0);
1897} 1616}
1898 1617
1899u16 hpi_bitstream_get_activity(const struct hpi_hsubsys *ph_subsys, 1618u16 hpi_bitstream_get_activity(u32 h_control, u16 *pw_clk_activity,
1900 u32 h_control, u16 *pw_clk_activity, u16 *pw_data_activity) 1619 u16 *pw_data_activity)
1901{ 1620{
1902 struct hpi_message hm; 1621 struct hpi_message hm;
1903 struct hpi_response hr; 1622 struct hpi_response hr;
1904 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1623 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1905 HPI_CONTROL_GET_STATE); 1624 HPI_CONTROL_GET_STATE);
1906 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1625 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1626 return HPI_ERROR_INVALID_HANDLE;
1907 hm.u.c.attribute = HPI_BITSTREAM_ACTIVITY; 1627 hm.u.c.attribute = HPI_BITSTREAM_ACTIVITY;
1908 hpi_send_recv(&hm, &hr); 1628 hpi_send_recv(&hm, &hr);
1909 if (pw_clk_activity) 1629 if (pw_clk_activity)
@@ -1913,45 +1633,43 @@ u16 hpi_bitstream_get_activity(const struct hpi_hsubsys *ph_subsys,
1913 return hr.error; 1633 return hr.error;
1914} 1634}
1915 1635
1916u16 hpi_channel_mode_query_mode(const struct hpi_hsubsys *ph_subsys, 1636u16 hpi_channel_mode_query_mode(const u32 h_mode, const u32 index,
1917 const u32 h_mode, const u32 index, u16 *pw_mode) 1637 u16 *pw_mode)
1918{ 1638{
1919 u32 qr; 1639 u32 qr;
1920 u16 err; 1640 u16 err;
1921 1641
1922 err = hpi_control_query(ph_subsys, h_mode, HPI_CHANNEL_MODE_MODE, 1642 err = hpi_control_query(h_mode, HPI_CHANNEL_MODE_MODE, index, 0, &qr);
1923 index, 0, &qr);
1924 *pw_mode = (u16)qr; 1643 *pw_mode = (u16)qr;
1925 return err; 1644 return err;
1926} 1645}
1927 1646
1928u16 hpi_channel_mode_set(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1647u16 hpi_channel_mode_set(u32 h_control, u16 mode)
1929 u16 mode)
1930{ 1648{
1931 return hpi_control_param_set(ph_subsys, h_control, 1649 return hpi_control_param_set(h_control, HPI_CHANNEL_MODE_MODE, mode,
1932 HPI_CHANNEL_MODE_MODE, mode, 0); 1650 0);
1933} 1651}
1934 1652
1935u16 hpi_channel_mode_get(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1653u16 hpi_channel_mode_get(u32 h_control, u16 *mode)
1936 u16 *mode)
1937{ 1654{
1938 u32 mode32 = 0; 1655 u32 mode32 = 0;
1939 u16 error = hpi_control_param1_get(ph_subsys, h_control, 1656 u16 err = hpi_control_param1_get(h_control,
1940 HPI_CHANNEL_MODE_MODE, &mode32); 1657 HPI_CHANNEL_MODE_MODE, &mode32);
1941 if (mode) 1658 if (mode)
1942 *mode = (u16)mode32; 1659 *mode = (u16)mode32;
1943 return error; 1660 return err;
1944} 1661}
1945 1662
1946u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1663u16 hpi_cobranet_hmi_write(u32 h_control, u32 hmi_address, u32 byte_count,
1947 u32 hmi_address, u32 byte_count, u8 *pb_data) 1664 u8 *pb_data)
1948{ 1665{
1949 struct hpi_message hm; 1666 struct hpi_message hm;
1950 struct hpi_response hr; 1667 struct hpi_response hr;
1951 1668
1952 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, 1669 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1953 HPI_CONTROL_SET_STATE); 1670 HPI_CONTROL_SET_STATE);
1954 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1671 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1672 return HPI_ERROR_INVALID_HANDLE;
1955 1673
1956 hm.u.cx.u.cobranet_data.byte_count = byte_count; 1674 hm.u.cx.u.cobranet_data.byte_count = byte_count;
1957 hm.u.cx.u.cobranet_data.hmi_address = hmi_address; 1675 hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
@@ -1969,15 +1687,16 @@ u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1969 return hr.error; 1687 return hr.error;
1970} 1688}
1971 1689
1972u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1690u16 hpi_cobranet_hmi_read(u32 h_control, u32 hmi_address, u32 max_byte_count,
1973 u32 hmi_address, u32 max_byte_count, u32 *pbyte_count, u8 *pb_data) 1691 u32 *pbyte_count, u8 *pb_data)
1974{ 1692{
1975 struct hpi_message hm; 1693 struct hpi_message hm;
1976 struct hpi_response hr; 1694 struct hpi_response hr;
1977 1695
1978 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, 1696 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1979 HPI_CONTROL_GET_STATE); 1697 HPI_CONTROL_GET_STATE);
1980 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1698 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1699 return HPI_ERROR_INVALID_HANDLE;
1981 1700
1982 hm.u.cx.u.cobranet_data.byte_count = max_byte_count; 1701 hm.u.cx.u.cobranet_data.byte_count = max_byte_count;
1983 hm.u.cx.u.cobranet_data.hmi_address = hmi_address; 1702 hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
@@ -2008,16 +1727,16 @@ u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2008 return hr.error; 1727 return hr.error;
2009} 1728}
2010 1729
2011u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys, 1730u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
2012 u32 h_control, u32 *pstatus, u32 *preadable_size, 1731 u32 *preadable_size, u32 *pwriteable_size)
2013 u32 *pwriteable_size)
2014{ 1732{
2015 struct hpi_message hm; 1733 struct hpi_message hm;
2016 struct hpi_response hr; 1734 struct hpi_response hr;
2017 1735
2018 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, 1736 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
2019 HPI_CONTROL_GET_STATE); 1737 HPI_CONTROL_GET_STATE);
2020 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1738 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1739 return HPI_ERROR_INVALID_HANDLE;
2021 1740
2022 hm.u.cx.attribute = HPI_COBRANET_GET_STATUS; 1741 hm.u.cx.attribute = HPI_COBRANET_GET_STATUS;
2023 1742
@@ -2035,177 +1754,176 @@ u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys,
2035 return hr.error; 1754 return hr.error;
2036} 1755}
2037 1756
2038u16 hpi_cobranet_getI_paddress(const struct hpi_hsubsys *ph_subsys, 1757u16 hpi_cobranet_get_ip_address(u32 h_control, u32 *pdw_ip_address)
2039 u32 h_control, u32 *pi_paddress)
2040{ 1758{
2041 u32 byte_count; 1759 u32 byte_count;
2042 u32 iP; 1760 u32 iP;
2043 u16 error; 1761 u16 err;
2044 1762
2045 error = hpi_cobranet_hmi_read(ph_subsys, h_control, 1763 err = hpi_cobranet_hmi_read(h_control,
2046 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, &byte_count, 1764 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, &byte_count,
2047 (u8 *)&iP); 1765 (u8 *)&iP);
2048 1766
2049 *pi_paddress = 1767 *pdw_ip_address =
2050 ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP & 1768 ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP &
2051 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8); 1769 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8);
2052 1770
2053 if (error) 1771 if (err)
2054 *pi_paddress = 0; 1772 *pdw_ip_address = 0;
2055 1773
2056 return error; 1774 return err;
2057 1775
2058} 1776}
2059 1777
2060u16 hpi_cobranet_setI_paddress(const struct hpi_hsubsys *ph_subsys, 1778u16 hpi_cobranet_set_ip_address(u32 h_control, u32 dw_ip_address)
2061 u32 h_control, u32 i_paddress)
2062{ 1779{
2063 u32 iP; 1780 u32 iP;
2064 u16 error; 1781 u16 err;
2065 1782
2066 iP = ((i_paddress & 0xff000000) >> 8) | ((i_paddress & 0x00ff0000) << 1783 iP = ((dw_ip_address & 0xff000000) >> 8) | ((dw_ip_address &
2067 8) | ((i_paddress & 0x0000ff00) >> 8) | ((i_paddress & 1784 0x00ff0000) << 8) | ((dw_ip_address & 0x0000ff00) >>
2068 0x000000ff) << 8); 1785 8) | ((dw_ip_address & 0x000000ff) << 8);
2069 1786
2070 error = hpi_cobranet_hmi_write(ph_subsys, h_control, 1787 err = hpi_cobranet_hmi_write(h_control,
2071 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, (u8 *)&iP); 1788 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, (u8 *)&iP);
2072 1789
2073 return error; 1790 return err;
2074 1791
2075} 1792}
2076 1793
2077u16 hpi_cobranet_get_staticI_paddress(const struct hpi_hsubsys *ph_subsys, 1794u16 hpi_cobranet_get_static_ip_address(u32 h_control, u32 *pdw_ip_address)
2078 u32 h_control, u32 *pi_paddress)
2079{ 1795{
2080 u32 byte_count; 1796 u32 byte_count;
2081 u32 iP; 1797 u32 iP;
2082 u16 error; 1798 u16 err;
2083 error = hpi_cobranet_hmi_read(ph_subsys, h_control, 1799 err = hpi_cobranet_hmi_read(h_control,
2084 HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, &byte_count, 1800 HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, &byte_count,
2085 (u8 *)&iP); 1801 (u8 *)&iP);
2086 1802
2087 *pi_paddress = 1803 *pdw_ip_address =
2088 ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP & 1804 ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP &
2089 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8); 1805 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8);
2090 1806
2091 if (error) 1807 if (err)
2092 *pi_paddress = 0; 1808 *pdw_ip_address = 0;
2093 1809
2094 return error; 1810 return err;
2095 1811
2096} 1812}
2097 1813
2098u16 hpi_cobranet_set_staticI_paddress(const struct hpi_hsubsys *ph_subsys, 1814u16 hpi_cobranet_set_static_ip_address(u32 h_control, u32 dw_ip_address)
2099 u32 h_control, u32 i_paddress)
2100{ 1815{
2101 u32 iP; 1816 u32 iP;
2102 u16 error; 1817 u16 err;
2103 1818
2104 iP = ((i_paddress & 0xff000000) >> 8) | ((i_paddress & 0x00ff0000) << 1819 iP = ((dw_ip_address & 0xff000000) >> 8) | ((dw_ip_address &
2105 8) | ((i_paddress & 0x0000ff00) >> 8) | ((i_paddress & 1820 0x00ff0000) << 8) | ((dw_ip_address & 0x0000ff00) >>
2106 0x000000ff) << 8); 1821 8) | ((dw_ip_address & 0x000000ff) << 8);
2107 1822
2108 error = hpi_cobranet_hmi_write(ph_subsys, h_control, 1823 err = hpi_cobranet_hmi_write(h_control,
2109 HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, (u8 *)&iP); 1824 HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, (u8 *)&iP);
2110 1825
2111 return error; 1826 return err;
2112 1827
2113} 1828}
2114 1829
2115u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys, 1830u16 hpi_cobranet_get_macaddress(u32 h_control, u32 *p_mac_msbs,
2116 u32 h_control, u32 *pmAC_MS_bs, u32 *pmAC_LS_bs) 1831 u32 *p_mac_lsbs)
2117{ 1832{
2118 u32 byte_count; 1833 u32 byte_count;
2119 u16 error; 1834 u16 err;
2120 u32 mAC; 1835 u32 mac;
2121 1836
2122 error = hpi_cobranet_hmi_read(ph_subsys, h_control, 1837 err = hpi_cobranet_hmi_read(h_control,
2123 HPI_COBRANET_HMI_cobra_if_phy_address, 4, &byte_count, 1838 HPI_COBRANET_HMI_cobra_if_phy_address, 4, &byte_count,
2124 (u8 *)&mAC); 1839 (u8 *)&mac);
2125 *pmAC_MS_bs = 1840
2126 ((mAC & 0xff000000) >> 8) | ((mAC & 0x00ff0000) << 8) | ((mAC 1841 if (!err) {
2127 & 0x0000ff00) >> 8) | ((mAC & 0x000000ff) << 8); 1842 *p_mac_msbs =
2128 error += hpi_cobranet_hmi_read(ph_subsys, h_control, 1843 ((mac & 0xff000000) >> 8) | ((mac & 0x00ff0000) << 8)
2129 HPI_COBRANET_HMI_cobra_if_phy_address + 1, 4, &byte_count, 1844 | ((mac & 0x0000ff00) >> 8) | ((mac & 0x000000ff) <<
2130 (u8 *)&mAC); 1845 8);
2131 *pmAC_LS_bs = 1846
2132 ((mAC & 0xff000000) >> 8) | ((mAC & 0x00ff0000) << 8) | ((mAC 1847 err = hpi_cobranet_hmi_read(h_control,
2133 & 0x0000ff00) >> 8) | ((mAC & 0x000000ff) << 8); 1848 HPI_COBRANET_HMI_cobra_if_phy_address + 1, 4,
2134 1849 &byte_count, (u8 *)&mac);
2135 if (error) {
2136 *pmAC_MS_bs = 0;
2137 *pmAC_LS_bs = 0;
2138 } 1850 }
2139 1851
2140 return error; 1852 if (!err) {
1853 *p_mac_lsbs =
1854 ((mac & 0xff000000) >> 8) | ((mac & 0x00ff0000) << 8)
1855 | ((mac & 0x0000ff00) >> 8) | ((mac & 0x000000ff) <<
1856 8);
1857 } else {
1858 *p_mac_msbs = 0;
1859 *p_mac_lsbs = 0;
1860 }
1861
1862 return err;
2141} 1863}
2142 1864
2143u16 hpi_compander_set_enable(const struct hpi_hsubsys *ph_subsys, 1865u16 hpi_compander_set_enable(u32 h_control, u32 enable)
2144 u32 h_control, u32 enable)
2145{ 1866{
2146 return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE, 1867 return hpi_control_param_set(h_control, HPI_GENERIC_ENABLE, enable,
2147 enable, 0); 1868 0);
2148} 1869}
2149 1870
2150u16 hpi_compander_get_enable(const struct hpi_hsubsys *ph_subsys, 1871u16 hpi_compander_get_enable(u32 h_control, u32 *enable)
2151 u32 h_control, u32 *enable)
2152{ 1872{
2153 return hpi_control_param1_get(ph_subsys, h_control, 1873 return hpi_control_param1_get(h_control, HPI_GENERIC_ENABLE, enable);
2154 HPI_GENERIC_ENABLE, enable);
2155} 1874}
2156 1875
2157u16 hpi_compander_set_makeup_gain(const struct hpi_hsubsys *ph_subsys, 1876u16 hpi_compander_set_makeup_gain(u32 h_control, short makeup_gain0_01dB)
2158 u32 h_control, short makeup_gain0_01dB)
2159{ 1877{
2160 return hpi_control_log_set2(h_control, HPI_COMPANDER_MAKEUPGAIN, 1878 return hpi_control_log_set2(h_control, HPI_COMPANDER_MAKEUPGAIN,
2161 makeup_gain0_01dB, 0); 1879 makeup_gain0_01dB, 0);
2162} 1880}
2163 1881
2164u16 hpi_compander_get_makeup_gain(const struct hpi_hsubsys *ph_subsys, 1882u16 hpi_compander_get_makeup_gain(u32 h_control, short *makeup_gain0_01dB)
2165 u32 h_control, short *makeup_gain0_01dB)
2166{ 1883{
2167 return hpi_control_log_get2(ph_subsys, h_control, 1884 return hpi_control_log_get2(h_control, HPI_COMPANDER_MAKEUPGAIN,
2168 HPI_COMPANDER_MAKEUPGAIN, makeup_gain0_01dB, NULL); 1885 makeup_gain0_01dB, NULL);
2169} 1886}
2170 1887
2171u16 hpi_compander_set_attack_time_constant(const struct hpi_hsubsys 1888u16 hpi_compander_set_attack_time_constant(u32 h_control, unsigned int index,
2172 *ph_subsys, u32 h_control, unsigned int index, u32 attack) 1889 u32 attack)
2173{ 1890{
2174 return hpi_control_param_set(ph_subsys, h_control, 1891 return hpi_control_param_set(h_control, HPI_COMPANDER_ATTACK, attack,
2175 HPI_COMPANDER_ATTACK, attack, index); 1892 index);
2176} 1893}
2177 1894
2178u16 hpi_compander_get_attack_time_constant(const struct hpi_hsubsys 1895u16 hpi_compander_get_attack_time_constant(u32 h_control, unsigned int index,
2179 *ph_subsys, u32 h_control, unsigned int index, u32 *attack) 1896 u32 *attack)
2180{ 1897{
2181 return hpi_control_param_get(ph_subsys, h_control, 1898 return hpi_control_param_get(h_control, HPI_COMPANDER_ATTACK, 0,
2182 HPI_COMPANDER_ATTACK, 0, index, attack, NULL); 1899 index, attack, NULL);
2183} 1900}
2184 1901
2185u16 hpi_compander_set_decay_time_constant(const struct hpi_hsubsys *ph_subsys, 1902u16 hpi_compander_set_decay_time_constant(u32 h_control, unsigned int index,
2186 u32 h_control, unsigned int index, u32 decay) 1903 u32 decay)
2187{ 1904{
2188 return hpi_control_param_set(ph_subsys, h_control, 1905 return hpi_control_param_set(h_control, HPI_COMPANDER_DECAY, decay,
2189 HPI_COMPANDER_DECAY, decay, index); 1906 index);
2190} 1907}
2191 1908
2192u16 hpi_compander_get_decay_time_constant(const struct hpi_hsubsys *ph_subsys, 1909u16 hpi_compander_get_decay_time_constant(u32 h_control, unsigned int index,
2193 u32 h_control, unsigned int index, u32 *decay) 1910 u32 *decay)
2194{ 1911{
2195 return hpi_control_param_get(ph_subsys, h_control, 1912 return hpi_control_param_get(h_control, HPI_COMPANDER_DECAY, 0, index,
2196 HPI_COMPANDER_DECAY, 0, index, decay, NULL); 1913 decay, NULL);
2197 1914
2198} 1915}
2199 1916
2200u16 hpi_compander_set_threshold(const struct hpi_hsubsys *ph_subsys, 1917u16 hpi_compander_set_threshold(u32 h_control, unsigned int index,
2201 u32 h_control, unsigned int index, short threshold0_01dB) 1918 short threshold0_01dB)
2202{ 1919{
2203 struct hpi_message hm; 1920 struct hpi_message hm;
2204 struct hpi_response hr; 1921 struct hpi_response hr;
2205 1922
2206 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1923 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2207 HPI_CONTROL_SET_STATE); 1924 HPI_CONTROL_SET_STATE);
2208 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1925 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1926 return HPI_ERROR_INVALID_HANDLE;
2209 hm.u.c.attribute = HPI_COMPANDER_THRESHOLD; 1927 hm.u.c.attribute = HPI_COMPANDER_THRESHOLD;
2210 hm.u.c.param2 = index; 1928 hm.u.c.param2 = index;
2211 hm.u.c.an_log_value[0] = threshold0_01dB; 1929 hm.u.c.an_log_value[0] = threshold0_01dB;
@@ -2215,15 +1933,16 @@ u16 hpi_compander_set_threshold(const struct hpi_hsubsys *ph_subsys,
2215 return hr.error; 1933 return hr.error;
2216} 1934}
2217 1935
2218u16 hpi_compander_get_threshold(const struct hpi_hsubsys *ph_subsys, 1936u16 hpi_compander_get_threshold(u32 h_control, unsigned int index,
2219 u32 h_control, unsigned int index, short *threshold0_01dB) 1937 short *threshold0_01dB)
2220{ 1938{
2221 struct hpi_message hm; 1939 struct hpi_message hm;
2222 struct hpi_response hr; 1940 struct hpi_response hr;
2223 1941
2224 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1942 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2225 HPI_CONTROL_GET_STATE); 1943 HPI_CONTROL_GET_STATE);
2226 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1944 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1945 return HPI_ERROR_INVALID_HANDLE;
2227 hm.u.c.attribute = HPI_COMPANDER_THRESHOLD; 1946 hm.u.c.attribute = HPI_COMPANDER_THRESHOLD;
2228 hm.u.c.param2 = index; 1947 hm.u.c.param2 = index;
2229 1948
@@ -2233,29 +1952,28 @@ u16 hpi_compander_get_threshold(const struct hpi_hsubsys *ph_subsys,
2233 return hr.error; 1952 return hr.error;
2234} 1953}
2235 1954
2236u16 hpi_compander_set_ratio(const struct hpi_hsubsys *ph_subsys, 1955u16 hpi_compander_set_ratio(u32 h_control, u32 index, u32 ratio100)
2237 u32 h_control, u32 index, u32 ratio100)
2238{ 1956{
2239 return hpi_control_param_set(ph_subsys, h_control, 1957 return hpi_control_param_set(h_control, HPI_COMPANDER_RATIO, ratio100,
2240 HPI_COMPANDER_RATIO, ratio100, index); 1958 index);
2241} 1959}
2242 1960
2243u16 hpi_compander_get_ratio(const struct hpi_hsubsys *ph_subsys, 1961u16 hpi_compander_get_ratio(u32 h_control, u32 index, u32 *ratio100)
2244 u32 h_control, u32 index, u32 *ratio100)
2245{ 1962{
2246 return hpi_control_param_get(ph_subsys, h_control, 1963 return hpi_control_param_get(h_control, HPI_COMPANDER_RATIO, 0, index,
2247 HPI_COMPANDER_RATIO, 0, index, ratio100, NULL); 1964 ratio100, NULL);
2248} 1965}
2249 1966
2250u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1967u16 hpi_level_query_range(u32 h_control, short *min_gain_01dB,
2251 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB) 1968 short *max_gain_01dB, short *step_gain_01dB)
2252{ 1969{
2253 struct hpi_message hm; 1970 struct hpi_message hm;
2254 struct hpi_response hr; 1971 struct hpi_response hr;
2255 1972
2256 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1973 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2257 HPI_CONTROL_GET_STATE); 1974 HPI_CONTROL_GET_STATE);
2258 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1975 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1976 return HPI_ERROR_INVALID_HANDLE;
2259 hm.u.c.attribute = HPI_LEVEL_RANGE; 1977 hm.u.c.attribute = HPI_LEVEL_RANGE;
2260 1978
2261 hpi_send_recv(&hm, &hr); 1979 hpi_send_recv(&hm, &hr);
@@ -2273,31 +1991,27 @@ u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2273 return hr.error; 1991 return hr.error;
2274} 1992}
2275 1993
2276u16 hpi_level_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1994u16 hpi_level_set_gain(u32 h_control, short an_gain0_01dB[HPI_MAX_CHANNELS]
2277 short an_gain0_01dB[HPI_MAX_CHANNELS]
2278 ) 1995 )
2279{ 1996{
2280 return hpi_control_log_set2(h_control, HPI_LEVEL_GAIN, 1997 return hpi_control_log_set2(h_control, HPI_LEVEL_GAIN,
2281 an_gain0_01dB[0], an_gain0_01dB[1]); 1998 an_gain0_01dB[0], an_gain0_01dB[1]);
2282} 1999}
2283 2000
2284u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2001u16 hpi_level_get_gain(u32 h_control, short an_gain0_01dB[HPI_MAX_CHANNELS]
2285 short an_gain0_01dB[HPI_MAX_CHANNELS]
2286 ) 2002 )
2287{ 2003{
2288 return hpi_control_log_get2(ph_subsys, h_control, HPI_LEVEL_GAIN, 2004 return hpi_control_log_get2(h_control, HPI_LEVEL_GAIN,
2289 &an_gain0_01dB[0], &an_gain0_01dB[1]); 2005 &an_gain0_01dB[0], &an_gain0_01dB[1]);
2290} 2006}
2291 2007
2292u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys, 2008u16 hpi_meter_query_channels(const u32 h_meter, u32 *p_channels)
2293 const u32 h_meter, u32 *p_channels)
2294{ 2009{
2295 return hpi_control_query(ph_subsys, h_meter, HPI_METER_NUM_CHANNELS, 2010 return hpi_control_query(h_meter, HPI_METER_NUM_CHANNELS, 0, 0,
2296 0, 0, p_channels); 2011 p_channels);
2297} 2012}
2298 2013
2299u16 hpi_meter_get_peak(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2014u16 hpi_meter_get_peak(u32 h_control, short an_peakdB[HPI_MAX_CHANNELS]
2300 short an_peakdB[HPI_MAX_CHANNELS]
2301 ) 2015 )
2302{ 2016{
2303 short i = 0; 2017 short i = 0;
@@ -2307,7 +2021,8 @@ u16 hpi_meter_get_peak(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2307 2021
2308 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2022 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2309 HPI_CONTROL_GET_STATE); 2023 HPI_CONTROL_GET_STATE);
2310 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2024 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2025 return HPI_ERROR_INVALID_HANDLE;
2311 hm.obj_index = hm.obj_index; 2026 hm.obj_index = hm.obj_index;
2312 hm.u.c.attribute = HPI_METER_PEAK; 2027 hm.u.c.attribute = HPI_METER_PEAK;
2313 2028
@@ -2322,8 +2037,7 @@ u16 hpi_meter_get_peak(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2322 return hr.error; 2037 return hr.error;
2323} 2038}
2324 2039
2325u16 hpi_meter_get_rms(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2040u16 hpi_meter_get_rms(u32 h_control, short an_rmsdB[HPI_MAX_CHANNELS]
2326 short an_rmsdB[HPI_MAX_CHANNELS]
2327 ) 2041 )
2328{ 2042{
2329 short i = 0; 2043 short i = 0;
@@ -2333,7 +2047,8 @@ u16 hpi_meter_get_rms(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2333 2047
2334 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2048 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2335 HPI_CONTROL_GET_STATE); 2049 HPI_CONTROL_GET_STATE);
2336 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2050 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2051 return HPI_ERROR_INVALID_HANDLE;
2337 hm.u.c.attribute = HPI_METER_RMS; 2052 hm.u.c.attribute = HPI_METER_RMS;
2338 2053
2339 hpi_send_recv(&hm, &hr); 2054 hpi_send_recv(&hm, &hr);
@@ -2348,22 +2063,20 @@ u16 hpi_meter_get_rms(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2348 return hr.error; 2063 return hr.error;
2349} 2064}
2350 2065
2351u16 hpi_meter_set_rms_ballistics(const struct hpi_hsubsys *ph_subsys, 2066u16 hpi_meter_set_rms_ballistics(u32 h_control, u16 attack, u16 decay)
2352 u32 h_control, u16 attack, u16 decay)
2353{ 2067{
2354 return hpi_control_param_set(ph_subsys, h_control, 2068 return hpi_control_param_set(h_control, HPI_METER_RMS_BALLISTICS,
2355 HPI_METER_RMS_BALLISTICS, attack, decay); 2069 attack, decay);
2356} 2070}
2357 2071
2358u16 hpi_meter_get_rms_ballistics(const struct hpi_hsubsys *ph_subsys, 2072u16 hpi_meter_get_rms_ballistics(u32 h_control, u16 *pn_attack, u16 *pn_decay)
2359 u32 h_control, u16 *pn_attack, u16 *pn_decay)
2360{ 2073{
2361 u32 attack; 2074 u32 attack;
2362 u32 decay; 2075 u32 decay;
2363 u16 error; 2076 u16 error;
2364 2077
2365 error = hpi_control_param2_get(ph_subsys, h_control, 2078 error = hpi_control_param2_get(h_control, HPI_METER_RMS_BALLISTICS,
2366 HPI_METER_RMS_BALLISTICS, &attack, &decay); 2079 &attack, &decay);
2367 2080
2368 if (pn_attack) 2081 if (pn_attack)
2369 *pn_attack = (unsigned short)attack; 2082 *pn_attack = (unsigned short)attack;
@@ -2373,22 +2086,21 @@ u16 hpi_meter_get_rms_ballistics(const struct hpi_hsubsys *ph_subsys,
2373 return error; 2086 return error;
2374} 2087}
2375 2088
2376u16 hpi_meter_set_peak_ballistics(const struct hpi_hsubsys *ph_subsys, 2089u16 hpi_meter_set_peak_ballistics(u32 h_control, u16 attack, u16 decay)
2377 u32 h_control, u16 attack, u16 decay)
2378{ 2090{
2379 return hpi_control_param_set(ph_subsys, h_control, 2091 return hpi_control_param_set(h_control, HPI_METER_PEAK_BALLISTICS,
2380 HPI_METER_PEAK_BALLISTICS, attack, decay); 2092 attack, decay);
2381} 2093}
2382 2094
2383u16 hpi_meter_get_peak_ballistics(const struct hpi_hsubsys *ph_subsys, 2095u16 hpi_meter_get_peak_ballistics(u32 h_control, u16 *pn_attack,
2384 u32 h_control, u16 *pn_attack, u16 *pn_decay) 2096 u16 *pn_decay)
2385{ 2097{
2386 u32 attack; 2098 u32 attack;
2387 u32 decay; 2099 u32 decay;
2388 u16 error; 2100 u16 error;
2389 2101
2390 error = hpi_control_param2_get(ph_subsys, h_control, 2102 error = hpi_control_param2_get(h_control, HPI_METER_PEAK_BALLISTICS,
2391 HPI_METER_PEAK_BALLISTICS, &attack, &decay); 2103 &attack, &decay);
2392 2104
2393 if (pn_attack) 2105 if (pn_attack)
2394 *pn_attack = (short)attack; 2106 *pn_attack = (short)attack;
@@ -2398,55 +2110,53 @@ u16 hpi_meter_get_peak_ballistics(const struct hpi_hsubsys *ph_subsys,
2398 return error; 2110 return error;
2399} 2111}
2400 2112
2401u16 hpi_microphone_set_phantom_power(const struct hpi_hsubsys *ph_subsys, 2113u16 hpi_microphone_set_phantom_power(u32 h_control, u16 on_off)
2402 u32 h_control, u16 on_off)
2403{ 2114{
2404 return hpi_control_param_set(ph_subsys, h_control, 2115 return hpi_control_param_set(h_control, HPI_MICROPHONE_PHANTOM_POWER,
2405 HPI_MICROPHONE_PHANTOM_POWER, (u32)on_off, 0); 2116 (u32)on_off, 0);
2406} 2117}
2407 2118
2408u16 hpi_microphone_get_phantom_power(const struct hpi_hsubsys *ph_subsys, 2119u16 hpi_microphone_get_phantom_power(u32 h_control, u16 *pw_on_off)
2409 u32 h_control, u16 *pw_on_off)
2410{ 2120{
2411 u16 error = 0; 2121 u16 error = 0;
2412 u32 on_off = 0; 2122 u32 on_off = 0;
2413 error = hpi_control_param1_get(ph_subsys, h_control, 2123 error = hpi_control_param1_get(h_control,
2414 HPI_MICROPHONE_PHANTOM_POWER, &on_off); 2124 HPI_MICROPHONE_PHANTOM_POWER, &on_off);
2415 if (pw_on_off) 2125 if (pw_on_off)
2416 *pw_on_off = (u16)on_off; 2126 *pw_on_off = (u16)on_off;
2417 return error; 2127 return error;
2418} 2128}
2419 2129
2420u16 hpi_multiplexer_set_source(const struct hpi_hsubsys *ph_subsys, 2130u16 hpi_multiplexer_set_source(u32 h_control, u16 source_node_type,
2421 u32 h_control, u16 source_node_type, u16 source_node_index) 2131 u16 source_node_index)
2422{ 2132{
2423 return hpi_control_param_set(ph_subsys, h_control, 2133 return hpi_control_param_set(h_control, HPI_MULTIPLEXER_SOURCE,
2424 HPI_MULTIPLEXER_SOURCE, source_node_type, source_node_index); 2134 source_node_type, source_node_index);
2425} 2135}
2426 2136
2427u16 hpi_multiplexer_get_source(const struct hpi_hsubsys *ph_subsys, 2137u16 hpi_multiplexer_get_source(u32 h_control, u16 *source_node_type,
2428 u32 h_control, u16 *source_node_type, u16 *source_node_index) 2138 u16 *source_node_index)
2429{ 2139{
2430 u32 node, index; 2140 u32 node, index;
2431 u16 error = hpi_control_param2_get(ph_subsys, h_control, 2141 u16 err = hpi_control_param2_get(h_control,
2432 HPI_MULTIPLEXER_SOURCE, &node, 2142 HPI_MULTIPLEXER_SOURCE, &node,
2433 &index); 2143 &index);
2434 if (source_node_type) 2144 if (source_node_type)
2435 *source_node_type = (u16)node; 2145 *source_node_type = (u16)node;
2436 if (source_node_index) 2146 if (source_node_index)
2437 *source_node_index = (u16)index; 2147 *source_node_index = (u16)index;
2438 return error; 2148 return err;
2439} 2149}
2440 2150
2441u16 hpi_multiplexer_query_source(const struct hpi_hsubsys *ph_subsys, 2151u16 hpi_multiplexer_query_source(u32 h_control, u16 index,
2442 u32 h_control, u16 index, u16 *source_node_type, 2152 u16 *source_node_type, u16 *source_node_index)
2443 u16 *source_node_index)
2444{ 2153{
2445 struct hpi_message hm; 2154 struct hpi_message hm;
2446 struct hpi_response hr; 2155 struct hpi_response hr;
2447 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2156 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2448 HPI_CONTROL_GET_STATE); 2157 HPI_CONTROL_GET_STATE);
2449 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2158 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2159 return HPI_ERROR_INVALID_HANDLE;
2450 hm.u.c.attribute = HPI_MULTIPLEXER_QUERYSOURCE; 2160 hm.u.c.attribute = HPI_MULTIPLEXER_QUERYSOURCE;
2451 hm.u.c.param1 = index; 2161 hm.u.c.param1 = index;
2452 2162
@@ -2459,15 +2169,15 @@ u16 hpi_multiplexer_query_source(const struct hpi_hsubsys *ph_subsys,
2459 return hr.error; 2169 return hr.error;
2460} 2170}
2461 2171
2462u16 hpi_parametricEQ__get_info(const struct hpi_hsubsys *ph_subsys, 2172u16 hpi_parametric_eq_get_info(u32 h_control, u16 *pw_number_of_bands,
2463 u32 h_control, u16 *pw_number_of_bands, u16 *pw_on_off) 2173 u16 *pw_on_off)
2464{ 2174{
2465 u32 oB = 0; 2175 u32 oB = 0;
2466 u32 oO = 0; 2176 u32 oO = 0;
2467 u16 error = 0; 2177 u16 error = 0;
2468 2178
2469 error = hpi_control_param2_get(ph_subsys, h_control, 2179 error = hpi_control_param2_get(h_control, HPI_EQUALIZER_NUM_FILTERS,
2470 HPI_EQUALIZER_NUM_FILTERS, &oO, &oB); 2180 &oO, &oB);
2471 if (pw_number_of_bands) 2181 if (pw_number_of_bands)
2472 *pw_number_of_bands = (u16)oB; 2182 *pw_number_of_bands = (u16)oB;
2473 if (pw_on_off) 2183 if (pw_on_off)
@@ -2475,23 +2185,22 @@ u16 hpi_parametricEQ__get_info(const struct hpi_hsubsys *ph_subsys,
2475 return error; 2185 return error;
2476} 2186}
2477 2187
2478u16 hpi_parametricEQ__set_state(const struct hpi_hsubsys *ph_subsys, 2188u16 hpi_parametric_eq_set_state(u32 h_control, u16 on_off)
2479 u32 h_control, u16 on_off)
2480{ 2189{
2481 return hpi_control_param_set(ph_subsys, h_control, 2190 return hpi_control_param_set(h_control, HPI_EQUALIZER_NUM_FILTERS,
2482 HPI_EQUALIZER_NUM_FILTERS, on_off, 0); 2191 on_off, 0);
2483} 2192}
2484 2193
2485u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys, 2194u16 hpi_parametric_eq_get_band(u32 h_control, u16 index, u16 *pn_type,
2486 u32 h_control, u16 index, u16 *pn_type, u32 *pfrequency_hz, 2195 u32 *pfrequency_hz, short *pnQ100, short *pn_gain0_01dB)
2487 short *pnQ100, short *pn_gain0_01dB)
2488{ 2196{
2489 struct hpi_message hm; 2197 struct hpi_message hm;
2490 struct hpi_response hr; 2198 struct hpi_response hr;
2491 2199
2492 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2200 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2493 HPI_CONTROL_GET_STATE); 2201 HPI_CONTROL_GET_STATE);
2494 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2202 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2203 return HPI_ERROR_INVALID_HANDLE;
2495 hm.u.c.attribute = HPI_EQUALIZER_FILTER; 2204 hm.u.c.attribute = HPI_EQUALIZER_FILTER;
2496 hm.u.c.param2 = index; 2205 hm.u.c.param2 = index;
2497 2206
@@ -2509,16 +2218,16 @@ u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys,
2509 return hr.error; 2218 return hr.error;
2510} 2219}
2511 2220
2512u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys, 2221u16 hpi_parametric_eq_set_band(u32 h_control, u16 index, u16 type,
2513 u32 h_control, u16 index, u16 type, u32 frequency_hz, short q100, 2222 u32 frequency_hz, short q100, short gain0_01dB)
2514 short gain0_01dB)
2515{ 2223{
2516 struct hpi_message hm; 2224 struct hpi_message hm;
2517 struct hpi_response hr; 2225 struct hpi_response hr;
2518 2226
2519 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2227 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2520 HPI_CONTROL_SET_STATE); 2228 HPI_CONTROL_SET_STATE);
2521 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2229 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2230 return HPI_ERROR_INVALID_HANDLE;
2522 2231
2523 hm.u.c.param1 = frequency_hz; 2232 hm.u.c.param1 = frequency_hz;
2524 hm.u.c.param2 = (index & 0xFFFFL) + ((u32)type << 16); 2233 hm.u.c.param2 = (index & 0xFFFFL) + ((u32)type << 16);
@@ -2531,8 +2240,7 @@ u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys,
2531 return hr.error; 2240 return hr.error;
2532} 2241}
2533 2242
2534u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys, 2243u16 hpi_parametric_eq_get_coeffs(u32 h_control, u16 index, short coeffs[5]
2535 u32 h_control, u16 index, short coeffs[5]
2536 ) 2244 )
2537{ 2245{
2538 struct hpi_message hm; 2246 struct hpi_message hm;
@@ -2540,7 +2248,8 @@ u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys,
2540 2248
2541 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2249 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2542 HPI_CONTROL_GET_STATE); 2250 HPI_CONTROL_GET_STATE);
2543 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2251 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2252 return HPI_ERROR_INVALID_HANDLE;
2544 hm.u.c.attribute = HPI_EQUALIZER_COEFFICIENTS; 2253 hm.u.c.attribute = HPI_EQUALIZER_COEFFICIENTS;
2545 hm.u.c.param2 = index; 2254 hm.u.c.param2 = index;
2546 2255
@@ -2555,444 +2264,388 @@ u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys,
2555 return hr.error; 2264 return hr.error;
2556} 2265}
2557 2266
2558u16 hpi_sample_clock_query_source(const struct hpi_hsubsys *ph_subsys, 2267u16 hpi_sample_clock_query_source(const u32 h_clock, const u32 index,
2559 const u32 h_clock, const u32 index, u16 *pw_source) 2268 u16 *pw_source)
2560{ 2269{
2561 u32 qr; 2270 u32 qr;
2562 u16 err; 2271 u16 err;
2563 2272
2564 err = hpi_control_query(ph_subsys, h_clock, HPI_SAMPLECLOCK_SOURCE, 2273 err = hpi_control_query(h_clock, HPI_SAMPLECLOCK_SOURCE, index, 0,
2565 index, 0, &qr); 2274 &qr);
2566 *pw_source = (u16)qr; 2275 *pw_source = (u16)qr;
2567 return err; 2276 return err;
2568} 2277}
2569 2278
2570u16 hpi_sample_clock_set_source(const struct hpi_hsubsys *ph_subsys, 2279u16 hpi_sample_clock_set_source(u32 h_control, u16 source)
2571 u32 h_control, u16 source)
2572{ 2280{
2573 return hpi_control_param_set(ph_subsys, h_control, 2281 return hpi_control_param_set(h_control, HPI_SAMPLECLOCK_SOURCE,
2574 HPI_SAMPLECLOCK_SOURCE, source, 0); 2282 source, 0);
2575} 2283}
2576 2284
2577u16 hpi_sample_clock_get_source(const struct hpi_hsubsys *ph_subsys, 2285u16 hpi_sample_clock_get_source(u32 h_control, u16 *pw_source)
2578 u32 h_control, u16 *pw_source)
2579{ 2286{
2580 u16 error = 0; 2287 u16 err = 0;
2581 u32 source = 0; 2288 u32 source = 0;
2582 error = hpi_control_param1_get(ph_subsys, h_control, 2289 err = hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_SOURCE,
2583 HPI_SAMPLECLOCK_SOURCE, &source); 2290 &source);
2584 if (!error) 2291 if (!err)
2585 if (pw_source) 2292 if (pw_source)
2586 *pw_source = (u16)source; 2293 *pw_source = (u16)source;
2587 return error; 2294 return err;
2588} 2295}
2589 2296
2590u16 hpi_sample_clock_query_source_index(const struct hpi_hsubsys *ph_subsys, 2297u16 hpi_sample_clock_query_source_index(const u32 h_clock, const u32 index,
2591 const u32 h_clock, const u32 index, const u32 source, 2298 const u32 source, u16 *pw_source_index)
2592 u16 *pw_source_index)
2593{ 2299{
2594 u32 qr; 2300 u32 qr;
2595 u16 err; 2301 u16 err;
2596 2302
2597 err = hpi_control_query(ph_subsys, h_clock, 2303 err = hpi_control_query(h_clock, HPI_SAMPLECLOCK_SOURCE_INDEX, index,
2598 HPI_SAMPLECLOCK_SOURCE_INDEX, index, source, &qr); 2304 source, &qr);
2599 *pw_source_index = (u16)qr; 2305 *pw_source_index = (u16)qr;
2600 return err; 2306 return err;
2601} 2307}
2602 2308
2603u16 hpi_sample_clock_set_source_index(const struct hpi_hsubsys *ph_subsys, 2309u16 hpi_sample_clock_set_source_index(u32 h_control, u16 source_index)
2604 u32 h_control, u16 source_index)
2605{ 2310{
2606 return hpi_control_param_set(ph_subsys, h_control, 2311 return hpi_control_param_set(h_control, HPI_SAMPLECLOCK_SOURCE_INDEX,
2607 HPI_SAMPLECLOCK_SOURCE_INDEX, source_index, 0); 2312 source_index, 0);
2608} 2313}
2609 2314
2610u16 hpi_sample_clock_get_source_index(const struct hpi_hsubsys *ph_subsys, 2315u16 hpi_sample_clock_get_source_index(u32 h_control, u16 *pw_source_index)
2611 u32 h_control, u16 *pw_source_index)
2612{ 2316{
2613 u16 error = 0; 2317 u16 err = 0;
2614 u32 source_index = 0; 2318 u32 source_index = 0;
2615 error = hpi_control_param1_get(ph_subsys, h_control, 2319 err = hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_SOURCE_INDEX,
2616 HPI_SAMPLECLOCK_SOURCE_INDEX, &source_index); 2320 &source_index);
2617 if (!error) 2321 if (!err)
2618 if (pw_source_index) 2322 if (pw_source_index)
2619 *pw_source_index = (u16)source_index; 2323 *pw_source_index = (u16)source_index;
2620 return error; 2324 return err;
2621} 2325}
2622 2326
2623u16 hpi_sample_clock_query_local_rate(const struct hpi_hsubsys *ph_subsys, 2327u16 hpi_sample_clock_query_local_rate(const u32 h_clock, const u32 index,
2624 const u32 h_clock, const u32 index, u32 *prate) 2328 u32 *prate)
2625{ 2329{
2626 u16 err; 2330 u16 err;
2627 err = hpi_control_query(ph_subsys, h_clock, 2331 err = hpi_control_query(h_clock, HPI_SAMPLECLOCK_LOCAL_SAMPLERATE,
2628 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, index, 0, prate); 2332 index, 0, prate);
2629 2333
2630 return err; 2334 return err;
2631} 2335}
2632 2336
2633u16 hpi_sample_clock_set_local_rate(const struct hpi_hsubsys *ph_subsys, 2337u16 hpi_sample_clock_set_local_rate(u32 h_control, u32 sample_rate)
2634 u32 h_control, u32 sample_rate)
2635{ 2338{
2636 return hpi_control_param_set(ph_subsys, h_control, 2339 return hpi_control_param_set(h_control,
2637 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, sample_rate, 0); 2340 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, sample_rate, 0);
2638} 2341}
2639 2342
2640u16 hpi_sample_clock_get_local_rate(const struct hpi_hsubsys *ph_subsys, 2343u16 hpi_sample_clock_get_local_rate(u32 h_control, u32 *psample_rate)
2641 u32 h_control, u32 *psample_rate)
2642{ 2344{
2643 u16 error = 0; 2345 u16 err = 0;
2644 u32 sample_rate = 0; 2346 u32 sample_rate = 0;
2645 error = hpi_control_param1_get(ph_subsys, h_control, 2347 err = hpi_control_param1_get(h_control,
2646 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, &sample_rate); 2348 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, &sample_rate);
2647 if (!error) 2349 if (!err)
2648 if (psample_rate) 2350 if (psample_rate)
2649 *psample_rate = sample_rate; 2351 *psample_rate = sample_rate;
2650 return error; 2352 return err;
2651} 2353}
2652 2354
2653u16 hpi_sample_clock_get_sample_rate(const struct hpi_hsubsys *ph_subsys, 2355u16 hpi_sample_clock_get_sample_rate(u32 h_control, u32 *psample_rate)
2654 u32 h_control, u32 *psample_rate)
2655{ 2356{
2656 u16 error = 0; 2357 u16 err = 0;
2657 u32 sample_rate = 0; 2358 u32 sample_rate = 0;
2658 error = hpi_control_param1_get(ph_subsys, h_control, 2359 err = hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_SAMPLERATE,
2659 HPI_SAMPLECLOCK_SAMPLERATE, &sample_rate); 2360 &sample_rate);
2660 if (!error) 2361 if (!err)
2661 if (psample_rate) 2362 if (psample_rate)
2662 *psample_rate = sample_rate; 2363 *psample_rate = sample_rate;
2663 return error; 2364 return err;
2664} 2365}
2665 2366
2666u16 hpi_sample_clock_set_auto(const struct hpi_hsubsys *ph_subsys, 2367u16 hpi_sample_clock_set_auto(u32 h_control, u32 enable)
2667 u32 h_control, u32 enable)
2668{ 2368{
2669 return hpi_control_param_set(ph_subsys, h_control, 2369 return hpi_control_param_set(h_control, HPI_SAMPLECLOCK_AUTO, enable,
2670 HPI_SAMPLECLOCK_AUTO, enable, 0); 2370 0);
2671} 2371}
2672 2372
2673u16 hpi_sample_clock_get_auto(const struct hpi_hsubsys *ph_subsys, 2373u16 hpi_sample_clock_get_auto(u32 h_control, u32 *penable)
2674 u32 h_control, u32 *penable)
2675{ 2374{
2676 return hpi_control_param1_get(ph_subsys, h_control, 2375 return hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_AUTO,
2677 HPI_SAMPLECLOCK_AUTO, penable); 2376 penable);
2678} 2377}
2679 2378
2680u16 hpi_sample_clock_set_local_rate_lock(const struct hpi_hsubsys *ph_subsys, 2379u16 hpi_sample_clock_set_local_rate_lock(u32 h_control, u32 lock)
2681 u32 h_control, u32 lock)
2682{ 2380{
2683 return hpi_control_param_set(ph_subsys, h_control, 2381 return hpi_control_param_set(h_control, HPI_SAMPLECLOCK_LOCAL_LOCK,
2684 HPI_SAMPLECLOCK_LOCAL_LOCK, lock, 0); 2382 lock, 0);
2685} 2383}
2686 2384
2687u16 hpi_sample_clock_get_local_rate_lock(const struct hpi_hsubsys *ph_subsys, 2385u16 hpi_sample_clock_get_local_rate_lock(u32 h_control, u32 *plock)
2688 u32 h_control, u32 *plock)
2689{ 2386{
2690 return hpi_control_param1_get(ph_subsys, h_control, 2387 return hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_LOCAL_LOCK,
2691 HPI_SAMPLECLOCK_LOCAL_LOCK, plock); 2388 plock);
2692} 2389}
2693 2390
2694u16 hpi_tone_detector_get_frequency(const struct hpi_hsubsys *ph_subsys, 2391u16 hpi_tone_detector_get_frequency(u32 h_control, u32 index, u32 *frequency)
2695 u32 h_control, u32 index, u32 *frequency)
2696{ 2392{
2697 return hpi_control_param_get(ph_subsys, h_control, 2393 return hpi_control_param_get(h_control, HPI_TONEDETECTOR_FREQUENCY,
2698 HPI_TONEDETECTOR_FREQUENCY, index, 0, frequency, NULL); 2394 index, 0, frequency, NULL);
2699} 2395}
2700 2396
2701u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys, 2397u16 hpi_tone_detector_get_state(u32 h_control, u32 *state)
2702 u32 h_control, u32 *state)
2703{ 2398{
2704 return hpi_control_param1_get(ph_subsys, h_control, 2399 return hpi_control_param1_get(h_control, HPI_TONEDETECTOR_STATE,
2705 HPI_TONEDETECTOR_STATE, state); 2400 state);
2706} 2401}
2707 2402
2708u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys, 2403u16 hpi_tone_detector_set_enable(u32 h_control, u32 enable)
2709 u32 h_control, u32 enable)
2710{ 2404{
2711 return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE, 2405 return hpi_control_param_set(h_control, HPI_GENERIC_ENABLE, enable,
2712 (u32)enable, 0); 2406 0);
2713} 2407}
2714 2408
2715u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys, 2409u16 hpi_tone_detector_get_enable(u32 h_control, u32 *enable)
2716 u32 h_control, u32 *enable)
2717{ 2410{
2718 return hpi_control_param1_get(ph_subsys, h_control, 2411 return hpi_control_param1_get(h_control, HPI_GENERIC_ENABLE, enable);
2719 HPI_GENERIC_ENABLE, enable);
2720} 2412}
2721 2413
2722u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, 2414u16 hpi_tone_detector_set_event_enable(u32 h_control, u32 event_enable)
2723 u32 h_control, u32 event_enable)
2724{ 2415{
2725 return hpi_control_param_set(ph_subsys, h_control, 2416 return hpi_control_param_set(h_control, HPI_GENERIC_EVENT_ENABLE,
2726 HPI_GENERIC_EVENT_ENABLE, (u32)event_enable, 0); 2417 (u32)event_enable, 0);
2727} 2418}
2728 2419
2729u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys, 2420u16 hpi_tone_detector_get_event_enable(u32 h_control, u32 *event_enable)
2730 u32 h_control, u32 *event_enable)
2731{ 2421{
2732 return hpi_control_param1_get(ph_subsys, h_control, 2422 return hpi_control_param1_get(h_control, HPI_GENERIC_EVENT_ENABLE,
2733 HPI_GENERIC_EVENT_ENABLE, event_enable); 2423 event_enable);
2734} 2424}
2735 2425
2736u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, 2426u16 hpi_tone_detector_set_threshold(u32 h_control, int threshold)
2737 u32 h_control, int threshold)
2738{ 2427{
2739 return hpi_control_param_set(ph_subsys, h_control, 2428 return hpi_control_param_set(h_control, HPI_TONEDETECTOR_THRESHOLD,
2740 HPI_TONEDETECTOR_THRESHOLD, (u32)threshold, 0); 2429 (u32)threshold, 0);
2741} 2430}
2742 2431
2743u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys, 2432u16 hpi_tone_detector_get_threshold(u32 h_control, int *threshold)
2744 u32 h_control, int *threshold)
2745{ 2433{
2746 return hpi_control_param1_get(ph_subsys, h_control, 2434 return hpi_control_param1_get(h_control, HPI_TONEDETECTOR_THRESHOLD,
2747 HPI_TONEDETECTOR_THRESHOLD, (u32 *)threshold); 2435 (u32 *)threshold);
2748} 2436}
2749 2437
2750u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys, 2438u16 hpi_silence_detector_get_state(u32 h_control, u32 *state)
2751 u32 h_control, u32 *state)
2752{ 2439{
2753 return hpi_control_param1_get(ph_subsys, h_control, 2440 return hpi_control_param1_get(h_control, HPI_SILENCEDETECTOR_STATE,
2754 HPI_SILENCEDETECTOR_STATE, state); 2441 state);
2755} 2442}
2756 2443
2757u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys, 2444u16 hpi_silence_detector_set_enable(u32 h_control, u32 enable)
2758 u32 h_control, u32 enable)
2759{ 2445{
2760 return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE, 2446 return hpi_control_param_set(h_control, HPI_GENERIC_ENABLE, enable,
2761 (u32)enable, 0); 2447 0);
2762} 2448}
2763 2449
2764u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys, 2450u16 hpi_silence_detector_get_enable(u32 h_control, u32 *enable)
2765 u32 h_control, u32 *enable)
2766{ 2451{
2767 return hpi_control_param1_get(ph_subsys, h_control, 2452 return hpi_control_param1_get(h_control, HPI_GENERIC_ENABLE, enable);
2768 HPI_GENERIC_ENABLE, enable);
2769} 2453}
2770 2454
2771u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, 2455u16 hpi_silence_detector_set_event_enable(u32 h_control, u32 event_enable)
2772 u32 h_control, u32 event_enable)
2773{ 2456{
2774 return hpi_control_param_set(ph_subsys, h_control, 2457 return hpi_control_param_set(h_control, HPI_GENERIC_EVENT_ENABLE,
2775 HPI_GENERIC_EVENT_ENABLE, event_enable, 0); 2458 event_enable, 0);
2776} 2459}
2777 2460
2778u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys, 2461u16 hpi_silence_detector_get_event_enable(u32 h_control, u32 *event_enable)
2779 u32 h_control, u32 *event_enable)
2780{ 2462{
2781 return hpi_control_param1_get(ph_subsys, h_control, 2463 return hpi_control_param1_get(h_control, HPI_GENERIC_EVENT_ENABLE,
2782 HPI_GENERIC_EVENT_ENABLE, event_enable); 2464 event_enable);
2783} 2465}
2784 2466
2785u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys, 2467u16 hpi_silence_detector_set_delay(u32 h_control, u32 delay)
2786 u32 h_control, u32 delay)
2787{ 2468{
2788 return hpi_control_param_set(ph_subsys, h_control, 2469 return hpi_control_param_set(h_control, HPI_SILENCEDETECTOR_DELAY,
2789 HPI_SILENCEDETECTOR_DELAY, delay, 0); 2470 delay, 0);
2790} 2471}
2791 2472
2792u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys, 2473u16 hpi_silence_detector_get_delay(u32 h_control, u32 *delay)
2793 u32 h_control, u32 *delay)
2794{ 2474{
2795 return hpi_control_param1_get(ph_subsys, h_control, 2475 return hpi_control_param1_get(h_control, HPI_SILENCEDETECTOR_DELAY,
2796 HPI_SILENCEDETECTOR_DELAY, delay); 2476 delay);
2797} 2477}
2798 2478
2799u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, 2479u16 hpi_silence_detector_set_threshold(u32 h_control, int threshold)
2800 u32 h_control, int threshold)
2801{ 2480{
2802 return hpi_control_param_set(ph_subsys, h_control, 2481 return hpi_control_param_set(h_control, HPI_SILENCEDETECTOR_THRESHOLD,
2803 HPI_SILENCEDETECTOR_THRESHOLD, threshold, 0); 2482 threshold, 0);
2804} 2483}
2805 2484
2806u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys, 2485u16 hpi_silence_detector_get_threshold(u32 h_control, int *threshold)
2807 u32 h_control, int *threshold)
2808{ 2486{
2809 return hpi_control_param1_get(ph_subsys, h_control, 2487 return hpi_control_param1_get(h_control,
2810 HPI_SILENCEDETECTOR_THRESHOLD, (u32 *)threshold); 2488 HPI_SILENCEDETECTOR_THRESHOLD, (u32 *)threshold);
2811} 2489}
2812 2490
2813u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys, 2491u16 hpi_tuner_query_band(const u32 h_tuner, const u32 index, u16 *pw_band)
2814 const u32 h_tuner, const u32 index, u16 *pw_band)
2815{ 2492{
2816 u32 qr; 2493 u32 qr;
2817 u16 err; 2494 u16 err;
2818 2495
2819 err = hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_BAND, index, 0, 2496 err = hpi_control_query(h_tuner, HPI_TUNER_BAND, index, 0, &qr);
2820 &qr);
2821 *pw_band = (u16)qr; 2497 *pw_band = (u16)qr;
2822 return err; 2498 return err;
2823} 2499}
2824 2500
2825u16 hpi_tuner_set_band(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2501u16 hpi_tuner_set_band(u32 h_control, u16 band)
2826 u16 band)
2827{ 2502{
2828 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_BAND, 2503 return hpi_control_param_set(h_control, HPI_TUNER_BAND, band, 0);
2829 band, 0);
2830} 2504}
2831 2505
2832u16 hpi_tuner_get_band(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2506u16 hpi_tuner_get_band(u32 h_control, u16 *pw_band)
2833 u16 *pw_band)
2834{ 2507{
2835 u32 band = 0; 2508 u32 band = 0;
2836 u16 error = 0; 2509 u16 error = 0;
2837 2510
2838 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_BAND, 2511 error = hpi_control_param1_get(h_control, HPI_TUNER_BAND, &band);
2839 &band);
2840 if (pw_band) 2512 if (pw_band)
2841 *pw_band = (u16)band; 2513 *pw_band = (u16)band;
2842 return error; 2514 return error;
2843} 2515}
2844 2516
2845u16 hpi_tuner_query_frequency(const struct hpi_hsubsys *ph_subsys, 2517u16 hpi_tuner_query_frequency(const u32 h_tuner, const u32 index,
2846 const u32 h_tuner, const u32 index, const u16 band, u32 *pfreq) 2518 const u16 band, u32 *pfreq)
2847{ 2519{
2848 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_FREQ, index, 2520 return hpi_control_query(h_tuner, HPI_TUNER_FREQ, index, band, pfreq);
2849 band, pfreq);
2850} 2521}
2851 2522
2852u16 hpi_tuner_set_frequency(const struct hpi_hsubsys *ph_subsys, 2523u16 hpi_tuner_set_frequency(u32 h_control, u32 freq_ink_hz)
2853 u32 h_control, u32 freq_ink_hz)
2854{ 2524{
2855 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_FREQ, 2525 return hpi_control_param_set(h_control, HPI_TUNER_FREQ, freq_ink_hz,
2856 freq_ink_hz, 0); 2526 0);
2857} 2527}
2858 2528
2859u16 hpi_tuner_get_frequency(const struct hpi_hsubsys *ph_subsys, 2529u16 hpi_tuner_get_frequency(u32 h_control, u32 *pw_freq_ink_hz)
2860 u32 h_control, u32 *pw_freq_ink_hz)
2861{ 2530{
2862 return hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_FREQ, 2531 return hpi_control_param1_get(h_control, HPI_TUNER_FREQ,
2863 pw_freq_ink_hz); 2532 pw_freq_ink_hz);
2864} 2533}
2865 2534
2866u16 hpi_tuner_query_gain(const struct hpi_hsubsys *ph_subsys, 2535u16 hpi_tuner_query_gain(const u32 h_tuner, const u32 index, u16 *pw_gain)
2867 const u32 h_tuner, const u32 index, u16 *pw_gain)
2868{ 2536{
2869 u32 qr; 2537 u32 qr;
2870 u16 err; 2538 u16 err;
2871 2539
2872 err = hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_BAND, index, 0, 2540 err = hpi_control_query(h_tuner, HPI_TUNER_BAND, index, 0, &qr);
2873 &qr);
2874 *pw_gain = (u16)qr; 2541 *pw_gain = (u16)qr;
2875 return err; 2542 return err;
2876} 2543}
2877 2544
2878u16 hpi_tuner_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2545u16 hpi_tuner_set_gain(u32 h_control, short gain)
2879 short gain)
2880{ 2546{
2881 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_GAIN, 2547 return hpi_control_param_set(h_control, HPI_TUNER_GAIN, gain, 0);
2882 gain, 0);
2883} 2548}
2884 2549
2885u16 hpi_tuner_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2550u16 hpi_tuner_get_gain(u32 h_control, short *pn_gain)
2886 short *pn_gain)
2887{ 2551{
2888 u32 gain = 0; 2552 u32 gain = 0;
2889 u16 error = 0; 2553 u16 error = 0;
2890 2554
2891 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_GAIN, 2555 error = hpi_control_param1_get(h_control, HPI_TUNER_GAIN, &gain);
2892 &gain);
2893 if (pn_gain) 2556 if (pn_gain)
2894 *pn_gain = (u16)gain; 2557 *pn_gain = (u16)gain;
2895 return error; 2558 return error;
2896} 2559}
2897 2560
2898u16 hpi_tuner_getRF_level(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2561u16 hpi_tuner_get_rf_level(u32 h_control, short *pw_level)
2899 short *pw_level)
2900{ 2562{
2901 struct hpi_message hm; 2563 struct hpi_message hm;
2902 struct hpi_response hr; 2564 struct hpi_response hr;
2903 2565
2904 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2566 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2905 HPI_CONTROL_GET_STATE); 2567 HPI_CONTROL_GET_STATE);
2906 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2568 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2907 hm.u.c.attribute = HPI_TUNER_LEVEL; 2569 return HPI_ERROR_INVALID_HANDLE;
2908 hm.u.c.param1 = HPI_TUNER_LEVEL_AVERAGE; 2570 hm.u.cu.attribute = HPI_TUNER_LEVEL_AVG;
2909 hpi_send_recv(&hm, &hr); 2571 hpi_send_recv(&hm, &hr);
2910 if (pw_level) 2572 if (pw_level)
2911 *pw_level = (short)hr.u.c.param1; 2573 *pw_level = hr.u.cu.tuner.s_level;
2912 return hr.error; 2574 return hr.error;
2913} 2575}
2914 2576
2915u16 hpi_tuner_get_rawRF_level(const struct hpi_hsubsys *ph_subsys, 2577u16 hpi_tuner_get_raw_rf_level(u32 h_control, short *pw_level)
2916 u32 h_control, short *pw_level)
2917{ 2578{
2918 struct hpi_message hm; 2579 struct hpi_message hm;
2919 struct hpi_response hr; 2580 struct hpi_response hr;
2920 2581
2921 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2582 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2922 HPI_CONTROL_GET_STATE); 2583 HPI_CONTROL_GET_STATE);
2923 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2584 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2924 hm.u.c.attribute = HPI_TUNER_LEVEL; 2585 return HPI_ERROR_INVALID_HANDLE;
2925 hm.u.c.param1 = HPI_TUNER_LEVEL_RAW; 2586 hm.u.cu.attribute = HPI_TUNER_LEVEL_RAW;
2926 hpi_send_recv(&hm, &hr); 2587 hpi_send_recv(&hm, &hr);
2927 if (pw_level) 2588 if (pw_level)
2928 *pw_level = (short)hr.u.c.param1; 2589 *pw_level = hr.u.cu.tuner.s_level;
2929 return hr.error; 2590 return hr.error;
2930} 2591}
2931 2592
2932u16 hpi_tuner_query_deemphasis(const struct hpi_hsubsys *ph_subsys, 2593u16 hpi_tuner_query_deemphasis(const u32 h_tuner, const u32 index,
2933 const u32 h_tuner, const u32 index, const u16 band, u32 *pdeemphasis) 2594 const u16 band, u32 *pdeemphasis)
2934{ 2595{
2935 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_DEEMPHASIS, 2596 return hpi_control_query(h_tuner, HPI_TUNER_DEEMPHASIS, index, band,
2936 index, band, pdeemphasis); 2597 pdeemphasis);
2937} 2598}
2938 2599
2939u16 hpi_tuner_set_deemphasis(const struct hpi_hsubsys *ph_subsys, 2600u16 hpi_tuner_set_deemphasis(u32 h_control, u32 deemphasis)
2940 u32 h_control, u32 deemphasis)
2941{ 2601{
2942 return hpi_control_param_set(ph_subsys, h_control, 2602 return hpi_control_param_set(h_control, HPI_TUNER_DEEMPHASIS,
2943 HPI_TUNER_DEEMPHASIS, deemphasis, 0); 2603 deemphasis, 0);
2944} 2604}
2945 2605
2946u16 hpi_tuner_get_deemphasis(const struct hpi_hsubsys *ph_subsys, 2606u16 hpi_tuner_get_deemphasis(u32 h_control, u32 *pdeemphasis)
2947 u32 h_control, u32 *pdeemphasis)
2948{ 2607{
2949 return hpi_control_param1_get(ph_subsys, h_control, 2608 return hpi_control_param1_get(h_control, HPI_TUNER_DEEMPHASIS,
2950 HPI_TUNER_DEEMPHASIS, pdeemphasis); 2609 pdeemphasis);
2951} 2610}
2952 2611
2953u16 hpi_tuner_query_program(const struct hpi_hsubsys *ph_subsys, 2612u16 hpi_tuner_query_program(const u32 h_tuner, u32 *pbitmap_program)
2954 const u32 h_tuner, u32 *pbitmap_program)
2955{ 2613{
2956 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_PROGRAM, 0, 0, 2614 return hpi_control_query(h_tuner, HPI_TUNER_PROGRAM, 0, 0,
2957 pbitmap_program); 2615 pbitmap_program);
2958} 2616}
2959 2617
2960u16 hpi_tuner_set_program(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2618u16 hpi_tuner_set_program(u32 h_control, u32 program)
2961 u32 program)
2962{ 2619{
2963 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_PROGRAM, 2620 return hpi_control_param_set(h_control, HPI_TUNER_PROGRAM, program,
2964 program, 0); 2621 0);
2965} 2622}
2966 2623
2967u16 hpi_tuner_get_program(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2624u16 hpi_tuner_get_program(u32 h_control, u32 *pprogram)
2968 u32 *pprogram)
2969{ 2625{
2970 return hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_PROGRAM, 2626 return hpi_control_param1_get(h_control, HPI_TUNER_PROGRAM, pprogram);
2971 pprogram);
2972} 2627}
2973 2628
2974u16 hpi_tuner_get_hd_radio_dsp_version(const struct hpi_hsubsys *ph_subsys, 2629u16 hpi_tuner_get_hd_radio_dsp_version(u32 h_control, char *psz_dsp_version,
2975 u32 h_control, char *psz_dsp_version, const u32 string_size) 2630 const u32 string_size)
2976{ 2631{
2977 return hpi_control_get_string(h_control, 2632 return hpi_control_get_string(h_control,
2978 HPI_TUNER_HDRADIO_DSP_VERSION, psz_dsp_version, string_size); 2633 HPI_TUNER_HDRADIO_DSP_VERSION, psz_dsp_version, string_size);
2979} 2634}
2980 2635
2981u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys, 2636u16 hpi_tuner_get_hd_radio_sdk_version(u32 h_control, char *psz_sdk_version,
2982 u32 h_control, char *psz_sdk_version, const u32 string_size) 2637 const u32 string_size)
2983{ 2638{
2984 return hpi_control_get_string(h_control, 2639 return hpi_control_get_string(h_control,
2985 HPI_TUNER_HDRADIO_SDK_VERSION, psz_sdk_version, string_size); 2640 HPI_TUNER_HDRADIO_SDK_VERSION, psz_sdk_version, string_size);
2986} 2641}
2987 2642
2988u16 hpi_tuner_get_status(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2643u16 hpi_tuner_get_status(u32 h_control, u16 *pw_status_mask, u16 *pw_status)
2989 u16 *pw_status_mask, u16 *pw_status)
2990{ 2644{
2991 u32 status = 0; 2645 u32 status = 0;
2992 u16 error = 0; 2646 u16 error = 0;
2993 2647
2994 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_STATUS, 2648 error = hpi_control_param1_get(h_control, HPI_TUNER_STATUS, &status);
2995 &status);
2996 if (pw_status) { 2649 if (pw_status) {
2997 if (!error) { 2650 if (!error) {
2998 *pw_status_mask = (u16)(status >> 16); 2651 *pw_status_mask = (u16)(status >> 16);
@@ -3005,50 +2658,44 @@ u16 hpi_tuner_get_status(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3005 return error; 2658 return error;
3006} 2659}
3007 2660
3008u16 hpi_tuner_set_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2661u16 hpi_tuner_set_mode(u32 h_control, u32 mode, u32 value)
3009 u32 mode, u32 value)
3010{ 2662{
3011 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_MODE, 2663 return hpi_control_param_set(h_control, HPI_TUNER_MODE, mode, value);
3012 mode, value);
3013} 2664}
3014 2665
3015u16 hpi_tuner_get_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2666u16 hpi_tuner_get_mode(u32 h_control, u32 mode, u32 *pn_value)
3016 u32 mode, u32 *pn_value)
3017{ 2667{
3018 return hpi_control_param_get(ph_subsys, h_control, HPI_TUNER_MODE, 2668 return hpi_control_param_get(h_control, HPI_TUNER_MODE, mode, 0,
3019 mode, 0, pn_value, NULL); 2669 pn_value, NULL);
3020} 2670}
3021 2671
3022u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys, 2672u16 hpi_tuner_get_hd_radio_signal_quality(u32 h_control, u32 *pquality)
3023 u32 h_control, u32 *pquality)
3024{ 2673{
3025 return hpi_control_param1_get(ph_subsys, h_control, 2674 return hpi_control_param1_get(h_control,
3026 HPI_TUNER_HDRADIO_SIGNAL_QUALITY, pquality); 2675 HPI_TUNER_HDRADIO_SIGNAL_QUALITY, pquality);
3027} 2676}
3028 2677
3029u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, 2678u16 hpi_tuner_get_hd_radio_signal_blend(u32 h_control, u32 *pblend)
3030 u32 h_control, u32 *pblend)
3031{ 2679{
3032 return hpi_control_param1_get(ph_subsys, h_control, 2680 return hpi_control_param1_get(h_control, HPI_TUNER_HDRADIO_BLEND,
3033 HPI_TUNER_HDRADIO_BLEND, pblend); 2681 pblend);
3034} 2682}
3035 2683
3036u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, 2684u16 hpi_tuner_set_hd_radio_signal_blend(u32 h_control, const u32 blend)
3037 u32 h_control, const u32 blend)
3038{ 2685{
3039 return hpi_control_param_set(ph_subsys, h_control, 2686 return hpi_control_param_set(h_control, HPI_TUNER_HDRADIO_BLEND,
3040 HPI_TUNER_HDRADIO_BLEND, blend, 0); 2687 blend, 0);
3041} 2688}
3042 2689
3043u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2690u16 hpi_tuner_get_rds(u32 h_control, char *p_data)
3044 char *p_data)
3045{ 2691{
3046 struct hpi_message hm; 2692 struct hpi_message hm;
3047 struct hpi_response hr; 2693 struct hpi_response hr;
3048 2694
3049 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2695 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3050 HPI_CONTROL_GET_STATE); 2696 HPI_CONTROL_GET_STATE);
3051 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2697 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2698 return HPI_ERROR_INVALID_HANDLE;
3052 hm.u.c.attribute = HPI_TUNER_RDS; 2699 hm.u.c.attribute = HPI_TUNER_RDS;
3053 hpi_send_recv(&hm, &hr); 2700 hpi_send_recv(&hm, &hr);
3054 if (p_data) { 2701 if (p_data) {
@@ -3059,80 +2706,82 @@ u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3059 return hr.error; 2706 return hr.error;
3060} 2707}
3061 2708
3062u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys, 2709u16 hpi_pad_get_channel_name(u32 h_control, char *psz_string,
3063 u32 h_control, char *psz_string, const u32 data_length) 2710 const u32 data_length)
3064{ 2711{
3065 return hpi_control_get_string(h_control, HPI_PAD_CHANNEL_NAME, 2712 return hpi_control_get_string(h_control, HPI_PAD_CHANNEL_NAME,
3066 psz_string, data_length); 2713 psz_string, data_length);
3067} 2714}
3068 2715
3069u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2716u16 hpi_pad_get_artist(u32 h_control, char *psz_string, const u32 data_length)
3070 char *psz_string, const u32 data_length)
3071{ 2717{
3072 return hpi_control_get_string(h_control, HPI_PAD_ARTIST, psz_string, 2718 return hpi_control_get_string(h_control, HPI_PAD_ARTIST, psz_string,
3073 data_length); 2719 data_length);
3074} 2720}
3075 2721
3076u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2722u16 hpi_pad_get_title(u32 h_control, char *psz_string, const u32 data_length)
3077 char *psz_string, const u32 data_length)
3078{ 2723{
3079 return hpi_control_get_string(h_control, HPI_PAD_TITLE, psz_string, 2724 return hpi_control_get_string(h_control, HPI_PAD_TITLE, psz_string,
3080 data_length); 2725 data_length);
3081} 2726}
3082 2727
3083u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2728u16 hpi_pad_get_comment(u32 h_control, char *psz_string,
3084 char *psz_string, const u32 data_length) 2729 const u32 data_length)
3085{ 2730{
3086 return hpi_control_get_string(h_control, HPI_PAD_COMMENT, psz_string, 2731 return hpi_control_get_string(h_control, HPI_PAD_COMMENT, psz_string,
3087 data_length); 2732 data_length);
3088} 2733}
3089 2734
3090u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys, 2735u16 hpi_pad_get_program_type(u32 h_control, u32 *ppTY)
3091 u32 h_control, u32 *ppTY)
3092{ 2736{
3093 return hpi_control_param1_get(ph_subsys, h_control, 2737 return hpi_control_param1_get(h_control, HPI_PAD_PROGRAM_TYPE, ppTY);
3094 HPI_PAD_PROGRAM_TYPE, ppTY);
3095} 2738}
3096 2739
3097u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2740u16 hpi_pad_get_rdsPI(u32 h_control, u32 *ppI)
3098 u32 *ppI)
3099{ 2741{
3100 return hpi_control_param1_get(ph_subsys, h_control, 2742 return hpi_control_param1_get(h_control, HPI_PAD_PROGRAM_ID, ppI);
3101 HPI_PAD_PROGRAM_ID, ppI);
3102} 2743}
3103 2744
3104u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys, 2745u16 hpi_volume_query_channels(const u32 h_volume, u32 *p_channels)
3105 const u32 h_volume, u32 *p_channels)
3106{ 2746{
3107 return hpi_control_query(ph_subsys, h_volume, HPI_VOLUME_NUM_CHANNELS, 2747 return hpi_control_query(h_volume, HPI_VOLUME_NUM_CHANNELS, 0, 0,
3108 0, 0, p_channels); 2748 p_channels);
3109} 2749}
3110 2750
3111u16 hpi_volume_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2751u16 hpi_volume_set_gain(u32 h_control, short an_log_gain[HPI_MAX_CHANNELS]
3112 short an_log_gain[HPI_MAX_CHANNELS]
3113 ) 2752 )
3114{ 2753{
3115 return hpi_control_log_set2(h_control, HPI_VOLUME_GAIN, 2754 return hpi_control_log_set2(h_control, HPI_VOLUME_GAIN,
3116 an_log_gain[0], an_log_gain[1]); 2755 an_log_gain[0], an_log_gain[1]);
3117} 2756}
3118 2757
3119u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2758u16 hpi_volume_get_gain(u32 h_control, short an_log_gain[HPI_MAX_CHANNELS]
3120 short an_log_gain[HPI_MAX_CHANNELS]
3121 ) 2759 )
3122{ 2760{
3123 return hpi_control_log_get2(ph_subsys, h_control, HPI_VOLUME_GAIN, 2761 return hpi_control_log_get2(h_control, HPI_VOLUME_GAIN,
3124 &an_log_gain[0], &an_log_gain[1]); 2762 &an_log_gain[0], &an_log_gain[1]);
3125} 2763}
3126 2764
3127u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2765u16 hpi_volume_set_mute(u32 h_control, u32 mute)
3128 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB) 2766{
2767 return hpi_control_param_set(h_control, HPI_VOLUME_MUTE, mute, 0);
2768}
2769
2770u16 hpi_volume_get_mute(u32 h_control, u32 *mute)
2771{
2772 return hpi_control_param1_get(h_control, HPI_VOLUME_MUTE, mute);
2773}
2774
2775u16 hpi_volume_query_range(u32 h_control, short *min_gain_01dB,
2776 short *max_gain_01dB, short *step_gain_01dB)
3129{ 2777{
3130 struct hpi_message hm; 2778 struct hpi_message hm;
3131 struct hpi_response hr; 2779 struct hpi_response hr;
3132 2780
3133 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2781 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3134 HPI_CONTROL_GET_STATE); 2782 HPI_CONTROL_GET_STATE);
3135 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2783 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2784 return HPI_ERROR_INVALID_HANDLE;
3136 hm.u.c.attribute = HPI_VOLUME_RANGE; 2785 hm.u.c.attribute = HPI_VOLUME_RANGE;
3137 2786
3138 hpi_send_recv(&hm, &hr); 2787 hpi_send_recv(&hm, &hr);
@@ -3150,16 +2799,17 @@ u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3150 return hr.error; 2799 return hr.error;
3151} 2800}
3152 2801
3153u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys, 2802u16 hpi_volume_auto_fade_profile(u32 h_control,
3154 u32 h_control, short an_stop_gain0_01dB[HPI_MAX_CHANNELS], 2803 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms,
3155 u32 duration_ms, u16 profile) 2804 u16 profile)
3156{ 2805{
3157 struct hpi_message hm; 2806 struct hpi_message hm;
3158 struct hpi_response hr; 2807 struct hpi_response hr;
3159 2808
3160 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2809 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3161 HPI_CONTROL_SET_STATE); 2810 HPI_CONTROL_SET_STATE);
3162 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2811 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2812 return HPI_ERROR_INVALID_HANDLE;
3163 2813
3164 memcpy(hm.u.c.an_log_value, an_stop_gain0_01dB, 2814 memcpy(hm.u.c.an_log_value, an_stop_gain0_01dB,
3165 sizeof(short) * HPI_MAX_CHANNELS); 2815 sizeof(short) * HPI_MAX_CHANNELS);
@@ -3173,21 +2823,21 @@ u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys,
3173 return hr.error; 2823 return hr.error;
3174} 2824}
3175 2825
3176u16 hpi_volume_auto_fade(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2826u16 hpi_volume_auto_fade(u32 h_control,
3177 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms) 2827 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms)
3178{ 2828{
3179 return hpi_volume_auto_fade_profile(ph_subsys, h_control, 2829 return hpi_volume_auto_fade_profile(h_control, an_stop_gain0_01dB,
3180 an_stop_gain0_01dB, duration_ms, HPI_VOLUME_AUTOFADE_LOG); 2830 duration_ms, HPI_VOLUME_AUTOFADE_LOG);
3181} 2831}
3182 2832
3183u16 hpi_vox_set_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2833u16 hpi_vox_set_threshold(u32 h_control, short an_gain0_01dB)
3184 short an_gain0_01dB)
3185{ 2834{
3186 struct hpi_message hm; 2835 struct hpi_message hm;
3187 struct hpi_response hr; 2836 struct hpi_response hr;
3188 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2837 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3189 HPI_CONTROL_SET_STATE); 2838 HPI_CONTROL_SET_STATE);
3190 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2839 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2840 return HPI_ERROR_INVALID_HANDLE;
3191 hm.u.c.attribute = HPI_VOX_THRESHOLD; 2841 hm.u.c.attribute = HPI_VOX_THRESHOLD;
3192 2842
3193 hm.u.c.an_log_value[0] = an_gain0_01dB; 2843 hm.u.c.an_log_value[0] = an_gain0_01dB;
@@ -3197,14 +2847,14 @@ u16 hpi_vox_set_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3197 return hr.error; 2847 return hr.error;
3198} 2848}
3199 2849
3200u16 hpi_vox_get_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2850u16 hpi_vox_get_threshold(u32 h_control, short *an_gain0_01dB)
3201 short *an_gain0_01dB)
3202{ 2851{
3203 struct hpi_message hm; 2852 struct hpi_message hm;
3204 struct hpi_response hr; 2853 struct hpi_response hr;
3205 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2854 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3206 HPI_CONTROL_GET_STATE); 2855 HPI_CONTROL_GET_STATE);
3207 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2856 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2857 return HPI_ERROR_INVALID_HANDLE;
3208 hm.u.c.attribute = HPI_VOX_THRESHOLD; 2858 hm.u.c.attribute = HPI_VOX_THRESHOLD;
3209 2859
3210 hpi_send_recv(&hm, &hr); 2860 hpi_send_recv(&hm, &hr);
@@ -3213,728 +2863,3 @@ u16 hpi_vox_get_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3213 2863
3214 return hr.error; 2864 return hr.error;
3215} 2865}
3216
3217static size_t strv_packet_size = MIN_STRV_PACKET_SIZE;
3218
3219static size_t entity_type_to_size[LAST_ENTITY_TYPE] = {
3220 0,
3221 sizeof(struct hpi_entity),
3222 sizeof(void *),
3223
3224 sizeof(int),
3225 sizeof(float),
3226 sizeof(double),
3227
3228 sizeof(char),
3229 sizeof(char),
3230
3231 4 * sizeof(char),
3232 16 * sizeof(char),
3233 6 * sizeof(char),
3234};
3235
3236static inline size_t hpi_entity_size(struct hpi_entity *entity_ptr)
3237{
3238 return entity_ptr->header.size;
3239}
3240
3241static inline size_t hpi_entity_header_size(struct hpi_entity *entity_ptr)
3242{
3243 return sizeof(entity_ptr->header);
3244}
3245
3246static inline size_t hpi_entity_value_size(struct hpi_entity *entity_ptr)
3247{
3248 return hpi_entity_size(entity_ptr) -
3249 hpi_entity_header_size(entity_ptr);
3250}
3251
3252static inline size_t hpi_entity_item_count(struct hpi_entity *entity_ptr)
3253{
3254 return hpi_entity_value_size(entity_ptr) /
3255 entity_type_to_size[entity_ptr->header.type];
3256}
3257
3258static inline struct hpi_entity *hpi_entity_ptr_to_next(struct hpi_entity
3259 *entity_ptr)
3260{
3261 return (void *)(((u8 *)entity_ptr) + hpi_entity_size(entity_ptr));
3262}
3263
3264static inline u16 hpi_entity_check_type(const enum e_entity_type t)
3265{
3266 if (t >= 0 && t < STR_TYPE_FIELD_MAX)
3267 return 0;
3268 return HPI_ERROR_ENTITY_TYPE_INVALID;
3269}
3270
3271static inline u16 hpi_entity_check_role(const enum e_entity_role r)
3272{
3273 if (r >= 0 && r < STR_ROLE_FIELD_MAX)
3274 return 0;
3275 return HPI_ERROR_ENTITY_ROLE_INVALID;
3276}
3277
3278static u16 hpi_entity_get_next(struct hpi_entity *entity, int recursive_flag,
3279 void *guard_p, struct hpi_entity **next)
3280{
3281 HPI_DEBUG_ASSERT(entity != NULL);
3282 HPI_DEBUG_ASSERT(next != NULL);
3283 HPI_DEBUG_ASSERT(hpi_entity_size(entity) != 0);
3284
3285 if (guard_p <= (void *)entity) {
3286 *next = NULL;
3287 return 0;
3288 }
3289
3290 if (recursive_flag && entity->header.type == entity_type_sequence)
3291 *next = (struct hpi_entity *)entity->value;
3292 else
3293 *next = (struct hpi_entity *)hpi_entity_ptr_to_next(entity);
3294
3295 if (guard_p <= (void *)*next) {
3296 *next = NULL;
3297 return 0;
3298 }
3299
3300 HPI_DEBUG_ASSERT(guard_p >= (void *)hpi_entity_ptr_to_next(*next));
3301 return 0;
3302}
3303
3304u16 hpi_entity_find_next(struct hpi_entity *container_entity,
3305 enum e_entity_type type, enum e_entity_role role, int recursive_flag,
3306 struct hpi_entity **current_match)
3307{
3308 struct hpi_entity *tmp = NULL;
3309 void *guard_p = NULL;
3310
3311 HPI_DEBUG_ASSERT(container_entity != NULL);
3312 guard_p = hpi_entity_ptr_to_next(container_entity);
3313
3314 if (*current_match != NULL)
3315 hpi_entity_get_next(*current_match, recursive_flag, guard_p,
3316 &tmp);
3317 else
3318 hpi_entity_get_next(container_entity, 1, guard_p, &tmp);
3319
3320 while (tmp) {
3321 u16 err;
3322
3323 HPI_DEBUG_ASSERT((void *)tmp >= (void *)container_entity);
3324
3325 if ((!type || tmp->header.type == type) && (!role
3326 || tmp->header.role == role)) {
3327 *current_match = tmp;
3328 return 0;
3329 }
3330
3331 err = hpi_entity_get_next(tmp, recursive_flag, guard_p,
3332 current_match);
3333 if (err)
3334 return err;
3335
3336 tmp = *current_match;
3337 }
3338
3339 *current_match = NULL;
3340 return 0;
3341}
3342
3343void hpi_entity_free(struct hpi_entity *entity)
3344{
3345 kfree(entity);
3346}
3347
3348static u16 hpi_entity_alloc_and_copy(struct hpi_entity *src,
3349 struct hpi_entity **dst)
3350{
3351 size_t buf_size;
3352 HPI_DEBUG_ASSERT(dst != NULL);
3353 HPI_DEBUG_ASSERT(src != NULL);
3354
3355 buf_size = hpi_entity_size(src);
3356 *dst = kmalloc(buf_size, GFP_KERNEL);
3357 if (*dst == NULL)
3358 return HPI_ERROR_MEMORY_ALLOC;
3359 memcpy(*dst, src, buf_size);
3360 return 0;
3361}
3362
3363u16 hpi_universal_info(const struct hpi_hsubsys *ph_subsys, u32 hC,
3364 struct hpi_entity **info)
3365{
3366 struct hpi_msg_strv hm;
3367 struct hpi_res_strv *phr;
3368 u16 hpi_err;
3369 int remaining_attempts = 2;
3370 size_t resp_packet_size = 1024;
3371
3372 *info = NULL;
3373
3374 while (remaining_attempts--) {
3375 phr = kmalloc(resp_packet_size, GFP_KERNEL);
3376 HPI_DEBUG_ASSERT(phr != NULL);
3377
3378 hpi_init_message_responseV1(&hm.h, (u16)sizeof(hm), &phr->h,
3379 (u16)resp_packet_size, HPI_OBJ_CONTROL,
3380 HPI_CONTROL_GET_INFO);
3381 u32TOINDEXES(hC, &hm.h.adapter_index, &hm.h.obj_index);
3382
3383 hm.strv.header.size = sizeof(hm.strv);
3384 phr->strv.header.size = resp_packet_size - sizeof(phr->h);
3385
3386 hpi_send_recv((struct hpi_message *)&hm.h,
3387 (struct hpi_response *)&phr->h);
3388 if (phr->h.error == HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL) {
3389
3390 HPI_DEBUG_ASSERT(phr->h.specific_error >
3391 MIN_STRV_PACKET_SIZE
3392 && phr->h.specific_error < 1500);
3393 resp_packet_size = phr->h.specific_error;
3394 } else {
3395 remaining_attempts = 0;
3396 if (!phr->h.error)
3397 hpi_entity_alloc_and_copy(&phr->strv, info);
3398 }
3399
3400 hpi_err = phr->h.error;
3401 kfree(phr);
3402 }
3403
3404 return hpi_err;
3405}
3406
3407u16 hpi_universal_get(const struct hpi_hsubsys *ph_subsys, u32 hC,
3408 struct hpi_entity **value)
3409{
3410 struct hpi_msg_strv hm;
3411 struct hpi_res_strv *phr;
3412 u16 hpi_err;
3413 int remaining_attempts = 2;
3414
3415 *value = NULL;
3416
3417 while (remaining_attempts--) {
3418 phr = kmalloc(strv_packet_size, GFP_KERNEL);
3419 if (!phr)
3420 return HPI_ERROR_MEMORY_ALLOC;
3421
3422 hpi_init_message_responseV1(&hm.h, (u16)sizeof(hm), &phr->h,
3423 (u16)strv_packet_size, HPI_OBJ_CONTROL,
3424 HPI_CONTROL_GET_STATE);
3425 u32TOINDEXES(hC, &hm.h.adapter_index, &hm.h.obj_index);
3426
3427 hm.strv.header.size = sizeof(hm.strv);
3428 phr->strv.header.size = strv_packet_size - sizeof(phr->h);
3429
3430 hpi_send_recv((struct hpi_message *)&hm.h,
3431 (struct hpi_response *)&phr->h);
3432 if (phr->h.error == HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL) {
3433
3434 HPI_DEBUG_ASSERT(phr->h.specific_error >
3435 MIN_STRV_PACKET_SIZE
3436 && phr->h.specific_error < 1000);
3437 strv_packet_size = phr->h.specific_error;
3438 } else {
3439 remaining_attempts = 0;
3440 if (!phr->h.error)
3441 hpi_entity_alloc_and_copy(&phr->strv, value);
3442 }
3443
3444 hpi_err = phr->h.error;
3445 kfree(phr);
3446 }
3447
3448 return hpi_err;
3449}
3450
3451u16 hpi_universal_set(const struct hpi_hsubsys *ph_subsys, u32 hC,
3452 struct hpi_entity *value)
3453{
3454 struct hpi_msg_strv *phm;
3455 struct hpi_res_strv hr;
3456
3457 phm = kmalloc(sizeof(phm->h) + value->header.size, GFP_KERNEL);
3458 HPI_DEBUG_ASSERT(phm != NULL);
3459
3460 hpi_init_message_responseV1(&phm->h,
3461 sizeof(phm->h) + value->header.size, &hr.h, sizeof(hr),
3462 HPI_OBJ_CONTROL, HPI_CONTROL_SET_STATE);
3463 u32TOINDEXES(hC, &phm->h.adapter_index, &phm->h.obj_index);
3464 hr.strv.header.size = sizeof(hr.strv);
3465
3466 memcpy(&phm->strv, value, value->header.size);
3467 hpi_send_recv((struct hpi_message *)&phm->h,
3468 (struct hpi_response *)&hr.h);
3469
3470 return hr.h.error;
3471}
3472
3473u16 hpi_entity_alloc_and_pack(const enum e_entity_type type,
3474 const size_t item_count, const enum e_entity_role role, void *value,
3475 struct hpi_entity **entity)
3476{
3477 size_t bytes_to_copy, total_size;
3478 u16 hE = 0;
3479 *entity = NULL;
3480
3481 hE = hpi_entity_check_type(type);
3482 if (hE)
3483 return hE;
3484
3485 HPI_DEBUG_ASSERT(role > entity_role_null && type < LAST_ENTITY_TYPE);
3486
3487 bytes_to_copy = entity_type_to_size[type] * item_count;
3488 total_size = hpi_entity_header_size(*entity) + bytes_to_copy;
3489
3490 HPI_DEBUG_ASSERT(total_size >= hpi_entity_header_size(*entity)
3491 && total_size < STR_SIZE_FIELD_MAX);
3492
3493 *entity = kmalloc(total_size, GFP_KERNEL);
3494 if (*entity == NULL)
3495 return HPI_ERROR_MEMORY_ALLOC;
3496 memcpy((*entity)->value, value, bytes_to_copy);
3497 (*entity)->header.size =
3498 hpi_entity_header_size(*entity) + bytes_to_copy;
3499 (*entity)->header.type = type;
3500 (*entity)->header.role = role;
3501 return 0;
3502}
3503
3504u16 hpi_entity_copy_value_from(struct hpi_entity *entity,
3505 enum e_entity_type type, size_t item_count, void *value_dst_p)
3506{
3507 size_t bytes_to_copy;
3508
3509 if (entity->header.type != type)
3510 return HPI_ERROR_ENTITY_TYPE_MISMATCH;
3511
3512 if (hpi_entity_item_count(entity) != item_count)
3513 return HPI_ERROR_ENTITY_ITEM_COUNT;
3514
3515 bytes_to_copy = entity_type_to_size[type] * item_count;
3516 memcpy(value_dst_p, entity->value, bytes_to_copy);
3517 return 0;
3518}
3519
3520u16 hpi_entity_unpack(struct hpi_entity *entity, enum e_entity_type *type,
3521 size_t *item_count, enum e_entity_role *role, void **value)
3522{
3523 u16 err = 0;
3524 HPI_DEBUG_ASSERT(entity != NULL);
3525
3526 if (type)
3527 *type = entity->header.type;
3528
3529 if (role)
3530 *role = entity->header.role;
3531
3532 if (value)
3533 *value = entity->value;
3534
3535 if (item_count != NULL) {
3536 if (entity->header.type == entity_type_sequence) {
3537 void *guard_p = hpi_entity_ptr_to_next(entity);
3538 struct hpi_entity *next = NULL;
3539 void *contents = entity->value;
3540
3541 *item_count = 0;
3542 while (contents < guard_p) {
3543 (*item_count)++;
3544 err = hpi_entity_get_next(contents, 0,
3545 guard_p, &next);
3546 if (next == NULL || err)
3547 break;
3548 contents = next;
3549 }
3550 } else {
3551 *item_count = hpi_entity_item_count(entity);
3552 }
3553 }
3554 return err;
3555}
3556
3557u16 hpi_gpio_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3558 u32 *ph_gpio, u16 *pw_number_input_bits, u16 *pw_number_output_bits)
3559{
3560 struct hpi_message hm;
3561 struct hpi_response hr;
3562 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_OPEN);
3563 hm.adapter_index = adapter_index;
3564
3565 hpi_send_recv(&hm, &hr);
3566
3567 if (hr.error == 0) {
3568 *ph_gpio =
3569 hpi_indexes_to_handle(HPI_OBJ_GPIO, adapter_index, 0);
3570 if (pw_number_input_bits)
3571 *pw_number_input_bits = hr.u.l.number_input_bits;
3572 if (pw_number_output_bits)
3573 *pw_number_output_bits = hr.u.l.number_output_bits;
3574 } else
3575 *ph_gpio = 0;
3576 return hr.error;
3577}
3578
3579u16 hpi_gpio_read_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3580 u16 bit_index, u16 *pw_bit_data)
3581{
3582 struct hpi_message hm;
3583 struct hpi_response hr;
3584 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_READ_BIT);
3585 u32TOINDEX(h_gpio, &hm.adapter_index);
3586 hm.u.l.bit_index = bit_index;
3587
3588 hpi_send_recv(&hm, &hr);
3589
3590 *pw_bit_data = hr.u.l.bit_data[0];
3591 return hr.error;
3592}
3593
3594u16 hpi_gpio_read_all_bits(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3595 u16 aw_all_bit_data[4]
3596 )
3597{
3598 struct hpi_message hm;
3599 struct hpi_response hr;
3600 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_READ_ALL);
3601 u32TOINDEX(h_gpio, &hm.adapter_index);
3602
3603 hpi_send_recv(&hm, &hr);
3604
3605 if (aw_all_bit_data) {
3606 aw_all_bit_data[0] = hr.u.l.bit_data[0];
3607 aw_all_bit_data[1] = hr.u.l.bit_data[1];
3608 aw_all_bit_data[2] = hr.u.l.bit_data[2];
3609 aw_all_bit_data[3] = hr.u.l.bit_data[3];
3610 }
3611 return hr.error;
3612}
3613
3614u16 hpi_gpio_write_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3615 u16 bit_index, u16 bit_data)
3616{
3617 struct hpi_message hm;
3618 struct hpi_response hr;
3619 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_WRITE_BIT);
3620 u32TOINDEX(h_gpio, &hm.adapter_index);
3621 hm.u.l.bit_index = bit_index;
3622 hm.u.l.bit_data = bit_data;
3623
3624 hpi_send_recv(&hm, &hr);
3625
3626 return hr.error;
3627}
3628
3629u16 hpi_gpio_write_status(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3630 u16 aw_all_bit_data[4]
3631 )
3632{
3633 struct hpi_message hm;
3634 struct hpi_response hr;
3635 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO,
3636 HPI_GPIO_WRITE_STATUS);
3637 u32TOINDEX(h_gpio, &hm.adapter_index);
3638
3639 hpi_send_recv(&hm, &hr);
3640
3641 if (aw_all_bit_data) {
3642 aw_all_bit_data[0] = hr.u.l.bit_data[0];
3643 aw_all_bit_data[1] = hr.u.l.bit_data[1];
3644 aw_all_bit_data[2] = hr.u.l.bit_data[2];
3645 aw_all_bit_data[3] = hr.u.l.bit_data[3];
3646 }
3647 return hr.error;
3648}
3649
3650u16 hpi_async_event_open(const struct hpi_hsubsys *ph_subsys,
3651 u16 adapter_index, u32 *ph_async)
3652{
3653 struct hpi_message hm;
3654 struct hpi_response hr;
3655 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3656 HPI_ASYNCEVENT_OPEN);
3657 hm.adapter_index = adapter_index;
3658
3659 hpi_send_recv(&hm, &hr);
3660
3661 if (hr.error == 0)
3662
3663 *ph_async =
3664 hpi_indexes_to_handle(HPI_OBJ_ASYNCEVENT,
3665 adapter_index, 0);
3666 else
3667 *ph_async = 0;
3668 return hr.error;
3669
3670}
3671
3672u16 hpi_async_event_close(const struct hpi_hsubsys *ph_subsys, u32 h_async)
3673{
3674 struct hpi_message hm;
3675 struct hpi_response hr;
3676 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3677 HPI_ASYNCEVENT_OPEN);
3678 u32TOINDEX(h_async, &hm.adapter_index);
3679
3680 hpi_send_recv(&hm, &hr);
3681
3682 return hr.error;
3683}
3684
3685u16 hpi_async_event_wait(const struct hpi_hsubsys *ph_subsys, u32 h_async,
3686 u16 maximum_events, struct hpi_async_event *p_events,
3687 u16 *pw_number_returned)
3688{
3689
3690 return 0;
3691}
3692
3693u16 hpi_async_event_get_count(const struct hpi_hsubsys *ph_subsys,
3694 u32 h_async, u16 *pw_count)
3695{
3696 struct hpi_message hm;
3697 struct hpi_response hr;
3698 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3699 HPI_ASYNCEVENT_GETCOUNT);
3700 u32TOINDEX(h_async, &hm.adapter_index);
3701
3702 hpi_send_recv(&hm, &hr);
3703
3704 if (hr.error == 0)
3705 if (pw_count)
3706 *pw_count = hr.u.as.u.count.count;
3707
3708 return hr.error;
3709}
3710
3711u16 hpi_async_event_get(const struct hpi_hsubsys *ph_subsys, u32 h_async,
3712 u16 maximum_events, struct hpi_async_event *p_events,
3713 u16 *pw_number_returned)
3714{
3715 struct hpi_message hm;
3716 struct hpi_response hr;
3717 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3718 HPI_ASYNCEVENT_GET);
3719 u32TOINDEX(h_async, &hm.adapter_index);
3720
3721 hpi_send_recv(&hm, &hr);
3722 if (!hr.error) {
3723 memcpy(p_events, &hr.u.as.u.event,
3724 sizeof(struct hpi_async_event));
3725 *pw_number_returned = 1;
3726 }
3727
3728 return hr.error;
3729}
3730
3731u16 hpi_nv_memory_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3732 u32 *ph_nv_memory, u16 *pw_size_in_bytes)
3733{
3734 struct hpi_message hm;
3735 struct hpi_response hr;
3736 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3737 HPI_NVMEMORY_OPEN);
3738 hm.adapter_index = adapter_index;
3739
3740 hpi_send_recv(&hm, &hr);
3741
3742 if (hr.error == 0) {
3743 *ph_nv_memory =
3744 hpi_indexes_to_handle(HPI_OBJ_NVMEMORY, adapter_index,
3745 0);
3746 if (pw_size_in_bytes)
3747 *pw_size_in_bytes = hr.u.n.size_in_bytes;
3748 } else
3749 *ph_nv_memory = 0;
3750 return hr.error;
3751}
3752
3753u16 hpi_nv_memory_read_byte(const struct hpi_hsubsys *ph_subsys,
3754 u32 h_nv_memory, u16 index, u16 *pw_data)
3755{
3756 struct hpi_message hm;
3757 struct hpi_response hr;
3758 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3759 HPI_NVMEMORY_READ_BYTE);
3760 u32TOINDEX(h_nv_memory, &hm.adapter_index);
3761 hm.u.n.address = index;
3762
3763 hpi_send_recv(&hm, &hr);
3764
3765 *pw_data = hr.u.n.data;
3766 return hr.error;
3767}
3768
3769u16 hpi_nv_memory_write_byte(const struct hpi_hsubsys *ph_subsys,
3770 u32 h_nv_memory, u16 index, u16 data)
3771{
3772 struct hpi_message hm;
3773 struct hpi_response hr;
3774 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3775 HPI_NVMEMORY_WRITE_BYTE);
3776 u32TOINDEX(h_nv_memory, &hm.adapter_index);
3777 hm.u.n.address = index;
3778 hm.u.n.data = data;
3779
3780 hpi_send_recv(&hm, &hr);
3781
3782 return hr.error;
3783}
3784
3785u16 hpi_profile_open_all(const struct hpi_hsubsys *ph_subsys,
3786 u16 adapter_index, u16 profile_index, u32 *ph_profile,
3787 u16 *pw_max_profiles)
3788{
3789 struct hpi_message hm;
3790 struct hpi_response hr;
3791 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3792 HPI_PROFILE_OPEN_ALL);
3793 hm.adapter_index = adapter_index;
3794 hm.obj_index = profile_index;
3795 hpi_send_recv(&hm, &hr);
3796
3797 *pw_max_profiles = hr.u.p.u.o.max_profiles;
3798 if (hr.error == 0)
3799 *ph_profile =
3800 hpi_indexes_to_handle(HPI_OBJ_PROFILE, adapter_index,
3801 profile_index);
3802 else
3803 *ph_profile = 0;
3804 return hr.error;
3805}
3806
3807u16 hpi_profile_get(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
3808 u16 bin_index, u16 *pw_seconds, u32 *pmicro_seconds, u32 *pcall_count,
3809 u32 *pmax_micro_seconds, u32 *pmin_micro_seconds)
3810{
3811 struct hpi_message hm;
3812 struct hpi_response hr;
3813 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE, HPI_PROFILE_GET);
3814 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3815 hm.u.p.bin_index = bin_index;
3816 hpi_send_recv(&hm, &hr);
3817 if (pw_seconds)
3818 *pw_seconds = hr.u.p.u.t.seconds;
3819 if (pmicro_seconds)
3820 *pmicro_seconds = hr.u.p.u.t.micro_seconds;
3821 if (pcall_count)
3822 *pcall_count = hr.u.p.u.t.call_count;
3823 if (pmax_micro_seconds)
3824 *pmax_micro_seconds = hr.u.p.u.t.max_micro_seconds;
3825 if (pmin_micro_seconds)
3826 *pmin_micro_seconds = hr.u.p.u.t.min_micro_seconds;
3827 return hr.error;
3828}
3829
3830u16 hpi_profile_get_utilization(const struct hpi_hsubsys *ph_subsys,
3831 u32 h_profile, u32 *putilization)
3832{
3833 struct hpi_message hm;
3834 struct hpi_response hr;
3835 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3836 HPI_PROFILE_GET_UTILIZATION);
3837 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3838 hpi_send_recv(&hm, &hr);
3839 if (hr.error) {
3840 if (putilization)
3841 *putilization = 0;
3842 } else {
3843 if (putilization)
3844 *putilization = hr.u.p.u.t.call_count;
3845 }
3846 return hr.error;
3847}
3848
3849u16 hpi_profile_get_name(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
3850 u16 bin_index, char *sz_name, u16 name_length)
3851{
3852 struct hpi_message hm;
3853 struct hpi_response hr;
3854 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3855 HPI_PROFILE_GET_NAME);
3856 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3857 hm.u.p.bin_index = bin_index;
3858 hpi_send_recv(&hm, &hr);
3859 if (hr.error) {
3860 if (sz_name)
3861 strcpy(sz_name, "??");
3862 } else {
3863 if (sz_name)
3864 memcpy(sz_name, (char *)hr.u.p.u.n.sz_name,
3865 name_length);
3866 }
3867 return hr.error;
3868}
3869
3870u16 hpi_profile_start_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile)
3871{
3872 struct hpi_message hm;
3873 struct hpi_response hr;
3874 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3875 HPI_PROFILE_START_ALL);
3876 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3877 hpi_send_recv(&hm, &hr);
3878
3879 return hr.error;
3880}
3881
3882u16 hpi_profile_stop_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile)
3883{
3884 struct hpi_message hm;
3885 struct hpi_response hr;
3886 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3887 HPI_PROFILE_STOP_ALL);
3888 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3889 hpi_send_recv(&hm, &hr);
3890
3891 return hr.error;
3892}
3893
3894u16 hpi_watchdog_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3895 u32 *ph_watchdog)
3896{
3897 struct hpi_message hm;
3898 struct hpi_response hr;
3899 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3900 HPI_WATCHDOG_OPEN);
3901 hm.adapter_index = adapter_index;
3902
3903 hpi_send_recv(&hm, &hr);
3904
3905 if (hr.error == 0)
3906 *ph_watchdog =
3907 hpi_indexes_to_handle(HPI_OBJ_WATCHDOG, adapter_index,
3908 0);
3909 else
3910 *ph_watchdog = 0;
3911 return hr.error;
3912}
3913
3914u16 hpi_watchdog_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog,
3915 u32 time_millisec)
3916{
3917 struct hpi_message hm;
3918 struct hpi_response hr;
3919 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3920 HPI_WATCHDOG_SET_TIME);
3921 u32TOINDEX(h_watchdog, &hm.adapter_index);
3922 hm.u.w.time_ms = time_millisec;
3923
3924 hpi_send_recv(&hm, &hr);
3925
3926 return hr.error;
3927}
3928
3929u16 hpi_watchdog_ping(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog)
3930{
3931 struct hpi_message hm;
3932 struct hpi_response hr;
3933 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3934 HPI_WATCHDOG_PING);
3935 u32TOINDEX(h_watchdog, &hm.adapter_index);
3936
3937 hpi_send_recv(&hm, &hr);
3938
3939 return hr.error;
3940}
diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c
index 8e1d099ed7e4..628376ce4a49 100644
--- a/sound/pci/asihpi/hpimsginit.c
+++ b/sound/pci/asihpi/hpimsginit.c
@@ -32,21 +32,6 @@ static u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT;
32static u16 gwSSX2_bypass; 32static u16 gwSSX2_bypass;
33 33
34/** \internal 34/** \internal
35 * Used by ASIO driver to disable SSX2 for a single process
36 * \param phSubSys Pointer to HPI subsystem handle.
37 * \param wBypass New bypass setting 0 = off, nonzero = on
38 * \return Previous bypass setting.
39 */
40u16 hpi_subsys_ssx2_bypass(const struct hpi_hsubsys *ph_subsys, u16 bypass)
41{
42 u16 old_value = gwSSX2_bypass;
43
44 gwSSX2_bypass = bypass;
45
46 return old_value;
47}
48
49/** \internal
50 * initialize the HPI message structure 35 * initialize the HPI message structure
51 */ 36 */
52static void hpi_init_message(struct hpi_message *phm, u16 object, 37static void hpi_init_message(struct hpi_message *phm, u16 object,
@@ -65,7 +50,8 @@ static void hpi_init_message(struct hpi_message *phm, u16 object,
65 phm->object = object; 50 phm->object = object;
66 phm->function = function; 51 phm->function = function;
67 phm->version = 0; 52 phm->version = 0;
68 /* Expect adapter index to be set by caller */ 53 phm->adapter_index = HPI_ADAPTER_INDEX_INVALID;
54 /* Expect actual adapter index to be set by caller */
69} 55}
70 56
71/** \internal 57/** \internal
diff --git a/sound/pci/asihpi/hpimsginit.h b/sound/pci/asihpi/hpimsginit.h
index 864ad020c9b3..bfd330d78b58 100644
--- a/sound/pci/asihpi/hpimsginit.h
+++ b/sound/pci/asihpi/hpimsginit.h
@@ -21,11 +21,15 @@
21 (C) Copyright AudioScience Inc. 2007 21 (C) Copyright AudioScience Inc. 2007
22*******************************************************************************/ 22*******************************************************************************/
23/* Initialise response headers, or msg/response pairs. 23/* Initialise response headers, or msg/response pairs.
24Note that it is valid to just init a response e.g. when a lower level is preparing 24Note that it is valid to just init a response e.g. when a lower level is
25a response to a message. 25preparing a response to a message.
26However, when sending a message, a matching response buffer always must be prepared 26However, when sending a message, a matching response buffer must always be
27prepared.
27*/ 28*/
28 29
30#ifndef _HPIMSGINIT_H_
31#define _HPIMSGINIT_H_
32
29void hpi_init_response(struct hpi_response *phr, u16 object, u16 function, 33void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
30 u16 error); 34 u16 error);
31 35
@@ -38,3 +42,5 @@ void hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
38void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size, 42void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
39 struct hpi_response_header *phr, u16 res_size, u16 object, 43 struct hpi_response_header *phr, u16 res_size, u16 object,
40 u16 function); 44 u16 function);
45
46#endif /* _HPIMSGINIT_H_ */
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c
index f01ab964f602..7352a5f7b4f7 100644
--- a/sound/pci/asihpi/hpimsgx.c
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -23,6 +23,7 @@ Extended Message Function With Response Cacheing
23#define SOURCEFILE_NAME "hpimsgx.c" 23#define SOURCEFILE_NAME "hpimsgx.c"
24#include "hpi_internal.h" 24#include "hpi_internal.h"
25#include "hpimsginit.h" 25#include "hpimsginit.h"
26#include "hpicmn.h"
26#include "hpimsgx.h" 27#include "hpimsgx.h"
27#include "hpidebug.h" 28#include "hpidebug.h"
28 29
@@ -42,22 +43,24 @@ static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci
42 43
43 for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) { 44 for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) {
44 if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID 45 if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID
45 && asihpi_pci_tbl[i].vendor != pci_info->vendor_id) 46 && asihpi_pci_tbl[i].vendor !=
47 pci_info->pci_dev->vendor)
46 continue; 48 continue;
47 if (asihpi_pci_tbl[i].device != PCI_ANY_ID 49 if (asihpi_pci_tbl[i].device != PCI_ANY_ID
48 && asihpi_pci_tbl[i].device != pci_info->device_id) 50 && asihpi_pci_tbl[i].device !=
51 pci_info->pci_dev->device)
49 continue; 52 continue;
50 if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID 53 if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID
51 && asihpi_pci_tbl[i].subvendor != 54 && asihpi_pci_tbl[i].subvendor !=
52 pci_info->subsys_vendor_id) 55 pci_info->pci_dev->subsystem_vendor)
53 continue; 56 continue;
54 if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID 57 if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID
55 && asihpi_pci_tbl[i].subdevice != 58 && asihpi_pci_tbl[i].subdevice !=
56 pci_info->subsys_device_id) 59 pci_info->pci_dev->subsystem_device)
57 continue; 60 continue;
58 61
59 HPI_DEBUG_LOG(DEBUG, " %x,%lu\n", i, 62 /* HPI_DEBUG_LOG(DEBUG, " %x,%lx\n", i,
60 asihpi_pci_tbl[i].driver_data); 63 asihpi_pci_tbl[i].driver_data); */
61 return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data; 64 return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data;
62 } 65 }
63 66
@@ -67,21 +70,12 @@ static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci
67static inline void hw_entry_point(struct hpi_message *phm, 70static inline void hw_entry_point(struct hpi_message *phm,
68 struct hpi_response *phr) 71 struct hpi_response *phr)
69{ 72{
70 73 if ((phm->adapter_index < HPI_MAX_ADAPTERS)
71 hpi_handler_func *ep; 74 && hpi_entry_points[phm->adapter_index])
72 75 hpi_entry_points[phm->adapter_index] (phm, phr);
73 if (phm->adapter_index < HPI_MAX_ADAPTERS) { 76 else
74 ep = (hpi_handler_func *) hpi_entry_points[phm-> 77 hpi_init_response(phr, phm->object, phm->function,
75 adapter_index]; 78 HPI_ERROR_PROCESSING_MESSAGE);
76 if (ep) {
77 HPI_DEBUG_MESSAGE(DEBUG, phm);
78 ep(phm, phr);
79 HPI_DEBUG_RESPONSE(phr);
80 return;
81 }
82 }
83 hpi_init_response(phr, phm->object, phm->function,
84 HPI_ERROR_PROCESSING_MESSAGE);
85} 79}
86 80
87static void adapter_open(struct hpi_message *phm, struct hpi_response *phr); 81static void adapter_open(struct hpi_message *phm, struct hpi_response *phr);
@@ -100,6 +94,7 @@ static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
100 void *h_owner); 94 void *h_owner);
101 95
102static void HPIMSGX__reset(u16 adapter_index); 96static void HPIMSGX__reset(u16 adapter_index);
97
103static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr); 98static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr);
104static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner); 99static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner);
105 100
@@ -153,8 +148,6 @@ static struct hpi_stream_response
153 148
154static struct hpi_mixer_response rESP_HPI_MIXER_OPEN[HPI_MAX_ADAPTERS]; 149static struct hpi_mixer_response rESP_HPI_MIXER_OPEN[HPI_MAX_ADAPTERS];
155 150
156static struct hpi_subsys_response gRESP_HPI_SUBSYS_FIND_ADAPTERS;
157
158static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS]; 151static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS];
159 152
160/* use these to keep track of opens from user mode apps/DLLs */ 153/* use these to keep track of opens from user mode apps/DLLs */
@@ -167,6 +160,11 @@ static struct asi_open_state
167static void subsys_message(struct hpi_message *phm, struct hpi_response *phr, 160static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
168 void *h_owner) 161 void *h_owner)
169{ 162{
163 if (phm->adapter_index != HPI_ADAPTER_INDEX_INVALID)
164 HPI_DEBUG_LOG(WARNING,
165 "suspicious adapter index %d in subsys message 0x%x.\n",
166 phm->adapter_index, phm->function);
167
170 switch (phm->function) { 168 switch (phm->function) {
171 case HPI_SUBSYS_GET_VERSION: 169 case HPI_SUBSYS_GET_VERSION:
172 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, 170 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
@@ -204,85 +202,19 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
204 HPI_SUBSYS_DRIVER_UNLOAD, 0); 202 HPI_SUBSYS_DRIVER_UNLOAD, 0);
205 return; 203 return;
206 204
207 case HPI_SUBSYS_GET_INFO:
208 HPI_COMMON(phm, phr);
209 break;
210
211 case HPI_SUBSYS_FIND_ADAPTERS:
212 memcpy(phr, &gRESP_HPI_SUBSYS_FIND_ADAPTERS,
213 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
214 break;
215 case HPI_SUBSYS_GET_NUM_ADAPTERS: 205 case HPI_SUBSYS_GET_NUM_ADAPTERS:
216 memcpy(phr, &gRESP_HPI_SUBSYS_FIND_ADAPTERS,
217 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
218 phr->function = HPI_SUBSYS_GET_NUM_ADAPTERS;
219 break;
220 case HPI_SUBSYS_GET_ADAPTER: 206 case HPI_SUBSYS_GET_ADAPTER:
221 { 207 HPI_COMMON(phm, phr);
222 int count = phm->adapter_index; 208 break;
223 int index = 0;
224 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
225 HPI_SUBSYS_GET_ADAPTER, 0);
226
227 /* This is complicated by the fact that we want to
228 * "skip" 0's in the adapter list.
229 * First, make sure we are pointing to a
230 * non-zero adapter type.
231 */
232 while (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
233 s.aw_adapter_list[index] == 0) {
234 index++;
235 if (index >= HPI_MAX_ADAPTERS)
236 break;
237 }
238 while (count) {
239 /* move on to the next adapter */
240 index++;
241 if (index >= HPI_MAX_ADAPTERS)
242 break;
243 while (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
244 s.aw_adapter_list[index] == 0) {
245 index++;
246 if (index >= HPI_MAX_ADAPTERS)
247 break;
248 }
249 count--;
250 }
251 209
252 if (index < HPI_MAX_ADAPTERS) {
253 phr->u.s.adapter_index = (u16)index;
254 phr->u.s.aw_adapter_list[0] =
255 gRESP_HPI_SUBSYS_FIND_ADAPTERS.
256 s.aw_adapter_list[index];
257 } else {
258 phr->u.s.adapter_index = 0;
259 phr->u.s.aw_adapter_list[0] = 0;
260 phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
261 }
262 break;
263 }
264 case HPI_SUBSYS_CREATE_ADAPTER: 210 case HPI_SUBSYS_CREATE_ADAPTER:
265 HPIMSGX__init(phm, phr); 211 HPIMSGX__init(phm, phr);
266 break; 212 break;
267 case HPI_SUBSYS_DELETE_ADAPTER: 213
268 HPIMSGX__cleanup(phm->adapter_index, h_owner);
269 {
270 struct hpi_message hm;
271 struct hpi_response hr;
272 /* call to HPI_ADAPTER_CLOSE */
273 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
274 HPI_ADAPTER_CLOSE);
275 hm.adapter_index = phm->adapter_index;
276 hw_entry_point(&hm, &hr);
277 }
278 hw_entry_point(phm, phr);
279 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.
280 aw_adapter_list[phm->adapter_index]
281 = 0;
282 hpi_entry_points[phm->adapter_index] = NULL;
283 break;
284 default: 214 default:
285 hw_entry_point(phm, phr); 215 /* Must explicitly handle every subsys message in this switch */
216 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function,
217 HPI_ERROR_INVALID_FUNC);
286 break; 218 break;
287 } 219 }
288} 220}
@@ -297,6 +229,19 @@ static void adapter_message(struct hpi_message *phm, struct hpi_response *phr,
297 case HPI_ADAPTER_CLOSE: 229 case HPI_ADAPTER_CLOSE:
298 adapter_close(phm, phr); 230 adapter_close(phm, phr);
299 break; 231 break;
232 case HPI_ADAPTER_DELETE:
233 HPIMSGX__cleanup(phm->adapter_index, h_owner);
234 {
235 struct hpi_message hm;
236 struct hpi_response hr;
237 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
238 HPI_ADAPTER_CLOSE);
239 hm.adapter_index = phm->adapter_index;
240 hw_entry_point(&hm, &hr);
241 }
242 hw_entry_point(phm, phr);
243 break;
244
300 default: 245 default:
301 hw_entry_point(phm, phr); 246 hw_entry_point(phm, phr);
302 break; 247 break;
@@ -409,33 +354,7 @@ void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
409 break; 354 break;
410 } 355 }
411 HPI_DEBUG_RESPONSE(phr); 356 HPI_DEBUG_RESPONSE(phr);
412#if 1 357
413 if (phr->error >= HPI_ERROR_BACKEND_BASE) {
414 void *ep = NULL;
415 char *ep_name;
416
417 HPI_DEBUG_MESSAGE(ERROR, phm);
418
419 if (phm->adapter_index < HPI_MAX_ADAPTERS)
420 ep = hpi_entry_points[phm->adapter_index];
421
422 /* Don't need this? Have adapter index in debug info
423 Know at driver load time index->backend mapping */
424 if (ep == HPI_6000)
425 ep_name = "HPI_6000";
426 else if (ep == HPI_6205)
427 ep_name = "HPI_6205";
428 else
429 ep_name = "unknown";
430
431 HPI_DEBUG_LOG(ERROR, "HPI %s response - error# %d\n", ep_name,
432 phr->error);
433
434 if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE)
435 hpi_debug_data((u16 *)phm,
436 sizeof(*phm) / sizeof(u16));
437 }
438#endif
439} 358}
440 359
441static void adapter_open(struct hpi_message *phm, struct hpi_response *phr) 360static void adapter_open(struct hpi_message *phm, struct hpi_response *phr)
@@ -484,7 +403,7 @@ static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
484 else { 403 else {
485 instream_user_open[phm->adapter_index][phm-> 404 instream_user_open[phm->adapter_index][phm->
486 obj_index].open_flag = 1; 405 obj_index].open_flag = 1;
487 hpios_msgxlock_un_lock(&msgx_lock); 406 hpios_msgxlock_unlock(&msgx_lock);
488 407
489 /* issue a reset */ 408 /* issue a reset */
490 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 409 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
@@ -509,7 +428,7 @@ static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
509 sizeof(rESP_HPI_ISTREAM_OPEN[0][0])); 428 sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
510 } 429 }
511 } 430 }
512 hpios_msgxlock_un_lock(&msgx_lock); 431 hpios_msgxlock_unlock(&msgx_lock);
513} 432}
514 433
515static void instream_close(struct hpi_message *phm, struct hpi_response *phr, 434static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
@@ -530,7 +449,7 @@ static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
530 phm->wAdapterIndex, phm->wObjIndex, hOwner); */ 449 phm->wAdapterIndex, phm->wObjIndex, hOwner); */
531 instream_user_open[phm->adapter_index][phm-> 450 instream_user_open[phm->adapter_index][phm->
532 obj_index].h_owner = NULL; 451 obj_index].h_owner = NULL;
533 hpios_msgxlock_un_lock(&msgx_lock); 452 hpios_msgxlock_unlock(&msgx_lock);
534 /* issue a reset */ 453 /* issue a reset */
535 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 454 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
536 HPI_ISTREAM_RESET); 455 HPI_ISTREAM_RESET);
@@ -556,7 +475,7 @@ static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
556 obj_index].h_owner); 475 obj_index].h_owner);
557 phr->error = HPI_ERROR_OBJ_NOT_OPEN; 476 phr->error = HPI_ERROR_OBJ_NOT_OPEN;
558 } 477 }
559 hpios_msgxlock_un_lock(&msgx_lock); 478 hpios_msgxlock_unlock(&msgx_lock);
560} 479}
561 480
562static void outstream_open(struct hpi_message *phm, struct hpi_response *phr, 481static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
@@ -581,7 +500,7 @@ static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
581 else { 500 else {
582 outstream_user_open[phm->adapter_index][phm-> 501 outstream_user_open[phm->adapter_index][phm->
583 obj_index].open_flag = 1; 502 obj_index].open_flag = 1;
584 hpios_msgxlock_un_lock(&msgx_lock); 503 hpios_msgxlock_unlock(&msgx_lock);
585 504
586 /* issue a reset */ 505 /* issue a reset */
587 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 506 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
@@ -606,7 +525,7 @@ static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
606 sizeof(rESP_HPI_OSTREAM_OPEN[0][0])); 525 sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
607 } 526 }
608 } 527 }
609 hpios_msgxlock_un_lock(&msgx_lock); 528 hpios_msgxlock_unlock(&msgx_lock);
610} 529}
611 530
612static void outstream_close(struct hpi_message *phm, struct hpi_response *phr, 531static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
@@ -628,7 +547,7 @@ static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
628 phm->wAdapterIndex, phm->wObjIndex, hOwner); */ 547 phm->wAdapterIndex, phm->wObjIndex, hOwner); */
629 outstream_user_open[phm->adapter_index][phm-> 548 outstream_user_open[phm->adapter_index][phm->
630 obj_index].h_owner = NULL; 549 obj_index].h_owner = NULL;
631 hpios_msgxlock_un_lock(&msgx_lock); 550 hpios_msgxlock_unlock(&msgx_lock);
632 /* issue a reset */ 551 /* issue a reset */
633 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 552 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
634 HPI_OSTREAM_RESET); 553 HPI_OSTREAM_RESET);
@@ -654,7 +573,7 @@ static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
654 obj_index].h_owner); 573 obj_index].h_owner);
655 phr->error = HPI_ERROR_OBJ_NOT_OPEN; 574 phr->error = HPI_ERROR_OBJ_NOT_OPEN;
656 } 575 }
657 hpios_msgxlock_un_lock(&msgx_lock); 576 hpios_msgxlock_unlock(&msgx_lock);
658} 577}
659 578
660static u16 adapter_prepare(u16 adapter) 579static u16 adapter_prepare(u16 adapter)
@@ -683,16 +602,9 @@ static u16 adapter_prepare(u16 adapter)
683 if (hr.error) 602 if (hr.error)
684 return hr.error; 603 return hr.error;
685 604
686 aDAPTER_INFO[adapter].num_outstreams = hr.u.a.num_outstreams; 605 aDAPTER_INFO[adapter].num_outstreams = hr.u.ax.info.num_outstreams;
687 aDAPTER_INFO[adapter].num_instreams = hr.u.a.num_instreams; 606 aDAPTER_INFO[adapter].num_instreams = hr.u.ax.info.num_instreams;
688 aDAPTER_INFO[adapter].type = hr.u.a.adapter_type; 607 aDAPTER_INFO[adapter].type = hr.u.ax.info.adapter_type;
689
690 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list[adapter] =
691 hr.u.a.adapter_type;
692 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters++;
693 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters > HPI_MAX_ADAPTERS)
694 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters =
695 HPI_MAX_ADAPTERS;
696 608
697 /* call to HPI_OSTREAM_OPEN */ 609 /* call to HPI_OSTREAM_OPEN */
698 for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) { 610 for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) {
@@ -727,7 +639,7 @@ static u16 adapter_prepare(u16 adapter)
727 memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr, 639 memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
728 sizeof(rESP_HPI_MIXER_OPEN[0])); 640 sizeof(rESP_HPI_MIXER_OPEN[0]));
729 641
730 return gRESP_HPI_SUBSYS_FIND_ADAPTERS.h.error; 642 return 0;
731} 643}
732 644
733static void HPIMSGX__reset(u16 adapter_index) 645static void HPIMSGX__reset(u16 adapter_index)
@@ -737,12 +649,6 @@ static void HPIMSGX__reset(u16 adapter_index)
737 struct hpi_response hr; 649 struct hpi_response hr;
738 650
739 if (adapter_index == HPIMSGX_ALLADAPTERS) { 651 if (adapter_index == HPIMSGX_ALLADAPTERS) {
740 /* reset all responses to contain errors */
741 hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM,
742 HPI_SUBSYS_FIND_ADAPTERS, 0);
743 memcpy(&gRESP_HPI_SUBSYS_FIND_ADAPTERS, &hr,
744 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
745
746 for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) { 652 for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) {
747 653
748 hpi_init_response(&hr, HPI_OBJ_ADAPTER, 654 hpi_init_response(&hr, HPI_OBJ_ADAPTER,
@@ -783,12 +689,6 @@ static void HPIMSGX__reset(u16 adapter_index)
783 rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error = 689 rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error =
784 HPI_ERROR_INVALID_OBJ; 690 HPI_ERROR_INVALID_OBJ;
785 } 691 }
786 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
787 s.aw_adapter_list[adapter_index]) {
788 gRESP_HPI_SUBSYS_FIND_ADAPTERS.
789 s.aw_adapter_list[adapter_index] = 0;
790 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters--;
791 }
792 } 692 }
793} 693}
794 694
@@ -802,15 +702,9 @@ static u16 HPIMSGX__init(struct hpi_message *phm,
802 hpi_handler_func *entry_point_func; 702 hpi_handler_func *entry_point_func;
803 struct hpi_response hr; 703 struct hpi_response hr;
804 704
805 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters >= HPI_MAX_ADAPTERS)
806 return HPI_ERROR_BAD_ADAPTER_NUMBER;
807
808 /* Init response here so we can pass in previous adapter list */ 705 /* Init response here so we can pass in previous adapter list */
809 hpi_init_response(&hr, phm->object, phm->function, 706 hpi_init_response(&hr, phm->object, phm->function,
810 HPI_ERROR_INVALID_OBJ); 707 HPI_ERROR_INVALID_OBJ);
811 memcpy(hr.u.s.aw_adapter_list,
812 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list,
813 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list));
814 708
815 entry_point_func = 709 entry_point_func =
816 hpi_lookup_entry_point_function(phm->u.s.resource.r.pci); 710 hpi_lookup_entry_point_function(phm->u.s.resource.r.pci);
@@ -823,7 +717,7 @@ static u16 HPIMSGX__init(struct hpi_message *phm,
823 return phr->error; 717 return phr->error;
824 } 718 }
825 if (hr.error == 0) { 719 if (hr.error == 0) {
826 /* the adapter was created succesfully 720 /* the adapter was created successfully
827 save the mapping for future use */ 721 save the mapping for future use */
828 hpi_entry_points[hr.u.s.adapter_index] = entry_point_func; 722 hpi_entry_points[hr.u.s.adapter_index] = entry_point_func;
829 /* prepare adapter (pre-open streams etc.) */ 723 /* prepare adapter (pre-open streams etc.) */
@@ -860,7 +754,7 @@ static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner)
860 struct hpi_response hr; 754 struct hpi_response hr;
861 755
862 HPI_DEBUG_LOG(DEBUG, 756 HPI_DEBUG_LOG(DEBUG,
863 "close adapter %d ostream %d\n", 757 "Close adapter %d ostream %d\n",
864 adapter, i); 758 adapter, i);
865 759
866 hpi_init_message_response(&hm, &hr, 760 hpi_init_message_response(&hm, &hr,
@@ -884,7 +778,7 @@ static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner)
884 struct hpi_response hr; 778 struct hpi_response hr;
885 779
886 HPI_DEBUG_LOG(DEBUG, 780 HPI_DEBUG_LOG(DEBUG,
887 "close adapter %d istream %d\n", 781 "Close adapter %d istream %d\n",
888 adapter, i); 782 adapter, i);
889 783
890 hpi_init_message_response(&hm, &hr, 784 hpi_init_message_response(&hm, &hr,
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index 62895a719fcb..d8e7047512f8 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -25,11 +25,13 @@ Common Linux HPI ioctl and module probe/remove functions
25#include "hpidebug.h" 25#include "hpidebug.h"
26#include "hpimsgx.h" 26#include "hpimsgx.h"
27#include "hpioctl.h" 27#include "hpioctl.h"
28#include "hpicmn.h"
28 29
29#include <linux/fs.h> 30#include <linux/fs.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31#include <linux/moduleparam.h> 32#include <linux/moduleparam.h>
32#include <asm/uaccess.h> 33#include <asm/uaccess.h>
34#include <linux/pci.h>
33#include <linux/stringify.h> 35#include <linux/stringify.h>
34 36
35#ifdef MODULE_FIRMWARE 37#ifdef MODULE_FIRMWARE
@@ -45,7 +47,7 @@ MODULE_FIRMWARE("asihpi/dsp8900.bin");
45static int prealloc_stream_buf; 47static int prealloc_stream_buf;
46module_param(prealloc_stream_buf, int, S_IRUGO); 48module_param(prealloc_stream_buf, int, S_IRUGO);
47MODULE_PARM_DESC(prealloc_stream_buf, 49MODULE_PARM_DESC(prealloc_stream_buf,
48 "preallocate size for per-adapter stream buffer"); 50 "Preallocate size for per-adapter stream buffer");
49 51
50/* Allow the debug level to be changed after module load. 52/* Allow the debug level to be changed after module load.
51 E.g. echo 2 > /sys/module/asihpi/parameters/hpiDebugLevel 53 E.g. echo 2 > /sys/module/asihpi/parameters/hpiDebugLevel
@@ -121,8 +123,8 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
121 phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg; 123 phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg;
122 124
123 /* Read the message and response pointers from user space. */ 125 /* Read the message and response pointers from user space. */
124 if (get_user(puhm, &phpi_ioctl_data->phm) || 126 if (get_user(puhm, &phpi_ioctl_data->phm)
125 get_user(puhr, &phpi_ioctl_data->phr)) { 127 || get_user(puhr, &phpi_ioctl_data->phr)) {
126 err = -EFAULT; 128 err = -EFAULT;
127 goto out; 129 goto out;
128 } 130 }
@@ -135,7 +137,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
135 if (hm->h.size > sizeof(*hm)) 137 if (hm->h.size > sizeof(*hm))
136 hm->h.size = sizeof(*hm); 138 hm->h.size = sizeof(*hm);
137 139
138 /*printk(KERN_INFO "message size %d\n", hm->h.wSize); */ 140 /* printk(KERN_INFO "message size %d\n", hm->h.wSize); */
139 141
140 uncopied_bytes = copy_from_user(hm, puhm, hm->h.size); 142 uncopied_bytes = copy_from_user(hm, puhm, hm->h.size);
141 if (uncopied_bytes) { 143 if (uncopied_bytes) {
@@ -155,26 +157,29 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
155 goto out; 157 goto out;
156 } 158 }
157 159
158 pa = &adapters[hm->h.adapter_index]; 160 if (hm->h.adapter_index >= HPI_MAX_ADAPTERS) {
159 hr->h.size = 0; 161 err = -EINVAL;
160 if (hm->h.object == HPI_OBJ_SUBSYSTEM) { 162 goto out;
161 switch (hm->h.function) { 163 }
162 case HPI_SUBSYS_CREATE_ADAPTER:
163 case HPI_SUBSYS_DELETE_ADAPTER:
164 /* Application must not use these functions! */
165 hr->h.size = sizeof(hr->h);
166 hr->h.error = HPI_ERROR_INVALID_OPERATION;
167 hr->h.function = hm->h.function;
168 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
169 if (uncopied_bytes)
170 err = -EFAULT;
171 else
172 err = 0;
173 goto out;
174 164
175 default: 165 switch (hm->h.function) {
176 hpi_send_recv_f(&hm->m0, &hr->r0, file); 166 case HPI_SUBSYS_CREATE_ADAPTER:
177 } 167 case HPI_ADAPTER_DELETE:
168 /* Application must not use these functions! */
169 hr->h.size = sizeof(hr->h);
170 hr->h.error = HPI_ERROR_INVALID_OPERATION;
171 hr->h.function = hm->h.function;
172 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
173 if (uncopied_bytes)
174 err = -EFAULT;
175 else
176 err = 0;
177 goto out;
178 }
179
180 hr->h.size = res_max_size;
181 if (hm->h.object == HPI_OBJ_SUBSYSTEM) {
182 hpi_send_recv_f(&hm->m0, &hr->r0, file);
178 } else { 183 } else {
179 u16 __user *ptr = NULL; 184 u16 __user *ptr = NULL;
180 u32 size = 0; 185 u32 size = 0;
@@ -182,8 +187,9 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
182 /* -1=no data 0=read from user mem, 1=write to user mem */ 187 /* -1=no data 0=read from user mem, 1=write to user mem */
183 int wrflag = -1; 188 int wrflag = -1;
184 u32 adapter = hm->h.adapter_index; 189 u32 adapter = hm->h.adapter_index;
190 pa = &adapters[adapter];
185 191
186 if ((hm->h.adapter_index > HPI_MAX_ADAPTERS) || (!pa->type)) { 192 if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) {
187 hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER, 193 hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER,
188 HPI_ADAPTER_OPEN, 194 HPI_ADAPTER_OPEN,
189 HPI_ERROR_BAD_ADAPTER_NUMBER); 195 HPI_ERROR_BAD_ADAPTER_NUMBER);
@@ -216,7 +222,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
216 */ 222 */
217 if (pa->buffer_size < size) { 223 if (pa->buffer_size < size) {
218 HPI_DEBUG_LOG(DEBUG, 224 HPI_DEBUG_LOG(DEBUG,
219 "realloc adapter %d stream " 225 "Realloc adapter %d stream "
220 "buffer from %zd to %d\n", 226 "buffer from %zd to %d\n",
221 hm->h.adapter_index, 227 hm->h.adapter_index,
222 pa->buffer_size, size); 228 pa->buffer_size, size);
@@ -259,7 +265,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
259 copy_from_user(pa->p_buffer, ptr, size); 265 copy_from_user(pa->p_buffer, ptr, size);
260 if (uncopied_bytes) 266 if (uncopied_bytes)
261 HPI_DEBUG_LOG(WARNING, 267 HPI_DEBUG_LOG(WARNING,
262 "missed %d of %d " 268 "Missed %d of %d "
263 "bytes from user\n", uncopied_bytes, 269 "bytes from user\n", uncopied_bytes,
264 size); 270 size);
265 } 271 }
@@ -271,7 +277,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
271 copy_to_user(ptr, pa->p_buffer, size); 277 copy_to_user(ptr, pa->p_buffer, size);
272 if (uncopied_bytes) 278 if (uncopied_bytes)
273 HPI_DEBUG_LOG(WARNING, 279 HPI_DEBUG_LOG(WARNING,
274 "missed %d of %d " "bytes to user\n", 280 "Missed %d of %d " "bytes to user\n",
275 uncopied_bytes, size); 281 uncopied_bytes, size);
276 } 282 }
277 283
@@ -290,9 +296,9 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
290 if (hr->h.size > res_max_size) { 296 if (hr->h.size > res_max_size) {
291 HPI_DEBUG_LOG(ERROR, "response too big %d %d\n", hr->h.size, 297 HPI_DEBUG_LOG(ERROR, "response too big %d %d\n", hr->h.size,
292 res_max_size); 298 res_max_size);
293 /*HPI_DEBUG_MESSAGE(ERROR, hm); */ 299 hr->h.error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
294 err = -EFAULT; 300 hr->h.specific_error = hr->h.size;
295 goto out; 301 hr->h.size = sizeof(hr->h);
296 } 302 }
297 303
298 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size); 304 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
@@ -311,7 +317,7 @@ out:
311int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, 317int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
312 const struct pci_device_id *pci_id) 318 const struct pci_device_id *pci_id)
313{ 319{
314 int err, idx, nm; 320 int idx, nm;
315 unsigned int memlen; 321 unsigned int memlen;
316 struct hpi_message hm; 322 struct hpi_message hm;
317 struct hpi_response hr; 323 struct hpi_response hr;
@@ -320,28 +326,33 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
320 326
321 memset(&adapter, 0, sizeof(adapter)); 327 memset(&adapter, 0, sizeof(adapter));
322 328
323 printk(KERN_DEBUG "probe PCI device (%04x:%04x,%04x:%04x,%04x)\n", 329 dev_printk(KERN_DEBUG, &pci_dev->dev,
324 pci_dev->vendor, pci_dev->device, pci_dev->subsystem_vendor, 330 "probe %04x:%04x,%04x:%04x,%04x\n", pci_dev->vendor,
331 pci_dev->device, pci_dev->subsystem_vendor,
325 pci_dev->subsystem_device, pci_dev->devfn); 332 pci_dev->subsystem_device, pci_dev->devfn);
326 333
334 if (pci_enable_device(pci_dev) < 0) {
335 dev_printk(KERN_ERR, &pci_dev->dev,
336 "pci_enable_device failed, disabling device\n");
337 return -EIO;
338 }
339
340 pci_set_master(pci_dev); /* also sets latency timer if < 16 */
341
327 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, 342 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
328 HPI_SUBSYS_CREATE_ADAPTER); 343 HPI_SUBSYS_CREATE_ADAPTER);
329 hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CREATE_ADAPTER, 344 hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CREATE_ADAPTER,
330 HPI_ERROR_PROCESSING_MESSAGE); 345 HPI_ERROR_PROCESSING_MESSAGE);
331 346
332 hm.adapter_index = -1; /* an invalid index */ 347 hm.adapter_index = HPI_ADAPTER_INDEX_INVALID;
333 348
334 /* fill in HPI_PCI information from kernel provided information */
335 adapter.pci = pci_dev; 349 adapter.pci = pci_dev;
336 350
337 nm = HPI_MAX_ADAPTER_MEM_SPACES; 351 nm = HPI_MAX_ADAPTER_MEM_SPACES;
338 352
339 for (idx = 0; idx < nm; idx++) { 353 for (idx = 0; idx < nm; idx++) {
340 HPI_DEBUG_LOG(INFO, "resource %d %s %08llx-%08llx %04llx\n", 354 HPI_DEBUG_LOG(INFO, "resource %d %pR\n", idx,
341 idx, pci_dev->resource[idx].name, 355 &pci_dev->resource[idx]);
342 (unsigned long long)pci_resource_start(pci_dev, idx),
343 (unsigned long long)pci_resource_end(pci_dev, idx),
344 (unsigned long long)pci_resource_flags(pci_dev, idx));
345 356
346 if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) { 357 if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) {
347 memlen = pci_resource_len(pci_dev, idx); 358 memlen = pci_resource_len(pci_dev, idx);
@@ -359,19 +370,7 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
359 pci.ap_mem_base[idx] = adapter.ap_remapped_mem_base[idx]; 370 pci.ap_mem_base[idx] = adapter.ap_remapped_mem_base[idx];
360 } 371 }
361 372
362 /* could replace Pci with direct pointer to pci_dev for linux 373 pci.pci_dev = pci_dev;
363 Instead wrap accessor functions for IDs etc.
364 Would it work for windows?
365 */
366 pci.bus_number = pci_dev->bus->number;
367 pci.vendor_id = (u16)pci_dev->vendor;
368 pci.device_id = (u16)pci_dev->device;
369 pci.subsys_vendor_id = (u16)(pci_dev->subsystem_vendor & 0xffff);
370 pci.subsys_device_id = (u16)(pci_dev->subsystem_device & 0xffff);
371 pci.device_number = pci_dev->devfn;
372 pci.interrupt = pci_dev->irq;
373 pci.p_os_data = pci_dev;
374
375 hm.u.s.resource.bus_type = HPI_BUS_PCI; 374 hm.u.s.resource.bus_type = HPI_BUS_PCI;
376 hm.u.s.resource.r.pci = &pci; 375 hm.u.s.resource.r.pci = &pci;
377 376
@@ -392,23 +391,27 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
392 } 391 }
393 392
394 adapter.index = hr.u.s.adapter_index; 393 adapter.index = hr.u.s.adapter_index;
395 adapter.type = hr.u.s.aw_adapter_list[adapter.index]; 394 adapter.type = hr.u.s.adapter_type;
395
396 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
397 HPI_ADAPTER_OPEN);
396 hm.adapter_index = adapter.index; 398 hm.adapter_index = adapter.index;
399 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
397 400
398 err = hpi_adapter_open(NULL, adapter.index); 401 if (hr.error)
399 if (err)
400 goto err; 402 goto err;
401 403
402 adapter.snd_card_asihpi = NULL; 404 adapter.snd_card_asihpi = NULL;
403 /* WARNING can't init mutex in 'adapter' 405 /* WARNING can't init mutex in 'adapter'
404 * and then copy it to adapters[] ?!?! 406 * and then copy it to adapters[] ?!?!
405 */ 407 */
406 adapters[hr.u.s.adapter_index] = adapter; 408 adapters[adapter.index] = adapter;
407 mutex_init(&adapters[adapter.index].mutex); 409 mutex_init(&adapters[adapter.index].mutex);
408 pci_set_drvdata(pci_dev, &adapters[adapter.index]); 410 pci_set_drvdata(pci_dev, &adapters[adapter.index]);
409 411
410 printk(KERN_INFO "probe found adapter ASI%04X HPI index #%d.\n", 412 dev_printk(KERN_INFO, &pci_dev->dev,
411 adapter.type, adapter.index); 413 "probe succeeded for ASI%04X HPI index %d\n", adapter.type,
414 adapter.index);
412 415
413 return 0; 416 return 0;
414 417
@@ -435,10 +438,10 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
435 struct hpi_message hm; 438 struct hpi_message hm;
436 struct hpi_response hr; 439 struct hpi_response hr;
437 struct hpi_adapter *pa; 440 struct hpi_adapter *pa;
438 pa = (struct hpi_adapter *)pci_get_drvdata(pci_dev); 441 pa = pci_get_drvdata(pci_dev);
439 442
440 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, 443 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
441 HPI_SUBSYS_DELETE_ADAPTER); 444 HPI_ADAPTER_DELETE);
442 hm.adapter_index = pa->index; 445 hm.adapter_index = pa->index;
443 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); 446 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
444 447
@@ -450,20 +453,18 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
450 } 453 }
451 } 454 }
452 455
453 if (pa->p_buffer) { 456 if (pa->p_buffer)
454 pa->buffer_size = 0;
455 vfree(pa->p_buffer); 457 vfree(pa->p_buffer);
456 }
457 458
458 pci_set_drvdata(pci_dev, NULL); 459 pci_set_drvdata(pci_dev, NULL);
459 /* 460 if (1)
460 printk(KERN_INFO "PCI device (%04x:%04x,%04x:%04x,%04x)," 461 dev_printk(KERN_INFO, &pci_dev->dev,
461 " HPI index # %d, removed.\n", 462 "remove %04x:%04x,%04x:%04x,%04x," " HPI index %d.\n",
462 pci_dev->vendor, pci_dev->device, 463 pci_dev->vendor, pci_dev->device,
463 pci_dev->subsystem_vendor, 464 pci_dev->subsystem_vendor, pci_dev->subsystem_device,
464 pci_dev->subsystem_device, pci_dev->devfn, 465 pci_dev->devfn, pa->index);
465 pa->index); 466
466 */ 467 memset(pa, 0, sizeof(*pa));
467} 468}
468 469
469void __init asihpi_init(void) 470void __init asihpi_init(void)
diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h
index 370f39b43f85..03273e729f99 100644
--- a/sound/pci/asihpi/hpios.h
+++ b/sound/pci/asihpi/hpios.h
@@ -27,9 +27,7 @@ HPI Operating System Specific macros for Linux Kernel driver
27#define HPI_OS_LINUX_KERNEL 27#define HPI_OS_LINUX_KERNEL
28 28
29#define HPI_OS_DEFINED 29#define HPI_OS_DEFINED
30#define HPI_KERNEL_MODE 30#define HPI_BUILD_KERNEL_MODE
31
32#define HPI_REASSIGN_DUPLICATE_ADAPTER_IDX
33 31
34#include <linux/io.h> 32#include <linux/io.h>
35#include <asm/system.h> 33#include <asm/system.h>
@@ -135,20 +133,20 @@ static inline void cond_unlock(struct hpios_spinlock *l)
135 133
136#define hpios_msgxlock_init(obj) spin_lock_init(&(obj)->lock) 134#define hpios_msgxlock_init(obj) spin_lock_init(&(obj)->lock)
137#define hpios_msgxlock_lock(obj) cond_lock(obj) 135#define hpios_msgxlock_lock(obj) cond_lock(obj)
138#define hpios_msgxlock_un_lock(obj) cond_unlock(obj) 136#define hpios_msgxlock_unlock(obj) cond_unlock(obj)
139 137
140#define hpios_dsplock_init(obj) spin_lock_init(&(obj)->dsp_lock.lock) 138#define hpios_dsplock_init(obj) spin_lock_init(&(obj)->dsp_lock.lock)
141#define hpios_dsplock_lock(obj) cond_lock(&(obj)->dsp_lock) 139#define hpios_dsplock_lock(obj) cond_lock(&(obj)->dsp_lock)
142#define hpios_dsplock_unlock(obj) cond_unlock(&(obj)->dsp_lock) 140#define hpios_dsplock_unlock(obj) cond_unlock(&(obj)->dsp_lock)
143 141
144#ifdef CONFIG_SND_DEBUG 142#ifdef CONFIG_SND_DEBUG
145#define HPI_DEBUG 143#define HPI_BUILD_DEBUG
146#endif 144#endif
147 145
148#define HPI_ALIST_LOCKING 146#define HPI_ALIST_LOCKING
149#define hpios_alistlock_init(obj) spin_lock_init(&((obj)->list_lock.lock)) 147#define hpios_alistlock_init(obj) spin_lock_init(&((obj)->list_lock.lock))
150#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock)) 148#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
151#define hpios_alistlock_un_lock(obj) spin_unlock(&((obj)->list_lock.lock)) 149#define hpios_alistlock_unlock(obj) spin_unlock(&((obj)->list_lock.lock))
152 150
153struct hpi_adapter { 151struct hpi_adapter {
154 /* mutex prevents contention for one card 152 /* mutex prevents contention for one card
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 49d572a7b235..3119cd97a217 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -522,7 +522,7 @@ static int snd_atiixp_aclink_reset(struct atiixp *chip)
522 atiixp_read(chip, CMD); 522 atiixp_read(chip, CMD);
523 mdelay(1); 523 mdelay(1);
524 atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET); 524 atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET);
525 if (--timeout) { 525 if (!--timeout) {
526 snd_printk(KERN_ERR "atiixp: codec reset timeout\n"); 526 snd_printk(KERN_ERR "atiixp: codec reset timeout\n");
527 break; 527 break;
528 } 528 }
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 91d7036b6411..2f74c2fdf1ea 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -498,7 +498,7 @@ static int snd_atiixp_aclink_reset(struct atiixp_modem *chip)
498 atiixp_read(chip, CMD); 498 atiixp_read(chip, CMD);
499 msleep(1); 499 msleep(1);
500 atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET); 500 atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET);
501 if (--timeout) { 501 if (!--timeout) {
502 snd_printk(KERN_ERR "atiixp-modem: codec reset timeout\n"); 502 snd_printk(KERN_ERR "atiixp-modem: codec reset timeout\n");
503 break; 503 break;
504 } 504 }
diff --git a/sound/pci/au88x0/au8810.h b/sound/pci/au88x0/au8810.h
index 5d69c31fe3f4..79fbee3845eb 100644
--- a/sound/pci/au88x0/au8810.h
+++ b/sound/pci/au88x0/au8810.h
@@ -4,7 +4,7 @@
4 4
5#define CHIP_AU8810 5#define CHIP_AU8810
6 6
7#define CARD_NAME "Aureal Advantage 3D Sound Processor" 7#define CARD_NAME "Aureal Advantage"
8#define CARD_NAME_SHORT "au8810" 8#define CARD_NAME_SHORT "au8810"
9 9
10#define NR_ADB 0x10 10#define NR_ADB 0x10
diff --git a/sound/pci/au88x0/au8820.h b/sound/pci/au88x0/au8820.h
index abbe85e4f7a9..cafdb9668a34 100644
--- a/sound/pci/au88x0/au8820.h
+++ b/sound/pci/au88x0/au8820.h
@@ -11,7 +11,7 @@
11 11
12#define CHIP_AU8820 12#define CHIP_AU8820
13 13
14#define CARD_NAME "Aureal Vortex 3D Sound Processor" 14#define CARD_NAME "Aureal Vortex"
15#define CARD_NAME_SHORT "au8820" 15#define CARD_NAME_SHORT "au8820"
16 16
17/* Number of ADB and WT channels */ 17/* Number of ADB and WT channels */
diff --git a/sound/pci/au88x0/au8830.h b/sound/pci/au88x0/au8830.h
index 04ece1b1c218..999b29ab34ad 100644
--- a/sound/pci/au88x0/au8830.h
+++ b/sound/pci/au88x0/au8830.h
@@ -11,7 +11,7 @@
11 11
12#define CHIP_AU8830 12#define CHIP_AU8830
13 13
14#define CARD_NAME "Aureal Vortex 2 3D Sound Processor" 14#define CARD_NAME "Aureal Vortex 2"
15#define CARD_NAME_SHORT "au8830" 15#define CARD_NAME_SHORT "au8830"
16 16
17#define NR_ADB 0x20 17#define NR_ADB 0x20
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index cf46bba563cf..02f6e08f7592 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -104,7 +104,7 @@
104#define MIX_PLAYB(x) (vortex->mixplayb[x]) 104#define MIX_PLAYB(x) (vortex->mixplayb[x])
105#define MIX_SPDIF(x) (vortex->mixspdif[x]) 105#define MIX_SPDIF(x) (vortex->mixspdif[x])
106 106
107#define NR_WTPB 0x20 /* WT channels per eahc bank. */ 107#define NR_WTPB 0x20 /* WT channels per each bank. */
108 108
109/* Structs */ 109/* Structs */
110typedef struct { 110typedef struct {
@@ -211,7 +211,7 @@ static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma);
211//static void vortex_adbdma_stopfifo(vortex_t *vortex, int adbdma); 211//static void vortex_adbdma_stopfifo(vortex_t *vortex, int adbdma);
212static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma); 212static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma);
213static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma); 213static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma);
214static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma); 214static inline int vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma);
215static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma); 215static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma);
216 216
217#ifndef CHIP_AU8810 217#ifndef CHIP_AU8810
@@ -219,7 +219,7 @@ static void vortex_wtdma_startfifo(vortex_t * vortex, int wtdma);
219static void vortex_wtdma_stopfifo(vortex_t * vortex, int wtdma); 219static void vortex_wtdma_stopfifo(vortex_t * vortex, int wtdma);
220static void vortex_wtdma_pausefifo(vortex_t * vortex, int wtdma); 220static void vortex_wtdma_pausefifo(vortex_t * vortex, int wtdma);
221static void vortex_wtdma_resumefifo(vortex_t * vortex, int wtdma); 221static void vortex_wtdma_resumefifo(vortex_t * vortex, int wtdma);
222static int inline vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma); 222static inline int vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma);
223#endif 223#endif
224 224
225/* global stuff. */ 225/* global stuff. */
diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c
index f4aa8ff6f5f9..9ae8b3b17651 100644
--- a/sound/pci/au88x0/au88x0_a3d.c
+++ b/sound/pci/au88x0/au88x0_a3d.c
@@ -53,7 +53,7 @@ a3dsrc_GetTimeConsts(a3dsrc_t * a, short *HrtfTrack, short *ItdTrack,
53} 53}
54 54
55#endif 55#endif
56/* Atmospheric absorbtion. */ 56/* Atmospheric absorption. */
57 57
58static void 58static void
59a3dsrc_SetAtmosTarget(a3dsrc_t * a, short aa, short b, short c, short d, 59a3dsrc_SetAtmosTarget(a3dsrc_t * a, short aa, short b, short c, short d,
@@ -835,7 +835,7 @@ snd_vortex_a3d_filter_put(struct snd_kcontrol *kcontrol,
835 params[i] = ucontrol->value.integer.value[i]; 835 params[i] = ucontrol->value.integer.value[i];
836 /* Translate generic filter params to a3d filter params. */ 836 /* Translate generic filter params to a3d filter params. */
837 vortex_a3d_translate_filter(a->filter, params); 837 vortex_a3d_translate_filter(a->filter, params);
838 /* Atmospheric absorbtion and filtering. */ 838 /* Atmospheric absorption and filtering. */
839 a3dsrc_SetAtmosTarget(a, a->filter[0], 839 a3dsrc_SetAtmosTarget(a, a->filter[0],
840 a->filter[1], a->filter[2], 840 a->filter[1], a->filter[2],
841 a->filter[3], a->filter[4]); 841 a->filter[3], a->filter[4]);
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 23f49f356e0f..489150380eac 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -1249,14 +1249,22 @@ static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
1249 } 1249 }
1250} 1250}
1251 1251
1252static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma) 1252static inline int vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma)
1253{ 1253{
1254 stream_t *dma = &vortex->dma_adb[adbdma]; 1254 stream_t *dma = &vortex->dma_adb[adbdma];
1255 int temp; 1255 int temp, page, delta;
1256 1256
1257 temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2)); 1257 temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2));
1258 temp = (dma->period_virt * dma->period_bytes) + (temp & (dma->period_bytes - 1)); 1258 page = (temp & ADB_SUBBUF_MASK) >> ADB_SUBBUF_SHIFT;
1259 return temp; 1259 if (dma->nr_periods >= 4)
1260 delta = (page - dma->period_real) & 3;
1261 else {
1262 delta = (page - dma->period_real);
1263 if (delta < 0)
1264 delta += dma->nr_periods;
1265 }
1266 return (dma->period_virt + delta) * dma->period_bytes
1267 + (temp & (dma->period_bytes - 1));
1260} 1268}
1261 1269
1262static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma) 1270static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma)
@@ -1498,7 +1506,7 @@ static int vortex_wtdma_getcursubuffer(vortex_t * vortex, int wtdma)
1498 POS_SHIFT) & POS_MASK); 1506 POS_SHIFT) & POS_MASK);
1499} 1507}
1500#endif 1508#endif
1501static int inline vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma) 1509static inline int vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma)
1502{ 1510{
1503 stream_t *dma = &vortex->dma_wt[wtdma]; 1511 stream_t *dma = &vortex->dma_wt[wtdma];
1504 int temp; 1512 int temp;
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index 38602b85874d..278ed8189fca 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -896,7 +896,8 @@ static int __devinit vortex_eq_init(vortex_t * vortex)
896 if ((kcontrol = 896 if ((kcontrol =
897 snd_ctl_new1(&vortex_eq_kcontrol, vortex)) == NULL) 897 snd_ctl_new1(&vortex_eq_kcontrol, vortex)) == NULL)
898 return -ENOMEM; 898 return -ENOMEM;
899 strcpy(kcontrol->id.name, EqBandLabels[i]); 899 snprintf(kcontrol->id.name, sizeof(kcontrol->id.name),
900 "%s Playback Volume", EqBandLabels[i]);
900 kcontrol->private_value = i; 901 kcontrol->private_value = i;
901 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0) 902 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
902 return err; 903 return err;
diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c
index c92f493d341e..557c782ae4fc 100644
--- a/sound/pci/au88x0/au88x0_mixer.c
+++ b/sound/pci/au88x0/au88x0_mixer.c
@@ -23,7 +23,7 @@ static int __devinit snd_vortex_mixer(vortex_t * vortex)
23 if ((err = snd_ac97_bus(vortex->card, 0, &ops, NULL, &pbus)) < 0) 23 if ((err = snd_ac97_bus(vortex->card, 0, &ops, NULL, &pbus)) < 0)
24 return err; 24 return err;
25 memset(&ac97, 0, sizeof(ac97)); 25 memset(&ac97, 0, sizeof(ac97));
26 // Intialize AC97 codec stuff. 26 // Initialize AC97 codec stuff.
27 ac97.private_data = vortex; 27 ac97.private_data = vortex;
28 ac97.scaps = AC97_SCAP_NO_SPDIF; 28 ac97.scaps = AC97_SCAP_NO_SPDIF;
29 err = snd_ac97_mixer(pbus, &ac97, &vortex->codec); 29 err = snd_ac97_mixer(pbus, &ac97, &vortex->codec);
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index b9d2f202cf9b..c5f7ae46afef 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -42,16 +42,12 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_adb = {
42 .rate_min = 5000, 42 .rate_min = 5000,
43 .rate_max = 48000, 43 .rate_max = 48000,
44 .channels_min = 1, 44 .channels_min = 1,
45#ifdef CHIP_AU8830
46 .channels_max = 4,
47#else
48 .channels_max = 2, 45 .channels_max = 2,
49#endif
50 .buffer_bytes_max = 0x10000, 46 .buffer_bytes_max = 0x10000,
51 .period_bytes_min = 0x1, 47 .period_bytes_min = 0x20,
52 .period_bytes_max = 0x1000, 48 .period_bytes_max = 0x1000,
53 .periods_min = 2, 49 .periods_min = 2,
54 .periods_max = 32, 50 .periods_max = 1024,
55}; 51};
56 52
57#ifndef CHIP_AU8820 53#ifndef CHIP_AU8820
@@ -115,6 +111,17 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_wt = {
115 .periods_max = 64, 111 .periods_max = 64,
116}; 112};
117#endif 113#endif
114#ifdef CHIP_AU8830
115static unsigned int au8830_channels[3] = {
116 1, 2, 4,
117};
118
119static struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = {
120 .count = ARRAY_SIZE(au8830_channels),
121 .list = au8830_channels,
122 .mask = 0,
123};
124#endif
118/* open callback */ 125/* open callback */
119static int snd_vortex_pcm_open(struct snd_pcm_substream *substream) 126static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
120{ 127{
@@ -133,6 +140,9 @@ static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
133 SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0) 140 SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0)
134 return err; 141 return err;
135 142
143 snd_pcm_hw_constraint_step(runtime, 0,
144 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 64);
145
136 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { 146 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
137#ifndef CHIP_AU8820 147#ifndef CHIP_AU8820
138 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_A3D) { 148 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_A3D) {
@@ -156,6 +166,15 @@ static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
156 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB 166 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB
157 || VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_I2S) 167 || VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_I2S)
158 runtime->hw = snd_vortex_playback_hw_adb; 168 runtime->hw = snd_vortex_playback_hw_adb;
169#ifdef CHIP_AU8830
170 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
171 VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
172 runtime->hw.channels_max = 4;
173 snd_pcm_hw_constraint_list(runtime, 0,
174 SNDRV_PCM_HW_PARAM_CHANNELS,
175 &hw_constraints_au8830_channels);
176 }
177#endif
159 substream->runtime->private_data = NULL; 178 substream->runtime->private_data = NULL;
160 } 179 }
161#ifndef CHIP_AU8810 180#ifndef CHIP_AU8810
@@ -407,11 +426,11 @@ static struct snd_pcm_ops snd_vortex_playback_ops = {
407*/ 426*/
408 427
409static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = { 428static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = {
410 "AU88x0 ADB", 429 CARD_NAME " ADB",
411 "AU88x0 SPDIF", 430 CARD_NAME " SPDIF",
412 "AU88x0 A3D", 431 CARD_NAME " A3D",
413 "AU88x0 WT", 432 CARD_NAME " WT",
414 "AU88x0 I2S", 433 CARD_NAME " I2S",
415}; 434};
416static char *vortex_pcm_name[VORTEX_PCM_LAST] = { 435static char *vortex_pcm_name[VORTEX_PCM_LAST] = {
417 "adb", 436 "adb",
@@ -499,7 +518,7 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
499 return -ENODEV; 518 return -ENODEV;
500 519
501 /* idx indicates which kind of PCM device. ADB, SPDIF, I2S and A3D share the 520 /* idx indicates which kind of PCM device. ADB, SPDIF, I2S and A3D share the
502 * same dma engine. WT uses it own separate dma engine whcih cant capture. */ 521 * same dma engine. WT uses it own separate dma engine which can't capture. */
503 if (idx == VORTEX_PCM_ADB) 522 if (idx == VORTEX_PCM_ADB)
504 nr_capt = nr; 523 nr_capt = nr;
505 else 524 else
@@ -508,7 +527,8 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
508 nr_capt, &pcm); 527 nr_capt, &pcm);
509 if (err < 0) 528 if (err < 0)
510 return err; 529 return err;
511 strcpy(pcm->name, vortex_pcm_name[idx]); 530 snprintf(pcm->name, sizeof(pcm->name),
531 "%s %s", CARD_NAME_SHORT, vortex_pcm_name[idx]);
512 chip->pcm[idx] = pcm; 532 chip->pcm[idx] = pcm;
513 // This is an evil hack, but it saves a lot of duplicated code. 533 // This is an evil hack, but it saves a lot of duplicated code.
514 VORTEX_PCM_TYPE(pcm) = idx; 534 VORTEX_PCM_TYPE(pcm) = idx;
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 4679ed83a43b..9b7a6346037a 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,5 @@
1/* 1/* azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). 2 * Copyright (C) 2002, 2005 - 2011 by Andreas Mohr <andi AT lisas.de>
3 * Copyright (C) 2002, 2005 - 2009 by Andreas Mohr <andi AT lisas.de>
4 * 3 *
5 * Framework borrowed from Bart Hartgers's als4000.c. 4 * Framework borrowed from Bart Hartgers's als4000.c.
6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), 5 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -66,6 +65,13 @@
66 * addresses illegally. So far unfortunately it looks like the very flexible 65 * addresses illegally. So far unfortunately it looks like the very flexible
67 * ALSA AC97 support is still not enough to easily compensate for such a 66 * ALSA AC97 support is still not enough to easily compensate for such a
68 * grave layout violation despite all tweaks and quirks mechanisms it offers. 67 * grave layout violation despite all tweaks and quirks mechanisms it offers.
68 * Well, not quite: now ac97 layer is much improved (bus-specific ops!),
69 * thus I was able to implement support - it's actually working quite well.
70 * An interesting item might be Aztech AMR 2800-W, since it's an AC97
71 * modem card which might reveal the Aztech-specific codec ID which
72 * we might want to pretend, too. Dito PCI168's brother, PCI368,
73 * where the advertising datasheet says it's AC97-based and has a
74 * Digital Enhanced Game Port.
69 * - builtin genuine OPL3 - verified to work fine, 20080506 75 * - builtin genuine OPL3 - verified to work fine, 20080506
70 * - full duplex 16bit playback/record at independent sampling rate 76 * - full duplex 16bit playback/record at independent sampling rate
71 * - MPU401 (+ legacy address support, claimed by one official spec sheet) 77 * - MPU401 (+ legacy address support, claimed by one official spec sheet)
@@ -134,7 +140,7 @@
134 * Possible remedies: 140 * Possible remedies:
135 * - use speaker (amplifier) output instead of headphone output 141 * - use speaker (amplifier) output instead of headphone output
136 * (in case crackling is due to overloaded output clipping) 142 * (in case crackling is due to overloaded output clipping)
137 * - plug card into a different PCI slot, preferrably one that isn't shared 143 * - plug card into a different PCI slot, preferably one that isn't shared
138 * too much (this helps a lot, but not completely!) 144 * too much (this helps a lot, but not completely!)
139 * - get rid of PCI VGA card, use AGP instead 145 * - get rid of PCI VGA card, use AGP instead
140 * - upgrade or downgrade BIOS 146 * - upgrade or downgrade BIOS
@@ -175,6 +181,7 @@
175 181
176#include <asm/io.h> 182#include <asm/io.h>
177#include <linux/init.h> 183#include <linux/init.h>
184#include <linux/bug.h> /* WARN_ONCE */
178#include <linux/pci.h> 185#include <linux/pci.h>
179#include <linux/delay.h> 186#include <linux/delay.h>
180#include <linux/slab.h> 187#include <linux/slab.h>
@@ -188,6 +195,16 @@
188#include <sound/mpu401.h> 195#include <sound/mpu401.h>
189#include <sound/opl3.h> 196#include <sound/opl3.h>
190#include <sound/initval.h> 197#include <sound/initval.h>
198/*
199 * Config switch, to use ALSA's AC97 layer instead of old custom mixer crap.
200 * If the AC97 compatibility parts we needed to implement locally turn out
201 * to work nicely, then remove the old implementation eventually.
202 */
203#define AZF_USE_AC97_LAYER 1
204
205#ifdef AZF_USE_AC97_LAYER
206#include <sound/ac97_codec.h>
207#endif
191#include "azt3328.h" 208#include "azt3328.h"
192 209
193MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>"); 210MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>");
@@ -201,14 +218,15 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
201 218
202/* === Debug settings === 219/* === Debug settings ===
203 Further diagnostic functionality than the settings below 220 Further diagnostic functionality than the settings below
204 does not need to be provided, since one can easily write a bash script 221 does not need to be provided, since one can easily write a POSIX shell script
205 to dump the card's I/O ports (those listed in lspci -v -v): 222 to dump the card's I/O ports (those listed in lspci -v -v):
206 function dump() 223 dump()
207 { 224 {
208 local descr=$1; local addr=$2; local count=$3 225 local descr=$1; local addr=$2; local count=$3
209 226
210 echo "${descr}: ${count} @ ${addr}:" 227 echo "${descr}: ${count} @ ${addr}:"
211 dd if=/dev/port skip=$[${addr}] count=${count} bs=1 2>/dev/null| hexdump -C 228 dd if=/dev/port skip=`printf %d ${addr}` count=${count} bs=1 \
229 2>/dev/null| hexdump -C
212 } 230 }
213 and then use something like 231 and then use something like
214 "dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8", 232 "dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8",
@@ -216,14 +234,14 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
216 possibly within a "while true; do ... sleep 1; done" loop. 234 possibly within a "while true; do ... sleep 1; done" loop.
217 Tweaking ports could be done using 235 Tweaking ports could be done using
218 VALSTRING="`printf "%02x" $value`" 236 VALSTRING="`printf "%02x" $value`"
219 printf "\x""$VALSTRING"|dd of=/dev/port seek=$[${addr}] bs=1 2>/dev/null 237 printf "\x""$VALSTRING"|dd of=/dev/port seek=`printf %d ${addr}` bs=1 \
238 2>/dev/null
220*/ 239*/
221 240
222#define DEBUG_MISC 0 241#define DEBUG_MISC 0
223#define DEBUG_CALLS 0 242#define DEBUG_CALLS 0
224#define DEBUG_MIXER 0 243#define DEBUG_MIXER 0
225#define DEBUG_CODEC 0 244#define DEBUG_CODEC 0
226#define DEBUG_IO 0
227#define DEBUG_TIMER 0 245#define DEBUG_TIMER 0
228#define DEBUG_GAME 0 246#define DEBUG_GAME 0
229#define DEBUG_PM 0 247#define DEBUG_PM 0
@@ -291,19 +309,23 @@ static int seqtimer_scaling = 128;
291module_param(seqtimer_scaling, int, 0444); 309module_param(seqtimer_scaling, int, 0444);
292MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128."); 310MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
293 311
294struct snd_azf3328_codec_data {
295 unsigned long io_base;
296 struct snd_pcm_substream *substream;
297 bool running;
298 const char *name;
299};
300
301enum snd_azf3328_codec_type { 312enum snd_azf3328_codec_type {
313 /* warning: fixed indices (also used for bitmask checks!) */
302 AZF_CODEC_PLAYBACK = 0, 314 AZF_CODEC_PLAYBACK = 0,
303 AZF_CODEC_CAPTURE = 1, 315 AZF_CODEC_CAPTURE = 1,
304 AZF_CODEC_I2S_OUT = 2, 316 AZF_CODEC_I2S_OUT = 2,
305}; 317};
306 318
319struct snd_azf3328_codec_data {
320 unsigned long io_base; /* keep first! (avoid offset calc) */
321 unsigned int dma_base; /* helper to avoid an indirection in hotpath */
322 spinlock_t *lock; /* TODO: convert to our own per-codec lock member */
323 struct snd_pcm_substream *substream;
324 bool running;
325 enum snd_azf3328_codec_type type;
326 const char *name;
327};
328
307struct snd_azf3328 { 329struct snd_azf3328 {
308 /* often-used fields towards beginning, then grouped */ 330 /* often-used fields towards beginning, then grouped */
309 331
@@ -322,6 +344,10 @@ struct snd_azf3328 {
322 /* playback, recording and I2S out codecs */ 344 /* playback, recording and I2S out codecs */
323 struct snd_azf3328_codec_data codecs[3]; 345 struct snd_azf3328_codec_data codecs[3];
324 346
347#ifdef AZF_USE_AC97_LAYER
348 struct snd_ac97 *ac97;
349#endif
350
325 struct snd_card *card; 351 struct snd_card *card;
326 struct snd_rawmidi *rmidi; 352 struct snd_rawmidi *rmidi;
327 353
@@ -362,6 +388,9 @@ MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
362static int 388static int
363snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set) 389snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set)
364{ 390{
391 /* Well, strictly spoken, the inb/outb sequence isn't atomic
392 and would need locking. However we currently don't care
393 since it potentially complicates matters. */
365 u8 prev = inb(reg), new; 394 u8 prev = inb(reg), new;
366 395
367 new = (do_set) ? (prev|mask) : (prev & ~mask); 396 new = (do_set) ? (prev|mask) : (prev & ~mask);
@@ -413,6 +442,21 @@ snd_azf3328_codec_outl(const struct snd_azf3328_codec_data *codec,
413 outl(value, codec->io_base + reg); 442 outl(value, codec->io_base + reg);
414} 443}
415 444
445static inline void
446snd_azf3328_codec_outl_multi(const struct snd_azf3328_codec_data *codec,
447 unsigned reg, const void *buffer, int count
448)
449{
450 unsigned long addr = codec->io_base + reg;
451 if (count) {
452 const u32 *buf = buffer;
453 do {
454 outl(*buf++, addr);
455 addr += 4;
456 } while (--count);
457 }
458}
459
416static inline u32 460static inline u32
417snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg) 461snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg)
418{ 462{
@@ -482,7 +526,7 @@ snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, unsigned reg)
482#define AZF_MUTE_BIT 0x80 526#define AZF_MUTE_BIT 0x80
483 527
484static bool 528static bool
485snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip, 529snd_azf3328_mixer_mute_control(const struct snd_azf3328 *chip,
486 unsigned reg, bool do_mute 530 unsigned reg, bool do_mute
487) 531)
488{ 532{
@@ -497,6 +541,323 @@ snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip,
497 return (do_mute) ? !updated : updated; 541 return (do_mute) ? !updated : updated;
498} 542}
499 543
544static inline bool
545snd_azf3328_mixer_mute_control_master(const struct snd_azf3328 *chip,
546 bool do_mute
547)
548{
549 return snd_azf3328_mixer_mute_control(
550 chip,
551 IDX_MIXER_PLAY_MASTER,
552 do_mute
553 );
554}
555
556static inline bool
557snd_azf3328_mixer_mute_control_pcm(const struct snd_azf3328 *chip,
558 bool do_mute
559)
560{
561 return snd_azf3328_mixer_mute_control(
562 chip,
563 IDX_MIXER_WAVEOUT,
564 do_mute
565 );
566}
567
568static inline void
569snd_azf3328_mixer_reset(const struct snd_azf3328 *chip)
570{
571 /* reset (close) mixer:
572 * first mute master volume, then reset
573 */
574 snd_azf3328_mixer_mute_control_master(chip, 1);
575 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
576}
577
578#ifdef AZF_USE_AC97_LAYER
579
580static inline void
581snd_azf3328_mixer_ac97_map_unsupported(unsigned short reg, const char *mode)
582{
583 /* need to add some more or less clever emulation? */
584 printk(KERN_WARNING
585 "azt3328: missing %s emulation for AC97 register 0x%02x!\n",
586 mode, reg);
587}
588
589/*
590 * Need to have _special_ AC97 mixer hardware register index mapper,
591 * to compensate for the issue of a rather AC97-incompatible hardware layout.
592 */
593#define AZF_REG_MASK 0x3f
594#define AZF_AC97_REG_UNSUPPORTED 0x8000
595#define AZF_AC97_REG_REAL_IO_READ 0x4000
596#define AZF_AC97_REG_REAL_IO_WRITE 0x2000
597#define AZF_AC97_REG_REAL_IO_RW \
598 (AZF_AC97_REG_REAL_IO_READ | AZF_AC97_REG_REAL_IO_WRITE)
599#define AZF_AC97_REG_EMU_IO_READ 0x0400
600#define AZF_AC97_REG_EMU_IO_WRITE 0x0200
601#define AZF_AC97_REG_EMU_IO_RW \
602 (AZF_AC97_REG_EMU_IO_READ | AZF_AC97_REG_EMU_IO_WRITE)
603static unsigned short
604snd_azf3328_mixer_ac97_map_reg_idx(unsigned short reg)
605{
606 static const struct {
607 unsigned short azf_reg;
608 } azf_reg_mapper[] = {
609 /* Especially when taking into consideration
610 * mono/stereo-based sequence of azf vs. AC97 control series,
611 * it's quite obvious that azf simply got rid
612 * of the AC97_HEADPHONE control at its intended offset,
613 * thus shifted _all_ controls by one,
614 * and _then_ simply added it as an FMSYNTH control at the end,
615 * to make up for the offset.
616 * This means we'll have to translate indices here as
617 * needed and then do some tiny AC97 patch action
618 * (snd_ac97_rename_vol_ctl() etc.) - that's it.
619 */
620 { /* AC97_RESET */ IDX_MIXER_RESET
621 | AZF_AC97_REG_REAL_IO_WRITE
622 | AZF_AC97_REG_EMU_IO_READ },
623 { /* AC97_MASTER */ IDX_MIXER_PLAY_MASTER },
624 /* note large shift: AC97_HEADPHONE to IDX_MIXER_FMSYNTH! */
625 { /* AC97_HEADPHONE */ IDX_MIXER_FMSYNTH },
626 { /* AC97_MASTER_MONO */ IDX_MIXER_MODEMOUT },
627 { /* AC97_MASTER_TONE */ IDX_MIXER_BASSTREBLE },
628 { /* AC97_PC_BEEP */ IDX_MIXER_PCBEEP },
629 { /* AC97_PHONE */ IDX_MIXER_MODEMIN },
630 { /* AC97_MIC */ IDX_MIXER_MIC },
631 { /* AC97_LINE */ IDX_MIXER_LINEIN },
632 { /* AC97_CD */ IDX_MIXER_CDAUDIO },
633 { /* AC97_VIDEO */ IDX_MIXER_VIDEO },
634 { /* AC97_AUX */ IDX_MIXER_AUX },
635 { /* AC97_PCM */ IDX_MIXER_WAVEOUT },
636 { /* AC97_REC_SEL */ IDX_MIXER_REC_SELECT },
637 { /* AC97_REC_GAIN */ IDX_MIXER_REC_VOLUME },
638 { /* AC97_REC_GAIN_MIC */ AZF_AC97_REG_EMU_IO_RW },
639 { /* AC97_GENERAL_PURPOSE */ IDX_MIXER_ADVCTL2 },
640 { /* AC97_3D_CONTROL */ IDX_MIXER_ADVCTL1 },
641 };
642
643 unsigned short reg_azf = AZF_AC97_REG_UNSUPPORTED;
644
645 /* azf3328 supports the low-numbered and low-spec:ed range
646 of AC97 regs only */
647 if (reg <= AC97_3D_CONTROL) {
648 unsigned short reg_idx = reg / 2;
649 reg_azf = azf_reg_mapper[reg_idx].azf_reg;
650 /* a translation-only entry means it's real read/write: */
651 if (!(reg_azf & ~AZF_REG_MASK))
652 reg_azf |= AZF_AC97_REG_REAL_IO_RW;
653 } else {
654 switch (reg) {
655 case AC97_POWERDOWN:
656 reg_azf = AZF_AC97_REG_EMU_IO_RW;
657 break;
658 case AC97_EXTENDED_ID:
659 reg_azf = AZF_AC97_REG_EMU_IO_READ;
660 break;
661 case AC97_EXTENDED_STATUS:
662 /* I don't know what the h*ll AC97 layer
663 * would consult this _extended_ register for
664 * given a base-AC97-advertised card,
665 * but let's just emulate it anyway :-P
666 */
667 reg_azf = AZF_AC97_REG_EMU_IO_RW;
668 break;
669 case AC97_VENDOR_ID1:
670 case AC97_VENDOR_ID2:
671 reg_azf = AZF_AC97_REG_EMU_IO_READ;
672 break;
673 }
674 }
675 return reg_azf;
676}
677
678static const unsigned short
679azf_emulated_ac97_caps =
680 AC97_BC_DEDICATED_MIC |
681 AC97_BC_BASS_TREBLE |
682 /* Headphone is an FM Synth control here */
683 AC97_BC_HEADPHONE |
684 /* no AC97_BC_LOUDNESS! */
685 /* mask 0x7c00 is
686 vendor-specific 3D enhancement
687 vendor indicator.
688 Since there actually _is_ an
689 entry for Aztech Labs
690 (13), make damn sure
691 to indicate it. */
692 (13 << 10);
693
694static const unsigned short
695azf_emulated_ac97_powerdown =
696 /* pretend everything to be active */
697 AC97_PD_ADC_STATUS |
698 AC97_PD_DAC_STATUS |
699 AC97_PD_MIXER_STATUS |
700 AC97_PD_VREF_STATUS;
701
702/*
703 * Emulated, _inofficial_ vendor ID
704 * (there might be some devices such as the MR 2800-W
705 * which could reveal the real Aztech AC97 ID).
706 * We choose to use "AZT" prefix, and then use 1 to indicate PCI168
707 * (better don't use 0x68 since there's a PCI368 as well).
708 */
709static const unsigned int
710azf_emulated_ac97_vendor_id = 0x415a5401;
711
712static unsigned short
713snd_azf3328_mixer_ac97_read(struct snd_ac97 *ac97, unsigned short reg_ac97)
714{
715 const struct snd_azf3328 *chip = ac97->private_data;
716 unsigned short reg_azf = snd_azf3328_mixer_ac97_map_reg_idx(reg_ac97);
717 unsigned short reg_val = 0;
718 bool unsupported = 0;
719
720 snd_azf3328_dbgmixer(
721 "snd_azf3328_mixer_ac97_read reg_ac97 %u\n",
722 reg_ac97
723 );
724 if (reg_azf & AZF_AC97_REG_UNSUPPORTED)
725 unsupported = 1;
726 else {
727 if (reg_azf & AZF_AC97_REG_REAL_IO_READ)
728 reg_val = snd_azf3328_mixer_inw(chip,
729 reg_azf & AZF_REG_MASK);
730 else {
731 /*
732 * Proceed with dummy I/O read,
733 * to ensure compatible timing where this may matter.
734 * (ALSA AC97 layer usually doesn't call I/O functions
735 * due to intelligent I/O caching anyway)
736 * Choose a mixer register that's thoroughly unrelated
737 * to common audio (try to minimize distortion).
738 */
739 snd_azf3328_mixer_inw(chip, IDX_MIXER_SOMETHING30H);
740 }
741
742 if (reg_azf & AZF_AC97_REG_EMU_IO_READ) {
743 switch (reg_ac97) {
744 case AC97_RESET:
745 reg_val |= azf_emulated_ac97_caps;
746 break;
747 case AC97_POWERDOWN:
748 reg_val |= azf_emulated_ac97_powerdown;
749 break;
750 case AC97_EXTENDED_ID:
751 case AC97_EXTENDED_STATUS:
752 /* AFAICS we simply can't support anything: */
753 reg_val |= 0;
754 break;
755 case AC97_VENDOR_ID1:
756 reg_val = azf_emulated_ac97_vendor_id >> 16;
757 break;
758 case AC97_VENDOR_ID2:
759 reg_val = azf_emulated_ac97_vendor_id & 0xffff;
760 break;
761 default:
762 unsupported = 1;
763 break;
764 }
765 }
766 }
767 if (unsupported)
768 snd_azf3328_mixer_ac97_map_unsupported(reg_ac97, "read");
769
770 return reg_val;
771}
772
773static void
774snd_azf3328_mixer_ac97_write(struct snd_ac97 *ac97,
775 unsigned short reg_ac97, unsigned short val)
776{
777 const struct snd_azf3328 *chip = ac97->private_data;
778 unsigned short reg_azf = snd_azf3328_mixer_ac97_map_reg_idx(reg_ac97);
779 bool unsupported = 0;
780
781 snd_azf3328_dbgmixer(
782 "snd_azf3328_mixer_ac97_write reg_ac97 %u val %u\n",
783 reg_ac97, val
784 );
785 if (reg_azf & AZF_AC97_REG_UNSUPPORTED)
786 unsupported = 1;
787 else {
788 if (reg_azf & AZF_AC97_REG_REAL_IO_WRITE)
789 snd_azf3328_mixer_outw(
790 chip,
791 reg_azf & AZF_REG_MASK,
792 val
793 );
794 else
795 if (reg_azf & AZF_AC97_REG_EMU_IO_WRITE) {
796 switch (reg_ac97) {
797 case AC97_REC_GAIN_MIC:
798 case AC97_POWERDOWN:
799 case AC97_EXTENDED_STATUS:
800 /*
801 * Silently swallow these writes.
802 * Since for most registers our card doesn't
803 * actually support a comparable feature,
804 * this is exactly what we should do here.
805 * The AC97 layer's I/O caching probably
806 * automatically takes care of all the rest...
807 * (remembers written values etc.)
808 */
809 break;
810 default:
811 unsupported = 1;
812 break;
813 }
814 }
815 }
816 if (unsupported)
817 snd_azf3328_mixer_ac97_map_unsupported(reg_ac97, "write");
818}
819
820static int __devinit
821snd_azf3328_mixer_new(struct snd_azf3328 *chip)
822{
823 struct snd_ac97_bus *bus;
824 struct snd_ac97_template ac97;
825 static struct snd_ac97_bus_ops ops = {
826 .write = snd_azf3328_mixer_ac97_write,
827 .read = snd_azf3328_mixer_ac97_read,
828 };
829 int rc;
830
831 memset(&ac97, 0, sizeof(ac97));
832 ac97.scaps = AC97_SCAP_SKIP_MODEM
833 | AC97_SCAP_AUDIO /* we support audio! */
834 | AC97_SCAP_NO_SPDIF;
835 ac97.private_data = chip;
836 ac97.pci = chip->pci;
837
838 /*
839 * ALSA's AC97 layer has terrible init crackling issues,
840 * unfortunately, and since it makes use of AC97_RESET,
841 * there's no use trying to mute Master Playback proactively.
842 */
843
844 rc = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus);
845 if (!rc)
846 rc = snd_ac97_mixer(bus, &ac97, &chip->ac97);
847 /*
848 * Make sure to complain loudly in case of AC97 init failure,
849 * since failure may happen quite often,
850 * due to this card being a very quirky AC97 "lookalike".
851 */
852 if (rc)
853 printk(KERN_ERR "azt3328: AC97 init failed, err %d!\n", rc);
854
855 /* If we return an error here, then snd_card_free() should
856 * free up any ac97 codecs that got created, as well as the bus.
857 */
858 return rc;
859}
860#else /* AZF_USE_AC97_LAYER */
500static void 861static void
501snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, 862snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip,
502 unsigned reg, 863 unsigned reg,
@@ -921,6 +1282,7 @@ snd_azf3328_mixer_new(struct snd_azf3328 *chip)
921 snd_azf3328_dbgcallleave(); 1282 snd_azf3328_dbgcallleave();
922 return 0; 1283 return 0;
923} 1284}
1285#endif /* AZF_USE_AC97_LAYER */
924 1286
925static int 1287static int
926snd_azf3328_hw_params(struct snd_pcm_substream *substream, 1288snd_azf3328_hw_params(struct snd_pcm_substream *substream,
@@ -943,38 +1305,37 @@ snd_azf3328_hw_free(struct snd_pcm_substream *substream)
943} 1305}
944 1306
945static void 1307static void
946snd_azf3328_codec_setfmt(struct snd_azf3328 *chip, 1308snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec,
947 enum snd_azf3328_codec_type codec_type,
948 enum azf_freq_t bitrate, 1309 enum azf_freq_t bitrate,
949 unsigned int format_width, 1310 unsigned int format_width,
950 unsigned int channels 1311 unsigned int channels
951) 1312)
952{ 1313{
953 unsigned long flags; 1314 unsigned long flags;
954 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
955 u16 val = 0xff00; 1315 u16 val = 0xff00;
1316 u8 freq = 0;
956 1317
957 snd_azf3328_dbgcallenter(); 1318 snd_azf3328_dbgcallenter();
958 switch (bitrate) { 1319 switch (bitrate) {
959 case AZF_FREQ_4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break; 1320 case AZF_FREQ_4000: freq = SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
960 case AZF_FREQ_4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break; 1321 case AZF_FREQ_4800: freq = SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
961 case AZF_FREQ_5512: 1322 case AZF_FREQ_5512:
962 /* the AZF3328 names it "5510" for some strange reason */ 1323 /* the AZF3328 names it "5510" for some strange reason */
963 val |= SOUNDFORMAT_FREQ_5510; break; 1324 freq = SOUNDFORMAT_FREQ_5510; break;
964 case AZF_FREQ_6620: val |= SOUNDFORMAT_FREQ_6620; break; 1325 case AZF_FREQ_6620: freq = SOUNDFORMAT_FREQ_6620; break;
965 case AZF_FREQ_8000: val |= SOUNDFORMAT_FREQ_8000; break; 1326 case AZF_FREQ_8000: freq = SOUNDFORMAT_FREQ_8000; break;
966 case AZF_FREQ_9600: val |= SOUNDFORMAT_FREQ_9600; break; 1327 case AZF_FREQ_9600: freq = SOUNDFORMAT_FREQ_9600; break;
967 case AZF_FREQ_11025: val |= SOUNDFORMAT_FREQ_11025; break; 1328 case AZF_FREQ_11025: freq = SOUNDFORMAT_FREQ_11025; break;
968 case AZF_FREQ_13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break; 1329 case AZF_FREQ_13240: freq = SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
969 case AZF_FREQ_16000: val |= SOUNDFORMAT_FREQ_16000; break; 1330 case AZF_FREQ_16000: freq = SOUNDFORMAT_FREQ_16000; break;
970 case AZF_FREQ_22050: val |= SOUNDFORMAT_FREQ_22050; break; 1331 case AZF_FREQ_22050: freq = SOUNDFORMAT_FREQ_22050; break;
971 case AZF_FREQ_32000: val |= SOUNDFORMAT_FREQ_32000; break; 1332 case AZF_FREQ_32000: freq = SOUNDFORMAT_FREQ_32000; break;
972 default: 1333 default:
973 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate); 1334 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
974 /* fall-through */ 1335 /* fall-through */
975 case AZF_FREQ_44100: val |= SOUNDFORMAT_FREQ_44100; break; 1336 case AZF_FREQ_44100: freq = SOUNDFORMAT_FREQ_44100; break;
976 case AZF_FREQ_48000: val |= SOUNDFORMAT_FREQ_48000; break; 1337 case AZF_FREQ_48000: freq = SOUNDFORMAT_FREQ_48000; break;
977 case AZF_FREQ_66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break; 1338 case AZF_FREQ_66200: freq = SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
978 } 1339 }
979 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */ 1340 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
980 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */ 1341 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
@@ -986,13 +1347,15 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
986 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */ 1347 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
987 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */ 1348 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
988 1349
1350 val |= freq;
1351
989 if (channels == 2) 1352 if (channels == 2)
990 val |= SOUNDFORMAT_FLAG_2CHANNELS; 1353 val |= SOUNDFORMAT_FLAG_2CHANNELS;
991 1354
992 if (format_width == 16) 1355 if (format_width == 16)
993 val |= SOUNDFORMAT_FLAG_16BIT; 1356 val |= SOUNDFORMAT_FLAG_16BIT;
994 1357
995 spin_lock_irqsave(&chip->reg_lock, flags); 1358 spin_lock_irqsave(codec->lock, flags);
996 1359
997 /* set bitrate/format */ 1360 /* set bitrate/format */
998 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val); 1361 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val);
@@ -1004,7 +1367,8 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
1004 * (FIXME: yes, it works, but what exactly am I doing here?? :) 1367 * (FIXME: yes, it works, but what exactly am I doing here?? :)
1005 * FIXME: does this have some side effects for full-duplex 1368 * FIXME: does this have some side effects for full-duplex
1006 * or other dramatic side effects? */ 1369 * or other dramatic side effects? */
1007 if (codec_type == AZF_CODEC_PLAYBACK) /* only do it for playback */ 1370 /* do it for non-capture codecs only */
1371 if (codec->type != AZF_CODEC_CAPTURE)
1008 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, 1372 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1009 snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) | 1373 snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) |
1010 DMA_RUN_SOMETHING1 | 1374 DMA_RUN_SOMETHING1 |
@@ -1014,20 +1378,19 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
1014 DMA_SOMETHING_ELSE 1378 DMA_SOMETHING_ELSE
1015 ); 1379 );
1016 1380
1017 spin_unlock_irqrestore(&chip->reg_lock, flags); 1381 spin_unlock_irqrestore(codec->lock, flags);
1018 snd_azf3328_dbgcallleave(); 1382 snd_azf3328_dbgcallleave();
1019} 1383}
1020 1384
1021static inline void 1385static inline void
1022snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip, 1386snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328_codec_data *codec
1023 enum snd_azf3328_codec_type codec_type
1024) 1387)
1025{ 1388{
1026 /* choose lowest frequency for low power consumption. 1389 /* choose lowest frequency for low power consumption.
1027 * While this will cause louder noise due to rather coarse frequency, 1390 * While this will cause louder noise due to rather coarse frequency,
1028 * it should never matter since output should always 1391 * it should never matter since output should always
1029 * get disabled properly when idle anyway. */ 1392 * get disabled properly when idle anyway. */
1030 snd_azf3328_codec_setfmt(chip, codec_type, AZF_FREQ_4000, 8, 1); 1393 snd_azf3328_codec_setfmt(codec, AZF_FREQ_4000, 8, 1);
1031} 1394}
1032 1395
1033static void 1396static void
@@ -1101,68 +1464,87 @@ snd_azf3328_ctrl_codec_activity(struct snd_azf3328 *chip,
1101 /* ...and adjust clock, too 1464 /* ...and adjust clock, too
1102 * (reduce noise and power consumption) */ 1465 * (reduce noise and power consumption) */
1103 if (!enable) 1466 if (!enable)
1104 snd_azf3328_codec_setfmt_lowpower( 1467 snd_azf3328_codec_setfmt_lowpower(codec);
1105 chip,
1106 codec_type
1107 );
1108 codec->running = enable; 1468 codec->running = enable;
1109 } 1469 }
1110} 1470}
1111 1471
1112static void 1472static void
1113snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip, 1473snd_azf3328_codec_setdmaa(struct snd_azf3328_codec_data *codec,
1114 enum snd_azf3328_codec_type codec_type,
1115 unsigned long addr, 1474 unsigned long addr,
1116 unsigned int count, 1475 unsigned int period_bytes,
1117 unsigned int size 1476 unsigned int buffer_bytes
1118) 1477)
1119{ 1478{
1120 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1121 snd_azf3328_dbgcallenter(); 1479 snd_azf3328_dbgcallenter();
1480 WARN_ONCE(period_bytes & 1, "odd period length!?\n");
1481 WARN_ONCE(buffer_bytes != 2 * period_bytes,
1482 "missed our input expectations! %u vs. %u\n",
1483 buffer_bytes, period_bytes);
1122 if (!codec->running) { 1484 if (!codec->running) {
1123 /* AZF3328 uses a two buffer pointer DMA transfer approach */ 1485 /* AZF3328 uses a two buffer pointer DMA transfer approach */
1124 1486
1125 unsigned long flags, addr_area2; 1487 unsigned long flags;
1126 1488
1127 /* width 32bit (prevent overflow): */ 1489 /* width 32bit (prevent overflow): */
1128 u32 count_areas, lengths; 1490 u32 area_length;
1491 struct codec_setup_io {
1492 u32 dma_start_1;
1493 u32 dma_start_2;
1494 u32 dma_lengths;
1495 } __attribute__((packed)) setup_io;
1496
1497 area_length = buffer_bytes/2;
1498
1499 setup_io.dma_start_1 = addr;
1500 setup_io.dma_start_2 = addr+area_length;
1129 1501
1130 count_areas = size/2; 1502 snd_azf3328_dbgcodec(
1131 addr_area2 = addr+count_areas; 1503 "setdma: buffers %08x[%u] / %08x[%u], %u, %u\n",
1132 count_areas--; /* max. index */ 1504 setup_io.dma_start_1, area_length,
1133 snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n", 1505 setup_io.dma_start_2, area_length,
1134 addr, count_areas, addr_area2, count_areas); 1506 period_bytes, buffer_bytes);
1507
1508 /* Hmm, are we really supposed to decrement this by 1??
1509 Most definitely certainly not: configuring full length does
1510 work properly (i.e. likely better), and BTW we
1511 violated possibly differing frame sizes with this...
1512
1513 area_length--; |* max. index *|
1514 */
1135 1515
1136 /* build combined I/O buffer length word */ 1516 /* build combined I/O buffer length word */
1137 lengths = (count_areas << 16) | (count_areas); 1517 setup_io.dma_lengths = (area_length << 16) | (area_length);
1138 spin_lock_irqsave(&chip->reg_lock, flags); 1518
1139 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_1, addr); 1519 spin_lock_irqsave(codec->lock, flags);
1140 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_2, 1520 snd_azf3328_codec_outl_multi(
1141 addr_area2); 1521 codec, IDX_IO_CODEC_DMA_START_1, &setup_io, 3
1142 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_LENGTHS, 1522 );
1143 lengths); 1523 spin_unlock_irqrestore(codec->lock, flags);
1144 spin_unlock_irqrestore(&chip->reg_lock, flags);
1145 } 1524 }
1146 snd_azf3328_dbgcallleave(); 1525 snd_azf3328_dbgcallleave();
1147} 1526}
1148 1527
1149static int 1528static int
1150snd_azf3328_codec_prepare(struct snd_pcm_substream *substream) 1529snd_azf3328_pcm_prepare(struct snd_pcm_substream *substream)
1151{ 1530{
1152#if 0
1153 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1154 struct snd_pcm_runtime *runtime = substream->runtime; 1531 struct snd_pcm_runtime *runtime = substream->runtime;
1532 struct snd_azf3328_codec_data *codec = runtime->private_data;
1533#if 0
1155 unsigned int size = snd_pcm_lib_buffer_bytes(substream); 1534 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1156 unsigned int count = snd_pcm_lib_period_bytes(substream); 1535 unsigned int count = snd_pcm_lib_period_bytes(substream);
1157#endif 1536#endif
1158 1537
1159 snd_azf3328_dbgcallenter(); 1538 snd_azf3328_dbgcallenter();
1539
1540 codec->dma_base = runtime->dma_addr;
1541
1160#if 0 1542#if 0
1161 snd_azf3328_codec_setfmt(chip, AZF_CODEC_..., 1543 snd_azf3328_codec_setfmt(codec,
1162 runtime->rate, 1544 runtime->rate,
1163 snd_pcm_format_width(runtime->format), 1545 snd_pcm_format_width(runtime->format),
1164 runtime->channels); 1546 runtime->channels);
1165 snd_azf3328_codec_setdmaa(chip, AZF_CODEC_..., 1547 snd_azf3328_codec_setdmaa(codec,
1166 runtime->dma_addr, count, size); 1548 runtime->dma_addr, count, size);
1167#endif 1549#endif
1168 snd_azf3328_dbgcallleave(); 1550 snd_azf3328_dbgcallleave();
@@ -1170,37 +1552,36 @@ snd_azf3328_codec_prepare(struct snd_pcm_substream *substream)
1170} 1552}
1171 1553
1172static int 1554static int
1173snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type, 1555snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1174 struct snd_pcm_substream *substream, int cmd)
1175{ 1556{
1176 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1557 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1177 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1178 struct snd_pcm_runtime *runtime = substream->runtime; 1558 struct snd_pcm_runtime *runtime = substream->runtime;
1559 struct snd_azf3328_codec_data *codec = runtime->private_data;
1179 int result = 0; 1560 int result = 0;
1180 u16 flags1; 1561 u16 flags1;
1181 bool previously_muted = 0; 1562 bool previously_muted = 0;
1182 bool is_playback_codec = (AZF_CODEC_PLAYBACK == codec_type); 1563 bool is_main_mixer_playback_codec = (AZF_CODEC_PLAYBACK == codec->type);
1183 1564
1184 snd_azf3328_dbgcalls("snd_azf3328_codec_trigger cmd %d\n", cmd); 1565 snd_azf3328_dbgcalls("snd_azf3328_pcm_trigger cmd %d\n", cmd);
1185 1566
1186 switch (cmd) { 1567 switch (cmd) {
1187 case SNDRV_PCM_TRIGGER_START: 1568 case SNDRV_PCM_TRIGGER_START:
1188 snd_azf3328_dbgcodec("START %s\n", codec->name); 1569 snd_azf3328_dbgcodec("START %s\n", codec->name);
1189 1570
1190 if (is_playback_codec) { 1571 if (is_main_mixer_playback_codec) {
1191 /* mute WaveOut (avoid clicking during setup) */ 1572 /* mute WaveOut (avoid clicking during setup) */
1192 previously_muted = 1573 previously_muted =
1193 snd_azf3328_mixer_set_mute( 1574 snd_azf3328_mixer_mute_control_pcm(
1194 chip, IDX_MIXER_WAVEOUT, 1 1575 chip, 1
1195 ); 1576 );
1196 } 1577 }
1197 1578
1198 snd_azf3328_codec_setfmt(chip, codec_type, 1579 snd_azf3328_codec_setfmt(codec,
1199 runtime->rate, 1580 runtime->rate,
1200 snd_pcm_format_width(runtime->format), 1581 snd_pcm_format_width(runtime->format),
1201 runtime->channels); 1582 runtime->channels);
1202 1583
1203 spin_lock(&chip->reg_lock); 1584 spin_lock(codec->lock);
1204 /* first, remember current value: */ 1585 /* first, remember current value: */
1205 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS); 1586 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1206 1587
@@ -1210,14 +1591,14 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1210 1591
1211 /* FIXME: clear interrupts or what??? */ 1592 /* FIXME: clear interrupts or what??? */
1212 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff); 1593 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff);
1213 spin_unlock(&chip->reg_lock); 1594 spin_unlock(codec->lock);
1214 1595
1215 snd_azf3328_codec_setdmaa(chip, codec_type, runtime->dma_addr, 1596 snd_azf3328_codec_setdmaa(codec, runtime->dma_addr,
1216 snd_pcm_lib_period_bytes(substream), 1597 snd_pcm_lib_period_bytes(substream),
1217 snd_pcm_lib_buffer_bytes(substream) 1598 snd_pcm_lib_buffer_bytes(substream)
1218 ); 1599 );
1219 1600
1220 spin_lock(&chip->reg_lock); 1601 spin_lock(codec->lock);
1221#ifdef WIN9X 1602#ifdef WIN9X
1222 /* FIXME: enable playback/recording??? */ 1603 /* FIXME: enable playback/recording??? */
1223 flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2; 1604 flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2;
@@ -1241,14 +1622,14 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1241 DMA_EPILOGUE_SOMETHING | 1622 DMA_EPILOGUE_SOMETHING |
1242 DMA_SOMETHING_ELSE); 1623 DMA_SOMETHING_ELSE);
1243#endif 1624#endif
1244 spin_unlock(&chip->reg_lock); 1625 spin_unlock(codec->lock);
1245 snd_azf3328_ctrl_codec_activity(chip, codec_type, 1); 1626 snd_azf3328_ctrl_codec_activity(chip, codec->type, 1);
1246 1627
1247 if (is_playback_codec) { 1628 if (is_main_mixer_playback_codec) {
1248 /* now unmute WaveOut */ 1629 /* now unmute WaveOut */
1249 if (!previously_muted) 1630 if (!previously_muted)
1250 snd_azf3328_mixer_set_mute( 1631 snd_azf3328_mixer_mute_control_pcm(
1251 chip, IDX_MIXER_WAVEOUT, 0 1632 chip, 0
1252 ); 1633 );
1253 } 1634 }
1254 1635
@@ -1257,27 +1638,27 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1257 case SNDRV_PCM_TRIGGER_RESUME: 1638 case SNDRV_PCM_TRIGGER_RESUME:
1258 snd_azf3328_dbgcodec("RESUME %s\n", codec->name); 1639 snd_azf3328_dbgcodec("RESUME %s\n", codec->name);
1259 /* resume codec if we were active */ 1640 /* resume codec if we were active */
1260 spin_lock(&chip->reg_lock); 1641 spin_lock(codec->lock);
1261 if (codec->running) 1642 if (codec->running)
1262 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, 1643 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1263 snd_azf3328_codec_inw( 1644 snd_azf3328_codec_inw(
1264 codec, IDX_IO_CODEC_DMA_FLAGS 1645 codec, IDX_IO_CODEC_DMA_FLAGS
1265 ) | DMA_RESUME 1646 ) | DMA_RESUME
1266 ); 1647 );
1267 spin_unlock(&chip->reg_lock); 1648 spin_unlock(codec->lock);
1268 break; 1649 break;
1269 case SNDRV_PCM_TRIGGER_STOP: 1650 case SNDRV_PCM_TRIGGER_STOP:
1270 snd_azf3328_dbgcodec("STOP %s\n", codec->name); 1651 snd_azf3328_dbgcodec("STOP %s\n", codec->name);
1271 1652
1272 if (is_playback_codec) { 1653 if (is_main_mixer_playback_codec) {
1273 /* mute WaveOut (avoid clicking during setup) */ 1654 /* mute WaveOut (avoid clicking during setup) */
1274 previously_muted = 1655 previously_muted =
1275 snd_azf3328_mixer_set_mute( 1656 snd_azf3328_mixer_mute_control_pcm(
1276 chip, IDX_MIXER_WAVEOUT, 1 1657 chip, 1
1277 ); 1658 );
1278 } 1659 }
1279 1660
1280 spin_lock(&chip->reg_lock); 1661 spin_lock(codec->lock);
1281 /* first, remember current value: */ 1662 /* first, remember current value: */
1282 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS); 1663 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1283 1664
@@ -1292,14 +1673,14 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1292 1673
1293 flags1 &= ~DMA_RUN_SOMETHING1; 1674 flags1 &= ~DMA_RUN_SOMETHING1;
1294 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1); 1675 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1295 spin_unlock(&chip->reg_lock); 1676 spin_unlock(codec->lock);
1296 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0); 1677 snd_azf3328_ctrl_codec_activity(chip, codec->type, 0);
1297 1678
1298 if (is_playback_codec) { 1679 if (is_main_mixer_playback_codec) {
1299 /* now unmute WaveOut */ 1680 /* now unmute WaveOut */
1300 if (!previously_muted) 1681 if (!previously_muted)
1301 snd_azf3328_mixer_set_mute( 1682 snd_azf3328_mixer_mute_control_pcm(
1302 chip, IDX_MIXER_WAVEOUT, 0 1683 chip, 0
1303 ); 1684 );
1304 } 1685 }
1305 1686
@@ -1329,67 +1710,29 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1329 return result; 1710 return result;
1330} 1711}
1331 1712
1332static int
1333snd_azf3328_codec_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1334{
1335 return snd_azf3328_codec_trigger(AZF_CODEC_PLAYBACK, substream, cmd);
1336}
1337
1338static int
1339snd_azf3328_codec_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1340{
1341 return snd_azf3328_codec_trigger(AZF_CODEC_CAPTURE, substream, cmd);
1342}
1343
1344static int
1345snd_azf3328_codec_i2s_out_trigger(struct snd_pcm_substream *substream, int cmd)
1346{
1347 return snd_azf3328_codec_trigger(AZF_CODEC_I2S_OUT, substream, cmd);
1348}
1349
1350static snd_pcm_uframes_t 1713static snd_pcm_uframes_t
1351snd_azf3328_codec_pointer(struct snd_pcm_substream *substream, 1714snd_azf3328_pcm_pointer(struct snd_pcm_substream *substream
1352 enum snd_azf3328_codec_type codec_type
1353) 1715)
1354{ 1716{
1355 const struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1717 const struct snd_azf3328_codec_data *codec =
1356 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; 1718 substream->runtime->private_data;
1357 unsigned long bufptr, result; 1719 unsigned long result;
1358 snd_pcm_uframes_t frmres; 1720 snd_pcm_uframes_t frmres;
1359 1721
1360#ifdef QUERY_HARDWARE
1361 bufptr = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
1362#else
1363 bufptr = substream->runtime->dma_addr;
1364#endif
1365 result = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_CURRPOS); 1722 result = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_CURRPOS);
1366 1723
1367 /* calculate offset */ 1724 /* calculate offset */
1368 result -= bufptr; 1725#ifdef QUERY_HARDWARE
1726 result -= snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
1727#else
1728 result -= codec->dma_base;
1729#endif
1369 frmres = bytes_to_frames( substream->runtime, result); 1730 frmres = bytes_to_frames( substream->runtime, result);
1370 snd_azf3328_dbgcodec("%s @ 0x%8lx, frames %8ld\n", 1731 snd_azf3328_dbgcodec("%08li %s @ 0x%8lx, frames %8ld\n",
1371 codec->name, result, frmres); 1732 jiffies, codec->name, result, frmres);
1372 return frmres; 1733 return frmres;
1373} 1734}
1374 1735
1375static snd_pcm_uframes_t
1376snd_azf3328_codec_playback_pointer(struct snd_pcm_substream *substream)
1377{
1378 return snd_azf3328_codec_pointer(substream, AZF_CODEC_PLAYBACK);
1379}
1380
1381static snd_pcm_uframes_t
1382snd_azf3328_codec_capture_pointer(struct snd_pcm_substream *substream)
1383{
1384 return snd_azf3328_codec_pointer(substream, AZF_CODEC_CAPTURE);
1385}
1386
1387static snd_pcm_uframes_t
1388snd_azf3328_codec_i2s_out_pointer(struct snd_pcm_substream *substream)
1389{
1390 return snd_azf3328_codec_pointer(substream, AZF_CODEC_I2S_OUT);
1391}
1392
1393/******************************************************************/ 1736/******************************************************************/
1394 1737
1395#ifdef SUPPORT_GAMEPORT 1738#ifdef SUPPORT_GAMEPORT
@@ -1531,7 +1874,7 @@ snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1531 } 1874 }
1532 } 1875 }
1533 1876
1534 /* trigger next axes sampling, to be evaluated the next time we 1877 /* trigger next sampling of axes, to be evaluated the next time we
1535 * enter this function */ 1878 * enter this function */
1536 1879
1537 /* for some very, very strange reason we cannot enable 1880 /* for some very, very strange reason we cannot enable
@@ -1623,29 +1966,29 @@ snd_azf3328_irq_log_unknown_type(u8 which)
1623} 1966}
1624 1967
1625static inline void 1968static inline void
1626snd_azf3328_codec_interrupt(struct snd_azf3328 *chip, u8 status) 1969snd_azf3328_pcm_interrupt(const struct snd_azf3328_codec_data *first_codec,
1970 u8 status
1971)
1627{ 1972{
1628 u8 which; 1973 u8 which;
1629 enum snd_azf3328_codec_type codec_type; 1974 enum snd_azf3328_codec_type codec_type;
1630 const struct snd_azf3328_codec_data *codec; 1975 const struct snd_azf3328_codec_data *codec = first_codec;
1631 1976
1632 for (codec_type = AZF_CODEC_PLAYBACK; 1977 for (codec_type = AZF_CODEC_PLAYBACK;
1633 codec_type <= AZF_CODEC_I2S_OUT; 1978 codec_type <= AZF_CODEC_I2S_OUT;
1634 ++codec_type) { 1979 ++codec_type, ++codec) {
1635 1980
1636 /* skip codec if there's no interrupt for it */ 1981 /* skip codec if there's no interrupt for it */
1637 if (!(status & (1 << codec_type))) 1982 if (!(status & (1 << codec_type)))
1638 continue; 1983 continue;
1639 1984
1640 codec = &chip->codecs[codec_type]; 1985 spin_lock(codec->lock);
1641
1642 spin_lock(&chip->reg_lock);
1643 which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE); 1986 which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE);
1644 /* ack all IRQ types immediately */ 1987 /* ack all IRQ types immediately */
1645 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which); 1988 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which);
1646 spin_unlock(&chip->reg_lock); 1989 spin_unlock(codec->lock);
1647 1990
1648 if ((chip->pcm[codec_type]) && (codec->substream)) { 1991 if (codec->substream) {
1649 snd_pcm_period_elapsed(codec->substream); 1992 snd_pcm_period_elapsed(codec->substream);
1650 snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n", 1993 snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n",
1651 codec->name, 1994 codec->name,
@@ -1700,7 +2043,7 @@ snd_azf3328_interrupt(int irq, void *dev_id)
1700 } 2043 }
1701 2044
1702 if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT)) 2045 if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT))
1703 snd_azf3328_codec_interrupt(chip, status); 2046 snd_azf3328_pcm_interrupt(chip->codecs, status);
1704 2047
1705 if (status & IRQ_GAMEPORT) 2048 if (status & IRQ_GAMEPORT)
1706 snd_azf3328_gameport_interrupt(chip); 2049 snd_azf3328_gameport_interrupt(chip);
@@ -1740,11 +2083,15 @@ static const struct snd_pcm_hardware snd_azf3328_hardware =
1740 .rate_max = AZF_FREQ_66200, 2083 .rate_max = AZF_FREQ_66200,
1741 .channels_min = 1, 2084 .channels_min = 1,
1742 .channels_max = 2, 2085 .channels_max = 2,
1743 .buffer_bytes_max = 65536, 2086 .buffer_bytes_max = (64*1024),
1744 .period_bytes_min = 64, 2087 .period_bytes_min = 1024,
1745 .period_bytes_max = 65536, 2088 .period_bytes_max = (32*1024),
1746 .periods_min = 1, 2089 /* We simply have two DMA areas (instead of a list of descriptors
1747 .periods_max = 1024, 2090 such as other cards); I believe that this is a fixed hardware
2091 attribute and there isn't much driver magic to be done to expand it.
2092 Thus indicate that we have at least and at most 2 periods. */
2093 .periods_min = 2,
2094 .periods_max = 2,
1748 /* FIXME: maybe that card actually has a FIFO? 2095 /* FIXME: maybe that card actually has a FIFO?
1749 * Hmm, it seems newer revisions do have one, but we still don't know 2096 * Hmm, it seems newer revisions do have one, but we still don't know
1750 * its size... */ 2097 * its size... */
@@ -1784,101 +2131,85 @@ snd_azf3328_pcm_open(struct snd_pcm_substream *substream,
1784{ 2131{
1785 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 2132 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1786 struct snd_pcm_runtime *runtime = substream->runtime; 2133 struct snd_pcm_runtime *runtime = substream->runtime;
2134 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1787 2135
1788 snd_azf3328_dbgcallenter(); 2136 snd_azf3328_dbgcallenter();
1789 chip->codecs[codec_type].substream = substream; 2137 codec->substream = substream;
1790 2138
1791 /* same parameters for all our codecs - at least we think so... */ 2139 /* same parameters for all our codecs - at least we think so... */
1792 runtime->hw = snd_azf3328_hardware; 2140 runtime->hw = snd_azf3328_hardware;
1793 2141
1794 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 2142 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1795 &snd_azf3328_hw_constraints_rates); 2143 &snd_azf3328_hw_constraints_rates);
2144 runtime->private_data = codec;
1796 snd_azf3328_dbgcallleave(); 2145 snd_azf3328_dbgcallleave();
1797 return 0; 2146 return 0;
1798} 2147}
1799 2148
1800static int 2149static int
1801snd_azf3328_playback_open(struct snd_pcm_substream *substream) 2150snd_azf3328_pcm_playback_open(struct snd_pcm_substream *substream)
1802{ 2151{
1803 return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK); 2152 return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK);
1804} 2153}
1805 2154
1806static int 2155static int
1807snd_azf3328_capture_open(struct snd_pcm_substream *substream) 2156snd_azf3328_pcm_capture_open(struct snd_pcm_substream *substream)
1808{ 2157{
1809 return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE); 2158 return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE);
1810} 2159}
1811 2160
1812static int 2161static int
1813snd_azf3328_i2s_out_open(struct snd_pcm_substream *substream) 2162snd_azf3328_pcm_i2s_out_open(struct snd_pcm_substream *substream)
1814{ 2163{
1815 return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT); 2164 return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT);
1816} 2165}
1817 2166
1818static int 2167static int
1819snd_azf3328_pcm_close(struct snd_pcm_substream *substream, 2168snd_azf3328_pcm_close(struct snd_pcm_substream *substream
1820 enum snd_azf3328_codec_type codec_type
1821) 2169)
1822{ 2170{
1823 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 2171 struct snd_azf3328_codec_data *codec =
2172 substream->runtime->private_data;
1824 2173
1825 snd_azf3328_dbgcallenter(); 2174 snd_azf3328_dbgcallenter();
1826 chip->codecs[codec_type].substream = NULL; 2175 codec->substream = NULL;
1827 snd_azf3328_dbgcallleave(); 2176 snd_azf3328_dbgcallleave();
1828 return 0; 2177 return 0;
1829} 2178}
1830 2179
1831static int
1832snd_azf3328_playback_close(struct snd_pcm_substream *substream)
1833{
1834 return snd_azf3328_pcm_close(substream, AZF_CODEC_PLAYBACK);
1835}
1836
1837static int
1838snd_azf3328_capture_close(struct snd_pcm_substream *substream)
1839{
1840 return snd_azf3328_pcm_close(substream, AZF_CODEC_CAPTURE);
1841}
1842
1843static int
1844snd_azf3328_i2s_out_close(struct snd_pcm_substream *substream)
1845{
1846 return snd_azf3328_pcm_close(substream, AZF_CODEC_I2S_OUT);
1847}
1848
1849/******************************************************************/ 2180/******************************************************************/
1850 2181
1851static struct snd_pcm_ops snd_azf3328_playback_ops = { 2182static struct snd_pcm_ops snd_azf3328_playback_ops = {
1852 .open = snd_azf3328_playback_open, 2183 .open = snd_azf3328_pcm_playback_open,
1853 .close = snd_azf3328_playback_close, 2184 .close = snd_azf3328_pcm_close,
1854 .ioctl = snd_pcm_lib_ioctl, 2185 .ioctl = snd_pcm_lib_ioctl,
1855 .hw_params = snd_azf3328_hw_params, 2186 .hw_params = snd_azf3328_hw_params,
1856 .hw_free = snd_azf3328_hw_free, 2187 .hw_free = snd_azf3328_hw_free,
1857 .prepare = snd_azf3328_codec_prepare, 2188 .prepare = snd_azf3328_pcm_prepare,
1858 .trigger = snd_azf3328_codec_playback_trigger, 2189 .trigger = snd_azf3328_pcm_trigger,
1859 .pointer = snd_azf3328_codec_playback_pointer 2190 .pointer = snd_azf3328_pcm_pointer
1860}; 2191};
1861 2192
1862static struct snd_pcm_ops snd_azf3328_capture_ops = { 2193static struct snd_pcm_ops snd_azf3328_capture_ops = {
1863 .open = snd_azf3328_capture_open, 2194 .open = snd_azf3328_pcm_capture_open,
1864 .close = snd_azf3328_capture_close, 2195 .close = snd_azf3328_pcm_close,
1865 .ioctl = snd_pcm_lib_ioctl, 2196 .ioctl = snd_pcm_lib_ioctl,
1866 .hw_params = snd_azf3328_hw_params, 2197 .hw_params = snd_azf3328_hw_params,
1867 .hw_free = snd_azf3328_hw_free, 2198 .hw_free = snd_azf3328_hw_free,
1868 .prepare = snd_azf3328_codec_prepare, 2199 .prepare = snd_azf3328_pcm_prepare,
1869 .trigger = snd_azf3328_codec_capture_trigger, 2200 .trigger = snd_azf3328_pcm_trigger,
1870 .pointer = snd_azf3328_codec_capture_pointer 2201 .pointer = snd_azf3328_pcm_pointer
1871}; 2202};
1872 2203
1873static struct snd_pcm_ops snd_azf3328_i2s_out_ops = { 2204static struct snd_pcm_ops snd_azf3328_i2s_out_ops = {
1874 .open = snd_azf3328_i2s_out_open, 2205 .open = snd_azf3328_pcm_i2s_out_open,
1875 .close = snd_azf3328_i2s_out_close, 2206 .close = snd_azf3328_pcm_close,
1876 .ioctl = snd_pcm_lib_ioctl, 2207 .ioctl = snd_pcm_lib_ioctl,
1877 .hw_params = snd_azf3328_hw_params, 2208 .hw_params = snd_azf3328_hw_params,
1878 .hw_free = snd_azf3328_hw_free, 2209 .hw_free = snd_azf3328_hw_free,
1879 .prepare = snd_azf3328_codec_prepare, 2210 .prepare = snd_azf3328_pcm_prepare,
1880 .trigger = snd_azf3328_codec_i2s_out_trigger, 2211 .trigger = snd_azf3328_pcm_trigger,
1881 .pointer = snd_azf3328_codec_i2s_out_pointer 2212 .pointer = snd_azf3328_pcm_pointer
1882}; 2213};
1883 2214
1884static int __devinit 2215static int __devinit
@@ -1961,7 +2292,7 @@ snd_azf3328_timer_start(struct snd_timer *timer)
1961 snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay); 2292 snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
1962 delay = 49; /* minimum time is 49 ticks */ 2293 delay = 49; /* minimum time is 49 ticks */
1963 } 2294 }
1964 snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay); 2295 snd_azf3328_dbgtimer("setting timer countdown value %d\n", delay);
1965 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE; 2296 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
1966 spin_lock_irqsave(&chip->reg_lock, flags); 2297 spin_lock_irqsave(&chip->reg_lock, flags);
1967 snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay); 2298 snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay);
@@ -1980,8 +2311,13 @@ snd_azf3328_timer_stop(struct snd_timer *timer)
1980 chip = snd_timer_chip(timer); 2311 chip = snd_timer_chip(timer);
1981 spin_lock_irqsave(&chip->reg_lock, flags); 2312 spin_lock_irqsave(&chip->reg_lock, flags);
1982 /* disable timer countdown and interrupt */ 2313 /* disable timer countdown and interrupt */
1983 /* FIXME: should we write TIMER_IRQ_ACK here? */ 2314 /* Hmm, should we write TIMER_IRQ_ACK here?
1984 snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0); 2315 YES indeed, otherwise a rogue timer operation - which prompts
2316 ALSA(?) to call repeated stop() in vain, but NOT start() -
2317 will never end (value 0x03 is kept shown in control byte).
2318 Simply manually poking 0x04 _once_ immediately successfully stops
2319 the hardware/ALSA interrupt activity. */
2320 snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x04);
1985 spin_unlock_irqrestore(&chip->reg_lock, flags); 2321 spin_unlock_irqrestore(&chip->reg_lock, flags);
1986 snd_azf3328_dbgcallleave(); 2322 snd_azf3328_dbgcallleave();
1987 return 0; 2323 return 0;
@@ -2052,11 +2388,7 @@ snd_azf3328_free(struct snd_azf3328 *chip)
2052 if (chip->irq < 0) 2388 if (chip->irq < 0)
2053 goto __end_hw; 2389 goto __end_hw;
2054 2390
2055 /* reset (close) mixer: 2391 snd_azf3328_mixer_reset(chip);
2056 * first mute master volume, then reset
2057 */
2058 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
2059 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
2060 2392
2061 snd_azf3328_timer_stop(chip->timer); 2393 snd_azf3328_timer_stop(chip->timer);
2062 snd_azf3328_gameport_free(chip); 2394 snd_azf3328_gameport_free(chip);
@@ -2170,6 +2502,7 @@ snd_azf3328_create(struct snd_card *card,
2170 }; 2502 };
2171 u8 dma_init; 2503 u8 dma_init;
2172 enum snd_azf3328_codec_type codec_type; 2504 enum snd_azf3328_codec_type codec_type;
2505 struct snd_azf3328_codec_data *codec_setup;
2173 2506
2174 *rchip = NULL; 2507 *rchip = NULL;
2175 2508
@@ -2207,15 +2540,23 @@ snd_azf3328_create(struct snd_card *card,
2207 chip->opl3_io = pci_resource_start(pci, 3); 2540 chip->opl3_io = pci_resource_start(pci, 3);
2208 chip->mixer_io = pci_resource_start(pci, 4); 2541 chip->mixer_io = pci_resource_start(pci, 4);
2209 2542
2210 chip->codecs[AZF_CODEC_PLAYBACK].io_base = 2543 codec_setup = &chip->codecs[AZF_CODEC_PLAYBACK];
2211 chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK; 2544 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK;
2212 chip->codecs[AZF_CODEC_PLAYBACK].name = "PLAYBACK"; 2545 codec_setup->lock = &chip->reg_lock;
2213 chip->codecs[AZF_CODEC_CAPTURE].io_base = 2546 codec_setup->type = AZF_CODEC_PLAYBACK;
2214 chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE; 2547 codec_setup->name = "PLAYBACK";
2215 chip->codecs[AZF_CODEC_CAPTURE].name = "CAPTURE"; 2548
2216 chip->codecs[AZF_CODEC_I2S_OUT].io_base = 2549 codec_setup = &chip->codecs[AZF_CODEC_CAPTURE];
2217 chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT; 2550 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE;
2218 chip->codecs[AZF_CODEC_I2S_OUT].name = "I2S_OUT"; 2551 codec_setup->lock = &chip->reg_lock;
2552 codec_setup->type = AZF_CODEC_CAPTURE;
2553 codec_setup->name = "CAPTURE";
2554
2555 codec_setup = &chip->codecs[AZF_CODEC_I2S_OUT];
2556 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT;
2557 codec_setup->lock = &chip->reg_lock;
2558 codec_setup->type = AZF_CODEC_I2S_OUT;
2559 codec_setup->name = "I2S_OUT";
2219 2560
2220 if (request_irq(pci->irq, snd_azf3328_interrupt, 2561 if (request_irq(pci->irq, snd_azf3328_interrupt,
2221 IRQF_SHARED, card->shortname, chip)) { 2562 IRQF_SHARED, card->shortname, chip)) {
@@ -2247,15 +2588,15 @@ snd_azf3328_create(struct snd_card *card,
2247 struct snd_azf3328_codec_data *codec = 2588 struct snd_azf3328_codec_data *codec =
2248 &chip->codecs[codec_type]; 2589 &chip->codecs[codec_type];
2249 2590
2250 /* shutdown codecs to save power */ 2591 /* shutdown codecs to reduce power / noise */
2251 /* have ...ctrl_codec_activity() act properly */ 2592 /* have ...ctrl_codec_activity() act properly */
2252 codec->running = 1; 2593 codec->running = 1;
2253 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0); 2594 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
2254 2595
2255 spin_lock_irq(&chip->reg_lock); 2596 spin_lock_irq(codec->lock);
2256 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS, 2597 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS,
2257 dma_init); 2598 dma_init);
2258 spin_unlock_irq(&chip->reg_lock); 2599 spin_unlock_irq(codec->lock);
2259 } 2600 }
2260 2601
2261 snd_card_set_dev(card, &pci->dev); 2602 snd_card_set_dev(card, &pci->dev);
@@ -2400,6 +2741,55 @@ snd_azf3328_suspend_regs(unsigned long io_addr, unsigned count, u32 *saved_regs)
2400 } 2741 }
2401} 2742}
2402 2743
2744static inline void
2745snd_azf3328_resume_regs(const u32 *saved_regs,
2746 unsigned long io_addr,
2747 unsigned count
2748)
2749{
2750 unsigned reg;
2751
2752 for (reg = 0; reg < count; ++reg) {
2753 outl(*saved_regs, io_addr);
2754 snd_azf3328_dbgpm("resume: io 0x%04lx: 0x%08x --> 0x%08x\n",
2755 io_addr, *saved_regs, inl(io_addr));
2756 ++saved_regs;
2757 io_addr += sizeof(*saved_regs);
2758 }
2759}
2760
2761static inline void
2762snd_azf3328_suspend_ac97(struct snd_azf3328 *chip)
2763{
2764#ifdef AZF_USE_AC97_LAYER
2765 snd_ac97_suspend(chip->ac97);
2766#else
2767 snd_azf3328_suspend_regs(chip->mixer_io,
2768 ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer);
2769
2770 /* make sure to disable master volume etc. to prevent looping sound */
2771 snd_azf3328_mixer_mute_control_master(chip, 1);
2772 snd_azf3328_mixer_mute_control_pcm(chip, 1);
2773#endif /* AZF_USE_AC97_LAYER */
2774}
2775
2776static inline void
2777snd_azf3328_resume_ac97(const struct snd_azf3328 *chip)
2778{
2779#ifdef AZF_USE_AC97_LAYER
2780 snd_ac97_resume(chip->ac97);
2781#else
2782 snd_azf3328_resume_regs(chip->saved_regs_mixer, chip->mixer_io,
2783 ARRAY_SIZE(chip->saved_regs_mixer));
2784
2785 /* unfortunately with 32bit transfers, IDX_MIXER_PLAY_MASTER (0x02)
2786 and IDX_MIXER_RESET (offset 0x00) get touched at the same time,
2787 resulting in a mixer reset condition persisting until _after_
2788 master vol was restored. Thus master vol needs an extra restore. */
2789 outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2);
2790#endif /* AZF_USE_AC97_LAYER */
2791}
2792
2403static int 2793static int
2404snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state) 2794snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2405{ 2795{
@@ -2409,15 +2799,11 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2409 2799
2410 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2800 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2411 2801
2802 /* same pcm object for playback/capture */
2412 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]); 2803 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]);
2413 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]); 2804 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]);
2414 2805
2415 snd_azf3328_suspend_regs(chip->mixer_io, 2806 snd_azf3328_suspend_ac97(chip);
2416 ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer);
2417
2418 /* make sure to disable master volume etc. to prevent looping sound */
2419 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
2420 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
2421 2807
2422 snd_azf3328_suspend_regs(chip->ctrl_io, 2808 snd_azf3328_suspend_regs(chip->ctrl_io,
2423 ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl); 2809 ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl);
@@ -2439,23 +2825,6 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2439 return 0; 2825 return 0;
2440} 2826}
2441 2827
2442static inline void
2443snd_azf3328_resume_regs(const u32 *saved_regs,
2444 unsigned long io_addr,
2445 unsigned count
2446)
2447{
2448 unsigned reg;
2449
2450 for (reg = 0; reg < count; ++reg) {
2451 outl(*saved_regs, io_addr);
2452 snd_azf3328_dbgpm("resume: io 0x%04lx: 0x%08x --> 0x%08x\n",
2453 io_addr, *saved_regs, inl(io_addr));
2454 ++saved_regs;
2455 io_addr += sizeof(*saved_regs);
2456 }
2457}
2458
2459static int 2828static int
2460snd_azf3328_resume(struct pci_dev *pci) 2829snd_azf3328_resume(struct pci_dev *pci)
2461{ 2830{
@@ -2479,14 +2848,7 @@ snd_azf3328_resume(struct pci_dev *pci)
2479 snd_azf3328_resume_regs(chip->saved_regs_opl3, chip->opl3_io, 2848 snd_azf3328_resume_regs(chip->saved_regs_opl3, chip->opl3_io,
2480 ARRAY_SIZE(chip->saved_regs_opl3)); 2849 ARRAY_SIZE(chip->saved_regs_opl3));
2481 2850
2482 snd_azf3328_resume_regs(chip->saved_regs_mixer, chip->mixer_io, 2851 snd_azf3328_resume_ac97(chip);
2483 ARRAY_SIZE(chip->saved_regs_mixer));
2484
2485 /* unfortunately with 32bit transfers, IDX_MIXER_PLAY_MASTER (0x02)
2486 and IDX_MIXER_RESET (offset 0x00) get touched at the same time,
2487 resulting in a mixer reset condition persisting until _after_
2488 master vol was restored. Thus master vol needs an extra restore. */
2489 outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2);
2490 2852
2491 snd_azf3328_resume_regs(chip->saved_regs_ctrl, chip->ctrl_io, 2853 snd_azf3328_resume_regs(chip->saved_regs_ctrl, chip->ctrl_io,
2492 ARRAY_SIZE(chip->saved_regs_ctrl)); 2854 ARRAY_SIZE(chip->saved_regs_ctrl));
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 37e1b5df5ab8..2958a05b5293 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -637,15 +637,9 @@ static struct snd_kcontrol_new snd_bt87x_capture_boost = {
637static int snd_bt87x_capture_source_info(struct snd_kcontrol *kcontrol, 637static int snd_bt87x_capture_source_info(struct snd_kcontrol *kcontrol,
638 struct snd_ctl_elem_info *info) 638 struct snd_ctl_elem_info *info)
639{ 639{
640 static char *texts[3] = {"TV Tuner", "FM", "Mic/Line"}; 640 static const char *const texts[3] = {"TV Tuner", "FM", "Mic/Line"};
641 641
642 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 642 return snd_ctl_enum_info(info, 1, 3, texts);
643 info->count = 1;
644 info->value.enumerated.items = 3;
645 if (info->value.enumerated.item > 2)
646 info->value.enumerated.item = 2;
647 strcpy(info->value.enumerated.name, texts[info->value.enumerated.item]);
648 return 0;
649} 643}
650 644
651static int snd_bt87x_capture_source_get(struct snd_kcontrol *kcontrol, 645static int snd_bt87x_capture_source_get(struct snd_kcontrol *kcontrol,
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index 14b8d9a91aae..e8e8ccc96403 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -51,7 +51,7 @@
51 * Add support for mute control on SB Live 24bit (cards w/ SPI DAC) 51 * Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
52 * 52 *
53 * 53 *
54 * This code was initally based on code from ALSA's emu10k1x.c which is: 54 * This code was initially based on code from ALSA's emu10k1x.c which is:
55 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com> 55 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
56 * 56 *
57 * This program is free software; you can redistribute it and/or modify 57 * This program is free software; you can redistribute it and/or modify
@@ -175,7 +175,7 @@
175/* CA0106 pointer-offset register set, accessed through the PTR and DATA registers */ 175/* CA0106 pointer-offset register set, accessed through the PTR and DATA registers */
176/********************************************************************************************************/ 176/********************************************************************************************************/
177 177
178/* Initally all registers from 0x00 to 0x3f have zero contents. */ 178/* Initially all registers from 0x00 to 0x3f have zero contents. */
179#define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */ 179#define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */
180 /* One list entry: 4 bytes for DMA address, 180 /* One list entry: 4 bytes for DMA address,
181 * 4 bytes for period_size << 16. 181 * 4 bytes for period_size << 16.
@@ -188,7 +188,7 @@
188#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */ 188#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
189 /* PTR[5:0], Default: 0x0 */ 189 /* PTR[5:0], Default: 0x0 */
190#define PLAYBACK_UNKNOWN3 0x03 /* Not used ?? */ 190#define PLAYBACK_UNKNOWN3 0x03 /* Not used ?? */
191#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */ 191#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */
192 /* DMA[31:0], Default: 0x0 */ 192 /* DMA[31:0], Default: 0x0 */
193#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */ 193#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */
194 /* SIZE[31:16], Default: 0x0 */ 194 /* SIZE[31:16], Default: 0x0 */
@@ -223,7 +223,7 @@
223 * The jack has 4 poles. I will call 1 - Tip, 2 - Next to 1, 3 - Next to 2, 4 - Next to 3 223 * The jack has 4 poles. I will call 1 - Tip, 2 - Next to 1, 3 - Next to 2, 4 - Next to 3
224 * For Analogue: 1 -> Center Speaker, 2 -> Sub Woofer, 3 -> Ground, 4 -> Ground 224 * For Analogue: 1 -> Center Speaker, 2 -> Sub Woofer, 3 -> Ground, 4 -> Ground
225 * For Digital: 1 -> Front SPDIF, 2 -> Rear SPDIF, 3 -> Center/Subwoofer SPDIF, 4 -> Ground. 225 * For Digital: 1 -> Front SPDIF, 2 -> Rear SPDIF, 3 -> Center/Subwoofer SPDIF, 4 -> Ground.
226 * Standard 4 pole Video A/V cable with RCA outputs: 1 -> White, 2 -> Yellow, 3 -> Sheild on all three, 4 -> Red. 226 * Standard 4 pole Video A/V cable with RCA outputs: 1 -> White, 2 -> Yellow, 3 -> Shield on all three, 4 -> Red.
227 * So, from this you can see that you cannot use a Standard 4 pole Video A/V cable with the SB Audigy LS card. 227 * So, from this you can see that you cannot use a Standard 4 pole Video A/V cable with the SB Audigy LS card.
228 */ 228 */
229/* The Front SPDIF PCM gets mixed with samples from the AC97 codec, so can only work for Stereo PCM and not AC3/DTS 229/* The Front SPDIF PCM gets mixed with samples from the AC97 codec, so can only work for Stereo PCM and not AC3/DTS
@@ -670,8 +670,9 @@ struct snd_ca0106_details {
670 gpio_type = 2 -> shared side-out/line-in. */ 670 gpio_type = 2 -> shared side-out/line-in. */
671 int i2c_adc; /* with i2c_adc=1, the driver adds some capture volume 671 int i2c_adc; /* with i2c_adc=1, the driver adds some capture volume
672 controls, phone, mic, line-in and aux. */ 672 controls, phone, mic, line-in and aux. */
673 int spi_dac; /* spi_dac=1 adds the mute switch for each analog 673 u16 spi_dac; /* spi_dac = 0 -> no spi interface for DACs
674 output, front, rear, etc. */ 674 spi_dac = 0x<front><rear><center-lfe><side>
675 -> specifies DAC id for each channel pair. */
675}; 676};
676 677
677// definition of the chip-specific record 678// definition of the chip-specific record
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 0a3d3d6e77b4..437759239694 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -117,7 +117,7 @@
117 * DAC: Unknown 117 * DAC: Unknown
118 * Trying to handle it like the SB0410. 118 * Trying to handle it like the SB0410.
119 * 119 *
120 * This code was initally based on code from ALSA's emu10k1x.c which is: 120 * This code was initially based on code from ALSA's emu10k1x.c which is:
121 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com> 121 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
122 * 122 *
123 * This program is free software; you can redistribute it and/or modify 123 * This program is free software; you can redistribute it and/or modify
@@ -227,7 +227,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
227 .name = "Audigy SE [SB0570]", 227 .name = "Audigy SE [SB0570]",
228 .gpio_type = 1, 228 .gpio_type = 1,
229 .i2c_adc = 1, 229 .i2c_adc = 1,
230 .spi_dac = 1 } , 230 .spi_dac = 0x4021 } ,
231 /* New Audigy LS. Has a different DAC. */ 231 /* New Audigy LS. Has a different DAC. */
232 /* SB0570: 232 /* SB0570:
233 * CTRL:CA0106-DAT 233 * CTRL:CA0106-DAT
@@ -238,7 +238,17 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
238 .name = "Audigy SE OEM [SB0570a]", 238 .name = "Audigy SE OEM [SB0570a]",
239 .gpio_type = 1, 239 .gpio_type = 1,
240 .i2c_adc = 1, 240 .i2c_adc = 1,
241 .spi_dac = 1 } , 241 .spi_dac = 0x4021 } ,
242 /* Sound Blaster 5.1vx
243 * Tested: Playback on front, rear, center/lfe speakers
244 * Not-Tested: Capture
245 */
246 { .serial = 0x10041102,
247 .name = "Sound Blaster 5.1vx [SB1070]",
248 .gpio_type = 1,
249 .i2c_adc = 0,
250 .spi_dac = 0x0124
251 } ,
242 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */ 252 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */
243 /* SB0438 253 /* SB0438
244 * CTRL:CA0106-DAT 254 * CTRL:CA0106-DAT
@@ -254,7 +264,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
254 .name = "MSI K8N Diamond MB", 264 .name = "MSI K8N Diamond MB",
255 .gpio_type = 2, 265 .gpio_type = 2,
256 .i2c_adc = 1, 266 .i2c_adc = 1,
257 .spi_dac = 1 } , 267 .spi_dac = 0x4021 } ,
258 /* Giga-byte GA-G1975X mobo 268 /* Giga-byte GA-G1975X mobo
259 * Novell bnc#395807 269 * Novell bnc#395807
260 */ 270 */
@@ -483,16 +493,18 @@ static void snd_ca0106_pcm_free_substream(struct snd_pcm_runtime *runtime)
483} 493}
484 494
485static const int spi_dacd_reg[] = { 495static const int spi_dacd_reg[] = {
486 [PCM_FRONT_CHANNEL] = SPI_DACD4_REG, 496 SPI_DACD0_REG,
487 [PCM_REAR_CHANNEL] = SPI_DACD0_REG, 497 SPI_DACD1_REG,
488 [PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_REG, 498 SPI_DACD2_REG,
489 [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_REG, 499 0,
500 SPI_DACD4_REG,
490}; 501};
491static const int spi_dacd_bit[] = { 502static const int spi_dacd_bit[] = {
492 [PCM_FRONT_CHANNEL] = SPI_DACD4_BIT, 503 SPI_DACD0_BIT,
493 [PCM_REAR_CHANNEL] = SPI_DACD0_BIT, 504 SPI_DACD1_BIT,
494 [PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_BIT, 505 SPI_DACD2_BIT,
495 [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_BIT, 506 0,
507 SPI_DACD4_BIT,
496}; 508};
497 509
498static void restore_spdif_bits(struct snd_ca0106 *chip, int idx) 510static void restore_spdif_bits(struct snd_ca0106 *chip, int idx)
@@ -504,6 +516,45 @@ static void restore_spdif_bits(struct snd_ca0106 *chip, int idx)
504 } 516 }
505} 517}
506 518
519static int snd_ca0106_channel_dac(struct snd_ca0106_details *details,
520 int channel_id)
521{
522 switch (channel_id) {
523 case PCM_FRONT_CHANNEL:
524 return (details->spi_dac & 0xf000) >> (4 * 3);
525 case PCM_REAR_CHANNEL:
526 return (details->spi_dac & 0x0f00) >> (4 * 2);
527 case PCM_CENTER_LFE_CHANNEL:
528 return (details->spi_dac & 0x00f0) >> (4 * 1);
529 case PCM_UNKNOWN_CHANNEL:
530 return (details->spi_dac & 0x000f) >> (4 * 0);
531 default:
532 snd_printk(KERN_DEBUG "ca0106: unknown channel_id %d\n",
533 channel_id);
534 }
535 return 0;
536}
537
538static int snd_ca0106_pcm_power_dac(struct snd_ca0106 *chip, int channel_id,
539 int power)
540{
541 if (chip->details->spi_dac) {
542 const int dac = snd_ca0106_channel_dac(chip->details,
543 channel_id);
544 const int reg = spi_dacd_reg[dac];
545 const int bit = spi_dacd_bit[dac];
546
547 if (power)
548 /* Power up */
549 chip->spi_dac_reg[reg] &= ~bit;
550 else
551 /* Power down */
552 chip->spi_dac_reg[reg] |= bit;
553 return snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]);
554 }
555 return 0;
556}
557
507/* open_playback callback */ 558/* open_playback callback */
508static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream, 559static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream,
509 int channel_id) 560 int channel_id)
@@ -543,12 +594,9 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr
543 return err; 594 return err;
544 snd_pcm_set_sync(substream); 595 snd_pcm_set_sync(substream);
545 596
546 if (chip->details->spi_dac && channel_id != PCM_FRONT_CHANNEL) { 597 /* Front channel dac should already be on */
547 const int reg = spi_dacd_reg[channel_id]; 598 if (channel_id != PCM_FRONT_CHANNEL) {
548 599 err = snd_ca0106_pcm_power_dac(chip, channel_id, 1);
549 /* Power up dac */
550 chip->spi_dac_reg[reg] &= ~spi_dacd_bit[channel_id];
551 err = snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]);
552 if (err < 0) 600 if (err < 0)
553 return err; 601 return err;
554 } 602 }
@@ -568,13 +616,14 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream)
568 616
569 restore_spdif_bits(chip, epcm->channel_id); 617 restore_spdif_bits(chip, epcm->channel_id);
570 618
571 if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) { 619 /* Front channel dac should stay on */
572 const int reg = spi_dacd_reg[epcm->channel_id]; 620 if (epcm->channel_id != PCM_FRONT_CHANNEL) {
573 621 int err;
574 /* Power down DAC */ 622 err = snd_ca0106_pcm_power_dac(chip, epcm->channel_id, 0);
575 chip->spi_dac_reg[reg] |= spi_dacd_bit[epcm->channel_id]; 623 if (err < 0)
576 snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]); 624 return err;
577 } 625 }
626
578 /* FIXME: maybe zero others */ 627 /* FIXME: maybe zero others */
579 return 0; 628 return 0;
580} 629}
@@ -1002,29 +1051,27 @@ snd_ca0106_pcm_pointer_playback(struct snd_pcm_substream *substream)
1002 struct snd_ca0106 *emu = snd_pcm_substream_chip(substream); 1051 struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
1003 struct snd_pcm_runtime *runtime = substream->runtime; 1052 struct snd_pcm_runtime *runtime = substream->runtime;
1004 struct snd_ca0106_pcm *epcm = runtime->private_data; 1053 struct snd_ca0106_pcm *epcm = runtime->private_data;
1005 snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0; 1054 unsigned int ptr, prev_ptr;
1006 int channel = epcm->channel_id; 1055 int channel = epcm->channel_id;
1056 int timeout = 10;
1007 1057
1008 if (!epcm->running) 1058 if (!epcm->running)
1009 return 0; 1059 return 0;
1010 1060
1011 ptr3 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel); 1061 prev_ptr = -1;
1012 ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel); 1062 do {
1013 ptr4 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel); 1063 ptr = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
1014 if (ptr3 != ptr4) ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel); 1064 ptr = (ptr >> 3) * runtime->period_size;
1015 ptr2 = bytes_to_frames(runtime, ptr1); 1065 ptr += bytes_to_frames(runtime,
1016 ptr2+= (ptr4 >> 3) * runtime->period_size; 1066 snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel));
1017 ptr=ptr2; 1067 if (ptr >= runtime->buffer_size)
1018 if (ptr >= runtime->buffer_size) 1068 ptr -= runtime->buffer_size;
1019 ptr -= runtime->buffer_size; 1069 if (prev_ptr == ptr)
1020 /* 1070 return ptr;
1021 printk(KERN_DEBUG "ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, " 1071 prev_ptr = ptr;
1022 "buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", 1072 } while (--timeout);
1023 ptr1, ptr2, ptr, (int)runtime->buffer_size, 1073 snd_printk(KERN_WARNING "ca0106: unstable DMA pointer!\n");
1024 (int)runtime->period_size, (int)runtime->frame_bits, 1074 return 0;
1025 (int)runtime->rate);
1026 */
1027 return ptr;
1028} 1075}
1029 1076
1030/* pointer_capture callback */ 1077/* pointer_capture callback */
@@ -1035,7 +1082,7 @@ snd_ca0106_pcm_pointer_capture(struct snd_pcm_substream *substream)
1035 struct snd_pcm_runtime *runtime = substream->runtime; 1082 struct snd_pcm_runtime *runtime = substream->runtime;
1036 struct snd_ca0106_pcm *epcm = runtime->private_data; 1083 struct snd_ca0106_pcm *epcm = runtime->private_data;
1037 snd_pcm_uframes_t ptr, ptr1, ptr2 = 0; 1084 snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
1038 int channel = channel=epcm->channel_id; 1085 int channel = epcm->channel_id;
1039 1086
1040 if (!epcm->running) 1087 if (!epcm->running)
1041 return 0; 1088 return 0;
@@ -1362,7 +1409,7 @@ static unsigned int spi_dac_init[] = {
1362 SPI_REG(12, 0x00), 1409 SPI_REG(12, 0x00),
1363 SPI_REG(SPI_LDA4_REG, SPI_DA_BIT_0dB), 1410 SPI_REG(SPI_LDA4_REG, SPI_DA_BIT_0dB),
1364 SPI_REG(SPI_RDA4_REG, SPI_DA_BIT_0dB | SPI_DA_BIT_UPDATE), 1411 SPI_REG(SPI_RDA4_REG, SPI_DA_BIT_0dB | SPI_DA_BIT_UPDATE),
1365 SPI_REG(SPI_DACD4_REG, 0x00), 1412 SPI_REG(SPI_DACD4_REG, SPI_DACD4_BIT),
1366}; 1413};
1367 1414
1368static unsigned int i2c_adc_init[][2] = { 1415static unsigned int i2c_adc_init[][2] = {
@@ -1541,7 +1588,7 @@ static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
1541 /* snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); */ 1588 /* snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); */
1542 } 1589 }
1543 1590
1544 if (chip->details->spi_dac == 1) { 1591 if (chip->details->spi_dac) {
1545 /* The SB0570 use SPI to control DAC. */ 1592 /* The SB0570 use SPI to control DAC. */
1546 int size, n; 1593 int size, n;
1547 1594
@@ -1553,6 +1600,9 @@ static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
1553 if (reg < ARRAY_SIZE(chip->spi_dac_reg)) 1600 if (reg < ARRAY_SIZE(chip->spi_dac_reg))
1554 chip->spi_dac_reg[reg] = spi_dac_init[n]; 1601 chip->spi_dac_reg[reg] = spi_dac_init[n];
1555 } 1602 }
1603
1604 /* Enable front dac only */
1605 snd_ca0106_pcm_power_dac(chip, PCM_FRONT_CHANNEL, 1);
1556 } 1606 }
1557} 1607}
1558 1608
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 85fd315d9999..84f3f92436b5 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -42,7 +42,7 @@
42 * 0.0.18 42 * 0.0.18
43 * Add support for mute control on SB Live 24bit (cards w/ SPI DAC) 43 * Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
44 * 44 *
45 * This code was initally based on code from ALSA's emu10k1x.c which is: 45 * This code was initially based on code from ALSA's emu10k1x.c which is:
46 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com> 46 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
47 * 47 *
48 * This program is free software; you can redistribute it and/or modify 48 * This program is free software; you can redistribute it and/or modify
@@ -676,28 +676,65 @@ static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata =
676 I2C_VOLUME("Aux Capture Volume", 3), 676 I2C_VOLUME("Aux Capture Volume", 3),
677}; 677};
678 678
679#define SPI_SWITCH(xname,reg,bit) \ 679static const int spi_dmute_reg[] = {
680{ \ 680 SPI_DMUTE0_REG,
681 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 681 SPI_DMUTE1_REG,
682 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 682 SPI_DMUTE2_REG,
683 .info = spi_mute_info, \ 683 0,
684 .get = spi_mute_get, \ 684 SPI_DMUTE4_REG,
685 .put = spi_mute_put, \ 685};
686 .private_value = (reg<<SPI_REG_SHIFT) | (bit) \ 686static const int spi_dmute_bit[] = {
687} 687 SPI_DMUTE0_BIT,
688 688 SPI_DMUTE1_BIT,
689static struct snd_kcontrol_new snd_ca0106_volume_spi_dac_ctls[] 689 SPI_DMUTE2_BIT,
690__devinitdata = { 690 0,
691 SPI_SWITCH("Analog Front Playback Switch", 691 SPI_DMUTE4_BIT,
692 SPI_DMUTE4_REG, SPI_DMUTE4_BIT),
693 SPI_SWITCH("Analog Rear Playback Switch",
694 SPI_DMUTE0_REG, SPI_DMUTE0_BIT),
695 SPI_SWITCH("Analog Center/LFE Playback Switch",
696 SPI_DMUTE2_REG, SPI_DMUTE2_BIT),
697 SPI_SWITCH("Analog Side Playback Switch",
698 SPI_DMUTE1_REG, SPI_DMUTE1_BIT),
699}; 692};
700 693
694static struct snd_kcontrol_new __devinit
695snd_ca0106_volume_spi_dac_ctl(struct snd_ca0106_details *details,
696 int channel_id)
697{
698 struct snd_kcontrol_new spi_switch = {0};
699 int reg, bit;
700 int dac_id;
701
702 spi_switch.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
703 spi_switch.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
704 spi_switch.info = spi_mute_info;
705 spi_switch.get = spi_mute_get;
706 spi_switch.put = spi_mute_put;
707
708 switch (channel_id) {
709 case PCM_FRONT_CHANNEL:
710 spi_switch.name = "Analog Front Playback Switch";
711 dac_id = (details->spi_dac & 0xf000) >> (4 * 3);
712 break;
713 case PCM_REAR_CHANNEL:
714 spi_switch.name = "Analog Rear Playback Switch";
715 dac_id = (details->spi_dac & 0x0f00) >> (4 * 2);
716 break;
717 case PCM_CENTER_LFE_CHANNEL:
718 spi_switch.name = "Analog Center/LFE Playback Switch";
719 dac_id = (details->spi_dac & 0x00f0) >> (4 * 1);
720 break;
721 case PCM_UNKNOWN_CHANNEL:
722 spi_switch.name = "Analog Side Playback Switch";
723 dac_id = (details->spi_dac & 0x000f) >> (4 * 0);
724 break;
725 default:
726 /* Unused channel */
727 spi_switch.name = NULL;
728 dac_id = 0;
729 }
730 reg = spi_dmute_reg[dac_id];
731 bit = spi_dmute_bit[dac_id];
732
733 spi_switch.private_value = (reg << SPI_REG_SHIFT) | bit;
734
735 return spi_switch;
736}
737
701static int __devinit remove_ctl(struct snd_card *card, const char *name) 738static int __devinit remove_ctl(struct snd_card *card, const char *name)
702{ 739{
703 struct snd_ctl_elem_id id; 740 struct snd_ctl_elem_id id;
@@ -832,8 +869,18 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
832 if (err < 0) 869 if (err < 0)
833 return err; 870 return err;
834 } 871 }
835 if (emu->details->spi_dac == 1) 872 if (emu->details->spi_dac) {
836 ADD_CTLS(emu, snd_ca0106_volume_spi_dac_ctls); 873 int i;
874 for (i = 0;; i++) {
875 struct snd_kcontrol_new ctl;
876 ctl = snd_ca0106_volume_spi_dac_ctl(emu->details, i);
877 if (!ctl.name)
878 break;
879 err = snd_ctl_add(card, snd_ctl_new1(&ctl, emu));
880 if (err < 0)
881 return err;
882 }
883 }
837 884
838 /* Create virtual master controls */ 885 /* Create virtual master controls */
839 vmaster = snd_ctl_make_virtual_master("Master Playback Volume", 886 vmaster = snd_ctl_make_virtual_master("Master Playback Volume",
@@ -845,7 +892,7 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
845 return err; 892 return err;
846 add_slaves(card, vmaster, slave_vols); 893 add_slaves(card, vmaster, slave_vols);
847 894
848 if (emu->details->spi_dac == 1) { 895 if (emu->details->spi_dac) {
849 vmaster = snd_ctl_make_virtual_master("Master Playback Switch", 896 vmaster = snd_ctl_make_virtual_master("Master Playback Switch",
850 NULL); 897 NULL);
851 if (!vmaster) 898 if (!vmaster)
diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
index ba96428c9f4c..c694464b1168 100644
--- a/sound/pci/ca0106/ca0106_proc.c
+++ b/sound/pci/ca0106/ca0106_proc.c
@@ -42,7 +42,7 @@
42 * 0.0.18 42 * 0.0.18
43 * Implement support for Line-in capture on SB Live 24bit. 43 * Implement support for Line-in capture on SB Live 24bit.
44 * 44 *
45 * This code was initally based on code from ALSA's emu10k1x.c which is: 45 * This code was initially based on code from ALSA's emu10k1x.c which is:
46 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com> 46 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
47 * 47 *
48 * This program is free software; you can redistribute it and/or modify 48 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 329968edca9b..f4e573555da3 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -73,7 +73,7 @@ MODULE_PARM_DESC(mpu_port, "MPU-401 port.");
73module_param_array(fm_port, long, NULL, 0444); 73module_param_array(fm_port, long, NULL, 0444);
74MODULE_PARM_DESC(fm_port, "FM port."); 74MODULE_PARM_DESC(fm_port, "FM port.");
75module_param_array(soft_ac3, bool, NULL, 0444); 75module_param_array(soft_ac3, bool, NULL, 0444);
76MODULE_PARM_DESC(soft_ac3, "Sofware-conversion of raw SPDIF packets (model 033 only)."); 76MODULE_PARM_DESC(soft_ac3, "Software-conversion of raw SPDIF packets (model 033 only).");
77#ifdef SUPPORT_JOYSTICK 77#ifdef SUPPORT_JOYSTICK
78module_param_array(joystick_port, int, NULL, 0444); 78module_param_array(joystick_port, int, NULL, 0444);
79MODULE_PARM_DESC(joystick_port, "Joystick port address."); 79MODULE_PARM_DESC(joystick_port, "Joystick port address.");
@@ -656,8 +656,8 @@ out:
656} 656}
657 657
658/* 658/*
659 * Program pll register bits, I assume that the 8 registers 0xf8 upto 0xff 659 * Program pll register bits, I assume that the 8 registers 0xf8 up to 0xff
660 * are mapped onto the 8 ADC/DAC sampling frequency which can be choosen 660 * are mapped onto the 8 ADC/DAC sampling frequency which can be chosen
661 * at the register CM_REG_FUNCTRL1 (0x04). 661 * at the register CM_REG_FUNCTRL1 (0x04).
662 * Problem: other ways are also possible (any information about that?) 662 * Problem: other ways are also possible (any information about that?)
663 */ 663 */
@@ -666,7 +666,7 @@ static void snd_cmipci_set_pll(struct cmipci *cm, unsigned int rate, unsigned in
666 unsigned int reg = CM_REG_PLL + slot; 666 unsigned int reg = CM_REG_PLL + slot;
667 /* 667 /*
668 * Guess that this programs at reg. 0x04 the pos 15:13/12:10 668 * Guess that this programs at reg. 0x04 the pos 15:13/12:10
669 * for DSFC/ASFC (000 upto 111). 669 * for DSFC/ASFC (000 up to 111).
670 */ 670 */
671 671
672 /* FIXME: Init (Do we've to set an other register first before programming?) */ 672 /* FIXME: Init (Do we've to set an other register first before programming?) */
@@ -2507,14 +2507,12 @@ static int snd_cmipci_line_in_mode_info(struct snd_kcontrol *kcontrol,
2507 struct snd_ctl_elem_info *uinfo) 2507 struct snd_ctl_elem_info *uinfo)
2508{ 2508{
2509 struct cmipci *cm = snd_kcontrol_chip(kcontrol); 2509 struct cmipci *cm = snd_kcontrol_chip(kcontrol);
2510 static char *texts[3] = { "Line-In", "Rear Output", "Bass Output" }; 2510 static const char *const texts[3] = {
2511 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2511 "Line-In", "Rear Output", "Bass Output"
2512 uinfo->count = 1; 2512 };
2513 uinfo->value.enumerated.items = cm->chip_version >= 39 ? 3 : 2; 2513
2514 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 2514 return snd_ctl_enum_info(uinfo, 1,
2515 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 2515 cm->chip_version >= 39 ? 3 : 2, texts);
2516 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2517 return 0;
2518} 2516}
2519 2517
2520static inline unsigned int get_line_in_mode(struct cmipci *cm) 2518static inline unsigned int get_line_in_mode(struct cmipci *cm)
@@ -2564,14 +2562,9 @@ static int snd_cmipci_line_in_mode_put(struct snd_kcontrol *kcontrol,
2564static int snd_cmipci_mic_in_mode_info(struct snd_kcontrol *kcontrol, 2562static int snd_cmipci_mic_in_mode_info(struct snd_kcontrol *kcontrol,
2565 struct snd_ctl_elem_info *uinfo) 2563 struct snd_ctl_elem_info *uinfo)
2566{ 2564{
2567 static char *texts[2] = { "Mic-In", "Center/LFE Output" }; 2565 static const char *const texts[2] = { "Mic-In", "Center/LFE Output" };
2568 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2566
2569 uinfo->count = 1; 2567 return snd_ctl_enum_info(uinfo, 1, 2, texts);
2570 uinfo->value.enumerated.items = 2;
2571 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2572 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2573 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2574 return 0;
2575} 2568}
2576 2569
2577static int snd_cmipci_mic_in_mode_get(struct snd_kcontrol *kcontrol, 2570static int snd_cmipci_mic_in_mode_get(struct snd_kcontrol *kcontrol,
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index 3e5ca8fb519f..e377287192aa 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -225,39 +225,25 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip)
225{ 225{
226 struct dsp_spos_instance * ins = kzalloc(sizeof(struct dsp_spos_instance), GFP_KERNEL); 226 struct dsp_spos_instance * ins = kzalloc(sizeof(struct dsp_spos_instance), GFP_KERNEL);
227 227
228 if (ins == NULL) 228 if (ins == NULL)
229 return NULL; 229 return NULL;
230 230
231 /* better to use vmalloc for this big table */ 231 /* better to use vmalloc for this big table */
232 ins->symbol_table.nsymbols = 0;
233 ins->symbol_table.symbols = vmalloc(sizeof(struct dsp_symbol_entry) * 232 ins->symbol_table.symbols = vmalloc(sizeof(struct dsp_symbol_entry) *
234 DSP_MAX_SYMBOLS); 233 DSP_MAX_SYMBOLS);
235 ins->symbol_table.highest_frag_index = 0; 234 ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL);
236 235 ins->modules = kmalloc(sizeof(struct dsp_module_desc) * DSP_MAX_MODULES, GFP_KERNEL);
237 if (ins->symbol_table.symbols == NULL) { 236 if (!ins->symbol_table.symbols || !ins->code.data || !ins->modules) {
238 cs46xx_dsp_spos_destroy(chip); 237 cs46xx_dsp_spos_destroy(chip);
239 goto error; 238 goto error;
240 } 239 }
241 240 ins->symbol_table.nsymbols = 0;
241 ins->symbol_table.highest_frag_index = 0;
242 ins->code.offset = 0; 242 ins->code.offset = 0;
243 ins->code.size = 0; 243 ins->code.size = 0;
244 ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL);
245
246 if (ins->code.data == NULL) {
247 cs46xx_dsp_spos_destroy(chip);
248 goto error;
249 }
250
251 ins->nscb = 0; 244 ins->nscb = 0;
252 ins->ntask = 0; 245 ins->ntask = 0;
253
254 ins->nmodules = 0; 246 ins->nmodules = 0;
255 ins->modules = kmalloc(sizeof(struct dsp_module_desc) * DSP_MAX_MODULES, GFP_KERNEL);
256
257 if (ins->modules == NULL) {
258 cs46xx_dsp_spos_destroy(chip);
259 goto error;
260 }
261 247
262 /* default SPDIF input sample rate 248 /* default SPDIF input sample rate
263 to 48000 khz */ 249 to 48000 khz */
@@ -271,8 +257,8 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip)
271 257
272 /* set left and right validity bits and 258 /* set left and right validity bits and
273 default channel status */ 259 default channel status */
274 ins->spdif_csuv_default = 260 ins->spdif_csuv_default =
275 ins->spdif_csuv_stream = 261 ins->spdif_csuv_stream =
276 /* byte 0 */ ((unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF & 0xff)) << 24) | 262 /* byte 0 */ ((unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF & 0xff)) << 24) |
277 /* byte 1 */ ((unsigned int)_wrap_all_bits( ((SNDRV_PCM_DEFAULT_CON_SPDIF >> 8) & 0xff)) << 16) | 263 /* byte 1 */ ((unsigned int)_wrap_all_bits( ((SNDRV_PCM_DEFAULT_CON_SPDIF >> 8) & 0xff)) << 16) |
278 /* byte 3 */ (unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF >> 24) & 0xff) | 264 /* byte 3 */ (unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF >> 24) & 0xff) |
@@ -281,6 +267,9 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip)
281 return ins; 267 return ins;
282 268
283error: 269error:
270 kfree(ins->modules);
271 kfree(ins->code.data);
272 vfree(ins->symbol_table.symbols);
284 kfree(ins); 273 kfree(ins);
285 return NULL; 274 return NULL;
286} 275}
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index f16bc8aad6ed..e083122ca55a 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -149,7 +149,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au,
149 &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[i]; 149 &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[i];
150 desc->addr = cpu_to_le32(addr); 150 desc->addr = cpu_to_le32(addr);
151 desc->size = cpu_to_le32(period_bytes); 151 desc->size = cpu_to_le32(period_bytes);
152 desc->ctlreserved = cpu_to_le32(PRD_EOP); 152 desc->ctlreserved = cpu_to_le16(PRD_EOP);
153 desc_addr += sizeof(struct cs5535audio_dma_desc); 153 desc_addr += sizeof(struct cs5535audio_dma_desc);
154 addr += period_bytes; 154 addr += period_bytes;
155 } 155 }
@@ -157,7 +157,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au,
157 lastdesc = &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[periods]; 157 lastdesc = &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[periods];
158 lastdesc->addr = cpu_to_le32((u32) dma->desc_buf.addr); 158 lastdesc->addr = cpu_to_le32((u32) dma->desc_buf.addr);
159 lastdesc->size = 0; 159 lastdesc->size = 0;
160 lastdesc->ctlreserved = cpu_to_le32(PRD_JMP); 160 lastdesc->ctlreserved = cpu_to_le16(PRD_JMP);
161 jmpprd_addr = cpu_to_le32(lastdesc->addr + 161 jmpprd_addr = cpu_to_le32(lastdesc->addr +
162 (sizeof(struct cs5535audio_dma_desc)*periods)); 162 (sizeof(struct cs5535audio_dma_desc)*periods));
163 163
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c
index a3301cc4ab82..185b00088320 100644
--- a/sound/pci/cs5535audio/cs5535audio_pm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pm.c
@@ -90,12 +90,7 @@ int snd_cs5535audio_resume(struct pci_dev *pci)
90 int i; 90 int i;
91 91
92 pci_set_power_state(pci, PCI_D0); 92 pci_set_power_state(pci, PCI_D0);
93 if (pci_restore_state(pci) < 0) { 93 pci_restore_state(pci);
94 printk(KERN_ERR "cs5535audio: pci_restore_state failed, "
95 "disabling device\n");
96 snd_card_disconnect(card);
97 return -EIO;
98 }
99 if (pci_enable_device(pci) < 0) { 94 if (pci_enable_device(pci) < 0) {
100 printk(KERN_ERR "cs5535audio: pci_enable_device failed, " 95 printk(KERN_ERR "cs5535audio: pci_enable_device failed, "
101 "disabling device\n"); 96 "disabling device\n");
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 1bff80cde0a2..13f33c0719d3 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -869,7 +869,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm)
869 mutex_lock(&atc->atc_mutex); 869 mutex_lock(&atc->atc_mutex);
870 dao->ops->get_spos(dao, &status); 870 dao->ops->get_spos(dao, &status);
871 if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) { 871 if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) {
872 status &= ((~IEC958_AES3_CON_FS) << 24); 872 status &= ~(IEC958_AES3_CON_FS << 24);
873 status |= (iec958_con_fs << 24); 873 status |= (iec958_con_fs << 24);
874 dao->ops->set_spos(dao, status); 874 dao->ops->set_spos(dao, status);
875 dao->ops->commit_write(dao); 875 dao->ops->commit_write(dao);
@@ -1627,7 +1627,7 @@ static struct ct_atc atc_preset __devinitdata = {
1627 * Creates and initializes a hardware manager. 1627 * Creates and initializes a hardware manager.
1628 * 1628 *
1629 * Creates kmallocated ct_atc structure. Initializes hardware. 1629 * Creates kmallocated ct_atc structure. Initializes hardware.
1630 * Returns 0 if suceeds, or negative error code if fails. 1630 * Returns 0 if succeeds, or negative error code if fails.
1631 */ 1631 */
1632 1632
1633int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, 1633int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c
index af56eb949bde..47d9ea97de02 100644
--- a/sound/pci/ctxfi/ctdaio.c
+++ b/sound/pci/ctxfi/ctdaio.c
@@ -176,6 +176,7 @@ static int dao_set_left_input(struct dao *dao, struct rsc *input)
176 if (!entry) 176 if (!entry)
177 return -ENOMEM; 177 return -ENOMEM;
178 178
179 dao->ops->clear_left_input(dao);
179 /* Program master and conjugate resources */ 180 /* Program master and conjugate resources */
180 input->ops->master(input); 181 input->ops->master(input);
181 daio->rscl.ops->master(&daio->rscl); 182 daio->rscl.ops->master(&daio->rscl);
@@ -204,6 +205,7 @@ static int dao_set_right_input(struct dao *dao, struct rsc *input)
204 if (!entry) 205 if (!entry)
205 return -ENOMEM; 206 return -ENOMEM;
206 207
208 dao->ops->clear_right_input(dao);
207 /* Program master and conjugate resources */ 209 /* Program master and conjugate resources */
208 input->ops->master(input); 210 input->ops->master(input);
209 daio->rscr.ops->master(&daio->rscr); 211 daio->rscr.ops->master(&daio->rscr);
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index 0cf400f879f9..a5c957db5cea 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -1285,7 +1285,7 @@ static int hw_trn_init(struct hw *hw, const struct trn_conf *info)
1285 hw_write_20kx(hw, PTPALX, ptp_phys_low); 1285 hw_write_20kx(hw, PTPALX, ptp_phys_low);
1286 hw_write_20kx(hw, PTPAHX, ptp_phys_high); 1286 hw_write_20kx(hw, PTPAHX, ptp_phys_high);
1287 hw_write_20kx(hw, TRNCTL, trnctl); 1287 hw_write_20kx(hw, TRNCTL, trnctl);
1288 hw_write_20kx(hw, TRNIS, 0x200c01); /* realy needed? */ 1288 hw_write_20kx(hw, TRNIS, 0x200c01); /* really needed? */
1289 1289
1290 return 0; 1290 return 0;
1291} 1291}
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
index b6b11bfe7574..5364164674e4 100644
--- a/sound/pci/ctxfi/cthw20k2.c
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -1307,10 +1307,10 @@ static int hw_pll_init(struct hw *hw, unsigned int rsr)
1307 set_field(&pllctl, PLLCTL_B, 0); 1307 set_field(&pllctl, PLLCTL_B, 0);
1308 if (48000 == rsr) { 1308 if (48000 == rsr) {
1309 set_field(&pllctl, PLLCTL_FD, 16 - 2); 1309 set_field(&pllctl, PLLCTL_FD, 16 - 2);
1310 set_field(&pllctl, PLLCTL_RD, 1 - 1); 1310 set_field(&pllctl, PLLCTL_RD, 1 - 1); /* 3000*16/1 = 48000 */
1311 } else { /* 44100 */ 1311 } else { /* 44100 */
1312 set_field(&pllctl, PLLCTL_FD, 147 - 2); 1312 set_field(&pllctl, PLLCTL_FD, 147 - 2);
1313 set_field(&pllctl, PLLCTL_RD, 10 - 1); 1313 set_field(&pllctl, PLLCTL_RD, 10 - 1); /* 3000*147/10 = 44100 */
1314 } 1314 }
1315 hw_write_20kx(hw, PLL_CTL, pllctl); 1315 hw_write_20kx(hw, PLL_CTL, pllctl);
1316 mdelay(40); 1316 mdelay(40);
@@ -1740,6 +1740,10 @@ static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
1740 return data; 1740 return data;
1741} 1741}
1742 1742
1743#define MIC_BOOST_0DB 0xCF
1744#define MIC_BOOST_STEPS_PER_DB 2
1745#define MIC_BOOST_20DB (MIC_BOOST_0DB + 20 * MIC_BOOST_STEPS_PER_DB)
1746
1743static int hw_adc_input_select(struct hw *hw, enum ADCSRC type) 1747static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
1744{ 1748{
1745 u32 data; 1749 u32 data;
@@ -1751,10 +1755,12 @@ static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
1751 hw_write_20kx(hw, GPIO_DATA, data); 1755 hw_write_20kx(hw, GPIO_DATA, data);
1752 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101), 1756 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
1753 MAKE_WM8775_DATA(0x101)); /* Mic-in */ 1757 MAKE_WM8775_DATA(0x101)); /* Mic-in */
1754 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xE7), 1758 hw20k2_i2c_write(hw,
1755 MAKE_WM8775_DATA(0xE7)); /* +12dB boost */ 1759 MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB),
1756 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xE7), 1760 MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
1757 MAKE_WM8775_DATA(0xE7)); /* +12dB boost */ 1761 hw20k2_i2c_write(hw,
1762 MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB),
1763 MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
1758 break; 1764 break;
1759 case ADC_LINEIN: 1765 case ADC_LINEIN:
1760 data &= ~(0x1 << 14); 1766 data &= ~(0x1 << 14);
@@ -1827,10 +1833,12 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
1827 1833
1828 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101), 1834 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
1829 MAKE_WM8775_DATA(0x101)); /* Mic-in */ 1835 MAKE_WM8775_DATA(0x101)); /* Mic-in */
1830 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xE7), 1836 hw20k2_i2c_write(hw,
1831 MAKE_WM8775_DATA(0xE7)); /* +12dB boost */ 1837 MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB),
1832 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xE7), 1838 MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
1833 MAKE_WM8775_DATA(0xE7)); /* +12dB boost */ 1839 hw20k2_i2c_write(hw,
1840 MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB),
1841 MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
1834 } else if (mux == 2) { 1842 } else if (mux == 2) {
1835 /* Configures GPIO data to select Line-in */ 1843 /* Configures GPIO data to select Line-in */
1836 data &= ~(0x1 << 14); 1844 data &= ~(0x1 << 14);
diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c
index 15c1e7271ea8..c3519ff42fbb 100644
--- a/sound/pci/ctxfi/ctmixer.c
+++ b/sound/pci/ctxfi/ctmixer.c
@@ -566,19 +566,6 @@ static int ct_spdif_get_mask(struct snd_kcontrol *kcontrol,
566 return 0; 566 return 0;
567} 567}
568 568
569static int ct_spdif_default_get(struct snd_kcontrol *kcontrol,
570 struct snd_ctl_elem_value *ucontrol)
571{
572 unsigned int status = SNDRV_PCM_DEFAULT_CON_SPDIF;
573
574 ucontrol->value.iec958.status[0] = (status >> 0) & 0xff;
575 ucontrol->value.iec958.status[1] = (status >> 8) & 0xff;
576 ucontrol->value.iec958.status[2] = (status >> 16) & 0xff;
577 ucontrol->value.iec958.status[3] = (status >> 24) & 0xff;
578
579 return 0;
580}
581
582static int ct_spdif_get(struct snd_kcontrol *kcontrol, 569static int ct_spdif_get(struct snd_kcontrol *kcontrol,
583 struct snd_ctl_elem_value *ucontrol) 570 struct snd_ctl_elem_value *ucontrol)
584{ 571{
@@ -586,6 +573,10 @@ static int ct_spdif_get(struct snd_kcontrol *kcontrol,
586 unsigned int status; 573 unsigned int status;
587 574
588 atc->spdif_out_get_status(atc, &status); 575 atc->spdif_out_get_status(atc, &status);
576
577 if (status == 0)
578 status = SNDRV_PCM_DEFAULT_CON_SPDIF;
579
589 ucontrol->value.iec958.status[0] = (status >> 0) & 0xff; 580 ucontrol->value.iec958.status[0] = (status >> 0) & 0xff;
590 ucontrol->value.iec958.status[1] = (status >> 8) & 0xff; 581 ucontrol->value.iec958.status[1] = (status >> 8) & 0xff;
591 ucontrol->value.iec958.status[2] = (status >> 16) & 0xff; 582 ucontrol->value.iec958.status[2] = (status >> 16) & 0xff;
@@ -629,7 +620,7 @@ static struct snd_kcontrol_new iec958_default_ctl = {
629 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), 620 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
630 .count = 1, 621 .count = 1,
631 .info = ct_spdif_info, 622 .info = ct_spdif_info,
632 .get = ct_spdif_default_get, 623 .get = ct_spdif_get,
633 .put = ct_spdif_put, 624 .put = ct_spdif_put,
634 .private_value = MIXER_IEC958_DEFAULT 625 .private_value = MIXER_IEC958_DEFAULT
635}; 626};
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c
index 85ab43e89212..457d21189b0d 100644
--- a/sound/pci/ctxfi/ctpcm.c
+++ b/sound/pci/ctxfi/ctpcm.c
@@ -129,8 +129,6 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
129 129
130 apcm->substream = substream; 130 apcm->substream = substream;
131 apcm->interrupt = ct_atc_pcm_interrupt; 131 apcm->interrupt = ct_atc_pcm_interrupt;
132 runtime->private_data = apcm;
133 runtime->private_free = ct_atc_pcm_free_substream;
134 if (IEC958 == substream->pcm->device) { 132 if (IEC958 == substream->pcm->device) {
135 runtime->hw = ct_spdif_passthru_playback_hw; 133 runtime->hw = ct_spdif_passthru_playback_hw;
136 atc->spdif_out_passthru(atc, 1); 134 atc->spdif_out_passthru(atc, 1);
@@ -155,8 +153,12 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
155 } 153 }
156 154
157 apcm->timer = ct_timer_instance_new(atc->timer, apcm); 155 apcm->timer = ct_timer_instance_new(atc->timer, apcm);
158 if (!apcm->timer) 156 if (!apcm->timer) {
157 kfree(apcm);
159 return -ENOMEM; 158 return -ENOMEM;
159 }
160 runtime->private_data = apcm;
161 runtime->private_free = ct_atc_pcm_free_substream;
160 162
161 return 0; 163 return 0;
162} 164}
@@ -278,8 +280,6 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
278 apcm->started = 0; 280 apcm->started = 0;
279 apcm->substream = substream; 281 apcm->substream = substream;
280 apcm->interrupt = ct_atc_pcm_interrupt; 282 apcm->interrupt = ct_atc_pcm_interrupt;
281 runtime->private_data = apcm;
282 runtime->private_free = ct_atc_pcm_free_substream;
283 runtime->hw = ct_pcm_capture_hw; 283 runtime->hw = ct_pcm_capture_hw;
284 runtime->hw.rate_max = atc->rsr * atc->msr; 284 runtime->hw.rate_max = atc->rsr * atc->msr;
285 285
@@ -298,8 +298,12 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
298 } 298 }
299 299
300 apcm->timer = ct_timer_instance_new(atc->timer, apcm); 300 apcm->timer = ct_timer_instance_new(atc->timer, apcm);
301 if (!apcm->timer) 301 if (!apcm->timer) {
302 kfree(apcm);
302 return -ENOMEM; 303 return -ENOMEM;
304 }
305 runtime->private_data = apcm;
306 runtime->private_free = ct_atc_pcm_free_substream;
303 307
304 return 0; 308 return 0;
305} 309}
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c
index 65da6e466f80..b78f3fc3c33c 100644
--- a/sound/pci/ctxfi/ctvmem.c
+++ b/sound/pci/ctxfi/ctvmem.c
@@ -52,8 +52,7 @@ get_vm_block(struct ct_vm *vm, unsigned int size)
52 52
53 if (entry->size == size) { 53 if (entry->size == size) {
54 /* Move the vm node from unused list to used list directly */ 54 /* Move the vm node from unused list to used list directly */
55 list_del(&entry->list); 55 list_move(&entry->list, &vm->used);
56 list_add(&entry->list, &vm->used);
57 vm->size -= size; 56 vm->size -= size;
58 block = entry; 57 block = entry;
59 goto out; 58 goto out;
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 66c7fb3ced3e..15f0161ce4a2 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -926,7 +926,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
926 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); 926 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19);
927 /* Unknown. */ 927 /* Unknown. */
928 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); 928 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c);
929 /* IRQ Enable: Alll on */ 929 /* IRQ Enable: All on */
930 /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); */ 930 /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); */
931 /* IRQ Enable: All off */ 931 /* IRQ Enable: All off */
932 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00); 932 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00);
@@ -1440,6 +1440,14 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1440 .ca0102_chip = 1, 1440 .ca0102_chip = 1,
1441 .spk71 = 1, 1441 .spk71 = 1,
1442 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */ 1442 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */
1443 /* EMU0404 PCIe */
1444 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40051102,
1445 .driver = "Audigy2", .name = "E-mu 0404 PCIe [MAEM8984]",
1446 .id = "EMU0404",
1447 .emu10k2_chip = 1,
1448 .ca0108_chip = 1,
1449 .spk71 = 1,
1450 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 PCIe ver_03 */
1443 /* Note that all E-mu cards require kernel 2.6 or newer. */ 1451 /* Note that all E-mu cards require kernel 2.6 or newer. */
1444 {.vendor = 0x1102, .device = 0x0008, 1452 {.vendor = 0x1102, .device = 0x0008,
1445 .driver = "Audigy2", .name = "SB Audigy 2 Value [Unknown]", 1453 .driver = "Audigy2", .name = "SB Audigy 2 Value [Unknown]",
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index df47f738098d..0c701e4ec8a5 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -114,7 +114,7 @@ MODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard.");
114 */ 114 */
115#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */ 115#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */
116#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */ 116#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
117#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */ 117#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */
118#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size */ 118#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size */
119#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Sample currently in DAC */ 119#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Sample currently in DAC */
120#define PLAYBACK_UNKNOWN1 0x07 120#define PLAYBACK_UNKNOWN1 0x07
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 7a9401462c1c..dae4050ede5c 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -303,6 +303,9 @@ static const u32 db_table[101] = {
303static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); 303static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1);
304static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0); 304static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0);
305 305
306/* EMU10K1 bass/treble db gain */
307static const DECLARE_TLV_DB_SCALE(snd_emu10k1_bass_treble_db_scale, -1200, 60, 0);
308
306static const u32 onoff_table[2] = { 309static const u32 onoff_table[2] = {
307 0x00000000, 0x00000001 310 0x00000000, 0x00000001
308}; 311};
@@ -2163,6 +2166,7 @@ static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2163 ctl->min = 0; 2166 ctl->min = 0;
2164 ctl->max = 40; 2167 ctl->max = 40;
2165 ctl->value[0] = ctl->value[1] = 20; 2168 ctl->value[0] = ctl->value[1] = 20;
2169 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
2166 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS; 2170 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
2167 ctl = &controls[i + 1]; 2171 ctl = &controls[i + 1];
2168 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2172 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
@@ -2172,6 +2176,7 @@ static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2172 ctl->min = 0; 2176 ctl->min = 0;
2173 ctl->max = 40; 2177 ctl->max = 40;
2174 ctl->value[0] = ctl->value[1] = 20; 2178 ctl->value[0] = ctl->value[1] = 20;
2179 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
2175 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE; 2180 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
2176 2181
2177#define BASS_GPR 0x8c 2182#define BASS_GPR 0x8c
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 05afe06e353a..9d890a5aec5a 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -1729,8 +1729,6 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1729 "Master Mono Playback Volume", 1729 "Master Mono Playback Volume",
1730 "PCM Out Path & Mute", 1730 "PCM Out Path & Mute",
1731 "Mono Output Select", 1731 "Mono Output Select",
1732 "Front Playback Switch",
1733 "Front Playback Volume",
1734 "Surround Playback Switch", 1732 "Surround Playback Switch",
1735 "Surround Playback Volume", 1733 "Surround Playback Volume",
1736 "Center Playback Switch", 1734 "Center Playback Switch",
@@ -1879,6 +1877,8 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1879 emu->rear_ac97 = 1; 1877 emu->rear_ac97 = 1;
1880 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT); 1878 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
1881 snd_ac97_write_cache(emu->ac97, AC97_HEADPHONE, 0x0202); 1879 snd_ac97_write_cache(emu->ac97, AC97_HEADPHONE, 0x0202);
1880 remove_ctl(card,"Front Playback Volume");
1881 remove_ctl(card,"Front Playback Switch");
1882 } 1882 }
1883 /* remove unused AC97 controls */ 1883 /* remove unused AC97 controls */
1884 snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202); 1884 snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
@@ -1913,6 +1913,12 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1913 for (; *c; c += 2) 1913 for (; *c; c += 2)
1914 rename_ctl(card, c[0], c[1]); 1914 rename_ctl(card, c[0], c[1]);
1915 1915
1916 if (emu->card_capabilities->subsystem == 0x80401102) { /* SB Live! Platinum CT4760P */
1917 remove_ctl(card, "Center Playback Volume");
1918 remove_ctl(card, "LFE Playback Volume");
1919 remove_ctl(card, "Wave Center Playback Volume");
1920 remove_ctl(card, "Wave LFE Playback Volume");
1921 }
1916 if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */ 1922 if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */
1917 rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume"); 1923 rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume");
1918 rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume"); 1924 rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume");
diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c
index 8578c70c61f2..bab564824efe 100644
--- a/sound/pci/emu10k1/emumpu401.c
+++ b/sound/pci/emu10k1/emumpu401.c
@@ -321,7 +321,7 @@ static struct snd_rawmidi_ops snd_emu10k1_midi_input =
321 321
322static void snd_emu10k1_midi_free(struct snd_rawmidi *rmidi) 322static void snd_emu10k1_midi_free(struct snd_rawmidi *rmidi)
323{ 323{
324 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)rmidi->private_data; 324 struct snd_emu10k1_midi *midi = rmidi->private_data;
325 midi->interrupt = NULL; 325 midi->interrupt = NULL;
326 midi->rmidi = NULL; 326 midi->rmidi = NULL;
327} 327}
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 957a311514c8..c250614dadd0 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -248,7 +248,7 @@ static int is_valid_page(struct snd_emu10k1 *emu, dma_addr_t addr)
248/* 248/*
249 * map the given memory block on PTB. 249 * map the given memory block on PTB.
250 * if the block is already mapped, update the link order. 250 * if the block is already mapped, update the link order.
251 * if no empty pages are found, tries to release unsed memory blocks 251 * if no empty pages are found, tries to release unused memory blocks
252 * and retry the mapping. 252 * and retry the mapping.
253 */ 253 */
254int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) 254int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index 61b8ab39800f..a81dc44228ea 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -69,7 +69,7 @@
69 * ADC: Philips 1361T (Stereo 24bit) 69 * ADC: Philips 1361T (Stereo 24bit)
70 * DAC: CS4382-K (8-channel, 24bit, 192Khz) 70 * DAC: CS4382-K (8-channel, 24bit, 192Khz)
71 * 71 *
72 * This code was initally based on code from ALSA's emu10k1x.c which is: 72 * This code was initially based on code from ALSA's emu10k1x.c which is:
73 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com> 73 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
74 * 74 *
75 * This program is free software; you can redistribute it and/or modify 75 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/pci/emu10k1/p16v.h b/sound/pci/emu10k1/p16v.h
index 153214940336..4e0ee1a9747a 100644
--- a/sound/pci/emu10k1/p16v.h
+++ b/sound/pci/emu10k1/p16v.h
@@ -59,7 +59,7 @@
59 * ADC: Philips 1361T (Stereo 24bit) 59 * ADC: Philips 1361T (Stereo 24bit)
60 * DAC: CS4382-K (8-channel, 24bit, 192Khz) 60 * DAC: CS4382-K (8-channel, 24bit, 192Khz)
61 * 61 *
62 * This code was initally based on code from ALSA's emu10k1x.c which is: 62 * This code was initially based on code from ALSA's emu10k1x.c which is:
63 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com> 63 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
64 * 64 *
65 * This program is free software; you can redistribute it and/or modify 65 * This program is free software; you can redistribute it and/or modify
@@ -86,7 +86,7 @@
86 * The sample rate is also controlled by the same registers that control the rate of the EMU10K2 sample rate converters. 86 * The sample rate is also controlled by the same registers that control the rate of the EMU10K2 sample rate converters.
87 */ 87 */
88 88
89/* Initally all registers from 0x00 to 0x3f have zero contents. */ 89/* Initially all registers from 0x00 to 0x3f have zero contents. */
90#define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */ 90#define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */
91 /* One list entry: 4 bytes for DMA address, 91 /* One list entry: 4 bytes for DMA address,
92 * 4 bytes for period_size << 16. 92 * 4 bytes for period_size << 16.
@@ -96,7 +96,7 @@
96#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */ 96#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */
97#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */ 97#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
98#define PLAYBACK_UNKNOWN3 0x03 /* Not used */ 98#define PLAYBACK_UNKNOWN3 0x03 /* Not used */
99#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */ 99#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */
100#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */ 100#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */
101#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Used with PLAYBACK_LIST_PTR to determine buffer position currently in DAC */ 101#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Used with PLAYBACK_LIST_PTR to determine buffer position currently in DAC */
102#define PLAYBACK_FIFO_END_ADDRESS 0x07 /* Playback FIFO end address */ 102#define PLAYBACK_FIFO_END_ADDRESS 0x07 /* Playback FIFO end address */
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index c7fba5379813..863eafea691f 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -22,7 +22,7 @@
22/* Power-Management-Code ( CONFIG_PM ) 22/* Power-Management-Code ( CONFIG_PM )
23 * for ens1371 only ( FIXME ) 23 * for ens1371 only ( FIXME )
24 * derived from cs4281.c, atiixp.c and via82xx.c 24 * derived from cs4281.c, atiixp.c and via82xx.c
25 * using http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c1540.htm 25 * using http://www.alsa-project.org/~tiwai/writing-an-alsa-driver/
26 * by Kurt J. Bosch 26 * by Kurt J. Bosch
27 */ 27 */
28 28
@@ -229,6 +229,7 @@ MODULE_PARM_DESC(lineio, "Line In to Rear Out (0 = auto, 1 = force).");
229#define ES_REG_1371_CODEC 0x14 /* W/R: Codec Read/Write register address */ 229#define ES_REG_1371_CODEC 0x14 /* W/R: Codec Read/Write register address */
230#define ES_1371_CODEC_RDY (1<<31) /* codec ready */ 230#define ES_1371_CODEC_RDY (1<<31) /* codec ready */
231#define ES_1371_CODEC_WIP (1<<30) /* codec register access in progress */ 231#define ES_1371_CODEC_WIP (1<<30) /* codec register access in progress */
232#define EV_1938_CODEC_MAGIC (1<<26)
232#define ES_1371_CODEC_PIRD (1<<23) /* codec read/write select register */ 233#define ES_1371_CODEC_PIRD (1<<23) /* codec read/write select register */
233#define ES_1371_CODEC_WRITE(a,d) ((((a)&0x7f)<<16)|(((d)&0xffff)<<0)) 234#define ES_1371_CODEC_WRITE(a,d) ((((a)&0x7f)<<16)|(((d)&0xffff)<<0))
234#define ES_1371_CODEC_READS(a) ((((a)&0x7f)<<16)|ES_1371_CODEC_PIRD) 235#define ES_1371_CODEC_READS(a) ((((a)&0x7f)<<16)|ES_1371_CODEC_PIRD)
@@ -603,12 +604,18 @@ static void snd_es1370_codec_write(struct snd_ak4531 *ak4531,
603 604
604#ifdef CHIP1371 605#ifdef CHIP1371
605 606
607static inline bool is_ev1938(struct ensoniq *ensoniq)
608{
609 return ensoniq->pci->device == 0x8938;
610}
611
606static void snd_es1371_codec_write(struct snd_ac97 *ac97, 612static void snd_es1371_codec_write(struct snd_ac97 *ac97,
607 unsigned short reg, unsigned short val) 613 unsigned short reg, unsigned short val)
608{ 614{
609 struct ensoniq *ensoniq = ac97->private_data; 615 struct ensoniq *ensoniq = ac97->private_data;
610 unsigned int t, x; 616 unsigned int t, x, flag;
611 617
618 flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0;
612 mutex_lock(&ensoniq->src_mutex); 619 mutex_lock(&ensoniq->src_mutex);
613 for (t = 0; t < POLL_COUNT; t++) { 620 for (t = 0; t < POLL_COUNT; t++) {
614 if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { 621 if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {
@@ -630,7 +637,8 @@ static void snd_es1371_codec_write(struct snd_ac97 *ac97,
630 0x00010000) 637 0x00010000)
631 break; 638 break;
632 } 639 }
633 outl(ES_1371_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1371_CODEC)); 640 outl(ES_1371_CODEC_WRITE(reg, val) | flag,
641 ES_REG(ensoniq, 1371_CODEC));
634 /* restore SRC reg */ 642 /* restore SRC reg */
635 snd_es1371_wait_src_ready(ensoniq); 643 snd_es1371_wait_src_ready(ensoniq);
636 outl(x, ES_REG(ensoniq, 1371_SMPRATE)); 644 outl(x, ES_REG(ensoniq, 1371_SMPRATE));
@@ -647,8 +655,9 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,
647 unsigned short reg) 655 unsigned short reg)
648{ 656{
649 struct ensoniq *ensoniq = ac97->private_data; 657 struct ensoniq *ensoniq = ac97->private_data;
650 unsigned int t, x, fail = 0; 658 unsigned int t, x, flag, fail = 0;
651 659
660 flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0;
652 __again: 661 __again:
653 mutex_lock(&ensoniq->src_mutex); 662 mutex_lock(&ensoniq->src_mutex);
654 for (t = 0; t < POLL_COUNT; t++) { 663 for (t = 0; t < POLL_COUNT; t++) {
@@ -671,7 +680,8 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,
671 0x00010000) 680 0x00010000)
672 break; 681 break;
673 } 682 }
674 outl(ES_1371_CODEC_READS(reg), ES_REG(ensoniq, 1371_CODEC)); 683 outl(ES_1371_CODEC_READS(reg) | flag,
684 ES_REG(ensoniq, 1371_CODEC));
675 /* restore SRC reg */ 685 /* restore SRC reg */
676 snd_es1371_wait_src_ready(ensoniq); 686 snd_es1371_wait_src_ready(ensoniq);
677 outl(x, ES_REG(ensoniq, 1371_SMPRATE)); 687 outl(x, ES_REG(ensoniq, 1371_SMPRATE));
@@ -683,6 +693,11 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,
683 /* now wait for the stinkin' data (RDY) */ 693 /* now wait for the stinkin' data (RDY) */
684 for (t = 0; t < POLL_COUNT; t++) { 694 for (t = 0; t < POLL_COUNT; t++) {
685 if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) { 695 if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) {
696 if (is_ev1938(ensoniq)) {
697 for (t = 0; t < 100; t++)
698 inl(ES_REG(ensoniq, CONTROL));
699 x = inl(ES_REG(ensoniq, 1371_CODEC));
700 }
686 mutex_unlock(&ensoniq->src_mutex); 701 mutex_unlock(&ensoniq->src_mutex);
687 return ES_1371_CODEC_READ(x); 702 return ES_1371_CODEC_READ(x);
688 } 703 }
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 23a58f0d6cb9..ab0a6156a704 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -112,6 +112,10 @@
112#include <sound/ac97_codec.h> 112#include <sound/ac97_codec.h>
113#include <sound/initval.h> 113#include <sound/initval.h>
114 114
115#ifdef CONFIG_SND_ES1968_RADIO
116#include <sound/tea575x-tuner.h>
117#endif
118
115#define CARD_NAME "ESS Maestro1/2" 119#define CARD_NAME "ESS Maestro1/2"
116#define DRIVER_NAME "ES1968" 120#define DRIVER_NAME "ES1968"
117 121
@@ -220,7 +224,7 @@ MODULE_PARM_DESC(joystick, "Enable joystick.");
220#define RINGB_EN_2CODEC 0x0020 224#define RINGB_EN_2CODEC 0x0020
221#define RINGB_SING_BIT_DUAL 0x0040 225#define RINGB_SING_BIT_DUAL 0x0040
222 226
223/* ****Port Adresses**** */ 227/* ****Port Addresses**** */
224 228
225/* Write & Read */ 229/* Write & Read */
226#define ESM_INDEX 0x02 230#define ESM_INDEX 0x02
@@ -553,6 +557,10 @@ struct es1968 {
553 spinlock_t ac97_lock; 557 spinlock_t ac97_lock;
554 struct tasklet_struct hwvol_tq; 558 struct tasklet_struct hwvol_tq;
555#endif 559#endif
560
561#ifdef CONFIG_SND_ES1968_RADIO
562 struct snd_tea575x tea;
563#endif
556}; 564};
557 565
558static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); 566static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
@@ -2571,6 +2579,63 @@ static int __devinit snd_es1968_input_register(struct es1968 *chip)
2571} 2579}
2572#endif /* CONFIG_SND_ES1968_INPUT */ 2580#endif /* CONFIG_SND_ES1968_INPUT */
2573 2581
2582#ifdef CONFIG_SND_ES1968_RADIO
2583#define GPIO_DATA 0x60
2584#define IO_MASK 4 /* mask register offset from GPIO_DATA
2585 bits 1=unmask write to given bit */
2586#define IO_DIR 8 /* direction register offset from GPIO_DATA
2587 bits 0/1=read/write direction */
2588/* mask bits for GPIO lines */
2589#define STR_DATA 0x0040 /* GPIO6 */
2590#define STR_CLK 0x0080 /* GPIO7 */
2591#define STR_WREN 0x0100 /* GPIO8 */
2592#define STR_MOST 0x0200 /* GPIO9 */
2593
2594static void snd_es1968_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
2595{
2596 struct es1968 *chip = tea->private_data;
2597 unsigned long io = chip->io_port + GPIO_DATA;
2598 u16 val = 0;
2599
2600 val |= (pins & TEA575X_DATA) ? STR_DATA : 0;
2601 val |= (pins & TEA575X_CLK) ? STR_CLK : 0;
2602 val |= (pins & TEA575X_WREN) ? STR_WREN : 0;
2603
2604 outw(val, io);
2605}
2606
2607static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea)
2608{
2609 struct es1968 *chip = tea->private_data;
2610 unsigned long io = chip->io_port + GPIO_DATA;
2611 u16 val = inw(io);
2612
2613 return (val & STR_DATA) ? TEA575X_DATA : 0 |
2614 (val & STR_MOST) ? TEA575X_MOST : 0;
2615}
2616
2617static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output)
2618{
2619 struct es1968 *chip = tea->private_data;
2620 unsigned long io = chip->io_port + GPIO_DATA;
2621 u16 odir = inw(io + IO_DIR);
2622
2623 if (output) {
2624 outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
2625 outw(odir | STR_DATA | STR_CLK | STR_WREN, io + IO_DIR);
2626 } else {
2627 outw(~(STR_CLK | STR_WREN | STR_DATA | STR_MOST), io + IO_MASK);
2628 outw((odir & ~(STR_DATA | STR_MOST)) | STR_CLK | STR_WREN, io + IO_DIR);
2629 }
2630}
2631
2632static struct snd_tea575x_ops snd_es1968_tea_ops = {
2633 .set_pins = snd_es1968_tea575x_set_pins,
2634 .get_pins = snd_es1968_tea575x_get_pins,
2635 .set_direction = snd_es1968_tea575x_set_direction,
2636};
2637#endif
2638
2574static int snd_es1968_free(struct es1968 *chip) 2639static int snd_es1968_free(struct es1968 *chip)
2575{ 2640{
2576#ifdef CONFIG_SND_ES1968_INPUT 2641#ifdef CONFIG_SND_ES1968_INPUT
@@ -2585,6 +2650,10 @@ static int snd_es1968_free(struct es1968 *chip)
2585 outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */ 2650 outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */
2586 } 2651 }
2587 2652
2653#ifdef CONFIG_SND_ES1968_RADIO
2654 snd_tea575x_exit(&chip->tea);
2655#endif
2656
2588 if (chip->irq >= 0) 2657 if (chip->irq >= 0)
2589 free_irq(chip->irq, chip); 2658 free_irq(chip->irq, chip);
2590 snd_es1968_free_gameport(chip); 2659 snd_es1968_free_gameport(chip);
@@ -2723,6 +2792,15 @@ static int __devinit snd_es1968_create(struct snd_card *card,
2723 2792
2724 snd_card_set_dev(card, &pci->dev); 2793 snd_card_set_dev(card, &pci->dev);
2725 2794
2795#ifdef CONFIG_SND_ES1968_RADIO
2796 chip->tea.private_data = chip;
2797 chip->tea.ops = &snd_es1968_tea_ops;
2798 strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card));
2799 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
2800 if (!snd_tea575x_init(&chip->tea))
2801 printk(KERN_INFO "es1968: detected TEA575x radio\n");
2802#endif
2803
2726 *chip_ret = chip; 2804 *chip_ret = chip;
2727 2805
2728 return 0; 2806 return 0;
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index e1baad74ea4b..a7ec7030cf87 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -38,7 +38,6 @@
38 38
39#ifdef CONFIG_SND_FM801_TEA575X_BOOL 39#ifdef CONFIG_SND_FM801_TEA575X_BOOL
40#include <sound/tea575x-tuner.h> 40#include <sound/tea575x-tuner.h>
41#define TEA575X_RADIO 1
42#endif 41#endif
43 42
44MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 43MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
@@ -53,7 +52,7 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card *
53/* 52/*
54 * Enable TEA575x tuner 53 * Enable TEA575x tuner
55 * 1 = MediaForte 256-PCS 54 * 1 = MediaForte 256-PCS
56 * 2 = MediaForte 256-PCPR 55 * 2 = MediaForte 256-PCP
57 * 3 = MediaForte 64-PCR 56 * 3 = MediaForte 64-PCR
58 * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card 57 * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card
59 * High 16-bits are video (radio) device number + 1 58 * High 16-bits are video (radio) device number + 1
@@ -67,7 +66,7 @@ MODULE_PARM_DESC(id, "ID string for the FM801 soundcard.");
67module_param_array(enable, bool, NULL, 0444); 66module_param_array(enable, bool, NULL, 0444);
68MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); 67MODULE_PARM_DESC(enable, "Enable FM801 soundcard.");
69module_param_array(tea575x_tuner, int, NULL, 0444); 68module_param_array(tea575x_tuner, int, NULL, 0444);
70MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (1 = SF256-PCS, 2=SF256-PCPR, 3=SF64-PCR, +16=tuner-only)."); 69MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only).");
71 70
72#define TUNER_ONLY (1<<4) 71#define TUNER_ONLY (1<<4)
73#define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF) 72#define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF)
@@ -196,7 +195,7 @@ struct fm801 {
196 spinlock_t reg_lock; 195 spinlock_t reg_lock;
197 struct snd_info_entry *proc_entry; 196 struct snd_info_entry *proc_entry;
198 197
199#ifdef TEA575X_RADIO 198#ifdef CONFIG_SND_FM801_TEA575X_BOOL
200 struct snd_tea575x tea; 199 struct snd_tea575x tea;
201#endif 200#endif
202 201
@@ -715,310 +714,89 @@ static int __devinit snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pc
715 * TEA5757 radio 714 * TEA5757 radio
716 */ 715 */
717 716
718#ifdef TEA575X_RADIO 717#ifdef CONFIG_SND_FM801_TEA575X_BOOL
719
720/* 256PCS GPIO numbers */
721#define TEA_256PCS_DATA 1
722#define TEA_256PCS_WRITE_ENABLE 2 /* inverted */
723#define TEA_256PCS_BUS_CLOCK 3
724
725static void snd_fm801_tea575x_256pcs_write(struct snd_tea575x *tea, unsigned int val)
726{
727 struct fm801 *chip = tea->private_data;
728 unsigned short reg;
729 int i = 25;
730 718
731 spin_lock_irq(&chip->reg_lock); 719/* GPIO to TEA575x maps */
732 reg = inw(FM801_REG(chip, GPIO_CTRL)); 720struct snd_fm801_tea575x_gpio {
733 /* use GPIO lines and set write enable bit */ 721 u8 data, clk, wren, most;
734 reg |= FM801_GPIO_GS(TEA_256PCS_DATA) | 722 char *name;
735 FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) | 723};
736 FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK);
737 /* all of lines are in the write direction */
738 /* clear data and clock lines */
739 reg &= ~(FM801_GPIO_GD(TEA_256PCS_DATA) |
740 FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) |
741 FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) |
742 FM801_GPIO_GP(TEA_256PCS_DATA) |
743 FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK) |
744 FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE));
745 outw(reg, FM801_REG(chip, GPIO_CTRL));
746 udelay(1);
747
748 while (i--) {
749 if (val & (1 << i))
750 reg |= FM801_GPIO_GP(TEA_256PCS_DATA);
751 else
752 reg &= ~FM801_GPIO_GP(TEA_256PCS_DATA);
753 outw(reg, FM801_REG(chip, GPIO_CTRL));
754 udelay(1);
755 reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
756 outw(reg, FM801_REG(chip, GPIO_CTRL));
757 reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
758 outw(reg, FM801_REG(chip, GPIO_CTRL));
759 udelay(1);
760 }
761 724
762 /* and reset the write enable bit */ 725static struct snd_fm801_tea575x_gpio snd_fm801_tea575x_gpios[] = {
763 reg |= FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE) | 726 { .data = 1, .clk = 3, .wren = 2, .most = 0, .name = "SF256-PCS" },
764 FM801_GPIO_GP(TEA_256PCS_DATA); 727 { .data = 1, .clk = 0, .wren = 2, .most = 3, .name = "SF256-PCP" },
765 outw(reg, FM801_REG(chip, GPIO_CTRL)); 728 { .data = 2, .clk = 0, .wren = 1, .most = 3, .name = "SF64-PCR" },
766 spin_unlock_irq(&chip->reg_lock); 729};
767}
768 730
769static unsigned int snd_fm801_tea575x_256pcs_read(struct snd_tea575x *tea) 731static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
770{ 732{
771 struct fm801 *chip = tea->private_data; 733 struct fm801 *chip = tea->private_data;
772 unsigned short reg; 734 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
773 unsigned int val = 0; 735 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1];
774 int i;
775
776 spin_lock_irq(&chip->reg_lock);
777 reg = inw(FM801_REG(chip, GPIO_CTRL));
778 /* use GPIO lines, set data direction to input */
779 reg |= FM801_GPIO_GS(TEA_256PCS_DATA) |
780 FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) |
781 FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK) |
782 FM801_GPIO_GD(TEA_256PCS_DATA) |
783 FM801_GPIO_GP(TEA_256PCS_DATA) |
784 FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE);
785 /* all of lines are in the write direction, except data */
786 /* clear data, write enable and clock lines */
787 reg &= ~(FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) |
788 FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) |
789 FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK));
790
791 for (i = 0; i < 24; i++) {
792 reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
793 outw(reg, FM801_REG(chip, GPIO_CTRL));
794 udelay(1);
795 reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
796 outw(reg, FM801_REG(chip, GPIO_CTRL));
797 udelay(1);
798 val <<= 1;
799 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCS_DATA))
800 val |= 1;
801 }
802 736
803 spin_unlock_irq(&chip->reg_lock); 737 reg &= ~(FM801_GPIO_GP(gpio.data) |
804 738 FM801_GPIO_GP(gpio.clk) |
805 return val; 739 FM801_GPIO_GP(gpio.wren));
806}
807 740
808/* 256PCPR GPIO numbers */ 741 reg |= (pins & TEA575X_DATA) ? FM801_GPIO_GP(gpio.data) : 0;
809#define TEA_256PCPR_BUS_CLOCK 0 742 reg |= (pins & TEA575X_CLK) ? FM801_GPIO_GP(gpio.clk) : 0;
810#define TEA_256PCPR_DATA 1 743 /* WRITE_ENABLE is inverted */
811#define TEA_256PCPR_WRITE_ENABLE 2 /* inverted */ 744 reg |= (pins & TEA575X_WREN) ? 0 : FM801_GPIO_GP(gpio.wren);
812
813static void snd_fm801_tea575x_256pcpr_write(struct snd_tea575x *tea, unsigned int val)
814{
815 struct fm801 *chip = tea->private_data;
816 unsigned short reg;
817 int i = 25;
818
819 spin_lock_irq(&chip->reg_lock);
820 reg = inw(FM801_REG(chip, GPIO_CTRL));
821 /* use GPIO lines and set write enable bit */
822 reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) |
823 FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) |
824 FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK);
825 /* all of lines are in the write direction */
826 /* clear data and clock lines */
827 reg &= ~(FM801_GPIO_GD(TEA_256PCPR_DATA) |
828 FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) |
829 FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) |
830 FM801_GPIO_GP(TEA_256PCPR_DATA) |
831 FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK) |
832 FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE));
833 outw(reg, FM801_REG(chip, GPIO_CTRL));
834 udelay(1);
835
836 while (i--) {
837 if (val & (1 << i))
838 reg |= FM801_GPIO_GP(TEA_256PCPR_DATA);
839 else
840 reg &= ~FM801_GPIO_GP(TEA_256PCPR_DATA);
841 outw(reg, FM801_REG(chip, GPIO_CTRL));
842 udelay(1);
843 reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
844 outw(reg, FM801_REG(chip, GPIO_CTRL));
845 reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
846 outw(reg, FM801_REG(chip, GPIO_CTRL));
847 udelay(1);
848 }
849 745
850 /* and reset the write enable bit */
851 reg |= FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE) |
852 FM801_GPIO_GP(TEA_256PCPR_DATA);
853 outw(reg, FM801_REG(chip, GPIO_CTRL)); 746 outw(reg, FM801_REG(chip, GPIO_CTRL));
854 spin_unlock_irq(&chip->reg_lock);
855} 747}
856 748
857static unsigned int snd_fm801_tea575x_256pcpr_read(struct snd_tea575x *tea) 749static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea)
858{ 750{
859 struct fm801 *chip = tea->private_data; 751 struct fm801 *chip = tea->private_data;
860 unsigned short reg; 752 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
861 unsigned int val = 0; 753 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1];
862 int i;
863
864 spin_lock_irq(&chip->reg_lock);
865 reg = inw(FM801_REG(chip, GPIO_CTRL));
866 /* use GPIO lines, set data direction to input */
867 reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) |
868 FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) |
869 FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK) |
870 FM801_GPIO_GD(TEA_256PCPR_DATA) |
871 FM801_GPIO_GP(TEA_256PCPR_DATA) |
872 FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE);
873 /* all of lines are in the write direction, except data */
874 /* clear data, write enable and clock lines */
875 reg &= ~(FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) |
876 FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) |
877 FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK));
878
879 for (i = 0; i < 24; i++) {
880 reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
881 outw(reg, FM801_REG(chip, GPIO_CTRL));
882 udelay(1);
883 reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
884 outw(reg, FM801_REG(chip, GPIO_CTRL));
885 udelay(1);
886 val <<= 1;
887 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCPR_DATA))
888 val |= 1;
889 }
890
891 spin_unlock_irq(&chip->reg_lock);
892 754
893 return val; 755 return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 |
756 (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0;
894} 757}
895 758
896/* 64PCR GPIO numbers */ 759static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output)
897#define TEA_64PCR_BUS_CLOCK 0
898#define TEA_64PCR_WRITE_ENABLE 1 /* inverted */
899#define TEA_64PCR_DATA 2
900
901static void snd_fm801_tea575x_64pcr_write(struct snd_tea575x *tea, unsigned int val)
902{ 760{
903 struct fm801 *chip = tea->private_data; 761 struct fm801 *chip = tea->private_data;
904 unsigned short reg; 762 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
905 int i = 25; 763 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1];
906 764
907 spin_lock_irq(&chip->reg_lock);
908 reg = inw(FM801_REG(chip, GPIO_CTRL));
909 /* use GPIO lines and set write enable bit */ 765 /* use GPIO lines and set write enable bit */
910 reg |= FM801_GPIO_GS(TEA_64PCR_DATA) | 766 reg |= FM801_GPIO_GS(gpio.data) |
911 FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) | 767 FM801_GPIO_GS(gpio.wren) |
912 FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK); 768 FM801_GPIO_GS(gpio.clk) |
913 /* all of lines are in the write direction */ 769 FM801_GPIO_GS(gpio.most);
914 /* clear data and clock lines */ 770 if (output) {
915 reg &= ~(FM801_GPIO_GD(TEA_64PCR_DATA) | 771 /* all of lines are in the write direction */
916 FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) | 772 /* clear data and clock lines */
917 FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) | 773 reg &= ~(FM801_GPIO_GD(gpio.data) |
918 FM801_GPIO_GP(TEA_64PCR_DATA) | 774 FM801_GPIO_GD(gpio.wren) |
919 FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK) | 775 FM801_GPIO_GD(gpio.clk) |
920 FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE)); 776 FM801_GPIO_GP(gpio.data) |
921 outw(reg, FM801_REG(chip, GPIO_CTRL)); 777 FM801_GPIO_GP(gpio.clk) |
922 udelay(1); 778 FM801_GPIO_GP(gpio.wren));
923 779 } else {
924 while (i--) { 780 /* use GPIO lines, set data direction to input */
925 if (val & (1 << i)) 781 reg |= FM801_GPIO_GD(gpio.data) |
926 reg |= FM801_GPIO_GP(TEA_64PCR_DATA); 782 FM801_GPIO_GD(gpio.most) |
927 else 783 FM801_GPIO_GP(gpio.data) |
928 reg &= ~FM801_GPIO_GP(TEA_64PCR_DATA); 784 FM801_GPIO_GP(gpio.most) |
929 outw(reg, FM801_REG(chip, GPIO_CTRL)); 785 FM801_GPIO_GP(gpio.wren);
930 udelay(1); 786 /* all of lines are in the write direction, except data */
931 reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); 787 /* clear data, write enable and clock lines */
932 outw(reg, FM801_REG(chip, GPIO_CTRL)); 788 reg &= ~(FM801_GPIO_GD(gpio.wren) |
933 reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); 789 FM801_GPIO_GD(gpio.clk) |
934 outw(reg, FM801_REG(chip, GPIO_CTRL)); 790 FM801_GPIO_GP(gpio.clk));
935 udelay(1);
936 }
937
938 /* and reset the write enable bit */
939 reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE) |
940 FM801_GPIO_GP(TEA_64PCR_DATA);
941 outw(reg, FM801_REG(chip, GPIO_CTRL));
942 spin_unlock_irq(&chip->reg_lock);
943}
944
945static unsigned int snd_fm801_tea575x_64pcr_read(struct snd_tea575x *tea)
946{
947 struct fm801 *chip = tea->private_data;
948 unsigned short reg;
949 unsigned int val = 0;
950 int i;
951
952 spin_lock_irq(&chip->reg_lock);
953 reg = inw(FM801_REG(chip, GPIO_CTRL));
954 /* use GPIO lines, set data direction to input */
955 reg |= FM801_GPIO_GS(TEA_64PCR_DATA) |
956 FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) |
957 FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK) |
958 FM801_GPIO_GD(TEA_64PCR_DATA) |
959 FM801_GPIO_GP(TEA_64PCR_DATA) |
960 FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
961 /* all of lines are in the write direction, except data */
962 /* clear data, write enable and clock lines */
963 reg &= ~(FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) |
964 FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) |
965 FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK));
966
967 for (i = 0; i < 24; i++) {
968 reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
969 outw(reg, FM801_REG(chip, GPIO_CTRL));
970 udelay(1);
971 reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
972 outw(reg, FM801_REG(chip, GPIO_CTRL));
973 udelay(1);
974 val <<= 1;
975 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_64PCR_DATA))
976 val |= 1;
977 } 791 }
978 792
979 spin_unlock_irq(&chip->reg_lock);
980
981 return val;
982}
983
984static void snd_fm801_tea575x_64pcr_mute(struct snd_tea575x *tea,
985 unsigned int mute)
986{
987 struct fm801 *chip = tea->private_data;
988 unsigned short reg;
989
990 spin_lock_irq(&chip->reg_lock);
991
992 reg = inw(FM801_REG(chip, GPIO_CTRL));
993 if (mute)
994 /* 0xf800 (mute) */
995 reg &= ~FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
996 else
997 /* 0xf802 (unmute) */
998 reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
999 outw(reg, FM801_REG(chip, GPIO_CTRL)); 793 outw(reg, FM801_REG(chip, GPIO_CTRL));
1000 udelay(1);
1001
1002 spin_unlock_irq(&chip->reg_lock);
1003} 794}
1004 795
1005static struct snd_tea575x_ops snd_fm801_tea_ops[3] = { 796static struct snd_tea575x_ops snd_fm801_tea_ops = {
1006 { 797 .set_pins = snd_fm801_tea575x_set_pins,
1007 /* 1 = MediaForte 256-PCS */ 798 .get_pins = snd_fm801_tea575x_get_pins,
1008 .write = snd_fm801_tea575x_256pcs_write, 799 .set_direction = snd_fm801_tea575x_set_direction,
1009 .read = snd_fm801_tea575x_256pcs_read,
1010 },
1011 {
1012 /* 2 = MediaForte 256-PCPR */
1013 .write = snd_fm801_tea575x_256pcpr_write,
1014 .read = snd_fm801_tea575x_256pcpr_read,
1015 },
1016 {
1017 /* 3 = MediaForte 64-PCR */
1018 .write = snd_fm801_tea575x_64pcr_write,
1019 .read = snd_fm801_tea575x_64pcr_read,
1020 .mute = snd_fm801_tea575x_64pcr_mute,
1021 }
1022}; 800};
1023#endif 801#endif
1024 802
@@ -1371,7 +1149,7 @@ static int snd_fm801_free(struct fm801 *chip)
1371 outw(cmdw, FM801_REG(chip, IRQ_MASK)); 1149 outw(cmdw, FM801_REG(chip, IRQ_MASK));
1372 1150
1373 __end_hw: 1151 __end_hw:
1374#ifdef TEA575X_RADIO 1152#ifdef CONFIG_SND_FM801_TEA575X_BOOL
1375 snd_tea575x_exit(&chip->tea); 1153 snd_tea575x_exit(&chip->tea);
1376#endif 1154#endif
1377 if (chip->irq >= 0) 1155 if (chip->irq >= 0)
@@ -1450,16 +1228,34 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1450 1228
1451 snd_card_set_dev(card, &pci->dev); 1229 snd_card_set_dev(card, &pci->dev);
1452 1230
1453#ifdef TEA575X_RADIO 1231#ifdef CONFIG_SND_FM801_TEA575X_BOOL
1232 chip->tea.private_data = chip;
1233 chip->tea.ops = &snd_fm801_tea_ops;
1234 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
1454 if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && 1235 if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 &&
1455 (tea575x_tuner & TUNER_TYPE_MASK) < 4) { 1236 (tea575x_tuner & TUNER_TYPE_MASK) < 4) {
1456 chip->tea.dev_nr = tea575x_tuner >> 16; 1237 if (snd_tea575x_init(&chip->tea)) {
1457 chip->tea.card = card; 1238 snd_printk(KERN_ERR "TEA575x radio not found\n");
1458 chip->tea.freq_fixup = 10700; 1239 snd_fm801_free(chip);
1459 chip->tea.private_data = chip; 1240 return -ENODEV;
1460 chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & TUNER_TYPE_MASK) - 1]; 1241 }
1461 snd_tea575x_init(&chip->tea); 1242 } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) {
1243 /* autodetect tuner connection */
1244 for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) {
1245 chip->tea575x_tuner = tea575x_tuner;
1246 if (!snd_tea575x_init(&chip->tea)) {
1247 snd_printk(KERN_INFO "detected TEA575x radio type %s\n",
1248 snd_fm801_tea575x_gpios[tea575x_tuner - 1].name);
1249 break;
1250 }
1251 }
1252 if (tea575x_tuner == 4) {
1253 snd_printk(KERN_ERR "TEA575x radio not found\n");
1254 snd_fm801_free(chip);
1255 return -ENODEV;
1256 }
1462 } 1257 }
1258 strlcpy(chip->tea.card, snd_fm801_tea575x_gpios[(tea575x_tuner & TUNER_TYPE_MASK) - 1].name, sizeof(chip->tea.card));
1463#endif 1259#endif
1464 1260
1465 *rchip = chip; 1261 *rchip = chip;
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 9194c3c1d04a..0ea5cc60ac78 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -119,47 +119,20 @@ config SND_HDA_CODEC_VIA
119 snd-hda-codec-via. 119 snd-hda-codec-via.
120 This module is automatically loaded at probing. 120 This module is automatically loaded at probing.
121 121
122config SND_HDA_CODEC_ATIHDMI 122config SND_HDA_CODEC_HDMI
123 bool "Build ATI HDMI HD-audio codec support" 123 bool "Build HDMI/DisplayPort HD-audio codec support"
124 default y
125 help
126 Say Y here to include ATI HDMI HD-audio codec support in
127 snd-hda-intel driver, such as ATI RS600 HDMI.
128
129 When the HD-audio driver is built as a module, the codec
130 support code is also built as another module,
131 snd-hda-codec-atihdmi.
132 This module is automatically loaded at probing.
133
134config SND_HDA_CODEC_NVHDMI
135 bool "Build NVIDIA HDMI HD-audio codec support"
136 default y
137 help
138 Say Y here to include NVIDIA HDMI HD-audio codec support in
139 snd-hda-intel driver, such as NVIDIA MCP78 HDMI.
140
141 When the HD-audio driver is built as a module, the codec
142 support code is also built as another module,
143 snd-hda-codec-nvhdmi.
144 This module is automatically loaded at probing.
145
146config SND_HDA_CODEC_INTELHDMI
147 bool "Build INTEL HDMI HD-audio codec support"
148 select SND_DYNAMIC_MINORS 124 select SND_DYNAMIC_MINORS
149 default y 125 default y
150 help 126 help
151 Say Y here to include INTEL HDMI HD-audio codec support in 127 Say Y here to include HDMI and DisplayPort HD-audio codec
152 snd-hda-intel driver, such as Eaglelake integrated HDMI. 128 support in snd-hda-intel driver. This includes all AMD/ATI,
129 Intel and Nvidia HDMI/DisplayPort codecs.
153 130
154 When the HD-audio driver is built as a module, the codec 131 When the HD-audio driver is built as a module, the codec
155 support code is also built as another module, 132 support code is also built as another module,
156 snd-hda-codec-intelhdmi. 133 snd-hda-codec-hdmi.
157 This module is automatically loaded at probing. 134 This module is automatically loaded at probing.
158 135
159config SND_HDA_ELD
160 def_bool y
161 depends on SND_HDA_CODEC_INTELHDMI || SND_HDA_CODEC_NVHDMI
162
163config SND_HDA_CODEC_CIRRUS 136config SND_HDA_CODEC_CIRRUS
164 bool "Build Cirrus Logic codec support" 137 bool "Build Cirrus Logic codec support"
165 depends on SND_HDA_INTEL 138 depends on SND_HDA_INTEL
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 24bc195b02da..17ef3658f34b 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -3,7 +3,6 @@ snd-hda-intel-objs := hda_intel.o
3snd-hda-codec-y := hda_codec.o 3snd-hda-codec-y := hda_codec.o
4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o 4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o 5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
6snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o
7snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o 6snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
8snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o 7snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
9 8
@@ -12,13 +11,11 @@ snd-hda-codec-cmedia-objs := patch_cmedia.o
12snd-hda-codec-analog-objs := patch_analog.o 11snd-hda-codec-analog-objs := patch_analog.o
13snd-hda-codec-idt-objs := patch_sigmatel.o 12snd-hda-codec-idt-objs := patch_sigmatel.o
14snd-hda-codec-si3054-objs := patch_si3054.o 13snd-hda-codec-si3054-objs := patch_si3054.o
15snd-hda-codec-atihdmi-objs := patch_atihdmi.o
16snd-hda-codec-cirrus-objs := patch_cirrus.o 14snd-hda-codec-cirrus-objs := patch_cirrus.o
17snd-hda-codec-ca0110-objs := patch_ca0110.o 15snd-hda-codec-ca0110-objs := patch_ca0110.o
18snd-hda-codec-conexant-objs := patch_conexant.o 16snd-hda-codec-conexant-objs := patch_conexant.o
19snd-hda-codec-via-objs := patch_via.o 17snd-hda-codec-via-objs := patch_via.o
20snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o 18snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o
21snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o
22 19
23# common driver 20# common driver
24obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o 21obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o
@@ -39,9 +36,6 @@ endif
39ifdef CONFIG_SND_HDA_CODEC_SI3054 36ifdef CONFIG_SND_HDA_CODEC_SI3054
40obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-si3054.o 37obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-si3054.o
41endif 38endif
42ifdef CONFIG_SND_HDA_CODEC_ATIHDMI
43obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o
44endif
45ifdef CONFIG_SND_HDA_CODEC_CIRRUS 39ifdef CONFIG_SND_HDA_CODEC_CIRRUS
46obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cirrus.o 40obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cirrus.o
47endif 41endif
@@ -54,11 +48,8 @@ endif
54ifdef CONFIG_SND_HDA_CODEC_VIA 48ifdef CONFIG_SND_HDA_CODEC_VIA
55obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-via.o 49obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-via.o
56endif 50endif
57ifdef CONFIG_SND_HDA_CODEC_NVHDMI 51ifdef CONFIG_SND_HDA_CODEC_HDMI
58obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-nvhdmi.o 52obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-hdmi.o
59endif
60ifdef CONFIG_SND_HDA_CODEC_INTELHDMI
61obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-intelhdmi.o
62endif 53endif
63 54
64# this must be the last entry after codec drivers; 55# this must be the last entry after codec drivers;
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
index f1de1bac042c..55f0647458c7 100644
--- a/sound/pci/hda/hda_beep.h
+++ b/sound/pci/hda/hda_beep.h
@@ -50,7 +50,12 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable);
50int snd_hda_attach_beep_device(struct hda_codec *codec, int nid); 50int snd_hda_attach_beep_device(struct hda_codec *codec, int nid);
51void snd_hda_detach_beep_device(struct hda_codec *codec); 51void snd_hda_detach_beep_device(struct hda_codec *codec);
52#else 52#else
53#define snd_hda_attach_beep_device(...) 0 53static inline int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
54#define snd_hda_detach_beep_device(...) 54{
55 return 0;
56}
57static inline void snd_hda_detach_beep_device(struct hda_codec *codec)
58{
59}
55#endif 60#endif
56#endif 61#endif
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 14829210ef0b..45b4a8d70e08 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -29,6 +29,7 @@
29#include <sound/asoundef.h> 29#include <sound/asoundef.h>
30#include <sound/tlv.h> 30#include <sound/tlv.h>
31#include <sound/initval.h> 31#include <sound/initval.h>
32#include <sound/jack.h>
32#include "hda_local.h" 33#include "hda_local.h"
33#include "hda_beep.h" 34#include "hda_beep.h"
34#include <sound/hda_hwdep.h> 35#include <sound/hda_hwdep.h>
@@ -306,6 +307,12 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
306} 307}
307EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); 308EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes);
308 309
310static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
311 hda_nid_t *conn_list, int max_conns);
312static bool add_conn_list(struct snd_array *array, hda_nid_t nid);
313static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst,
314 hda_nid_t *src, int len);
315
309/** 316/**
310 * snd_hda_get_connections - get connection list 317 * snd_hda_get_connections - get connection list
311 * @codec: the HDA codec 318 * @codec: the HDA codec
@@ -319,7 +326,44 @@ EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes);
319 * Returns the number of connections, or a negative error code. 326 * Returns the number of connections, or a negative error code.
320 */ 327 */
321int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 328int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
322 hda_nid_t *conn_list, int max_conns) 329 hda_nid_t *conn_list, int max_conns)
330{
331 struct snd_array *array = &codec->conn_lists;
332 int i, len, old_used;
333 hda_nid_t list[HDA_MAX_CONNECTIONS];
334
335 /* look up the cached results */
336 for (i = 0; i < array->used; ) {
337 hda_nid_t *p = snd_array_elem(array, i);
338 len = p[1];
339 if (nid == *p)
340 return copy_conn_list(nid, conn_list, max_conns,
341 p + 2, len);
342 i += len + 2;
343 }
344
345 len = _hda_get_connections(codec, nid, list, HDA_MAX_CONNECTIONS);
346 if (len < 0)
347 return len;
348
349 /* add to the cache */
350 old_used = array->used;
351 if (!add_conn_list(array, nid) || !add_conn_list(array, len))
352 goto error_add;
353 for (i = 0; i < len; i++)
354 if (!add_conn_list(array, list[i]))
355 goto error_add;
356
357 return copy_conn_list(nid, conn_list, max_conns, list, len);
358
359 error_add:
360 array->used = old_used;
361 return -ENOMEM;
362}
363EXPORT_SYMBOL_HDA(snd_hda_get_connections);
364
365static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
366 hda_nid_t *conn_list, int max_conns)
323{ 367{
324 unsigned int parm; 368 unsigned int parm;
325 int i, conn_len, conns; 369 int i, conn_len, conns;
@@ -416,8 +460,28 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
416 } 460 }
417 return conns; 461 return conns;
418} 462}
419EXPORT_SYMBOL_HDA(snd_hda_get_connections);
420 463
464static bool add_conn_list(struct snd_array *array, hda_nid_t nid)
465{
466 hda_nid_t *p = snd_array_new(array);
467 if (!p)
468 return false;
469 *p = nid;
470 return true;
471}
472
473static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst,
474 hda_nid_t *src, int len)
475{
476 if (len > max_dst) {
477 snd_printk(KERN_ERR "hda_codec: "
478 "Too many connections %d for NID 0x%x\n",
479 len, nid);
480 return -EINVAL;
481 }
482 memcpy(dst, src, len * sizeof(hda_nid_t));
483 return len;
484}
421 485
422/** 486/**
423 * snd_hda_queue_unsol_event - add an unsolicited event to queue 487 * snd_hda_queue_unsol_event - add an unsolicited event to queue
@@ -936,6 +1000,7 @@ void snd_hda_shutup_pins(struct hda_codec *codec)
936} 1000}
937EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); 1001EXPORT_SYMBOL_HDA(snd_hda_shutup_pins);
938 1002
1003#ifdef SND_HDA_NEEDS_RESUME
939/* Restore the pin controls cleared previously via snd_hda_shutup_pins() */ 1004/* Restore the pin controls cleared previously via snd_hda_shutup_pins() */
940static void restore_shutup_pins(struct hda_codec *codec) 1005static void restore_shutup_pins(struct hda_codec *codec)
941{ 1006{
@@ -952,6 +1017,7 @@ static void restore_shutup_pins(struct hda_codec *codec)
952 } 1017 }
953 codec->pins_shutup = 0; 1018 codec->pins_shutup = 0;
954} 1019}
1020#endif
955 1021
956static void init_hda_cache(struct hda_cache_rec *cache, 1022static void init_hda_cache(struct hda_cache_rec *cache,
957 unsigned int record_size); 1023 unsigned int record_size);
@@ -1016,6 +1082,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
1016 list_del(&codec->list); 1082 list_del(&codec->list);
1017 snd_array_free(&codec->mixers); 1083 snd_array_free(&codec->mixers);
1018 snd_array_free(&codec->nids); 1084 snd_array_free(&codec->nids);
1085 snd_array_free(&codec->conn_lists);
1019 codec->bus->caddr_tbl[codec->addr] = NULL; 1086 codec->bus->caddr_tbl[codec->addr] = NULL;
1020 if (codec->patch_ops.free) 1087 if (codec->patch_ops.free)
1021 codec->patch_ops.free(codec); 1088 codec->patch_ops.free(codec);
@@ -1076,6 +1143,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
1076 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); 1143 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
1077 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); 1144 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
1078 snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); 1145 snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
1146 snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64);
1079 if (codec->bus->modelname) { 1147 if (codec->bus->modelname) {
1080 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); 1148 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
1081 if (!codec->modelname) { 1149 if (!codec->modelname) {
@@ -1216,6 +1284,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
1216 struct hda_codec *c; 1284 struct hda_codec *c;
1217 struct hda_cvt_setup *p; 1285 struct hda_cvt_setup *p;
1218 unsigned int oldval, newval; 1286 unsigned int oldval, newval;
1287 int type;
1219 int i; 1288 int i;
1220 1289
1221 if (!nid) 1290 if (!nid)
@@ -1254,10 +1323,12 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
1254 p->dirty = 0; 1323 p->dirty = 0;
1255 1324
1256 /* make other inactive cvts with the same stream-tag dirty */ 1325 /* make other inactive cvts with the same stream-tag dirty */
1326 type = get_wcaps_type(get_wcaps(codec, nid));
1257 list_for_each_entry(c, &codec->bus->codec_list, list) { 1327 list_for_each_entry(c, &codec->bus->codec_list, list) {
1258 for (i = 0; i < c->cvt_setups.used; i++) { 1328 for (i = 0; i < c->cvt_setups.used; i++) {
1259 p = snd_array_elem(&c->cvt_setups, i); 1329 p = snd_array_elem(&c->cvt_setups, i);
1260 if (!p->active && p->stream_tag == stream_tag) 1330 if (!p->active && p->stream_tag == stream_tag &&
1331 get_wcaps_type(get_wcaps(codec, p->nid)) == type)
1261 p->dirty = 1; 1332 p->dirty = 1;
1262 } 1333 }
1263 } 1334 }
@@ -1281,6 +1352,9 @@ void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
1281 if (!nid) 1352 if (!nid)
1282 return; 1353 return;
1283 1354
1355 if (codec->no_sticky_stream)
1356 do_now = 1;
1357
1284 snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid); 1358 snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid);
1285 p = get_hda_cvt_setup(codec, nid); 1359 p = get_hda_cvt_setup(codec, nid);
1286 if (p) { 1360 if (p) {
@@ -1322,6 +1396,7 @@ static void purify_inactive_streams(struct hda_codec *codec)
1322 } 1396 }
1323} 1397}
1324 1398
1399#ifdef SND_HDA_NEEDS_RESUME
1325/* clean up all streams; called from suspend */ 1400/* clean up all streams; called from suspend */
1326static void hda_cleanup_all_streams(struct hda_codec *codec) 1401static void hda_cleanup_all_streams(struct hda_codec *codec)
1327{ 1402{
@@ -1333,6 +1408,7 @@ static void hda_cleanup_all_streams(struct hda_codec *codec)
1333 really_cleanup_stream(codec, p); 1408 really_cleanup_stream(codec, p);
1334 } 1409 }
1335} 1410}
1411#endif
1336 1412
1337/* 1413/*
1338 * amp access functions 1414 * amp access functions
@@ -1831,6 +1907,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1831 hda_nid_t nid = get_amp_nid(kcontrol); 1907 hda_nid_t nid = get_amp_nid(kcontrol);
1832 int dir = get_amp_direction(kcontrol); 1908 int dir = get_amp_direction(kcontrol);
1833 unsigned int ofs = get_amp_offset(kcontrol); 1909 unsigned int ofs = get_amp_offset(kcontrol);
1910 bool min_mute = get_amp_min_mute(kcontrol);
1834 u32 caps, val1, val2; 1911 u32 caps, val1, val2;
1835 1912
1836 if (size < 4 * sizeof(unsigned int)) 1913 if (size < 4 * sizeof(unsigned int))
@@ -1841,6 +1918,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1841 val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); 1918 val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
1842 val1 += ofs; 1919 val1 += ofs;
1843 val1 = ((int)val1) * ((int)val2); 1920 val1 = ((int)val1) * ((int)val2);
1921 if (min_mute)
1922 val2 |= TLV_DB_SCALE_MUTE;
1844 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) 1923 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
1845 return -EFAULT; 1924 return -EFAULT;
1846 if (put_user(2 * sizeof(unsigned int), _tlv + 1)) 1925 if (put_user(2 * sizeof(unsigned int), _tlv + 1))
@@ -1910,6 +1989,16 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1910} 1989}
1911EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); 1990EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
1912 1991
1992static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name)
1993{
1994 int idx;
1995 for (idx = 0; idx < 16; idx++) { /* 16 ctlrs should be large enough */
1996 if (!_snd_hda_find_mixer_ctl(codec, name, idx))
1997 return idx;
1998 }
1999 return -EBUSY;
2000}
2001
1913/** 2002/**
1914 * snd_hda_ctl_add - Add a control element and assign to the codec 2003 * snd_hda_ctl_add - Add a control element and assign to the codec
1915 * @codec: HD-audio codec 2004 * @codec: HD-audio codec
@@ -2115,10 +2204,10 @@ int snd_hda_codec_reset(struct hda_codec *codec)
2115 * This function returns zero if successful or a negative error code. 2204 * This function returns zero if successful or a negative error code.
2116 */ 2205 */
2117int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 2206int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
2118 unsigned int *tlv, const char **slaves) 2207 unsigned int *tlv, const char * const *slaves)
2119{ 2208{
2120 struct snd_kcontrol *kctl; 2209 struct snd_kcontrol *kctl;
2121 const char **s; 2210 const char * const *s;
2122 int err; 2211 int err;
2123 2212
2124 for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) 2213 for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++)
@@ -2228,10 +2317,7 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
2228 change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, 2317 change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
2229 HDA_AMP_MUTE, 2318 HDA_AMP_MUTE,
2230 *valp ? 0 : HDA_AMP_MUTE); 2319 *valp ? 0 : HDA_AMP_MUTE);
2231#ifdef CONFIG_SND_HDA_POWER_SAVE 2320 hda_call_check_power_status(codec, nid);
2232 if (codec->patch_ops.check_power_status)
2233 codec->patch_ops.check_power_status(codec, nid);
2234#endif
2235 snd_hda_power_down(codec); 2321 snd_hda_power_down(codec);
2236 return change; 2322 return change;
2237} 2323}
@@ -2535,7 +2621,7 @@ static unsigned int convert_to_spdif_status(unsigned short val)
2535static void set_dig_out(struct hda_codec *codec, hda_nid_t nid, 2621static void set_dig_out(struct hda_codec *codec, hda_nid_t nid,
2536 int verb, int val) 2622 int verb, int val)
2537{ 2623{
2538 hda_nid_t *d; 2624 const hda_nid_t *d;
2539 2625
2540 snd_hda_codec_write_cache(codec, nid, 0, verb, val); 2626 snd_hda_codec_write_cache(codec, nid, 0, verb, val);
2541 d = codec->slave_dig_outs; 2627 d = codec->slave_dig_outs;
@@ -2648,8 +2734,6 @@ static struct snd_kcontrol_new dig_mixes[] = {
2648 { } /* end */ 2734 { } /* end */
2649}; 2735};
2650 2736
2651#define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */
2652
2653/** 2737/**
2654 * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls 2738 * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls
2655 * @codec: the HDA codec 2739 * @codec: the HDA codec
@@ -2667,12 +2751,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
2667 struct snd_kcontrol_new *dig_mix; 2751 struct snd_kcontrol_new *dig_mix;
2668 int idx; 2752 int idx;
2669 2753
2670 for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { 2754 idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch");
2671 if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch", 2755 if (idx < 0) {
2672 idx))
2673 break;
2674 }
2675 if (idx >= SPDIF_MAX_IDX) {
2676 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); 2756 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
2677 return -EBUSY; 2757 return -EBUSY;
2678 } 2758 }
@@ -2823,12 +2903,8 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
2823 struct snd_kcontrol_new *dig_mix; 2903 struct snd_kcontrol_new *dig_mix;
2824 int idx; 2904 int idx;
2825 2905
2826 for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { 2906 idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch");
2827 if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch", 2907 if (idx < 0) {
2828 idx))
2829 break;
2830 }
2831 if (idx >= SPDIF_MAX_IDX) {
2832 printk(KERN_ERR "hda_codec: too many IEC958 inputs\n"); 2908 printk(KERN_ERR "hda_codec: too many IEC958 inputs\n");
2833 return -EBUSY; 2909 return -EBUSY;
2834 } 2910 }
@@ -3654,7 +3730,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
3654 * with the proper parameters for set up. 3730 * with the proper parameters for set up.
3655 * ops.cleanup should be called in hw_free for clean up of streams. 3731 * ops.cleanup should be called in hw_free for clean up of streams.
3656 * 3732 *
3657 * This function returns 0 if successfull, or a negative error code. 3733 * This function returns 0 if successful, or a negative error code.
3658 */ 3734 */
3659int __devinit snd_hda_build_pcms(struct hda_bus *bus) 3735int __devinit snd_hda_build_pcms(struct hda_bus *bus)
3660{ 3736{
@@ -3683,7 +3759,7 @@ EXPORT_SYMBOL_HDA(snd_hda_build_pcms);
3683 * If no entries are matching, the function returns a negative value. 3759 * If no entries are matching, the function returns a negative value.
3684 */ 3760 */
3685int snd_hda_check_board_config(struct hda_codec *codec, 3761int snd_hda_check_board_config(struct hda_codec *codec,
3686 int num_configs, const char **models, 3762 int num_configs, const char * const *models,
3687 const struct snd_pci_quirk *tbl) 3763 const struct snd_pci_quirk *tbl)
3688{ 3764{
3689 if (codec->modelname && models) { 3765 if (codec->modelname && models) {
@@ -3747,7 +3823,7 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
3747 * If no entries are matching, the function returns a negative value. 3823 * If no entries are matching, the function returns a negative value.
3748 */ 3824 */
3749int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, 3825int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
3750 int num_configs, const char **models, 3826 int num_configs, const char * const *models,
3751 const struct snd_pci_quirk *tbl) 3827 const struct snd_pci_quirk *tbl)
3752{ 3828{
3753 const struct snd_pci_quirk *q; 3829 const struct snd_pci_quirk *q;
@@ -3796,27 +3872,39 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config);
3796 * 3872 *
3797 * Returns 0 if successful, or a negative error code. 3873 * Returns 0 if successful, or a negative error code.
3798 */ 3874 */
3799int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) 3875int snd_hda_add_new_ctls(struct hda_codec *codec,
3876 const struct snd_kcontrol_new *knew)
3800{ 3877{
3801 int err; 3878 int err;
3802 3879
3803 for (; knew->name; knew++) { 3880 for (; knew->name; knew++) {
3804 struct snd_kcontrol *kctl; 3881 struct snd_kcontrol *kctl;
3882 int addr = 0, idx = 0;
3805 if (knew->iface == -1) /* skip this codec private value */ 3883 if (knew->iface == -1) /* skip this codec private value */
3806 continue; 3884 continue;
3807 kctl = snd_ctl_new1(knew, codec); 3885 for (;;) {
3808 if (!kctl)
3809 return -ENOMEM;
3810 err = snd_hda_ctl_add(codec, 0, kctl);
3811 if (err < 0) {
3812 if (!codec->addr)
3813 return err;
3814 kctl = snd_ctl_new1(knew, codec); 3886 kctl = snd_ctl_new1(knew, codec);
3815 if (!kctl) 3887 if (!kctl)
3816 return -ENOMEM; 3888 return -ENOMEM;
3817 kctl->id.device = codec->addr; 3889 if (addr > 0)
3890 kctl->id.device = addr;
3891 if (idx > 0)
3892 kctl->id.index = idx;
3818 err = snd_hda_ctl_add(codec, 0, kctl); 3893 err = snd_hda_ctl_add(codec, 0, kctl);
3819 if (err < 0) 3894 if (!err)
3895 break;
3896 /* try first with another device index corresponding to
3897 * the codec addr; if it still fails (or it's the
3898 * primary codec), then try another control index
3899 */
3900 if (!addr && codec->addr)
3901 addr = codec->addr;
3902 else if (!idx && !knew->index) {
3903 idx = find_empty_mixer_ctl_idx(codec,
3904 knew->name);
3905 if (idx <= 0)
3906 return err;
3907 } else
3820 return err; 3908 return err;
3821 } 3909 }
3822 } 3910 }
@@ -3928,7 +4016,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
3928 struct hda_loopback_check *check, 4016 struct hda_loopback_check *check,
3929 hda_nid_t nid) 4017 hda_nid_t nid)
3930{ 4018{
3931 struct hda_amp_list *p; 4019 const struct hda_amp_list *p;
3932 int ch, v; 4020 int ch, v;
3933 4021
3934 if (!check->amplist) 4022 if (!check->amplist)
@@ -4096,7 +4184,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
4096 -1); 4184 -1);
4097 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 4185 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
4098 if (codec->slave_dig_outs) { 4186 if (codec->slave_dig_outs) {
4099 hda_nid_t *d; 4187 const hda_nid_t *d;
4100 for (d = codec->slave_dig_outs; *d; d++) 4188 for (d = codec->slave_dig_outs; *d; d++)
4101 snd_hda_codec_setup_stream(codec, *d, stream_tag, 0, 4189 snd_hda_codec_setup_stream(codec, *d, stream_tag, 0,
4102 format); 4190 format);
@@ -4111,7 +4199,7 @@ static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
4111{ 4199{
4112 snd_hda_codec_cleanup_stream(codec, nid); 4200 snd_hda_codec_cleanup_stream(codec, nid);
4113 if (codec->slave_dig_outs) { 4201 if (codec->slave_dig_outs) {
4114 hda_nid_t *d; 4202 const hda_nid_t *d;
4115 for (d = codec->slave_dig_outs; *d; d++) 4203 for (d = codec->slave_dig_outs; *d; d++)
4116 snd_hda_codec_cleanup_stream(codec, *d); 4204 snd_hda_codec_cleanup_stream(codec, *d);
4117 } 4205 }
@@ -4258,7 +4346,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
4258 unsigned int format, 4346 unsigned int format,
4259 struct snd_pcm_substream *substream) 4347 struct snd_pcm_substream *substream)
4260{ 4348{
4261 hda_nid_t *nids = mout->dac_nids; 4349 const hda_nid_t *nids = mout->dac_nids;
4262 int chs = substream->runtime->channels; 4350 int chs = substream->runtime->channels;
4263 int i; 4351 int i;
4264 4352
@@ -4313,7 +4401,7 @@ EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_prepare);
4313int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, 4401int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
4314 struct hda_multi_out *mout) 4402 struct hda_multi_out *mout)
4315{ 4403{
4316 hda_nid_t *nids = mout->dac_nids; 4404 const hda_nid_t *nids = mout->dac_nids;
4317 int i; 4405 int i;
4318 4406
4319 for (i = 0; i < mout->num_dacs; i++) 4407 for (i = 0; i < mout->num_dacs; i++)
@@ -4338,7 +4426,7 @@ EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup);
4338 * Helper for automatic pin configuration 4426 * Helper for automatic pin configuration
4339 */ 4427 */
4340 4428
4341static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) 4429static int is_in_nid_list(hda_nid_t nid, const hda_nid_t *list)
4342{ 4430{
4343 for (; *list; list++) 4431 for (; *list; list++)
4344 if (*list == nid) 4432 if (*list == nid)
@@ -4372,6 +4460,34 @@ static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences,
4372} 4460}
4373 4461
4374 4462
4463/* add the found input-pin to the cfg->inputs[] table */
4464static void add_auto_cfg_input_pin(struct auto_pin_cfg *cfg, hda_nid_t nid,
4465 int type)
4466{
4467 if (cfg->num_inputs < AUTO_CFG_MAX_INS) {
4468 cfg->inputs[cfg->num_inputs].pin = nid;
4469 cfg->inputs[cfg->num_inputs].type = type;
4470 cfg->num_inputs++;
4471 }
4472}
4473
4474/* sort inputs in the order of AUTO_PIN_* type */
4475static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg)
4476{
4477 int i, j;
4478
4479 for (i = 0; i < cfg->num_inputs; i++) {
4480 for (j = i + 1; j < cfg->num_inputs; j++) {
4481 if (cfg->inputs[i].type > cfg->inputs[j].type) {
4482 struct auto_pin_cfg_item tmp;
4483 tmp = cfg->inputs[i];
4484 cfg->inputs[i] = cfg->inputs[j];
4485 cfg->inputs[j] = tmp;
4486 }
4487 }
4488 }
4489}
4490
4375/* 4491/*
4376 * Parse all pin widgets and store the useful pin nids to cfg 4492 * Parse all pin widgets and store the useful pin nids to cfg
4377 * 4493 *
@@ -4385,19 +4501,20 @@ static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences,
4385 * output, i.e. to line_out_pins[0]. So, line_outs is always positive 4501 * output, i.e. to line_out_pins[0]. So, line_outs is always positive
4386 * if any analog output exists. 4502 * if any analog output exists.
4387 * 4503 *
4388 * The analog input pins are assigned to input_pins array. 4504 * The analog input pins are assigned to inputs array.
4389 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, 4505 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
4390 * respectively. 4506 * respectively.
4391 */ 4507 */
4392int snd_hda_parse_pin_def_config(struct hda_codec *codec, 4508int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4393 struct auto_pin_cfg *cfg, 4509 struct auto_pin_cfg *cfg,
4394 hda_nid_t *ignore_nids) 4510 const hda_nid_t *ignore_nids)
4395{ 4511{
4396 hda_nid_t nid, end_nid; 4512 hda_nid_t nid, end_nid;
4397 short seq, assoc_line_out, assoc_speaker; 4513 short seq, assoc_line_out, assoc_speaker;
4398 short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; 4514 short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)];
4399 short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; 4515 short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)];
4400 short sequences_hp[ARRAY_SIZE(cfg->hp_pins)]; 4516 short sequences_hp[ARRAY_SIZE(cfg->hp_pins)];
4517 int i;
4401 4518
4402 memset(cfg, 0, sizeof(*cfg)); 4519 memset(cfg, 0, sizeof(*cfg));
4403 4520
@@ -4468,33 +4585,17 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4468 sequences_hp[cfg->hp_outs] = (assoc << 4) | seq; 4585 sequences_hp[cfg->hp_outs] = (assoc << 4) | seq;
4469 cfg->hp_outs++; 4586 cfg->hp_outs++;
4470 break; 4587 break;
4471 case AC_JACK_MIC_IN: { 4588 case AC_JACK_MIC_IN:
4472 int preferred, alt; 4589 add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_MIC);
4473 if (loc == AC_JACK_LOC_FRONT ||
4474 (loc & 0x30) == AC_JACK_LOC_INTERNAL) {
4475 preferred = AUTO_PIN_FRONT_MIC;
4476 alt = AUTO_PIN_MIC;
4477 } else {
4478 preferred = AUTO_PIN_MIC;
4479 alt = AUTO_PIN_FRONT_MIC;
4480 }
4481 if (!cfg->input_pins[preferred])
4482 cfg->input_pins[preferred] = nid;
4483 else if (!cfg->input_pins[alt])
4484 cfg->input_pins[alt] = nid;
4485 break; 4590 break;
4486 }
4487 case AC_JACK_LINE_IN: 4591 case AC_JACK_LINE_IN:
4488 if (loc == AC_JACK_LOC_FRONT) 4592 add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_LINE_IN);
4489 cfg->input_pins[AUTO_PIN_FRONT_LINE] = nid;
4490 else
4491 cfg->input_pins[AUTO_PIN_LINE] = nid;
4492 break; 4593 break;
4493 case AC_JACK_CD: 4594 case AC_JACK_CD:
4494 cfg->input_pins[AUTO_PIN_CD] = nid; 4595 add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_CD);
4495 break; 4596 break;
4496 case AC_JACK_AUX: 4597 case AC_JACK_AUX:
4497 cfg->input_pins[AUTO_PIN_AUX] = nid; 4598 add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_AUX);
4498 break; 4599 break;
4499 case AC_JACK_SPDIF_OUT: 4600 case AC_JACK_SPDIF_OUT:
4500 case AC_JACK_DIG_OTHER_OUT: 4601 case AC_JACK_DIG_OTHER_OUT:
@@ -4539,6 +4640,11 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4539 memmove(sequences_hp + i, sequences_hp + i + 1, 4640 memmove(sequences_hp + i, sequences_hp + i + 1,
4540 sizeof(sequences_hp[0]) * (cfg->hp_outs - i)); 4641 sizeof(sequences_hp[0]) * (cfg->hp_outs - i));
4541 } 4642 }
4643 memset(cfg->hp_pins + cfg->hp_outs, 0,
4644 sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs));
4645 if (!cfg->hp_outs)
4646 cfg->line_out_type = AUTO_PIN_HP_OUT;
4647
4542 } 4648 }
4543 4649
4544 /* sort by sequence */ 4650 /* sort by sequence */
@@ -4549,21 +4655,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4549 sort_pins_by_sequence(cfg->hp_pins, sequences_hp, 4655 sort_pins_by_sequence(cfg->hp_pins, sequences_hp,
4550 cfg->hp_outs); 4656 cfg->hp_outs);
4551 4657
4552 /* if we have only one mic, make it AUTO_PIN_MIC */
4553 if (!cfg->input_pins[AUTO_PIN_MIC] &&
4554 cfg->input_pins[AUTO_PIN_FRONT_MIC]) {
4555 cfg->input_pins[AUTO_PIN_MIC] =
4556 cfg->input_pins[AUTO_PIN_FRONT_MIC];
4557 cfg->input_pins[AUTO_PIN_FRONT_MIC] = 0;
4558 }
4559 /* ditto for line-in */
4560 if (!cfg->input_pins[AUTO_PIN_LINE] &&
4561 cfg->input_pins[AUTO_PIN_FRONT_LINE]) {
4562 cfg->input_pins[AUTO_PIN_LINE] =
4563 cfg->input_pins[AUTO_PIN_FRONT_LINE];
4564 cfg->input_pins[AUTO_PIN_FRONT_LINE] = 0;
4565 }
4566
4567 /* 4658 /*
4568 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin 4659 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
4569 * as a primary output 4660 * as a primary output
@@ -4602,13 +4693,18 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4602 break; 4693 break;
4603 } 4694 }
4604 4695
4696 sort_autocfg_input_pins(cfg);
4697
4605 /* 4698 /*
4606 * debug prints of the parsed results 4699 * debug prints of the parsed results
4607 */ 4700 */
4608 snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", 4701 snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x) type:%s\n",
4609 cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], 4702 cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1],
4610 cfg->line_out_pins[2], cfg->line_out_pins[3], 4703 cfg->line_out_pins[2], cfg->line_out_pins[3],
4611 cfg->line_out_pins[4]); 4704 cfg->line_out_pins[4],
4705 cfg->line_out_type == AUTO_PIN_HP_OUT ? "hp" :
4706 (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ?
4707 "speaker" : "line"));
4612 snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", 4708 snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
4613 cfg->speaker_outs, cfg->speaker_pins[0], 4709 cfg->speaker_outs, cfg->speaker_pins[0],
4614 cfg->speaker_pins[1], cfg->speaker_pins[2], 4710 cfg->speaker_pins[1], cfg->speaker_pins[2],
@@ -4621,14 +4717,13 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4621 if (cfg->dig_outs) 4717 if (cfg->dig_outs)
4622 snd_printd(" dig-out=0x%x/0x%x\n", 4718 snd_printd(" dig-out=0x%x/0x%x\n",
4623 cfg->dig_out_pins[0], cfg->dig_out_pins[1]); 4719 cfg->dig_out_pins[0], cfg->dig_out_pins[1]);
4624 snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x," 4720 snd_printd(" inputs:");
4625 " cd=0x%x, aux=0x%x\n", 4721 for (i = 0; i < cfg->num_inputs; i++) {
4626 cfg->input_pins[AUTO_PIN_MIC], 4722 snd_printd(" %s=0x%x",
4627 cfg->input_pins[AUTO_PIN_FRONT_MIC], 4723 hda_get_autocfg_input_label(codec, cfg, i),
4628 cfg->input_pins[AUTO_PIN_LINE], 4724 cfg->inputs[i].pin);
4629 cfg->input_pins[AUTO_PIN_FRONT_LINE], 4725 }
4630 cfg->input_pins[AUTO_PIN_CD], 4726 snd_printd("\n");
4631 cfg->input_pins[AUTO_PIN_AUX]);
4632 if (cfg->dig_in_pin) 4727 if (cfg->dig_in_pin)
4633 snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin); 4728 snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin);
4634 4729
@@ -4636,11 +4731,165 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4636} 4731}
4637EXPORT_SYMBOL_HDA(snd_hda_parse_pin_def_config); 4732EXPORT_SYMBOL_HDA(snd_hda_parse_pin_def_config);
4638 4733
4639/* labels for input pins */ 4734int snd_hda_get_input_pin_attr(unsigned int def_conf)
4640const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = { 4735{
4641 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux" 4736 unsigned int loc = get_defcfg_location(def_conf);
4642}; 4737 unsigned int conn = get_defcfg_connect(def_conf);
4643EXPORT_SYMBOL_HDA(auto_pin_cfg_labels); 4738 if (conn == AC_JACK_PORT_NONE)
4739 return INPUT_PIN_ATTR_UNUSED;
4740 /* Windows may claim the internal mic to be BOTH, too */
4741 if (conn == AC_JACK_PORT_FIXED || conn == AC_JACK_PORT_BOTH)
4742 return INPUT_PIN_ATTR_INT;
4743 if ((loc & 0x30) == AC_JACK_LOC_INTERNAL)
4744 return INPUT_PIN_ATTR_INT;
4745 if ((loc & 0x30) == AC_JACK_LOC_SEPARATE)
4746 return INPUT_PIN_ATTR_DOCK;
4747 if (loc == AC_JACK_LOC_REAR)
4748 return INPUT_PIN_ATTR_REAR;
4749 if (loc == AC_JACK_LOC_FRONT)
4750 return INPUT_PIN_ATTR_FRONT;
4751 return INPUT_PIN_ATTR_NORMAL;
4752}
4753EXPORT_SYMBOL_HDA(snd_hda_get_input_pin_attr);
4754
4755/**
4756 * hda_get_input_pin_label - Give a label for the given input pin
4757 *
4758 * When check_location is true, the function checks the pin location
4759 * for mic and line-in pins, and set an appropriate prefix like "Front",
4760 * "Rear", "Internal".
4761 */
4762
4763const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin,
4764 int check_location)
4765{
4766 unsigned int def_conf;
4767 static const char * const mic_names[] = {
4768 "Internal Mic", "Dock Mic", "Mic", "Front Mic", "Rear Mic",
4769 };
4770 int attr;
4771
4772 def_conf = snd_hda_codec_get_pincfg(codec, pin);
4773
4774 switch (get_defcfg_device(def_conf)) {
4775 case AC_JACK_MIC_IN:
4776 if (!check_location)
4777 return "Mic";
4778 attr = snd_hda_get_input_pin_attr(def_conf);
4779 if (!attr)
4780 return "None";
4781 return mic_names[attr - 1];
4782 case AC_JACK_LINE_IN:
4783 if (!check_location)
4784 return "Line";
4785 attr = snd_hda_get_input_pin_attr(def_conf);
4786 if (!attr)
4787 return "None";
4788 if (attr == INPUT_PIN_ATTR_DOCK)
4789 return "Dock Line";
4790 return "Line";
4791 case AC_JACK_AUX:
4792 return "Aux";
4793 case AC_JACK_CD:
4794 return "CD";
4795 case AC_JACK_SPDIF_IN:
4796 return "SPDIF In";
4797 case AC_JACK_DIG_OTHER_IN:
4798 return "Digital In";
4799 default:
4800 return "Misc";
4801 }
4802}
4803EXPORT_SYMBOL_HDA(hda_get_input_pin_label);
4804
4805/* Check whether the location prefix needs to be added to the label.
4806 * If all mic-jacks are in the same location (e.g. rear panel), we don't
4807 * have to put "Front" prefix to each label. In such a case, returns false.
4808 */
4809static int check_mic_location_need(struct hda_codec *codec,
4810 const struct auto_pin_cfg *cfg,
4811 int input)
4812{
4813 unsigned int defc;
4814 int i, attr, attr2;
4815
4816 defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[input].pin);
4817 attr = snd_hda_get_input_pin_attr(defc);
4818 /* for internal or docking mics, we need locations */
4819 if (attr <= INPUT_PIN_ATTR_NORMAL)
4820 return 1;
4821
4822 attr = 0;
4823 for (i = 0; i < cfg->num_inputs; i++) {
4824 defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[i].pin);
4825 attr2 = snd_hda_get_input_pin_attr(defc);
4826 if (attr2 >= INPUT_PIN_ATTR_NORMAL) {
4827 if (attr && attr != attr2)
4828 return 1; /* different locations found */
4829 attr = attr2;
4830 }
4831 }
4832 return 0;
4833}
4834
4835/**
4836 * hda_get_autocfg_input_label - Get a label for the given input
4837 *
4838 * Get a label for the given input pin defined by the autocfg item.
4839 * Unlike hda_get_input_pin_label(), this function checks all inputs
4840 * defined in autocfg and avoids the redundant mic/line prefix as much as
4841 * possible.
4842 */
4843const char *hda_get_autocfg_input_label(struct hda_codec *codec,
4844 const struct auto_pin_cfg *cfg,
4845 int input)
4846{
4847 int type = cfg->inputs[input].type;
4848 int has_multiple_pins = 0;
4849
4850 if ((input > 0 && cfg->inputs[input - 1].type == type) ||
4851 (input < cfg->num_inputs - 1 && cfg->inputs[input + 1].type == type))
4852 has_multiple_pins = 1;
4853 if (has_multiple_pins && type == AUTO_PIN_MIC)
4854 has_multiple_pins &= check_mic_location_need(codec, cfg, input);
4855 return hda_get_input_pin_label(codec, cfg->inputs[input].pin,
4856 has_multiple_pins);
4857}
4858EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label);
4859
4860/**
4861 * snd_hda_add_imux_item - Add an item to input_mux
4862 *
4863 * When the same label is used already in the existing items, the number
4864 * suffix is appended to the label. This label index number is stored
4865 * to type_idx when non-NULL pointer is given.
4866 */
4867int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label,
4868 int index, int *type_idx)
4869{
4870 int i, label_idx = 0;
4871 if (imux->num_items >= HDA_MAX_NUM_INPUTS) {
4872 snd_printd(KERN_ERR "hda_codec: Too many imux items!\n");
4873 return -EINVAL;
4874 }
4875 for (i = 0; i < imux->num_items; i++) {
4876 if (!strncmp(label, imux->items[i].label, strlen(label)))
4877 label_idx++;
4878 }
4879 if (type_idx)
4880 *type_idx = label_idx;
4881 if (label_idx > 0)
4882 snprintf(imux->items[imux->num_items].label,
4883 sizeof(imux->items[imux->num_items].label),
4884 "%s %d", label, label_idx);
4885 else
4886 strlcpy(imux->items[imux->num_items].label, label,
4887 sizeof(imux->items[imux->num_items].label));
4888 imux->items[imux->num_items].index = index;
4889 imux->num_items++;
4890 return 0;
4891}
4892EXPORT_SYMBOL_HDA(snd_hda_add_imux_item);
4644 4893
4645 4894
4646#ifdef CONFIG_PM 4895#ifdef CONFIG_PM
@@ -4675,7 +4924,7 @@ EXPORT_SYMBOL_HDA(snd_hda_suspend);
4675 * 4924 *
4676 * Returns 0 if successful. 4925 * Returns 0 if successful.
4677 * 4926 *
4678 * This fucntion is defined only when POWER_SAVE isn't set. 4927 * This function is defined only when POWER_SAVE isn't set.
4679 * In the power-save mode, the codec is resumed dynamically. 4928 * In the power-save mode, the codec is resumed dynamically.
4680 */ 4929 */
4681int snd_hda_resume(struct hda_bus *bus) 4930int snd_hda_resume(struct hda_bus *bus)
@@ -4784,5 +5033,111 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen)
4784} 5033}
4785EXPORT_SYMBOL_HDA(snd_print_pcm_bits); 5034EXPORT_SYMBOL_HDA(snd_print_pcm_bits);
4786 5035
5036#ifdef CONFIG_SND_HDA_INPUT_JACK
5037/*
5038 * Input-jack notification support
5039 */
5040struct hda_jack_item {
5041 hda_nid_t nid;
5042 int type;
5043 struct snd_jack *jack;
5044};
5045
5046static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid,
5047 int type)
5048{
5049 switch (type) {
5050 case SND_JACK_HEADPHONE:
5051 return "Headphone";
5052 case SND_JACK_MICROPHONE:
5053 return "Mic";
5054 case SND_JACK_LINEOUT:
5055 return "Line-out";
5056 case SND_JACK_HEADSET:
5057 return "Headset";
5058 case SND_JACK_VIDEOOUT:
5059 return "HDMI/DP";
5060 default:
5061 return "Misc";
5062 }
5063}
5064
5065static void hda_free_jack_priv(struct snd_jack *jack)
5066{
5067 struct hda_jack_item *jacks = jack->private_data;
5068 jacks->nid = 0;
5069 jacks->jack = NULL;
5070}
5071
5072int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type,
5073 const char *name)
5074{
5075 struct hda_jack_item *jack;
5076 int err;
5077
5078 snd_array_init(&codec->jacks, sizeof(*jack), 32);
5079 jack = snd_array_new(&codec->jacks);
5080 if (!jack)
5081 return -ENOMEM;
5082
5083 jack->nid = nid;
5084 jack->type = type;
5085 if (!name)
5086 name = get_jack_default_name(codec, nid, type);
5087 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
5088 if (err < 0) {
5089 jack->nid = 0;
5090 return err;
5091 }
5092 jack->jack->private_data = jack;
5093 jack->jack->private_free = hda_free_jack_priv;
5094 return 0;
5095}
5096EXPORT_SYMBOL_HDA(snd_hda_input_jack_add);
5097
5098void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid)
5099{
5100 struct hda_jack_item *jacks = codec->jacks.list;
5101 int i;
5102
5103 if (!jacks)
5104 return;
5105
5106 for (i = 0; i < codec->jacks.used; i++, jacks++) {
5107 unsigned int pin_ctl;
5108 unsigned int present;
5109 int type;
5110
5111 if (jacks->nid != nid)
5112 continue;
5113 present = snd_hda_jack_detect(codec, nid);
5114 type = jacks->type;
5115 if (type == (SND_JACK_HEADPHONE | SND_JACK_LINEOUT)) {
5116 pin_ctl = snd_hda_codec_read(codec, nid, 0,
5117 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5118 type = (pin_ctl & AC_PINCTL_HP_EN) ?
5119 SND_JACK_HEADPHONE : SND_JACK_LINEOUT;
5120 }
5121 snd_jack_report(jacks->jack, present ? type : 0);
5122 }
5123}
5124EXPORT_SYMBOL_HDA(snd_hda_input_jack_report);
5125
5126/* free jack instances manually when clearing/reconfiguring */
5127void snd_hda_input_jack_free(struct hda_codec *codec)
5128{
5129 if (!codec->bus->shutdown && codec->jacks.list) {
5130 struct hda_jack_item *jacks = codec->jacks.list;
5131 int i;
5132 for (i = 0; i < codec->jacks.used; i++, jacks++) {
5133 if (jacks->jack)
5134 snd_device_free(codec->bus->card, jacks->jack);
5135 }
5136 }
5137 snd_array_free(&codec->jacks);
5138}
5139EXPORT_SYMBOL_HDA(snd_hda_input_jack_free);
5140#endif /* CONFIG_SND_HDA_INPUT_JACK */
5141
4787MODULE_DESCRIPTION("HDA codec core"); 5142MODULE_DESCRIPTION("HDA codec core");
4788MODULE_LICENSE("GPL"); 5143MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 62c702240108..59c97306c1de 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -825,12 +825,14 @@ struct hda_codec {
825 struct hda_cache_rec amp_cache; /* cache for amp access */ 825 struct hda_cache_rec amp_cache; /* cache for amp access */
826 struct hda_cache_rec cmd_cache; /* cache for other commands */ 826 struct hda_cache_rec cmd_cache; /* cache for other commands */
827 827
828 struct snd_array conn_lists; /* connection-list array */
829
828 struct mutex spdif_mutex; 830 struct mutex spdif_mutex;
829 struct mutex control_mutex; 831 struct mutex control_mutex;
830 unsigned int spdif_status; /* IEC958 status bits */ 832 unsigned int spdif_status; /* IEC958 status bits */
831 unsigned short spdif_ctls; /* SPDIF control bits */ 833 unsigned short spdif_ctls; /* SPDIF control bits */
832 unsigned int spdif_in_enable; /* SPDIF input enable? */ 834 unsigned int spdif_in_enable; /* SPDIF input enable? */
833 hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ 835 const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
834 struct snd_array init_pins; /* initial (BIOS) pin configurations */ 836 struct snd_array init_pins; /* initial (BIOS) pin configurations */
835 struct snd_array driver_pins; /* pin configs set by codec parser */ 837 struct snd_array driver_pins; /* pin configs set by codec parser */
836 struct snd_array cvt_setups; /* audio convert setups */ 838 struct snd_array cvt_setups; /* audio convert setups */
@@ -850,6 +852,7 @@ struct hda_codec {
850 unsigned int pin_amp_workaround:1; /* pin out-amp takes index 852 unsigned int pin_amp_workaround:1; /* pin out-amp takes index
851 * (e.g. Conexant codecs) 853 * (e.g. Conexant codecs)
852 */ 854 */
855 unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */
853 unsigned int pins_shutup:1; /* pins are shut up */ 856 unsigned int pins_shutup:1; /* pins are shut up */
854 unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ 857 unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
855#ifdef CONFIG_SND_HDA_POWER_SAVE 858#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -865,6 +868,11 @@ struct hda_codec {
865 /* codec-specific additional proc output */ 868 /* codec-specific additional proc output */
866 void (*proc_widget_hook)(struct snd_info_buffer *buffer, 869 void (*proc_widget_hook)(struct snd_info_buffer *buffer,
867 struct hda_codec *codec, hda_nid_t nid); 870 struct hda_codec *codec, hda_nid_t nid);
871
872#ifdef CONFIG_SND_HDA_INPUT_JACK
873 /* jack detection */
874 struct snd_array jacks;
875#endif
868}; 876};
869 877
870/* direction */ 878/* direction */
@@ -989,6 +997,18 @@ int snd_hda_suspend(struct hda_bus *bus);
989int snd_hda_resume(struct hda_bus *bus); 997int snd_hda_resume(struct hda_bus *bus);
990#endif 998#endif
991 999
1000#ifdef CONFIG_SND_HDA_POWER_SAVE
1001static inline
1002int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1003{
1004 if (codec->patch_ops.check_power_status)
1005 return codec->patch_ops.check_power_status(codec, nid);
1006 return 0;
1007}
1008#else
1009#define hda_call_check_power_status(codec, nid) 0
1010#endif
1011
992/* 1012/*
993 * get widget information 1013 * get widget information
994 */ 1014 */
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index 26c3ade73583..e3e853153d14 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -189,6 +189,9 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
189 a->channels = GRAB_BITS(buf, 0, 0, 3); 189 a->channels = GRAB_BITS(buf, 0, 0, 3);
190 a->channels++; 190 a->channels++;
191 191
192 a->sample_bits = 0;
193 a->max_bitrate = 0;
194
192 a->format = GRAB_BITS(buf, 0, 3, 4); 195 a->format = GRAB_BITS(buf, 0, 3, 4);
193 switch (a->format) { 196 switch (a->format) {
194 case AUDIO_CODING_TYPE_REF_STREAM_HEADER: 197 case AUDIO_CODING_TYPE_REF_STREAM_HEADER:
@@ -198,7 +201,6 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
198 201
199 case AUDIO_CODING_TYPE_LPCM: 202 case AUDIO_CODING_TYPE_LPCM:
200 val = GRAB_BITS(buf, 2, 0, 3); 203 val = GRAB_BITS(buf, 2, 0, 3);
201 a->sample_bits = 0;
202 for (i = 0; i < 3; i++) 204 for (i = 0; i < 3; i++)
203 if (val & (1 << i)) 205 if (val & (1 << i))
204 a->sample_bits |= cea_sample_sizes[i + 1]; 206 a->sample_bits |= cea_sample_sizes[i + 1];
@@ -292,7 +294,7 @@ static int hdmi_update_eld(struct hdmi_eld *e,
292 snd_printd(KERN_INFO "HDMI: out of range MNL %d\n", mnl); 294 snd_printd(KERN_INFO "HDMI: out of range MNL %d\n", mnl);
293 goto out_fail; 295 goto out_fail;
294 } else 296 } else
295 strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl); 297 strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl + 1);
296 298
297 for (i = 0; i < e->sad_count; i++) { 299 for (i = 0; i < e->sad_count; i++) {
298 if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) { 300 if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) {
@@ -310,29 +312,11 @@ out_fail:
310 return -EINVAL; 312 return -EINVAL;
311} 313}
312 314
313static int hdmi_eld_valid(struct hda_codec *codec, hda_nid_t nid)
314{
315 int eldv;
316 int present;
317
318 present = snd_hda_pin_sense(codec, nid);
319 eldv = (present & AC_PINSENSE_ELDV);
320 present = (present & AC_PINSENSE_PRESENCE);
321
322#ifdef CONFIG_SND_DEBUG_VERBOSE
323 printk(KERN_INFO "HDMI: sink_present = %d, eld_valid = %d\n",
324 !!present, !!eldv);
325#endif
326
327 return eldv && present;
328}
329
330int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid) 315int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
331{ 316{
332 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, 317 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
333 AC_DIPSIZE_ELD_BUF); 318 AC_DIPSIZE_ELD_BUF);
334} 319}
335EXPORT_SYMBOL_HDA(snd_hdmi_get_eld_size);
336 320
337int snd_hdmi_get_eld(struct hdmi_eld *eld, 321int snd_hdmi_get_eld(struct hdmi_eld *eld,
338 struct hda_codec *codec, hda_nid_t nid) 322 struct hda_codec *codec, hda_nid_t nid)
@@ -342,7 +326,7 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
342 int size; 326 int size;
343 unsigned char *buf; 327 unsigned char *buf;
344 328
345 if (!hdmi_eld_valid(codec, nid)) 329 if (!eld->eld_valid)
346 return -ENOENT; 330 return -ENOENT;
347 331
348 size = snd_hdmi_get_eld_size(codec, nid); 332 size = snd_hdmi_get_eld_size(codec, nid);
@@ -368,7 +352,6 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
368 kfree(buf); 352 kfree(buf);
369 return ret; 353 return ret;
370} 354}
371EXPORT_SYMBOL_HDA(snd_hdmi_get_eld);
372 355
373static void hdmi_show_short_audio_desc(struct cea_sad *a) 356static void hdmi_show_short_audio_desc(struct cea_sad *a)
374{ 357{
@@ -381,7 +364,7 @@ static void hdmi_show_short_audio_desc(struct cea_sad *a)
381 snd_print_pcm_rates(a->rates, buf, sizeof(buf)); 364 snd_print_pcm_rates(a->rates, buf, sizeof(buf));
382 365
383 if (a->format == AUDIO_CODING_TYPE_LPCM) 366 if (a->format == AUDIO_CODING_TYPE_LPCM)
384 snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2 - 8)); 367 snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2) - 8);
385 else if (a->max_bitrate) 368 else if (a->max_bitrate)
386 snprintf(buf2, sizeof(buf2), 369 snprintf(buf2, sizeof(buf2),
387 ", max bitrate = %d", a->max_bitrate); 370 ", max bitrate = %d", a->max_bitrate);
@@ -407,7 +390,6 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
407 } 390 }
408 buf[j] = '\0'; /* necessary when j == 0 */ 391 buf[j] = '\0'; /* necessary when j == 0 */
409} 392}
410EXPORT_SYMBOL_HDA(snd_print_channel_allocation);
411 393
412void snd_hdmi_show_eld(struct hdmi_eld *e) 394void snd_hdmi_show_eld(struct hdmi_eld *e)
413{ 395{
@@ -426,7 +408,6 @@ void snd_hdmi_show_eld(struct hdmi_eld *e)
426 for (i = 0; i < e->sad_count; i++) 408 for (i = 0; i < e->sad_count; i++)
427 hdmi_show_short_audio_desc(e->sad + i); 409 hdmi_show_short_audio_desc(e->sad + i);
428} 410}
429EXPORT_SYMBOL_HDA(snd_hdmi_show_eld);
430 411
431#ifdef CONFIG_PROC_FS 412#ifdef CONFIG_PROC_FS
432 413
@@ -479,6 +460,8 @@ static void hdmi_print_eld_info(struct snd_info_entry *entry,
479 460
480 snd_iprintf(buffer, "monitor_present\t\t%d\n", e->monitor_present); 461 snd_iprintf(buffer, "monitor_present\t\t%d\n", e->monitor_present);
481 snd_iprintf(buffer, "eld_valid\t\t%d\n", e->eld_valid); 462 snd_iprintf(buffer, "eld_valid\t\t%d\n", e->eld_valid);
463 if (!e->eld_valid)
464 return;
482 snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); 465 snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name);
483 snd_iprintf(buffer, "connection_type\t\t%s\n", 466 snd_iprintf(buffer, "connection_type\t\t%s\n",
484 eld_connection_type_names[e->conn_type]); 467 eld_connection_type_names[e->conn_type]);
@@ -585,7 +568,6 @@ int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
585 568
586 return 0; 569 return 0;
587} 570}
588EXPORT_SYMBOL_HDA(snd_hda_eld_proc_new);
589 571
590void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld) 572void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
591{ 573{
@@ -594,7 +576,6 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
594 eld->proc_entry = NULL; 576 eld->proc_entry = NULL;
595 } 577 }
596} 578}
597EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free);
598 579
599#endif /* CONFIG_PROC_FS */ 580#endif /* CONFIG_PROC_FS */
600 581
@@ -604,24 +585,19 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
604{ 585{
605 int i; 586 int i;
606 587
607 pcm->rates = 0; 588 /* assume basic audio support (the basic audio flag is not in ELD;
608 pcm->formats = 0; 589 * however, all audio capable sinks are required to support basic
609 pcm->maxbps = 0; 590 * audio) */
610 pcm->channels_min = -1; 591 pcm->rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
611 pcm->channels_max = 0; 592 pcm->formats = SNDRV_PCM_FMTBIT_S16_LE;
593 pcm->maxbps = 16;
594 pcm->channels_max = 2;
612 for (i = 0; i < eld->sad_count; i++) { 595 for (i = 0; i < eld->sad_count; i++) {
613 struct cea_sad *a = &eld->sad[i]; 596 struct cea_sad *a = &eld->sad[i];
614 pcm->rates |= a->rates; 597 pcm->rates |= a->rates;
615 if (a->channels < pcm->channels_min)
616 pcm->channels_min = a->channels;
617 if (a->channels > pcm->channels_max) 598 if (a->channels > pcm->channels_max)
618 pcm->channels_max = a->channels; 599 pcm->channels_max = a->channels;
619 if (a->format == AUDIO_CODING_TYPE_LPCM) { 600 if (a->format == AUDIO_CODING_TYPE_LPCM) {
620 if (a->sample_bits & AC_SUPPCM_BITS_16) {
621 pcm->formats |= SNDRV_PCM_FMTBIT_S16_LE;
622 if (pcm->maxbps < 16)
623 pcm->maxbps = 16;
624 }
625 if (a->sample_bits & AC_SUPPCM_BITS_20) { 601 if (a->sample_bits & AC_SUPPCM_BITS_20) {
626 pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE; 602 pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE;
627 if (pcm->maxbps < 20) 603 if (pcm->maxbps < 20)
@@ -641,8 +617,6 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
641 /* restrict the parameters by the values the codec provides */ 617 /* restrict the parameters by the values the codec provides */
642 pcm->rates &= codec_pars->rates; 618 pcm->rates &= codec_pars->rates;
643 pcm->formats &= codec_pars->formats; 619 pcm->formats &= codec_pars->formats;
644 pcm->channels_min = max(pcm->channels_min, codec_pars->channels_min);
645 pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max); 620 pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max);
646 pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); 621 pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps);
647} 622}
648EXPORT_SYMBOL_HDA(hdmi_eld_update_pcm_info);
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 5ea21285ee1f..a63c54d9d767 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -61,7 +61,6 @@ struct hda_gspec {
61 struct hda_gnode *cap_vol_node; /* Node for capture volume */ 61 struct hda_gnode *cap_vol_node; /* Node for capture volume */
62 unsigned int cur_cap_src; /* current capture source */ 62 unsigned int cur_cap_src; /* current capture source */
63 struct hda_input_mux input_mux; 63 struct hda_input_mux input_mux;
64 char cap_labels[HDA_MAX_NUM_INPUTS][16];
65 64
66 unsigned int def_amp_in_caps; 65 unsigned int def_amp_in_caps;
67 unsigned int def_amp_out_caps; 66 unsigned int def_amp_out_caps;
@@ -506,11 +505,10 @@ static const char *get_input_type(struct hda_gnode *node, unsigned int *pinctl)
506 * returns 0 if not found, 1 if found, or a negative error code. 505 * returns 0 if not found, 1 if found, or a negative error code.
507 */ 506 */
508static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec, 507static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec,
509 struct hda_gnode *node) 508 struct hda_gnode *node, int idx)
510{ 509{
511 int i, err; 510 int i, err;
512 unsigned int pinctl; 511 unsigned int pinctl;
513 char *label;
514 const char *type; 512 const char *type;
515 513
516 if (node->checked) 514 if (node->checked)
@@ -523,7 +521,7 @@ static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec,
523 child = hda_get_node(spec, node->conn_list[i]); 521 child = hda_get_node(spec, node->conn_list[i]);
524 if (! child) 522 if (! child)
525 continue; 523 continue;
526 err = parse_adc_sub_nodes(codec, spec, child); 524 err = parse_adc_sub_nodes(codec, spec, child, idx);
527 if (err < 0) 525 if (err < 0)
528 return err; 526 return err;
529 if (err > 0) { 527 if (err > 0) {
@@ -564,9 +562,7 @@ static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec,
564 return 0; 562 return 0;
565 type = "Input"; 563 type = "Input";
566 } 564 }
567 label = spec->cap_labels[spec->input_mux.num_items]; 565 snd_hda_add_imux_item(&spec->input_mux, type, idx, NULL);
568 strcpy(label, type);
569 spec->input_mux.items[spec->input_mux.num_items].label = label;
570 566
571 /* unmute the PIN external input */ 567 /* unmute the PIN external input */
572 unmute_input(codec, node, 0); /* index = 0? */ 568 unmute_input(codec, node, 0); /* index = 0? */
@@ -577,29 +573,6 @@ static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec,
577 return 1; /* found */ 573 return 1; /* found */
578} 574}
579 575
580/* add a capture source element */
581static void add_cap_src(struct hda_gspec *spec, int idx)
582{
583 struct hda_input_mux_item *csrc;
584 char *buf;
585 int num, ocap;
586
587 num = spec->input_mux.num_items;
588 csrc = &spec->input_mux.items[num];
589 buf = spec->cap_labels[num];
590 for (ocap = 0; ocap < num; ocap++) {
591 if (! strcmp(buf, spec->cap_labels[ocap])) {
592 /* same label already exists,
593 * put the index number to be unique
594 */
595 sprintf(buf, "%s %d", spec->cap_labels[ocap], num);
596 break;
597 }
598 }
599 csrc->index = idx;
600 spec->input_mux.num_items++;
601}
602
603/* 576/*
604 * parse input 577 * parse input
605 */ 578 */
@@ -624,22 +597,18 @@ static int parse_input_path(struct hda_codec *codec, struct hda_gnode *adc_node)
624 for (i = 0; i < adc_node->nconns; i++) { 597 for (i = 0; i < adc_node->nconns; i++) {
625 node = hda_get_node(spec, adc_node->conn_list[i]); 598 node = hda_get_node(spec, adc_node->conn_list[i]);
626 if (node && node->type == AC_WID_PIN) { 599 if (node && node->type == AC_WID_PIN) {
627 err = parse_adc_sub_nodes(codec, spec, node); 600 err = parse_adc_sub_nodes(codec, spec, node, i);
628 if (err < 0) 601 if (err < 0)
629 return err; 602 return err;
630 else if (err > 0)
631 add_cap_src(spec, i);
632 } 603 }
633 } 604 }
634 /* ... then check the rests, more complicated connections */ 605 /* ... then check the rests, more complicated connections */
635 for (i = 0; i < adc_node->nconns; i++) { 606 for (i = 0; i < adc_node->nconns; i++) {
636 node = hda_get_node(spec, adc_node->conn_list[i]); 607 node = hda_get_node(spec, adc_node->conn_list[i]);
637 if (node && node->type != AC_WID_PIN) { 608 if (node && node->type != AC_WID_PIN) {
638 err = parse_adc_sub_nodes(codec, spec, node); 609 err = parse_adc_sub_nodes(codec, spec, node, i);
639 if (err < 0) 610 if (err < 0)
640 return err; 611 return err;
641 else if (err > 0)
642 add_cap_src(spec, i);
643 } 612 }
644 } 613 }
645 614
@@ -793,7 +762,8 @@ static int check_existing_control(struct hda_codec *codec, const char *type, con
793/* 762/*
794 * build output mixer controls 763 * build output mixer controls
795 */ 764 */
796static int create_output_mixers(struct hda_codec *codec, const char **names) 765static int create_output_mixers(struct hda_codec *codec,
766 const char * const *names)
797{ 767{
798 struct hda_gspec *spec = codec->spec; 768 struct hda_gspec *spec = codec->spec;
799 int i, err; 769 int i, err;
@@ -811,8 +781,8 @@ static int create_output_mixers(struct hda_codec *codec, const char **names)
811static int build_output_controls(struct hda_codec *codec) 781static int build_output_controls(struct hda_codec *codec)
812{ 782{
813 struct hda_gspec *spec = codec->spec; 783 struct hda_gspec *spec = codec->spec;
814 static const char *types_speaker[] = { "Speaker", "Headphone" }; 784 static const char * const types_speaker[] = { "Speaker", "Headphone" };
815 static const char *types_line[] = { "Front", "Headphone" }; 785 static const char * const types_line[] = { "Front", "Headphone" };
816 786
817 switch (spec->pcm_vol_nodes) { 787 switch (spec->pcm_vol_nodes) {
818 case 1: 788 case 1:
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 34940a079051..486f6deb3eee 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -78,8 +78,8 @@ MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
78module_param_array(model, charp, NULL, 0444); 78module_param_array(model, charp, NULL, 0444);
79MODULE_PARM_DESC(model, "Use the given board model."); 79MODULE_PARM_DESC(model, "Use the given board model.");
80module_param_array(position_fix, int, NULL, 0444); 80module_param_array(position_fix, int, NULL, 0444);
81MODULE_PARM_DESC(position_fix, "Fix DMA pointer " 81MODULE_PARM_DESC(position_fix, "DMA pointer read method."
82 "(0 = auto, 1 = none, 2 = POSBUF)."); 82 "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO).");
83module_param_array(bdl_pos_adj, int, NULL, 0644); 83module_param_array(bdl_pos_adj, int, NULL, 0644);
84MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); 84MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
85module_param_array(probe_mask, int, NULL, 0444); 85module_param_array(probe_mask, int, NULL, 0444);
@@ -126,6 +126,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
126 "{Intel, ICH10}," 126 "{Intel, ICH10},"
127 "{Intel, PCH}," 127 "{Intel, PCH},"
128 "{Intel, CPT}," 128 "{Intel, CPT},"
129 "{Intel, PPT},"
129 "{Intel, PBG}," 130 "{Intel, PBG},"
130 "{Intel, SCH}," 131 "{Intel, SCH},"
131 "{ATI, SB450}," 132 "{ATI, SB450},"
@@ -305,6 +306,7 @@ enum {
305 POS_FIX_AUTO, 306 POS_FIX_AUTO,
306 POS_FIX_LPIB, 307 POS_FIX_LPIB,
307 POS_FIX_POSBUF, 308 POS_FIX_POSBUF,
309 POS_FIX_VIACOMBO,
308}; 310};
309 311
310/* Defines for ATI HD Audio support in SB450 south bridge */ 312/* Defines for ATI HD Audio support in SB450 south bridge */
@@ -389,6 +391,7 @@ struct azx {
389 391
390 /* chip type specific */ 392 /* chip type specific */
391 int driver_type; 393 int driver_type;
394 unsigned int driver_caps;
392 int playback_streams; 395 int playback_streams;
393 int playback_index_offset; 396 int playback_index_offset;
394 int capture_streams; 397 int capture_streams;
@@ -433,7 +436,6 @@ struct azx {
433 unsigned int polling_mode :1; 436 unsigned int polling_mode :1;
434 unsigned int msi :1; 437 unsigned int msi :1;
435 unsigned int irq_pending_warned :1; 438 unsigned int irq_pending_warned :1;
436 unsigned int via_dmapos_patch :1; /* enable DMA-position fix for VIA */
437 unsigned int probing :1; /* codec probing phase */ 439 unsigned int probing :1; /* codec probing phase */
438 440
439 /* for debugging */ 441 /* for debugging */
@@ -458,10 +460,39 @@ enum {
458 AZX_DRIVER_ULI, 460 AZX_DRIVER_ULI,
459 AZX_DRIVER_NVIDIA, 461 AZX_DRIVER_NVIDIA,
460 AZX_DRIVER_TERA, 462 AZX_DRIVER_TERA,
463 AZX_DRIVER_CTX,
461 AZX_DRIVER_GENERIC, 464 AZX_DRIVER_GENERIC,
462 AZX_NUM_DRIVERS, /* keep this as last entry */ 465 AZX_NUM_DRIVERS, /* keep this as last entry */
463}; 466};
464 467
468/* driver quirks (capabilities) */
469/* bits 0-7 are used for indicating driver type */
470#define AZX_DCAPS_NO_TCSEL (1 << 8) /* No Intel TCSEL bit */
471#define AZX_DCAPS_NO_MSI (1 << 9) /* No MSI support */
472#define AZX_DCAPS_ATI_SNOOP (1 << 10) /* ATI snoop enable */
473#define AZX_DCAPS_NVIDIA_SNOOP (1 << 11) /* Nvidia snoop enable */
474#define AZX_DCAPS_SCH_SNOOP (1 << 12) /* SCH/PCH snoop enable */
475#define AZX_DCAPS_RIRB_DELAY (1 << 13) /* Long delay in read loop */
476#define AZX_DCAPS_RIRB_PRE_DELAY (1 << 14) /* Put a delay before read */
477#define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */
478#define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */
479#define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */
480#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */
481#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */
482
483/* quirks for ATI SB / AMD Hudson */
484#define AZX_DCAPS_PRESET_ATI_SB \
485 (AZX_DCAPS_ATI_SNOOP | AZX_DCAPS_NO_TCSEL | \
486 AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB)
487
488/* quirks for ATI/AMD HDMI */
489#define AZX_DCAPS_PRESET_ATI_HDMI \
490 (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB)
491
492/* quirks for Nvidia */
493#define AZX_DCAPS_PRESET_NVIDIA \
494 (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI)
495
465static char *driver_short_names[] __devinitdata = { 496static char *driver_short_names[] __devinitdata = {
466 [AZX_DRIVER_ICH] = "HDA Intel", 497 [AZX_DRIVER_ICH] = "HDA Intel",
467 [AZX_DRIVER_PCH] = "HDA Intel PCH", 498 [AZX_DRIVER_PCH] = "HDA Intel PCH",
@@ -473,6 +504,7 @@ static char *driver_short_names[] __devinitdata = {
473 [AZX_DRIVER_ULI] = "HDA ULI M5461", 504 [AZX_DRIVER_ULI] = "HDA ULI M5461",
474 [AZX_DRIVER_NVIDIA] = "HDA NVidia", 505 [AZX_DRIVER_NVIDIA] = "HDA NVidia",
475 [AZX_DRIVER_TERA] = "HDA Teradici", 506 [AZX_DRIVER_TERA] = "HDA Teradici",
507 [AZX_DRIVER_CTX] = "HDA Creative",
476 [AZX_DRIVER_GENERIC] = "HD-Audio Generic", 508 [AZX_DRIVER_GENERIC] = "HD-Audio Generic",
477}; 509};
478 510
@@ -563,7 +595,10 @@ static void azx_init_cmd_io(struct azx *chip)
563 /* reset the rirb hw write pointer */ 595 /* reset the rirb hw write pointer */
564 azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST); 596 azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST);
565 /* set N=1, get RIRB response interrupt for new entry */ 597 /* set N=1, get RIRB response interrupt for new entry */
566 azx_writew(chip, RINTCNT, 1); 598 if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
599 azx_writew(chip, RINTCNT, 0xc0);
600 else
601 azx_writew(chip, RINTCNT, 1);
567 /* enable rirb dma and response irq */ 602 /* enable rirb dma and response irq */
568 azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN); 603 azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN);
569 spin_unlock_irq(&chip->reg_lock); 604 spin_unlock_irq(&chip->reg_lock);
@@ -1047,19 +1082,27 @@ static void azx_init_pci(struct azx *chip)
1047 /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) 1082 /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
1048 * TCSEL == Traffic Class Select Register, which sets PCI express QOS 1083 * TCSEL == Traffic Class Select Register, which sets PCI express QOS
1049 * Ensuring these bits are 0 clears playback static on some HD Audio 1084 * Ensuring these bits are 0 clears playback static on some HD Audio
1050 * codecs 1085 * codecs.
1086 * The PCI register TCSEL is defined in the Intel manuals.
1051 */ 1087 */
1052 update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0); 1088 if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) {
1089 snd_printdd(SFX "Clearing TCSEL\n");
1090 update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0);
1091 }
1053 1092
1054 switch (chip->driver_type) { 1093 /* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio,
1055 case AZX_DRIVER_ATI: 1094 * we need to enable snoop.
1056 /* For ATI SB450 azalia HD audio, we need to enable snoop */ 1095 */
1096 if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) {
1097 snd_printdd(SFX "Enabling ATI snoop\n");
1057 update_pci_byte(chip->pci, 1098 update_pci_byte(chip->pci,
1058 ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 1099 ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR,
1059 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP); 1100 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP);
1060 break; 1101 }
1061 case AZX_DRIVER_NVIDIA: 1102
1062 /* For NVIDIA HDA, enable snoop */ 1103 /* For NVIDIA HDA, enable snoop */
1104 if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) {
1105 snd_printdd(SFX "Enabling Nvidia snoop\n");
1063 update_pci_byte(chip->pci, 1106 update_pci_byte(chip->pci,
1064 NVIDIA_HDA_TRANSREG_ADDR, 1107 NVIDIA_HDA_TRANSREG_ADDR,
1065 0x0f, NVIDIA_HDA_ENABLE_COHBITS); 1108 0x0f, NVIDIA_HDA_ENABLE_COHBITS);
@@ -1069,9 +1112,10 @@ static void azx_init_pci(struct azx *chip)
1069 update_pci_byte(chip->pci, 1112 update_pci_byte(chip->pci,
1070 NVIDIA_HDA_OSTRM_COH, 1113 NVIDIA_HDA_OSTRM_COH,
1071 0x01, NVIDIA_HDA_ENABLE_COHBIT); 1114 0x01, NVIDIA_HDA_ENABLE_COHBIT);
1072 break; 1115 }
1073 case AZX_DRIVER_SCH: 1116
1074 case AZX_DRIVER_PCH: 1117 /* Enable SCH/PCH snoop if needed */
1118 if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) {
1075 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); 1119 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
1076 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { 1120 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) {
1077 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, 1121 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC,
@@ -1082,8 +1126,6 @@ static void azx_init_pci(struct azx *chip)
1082 (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) 1126 (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)
1083 ? "Failed" : "OK"); 1127 ? "Failed" : "OK");
1084 } 1128 }
1085 break;
1086
1087 } 1129 }
1088} 1130}
1089 1131
@@ -1136,8 +1178,11 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
1136 /* clear rirb int */ 1178 /* clear rirb int */
1137 status = azx_readb(chip, RIRBSTS); 1179 status = azx_readb(chip, RIRBSTS);
1138 if (status & RIRB_INT_MASK) { 1180 if (status & RIRB_INT_MASK) {
1139 if (status & RIRB_INT_RESPONSE) 1181 if (status & RIRB_INT_RESPONSE) {
1182 if (chip->driver_caps & AZX_DCAPS_RIRB_PRE_DELAY)
1183 udelay(80);
1140 azx_update_rirb(chip); 1184 azx_update_rirb(chip);
1185 }
1141 azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); 1186 azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
1142 } 1187 }
1143 1188
@@ -1227,7 +1272,8 @@ static int azx_setup_periods(struct azx *chip,
1227 pos_adj = 0; 1272 pos_adj = 0;
1228 } else { 1273 } else {
1229 ofs = setup_bdle(substream, azx_dev, 1274 ofs = setup_bdle(substream, azx_dev,
1230 &bdl, ofs, pos_adj, 1); 1275 &bdl, ofs, pos_adj,
1276 !substream->runtime->no_period_wakeup);
1231 if (ofs < 0) 1277 if (ofs < 0)
1232 goto error; 1278 goto error;
1233 } 1279 }
@@ -1239,7 +1285,8 @@ static int azx_setup_periods(struct azx *chip,
1239 period_bytes - pos_adj, 0); 1285 period_bytes - pos_adj, 0);
1240 else 1286 else
1241 ofs = setup_bdle(substream, azx_dev, &bdl, ofs, 1287 ofs = setup_bdle(substream, azx_dev, &bdl, ofs,
1242 period_bytes, 1); 1288 period_bytes,
1289 !substream->runtime->no_period_wakeup);
1243 if (ofs < 0) 1290 if (ofs < 0)
1244 goto error; 1291 goto error;
1245 } 1292 }
@@ -1309,11 +1356,8 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
1309 azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr)); 1356 azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr));
1310 1357
1311 /* enable the position buffer */ 1358 /* enable the position buffer */
1312 if (chip->position_fix[0] == POS_FIX_POSBUF || 1359 if (chip->position_fix[0] != POS_FIX_LPIB ||
1313 chip->position_fix[0] == POS_FIX_AUTO || 1360 chip->position_fix[1] != POS_FIX_LPIB) {
1314 chip->position_fix[1] == POS_FIX_POSBUF ||
1315 chip->position_fix[1] == POS_FIX_AUTO ||
1316 chip->via_dmapos_patch) {
1317 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) 1361 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
1318 azx_writel(chip, DPLBASE, 1362 azx_writel(chip, DPLBASE,
1319 (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); 1363 (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
@@ -1404,8 +1448,10 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1404 if (err < 0) 1448 if (err < 0)
1405 return err; 1449 return err;
1406 1450
1407 if (chip->driver_type == AZX_DRIVER_NVIDIA) 1451 if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) {
1452 snd_printd(SFX "Enable delay in RIRB handling\n");
1408 chip->bus->needs_damn_long_delay = 1; 1453 chip->bus->needs_damn_long_delay = 1;
1454 }
1409 1455
1410 codecs = 0; 1456 codecs = 0;
1411 max_slots = azx_max_codecs[chip->driver_type]; 1457 max_slots = azx_max_codecs[chip->driver_type];
@@ -1436,6 +1482,16 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1436 } 1482 }
1437 } 1483 }
1438 1484
1485 /* AMD chipsets often cause the communication stalls upon certain
1486 * sequence like the pin-detection. It seems that forcing the synced
1487 * access works around the stall. Grrr...
1488 */
1489 if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) {
1490 snd_printd(SFX "Enable sync_write for stable communication\n");
1491 chip->bus->sync_write = 1;
1492 chip->bus->allow_bus_reset = 1;
1493 }
1494
1439 /* Then create codec instances */ 1495 /* Then create codec instances */
1440 for (c = 0; c < max_slots; c++) { 1496 for (c = 0; c < max_slots; c++) {
1441 if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { 1497 if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
@@ -1510,7 +1566,8 @@ static struct snd_pcm_hardware azx_pcm_hw = {
1510 /* No full-resume yet implemented */ 1566 /* No full-resume yet implemented */
1511 /* SNDRV_PCM_INFO_RESUME |*/ 1567 /* SNDRV_PCM_INFO_RESUME |*/
1512 SNDRV_PCM_INFO_PAUSE | 1568 SNDRV_PCM_INFO_PAUSE |
1513 SNDRV_PCM_INFO_SYNC_START), 1569 SNDRV_PCM_INFO_SYNC_START |
1570 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
1514 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1571 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1515 .rates = SNDRV_PCM_RATE_48000, 1572 .rates = SNDRV_PCM_RATE_48000,
1516 .rate_min = 48000, 1573 .rate_min = 48000,
@@ -1647,7 +1704,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1647 struct azx_dev *azx_dev = get_azx_dev(substream); 1704 struct azx_dev *azx_dev = get_azx_dev(substream);
1648 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; 1705 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
1649 struct snd_pcm_runtime *runtime = substream->runtime; 1706 struct snd_pcm_runtime *runtime = substream->runtime;
1650 unsigned int bufsize, period_bytes, format_val; 1707 unsigned int bufsize, period_bytes, format_val, stream_tag;
1651 int err; 1708 int err;
1652 1709
1653 azx_stream_reset(chip, azx_dev); 1710 azx_stream_reset(chip, azx_dev);
@@ -1689,7 +1746,12 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1689 else 1746 else
1690 azx_dev->fifo_size = 0; 1747 azx_dev->fifo_size = 0;
1691 1748
1692 return snd_hda_codec_prepare(apcm->codec, hinfo, azx_dev->stream_tag, 1749 stream_tag = azx_dev->stream_tag;
1750 /* CA-IBG chips need the playback stream starting from 1 */
1751 if ((chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) &&
1752 stream_tag > chip->capture_streams)
1753 stream_tag -= chip->capture_streams;
1754 return snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag,
1693 azx_dev->format_val, substream); 1755 azx_dev->format_val, substream);
1694} 1756}
1695 1757
@@ -1852,20 +1914,21 @@ static unsigned int azx_get_position(struct azx *chip,
1852 struct azx_dev *azx_dev) 1914 struct azx_dev *azx_dev)
1853{ 1915{
1854 unsigned int pos; 1916 unsigned int pos;
1917 int stream = azx_dev->substream->stream;
1855 1918
1856 if (chip->via_dmapos_patch) 1919 switch (chip->position_fix[stream]) {
1920 case POS_FIX_LPIB:
1921 /* read LPIB */
1922 pos = azx_sd_readl(azx_dev, SD_LPIB);
1923 break;
1924 case POS_FIX_VIACOMBO:
1857 pos = azx_via_get_position(chip, azx_dev); 1925 pos = azx_via_get_position(chip, azx_dev);
1858 else { 1926 break;
1859 int stream = azx_dev->substream->stream; 1927 default:
1860 if (chip->position_fix[stream] == POS_FIX_POSBUF || 1928 /* use the position buffer */
1861 chip->position_fix[stream] == POS_FIX_AUTO) { 1929 pos = le32_to_cpu(*azx_dev->posbuf);
1862 /* use the position buffer */
1863 pos = le32_to_cpu(*azx_dev->posbuf);
1864 } else {
1865 /* read LPIB */
1866 pos = azx_sd_readl(azx_dev, SD_LPIB);
1867 }
1868 } 1930 }
1931
1869 if (pos >= azx_dev->bufsize) 1932 if (pos >= azx_dev->bufsize)
1870 pos = 0; 1933 pos = 0;
1871 return pos; 1934 return pos;
@@ -2285,13 +2348,16 @@ static int azx_dev_free(struct snd_device *device)
2285 */ 2348 */
2286static struct snd_pci_quirk position_fix_list[] __devinitdata = { 2349static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2287 SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB), 2350 SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB),
2351 SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB),
2288 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), 2352 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
2289 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), 2353 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
2290 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), 2354 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
2355 SND_PCI_QUIRK(0x1028, 0x0470, "Dell Inspiron 1120", POS_FIX_LPIB),
2291 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), 2356 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
2292 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2357 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2293 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), 2358 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
2294 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), 2359 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
2360 SND_PCI_QUIRK(0x1043, 0x8410, "ASUS", POS_FIX_LPIB),
2295 SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), 2361 SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
2296 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), 2362 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
2297 SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB), 2363 SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB),
@@ -2313,19 +2379,10 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
2313 switch (fix) { 2379 switch (fix) {
2314 case POS_FIX_LPIB: 2380 case POS_FIX_LPIB:
2315 case POS_FIX_POSBUF: 2381 case POS_FIX_POSBUF:
2382 case POS_FIX_VIACOMBO:
2316 return fix; 2383 return fix;
2317 } 2384 }
2318 2385
2319 /* Check VIA/ATI HD Audio Controller exist */
2320 switch (chip->driver_type) {
2321 case AZX_DRIVER_VIA:
2322 case AZX_DRIVER_ATI:
2323 chip->via_dmapos_patch = 1;
2324 /* Use link position directly, avoid any transfer problem. */
2325 return POS_FIX_LPIB;
2326 }
2327 chip->via_dmapos_patch = 0;
2328
2329 q = snd_pci_quirk_lookup(chip->pci, position_fix_list); 2386 q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
2330 if (q) { 2387 if (q) {
2331 printk(KERN_INFO 2388 printk(KERN_INFO
@@ -2334,6 +2391,16 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
2334 q->value, q->subvendor, q->subdevice); 2391 q->value, q->subvendor, q->subdevice);
2335 return q->value; 2392 return q->value;
2336 } 2393 }
2394
2395 /* Check VIA/ATI HD Audio Controller exist */
2396 if (chip->driver_caps & AZX_DCAPS_POSFIX_VIA) {
2397 snd_printd(SFX "Using VIACOMBO position fix\n");
2398 return POS_FIX_VIACOMBO;
2399 }
2400 if (chip->driver_caps & AZX_DCAPS_POSFIX_LPIB) {
2401 snd_printd(SFX "Using LPIB position fix\n");
2402 return POS_FIX_LPIB;
2403 }
2337 return POS_FIX_AUTO; 2404 return POS_FIX_AUTO;
2338} 2405}
2339 2406
@@ -2415,8 +2482,8 @@ static void __devinit check_msi(struct azx *chip)
2415 } 2482 }
2416 2483
2417 /* NVidia chipsets seem to cause troubles with MSI */ 2484 /* NVidia chipsets seem to cause troubles with MSI */
2418 if (chip->driver_type == AZX_DRIVER_NVIDIA) { 2485 if (chip->driver_caps & AZX_DCAPS_NO_MSI) {
2419 printk(KERN_INFO "hda_intel: Disable MSI for Nvidia chipset\n"); 2486 printk(KERN_INFO "hda_intel: Disabling MSI\n");
2420 chip->msi = 0; 2487 chip->msi = 0;
2421 } 2488 }
2422} 2489}
@@ -2426,7 +2493,7 @@ static void __devinit check_msi(struct azx *chip)
2426 * constructor 2493 * constructor
2427 */ 2494 */
2428static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, 2495static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2429 int dev, int driver_type, 2496 int dev, unsigned int driver_caps,
2430 struct azx **rchip) 2497 struct azx **rchip)
2431{ 2498{
2432 struct azx *chip; 2499 struct azx *chip;
@@ -2454,7 +2521,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2454 chip->card = card; 2521 chip->card = card;
2455 chip->pci = pci; 2522 chip->pci = pci;
2456 chip->irq = -1; 2523 chip->irq = -1;
2457 chip->driver_type = driver_type; 2524 chip->driver_caps = driver_caps;
2525 chip->driver_type = driver_caps & 0xff;
2458 check_msi(chip); 2526 check_msi(chip);
2459 chip->dev_index = dev; 2527 chip->dev_index = dev;
2460 INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); 2528 INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
@@ -2518,8 +2586,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2518 snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap); 2586 snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap);
2519 2587
2520 /* disable SB600 64bit support for safety */ 2588 /* disable SB600 64bit support for safety */
2521 if ((chip->driver_type == AZX_DRIVER_ATI) || 2589 if (chip->pci->vendor == PCI_VENDOR_ID_ATI) {
2522 (chip->driver_type == AZX_DRIVER_ATIHDMI)) {
2523 struct pci_dev *p_smbus; 2590 struct pci_dev *p_smbus;
2524 p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, 2591 p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
2525 PCI_DEVICE_ID_ATI_SBX00_SMBUS, 2592 PCI_DEVICE_ID_ATI_SBX00_SMBUS,
@@ -2531,10 +2598,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2531 } 2598 }
2532 } 2599 }
2533 2600
2534 /* disable 64bit DMA address for Teradici */ 2601 /* disable 64bit DMA address on some devices */
2535 /* it does not work with device 6549:1200 subsys e4a2:040b */ 2602 if (chip->driver_caps & AZX_DCAPS_NO_64BIT) {
2536 if (chip->driver_type == AZX_DRIVER_TERA) 2603 snd_printd(SFX "Disabling 64bit DMA\n");
2537 gcap &= ~ICH6_GCAP_64OK; 2604 gcap &= ~ICH6_GCAP_64OK;
2605 }
2538 2606
2539 /* allow 64bit DMA address if supported by H/W */ 2607 /* allow 64bit DMA address if supported by H/W */
2540 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) 2608 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
@@ -2687,7 +2755,7 @@ static int __devinit azx_probe(struct pci_dev *pci,
2687 if (err < 0) 2755 if (err < 0)
2688 goto out_free; 2756 goto out_free;
2689#ifdef CONFIG_SND_HDA_PATCH_LOADER 2757#ifdef CONFIG_SND_HDA_PATCH_LOADER
2690 if (patch[dev]) { 2758 if (patch[dev] && *patch[dev]) {
2691 snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n", 2759 snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
2692 patch[dev]); 2760 patch[dev]);
2693 err = snd_hda_load_patch(chip->bus, patch[dev]); 2761 err = snd_hda_load_patch(chip->bus, patch[dev]);
@@ -2735,45 +2803,63 @@ static void __devexit azx_remove(struct pci_dev *pci)
2735 2803
2736/* PCI IDs */ 2804/* PCI IDs */
2737static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { 2805static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2738 /* ICH 6..10 */
2739 { PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH },
2740 { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH },
2741 { PCI_DEVICE(0x8086, 0x269a), .driver_data = AZX_DRIVER_ICH },
2742 { PCI_DEVICE(0x8086, 0x284b), .driver_data = AZX_DRIVER_ICH },
2743 { PCI_DEVICE(0x8086, 0x2911), .driver_data = AZX_DRIVER_ICH },
2744 { PCI_DEVICE(0x8086, 0x293e), .driver_data = AZX_DRIVER_ICH },
2745 { PCI_DEVICE(0x8086, 0x293f), .driver_data = AZX_DRIVER_ICH },
2746 { PCI_DEVICE(0x8086, 0x3a3e), .driver_data = AZX_DRIVER_ICH },
2747 { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH },
2748 /* PCH */
2749 { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH },
2750 { PCI_DEVICE(0x8086, 0x3b57), .driver_data = AZX_DRIVER_ICH },
2751 /* CPT */ 2806 /* CPT */
2752 { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH }, 2807 { PCI_DEVICE(0x8086, 0x1c20),
2808 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
2753 /* PBG */ 2809 /* PBG */
2754 { PCI_DEVICE(0x8086, 0x1d20), .driver_data = AZX_DRIVER_PCH }, 2810 { PCI_DEVICE(0x8086, 0x1d20),
2811 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
2812 /* Panther Point */
2813 { PCI_DEVICE(0x8086, 0x1e20),
2814 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
2755 /* SCH */ 2815 /* SCH */
2756 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, 2816 { PCI_DEVICE(0x8086, 0x811b),
2757 /* ATI SB 450/600 */ 2817 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP },
2758 { PCI_DEVICE(0x1002, 0x437b), .driver_data = AZX_DRIVER_ATI }, 2818 /* Generic Intel */
2759 { PCI_DEVICE(0x1002, 0x4383), .driver_data = AZX_DRIVER_ATI }, 2819 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
2820 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2821 .class_mask = 0xffffff,
2822 .driver_data = AZX_DRIVER_ICH },
2823 /* ATI SB 450/600/700/800/900 */
2824 { PCI_DEVICE(0x1002, 0x437b),
2825 .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
2826 { PCI_DEVICE(0x1002, 0x4383),
2827 .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
2828 /* AMD Hudson */
2829 { PCI_DEVICE(0x1022, 0x780d),
2830 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
2760 /* ATI HDMI */ 2831 /* ATI HDMI */
2761 { PCI_DEVICE(0x1002, 0x793b), .driver_data = AZX_DRIVER_ATIHDMI }, 2832 { PCI_DEVICE(0x1002, 0x793b),
2762 { PCI_DEVICE(0x1002, 0x7919), .driver_data = AZX_DRIVER_ATIHDMI }, 2833 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2763 { PCI_DEVICE(0x1002, 0x960f), .driver_data = AZX_DRIVER_ATIHDMI }, 2834 { PCI_DEVICE(0x1002, 0x7919),
2764 { PCI_DEVICE(0x1002, 0x970f), .driver_data = AZX_DRIVER_ATIHDMI }, 2835 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2765 { PCI_DEVICE(0x1002, 0xaa00), .driver_data = AZX_DRIVER_ATIHDMI }, 2836 { PCI_DEVICE(0x1002, 0x960f),
2766 { PCI_DEVICE(0x1002, 0xaa08), .driver_data = AZX_DRIVER_ATIHDMI }, 2837 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2767 { PCI_DEVICE(0x1002, 0xaa10), .driver_data = AZX_DRIVER_ATIHDMI }, 2838 { PCI_DEVICE(0x1002, 0x970f),
2768 { PCI_DEVICE(0x1002, 0xaa18), .driver_data = AZX_DRIVER_ATIHDMI }, 2839 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2769 { PCI_DEVICE(0x1002, 0xaa20), .driver_data = AZX_DRIVER_ATIHDMI }, 2840 { PCI_DEVICE(0x1002, 0xaa00),
2770 { PCI_DEVICE(0x1002, 0xaa28), .driver_data = AZX_DRIVER_ATIHDMI }, 2841 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2771 { PCI_DEVICE(0x1002, 0xaa30), .driver_data = AZX_DRIVER_ATIHDMI }, 2842 { PCI_DEVICE(0x1002, 0xaa08),
2772 { PCI_DEVICE(0x1002, 0xaa38), .driver_data = AZX_DRIVER_ATIHDMI }, 2843 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2773 { PCI_DEVICE(0x1002, 0xaa40), .driver_data = AZX_DRIVER_ATIHDMI }, 2844 { PCI_DEVICE(0x1002, 0xaa10),
2774 { PCI_DEVICE(0x1002, 0xaa48), .driver_data = AZX_DRIVER_ATIHDMI }, 2845 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2846 { PCI_DEVICE(0x1002, 0xaa18),
2847 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2848 { PCI_DEVICE(0x1002, 0xaa20),
2849 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2850 { PCI_DEVICE(0x1002, 0xaa28),
2851 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2852 { PCI_DEVICE(0x1002, 0xaa30),
2853 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2854 { PCI_DEVICE(0x1002, 0xaa38),
2855 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2856 { PCI_DEVICE(0x1002, 0xaa40),
2857 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2858 { PCI_DEVICE(0x1002, 0xaa48),
2859 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2775 /* VIA VT8251/VT8237A */ 2860 /* VIA VT8251/VT8237A */
2776 { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA }, 2861 { PCI_DEVICE(0x1106, 0x3288),
2862 .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA },
2777 /* SIS966 */ 2863 /* SIS966 */
2778 { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS }, 2864 { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS },
2779 /* ULI M5461 */ 2865 /* ULI M5461 */
@@ -2782,9 +2868,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2782 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), 2868 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
2783 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 2869 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2784 .class_mask = 0xffffff, 2870 .class_mask = 0xffffff,
2785 .driver_data = AZX_DRIVER_NVIDIA }, 2871 .driver_data = AZX_DRIVER_NVIDIA | AZX_DCAPS_PRESET_NVIDIA },
2786 /* Teradici */ 2872 /* Teradici */
2787 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, 2873 { PCI_DEVICE(0x6549, 0x1200),
2874 .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
2788 /* Creative X-Fi (CA0110-IBG) */ 2875 /* Creative X-Fi (CA0110-IBG) */
2789#if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE) 2876#if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE)
2790 /* the following entry conflicts with snd-ctxfi driver, 2877 /* the following entry conflicts with snd-ctxfi driver,
@@ -2794,20 +2881,27 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2794 { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID), 2881 { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID),
2795 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 2882 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2796 .class_mask = 0xffffff, 2883 .class_mask = 0xffffff,
2797 .driver_data = AZX_DRIVER_GENERIC }, 2884 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
2885 AZX_DCAPS_RIRB_PRE_DELAY },
2798#else 2886#else
2799 /* this entry seems still valid -- i.e. without emu20kx chip */ 2887 /* this entry seems still valid -- i.e. without emu20kx chip */
2800 { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC }, 2888 { PCI_DEVICE(0x1102, 0x0009),
2889 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
2890 AZX_DCAPS_RIRB_PRE_DELAY },
2801#endif 2891#endif
2892 /* Vortex86MX */
2893 { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
2894 /* VMware HDAudio */
2895 { PCI_DEVICE(0x15ad, 0x1977), .driver_data = AZX_DRIVER_GENERIC },
2802 /* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */ 2896 /* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */
2803 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), 2897 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
2804 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 2898 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2805 .class_mask = 0xffffff, 2899 .class_mask = 0xffffff,
2806 .driver_data = AZX_DRIVER_GENERIC }, 2900 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
2807 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID), 2901 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID),
2808 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 2902 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2809 .class_mask = 0xffffff, 2903 .class_mask = 0xffffff,
2810 .driver_data = AZX_DRIVER_GENERIC }, 2904 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
2811 { 0, } 2905 { 0, }
2812}; 2906};
2813MODULE_DEVICE_TABLE(pci, azx_ids); 2907MODULE_DEVICE_TABLE(pci, azx_ids);
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 28ab4aead48f..08ec073444e2 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -38,10 +38,11 @@
38 */ 38 */
39#define HDA_COMPOSE_AMP_VAL_OFS(nid,chs,idx,dir,ofs) \ 39#define HDA_COMPOSE_AMP_VAL_OFS(nid,chs,idx,dir,ofs) \
40 ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19) | ((ofs)<<23)) 40 ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19) | ((ofs)<<23))
41#define HDA_AMP_VAL_MIN_MUTE (1<<29)
41#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \ 42#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \
42 HDA_COMPOSE_AMP_VAL_OFS(nid, chs, idx, dir, 0) 43 HDA_COMPOSE_AMP_VAL_OFS(nid, chs, idx, dir, 0)
43/* mono volume with index (index=0,1,...) (channel=1,2) */ 44/* mono volume with index (index=0,1,...) (channel=1,2) */
44#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 45#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, dir, flags) \
45 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 46 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
46 .subdevice = HDA_SUBDEV_AMP_FLAG, \ 47 .subdevice = HDA_SUBDEV_AMP_FLAG, \
47 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 48 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
@@ -51,16 +52,20 @@
51 .get = snd_hda_mixer_amp_volume_get, \ 52 .get = snd_hda_mixer_amp_volume_get, \
52 .put = snd_hda_mixer_amp_volume_put, \ 53 .put = snd_hda_mixer_amp_volume_put, \
53 .tlv = { .c = snd_hda_mixer_amp_tlv }, \ 54 .tlv = { .c = snd_hda_mixer_amp_tlv }, \
54 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } 55 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, dir) | flags }
55/* stereo volume with index */ 56/* stereo volume with index */
56#define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \ 57#define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
57 HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction) 58 HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction, 0)
58/* mono volume */ 59/* mono volume */
59#define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \ 60#define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \
60 HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction) 61 HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction, 0)
61/* stereo volume */ 62/* stereo volume */
62#define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \ 63#define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \
63 HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction) 64 HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction)
65/* stereo volume with min=mute */
66#define HDA_CODEC_VOLUME_MIN_MUTE(xname, nid, xindex, direction) \
67 HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, 3, xindex, direction, \
68 HDA_AMP_VAL_MIN_MUTE)
64/* mono mute switch with index (index=0,1,...) (channel=1,2) */ 69/* mono mute switch with index (index=0,1,...) (channel=1,2) */
65#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 70#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
66 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 71 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
@@ -135,7 +140,7 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
135struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, 140struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
136 const char *name); 141 const char *name);
137int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 142int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
138 unsigned int *tlv, const char **slaves); 143 unsigned int *tlv, const char * const *slaves);
139int snd_hda_codec_reset(struct hda_codec *codec); 144int snd_hda_codec_reset(struct hda_codec *codec);
140 145
141/* amp value bits */ 146/* amp value bits */
@@ -215,7 +220,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
215 */ 220 */
216#define HDA_MAX_NUM_INPUTS 16 221#define HDA_MAX_NUM_INPUTS 16
217struct hda_input_mux_item { 222struct hda_input_mux_item {
218 const char *label; 223 char label[32];
219 unsigned int index; 224 unsigned int index;
220}; 225};
221struct hda_input_mux { 226struct hda_input_mux {
@@ -262,11 +267,11 @@ enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */
262 267
263struct hda_multi_out { 268struct hda_multi_out {
264 int num_dacs; /* # of DACs, must be more than 1 */ 269 int num_dacs; /* # of DACs, must be more than 1 */
265 hda_nid_t *dac_nids; /* DAC list */ 270 const hda_nid_t *dac_nids; /* DAC list */
266 hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */ 271 hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */
267 hda_nid_t extra_out_nid[3]; /* optional DACs, 0 when not exists */ 272 hda_nid_t extra_out_nid[3]; /* optional DACs, 0 when not exists */
268 hda_nid_t dig_out_nid; /* digital out audio widget */ 273 hda_nid_t dig_out_nid; /* digital out audio widget */
269 hda_nid_t *slave_dig_outs; 274 const hda_nid_t *slave_dig_outs;
270 int max_channels; /* currently supported analog channels */ 275 int max_channels; /* currently supported analog channels */
271 int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */ 276 int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */
272 int no_share_stream; /* don't share a stream with multiple pins */ 277 int no_share_stream; /* don't share a stream with multiple pins */
@@ -336,13 +341,13 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen);
336 * Misc 341 * Misc
337 */ 342 */
338int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, 343int snd_hda_check_board_config(struct hda_codec *codec, int num_configs,
339 const char **modelnames, 344 const char * const *modelnames,
340 const struct snd_pci_quirk *pci_list); 345 const struct snd_pci_quirk *pci_list);
341int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, 346int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
342 int num_configs, const char **models, 347 int num_configs, const char * const *models,
343 const struct snd_pci_quirk *tbl); 348 const struct snd_pci_quirk *tbl);
344int snd_hda_add_new_ctls(struct hda_codec *codec, 349int snd_hda_add_new_ctls(struct hda_codec *codec,
345 struct snd_kcontrol_new *knew); 350 const struct snd_kcontrol_new *knew);
346 351
347/* 352/*
348 * unsolicited event handler 353 * unsolicited event handler
@@ -366,9 +371,7 @@ struct hda_bus_unsolicited {
366 371
367enum { 372enum {
368 AUTO_PIN_MIC, 373 AUTO_PIN_MIC,
369 AUTO_PIN_FRONT_MIC, 374 AUTO_PIN_LINE_IN,
370 AUTO_PIN_LINE,
371 AUTO_PIN_FRONT_LINE,
372 AUTO_PIN_CD, 375 AUTO_PIN_CD,
373 AUTO_PIN_AUX, 376 AUTO_PIN_AUX,
374 AUTO_PIN_LAST 377 AUTO_PIN_LAST
@@ -380,9 +383,33 @@ enum {
380 AUTO_PIN_HP_OUT 383 AUTO_PIN_HP_OUT
381}; 384};
382 385
383extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST];
384
385#define AUTO_CFG_MAX_OUTS 5 386#define AUTO_CFG_MAX_OUTS 5
387#define AUTO_CFG_MAX_INS 8
388
389struct auto_pin_cfg_item {
390 hda_nid_t pin;
391 int type;
392};
393
394struct auto_pin_cfg;
395const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin,
396 int check_location);
397const char *hda_get_autocfg_input_label(struct hda_codec *codec,
398 const struct auto_pin_cfg *cfg,
399 int input);
400int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label,
401 int index, int *type_index_ret);
402
403enum {
404 INPUT_PIN_ATTR_UNUSED, /* pin not connected */
405 INPUT_PIN_ATTR_INT, /* internal mic/line-in */
406 INPUT_PIN_ATTR_DOCK, /* docking mic/line-in */
407 INPUT_PIN_ATTR_NORMAL, /* mic/line-in jack */
408 INPUT_PIN_ATTR_FRONT, /* mic/line-in jack in front */
409 INPUT_PIN_ATTR_REAR, /* mic/line-in jack in rear */
410};
411
412int snd_hda_get_input_pin_attr(unsigned int def_conf);
386 413
387struct auto_pin_cfg { 414struct auto_pin_cfg {
388 int line_outs; 415 int line_outs;
@@ -393,7 +420,8 @@ struct auto_pin_cfg {
393 int hp_outs; 420 int hp_outs;
394 int line_out_type; /* AUTO_PIN_XXX_OUT */ 421 int line_out_type; /* AUTO_PIN_XXX_OUT */
395 hda_nid_t hp_pins[AUTO_CFG_MAX_OUTS]; 422 hda_nid_t hp_pins[AUTO_CFG_MAX_OUTS];
396 hda_nid_t input_pins[AUTO_PIN_LAST]; 423 int num_inputs;
424 struct auto_pin_cfg_item inputs[AUTO_CFG_MAX_INS];
397 int dig_outs; 425 int dig_outs;
398 hda_nid_t dig_out_pins[2]; 426 hda_nid_t dig_out_pins[2];
399 hda_nid_t dig_in_pin; 427 hda_nid_t dig_in_pin;
@@ -415,7 +443,7 @@ struct auto_pin_cfg {
415 443
416int snd_hda_parse_pin_def_config(struct hda_codec *codec, 444int snd_hda_parse_pin_def_config(struct hda_codec *codec,
417 struct auto_pin_cfg *cfg, 445 struct auto_pin_cfg *cfg,
418 hda_nid_t *ignore_nids); 446 const hda_nid_t *ignore_nids);
419 447
420/* amp values */ 448/* amp values */
421#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) 449#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8))
@@ -465,6 +493,12 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid);
465u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); 493u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
466int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); 494int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
467 495
496static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
497{
498 return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) &&
499 (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP);
500}
501
468/* flags for hda_nid_item */ 502/* flags for hda_nid_item */
469#define HDA_NID_ITEM_AMP (1<<0) 503#define HDA_NID_ITEM_AMP (1<<0)
470 504
@@ -539,7 +573,7 @@ struct hda_amp_list {
539}; 573};
540 574
541struct hda_loopback_check { 575struct hda_loopback_check {
542 struct hda_amp_list *amplist; 576 const struct hda_amp_list *amplist;
543 int power_on; 577 int power_on;
544}; 578};
545 579
@@ -558,6 +592,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
558#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) 592#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1)
559#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) 593#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
560#define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f) 594#define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f)
595#define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1)
561 596
562/* 597/*
563 * CEA Short Audio Descriptor data 598 * CEA Short Audio Descriptor data
@@ -627,4 +662,28 @@ static inline void snd_hda_eld_proc_free(struct hda_codec *codec,
627#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 662#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
628void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen); 663void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
629 664
665/*
666 * Input-jack notification support
667 */
668#ifdef CONFIG_SND_HDA_INPUT_JACK
669int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type,
670 const char *name);
671void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid);
672void snd_hda_input_jack_free(struct hda_codec *codec);
673#else /* CONFIG_SND_HDA_INPUT_JACK */
674static inline int snd_hda_input_jack_add(struct hda_codec *codec,
675 hda_nid_t nid, int type,
676 const char *name)
677{
678 return 0;
679}
680static inline void snd_hda_input_jack_report(struct hda_codec *codec,
681 hda_nid_t nid)
682{
683}
684static inline void snd_hda_input_jack_free(struct hda_codec *codec)
685{
686}
687#endif /* CONFIG_SND_HDA_INPUT_JACK */
688
630#endif /* __SOUND_HDA_LOCAL_H */ 689#endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index f025200f2a62..bfe74c2fb079 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -418,7 +418,7 @@ static void print_digital_conv(struct snd_info_buffer *buffer,
418 418
419static const char *get_pwr_state(u32 state) 419static const char *get_pwr_state(u32 state)
420{ 420{
421 static const char *buf[4] = { 421 static const char * const buf[4] = {
422 "D0", "D1", "D2", "D3" 422 "D0", "D1", "D2", "D3"
423 }; 423 };
424 if (state < 4) 424 if (state < 4)
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 10bbbaf6ebc3..d694e9d4921d 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -30,10 +30,10 @@
30#include "hda_beep.h" 30#include "hda_beep.h"
31 31
32struct ad198x_spec { 32struct ad198x_spec {
33 struct snd_kcontrol_new *mixers[5]; 33 const struct snd_kcontrol_new *mixers[6];
34 int num_mixers; 34 int num_mixers;
35 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 35 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
36 const struct hda_verb *init_verbs[5]; /* initialization verbs 36 const struct hda_verb *init_verbs[6]; /* initialization verbs
37 * don't forget NULL termination! 37 * don't forget NULL termination!
38 */ 38 */
39 unsigned int num_init_verbs; 39 unsigned int num_init_verbs;
@@ -46,14 +46,17 @@ struct ad198x_spec {
46 unsigned int cur_eapd; 46 unsigned int cur_eapd;
47 unsigned int need_dac_fix; 47 unsigned int need_dac_fix;
48 48
49 const hda_nid_t *alt_dac_nid;
50 const struct hda_pcm_stream *stream_analog_alt_playback;
51
49 /* capture */ 52 /* capture */
50 unsigned int num_adc_nids; 53 unsigned int num_adc_nids;
51 hda_nid_t *adc_nids; 54 const hda_nid_t *adc_nids;
52 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 55 hda_nid_t dig_in_nid; /* digital-in NID; optional */
53 56
54 /* capture source */ 57 /* capture source */
55 const struct hda_input_mux *input_mux; 58 const struct hda_input_mux *input_mux;
56 hda_nid_t *capsrc_nids; 59 const hda_nid_t *capsrc_nids;
57 unsigned int cur_mux[3]; 60 unsigned int cur_mux[3];
58 61
59 /* channel model */ 62 /* channel model */
@@ -81,8 +84,8 @@ struct ad198x_spec {
81#endif 84#endif
82 /* for virtual master */ 85 /* for virtual master */
83 hda_nid_t vmaster_nid; 86 hda_nid_t vmaster_nid;
84 const char **slave_vols; 87 const char * const *slave_vols;
85 const char **slave_sws; 88 const char * const *slave_sws;
86}; 89};
87 90
88/* 91/*
@@ -130,7 +133,7 @@ static int ad198x_init(struct hda_codec *codec)
130 return 0; 133 return 0;
131} 134}
132 135
133static const char *ad_slave_vols[] = { 136static const char * const ad_slave_vols[] = {
134 "Front Playback Volume", 137 "Front Playback Volume",
135 "Surround Playback Volume", 138 "Surround Playback Volume",
136 "Center Playback Volume", 139 "Center Playback Volume",
@@ -143,7 +146,7 @@ static const char *ad_slave_vols[] = {
143 NULL 146 NULL
144}; 147};
145 148
146static const char *ad_slave_sws[] = { 149static const char * const ad_slave_sws[] = {
147 "Front Playback Switch", 150 "Front Playback Switch",
148 "Surround Playback Switch", 151 "Surround Playback Switch",
149 "Center Playback Switch", 152 "Center Playback Switch",
@@ -156,17 +159,36 @@ static const char *ad_slave_sws[] = {
156 NULL 159 NULL
157}; 160};
158 161
162static const char * const ad1988_6stack_fp_slave_vols[] = {
163 "Front Playback Volume",
164 "Surround Playback Volume",
165 "Center Playback Volume",
166 "LFE Playback Volume",
167 "Side Playback Volume",
168 "IEC958 Playback Volume",
169 NULL
170};
171
172static const char * const ad1988_6stack_fp_slave_sws[] = {
173 "Front Playback Switch",
174 "Surround Playback Switch",
175 "Center Playback Switch",
176 "LFE Playback Switch",
177 "Side Playback Switch",
178 "IEC958 Playback Switch",
179 NULL
180};
159static void ad198x_free_kctls(struct hda_codec *codec); 181static void ad198x_free_kctls(struct hda_codec *codec);
160 182
161#ifdef CONFIG_SND_HDA_INPUT_BEEP 183#ifdef CONFIG_SND_HDA_INPUT_BEEP
162/* additional beep mixers; the actual parameters are overwritten at build */ 184/* additional beep mixers; the actual parameters are overwritten at build */
163static struct snd_kcontrol_new ad_beep_mixer[] = { 185static const struct snd_kcontrol_new ad_beep_mixer[] = {
164 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT), 186 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT),
165 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT), 187 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT),
166 { } /* end */ 188 { } /* end */
167}; 189};
168 190
169static struct snd_kcontrol_new ad_beep2_mixer[] = { 191static const struct snd_kcontrol_new ad_beep2_mixer[] = {
170 HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT), 192 HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT),
171 HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT), 193 HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT),
172 { } /* end */ 194 { } /* end */
@@ -209,7 +231,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
209 /* create beep controls if needed */ 231 /* create beep controls if needed */
210#ifdef CONFIG_SND_HDA_INPUT_BEEP 232#ifdef CONFIG_SND_HDA_INPUT_BEEP
211 if (spec->beep_amp) { 233 if (spec->beep_amp) {
212 struct snd_kcontrol_new *knew; 234 const struct snd_kcontrol_new *knew;
213 knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer; 235 knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer;
214 for ( ; knew->name; knew++) { 236 for ( ; knew->name; knew++) {
215 struct snd_kcontrol *kctl; 237 struct snd_kcontrol *kctl;
@@ -309,6 +331,13 @@ static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
309 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 331 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
310} 332}
311 333
334static const struct hda_pcm_stream ad198x_pcm_analog_alt_playback = {
335 .substreams = 1,
336 .channels_min = 2,
337 .channels_max = 2,
338 /* NID is set in ad198x_build_pcms */
339};
340
312/* 341/*
313 * Digital out 342 * Digital out
314 */ 343 */
@@ -374,7 +403,7 @@ static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
374 403
375/* 404/*
376 */ 405 */
377static struct hda_pcm_stream ad198x_pcm_analog_playback = { 406static const struct hda_pcm_stream ad198x_pcm_analog_playback = {
378 .substreams = 1, 407 .substreams = 1,
379 .channels_min = 2, 408 .channels_min = 2,
380 .channels_max = 6, /* changed later */ 409 .channels_max = 6, /* changed later */
@@ -386,7 +415,7 @@ static struct hda_pcm_stream ad198x_pcm_analog_playback = {
386 }, 415 },
387}; 416};
388 417
389static struct hda_pcm_stream ad198x_pcm_analog_capture = { 418static const struct hda_pcm_stream ad198x_pcm_analog_capture = {
390 .substreams = 1, 419 .substreams = 1,
391 .channels_min = 2, 420 .channels_min = 2,
392 .channels_max = 2, 421 .channels_max = 2,
@@ -397,7 +426,7 @@ static struct hda_pcm_stream ad198x_pcm_analog_capture = {
397 }, 426 },
398}; 427};
399 428
400static struct hda_pcm_stream ad198x_pcm_digital_playback = { 429static const struct hda_pcm_stream ad198x_pcm_digital_playback = {
401 .substreams = 1, 430 .substreams = 1,
402 .channels_min = 2, 431 .channels_min = 2,
403 .channels_max = 2, 432 .channels_max = 2,
@@ -410,7 +439,7 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = {
410 }, 439 },
411}; 440};
412 441
413static struct hda_pcm_stream ad198x_pcm_digital_capture = { 442static const struct hda_pcm_stream ad198x_pcm_digital_capture = {
414 .substreams = 1, 443 .substreams = 1,
415 .channels_min = 2, 444 .channels_min = 2,
416 .channels_max = 2, 445 .channels_max = 2,
@@ -446,12 +475,18 @@ static int ad198x_build_pcms(struct hda_codec *codec)
446 } 475 }
447 } 476 }
448 477
449 return 0; 478 if (spec->alt_dac_nid && spec->stream_analog_alt_playback) {
450} 479 codec->num_pcms++;
480 info = spec->pcm_rec + 2;
481 info->name = "AD198x Headphone";
482 info->pcm_type = HDA_PCM_TYPE_AUDIO;
483 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
484 *spec->stream_analog_alt_playback;
485 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
486 spec->alt_dac_nid[0];
487 }
451 488
452static inline void ad198x_shutup(struct hda_codec *codec) 489 return 0;
453{
454 snd_hda_shutup_pins(codec);
455} 490}
456 491
457static void ad198x_free_kctls(struct hda_codec *codec) 492static void ad198x_free_kctls(struct hda_codec *codec)
@@ -471,9 +506,11 @@ static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
471 hda_nid_t hp) 506 hda_nid_t hp)
472{ 507{
473 struct ad198x_spec *spec = codec->spec; 508 struct ad198x_spec *spec = codec->spec;
474 snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE, 509 if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD)
510 snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
475 !spec->inv_eapd ? 0x00 : 0x02); 511 !spec->inv_eapd ? 0x00 : 0x02);
476 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE, 512 if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD)
513 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
477 !spec->inv_eapd ? 0x00 : 0x02); 514 !spec->inv_eapd ? 0x00 : 0x02);
478} 515}
479 516
@@ -489,6 +526,10 @@ static void ad198x_power_eapd(struct hda_codec *codec)
489 case 0x11d4184a: 526 case 0x11d4184a:
490 case 0x11d4194a: 527 case 0x11d4194a:
491 case 0x11d4194b: 528 case 0x11d4194b:
529 case 0x11d41988:
530 case 0x11d4198b:
531 case 0x11d4989a:
532 case 0x11d4989b:
492 ad198x_power_eapd_write(codec, 0x12, 0x11); 533 ad198x_power_eapd_write(codec, 0x12, 0x11);
493 break; 534 break;
494 case 0x11d41981: 535 case 0x11d41981:
@@ -498,15 +539,15 @@ static void ad198x_power_eapd(struct hda_codec *codec)
498 case 0x11d41986: 539 case 0x11d41986:
499 ad198x_power_eapd_write(codec, 0x1b, 0x1a); 540 ad198x_power_eapd_write(codec, 0x1b, 0x1a);
500 break; 541 break;
501 case 0x11d41988:
502 case 0x11d4198b:
503 case 0x11d4989a:
504 case 0x11d4989b:
505 ad198x_power_eapd_write(codec, 0x29, 0x22);
506 break;
507 } 542 }
508} 543}
509 544
545static void ad198x_shutup(struct hda_codec *codec)
546{
547 snd_hda_shutup_pins(codec);
548 ad198x_power_eapd(codec);
549}
550
510static void ad198x_free(struct hda_codec *codec) 551static void ad198x_free(struct hda_codec *codec)
511{ 552{
512 struct ad198x_spec *spec = codec->spec; 553 struct ad198x_spec *spec = codec->spec;
@@ -524,12 +565,11 @@ static void ad198x_free(struct hda_codec *codec)
524static int ad198x_suspend(struct hda_codec *codec, pm_message_t state) 565static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
525{ 566{
526 ad198x_shutup(codec); 567 ad198x_shutup(codec);
527 ad198x_power_eapd(codec);
528 return 0; 568 return 0;
529} 569}
530#endif 570#endif
531 571
532static struct hda_codec_ops ad198x_patch_ops = { 572static const struct hda_codec_ops ad198x_patch_ops = {
533 .build_controls = ad198x_build_controls, 573 .build_controls = ad198x_build_controls,
534 .build_pcms = ad198x_build_pcms, 574 .build_pcms = ad198x_build_pcms,
535 .init = ad198x_init, 575 .init = ad198x_init,
@@ -599,13 +639,13 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
599#define AD1986A_CLFE_DAC 0x05 639#define AD1986A_CLFE_DAC 0x05
600#define AD1986A_ADC 0x06 640#define AD1986A_ADC 0x06
601 641
602static hda_nid_t ad1986a_dac_nids[3] = { 642static const hda_nid_t ad1986a_dac_nids[3] = {
603 AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC 643 AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
604}; 644};
605static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC }; 645static const hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
606static hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 }; 646static const hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 };
607 647
608static struct hda_input_mux ad1986a_capture_source = { 648static const struct hda_input_mux ad1986a_capture_source = {
609 .num_items = 7, 649 .num_items = 7,
610 .items = { 650 .items = {
611 { "Mic", 0x0 }, 651 { "Mic", 0x0 },
@@ -619,7 +659,7 @@ static struct hda_input_mux ad1986a_capture_source = {
619}; 659};
620 660
621 661
622static struct hda_bind_ctls ad1986a_bind_pcm_vol = { 662static const struct hda_bind_ctls ad1986a_bind_pcm_vol = {
623 .ops = &snd_hda_bind_vol, 663 .ops = &snd_hda_bind_vol,
624 .values = { 664 .values = {
625 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), 665 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
@@ -629,7 +669,7 @@ static struct hda_bind_ctls ad1986a_bind_pcm_vol = {
629 }, 669 },
630}; 670};
631 671
632static struct hda_bind_ctls ad1986a_bind_pcm_sw = { 672static const struct hda_bind_ctls ad1986a_bind_pcm_sw = {
633 .ops = &snd_hda_bind_sw, 673 .ops = &snd_hda_bind_sw,
634 .values = { 674 .values = {
635 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), 675 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
@@ -642,7 +682,7 @@ static struct hda_bind_ctls ad1986a_bind_pcm_sw = {
642/* 682/*
643 * mixers 683 * mixers
644 */ 684 */
645static struct snd_kcontrol_new ad1986a_mixers[] = { 685static const struct snd_kcontrol_new ad1986a_mixers[] = {
646 /* 686 /*
647 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity 687 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
648 */ 688 */
@@ -666,7 +706,7 @@ static struct snd_kcontrol_new ad1986a_mixers[] = {
666 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), 706 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
668 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 708 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
669 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), 709 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
670 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), 710 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
671 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), 711 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
672 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 712 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
@@ -683,7 +723,7 @@ static struct snd_kcontrol_new ad1986a_mixers[] = {
683}; 723};
684 724
685/* additional mixers for 3stack mode */ 725/* additional mixers for 3stack mode */
686static struct snd_kcontrol_new ad1986a_3st_mixers[] = { 726static const struct snd_kcontrol_new ad1986a_3st_mixers[] = {
687 { 727 {
688 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 728 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
689 .name = "Channel Mode", 729 .name = "Channel Mode",
@@ -695,10 +735,10 @@ static struct snd_kcontrol_new ad1986a_3st_mixers[] = {
695}; 735};
696 736
697/* laptop model - 2ch only */ 737/* laptop model - 2ch only */
698static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC }; 738static const hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
699 739
700/* master controls both pins 0x1a and 0x1b */ 740/* master controls both pins 0x1a and 0x1b */
701static struct hda_bind_ctls ad1986a_laptop_master_vol = { 741static const struct hda_bind_ctls ad1986a_laptop_master_vol = {
702 .ops = &snd_hda_bind_vol, 742 .ops = &snd_hda_bind_vol,
703 .values = { 743 .values = {
704 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), 744 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
@@ -707,7 +747,7 @@ static struct hda_bind_ctls ad1986a_laptop_master_vol = {
707 }, 747 },
708}; 748};
709 749
710static struct hda_bind_ctls ad1986a_laptop_master_sw = { 750static const struct hda_bind_ctls ad1986a_laptop_master_sw = {
711 .ops = &snd_hda_bind_sw, 751 .ops = &snd_hda_bind_sw,
712 .values = { 752 .values = {
713 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), 753 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
@@ -716,7 +756,7 @@ static struct hda_bind_ctls ad1986a_laptop_master_sw = {
716 }, 756 },
717}; 757};
718 758
719static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { 759static const struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
720 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), 760 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
721 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 761 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
722 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), 762 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
@@ -729,7 +769,7 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
729 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), 769 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
730 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 770 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
731 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 771 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
732 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), 772 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
733 /* 773 /*
734 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), 774 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
735 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */ 775 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
@@ -747,7 +787,7 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
747 787
748/* laptop-eapd model - 2ch only */ 788/* laptop-eapd model - 2ch only */
749 789
750static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { 790static const struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
751 .num_items = 3, 791 .num_items = 3,
752 .items = { 792 .items = {
753 { "Mic", 0x0 }, 793 { "Mic", 0x0 },
@@ -756,7 +796,7 @@ static struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
756 }, 796 },
757}; 797};
758 798
759static struct hda_input_mux ad1986a_automic_capture_source = { 799static const struct hda_input_mux ad1986a_automic_capture_source = {
760 .num_items = 2, 800 .num_items = 2,
761 .items = { 801 .items = {
762 { "Mic", 0x0 }, 802 { "Mic", 0x0 },
@@ -764,18 +804,18 @@ static struct hda_input_mux ad1986a_automic_capture_source = {
764 }, 804 },
765}; 805};
766 806
767static struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = { 807static const struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = {
768 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), 808 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
769 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), 809 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
770 { } /* end */ 810 { } /* end */
771}; 811};
772 812
773static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { 813static const struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
774 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), 814 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
775 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 815 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
776 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
777 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 817 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
778 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), 818 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
779 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 819 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
780 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), 820 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
781 { 821 {
@@ -797,7 +837,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
797 { } /* end */ 837 { } /* end */
798}; 838};
799 839
800static struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = { 840static const struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = {
801 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT), 841 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT),
802 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT), 842 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT),
803 { } /* end */ 843 { } /* end */
@@ -891,7 +931,7 @@ static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
891 return change; 931 return change;
892} 932}
893 933
894static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { 934static const struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
895 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), 935 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
896 { 936 {
897 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 937 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -909,7 +949,7 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
909/* 949/*
910 * initialization verbs 950 * initialization verbs
911 */ 951 */
912static struct hda_verb ad1986a_init_verbs[] = { 952static const struct hda_verb ad1986a_init_verbs[] = {
913 /* Front, Surround, CLFE DAC; mute as default */ 953 /* Front, Surround, CLFE DAC; mute as default */
914 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 954 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
915 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 955 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
@@ -964,7 +1004,7 @@ static struct hda_verb ad1986a_init_verbs[] = {
964 { } /* end */ 1004 { } /* end */
965}; 1005};
966 1006
967static struct hda_verb ad1986a_ch2_init[] = { 1007static const struct hda_verb ad1986a_ch2_init[] = {
968 /* Surround out -> Line In */ 1008 /* Surround out -> Line In */
969 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1009 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
970 /* Line-in selectors */ 1010 /* Line-in selectors */
@@ -976,7 +1016,7 @@ static struct hda_verb ad1986a_ch2_init[] = {
976 { } /* end */ 1016 { } /* end */
977}; 1017};
978 1018
979static struct hda_verb ad1986a_ch4_init[] = { 1019static const struct hda_verb ad1986a_ch4_init[] = {
980 /* Surround out -> Surround */ 1020 /* Surround out -> Surround */
981 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1021 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
982 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1022 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
@@ -986,7 +1026,7 @@ static struct hda_verb ad1986a_ch4_init[] = {
986 { } /* end */ 1026 { } /* end */
987}; 1027};
988 1028
989static struct hda_verb ad1986a_ch6_init[] = { 1029static const struct hda_verb ad1986a_ch6_init[] = {
990 /* Surround out -> Surround out */ 1030 /* Surround out -> Surround out */
991 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1031 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
992 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1032 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
@@ -996,19 +1036,19 @@ static struct hda_verb ad1986a_ch6_init[] = {
996 { } /* end */ 1036 { } /* end */
997}; 1037};
998 1038
999static struct hda_channel_mode ad1986a_modes[3] = { 1039static const struct hda_channel_mode ad1986a_modes[3] = {
1000 { 2, ad1986a_ch2_init }, 1040 { 2, ad1986a_ch2_init },
1001 { 4, ad1986a_ch4_init }, 1041 { 4, ad1986a_ch4_init },
1002 { 6, ad1986a_ch6_init }, 1042 { 6, ad1986a_ch6_init },
1003}; 1043};
1004 1044
1005/* eapd initialization */ 1045/* eapd initialization */
1006static struct hda_verb ad1986a_eapd_init_verbs[] = { 1046static const struct hda_verb ad1986a_eapd_init_verbs[] = {
1007 {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, 1047 {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
1008 {} 1048 {}
1009}; 1049};
1010 1050
1011static struct hda_verb ad1986a_automic_verbs[] = { 1051static const struct hda_verb ad1986a_automic_verbs[] = {
1012 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1052 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1013 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1053 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1014 /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/ 1054 /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/
@@ -1018,7 +1058,7 @@ static struct hda_verb ad1986a_automic_verbs[] = {
1018}; 1058};
1019 1059
1020/* Ultra initialization */ 1060/* Ultra initialization */
1021static struct hda_verb ad1986a_ultra_init[] = { 1061static const struct hda_verb ad1986a_ultra_init[] = {
1022 /* eapd initialization */ 1062 /* eapd initialization */
1023 { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, 1063 { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
1024 /* CLFE -> Mic in */ 1064 /* CLFE -> Mic in */
@@ -1029,7 +1069,7 @@ static struct hda_verb ad1986a_ultra_init[] = {
1029}; 1069};
1030 1070
1031/* pin sensing on HP jack */ 1071/* pin sensing on HP jack */
1032static struct hda_verb ad1986a_hp_init_verbs[] = { 1072static const struct hda_verb ad1986a_hp_init_verbs[] = {
1033 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT}, 1073 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT},
1034 {} 1074 {}
1035}; 1075};
@@ -1069,7 +1109,7 @@ enum {
1069 AD1986A_MODELS 1109 AD1986A_MODELS
1070}; 1110};
1071 1111
1072static const char *ad1986a_models[AD1986A_MODELS] = { 1112static const char * const ad1986a_models[AD1986A_MODELS] = {
1073 [AD1986A_6STACK] = "6stack", 1113 [AD1986A_6STACK] = "6stack",
1074 [AD1986A_3STACK] = "3stack", 1114 [AD1986A_3STACK] = "3stack",
1075 [AD1986A_LAPTOP] = "laptop", 1115 [AD1986A_LAPTOP] = "laptop",
@@ -1080,7 +1120,7 @@ static const char *ad1986a_models[AD1986A_MODELS] = {
1080 [AD1986A_SAMSUNG_P50] = "samsung-p50", 1120 [AD1986A_SAMSUNG_P50] = "samsung-p50",
1081}; 1121};
1082 1122
1083static struct snd_pci_quirk ad1986a_cfg_tbl[] = { 1123static const struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1084 SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD), 1124 SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD),
1085 SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD), 1125 SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD),
1086 SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD), 1126 SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD),
@@ -1112,7 +1152,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1112}; 1152};
1113 1153
1114#ifdef CONFIG_SND_HDA_POWER_SAVE 1154#ifdef CONFIG_SND_HDA_POWER_SAVE
1115static struct hda_amp_list ad1986a_loopbacks[] = { 1155static const struct hda_amp_list ad1986a_loopbacks[] = {
1116 { 0x13, HDA_OUTPUT, 0 }, /* Mic */ 1156 { 0x13, HDA_OUTPUT, 0 }, /* Mic */
1117 { 0x14, HDA_OUTPUT, 0 }, /* Phone */ 1157 { 0x14, HDA_OUTPUT, 0 }, /* Phone */
1118 { 0x15, HDA_OUTPUT, 0 }, /* CD */ 1158 { 0x15, HDA_OUTPUT, 0 }, /* CD */
@@ -1276,6 +1316,7 @@ static int patch_ad1986a(struct hda_codec *codec)
1276 spec->multiout.no_share_stream = 1; 1316 spec->multiout.no_share_stream = 1;
1277 1317
1278 codec->no_trigger_sense = 1; 1318 codec->no_trigger_sense = 1;
1319 codec->no_sticky_stream = 1;
1279 1320
1280 return 0; 1321 return 0;
1281} 1322}
@@ -1288,11 +1329,11 @@ static int patch_ad1986a(struct hda_codec *codec)
1288#define AD1983_DAC 0x03 1329#define AD1983_DAC 0x03
1289#define AD1983_ADC 0x04 1330#define AD1983_ADC 0x04
1290 1331
1291static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; 1332static const hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
1292static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; 1333static const hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
1293static hda_nid_t ad1983_capsrc_nids[1] = { 0x15 }; 1334static const hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
1294 1335
1295static struct hda_input_mux ad1983_capture_source = { 1336static const struct hda_input_mux ad1983_capture_source = {
1296 .num_items = 4, 1337 .num_items = 4,
1297 .items = { 1338 .items = {
1298 { "Mic", 0x0 }, 1339 { "Mic", 0x0 },
@@ -1307,7 +1348,7 @@ static struct hda_input_mux ad1983_capture_source = {
1307 */ 1348 */
1308static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1349static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1309{ 1350{
1310 static char *texts[] = { "PCM", "ADC" }; 1351 static const char * const texts[] = { "PCM", "ADC" };
1311 1352
1312 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1353 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1313 uinfo->count = 1; 1354 uinfo->count = 1;
@@ -1344,7 +1385,7 @@ static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
1344 return 0; 1385 return 0;
1345} 1386}
1346 1387
1347static struct snd_kcontrol_new ad1983_mixers[] = { 1388static const struct snd_kcontrol_new ad1983_mixers[] = {
1348 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), 1389 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1349 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), 1390 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1350 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), 1391 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
@@ -1357,7 +1398,7 @@ static struct snd_kcontrol_new ad1983_mixers[] = {
1357 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1398 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1358 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT), 1399 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1359 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), 1400 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1360 HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT), 1401 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0c, 0x0, HDA_OUTPUT),
1361 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1402 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1362 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1403 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1363 { 1404 {
@@ -1377,7 +1418,7 @@ static struct snd_kcontrol_new ad1983_mixers[] = {
1377 { } /* end */ 1418 { } /* end */
1378}; 1419};
1379 1420
1380static struct hda_verb ad1983_init_verbs[] = { 1421static const struct hda_verb ad1983_init_verbs[] = {
1381 /* Front, HP, Mono; mute as default */ 1422 /* Front, HP, Mono; mute as default */
1382 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1423 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1383 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1424 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
@@ -1417,7 +1458,7 @@ static struct hda_verb ad1983_init_verbs[] = {
1417}; 1458};
1418 1459
1419#ifdef CONFIG_SND_HDA_POWER_SAVE 1460#ifdef CONFIG_SND_HDA_POWER_SAVE
1420static struct hda_amp_list ad1983_loopbacks[] = { 1461static const struct hda_amp_list ad1983_loopbacks[] = {
1421 { 0x12, HDA_OUTPUT, 0 }, /* Mic */ 1462 { 0x12, HDA_OUTPUT, 0 }, /* Mic */
1422 { 0x13, HDA_OUTPUT, 0 }, /* Line */ 1463 { 0x13, HDA_OUTPUT, 0 }, /* Line */
1423 { } /* end */ 1464 { } /* end */
@@ -1463,6 +1504,7 @@ static int patch_ad1983(struct hda_codec *codec)
1463 codec->patch_ops = ad198x_patch_ops; 1504 codec->patch_ops = ad198x_patch_ops;
1464 1505
1465 codec->no_trigger_sense = 1; 1506 codec->no_trigger_sense = 1;
1507 codec->no_sticky_stream = 1;
1466 1508
1467 return 0; 1509 return 0;
1468} 1510}
@@ -1476,12 +1518,12 @@ static int patch_ad1983(struct hda_codec *codec)
1476#define AD1981_DAC 0x03 1518#define AD1981_DAC 0x03
1477#define AD1981_ADC 0x04 1519#define AD1981_ADC 0x04
1478 1520
1479static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; 1521static const hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
1480static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; 1522static const hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
1481static hda_nid_t ad1981_capsrc_nids[1] = { 0x15 }; 1523static const hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
1482 1524
1483/* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ 1525/* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
1484static struct hda_input_mux ad1981_capture_source = { 1526static const struct hda_input_mux ad1981_capture_source = {
1485 .num_items = 7, 1527 .num_items = 7,
1486 .items = { 1528 .items = {
1487 { "Front Mic", 0x0 }, 1529 { "Front Mic", 0x0 },
@@ -1494,7 +1536,7 @@ static struct hda_input_mux ad1981_capture_source = {
1494 }, 1536 },
1495}; 1537};
1496 1538
1497static struct snd_kcontrol_new ad1981_mixers[] = { 1539static const struct snd_kcontrol_new ad1981_mixers[] = {
1498 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), 1540 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1499 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), 1541 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1500 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), 1542 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
@@ -1513,8 +1555,8 @@ static struct snd_kcontrol_new ad1981_mixers[] = {
1513 HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT), 1555 HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1514 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 1556 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1515 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 1557 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1516 HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT), 1558 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1517 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT), 1559 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
1518 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1560 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1519 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1561 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1520 { 1562 {
@@ -1535,7 +1577,7 @@ static struct snd_kcontrol_new ad1981_mixers[] = {
1535 { } /* end */ 1577 { } /* end */
1536}; 1578};
1537 1579
1538static struct hda_verb ad1981_init_verbs[] = { 1580static const struct hda_verb ad1981_init_verbs[] = {
1539 /* Front, HP, Mono; mute as default */ 1581 /* Front, HP, Mono; mute as default */
1540 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1582 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1541 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1583 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
@@ -1583,7 +1625,7 @@ static struct hda_verb ad1981_init_verbs[] = {
1583}; 1625};
1584 1626
1585#ifdef CONFIG_SND_HDA_POWER_SAVE 1627#ifdef CONFIG_SND_HDA_POWER_SAVE
1586static struct hda_amp_list ad1981_loopbacks[] = { 1628static const struct hda_amp_list ad1981_loopbacks[] = {
1587 { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */ 1629 { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
1588 { 0x13, HDA_OUTPUT, 0 }, /* Line */ 1630 { 0x13, HDA_OUTPUT, 0 }, /* Line */
1589 { 0x1b, HDA_OUTPUT, 0 }, /* Aux */ 1631 { 0x1b, HDA_OUTPUT, 0 }, /* Aux */
@@ -1603,7 +1645,7 @@ static struct hda_amp_list ad1981_loopbacks[] = {
1603#define AD1981_HP_EVENT 0x37 1645#define AD1981_HP_EVENT 0x37
1604#define AD1981_MIC_EVENT 0x38 1646#define AD1981_MIC_EVENT 0x38
1605 1647
1606static struct hda_verb ad1981_hp_init_verbs[] = { 1648static const struct hda_verb ad1981_hp_init_verbs[] = {
1607 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */ 1649 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */
1608 /* pin sensing on HP and Mic jacks */ 1650 /* pin sensing on HP and Mic jacks */
1609 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, 1651 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
@@ -1632,7 +1674,7 @@ static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1632} 1674}
1633 1675
1634/* bind volumes of both NID 0x05 and 0x06 */ 1676/* bind volumes of both NID 0x05 and 0x06 */
1635static struct hda_bind_ctls ad1981_hp_bind_master_vol = { 1677static const struct hda_bind_ctls ad1981_hp_bind_master_vol = {
1636 .ops = &snd_hda_bind_vol, 1678 .ops = &snd_hda_bind_vol,
1637 .values = { 1679 .values = {
1638 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), 1680 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
@@ -1654,12 +1696,12 @@ static void ad1981_hp_automute(struct hda_codec *codec)
1654/* toggle input of built-in and mic jack appropriately */ 1696/* toggle input of built-in and mic jack appropriately */
1655static void ad1981_hp_automic(struct hda_codec *codec) 1697static void ad1981_hp_automic(struct hda_codec *codec)
1656{ 1698{
1657 static struct hda_verb mic_jack_on[] = { 1699 static const struct hda_verb mic_jack_on[] = {
1658 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1700 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1659 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 1701 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1660 {} 1702 {}
1661 }; 1703 };
1662 static struct hda_verb mic_jack_off[] = { 1704 static const struct hda_verb mic_jack_off[] = {
1663 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 1705 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1664 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 1706 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1665 {} 1707 {}
@@ -1688,7 +1730,7 @@ static void ad1981_hp_unsol_event(struct hda_codec *codec,
1688 } 1730 }
1689} 1731}
1690 1732
1691static struct hda_input_mux ad1981_hp_capture_source = { 1733static const struct hda_input_mux ad1981_hp_capture_source = {
1692 .num_items = 3, 1734 .num_items = 3,
1693 .items = { 1735 .items = {
1694 { "Mic", 0x0 }, 1736 { "Mic", 0x0 },
@@ -1697,7 +1739,7 @@ static struct hda_input_mux ad1981_hp_capture_source = {
1697 }, 1739 },
1698}; 1740};
1699 1741
1700static struct snd_kcontrol_new ad1981_hp_mixers[] = { 1742static const struct snd_kcontrol_new ad1981_hp_mixers[] = {
1701 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), 1743 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1702 { 1744 {
1703 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1745 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1724,8 +1766,8 @@ static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1724 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 1766 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1725 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 1767 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1726#endif 1768#endif
1727 HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT), 1769 HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1728 HDA_CODEC_VOLUME("Internal Mic Boost", 0x18, 0x0, HDA_INPUT), 1770 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
1729 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1771 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1730 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1772 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1731 { 1773 {
@@ -1748,7 +1790,7 @@ static int ad1981_hp_init(struct hda_codec *codec)
1748} 1790}
1749 1791
1750/* configuration for Toshiba Laptops */ 1792/* configuration for Toshiba Laptops */
1751static struct hda_verb ad1981_toshiba_init_verbs[] = { 1793static const struct hda_verb ad1981_toshiba_init_verbs[] = {
1752 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */ 1794 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
1753 /* pin sensing on HP and Mic jacks */ 1795 /* pin sensing on HP and Mic jacks */
1754 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, 1796 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
@@ -1756,14 +1798,14 @@ static struct hda_verb ad1981_toshiba_init_verbs[] = {
1756 {} 1798 {}
1757}; 1799};
1758 1800
1759static struct snd_kcontrol_new ad1981_toshiba_mixers[] = { 1801static const struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
1760 HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT), 1802 HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
1761 HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT), 1803 HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
1762 { } 1804 { }
1763}; 1805};
1764 1806
1765/* configuration for Lenovo Thinkpad T60 */ 1807/* configuration for Lenovo Thinkpad T60 */
1766static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = { 1808static const struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1767 HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT), 1809 HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1768 HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT), 1810 HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1769 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), 1811 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
@@ -1772,7 +1814,7 @@ static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1772 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1814 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1773 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 1815 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1774 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 1816 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1775 HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT), 1817 HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1776 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1818 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1777 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1819 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1778 { 1820 {
@@ -1793,7 +1835,7 @@ static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1793 { } /* end */ 1835 { } /* end */
1794}; 1836};
1795 1837
1796static struct hda_input_mux ad1981_thinkpad_capture_source = { 1838static const struct hda_input_mux ad1981_thinkpad_capture_source = {
1797 .num_items = 3, 1839 .num_items = 3,
1798 .items = { 1840 .items = {
1799 { "Mic", 0x0 }, 1841 { "Mic", 0x0 },
@@ -1811,14 +1853,14 @@ enum {
1811 AD1981_MODELS 1853 AD1981_MODELS
1812}; 1854};
1813 1855
1814static const char *ad1981_models[AD1981_MODELS] = { 1856static const char * const ad1981_models[AD1981_MODELS] = {
1815 [AD1981_HP] = "hp", 1857 [AD1981_HP] = "hp",
1816 [AD1981_THINKPAD] = "thinkpad", 1858 [AD1981_THINKPAD] = "thinkpad",
1817 [AD1981_BASIC] = "basic", 1859 [AD1981_BASIC] = "basic",
1818 [AD1981_TOSHIBA] = "toshiba" 1860 [AD1981_TOSHIBA] = "toshiba"
1819}; 1861};
1820 1862
1821static struct snd_pci_quirk ad1981_cfg_tbl[] = { 1863static const struct snd_pci_quirk ad1981_cfg_tbl[] = {
1822 SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), 1864 SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
1823 SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD), 1865 SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
1824 /* All HP models */ 1866 /* All HP models */
@@ -1917,6 +1959,7 @@ static int patch_ad1981(struct hda_codec *codec)
1917 } 1959 }
1918 1960
1919 codec->no_trigger_sense = 1; 1961 codec->no_trigger_sense = 1;
1962 codec->no_sticky_stream = 1;
1920 1963
1921 return 0; 1964 return 0;
1922} 1965}
@@ -2012,6 +2055,7 @@ static int patch_ad1981(struct hda_codec *codec)
2012enum { 2055enum {
2013 AD1988_6STACK, 2056 AD1988_6STACK,
2014 AD1988_6STACK_DIG, 2057 AD1988_6STACK_DIG,
2058 AD1988_6STACK_DIG_FP,
2015 AD1988_3STACK, 2059 AD1988_3STACK,
2016 AD1988_3STACK_DIG, 2060 AD1988_3STACK_DIG,
2017 AD1988_LAPTOP, 2061 AD1988_LAPTOP,
@@ -2031,28 +2075,32 @@ enum {
2031 * mixers 2075 * mixers
2032 */ 2076 */
2033 2077
2034static hda_nid_t ad1988_6stack_dac_nids[4] = { 2078static const hda_nid_t ad1988_6stack_dac_nids[4] = {
2035 0x04, 0x06, 0x05, 0x0a 2079 0x04, 0x06, 0x05, 0x0a
2036}; 2080};
2037 2081
2038static hda_nid_t ad1988_3stack_dac_nids[3] = { 2082static const hda_nid_t ad1988_3stack_dac_nids[3] = {
2039 0x04, 0x05, 0x0a 2083 0x04, 0x05, 0x0a
2040}; 2084};
2041 2085
2042/* for AD1988A revision-2, DAC2-4 are swapped */ 2086/* for AD1988A revision-2, DAC2-4 are swapped */
2043static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = { 2087static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
2044 0x04, 0x05, 0x0a, 0x06 2088 0x04, 0x05, 0x0a, 0x06
2045}; 2089};
2046 2090
2047static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = { 2091static const hda_nid_t ad1988_alt_dac_nid[1] = {
2092 0x03
2093};
2094
2095static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
2048 0x04, 0x0a, 0x06 2096 0x04, 0x0a, 0x06
2049}; 2097};
2050 2098
2051static hda_nid_t ad1988_adc_nids[3] = { 2099static const hda_nid_t ad1988_adc_nids[3] = {
2052 0x08, 0x09, 0x0f 2100 0x08, 0x09, 0x0f
2053}; 2101};
2054 2102
2055static hda_nid_t ad1988_capsrc_nids[3] = { 2103static const hda_nid_t ad1988_capsrc_nids[3] = {
2056 0x0c, 0x0d, 0x0e 2104 0x0c, 0x0d, 0x0e
2057}; 2105};
2058 2106
@@ -2060,11 +2108,11 @@ static hda_nid_t ad1988_capsrc_nids[3] = {
2060#define AD1988_SPDIF_OUT_HDMI 0x0b 2108#define AD1988_SPDIF_OUT_HDMI 0x0b
2061#define AD1988_SPDIF_IN 0x07 2109#define AD1988_SPDIF_IN 0x07
2062 2110
2063static hda_nid_t ad1989b_slave_dig_outs[] = { 2111static const hda_nid_t ad1989b_slave_dig_outs[] = {
2064 AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0 2112 AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0
2065}; 2113};
2066 2114
2067static struct hda_input_mux ad1988_6stack_capture_source = { 2115static const struct hda_input_mux ad1988_6stack_capture_source = {
2068 .num_items = 5, 2116 .num_items = 5,
2069 .items = { 2117 .items = {
2070 { "Front Mic", 0x1 }, /* port-B */ 2118 { "Front Mic", 0x1 }, /* port-B */
@@ -2075,7 +2123,7 @@ static struct hda_input_mux ad1988_6stack_capture_source = {
2075 }, 2123 },
2076}; 2124};
2077 2125
2078static struct hda_input_mux ad1988_laptop_capture_source = { 2126static const struct hda_input_mux ad1988_laptop_capture_source = {
2079 .num_items = 3, 2127 .num_items = 3,
2080 .items = { 2128 .items = {
2081 { "Mic/Line", 0x1 }, /* port-B */ 2129 { "Mic/Line", 0x1 }, /* port-B */
@@ -2118,7 +2166,7 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
2118} 2166}
2119 2167
2120/* 6-stack mode */ 2168/* 6-stack mode */
2121static struct snd_kcontrol_new ad1988_6stack_mixers1[] = { 2169static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
2122 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2170 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2123 HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT), 2171 HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2124 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 2172 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
@@ -2127,7 +2175,7 @@ static struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
2127 { } /* end */ 2175 { } /* end */
2128}; 2176};
2129 2177
2130static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = { 2178static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
2131 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2179 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2132 HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT), 2180 HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
2133 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 2181 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
@@ -2136,7 +2184,7 @@ static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
2136 { } /* end */ 2184 { } /* end */
2137}; 2185};
2138 2186
2139static struct snd_kcontrol_new ad1988_6stack_mixers2[] = { 2187static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2140 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), 2188 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2141 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), 2189 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
2142 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), 2190 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
@@ -2157,14 +2205,20 @@ static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2157 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 2205 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2158 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 2206 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2159 2207
2160 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), 2208 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2161 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), 2209 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2210
2211 { } /* end */
2212};
2213
2214static const struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = {
2215 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2162 2216
2163 { } /* end */ 2217 { } /* end */
2164}; 2218};
2165 2219
2166/* 3-stack mode */ 2220/* 3-stack mode */
2167static struct snd_kcontrol_new ad1988_3stack_mixers1[] = { 2221static const struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
2168 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2222 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2169 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 2223 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2170 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 2224 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
@@ -2172,7 +2226,7 @@ static struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
2172 { } /* end */ 2226 { } /* end */
2173}; 2227};
2174 2228
2175static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = { 2229static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
2176 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2230 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2177 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 2231 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2178 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT), 2232 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
@@ -2180,7 +2234,7 @@ static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
2180 { } /* end */ 2234 { } /* end */
2181}; 2235};
2182 2236
2183static struct snd_kcontrol_new ad1988_3stack_mixers2[] = { 2237static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2184 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), 2238 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2185 HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT), 2239 HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
2186 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT), 2240 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
@@ -2200,8 +2254,8 @@ static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2200 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 2254 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2201 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 2255 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2202 2256
2203 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), 2257 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2204 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), 2258 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2205 { 2259 {
2206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2260 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2207 .name = "Channel Mode", 2261 .name = "Channel Mode",
@@ -2214,7 +2268,7 @@ static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2214}; 2268};
2215 2269
2216/* laptop mode */ 2270/* laptop mode */
2217static struct snd_kcontrol_new ad1988_laptop_mixers[] = { 2271static const struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2218 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2272 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2219 HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT), 2273 HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
2220 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), 2274 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
@@ -2229,7 +2283,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2229 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 2283 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2230 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 2284 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2231 2285
2232 HDA_CODEC_VOLUME("Mic Boost", 0x39, 0x0, HDA_OUTPUT), 2286 HDA_CODEC_VOLUME("Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2233 2287
2234 { 2288 {
2235 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2289 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2245,7 +2299,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2245}; 2299};
2246 2300
2247/* capture */ 2301/* capture */
2248static struct snd_kcontrol_new ad1988_capture_mixers[] = { 2302static const struct snd_kcontrol_new ad1988_capture_mixers[] = {
2249 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 2303 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2250 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 2304 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2251 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 2305 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -2270,7 +2324,7 @@ static struct snd_kcontrol_new ad1988_capture_mixers[] = {
2270static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol, 2324static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
2271 struct snd_ctl_elem_info *uinfo) 2325 struct snd_ctl_elem_info *uinfo)
2272{ 2326{
2273 static char *texts[] = { 2327 static const char * const texts[] = {
2274 "PCM", "ADC1", "ADC2", "ADC3" 2328 "PCM", "ADC1", "ADC2", "ADC3"
2275 }; 2329 };
2276 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2330 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -2351,7 +2405,7 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
2351 return change; 2405 return change;
2352} 2406}
2353 2407
2354static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = { 2408static const struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2355 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 2409 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2356 { 2410 {
2357 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2411 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2364,12 +2418,12 @@ static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2364 { } /* end */ 2418 { } /* end */
2365}; 2419};
2366 2420
2367static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = { 2421static const struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
2368 HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT), 2422 HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
2369 { } /* end */ 2423 { } /* end */
2370}; 2424};
2371 2425
2372static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = { 2426static const struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
2373 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 2427 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2374 HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 2428 HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2375 { } /* end */ 2429 { } /* end */
@@ -2382,7 +2436,7 @@ static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
2382/* 2436/*
2383 * for 6-stack (+dig) 2437 * for 6-stack (+dig)
2384 */ 2438 */
2385static struct hda_verb ad1988_6stack_init_verbs[] = { 2439static const struct hda_verb ad1988_6stack_init_verbs[] = {
2386 /* Front, Surround, CLFE, side DAC; unmute as default */ 2440 /* Front, Surround, CLFE, side DAC; unmute as default */
2387 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2441 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2388 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2442 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -2442,7 +2496,20 @@ static struct hda_verb ad1988_6stack_init_verbs[] = {
2442 { } 2496 { }
2443}; 2497};
2444 2498
2445static struct hda_verb ad1988_capture_init_verbs[] = { 2499static const struct hda_verb ad1988_6stack_fp_init_verbs[] = {
2500 /* Headphone; unmute as default */
2501 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2502 /* Port-A front headphon path */
2503 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2504 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2505 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2506 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2507 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2508
2509 { }
2510};
2511
2512static const struct hda_verb ad1988_capture_init_verbs[] = {
2446 /* mute analog mix */ 2513 /* mute analog mix */
2447 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2514 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2448 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2515 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
@@ -2460,7 +2527,7 @@ static struct hda_verb ad1988_capture_init_verbs[] = {
2460 { } 2527 { }
2461}; 2528};
2462 2529
2463static struct hda_verb ad1988_spdif_init_verbs[] = { 2530static const struct hda_verb ad1988_spdif_init_verbs[] = {
2464 /* SPDIF out sel */ 2531 /* SPDIF out sel */
2465 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ 2532 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2466 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */ 2533 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
@@ -2472,14 +2539,14 @@ static struct hda_verb ad1988_spdif_init_verbs[] = {
2472 { } 2539 { }
2473}; 2540};
2474 2541
2475static struct hda_verb ad1988_spdif_in_init_verbs[] = { 2542static const struct hda_verb ad1988_spdif_in_init_verbs[] = {
2476 /* unmute SPDIF input pin */ 2543 /* unmute SPDIF input pin */
2477 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2544 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2478 { } 2545 { }
2479}; 2546};
2480 2547
2481/* AD1989 has no ADC -> SPDIF route */ 2548/* AD1989 has no ADC -> SPDIF route */
2482static struct hda_verb ad1989_spdif_init_verbs[] = { 2549static const struct hda_verb ad1989_spdif_init_verbs[] = {
2483 /* SPDIF-1 out pin */ 2550 /* SPDIF-1 out pin */
2484 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2551 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2485 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 2552 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
@@ -2492,7 +2559,7 @@ static struct hda_verb ad1989_spdif_init_verbs[] = {
2492/* 2559/*
2493 * verbs for 3stack (+dig) 2560 * verbs for 3stack (+dig)
2494 */ 2561 */
2495static struct hda_verb ad1988_3stack_ch2_init[] = { 2562static const struct hda_verb ad1988_3stack_ch2_init[] = {
2496 /* set port-C to line-in */ 2563 /* set port-C to line-in */
2497 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2564 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2498 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2565 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
@@ -2502,7 +2569,7 @@ static struct hda_verb ad1988_3stack_ch2_init[] = {
2502 { } /* end */ 2569 { } /* end */
2503}; 2570};
2504 2571
2505static struct hda_verb ad1988_3stack_ch6_init[] = { 2572static const struct hda_verb ad1988_3stack_ch6_init[] = {
2506 /* set port-C to surround out */ 2573 /* set port-C to surround out */
2507 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2574 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2508 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2575 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
@@ -2512,12 +2579,12 @@ static struct hda_verb ad1988_3stack_ch6_init[] = {
2512 { } /* end */ 2579 { } /* end */
2513}; 2580};
2514 2581
2515static struct hda_channel_mode ad1988_3stack_modes[2] = { 2582static const struct hda_channel_mode ad1988_3stack_modes[2] = {
2516 { 2, ad1988_3stack_ch2_init }, 2583 { 2, ad1988_3stack_ch2_init },
2517 { 6, ad1988_3stack_ch6_init }, 2584 { 6, ad1988_3stack_ch6_init },
2518}; 2585};
2519 2586
2520static struct hda_verb ad1988_3stack_init_verbs[] = { 2587static const struct hda_verb ad1988_3stack_init_verbs[] = {
2521 /* Front, Surround, CLFE, side DAC; unmute as default */ 2588 /* Front, Surround, CLFE, side DAC; unmute as default */
2522 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2589 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2523 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2590 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -2577,13 +2644,13 @@ static struct hda_verb ad1988_3stack_init_verbs[] = {
2577/* 2644/*
2578 * verbs for laptop mode (+dig) 2645 * verbs for laptop mode (+dig)
2579 */ 2646 */
2580static struct hda_verb ad1988_laptop_hp_on[] = { 2647static const struct hda_verb ad1988_laptop_hp_on[] = {
2581 /* unmute port-A and mute port-D */ 2648 /* unmute port-A and mute port-D */
2582 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2649 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2583 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2650 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2584 { } /* end */ 2651 { } /* end */
2585}; 2652};
2586static struct hda_verb ad1988_laptop_hp_off[] = { 2653static const struct hda_verb ad1988_laptop_hp_off[] = {
2587 /* mute port-A and unmute port-D */ 2654 /* mute port-A and unmute port-D */
2588 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2655 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2589 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2656 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
@@ -2592,7 +2659,7 @@ static struct hda_verb ad1988_laptop_hp_off[] = {
2592 2659
2593#define AD1988_HP_EVENT 0x01 2660#define AD1988_HP_EVENT 0x01
2594 2661
2595static struct hda_verb ad1988_laptop_init_verbs[] = { 2662static const struct hda_verb ad1988_laptop_init_verbs[] = {
2596 /* Front, Surround, CLFE, side DAC; unmute as default */ 2663 /* Front, Surround, CLFE, side DAC; unmute as default */
2597 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2664 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2598 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2665 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -2656,7 +2723,7 @@ static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
2656} 2723}
2657 2724
2658#ifdef CONFIG_SND_HDA_POWER_SAVE 2725#ifdef CONFIG_SND_HDA_POWER_SAVE
2659static struct hda_amp_list ad1988_loopbacks[] = { 2726static const struct hda_amp_list ad1988_loopbacks[] = {
2660 { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 2727 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
2661 { 0x20, HDA_INPUT, 1 }, /* Line */ 2728 { 0x20, HDA_INPUT, 1 }, /* Line */
2662 { 0x20, HDA_INPUT, 4 }, /* Mic */ 2729 { 0x20, HDA_INPUT, 4 }, /* Mic */
@@ -2674,7 +2741,7 @@ enum {
2674 AD_CTL_WIDGET_MUTE, 2741 AD_CTL_WIDGET_MUTE,
2675 AD_CTL_BIND_MUTE, 2742 AD_CTL_BIND_MUTE,
2676}; 2743};
2677static struct snd_kcontrol_new ad1988_control_templates[] = { 2744static const struct snd_kcontrol_new ad1988_control_templates[] = {
2678 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2745 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2679 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2746 HDA_CODEC_MUTE(NULL, 0, 0, 0),
2680 HDA_BIND_MUTE(NULL, 0, 0, 0), 2747 HDA_BIND_MUTE(NULL, 0, 0, 0),
@@ -2703,18 +2770,18 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name,
2703#define AD1988_PIN_CD_NID 0x18 2770#define AD1988_PIN_CD_NID 0x18
2704#define AD1988_PIN_BEEP_NID 0x10 2771#define AD1988_PIN_BEEP_NID 0x10
2705 2772
2706static hda_nid_t ad1988_mixer_nids[8] = { 2773static const hda_nid_t ad1988_mixer_nids[8] = {
2707 /* A B C D E F G H */ 2774 /* A B C D E F G H */
2708 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28 2775 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
2709}; 2776};
2710 2777
2711static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx) 2778static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
2712{ 2779{
2713 static hda_nid_t idx_to_dac[8] = { 2780 static const hda_nid_t idx_to_dac[8] = {
2714 /* A B C D E F G H */ 2781 /* A B C D E F G H */
2715 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a 2782 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
2716 }; 2783 };
2717 static hda_nid_t idx_to_dac_rev2[8] = { 2784 static const hda_nid_t idx_to_dac_rev2[8] = {
2718 /* A B C D E F G H */ 2785 /* A B C D E F G H */
2719 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06 2786 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
2720 }; 2787 };
@@ -2724,13 +2791,13 @@ static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
2724 return idx_to_dac[idx]; 2791 return idx_to_dac[idx];
2725} 2792}
2726 2793
2727static hda_nid_t ad1988_boost_nids[8] = { 2794static const hda_nid_t ad1988_boost_nids[8] = {
2728 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0 2795 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
2729}; 2796};
2730 2797
2731static int ad1988_pin_idx(hda_nid_t nid) 2798static int ad1988_pin_idx(hda_nid_t nid)
2732{ 2799{
2733 static hda_nid_t ad1988_io_pins[8] = { 2800 static const hda_nid_t ad1988_io_pins[8] = {
2734 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25 2801 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
2735 }; 2802 };
2736 int i; 2803 int i;
@@ -2742,7 +2809,7 @@ static int ad1988_pin_idx(hda_nid_t nid)
2742 2809
2743static int ad1988_pin_to_loopback_idx(hda_nid_t nid) 2810static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
2744{ 2811{
2745 static int loopback_idx[8] = { 2812 static const int loopback_idx[8] = {
2746 2, 0, 1, 3, 4, 5, 1, 4 2813 2, 0, 1, 3, 4, 5, 1, 4
2747 }; 2814 };
2748 switch (nid) { 2815 switch (nid) {
@@ -2755,7 +2822,7 @@ static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
2755 2822
2756static int ad1988_pin_to_adc_idx(hda_nid_t nid) 2823static int ad1988_pin_to_adc_idx(hda_nid_t nid)
2757{ 2824{
2758 static int adc_idx[8] = { 2825 static const int adc_idx[8] = {
2759 0, 1, 2, 8, 4, 3, 6, 7 2826 0, 1, 2, 8, 4, 3, 6, 7
2760 }; 2827 };
2761 switch (nid) { 2828 switch (nid) {
@@ -2778,7 +2845,7 @@ static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
2778 /* check the pins hardwired to audio widget */ 2845 /* check the pins hardwired to audio widget */
2779 for (i = 0; i < cfg->line_outs; i++) { 2846 for (i = 0; i < cfg->line_outs; i++) {
2780 idx = ad1988_pin_idx(cfg->line_out_pins[i]); 2847 idx = ad1988_pin_idx(cfg->line_out_pins[i]);
2781 spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx); 2848 spec->private_dac_nids[i] = ad1988_idx_to_dac(codec, idx);
2782 } 2849 }
2783 spec->multiout.num_dacs = cfg->line_outs; 2850 spec->multiout.num_dacs = cfg->line_outs;
2784 return 0; 2851 return 0;
@@ -2789,7 +2856,9 @@ static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
2789 const struct auto_pin_cfg *cfg) 2856 const struct auto_pin_cfg *cfg)
2790{ 2857{
2791 char name[32]; 2858 char name[32];
2792 static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; 2859 static const char * const chname[4] = {
2860 "Front", "Surround", NULL /*CLFE*/, "Side"
2861 };
2793 hda_nid_t nid; 2862 hda_nid_t nid;
2794 int i, err; 2863 int i, err;
2795 2864
@@ -2880,7 +2949,7 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2880 2949
2881/* create input playback/capture controls for the given pin */ 2950/* create input playback/capture controls for the given pin */
2882static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin, 2951static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
2883 const char *ctlname, int boost) 2952 const char *ctlname, int ctlidx, int boost)
2884{ 2953{
2885 char name[32]; 2954 char name[32];
2886 int err, idx; 2955 int err, idx;
@@ -2899,7 +2968,7 @@ static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
2899 idx = ad1988_pin_idx(pin); 2968 idx = ad1988_pin_idx(pin);
2900 bnid = ad1988_boost_nids[idx]; 2969 bnid = ad1988_boost_nids[idx];
2901 if (bnid) { 2970 if (bnid) {
2902 sprintf(name, "%s Boost", ctlname); 2971 sprintf(name, "%s Boost Volume", ctlname);
2903 return add_control(spec, AD_CTL_WIDGET_VOL, name, 2972 return add_control(spec, AD_CTL_WIDGET_VOL, name,
2904 HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT)); 2973 HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
2905 2974
@@ -2909,25 +2978,27 @@ static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
2909} 2978}
2910 2979
2911/* create playback/capture controls for input pins */ 2980/* create playback/capture controls for input pins */
2912static int ad1988_auto_create_analog_input_ctls(struct ad198x_spec *spec, 2981static int ad1988_auto_create_analog_input_ctls(struct hda_codec *codec,
2913 const struct auto_pin_cfg *cfg) 2982 const struct auto_pin_cfg *cfg)
2914{ 2983{
2984 struct ad198x_spec *spec = codec->spec;
2915 struct hda_input_mux *imux = &spec->private_imux; 2985 struct hda_input_mux *imux = &spec->private_imux;
2916 int i, err; 2986 int i, err, type, type_idx;
2917 2987
2918 for (i = 0; i < AUTO_PIN_LAST; i++) { 2988 for (i = 0; i < cfg->num_inputs; i++) {
2919 err = new_analog_input(spec, cfg->input_pins[i], 2989 const char *label;
2920 auto_pin_cfg_labels[i], 2990 type = cfg->inputs[i].type;
2921 i <= AUTO_PIN_FRONT_MIC); 2991 label = hda_get_autocfg_input_label(codec, cfg, i);
2992 snd_hda_add_imux_item(imux, label,
2993 ad1988_pin_to_adc_idx(cfg->inputs[i].pin),
2994 &type_idx);
2995 err = new_analog_input(spec, cfg->inputs[i].pin,
2996 label, type_idx,
2997 type == AUTO_PIN_MIC);
2922 if (err < 0) 2998 if (err < 0)
2923 return err; 2999 return err;
2924 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2925 imux->items[imux->num_items].index = ad1988_pin_to_adc_idx(cfg->input_pins[i]);
2926 imux->num_items++;
2927 } 3000 }
2928 imux->items[imux->num_items].label = "Mix"; 3001 snd_hda_add_imux_item(imux, "Mix", 9, NULL);
2929 imux->items[imux->num_items].index = 9;
2930 imux->num_items++;
2931 3002
2932 if ((err = add_control(spec, AD_CTL_WIDGET_VOL, 3003 if ((err = add_control(spec, AD_CTL_WIDGET_VOL,
2933 "Analog Mix Playback Volume", 3004 "Analog Mix Playback Volume",
@@ -2994,12 +3065,12 @@ static void ad1988_auto_init_extra_out(struct hda_codec *codec)
2994static void ad1988_auto_init_analog_input(struct hda_codec *codec) 3065static void ad1988_auto_init_analog_input(struct hda_codec *codec)
2995{ 3066{
2996 struct ad198x_spec *spec = codec->spec; 3067 struct ad198x_spec *spec = codec->spec;
3068 const struct auto_pin_cfg *cfg = &spec->autocfg;
2997 int i, idx; 3069 int i, idx;
2998 3070
2999 for (i = 0; i < AUTO_PIN_LAST; i++) { 3071 for (i = 0; i < cfg->num_inputs; i++) {
3000 hda_nid_t nid = spec->autocfg.input_pins[i]; 3072 hda_nid_t nid = cfg->inputs[i].pin;
3001 if (! nid) 3073 int type = cfg->inputs[i].type;
3002 continue;
3003 switch (nid) { 3074 switch (nid) {
3004 case 0x15: /* port-C */ 3075 case 0x15: /* port-C */
3005 snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0); 3076 snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
@@ -3009,7 +3080,7 @@ static void ad1988_auto_init_analog_input(struct hda_codec *codec)
3009 break; 3080 break;
3010 } 3081 }
3011 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 3082 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3012 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); 3083 type == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN);
3013 if (nid != AD1988_PIN_CD_NID) 3084 if (nid != AD1988_PIN_CD_NID)
3014 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3085 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3015 AMP_OUT_MUTE); 3086 AMP_OUT_MUTE);
@@ -3040,7 +3111,7 @@ static int ad1988_parse_auto_config(struct hda_codec *codec)
3040 "Speaker")) < 0 || 3111 "Speaker")) < 0 ||
3041 (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], 3112 (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
3042 "Headphone")) < 0 || 3113 "Headphone")) < 0 ||
3043 (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) 3114 (err = ad1988_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
3044 return err; 3115 return err;
3045 3116
3046 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3117 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
@@ -3070,13 +3141,13 @@ static int ad1988_auto_init(struct hda_codec *codec)
3070 return 0; 3141 return 0;
3071} 3142}
3072 3143
3073
3074/* 3144/*
3075 */ 3145 */
3076 3146
3077static const char *ad1988_models[AD1988_MODEL_LAST] = { 3147static const char * const ad1988_models[AD1988_MODEL_LAST] = {
3078 [AD1988_6STACK] = "6stack", 3148 [AD1988_6STACK] = "6stack",
3079 [AD1988_6STACK_DIG] = "6stack-dig", 3149 [AD1988_6STACK_DIG] = "6stack-dig",
3150 [AD1988_6STACK_DIG_FP] = "6stack-dig-fp",
3080 [AD1988_3STACK] = "3stack", 3151 [AD1988_3STACK] = "3stack",
3081 [AD1988_3STACK_DIG] = "3stack-dig", 3152 [AD1988_3STACK_DIG] = "3stack-dig",
3082 [AD1988_LAPTOP] = "laptop", 3153 [AD1988_LAPTOP] = "laptop",
@@ -3084,10 +3155,11 @@ static const char *ad1988_models[AD1988_MODEL_LAST] = {
3084 [AD1988_AUTO] = "auto", 3155 [AD1988_AUTO] = "auto",
3085}; 3156};
3086 3157
3087static struct snd_pci_quirk ad1988_cfg_tbl[] = { 3158static const struct snd_pci_quirk ad1988_cfg_tbl[] = {
3088 SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), 3159 SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
3089 SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), 3160 SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
3090 SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG), 3161 SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
3162 SND_PCI_QUIRK(0x1043, 0x82c0, "Asus M3N-HT Deluxe", AD1988_6STACK_DIG),
3091 SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG), 3163 SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
3092 {} 3164 {}
3093}; 3165};
@@ -3136,6 +3208,7 @@ static int patch_ad1988(struct hda_codec *codec)
3136 switch (board_config) { 3208 switch (board_config) {
3137 case AD1988_6STACK: 3209 case AD1988_6STACK:
3138 case AD1988_6STACK_DIG: 3210 case AD1988_6STACK_DIG:
3211 case AD1988_6STACK_DIG_FP:
3139 spec->multiout.max_channels = 8; 3212 spec->multiout.max_channels = 8;
3140 spec->multiout.num_dacs = 4; 3213 spec->multiout.num_dacs = 4;
3141 if (is_rev2(codec)) 3214 if (is_rev2(codec))
@@ -3151,7 +3224,19 @@ static int patch_ad1988(struct hda_codec *codec)
3151 spec->mixers[1] = ad1988_6stack_mixers2; 3224 spec->mixers[1] = ad1988_6stack_mixers2;
3152 spec->num_init_verbs = 1; 3225 spec->num_init_verbs = 1;
3153 spec->init_verbs[0] = ad1988_6stack_init_verbs; 3226 spec->init_verbs[0] = ad1988_6stack_init_verbs;
3154 if (board_config == AD1988_6STACK_DIG) { 3227 if (board_config == AD1988_6STACK_DIG_FP) {
3228 spec->num_mixers++;
3229 spec->mixers[2] = ad1988_6stack_fp_mixers;
3230 spec->num_init_verbs++;
3231 spec->init_verbs[1] = ad1988_6stack_fp_init_verbs;
3232 spec->slave_vols = ad1988_6stack_fp_slave_vols;
3233 spec->slave_sws = ad1988_6stack_fp_slave_sws;
3234 spec->alt_dac_nid = ad1988_alt_dac_nid;
3235 spec->stream_analog_alt_playback =
3236 &ad198x_pcm_analog_alt_playback;
3237 }
3238 if ((board_config == AD1988_6STACK_DIG) ||
3239 (board_config == AD1988_6STACK_DIG_FP)) {
3155 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 3240 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3156 spec->dig_in_nid = AD1988_SPDIF_IN; 3241 spec->dig_in_nid = AD1988_SPDIF_IN;
3157 } 3242 }
@@ -3235,6 +3320,7 @@ static int patch_ad1988(struct hda_codec *codec)
3235 spec->vmaster_nid = 0x04; 3320 spec->vmaster_nid = 0x04;
3236 3321
3237 codec->no_trigger_sense = 1; 3322 codec->no_trigger_sense = 1;
3323 codec->no_sticky_stream = 1;
3238 3324
3239 return 0; 3325 return 0;
3240} 3326}
@@ -3258,21 +3344,21 @@ static int patch_ad1988(struct hda_codec *codec)
3258 * but no build-up framework is given, so far. 3344 * but no build-up framework is given, so far.
3259 */ 3345 */
3260 3346
3261static hda_nid_t ad1884_dac_nids[1] = { 3347static const hda_nid_t ad1884_dac_nids[1] = {
3262 0x04, 3348 0x04,
3263}; 3349};
3264 3350
3265static hda_nid_t ad1884_adc_nids[2] = { 3351static const hda_nid_t ad1884_adc_nids[2] = {
3266 0x08, 0x09, 3352 0x08, 0x09,
3267}; 3353};
3268 3354
3269static hda_nid_t ad1884_capsrc_nids[2] = { 3355static const hda_nid_t ad1884_capsrc_nids[2] = {
3270 0x0c, 0x0d, 3356 0x0c, 0x0d,
3271}; 3357};
3272 3358
3273#define AD1884_SPDIF_OUT 0x02 3359#define AD1884_SPDIF_OUT 0x02
3274 3360
3275static struct hda_input_mux ad1884_capture_source = { 3361static const struct hda_input_mux ad1884_capture_source = {
3276 .num_items = 4, 3362 .num_items = 4,
3277 .items = { 3363 .items = {
3278 { "Front Mic", 0x0 }, 3364 { "Front Mic", 0x0 },
@@ -3282,7 +3368,7 @@ static struct hda_input_mux ad1884_capture_source = {
3282 }, 3368 },
3283}; 3369};
3284 3370
3285static struct snd_kcontrol_new ad1884_base_mixers[] = { 3371static const struct snd_kcontrol_new ad1884_base_mixers[] = {
3286 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 3372 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3287 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ 3373 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3288 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 3374 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
@@ -3295,8 +3381,8 @@ static struct snd_kcontrol_new ad1884_base_mixers[] = {
3295 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 3381 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3296 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), 3382 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3297 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), 3383 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3298 HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT), 3384 HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3299 HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), 3385 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3300 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3386 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3301 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3387 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3302 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3388 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -3326,7 +3412,7 @@ static struct snd_kcontrol_new ad1884_base_mixers[] = {
3326 { } /* end */ 3412 { } /* end */
3327}; 3413};
3328 3414
3329static struct snd_kcontrol_new ad1984_dmic_mixers[] = { 3415static const struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3330 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT), 3416 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
3331 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT), 3417 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
3332 HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0, 3418 HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
@@ -3339,7 +3425,7 @@ static struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3339/* 3425/*
3340 * initialization verbs 3426 * initialization verbs
3341 */ 3427 */
3342static struct hda_verb ad1884_init_verbs[] = { 3428static const struct hda_verb ad1884_init_verbs[] = {
3343 /* DACs; mute as default */ 3429 /* DACs; mute as default */
3344 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3430 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3345 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3431 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -3385,7 +3471,7 @@ static struct hda_verb ad1884_init_verbs[] = {
3385}; 3471};
3386 3472
3387#ifdef CONFIG_SND_HDA_POWER_SAVE 3473#ifdef CONFIG_SND_HDA_POWER_SAVE
3388static struct hda_amp_list ad1884_loopbacks[] = { 3474static const struct hda_amp_list ad1884_loopbacks[] = {
3389 { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 3475 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3390 { 0x20, HDA_INPUT, 1 }, /* Mic */ 3476 { 0x20, HDA_INPUT, 1 }, /* Mic */
3391 { 0x20, HDA_INPUT, 2 }, /* CD */ 3477 { 0x20, HDA_INPUT, 2 }, /* CD */
@@ -3394,7 +3480,7 @@ static struct hda_amp_list ad1884_loopbacks[] = {
3394}; 3480};
3395#endif 3481#endif
3396 3482
3397static const char *ad1884_slave_vols[] = { 3483static const char * const ad1884_slave_vols[] = {
3398 "PCM Playback Volume", 3484 "PCM Playback Volume",
3399 "Mic Playback Volume", 3485 "Mic Playback Volume",
3400 "Mono Playback Volume", 3486 "Mono Playback Volume",
@@ -3449,6 +3535,7 @@ static int patch_ad1884(struct hda_codec *codec)
3449 codec->patch_ops = ad198x_patch_ops; 3535 codec->patch_ops = ad198x_patch_ops;
3450 3536
3451 codec->no_trigger_sense = 1; 3537 codec->no_trigger_sense = 1;
3538 codec->no_sticky_stream = 1;
3452 3539
3453 return 0; 3540 return 0;
3454} 3541}
@@ -3456,7 +3543,7 @@ static int patch_ad1884(struct hda_codec *codec)
3456/* 3543/*
3457 * Lenovo Thinkpad T61/X61 3544 * Lenovo Thinkpad T61/X61
3458 */ 3545 */
3459static struct hda_input_mux ad1984_thinkpad_capture_source = { 3546static const struct hda_input_mux ad1984_thinkpad_capture_source = {
3460 .num_items = 4, 3547 .num_items = 4,
3461 .items = { 3548 .items = {
3462 { "Mic", 0x0 }, 3549 { "Mic", 0x0 },
@@ -3470,7 +3557,7 @@ static struct hda_input_mux ad1984_thinkpad_capture_source = {
3470/* 3557/*
3471 * Dell Precision T3400 3558 * Dell Precision T3400
3472 */ 3559 */
3473static struct hda_input_mux ad1984_dell_desktop_capture_source = { 3560static const struct hda_input_mux ad1984_dell_desktop_capture_source = {
3474 .num_items = 3, 3561 .num_items = 3,
3475 .items = { 3562 .items = {
3476 { "Front Mic", 0x0 }, 3563 { "Front Mic", 0x0 },
@@ -3480,7 +3567,7 @@ static struct hda_input_mux ad1984_dell_desktop_capture_source = {
3480}; 3567};
3481 3568
3482 3569
3483static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = { 3570static const struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3484 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 3571 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3485 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ 3572 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3486 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 3573 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
@@ -3493,9 +3580,9 @@ static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3493 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT), 3580 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3494 HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 3581 HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3495 HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 3582 HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3496 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), 3583 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3497 HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT), 3584 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3498 HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT), 3585 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3499 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3586 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3500 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3587 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3501 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3588 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -3526,7 +3613,7 @@ static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3526}; 3613};
3527 3614
3528/* additional verbs */ 3615/* additional verbs */
3529static struct hda_verb ad1984_thinkpad_init_verbs[] = { 3616static const struct hda_verb ad1984_thinkpad_init_verbs[] = {
3530 /* Port-E (docking station mic) pin */ 3617 /* Port-E (docking station mic) pin */
3531 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3618 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3532 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3619 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
@@ -3544,7 +3631,7 @@ static struct hda_verb ad1984_thinkpad_init_verbs[] = {
3544/* 3631/*
3545 * Dell Precision T3400 3632 * Dell Precision T3400
3546 */ 3633 */
3547static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = { 3634static const struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3548 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 3635 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3549 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 3636 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3550 HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT), 3637 HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
@@ -3554,8 +3641,8 @@ static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3554 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 3641 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3555 HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT), 3642 HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3556 HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT), 3643 HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3557 HDA_CODEC_VOLUME("Line-In Boost", 0x15, 0x0, HDA_INPUT), 3644 HDA_CODEC_VOLUME("Line-In Boost Volume", 0x15, 0x0, HDA_INPUT),
3558 HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), 3645 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3559 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3646 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3560 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3647 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3561 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3648 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -3595,7 +3682,7 @@ static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3595 return 0; 3682 return 0;
3596} 3683}
3597 3684
3598static struct hda_pcm_stream ad1984_pcm_dmic_capture = { 3685static const struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3599 .substreams = 2, 3686 .substreams = 2,
3600 .channels_min = 2, 3687 .channels_min = 2,
3601 .channels_max = 2, 3688 .channels_max = 2,
@@ -3631,13 +3718,13 @@ enum {
3631 AD1984_MODELS 3718 AD1984_MODELS
3632}; 3719};
3633 3720
3634static const char *ad1984_models[AD1984_MODELS] = { 3721static const char * const ad1984_models[AD1984_MODELS] = {
3635 [AD1984_BASIC] = "basic", 3722 [AD1984_BASIC] = "basic",
3636 [AD1984_THINKPAD] = "thinkpad", 3723 [AD1984_THINKPAD] = "thinkpad",
3637 [AD1984_DELL_DESKTOP] = "dell_desktop", 3724 [AD1984_DELL_DESKTOP] = "dell_desktop",
3638}; 3725};
3639 3726
3640static struct snd_pci_quirk ad1984_cfg_tbl[] = { 3727static const struct snd_pci_quirk ad1984_cfg_tbl[] = {
3641 /* Lenovo Thinkpad T61/X61 */ 3728 /* Lenovo Thinkpad T61/X61 */
3642 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD), 3729 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
3643 SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP), 3730 SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
@@ -3702,7 +3789,7 @@ static int patch_ad1984(struct hda_codec *codec)
3702 * We share the single DAC for both HP and line-outs (see AD1884/1984). 3789 * We share the single DAC for both HP and line-outs (see AD1884/1984).
3703 */ 3790 */
3704 3791
3705static hda_nid_t ad1884a_dac_nids[1] = { 3792static const hda_nid_t ad1884a_dac_nids[1] = {
3706 0x03, 3793 0x03,
3707}; 3794};
3708 3795
@@ -3711,7 +3798,7 @@ static hda_nid_t ad1884a_dac_nids[1] = {
3711 3798
3712#define AD1884A_SPDIF_OUT 0x02 3799#define AD1884A_SPDIF_OUT 0x02
3713 3800
3714static struct hda_input_mux ad1884a_capture_source = { 3801static const struct hda_input_mux ad1884a_capture_source = {
3715 .num_items = 5, 3802 .num_items = 5,
3716 .items = { 3803 .items = {
3717 { "Front Mic", 0x0 }, 3804 { "Front Mic", 0x0 },
@@ -3722,7 +3809,7 @@ static struct hda_input_mux ad1884a_capture_source = {
3722 }, 3809 },
3723}; 3810};
3724 3811
3725static struct snd_kcontrol_new ad1884a_base_mixers[] = { 3812static const struct snd_kcontrol_new ad1884a_base_mixers[] = {
3726 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 3813 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3727 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), 3814 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3728 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 3815 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
@@ -3739,9 +3826,9 @@ static struct snd_kcontrol_new ad1884a_base_mixers[] = {
3739 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 3826 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3740 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), 3827 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3741 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), 3828 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3742 HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), 3829 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3743 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x0, HDA_INPUT), 3830 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x0, HDA_INPUT),
3744 HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT), 3831 HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3745 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3832 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3746 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3833 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3747 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3834 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -3774,7 +3861,7 @@ static struct snd_kcontrol_new ad1884a_base_mixers[] = {
3774/* 3861/*
3775 * initialization verbs 3862 * initialization verbs
3776 */ 3863 */
3777static struct hda_verb ad1884a_init_verbs[] = { 3864static const struct hda_verb ad1884a_init_verbs[] = {
3778 /* DACs; unmute as default */ 3865 /* DACs; unmute as default */
3779 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 3866 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3780 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 3867 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
@@ -3829,7 +3916,7 @@ static struct hda_verb ad1884a_init_verbs[] = {
3829}; 3916};
3830 3917
3831#ifdef CONFIG_SND_HDA_POWER_SAVE 3918#ifdef CONFIG_SND_HDA_POWER_SAVE
3832static struct hda_amp_list ad1884a_loopbacks[] = { 3919static const struct hda_amp_list ad1884a_loopbacks[] = {
3833 { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 3920 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3834 { 0x20, HDA_INPUT, 1 }, /* Mic */ 3921 { 0x20, HDA_INPUT, 1 }, /* Mic */
3835 { 0x20, HDA_INPUT, 2 }, /* CD */ 3922 { 0x20, HDA_INPUT, 2 }, /* CD */
@@ -3862,7 +3949,7 @@ static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
3862 return ret; 3949 return ret;
3863} 3950}
3864 3951
3865static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { 3952static const struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3866 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 3953 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3867 { 3954 {
3868 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3955 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -3882,15 +3969,15 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3882 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 3969 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3883 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 3970 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3884 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 3971 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3885 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), 3972 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3886 HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT), 3973 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3887 HDA_CODEC_VOLUME("Dock Mic Boost", 0x25, 0x0, HDA_OUTPUT), 3974 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3888 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3975 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3889 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3976 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3890 { } /* end */ 3977 { } /* end */
3891}; 3978};
3892 3979
3893static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { 3980static const struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3894 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 3981 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3895 /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 3982 /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
3896 { 3983 {
@@ -4010,7 +4097,7 @@ static int ad1884a_laptop_init(struct hda_codec *codec)
4010} 4097}
4011 4098
4012/* additional verbs for laptop model */ 4099/* additional verbs for laptop model */
4013static struct hda_verb ad1884a_laptop_verbs[] = { 4100static const struct hda_verb ad1884a_laptop_verbs[] = {
4014 /* Port-A (HP) pin - always unmuted */ 4101 /* Port-A (HP) pin - always unmuted */
4015 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4102 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4016 /* Port-F (int speaker) mixer - route only from analog mixer */ 4103 /* Port-F (int speaker) mixer - route only from analog mixer */
@@ -4041,7 +4128,7 @@ static struct hda_verb ad1884a_laptop_verbs[] = {
4041 { } /* end */ 4128 { } /* end */
4042}; 4129};
4043 4130
4044static struct hda_verb ad1884a_mobile_verbs[] = { 4131static const struct hda_verb ad1884a_mobile_verbs[] = {
4045 /* DACs; unmute as default */ 4132 /* DACs; unmute as default */
4046 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 4133 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4047 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 4134 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
@@ -4096,7 +4183,7 @@ static struct hda_verb ad1884a_mobile_verbs[] = {
4096 * 0x17 - built-in mic 4183 * 0x17 - built-in mic
4097 */ 4184 */
4098 4185
4099static struct hda_verb ad1984a_thinkpad_verbs[] = { 4186static const struct hda_verb ad1984a_thinkpad_verbs[] = {
4100 /* HP unmute */ 4187 /* HP unmute */
4101 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4188 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4102 /* analog mix */ 4189 /* analog mix */
@@ -4113,15 +4200,15 @@ static struct hda_verb ad1984a_thinkpad_verbs[] = {
4113 { } /* end */ 4200 { } /* end */
4114}; 4201};
4115 4202
4116static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = { 4203static const struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4117 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 4204 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4118 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), 4205 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4119 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 4206 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4120 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 4207 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4121 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 4208 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4122 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 4209 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4123 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), 4210 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4124 HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT), 4211 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4125 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4212 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4126 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4213 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4127 { 4214 {
@@ -4134,7 +4221,7 @@ static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4134 { } /* end */ 4221 { } /* end */
4135}; 4222};
4136 4223
4137static struct hda_input_mux ad1984a_thinkpad_capture_source = { 4224static const struct hda_input_mux ad1984a_thinkpad_capture_source = {
4138 .num_items = 3, 4225 .num_items = 3,
4139 .items = { 4226 .items = {
4140 { "Mic", 0x0 }, 4227 { "Mic", 0x0 },
@@ -4171,6 +4258,84 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec)
4171} 4258}
4172 4259
4173/* 4260/*
4261 * Precision R5500
4262 * 0x12 - HP/line-out
4263 * 0x13 - speaker (mono)
4264 * 0x15 - mic-in
4265 */
4266
4267static const struct hda_verb ad1984a_precision_verbs[] = {
4268 /* Unmute main output path */
4269 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4270 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */
4271 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */
4272 /* Analog mixer; mute as default */
4273 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4274 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4275 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4276 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4277 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4278 /* Select mic as input */
4279 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
4280 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */
4281 /* Configure as mic */
4282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4283 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4284 /* HP unmute */
4285 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4286 /* turn on EAPD */
4287 {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4288 /* unsolicited event for pin-sense */
4289 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4290 { } /* end */
4291};
4292
4293static const struct snd_kcontrol_new ad1984a_precision_mixers[] = {
4294 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4295 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4296 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4297 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4298 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4299 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4300 HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
4301 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4302 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT),
4303 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4304 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4305 { } /* end */
4306};
4307
4308
4309/* mute internal speaker if HP is plugged */
4310static void ad1984a_precision_automute(struct hda_codec *codec)
4311{
4312 unsigned int present;
4313
4314 present = snd_hda_jack_detect(codec, 0x12);
4315 snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
4316 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4317}
4318
4319
4320/* unsolicited event for HP jack sensing */
4321static void ad1984a_precision_unsol_event(struct hda_codec *codec,
4322 unsigned int res)
4323{
4324 if ((res >> 26) != AD1884A_HP_EVENT)
4325 return;
4326 ad1984a_precision_automute(codec);
4327}
4328
4329/* initialize jack-sensing, too */
4330static int ad1984a_precision_init(struct hda_codec *codec)
4331{
4332 ad198x_init(codec);
4333 ad1984a_precision_automute(codec);
4334 return 0;
4335}
4336
4337
4338/*
4174 * HP Touchsmart 4339 * HP Touchsmart
4175 * port-A (0x11) - front hp-out 4340 * port-A (0x11) - front hp-out
4176 * port-B (0x14) - unused 4341 * port-B (0x14) - unused
@@ -4181,7 +4346,7 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec)
4181 * digital-mic (0x17) - Internal mic 4346 * digital-mic (0x17) - Internal mic
4182 */ 4347 */
4183 4348
4184static struct hda_verb ad1984a_touchsmart_verbs[] = { 4349static const struct hda_verb ad1984a_touchsmart_verbs[] = {
4185 /* DACs; unmute as default */ 4350 /* DACs; unmute as default */
4186 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 4351 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4187 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 4352 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
@@ -4233,7 +4398,7 @@ static struct hda_verb ad1984a_touchsmart_verbs[] = {
4233 { } /* end */ 4398 { } /* end */
4234}; 4399};
4235 4400
4236static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = { 4401static const struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4237 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 4402 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4238/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 4403/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4239 { 4404 {
@@ -4249,8 +4414,8 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4249 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 4414 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4250 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4415 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4251 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4416 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4252 HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT), 4417 HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4253 HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT), 4418 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4254 { } /* end */ 4419 { } /* end */
4255}; 4420};
4256 4421
@@ -4299,18 +4464,21 @@ enum {
4299 AD1884A_MOBILE, 4464 AD1884A_MOBILE,
4300 AD1884A_THINKPAD, 4465 AD1884A_THINKPAD,
4301 AD1984A_TOUCHSMART, 4466 AD1984A_TOUCHSMART,
4467 AD1984A_PRECISION,
4302 AD1884A_MODELS 4468 AD1884A_MODELS
4303}; 4469};
4304 4470
4305static const char *ad1884a_models[AD1884A_MODELS] = { 4471static const char * const ad1884a_models[AD1884A_MODELS] = {
4306 [AD1884A_DESKTOP] = "desktop", 4472 [AD1884A_DESKTOP] = "desktop",
4307 [AD1884A_LAPTOP] = "laptop", 4473 [AD1884A_LAPTOP] = "laptop",
4308 [AD1884A_MOBILE] = "mobile", 4474 [AD1884A_MOBILE] = "mobile",
4309 [AD1884A_THINKPAD] = "thinkpad", 4475 [AD1884A_THINKPAD] = "thinkpad",
4310 [AD1984A_TOUCHSMART] = "touchsmart", 4476 [AD1984A_TOUCHSMART] = "touchsmart",
4477 [AD1984A_PRECISION] = "precision",
4311}; 4478};
4312 4479
4313static struct snd_pci_quirk ad1884a_cfg_tbl[] = { 4480static const struct snd_pci_quirk ad1884a_cfg_tbl[] = {
4481 SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION),
4314 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), 4482 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
4315 SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), 4483 SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
4316 SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), 4484 SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
@@ -4404,6 +4572,14 @@ static int patch_ad1884a(struct hda_codec *codec)
4404 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; 4572 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
4405 codec->patch_ops.init = ad1984a_thinkpad_init; 4573 codec->patch_ops.init = ad1984a_thinkpad_init;
4406 break; 4574 break;
4575 case AD1984A_PRECISION:
4576 spec->mixers[0] = ad1984a_precision_mixers;
4577 spec->init_verbs[spec->num_init_verbs++] =
4578 ad1984a_precision_verbs;
4579 spec->multiout.dig_out_nid = 0;
4580 codec->patch_ops.unsol_event = ad1984a_precision_unsol_event;
4581 codec->patch_ops.init = ad1984a_precision_init;
4582 break;
4407 case AD1984A_TOUCHSMART: 4583 case AD1984A_TOUCHSMART:
4408 spec->mixers[0] = ad1984a_touchsmart_mixers; 4584 spec->mixers[0] = ad1984a_touchsmart_mixers;
4409 spec->init_verbs[0] = ad1984a_touchsmart_verbs; 4585 spec->init_verbs[0] = ad1984a_touchsmart_verbs;
@@ -4422,6 +4598,7 @@ static int patch_ad1884a(struct hda_codec *codec)
4422 } 4598 }
4423 4599
4424 codec->no_trigger_sense = 1; 4600 codec->no_trigger_sense = 1;
4601 codec->no_sticky_stream = 1;
4425 4602
4426 return 0; 4603 return 0;
4427} 4604}
@@ -4439,22 +4616,22 @@ static int patch_ad1884a(struct hda_codec *codec)
4439 * port-G - rear clfe-out (6stack) 4616 * port-G - rear clfe-out (6stack)
4440 */ 4617 */
4441 4618
4442static hda_nid_t ad1882_dac_nids[3] = { 4619static const hda_nid_t ad1882_dac_nids[3] = {
4443 0x04, 0x03, 0x05 4620 0x04, 0x03, 0x05
4444}; 4621};
4445 4622
4446static hda_nid_t ad1882_adc_nids[2] = { 4623static const hda_nid_t ad1882_adc_nids[2] = {
4447 0x08, 0x09, 4624 0x08, 0x09,
4448}; 4625};
4449 4626
4450static hda_nid_t ad1882_capsrc_nids[2] = { 4627static const hda_nid_t ad1882_capsrc_nids[2] = {
4451 0x0c, 0x0d, 4628 0x0c, 0x0d,
4452}; 4629};
4453 4630
4454#define AD1882_SPDIF_OUT 0x02 4631#define AD1882_SPDIF_OUT 0x02
4455 4632
4456/* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */ 4633/* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
4457static struct hda_input_mux ad1882_capture_source = { 4634static const struct hda_input_mux ad1882_capture_source = {
4458 .num_items = 5, 4635 .num_items = 5,
4459 .items = { 4636 .items = {
4460 { "Front Mic", 0x1 }, 4637 { "Front Mic", 0x1 },
@@ -4466,7 +4643,7 @@ static struct hda_input_mux ad1882_capture_source = {
4466}; 4643};
4467 4644
4468/* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */ 4645/* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
4469static struct hda_input_mux ad1882a_capture_source = { 4646static const struct hda_input_mux ad1882a_capture_source = {
4470 .num_items = 5, 4647 .num_items = 5,
4471 .items = { 4648 .items = {
4472 { "Front Mic", 0x1 }, 4649 { "Front Mic", 0x1 },
@@ -4477,7 +4654,7 @@ static struct hda_input_mux ad1882a_capture_source = {
4477 }, 4654 },
4478}; 4655};
4479 4656
4480static struct snd_kcontrol_new ad1882_base_mixers[] = { 4657static const struct snd_kcontrol_new ad1882_base_mixers[] = {
4481 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 4658 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
4482 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 4659 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
4483 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 4660 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
@@ -4487,9 +4664,9 @@ static struct snd_kcontrol_new ad1882_base_mixers[] = {
4487 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), 4664 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4488 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), 4665 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4489 4666
4490 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), 4667 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
4491 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), 4668 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
4492 HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT), 4669 HDA_CODEC_VOLUME("Line-In Boost Volume", 0x3a, 0x0, HDA_OUTPUT),
4493 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4670 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4494 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4671 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4495 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 4672 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -4519,7 +4696,7 @@ static struct snd_kcontrol_new ad1882_base_mixers[] = {
4519 { } /* end */ 4696 { } /* end */
4520}; 4697};
4521 4698
4522static struct snd_kcontrol_new ad1882_loopback_mixers[] = { 4699static const struct snd_kcontrol_new ad1882_loopback_mixers[] = {
4523 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 4700 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4524 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 4701 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4525 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), 4702 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
@@ -4531,7 +4708,7 @@ static struct snd_kcontrol_new ad1882_loopback_mixers[] = {
4531 { } /* end */ 4708 { } /* end */
4532}; 4709};
4533 4710
4534static struct snd_kcontrol_new ad1882a_loopback_mixers[] = { 4711static const struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4535 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 4712 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4536 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 4713 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4537 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 4714 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
@@ -4540,11 +4717,11 @@ static struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4540 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT), 4717 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4541 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), 4718 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4542 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), 4719 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4543 HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT), 4720 HDA_CODEC_VOLUME("Digital Mic Boost Volume", 0x1f, 0x0, HDA_INPUT),
4544 { } /* end */ 4721 { } /* end */
4545}; 4722};
4546 4723
4547static struct snd_kcontrol_new ad1882_3stack_mixers[] = { 4724static const struct snd_kcontrol_new ad1882_3stack_mixers[] = {
4548 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), 4725 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4549 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT), 4726 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
4550 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT), 4727 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
@@ -4558,14 +4735,14 @@ static struct snd_kcontrol_new ad1882_3stack_mixers[] = {
4558 { } /* end */ 4735 { } /* end */
4559}; 4736};
4560 4737
4561static struct snd_kcontrol_new ad1882_6stack_mixers[] = { 4738static const struct snd_kcontrol_new ad1882_6stack_mixers[] = {
4562 HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT), 4739 HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4563 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT), 4740 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
4564 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT), 4741 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
4565 { } /* end */ 4742 { } /* end */
4566}; 4743};
4567 4744
4568static struct hda_verb ad1882_ch2_init[] = { 4745static const struct hda_verb ad1882_ch2_init[] = {
4569 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4746 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4570 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4747 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4571 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4748 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
@@ -4575,7 +4752,7 @@ static struct hda_verb ad1882_ch2_init[] = {
4575 { } /* end */ 4752 { } /* end */
4576}; 4753};
4577 4754
4578static struct hda_verb ad1882_ch4_init[] = { 4755static const struct hda_verb ad1882_ch4_init[] = {
4579 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4756 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4580 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4757 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4581 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4758 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -4585,7 +4762,7 @@ static struct hda_verb ad1882_ch4_init[] = {
4585 { } /* end */ 4762 { } /* end */
4586}; 4763};
4587 4764
4588static struct hda_verb ad1882_ch6_init[] = { 4765static const struct hda_verb ad1882_ch6_init[] = {
4589 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4766 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4590 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4767 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4591 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4768 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -4595,7 +4772,7 @@ static struct hda_verb ad1882_ch6_init[] = {
4595 { } /* end */ 4772 { } /* end */
4596}; 4773};
4597 4774
4598static struct hda_channel_mode ad1882_modes[3] = { 4775static const struct hda_channel_mode ad1882_modes[3] = {
4599 { 2, ad1882_ch2_init }, 4776 { 2, ad1882_ch2_init },
4600 { 4, ad1882_ch4_init }, 4777 { 4, ad1882_ch4_init },
4601 { 6, ad1882_ch6_init }, 4778 { 6, ad1882_ch6_init },
@@ -4604,7 +4781,7 @@ static struct hda_channel_mode ad1882_modes[3] = {
4604/* 4781/*
4605 * initialization verbs 4782 * initialization verbs
4606 */ 4783 */
4607static struct hda_verb ad1882_init_verbs[] = { 4784static const struct hda_verb ad1882_init_verbs[] = {
4608 /* DACs; mute as default */ 4785 /* DACs; mute as default */
4609 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4786 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4610 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4787 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -4673,7 +4850,7 @@ static struct hda_verb ad1882_init_verbs[] = {
4673}; 4850};
4674 4851
4675#ifdef CONFIG_SND_HDA_POWER_SAVE 4852#ifdef CONFIG_SND_HDA_POWER_SAVE
4676static struct hda_amp_list ad1882_loopbacks[] = { 4853static const struct hda_amp_list ad1882_loopbacks[] = {
4677 { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 4854 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
4678 { 0x20, HDA_INPUT, 1 }, /* Mic */ 4855 { 0x20, HDA_INPUT, 1 }, /* Mic */
4679 { 0x20, HDA_INPUT, 4 }, /* Line */ 4856 { 0x20, HDA_INPUT, 4 }, /* Line */
@@ -4689,7 +4866,7 @@ enum {
4689 AD1882_MODELS 4866 AD1882_MODELS
4690}; 4867};
4691 4868
4692static const char *ad1882_models[AD1986A_MODELS] = { 4869static const char * const ad1882_models[AD1986A_MODELS] = {
4693 [AD1882_3STACK] = "3stack", 4870 [AD1882_3STACK] = "3stack",
4694 [AD1882_6STACK] = "6stack", 4871 [AD1882_6STACK] = "6stack",
4695}; 4872};
@@ -4761,6 +4938,7 @@ static int patch_ad1882(struct hda_codec *codec)
4761 } 4938 }
4762 4939
4763 codec->no_trigger_sense = 1; 4940 codec->no_trigger_sense = 1;
4941 codec->no_sticky_stream = 1;
4764 4942
4765 return 0; 4943 return 0;
4766} 4944}
@@ -4769,7 +4947,7 @@ static int patch_ad1882(struct hda_codec *codec)
4769/* 4947/*
4770 * patch entries 4948 * patch entries
4771 */ 4949 */
4772static struct hda_codec_preset snd_hda_preset_analog[] = { 4950static const struct hda_codec_preset snd_hda_preset_analog[] = {
4773 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a }, 4951 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a },
4774 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, 4952 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
4775 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a }, 4953 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a },
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
deleted file mode 100644
index fb684f00156b..000000000000
--- a/sound/pci/hda/patch_atihdmi.c
+++ /dev/null
@@ -1,224 +0,0 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ATI HDMI codecs
5 *
6 * Copyright (c) 2006 ATI Technologies Inc.
7 *
8 *
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/slab.h>
27#include <sound/core.h>
28#include "hda_codec.h"
29#include "hda_local.h"
30
31struct atihdmi_spec {
32 struct hda_multi_out multiout;
33
34 struct hda_pcm pcm_rec;
35};
36
37#define CVT_NID 0x02 /* audio converter */
38#define PIN_NID 0x03 /* HDMI output pin */
39
40static struct hda_verb atihdmi_basic_init[] = {
41 /* enable digital output on pin widget */
42 { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
43 {} /* terminator */
44};
45
46/*
47 * Controls
48 */
49static int atihdmi_build_controls(struct hda_codec *codec)
50{
51 struct atihdmi_spec *spec = codec->spec;
52 int err;
53
54 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
55 if (err < 0)
56 return err;
57
58 return 0;
59}
60
61static int atihdmi_init(struct hda_codec *codec)
62{
63 snd_hda_sequence_write(codec, atihdmi_basic_init);
64 /* SI codec requires to unmute the pin */
65 if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP)
66 snd_hda_codec_write(codec, PIN_NID, 0,
67 AC_VERB_SET_AMP_GAIN_MUTE,
68 AMP_OUT_UNMUTE);
69 return 0;
70}
71
72/*
73 * Digital out
74 */
75static int atihdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
76 struct hda_codec *codec,
77 struct snd_pcm_substream *substream)
78{
79 struct atihdmi_spec *spec = codec->spec;
80 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
81}
82
83static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
84 struct hda_codec *codec,
85 struct snd_pcm_substream *substream)
86{
87 struct atihdmi_spec *spec = codec->spec;
88 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
89}
90
91static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
92 struct hda_codec *codec,
93 unsigned int stream_tag,
94 unsigned int format,
95 struct snd_pcm_substream *substream)
96{
97 struct atihdmi_spec *spec = codec->spec;
98 int chans = substream->runtime->channels;
99 int i, err;
100
101 err = snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
102 format, substream);
103 if (err < 0)
104 return err;
105 snd_hda_codec_write(codec, CVT_NID, 0, AC_VERB_SET_CVT_CHAN_COUNT,
106 chans - 1);
107 /* FIXME: XXX */
108 for (i = 0; i < chans; i++) {
109 snd_hda_codec_write(codec, CVT_NID, 0,
110 AC_VERB_SET_HDMI_CHAN_SLOT,
111 (i << 4) | i);
112 }
113 return 0;
114}
115
116static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
117 .substreams = 1,
118 .channels_min = 2,
119 .channels_max = 2,
120 .nid = CVT_NID, /* NID to query formats and rates and setup streams */
121 .ops = {
122 .open = atihdmi_dig_playback_pcm_open,
123 .close = atihdmi_dig_playback_pcm_close,
124 .prepare = atihdmi_dig_playback_pcm_prepare
125 },
126};
127
128static int atihdmi_build_pcms(struct hda_codec *codec)
129{
130 struct atihdmi_spec *spec = codec->spec;
131 struct hda_pcm *info = &spec->pcm_rec;
132 unsigned int chans;
133
134 codec->num_pcms = 1;
135 codec->pcm_info = info;
136
137 info->name = "ATI HDMI";
138 info->pcm_type = HDA_PCM_TYPE_HDMI;
139 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = atihdmi_pcm_digital_playback;
140
141 /* FIXME: we must check ELD and change the PCM parameters dynamically
142 */
143 chans = get_wcaps(codec, CVT_NID);
144 chans = get_wcaps_channels(chans);
145 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
146
147 return 0;
148}
149
150static void atihdmi_free(struct hda_codec *codec)
151{
152 kfree(codec->spec);
153}
154
155static struct hda_codec_ops atihdmi_patch_ops = {
156 .build_controls = atihdmi_build_controls,
157 .build_pcms = atihdmi_build_pcms,
158 .init = atihdmi_init,
159 .free = atihdmi_free,
160};
161
162static int patch_atihdmi(struct hda_codec *codec)
163{
164 struct atihdmi_spec *spec;
165
166 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
167 if (spec == NULL)
168 return -ENOMEM;
169
170 codec->spec = spec;
171
172 spec->multiout.num_dacs = 0; /* no analog */
173 spec->multiout.max_channels = 2;
174 /* NID for copying analog to digital,
175 * seems to be unused in pure-digital
176 * case.
177 */
178 spec->multiout.dig_out_nid = CVT_NID;
179
180 codec->patch_ops = atihdmi_patch_ops;
181
182 return 0;
183}
184
185/*
186 * patch entries
187 */
188static struct hda_codec_preset snd_hda_preset_atihdmi[] = {
189 { .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
190 { .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
191 { .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
192 { .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi },
193 { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi },
194 { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi },
195 {} /* terminator */
196};
197
198MODULE_ALIAS("snd-hda-codec-id:1002793c");
199MODULE_ALIAS("snd-hda-codec-id:10027919");
200MODULE_ALIAS("snd-hda-codec-id:1002791a");
201MODULE_ALIAS("snd-hda-codec-id:1002aa01");
202MODULE_ALIAS("snd-hda-codec-id:10951390");
203MODULE_ALIAS("snd-hda-codec-id:17e80047");
204
205MODULE_LICENSE("GPL");
206MODULE_DESCRIPTION("ATI HDMI HD-audio codec");
207
208static struct hda_codec_preset_list atihdmi_list = {
209 .preset = snd_hda_preset_atihdmi,
210 .owner = THIS_MODULE,
211};
212
213static int __init patch_atihdmi_init(void)
214{
215 return snd_hda_add_codec_preset(&atihdmi_list);
216}
217
218static void __exit patch_atihdmi_exit(void)
219{
220 snd_hda_delete_codec_preset(&atihdmi_list);
221}
222
223module_init(patch_atihdmi_init)
224module_exit(patch_atihdmi_exit)
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c
index af478019088e..61b92634b161 100644
--- a/sound/pci/hda/patch_ca0110.c
+++ b/sound/pci/hda/patch_ca0110.c
@@ -134,7 +134,7 @@ static int ca0110_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
134/* 134/*
135 */ 135 */
136 136
137static char *dirstr[2] = { "Playback", "Capture" }; 137static const char * const dirstr[2] = { "Playback", "Capture" };
138 138
139static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, 139static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
140 int chan, int dir) 140 int chan, int dir)
@@ -171,7 +171,7 @@ static int ca0110_build_controls(struct hda_codec *codec)
171{ 171{
172 struct ca0110_spec *spec = codec->spec; 172 struct ca0110_spec *spec = codec->spec;
173 struct auto_pin_cfg *cfg = &spec->autocfg; 173 struct auto_pin_cfg *cfg = &spec->autocfg;
174 static char *prefix[AUTO_CFG_MAX_OUTS] = { 174 static const char * const prefix[AUTO_CFG_MAX_OUTS] = {
175 "Front", "Surround", NULL, "Side", "Multi" 175 "Front", "Surround", NULL, "Side", "Multi"
176 }; 176 };
177 hda_nid_t mutenid; 177 hda_nid_t mutenid;
@@ -259,7 +259,7 @@ static int ca0110_build_controls(struct hda_codec *codec)
259 259
260/* 260/*
261 */ 261 */
262static struct hda_pcm_stream ca0110_pcm_analog_playback = { 262static const struct hda_pcm_stream ca0110_pcm_analog_playback = {
263 .substreams = 1, 263 .substreams = 1,
264 .channels_min = 2, 264 .channels_min = 2,
265 .channels_max = 8, 265 .channels_max = 8,
@@ -270,7 +270,7 @@ static struct hda_pcm_stream ca0110_pcm_analog_playback = {
270 }, 270 },
271}; 271};
272 272
273static struct hda_pcm_stream ca0110_pcm_analog_capture = { 273static const struct hda_pcm_stream ca0110_pcm_analog_capture = {
274 .substreams = 1, 274 .substreams = 1,
275 .channels_min = 2, 275 .channels_min = 2,
276 .channels_max = 2, 276 .channels_max = 2,
@@ -280,7 +280,7 @@ static struct hda_pcm_stream ca0110_pcm_analog_capture = {
280 }, 280 },
281}; 281};
282 282
283static struct hda_pcm_stream ca0110_pcm_digital_playback = { 283static const struct hda_pcm_stream ca0110_pcm_digital_playback = {
284 .substreams = 1, 284 .substreams = 1,
285 .channels_min = 2, 285 .channels_min = 2,
286 .channels_max = 2, 286 .channels_max = 2,
@@ -291,7 +291,7 @@ static struct hda_pcm_stream ca0110_pcm_digital_playback = {
291 }, 291 },
292}; 292};
293 293
294static struct hda_pcm_stream ca0110_pcm_digital_capture = { 294static const struct hda_pcm_stream ca0110_pcm_digital_capture = {
295 .substreams = 1, 295 .substreams = 1,
296 .channels_min = 2, 296 .channels_min = 2,
297 .channels_max = 2, 297 .channels_max = 2,
@@ -389,7 +389,7 @@ static void ca0110_free(struct hda_codec *codec)
389 kfree(codec->spec); 389 kfree(codec->spec);
390} 390}
391 391
392static struct hda_codec_ops ca0110_patch_ops = { 392static const struct hda_codec_ops ca0110_patch_ops = {
393 .build_controls = ca0110_build_controls, 393 .build_controls = ca0110_build_controls,
394 .build_pcms = ca0110_build_pcms, 394 .build_pcms = ca0110_build_pcms,
395 .init = ca0110_init, 395 .init = ca0110_init,
@@ -468,13 +468,13 @@ static void parse_input(struct hda_codec *codec)
468 spec->dig_in = nid; 468 spec->dig_in = nid;
469 continue; 469 continue;
470 } 470 }
471 for (j = 0; j < AUTO_PIN_LAST; j++) 471 for (j = 0; j < cfg->num_inputs; j++)
472 if (cfg->input_pins[j] == pin) 472 if (cfg->inputs[j].pin == pin)
473 break; 473 break;
474 if (j >= AUTO_PIN_LAST) 474 if (j >= cfg->num_inputs)
475 continue; 475 continue;
476 spec->input_pins[n] = pin; 476 spec->input_pins[n] = pin;
477 spec->input_labels[n] = auto_pin_cfg_labels[j]; 477 spec->input_labels[n] = hda_get_input_pin_label(codec, pin, 1);
478 spec->adcs[n] = nid; 478 spec->adcs[n] = nid;
479 n++; 479 n++;
480 } 480 }
@@ -489,7 +489,7 @@ static void parse_digital(struct hda_codec *codec)
489 if (cfg->dig_outs && 489 if (cfg->dig_outs &&
490 snd_hda_get_connections(codec, cfg->dig_out_pins[0], 490 snd_hda_get_connections(codec, cfg->dig_out_pins[0],
491 &spec->dig_out, 1) == 1) 491 &spec->dig_out, 1) == 1)
492 spec->multiout.dig_out_nid = cfg->dig_out_pins[0]; 492 spec->multiout.dig_out_nid = spec->dig_out;
493} 493}
494 494
495static int ca0110_parse_auto_config(struct hda_codec *codec) 495static int ca0110_parse_auto_config(struct hda_codec *codec)
@@ -539,7 +539,7 @@ static int patch_ca0110(struct hda_codec *codec)
539/* 539/*
540 * patch entries 540 * patch entries
541 */ 541 */
542static struct hda_codec_preset snd_hda_preset_ca0110[] = { 542static const struct hda_codec_preset snd_hda_preset_ca0110[] = {
543 { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 }, 543 { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 },
544 { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 }, 544 { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 },
545 { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 }, 545 { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 },
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 488fd9ade1ba..26a1521045bb 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -51,7 +51,7 @@ struct cs_spec {
51 unsigned int cur_adc_format; 51 unsigned int cur_adc_format;
52 hda_nid_t dig_in; 52 hda_nid_t dig_in;
53 53
54 struct hda_bind_ctls *capture_bind[2]; 54 const struct hda_bind_ctls *capture_bind[2];
55 55
56 unsigned int gpio_mask; 56 unsigned int gpio_mask;
57 unsigned int gpio_dir; 57 unsigned int gpio_dir;
@@ -65,6 +65,7 @@ struct cs_spec {
65 65
66/* available models */ 66/* available models */
67enum { 67enum {
68 CS420X_MBP53,
68 CS420X_MBP55, 69 CS420X_MBP55,
69 CS420X_IMAC27, 70 CS420X_IMAC27,
70 CS420X_AUTO, 71 CS420X_AUTO,
@@ -230,7 +231,7 @@ static int cs_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
230 231
231/* 232/*
232 */ 233 */
233static struct hda_pcm_stream cs_pcm_analog_playback = { 234static const struct hda_pcm_stream cs_pcm_analog_playback = {
234 .substreams = 1, 235 .substreams = 1,
235 .channels_min = 2, 236 .channels_min = 2,
236 .channels_max = 2, 237 .channels_max = 2,
@@ -241,7 +242,7 @@ static struct hda_pcm_stream cs_pcm_analog_playback = {
241 }, 242 },
242}; 243};
243 244
244static struct hda_pcm_stream cs_pcm_analog_capture = { 245static const struct hda_pcm_stream cs_pcm_analog_capture = {
245 .substreams = 1, 246 .substreams = 1,
246 .channels_min = 2, 247 .channels_min = 2,
247 .channels_max = 2, 248 .channels_max = 2,
@@ -251,7 +252,7 @@ static struct hda_pcm_stream cs_pcm_analog_capture = {
251 }, 252 },
252}; 253};
253 254
254static struct hda_pcm_stream cs_pcm_digital_playback = { 255static const struct hda_pcm_stream cs_pcm_digital_playback = {
255 .substreams = 1, 256 .substreams = 1,
256 .channels_min = 2, 257 .channels_min = 2,
257 .channels_max = 2, 258 .channels_max = 2,
@@ -263,7 +264,7 @@ static struct hda_pcm_stream cs_pcm_digital_playback = {
263 }, 264 },
264}; 265};
265 266
266static struct hda_pcm_stream cs_pcm_digital_capture = { 267static const struct hda_pcm_stream cs_pcm_digital_capture = {
267 .substreams = 1, 268 .substreams = 1,
268 .channels_min = 2, 269 .channels_min = 2,
269 .channels_max = 2, 270 .channels_max = 2,
@@ -329,12 +330,12 @@ static int is_ext_mic(struct hda_codec *codec, unsigned int idx)
329{ 330{
330 struct cs_spec *spec = codec->spec; 331 struct cs_spec *spec = codec->spec;
331 struct auto_pin_cfg *cfg = &spec->autocfg; 332 struct auto_pin_cfg *cfg = &spec->autocfg;
332 hda_nid_t pin = cfg->input_pins[idx]; 333 hda_nid_t pin = cfg->inputs[idx].pin;
333 unsigned int val = snd_hda_query_pin_caps(codec, pin); 334 unsigned int val;
334 if (!(val & AC_PINCAP_PRES_DETECT)) 335 if (!is_jack_detectable(codec, pin))
335 return 0; 336 return 0;
336 val = snd_hda_codec_get_pincfg(codec, pin); 337 val = snd_hda_codec_get_pincfg(codec, pin);
337 return (get_defcfg_connect(val) == AC_JACK_PORT_COMPLEX); 338 return (snd_hda_get_input_pin_attr(val) != INPUT_PIN_ATTR_INT);
338} 339}
339 340
340static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin, 341static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
@@ -348,8 +349,7 @@ static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
348 hda_nid_t pins[2]; 349 hda_nid_t pins[2];
349 unsigned int type; 350 unsigned int type;
350 int j, nums; 351 int j, nums;
351 type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) 352 type = get_wcaps_type(get_wcaps(codec, nid));
352 >> AC_WCAP_TYPE_SHIFT;
353 if (type != AC_WID_AUD_IN) 353 if (type != AC_WID_AUD_IN)
354 continue; 354 continue;
355 nums = snd_hda_get_connections(codec, nid, pins, 355 nums = snd_hda_get_connections(codec, nid, pins,
@@ -424,10 +424,8 @@ static int parse_input(struct hda_codec *codec)
424 struct auto_pin_cfg *cfg = &spec->autocfg; 424 struct auto_pin_cfg *cfg = &spec->autocfg;
425 int i; 425 int i;
426 426
427 for (i = 0; i < AUTO_PIN_LAST; i++) { 427 for (i = 0; i < cfg->num_inputs; i++) {
428 hda_nid_t pin = cfg->input_pins[i]; 428 hda_nid_t pin = cfg->inputs[i].pin;
429 if (!pin)
430 continue;
431 spec->input_idx[spec->num_inputs] = i; 429 spec->input_idx[spec->num_inputs] = i;
432 spec->capsrc_idx[i] = spec->num_inputs++; 430 spec->capsrc_idx[i] = spec->num_inputs++;
433 spec->cur_input = i; 431 spec->cur_input = i;
@@ -438,16 +436,17 @@ static int parse_input(struct hda_codec *codec)
438 436
439 /* check whether the automatic mic switch is available */ 437 /* check whether the automatic mic switch is available */
440 if (spec->num_inputs == 2 && 438 if (spec->num_inputs == 2 &&
441 spec->adc_nid[AUTO_PIN_MIC] && spec->adc_nid[AUTO_PIN_FRONT_MIC]) { 439 cfg->inputs[0].type == AUTO_PIN_MIC &&
442 if (is_ext_mic(codec, cfg->input_pins[AUTO_PIN_FRONT_MIC])) { 440 cfg->inputs[1].type == AUTO_PIN_MIC) {
443 if (!is_ext_mic(codec, cfg->input_pins[AUTO_PIN_MIC])) { 441 if (is_ext_mic(codec, cfg->inputs[0].pin)) {
442 if (!is_ext_mic(codec, cfg->inputs[1].pin)) {
444 spec->mic_detect = 1; 443 spec->mic_detect = 1;
445 spec->automic_idx = AUTO_PIN_FRONT_MIC; 444 spec->automic_idx = 0;
446 } 445 }
447 } else { 446 } else {
448 if (is_ext_mic(codec, cfg->input_pins[AUTO_PIN_MIC])) { 447 if (is_ext_mic(codec, cfg->inputs[1].pin)) {
449 spec->mic_detect = 1; 448 spec->mic_detect = 1;
450 spec->automic_idx = AUTO_PIN_MIC; 449 spec->automic_idx = 1;
451 } 450 }
452 } 451 }
453 } 452 }
@@ -490,7 +489,7 @@ static int parse_digital_input(struct hda_codec *codec)
490 * create mixer controls 489 * create mixer controls
491 */ 490 */
492 491
493static const char *dir_sfx[2] = { "Playback", "Capture" }; 492static const char * const dir_sfx[2] = { "Playback", "Capture" };
494 493
495static int add_mute(struct hda_codec *codec, const char *name, int index, 494static int add_mute(struct hda_codec *codec, const char *name, int index,
496 unsigned int pval, int dir, struct snd_kcontrol **kctlp) 495 unsigned int pval, int dir, struct snd_kcontrol **kctlp)
@@ -559,10 +558,10 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx,
559 const char *name; 558 const char *name;
560 int err, index; 559 int err, index;
561 struct snd_kcontrol *kctl; 560 struct snd_kcontrol *kctl;
562 static char *speakers[] = { 561 static const char * const speakers[] = {
563 "Front Speaker", "Surround Speaker", "Bass Speaker" 562 "Front Speaker", "Surround Speaker", "Bass Speaker"
564 }; 563 };
565 static char *line_outs[] = { 564 static const char * const line_outs[] = {
566 "Front Line-Out", "Surround Line-Out", "Bass Line-Out" 565 "Front Line-Out", "Surround Line-Out", "Bass Line-Out"
567 }; 566 };
568 567
@@ -642,7 +641,7 @@ static int build_output(struct hda_codec *codec)
642/* 641/*
643 */ 642 */
644 643
645static struct snd_kcontrol_new cs_capture_ctls[] = { 644static const struct snd_kcontrol_new cs_capture_ctls[] = {
646 HDA_BIND_SW("Capture Switch", 0), 645 HDA_BIND_SW("Capture Switch", 0),
647 HDA_BIND_VOL("Capture Volume", 0), 646 HDA_BIND_VOL("Capture Volume", 0),
648}; 647};
@@ -674,6 +673,7 @@ static int cs_capture_source_info(struct snd_kcontrol *kcontrol,
674{ 673{
675 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 674 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
676 struct cs_spec *spec = codec->spec; 675 struct cs_spec *spec = codec->spec;
676 struct auto_pin_cfg *cfg = &spec->autocfg;
677 unsigned int idx; 677 unsigned int idx;
678 678
679 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 679 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -682,7 +682,8 @@ static int cs_capture_source_info(struct snd_kcontrol *kcontrol,
682 if (uinfo->value.enumerated.item >= spec->num_inputs) 682 if (uinfo->value.enumerated.item >= spec->num_inputs)
683 uinfo->value.enumerated.item = spec->num_inputs - 1; 683 uinfo->value.enumerated.item = spec->num_inputs - 1;
684 idx = spec->input_idx[uinfo->value.enumerated.item]; 684 idx = spec->input_idx[uinfo->value.enumerated.item];
685 strcpy(uinfo->value.enumerated.name, auto_pin_cfg_labels[idx]); 685 strcpy(uinfo->value.enumerated.name,
686 hda_get_input_pin_label(codec, cfg->inputs[idx].pin, 1));
686 return 0; 687 return 0;
687} 688}
688 689
@@ -708,7 +709,7 @@ static int cs_capture_source_put(struct snd_kcontrol *kcontrol,
708 return change_cur_input(codec, idx, 0); 709 return change_cur_input(codec, idx, 0);
709} 710}
710 711
711static struct snd_kcontrol_new cs_capture_source = { 712static const struct snd_kcontrol_new cs_capture_source = {
712 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 713 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
713 .name = "Capture Source", 714 .name = "Capture Source",
714 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 715 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -717,7 +718,7 @@ static struct snd_kcontrol_new cs_capture_source = {
717 .put = cs_capture_source_put, 718 .put = cs_capture_source_put,
718}; 719};
719 720
720static struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec, 721static const struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec,
721 struct hda_ctl_ops *ops) 722 struct hda_ctl_ops *ops)
722{ 723{
723 struct cs_spec *spec = codec->spec; 724 struct cs_spec *spec = codec->spec;
@@ -740,6 +741,27 @@ static struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec,
740 return bind; 741 return bind;
741} 742}
742 743
744/* add a (input-boost) volume control to the given input pin */
745static int add_input_volume_control(struct hda_codec *codec,
746 struct auto_pin_cfg *cfg,
747 int item)
748{
749 hda_nid_t pin = cfg->inputs[item].pin;
750 u32 caps;
751 const char *label;
752 struct snd_kcontrol *kctl;
753
754 if (!(get_wcaps(codec, pin) & AC_WCAP_IN_AMP))
755 return 0;
756 caps = query_amp_caps(codec, pin, HDA_INPUT);
757 caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
758 if (caps <= 1)
759 return 0;
760 label = hda_get_autocfg_input_label(codec, cfg, item);
761 return add_volume(codec, label, 0,
762 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT), 1, &kctl);
763}
764
743static int build_input(struct hda_codec *codec) 765static int build_input(struct hda_codec *codec)
744{ 766{
745 struct cs_spec *spec = codec->spec; 767 struct cs_spec *spec = codec->spec;
@@ -779,6 +801,12 @@ static int build_input(struct hda_codec *codec)
779 return err; 801 return err;
780 } 802 }
781 803
804 for (i = 0; i < spec->num_inputs; i++) {
805 err = add_input_volume_control(codec, &spec->autocfg, i);
806 if (err < 0)
807 return err;
808 }
809
782 return 0; 810 return 0;
783} 811}
784 812
@@ -818,15 +846,14 @@ static void cs_automute(struct hda_codec *codec)
818{ 846{
819 struct cs_spec *spec = codec->spec; 847 struct cs_spec *spec = codec->spec;
820 struct auto_pin_cfg *cfg = &spec->autocfg; 848 struct auto_pin_cfg *cfg = &spec->autocfg;
821 unsigned int caps, hp_present; 849 unsigned int hp_present;
822 hda_nid_t nid; 850 hda_nid_t nid;
823 int i; 851 int i;
824 852
825 hp_present = 0; 853 hp_present = 0;
826 for (i = 0; i < cfg->hp_outs; i++) { 854 for (i = 0; i < cfg->hp_outs; i++) {
827 nid = cfg->hp_pins[i]; 855 nid = cfg->hp_pins[i];
828 caps = snd_hda_query_pin_caps(codec, nid); 856 if (!is_jack_detectable(codec, nid))
829 if (!(caps & AC_PINCAP_PRES_DETECT))
830 continue; 857 continue;
831 hp_present = snd_hda_jack_detect(codec, nid); 858 hp_present = snd_hda_jack_detect(codec, nid);
832 if (hp_present) 859 if (hp_present)
@@ -838,7 +865,8 @@ static void cs_automute(struct hda_codec *codec)
838 AC_VERB_SET_PIN_WIDGET_CONTROL, 865 AC_VERB_SET_PIN_WIDGET_CONTROL,
839 hp_present ? 0 : PIN_OUT); 866 hp_present ? 0 : PIN_OUT);
840 } 867 }
841 if (spec->board_config == CS420X_MBP55 || 868 if (spec->board_config == CS420X_MBP53 ||
869 spec->board_config == CS420X_MBP55 ||
842 spec->board_config == CS420X_IMAC27) { 870 spec->board_config == CS420X_IMAC27) {
843 unsigned int gpio = hp_present ? 0x02 : 0x08; 871 unsigned int gpio = hp_present ? 0x02 : 0x08;
844 snd_hda_codec_write(codec, 0x01, 0, 872 snd_hda_codec_write(codec, 0x01, 0,
@@ -853,15 +881,12 @@ static void cs_automic(struct hda_codec *codec)
853 hda_nid_t nid; 881 hda_nid_t nid;
854 unsigned int present; 882 unsigned int present;
855 883
856 nid = cfg->input_pins[spec->automic_idx]; 884 nid = cfg->inputs[spec->automic_idx].pin;
857 present = snd_hda_jack_detect(codec, nid); 885 present = snd_hda_jack_detect(codec, nid);
858 if (present) 886 if (present)
859 change_cur_input(codec, spec->automic_idx, 0); 887 change_cur_input(codec, spec->automic_idx, 0);
860 else { 888 else
861 unsigned int imic = (spec->automic_idx == AUTO_PIN_MIC) ? 889 change_cur_input(codec, !spec->automic_idx, 0);
862 AUTO_PIN_FRONT_MIC : AUTO_PIN_MIC;
863 change_cur_input(codec, imic, 0);
864 }
865} 890}
866 891
867/* 892/*
@@ -897,7 +922,7 @@ static void init_output(struct hda_codec *codec)
897 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); 922 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
898 if (!cfg->speaker_outs) 923 if (!cfg->speaker_outs)
899 continue; 924 continue;
900 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { 925 if (is_jack_detectable(codec, nid)) {
901 snd_hda_codec_write(codec, nid, 0, 926 snd_hda_codec_write(codec, nid, 0,
902 AC_VERB_SET_UNSOLICITED_ENABLE, 927 AC_VERB_SET_UNSOLICITED_ENABLE,
903 AC_USRSP_EN | HP_EVENT); 928 AC_USRSP_EN | HP_EVENT);
@@ -918,14 +943,14 @@ static void init_input(struct hda_codec *codec)
918 unsigned int coef; 943 unsigned int coef;
919 int i; 944 int i;
920 945
921 for (i = 0; i < AUTO_PIN_LAST; i++) { 946 for (i = 0; i < cfg->num_inputs; i++) {
922 unsigned int ctl; 947 unsigned int ctl;
923 hda_nid_t pin = cfg->input_pins[i]; 948 hda_nid_t pin = cfg->inputs[i].pin;
924 if (!pin || !spec->adc_nid[i]) 949 if (!spec->adc_nid[i])
925 continue; 950 continue;
926 /* set appropriate pin control and mute first */ 951 /* set appropriate pin control and mute first */
927 ctl = PIN_IN; 952 ctl = PIN_IN;
928 if (i <= AUTO_PIN_FRONT_MIC) { 953 if (cfg->inputs[i].type == AUTO_PIN_MIC) {
929 unsigned int caps = snd_hda_query_pin_caps(codec, pin); 954 unsigned int caps = snd_hda_query_pin_caps(codec, pin);
930 caps >>= AC_PINCAP_VREF_SHIFT; 955 caps >>= AC_PINCAP_VREF_SHIFT;
931 if (caps & AC_PINCAP_VREF_80) 956 if (caps & AC_PINCAP_VREF_80)
@@ -956,7 +981,7 @@ static void init_input(struct hda_codec *codec)
956 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); 981 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
957} 982}
958 983
959static struct hda_verb cs_coef_init_verbs[] = { 984static const struct hda_verb cs_coef_init_verbs[] = {
960 {0x11, AC_VERB_SET_PROC_STATE, 1}, 985 {0x11, AC_VERB_SET_PROC_STATE, 1},
961 {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, 986 {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG},
962 {0x11, AC_VERB_SET_PROC_COEF, 987 {0x11, AC_VERB_SET_PROC_COEF,
@@ -990,7 +1015,7 @@ static struct hda_verb cs_coef_init_verbs[] = {
990 * blocks, which will alleviate the issue. 1015 * blocks, which will alleviate the issue.
991 */ 1016 */
992 1017
993static struct hda_verb cs_errata_init_verbs[] = { 1018static const struct hda_verb cs_errata_init_verbs[] = {
994 {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */ 1019 {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */
995 {0x11, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */ 1020 {0x11, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */
996 1021
@@ -1012,9 +1037,11 @@ static struct hda_verb cs_errata_init_verbs[] = {
1012 {0x11, AC_VERB_SET_PROC_COEF, 0x0008}, 1037 {0x11, AC_VERB_SET_PROC_COEF, 0x0008},
1013 {0x11, AC_VERB_SET_PROC_STATE, 0x00}, 1038 {0x11, AC_VERB_SET_PROC_STATE, 0x00},
1014 1039
1040#if 0 /* Don't to set to D3 as we are in power-up sequence */
1015 {0x07, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Rx: D3 */ 1041 {0x07, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Rx: D3 */
1016 {0x08, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Tx: D3 */ 1042 {0x08, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Tx: D3 */
1017 /*{0x01, AC_VERB_SET_POWER_STATE, 0x03},*/ /* AFG: D3 This is already handled */ 1043 /*{0x01, AC_VERB_SET_POWER_STATE, 0x03},*/ /* AFG: D3 This is already handled */
1044#endif
1018 1045
1019 {} /* terminator */ 1046 {} /* terminator */
1020}; 1047};
@@ -1097,7 +1124,7 @@ static void cs_unsol_event(struct hda_codec *codec, unsigned int res)
1097 } 1124 }
1098} 1125}
1099 1126
1100static struct hda_codec_ops cs_patch_ops = { 1127static const struct hda_codec_ops cs_patch_ops = {
1101 .build_controls = cs_build_controls, 1128 .build_controls = cs_build_controls,
1102 .build_pcms = cs_build_pcms, 1129 .build_pcms = cs_build_pcms,
1103 .init = cs_init, 1130 .init = cs_init,
@@ -1129,15 +1156,19 @@ static int cs_parse_auto_config(struct hda_codec *codec)
1129 return 0; 1156 return 0;
1130} 1157}
1131 1158
1132static const char *cs420x_models[CS420X_MODELS] = { 1159static const char * const cs420x_models[CS420X_MODELS] = {
1160 [CS420X_MBP53] = "mbp53",
1133 [CS420X_MBP55] = "mbp55", 1161 [CS420X_MBP55] = "mbp55",
1134 [CS420X_IMAC27] = "imac27", 1162 [CS420X_IMAC27] = "imac27",
1135 [CS420X_AUTO] = "auto", 1163 [CS420X_AUTO] = "auto",
1136}; 1164};
1137 1165
1138 1166
1139static struct snd_pci_quirk cs420x_cfg_tbl[] = { 1167static const struct snd_pci_quirk cs420x_cfg_tbl[] = {
1168 SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53),
1169 SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55),
1140 SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), 1170 SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55),
1171 SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55),
1141 SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27), 1172 SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),
1142 {} /* terminator */ 1173 {} /* terminator */
1143}; 1174};
@@ -1147,7 +1178,21 @@ struct cs_pincfg {
1147 u32 val; 1178 u32 val;
1148}; 1179};
1149 1180
1150static struct cs_pincfg mbp55_pincfgs[] = { 1181static const struct cs_pincfg mbp53_pincfgs[] = {
1182 { 0x09, 0x012b4050 },
1183 { 0x0a, 0x90100141 },
1184 { 0x0b, 0x90100140 },
1185 { 0x0c, 0x018b3020 },
1186 { 0x0d, 0x90a00110 },
1187 { 0x0e, 0x400000f0 },
1188 { 0x0f, 0x01cbe030 },
1189 { 0x10, 0x014be060 },
1190 { 0x12, 0x400000f0 },
1191 { 0x15, 0x400000f0 },
1192 {} /* terminator */
1193};
1194
1195static const struct cs_pincfg mbp55_pincfgs[] = {
1151 { 0x09, 0x012b4030 }, 1196 { 0x09, 0x012b4030 },
1152 { 0x0a, 0x90100121 }, 1197 { 0x0a, 0x90100121 },
1153 { 0x0b, 0x90100120 }, 1198 { 0x0b, 0x90100120 },
@@ -1161,7 +1206,7 @@ static struct cs_pincfg mbp55_pincfgs[] = {
1161 {} /* terminator */ 1206 {} /* terminator */
1162}; 1207};
1163 1208
1164static struct cs_pincfg imac27_pincfgs[] = { 1209static const struct cs_pincfg imac27_pincfgs[] = {
1165 { 0x09, 0x012b4050 }, 1210 { 0x09, 0x012b4050 },
1166 { 0x0a, 0x90100140 }, 1211 { 0x0a, 0x90100140 },
1167 { 0x0b, 0x90100142 }, 1212 { 0x0b, 0x90100142 },
@@ -1175,7 +1220,8 @@ static struct cs_pincfg imac27_pincfgs[] = {
1175 {} /* terminator */ 1220 {} /* terminator */
1176}; 1221};
1177 1222
1178static struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = { 1223static const struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = {
1224 [CS420X_MBP53] = mbp53_pincfgs,
1179 [CS420X_MBP55] = mbp55_pincfgs, 1225 [CS420X_MBP55] = mbp55_pincfgs,
1180 [CS420X_IMAC27] = imac27_pincfgs, 1226 [CS420X_IMAC27] = imac27_pincfgs,
1181}; 1227};
@@ -1208,6 +1254,7 @@ static int patch_cs420x(struct hda_codec *codec)
1208 1254
1209 switch (spec->board_config) { 1255 switch (spec->board_config) {
1210 case CS420X_IMAC27: 1256 case CS420X_IMAC27:
1257 case CS420X_MBP53:
1211 case CS420X_MBP55: 1258 case CS420X_MBP55:
1212 /* GPIO1 = headphones */ 1259 /* GPIO1 = headphones */
1213 /* GPIO3 = speakers */ 1260 /* GPIO3 = speakers */
@@ -1234,7 +1281,7 @@ static int patch_cs420x(struct hda_codec *codec)
1234/* 1281/*
1235 * patch entries 1282 * patch entries
1236 */ 1283 */
1237static struct hda_codec_preset snd_hda_preset_cirrus[] = { 1284static const struct hda_codec_preset snd_hda_preset_cirrus[] = {
1238 { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x }, 1285 { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x },
1239 { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x }, 1286 { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x },
1240 {} /* terminator */ 1287 {} /* terminator */
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index ff60908f4554..ab3308daa960 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -53,7 +53,7 @@ struct cmi_spec {
53 int num_dacs; 53 int num_dacs;
54 54
55 /* capture */ 55 /* capture */
56 hda_nid_t *adc_nids; 56 const hda_nid_t *adc_nids;
57 hda_nid_t dig_in_nid; 57 hda_nid_t dig_in_nid;
58 58
59 /* capture source */ 59 /* capture source */
@@ -110,7 +110,7 @@ static int cmi_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
110 */ 110 */
111 111
112/* 3-stack / 2 channel */ 112/* 3-stack / 2 channel */
113static struct hda_verb cmi9880_ch2_init[] = { 113static const struct hda_verb cmi9880_ch2_init[] = {
114 /* set line-in PIN for input */ 114 /* set line-in PIN for input */
115 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 115 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
116 /* set mic PIN for input, also enable vref */ 116 /* set mic PIN for input, also enable vref */
@@ -121,7 +121,7 @@ static struct hda_verb cmi9880_ch2_init[] = {
121}; 121};
122 122
123/* 3-stack / 6 channel */ 123/* 3-stack / 6 channel */
124static struct hda_verb cmi9880_ch6_init[] = { 124static const struct hda_verb cmi9880_ch6_init[] = {
125 /* set line-in PIN for output */ 125 /* set line-in PIN for output */
126 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 126 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
127 /* set mic PIN for output */ 127 /* set mic PIN for output */
@@ -132,7 +132,7 @@ static struct hda_verb cmi9880_ch6_init[] = {
132}; 132};
133 133
134/* 3-stack+front / 8 channel */ 134/* 3-stack+front / 8 channel */
135static struct hda_verb cmi9880_ch8_init[] = { 135static const struct hda_verb cmi9880_ch8_init[] = {
136 /* set line-in PIN for output */ 136 /* set line-in PIN for output */
137 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 137 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
138 /* set mic PIN for output */ 138 /* set mic PIN for output */
@@ -142,7 +142,7 @@ static struct hda_verb cmi9880_ch8_init[] = {
142 {} 142 {}
143}; 143};
144 144
145static struct hda_channel_mode cmi9880_channel_modes[3] = { 145static const struct hda_channel_mode cmi9880_channel_modes[3] = {
146 { 2, cmi9880_ch2_init }, 146 { 2, cmi9880_ch2_init },
147 { 6, cmi9880_ch6_init }, 147 { 6, cmi9880_ch6_init },
148 { 8, cmi9880_ch8_init }, 148 { 8, cmi9880_ch8_init },
@@ -174,7 +174,7 @@ static int cmi_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
174 174
175/* 175/*
176 */ 176 */
177static struct snd_kcontrol_new cmi9880_basic_mixer[] = { 177static const struct snd_kcontrol_new cmi9880_basic_mixer[] = {
178 /* CMI9880 has no playback volumes! */ 178 /* CMI9880 has no playback volumes! */
179 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), /* front */ 179 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), /* front */
180 HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0x0, HDA_OUTPUT), 180 HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0x0, HDA_OUTPUT),
@@ -205,7 +205,7 @@ static struct snd_kcontrol_new cmi9880_basic_mixer[] = {
205/* 205/*
206 * shared I/O pins 206 * shared I/O pins
207 */ 207 */
208static struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = { 208static const struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = {
209 { 209 {
210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
211 .name = "Channel Mode", 211 .name = "Channel Mode",
@@ -219,7 +219,7 @@ static struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = {
219/* AUD-in selections: 219/* AUD-in selections:
220 * 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x1f 0x20 220 * 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x1f 0x20
221 */ 221 */
222static struct hda_input_mux cmi9880_basic_mux = { 222static const struct hda_input_mux cmi9880_basic_mux = {
223 .num_items = 4, 223 .num_items = 4,
224 .items = { 224 .items = {
225 { "Front Mic", 0x5 }, 225 { "Front Mic", 0x5 },
@@ -229,7 +229,7 @@ static struct hda_input_mux cmi9880_basic_mux = {
229 } 229 }
230}; 230};
231 231
232static struct hda_input_mux cmi9880_no_line_mux = { 232static const struct hda_input_mux cmi9880_no_line_mux = {
233 .num_items = 3, 233 .num_items = 3,
234 .items = { 234 .items = {
235 { "Front Mic", 0x5 }, 235 { "Front Mic", 0x5 },
@@ -239,11 +239,11 @@ static struct hda_input_mux cmi9880_no_line_mux = {
239}; 239};
240 240
241/* front, rear, clfe, rear_surr */ 241/* front, rear, clfe, rear_surr */
242static hda_nid_t cmi9880_dac_nids[4] = { 242static const hda_nid_t cmi9880_dac_nids[4] = {
243 0x03, 0x04, 0x05, 0x06 243 0x03, 0x04, 0x05, 0x06
244}; 244};
245/* ADC0, ADC1 */ 245/* ADC0, ADC1 */
246static hda_nid_t cmi9880_adc_nids[2] = { 246static const hda_nid_t cmi9880_adc_nids[2] = {
247 0x08, 0x09 247 0x08, 0x09
248}; 248};
249 249
@@ -252,7 +252,7 @@ static hda_nid_t cmi9880_adc_nids[2] = {
252 252
253/* 253/*
254 */ 254 */
255static struct hda_verb cmi9880_basic_init[] = { 255static const struct hda_verb cmi9880_basic_init[] = {
256 /* port-D for line out (rear panel) */ 256 /* port-D for line out (rear panel) */
257 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 257 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
258 /* port-E for HP out (front panel) */ 258 /* port-E for HP out (front panel) */
@@ -281,7 +281,7 @@ static struct hda_verb cmi9880_basic_init[] = {
281 {} /* terminator */ 281 {} /* terminator */
282}; 282};
283 283
284static struct hda_verb cmi9880_allout_init[] = { 284static const struct hda_verb cmi9880_allout_init[] = {
285 /* port-D for line out (rear panel) */ 285 /* port-D for line out (rear panel) */
286 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 286 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
287 /* port-E for HP out (front panel) */ 287 /* port-E for HP out (front panel) */
@@ -528,7 +528,7 @@ static int cmi9880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
528 528
529/* 529/*
530 */ 530 */
531static struct hda_pcm_stream cmi9880_pcm_analog_playback = { 531static const struct hda_pcm_stream cmi9880_pcm_analog_playback = {
532 .substreams = 1, 532 .substreams = 1,
533 .channels_min = 2, 533 .channels_min = 2,
534 .channels_max = 8, 534 .channels_max = 8,
@@ -540,7 +540,7 @@ static struct hda_pcm_stream cmi9880_pcm_analog_playback = {
540 }, 540 },
541}; 541};
542 542
543static struct hda_pcm_stream cmi9880_pcm_analog_capture = { 543static const struct hda_pcm_stream cmi9880_pcm_analog_capture = {
544 .substreams = 2, 544 .substreams = 2,
545 .channels_min = 2, 545 .channels_min = 2,
546 .channels_max = 2, 546 .channels_max = 2,
@@ -551,7 +551,7 @@ static struct hda_pcm_stream cmi9880_pcm_analog_capture = {
551 }, 551 },
552}; 552};
553 553
554static struct hda_pcm_stream cmi9880_pcm_digital_playback = { 554static const struct hda_pcm_stream cmi9880_pcm_digital_playback = {
555 .substreams = 1, 555 .substreams = 1,
556 .channels_min = 2, 556 .channels_min = 2,
557 .channels_max = 2, 557 .channels_max = 2,
@@ -563,7 +563,7 @@ static struct hda_pcm_stream cmi9880_pcm_digital_playback = {
563 }, 563 },
564}; 564};
565 565
566static struct hda_pcm_stream cmi9880_pcm_digital_capture = { 566static const struct hda_pcm_stream cmi9880_pcm_digital_capture = {
567 .substreams = 1, 567 .substreams = 1,
568 .channels_min = 2, 568 .channels_min = 2,
569 .channels_max = 2, 569 .channels_max = 2,
@@ -608,7 +608,7 @@ static void cmi9880_free(struct hda_codec *codec)
608/* 608/*
609 */ 609 */
610 610
611static const char *cmi9880_models[CMI_MODELS] = { 611static const char * const cmi9880_models[CMI_MODELS] = {
612 [CMI_MINIMAL] = "minimal", 612 [CMI_MINIMAL] = "minimal",
613 [CMI_MIN_FP] = "min_fp", 613 [CMI_MIN_FP] = "min_fp",
614 [CMI_FULL] = "full", 614 [CMI_FULL] = "full",
@@ -617,14 +617,14 @@ static const char *cmi9880_models[CMI_MODELS] = {
617 [CMI_AUTO] = "auto", 617 [CMI_AUTO] = "auto",
618}; 618};
619 619
620static struct snd_pci_quirk cmi9880_cfg_tbl[] = { 620static const struct snd_pci_quirk cmi9880_cfg_tbl[] = {
621 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG), 621 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG),
622 SND_PCI_QUIRK(0x1854, 0x002b, "LG LS75", CMI_MINIMAL), 622 SND_PCI_QUIRK(0x1854, 0x002b, "LG LS75", CMI_MINIMAL),
623 SND_PCI_QUIRK(0x1854, 0x0032, "LG", CMI_FULL_DIG), 623 SND_PCI_QUIRK(0x1854, 0x0032, "LG", CMI_FULL_DIG),
624 {} /* terminator */ 624 {} /* terminator */
625}; 625};
626 626
627static struct hda_codec_ops cmi9880_patch_ops = { 627static const struct hda_codec_ops cmi9880_patch_ops = {
628 .build_controls = cmi9880_build_controls, 628 .build_controls = cmi9880_build_controls,
629 .build_pcms = cmi9880_build_pcms, 629 .build_pcms = cmi9880_build_pcms,
630 .init = cmi9880_init, 630 .init = cmi9880_init,
@@ -745,7 +745,7 @@ static int patch_cmi9880(struct hda_codec *codec)
745/* 745/*
746 * patch entries 746 * patch entries
747 */ 747 */
748static struct hda_codec_preset snd_hda_preset_cmedia[] = { 748static const struct hda_codec_preset snd_hda_preset_cmedia[] = {
749 { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 }, 749 { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 },
750 { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 }, 750 { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 },
751 {} /* terminator */ 751 {} /* terminator */
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 972e7c453b3d..7bbc5f237a5e 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -39,6 +39,7 @@
39 39
40#define CONEXANT_HP_EVENT 0x37 40#define CONEXANT_HP_EVENT 0x37
41#define CONEXANT_MIC_EVENT 0x38 41#define CONEXANT_MIC_EVENT 0x38
42#define CONEXANT_LINE_EVENT 0x39
42 43
43/* Conexant 5051 specific */ 44/* Conexant 5051 specific */
44 45
@@ -49,17 +50,22 @@
49#define AUTO_MIC_PORTB (1 << 1) 50#define AUTO_MIC_PORTB (1 << 1)
50#define AUTO_MIC_PORTC (1 << 2) 51#define AUTO_MIC_PORTC (1 << 2)
51 52
52struct conexant_jack { 53struct pin_dac_pair {
53 54 hda_nid_t pin;
54 hda_nid_t nid; 55 hda_nid_t dac;
55 int type; 56 int type;
56 struct snd_jack *jack; 57};
57 58
59struct imux_info {
60 hda_nid_t pin; /* input pin NID */
61 hda_nid_t adc; /* connected ADC NID */
62 hda_nid_t boost; /* optional boost volume NID */
63 int index; /* corresponding to autocfg.input */
58}; 64};
59 65
60struct conexant_spec { 66struct conexant_spec {
61 67
62 struct snd_kcontrol_new *mixers[5]; 68 const struct snd_kcontrol_new *mixers[5];
63 int num_mixers; 69 int num_mixers;
64 hda_nid_t vmaster_nid; 70 hda_nid_t vmaster_nid;
65 71
@@ -76,12 +82,17 @@ struct conexant_spec {
76 */ 82 */
77 unsigned int cur_eapd; 83 unsigned int cur_eapd;
78 unsigned int hp_present; 84 unsigned int hp_present;
85 unsigned int line_present;
79 unsigned int auto_mic; 86 unsigned int auto_mic;
87 int auto_mic_ext; /* imux_pins[] index for ext mic */
88 int auto_mic_dock; /* imux_pins[] index for dock mic */
89 int auto_mic_int; /* imux_pins[] index for int mic */
80 unsigned int need_dac_fix; 90 unsigned int need_dac_fix;
91 hda_nid_t slave_dig_outs[2];
81 92
82 /* capture */ 93 /* capture */
83 unsigned int num_adc_nids; 94 unsigned int num_adc_nids;
84 hda_nid_t *adc_nids; 95 const hda_nid_t *adc_nids;
85 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 96 hda_nid_t dig_in_nid; /* digital-in NID; optional */
86 97
87 unsigned int cur_adc_idx; 98 unsigned int cur_adc_idx;
@@ -89,9 +100,11 @@ struct conexant_spec {
89 unsigned int cur_adc_stream_tag; 100 unsigned int cur_adc_stream_tag;
90 unsigned int cur_adc_format; 101 unsigned int cur_adc_format;
91 102
103 const struct hda_pcm_stream *capture_stream;
104
92 /* capture source */ 105 /* capture source */
93 const struct hda_input_mux *input_mux; 106 const struct hda_input_mux *input_mux;
94 hda_nid_t *capsrc_nids; 107 const hda_nid_t *capsrc_nids;
95 unsigned int cur_mux[3]; 108 unsigned int cur_mux[3];
96 109
97 /* channel model */ 110 /* channel model */
@@ -103,20 +116,28 @@ struct conexant_spec {
103 116
104 unsigned int spdif_route; 117 unsigned int spdif_route;
105 118
106 /* jack detection */
107 struct snd_array jacks;
108
109 /* dynamic controls, init_verbs and input_mux */ 119 /* dynamic controls, init_verbs and input_mux */
110 struct auto_pin_cfg autocfg; 120 struct auto_pin_cfg autocfg;
111 struct hda_input_mux private_imux; 121 struct hda_input_mux private_imux;
122 struct imux_info imux_info[HDA_MAX_NUM_INPUTS];
123 hda_nid_t private_adc_nids[HDA_MAX_NUM_INPUTS];
112 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 124 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
125 struct pin_dac_pair dac_info[8];
126 int dac_info_filled;
113 127
114 unsigned int dell_automute;
115 unsigned int port_d_mode; 128 unsigned int port_d_mode;
129 unsigned int auto_mute:1; /* used in auto-parser */
130 unsigned int detect_line:1; /* Line-out detection enabled */
131 unsigned int automute_lines:1; /* automute line-out as well */
132 unsigned int automute_hp_lo:1; /* both HP and LO available */
133 unsigned int dell_automute:1;
116 unsigned int dell_vostro:1; 134 unsigned int dell_vostro:1;
117 unsigned int ideapad:1; 135 unsigned int ideapad:1;
118 unsigned int thinkpad:1; 136 unsigned int thinkpad:1;
119 unsigned int hp_laptop:1; 137 unsigned int hp_laptop:1;
138 unsigned int asus:1;
139
140 unsigned int adc_switching:1;
120 141
121 unsigned int ext_mic_present; 142 unsigned int ext_mic_present;
122 unsigned int recording; 143 unsigned int recording;
@@ -226,7 +247,7 @@ static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
226 247
227 248
228 249
229static struct hda_pcm_stream conexant_pcm_analog_playback = { 250static const struct hda_pcm_stream conexant_pcm_analog_playback = {
230 .substreams = 1, 251 .substreams = 1,
231 .channels_min = 2, 252 .channels_min = 2,
232 .channels_max = 2, 253 .channels_max = 2,
@@ -238,7 +259,7 @@ static struct hda_pcm_stream conexant_pcm_analog_playback = {
238 }, 259 },
239}; 260};
240 261
241static struct hda_pcm_stream conexant_pcm_analog_capture = { 262static const struct hda_pcm_stream conexant_pcm_analog_capture = {
242 .substreams = 1, 263 .substreams = 1,
243 .channels_min = 2, 264 .channels_min = 2,
244 .channels_max = 2, 265 .channels_max = 2,
@@ -250,7 +271,7 @@ static struct hda_pcm_stream conexant_pcm_analog_capture = {
250}; 271};
251 272
252 273
253static struct hda_pcm_stream conexant_pcm_digital_playback = { 274static const struct hda_pcm_stream conexant_pcm_digital_playback = {
254 .substreams = 1, 275 .substreams = 1,
255 .channels_min = 2, 276 .channels_min = 2,
256 .channels_max = 2, 277 .channels_max = 2,
@@ -262,7 +283,7 @@ static struct hda_pcm_stream conexant_pcm_digital_playback = {
262 }, 283 },
263}; 284};
264 285
265static struct hda_pcm_stream conexant_pcm_digital_capture = { 286static const struct hda_pcm_stream conexant_pcm_digital_capture = {
266 .substreams = 1, 287 .substreams = 1,
267 .channels_min = 2, 288 .channels_min = 2,
268 .channels_max = 2, 289 .channels_max = 2,
@@ -293,7 +314,7 @@ static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
293 return 0; 314 return 0;
294} 315}
295 316
296static struct hda_pcm_stream cx5051_pcm_analog_capture = { 317static const struct hda_pcm_stream cx5051_pcm_analog_capture = {
297 .substreams = 1, 318 .substreams = 1,
298 .channels_min = 2, 319 .channels_min = 2,
299 .channels_max = 2, 320 .channels_max = 2,
@@ -318,13 +339,19 @@ static int conexant_build_pcms(struct hda_codec *codec)
318 spec->multiout.max_channels; 339 spec->multiout.max_channels;
319 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 340 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
320 spec->multiout.dac_nids[0]; 341 spec->multiout.dac_nids[0];
321 if (codec->vendor_id == 0x14f15051) 342 if (spec->capture_stream)
322 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 343 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream;
323 cx5051_pcm_analog_capture; 344 else {
324 else 345 if (codec->vendor_id == 0x14f15051)
325 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 346 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
326 conexant_pcm_analog_capture; 347 cx5051_pcm_analog_capture;
327 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids; 348 else {
349 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
350 conexant_pcm_analog_capture;
351 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
352 spec->num_adc_nids;
353 }
354 }
328 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 355 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
329 356
330 if (spec->multiout.dig_out_nid) { 357 if (spec->multiout.dig_out_nid) {
@@ -342,6 +369,8 @@ static int conexant_build_pcms(struct hda_codec *codec)
342 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 369 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
343 spec->dig_in_nid; 370 spec->dig_in_nid;
344 } 371 }
372 if (spec->slave_dig_outs[0])
373 codec->slave_dig_outs = spec->slave_dig_outs;
345 } 374 }
346 375
347 return 0; 376 return 0;
@@ -379,65 +408,9 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
379 &spec->cur_mux[adc_idx]); 408 &spec->cur_mux[adc_idx]);
380} 409}
381 410
382#ifdef CONFIG_SND_HDA_INPUT_JACK
383static void conexant_free_jack_priv(struct snd_jack *jack)
384{
385 struct conexant_jack *jacks = jack->private_data;
386 jacks->nid = 0;
387 jacks->jack = NULL;
388}
389
390static int conexant_add_jack(struct hda_codec *codec,
391 hda_nid_t nid, int type)
392{
393 struct conexant_spec *spec;
394 struct conexant_jack *jack;
395 const char *name;
396 int err;
397
398 spec = codec->spec;
399 snd_array_init(&spec->jacks, sizeof(*jack), 32);
400 jack = snd_array_new(&spec->jacks);
401 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
402
403 if (!jack)
404 return -ENOMEM;
405
406 jack->nid = nid;
407 jack->type = type;
408
409 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
410 if (err < 0)
411 return err;
412 jack->jack->private_data = jack;
413 jack->jack->private_free = conexant_free_jack_priv;
414 return 0;
415}
416
417static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
418{
419 struct conexant_spec *spec = codec->spec;
420 struct conexant_jack *jacks = spec->jacks.list;
421
422 if (jacks) {
423 int i;
424 for (i = 0; i < spec->jacks.used; i++) {
425 if (jacks->nid == nid) {
426 unsigned int present;
427 present = snd_hda_jack_detect(codec, nid);
428
429 present = (present) ? jacks->type : 0 ;
430
431 snd_jack_report(jacks->jack,
432 present);
433 }
434 jacks++;
435 }
436 }
437}
438
439static int conexant_init_jacks(struct hda_codec *codec) 411static int conexant_init_jacks(struct hda_codec *codec)
440{ 412{
413#ifdef CONFIG_SND_HDA_INPUT_JACK
441 struct conexant_spec *spec = codec->spec; 414 struct conexant_spec *spec = codec->spec;
442 int i; 415 int i;
443 416
@@ -449,15 +422,15 @@ static int conexant_init_jacks(struct hda_codec *codec)
449 int err = 0; 422 int err = 0;
450 switch (hv->param ^ AC_USRSP_EN) { 423 switch (hv->param ^ AC_USRSP_EN) {
451 case CONEXANT_HP_EVENT: 424 case CONEXANT_HP_EVENT:
452 err = conexant_add_jack(codec, hv->nid, 425 err = snd_hda_input_jack_add(codec, hv->nid,
453 SND_JACK_HEADPHONE); 426 SND_JACK_HEADPHONE, NULL);
454 conexant_report_jack(codec, hv->nid); 427 snd_hda_input_jack_report(codec, hv->nid);
455 break; 428 break;
456 case CXT5051_PORTC_EVENT: 429 case CXT5051_PORTC_EVENT:
457 case CONEXANT_MIC_EVENT: 430 case CONEXANT_MIC_EVENT:
458 err = conexant_add_jack(codec, hv->nid, 431 err = snd_hda_input_jack_add(codec, hv->nid,
459 SND_JACK_MICROPHONE); 432 SND_JACK_MICROPHONE, NULL);
460 conexant_report_jack(codec, hv->nid); 433 snd_hda_input_jack_report(codec, hv->nid);
461 break; 434 break;
462 } 435 }
463 if (err < 0) 436 if (err < 0)
@@ -465,19 +438,9 @@ static int conexant_init_jacks(struct hda_codec *codec)
465 ++hv; 438 ++hv;
466 } 439 }
467 } 440 }
468 return 0; 441#endif /* CONFIG_SND_HDA_INPUT_JACK */
469
470}
471#else
472static inline void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
473{
474}
475
476static inline int conexant_init_jacks(struct hda_codec *codec)
477{
478 return 0; 442 return 0;
479} 443}
480#endif
481 444
482static int conexant_init(struct hda_codec *codec) 445static int conexant_init(struct hda_codec *codec)
483{ 446{
@@ -491,23 +454,12 @@ static int conexant_init(struct hda_codec *codec)
491 454
492static void conexant_free(struct hda_codec *codec) 455static void conexant_free(struct hda_codec *codec)
493{ 456{
494#ifdef CONFIG_SND_HDA_INPUT_JACK 457 snd_hda_input_jack_free(codec);
495 struct conexant_spec *spec = codec->spec;
496 if (spec->jacks.list) {
497 struct conexant_jack *jacks = spec->jacks.list;
498 int i;
499 for (i = 0; i < spec->jacks.used; i++, jacks++) {
500 if (jacks->jack)
501 snd_device_free(codec->bus->card, jacks->jack);
502 }
503 snd_array_free(&spec->jacks);
504 }
505#endif
506 snd_hda_detach_beep_device(codec); 458 snd_hda_detach_beep_device(codec);
507 kfree(codec->spec); 459 kfree(codec->spec);
508} 460}
509 461
510static struct snd_kcontrol_new cxt_capture_mixers[] = { 462static const struct snd_kcontrol_new cxt_capture_mixers[] = {
511 { 463 {
512 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 464 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
513 .name = "Capture Source", 465 .name = "Capture Source",
@@ -520,22 +472,28 @@ static struct snd_kcontrol_new cxt_capture_mixers[] = {
520 472
521#ifdef CONFIG_SND_HDA_INPUT_BEEP 473#ifdef CONFIG_SND_HDA_INPUT_BEEP
522/* additional beep mixers; the actual parameters are overwritten at build */ 474/* additional beep mixers; the actual parameters are overwritten at build */
523static struct snd_kcontrol_new cxt_beep_mixer[] = { 475static const struct snd_kcontrol_new cxt_beep_mixer[] = {
524 HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), 476 HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT),
525 HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), 477 HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT),
526 { } /* end */ 478 { } /* end */
527}; 479};
528#endif 480#endif
529 481
530static const char *slave_vols[] = { 482static const char * const slave_vols[] = {
531 "Headphone Playback Volume", 483 "Headphone Playback Volume",
532 "Speaker Playback Volume", 484 "Speaker Playback Volume",
485 "Front Playback Volume",
486 "Surround Playback Volume",
487 "CLFE Playback Volume",
533 NULL 488 NULL
534}; 489};
535 490
536static const char *slave_sws[] = { 491static const char * const slave_sws[] = {
537 "Headphone Playback Switch", 492 "Headphone Playback Switch",
538 "Speaker Playback Switch", 493 "Speaker Playback Switch",
494 "Front Playback Switch",
495 "Surround Playback Switch",
496 "CLFE Playback Switch",
539 NULL 497 NULL
540}; 498};
541 499
@@ -595,7 +553,7 @@ static int conexant_build_controls(struct hda_codec *codec)
595#ifdef CONFIG_SND_HDA_INPUT_BEEP 553#ifdef CONFIG_SND_HDA_INPUT_BEEP
596 /* create beep controls if needed */ 554 /* create beep controls if needed */
597 if (spec->beep_amp) { 555 if (spec->beep_amp) {
598 struct snd_kcontrol_new *knew; 556 const struct snd_kcontrol_new *knew;
599 for (knew = cxt_beep_mixer; knew->name; knew++) { 557 for (knew = cxt_beep_mixer; knew->name; knew++) {
600 struct snd_kcontrol *kctl; 558 struct snd_kcontrol *kctl;
601 kctl = snd_ctl_new1(knew, codec); 559 kctl = snd_ctl_new1(knew, codec);
@@ -620,7 +578,7 @@ static int conexant_suspend(struct hda_codec *codec, pm_message_t state)
620} 578}
621#endif 579#endif
622 580
623static struct hda_codec_ops conexant_patch_ops = { 581static const struct hda_codec_ops conexant_patch_ops = {
624 .build_controls = conexant_build_controls, 582 .build_controls = conexant_build_controls,
625 .build_pcms = conexant_build_pcms, 583 .build_pcms = conexant_build_pcms,
626 .init = conexant_init, 584 .init = conexant_init,
@@ -638,6 +596,7 @@ static struct hda_codec_ops conexant_patch_ops = {
638#define set_beep_amp(spec, nid, idx, dir) /* NOP */ 596#define set_beep_amp(spec, nid, idx, dir) /* NOP */
639#endif 597#endif
640 598
599static int patch_conexant_auto(struct hda_codec *codec);
641/* 600/*
642 * EAPD control 601 * EAPD control
643 * the private value = nid | (invert << 8) 602 * the private value = nid | (invert << 8)
@@ -736,16 +695,16 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
736 695
737/* Conexant 5045 specific */ 696/* Conexant 5045 specific */
738 697
739static hda_nid_t cxt5045_dac_nids[1] = { 0x19 }; 698static const hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
740static hda_nid_t cxt5045_adc_nids[1] = { 0x1a }; 699static const hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
741static hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a }; 700static const hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
742#define CXT5045_SPDIF_OUT 0x18 701#define CXT5045_SPDIF_OUT 0x18
743 702
744static struct hda_channel_mode cxt5045_modes[1] = { 703static const struct hda_channel_mode cxt5045_modes[1] = {
745 { 2, NULL }, 704 { 2, NULL },
746}; 705};
747 706
748static struct hda_input_mux cxt5045_capture_source = { 707static const struct hda_input_mux cxt5045_capture_source = {
749 .num_items = 2, 708 .num_items = 2,
750 .items = { 709 .items = {
751 { "IntMic", 0x1 }, 710 { "IntMic", 0x1 },
@@ -753,7 +712,7 @@ static struct hda_input_mux cxt5045_capture_source = {
753 } 712 }
754}; 713};
755 714
756static struct hda_input_mux cxt5045_capture_source_benq = { 715static const struct hda_input_mux cxt5045_capture_source_benq = {
757 .num_items = 5, 716 .num_items = 5,
758 .items = { 717 .items = {
759 { "IntMic", 0x1 }, 718 { "IntMic", 0x1 },
@@ -764,7 +723,7 @@ static struct hda_input_mux cxt5045_capture_source_benq = {
764 } 723 }
765}; 724};
766 725
767static struct hda_input_mux cxt5045_capture_source_hp530 = { 726static const struct hda_input_mux cxt5045_capture_source_hp530 = {
768 .num_items = 2, 727 .num_items = 2,
769 .items = { 728 .items = {
770 { "ExtMic", 0x1 }, 729 { "ExtMic", 0x1 },
@@ -797,7 +756,7 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
797} 756}
798 757
799/* bind volumes of both NID 0x10 and 0x11 */ 758/* bind volumes of both NID 0x10 and 0x11 */
800static struct hda_bind_ctls cxt5045_hp_bind_master_vol = { 759static const struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
801 .ops = &snd_hda_bind_vol, 760 .ops = &snd_hda_bind_vol,
802 .values = { 761 .values = {
803 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT), 762 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
@@ -809,12 +768,12 @@ static struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
809/* toggle input of built-in and mic jack appropriately */ 768/* toggle input of built-in and mic jack appropriately */
810static void cxt5045_hp_automic(struct hda_codec *codec) 769static void cxt5045_hp_automic(struct hda_codec *codec)
811{ 770{
812 static struct hda_verb mic_jack_on[] = { 771 static const struct hda_verb mic_jack_on[] = {
813 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 772 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
814 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 773 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
815 {} 774 {}
816 }; 775 };
817 static struct hda_verb mic_jack_off[] = { 776 static const struct hda_verb mic_jack_off[] = {
818 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 777 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
819 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 778 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
820 {} 779 {}
@@ -858,17 +817,17 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec,
858 } 817 }
859} 818}
860 819
861static struct snd_kcontrol_new cxt5045_mixers[] = { 820static const struct snd_kcontrol_new cxt5045_mixers[] = {
862 HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), 821 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
863 HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), 822 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
864 HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), 823 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
865 HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), 824 HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
866 HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), 825 HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
867 HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), 826 HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
868 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x1, HDA_INPUT), 827 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
869 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x1, HDA_INPUT), 828 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
870 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x2, HDA_INPUT), 829 HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
871 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x2, HDA_INPUT), 830 HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
872 HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), 831 HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
873 { 832 {
874 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -882,7 +841,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
882 {} 841 {}
883}; 842};
884 843
885static struct snd_kcontrol_new cxt5045_benq_mixers[] = { 844static const struct snd_kcontrol_new cxt5045_benq_mixers[] = {
886 HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT), 845 HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
887 HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT), 846 HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
888 HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT), 847 HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
@@ -899,17 +858,17 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
899 {} 858 {}
900}; 859};
901 860
902static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { 861static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
903 HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), 862 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
904 HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), 863 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
905 HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), 864 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
906 HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), 865 HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
907 HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), 866 HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
908 HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), 867 HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
909 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x2, HDA_INPUT), 868 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
910 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x2, HDA_INPUT), 869 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
911 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x1, HDA_INPUT), 870 HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
912 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x1, HDA_INPUT), 871 HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
913 HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), 872 HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
914 { 873 {
915 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 874 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -923,7 +882,7 @@ static struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
923 {} 882 {}
924}; 883};
925 884
926static struct hda_verb cxt5045_init_verbs[] = { 885static const struct hda_verb cxt5045_init_verbs[] = {
927 /* Line in, Mic */ 886 /* Line in, Mic */
928 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 887 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
929 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 888 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
@@ -937,7 +896,7 @@ static struct hda_verb cxt5045_init_verbs[] = {
937 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 896 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
938 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 897 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
939 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 898 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
940 /* Record selector: Int mic */ 899 /* Record selector: Internal mic */
941 {0x1a, AC_VERB_SET_CONNECT_SEL,0x1}, 900 {0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
942 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 901 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
943 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, 902 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
@@ -949,8 +908,8 @@ static struct hda_verb cxt5045_init_verbs[] = {
949 { } /* end */ 908 { } /* end */
950}; 909};
951 910
952static struct hda_verb cxt5045_benq_init_verbs[] = { 911static const struct hda_verb cxt5045_benq_init_verbs[] = {
953 /* Int Mic, Mic */ 912 /* Internal Mic, Mic */
954 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 913 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
955 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 914 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
956 /* Line In,HP, Amp */ 915 /* Line In,HP, Amp */
@@ -963,7 +922,7 @@ static struct hda_verb cxt5045_benq_init_verbs[] = {
963 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 922 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
964 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 923 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
965 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 924 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
966 /* Record selector: Int mic */ 925 /* Record selector: Internal mic */
967 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1}, 926 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1},
968 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 927 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
969 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, 928 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
@@ -975,13 +934,13 @@ static struct hda_verb cxt5045_benq_init_verbs[] = {
975 { } /* end */ 934 { } /* end */
976}; 935};
977 936
978static struct hda_verb cxt5045_hp_sense_init_verbs[] = { 937static const struct hda_verb cxt5045_hp_sense_init_verbs[] = {
979 /* pin sensing on HP jack */ 938 /* pin sensing on HP jack */
980 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, 939 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
981 { } /* end */ 940 { } /* end */
982}; 941};
983 942
984static struct hda_verb cxt5045_mic_sense_init_verbs[] = { 943static const struct hda_verb cxt5045_mic_sense_init_verbs[] = {
985 /* pin sensing on HP jack */ 944 /* pin sensing on HP jack */
986 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, 945 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
987 { } /* end */ 946 { } /* end */
@@ -991,7 +950,7 @@ static struct hda_verb cxt5045_mic_sense_init_verbs[] = {
991/* Test configuration for debugging, modelled after the ALC260 test 950/* Test configuration for debugging, modelled after the ALC260 test
992 * configuration. 951 * configuration.
993 */ 952 */
994static struct hda_input_mux cxt5045_test_capture_source = { 953static const struct hda_input_mux cxt5045_test_capture_source = {
995 .num_items = 5, 954 .num_items = 5,
996 .items = { 955 .items = {
997 { "MIXER", 0x0 }, 956 { "MIXER", 0x0 },
@@ -1002,7 +961,7 @@ static struct hda_input_mux cxt5045_test_capture_source = {
1002 }, 961 },
1003}; 962};
1004 963
1005static struct snd_kcontrol_new cxt5045_test_mixer[] = { 964static const struct snd_kcontrol_new cxt5045_test_mixer[] = {
1006 965
1007 /* Output controls */ 966 /* Output controls */
1008 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), 967 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
@@ -1052,7 +1011,7 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
1052 { } /* end */ 1011 { } /* end */
1053}; 1012};
1054 1013
1055static struct hda_verb cxt5045_test_init_verbs[] = { 1014static const struct hda_verb cxt5045_test_init_verbs[] = {
1056 /* Set connections */ 1015 /* Set connections */
1057 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1016 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
1058 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1017 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
@@ -1121,10 +1080,11 @@ enum {
1121#ifdef CONFIG_SND_DEBUG 1080#ifdef CONFIG_SND_DEBUG
1122 CXT5045_TEST, 1081 CXT5045_TEST,
1123#endif 1082#endif
1083 CXT5045_AUTO,
1124 CXT5045_MODELS 1084 CXT5045_MODELS
1125}; 1085};
1126 1086
1127static const char *cxt5045_models[CXT5045_MODELS] = { 1087static const char * const cxt5045_models[CXT5045_MODELS] = {
1128 [CXT5045_LAPTOP_HPSENSE] = "laptop-hpsense", 1088 [CXT5045_LAPTOP_HPSENSE] = "laptop-hpsense",
1129 [CXT5045_LAPTOP_MICSENSE] = "laptop-micsense", 1089 [CXT5045_LAPTOP_MICSENSE] = "laptop-micsense",
1130 [CXT5045_LAPTOP_HPMICSENSE] = "laptop-hpmicsense", 1090 [CXT5045_LAPTOP_HPMICSENSE] = "laptop-hpmicsense",
@@ -1133,9 +1093,10 @@ static const char *cxt5045_models[CXT5045_MODELS] = {
1133#ifdef CONFIG_SND_DEBUG 1093#ifdef CONFIG_SND_DEBUG
1134 [CXT5045_TEST] = "test", 1094 [CXT5045_TEST] = "test",
1135#endif 1095#endif
1096 [CXT5045_AUTO] = "auto",
1136}; 1097};
1137 1098
1138static struct snd_pci_quirk cxt5045_cfg_tbl[] = { 1099static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
1139 SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530), 1100 SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
1140 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", 1101 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1141 CXT5045_LAPTOP_HPSENSE), 1102 CXT5045_LAPTOP_HPSENSE),
@@ -1159,6 +1120,16 @@ static int patch_cxt5045(struct hda_codec *codec)
1159 struct conexant_spec *spec; 1120 struct conexant_spec *spec;
1160 int board_config; 1121 int board_config;
1161 1122
1123 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1124 cxt5045_models,
1125 cxt5045_cfg_tbl);
1126#if 0 /* use the old method just for safety */
1127 if (board_config < 0)
1128 board_config = CXT5045_AUTO;
1129#endif
1130 if (board_config == CXT5045_AUTO)
1131 return patch_conexant_auto(codec);
1132
1162 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1133 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1163 if (!spec) 1134 if (!spec)
1164 return -ENOMEM; 1135 return -ENOMEM;
@@ -1185,9 +1156,6 @@ static int patch_cxt5045(struct hda_codec *codec)
1185 1156
1186 codec->patch_ops = conexant_patch_ops; 1157 codec->patch_ops = conexant_patch_ops;
1187 1158
1188 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1189 cxt5045_models,
1190 cxt5045_cfg_tbl);
1191 switch (board_config) { 1159 switch (board_config) {
1192 case CXT5045_LAPTOP_HPSENSE: 1160 case CXT5045_LAPTOP_HPSENSE:
1193 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; 1161 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
@@ -1270,15 +1238,15 @@ static int patch_cxt5045(struct hda_codec *codec)
1270/* Conexant 5047 specific */ 1238/* Conexant 5047 specific */
1271#define CXT5047_SPDIF_OUT 0x11 1239#define CXT5047_SPDIF_OUT 0x11
1272 1240
1273static hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */ 1241static const hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */
1274static hda_nid_t cxt5047_adc_nids[1] = { 0x12 }; 1242static const hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
1275static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a }; 1243static const hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
1276 1244
1277static struct hda_channel_mode cxt5047_modes[1] = { 1245static const struct hda_channel_mode cxt5047_modes[1] = {
1278 { 2, NULL }, 1246 { 2, NULL },
1279}; 1247};
1280 1248
1281static struct hda_input_mux cxt5047_toshiba_capture_source = { 1249static const struct hda_input_mux cxt5047_toshiba_capture_source = {
1282 .num_items = 2, 1250 .num_items = 2,
1283 .items = { 1251 .items = {
1284 { "ExtMic", 0x2 }, 1252 { "ExtMic", 0x2 },
@@ -1330,12 +1298,12 @@ static void cxt5047_hp_automute(struct hda_codec *codec)
1330/* toggle input of built-in and mic jack appropriately */ 1298/* toggle input of built-in and mic jack appropriately */
1331static void cxt5047_hp_automic(struct hda_codec *codec) 1299static void cxt5047_hp_automic(struct hda_codec *codec)
1332{ 1300{
1333 static struct hda_verb mic_jack_on[] = { 1301 static const struct hda_verb mic_jack_on[] = {
1334 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1302 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1335 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1303 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1336 {} 1304 {}
1337 }; 1305 };
1338 static struct hda_verb mic_jack_off[] = { 1306 static const struct hda_verb mic_jack_off[] = {
1339 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1307 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1340 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1308 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1341 {} 1309 {}
@@ -1363,10 +1331,10 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec,
1363 } 1331 }
1364} 1332}
1365 1333
1366static struct snd_kcontrol_new cxt5047_base_mixers[] = { 1334static const struct snd_kcontrol_new cxt5047_base_mixers[] = {
1367 HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT), 1335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT),
1368 HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT), 1336 HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT),
1369 HDA_CODEC_VOLUME("Mic Boost", 0x1a, 0x0, HDA_OUTPUT), 1337 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1370 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT), 1338 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1371 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), 1339 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1372 HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), 1340 HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
@@ -1383,19 +1351,19 @@ static struct snd_kcontrol_new cxt5047_base_mixers[] = {
1383 {} 1351 {}
1384}; 1352};
1385 1353
1386static struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = { 1354static const struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = {
1387 /* See the note in cxt5047_hp_master_sw_put */ 1355 /* See the note in cxt5047_hp_master_sw_put */
1388 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT), 1356 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT),
1389 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT), 1357 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1390 {} 1358 {}
1391}; 1359};
1392 1360
1393static struct snd_kcontrol_new cxt5047_hp_only_mixers[] = { 1361static const struct snd_kcontrol_new cxt5047_hp_only_mixers[] = {
1394 HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT), 1362 HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1395 { } /* end */ 1363 { } /* end */
1396}; 1364};
1397 1365
1398static struct hda_verb cxt5047_init_verbs[] = { 1366static const struct hda_verb cxt5047_init_verbs[] = {
1399 /* Line in, Mic, Built-in Mic */ 1367 /* Line in, Mic, Built-in Mic */
1400 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1368 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1401 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, 1369 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
@@ -1422,7 +1390,7 @@ static struct hda_verb cxt5047_init_verbs[] = {
1422}; 1390};
1423 1391
1424/* configuration for Toshiba Laptops */ 1392/* configuration for Toshiba Laptops */
1425static struct hda_verb cxt5047_toshiba_init_verbs[] = { 1393static const struct hda_verb cxt5047_toshiba_init_verbs[] = {
1426 {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */ 1394 {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */
1427 {} 1395 {}
1428}; 1396};
@@ -1431,7 +1399,7 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = {
1431 * configuration. 1399 * configuration.
1432 */ 1400 */
1433#ifdef CONFIG_SND_DEBUG 1401#ifdef CONFIG_SND_DEBUG
1434static struct hda_input_mux cxt5047_test_capture_source = { 1402static const struct hda_input_mux cxt5047_test_capture_source = {
1435 .num_items = 4, 1403 .num_items = 4,
1436 .items = { 1404 .items = {
1437 { "LINE1 pin", 0x0 }, 1405 { "LINE1 pin", 0x0 },
@@ -1441,7 +1409,7 @@ static struct hda_input_mux cxt5047_test_capture_source = {
1441 }, 1409 },
1442}; 1410};
1443 1411
1444static struct snd_kcontrol_new cxt5047_test_mixer[] = { 1412static const struct snd_kcontrol_new cxt5047_test_mixer[] = {
1445 1413
1446 /* Output only controls */ 1414 /* Output only controls */
1447 HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT), 1415 HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT),
@@ -1494,7 +1462,7 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = {
1494 { } /* end */ 1462 { } /* end */
1495}; 1463};
1496 1464
1497static struct hda_verb cxt5047_test_init_verbs[] = { 1465static const struct hda_verb cxt5047_test_init_verbs[] = {
1498 /* Enable retasking pins as output, initially without power amp */ 1466 /* Enable retasking pins as output, initially without power amp */
1499 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1467 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1500 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1468 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -1566,19 +1534,21 @@ enum {
1566#ifdef CONFIG_SND_DEBUG 1534#ifdef CONFIG_SND_DEBUG
1567 CXT5047_TEST, 1535 CXT5047_TEST,
1568#endif 1536#endif
1537 CXT5047_AUTO,
1569 CXT5047_MODELS 1538 CXT5047_MODELS
1570}; 1539};
1571 1540
1572static const char *cxt5047_models[CXT5047_MODELS] = { 1541static const char * const cxt5047_models[CXT5047_MODELS] = {
1573 [CXT5047_LAPTOP] = "laptop", 1542 [CXT5047_LAPTOP] = "laptop",
1574 [CXT5047_LAPTOP_HP] = "laptop-hp", 1543 [CXT5047_LAPTOP_HP] = "laptop-hp",
1575 [CXT5047_LAPTOP_EAPD] = "laptop-eapd", 1544 [CXT5047_LAPTOP_EAPD] = "laptop-eapd",
1576#ifdef CONFIG_SND_DEBUG 1545#ifdef CONFIG_SND_DEBUG
1577 [CXT5047_TEST] = "test", 1546 [CXT5047_TEST] = "test",
1578#endif 1547#endif
1548 [CXT5047_AUTO] = "auto",
1579}; 1549};
1580 1550
1581static struct snd_pci_quirk cxt5047_cfg_tbl[] = { 1551static const struct snd_pci_quirk cxt5047_cfg_tbl[] = {
1582 SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP), 1552 SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
1583 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", 1553 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1584 CXT5047_LAPTOP), 1554 CXT5047_LAPTOP),
@@ -1591,6 +1561,16 @@ static int patch_cxt5047(struct hda_codec *codec)
1591 struct conexant_spec *spec; 1561 struct conexant_spec *spec;
1592 int board_config; 1562 int board_config;
1593 1563
1564 board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1565 cxt5047_models,
1566 cxt5047_cfg_tbl);
1567#if 0 /* not enabled as default, as BIOS often broken for this codec */
1568 if (board_config < 0)
1569 board_config = CXT5047_AUTO;
1570#endif
1571 if (board_config == CXT5047_AUTO)
1572 return patch_conexant_auto(codec);
1573
1594 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1574 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1595 if (!spec) 1575 if (!spec)
1596 return -ENOMEM; 1576 return -ENOMEM;
@@ -1614,9 +1594,6 @@ static int patch_cxt5047(struct hda_codec *codec)
1614 1594
1615 codec->patch_ops = conexant_patch_ops; 1595 codec->patch_ops = conexant_patch_ops;
1616 1596
1617 board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1618 cxt5047_models,
1619 cxt5047_cfg_tbl);
1620 switch (board_config) { 1597 switch (board_config) {
1621 case CXT5047_LAPTOP: 1598 case CXT5047_LAPTOP:
1622 spec->num_mixers = 2; 1599 spec->num_mixers = 2;
@@ -1665,10 +1642,10 @@ static int patch_cxt5047(struct hda_codec *codec)
1665} 1642}
1666 1643
1667/* Conexant 5051 specific */ 1644/* Conexant 5051 specific */
1668static hda_nid_t cxt5051_dac_nids[1] = { 0x10 }; 1645static const hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
1669static hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 }; 1646static const hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
1670 1647
1671static struct hda_channel_mode cxt5051_modes[1] = { 1648static const struct hda_channel_mode cxt5051_modes[1] = {
1672 { 2, NULL }, 1649 { 2, NULL },
1673}; 1650};
1674 1651
@@ -1767,10 +1744,10 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1767 cxt5051_portc_automic(codec); 1744 cxt5051_portc_automic(codec);
1768 break; 1745 break;
1769 } 1746 }
1770 conexant_report_jack(codec, nid); 1747 snd_hda_input_jack_report(codec, nid);
1771} 1748}
1772 1749
1773static struct snd_kcontrol_new cxt5051_playback_mixers[] = { 1750static const struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1774 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 1751 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1775 { 1752 {
1776 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1753 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1783,45 +1760,45 @@ static struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1783 {} 1760 {}
1784}; 1761};
1785 1762
1786static struct snd_kcontrol_new cxt5051_capture_mixers[] = { 1763static const struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1787 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1764 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1788 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1765 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1789 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT), 1766 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1790 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT), 1767 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1791 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT), 1768 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1792 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT), 1769 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1793 {} 1770 {}
1794}; 1771};
1795 1772
1796static struct snd_kcontrol_new cxt5051_hp_mixers[] = { 1773static const struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1797 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1774 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1798 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1775 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1799 HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT), 1776 HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT),
1800 HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT), 1777 HDA_CODEC_MUTE("Mic Switch", 0x15, 0x00, HDA_INPUT),
1801 {} 1778 {}
1802}; 1779};
1803 1780
1804static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { 1781static const struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1805 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT), 1782 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT),
1806 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT), 1783 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT),
1807 {} 1784 {}
1808}; 1785};
1809 1786
1810static struct snd_kcontrol_new cxt5051_f700_mixers[] = { 1787static const struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1811 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT), 1788 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT),
1812 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT), 1789 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT),
1813 {} 1790 {}
1814}; 1791};
1815 1792
1816static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { 1793static const struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1817 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1794 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1818 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1795 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1819 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT), 1796 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1820 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT), 1797 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1821 {} 1798 {}
1822}; 1799};
1823 1800
1824static struct hda_verb cxt5051_init_verbs[] = { 1801static const struct hda_verb cxt5051_init_verbs[] = {
1825 /* Line in, Mic */ 1802 /* Line in, Mic */
1826 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1803 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1827 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1804 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -1837,7 +1814,7 @@ static struct hda_verb cxt5051_init_verbs[] = {
1837 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 1814 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1838 /* DAC1 */ 1815 /* DAC1 */
1839 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1816 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1840 /* Record selector: Int mic */ 1817 /* Record selector: Internal mic */
1841 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1818 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1842 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1819 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1843 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1820 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
@@ -1850,7 +1827,7 @@ static struct hda_verb cxt5051_init_verbs[] = {
1850 { } /* end */ 1827 { } /* end */
1851}; 1828};
1852 1829
1853static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = { 1830static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1854 /* Line in, Mic */ 1831 /* Line in, Mic */
1855 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1832 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1856 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1833 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -1864,7 +1841,7 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1864 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 1841 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1865 /* DAC1 */ 1842 /* DAC1 */
1866 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1843 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1867 /* Record selector: Int mic */ 1844 /* Record selector: Internal mic */
1868 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1845 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1869 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1}, 1846 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1870 /* SPDIF route: PCM */ 1847 /* SPDIF route: PCM */
@@ -1875,7 +1852,7 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1875 { } /* end */ 1852 { } /* end */
1876}; 1853};
1877 1854
1878static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { 1855static const struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1879 /* Line in, Mic */ 1856 /* Line in, Mic */
1880 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1857 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1881 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1858 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -1894,7 +1871,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1894 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, 1871 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00},
1895 /* DAC1 */ 1872 /* DAC1 */
1896 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1873 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1897 /* Record selector: Int mic */ 1874 /* Record selector: Internal mic */
1898 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1875 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1899 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1876 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1900 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1877 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
@@ -1908,7 +1885,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1908 { } /* end */ 1885 { } /* end */
1909}; 1886};
1910 1887
1911static struct hda_verb cxt5051_f700_init_verbs[] = { 1888static const struct hda_verb cxt5051_f700_init_verbs[] = {
1912 /* Line in, Mic */ 1889 /* Line in, Mic */
1913 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1890 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1914 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1891 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -1922,7 +1899,7 @@ static struct hda_verb cxt5051_f700_init_verbs[] = {
1922 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 1899 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1923 /* DAC1 */ 1900 /* DAC1 */
1924 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1901 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1925 /* Record selector: Int mic */ 1902 /* Record selector: Internal mic */
1926 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1903 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1927 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1}, 1904 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1928 /* SPDIF route: PCM */ 1905 /* SPDIF route: PCM */
@@ -1939,13 +1916,11 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1939 snd_hda_codec_write(codec, nid, 0, 1916 snd_hda_codec_write(codec, nid, 0,
1940 AC_VERB_SET_UNSOLICITED_ENABLE, 1917 AC_VERB_SET_UNSOLICITED_ENABLE,
1941 AC_USRSP_EN | event); 1918 AC_USRSP_EN | event);
1942#ifdef CONFIG_SND_HDA_INPUT_JACK 1919 snd_hda_input_jack_add(codec, nid, SND_JACK_MICROPHONE, NULL);
1943 conexant_add_jack(codec, nid, SND_JACK_MICROPHONE); 1920 snd_hda_input_jack_report(codec, nid);
1944 conexant_report_jack(codec, nid);
1945#endif
1946} 1921}
1947 1922
1948static struct hda_verb cxt5051_ideapad_init_verbs[] = { 1923static const struct hda_verb cxt5051_ideapad_init_verbs[] = {
1949 /* Subwoofer */ 1924 /* Subwoofer */
1950 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1925 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1951 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1926 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -1982,10 +1957,11 @@ enum {
1982 CXT5051_F700, /* HP Compaq Presario F700 */ 1957 CXT5051_F700, /* HP Compaq Presario F700 */
1983 CXT5051_TOSHIBA, /* Toshiba M300 & co */ 1958 CXT5051_TOSHIBA, /* Toshiba M300 & co */
1984 CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */ 1959 CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */
1960 CXT5051_AUTO, /* auto-parser */
1985 CXT5051_MODELS 1961 CXT5051_MODELS
1986}; 1962};
1987 1963
1988static const char *cxt5051_models[CXT5051_MODELS] = { 1964static const char *const cxt5051_models[CXT5051_MODELS] = {
1989 [CXT5051_LAPTOP] = "laptop", 1965 [CXT5051_LAPTOP] = "laptop",
1990 [CXT5051_HP] = "hp", 1966 [CXT5051_HP] = "hp",
1991 [CXT5051_HP_DV6736] = "hp-dv6736", 1967 [CXT5051_HP_DV6736] = "hp-dv6736",
@@ -1993,9 +1969,10 @@ static const char *cxt5051_models[CXT5051_MODELS] = {
1993 [CXT5051_F700] = "hp-700", 1969 [CXT5051_F700] = "hp-700",
1994 [CXT5051_TOSHIBA] = "toshiba", 1970 [CXT5051_TOSHIBA] = "toshiba",
1995 [CXT5051_IDEAPAD] = "ideapad", 1971 [CXT5051_IDEAPAD] = "ideapad",
1972 [CXT5051_AUTO] = "auto",
1996}; 1973};
1997 1974
1998static struct snd_pci_quirk cxt5051_cfg_tbl[] = { 1975static const struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1999 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), 1976 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
2000 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP), 1977 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
2001 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700), 1978 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
@@ -2013,6 +1990,16 @@ static int patch_cxt5051(struct hda_codec *codec)
2013 struct conexant_spec *spec; 1990 struct conexant_spec *spec;
2014 int board_config; 1991 int board_config;
2015 1992
1993 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1994 cxt5051_models,
1995 cxt5051_cfg_tbl);
1996#if 0 /* use the old method just for safety */
1997 if (board_config < 0)
1998 board_config = CXT5051_AUTO;
1999#endif
2000 if (board_config == CXT5051_AUTO)
2001 return patch_conexant_auto(codec);
2002
2016 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 2003 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2017 if (!spec) 2004 if (!spec)
2018 return -ENOMEM; 2005 return -ENOMEM;
@@ -2043,9 +2030,6 @@ static int patch_cxt5051(struct hda_codec *codec)
2043 2030
2044 codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; 2031 codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
2045 2032
2046 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
2047 cxt5051_models,
2048 cxt5051_cfg_tbl);
2049 spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC; 2033 spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC;
2050 switch (board_config) { 2034 switch (board_config) {
2051 case CXT5051_HP: 2035 case CXT5051_HP:
@@ -2087,39 +2071,49 @@ static int patch_cxt5051(struct hda_codec *codec)
2087 2071
2088/* Conexant 5066 specific */ 2072/* Conexant 5066 specific */
2089 2073
2090static hda_nid_t cxt5066_dac_nids[1] = { 0x10 }; 2074static const hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
2091static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 }; 2075static const hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
2092static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 }; 2076static const hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
2093#define CXT5066_SPDIF_OUT 0x21 2077static const hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 };
2094 2078
2095/* OLPC's microphone port is DC coupled for use with external sensors, 2079/* OLPC's microphone port is DC coupled for use with external sensors,
2096 * therefore we use a 50% mic bias in order to center the input signal with 2080 * therefore we use a 50% mic bias in order to center the input signal with
2097 * the DC input range of the codec. */ 2081 * the DC input range of the codec. */
2098#define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50 2082#define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
2099 2083
2100static struct hda_channel_mode cxt5066_modes[1] = { 2084static const struct hda_channel_mode cxt5066_modes[1] = {
2101 { 2, NULL }, 2085 { 2, NULL },
2102}; 2086};
2103 2087
2088#define HP_PRESENT_PORT_A (1 << 0)
2089#define HP_PRESENT_PORT_D (1 << 1)
2090#define hp_port_a_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_A)
2091#define hp_port_d_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_D)
2092
2104static void cxt5066_update_speaker(struct hda_codec *codec) 2093static void cxt5066_update_speaker(struct hda_codec *codec)
2105{ 2094{
2106 struct conexant_spec *spec = codec->spec; 2095 struct conexant_spec *spec = codec->spec;
2107 unsigned int pinctl; 2096 unsigned int pinctl;
2108 2097
2109 snd_printdd("CXT5066: update speaker, hp_present=%d\n", 2098 snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n",
2110 spec->hp_present); 2099 spec->hp_present, spec->cur_eapd);
2111 2100
2112 /* Port A (HP) */ 2101 /* Port A (HP) */
2113 pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0; 2102 pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
2114 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2103 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2115 pinctl); 2104 pinctl);
2116 2105
2117 /* Port D (HP/LO) */ 2106 /* Port D (HP/LO) */
2118 pinctl = ((spec->hp_present & 2) && spec->cur_eapd) 2107 pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
2119 ? spec->port_d_mode : 0; 2108 if (spec->dell_automute || spec->thinkpad) {
2120 /* Mute if Port A is connected on Thinkpad */ 2109 /* Mute if Port A is connected */
2121 if (spec->thinkpad && (spec->hp_present & 1)) 2110 if (hp_port_a_present(spec))
2122 pinctl = 0; 2111 pinctl = 0;
2112 } else {
2113 /* Thinkpad/Dell doesn't give pin-D status */
2114 if (!hp_port_d_present(spec))
2115 pinctl = 0;
2116 }
2123 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2117 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2124 pinctl); 2118 pinctl);
2125 2119
@@ -2127,14 +2121,6 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
2127 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 2121 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
2128 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2122 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2129 pinctl); 2123 pinctl);
2130
2131 if (spec->dell_automute) {
2132 /* DELL AIO Port Rule: PortA > PortD > IntSpk */
2133 pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
2134 ? PIN_OUT : 0;
2135 snd_hda_codec_write(codec, 0x1c, 0,
2136 AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
2137 }
2138} 2124}
2139 2125
2140/* turn on/off EAPD (+ mute HP) as a master switch */ 2126/* turn on/off EAPD (+ mute HP) as a master switch */
@@ -2250,7 +2236,7 @@ static void cxt5066_vostro_automic(struct hda_codec *codec)
2250 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2236 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2251 {} 2237 {}
2252 }; 2238 };
2253 static struct hda_verb ext_mic_absent[] = { 2239 static const struct hda_verb ext_mic_absent[] = {
2254 /* enable internal mic, port C */ 2240 /* enable internal mic, port C */
2255 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2241 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2256 2242
@@ -2283,7 +2269,7 @@ static void cxt5066_ideapad_automic(struct hda_codec *codec)
2283 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2269 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2284 {} 2270 {}
2285 }; 2271 };
2286 static struct hda_verb ext_mic_absent[] = { 2272 static const struct hda_verb ext_mic_absent[] = {
2287 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, 2273 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2288 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2274 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2289 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2275 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
@@ -2300,6 +2286,19 @@ static void cxt5066_ideapad_automic(struct hda_codec *codec)
2300 } 2286 }
2301} 2287}
2302 2288
2289
2290/* toggle input of built-in digital mic and mic jack appropriately */
2291static void cxt5066_asus_automic(struct hda_codec *codec)
2292{
2293 unsigned int present;
2294
2295 present = snd_hda_jack_detect(codec, 0x1b);
2296 snd_printdd("CXT5066: external microphone present=%d\n", present);
2297 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2298 present ? 1 : 0);
2299}
2300
2301
2303/* toggle input of built-in digital mic and mic jack appropriately */ 2302/* toggle input of built-in digital mic and mic jack appropriately */
2304static void cxt5066_hp_laptop_automic(struct hda_codec *codec) 2303static void cxt5066_hp_laptop_automic(struct hda_codec *codec)
2305{ 2304{
@@ -2318,7 +2317,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2318{ 2317{
2319 unsigned int ext_present, dock_present; 2318 unsigned int ext_present, dock_present;
2320 2319
2321 static struct hda_verb ext_mic_present[] = { 2320 static const struct hda_verb ext_mic_present[] = {
2322 {0x14, AC_VERB_SET_CONNECT_SEL, 0}, 2321 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2323 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, 2322 {0x17, AC_VERB_SET_CONNECT_SEL, 1},
2324 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2323 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -2326,7 +2325,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2326 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2325 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2327 {} 2326 {}
2328 }; 2327 };
2329 static struct hda_verb dock_mic_present[] = { 2328 static const struct hda_verb dock_mic_present[] = {
2330 {0x14, AC_VERB_SET_CONNECT_SEL, 0}, 2329 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2331 {0x17, AC_VERB_SET_CONNECT_SEL, 0}, 2330 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2332 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2331 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -2334,7 +2333,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2334 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2333 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2335 {} 2334 {}
2336 }; 2335 };
2337 static struct hda_verb ext_mic_absent[] = { 2336 static const struct hda_verb ext_mic_absent[] = {
2338 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, 2337 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2339 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2338 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2340 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2339 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
@@ -2368,86 +2367,62 @@ static void cxt5066_hp_automute(struct hda_codec *codec)
2368 /* Port D */ 2367 /* Port D */
2369 portD = snd_hda_jack_detect(codec, 0x1c); 2368 portD = snd_hda_jack_detect(codec, 0x1c);
2370 2369
2371 spec->hp_present = !!(portA); 2370 spec->hp_present = portA ? HP_PRESENT_PORT_A : 0;
2372 spec->hp_present |= portD ? 2 : 0; 2371 spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0;
2373 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n", 2372 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2374 portA, portD, spec->hp_present); 2373 portA, portD, spec->hp_present);
2375 cxt5066_update_speaker(codec); 2374 cxt5066_update_speaker(codec);
2376} 2375}
2377 2376
2378/* unsolicited event for jack sensing */ 2377/* Dispatch the right mic autoswitch function */
2379static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res) 2378static void cxt5066_automic(struct hda_codec *codec)
2380{ 2379{
2381 struct conexant_spec *spec = codec->spec; 2380 struct conexant_spec *spec = codec->spec;
2382 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2383 switch (res >> 26) {
2384 case CONEXANT_HP_EVENT:
2385 cxt5066_hp_automute(codec);
2386 break;
2387 case CONEXANT_MIC_EVENT:
2388 /* ignore mic events in DC mode; we're always using the jack */
2389 if (!spec->dc_enable)
2390 cxt5066_olpc_automic(codec);
2391 break;
2392 }
2393}
2394 2381
2395/* unsolicited event for jack sensing */ 2382 if (spec->dell_vostro)
2396static void cxt5066_vostro_event(struct hda_codec *codec, unsigned int res)
2397{
2398 snd_printdd("CXT5066_vostro: unsol event %x (%x)\n", res, res >> 26);
2399 switch (res >> 26) {
2400 case CONEXANT_HP_EVENT:
2401 cxt5066_hp_automute(codec);
2402 break;
2403 case CONEXANT_MIC_EVENT:
2404 cxt5066_vostro_automic(codec); 2383 cxt5066_vostro_automic(codec);
2405 break; 2384 else if (spec->ideapad)
2406 }
2407}
2408
2409/* unsolicited event for jack sensing */
2410static void cxt5066_ideapad_event(struct hda_codec *codec, unsigned int res)
2411{
2412 snd_printdd("CXT5066_ideapad: unsol event %x (%x)\n", res, res >> 26);
2413 switch (res >> 26) {
2414 case CONEXANT_HP_EVENT:
2415 cxt5066_hp_automute(codec);
2416 break;
2417 case CONEXANT_MIC_EVENT:
2418 cxt5066_ideapad_automic(codec); 2385 cxt5066_ideapad_automic(codec);
2419 break; 2386 else if (spec->thinkpad)
2420 } 2387 cxt5066_thinkpad_automic(codec);
2388 else if (spec->hp_laptop)
2389 cxt5066_hp_laptop_automic(codec);
2390 else if (spec->asus)
2391 cxt5066_asus_automic(codec);
2421} 2392}
2422 2393
2423/* unsolicited event for jack sensing */ 2394/* unsolicited event for jack sensing */
2424static void cxt5066_hp_laptop_event(struct hda_codec *codec, unsigned int res) 2395static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res)
2425{ 2396{
2426 snd_printdd("CXT5066_hp_laptop: unsol event %x (%x)\n", res, res >> 26); 2397 struct conexant_spec *spec = codec->spec;
2398 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2427 switch (res >> 26) { 2399 switch (res >> 26) {
2428 case CONEXANT_HP_EVENT: 2400 case CONEXANT_HP_EVENT:
2429 cxt5066_hp_automute(codec); 2401 cxt5066_hp_automute(codec);
2430 break; 2402 break;
2431 case CONEXANT_MIC_EVENT: 2403 case CONEXANT_MIC_EVENT:
2432 cxt5066_hp_laptop_automic(codec); 2404 /* ignore mic events in DC mode; we're always using the jack */
2405 if (!spec->dc_enable)
2406 cxt5066_olpc_automic(codec);
2433 break; 2407 break;
2434 } 2408 }
2435} 2409}
2436 2410
2437/* unsolicited event for jack sensing */ 2411/* unsolicited event for jack sensing */
2438static void cxt5066_thinkpad_event(struct hda_codec *codec, unsigned int res) 2412static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res)
2439{ 2413{
2440 snd_printdd("CXT5066_thinkpad: unsol event %x (%x)\n", res, res >> 26); 2414 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2441 switch (res >> 26) { 2415 switch (res >> 26) {
2442 case CONEXANT_HP_EVENT: 2416 case CONEXANT_HP_EVENT:
2443 cxt5066_hp_automute(codec); 2417 cxt5066_hp_automute(codec);
2444 break; 2418 break;
2445 case CONEXANT_MIC_EVENT: 2419 case CONEXANT_MIC_EVENT:
2446 cxt5066_thinkpad_automic(codec); 2420 cxt5066_automic(codec);
2447 break; 2421 break;
2448 } 2422 }
2449} 2423}
2450 2424
2425
2451static const struct hda_input_mux cxt5066_analog_mic_boost = { 2426static const struct hda_input_mux cxt5066_analog_mic_boost = {
2452 .num_items = 5, 2427 .num_items = 5,
2453 .items = { 2428 .items = {
@@ -2621,7 +2596,28 @@ static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
2621 spec->recording = 0; 2596 spec->recording = 0;
2622} 2597}
2623 2598
2624static struct hda_input_mux cxt5066_capture_source = { 2599static void conexant_check_dig_outs(struct hda_codec *codec,
2600 const hda_nid_t *dig_pins,
2601 int num_pins)
2602{
2603 struct conexant_spec *spec = codec->spec;
2604 hda_nid_t *nid_loc = &spec->multiout.dig_out_nid;
2605 int i;
2606
2607 for (i = 0; i < num_pins; i++, dig_pins++) {
2608 unsigned int cfg = snd_hda_codec_get_pincfg(codec, *dig_pins);
2609 if (get_defcfg_connect(cfg) == AC_JACK_PORT_NONE)
2610 continue;
2611 if (snd_hda_get_connections(codec, *dig_pins, nid_loc, 1) != 1)
2612 continue;
2613 if (spec->slave_dig_outs[0])
2614 nid_loc++;
2615 else
2616 nid_loc = spec->slave_dig_outs;
2617 }
2618}
2619
2620static const struct hda_input_mux cxt5066_capture_source = {
2625 .num_items = 4, 2621 .num_items = 4,
2626 .items = { 2622 .items = {
2627 { "Mic B", 0 }, 2623 { "Mic B", 0 },
@@ -2631,7 +2627,7 @@ static struct hda_input_mux cxt5066_capture_source = {
2631 }, 2627 },
2632}; 2628};
2633 2629
2634static struct hda_bind_ctls cxt5066_bind_capture_vol_others = { 2630static const struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2635 .ops = &snd_hda_bind_vol, 2631 .ops = &snd_hda_bind_vol,
2636 .values = { 2632 .values = {
2637 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), 2633 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
@@ -2640,7 +2636,7 @@ static struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2640 }, 2636 },
2641}; 2637};
2642 2638
2643static struct hda_bind_ctls cxt5066_bind_capture_sw_others = { 2639static const struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2644 .ops = &snd_hda_bind_sw, 2640 .ops = &snd_hda_bind_sw,
2645 .values = { 2641 .values = {
2646 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), 2642 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
@@ -2649,12 +2645,12 @@ static struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2649 }, 2645 },
2650}; 2646};
2651 2647
2652static struct snd_kcontrol_new cxt5066_mixer_master[] = { 2648static const struct snd_kcontrol_new cxt5066_mixer_master[] = {
2653 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 2649 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
2654 {} 2650 {}
2655}; 2651};
2656 2652
2657static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { 2653static const struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2658 { 2654 {
2659 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2655 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2660 .name = "Master Playback Volume", 2656 .name = "Master Playback Volume",
@@ -2673,7 +2669,7 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2673 {} 2669 {}
2674}; 2670};
2675 2671
2676static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = { 2672static const struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2677 { 2673 {
2678 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2674 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2679 .name = "DC Mode Enable Switch", 2675 .name = "DC Mode Enable Switch",
@@ -2691,7 +2687,7 @@ static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2691 {} 2687 {}
2692}; 2688};
2693 2689
2694static struct snd_kcontrol_new cxt5066_mixers[] = { 2690static const struct snd_kcontrol_new cxt5066_mixers[] = {
2695 { 2691 {
2696 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2692 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2697 .name = "Master Playback Switch", 2693 .name = "Master Playback Switch",
@@ -2714,10 +2710,10 @@ static struct snd_kcontrol_new cxt5066_mixers[] = {
2714 {} 2710 {}
2715}; 2711};
2716 2712
2717static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { 2713static const struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2718 { 2714 {
2719 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2715 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2720 .name = "Int Mic Boost Capture Enum", 2716 .name = "Internal Mic Boost Capture Enum",
2721 .info = cxt5066_mic_boost_mux_enum_info, 2717 .info = cxt5066_mic_boost_mux_enum_info,
2722 .get = cxt5066_mic_boost_mux_enum_get, 2718 .get = cxt5066_mic_boost_mux_enum_get,
2723 .put = cxt5066_mic_boost_mux_enum_put, 2719 .put = cxt5066_mic_boost_mux_enum_put,
@@ -2726,7 +2722,7 @@ static struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2726 {} 2722 {}
2727}; 2723};
2728 2724
2729static struct hda_verb cxt5066_init_verbs[] = { 2725static const struct hda_verb cxt5066_init_verbs[] = {
2730 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ 2726 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2731 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ 2727 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2732 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ 2728 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
@@ -2781,7 +2777,7 @@ static struct hda_verb cxt5066_init_verbs[] = {
2781 { } /* end */ 2777 { } /* end */
2782}; 2778};
2783 2779
2784static struct hda_verb cxt5066_init_verbs_olpc[] = { 2780static const struct hda_verb cxt5066_init_verbs_olpc[] = {
2785 /* Port A: headphones */ 2781 /* Port A: headphones */
2786 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2782 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2787 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2783 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
@@ -2842,7 +2838,7 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
2842 { } /* end */ 2838 { } /* end */
2843}; 2839};
2844 2840
2845static struct hda_verb cxt5066_init_verbs_vostro[] = { 2841static const struct hda_verb cxt5066_init_verbs_vostro[] = {
2846 /* Port A: headphones */ 2842 /* Port A: headphones */
2847 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2843 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2848 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2844 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
@@ -2903,7 +2899,7 @@ static struct hda_verb cxt5066_init_verbs_vostro[] = {
2903 { } /* end */ 2899 { } /* end */
2904}; 2900};
2905 2901
2906static struct hda_verb cxt5066_init_verbs_ideapad[] = { 2902static const struct hda_verb cxt5066_init_verbs_ideapad[] = {
2907 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ 2903 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2908 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ 2904 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2909 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ 2905 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
@@ -2943,7 +2939,7 @@ static struct hda_verb cxt5066_init_verbs_ideapad[] = {
2943 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2939 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2944 2940
2945 /* internal microphone */ 2941 /* internal microphone */
2946 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */ 2942 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
2947 2943
2948 /* EAPD */ 2944 /* EAPD */
2949 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 2945 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
@@ -2953,7 +2949,7 @@ static struct hda_verb cxt5066_init_verbs_ideapad[] = {
2953 { } /* end */ 2949 { } /* end */
2954}; 2950};
2955 2951
2956static struct hda_verb cxt5066_init_verbs_thinkpad[] = { 2952static const struct hda_verb cxt5066_init_verbs_thinkpad[] = {
2957 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ 2953 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2958 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */ 2954 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2959 2955
@@ -2998,7 +2994,7 @@ static struct hda_verb cxt5066_init_verbs_thinkpad[] = {
2998 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2994 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2999 2995
3000 /* internal microphone */ 2996 /* internal microphone */
3001 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */ 2997 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
3002 2998
3003 /* EAPD */ 2999 /* EAPD */
3004 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 3000 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
@@ -3011,13 +3007,13 @@ static struct hda_verb cxt5066_init_verbs_thinkpad[] = {
3011 { } /* end */ 3007 { } /* end */
3012}; 3008};
3013 3009
3014static struct hda_verb cxt5066_init_verbs_portd_lo[] = { 3010static const struct hda_verb cxt5066_init_verbs_portd_lo[] = {
3015 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3011 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3016 { } /* end */ 3012 { } /* end */
3017}; 3013};
3018 3014
3019 3015
3020static struct hda_verb cxt5066_init_verbs_hp_laptop[] = { 3016static const struct hda_verb cxt5066_init_verbs_hp_laptop[] = {
3021 {0x14, AC_VERB_SET_CONNECT_SEL, 0x0}, 3017 {0x14, AC_VERB_SET_CONNECT_SEL, 0x0},
3022 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, 3018 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
3023 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, 3019 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
@@ -3027,20 +3023,11 @@ static struct hda_verb cxt5066_init_verbs_hp_laptop[] = {
3027/* initialize jack-sensing, too */ 3023/* initialize jack-sensing, too */
3028static int cxt5066_init(struct hda_codec *codec) 3024static int cxt5066_init(struct hda_codec *codec)
3029{ 3025{
3030 struct conexant_spec *spec = codec->spec;
3031
3032 snd_printdd("CXT5066: init\n"); 3026 snd_printdd("CXT5066: init\n");
3033 conexant_init(codec); 3027 conexant_init(codec);
3034 if (codec->patch_ops.unsol_event) { 3028 if (codec->patch_ops.unsol_event) {
3035 cxt5066_hp_automute(codec); 3029 cxt5066_hp_automute(codec);
3036 if (spec->dell_vostro) 3030 cxt5066_automic(codec);
3037 cxt5066_vostro_automic(codec);
3038 else if (spec->ideapad)
3039 cxt5066_ideapad_automic(codec);
3040 else if (spec->thinkpad)
3041 cxt5066_thinkpad_automic(codec);
3042 else if (spec->hp_laptop)
3043 cxt5066_hp_laptop_automic(codec);
3044 } 3031 }
3045 cxt5066_set_mic_boost(codec); 3032 cxt5066_set_mic_boost(codec);
3046 return 0; 3033 return 0;
@@ -3065,45 +3052,58 @@ enum {
3065 CXT5066_LAPTOP, /* Laptops w/ EAPD support */ 3052 CXT5066_LAPTOP, /* Laptops w/ EAPD support */
3066 CXT5066_DELL_LAPTOP, /* Dell Laptop */ 3053 CXT5066_DELL_LAPTOP, /* Dell Laptop */
3067 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ 3054 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */
3068 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ 3055 CXT5066_DELL_VOSTRO, /* Dell Vostro 1015i */
3069 CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */ 3056 CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */
3070 CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ 3057 CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */
3058 CXT5066_ASUS, /* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */
3071 CXT5066_HP_LAPTOP, /* HP Laptop */ 3059 CXT5066_HP_LAPTOP, /* HP Laptop */
3060 CXT5066_AUTO, /* BIOS auto-parser */
3072 CXT5066_MODELS 3061 CXT5066_MODELS
3073}; 3062};
3074 3063
3075static const char *cxt5066_models[CXT5066_MODELS] = { 3064static const char * const cxt5066_models[CXT5066_MODELS] = {
3076 [CXT5066_LAPTOP] = "laptop", 3065 [CXT5066_LAPTOP] = "laptop",
3077 [CXT5066_DELL_LAPTOP] = "dell-laptop", 3066 [CXT5066_DELL_LAPTOP] = "dell-laptop",
3078 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", 3067 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5",
3079 [CXT5066_DELL_VOSTO] = "dell-vostro", 3068 [CXT5066_DELL_VOSTRO] = "dell-vostro",
3080 [CXT5066_IDEAPAD] = "ideapad", 3069 [CXT5066_IDEAPAD] = "ideapad",
3081 [CXT5066_THINKPAD] = "thinkpad", 3070 [CXT5066_THINKPAD] = "thinkpad",
3071 [CXT5066_ASUS] = "asus",
3082 [CXT5066_HP_LAPTOP] = "hp-laptop", 3072 [CXT5066_HP_LAPTOP] = "hp-laptop",
3073 [CXT5066_AUTO] = "auto",
3083}; 3074};
3084 3075
3085static struct snd_pci_quirk cxt5066_cfg_tbl[] = { 3076static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3086 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", 3077 SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT5066_AUTO),
3087 CXT5066_LAPTOP), 3078 SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
3088 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", 3079 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
3089 CXT5066_DELL_LAPTOP), 3080 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
3090 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), 3081 SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO),
3091 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTO), 3082 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
3092 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
3093 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), 3083 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
3084 SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD),
3085 SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD),
3094 SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), 3086 SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
3087 SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_ASUS),
3088 SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS),
3089 SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS),
3095 SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), 3090 SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
3096 SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), 3091 SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
3097 SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), 3092 SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5),
3093 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
3094 CXT5066_LAPTOP),
3095 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
3098 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), 3096 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
3099 SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), 3097 SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
3100 SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), 3098 SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
3101 SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD),
3102 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), 3099 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
3103 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD), 3100 SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
3104 SND_PCI_QUIRK(0x17aa, 0x390a, "Lenovo S10-3t", CXT5066_IDEAPAD), 3101 SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
3105 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G series (AMD)", CXT5066_IDEAPAD), 3102 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
3106 SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), 3103 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
3104 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
3105 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
3106 SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO),
3107 {} 3107 {}
3108}; 3108};
3109 3109
@@ -3112,6 +3112,15 @@ static int patch_cxt5066(struct hda_codec *codec)
3112 struct conexant_spec *spec; 3112 struct conexant_spec *spec;
3113 int board_config; 3113 int board_config;
3114 3114
3115 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
3116 cxt5066_models, cxt5066_cfg_tbl);
3117#if 0 /* use the old method just for safety */
3118 if (board_config < 0)
3119 board_config = CXT5066_AUTO;
3120#endif
3121 if (board_config == CXT5066_AUTO)
3122 return patch_conexant_auto(codec);
3123
3115 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3124 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3116 if (!spec) 3125 if (!spec)
3117 return -ENOMEM; 3126 return -ENOMEM;
@@ -3124,7 +3133,8 @@ static int patch_cxt5066(struct hda_codec *codec)
3124 spec->multiout.max_channels = 2; 3133 spec->multiout.max_channels = 2;
3125 spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids); 3134 spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids);
3126 spec->multiout.dac_nids = cxt5066_dac_nids; 3135 spec->multiout.dac_nids = cxt5066_dac_nids;
3127 spec->multiout.dig_out_nid = CXT5066_SPDIF_OUT; 3136 conexant_check_dig_outs(codec, cxt5066_digout_pin_nids,
3137 ARRAY_SIZE(cxt5066_digout_pin_nids));
3128 spec->num_adc_nids = 1; 3138 spec->num_adc_nids = 1;
3129 spec->adc_nids = cxt5066_adc_nids; 3139 spec->adc_nids = cxt5066_adc_nids;
3130 spec->capsrc_nids = cxt5066_capsrc_nids; 3140 spec->capsrc_nids = cxt5066_capsrc_nids;
@@ -3141,8 +3151,6 @@ static int patch_cxt5066(struct hda_codec *codec)
3141 3151
3142 set_beep_amp(spec, 0x13, 0, HDA_OUTPUT); 3152 set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
3143 3153
3144 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
3145 cxt5066_models, cxt5066_cfg_tbl);
3146 switch (board_config) { 3154 switch (board_config) {
3147 default: 3155 default:
3148 case CXT5066_LAPTOP: 3156 case CXT5066_LAPTOP:
@@ -3158,17 +3166,20 @@ static int patch_cxt5066(struct hda_codec *codec)
3158 spec->num_init_verbs++; 3166 spec->num_init_verbs++;
3159 spec->dell_automute = 1; 3167 spec->dell_automute = 1;
3160 break; 3168 break;
3169 case CXT5066_ASUS:
3161 case CXT5066_HP_LAPTOP: 3170 case CXT5066_HP_LAPTOP:
3162 codec->patch_ops.init = cxt5066_init; 3171 codec->patch_ops.init = cxt5066_init;
3163 codec->patch_ops.unsol_event = cxt5066_hp_laptop_event; 3172 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3164 spec->init_verbs[spec->num_init_verbs] = 3173 spec->init_verbs[spec->num_init_verbs] =
3165 cxt5066_init_verbs_hp_laptop; 3174 cxt5066_init_verbs_hp_laptop;
3166 spec->num_init_verbs++; 3175 spec->num_init_verbs++;
3167 spec->hp_laptop = 1; 3176 spec->hp_laptop = board_config == CXT5066_HP_LAPTOP;
3177 spec->asus = board_config == CXT5066_ASUS;
3168 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; 3178 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3169 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 3179 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3170 /* no S/PDIF out */ 3180 /* no S/PDIF out */
3171 spec->multiout.dig_out_nid = 0; 3181 if (board_config == CXT5066_HP_LAPTOP)
3182 spec->multiout.dig_out_nid = 0;
3172 /* input source automatically selected */ 3183 /* input source automatically selected */
3173 spec->input_mux = NULL; 3184 spec->input_mux = NULL;
3174 spec->port_d_mode = 0; 3185 spec->port_d_mode = 0;
@@ -3196,9 +3207,9 @@ static int patch_cxt5066(struct hda_codec *codec)
3196 spec->capture_prepare = cxt5066_olpc_capture_prepare; 3207 spec->capture_prepare = cxt5066_olpc_capture_prepare;
3197 spec->capture_cleanup = cxt5066_olpc_capture_cleanup; 3208 spec->capture_cleanup = cxt5066_olpc_capture_cleanup;
3198 break; 3209 break;
3199 case CXT5066_DELL_VOSTO: 3210 case CXT5066_DELL_VOSTRO:
3200 codec->patch_ops.init = cxt5066_init; 3211 codec->patch_ops.init = cxt5066_init;
3201 codec->patch_ops.unsol_event = cxt5066_vostro_event; 3212 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3202 spec->init_verbs[0] = cxt5066_init_verbs_vostro; 3213 spec->init_verbs[0] = cxt5066_init_verbs_vostro;
3203 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; 3214 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
3204 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 3215 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
@@ -3215,7 +3226,7 @@ static int patch_cxt5066(struct hda_codec *codec)
3215 break; 3226 break;
3216 case CXT5066_IDEAPAD: 3227 case CXT5066_IDEAPAD:
3217 codec->patch_ops.init = cxt5066_init; 3228 codec->patch_ops.init = cxt5066_init;
3218 codec->patch_ops.unsol_event = cxt5066_ideapad_event; 3229 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3219 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; 3230 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3220 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 3231 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3221 spec->init_verbs[0] = cxt5066_init_verbs_ideapad; 3232 spec->init_verbs[0] = cxt5066_init_verbs_ideapad;
@@ -3231,7 +3242,7 @@ static int patch_cxt5066(struct hda_codec *codec)
3231 break; 3242 break;
3232 case CXT5066_THINKPAD: 3243 case CXT5066_THINKPAD:
3233 codec->patch_ops.init = cxt5066_init; 3244 codec->patch_ops.init = cxt5066_init;
3234 codec->patch_ops.unsol_event = cxt5066_thinkpad_event; 3245 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3235 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; 3246 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3236 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 3247 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3237 spec->init_verbs[0] = cxt5066_init_verbs_thinkpad; 3248 spec->init_verbs[0] = cxt5066_init_verbs_thinkpad;
@@ -3254,9 +3265,1117 @@ static int patch_cxt5066(struct hda_codec *codec)
3254} 3265}
3255 3266
3256/* 3267/*
3268 * Automatic parser for CX20641 & co
3269 */
3270
3271static int cx_auto_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3272 struct hda_codec *codec,
3273 unsigned int stream_tag,
3274 unsigned int format,
3275 struct snd_pcm_substream *substream)
3276{
3277 struct conexant_spec *spec = codec->spec;
3278 hda_nid_t adc = spec->imux_info[spec->cur_mux[0]].adc;
3279 if (spec->adc_switching) {
3280 spec->cur_adc = adc;
3281 spec->cur_adc_stream_tag = stream_tag;
3282 spec->cur_adc_format = format;
3283 }
3284 snd_hda_codec_setup_stream(codec, adc, stream_tag, 0, format);
3285 return 0;
3286}
3287
3288static int cx_auto_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3289 struct hda_codec *codec,
3290 struct snd_pcm_substream *substream)
3291{
3292 struct conexant_spec *spec = codec->spec;
3293 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3294 spec->cur_adc = 0;
3295 return 0;
3296}
3297
3298static const struct hda_pcm_stream cx_auto_pcm_analog_capture = {
3299 .substreams = 1,
3300 .channels_min = 2,
3301 .channels_max = 2,
3302 .nid = 0, /* fill later */
3303 .ops = {
3304 .prepare = cx_auto_capture_pcm_prepare,
3305 .cleanup = cx_auto_capture_pcm_cleanup
3306 },
3307};
3308
3309static const hda_nid_t cx_auto_adc_nids[] = { 0x14 };
3310
3311/* get the connection index of @nid in the widget @mux */
3312static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
3313 hda_nid_t nid)
3314{
3315 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3316 int i, nums;
3317
3318 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3319 for (i = 0; i < nums; i++)
3320 if (conn[i] == nid)
3321 return i;
3322 return -1;
3323}
3324
3325/* get an unassigned DAC from the given list.
3326 * Return the nid if found and reduce the DAC list, or return zero if
3327 * not found
3328 */
3329static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin,
3330 hda_nid_t *dacs, int *num_dacs)
3331{
3332 int i, nums = *num_dacs;
3333 hda_nid_t ret = 0;
3334
3335 for (i = 0; i < nums; i++) {
3336 if (get_connection_index(codec, pin, dacs[i]) >= 0) {
3337 ret = dacs[i];
3338 break;
3339 }
3340 }
3341 if (!ret)
3342 return 0;
3343 if (--nums > 0)
3344 memmove(dacs, dacs + 1, nums * sizeof(hda_nid_t));
3345 *num_dacs = nums;
3346 return ret;
3347}
3348
3349#define MAX_AUTO_DACS 5
3350
3351/* fill analog DAC list from the widget tree */
3352static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
3353{
3354 hda_nid_t nid, end_nid;
3355 int nums = 0;
3356
3357 end_nid = codec->start_nid + codec->num_nodes;
3358 for (nid = codec->start_nid; nid < end_nid; nid++) {
3359 unsigned int wcaps = get_wcaps(codec, nid);
3360 unsigned int type = get_wcaps_type(wcaps);
3361 if (type == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) {
3362 dacs[nums++] = nid;
3363 if (nums >= MAX_AUTO_DACS)
3364 break;
3365 }
3366 }
3367 return nums;
3368}
3369
3370/* fill pin_dac_pair list from the pin and dac list */
3371static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins,
3372 int num_pins, hda_nid_t *dacs, int *rest,
3373 struct pin_dac_pair *filled, int type)
3374{
3375 int i, nums;
3376
3377 nums = 0;
3378 for (i = 0; i < num_pins; i++) {
3379 filled[nums].pin = pins[i];
3380 filled[nums].type = type;
3381 filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest);
3382 nums++;
3383 }
3384 return nums;
3385}
3386
3387/* parse analog output paths */
3388static void cx_auto_parse_output(struct hda_codec *codec)
3389{
3390 struct conexant_spec *spec = codec->spec;
3391 struct auto_pin_cfg *cfg = &spec->autocfg;
3392 hda_nid_t dacs[MAX_AUTO_DACS];
3393 int i, j, nums, rest;
3394
3395 rest = fill_cx_auto_dacs(codec, dacs);
3396 /* parse all analog output pins */
3397 nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs,
3398 dacs, &rest, spec->dac_info,
3399 AUTO_PIN_LINE_OUT);
3400 nums += fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs,
3401 dacs, &rest, spec->dac_info + nums,
3402 AUTO_PIN_HP_OUT);
3403 nums += fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs,
3404 dacs, &rest, spec->dac_info + nums,
3405 AUTO_PIN_SPEAKER_OUT);
3406 spec->dac_info_filled = nums;
3407 /* fill multiout struct */
3408 for (i = 0; i < nums; i++) {
3409 hda_nid_t dac = spec->dac_info[i].dac;
3410 if (!dac)
3411 continue;
3412 switch (spec->dac_info[i].type) {
3413 case AUTO_PIN_LINE_OUT:
3414 spec->private_dac_nids[spec->multiout.num_dacs] = dac;
3415 spec->multiout.num_dacs++;
3416 break;
3417 case AUTO_PIN_HP_OUT:
3418 case AUTO_PIN_SPEAKER_OUT:
3419 if (!spec->multiout.hp_nid) {
3420 spec->multiout.hp_nid = dac;
3421 break;
3422 }
3423 for (j = 0; j < ARRAY_SIZE(spec->multiout.extra_out_nid); j++)
3424 if (!spec->multiout.extra_out_nid[j]) {
3425 spec->multiout.extra_out_nid[j] = dac;
3426 break;
3427 }
3428 break;
3429 }
3430 }
3431 spec->multiout.dac_nids = spec->private_dac_nids;
3432 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3433
3434 for (i = 0; i < cfg->hp_outs; i++) {
3435 if (is_jack_detectable(codec, cfg->hp_pins[i])) {
3436 spec->auto_mute = 1;
3437 break;
3438 }
3439 }
3440 if (spec->auto_mute &&
3441 cfg->line_out_pins[0] &&
3442 cfg->line_out_type != AUTO_PIN_SPEAKER_OUT &&
3443 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
3444 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
3445 for (i = 0; i < cfg->line_outs; i++) {
3446 if (is_jack_detectable(codec, cfg->line_out_pins[i])) {
3447 spec->detect_line = 1;
3448 break;
3449 }
3450 }
3451 spec->automute_lines = spec->detect_line;
3452 }
3453
3454 spec->vmaster_nid = spec->private_dac_nids[0];
3455}
3456
3457static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3458 hda_nid_t *pins, bool on);
3459
3460static void do_automute(struct hda_codec *codec, int num_pins,
3461 hda_nid_t *pins, bool on)
3462{
3463 int i;
3464 for (i = 0; i < num_pins; i++)
3465 snd_hda_codec_write(codec, pins[i], 0,
3466 AC_VERB_SET_PIN_WIDGET_CONTROL,
3467 on ? PIN_OUT : 0);
3468 cx_auto_turn_eapd(codec, num_pins, pins, on);
3469}
3470
3471static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
3472{
3473 int i, present = 0;
3474
3475 for (i = 0; i < num_pins; i++) {
3476 hda_nid_t nid = pins[i];
3477 if (!nid || !is_jack_detectable(codec, nid))
3478 break;
3479 snd_hda_input_jack_report(codec, nid);
3480 present |= snd_hda_jack_detect(codec, nid);
3481 }
3482 return present;
3483}
3484
3485/* auto-mute/unmute speaker and line outs according to headphone jack */
3486static void cx_auto_update_speakers(struct hda_codec *codec)
3487{
3488 struct conexant_spec *spec = codec->spec;
3489 struct auto_pin_cfg *cfg = &spec->autocfg;
3490 int on = 1;
3491
3492 /* turn on HP EAPD when HP jacks are present */
3493 if (spec->auto_mute)
3494 on = spec->hp_present;
3495 cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
3496 /* mute speakers in auto-mode if HP or LO jacks are plugged */
3497 if (spec->auto_mute)
3498 on = !(spec->hp_present ||
3499 (spec->detect_line && spec->line_present));
3500 do_automute(codec, cfg->speaker_outs, cfg->speaker_pins, on);
3501
3502 /* toggle line-out mutes if needed, too */
3503 /* if LO is a copy of either HP or Speaker, don't need to handle it */
3504 if (cfg->line_out_pins[0] == cfg->hp_pins[0] ||
3505 cfg->line_out_pins[0] == cfg->speaker_pins[0])
3506 return;
3507 if (spec->auto_mute) {
3508 /* mute LO in auto-mode when HP jack is present */
3509 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ||
3510 spec->automute_lines)
3511 on = !spec->hp_present;
3512 else
3513 on = 1;
3514 }
3515 do_automute(codec, cfg->line_outs, cfg->line_out_pins, on);
3516}
3517
3518static void cx_auto_hp_automute(struct hda_codec *codec)
3519{
3520 struct conexant_spec *spec = codec->spec;
3521 struct auto_pin_cfg *cfg = &spec->autocfg;
3522
3523 if (!spec->auto_mute)
3524 return;
3525 spec->hp_present = detect_jacks(codec, cfg->hp_outs, cfg->hp_pins);
3526 cx_auto_update_speakers(codec);
3527}
3528
3529static void cx_auto_line_automute(struct hda_codec *codec)
3530{
3531 struct conexant_spec *spec = codec->spec;
3532 struct auto_pin_cfg *cfg = &spec->autocfg;
3533
3534 if (!spec->auto_mute || !spec->detect_line)
3535 return;
3536 spec->line_present = detect_jacks(codec, cfg->line_outs,
3537 cfg->line_out_pins);
3538 cx_auto_update_speakers(codec);
3539}
3540
3541static int cx_automute_mode_info(struct snd_kcontrol *kcontrol,
3542 struct snd_ctl_elem_info *uinfo)
3543{
3544 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3545 struct conexant_spec *spec = codec->spec;
3546 static const char * const texts2[] = {
3547 "Disabled", "Enabled"
3548 };
3549 static const char * const texts3[] = {
3550 "Disabled", "Speaker Only", "Line-Out+Speaker"
3551 };
3552 const char * const *texts;
3553
3554 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3555 uinfo->count = 1;
3556 if (spec->automute_hp_lo) {
3557 uinfo->value.enumerated.items = 3;
3558 texts = texts3;
3559 } else {
3560 uinfo->value.enumerated.items = 2;
3561 texts = texts2;
3562 }
3563 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3564 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
3565 strcpy(uinfo->value.enumerated.name,
3566 texts[uinfo->value.enumerated.item]);
3567 return 0;
3568}
3569
3570static int cx_automute_mode_get(struct snd_kcontrol *kcontrol,
3571 struct snd_ctl_elem_value *ucontrol)
3572{
3573 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3574 struct conexant_spec *spec = codec->spec;
3575 unsigned int val;
3576 if (!spec->auto_mute)
3577 val = 0;
3578 else if (!spec->automute_lines)
3579 val = 1;
3580 else
3581 val = 2;
3582 ucontrol->value.enumerated.item[0] = val;
3583 return 0;
3584}
3585
3586static int cx_automute_mode_put(struct snd_kcontrol *kcontrol,
3587 struct snd_ctl_elem_value *ucontrol)
3588{
3589 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3590 struct conexant_spec *spec = codec->spec;
3591
3592 switch (ucontrol->value.enumerated.item[0]) {
3593 case 0:
3594 if (!spec->auto_mute)
3595 return 0;
3596 spec->auto_mute = 0;
3597 break;
3598 case 1:
3599 if (spec->auto_mute && !spec->automute_lines)
3600 return 0;
3601 spec->auto_mute = 1;
3602 spec->automute_lines = 0;
3603 break;
3604 case 2:
3605 if (!spec->automute_hp_lo)
3606 return -EINVAL;
3607 if (spec->auto_mute && spec->automute_lines)
3608 return 0;
3609 spec->auto_mute = 1;
3610 spec->automute_lines = 1;
3611 break;
3612 default:
3613 return -EINVAL;
3614 }
3615 cx_auto_update_speakers(codec);
3616 return 1;
3617}
3618
3619static const struct snd_kcontrol_new cx_automute_mode_enum[] = {
3620 {
3621 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3622 .name = "Auto-Mute Mode",
3623 .info = cx_automute_mode_info,
3624 .get = cx_automute_mode_get,
3625 .put = cx_automute_mode_put,
3626 },
3627 { }
3628};
3629
3630static int cx_auto_mux_enum_info(struct snd_kcontrol *kcontrol,
3631 struct snd_ctl_elem_info *uinfo)
3632{
3633 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3634 struct conexant_spec *spec = codec->spec;
3635
3636 return snd_hda_input_mux_info(&spec->private_imux, uinfo);
3637}
3638
3639static int cx_auto_mux_enum_get(struct snd_kcontrol *kcontrol,
3640 struct snd_ctl_elem_value *ucontrol)
3641{
3642 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3643 struct conexant_spec *spec = codec->spec;
3644
3645 ucontrol->value.enumerated.item[0] = spec->cur_mux[0];
3646 return 0;
3647}
3648
3649/* look for the route the given pin from mux and return the index;
3650 * if do_select is set, actually select the route.
3651 */
3652static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
3653 hda_nid_t pin, hda_nid_t *srcp,
3654 bool do_select, int depth)
3655{
3656 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3657 int i, nums;
3658
3659 switch (get_wcaps_type(get_wcaps(codec, mux))) {
3660 case AC_WID_AUD_IN:
3661 case AC_WID_AUD_SEL:
3662 case AC_WID_AUD_MIX:
3663 break;
3664 default:
3665 return -1;
3666 }
3667
3668 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3669 for (i = 0; i < nums; i++)
3670 if (conn[i] == pin) {
3671 if (do_select)
3672 snd_hda_codec_write(codec, mux, 0,
3673 AC_VERB_SET_CONNECT_SEL, i);
3674 if (srcp)
3675 *srcp = mux;
3676 return i;
3677 }
3678 depth++;
3679 if (depth == 2)
3680 return -1;
3681 for (i = 0; i < nums; i++) {
3682 int ret = __select_input_connection(codec, conn[i], pin, srcp,
3683 do_select, depth);
3684 if (ret >= 0) {
3685 if (do_select)
3686 snd_hda_codec_write(codec, mux, 0,
3687 AC_VERB_SET_CONNECT_SEL, i);
3688 return i;
3689 }
3690 }
3691 return -1;
3692}
3693
3694static void select_input_connection(struct hda_codec *codec, hda_nid_t mux,
3695 hda_nid_t pin)
3696{
3697 __select_input_connection(codec, mux, pin, NULL, true, 0);
3698}
3699
3700static int get_input_connection(struct hda_codec *codec, hda_nid_t mux,
3701 hda_nid_t pin)
3702{
3703 return __select_input_connection(codec, mux, pin, NULL, false, 0);
3704}
3705
3706static int cx_auto_mux_enum_update(struct hda_codec *codec,
3707 const struct hda_input_mux *imux,
3708 unsigned int idx)
3709{
3710 struct conexant_spec *spec = codec->spec;
3711 hda_nid_t adc;
3712 int changed = 1;
3713
3714 if (!imux->num_items)
3715 return 0;
3716 if (idx >= imux->num_items)
3717 idx = imux->num_items - 1;
3718 if (spec->cur_mux[0] == idx)
3719 changed = 0;
3720 adc = spec->imux_info[idx].adc;
3721 select_input_connection(codec, spec->imux_info[idx].adc,
3722 spec->imux_info[idx].pin);
3723 if (spec->cur_adc && spec->cur_adc != adc) {
3724 /* stream is running, let's swap the current ADC */
3725 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
3726 spec->cur_adc = adc;
3727 snd_hda_codec_setup_stream(codec, adc,
3728 spec->cur_adc_stream_tag, 0,
3729 spec->cur_adc_format);
3730 }
3731 spec->cur_mux[0] = idx;
3732 return changed;
3733}
3734
3735static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol,
3736 struct snd_ctl_elem_value *ucontrol)
3737{
3738 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3739 struct conexant_spec *spec = codec->spec;
3740
3741 return cx_auto_mux_enum_update(codec, &spec->private_imux,
3742 ucontrol->value.enumerated.item[0]);
3743}
3744
3745static const struct snd_kcontrol_new cx_auto_capture_mixers[] = {
3746 {
3747 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3748 .name = "Capture Source",
3749 .info = cx_auto_mux_enum_info,
3750 .get = cx_auto_mux_enum_get,
3751 .put = cx_auto_mux_enum_put
3752 },
3753 {}
3754};
3755
3756static bool select_automic(struct hda_codec *codec, int idx, bool detect)
3757{
3758 struct conexant_spec *spec = codec->spec;
3759 if (idx < 0)
3760 return false;
3761 if (detect && !snd_hda_jack_detect(codec, spec->imux_info[idx].pin))
3762 return false;
3763 cx_auto_mux_enum_update(codec, &spec->private_imux, idx);
3764 return true;
3765}
3766
3767/* automatic switch internal and external mic */
3768static void cx_auto_automic(struct hda_codec *codec)
3769{
3770 struct conexant_spec *spec = codec->spec;
3771
3772 if (!spec->auto_mic)
3773 return;
3774 if (!select_automic(codec, spec->auto_mic_ext, true))
3775 if (!select_automic(codec, spec->auto_mic_dock, true))
3776 select_automic(codec, spec->auto_mic_int, false);
3777}
3778
3779static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
3780{
3781 int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
3782 switch (res >> 26) {
3783 case CONEXANT_HP_EVENT:
3784 cx_auto_hp_automute(codec);
3785 break;
3786 case CONEXANT_LINE_EVENT:
3787 cx_auto_line_automute(codec);
3788 break;
3789 case CONEXANT_MIC_EVENT:
3790 cx_auto_automic(codec);
3791 snd_hda_input_jack_report(codec, nid);
3792 break;
3793 }
3794}
3795
3796/* check whether the pin config is suitable for auto-mic switching;
3797 * auto-mic is enabled only when one int-mic and one ext- and/or
3798 * one dock-mic exist
3799 */
3800static void cx_auto_check_auto_mic(struct hda_codec *codec)
3801{
3802 struct conexant_spec *spec = codec->spec;
3803 int pset[INPUT_PIN_ATTR_NORMAL + 1];
3804 int i;
3805
3806 for (i = 0; i < ARRAY_SIZE(pset); i++)
3807 pset[i] = -1;
3808 for (i = 0; i < spec->private_imux.num_items; i++) {
3809 hda_nid_t pin = spec->imux_info[i].pin;
3810 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin);
3811 int type, attr;
3812 attr = snd_hda_get_input_pin_attr(def_conf);
3813 if (attr == INPUT_PIN_ATTR_UNUSED)
3814 return; /* invalid entry */
3815 if (attr > INPUT_PIN_ATTR_NORMAL)
3816 attr = INPUT_PIN_ATTR_NORMAL;
3817 if (attr != INPUT_PIN_ATTR_INT &&
3818 !is_jack_detectable(codec, pin))
3819 return; /* non-detectable pin */
3820 type = get_defcfg_device(def_conf);
3821 if (type != AC_JACK_MIC_IN &&
3822 (attr != INPUT_PIN_ATTR_DOCK || type != AC_JACK_LINE_IN))
3823 return; /* no valid input type */
3824 if (pset[attr] >= 0)
3825 return; /* already occupied */
3826 pset[attr] = i;
3827 }
3828 if (pset[INPUT_PIN_ATTR_INT] < 0 ||
3829 (pset[INPUT_PIN_ATTR_NORMAL] < 0 && pset[INPUT_PIN_ATTR_DOCK]))
3830 return; /* no input to switch*/
3831 spec->auto_mic = 1;
3832 spec->auto_mic_ext = pset[INPUT_PIN_ATTR_NORMAL];
3833 spec->auto_mic_dock = pset[INPUT_PIN_ATTR_DOCK];
3834 spec->auto_mic_int = pset[INPUT_PIN_ATTR_INT];
3835}
3836
3837static void cx_auto_parse_input(struct hda_codec *codec)
3838{
3839 struct conexant_spec *spec = codec->spec;
3840 struct auto_pin_cfg *cfg = &spec->autocfg;
3841 struct hda_input_mux *imux;
3842 int i, j;
3843
3844 imux = &spec->private_imux;
3845 for (i = 0; i < cfg->num_inputs; i++) {
3846 for (j = 0; j < spec->num_adc_nids; j++) {
3847 hda_nid_t adc = spec->adc_nids[j];
3848 int idx = get_input_connection(codec, adc,
3849 cfg->inputs[i].pin);
3850 if (idx >= 0) {
3851 const char *label;
3852 label = hda_get_autocfg_input_label(codec, cfg, i);
3853 spec->imux_info[imux->num_items].index = i;
3854 spec->imux_info[imux->num_items].boost = 0;
3855 spec->imux_info[imux->num_items].adc = adc;
3856 spec->imux_info[imux->num_items].pin =
3857 cfg->inputs[i].pin;
3858 snd_hda_add_imux_item(imux, label, idx, NULL);
3859 break;
3860 }
3861 }
3862 }
3863 if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items)
3864 cx_auto_check_auto_mic(codec);
3865 if (imux->num_items > 1 && !spec->auto_mic) {
3866 for (i = 1; i < imux->num_items; i++) {
3867 if (spec->imux_info[i].adc != spec->imux_info[0].adc) {
3868 spec->adc_switching = 1;
3869 break;
3870 }
3871 }
3872 }
3873}
3874
3875/* get digital-input audio widget corresponding to the given pin */
3876static hda_nid_t cx_auto_get_dig_in(struct hda_codec *codec, hda_nid_t pin)
3877{
3878 hda_nid_t nid, end_nid;
3879
3880 end_nid = codec->start_nid + codec->num_nodes;
3881 for (nid = codec->start_nid; nid < end_nid; nid++) {
3882 unsigned int wcaps = get_wcaps(codec, nid);
3883 unsigned int type = get_wcaps_type(wcaps);
3884 if (type == AC_WID_AUD_IN && (wcaps & AC_WCAP_DIGITAL)) {
3885 if (get_connection_index(codec, nid, pin) >= 0)
3886 return nid;
3887 }
3888 }
3889 return 0;
3890}
3891
3892static void cx_auto_parse_digital(struct hda_codec *codec)
3893{
3894 struct conexant_spec *spec = codec->spec;
3895 struct auto_pin_cfg *cfg = &spec->autocfg;
3896 hda_nid_t nid;
3897
3898 if (cfg->dig_outs &&
3899 snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) == 1)
3900 spec->multiout.dig_out_nid = nid;
3901 if (cfg->dig_in_pin)
3902 spec->dig_in_nid = cx_auto_get_dig_in(codec, cfg->dig_in_pin);
3903}
3904
3905#ifdef CONFIG_SND_HDA_INPUT_BEEP
3906static void cx_auto_parse_beep(struct hda_codec *codec)
3907{
3908 struct conexant_spec *spec = codec->spec;
3909 hda_nid_t nid, end_nid;
3910
3911 end_nid = codec->start_nid + codec->num_nodes;
3912 for (nid = codec->start_nid; nid < end_nid; nid++)
3913 if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) {
3914 set_beep_amp(spec, nid, 0, HDA_OUTPUT);
3915 break;
3916 }
3917}
3918#else
3919#define cx_auto_parse_beep(codec)
3920#endif
3921
3922static int cx_auto_parse_auto_config(struct hda_codec *codec)
3923{
3924 struct conexant_spec *spec = codec->spec;
3925 int err;
3926
3927 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3928 if (err < 0)
3929 return err;
3930
3931 cx_auto_parse_output(codec);
3932 cx_auto_parse_input(codec);
3933 cx_auto_parse_digital(codec);
3934 cx_auto_parse_beep(codec);
3935 return 0;
3936}
3937
3938static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3939 hda_nid_t *pins, bool on)
3940{
3941 int i;
3942 for (i = 0; i < num_pins; i++) {
3943 if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD)
3944 snd_hda_codec_write(codec, pins[i], 0,
3945 AC_VERB_SET_EAPD_BTLENABLE,
3946 on ? 0x02 : 0);
3947 }
3948}
3949
3950static void select_connection(struct hda_codec *codec, hda_nid_t pin,
3951 hda_nid_t src)
3952{
3953 int idx = get_connection_index(codec, pin, src);
3954 if (idx >= 0)
3955 snd_hda_codec_write(codec, pin, 0,
3956 AC_VERB_SET_CONNECT_SEL, idx);
3957}
3958
3959static void mute_outputs(struct hda_codec *codec, int num_nids,
3960 const hda_nid_t *nids)
3961{
3962 int i, val;
3963
3964 for (i = 0; i < num_nids; i++) {
3965 hda_nid_t nid = nids[i];
3966 if (!(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
3967 continue;
3968 if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE)
3969 val = AMP_OUT_MUTE;
3970 else
3971 val = AMP_OUT_ZERO;
3972 snd_hda_codec_write(codec, nid, 0,
3973 AC_VERB_SET_AMP_GAIN_MUTE, val);
3974 }
3975}
3976
3977static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
3978 hda_nid_t *pins, unsigned int tag)
3979{
3980 int i;
3981 for (i = 0; i < num_pins; i++)
3982 snd_hda_codec_write(codec, pins[i], 0,
3983 AC_VERB_SET_UNSOLICITED_ENABLE,
3984 AC_USRSP_EN | tag);
3985}
3986
3987static void cx_auto_init_output(struct hda_codec *codec)
3988{
3989 struct conexant_spec *spec = codec->spec;
3990 struct auto_pin_cfg *cfg = &spec->autocfg;
3991 hda_nid_t nid;
3992 int i;
3993
3994 mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids);
3995 for (i = 0; i < cfg->hp_outs; i++)
3996 snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
3997 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
3998 mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);
3999 mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);
4000 mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins);
4001 for (i = 0; i < spec->dac_info_filled; i++) {
4002 nid = spec->dac_info[i].dac;
4003 if (!nid)
4004 nid = spec->multiout.dac_nids[0];
4005 select_connection(codec, spec->dac_info[i].pin, nid);
4006 }
4007 if (spec->auto_mute) {
4008 enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins,
4009 CONEXANT_HP_EVENT);
4010 spec->hp_present = detect_jacks(codec, cfg->hp_outs,
4011 cfg->hp_pins);
4012 if (spec->detect_line) {
4013 enable_unsol_pins(codec, cfg->line_outs,
4014 cfg->line_out_pins,
4015 CONEXANT_LINE_EVENT);
4016 spec->line_present =
4017 detect_jacks(codec, cfg->line_outs,
4018 cfg->line_out_pins);
4019 }
4020 }
4021 cx_auto_update_speakers(codec);
4022}
4023
4024static void cx_auto_init_input(struct hda_codec *codec)
4025{
4026 struct conexant_spec *spec = codec->spec;
4027 struct auto_pin_cfg *cfg = &spec->autocfg;
4028 int i, val;
4029
4030 for (i = 0; i < spec->num_adc_nids; i++) {
4031 hda_nid_t nid = spec->adc_nids[i];
4032 if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP))
4033 continue;
4034 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)
4035 val = AMP_IN_MUTE(0);
4036 else
4037 val = AMP_IN_UNMUTE(0);
4038 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4039 val);
4040 }
4041
4042 for (i = 0; i < cfg->num_inputs; i++) {
4043 unsigned int type;
4044 if (cfg->inputs[i].type == AUTO_PIN_MIC)
4045 type = PIN_VREF80;
4046 else
4047 type = PIN_IN;
4048 snd_hda_codec_write(codec, cfg->inputs[i].pin, 0,
4049 AC_VERB_SET_PIN_WIDGET_CONTROL, type);
4050 }
4051
4052 if (spec->auto_mic) {
4053 if (spec->auto_mic_ext >= 0) {
4054 snd_hda_codec_write(codec,
4055 cfg->inputs[spec->auto_mic_ext].pin, 0,
4056 AC_VERB_SET_UNSOLICITED_ENABLE,
4057 AC_USRSP_EN | CONEXANT_MIC_EVENT);
4058 }
4059 if (spec->auto_mic_dock >= 0) {
4060 snd_hda_codec_write(codec,
4061 cfg->inputs[spec->auto_mic_dock].pin, 0,
4062 AC_VERB_SET_UNSOLICITED_ENABLE,
4063 AC_USRSP_EN | CONEXANT_MIC_EVENT);
4064 }
4065 cx_auto_automic(codec);
4066 } else {
4067 select_input_connection(codec, spec->imux_info[0].adc,
4068 spec->imux_info[0].pin);
4069 }
4070}
4071
4072static void cx_auto_init_digital(struct hda_codec *codec)
4073{
4074 struct conexant_spec *spec = codec->spec;
4075 struct auto_pin_cfg *cfg = &spec->autocfg;
4076
4077 if (spec->multiout.dig_out_nid)
4078 snd_hda_codec_write(codec, cfg->dig_out_pins[0], 0,
4079 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4080 if (spec->dig_in_nid)
4081 snd_hda_codec_write(codec, cfg->dig_in_pin, 0,
4082 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
4083}
4084
4085static int cx_auto_init(struct hda_codec *codec)
4086{
4087 /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/
4088 cx_auto_init_output(codec);
4089 cx_auto_init_input(codec);
4090 cx_auto_init_digital(codec);
4091 return 0;
4092}
4093
4094static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
4095 const char *dir, int cidx,
4096 hda_nid_t nid, int hda_dir, int amp_idx)
4097{
4098 static char name[32];
4099 static struct snd_kcontrol_new knew[] = {
4100 HDA_CODEC_VOLUME(name, 0, 0, 0),
4101 HDA_CODEC_MUTE(name, 0, 0, 0),
4102 };
4103 static const char * const sfx[2] = { "Volume", "Switch" };
4104 int i, err;
4105
4106 for (i = 0; i < 2; i++) {
4107 struct snd_kcontrol *kctl;
4108 knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, amp_idx,
4109 hda_dir);
4110 knew[i].subdevice = HDA_SUBDEV_AMP_FLAG;
4111 knew[i].index = cidx;
4112 snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]);
4113 kctl = snd_ctl_new1(&knew[i], codec);
4114 if (!kctl)
4115 return -ENOMEM;
4116 err = snd_hda_ctl_add(codec, nid, kctl);
4117 if (err < 0)
4118 return err;
4119 if (!(query_amp_caps(codec, nid, hda_dir) & AC_AMPCAP_MUTE))
4120 break;
4121 }
4122 return 0;
4123}
4124
4125#define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir) \
4126 cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0)
4127
4128#define cx_auto_add_pb_volume(codec, nid, str, idx) \
4129 cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT)
4130
4131static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac,
4132 hda_nid_t pin, const char *name, int idx)
4133{
4134 unsigned int caps;
4135 caps = query_amp_caps(codec, dac, HDA_OUTPUT);
4136 if (caps & AC_AMPCAP_NUM_STEPS)
4137 return cx_auto_add_pb_volume(codec, dac, name, idx);
4138 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
4139 if (caps & AC_AMPCAP_NUM_STEPS)
4140 return cx_auto_add_pb_volume(codec, pin, name, idx);
4141 return 0;
4142}
4143
4144static int cx_auto_build_output_controls(struct hda_codec *codec)
4145{
4146 struct conexant_spec *spec = codec->spec;
4147 int i, err;
4148 int num_line = 0, num_hp = 0, num_spk = 0;
4149 static const char * const texts[3] = { "Front", "Surround", "CLFE" };
4150
4151 if (spec->dac_info_filled == 1)
4152 return try_add_pb_volume(codec, spec->dac_info[0].dac,
4153 spec->dac_info[0].pin,
4154 "Master", 0);
4155
4156 for (i = 0; i < spec->dac_info_filled; i++) {
4157 const char *label;
4158 int idx, type;
4159 if (!spec->dac_info[i].dac)
4160 continue;
4161 type = spec->dac_info[i].type;
4162 if (type == AUTO_PIN_LINE_OUT)
4163 type = spec->autocfg.line_out_type;
4164 switch (type) {
4165 case AUTO_PIN_LINE_OUT:
4166 default:
4167 label = texts[num_line++];
4168 idx = 0;
4169 break;
4170 case AUTO_PIN_HP_OUT:
4171 label = "Headphone";
4172 idx = num_hp++;
4173 break;
4174 case AUTO_PIN_SPEAKER_OUT:
4175 label = "Speaker";
4176 idx = num_spk++;
4177 break;
4178 }
4179 err = try_add_pb_volume(codec, spec->dac_info[i].dac,
4180 spec->dac_info[i].pin,
4181 label, idx);
4182 if (err < 0)
4183 return err;
4184 }
4185
4186 if (spec->auto_mute) {
4187 err = snd_hda_add_new_ctls(codec, cx_automute_mode_enum);
4188 if (err < 0)
4189 return err;
4190 }
4191
4192 return 0;
4193}
4194
4195static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
4196 const char *label, const char *pfx,
4197 int cidx)
4198{
4199 struct conexant_spec *spec = codec->spec;
4200 int i;
4201
4202 for (i = 0; i < spec->num_adc_nids; i++) {
4203 hda_nid_t adc_nid = spec->adc_nids[i];
4204 int idx = get_input_connection(codec, adc_nid, nid);
4205 if (idx < 0)
4206 continue;
4207 return cx_auto_add_volume_idx(codec, label, pfx,
4208 cidx, adc_nid, HDA_INPUT, idx);
4209 }
4210 return 0;
4211}
4212
4213static int cx_auto_add_boost_volume(struct hda_codec *codec, int idx,
4214 const char *label, int cidx)
4215{
4216 struct conexant_spec *spec = codec->spec;
4217 hda_nid_t mux, nid;
4218 int i, con;
4219
4220 nid = spec->imux_info[idx].pin;
4221 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
4222 return cx_auto_add_volume(codec, label, " Boost", cidx,
4223 nid, HDA_INPUT);
4224 con = __select_input_connection(codec, spec->imux_info[idx].adc, nid,
4225 &mux, false, 0);
4226 if (con < 0)
4227 return 0;
4228 for (i = 0; i < idx; i++) {
4229 if (spec->imux_info[i].boost == mux)
4230 return 0; /* already present */
4231 }
4232
4233 if (get_wcaps(codec, mux) & AC_WCAP_OUT_AMP) {
4234 spec->imux_info[idx].boost = mux;
4235 return cx_auto_add_volume(codec, label, " Boost", 0,
4236 mux, HDA_OUTPUT);
4237 }
4238 return 0;
4239}
4240
4241static int cx_auto_build_input_controls(struct hda_codec *codec)
4242{
4243 struct conexant_spec *spec = codec->spec;
4244 struct hda_input_mux *imux = &spec->private_imux;
4245 const char *prev_label;
4246 int input_conn[HDA_MAX_NUM_INPUTS];
4247 int i, err, cidx;
4248 int multi_connection;
4249
4250 multi_connection = 0;
4251 for (i = 0; i < imux->num_items; i++) {
4252 cidx = get_input_connection(codec, spec->imux_info[i].adc,
4253 spec->imux_info[i].pin);
4254 input_conn[i] = (spec->imux_info[i].adc << 8) | cidx;
4255 if (i > 0 && input_conn[i] != input_conn[0])
4256 multi_connection = 1;
4257 }
4258
4259 prev_label = NULL;
4260 cidx = 0;
4261 for (i = 0; i < imux->num_items; i++) {
4262 hda_nid_t nid = spec->imux_info[i].pin;
4263 const char *label;
4264
4265 label = hda_get_autocfg_input_label(codec, &spec->autocfg,
4266 spec->imux_info[i].index);
4267 if (label == prev_label)
4268 cidx++;
4269 else
4270 cidx = 0;
4271 prev_label = label;
4272
4273 err = cx_auto_add_boost_volume(codec, i, label, cidx);
4274 if (err < 0)
4275 return err;
4276
4277 if (!multi_connection) {
4278 if (i > 0)
4279 continue;
4280 err = cx_auto_add_capture_volume(codec, nid,
4281 "Capture", "", cidx);
4282 } else {
4283 err = cx_auto_add_capture_volume(codec, nid,
4284 label, " Capture", cidx);
4285 }
4286 if (err < 0)
4287 return err;
4288 }
4289
4290 if (spec->private_imux.num_items > 1 && !spec->auto_mic) {
4291 err = snd_hda_add_new_ctls(codec, cx_auto_capture_mixers);
4292 if (err < 0)
4293 return err;
4294 }
4295
4296 return 0;
4297}
4298
4299static int cx_auto_build_controls(struct hda_codec *codec)
4300{
4301 int err;
4302
4303 err = cx_auto_build_output_controls(codec);
4304 if (err < 0)
4305 return err;
4306 err = cx_auto_build_input_controls(codec);
4307 if (err < 0)
4308 return err;
4309 return conexant_build_controls(codec);
4310}
4311
4312static int cx_auto_search_adcs(struct hda_codec *codec)
4313{
4314 struct conexant_spec *spec = codec->spec;
4315 hda_nid_t nid, end_nid;
4316
4317 end_nid = codec->start_nid + codec->num_nodes;
4318 for (nid = codec->start_nid; nid < end_nid; nid++) {
4319 unsigned int caps = get_wcaps(codec, nid);
4320 if (get_wcaps_type(caps) != AC_WID_AUD_IN)
4321 continue;
4322 if (caps & AC_WCAP_DIGITAL)
4323 continue;
4324 if (snd_BUG_ON(spec->num_adc_nids >=
4325 ARRAY_SIZE(spec->private_adc_nids)))
4326 break;
4327 spec->private_adc_nids[spec->num_adc_nids++] = nid;
4328 }
4329 spec->adc_nids = spec->private_adc_nids;
4330 return 0;
4331}
4332
4333
4334static const struct hda_codec_ops cx_auto_patch_ops = {
4335 .build_controls = cx_auto_build_controls,
4336 .build_pcms = conexant_build_pcms,
4337 .init = cx_auto_init,
4338 .free = conexant_free,
4339 .unsol_event = cx_auto_unsol_event,
4340#ifdef CONFIG_SND_HDA_POWER_SAVE
4341 .suspend = conexant_suspend,
4342#endif
4343 .reboot_notify = snd_hda_shutup_pins,
4344};
4345
4346static int patch_conexant_auto(struct hda_codec *codec)
4347{
4348 struct conexant_spec *spec;
4349 int err;
4350
4351 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4352 codec->chip_name);
4353
4354 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4355 if (!spec)
4356 return -ENOMEM;
4357 codec->spec = spec;
4358 codec->pin_amp_workaround = 1;
4359 err = cx_auto_search_adcs(codec);
4360 if (err < 0)
4361 return err;
4362 err = cx_auto_parse_auto_config(codec);
4363 if (err < 0) {
4364 kfree(codec->spec);
4365 codec->spec = NULL;
4366 return err;
4367 }
4368 spec->capture_stream = &cx_auto_pcm_analog_capture;
4369 codec->patch_ops = cx_auto_patch_ops;
4370 if (spec->beep_amp)
4371 snd_hda_attach_beep_device(codec, spec->beep_amp);
4372 return 0;
4373}
4374
4375/*
3257 */ 4376 */
3258 4377
3259static struct hda_codec_preset snd_hda_preset_conexant[] = { 4378static const struct hda_codec_preset snd_hda_preset_conexant[] = {
3260 { .id = 0x14f15045, .name = "CX20549 (Venice)", 4379 { .id = 0x14f15045, .name = "CX20549 (Venice)",
3261 .patch = patch_cxt5045 }, 4380 .patch = patch_cxt5045 },
3262 { .id = 0x14f15047, .name = "CX20551 (Waikiki)", 4381 { .id = 0x14f15047, .name = "CX20551 (Waikiki)",
@@ -3271,6 +4390,26 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = {
3271 .patch = patch_cxt5066 }, 4390 .patch = patch_cxt5066 },
3272 { .id = 0x14f15069, .name = "CX20585", 4391 { .id = 0x14f15069, .name = "CX20585",
3273 .patch = patch_cxt5066 }, 4392 .patch = patch_cxt5066 },
4393 { .id = 0x14f1506c, .name = "CX20588",
4394 .patch = patch_cxt5066 },
4395 { .id = 0x14f1506e, .name = "CX20590",
4396 .patch = patch_cxt5066 },
4397 { .id = 0x14f15097, .name = "CX20631",
4398 .patch = patch_conexant_auto },
4399 { .id = 0x14f15098, .name = "CX20632",
4400 .patch = patch_conexant_auto },
4401 { .id = 0x14f150a1, .name = "CX20641",
4402 .patch = patch_conexant_auto },
4403 { .id = 0x14f150a2, .name = "CX20642",
4404 .patch = patch_conexant_auto },
4405 { .id = 0x14f150ab, .name = "CX20651",
4406 .patch = patch_conexant_auto },
4407 { .id = 0x14f150ac, .name = "CX20652",
4408 .patch = patch_conexant_auto },
4409 { .id = 0x14f150b8, .name = "CX20664",
4410 .patch = patch_conexant_auto },
4411 { .id = 0x14f150b9, .name = "CX20665",
4412 .patch = patch_conexant_auto },
3274 {} /* terminator */ 4413 {} /* terminator */
3275}; 4414};
3276 4415
@@ -3281,6 +4420,16 @@ MODULE_ALIAS("snd-hda-codec-id:14f15066");
3281MODULE_ALIAS("snd-hda-codec-id:14f15067"); 4420MODULE_ALIAS("snd-hda-codec-id:14f15067");
3282MODULE_ALIAS("snd-hda-codec-id:14f15068"); 4421MODULE_ALIAS("snd-hda-codec-id:14f15068");
3283MODULE_ALIAS("snd-hda-codec-id:14f15069"); 4422MODULE_ALIAS("snd-hda-codec-id:14f15069");
4423MODULE_ALIAS("snd-hda-codec-id:14f1506c");
4424MODULE_ALIAS("snd-hda-codec-id:14f1506e");
4425MODULE_ALIAS("snd-hda-codec-id:14f15097");
4426MODULE_ALIAS("snd-hda-codec-id:14f15098");
4427MODULE_ALIAS("snd-hda-codec-id:14f150a1");
4428MODULE_ALIAS("snd-hda-codec-id:14f150a2");
4429MODULE_ALIAS("snd-hda-codec-id:14f150ab");
4430MODULE_ALIAS("snd-hda-codec-id:14f150ac");
4431MODULE_ALIAS("snd-hda-codec-id:14f150b8");
4432MODULE_ALIAS("snd-hda-codec-id:14f150b9");
3284 4433
3285MODULE_LICENSE("GPL"); 4434MODULE_LICENSE("GPL");
3286MODULE_DESCRIPTION("Conexant HD-audio codec"); 4435MODULE_DESCRIPTION("Conexant HD-audio codec");
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index afd6022a96a7..bd0ae697f9c4 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,28 @@
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 <linux/moduleparam.h>
35#include <sound/core.h>
36#include <sound/jack.h>
37#include "hda_codec.h"
38#include "hda_local.h"
39
40static bool static_hdmi_pcm;
41module_param(static_hdmi_pcm, bool, 0644);
42MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
43
44/*
45 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
46 * could support two independent pipes, each of them can be connected to one or
47 * more ports (DVI, HDMI or DisplayPort).
48 *
49 * The HDA correspondence of pipes/ports are converter/pin nodes.
50 */
51#define MAX_HDMI_CVTS 4
52#define MAX_HDMI_PINS 4
28 53
29struct hdmi_spec { 54struct hdmi_spec {
30 int num_cvts; 55 int num_cvts;
@@ -49,14 +74,10 @@ struct hdmi_spec {
49 struct hda_pcm_stream codec_pcm_pars[MAX_HDMI_CVTS]; 74 struct hda_pcm_stream codec_pcm_pars[MAX_HDMI_CVTS];
50 75
51 /* 76 /*
52 * nvhdmi specific 77 * ati/nvhdmi specific
53 */ 78 */
54 struct hda_multi_out multiout; 79 struct hda_multi_out multiout;
55 unsigned int codec_type; 80 const struct hda_pcm_stream *pcm_playback;
56
57 /* misc flags */
58 /* PD bit indicates only the update, not the current state */
59 unsigned int old_pin_detect:1;
60}; 81};
61 82
62 83
@@ -65,13 +86,31 @@ struct hdmi_audio_infoframe {
65 u8 ver; /* 0x01 */ 86 u8 ver; /* 0x01 */
66 u8 len; /* 0x0a */ 87 u8 len; /* 0x0a */
67 88
68 u8 checksum; /* PB0 */ 89 u8 checksum;
90
69 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */ 91 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
70 u8 SS01_SF24; 92 u8 SS01_SF24;
71 u8 CXT04; 93 u8 CXT04;
72 u8 CA; 94 u8 CA;
73 u8 LFEPBL01_LSV36_DM_INH7; 95 u8 LFEPBL01_LSV36_DM_INH7;
74 u8 reserved[5]; /* PB6 - PB10 */ 96};
97
98struct dp_audio_infoframe {
99 u8 type; /* 0x84 */
100 u8 len; /* 0x1b */
101 u8 ver; /* 0x11 << 2 */
102
103 u8 CC02_CT47; /* match with HDMI infoframe from this on */
104 u8 SS01_SF24;
105 u8 CXT04;
106 u8 CA;
107 u8 LFEPBL01_LSV36_DM_INH7;
108};
109
110union audio_infoframe {
111 struct hdmi_audio_infoframe hdmi;
112 struct dp_audio_infoframe dp;
113 u8 bytes[0];
75}; 114};
76 115
77/* 116/*
@@ -162,7 +201,7 @@ static int hdmi_channel_mapping[0x32][8] = {
162 /* 4ch */ 201 /* 4ch */
163 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 }, 202 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
164 /* surround41 */ 203 /* surround41 */
165 [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 }, 204 [0x09] = { 0x00, 0x11, 0x24, 0x35, 0x42, 0xf3, 0xf6, 0xf7 },
166 /* surround50 */ 205 /* surround50 */
167 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 }, 206 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
168 /* surround51 */ 207 /* surround51 */
@@ -175,7 +214,7 @@ static int hdmi_channel_mapping[0x32][8] = {
175 * This is an ordered list! 214 * This is an ordered list!
176 * 215 *
177 * The preceding ones have better chances to be selected by 216 * The preceding ones have better chances to be selected by
178 * hdmi_setup_channel_allocation(). 217 * hdmi_channel_allocation().
179 */ 218 */
180static struct cea_channel_speaker_allocation channel_allocations[] = { 219static struct cea_channel_speaker_allocation channel_allocations[] = {
181/* channel: 7 6 5 4 3 2 1 0 */ 220/* channel: 7 6 5 4 3 2 1 0 */
@@ -257,13 +296,6 @@ static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
257 return -EINVAL; 296 return -EINVAL;
258} 297}
259 298
260static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
261 struct hdmi_eld *eld)
262{
263 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
264 snd_hdmi_show_eld(eld);
265}
266
267#ifdef BE_PARANOID 299#ifdef BE_PARANOID
268static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid, 300static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
269 int *packet_index, int *byte_index) 301 int *packet_index, int *byte_index)
@@ -352,14 +384,14 @@ static void init_channel_allocations(void)
352 * 384 *
353 * TODO: it could select the wrong CA from multiple candidates. 385 * TODO: it could select the wrong CA from multiple candidates.
354*/ 386*/
355static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid, 387static int hdmi_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
356 struct hdmi_audio_infoframe *ai) 388 int channels)
357{ 389{
358 struct hdmi_spec *spec = codec->spec; 390 struct hdmi_spec *spec = codec->spec;
359 struct hdmi_eld *eld; 391 struct hdmi_eld *eld;
360 int i; 392 int i;
393 int ca = 0;
361 int spk_mask = 0; 394 int spk_mask = 0;
362 int channels = 1 + (ai->CC02_CT47 & 0x7);
363 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; 395 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
364 396
365 /* 397 /*
@@ -397,16 +429,16 @@ static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
397 if (channels == channel_allocations[i].channels && 429 if (channels == channel_allocations[i].channels &&
398 (spk_mask & channel_allocations[i].spk_mask) == 430 (spk_mask & channel_allocations[i].spk_mask) ==
399 channel_allocations[i].spk_mask) { 431 channel_allocations[i].spk_mask) {
400 ai->CA = channel_allocations[i].ca_index; 432 ca = channel_allocations[i].ca_index;
401 break; 433 break;
402 } 434 }
403 } 435 }
404 436
405 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf)); 437 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
406 snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n", 438 snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n",
407 ai->CA, channels, buf); 439 ca, channels, buf);
408 440
409 return ai->CA; 441 return ca;
410} 442}
411 443
412static void hdmi_debug_channel_mapping(struct hda_codec *codec, 444static void hdmi_debug_channel_mapping(struct hda_codec *codec,
@@ -428,10 +460,9 @@ static void hdmi_debug_channel_mapping(struct hda_codec *codec,
428 460
429static void hdmi_setup_channel_mapping(struct hda_codec *codec, 461static void hdmi_setup_channel_mapping(struct hda_codec *codec,
430 hda_nid_t pin_nid, 462 hda_nid_t pin_nid,
431 struct hdmi_audio_infoframe *ai) 463 int ca)
432{ 464{
433 int i; 465 int i;
434 int ca = ai->CA;
435 int err; 466 int err;
436 467
437 if (hdmi_channel_mapping[ca][1] == 0) { 468 if (hdmi_channel_mapping[ca][1] == 0) {
@@ -528,41 +559,37 @@ static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
528#endif 559#endif
529} 560}
530 561
531static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai) 562static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *hdmi_ai)
532{ 563{
533 u8 *bytes = (u8 *)ai; 564 u8 *bytes = (u8 *)hdmi_ai;
534 u8 sum = 0; 565 u8 sum = 0;
535 int i; 566 int i;
536 567
537 ai->checksum = 0; 568 hdmi_ai->checksum = 0;
538 569
539 for (i = 0; i < sizeof(*ai); i++) 570 for (i = 0; i < sizeof(*hdmi_ai); i++)
540 sum += bytes[i]; 571 sum += bytes[i];
541 572
542 ai->checksum = -sum; 573 hdmi_ai->checksum = -sum;
543} 574}
544 575
545static void hdmi_fill_audio_infoframe(struct hda_codec *codec, 576static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
546 hda_nid_t pin_nid, 577 hda_nid_t pin_nid,
547 struct hdmi_audio_infoframe *ai) 578 u8 *dip, int size)
548{ 579{
549 u8 *bytes = (u8 *)ai;
550 int i; 580 int i;
551 581
552 hdmi_debug_dip_size(codec, pin_nid); 582 hdmi_debug_dip_size(codec, pin_nid);
553 hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */ 583 hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
554 584
555 hdmi_checksum_audio_infoframe(ai);
556
557 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0); 585 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
558 for (i = 0; i < sizeof(*ai); i++) 586 for (i = 0; i < size; i++)
559 hdmi_write_dip_byte(codec, pin_nid, bytes[i]); 587 hdmi_write_dip_byte(codec, pin_nid, dip[i]);
560} 588}
561 589
562static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid, 590static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
563 struct hdmi_audio_infoframe *ai) 591 u8 *dip, int size)
564{ 592{
565 u8 *bytes = (u8 *)ai;
566 u8 val; 593 u8 val;
567 int i; 594 int i;
568 595
@@ -571,10 +598,10 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
571 return false; 598 return false;
572 599
573 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0); 600 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
574 for (i = 0; i < sizeof(*ai); i++) { 601 for (i = 0; i < size; i++) {
575 val = snd_hda_codec_read(codec, pin_nid, 0, 602 val = snd_hda_codec_read(codec, pin_nid, 0,
576 AC_VERB_GET_HDMI_DIP_DATA, 0); 603 AC_VERB_GET_HDMI_DIP_DATA, 0);
577 if (val != bytes[i]) 604 if (val != dip[i])
578 return false; 605 return false;
579 } 606 }
580 607
@@ -586,15 +613,12 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
586{ 613{
587 struct hdmi_spec *spec = codec->spec; 614 struct hdmi_spec *spec = codec->spec;
588 hda_nid_t pin_nid; 615 hda_nid_t pin_nid;
616 int channels = substream->runtime->channels;
617 int ca;
589 int i; 618 int i;
590 struct hdmi_audio_infoframe ai = { 619 union audio_infoframe ai;
591 .type = 0x84,
592 .ver = 0x01,
593 .len = 0x0a,
594 .CC02_CT47 = substream->runtime->channels - 1,
595 };
596 620
597 hdmi_setup_channel_allocation(codec, nid, &ai); 621 ca = hdmi_channel_allocation(codec, nid, channels);
598 622
599 for (i = 0; i < spec->num_pins; i++) { 623 for (i = 0; i < spec->num_pins; i++) {
600 if (spec->pin_cvt[i] != nid) 624 if (spec->pin_cvt[i] != nid)
@@ -603,14 +627,46 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
603 continue; 627 continue;
604 628
605 pin_nid = spec->pin[i]; 629 pin_nid = spec->pin[i];
606 if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) { 630
631 memset(&ai, 0, sizeof(ai));
632 if (spec->sink_eld[i].conn_type == 0) { /* HDMI */
633 struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi;
634
635 hdmi_ai->type = 0x84;
636 hdmi_ai->ver = 0x01;
637 hdmi_ai->len = 0x0a;
638 hdmi_ai->CC02_CT47 = channels - 1;
639 hdmi_ai->CA = ca;
640 hdmi_checksum_audio_infoframe(hdmi_ai);
641 } else if (spec->sink_eld[i].conn_type == 1) { /* DisplayPort */
642 struct dp_audio_infoframe *dp_ai = &ai.dp;
643
644 dp_ai->type = 0x84;
645 dp_ai->len = 0x1b;
646 dp_ai->ver = 0x11 << 2;
647 dp_ai->CC02_CT47 = channels - 1;
648 dp_ai->CA = ca;
649 } else {
650 snd_printd("HDMI: unknown connection type at pin %d\n",
651 pin_nid);
652 continue;
653 }
654
655 /*
656 * sizeof(ai) is used instead of sizeof(*hdmi_ai) or
657 * sizeof(*dp_ai) to avoid partial match/update problems when
658 * the user switches between HDMI/DP monitors.
659 */
660 if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes,
661 sizeof(ai))) {
607 snd_printdd("hdmi_setup_audio_infoframe: " 662 snd_printdd("hdmi_setup_audio_infoframe: "
608 "cvt=%d pin=%d channels=%d\n", 663 "cvt=%d pin=%d channels=%d\n",
609 nid, pin_nid, 664 nid, pin_nid,
610 substream->runtime->channels); 665 channels);
611 hdmi_setup_channel_mapping(codec, pin_nid, &ai); 666 hdmi_setup_channel_mapping(codec, pin_nid, ca);
612 hdmi_stop_infoframe_trans(codec, pin_nid); 667 hdmi_stop_infoframe_trans(codec, pin_nid);
613 hdmi_fill_audio_infoframe(codec, pin_nid, &ai); 668 hdmi_fill_audio_infoframe(codec, pin_nid,
669 ai.bytes, sizeof(ai));
614 hdmi_start_infoframe_trans(codec, pin_nid); 670 hdmi_start_infoframe_trans(codec, pin_nid);
615 } 671 }
616 } 672 }
@@ -627,33 +683,20 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
627static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) 683static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
628{ 684{
629 struct hdmi_spec *spec = codec->spec; 685 struct hdmi_spec *spec = codec->spec;
630 int tag = res >> AC_UNSOL_RES_TAG_SHIFT; 686 int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT;
631 int pind = !!(res & AC_UNSOL_RES_PD); 687 int pd = !!(res & AC_UNSOL_RES_PD);
632 int eldv = !!(res & AC_UNSOL_RES_ELDV); 688 int eldv = !!(res & AC_UNSOL_RES_ELDV);
633 int index; 689 int index;
634 690
635 printk(KERN_INFO 691 printk(KERN_INFO
636 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 692 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
637 tag, pind, eldv); 693 pin_nid, pd, eldv);
638 694
639 index = hda_node_index(spec->pin, tag); 695 index = hda_node_index(spec->pin, pin_nid);
640 if (index < 0) 696 if (index < 0)
641 return; 697 return;
642 698
643 if (spec->old_pin_detect) { 699 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[index]);
644 if (pind)
645 hdmi_present_sense(codec, tag, &spec->sink_eld[index]);
646 pind = spec->sink_eld[index].monitor_present;
647 }
648
649 spec->sink_eld[index].monitor_present = pind;
650 spec->sink_eld[index].eld_valid = eldv;
651
652 if (pind && eldv) {
653 hdmi_get_show_eld(codec, spec->pin[index],
654 &spec->sink_eld[index]);
655 /* TODO: do real things about ELD */
656 }
657} 700}
658 701
659static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) 702static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
@@ -757,6 +800,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
757 struct hdmi_spec *spec = codec->spec; 800 struct hdmi_spec *spec = codec->spec;
758 struct hdmi_eld *eld; 801 struct hdmi_eld *eld;
759 struct hda_pcm_stream *codec_pars; 802 struct hda_pcm_stream *codec_pars;
803 struct snd_pcm_runtime *runtime = substream->runtime;
760 unsigned int idx; 804 unsigned int idx;
761 805
762 for (idx = 0; idx < spec->num_cvts; idx++) 806 for (idx = 0; idx < spec->num_cvts; idx++)
@@ -772,26 +816,32 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
772 *codec_pars = *hinfo; 816 *codec_pars = *hinfo;
773 817
774 eld = &spec->sink_eld[idx]; 818 eld = &spec->sink_eld[idx];
775 if (eld->sad_count > 0) { 819 if (!static_hdmi_pcm && eld->eld_valid && eld->sad_count > 0) {
776 hdmi_eld_update_pcm_info(eld, hinfo, codec_pars); 820 hdmi_eld_update_pcm_info(eld, hinfo, codec_pars);
777 if (hinfo->channels_min > hinfo->channels_max || 821 if (hinfo->channels_min > hinfo->channels_max ||
778 !hinfo->rates || !hinfo->formats) 822 !hinfo->rates || !hinfo->formats)
779 return -ENODEV; 823 return -ENODEV;
780 } else { 824 } else {
781 /* fallback to the codec default */ 825 /* fallback to the codec default */
782 hinfo->channels_min = codec_pars->channels_min;
783 hinfo->channels_max = codec_pars->channels_max; 826 hinfo->channels_max = codec_pars->channels_max;
784 hinfo->rates = codec_pars->rates; 827 hinfo->rates = codec_pars->rates;
785 hinfo->formats = codec_pars->formats; 828 hinfo->formats = codec_pars->formats;
786 hinfo->maxbps = codec_pars->maxbps; 829 hinfo->maxbps = codec_pars->maxbps;
787 } 830 }
831 /* store the updated parameters */
832 runtime->hw.channels_min = hinfo->channels_min;
833 runtime->hw.channels_max = hinfo->channels_max;
834 runtime->hw.formats = hinfo->formats;
835 runtime->hw.rates = hinfo->rates;
836
837 snd_pcm_hw_constraint_step(substream->runtime, 0,
838 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
788 return 0; 839 return 0;
789} 840}
790 841
791/* 842/*
792 * HDA/HDMI auto parsing 843 * HDA/HDMI auto parsing
793 */ 844 */
794
795static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid) 845static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
796{ 846{
797 struct hdmi_spec *spec = codec->spec; 847 struct hdmi_spec *spec = codec->spec;
@@ -827,18 +877,39 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
827static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, 877static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
828 struct hdmi_eld *eld) 878 struct hdmi_eld *eld)
829{ 879{
880 /*
881 * Always execute a GetPinSense verb here, even when called from
882 * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited
883 * response's PD bit is not the real PD value, but indicates that
884 * the real PD value changed. An older version of the HD-audio
885 * specification worked this way. Hence, we just ignore the data in
886 * the unsolicited response to avoid custom WARs.
887 */
830 int present = snd_hda_pin_sense(codec, pin_nid); 888 int present = snd_hda_pin_sense(codec, pin_nid);
831 889
890 memset(eld, 0, sizeof(*eld));
891
832 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); 892 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
833 eld->eld_valid = !!(present & AC_PINSENSE_ELDV); 893 if (eld->monitor_present)
894 eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
895 else
896 eld->eld_valid = 0;
897
898 printk(KERN_INFO
899 "HDMI status: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
900 pin_nid, eld->monitor_present, eld->eld_valid);
834 901
835 if (present & AC_PINSENSE_ELDV) 902 if (eld->eld_valid)
836 hdmi_get_show_eld(codec, pin_nid, eld); 903 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
904 snd_hdmi_show_eld(eld);
905
906 snd_hda_input_jack_report(codec, pin_nid);
837} 907}
838 908
839static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) 909static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
840{ 910{
841 struct hdmi_spec *spec = codec->spec; 911 struct hdmi_spec *spec = codec->spec;
912 int err;
842 913
843 if (spec->num_pins >= MAX_HDMI_PINS) { 914 if (spec->num_pins >= MAX_HDMI_PINS) {
844 snd_printk(KERN_WARNING 915 snd_printk(KERN_WARNING
@@ -846,28 +917,38 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
846 return -E2BIG; 917 return -E2BIG;
847 } 918 }
848 919
920 err = snd_hda_input_jack_add(codec, pin_nid,
921 SND_JACK_VIDEOOUT, NULL);
922 if (err < 0)
923 return err;
924
849 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]); 925 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
850 926
851 spec->pin[spec->num_pins] = pin_nid; 927 spec->pin[spec->num_pins] = pin_nid;
852 spec->num_pins++; 928 spec->num_pins++;
853 929
854 /*
855 * It is assumed that converter nodes come first in the node list and
856 * hence have been registered and usable now.
857 */
858 return hdmi_read_pin_conn(codec, pin_nid); 930 return hdmi_read_pin_conn(codec, pin_nid);
859} 931}
860 932
861static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid) 933static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
862{ 934{
935 int i, found_pin = 0;
863 struct hdmi_spec *spec = codec->spec; 936 struct hdmi_spec *spec = codec->spec;
864 937
865 if (spec->num_cvts >= MAX_HDMI_CVTS) { 938 for (i = 0; i < spec->num_pins; i++)
866 snd_printk(KERN_WARNING 939 if (nid == spec->pin_cvt[i]) {
867 "HDMI: no space for converter %d\n", nid); 940 found_pin = 1;
868 return -E2BIG; 941 break;
942 }
943
944 if (!found_pin) {
945 snd_printdd("HDMI: Skipping node %d (no connection)\n", nid);
946 return -EINVAL;
869 } 947 }
870 948
949 if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS))
950 return -E2BIG;
951
871 spec->cvt[spec->num_cvts] = nid; 952 spec->cvt[spec->num_cvts] = nid;
872 spec->num_cvts++; 953 spec->num_cvts++;
873 954
@@ -878,6 +959,8 @@ static int hdmi_parse_codec(struct hda_codec *codec)
878{ 959{
879 hda_nid_t nid; 960 hda_nid_t nid;
880 int i, nodes; 961 int i, nodes;
962 int num_tmp_cvts = 0;
963 hda_nid_t tmp_cvt[MAX_HDMI_CVTS];
881 964
882 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); 965 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
883 if (!nid || nodes < 0) { 966 if (!nid || nodes < 0) {
@@ -888,6 +971,7 @@ static int hdmi_parse_codec(struct hda_codec *codec)
888 for (i = 0; i < nodes; i++, nid++) { 971 for (i = 0; i < nodes; i++, nid++) {
889 unsigned int caps; 972 unsigned int caps;
890 unsigned int type; 973 unsigned int type;
974 unsigned int config;
891 975
892 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); 976 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
893 type = get_wcaps_type(caps); 977 type = get_wcaps_type(caps);
@@ -897,17 +981,32 @@ static int hdmi_parse_codec(struct hda_codec *codec)
897 981
898 switch (type) { 982 switch (type) {
899 case AC_WID_AUD_OUT: 983 case AC_WID_AUD_OUT:
900 hdmi_add_cvt(codec, nid); 984 if (num_tmp_cvts >= MAX_HDMI_CVTS) {
985 snd_printk(KERN_WARNING
986 "HDMI: no space for converter %d\n", nid);
987 continue;
988 }
989 tmp_cvt[num_tmp_cvts] = nid;
990 num_tmp_cvts++;
901 break; 991 break;
902 case AC_WID_PIN: 992 case AC_WID_PIN:
903 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); 993 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
904 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP))) 994 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
905 continue; 995 continue;
996
997 config = snd_hda_codec_read(codec, nid, 0,
998 AC_VERB_GET_CONFIG_DEFAULT, 0);
999 if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
1000 continue;
1001
906 hdmi_add_pin(codec, nid); 1002 hdmi_add_pin(codec, nid);
907 break; 1003 break;
908 } 1004 }
909 } 1005 }
910 1006
1007 for (i = 0; i < num_tmp_cvts; i++)
1008 hdmi_add_cvt(codec, tmp_cvt[i]);
1009
911 /* 1010 /*
912 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event 1011 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
913 * can be lost and presence sense verb will become inaccurate if the 1012 * can be lost and presence sense verb will become inaccurate if the
@@ -922,3 +1021,723 @@ static int hdmi_parse_codec(struct hda_codec *codec)
922 return 0; 1021 return 0;
923} 1022}
924 1023
1024/*
1025 */
1026static char *generic_hdmi_pcm_names[MAX_HDMI_CVTS] = {
1027 "HDMI 0",
1028 "HDMI 1",
1029 "HDMI 2",
1030 "HDMI 3",
1031};
1032
1033/*
1034 * HDMI callbacks
1035 */
1036
1037static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1038 struct hda_codec *codec,
1039 unsigned int stream_tag,
1040 unsigned int format,
1041 struct snd_pcm_substream *substream)
1042{
1043 hdmi_set_channel_count(codec, hinfo->nid,
1044 substream->runtime->channels);
1045
1046 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
1047
1048 return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
1049}
1050
1051static const struct hda_pcm_stream generic_hdmi_pcm_playback = {
1052 .substreams = 1,
1053 .channels_min = 2,
1054 .ops = {
1055 .open = hdmi_pcm_open,
1056 .prepare = generic_hdmi_playback_pcm_prepare,
1057 },
1058};
1059
1060static int generic_hdmi_build_pcms(struct hda_codec *codec)
1061{
1062 struct hdmi_spec *spec = codec->spec;
1063 struct hda_pcm *info = spec->pcm_rec;
1064 int i;
1065
1066 codec->num_pcms = spec->num_cvts;
1067 codec->pcm_info = info;
1068
1069 for (i = 0; i < codec->num_pcms; i++, info++) {
1070 unsigned int chans;
1071 struct hda_pcm_stream *pstr;
1072
1073 chans = get_wcaps(codec, spec->cvt[i]);
1074 chans = get_wcaps_channels(chans);
1075
1076 info->name = generic_hdmi_pcm_names[i];
1077 info->pcm_type = HDA_PCM_TYPE_HDMI;
1078 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
1079 if (spec->pcm_playback)
1080 *pstr = *spec->pcm_playback;
1081 else
1082 *pstr = generic_hdmi_pcm_playback;
1083 pstr->nid = spec->cvt[i];
1084 if (pstr->channels_max <= 2 && chans && chans <= 16)
1085 pstr->channels_max = chans;
1086 }
1087
1088 return 0;
1089}
1090
1091static int generic_hdmi_build_controls(struct hda_codec *codec)
1092{
1093 struct hdmi_spec *spec = codec->spec;
1094 int err;
1095 int i;
1096
1097 for (i = 0; i < codec->num_pcms; i++) {
1098 err = snd_hda_create_spdif_out_ctls(codec, spec->cvt[i]);
1099 if (err < 0)
1100 return err;
1101 }
1102
1103 return 0;
1104}
1105
1106static int generic_hdmi_init(struct hda_codec *codec)
1107{
1108 struct hdmi_spec *spec = codec->spec;
1109 int i;
1110
1111 for (i = 0; spec->pin[i]; i++) {
1112 hdmi_enable_output(codec, spec->pin[i]);
1113 snd_hda_codec_write(codec, spec->pin[i], 0,
1114 AC_VERB_SET_UNSOLICITED_ENABLE,
1115 AC_USRSP_EN | spec->pin[i]);
1116 }
1117 return 0;
1118}
1119
1120static void generic_hdmi_free(struct hda_codec *codec)
1121{
1122 struct hdmi_spec *spec = codec->spec;
1123 int i;
1124
1125 for (i = 0; i < spec->num_pins; i++)
1126 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
1127 snd_hda_input_jack_free(codec);
1128
1129 kfree(spec);
1130}
1131
1132static const struct hda_codec_ops generic_hdmi_patch_ops = {
1133 .init = generic_hdmi_init,
1134 .free = generic_hdmi_free,
1135 .build_pcms = generic_hdmi_build_pcms,
1136 .build_controls = generic_hdmi_build_controls,
1137 .unsol_event = hdmi_unsol_event,
1138};
1139
1140static int patch_generic_hdmi(struct hda_codec *codec)
1141{
1142 struct hdmi_spec *spec;
1143 int i;
1144
1145 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1146 if (spec == NULL)
1147 return -ENOMEM;
1148
1149 codec->spec = spec;
1150 if (hdmi_parse_codec(codec) < 0) {
1151 codec->spec = NULL;
1152 kfree(spec);
1153 return -EINVAL;
1154 }
1155 codec->patch_ops = generic_hdmi_patch_ops;
1156
1157 for (i = 0; i < spec->num_pins; i++)
1158 snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
1159
1160 init_channel_allocations();
1161
1162 return 0;
1163}
1164
1165/*
1166 * Nvidia specific implementations
1167 */
1168
1169#define Nv_VERB_SET_Channel_Allocation 0xF79
1170#define Nv_VERB_SET_Info_Frame_Checksum 0xF7A
1171#define Nv_VERB_SET_Audio_Protection_On 0xF98
1172#define Nv_VERB_SET_Audio_Protection_Off 0xF99
1173
1174#define nvhdmi_master_con_nid_7x 0x04
1175#define nvhdmi_master_pin_nid_7x 0x05
1176
1177static const hda_nid_t nvhdmi_con_nids_7x[4] = {
1178 /*front, rear, clfe, rear_surr */
1179 0x6, 0x8, 0xa, 0xc,
1180};
1181
1182static const struct hda_verb nvhdmi_basic_init_7x[] = {
1183 /* set audio protect on */
1184 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
1185 /* enable digital output on pin widget */
1186 { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
1187 { 0x7, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
1188 { 0x9, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
1189 { 0xb, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
1190 { 0xd, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
1191 {} /* terminator */
1192};
1193
1194#ifdef LIMITED_RATE_FMT_SUPPORT
1195/* support only the safe format and rate */
1196#define SUPPORTED_RATES SNDRV_PCM_RATE_48000
1197#define SUPPORTED_MAXBPS 16
1198#define SUPPORTED_FORMATS SNDRV_PCM_FMTBIT_S16_LE
1199#else
1200/* support all rates and formats */
1201#define SUPPORTED_RATES \
1202 (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
1203 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
1204 SNDRV_PCM_RATE_192000)
1205#define SUPPORTED_MAXBPS 24
1206#define SUPPORTED_FORMATS \
1207 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
1208#endif
1209
1210static int nvhdmi_7x_init(struct hda_codec *codec)
1211{
1212 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x);
1213 return 0;
1214}
1215
1216static unsigned int channels_2_6_8[] = {
1217 2, 6, 8
1218};
1219
1220static unsigned int channels_2_8[] = {
1221 2, 8
1222};
1223
1224static struct snd_pcm_hw_constraint_list hw_constraints_2_6_8_channels = {
1225 .count = ARRAY_SIZE(channels_2_6_8),
1226 .list = channels_2_6_8,
1227 .mask = 0,
1228};
1229
1230static struct snd_pcm_hw_constraint_list hw_constraints_2_8_channels = {
1231 .count = ARRAY_SIZE(channels_2_8),
1232 .list = channels_2_8,
1233 .mask = 0,
1234};
1235
1236static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo,
1237 struct hda_codec *codec,
1238 struct snd_pcm_substream *substream)
1239{
1240 struct hdmi_spec *spec = codec->spec;
1241 struct snd_pcm_hw_constraint_list *hw_constraints_channels = NULL;
1242
1243 switch (codec->preset->id) {
1244 case 0x10de0002:
1245 case 0x10de0003:
1246 case 0x10de0005:
1247 case 0x10de0006:
1248 hw_constraints_channels = &hw_constraints_2_8_channels;
1249 break;
1250 case 0x10de0007:
1251 hw_constraints_channels = &hw_constraints_2_6_8_channels;
1252 break;
1253 default:
1254 break;
1255 }
1256
1257 if (hw_constraints_channels != NULL) {
1258 snd_pcm_hw_constraint_list(substream->runtime, 0,
1259 SNDRV_PCM_HW_PARAM_CHANNELS,
1260 hw_constraints_channels);
1261 } else {
1262 snd_pcm_hw_constraint_step(substream->runtime, 0,
1263 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
1264 }
1265
1266 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1267}
1268
1269static int simple_playback_pcm_close(struct hda_pcm_stream *hinfo,
1270 struct hda_codec *codec,
1271 struct snd_pcm_substream *substream)
1272{
1273 struct hdmi_spec *spec = codec->spec;
1274 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1275}
1276
1277static int simple_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1278 struct hda_codec *codec,
1279 unsigned int stream_tag,
1280 unsigned int format,
1281 struct snd_pcm_substream *substream)
1282{
1283 struct hdmi_spec *spec = codec->spec;
1284 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1285 stream_tag, format, substream);
1286}
1287
1288static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec,
1289 int channels)
1290{
1291 unsigned int chanmask;
1292 int chan = channels ? (channels - 1) : 1;
1293
1294 switch (channels) {
1295 default:
1296 case 0:
1297 case 2:
1298 chanmask = 0x00;
1299 break;
1300 case 4:
1301 chanmask = 0x08;
1302 break;
1303 case 6:
1304 chanmask = 0x0b;
1305 break;
1306 case 8:
1307 chanmask = 0x13;
1308 break;
1309 }
1310
1311 /* Set the audio infoframe channel allocation and checksum fields. The
1312 * channel count is computed implicitly by the hardware. */
1313 snd_hda_codec_write(codec, 0x1, 0,
1314 Nv_VERB_SET_Channel_Allocation, chanmask);
1315
1316 snd_hda_codec_write(codec, 0x1, 0,
1317 Nv_VERB_SET_Info_Frame_Checksum,
1318 (0x71 - chan - chanmask));
1319}
1320
1321static int nvhdmi_8ch_7x_pcm_close(struct hda_pcm_stream *hinfo,
1322 struct hda_codec *codec,
1323 struct snd_pcm_substream *substream)
1324{
1325 struct hdmi_spec *spec = codec->spec;
1326 int i;
1327
1328 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
1329 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
1330 for (i = 0; i < 4; i++) {
1331 /* set the stream id */
1332 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
1333 AC_VERB_SET_CHANNEL_STREAMID, 0);
1334 /* set the stream format */
1335 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
1336 AC_VERB_SET_STREAM_FORMAT, 0);
1337 }
1338
1339 /* The audio hardware sends a channel count of 0x7 (8ch) when all the
1340 * streams are disabled. */
1341 nvhdmi_8ch_7x_set_info_frame_parameters(codec, 8);
1342
1343 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1344}
1345
1346static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1347 struct hda_codec *codec,
1348 unsigned int stream_tag,
1349 unsigned int format,
1350 struct snd_pcm_substream *substream)
1351{
1352 int chs;
1353 unsigned int dataDCC1, dataDCC2, channel_id;
1354 int i;
1355
1356 mutex_lock(&codec->spdif_mutex);
1357
1358 chs = substream->runtime->channels;
1359
1360 dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT;
1361 dataDCC2 = 0x2;
1362
1363 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
1364 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
1365 snd_hda_codec_write(codec,
1366 nvhdmi_master_con_nid_7x,
1367 0,
1368 AC_VERB_SET_DIGI_CONVERT_1,
1369 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
1370
1371 /* set the stream id */
1372 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
1373 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
1374
1375 /* set the stream format */
1376 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
1377 AC_VERB_SET_STREAM_FORMAT, format);
1378
1379 /* turn on again (if needed) */
1380 /* enable and set the channel status audio/data flag */
1381 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
1382 snd_hda_codec_write(codec,
1383 nvhdmi_master_con_nid_7x,
1384 0,
1385 AC_VERB_SET_DIGI_CONVERT_1,
1386 codec->spdif_ctls & 0xff);
1387 snd_hda_codec_write(codec,
1388 nvhdmi_master_con_nid_7x,
1389 0,
1390 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
1391 }
1392
1393 for (i = 0; i < 4; i++) {
1394 if (chs == 2)
1395 channel_id = 0;
1396 else
1397 channel_id = i * 2;
1398
1399 /* turn off SPDIF once;
1400 *otherwise the IEC958 bits won't be updated
1401 */
1402 if (codec->spdif_status_reset &&
1403 (codec->spdif_ctls & AC_DIG1_ENABLE))
1404 snd_hda_codec_write(codec,
1405 nvhdmi_con_nids_7x[i],
1406 0,
1407 AC_VERB_SET_DIGI_CONVERT_1,
1408 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
1409 /* set the stream id */
1410 snd_hda_codec_write(codec,
1411 nvhdmi_con_nids_7x[i],
1412 0,
1413 AC_VERB_SET_CHANNEL_STREAMID,
1414 (stream_tag << 4) | channel_id);
1415 /* set the stream format */
1416 snd_hda_codec_write(codec,
1417 nvhdmi_con_nids_7x[i],
1418 0,
1419 AC_VERB_SET_STREAM_FORMAT,
1420 format);
1421 /* turn on again (if needed) */
1422 /* enable and set the channel status audio/data flag */
1423 if (codec->spdif_status_reset &&
1424 (codec->spdif_ctls & AC_DIG1_ENABLE)) {
1425 snd_hda_codec_write(codec,
1426 nvhdmi_con_nids_7x[i],
1427 0,
1428 AC_VERB_SET_DIGI_CONVERT_1,
1429 codec->spdif_ctls & 0xff);
1430 snd_hda_codec_write(codec,
1431 nvhdmi_con_nids_7x[i],
1432 0,
1433 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
1434 }
1435 }
1436
1437 nvhdmi_8ch_7x_set_info_frame_parameters(codec, chs);
1438
1439 mutex_unlock(&codec->spdif_mutex);
1440 return 0;
1441}
1442
1443static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = {
1444 .substreams = 1,
1445 .channels_min = 2,
1446 .channels_max = 8,
1447 .nid = nvhdmi_master_con_nid_7x,
1448 .rates = SUPPORTED_RATES,
1449 .maxbps = SUPPORTED_MAXBPS,
1450 .formats = SUPPORTED_FORMATS,
1451 .ops = {
1452 .open = simple_playback_pcm_open,
1453 .close = nvhdmi_8ch_7x_pcm_close,
1454 .prepare = nvhdmi_8ch_7x_pcm_prepare
1455 },
1456};
1457
1458static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = {
1459 .substreams = 1,
1460 .channels_min = 2,
1461 .channels_max = 2,
1462 .nid = nvhdmi_master_con_nid_7x,
1463 .rates = SUPPORTED_RATES,
1464 .maxbps = SUPPORTED_MAXBPS,
1465 .formats = SUPPORTED_FORMATS,
1466 .ops = {
1467 .open = simple_playback_pcm_open,
1468 .close = simple_playback_pcm_close,
1469 .prepare = simple_playback_pcm_prepare
1470 },
1471};
1472
1473static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
1474 .build_controls = generic_hdmi_build_controls,
1475 .build_pcms = generic_hdmi_build_pcms,
1476 .init = nvhdmi_7x_init,
1477 .free = generic_hdmi_free,
1478};
1479
1480static const struct hda_codec_ops nvhdmi_patch_ops_2ch = {
1481 .build_controls = generic_hdmi_build_controls,
1482 .build_pcms = generic_hdmi_build_pcms,
1483 .init = nvhdmi_7x_init,
1484 .free = generic_hdmi_free,
1485};
1486
1487static int patch_nvhdmi_2ch(struct hda_codec *codec)
1488{
1489 struct hdmi_spec *spec;
1490
1491 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1492 if (spec == NULL)
1493 return -ENOMEM;
1494
1495 codec->spec = spec;
1496
1497 spec->multiout.num_dacs = 0; /* no analog */
1498 spec->multiout.max_channels = 2;
1499 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
1500 spec->num_cvts = 1;
1501 spec->cvt[0] = nvhdmi_master_con_nid_7x;
1502 spec->pcm_playback = &nvhdmi_pcm_playback_2ch;
1503
1504 codec->patch_ops = nvhdmi_patch_ops_2ch;
1505
1506 return 0;
1507}
1508
1509static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
1510{
1511 struct hdmi_spec *spec;
1512 int err = patch_nvhdmi_2ch(codec);
1513
1514 if (err < 0)
1515 return err;
1516 spec = codec->spec;
1517 spec->multiout.max_channels = 8;
1518 spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x;
1519 codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
1520
1521 /* Initialize the audio infoframe channel mask and checksum to something
1522 * valid */
1523 nvhdmi_8ch_7x_set_info_frame_parameters(codec, 8);
1524
1525 return 0;
1526}
1527
1528/*
1529 * ATI-specific implementations
1530 *
1531 * FIXME: we may omit the whole this and use the generic code once after
1532 * it's confirmed to work.
1533 */
1534
1535#define ATIHDMI_CVT_NID 0x02 /* audio converter */
1536#define ATIHDMI_PIN_NID 0x03 /* HDMI output pin */
1537
1538static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1539 struct hda_codec *codec,
1540 unsigned int stream_tag,
1541 unsigned int format,
1542 struct snd_pcm_substream *substream)
1543{
1544 struct hdmi_spec *spec = codec->spec;
1545 int chans = substream->runtime->channels;
1546 int i, err;
1547
1548 err = simple_playback_pcm_prepare(hinfo, codec, stream_tag, format,
1549 substream);
1550 if (err < 0)
1551 return err;
1552 snd_hda_codec_write(codec, spec->cvt[0], 0, AC_VERB_SET_CVT_CHAN_COUNT,
1553 chans - 1);
1554 /* FIXME: XXX */
1555 for (i = 0; i < chans; i++) {
1556 snd_hda_codec_write(codec, spec->cvt[0], 0,
1557 AC_VERB_SET_HDMI_CHAN_SLOT,
1558 (i << 4) | i);
1559 }
1560 return 0;
1561}
1562
1563static const struct hda_pcm_stream atihdmi_pcm_digital_playback = {
1564 .substreams = 1,
1565 .channels_min = 2,
1566 .channels_max = 2,
1567 .nid = ATIHDMI_CVT_NID,
1568 .ops = {
1569 .open = simple_playback_pcm_open,
1570 .close = simple_playback_pcm_close,
1571 .prepare = atihdmi_playback_pcm_prepare
1572 },
1573};
1574
1575static const struct hda_verb atihdmi_basic_init[] = {
1576 /* enable digital output on pin widget */
1577 { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1578 {} /* terminator */
1579};
1580
1581static int atihdmi_init(struct hda_codec *codec)
1582{
1583 struct hdmi_spec *spec = codec->spec;
1584
1585 snd_hda_sequence_write(codec, atihdmi_basic_init);
1586 /* SI codec requires to unmute the pin */
1587 if (get_wcaps(codec, spec->pin[0]) & AC_WCAP_OUT_AMP)
1588 snd_hda_codec_write(codec, spec->pin[0], 0,
1589 AC_VERB_SET_AMP_GAIN_MUTE,
1590 AMP_OUT_UNMUTE);
1591 return 0;
1592}
1593
1594static const struct hda_codec_ops atihdmi_patch_ops = {
1595 .build_controls = generic_hdmi_build_controls,
1596 .build_pcms = generic_hdmi_build_pcms,
1597 .init = atihdmi_init,
1598 .free = generic_hdmi_free,
1599};
1600
1601
1602static int patch_atihdmi(struct hda_codec *codec)
1603{
1604 struct hdmi_spec *spec;
1605
1606 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1607 if (spec == NULL)
1608 return -ENOMEM;
1609
1610 codec->spec = spec;
1611
1612 spec->multiout.num_dacs = 0; /* no analog */
1613 spec->multiout.max_channels = 2;
1614 spec->multiout.dig_out_nid = ATIHDMI_CVT_NID;
1615 spec->num_cvts = 1;
1616 spec->cvt[0] = ATIHDMI_CVT_NID;
1617 spec->pin[0] = ATIHDMI_PIN_NID;
1618 spec->pcm_playback = &atihdmi_pcm_digital_playback;
1619
1620 codec->patch_ops = atihdmi_patch_ops;
1621
1622 return 0;
1623}
1624
1625
1626/*
1627 * patch entries
1628 */
1629static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
1630{ .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
1631{ .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
1632{ .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
1633{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_generic_hdmi },
1634{ .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_generic_hdmi },
1635{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_generic_hdmi },
1636{ .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_generic_hdmi },
1637{ .id = 0x10de0002, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
1638{ .id = 0x10de0003, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
1639{ .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
1640{ .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
1641{ .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x },
1642{ .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_generic_hdmi },
1643{ .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_generic_hdmi },
1644{ .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_generic_hdmi },
1645{ .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_generic_hdmi },
1646{ .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_generic_hdmi },
1647{ .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_generic_hdmi },
1648{ .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_generic_hdmi },
1649{ .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_generic_hdmi },
1650{ .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_generic_hdmi },
1651{ .id = 0x10de0015, .name = "GPU 15 HDMI/DP", .patch = patch_generic_hdmi },
1652{ .id = 0x10de0016, .name = "GPU 16 HDMI/DP", .patch = patch_generic_hdmi },
1653/* 17 is known to be absent */
1654{ .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_generic_hdmi },
1655{ .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_generic_hdmi },
1656{ .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_generic_hdmi },
1657{ .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_generic_hdmi },
1658{ .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_generic_hdmi },
1659{ .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_generic_hdmi },
1660{ .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_generic_hdmi },
1661{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi },
1662{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi },
1663{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi },
1664{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
1665{ .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
1666{ .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
1667{ .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_generic_hdmi },
1668{ .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_generic_hdmi },
1669{ .id = 0x80862803, .name = "Eaglelake HDMI", .patch = patch_generic_hdmi },
1670{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
1671{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi },
1672{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi },
1673{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi },
1674{} /* terminator */
1675};
1676
1677MODULE_ALIAS("snd-hda-codec-id:1002793c");
1678MODULE_ALIAS("snd-hda-codec-id:10027919");
1679MODULE_ALIAS("snd-hda-codec-id:1002791a");
1680MODULE_ALIAS("snd-hda-codec-id:1002aa01");
1681MODULE_ALIAS("snd-hda-codec-id:10951390");
1682MODULE_ALIAS("snd-hda-codec-id:10951392");
1683MODULE_ALIAS("snd-hda-codec-id:10de0002");
1684MODULE_ALIAS("snd-hda-codec-id:10de0003");
1685MODULE_ALIAS("snd-hda-codec-id:10de0005");
1686MODULE_ALIAS("snd-hda-codec-id:10de0006");
1687MODULE_ALIAS("snd-hda-codec-id:10de0007");
1688MODULE_ALIAS("snd-hda-codec-id:10de000a");
1689MODULE_ALIAS("snd-hda-codec-id:10de000b");
1690MODULE_ALIAS("snd-hda-codec-id:10de000c");
1691MODULE_ALIAS("snd-hda-codec-id:10de000d");
1692MODULE_ALIAS("snd-hda-codec-id:10de0010");
1693MODULE_ALIAS("snd-hda-codec-id:10de0011");
1694MODULE_ALIAS("snd-hda-codec-id:10de0012");
1695MODULE_ALIAS("snd-hda-codec-id:10de0013");
1696MODULE_ALIAS("snd-hda-codec-id:10de0014");
1697MODULE_ALIAS("snd-hda-codec-id:10de0015");
1698MODULE_ALIAS("snd-hda-codec-id:10de0016");
1699MODULE_ALIAS("snd-hda-codec-id:10de0018");
1700MODULE_ALIAS("snd-hda-codec-id:10de0019");
1701MODULE_ALIAS("snd-hda-codec-id:10de001a");
1702MODULE_ALIAS("snd-hda-codec-id:10de001b");
1703MODULE_ALIAS("snd-hda-codec-id:10de001c");
1704MODULE_ALIAS("snd-hda-codec-id:10de0040");
1705MODULE_ALIAS("snd-hda-codec-id:10de0041");
1706MODULE_ALIAS("snd-hda-codec-id:10de0042");
1707MODULE_ALIAS("snd-hda-codec-id:10de0043");
1708MODULE_ALIAS("snd-hda-codec-id:10de0044");
1709MODULE_ALIAS("snd-hda-codec-id:10de0067");
1710MODULE_ALIAS("snd-hda-codec-id:10de8001");
1711MODULE_ALIAS("snd-hda-codec-id:17e80047");
1712MODULE_ALIAS("snd-hda-codec-id:80860054");
1713MODULE_ALIAS("snd-hda-codec-id:80862801");
1714MODULE_ALIAS("snd-hda-codec-id:80862802");
1715MODULE_ALIAS("snd-hda-codec-id:80862803");
1716MODULE_ALIAS("snd-hda-codec-id:80862804");
1717MODULE_ALIAS("snd-hda-codec-id:80862805");
1718MODULE_ALIAS("snd-hda-codec-id:80862806");
1719MODULE_ALIAS("snd-hda-codec-id:808629fb");
1720
1721MODULE_LICENSE("GPL");
1722MODULE_DESCRIPTION("HDMI HD-audio codec");
1723MODULE_ALIAS("snd-hda-codec-intelhdmi");
1724MODULE_ALIAS("snd-hda-codec-nvhdmi");
1725MODULE_ALIAS("snd-hda-codec-atihdmi");
1726
1727static struct hda_codec_preset_list intel_list = {
1728 .preset = snd_hda_preset_hdmi,
1729 .owner = THIS_MODULE,
1730};
1731
1732static int __init patch_hdmi_init(void)
1733{
1734 return snd_hda_add_codec_preset(&intel_list);
1735}
1736
1737static void __exit patch_hdmi_exit(void)
1738{
1739 snd_hda_delete_codec_preset(&intel_list);
1740}
1741
1742module_init(patch_hdmi_init)
1743module_exit(patch_hdmi_exit)
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
deleted file mode 100644
index 36a9b83a6174..000000000000
--- a/sound/pci/hda/patch_intelhdmi.c
+++ /dev/null
@@ -1,220 +0,0 @@
1/*
2 *
3 * patch_intelhdmi.c - Patch for Intel HDMI codecs
4 *
5 * Copyright(c) 2008 Intel Corporation. All rights reserved.
6 *
7 * Authors:
8 * Jiang Zhe <zhe.jiang@intel.com>
9 * Wu Fengguang <wfg@linux.intel.com>
10 *
11 * Maintained by:
12 * Wu Fengguang <wfg@linux.intel.com>
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the Free
16 * Software Foundation; either version 2 of the License, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/slab.h>
32#include <sound/core.h>
33#include "hda_codec.h"
34#include "hda_local.h"
35
36/*
37 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
38 * could support two independent pipes, each of them can be connected to one or
39 * more ports (DVI, HDMI or DisplayPort).
40 *
41 * The HDA correspondence of pipes/ports are converter/pin nodes.
42 */
43#define MAX_HDMI_CVTS 3
44#define MAX_HDMI_PINS 3
45
46#include "patch_hdmi.c"
47
48static char *intel_hdmi_pcm_names[MAX_HDMI_CVTS] = {
49 "INTEL HDMI 0",
50 "INTEL HDMI 1",
51 "INTEL HDMI 2",
52};
53
54/*
55 * HDMI callbacks
56 */
57
58static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
59 struct hda_codec *codec,
60 unsigned int stream_tag,
61 unsigned int format,
62 struct snd_pcm_substream *substream)
63{
64 hdmi_set_channel_count(codec, hinfo->nid,
65 substream->runtime->channels);
66
67 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
68
69 return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
70}
71
72static struct hda_pcm_stream intel_hdmi_pcm_playback = {
73 .substreams = 1,
74 .channels_min = 2,
75 .ops = {
76 .open = hdmi_pcm_open,
77 .prepare = intel_hdmi_playback_pcm_prepare,
78 },
79};
80
81static int intel_hdmi_build_pcms(struct hda_codec *codec)
82{
83 struct hdmi_spec *spec = codec->spec;
84 struct hda_pcm *info = spec->pcm_rec;
85 int i;
86
87 codec->num_pcms = spec->num_cvts;
88 codec->pcm_info = info;
89
90 for (i = 0; i < codec->num_pcms; i++, info++) {
91 unsigned int chans;
92
93 chans = get_wcaps(codec, spec->cvt[i]);
94 chans = get_wcaps_channels(chans);
95
96 info->name = intel_hdmi_pcm_names[i];
97 info->pcm_type = HDA_PCM_TYPE_HDMI;
98 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
99 intel_hdmi_pcm_playback;
100 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
101 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
102 }
103
104 return 0;
105}
106
107static int intel_hdmi_build_controls(struct hda_codec *codec)
108{
109 struct hdmi_spec *spec = codec->spec;
110 int err;
111 int i;
112
113 for (i = 0; i < codec->num_pcms; i++) {
114 err = snd_hda_create_spdif_out_ctls(codec, spec->cvt[i]);
115 if (err < 0)
116 return err;
117 }
118
119 return 0;
120}
121
122static int intel_hdmi_init(struct hda_codec *codec)
123{
124 struct hdmi_spec *spec = codec->spec;
125 int i;
126
127 for (i = 0; spec->pin[i]; i++) {
128 hdmi_enable_output(codec, spec->pin[i]);
129 snd_hda_codec_write(codec, spec->pin[i], 0,
130 AC_VERB_SET_UNSOLICITED_ENABLE,
131 AC_USRSP_EN | spec->pin[i]);
132 }
133 return 0;
134}
135
136static void intel_hdmi_free(struct hda_codec *codec)
137{
138 struct hdmi_spec *spec = codec->spec;
139 int i;
140
141 for (i = 0; i < spec->num_pins; i++)
142 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
143
144 kfree(spec);
145}
146
147static struct hda_codec_ops intel_hdmi_patch_ops = {
148 .init = intel_hdmi_init,
149 .free = intel_hdmi_free,
150 .build_pcms = intel_hdmi_build_pcms,
151 .build_controls = intel_hdmi_build_controls,
152 .unsol_event = hdmi_unsol_event,
153};
154
155static int patch_intel_hdmi(struct hda_codec *codec)
156{
157 struct hdmi_spec *spec;
158 int i;
159
160 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
161 if (spec == NULL)
162 return -ENOMEM;
163
164 codec->spec = spec;
165 if (hdmi_parse_codec(codec) < 0) {
166 codec->spec = NULL;
167 kfree(spec);
168 return -EINVAL;
169 }
170 codec->patch_ops = intel_hdmi_patch_ops;
171
172 for (i = 0; i < spec->num_pins; i++)
173 snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
174
175 init_channel_allocations();
176
177 return 0;
178}
179
180static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
181{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_intel_hdmi },
182{ .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_intel_hdmi },
183{ .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_intel_hdmi },
184{ .id = 0x80862803, .name = "Eaglelake HDMI", .patch = patch_intel_hdmi },
185{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_intel_hdmi },
186{ .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_intel_hdmi },
187{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_intel_hdmi },
188{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
189{} /* terminator */
190};
191
192MODULE_ALIAS("snd-hda-codec-id:808629fb");
193MODULE_ALIAS("snd-hda-codec-id:80862801");
194MODULE_ALIAS("snd-hda-codec-id:80862802");
195MODULE_ALIAS("snd-hda-codec-id:80862803");
196MODULE_ALIAS("snd-hda-codec-id:80862804");
197MODULE_ALIAS("snd-hda-codec-id:80862805");
198MODULE_ALIAS("snd-hda-codec-id:80860054");
199MODULE_ALIAS("snd-hda-codec-id:10951392");
200
201MODULE_LICENSE("GPL");
202MODULE_DESCRIPTION("Intel HDMI HD-audio codec");
203
204static struct hda_codec_preset_list intel_list = {
205 .preset = snd_hda_preset_intelhdmi,
206 .owner = THIS_MODULE,
207};
208
209static int __init patch_intelhdmi_init(void)
210{
211 return snd_hda_add_codec_preset(&intel_list);
212}
213
214static void __exit patch_intelhdmi_exit(void)
215{
216 snd_hda_delete_codec_preset(&intel_list);
217}
218
219module_init(patch_intelhdmi_init)
220module_exit(patch_intelhdmi_exit)
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
deleted file mode 100644
index baa108b9d6aa..000000000000
--- a/sound/pci/hda/patch_nvhdmi.c
+++ /dev/null
@@ -1,608 +0,0 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for NVIDIA HDMI codecs
5 *
6 * Copyright (c) 2008 NVIDIA Corp. All rights reserved.
7 * Copyright (c) 2008 Wei Ni <wni@nvidia.com>
8 *
9 *
10 * This driver is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This driver is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/slab.h>
28#include <sound/core.h>
29#include "hda_codec.h"
30#include "hda_local.h"
31
32#define MAX_HDMI_CVTS 1
33#define MAX_HDMI_PINS 1
34
35#include "patch_hdmi.c"
36
37static char *nvhdmi_pcm_names[MAX_HDMI_CVTS] = {
38 "NVIDIA HDMI",
39};
40
41/* define below to restrict the supported rates and formats */
42/* #define LIMITED_RATE_FMT_SUPPORT */
43
44enum HDACodec {
45 HDA_CODEC_NVIDIA_MCP7X,
46 HDA_CODEC_NVIDIA_MCP89,
47 HDA_CODEC_NVIDIA_GT21X,
48 HDA_CODEC_INVALID
49};
50
51#define Nv_VERB_SET_Channel_Allocation 0xF79
52#define Nv_VERB_SET_Info_Frame_Checksum 0xF7A
53#define Nv_VERB_SET_Audio_Protection_On 0xF98
54#define Nv_VERB_SET_Audio_Protection_Off 0xF99
55
56#define nvhdmi_master_con_nid_7x 0x04
57#define nvhdmi_master_pin_nid_7x 0x05
58
59#define nvhdmi_master_con_nid_89 0x04
60#define nvhdmi_master_pin_nid_89 0x05
61
62static hda_nid_t nvhdmi_con_nids_7x[4] = {
63 /*front, rear, clfe, rear_surr */
64 0x6, 0x8, 0xa, 0xc,
65};
66
67static struct hda_verb nvhdmi_basic_init_7x[] = {
68 /* set audio protect on */
69 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
70 /* enable digital output on pin widget */
71 { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
72 { 0x7, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
73 { 0x9, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
74 { 0xb, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
75 { 0xd, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
76 {} /* terminator */
77};
78
79#ifdef LIMITED_RATE_FMT_SUPPORT
80/* support only the safe format and rate */
81#define SUPPORTED_RATES SNDRV_PCM_RATE_48000
82#define SUPPORTED_MAXBPS 16
83#define SUPPORTED_FORMATS SNDRV_PCM_FMTBIT_S16_LE
84#else
85/* support all rates and formats */
86#define SUPPORTED_RATES \
87 (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
88 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
89 SNDRV_PCM_RATE_192000)
90#define SUPPORTED_MAXBPS 24
91#define SUPPORTED_FORMATS \
92 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
93#endif
94
95/*
96 * Controls
97 */
98static int nvhdmi_build_controls(struct hda_codec *codec)
99{
100 struct hdmi_spec *spec = codec->spec;
101 int err;
102 int i;
103
104 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
105 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
106 for (i = 0; i < codec->num_pcms; i++) {
107 err = snd_hda_create_spdif_out_ctls(codec,
108 spec->cvt[i]);
109 if (err < 0)
110 return err;
111 }
112 } else {
113 err = snd_hda_create_spdif_out_ctls(codec,
114 spec->multiout.dig_out_nid);
115 if (err < 0)
116 return err;
117 }
118
119 return 0;
120}
121
122static int nvhdmi_init(struct hda_codec *codec)
123{
124 struct hdmi_spec *spec = codec->spec;
125 int i;
126 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
127 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
128 for (i = 0; spec->pin[i]; i++) {
129 hdmi_enable_output(codec, spec->pin[i]);
130 snd_hda_codec_write(codec, spec->pin[i], 0,
131 AC_VERB_SET_UNSOLICITED_ENABLE,
132 AC_USRSP_EN | spec->pin[i]);
133 }
134 } else {
135 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x);
136 }
137 return 0;
138}
139
140static void nvhdmi_free(struct hda_codec *codec)
141{
142 struct hdmi_spec *spec = codec->spec;
143 int i;
144
145 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
146 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
147 for (i = 0; i < spec->num_pins; i++)
148 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
149 }
150
151 kfree(spec);
152}
153
154/*
155 * Digital out
156 */
157static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
158 struct hda_codec *codec,
159 struct snd_pcm_substream *substream)
160{
161 struct hdmi_spec *spec = codec->spec;
162 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
163}
164
165static int nvhdmi_dig_playback_pcm_close_8ch_7x(struct hda_pcm_stream *hinfo,
166 struct hda_codec *codec,
167 struct snd_pcm_substream *substream)
168{
169 struct hdmi_spec *spec = codec->spec;
170 int i;
171
172 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
173 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
174 for (i = 0; i < 4; i++) {
175 /* set the stream id */
176 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
177 AC_VERB_SET_CHANNEL_STREAMID, 0);
178 /* set the stream format */
179 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
180 AC_VERB_SET_STREAM_FORMAT, 0);
181 }
182
183 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
184}
185
186static int nvhdmi_dig_playback_pcm_close_2ch(struct hda_pcm_stream *hinfo,
187 struct hda_codec *codec,
188 struct snd_pcm_substream *substream)
189{
190 struct hdmi_spec *spec = codec->spec;
191 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
192}
193
194static int nvhdmi_dig_playback_pcm_prepare_8ch_89(struct hda_pcm_stream *hinfo,
195 struct hda_codec *codec,
196 unsigned int stream_tag,
197 unsigned int format,
198 struct snd_pcm_substream *substream)
199{
200 hdmi_set_channel_count(codec, hinfo->nid,
201 substream->runtime->channels);
202
203 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
204
205 return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
206}
207
208static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
209 struct hda_codec *codec,
210 unsigned int stream_tag,
211 unsigned int format,
212 struct snd_pcm_substream *substream)
213{
214 int chs;
215 unsigned int dataDCC1, dataDCC2, chan, chanmask, channel_id;
216 int i;
217
218 mutex_lock(&codec->spdif_mutex);
219
220 chs = substream->runtime->channels;
221 chan = chs ? (chs - 1) : 1;
222
223 switch (chs) {
224 default:
225 case 0:
226 case 2:
227 chanmask = 0x00;
228 break;
229 case 4:
230 chanmask = 0x08;
231 break;
232 case 6:
233 chanmask = 0x0b;
234 break;
235 case 8:
236 chanmask = 0x13;
237 break;
238 }
239 dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT;
240 dataDCC2 = 0x2;
241
242 /* set the Audio InforFrame Channel Allocation */
243 snd_hda_codec_write(codec, 0x1, 0,
244 Nv_VERB_SET_Channel_Allocation, chanmask);
245
246 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
247 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
248 snd_hda_codec_write(codec,
249 nvhdmi_master_con_nid_7x,
250 0,
251 AC_VERB_SET_DIGI_CONVERT_1,
252 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
253
254 /* set the stream id */
255 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
256 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
257
258 /* set the stream format */
259 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
260 AC_VERB_SET_STREAM_FORMAT, format);
261
262 /* turn on again (if needed) */
263 /* enable and set the channel status audio/data flag */
264 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
265 snd_hda_codec_write(codec,
266 nvhdmi_master_con_nid_7x,
267 0,
268 AC_VERB_SET_DIGI_CONVERT_1,
269 codec->spdif_ctls & 0xff);
270 snd_hda_codec_write(codec,
271 nvhdmi_master_con_nid_7x,
272 0,
273 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
274 }
275
276 for (i = 0; i < 4; i++) {
277 if (chs == 2)
278 channel_id = 0;
279 else
280 channel_id = i * 2;
281
282 /* turn off SPDIF once;
283 *otherwise the IEC958 bits won't be updated
284 */
285 if (codec->spdif_status_reset &&
286 (codec->spdif_ctls & AC_DIG1_ENABLE))
287 snd_hda_codec_write(codec,
288 nvhdmi_con_nids_7x[i],
289 0,
290 AC_VERB_SET_DIGI_CONVERT_1,
291 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
292 /* set the stream id */
293 snd_hda_codec_write(codec,
294 nvhdmi_con_nids_7x[i],
295 0,
296 AC_VERB_SET_CHANNEL_STREAMID,
297 (stream_tag << 4) | channel_id);
298 /* set the stream format */
299 snd_hda_codec_write(codec,
300 nvhdmi_con_nids_7x[i],
301 0,
302 AC_VERB_SET_STREAM_FORMAT,
303 format);
304 /* turn on again (if needed) */
305 /* enable and set the channel status audio/data flag */
306 if (codec->spdif_status_reset &&
307 (codec->spdif_ctls & AC_DIG1_ENABLE)) {
308 snd_hda_codec_write(codec,
309 nvhdmi_con_nids_7x[i],
310 0,
311 AC_VERB_SET_DIGI_CONVERT_1,
312 codec->spdif_ctls & 0xff);
313 snd_hda_codec_write(codec,
314 nvhdmi_con_nids_7x[i],
315 0,
316 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
317 }
318 }
319
320 /* set the Audio Info Frame Checksum */
321 snd_hda_codec_write(codec, 0x1, 0,
322 Nv_VERB_SET_Info_Frame_Checksum,
323 (0x71 - chan - chanmask));
324
325 mutex_unlock(&codec->spdif_mutex);
326 return 0;
327}
328
329static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo,
330 struct hda_codec *codec,
331 unsigned int stream_tag,
332 unsigned int format,
333 struct snd_pcm_substream *substream)
334{
335 struct hdmi_spec *spec = codec->spec;
336 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
337 format, substream);
338}
339
340static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_89 = {
341 .substreams = 1,
342 .channels_min = 2,
343 .ops = {
344 .open = hdmi_pcm_open,
345 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89,
346 },
347};
348
349static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_7x = {
350 .substreams = 1,
351 .channels_min = 2,
352 .channels_max = 8,
353 .nid = nvhdmi_master_con_nid_7x,
354 .rates = SUPPORTED_RATES,
355 .maxbps = SUPPORTED_MAXBPS,
356 .formats = SUPPORTED_FORMATS,
357 .ops = {
358 .open = nvhdmi_dig_playback_pcm_open,
359 .close = nvhdmi_dig_playback_pcm_close_8ch_7x,
360 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch
361 },
362};
363
364static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
365 .substreams = 1,
366 .channels_min = 2,
367 .channels_max = 2,
368 .nid = nvhdmi_master_con_nid_7x,
369 .rates = SUPPORTED_RATES,
370 .maxbps = SUPPORTED_MAXBPS,
371 .formats = SUPPORTED_FORMATS,
372 .ops = {
373 .open = nvhdmi_dig_playback_pcm_open,
374 .close = nvhdmi_dig_playback_pcm_close_2ch,
375 .prepare = nvhdmi_dig_playback_pcm_prepare_2ch
376 },
377};
378
379static int nvhdmi_build_pcms_8ch_89(struct hda_codec *codec)
380{
381 struct hdmi_spec *spec = codec->spec;
382 struct hda_pcm *info = spec->pcm_rec;
383 int i;
384
385 codec->num_pcms = spec->num_cvts;
386 codec->pcm_info = info;
387
388 for (i = 0; i < codec->num_pcms; i++, info++) {
389 unsigned int chans;
390
391 chans = get_wcaps(codec, spec->cvt[i]);
392 chans = get_wcaps_channels(chans);
393
394 info->name = nvhdmi_pcm_names[i];
395 info->pcm_type = HDA_PCM_TYPE_HDMI;
396 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
397 = nvhdmi_pcm_digital_playback_8ch_89;
398 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
399 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
400 }
401
402 return 0;
403}
404
405static int nvhdmi_build_pcms_8ch_7x(struct hda_codec *codec)
406{
407 struct hdmi_spec *spec = codec->spec;
408 struct hda_pcm *info = spec->pcm_rec;
409
410 codec->num_pcms = 1;
411 codec->pcm_info = info;
412
413 info->name = "NVIDIA HDMI";
414 info->pcm_type = HDA_PCM_TYPE_HDMI;
415 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
416 = nvhdmi_pcm_digital_playback_8ch_7x;
417
418 return 0;
419}
420
421static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
422{
423 struct hdmi_spec *spec = codec->spec;
424 struct hda_pcm *info = spec->pcm_rec;
425
426 codec->num_pcms = 1;
427 codec->pcm_info = info;
428
429 info->name = "NVIDIA HDMI";
430 info->pcm_type = HDA_PCM_TYPE_HDMI;
431 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
432 = nvhdmi_pcm_digital_playback_2ch;
433
434 return 0;
435}
436
437static struct hda_codec_ops nvhdmi_patch_ops_8ch_89 = {
438 .build_controls = nvhdmi_build_controls,
439 .build_pcms = nvhdmi_build_pcms_8ch_89,
440 .init = nvhdmi_init,
441 .free = nvhdmi_free,
442 .unsol_event = hdmi_unsol_event,
443};
444
445static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
446 .build_controls = nvhdmi_build_controls,
447 .build_pcms = nvhdmi_build_pcms_8ch_7x,
448 .init = nvhdmi_init,
449 .free = nvhdmi_free,
450};
451
452static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
453 .build_controls = nvhdmi_build_controls,
454 .build_pcms = nvhdmi_build_pcms_2ch,
455 .init = nvhdmi_init,
456 .free = nvhdmi_free,
457};
458
459static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
460{
461 struct hdmi_spec *spec;
462 int i;
463
464 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
465 if (spec == NULL)
466 return -ENOMEM;
467
468 codec->spec = spec;
469 spec->codec_type = HDA_CODEC_NVIDIA_MCP89;
470 spec->old_pin_detect = 1;
471
472 if (hdmi_parse_codec(codec) < 0) {
473 codec->spec = NULL;
474 kfree(spec);
475 return -EINVAL;
476 }
477 codec->patch_ops = nvhdmi_patch_ops_8ch_89;
478
479 for (i = 0; i < spec->num_pins; i++)
480 snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
481
482 init_channel_allocations();
483
484 return 0;
485}
486
487static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
488{
489 struct hdmi_spec *spec;
490
491 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
492 if (spec == NULL)
493 return -ENOMEM;
494
495 codec->spec = spec;
496
497 spec->multiout.num_dacs = 0; /* no analog */
498 spec->multiout.max_channels = 8;
499 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
500 spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
501 spec->old_pin_detect = 1;
502
503 codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
504
505 return 0;
506}
507
508static int patch_nvhdmi_2ch(struct hda_codec *codec)
509{
510 struct hdmi_spec *spec;
511
512 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
513 if (spec == NULL)
514 return -ENOMEM;
515
516 codec->spec = spec;
517
518 spec->multiout.num_dacs = 0; /* no analog */
519 spec->multiout.max_channels = 2;
520 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
521 spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
522 spec->old_pin_detect = 1;
523
524 codec->patch_ops = nvhdmi_patch_ops_2ch;
525
526 return 0;
527}
528
529/*
530 * patch entries
531 */
532static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
533 { .id = 0x10de0002, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
534 { .id = 0x10de0003, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
535 { .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
536 { .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
537 { .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x },
538 { .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
539 { .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
540 { .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_nvhdmi_8ch_89 },
541 { .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
542 { .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
543 { .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
544 { .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
545 { .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
546 { .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
547 { .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
548 { .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
549 { .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
550 { .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
551 { .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
552 { .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
553 { .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
554 { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
555 { .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
556 { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
557 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
558 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
559 {} /* terminator */
560};
561
562MODULE_ALIAS("snd-hda-codec-id:10de0002");
563MODULE_ALIAS("snd-hda-codec-id:10de0003");
564MODULE_ALIAS("snd-hda-codec-id:10de0005");
565MODULE_ALIAS("snd-hda-codec-id:10de0006");
566MODULE_ALIAS("snd-hda-codec-id:10de0007");
567MODULE_ALIAS("snd-hda-codec-id:10de000a");
568MODULE_ALIAS("snd-hda-codec-id:10de000b");
569MODULE_ALIAS("snd-hda-codec-id:10de000c");
570MODULE_ALIAS("snd-hda-codec-id:10de000d");
571MODULE_ALIAS("snd-hda-codec-id:10de0010");
572MODULE_ALIAS("snd-hda-codec-id:10de0011");
573MODULE_ALIAS("snd-hda-codec-id:10de0012");
574MODULE_ALIAS("snd-hda-codec-id:10de0013");
575MODULE_ALIAS("snd-hda-codec-id:10de0014");
576MODULE_ALIAS("snd-hda-codec-id:10de0018");
577MODULE_ALIAS("snd-hda-codec-id:10de0019");
578MODULE_ALIAS("snd-hda-codec-id:10de001a");
579MODULE_ALIAS("snd-hda-codec-id:10de001b");
580MODULE_ALIAS("snd-hda-codec-id:10de001c");
581MODULE_ALIAS("snd-hda-codec-id:10de0040");
582MODULE_ALIAS("snd-hda-codec-id:10de0041");
583MODULE_ALIAS("snd-hda-codec-id:10de0042");
584MODULE_ALIAS("snd-hda-codec-id:10de0043");
585MODULE_ALIAS("snd-hda-codec-id:10de0044");
586MODULE_ALIAS("snd-hda-codec-id:10de0067");
587MODULE_ALIAS("snd-hda-codec-id:10de8001");
588
589MODULE_LICENSE("GPL");
590MODULE_DESCRIPTION("NVIDIA HDMI HD-audio codec");
591
592static struct hda_codec_preset_list nvhdmi_list = {
593 .preset = snd_hda_preset_nvhdmi,
594 .owner = THIS_MODULE,
595};
596
597static int __init patch_nvhdmi_init(void)
598{
599 return snd_hda_add_codec_preset(&nvhdmi_list);
600}
601
602static void __exit patch_nvhdmi_exit(void)
603{
604 snd_hda_delete_codec_preset(&nvhdmi_list);
605}
606
607module_init(patch_nvhdmi_init)
608module_exit(patch_nvhdmi_exit)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index a432e6efd19b..b48fb43b5448 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -28,6 +28,7 @@
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <sound/core.h> 30#include <sound/core.h>
31#include <sound/jack.h>
31#include "hda_codec.h" 32#include "hda_codec.h"
32#include "hda_local.h" 33#include "hda_local.h"
33#include "hda_beep.h" 34#include "hda_beep.h"
@@ -230,7 +231,6 @@ enum {
230 ALC888_ACER_ASPIRE_8930G, 231 ALC888_ACER_ASPIRE_8930G,
231 ALC888_ACER_ASPIRE_7730G, 232 ALC888_ACER_ASPIRE_7730G,
232 ALC883_MEDION, 233 ALC883_MEDION,
233 ALC883_MEDION_MD2,
234 ALC883_MEDION_WIM2160, 234 ALC883_MEDION_WIM2160,
235 ALC883_LAPTOP_EAPD, 235 ALC883_LAPTOP_EAPD,
236 ALC883_LENOVO_101E_2ch, 236 ALC883_LENOVO_101E_2ch,
@@ -294,13 +294,28 @@ struct alc_customize_define {
294 unsigned int platform_type:1; 294 unsigned int platform_type:1;
295 unsigned int swap:1; 295 unsigned int swap:1;
296 unsigned int override:1; 296 unsigned int override:1;
297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
298};
299
300struct alc_fixup;
301
302struct alc_multi_io {
303 hda_nid_t pin; /* multi-io widget pin NID */
304 hda_nid_t dac; /* DAC to be connected */
305 unsigned int ctl_in; /* cached input-pin control value */
306};
307
308enum {
309 ALC_AUTOMUTE_PIN, /* change the pin control */
310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
297}; 312};
298 313
299struct alc_spec { 314struct alc_spec {
300 /* codec parameterization */ 315 /* codec parameterization */
301 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 316 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
302 unsigned int num_mixers; 317 unsigned int num_mixers;
303 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 318 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
304 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 319 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
305 320
306 const struct hda_verb *init_verbs[10]; /* initialization verbs 321 const struct hda_verb *init_verbs[10]; /* initialization verbs
@@ -310,14 +325,14 @@ struct alc_spec {
310 unsigned int num_init_verbs; 325 unsigned int num_init_verbs;
311 326
312 char stream_name_analog[32]; /* analog PCM stream */ 327 char stream_name_analog[32]; /* analog PCM stream */
313 struct hda_pcm_stream *stream_analog_playback; 328 const struct hda_pcm_stream *stream_analog_playback;
314 struct hda_pcm_stream *stream_analog_capture; 329 const struct hda_pcm_stream *stream_analog_capture;
315 struct hda_pcm_stream *stream_analog_alt_playback; 330 const struct hda_pcm_stream *stream_analog_alt_playback;
316 struct hda_pcm_stream *stream_analog_alt_capture; 331 const struct hda_pcm_stream *stream_analog_alt_capture;
317 332
318 char stream_name_digital[32]; /* digital PCM stream */ 333 char stream_name_digital[32]; /* digital PCM stream */
319 struct hda_pcm_stream *stream_digital_playback; 334 const struct hda_pcm_stream *stream_digital_playback;
320 struct hda_pcm_stream *stream_digital_capture; 335 const struct hda_pcm_stream *stream_digital_capture;
321 336
322 /* playback */ 337 /* playback */
323 struct hda_multi_out multiout; /* playback set-up 338 struct hda_multi_out multiout; /* playback set-up
@@ -330,8 +345,8 @@ struct alc_spec {
330 345
331 /* capture */ 346 /* capture */
332 unsigned int num_adc_nids; 347 unsigned int num_adc_nids;
333 hda_nid_t *adc_nids; 348 const hda_nid_t *adc_nids;
334 hda_nid_t *capsrc_nids; 349 const hda_nid_t *capsrc_nids;
335 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 350 hda_nid_t dig_in_nid; /* digital-in NID; optional */
336 351
337 /* capture setup for dynamic dual-adc switch */ 352 /* capture setup for dynamic dual-adc switch */
@@ -345,6 +360,7 @@ struct alc_spec {
345 const struct hda_input_mux *input_mux; 360 const struct hda_input_mux *input_mux;
346 unsigned int cur_mux[3]; 361 unsigned int cur_mux[3];
347 struct alc_mic_route ext_mic; 362 struct alc_mic_route ext_mic;
363 struct alc_mic_route dock_mic;
348 struct alc_mic_route int_mic; 364 struct alc_mic_route int_mic;
349 365
350 /* channel model */ 366 /* channel model */
@@ -372,17 +388,29 @@ struct alc_spec {
372#ifdef CONFIG_SND_HDA_POWER_SAVE 388#ifdef CONFIG_SND_HDA_POWER_SAVE
373 void (*power_hook)(struct hda_codec *codec); 389 void (*power_hook)(struct hda_codec *codec);
374#endif 390#endif
391 void (*shutup)(struct hda_codec *codec);
375 392
376 /* for pin sensing */ 393 /* for pin sensing */
377 unsigned int sense_updated: 1;
378 unsigned int jack_present: 1; 394 unsigned int jack_present: 1;
379 unsigned int master_sw: 1; 395 unsigned int line_jack_present:1;
396 unsigned int master_mute:1;
380 unsigned int auto_mic:1; 397 unsigned int auto_mic:1;
398 unsigned int automute:1; /* HP automute enabled */
399 unsigned int detect_line:1; /* Line-out detection enabled */
400 unsigned int automute_lines:1; /* automute line-out as well */
401 unsigned int automute_hp_lo:1; /* both HP and LO available */
381 402
382 /* other flags */ 403 /* other flags */
383 unsigned int no_analog :1; /* digital I/O only */ 404 unsigned int no_analog :1; /* digital I/O only */
384 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ 405 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
406 unsigned int single_input_src:1;
407
408 /* auto-mute control */
409 int automute_mode;
410 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
411
385 int init_amp; 412 int init_amp;
413 int codec_variant; /* flag for other variants */
386 414
387 /* for virtual master */ 415 /* for virtual master */
388 hda_nid_t vmaster_nid; 416 hda_nid_t vmaster_nid;
@@ -393,25 +421,34 @@ struct alc_spec {
393 /* for PLL fix */ 421 /* for PLL fix */
394 hda_nid_t pll_nid; 422 hda_nid_t pll_nid;
395 unsigned int pll_coef_idx, pll_coef_bit; 423 unsigned int pll_coef_idx, pll_coef_bit;
424
425 /* fix-up list */
426 int fixup_id;
427 const struct alc_fixup *fixup_list;
428 const char *fixup_name;
429
430 /* multi-io */
431 int multi_ios;
432 struct alc_multi_io multi_io[4];
396}; 433};
397 434
398/* 435/*
399 * configuration template - to be copied to the spec instance 436 * configuration template - to be copied to the spec instance
400 */ 437 */
401struct alc_config_preset { 438struct alc_config_preset {
402 struct snd_kcontrol_new *mixers[5]; /* should be identical size 439 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
403 * with spec 440 * with spec
404 */ 441 */
405 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 442 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
406 const struct hda_verb *init_verbs[5]; 443 const struct hda_verb *init_verbs[5];
407 unsigned int num_dacs; 444 unsigned int num_dacs;
408 hda_nid_t *dac_nids; 445 const hda_nid_t *dac_nids;
409 hda_nid_t dig_out_nid; /* optional */ 446 hda_nid_t dig_out_nid; /* optional */
410 hda_nid_t hp_nid; /* optional */ 447 hda_nid_t hp_nid; /* optional */
411 hda_nid_t *slave_dig_outs; 448 const hda_nid_t *slave_dig_outs;
412 unsigned int num_adc_nids; 449 unsigned int num_adc_nids;
413 hda_nid_t *adc_nids; 450 const hda_nid_t *adc_nids;
414 hda_nid_t *capsrc_nids; 451 const hda_nid_t *capsrc_nids;
415 hda_nid_t dig_in_nid; 452 hda_nid_t dig_in_nid;
416 unsigned int num_channel_mode; 453 unsigned int num_channel_mode;
417 const struct hda_channel_mode *channel_mode; 454 const struct hda_channel_mode *channel_mode;
@@ -423,7 +460,7 @@ struct alc_config_preset {
423 void (*setup)(struct hda_codec *); 460 void (*setup)(struct hda_codec *);
424 void (*init_hook)(struct hda_codec *); 461 void (*init_hook)(struct hda_codec *);
425#ifdef CONFIG_SND_HDA_POWER_SAVE 462#ifdef CONFIG_SND_HDA_POWER_SAVE
426 struct hda_amp_list *loopbacks; 463 const struct hda_amp_list *loopbacks;
427 void (*power_hook)(struct hda_codec *codec); 464 void (*power_hook)(struct hda_codec *codec);
428#endif 465#endif
429}; 466};
@@ -539,7 +576,7 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
539 576
540/* 577/*
541 * Control the mode of pin widget settings via the mixer. "pc" is used 578 * Control the mode of pin widget settings via the mixer. "pc" is used
542 * instead of "%" to avoid consequences of accidently treating the % as 579 * instead of "%" to avoid consequences of accidentally treating the % as
543 * being part of a format specifier. Maximum allowed length of a value is 580 * being part of a format specifier. Maximum allowed length of a value is
544 * 63 characters plus NULL terminator. 581 * 63 characters plus NULL terminator.
545 * 582 *
@@ -550,11 +587,11 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
550 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 587 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
551 * March 2006. 588 * March 2006.
552 */ 589 */
553static char *alc_pin_mode_names[] = { 590static const char * const alc_pin_mode_names[] = {
554 "Mic 50pc bias", "Mic 80pc bias", 591 "Mic 50pc bias", "Mic 80pc bias",
555 "Line in", "Line out", "Headphone out", 592 "Line in", "Line out", "Headphone out",
556}; 593};
557static unsigned char alc_pin_mode_values[] = { 594static const unsigned char alc_pin_mode_values[] = {
558 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 595 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
559}; 596};
560/* The control can present all 5 options, or it can limit the options based 597/* The control can present all 5 options, or it can limit the options based
@@ -573,7 +610,7 @@ static unsigned char alc_pin_mode_values[] = {
573/* Info about the pin modes supported by the different pin direction modes. 610/* Info about the pin modes supported by the different pin direction modes.
574 * For each direction the minimum and maximum values are given. 611 * For each direction the minimum and maximum values are given.
575 */ 612 */
576static signed char alc_pin_mode_dir_info[5][2] = { 613static const signed char alc_pin_mode_dir_info[5][2] = {
577 { 0, 2 }, /* ALC_PIN_DIR_IN */ 614 { 0, 2 }, /* ALC_PIN_DIR_IN */
578 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 615 { 3, 4 }, /* ALC_PIN_DIR_OUT */
579 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 616 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
@@ -846,7 +883,7 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
846{ 883{
847 unsigned int val = PIN_IN; 884 unsigned int val = PIN_IN;
848 885
849 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) { 886 if (auto_pin_type == AUTO_PIN_MIC) {
850 unsigned int pincap; 887 unsigned int pincap;
851 unsigned int oldval; 888 unsigned int oldval;
852 oldval = snd_hda_codec_read(codec, nid, 0, 889 oldval = snd_hda_codec_read(codec, nid, 0,
@@ -866,9 +903,31 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
866 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); 903 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
867} 904}
868 905
906static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
907{
908 struct alc_spec *spec = codec->spec;
909 struct auto_pin_cfg *cfg = &spec->autocfg;
910
911 if (!cfg->line_outs) {
912 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
913 cfg->line_out_pins[cfg->line_outs])
914 cfg->line_outs++;
915 }
916 if (!cfg->speaker_outs) {
917 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
918 cfg->speaker_pins[cfg->speaker_outs])
919 cfg->speaker_outs++;
920 }
921 if (!cfg->hp_outs) {
922 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
923 cfg->hp_pins[cfg->hp_outs])
924 cfg->hp_outs++;
925 }
926}
927
869/* 928/*
870 */ 929 */
871static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) 930static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
872{ 931{
873 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) 932 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
874 return; 933 return;
@@ -934,24 +993,26 @@ static void setup_preset(struct hda_codec *codec,
934 993
935 if (preset->setup) 994 if (preset->setup)
936 preset->setup(codec); 995 preset->setup(codec);
996
997 alc_fixup_autocfg_pin_nums(codec);
937} 998}
938 999
939/* Enable GPIO mask and set output */ 1000/* Enable GPIO mask and set output */
940static struct hda_verb alc_gpio1_init_verbs[] = { 1001static const struct hda_verb alc_gpio1_init_verbs[] = {
941 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 1002 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
942 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 1003 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
943 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 1004 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
944 { } 1005 { }
945}; 1006};
946 1007
947static struct hda_verb alc_gpio2_init_verbs[] = { 1008static const struct hda_verb alc_gpio2_init_verbs[] = {
948 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 1009 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
949 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 1010 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
950 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 1011 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
951 { } 1012 { }
952}; 1013};
953 1014
954static struct hda_verb alc_gpio3_init_verbs[] = { 1015static const struct hda_verb alc_gpio3_init_verbs[] = {
955 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 1016 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
956 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 1017 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
957 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 1018 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
@@ -990,25 +1051,149 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
990 alc_fix_pll(codec); 1051 alc_fix_pll(codec);
991} 1052}
992 1053
993static void alc_automute_pin(struct hda_codec *codec) 1054static int alc_init_jacks(struct hda_codec *codec)
1055{
1056#ifdef CONFIG_SND_HDA_INPUT_JACK
1057 struct alc_spec *spec = codec->spec;
1058 int err;
1059 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1060 unsigned int mic_nid = spec->ext_mic.pin;
1061 unsigned int dock_nid = spec->dock_mic.pin;
1062
1063 if (hp_nid) {
1064 err = snd_hda_input_jack_add(codec, hp_nid,
1065 SND_JACK_HEADPHONE, NULL);
1066 if (err < 0)
1067 return err;
1068 snd_hda_input_jack_report(codec, hp_nid);
1069 }
1070
1071 if (mic_nid) {
1072 err = snd_hda_input_jack_add(codec, mic_nid,
1073 SND_JACK_MICROPHONE, NULL);
1074 if (err < 0)
1075 return err;
1076 snd_hda_input_jack_report(codec, mic_nid);
1077 }
1078 if (dock_nid) {
1079 err = snd_hda_input_jack_add(codec, dock_nid,
1080 SND_JACK_MICROPHONE, NULL);
1081 if (err < 0)
1082 return err;
1083 snd_hda_input_jack_report(codec, dock_nid);
1084 }
1085#endif /* CONFIG_SND_HDA_INPUT_JACK */
1086 return 0;
1087}
1088
1089static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1090{
1091 int i, present = 0;
1092
1093 for (i = 0; i < num_pins; i++) {
1094 hda_nid_t nid = pins[i];
1095 if (!nid)
1096 break;
1097 snd_hda_input_jack_report(codec, nid);
1098 present |= snd_hda_jack_detect(codec, nid);
1099 }
1100 return present;
1101}
1102
1103static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1104 bool mute, bool hp_out)
994{ 1105{
995 struct alc_spec *spec = codec->spec; 1106 struct alc_spec *spec = codec->spec;
996 unsigned int nid = spec->autocfg.hp_pins[0]; 1107 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
1108 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
997 int i; 1109 int i;
998 1110
999 if (!nid) 1111 for (i = 0; i < num_pins; i++) {
1000 return; 1112 hda_nid_t nid = pins[i];
1001 spec->jack_present = snd_hda_jack_detect(codec, nid);
1002 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1003 nid = spec->autocfg.speaker_pins[i];
1004 if (!nid) 1113 if (!nid)
1005 break; 1114 break;
1006 snd_hda_codec_write(codec, nid, 0, 1115 switch (spec->automute_mode) {
1007 AC_VERB_SET_PIN_WIDGET_CONTROL, 1116 case ALC_AUTOMUTE_PIN:
1008 spec->jack_present ? 0 : PIN_OUT); 1117 snd_hda_codec_write(codec, nid, 0,
1118 AC_VERB_SET_PIN_WIDGET_CONTROL,
1119 pin_bits);
1120 break;
1121 case ALC_AUTOMUTE_AMP:
1122 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1123 HDA_AMP_MUTE, mute_bits);
1124 break;
1125 case ALC_AUTOMUTE_MIXER:
1126 nid = spec->automute_mixer_nid[i];
1127 if (!nid)
1128 break;
1129 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
1130 HDA_AMP_MUTE, mute_bits);
1131 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
1132 HDA_AMP_MUTE, mute_bits);
1133 break;
1134 }
1009 } 1135 }
1010} 1136}
1011 1137
1138/* Toggle internal speakers muting */
1139static void update_speakers(struct hda_codec *codec)
1140{
1141 struct alc_spec *spec = codec->spec;
1142 int on;
1143
1144 /* Control HP pins/amps depending on master_mute state;
1145 * in general, HP pins/amps control should be enabled in all cases,
1146 * but currently set only for master_mute, just to be safe
1147 */
1148 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1149 spec->autocfg.hp_pins, spec->master_mute, true);
1150
1151 if (!spec->automute)
1152 on = 0;
1153 else
1154 on = spec->jack_present | spec->line_jack_present;
1155 on |= spec->master_mute;
1156 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1157 spec->autocfg.speaker_pins, on, false);
1158
1159 /* toggle line-out mutes if needed, too */
1160 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1161 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1162 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
1163 return;
1164 if (!spec->automute_lines || !spec->automute)
1165 on = 0;
1166 else
1167 on = spec->jack_present;
1168 on |= spec->master_mute;
1169 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1170 spec->autocfg.line_out_pins, on, false);
1171}
1172
1173static void alc_hp_automute(struct hda_codec *codec)
1174{
1175 struct alc_spec *spec = codec->spec;
1176
1177 if (!spec->automute)
1178 return;
1179 spec->jack_present =
1180 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1181 spec->autocfg.hp_pins);
1182 update_speakers(codec);
1183}
1184
1185static void alc_line_automute(struct hda_codec *codec)
1186{
1187 struct alc_spec *spec = codec->spec;
1188
1189 if (!spec->automute || !spec->detect_line)
1190 return;
1191 spec->line_jack_present =
1192 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1193 spec->autocfg.line_out_pins);
1194 update_speakers(codec);
1195}
1196
1012static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 1197static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1013 hda_nid_t nid) 1198 hda_nid_t nid)
1014{ 1199{
@@ -1048,7 +1233,7 @@ static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1048static void alc_mic_automute(struct hda_codec *codec) 1233static void alc_mic_automute(struct hda_codec *codec)
1049{ 1234{
1050 struct alc_spec *spec = codec->spec; 1235 struct alc_spec *spec = codec->spec;
1051 struct alc_mic_route *dead, *alive; 1236 struct alc_mic_route *dead1, *dead2, *alive;
1052 unsigned int present, type; 1237 unsigned int present, type;
1053 hda_nid_t cap_nid; 1238 hda_nid_t cap_nid;
1054 1239
@@ -1066,13 +1251,24 @@ static void alc_mic_automute(struct hda_codec *codec)
1066 1251
1067 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; 1252 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1068 1253
1254 alive = &spec->int_mic;
1255 dead1 = &spec->ext_mic;
1256 dead2 = &spec->dock_mic;
1257
1069 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1258 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1070 if (present) { 1259 if (present) {
1071 alive = &spec->ext_mic; 1260 alive = &spec->ext_mic;
1072 dead = &spec->int_mic; 1261 dead1 = &spec->int_mic;
1073 } else { 1262 dead2 = &spec->dock_mic;
1074 alive = &spec->int_mic; 1263 }
1075 dead = &spec->ext_mic; 1264 if (!present && spec->dock_mic.pin > 0) {
1265 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1266 if (present) {
1267 alive = &spec->dock_mic;
1268 dead1 = &spec->int_mic;
1269 dead2 = &spec->ext_mic;
1270 }
1271 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
1076 } 1272 }
1077 1273
1078 type = get_wcaps_type(get_wcaps(codec, cap_nid)); 1274 type = get_wcaps_type(get_wcaps(codec, cap_nid));
@@ -1081,15 +1277,21 @@ static void alc_mic_automute(struct hda_codec *codec)
1081 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1277 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1082 alive->mux_idx, 1278 alive->mux_idx,
1083 HDA_AMP_MUTE, 0); 1279 HDA_AMP_MUTE, 0);
1084 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1280 if (dead1->pin > 0)
1085 dead->mux_idx, 1281 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1086 HDA_AMP_MUTE, HDA_AMP_MUTE); 1282 dead1->mux_idx,
1283 HDA_AMP_MUTE, HDA_AMP_MUTE);
1284 if (dead2->pin > 0)
1285 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1286 dead2->mux_idx,
1287 HDA_AMP_MUTE, HDA_AMP_MUTE);
1087 } else { 1288 } else {
1088 /* MUX style (e.g. ALC880) */ 1289 /* MUX style (e.g. ALC880) */
1089 snd_hda_codec_write_cache(codec, cap_nid, 0, 1290 snd_hda_codec_write_cache(codec, cap_nid, 0,
1090 AC_VERB_SET_CONNECT_SEL, 1291 AC_VERB_SET_CONNECT_SEL,
1091 alive->mux_idx); 1292 alive->mux_idx);
1092 } 1293 }
1294 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1093 1295
1094 /* FIXME: analog mixer */ 1296 /* FIXME: analog mixer */
1095} 1297}
@@ -1103,7 +1305,10 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1103 res >>= 26; 1305 res >>= 26;
1104 switch (res) { 1306 switch (res) {
1105 case ALC880_HP_EVENT: 1307 case ALC880_HP_EVENT:
1106 alc_automute_pin(codec); 1308 alc_hp_automute(codec);
1309 break;
1310 case ALC880_FRONT_EVENT:
1311 alc_line_automute(codec);
1107 break; 1312 break;
1108 case ALC880_MIC_EVENT: 1313 case ALC880_MIC_EVENT:
1109 alc_mic_automute(codec); 1314 alc_mic_automute(codec);
@@ -1113,7 +1318,8 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1113 1318
1114static void alc_inithook(struct hda_codec *codec) 1319static void alc_inithook(struct hda_codec *codec)
1115{ 1320{
1116 alc_automute_pin(codec); 1321 alc_hp_automute(codec);
1322 alc_line_automute(codec);
1117 alc_mic_automute(codec); 1323 alc_mic_automute(codec);
1118} 1324}
1119 1325
@@ -1155,6 +1361,43 @@ static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1155 on ? 2 : 0); 1361 on ? 2 : 0);
1156} 1362}
1157 1363
1364/* turn on/off EAPD controls of the codec */
1365static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1366{
1367 /* We currently only handle front, HP */
1368 switch (codec->vendor_id) {
1369 case 0x10ec0260:
1370 set_eapd(codec, 0x0f, on);
1371 set_eapd(codec, 0x10, on);
1372 break;
1373 case 0x10ec0262:
1374 case 0x10ec0267:
1375 case 0x10ec0268:
1376 case 0x10ec0269:
1377 case 0x10ec0270:
1378 case 0x10ec0272:
1379 case 0x10ec0660:
1380 case 0x10ec0662:
1381 case 0x10ec0663:
1382 case 0x10ec0665:
1383 case 0x10ec0862:
1384 case 0x10ec0889:
1385 case 0x10ec0892:
1386 set_eapd(codec, 0x14, on);
1387 set_eapd(codec, 0x15, on);
1388 break;
1389 }
1390}
1391
1392/* generic shutup callback;
1393 * just turning off EPAD and a little pause for avoiding pop-noise
1394 */
1395static void alc_eapd_shutup(struct hda_codec *codec)
1396{
1397 alc_auto_setup_eapd(codec, false);
1398 msleep(200);
1399}
1400
1158static void alc_auto_init_amp(struct hda_codec *codec, int type) 1401static void alc_auto_init_amp(struct hda_codec *codec, int type)
1159{ 1402{
1160 unsigned int tmp; 1403 unsigned int tmp;
@@ -1170,26 +1413,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1170 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 1413 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1171 break; 1414 break;
1172 case ALC_INIT_DEFAULT: 1415 case ALC_INIT_DEFAULT:
1173 switch (codec->vendor_id) { 1416 alc_auto_setup_eapd(codec, true);
1174 case 0x10ec0260:
1175 set_eapd(codec, 0x0f, 1);
1176 set_eapd(codec, 0x10, 1);
1177 break;
1178 case 0x10ec0262:
1179 case 0x10ec0267:
1180 case 0x10ec0268:
1181 case 0x10ec0269:
1182 case 0x10ec0270:
1183 case 0x10ec0272:
1184 case 0x10ec0660:
1185 case 0x10ec0662:
1186 case 0x10ec0663:
1187 case 0x10ec0862:
1188 case 0x10ec0889:
1189 set_eapd(codec, 0x14, 1);
1190 set_eapd(codec, 0x15, 1);
1191 break;
1192 }
1193 switch (codec->vendor_id) { 1417 switch (codec->vendor_id) {
1194 case 0x10ec0260: 1418 case 0x10ec0260:
1195 snd_hda_codec_write(codec, 0x1a, 0, 1419 snd_hda_codec_write(codec, 0x1a, 0,
@@ -1208,7 +1432,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1208 case 0x10ec0883: 1432 case 0x10ec0883:
1209 case 0x10ec0885: 1433 case 0x10ec0885:
1210 case 0x10ec0887: 1434 case 0x10ec0887:
1211 case 0x10ec0889: 1435 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
1212 alc889_coef_init(codec); 1436 alc889_coef_init(codec);
1213 break; 1437 break;
1214 case 0x10ec0888: 1438 case 0x10ec0888:
@@ -1233,73 +1457,230 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1233 } 1457 }
1234} 1458}
1235 1459
1460static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1461 struct snd_ctl_elem_info *uinfo)
1462{
1463 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1464 struct alc_spec *spec = codec->spec;
1465 static const char * const texts2[] = {
1466 "Disabled", "Enabled"
1467 };
1468 static const char * const texts3[] = {
1469 "Disabled", "Speaker Only", "Line-Out+Speaker"
1470 };
1471 const char * const *texts;
1472
1473 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1474 uinfo->count = 1;
1475 if (spec->automute_hp_lo) {
1476 uinfo->value.enumerated.items = 3;
1477 texts = texts3;
1478 } else {
1479 uinfo->value.enumerated.items = 2;
1480 texts = texts2;
1481 }
1482 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1483 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1484 strcpy(uinfo->value.enumerated.name,
1485 texts[uinfo->value.enumerated.item]);
1486 return 0;
1487}
1488
1489static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1490 struct snd_ctl_elem_value *ucontrol)
1491{
1492 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1493 struct alc_spec *spec = codec->spec;
1494 unsigned int val;
1495 if (!spec->automute)
1496 val = 0;
1497 else if (!spec->automute_lines)
1498 val = 1;
1499 else
1500 val = 2;
1501 ucontrol->value.enumerated.item[0] = val;
1502 return 0;
1503}
1504
1505static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1506 struct snd_ctl_elem_value *ucontrol)
1507{
1508 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1509 struct alc_spec *spec = codec->spec;
1510
1511 switch (ucontrol->value.enumerated.item[0]) {
1512 case 0:
1513 if (!spec->automute)
1514 return 0;
1515 spec->automute = 0;
1516 break;
1517 case 1:
1518 if (spec->automute && !spec->automute_lines)
1519 return 0;
1520 spec->automute = 1;
1521 spec->automute_lines = 0;
1522 break;
1523 case 2:
1524 if (!spec->automute_hp_lo)
1525 return -EINVAL;
1526 if (spec->automute && spec->automute_lines)
1527 return 0;
1528 spec->automute = 1;
1529 spec->automute_lines = 1;
1530 break;
1531 default:
1532 return -EINVAL;
1533 }
1534 update_speakers(codec);
1535 return 1;
1536}
1537
1538static const struct snd_kcontrol_new alc_automute_mode_enum = {
1539 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1540 .name = "Auto-Mute Mode",
1541 .info = alc_automute_mode_info,
1542 .get = alc_automute_mode_get,
1543 .put = alc_automute_mode_put,
1544};
1545
1546static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1547
1548static int alc_add_automute_mode_enum(struct hda_codec *codec)
1549{
1550 struct alc_spec *spec = codec->spec;
1551 struct snd_kcontrol_new *knew;
1552
1553 knew = alc_kcontrol_new(spec);
1554 if (!knew)
1555 return -ENOMEM;
1556 *knew = alc_automute_mode_enum;
1557 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1558 if (!knew->name)
1559 return -ENOMEM;
1560 return 0;
1561}
1562
1236static void alc_init_auto_hp(struct hda_codec *codec) 1563static void alc_init_auto_hp(struct hda_codec *codec)
1237{ 1564{
1238 struct alc_spec *spec = codec->spec; 1565 struct alc_spec *spec = codec->spec;
1566 struct auto_pin_cfg *cfg = &spec->autocfg;
1567 int present = 0;
1568 int i;
1239 1569
1240 if (!spec->autocfg.hp_pins[0]) 1570 if (cfg->hp_pins[0])
1571 present++;
1572 if (cfg->line_out_pins[0])
1573 present++;
1574 if (cfg->speaker_pins[0])
1575 present++;
1576 if (present < 2) /* need two different output types */
1241 return; 1577 return;
1578 if (present == 3)
1579 spec->automute_hp_lo = 1; /* both HP and LO automute */
1242 1580
1243 if (!spec->autocfg.speaker_pins[0]) { 1581 if (!cfg->speaker_pins[0]) {
1244 if (spec->autocfg.line_out_pins[0] && 1582 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1245 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) 1583 sizeof(cfg->speaker_pins));
1246 spec->autocfg.speaker_pins[0] = 1584 cfg->speaker_outs = cfg->line_outs;
1247 spec->autocfg.line_out_pins[0]; 1585 }
1248 else 1586
1249 return; 1587 if (!cfg->hp_pins[0]) {
1588 memcpy(cfg->hp_pins, cfg->line_out_pins,
1589 sizeof(cfg->hp_pins));
1590 cfg->hp_outs = cfg->line_outs;
1250 } 1591 }
1251 1592
1252 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", 1593 for (i = 0; i < cfg->hp_outs; i++) {
1253 spec->autocfg.hp_pins[0]); 1594 hda_nid_t nid = cfg->hp_pins[i];
1254 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0, 1595 if (!is_jack_detectable(codec, nid))
1596 continue;
1597 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1598 nid);
1599 snd_hda_codec_write_cache(codec, nid, 0,
1255 AC_VERB_SET_UNSOLICITED_ENABLE, 1600 AC_VERB_SET_UNSOLICITED_ENABLE,
1256 AC_USRSP_EN | ALC880_HP_EVENT); 1601 AC_USRSP_EN | ALC880_HP_EVENT);
1257 spec->unsol_event = alc_sku_unsol_event; 1602 spec->automute = 1;
1603 spec->automute_mode = ALC_AUTOMUTE_PIN;
1604 }
1605 if (spec->automute && cfg->line_out_pins[0] &&
1606 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1607 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1608 for (i = 0; i < cfg->line_outs; i++) {
1609 hda_nid_t nid = cfg->line_out_pins[i];
1610 if (!is_jack_detectable(codec, nid))
1611 continue;
1612 snd_printdd("realtek: Enable Line-Out auto-muting "
1613 "on NID 0x%x\n", nid);
1614 snd_hda_codec_write_cache(codec, nid, 0,
1615 AC_VERB_SET_UNSOLICITED_ENABLE,
1616 AC_USRSP_EN | ALC880_FRONT_EVENT);
1617 spec->detect_line = 1;
1618 }
1619 spec->automute_lines = spec->detect_line;
1620 }
1621
1622 if (spec->automute) {
1623 /* create a control for automute mode */
1624 alc_add_automute_mode_enum(codec);
1625 spec->unsol_event = alc_sku_unsol_event;
1626 }
1258} 1627}
1259 1628
1260static void alc_init_auto_mic(struct hda_codec *codec) 1629static void alc_init_auto_mic(struct hda_codec *codec)
1261{ 1630{
1262 struct alc_spec *spec = codec->spec; 1631 struct alc_spec *spec = codec->spec;
1263 struct auto_pin_cfg *cfg = &spec->autocfg; 1632 struct auto_pin_cfg *cfg = &spec->autocfg;
1264 hda_nid_t fixed, ext; 1633 hda_nid_t fixed, ext, dock;
1265 int i; 1634 int i;
1266 1635
1267 /* there must be only two mic inputs exclusively */ 1636 fixed = ext = dock = 0;
1268 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++) 1637 for (i = 0; i < cfg->num_inputs; i++) {
1269 if (cfg->input_pins[i]) 1638 hda_nid_t nid = cfg->inputs[i].pin;
1270 return;
1271
1272 fixed = ext = 0;
1273 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1274 hda_nid_t nid = cfg->input_pins[i];
1275 unsigned int defcfg; 1639 unsigned int defcfg;
1276 if (!nid)
1277 return;
1278 defcfg = snd_hda_codec_get_pincfg(codec, nid); 1640 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1279 switch (get_defcfg_connect(defcfg)) { 1641 switch (snd_hda_get_input_pin_attr(defcfg)) {
1280 case AC_JACK_PORT_FIXED: 1642 case INPUT_PIN_ATTR_INT:
1281 if (fixed) 1643 if (fixed)
1282 return; /* already occupied */ 1644 return; /* already occupied */
1645 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1646 return; /* invalid type */
1283 fixed = nid; 1647 fixed = nid;
1284 break; 1648 break;
1285 case AC_JACK_PORT_COMPLEX: 1649 case INPUT_PIN_ATTR_UNUSED:
1650 return; /* invalid entry */
1651 case INPUT_PIN_ATTR_DOCK:
1652 if (dock)
1653 return; /* already occupied */
1654 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1655 return; /* invalid type */
1656 dock = nid;
1657 break;
1658 default:
1286 if (ext) 1659 if (ext)
1287 return; /* already occupied */ 1660 return; /* already occupied */
1661 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1662 return; /* invalid type */
1288 ext = nid; 1663 ext = nid;
1289 break; 1664 break;
1290 default:
1291 return; /* invalid entry */
1292 } 1665 }
1293 } 1666 }
1667 if (!ext && dock) {
1668 ext = dock;
1669 dock = 0;
1670 }
1294 if (!ext || !fixed) 1671 if (!ext || !fixed)
1295 return; 1672 return;
1296 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) 1673 if (!is_jack_detectable(codec, ext))
1674 return; /* no unsol support */
1675 if (dock && !is_jack_detectable(codec, dock))
1297 return; /* no unsol support */ 1676 return; /* no unsol support */
1298 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", 1677 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1299 ext, fixed); 1678 ext, fixed, dock);
1300 spec->ext_mic.pin = ext; 1679 spec->ext_mic.pin = ext;
1680 spec->dock_mic.pin = dock;
1301 spec->int_mic.pin = fixed; 1681 spec->int_mic.pin = fixed;
1302 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1682 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1683 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1303 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1684 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1304 spec->auto_mic = 1; 1685 spec->auto_mic = 1;
1305 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, 1686 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
@@ -1308,6 +1689,11 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1308 spec->unsol_event = alc_sku_unsol_event; 1689 spec->unsol_event = alc_sku_unsol_event;
1309} 1690}
1310 1691
1692/* Could be any non-zero and even value. When used as fixup, tells
1693 * the driver to ignore any present sku defines.
1694 */
1695#define ALC_FIXUP_SKU_IGNORE (2)
1696
1311static int alc_auto_parse_customize_define(struct hda_codec *codec) 1697static int alc_auto_parse_customize_define(struct hda_codec *codec)
1312{ 1698{
1313 unsigned int ass, tmp, i; 1699 unsigned int ass, tmp, i;
@@ -1316,6 +1702,13 @@ static int alc_auto_parse_customize_define(struct hda_codec *codec)
1316 1702
1317 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ 1703 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1318 1704
1705 if (spec->cdefine.fixup) {
1706 ass = spec->cdefine.sku_cfg;
1707 if (ass == ALC_FIXUP_SKU_IGNORE)
1708 return -1;
1709 goto do_sku;
1710 }
1711
1319 ass = codec->subsystem_id & 0xffff; 1712 ass = codec->subsystem_id & 0xffff;
1320 if (ass != codec->bus->pci->subsystem_device && (ass & 1)) 1713 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1321 goto do_sku; 1714 goto do_sku;
@@ -1383,6 +1776,13 @@ static int alc_subsystem_id(struct hda_codec *codec,
1383 unsigned nid; 1776 unsigned nid;
1384 struct alc_spec *spec = codec->spec; 1777 struct alc_spec *spec = codec->spec;
1385 1778
1779 if (spec->cdefine.fixup) {
1780 ass = spec->cdefine.sku_cfg;
1781 if (ass == ALC_FIXUP_SKU_IGNORE)
1782 return 0;
1783 goto do_sku;
1784 }
1785
1386 ass = codec->subsystem_id & 0xffff; 1786 ass = codec->subsystem_id & 0xffff;
1387 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 1787 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1388 goto do_sku; 1788 goto do_sku;
@@ -1438,6 +1838,7 @@ do_sku:
1438 spec->init_amp = ALC_INIT_GPIO3; 1838 spec->init_amp = ALC_INIT_GPIO3;
1439 break; 1839 break;
1440 case 5: 1840 case 5:
1841 default:
1441 spec->init_amp = ALC_INIT_DEFAULT; 1842 spec->init_amp = ALC_INIT_DEFAULT;
1442 break; 1843 break;
1443 } 1844 }
@@ -1472,9 +1873,6 @@ do_sku:
1472 return 1; 1873 return 1;
1473 spec->autocfg.hp_pins[0] = nid; 1874 spec->autocfg.hp_pins[0] = nid;
1474 } 1875 }
1475
1476 alc_init_auto_hp(codec);
1477 alc_init_auto_mic(codec);
1478 return 1; 1876 return 1;
1479} 1877}
1480 1878
@@ -1487,9 +1885,10 @@ static void alc_ssid_check(struct hda_codec *codec,
1487 snd_printd("realtek: " 1885 snd_printd("realtek: "
1488 "Enable default setup for auto mode as fallback\n"); 1886 "Enable default setup for auto mode as fallback\n");
1489 spec->init_amp = ALC_INIT_DEFAULT; 1887 spec->init_amp = ALC_INIT_DEFAULT;
1490 alc_init_auto_hp(codec);
1491 alc_init_auto_mic(codec);
1492 } 1888 }
1889
1890 alc_init_auto_hp(codec);
1891 alc_init_auto_mic(codec);
1493} 1892}
1494 1893
1495/* 1894/*
@@ -1501,37 +1900,139 @@ struct alc_pincfg {
1501 u32 val; 1900 u32 val;
1502}; 1901};
1503 1902
1903struct alc_model_fixup {
1904 const int id;
1905 const char *name;
1906};
1907
1504struct alc_fixup { 1908struct alc_fixup {
1505 const struct alc_pincfg *pins; 1909 int type;
1506 const struct hda_verb *verbs; 1910 bool chained;
1911 int chain_id;
1912 union {
1913 unsigned int sku;
1914 const struct alc_pincfg *pins;
1915 const struct hda_verb *verbs;
1916 void (*func)(struct hda_codec *codec,
1917 const struct alc_fixup *fix,
1918 int action);
1919 } v;
1507}; 1920};
1508 1921
1509static void alc_pick_fixup(struct hda_codec *codec, 1922enum {
1510 const struct snd_pci_quirk *quirk, 1923 ALC_FIXUP_INVALID,
1511 const struct alc_fixup *fix, 1924 ALC_FIXUP_SKU,
1512 int pre_init) 1925 ALC_FIXUP_PINS,
1513{ 1926 ALC_FIXUP_VERBS,
1514 const struct alc_pincfg *cfg; 1927 ALC_FIXUP_FUNC,
1928};
1515 1929
1516 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 1930enum {
1517 if (!quirk) 1931 ALC_FIXUP_ACT_PRE_PROBE,
1518 return; 1932 ALC_FIXUP_ACT_PROBE,
1519 fix += quirk->value; 1933 ALC_FIXUP_ACT_INIT,
1520 cfg = fix->pins; 1934};
1521 if (pre_init && cfg) { 1935
1936static void alc_apply_fixup(struct hda_codec *codec, int action)
1937{
1938 struct alc_spec *spec = codec->spec;
1939 int id = spec->fixup_id;
1522#ifdef CONFIG_SND_DEBUG_VERBOSE 1940#ifdef CONFIG_SND_DEBUG_VERBOSE
1523 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", 1941 const char *modelname = spec->fixup_name;
1524 codec->chip_name, quirk->name);
1525#endif 1942#endif
1526 for (; cfg->nid; cfg++) 1943 int depth = 0;
1527 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); 1944
1945 if (!spec->fixup_list)
1946 return;
1947
1948 while (id >= 0) {
1949 const struct alc_fixup *fix = spec->fixup_list + id;
1950 const struct alc_pincfg *cfg;
1951
1952 switch (fix->type) {
1953 case ALC_FIXUP_SKU:
1954 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1955 break;;
1956 snd_printdd(KERN_INFO "hda_codec: %s: "
1957 "Apply sku override for %s\n",
1958 codec->chip_name, modelname);
1959 spec->cdefine.sku_cfg = fix->v.sku;
1960 spec->cdefine.fixup = 1;
1961 break;
1962 case ALC_FIXUP_PINS:
1963 cfg = fix->v.pins;
1964 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1965 break;
1966 snd_printdd(KERN_INFO "hda_codec: %s: "
1967 "Apply pincfg for %s\n",
1968 codec->chip_name, modelname);
1969 for (; cfg->nid; cfg++)
1970 snd_hda_codec_set_pincfg(codec, cfg->nid,
1971 cfg->val);
1972 break;
1973 case ALC_FIXUP_VERBS:
1974 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1975 break;
1976 snd_printdd(KERN_INFO "hda_codec: %s: "
1977 "Apply fix-verbs for %s\n",
1978 codec->chip_name, modelname);
1979 add_verb(codec->spec, fix->v.verbs);
1980 break;
1981 case ALC_FIXUP_FUNC:
1982 if (!fix->v.func)
1983 break;
1984 snd_printdd(KERN_INFO "hda_codec: %s: "
1985 "Apply fix-func for %s\n",
1986 codec->chip_name, modelname);
1987 fix->v.func(codec, fix, action);
1988 break;
1989 default:
1990 snd_printk(KERN_ERR "hda_codec: %s: "
1991 "Invalid fixup type %d\n",
1992 codec->chip_name, fix->type);
1993 break;
1994 }
1995 if (!fix->chained)
1996 break;
1997 if (++depth > 10)
1998 break;
1999 id = fix->chain_id;
2000 }
2001}
2002
2003static void alc_pick_fixup(struct hda_codec *codec,
2004 const struct alc_model_fixup *models,
2005 const struct snd_pci_quirk *quirk,
2006 const struct alc_fixup *fixlist)
2007{
2008 struct alc_spec *spec = codec->spec;
2009 int id = -1;
2010 const char *name = NULL;
2011
2012 if (codec->modelname && models) {
2013 while (models->name) {
2014 if (!strcmp(codec->modelname, models->name)) {
2015 id = models->id;
2016 name = models->name;
2017 break;
2018 }
2019 models++;
2020 }
1528 } 2021 }
1529 if (!pre_init && fix->verbs) { 2022 if (id < 0) {
2023 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2024 if (quirk) {
2025 id = quirk->value;
1530#ifdef CONFIG_SND_DEBUG_VERBOSE 2026#ifdef CONFIG_SND_DEBUG_VERBOSE
1531 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", 2027 name = quirk->name;
1532 codec->chip_name, quirk->name);
1533#endif 2028#endif
1534 add_verb(codec->spec, fix->verbs); 2029 }
2030 }
2031
2032 spec->fixup_id = id;
2033 if (id >= 0) {
2034 spec->fixup_list = fixlist;
2035 spec->fixup_name = name;
1535 } 2036 }
1536} 2037}
1537 2038
@@ -1546,6 +2047,15 @@ static int alc_read_coef_idx(struct hda_codec *codec,
1546 return val; 2047 return val;
1547} 2048}
1548 2049
2050static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2051 unsigned int coef_val)
2052{
2053 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2054 coef_idx);
2055 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2056 coef_val);
2057}
2058
1549/* set right pin controls for digital I/O */ 2059/* set right pin controls for digital I/O */
1550static void alc_auto_init_digital(struct hda_codec *codec) 2060static void alc_auto_init_digital(struct hda_codec *codec)
1551{ 2061{
@@ -1620,7 +2130,7 @@ static void alc_auto_parse_digital(struct hda_codec *codec)
1620/* 2130/*
1621 * 2ch mode 2131 * 2ch mode
1622 */ 2132 */
1623static struct hda_verb alc888_4ST_ch2_intel_init[] = { 2133static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
1624/* Mic-in jack as mic in */ 2134/* Mic-in jack as mic in */
1625 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2135 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1626 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2136 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
@@ -1635,7 +2145,7 @@ static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1635/* 2145/*
1636 * 4ch mode 2146 * 4ch mode
1637 */ 2147 */
1638static struct hda_verb alc888_4ST_ch4_intel_init[] = { 2148static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
1639/* Mic-in jack as mic in */ 2149/* Mic-in jack as mic in */
1640 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2150 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1641 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2151 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
@@ -1650,7 +2160,7 @@ static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1650/* 2160/*
1651 * 6ch mode 2161 * 6ch mode
1652 */ 2162 */
1653static struct hda_verb alc888_4ST_ch6_intel_init[] = { 2163static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
1654/* Mic-in jack as CLFE */ 2164/* Mic-in jack as CLFE */
1655 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2165 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1656 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2166 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
@@ -1665,7 +2175,7 @@ static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1665/* 2175/*
1666 * 8ch mode 2176 * 8ch mode
1667 */ 2177 */
1668static struct hda_verb alc888_4ST_ch8_intel_init[] = { 2178static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
1669/* Mic-in jack as CLFE */ 2179/* Mic-in jack as CLFE */
1670 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2180 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1671 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2181 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
@@ -1677,7 +2187,7 @@ static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1677 { } /* end */ 2187 { } /* end */
1678}; 2188};
1679 2189
1680static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { 2190static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1681 { 2, alc888_4ST_ch2_intel_init }, 2191 { 2, alc888_4ST_ch2_intel_init },
1682 { 4, alc888_4ST_ch4_intel_init }, 2192 { 4, alc888_4ST_ch4_intel_init },
1683 { 6, alc888_4ST_ch6_intel_init }, 2193 { 6, alc888_4ST_ch6_intel_init },
@@ -1688,7 +2198,7 @@ static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1688 * ALC888 Fujitsu Siemens Amillo xa3530 2198 * ALC888 Fujitsu Siemens Amillo xa3530
1689 */ 2199 */
1690 2200
1691static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { 2201static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1692/* Front Mic: set to PIN_IN (empty by default) */ 2202/* Front Mic: set to PIN_IN (empty by default) */
1693 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2203 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1694/* Connect Internal HP to Front */ 2204/* Connect Internal HP to Front */
@@ -1721,46 +2231,6 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1721 {} 2231 {}
1722}; 2232};
1723 2233
1724static void alc_automute_amp(struct hda_codec *codec)
1725{
1726 struct alc_spec *spec = codec->spec;
1727 unsigned int mute;
1728 hda_nid_t nid;
1729 int i;
1730
1731 spec->jack_present = 0;
1732 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1733 nid = spec->autocfg.hp_pins[i];
1734 if (!nid)
1735 break;
1736 if (snd_hda_jack_detect(codec, nid)) {
1737 spec->jack_present = 1;
1738 break;
1739 }
1740 }
1741
1742 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1743 /* Toggle internal speakers muting */
1744 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1745 nid = spec->autocfg.speaker_pins[i];
1746 if (!nid)
1747 break;
1748 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1749 HDA_AMP_MUTE, mute);
1750 }
1751}
1752
1753static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1754 unsigned int res)
1755{
1756 if (codec->vendor_id == 0x10ec0880)
1757 res >>= 28;
1758 else
1759 res >>= 26;
1760 if (res == ALC880_HP_EVENT)
1761 alc_automute_amp(codec);
1762}
1763
1764static void alc889_automute_setup(struct hda_codec *codec) 2234static void alc889_automute_setup(struct hda_codec *codec)
1765{ 2235{
1766 struct alc_spec *spec = codec->spec; 2236 struct alc_spec *spec = codec->spec;
@@ -1771,12 +2241,14 @@ static void alc889_automute_setup(struct hda_codec *codec)
1771 spec->autocfg.speaker_pins[2] = 0x17; 2241 spec->autocfg.speaker_pins[2] = 0x17;
1772 spec->autocfg.speaker_pins[3] = 0x19; 2242 spec->autocfg.speaker_pins[3] = 0x19;
1773 spec->autocfg.speaker_pins[4] = 0x1a; 2243 spec->autocfg.speaker_pins[4] = 0x1a;
2244 spec->automute = 1;
2245 spec->automute_mode = ALC_AUTOMUTE_AMP;
1774} 2246}
1775 2247
1776static void alc889_intel_init_hook(struct hda_codec *codec) 2248static void alc889_intel_init_hook(struct hda_codec *codec)
1777{ 2249{
1778 alc889_coef_init(codec); 2250 alc889_coef_init(codec);
1779 alc_automute_amp(codec); 2251 alc_hp_automute(codec);
1780} 2252}
1781 2253
1782static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) 2254static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
@@ -1787,13 +2259,15 @@ static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
1787 spec->autocfg.hp_pins[1] = 0x1b; /* hp */ 2259 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1788 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ 2260 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1789 spec->autocfg.speaker_pins[1] = 0x15; /* bass */ 2261 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2262 spec->automute = 1;
2263 spec->automute_mode = ALC_AUTOMUTE_AMP;
1790} 2264}
1791 2265
1792/* 2266/*
1793 * ALC888 Acer Aspire 4930G model 2267 * ALC888 Acer Aspire 4930G model
1794 */ 2268 */
1795 2269
1796static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { 2270static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1797/* Front Mic: set to PIN_IN (empty by default) */ 2271/* Front Mic: set to PIN_IN (empty by default) */
1798 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2272 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1799/* Unselect Front Mic by default in input mixer 3 */ 2273/* Unselect Front Mic by default in input mixer 3 */
@@ -1808,6 +2282,7 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1808 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1809 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2283 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1810 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2284 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2285 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
1811 { } 2286 { }
1812}; 2287};
1813 2288
@@ -1815,7 +2290,7 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1815 * ALC888 Acer Aspire 6530G model 2290 * ALC888 Acer Aspire 6530G model
1816 */ 2291 */
1817 2292
1818static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { 2293static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1819/* Route to built-in subwoofer as well as speakers */ 2294/* Route to built-in subwoofer as well as speakers */
1820 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2295 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1821 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2296 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -1842,10 +2317,40 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1842}; 2317};
1843 2318
1844/* 2319/*
2320 *ALC888 Acer Aspire 7730G model
2321 */
2322
2323static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2324/* Bias voltage on for external mic port */
2325 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2326/* Front Mic: set to PIN_IN (empty by default) */
2327 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2328/* Unselect Front Mic by default in input mixer 3 */
2329 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2330/* Enable unsolicited event for HP jack */
2331 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2332/* Enable speaker output */
2333 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2334 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2335 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2336/* Enable headphone output */
2337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2338 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2339 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2340 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2341/*Enable internal subwoofer */
2342 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2343 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2344 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2345 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2346 { }
2347};
2348
2349/*
1845 * ALC889 Acer Aspire 8930G model 2350 * ALC889 Acer Aspire 8930G model
1846 */ 2351 */
1847 2352
1848static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { 2353static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1849/* Front Mic: set to PIN_IN (empty by default) */ 2354/* Front Mic: set to PIN_IN (empty by default) */
1850 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2355 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1851/* Unselect Front Mic by default in input mixer 3 */ 2356/* Unselect Front Mic by default in input mixer 3 */
@@ -1891,7 +2396,7 @@ static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1891 { } 2396 { }
1892}; 2397};
1893 2398
1894static struct hda_input_mux alc888_2_capture_sources[2] = { 2399static const struct hda_input_mux alc888_2_capture_sources[2] = {
1895 /* Front mic only available on one ADC */ 2400 /* Front mic only available on one ADC */
1896 { 2401 {
1897 .num_items = 4, 2402 .num_items = 4,
@@ -1912,22 +2417,22 @@ static struct hda_input_mux alc888_2_capture_sources[2] = {
1912 } 2417 }
1913}; 2418};
1914 2419
1915static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { 2420static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1916 /* Interal mic only available on one ADC */ 2421 /* Interal mic only available on one ADC */
1917 { 2422 {
1918 .num_items = 5, 2423 .num_items = 5,
1919 .items = { 2424 .items = {
1920 { "Ext Mic", 0x0 }, 2425 { "Mic", 0x0 },
1921 { "Line In", 0x2 }, 2426 { "Line In", 0x2 },
1922 { "CD", 0x4 }, 2427 { "CD", 0x4 },
1923 { "Input Mix", 0xa }, 2428 { "Input Mix", 0xa },
1924 { "Int Mic", 0xb }, 2429 { "Internal Mic", 0xb },
1925 }, 2430 },
1926 }, 2431 },
1927 { 2432 {
1928 .num_items = 4, 2433 .num_items = 4,
1929 .items = { 2434 .items = {
1930 { "Ext Mic", 0x0 }, 2435 { "Mic", 0x0 },
1931 { "Line In", 0x2 }, 2436 { "Line In", 0x2 },
1932 { "CD", 0x4 }, 2437 { "CD", 0x4 },
1933 { "Input Mix", 0xa }, 2438 { "Input Mix", 0xa },
@@ -1935,7 +2440,7 @@ static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1935 } 2440 }
1936}; 2441};
1937 2442
1938static struct hda_input_mux alc889_capture_sources[3] = { 2443static const struct hda_input_mux alc889_capture_sources[3] = {
1939 /* Digital mic only available on first "ADC" */ 2444 /* Digital mic only available on first "ADC" */
1940 { 2445 {
1941 .num_items = 5, 2446 .num_items = 5,
@@ -1967,7 +2472,7 @@ static struct hda_input_mux alc889_capture_sources[3] = {
1967 } 2472 }
1968}; 2473};
1969 2474
1970static struct snd_kcontrol_new alc888_base_mixer[] = { 2475static const struct snd_kcontrol_new alc888_base_mixer[] = {
1971 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2476 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1972 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2477 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1973 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2478 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -1984,12 +2489,34 @@ static struct snd_kcontrol_new alc888_base_mixer[] = {
1984 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2489 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1985 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2490 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1986 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2491 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1987 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 2492 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1988 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2493 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1989 { } /* end */ 2494 { } /* end */
1990}; 2495};
1991 2496
1992static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { 2497static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2498 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2499 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2500 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2501 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2502 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2503 HDA_OUTPUT),
2504 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2505 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2506 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2507 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2508 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2509 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2510 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2511 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2512 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2514 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2515 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2516 { } /* end */
2517};
2518
2519static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
1993 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2520 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1994 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2521 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1995 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2522 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2002,7 +2529,7 @@ static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2002 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2529 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2003 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2530 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2004 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2531 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2005 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 2532 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2006 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2533 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2007 { } /* end */ 2534 { } /* end */
2008}; 2535};
@@ -2016,6 +2543,8 @@ static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2016 spec->autocfg.speaker_pins[0] = 0x14; 2543 spec->autocfg.speaker_pins[0] = 0x14;
2017 spec->autocfg.speaker_pins[1] = 0x16; 2544 spec->autocfg.speaker_pins[1] = 0x16;
2018 spec->autocfg.speaker_pins[2] = 0x17; 2545 spec->autocfg.speaker_pins[2] = 0x17;
2546 spec->automute = 1;
2547 spec->automute_mode = ALC_AUTOMUTE_AMP;
2019} 2548}
2020 2549
2021static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) 2550static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
@@ -2026,6 +2555,20 @@ static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2026 spec->autocfg.speaker_pins[0] = 0x14; 2555 spec->autocfg.speaker_pins[0] = 0x14;
2027 spec->autocfg.speaker_pins[1] = 0x16; 2556 spec->autocfg.speaker_pins[1] = 0x16;
2028 spec->autocfg.speaker_pins[2] = 0x17; 2557 spec->autocfg.speaker_pins[2] = 0x17;
2558 spec->automute = 1;
2559 spec->automute_mode = ALC_AUTOMUTE_AMP;
2560}
2561
2562static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2563{
2564 struct alc_spec *spec = codec->spec;
2565
2566 spec->autocfg.hp_pins[0] = 0x15;
2567 spec->autocfg.speaker_pins[0] = 0x14;
2568 spec->autocfg.speaker_pins[1] = 0x16;
2569 spec->autocfg.speaker_pins[2] = 0x17;
2570 spec->automute = 1;
2571 spec->automute_mode = ALC_AUTOMUTE_AMP;
2029} 2572}
2030 2573
2031static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) 2574static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
@@ -2036,6 +2579,8 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2036 spec->autocfg.speaker_pins[0] = 0x14; 2579 spec->autocfg.speaker_pins[0] = 0x14;
2037 spec->autocfg.speaker_pins[1] = 0x16; 2580 spec->autocfg.speaker_pins[1] = 0x16;
2038 spec->autocfg.speaker_pins[2] = 0x1b; 2581 spec->autocfg.speaker_pins[2] = 0x1b;
2582 spec->automute = 1;
2583 spec->automute_mode = ALC_AUTOMUTE_AMP;
2039} 2584}
2040 2585
2041/* 2586/*
@@ -2046,12 +2591,12 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2046 * F-Mic = 0x1b, HP = 0x19 2591 * F-Mic = 0x1b, HP = 0x19
2047 */ 2592 */
2048 2593
2049static hda_nid_t alc880_dac_nids[4] = { 2594static const hda_nid_t alc880_dac_nids[4] = {
2050 /* front, rear, clfe, rear_surr */ 2595 /* front, rear, clfe, rear_surr */
2051 0x02, 0x05, 0x04, 0x03 2596 0x02, 0x05, 0x04, 0x03
2052}; 2597};
2053 2598
2054static hda_nid_t alc880_adc_nids[3] = { 2599static const hda_nid_t alc880_adc_nids[3] = {
2055 /* ADC0-2 */ 2600 /* ADC0-2 */
2056 0x07, 0x08, 0x09, 2601 0x07, 0x08, 0x09,
2057}; 2602};
@@ -2060,7 +2605,7 @@ static hda_nid_t alc880_adc_nids[3] = {
2060 * but it shows zero connection in the real implementation on some devices. 2605 * but it shows zero connection in the real implementation on some devices.
2061 * Note: this is a 915GAV bug, fixed on 915GLV 2606 * Note: this is a 915GAV bug, fixed on 915GLV
2062 */ 2607 */
2063static hda_nid_t alc880_adc_nids_alt[2] = { 2608static const hda_nid_t alc880_adc_nids_alt[2] = {
2064 /* ADC1-2 */ 2609 /* ADC1-2 */
2065 0x08, 0x09, 2610 0x08, 0x09,
2066}; 2611};
@@ -2068,7 +2613,7 @@ static hda_nid_t alc880_adc_nids_alt[2] = {
2068#define ALC880_DIGOUT_NID 0x06 2613#define ALC880_DIGOUT_NID 0x06
2069#define ALC880_DIGIN_NID 0x0a 2614#define ALC880_DIGIN_NID 0x0a
2070 2615
2071static struct hda_input_mux alc880_capture_source = { 2616static const struct hda_input_mux alc880_capture_source = {
2072 .num_items = 4, 2617 .num_items = 4,
2073 .items = { 2618 .items = {
2074 { "Mic", 0x0 }, 2619 { "Mic", 0x0 },
@@ -2080,7 +2625,7 @@ static struct hda_input_mux alc880_capture_source = {
2080 2625
2081/* channel source setting (2/6 channel selection for 3-stack) */ 2626/* channel source setting (2/6 channel selection for 3-stack) */
2082/* 2ch mode */ 2627/* 2ch mode */
2083static struct hda_verb alc880_threestack_ch2_init[] = { 2628static const struct hda_verb alc880_threestack_ch2_init[] = {
2084 /* set line-in to input, mute it */ 2629 /* set line-in to input, mute it */
2085 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2630 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2086 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2631 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
@@ -2091,7 +2636,7 @@ static struct hda_verb alc880_threestack_ch2_init[] = {
2091}; 2636};
2092 2637
2093/* 6ch mode */ 2638/* 6ch mode */
2094static struct hda_verb alc880_threestack_ch6_init[] = { 2639static const struct hda_verb alc880_threestack_ch6_init[] = {
2095 /* set line-in to output, unmute it */ 2640 /* set line-in to output, unmute it */
2096 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2641 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2097 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2642 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
@@ -2101,12 +2646,12 @@ static struct hda_verb alc880_threestack_ch6_init[] = {
2101 { } /* end */ 2646 { } /* end */
2102}; 2647};
2103 2648
2104static struct hda_channel_mode alc880_threestack_modes[2] = { 2649static const struct hda_channel_mode alc880_threestack_modes[2] = {
2105 { 2, alc880_threestack_ch2_init }, 2650 { 2, alc880_threestack_ch2_init },
2106 { 6, alc880_threestack_ch6_init }, 2651 { 6, alc880_threestack_ch6_init },
2107}; 2652};
2108 2653
2109static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 2654static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2110 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2655 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2111 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2656 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2112 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2657 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
@@ -2170,17 +2715,30 @@ typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2170 2715
2171static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 2716static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2172 struct snd_ctl_elem_value *ucontrol, 2717 struct snd_ctl_elem_value *ucontrol,
2173 getput_call_t func) 2718 getput_call_t func, bool check_adc_switch)
2174{ 2719{
2175 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2720 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2176 struct alc_spec *spec = codec->spec; 2721 struct alc_spec *spec = codec->spec;
2177 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 2722 int i, err = 0;
2178 int err;
2179 2723
2180 mutex_lock(&codec->control_mutex); 2724 mutex_lock(&codec->control_mutex);
2181 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], 2725 if (check_adc_switch && spec->dual_adc_switch) {
2182 3, 0, HDA_INPUT); 2726 for (i = 0; i < spec->num_adc_nids; i++) {
2183 err = func(kcontrol, ucontrol); 2727 kcontrol->private_value =
2728 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2729 3, 0, HDA_INPUT);
2730 err = func(kcontrol, ucontrol);
2731 if (err < 0)
2732 goto error;
2733 }
2734 } else {
2735 i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2736 kcontrol->private_value =
2737 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2738 3, 0, HDA_INPUT);
2739 err = func(kcontrol, ucontrol);
2740 }
2741 error:
2184 mutex_unlock(&codec->control_mutex); 2742 mutex_unlock(&codec->control_mutex);
2185 return err; 2743 return err;
2186} 2744}
@@ -2189,14 +2747,14 @@ static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2189 struct snd_ctl_elem_value *ucontrol) 2747 struct snd_ctl_elem_value *ucontrol)
2190{ 2748{
2191 return alc_cap_getput_caller(kcontrol, ucontrol, 2749 return alc_cap_getput_caller(kcontrol, ucontrol,
2192 snd_hda_mixer_amp_volume_get); 2750 snd_hda_mixer_amp_volume_get, false);
2193} 2751}
2194 2752
2195static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, 2753static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2196 struct snd_ctl_elem_value *ucontrol) 2754 struct snd_ctl_elem_value *ucontrol)
2197{ 2755{
2198 return alc_cap_getput_caller(kcontrol, ucontrol, 2756 return alc_cap_getput_caller(kcontrol, ucontrol,
2199 snd_hda_mixer_amp_volume_put); 2757 snd_hda_mixer_amp_volume_put, true);
2200} 2758}
2201 2759
2202/* capture mixer elements */ 2760/* capture mixer elements */
@@ -2206,14 +2764,14 @@ static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2206 struct snd_ctl_elem_value *ucontrol) 2764 struct snd_ctl_elem_value *ucontrol)
2207{ 2765{
2208 return alc_cap_getput_caller(kcontrol, ucontrol, 2766 return alc_cap_getput_caller(kcontrol, ucontrol,
2209 snd_hda_mixer_amp_switch_get); 2767 snd_hda_mixer_amp_switch_get, false);
2210} 2768}
2211 2769
2212static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, 2770static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2213 struct snd_ctl_elem_value *ucontrol) 2771 struct snd_ctl_elem_value *ucontrol)
2214{ 2772{
2215 return alc_cap_getput_caller(kcontrol, ucontrol, 2773 return alc_cap_getput_caller(kcontrol, ucontrol,
2216 snd_hda_mixer_amp_switch_put); 2774 snd_hda_mixer_amp_switch_put, true);
2217} 2775}
2218 2776
2219#define _DEFINE_CAPMIX(num) \ 2777#define _DEFINE_CAPMIX(num) \
@@ -2251,14 +2809,14 @@ static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2251 } 2809 }
2252 2810
2253#define DEFINE_CAPMIX(num) \ 2811#define DEFINE_CAPMIX(num) \
2254static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ 2812static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2255 _DEFINE_CAPMIX(num), \ 2813 _DEFINE_CAPMIX(num), \
2256 _DEFINE_CAPSRC(num), \ 2814 _DEFINE_CAPSRC(num), \
2257 { } /* end */ \ 2815 { } /* end */ \
2258} 2816}
2259 2817
2260#define DEFINE_CAPMIX_NOSRC(num) \ 2818#define DEFINE_CAPMIX_NOSRC(num) \
2261static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ 2819static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2262 _DEFINE_CAPMIX(num), \ 2820 _DEFINE_CAPMIX(num), \
2263 { } /* end */ \ 2821 { } /* end */ \
2264} 2822}
@@ -2281,7 +2839,7 @@ DEFINE_CAPMIX_NOSRC(3);
2281 */ 2839 */
2282 2840
2283/* additional mixers to alc880_three_stack_mixer */ 2841/* additional mixers to alc880_three_stack_mixer */
2284static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 2842static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2285 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2843 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2286 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 2844 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2287 { } /* end */ 2845 { } /* end */
@@ -2289,7 +2847,7 @@ static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2289 2847
2290/* channel source setting (6/8 channel selection for 5-stack) */ 2848/* channel source setting (6/8 channel selection for 5-stack) */
2291/* 6ch mode */ 2849/* 6ch mode */
2292static struct hda_verb alc880_fivestack_ch6_init[] = { 2850static const struct hda_verb alc880_fivestack_ch6_init[] = {
2293 /* set line-in to input, mute it */ 2851 /* set line-in to input, mute it */
2294 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2852 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2295 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2853 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
@@ -2297,14 +2855,14 @@ static struct hda_verb alc880_fivestack_ch6_init[] = {
2297}; 2855};
2298 2856
2299/* 8ch mode */ 2857/* 8ch mode */
2300static struct hda_verb alc880_fivestack_ch8_init[] = { 2858static const struct hda_verb alc880_fivestack_ch8_init[] = {
2301 /* set line-in to output, unmute it */ 2859 /* set line-in to output, unmute it */
2302 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2860 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2303 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2861 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2304 { } /* end */ 2862 { } /* end */
2305}; 2863};
2306 2864
2307static struct hda_channel_mode alc880_fivestack_modes[2] = { 2865static const struct hda_channel_mode alc880_fivestack_modes[2] = {
2308 { 6, alc880_fivestack_ch6_init }, 2866 { 6, alc880_fivestack_ch6_init },
2309 { 8, alc880_fivestack_ch8_init }, 2867 { 8, alc880_fivestack_ch8_init },
2310}; 2868};
@@ -2319,12 +2877,12 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = {
2319 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 2877 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2320 */ 2878 */
2321 2879
2322static hda_nid_t alc880_6st_dac_nids[4] = { 2880static const hda_nid_t alc880_6st_dac_nids[4] = {
2323 /* front, rear, clfe, rear_surr */ 2881 /* front, rear, clfe, rear_surr */
2324 0x02, 0x03, 0x04, 0x05 2882 0x02, 0x03, 0x04, 0x05
2325}; 2883};
2326 2884
2327static struct hda_input_mux alc880_6stack_capture_source = { 2885static const struct hda_input_mux alc880_6stack_capture_source = {
2328 .num_items = 4, 2886 .num_items = 4,
2329 .items = { 2887 .items = {
2330 { "Mic", 0x0 }, 2888 { "Mic", 0x0 },
@@ -2335,11 +2893,11 @@ static struct hda_input_mux alc880_6stack_capture_source = {
2335}; 2893};
2336 2894
2337/* fixed 8-channels */ 2895/* fixed 8-channels */
2338static struct hda_channel_mode alc880_sixstack_modes[1] = { 2896static const struct hda_channel_mode alc880_sixstack_modes[1] = {
2339 { 8, NULL }, 2897 { 8, NULL },
2340}; 2898};
2341 2899
2342static struct snd_kcontrol_new alc880_six_stack_mixer[] = { 2900static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2343 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2901 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2344 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2902 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2345 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2903 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2394,18 +2952,18 @@ static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2394 * haven't setup any initialization verbs for these yet... 2952 * haven't setup any initialization verbs for these yet...
2395 */ 2953 */
2396 2954
2397static hda_nid_t alc880_w810_dac_nids[3] = { 2955static const hda_nid_t alc880_w810_dac_nids[3] = {
2398 /* front, rear/surround, clfe */ 2956 /* front, rear/surround, clfe */
2399 0x02, 0x03, 0x04 2957 0x02, 0x03, 0x04
2400}; 2958};
2401 2959
2402/* fixed 6 channels */ 2960/* fixed 6 channels */
2403static struct hda_channel_mode alc880_w810_modes[1] = { 2961static const struct hda_channel_mode alc880_w810_modes[1] = {
2404 { 6, NULL } 2962 { 6, NULL }
2405}; 2963};
2406 2964
2407/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 2965/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2408static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 2966static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2409 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2967 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2410 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2968 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2411 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2969 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2427,17 +2985,17 @@ static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2427 * Line = 0x1a 2985 * Line = 0x1a
2428 */ 2986 */
2429 2987
2430static hda_nid_t alc880_z71v_dac_nids[1] = { 2988static const hda_nid_t alc880_z71v_dac_nids[1] = {
2431 0x02 2989 0x02
2432}; 2990};
2433#define ALC880_Z71V_HP_DAC 0x03 2991#define ALC880_Z71V_HP_DAC 0x03
2434 2992
2435/* fixed 2 channels */ 2993/* fixed 2 channels */
2436static struct hda_channel_mode alc880_2_jack_modes[1] = { 2994static const struct hda_channel_mode alc880_2_jack_modes[1] = {
2437 { 2, NULL } 2995 { 2, NULL }
2438}; 2996};
2439 2997
2440static struct snd_kcontrol_new alc880_z71v_mixer[] = { 2998static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
2441 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2999 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2442 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3000 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2443 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3001 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2457,12 +3015,12 @@ static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2457 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 3015 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2458 */ 3016 */
2459 3017
2460static hda_nid_t alc880_f1734_dac_nids[1] = { 3018static const hda_nid_t alc880_f1734_dac_nids[1] = {
2461 0x03 3019 0x03
2462}; 3020};
2463#define ALC880_F1734_HP_DAC 0x02 3021#define ALC880_F1734_HP_DAC 0x02
2464 3022
2465static struct snd_kcontrol_new alc880_f1734_mixer[] = { 3023static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
2466 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3024 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2467 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 3025 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2468 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3026 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2474,7 +3032,7 @@ static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2474 { } /* end */ 3032 { } /* end */
2475}; 3033};
2476 3034
2477static struct hda_input_mux alc880_f1734_capture_source = { 3035static const struct hda_input_mux alc880_f1734_capture_source = {
2478 .num_items = 2, 3036 .num_items = 2,
2479 .items = { 3037 .items = {
2480 { "Mic", 0x1 }, 3038 { "Mic", 0x1 },
@@ -2494,7 +3052,7 @@ static struct hda_input_mux alc880_f1734_capture_source = {
2494#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 3052#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2495#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 3053#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2496 3054
2497static struct snd_kcontrol_new alc880_asus_mixer[] = { 3055static const struct snd_kcontrol_new alc880_asus_mixer[] = {
2498 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3056 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2499 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3057 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2500 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3058 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2528,14 +3086,14 @@ static struct snd_kcontrol_new alc880_asus_mixer[] = {
2528 */ 3086 */
2529 3087
2530/* additional mixers to alc880_asus_mixer */ 3088/* additional mixers to alc880_asus_mixer */
2531static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 3089static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2532 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 3090 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2533 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 3091 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2534 { } /* end */ 3092 { } /* end */
2535}; 3093};
2536 3094
2537/* TCL S700 */ 3095/* TCL S700 */
2538static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 3096static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2539 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3097 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2540 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 3098 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2541 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 3099 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -2549,7 +3107,7 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2549}; 3107};
2550 3108
2551/* Uniwill */ 3109/* Uniwill */
2552static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 3110static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2553 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3111 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2554 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 3112 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2555 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3113 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2576,21 +3134,21 @@ static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2576 { } /* end */ 3134 { } /* end */
2577}; 3135};
2578 3136
2579static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 3137static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2580 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3138 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2581 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 3139 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2582 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3140 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2583 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 3141 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2584 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 3142 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2585 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 3143 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2586 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3144 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2587 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2588 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3146 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2589 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 3147 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2590 { } /* end */ 3148 { } /* end */
2591}; 3149};
2592 3150
2593static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 3151static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2594 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3152 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2595 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 3153 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2596 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3154 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2607,7 +3165,7 @@ static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2607/* 3165/*
2608 * slave controls for virtual master 3166 * slave controls for virtual master
2609 */ 3167 */
2610static const char *alc_slave_vols[] = { 3168static const char * const alc_slave_vols[] = {
2611 "Front Playback Volume", 3169 "Front Playback Volume",
2612 "Surround Playback Volume", 3170 "Surround Playback Volume",
2613 "Center Playback Volume", 3171 "Center Playback Volume",
@@ -2617,11 +3175,10 @@ static const char *alc_slave_vols[] = {
2617 "Speaker Playback Volume", 3175 "Speaker Playback Volume",
2618 "Mono Playback Volume", 3176 "Mono Playback Volume",
2619 "Line-Out Playback Volume", 3177 "Line-Out Playback Volume",
2620 "PCM Playback Volume",
2621 NULL, 3178 NULL,
2622}; 3179};
2623 3180
2624static const char *alc_slave_sws[] = { 3181static const char * const alc_slave_sws[] = {
2625 "Front Playback Switch", 3182 "Front Playback Switch",
2626 "Surround Playback Switch", 3183 "Surround Playback Switch",
2627 "Center Playback Switch", 3184 "Center Playback Switch",
@@ -2632,7 +3189,6 @@ static const char *alc_slave_sws[] = {
2632 "Mono Playback Switch", 3189 "Mono Playback Switch",
2633 "IEC958 Playback Switch", 3190 "IEC958 Playback Switch",
2634 "Line-Out Playback Switch", 3191 "Line-Out Playback Switch",
2635 "PCM Playback Switch",
2636 NULL, 3192 NULL,
2637}; 3193};
2638 3194
@@ -2653,7 +3209,7 @@ static void alc_free_kctls(struct hda_codec *codec);
2653 3209
2654#ifdef CONFIG_SND_HDA_INPUT_BEEP 3210#ifdef CONFIG_SND_HDA_INPUT_BEEP
2655/* additional beep mixers; the actual parameters are overwritten at build */ 3211/* additional beep mixers; the actual parameters are overwritten at build */
2656static struct snd_kcontrol_new alc_beep_mixer[] = { 3212static const struct snd_kcontrol_new alc_beep_mixer[] = {
2657 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), 3213 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2658 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), 3214 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2659 { } /* end */ 3215 { } /* end */
@@ -2664,7 +3220,7 @@ static int alc_build_controls(struct hda_codec *codec)
2664{ 3220{
2665 struct alc_spec *spec = codec->spec; 3221 struct alc_spec *spec = codec->spec;
2666 struct snd_kcontrol *kctl = NULL; 3222 struct snd_kcontrol *kctl = NULL;
2667 struct snd_kcontrol_new *knew; 3223 const struct snd_kcontrol_new *knew;
2668 int i, j, err; 3224 int i, j, err;
2669 unsigned int u; 3225 unsigned int u;
2670 hda_nid_t nid; 3226 hda_nid_t nid;
@@ -2701,7 +3257,7 @@ static int alc_build_controls(struct hda_codec *codec)
2701#ifdef CONFIG_SND_HDA_INPUT_BEEP 3257#ifdef CONFIG_SND_HDA_INPUT_BEEP
2702 /* create beep controls if needed */ 3258 /* create beep controls if needed */
2703 if (spec->beep_amp) { 3259 if (spec->beep_amp) {
2704 struct snd_kcontrol_new *knew; 3260 const struct snd_kcontrol_new *knew;
2705 for (knew = alc_beep_mixer; knew->name; knew++) { 3261 for (knew = alc_beep_mixer; knew->name; knew++) {
2706 struct snd_kcontrol *kctl; 3262 struct snd_kcontrol *kctl;
2707 kctl = snd_ctl_new1(knew, codec); 3263 kctl = snd_ctl_new1(knew, codec);
@@ -2740,7 +3296,7 @@ static int alc_build_controls(struct hda_codec *codec)
2740 if (!kctl) 3296 if (!kctl)
2741 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 3297 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2742 for (i = 0; kctl && i < kctl->count; i++) { 3298 for (i = 0; kctl && i < kctl->count; i++) {
2743 hda_nid_t *nids = spec->capsrc_nids; 3299 const hda_nid_t *nids = spec->capsrc_nids;
2744 if (!nids) 3300 if (!nids)
2745 nids = spec->adc_nids; 3301 nids = spec->adc_nids;
2746 err = snd_hda_add_nid(codec, kctl, i, nids[i]); 3302 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
@@ -2818,7 +3374,7 @@ static int alc_build_controls(struct hda_codec *codec)
2818/* 3374/*
2819 * generic initialization of ADC, input mixers and output mixers 3375 * generic initialization of ADC, input mixers and output mixers
2820 */ 3376 */
2821static struct hda_verb alc880_volume_init_verbs[] = { 3377static const struct hda_verb alc880_volume_init_verbs[] = {
2822 /* 3378 /*
2823 * Unmute ADC0-2 and set the default input to mic-in 3379 * Unmute ADC0-2 and set the default input to mic-in
2824 */ 3380 */
@@ -2869,7 +3425,7 @@ static struct hda_verb alc880_volume_init_verbs[] = {
2869 * 3-stack pin configuration: 3425 * 3-stack pin configuration:
2870 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 3426 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2871 */ 3427 */
2872static struct hda_verb alc880_pin_3stack_init_verbs[] = { 3428static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
2873 /* 3429 /*
2874 * preset connection lists of input pins 3430 * preset connection lists of input pins
2875 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 3431 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
@@ -2907,7 +3463,7 @@ static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2907 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 3463 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2908 * line-in/side = 0x1a, f-mic = 0x1b 3464 * line-in/side = 0x1a, f-mic = 0x1b
2909 */ 3465 */
2910static struct hda_verb alc880_pin_5stack_init_verbs[] = { 3466static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
2911 /* 3467 /*
2912 * preset connection lists of input pins 3468 * preset connection lists of input pins
2913 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 3469 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
@@ -2951,7 +3507,7 @@ static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2951 * W810 pin configuration: 3507 * W810 pin configuration:
2952 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 3508 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2953 */ 3509 */
2954static struct hda_verb alc880_pin_w810_init_verbs[] = { 3510static const struct hda_verb alc880_pin_w810_init_verbs[] = {
2955 /* hphone/speaker input selector: front DAC */ 3511 /* hphone/speaker input selector: front DAC */
2956 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 3512 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2957 3513
@@ -2972,7 +3528,7 @@ static struct hda_verb alc880_pin_w810_init_verbs[] = {
2972 * Z71V pin configuration: 3528 * Z71V pin configuration:
2973 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 3529 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2974 */ 3530 */
2975static struct hda_verb alc880_pin_z71v_init_verbs[] = { 3531static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
2976 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2977 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2978 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3534 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -2991,7 +3547,7 @@ static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2991 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 3547 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2992 * f-mic = 0x19, line = 0x1a, HP = 0x1b 3548 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2993 */ 3549 */
2994static struct hda_verb alc880_pin_6stack_init_verbs[] = { 3550static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
2995 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3551 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2996 3552
2997 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3553 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -3021,7 +3577,7 @@ static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3021 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 3577 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3022 * line = 0x1a 3578 * line = 0x1a
3023 */ 3579 */
3024static struct hda_verb alc880_uniwill_init_verbs[] = { 3580static const struct hda_verb alc880_uniwill_init_verbs[] = {
3025 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3581 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3026 3582
3027 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3583 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -3059,7 +3615,7 @@ static struct hda_verb alc880_uniwill_init_verbs[] = {
3059* Uniwill P53 3615* Uniwill P53
3060* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 3616* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3061 */ 3617 */
3062static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 3618static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3063 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3619 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3064 3620
3065 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3621 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -3088,13 +3644,13 @@ static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3088 { } 3644 { }
3089}; 3645};
3090 3646
3091static struct hda_verb alc880_beep_init_verbs[] = { 3647static const struct hda_verb alc880_beep_init_verbs[] = {
3092 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 3648 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3093 { } 3649 { }
3094}; 3650};
3095 3651
3096/* auto-toggle front mic */ 3652/* auto-toggle front mic */
3097static void alc880_uniwill_mic_automute(struct hda_codec *codec) 3653static void alc88x_simple_mic_automute(struct hda_codec *codec)
3098{ 3654{
3099 unsigned int present; 3655 unsigned int present;
3100 unsigned char bits; 3656 unsigned char bits;
@@ -3111,12 +3667,14 @@ static void alc880_uniwill_setup(struct hda_codec *codec)
3111 spec->autocfg.hp_pins[0] = 0x14; 3667 spec->autocfg.hp_pins[0] = 0x14;
3112 spec->autocfg.speaker_pins[0] = 0x15; 3668 spec->autocfg.speaker_pins[0] = 0x15;
3113 spec->autocfg.speaker_pins[0] = 0x16; 3669 spec->autocfg.speaker_pins[0] = 0x16;
3670 spec->automute = 1;
3671 spec->automute_mode = ALC_AUTOMUTE_AMP;
3114} 3672}
3115 3673
3116static void alc880_uniwill_init_hook(struct hda_codec *codec) 3674static void alc880_uniwill_init_hook(struct hda_codec *codec)
3117{ 3675{
3118 alc_automute_amp(codec); 3676 alc_hp_automute(codec);
3119 alc880_uniwill_mic_automute(codec); 3677 alc88x_simple_mic_automute(codec);
3120} 3678}
3121 3679
3122static void alc880_uniwill_unsol_event(struct hda_codec *codec, 3680static void alc880_uniwill_unsol_event(struct hda_codec *codec,
@@ -3127,10 +3685,10 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3127 */ 3685 */
3128 switch (res >> 28) { 3686 switch (res >> 28) {
3129 case ALC880_MIC_EVENT: 3687 case ALC880_MIC_EVENT:
3130 alc880_uniwill_mic_automute(codec); 3688 alc88x_simple_mic_automute(codec);
3131 break; 3689 break;
3132 default: 3690 default:
3133 alc_automute_amp_unsol_event(codec, res); 3691 alc_sku_unsol_event(codec, res);
3134 break; 3692 break;
3135 } 3693 }
3136} 3694}
@@ -3141,6 +3699,8 @@ static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3141 3699
3142 spec->autocfg.hp_pins[0] = 0x14; 3700 spec->autocfg.hp_pins[0] = 0x14;
3143 spec->autocfg.speaker_pins[0] = 0x15; 3701 spec->autocfg.speaker_pins[0] = 0x15;
3702 spec->automute = 1;
3703 spec->automute_mode = ALC_AUTOMUTE_AMP;
3144} 3704}
3145 3705
3146static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 3706static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
@@ -3165,14 +3725,14 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3165 if ((res >> 28) == ALC880_DCVOL_EVENT) 3725 if ((res >> 28) == ALC880_DCVOL_EVENT)
3166 alc880_uniwill_p53_dcvol_automute(codec); 3726 alc880_uniwill_p53_dcvol_automute(codec);
3167 else 3727 else
3168 alc_automute_amp_unsol_event(codec, res); 3728 alc_sku_unsol_event(codec, res);
3169} 3729}
3170 3730
3171/* 3731/*
3172 * F1734 pin configuration: 3732 * F1734 pin configuration:
3173 * HP = 0x14, speaker-out = 0x15, mic = 0x18 3733 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3174 */ 3734 */
3175static struct hda_verb alc880_pin_f1734_init_verbs[] = { 3735static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
3176 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, 3736 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3177 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3737 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3178 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3738 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -3204,7 +3764,7 @@ static struct hda_verb alc880_pin_f1734_init_verbs[] = {
3204 * ASUS pin configuration: 3764 * ASUS pin configuration:
3205 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 3765 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3206 */ 3766 */
3207static struct hda_verb alc880_pin_asus_init_verbs[] = { 3767static const struct hda_verb alc880_pin_asus_init_verbs[] = {
3208 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3768 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3209 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3769 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3210 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3770 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
@@ -3238,7 +3798,7 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = {
3238#define alc880_gpio3_init_verbs alc_gpio3_init_verbs 3798#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3239 3799
3240/* Clevo m520g init */ 3800/* Clevo m520g init */
3241static struct hda_verb alc880_pin_clevo_init_verbs[] = { 3801static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
3242 /* headphone output */ 3802 /* headphone output */
3243 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3803 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3244 /* line-out */ 3804 /* line-out */
@@ -3266,7 +3826,7 @@ static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3266 { } 3826 { }
3267}; 3827};
3268 3828
3269static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 3829static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3270 /* change to EAPD mode */ 3830 /* change to EAPD mode */
3271 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3831 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3272 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3832 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
@@ -3304,12 +3864,12 @@ static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3304 */ 3864 */
3305 3865
3306/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 3866/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3307static hda_nid_t alc880_lg_dac_nids[3] = { 3867static const hda_nid_t alc880_lg_dac_nids[3] = {
3308 0x05, 0x02, 0x03 3868 0x05, 0x02, 0x03
3309}; 3869};
3310 3870
3311/* seems analog CD is not working */ 3871/* seems analog CD is not working */
3312static struct hda_input_mux alc880_lg_capture_source = { 3872static const struct hda_input_mux alc880_lg_capture_source = {
3313 .num_items = 3, 3873 .num_items = 3,
3314 .items = { 3874 .items = {
3315 { "Mic", 0x1 }, 3875 { "Mic", 0x1 },
@@ -3319,34 +3879,34 @@ static struct hda_input_mux alc880_lg_capture_source = {
3319}; 3879};
3320 3880
3321/* 2,4,6 channel modes */ 3881/* 2,4,6 channel modes */
3322static struct hda_verb alc880_lg_ch2_init[] = { 3882static const struct hda_verb alc880_lg_ch2_init[] = {
3323 /* set line-in and mic-in to input */ 3883 /* set line-in and mic-in to input */
3324 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 3884 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3325 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3885 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3326 { } 3886 { }
3327}; 3887};
3328 3888
3329static struct hda_verb alc880_lg_ch4_init[] = { 3889static const struct hda_verb alc880_lg_ch4_init[] = {
3330 /* set line-in to out and mic-in to input */ 3890 /* set line-in to out and mic-in to input */
3331 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3891 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3332 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3892 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3333 { } 3893 { }
3334}; 3894};
3335 3895
3336static struct hda_verb alc880_lg_ch6_init[] = { 3896static const struct hda_verb alc880_lg_ch6_init[] = {
3337 /* set line-in and mic-in to output */ 3897 /* set line-in and mic-in to output */
3338 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3898 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3339 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3899 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3340 { } 3900 { }
3341}; 3901};
3342 3902
3343static struct hda_channel_mode alc880_lg_ch_modes[3] = { 3903static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
3344 { 2, alc880_lg_ch2_init }, 3904 { 2, alc880_lg_ch2_init },
3345 { 4, alc880_lg_ch4_init }, 3905 { 4, alc880_lg_ch4_init },
3346 { 6, alc880_lg_ch6_init }, 3906 { 6, alc880_lg_ch6_init },
3347}; 3907};
3348 3908
3349static struct snd_kcontrol_new alc880_lg_mixer[] = { 3909static const struct snd_kcontrol_new alc880_lg_mixer[] = {
3350 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3910 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3351 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), 3911 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3352 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3912 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -3371,7 +3931,7 @@ static struct snd_kcontrol_new alc880_lg_mixer[] = {
3371 { } /* end */ 3931 { } /* end */
3372}; 3932};
3373 3933
3374static struct hda_verb alc880_lg_init_verbs[] = { 3934static const struct hda_verb alc880_lg_init_verbs[] = {
3375 /* set capture source to mic-in */ 3935 /* set capture source to mic-in */
3376 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3936 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3377 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3937 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -3409,6 +3969,8 @@ static void alc880_lg_setup(struct hda_codec *codec)
3409 3969
3410 spec->autocfg.hp_pins[0] = 0x1b; 3970 spec->autocfg.hp_pins[0] = 0x1b;
3411 spec->autocfg.speaker_pins[0] = 0x17; 3971 spec->autocfg.speaker_pins[0] = 0x17;
3972 spec->automute = 1;
3973 spec->automute_mode = ALC_AUTOMUTE_AMP;
3412} 3974}
3413 3975
3414/* 3976/*
@@ -3423,7 +3985,7 @@ static void alc880_lg_setup(struct hda_codec *codec)
3423 * SPDIF-Out: 0x1e 3985 * SPDIF-Out: 0x1e
3424 */ 3986 */
3425 3987
3426static struct hda_input_mux alc880_lg_lw_capture_source = { 3988static const struct hda_input_mux alc880_lg_lw_capture_source = {
3427 .num_items = 3, 3989 .num_items = 3,
3428 .items = { 3990 .items = {
3429 { "Mic", 0x0 }, 3991 { "Mic", 0x0 },
@@ -3434,7 +3996,7 @@ static struct hda_input_mux alc880_lg_lw_capture_source = {
3434 3996
3435#define alc880_lg_lw_modes alc880_threestack_modes 3997#define alc880_lg_lw_modes alc880_threestack_modes
3436 3998
3437static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 3999static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3438 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4000 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3439 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4001 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3440 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 4002 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
@@ -3459,7 +4021,7 @@ static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3459 { } /* end */ 4021 { } /* end */
3460}; 4022};
3461 4023
3462static struct hda_verb alc880_lg_lw_init_verbs[] = { 4024static const struct hda_verb alc880_lg_lw_init_verbs[] = {
3463 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 4025 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3464 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 4026 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3465 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 4027 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
@@ -3493,9 +4055,11 @@ static void alc880_lg_lw_setup(struct hda_codec *codec)
3493 4055
3494 spec->autocfg.hp_pins[0] = 0x1b; 4056 spec->autocfg.hp_pins[0] = 0x1b;
3495 spec->autocfg.speaker_pins[0] = 0x14; 4057 spec->autocfg.speaker_pins[0] = 0x14;
4058 spec->automute = 1;
4059 spec->automute_mode = ALC_AUTOMUTE_AMP;
3496} 4060}
3497 4061
3498static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { 4062static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3499 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4063 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3500 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 4064 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3501 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4065 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -3505,7 +4069,7 @@ static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3505 { } /* end */ 4069 { } /* end */
3506}; 4070};
3507 4071
3508static struct hda_input_mux alc880_medion_rim_capture_source = { 4072static const struct hda_input_mux alc880_medion_rim_capture_source = {
3509 .num_items = 2, 4073 .num_items = 2,
3510 .items = { 4074 .items = {
3511 { "Mic", 0x0 }, 4075 { "Mic", 0x0 },
@@ -3513,7 +4077,7 @@ static struct hda_input_mux alc880_medion_rim_capture_source = {
3513 }, 4077 },
3514}; 4078};
3515 4079
3516static struct hda_verb alc880_medion_rim_init_verbs[] = { 4080static const struct hda_verb alc880_medion_rim_init_verbs[] = {
3517 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 4081 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3518 4082
3519 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4083 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -3540,7 +4104,7 @@ static struct hda_verb alc880_medion_rim_init_verbs[] = {
3540static void alc880_medion_rim_automute(struct hda_codec *codec) 4104static void alc880_medion_rim_automute(struct hda_codec *codec)
3541{ 4105{
3542 struct alc_spec *spec = codec->spec; 4106 struct alc_spec *spec = codec->spec;
3543 alc_automute_amp(codec); 4107 alc_hp_automute(codec);
3544 /* toggle EAPD */ 4108 /* toggle EAPD */
3545 if (spec->jack_present) 4109 if (spec->jack_present)
3546 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); 4110 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
@@ -3564,10 +4128,12 @@ static void alc880_medion_rim_setup(struct hda_codec *codec)
3564 4128
3565 spec->autocfg.hp_pins[0] = 0x14; 4129 spec->autocfg.hp_pins[0] = 0x14;
3566 spec->autocfg.speaker_pins[0] = 0x1b; 4130 spec->autocfg.speaker_pins[0] = 0x1b;
4131 spec->automute = 1;
4132 spec->automute_mode = ALC_AUTOMUTE_AMP;
3567} 4133}
3568 4134
3569#ifdef CONFIG_SND_HDA_POWER_SAVE 4135#ifdef CONFIG_SND_HDA_POWER_SAVE
3570static struct hda_amp_list alc880_loopbacks[] = { 4136static const struct hda_amp_list alc880_loopbacks[] = {
3571 { 0x0b, HDA_INPUT, 0 }, 4137 { 0x0b, HDA_INPUT, 0 },
3572 { 0x0b, HDA_INPUT, 1 }, 4138 { 0x0b, HDA_INPUT, 1 },
3573 { 0x0b, HDA_INPUT, 2 }, 4139 { 0x0b, HDA_INPUT, 2 },
@@ -3576,7 +4142,7 @@ static struct hda_amp_list alc880_loopbacks[] = {
3576 { } /* end */ 4142 { } /* end */
3577}; 4143};
3578 4144
3579static struct hda_amp_list alc880_lg_loopbacks[] = { 4145static const struct hda_amp_list alc880_lg_loopbacks[] = {
3580 { 0x0b, HDA_INPUT, 1 }, 4146 { 0x0b, HDA_INPUT, 1 },
3581 { 0x0b, HDA_INPUT, 6 }, 4147 { 0x0b, HDA_INPUT, 6 },
3582 { 0x0b, HDA_INPUT, 7 }, 4148 { 0x0b, HDA_INPUT, 7 },
@@ -3588,6 +4154,8 @@ static struct hda_amp_list alc880_lg_loopbacks[] = {
3588 * Common callbacks 4154 * Common callbacks
3589 */ 4155 */
3590 4156
4157static void alc_init_special_input_src(struct hda_codec *codec);
4158
3591static int alc_init(struct hda_codec *codec) 4159static int alc_init(struct hda_codec *codec)
3592{ 4160{
3593 struct alc_spec *spec = codec->spec; 4161 struct alc_spec *spec = codec->spec;
@@ -3598,14 +4166,14 @@ static int alc_init(struct hda_codec *codec)
3598 4166
3599 for (i = 0; i < spec->num_init_verbs; i++) 4167 for (i = 0; i < spec->num_init_verbs; i++)
3600 snd_hda_sequence_write(codec, spec->init_verbs[i]); 4168 snd_hda_sequence_write(codec, spec->init_verbs[i]);
4169 alc_init_special_input_src(codec);
3601 4170
3602 if (spec->init_hook) 4171 if (spec->init_hook)
3603 spec->init_hook(codec); 4172 spec->init_hook(codec);
3604 4173
3605#ifdef CONFIG_SND_HDA_POWER_SAVE 4174 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
3606 if (codec->patch_ops.check_power_status) 4175
3607 codec->patch_ops.check_power_status(codec, 0x01); 4176 hda_call_check_power_status(codec, 0x01);
3608#endif
3609 return 0; 4177 return 0;
3610} 4178}
3611 4179
@@ -3746,7 +4314,7 @@ static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3746 return 0; 4314 return 0;
3747} 4315}
3748 4316
3749static struct hda_pcm_stream dualmic_pcm_analog_capture = { 4317static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
3750 .substreams = 1, 4318 .substreams = 1,
3751 .channels_min = 2, 4319 .channels_min = 2,
3752 .channels_max = 2, 4320 .channels_max = 2,
@@ -3759,7 +4327,7 @@ static struct hda_pcm_stream dualmic_pcm_analog_capture = {
3759 4327
3760/* 4328/*
3761 */ 4329 */
3762static struct hda_pcm_stream alc880_pcm_analog_playback = { 4330static const struct hda_pcm_stream alc880_pcm_analog_playback = {
3763 .substreams = 1, 4331 .substreams = 1,
3764 .channels_min = 2, 4332 .channels_min = 2,
3765 .channels_max = 8, 4333 .channels_max = 8,
@@ -3771,21 +4339,21 @@ static struct hda_pcm_stream alc880_pcm_analog_playback = {
3771 }, 4339 },
3772}; 4340};
3773 4341
3774static struct hda_pcm_stream alc880_pcm_analog_capture = { 4342static const struct hda_pcm_stream alc880_pcm_analog_capture = {
3775 .substreams = 1, 4343 .substreams = 1,
3776 .channels_min = 2, 4344 .channels_min = 2,
3777 .channels_max = 2, 4345 .channels_max = 2,
3778 /* NID is set in alc_build_pcms */ 4346 /* NID is set in alc_build_pcms */
3779}; 4347};
3780 4348
3781static struct hda_pcm_stream alc880_pcm_analog_alt_playback = { 4349static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3782 .substreams = 1, 4350 .substreams = 1,
3783 .channels_min = 2, 4351 .channels_min = 2,
3784 .channels_max = 2, 4352 .channels_max = 2,
3785 /* NID is set in alc_build_pcms */ 4353 /* NID is set in alc_build_pcms */
3786}; 4354};
3787 4355
3788static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { 4356static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3789 .substreams = 2, /* can be overridden */ 4357 .substreams = 2, /* can be overridden */
3790 .channels_min = 2, 4358 .channels_min = 2,
3791 .channels_max = 2, 4359 .channels_max = 2,
@@ -3796,7 +4364,7 @@ static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3796 }, 4364 },
3797}; 4365};
3798 4366
3799static struct hda_pcm_stream alc880_pcm_digital_playback = { 4367static const struct hda_pcm_stream alc880_pcm_digital_playback = {
3800 .substreams = 1, 4368 .substreams = 1,
3801 .channels_min = 2, 4369 .channels_min = 2,
3802 .channels_max = 2, 4370 .channels_max = 2,
@@ -3809,7 +4377,7 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = {
3809 }, 4377 },
3810}; 4378};
3811 4379
3812static struct hda_pcm_stream alc880_pcm_digital_capture = { 4380static const struct hda_pcm_stream alc880_pcm_digital_capture = {
3813 .substreams = 1, 4381 .substreams = 1,
3814 .channels_min = 2, 4382 .channels_min = 2,
3815 .channels_max = 2, 4383 .channels_max = 2,
@@ -3817,7 +4385,7 @@ static struct hda_pcm_stream alc880_pcm_digital_capture = {
3817}; 4385};
3818 4386
3819/* Used by alc_build_pcms to flag that a PCM has no playback stream */ 4387/* Used by alc_build_pcms to flag that a PCM has no playback stream */
3820static struct hda_pcm_stream alc_pcm_null_stream = { 4388static const struct hda_pcm_stream alc_pcm_null_stream = {
3821 .substreams = 0, 4389 .substreams = 0,
3822 .channels_min = 0, 4390 .channels_min = 0,
3823 .channels_max = 0, 4391 .channels_max = 0,
@@ -3911,7 +4479,7 @@ static int alc_build_pcms(struct hda_codec *codec)
3911 alc_pcm_null_stream; 4479 alc_pcm_null_stream;
3912 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 4480 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3913 } 4481 }
3914 if (spec->num_adc_nids > 1) { 4482 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
3915 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 4483 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3916 *spec->stream_analog_alt_capture; 4484 *spec->stream_analog_alt_capture;
3917 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 4485 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
@@ -3930,6 +4498,10 @@ static int alc_build_pcms(struct hda_codec *codec)
3930 4498
3931static inline void alc_shutup(struct hda_codec *codec) 4499static inline void alc_shutup(struct hda_codec *codec)
3932{ 4500{
4501 struct alc_spec *spec = codec->spec;
4502
4503 if (spec && spec->shutup)
4504 spec->shutup(codec);
3933 snd_hda_shutup_pins(codec); 4505 snd_hda_shutup_pins(codec);
3934} 4506}
3935 4507
@@ -3954,6 +4526,7 @@ static void alc_free(struct hda_codec *codec)
3954 return; 4526 return;
3955 4527
3956 alc_shutup(codec); 4528 alc_shutup(codec);
4529 snd_hda_input_jack_free(codec);
3957 alc_free_kctls(codec); 4530 alc_free_kctls(codec);
3958 kfree(spec); 4531 kfree(spec);
3959 snd_hda_detach_beep_device(codec); 4532 snd_hda_detach_beep_device(codec);
@@ -3962,27 +4535,7 @@ static void alc_free(struct hda_codec *codec)
3962#ifdef CONFIG_SND_HDA_POWER_SAVE 4535#ifdef CONFIG_SND_HDA_POWER_SAVE
3963static void alc_power_eapd(struct hda_codec *codec) 4536static void alc_power_eapd(struct hda_codec *codec)
3964{ 4537{
3965 /* We currently only handle front, HP */ 4538 alc_auto_setup_eapd(codec, false);
3966 switch (codec->vendor_id) {
3967 case 0x10ec0260:
3968 set_eapd(codec, 0x0f, 0);
3969 set_eapd(codec, 0x10, 0);
3970 break;
3971 case 0x10ec0262:
3972 case 0x10ec0267:
3973 case 0x10ec0268:
3974 case 0x10ec0269:
3975 case 0x10ec0270:
3976 case 0x10ec0272:
3977 case 0x10ec0660:
3978 case 0x10ec0662:
3979 case 0x10ec0663:
3980 case 0x10ec0862:
3981 case 0x10ec0889:
3982 set_eapd(codec, 0x14, 0);
3983 set_eapd(codec, 0x15, 0);
3984 break;
3985 }
3986} 4539}
3987 4540
3988static int alc_suspend(struct hda_codec *codec, pm_message_t state) 4541static int alc_suspend(struct hda_codec *codec, pm_message_t state)
@@ -3998,20 +4551,18 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3998#ifdef SND_HDA_NEEDS_RESUME 4551#ifdef SND_HDA_NEEDS_RESUME
3999static int alc_resume(struct hda_codec *codec) 4552static int alc_resume(struct hda_codec *codec)
4000{ 4553{
4554 msleep(150); /* to avoid pop noise */
4001 codec->patch_ops.init(codec); 4555 codec->patch_ops.init(codec);
4002 snd_hda_codec_resume_amp(codec); 4556 snd_hda_codec_resume_amp(codec);
4003 snd_hda_codec_resume_cache(codec); 4557 snd_hda_codec_resume_cache(codec);
4004#ifdef CONFIG_SND_HDA_POWER_SAVE 4558 hda_call_check_power_status(codec, 0x01);
4005 if (codec->patch_ops.check_power_status)
4006 codec->patch_ops.check_power_status(codec, 0x01);
4007#endif
4008 return 0; 4559 return 0;
4009} 4560}
4010#endif 4561#endif
4011 4562
4012/* 4563/*
4013 */ 4564 */
4014static struct hda_codec_ops alc_patch_ops = { 4565static const struct hda_codec_ops alc_patch_ops = {
4015 .build_controls = alc_build_controls, 4566 .build_controls = alc_build_controls,
4016 .build_pcms = alc_build_pcms, 4567 .build_pcms = alc_build_pcms,
4017 .init = alc_init, 4568 .init = alc_init,
@@ -4046,11 +4597,11 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name)
4046 * enum controls. 4597 * enum controls.
4047 */ 4598 */
4048#ifdef CONFIG_SND_DEBUG 4599#ifdef CONFIG_SND_DEBUG
4049static hda_nid_t alc880_test_dac_nids[4] = { 4600static const hda_nid_t alc880_test_dac_nids[4] = {
4050 0x02, 0x03, 0x04, 0x05 4601 0x02, 0x03, 0x04, 0x05
4051}; 4602};
4052 4603
4053static struct hda_input_mux alc880_test_capture_source = { 4604static const struct hda_input_mux alc880_test_capture_source = {
4054 .num_items = 7, 4605 .num_items = 7,
4055 .items = { 4606 .items = {
4056 { "In-1", 0x0 }, 4607 { "In-1", 0x0 },
@@ -4063,7 +4614,7 @@ static struct hda_input_mux alc880_test_capture_source = {
4063 }, 4614 },
4064}; 4615};
4065 4616
4066static struct hda_channel_mode alc880_test_modes[4] = { 4617static const struct hda_channel_mode alc880_test_modes[4] = {
4067 { 2, NULL }, 4618 { 2, NULL },
4068 { 4, NULL }, 4619 { 4, NULL },
4069 { 6, NULL }, 4620 { 6, NULL },
@@ -4073,7 +4624,7 @@ static struct hda_channel_mode alc880_test_modes[4] = {
4073static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 4624static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4074 struct snd_ctl_elem_info *uinfo) 4625 struct snd_ctl_elem_info *uinfo)
4075{ 4626{
4076 static char *texts[] = { 4627 static const char * const texts[] = {
4077 "N/A", "Line Out", "HP Out", 4628 "N/A", "Line Out", "HP Out",
4078 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 4629 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4079 }; 4630 };
@@ -4118,7 +4669,7 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4118{ 4669{
4119 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4670 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4120 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4671 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4121 static unsigned int ctls[] = { 4672 static const unsigned int ctls[] = {
4122 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 4673 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4123 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 4674 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4124 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 4675 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
@@ -4148,7 +4699,7 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4148static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 4699static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4149 struct snd_ctl_elem_info *uinfo) 4700 struct snd_ctl_elem_info *uinfo)
4150{ 4701{
4151 static char *texts[] = { 4702 static const char * const texts[] = {
4152 "Front", "Surround", "CLFE", "Side" 4703 "Front", "Surround", "CLFE", "Side"
4153 }; 4704 };
4154 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4705 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -4209,7 +4760,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4209 .private_value = nid \ 4760 .private_value = nid \
4210 } 4761 }
4211 4762
4212static struct snd_kcontrol_new alc880_test_mixer[] = { 4763static const struct snd_kcontrol_new alc880_test_mixer[] = {
4213 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4764 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4214 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 4765 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4215 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 4766 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
@@ -4250,7 +4801,7 @@ static struct snd_kcontrol_new alc880_test_mixer[] = {
4250 { } /* end */ 4801 { } /* end */
4251}; 4802};
4252 4803
4253static struct hda_verb alc880_test_init_verbs[] = { 4804static const struct hda_verb alc880_test_init_verbs[] = {
4254 /* Unmute inputs of 0x0c - 0x0f */ 4805 /* Unmute inputs of 0x0c - 0x0f */
4255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4806 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4807 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -4306,7 +4857,7 @@ static struct hda_verb alc880_test_init_verbs[] = {
4306/* 4857/*
4307 */ 4858 */
4308 4859
4309static const char *alc880_models[ALC880_MODEL_LAST] = { 4860static const char * const alc880_models[ALC880_MODEL_LAST] = {
4310 [ALC880_3ST] = "3stack", 4861 [ALC880_3ST] = "3stack",
4311 [ALC880_TCL_S700] = "tcl", 4862 [ALC880_TCL_S700] = "tcl",
4312 [ALC880_3ST_DIG] = "3stack-digout", 4863 [ALC880_3ST_DIG] = "3stack-digout",
@@ -4334,7 +4885,7 @@ static const char *alc880_models[ALC880_MODEL_LAST] = {
4334 [ALC880_AUTO] = "auto", 4885 [ALC880_AUTO] = "auto",
4335}; 4886};
4336 4887
4337static struct snd_pci_quirk alc880_cfg_tbl[] = { 4888static const struct snd_pci_quirk alc880_cfg_tbl[] = {
4338 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 4889 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4339 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 4890 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4340 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 4891 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
@@ -4345,7 +4896,6 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
4345 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), 4896 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4346 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), 4897 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4347 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), 4898 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4348 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
4349 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), 4899 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4350 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), 4900 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4351 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), 4901 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
@@ -4375,7 +4925,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
4375 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 4925 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4376 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 4926 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4377 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 4927 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4378 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), 4928 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
4379 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 4929 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4380 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 4930 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4381 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 4931 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
@@ -4388,6 +4938,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
4388 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 4938 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4389 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 4939 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4390 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 4940 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4941 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4391 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 4942 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4392 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 4943 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4393 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 4944 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
@@ -4413,7 +4964,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
4413/* 4964/*
4414 * ALC880 codec presets 4965 * ALC880 codec presets
4415 */ 4966 */
4416static struct alc_config_preset alc880_presets[] = { 4967static const struct alc_config_preset alc880_presets[] = {
4417 [ALC880_3ST] = { 4968 [ALC880_3ST] = {
4418 .mixers = { alc880_three_stack_mixer }, 4969 .mixers = { alc880_three_stack_mixer },
4419 .init_verbs = { alc880_volume_init_verbs, 4970 .init_verbs = { alc880_volume_init_verbs,
@@ -4531,7 +5082,7 @@ static struct alc_config_preset alc880_presets[] = {
4531 .input_mux = &alc880_f1734_capture_source, 5082 .input_mux = &alc880_f1734_capture_source,
4532 .unsol_event = alc880_uniwill_p53_unsol_event, 5083 .unsol_event = alc880_uniwill_p53_unsol_event,
4533 .setup = alc880_uniwill_p53_setup, 5084 .setup = alc880_uniwill_p53_setup,
4534 .init_hook = alc_automute_amp, 5085 .init_hook = alc_hp_automute,
4535 }, 5086 },
4536 [ALC880_ASUS] = { 5087 [ALC880_ASUS] = {
4537 .mixers = { alc880_asus_mixer }, 5088 .mixers = { alc880_asus_mixer },
@@ -4622,7 +5173,7 @@ static struct alc_config_preset alc880_presets[] = {
4622 .input_mux = &alc880_capture_source, 5173 .input_mux = &alc880_capture_source,
4623 .unsol_event = alc880_uniwill_p53_unsol_event, 5174 .unsol_event = alc880_uniwill_p53_unsol_event,
4624 .setup = alc880_uniwill_p53_setup, 5175 .setup = alc880_uniwill_p53_setup,
4625 .init_hook = alc_automute_amp, 5176 .init_hook = alc_hp_automute,
4626 }, 5177 },
4627 [ALC880_FUJITSU] = { 5178 [ALC880_FUJITSU] = {
4628 .mixers = { alc880_fujitsu_mixer }, 5179 .mixers = { alc880_fujitsu_mixer },
@@ -4637,7 +5188,7 @@ static struct alc_config_preset alc880_presets[] = {
4637 .input_mux = &alc880_capture_source, 5188 .input_mux = &alc880_capture_source,
4638 .unsol_event = alc880_uniwill_p53_unsol_event, 5189 .unsol_event = alc880_uniwill_p53_unsol_event,
4639 .setup = alc880_uniwill_p53_setup, 5190 .setup = alc880_uniwill_p53_setup,
4640 .init_hook = alc_automute_amp, 5191 .init_hook = alc_hp_automute,
4641 }, 5192 },
4642 [ALC880_CLEVO] = { 5193 [ALC880_CLEVO] = {
4643 .mixers = { alc880_three_stack_mixer }, 5194 .mixers = { alc880_three_stack_mixer },
@@ -4662,9 +5213,9 @@ static struct alc_config_preset alc880_presets[] = {
4662 .channel_mode = alc880_lg_ch_modes, 5213 .channel_mode = alc880_lg_ch_modes,
4663 .need_dac_fix = 1, 5214 .need_dac_fix = 1,
4664 .input_mux = &alc880_lg_capture_source, 5215 .input_mux = &alc880_lg_capture_source,
4665 .unsol_event = alc_automute_amp_unsol_event, 5216 .unsol_event = alc_sku_unsol_event,
4666 .setup = alc880_lg_setup, 5217 .setup = alc880_lg_setup,
4667 .init_hook = alc_automute_amp, 5218 .init_hook = alc_hp_automute,
4668#ifdef CONFIG_SND_HDA_POWER_SAVE 5219#ifdef CONFIG_SND_HDA_POWER_SAVE
4669 .loopbacks = alc880_lg_loopbacks, 5220 .loopbacks = alc880_lg_loopbacks,
4670#endif 5221#endif
@@ -4679,9 +5230,9 @@ static struct alc_config_preset alc880_presets[] = {
4679 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 5230 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4680 .channel_mode = alc880_lg_lw_modes, 5231 .channel_mode = alc880_lg_lw_modes,
4681 .input_mux = &alc880_lg_lw_capture_source, 5232 .input_mux = &alc880_lg_lw_capture_source,
4682 .unsol_event = alc_automute_amp_unsol_event, 5233 .unsol_event = alc_sku_unsol_event,
4683 .setup = alc880_lg_lw_setup, 5234 .setup = alc880_lg_lw_setup,
4684 .init_hook = alc_automute_amp, 5235 .init_hook = alc_hp_automute,
4685 }, 5236 },
4686 [ALC880_MEDION_RIM] = { 5237 [ALC880_MEDION_RIM] = {
4687 .mixers = { alc880_medion_rim_mixer }, 5238 .mixers = { alc880_medion_rim_mixer },
@@ -4721,26 +5272,32 @@ enum {
4721 ALC_CTL_WIDGET_MUTE, 5272 ALC_CTL_WIDGET_MUTE,
4722 ALC_CTL_BIND_MUTE, 5273 ALC_CTL_BIND_MUTE,
4723}; 5274};
4724static struct snd_kcontrol_new alc880_control_templates[] = { 5275static const struct snd_kcontrol_new alc880_control_templates[] = {
4725 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 5276 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4726 HDA_CODEC_MUTE(NULL, 0, 0, 0), 5277 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4727 HDA_BIND_MUTE(NULL, 0, 0, 0), 5278 HDA_BIND_MUTE(NULL, 0, 0, 0),
4728}; 5279};
4729 5280
5281static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5282{
5283 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5284 return snd_array_new(&spec->kctls);
5285}
5286
4730/* add dynamic controls */ 5287/* add dynamic controls */
4731static int add_control(struct alc_spec *spec, int type, const char *name, 5288static int add_control(struct alc_spec *spec, int type, const char *name,
4732 unsigned long val) 5289 int cidx, unsigned long val)
4733{ 5290{
4734 struct snd_kcontrol_new *knew; 5291 struct snd_kcontrol_new *knew;
4735 5292
4736 snd_array_init(&spec->kctls, sizeof(*knew), 32); 5293 knew = alc_kcontrol_new(spec);
4737 knew = snd_array_new(&spec->kctls);
4738 if (!knew) 5294 if (!knew)
4739 return -ENOMEM; 5295 return -ENOMEM;
4740 *knew = alc880_control_templates[type]; 5296 *knew = alc880_control_templates[type];
4741 knew->name = kstrdup(name, GFP_KERNEL); 5297 knew->name = kstrdup(name, GFP_KERNEL);
4742 if (!knew->name) 5298 if (!knew->name)
4743 return -ENOMEM; 5299 return -ENOMEM;
5300 knew->index = cidx;
4744 if (get_amp_nid_(val)) 5301 if (get_amp_nid_(val))
4745 knew->subdevice = HDA_SUBDEV_AMP_FLAG; 5302 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
4746 knew->private_value = val; 5303 knew->private_value = val;
@@ -4749,17 +5306,21 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
4749 5306
4750static int add_control_with_pfx(struct alc_spec *spec, int type, 5307static int add_control_with_pfx(struct alc_spec *spec, int type,
4751 const char *pfx, const char *dir, 5308 const char *pfx, const char *dir,
4752 const char *sfx, unsigned long val) 5309 const char *sfx, int cidx, unsigned long val)
4753{ 5310{
4754 char name[32]; 5311 char name[32];
4755 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); 5312 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4756 return add_control(spec, type, name, val); 5313 return add_control(spec, type, name, cidx, val);
4757} 5314}
4758 5315
4759#define add_pb_vol_ctrl(spec, type, pfx, val) \ 5316#define add_pb_vol_ctrl(spec, type, pfx, val) \
4760 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val) 5317 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
4761#define add_pb_sw_ctrl(spec, type, pfx, val) \ 5318#define add_pb_sw_ctrl(spec, type, pfx, val) \
4762 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val) 5319 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5320#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5321 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5322#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5323 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
4763 5324
4764#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 5325#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4765#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 5326#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
@@ -4787,7 +5348,7 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4787 nid = cfg->line_out_pins[i]; 5348 nid = cfg->line_out_pins[i];
4788 if (alc880_is_fixed_pin(nid)) { 5349 if (alc880_is_fixed_pin(nid)) {
4789 int idx = alc880_fixed_pin_idx(nid); 5350 int idx = alc880_fixed_pin_idx(nid);
4790 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 5351 spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
4791 assigned[idx] = 1; 5352 assigned[idx] = 1;
4792 } 5353 }
4793 } 5354 }
@@ -4799,7 +5360,7 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4799 /* search for an empty channel */ 5360 /* search for an empty channel */
4800 for (j = 0; j < cfg->line_outs; j++) { 5361 for (j = 0; j < cfg->line_outs; j++) {
4801 if (!assigned[j]) { 5362 if (!assigned[j]) {
4802 spec->multiout.dac_nids[i] = 5363 spec->private_dac_nids[i] =
4803 alc880_idx_to_dac(j); 5364 alc880_idx_to_dac(j);
4804 assigned[j] = 1; 5365 assigned[j] = 1;
4805 break; 5366 break;
@@ -4810,21 +5371,50 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4810 return 0; 5371 return 0;
4811} 5372}
4812 5373
5374static const char *alc_get_line_out_pfx(struct alc_spec *spec,
5375 bool can_be_master)
5376{
5377 struct auto_pin_cfg *cfg = &spec->autocfg;
5378
5379 if (cfg->line_outs == 1 && !spec->multi_ios &&
5380 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5381 return "Master";
5382
5383 switch (cfg->line_out_type) {
5384 case AUTO_PIN_SPEAKER_OUT:
5385 if (cfg->line_outs == 1)
5386 return "Speaker";
5387 break;
5388 case AUTO_PIN_HP_OUT:
5389 return "Headphone";
5390 default:
5391 if (cfg->line_outs == 1 && !spec->multi_ios)
5392 return "PCM";
5393 break;
5394 }
5395 return NULL;
5396}
5397
4813/* add playback controls from the parsed DAC table */ 5398/* add playback controls from the parsed DAC table */
4814static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 5399static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4815 const struct auto_pin_cfg *cfg) 5400 const struct auto_pin_cfg *cfg)
4816{ 5401{
4817 static const char *chname[4] = { 5402 static const char * const chname[4] = {
4818 "Front", "Surround", NULL /*CLFE*/, "Side" 5403 "Front", "Surround", NULL /*CLFE*/, "Side"
4819 }; 5404 };
5405 const char *pfx = alc_get_line_out_pfx(spec, false);
4820 hda_nid_t nid; 5406 hda_nid_t nid;
4821 int i, err; 5407 int i, err, noutputs;
4822 5408
4823 for (i = 0; i < cfg->line_outs; i++) { 5409 noutputs = cfg->line_outs;
5410 if (spec->multi_ios > 0)
5411 noutputs += spec->multi_ios;
5412
5413 for (i = 0; i < noutputs; i++) {
4824 if (!spec->multiout.dac_nids[i]) 5414 if (!spec->multiout.dac_nids[i])
4825 continue; 5415 continue;
4826 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 5416 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4827 if (i == 2) { 5417 if (!pfx && i == 2) {
4828 /* Center/LFE */ 5418 /* Center/LFE */
4829 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 5419 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4830 "Center", 5420 "Center",
@@ -4851,18 +5441,20 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4851 if (err < 0) 5441 if (err < 0)
4852 return err; 5442 return err;
4853 } else { 5443 } else {
4854 const char *pfx; 5444 const char *name = pfx;
4855 if (cfg->line_outs == 1 && 5445 int index = i;
4856 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 5446 if (!name) {
4857 pfx = "Speaker"; 5447 name = chname[i];
4858 else 5448 index = 0;
4859 pfx = chname[i]; 5449 }
4860 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 5450 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5451 name, index,
4861 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 5452 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4862 HDA_OUTPUT)); 5453 HDA_OUTPUT));
4863 if (err < 0) 5454 if (err < 0)
4864 return err; 5455 return err;
4865 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 5456 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5457 name, index,
4866 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 5458 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4867 HDA_INPUT)); 5459 HDA_INPUT));
4868 if (err < 0) 5460 if (err < 0)
@@ -4912,16 +5504,16 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4912 5504
4913/* create input playback/capture controls for the given pin */ 5505/* create input playback/capture controls for the given pin */
4914static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 5506static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4915 const char *ctlname, 5507 const char *ctlname, int ctlidx,
4916 int idx, hda_nid_t mix_nid) 5508 int idx, hda_nid_t mix_nid)
4917{ 5509{
4918 int err; 5510 int err;
4919 5511
4920 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 5512 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
4921 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 5513 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4922 if (err < 0) 5514 if (err < 0)
4923 return err; 5515 return err;
4924 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 5516 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
4925 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 5517 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4926 if (err < 0) 5518 if (err < 0)
4927 return err; 5519 return err;
@@ -4942,20 +5534,29 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec,
4942{ 5534{
4943 struct alc_spec *spec = codec->spec; 5535 struct alc_spec *spec = codec->spec;
4944 struct hda_input_mux *imux = &spec->private_imux[0]; 5536 struct hda_input_mux *imux = &spec->private_imux[0];
4945 int i, err, idx; 5537 int i, err, idx, type_idx = 0;
5538 const char *prev_label = NULL;
4946 5539
4947 for (i = 0; i < AUTO_PIN_LAST; i++) { 5540 for (i = 0; i < cfg->num_inputs; i++) {
4948 hda_nid_t pin; 5541 hda_nid_t pin;
5542 const char *label;
4949 5543
4950 pin = cfg->input_pins[i]; 5544 pin = cfg->inputs[i].pin;
4951 if (!alc_is_input_pin(codec, pin)) 5545 if (!alc_is_input_pin(codec, pin))
4952 continue; 5546 continue;
4953 5547
5548 label = hda_get_autocfg_input_label(codec, cfg, i);
5549 if (prev_label && !strcmp(label, prev_label))
5550 type_idx++;
5551 else
5552 type_idx = 0;
5553 prev_label = label;
5554
4954 if (mixer) { 5555 if (mixer) {
4955 idx = get_connection_index(codec, mixer, pin); 5556 idx = get_connection_index(codec, mixer, pin);
4956 if (idx >= 0) { 5557 if (idx >= 0) {
4957 err = new_analog_input(spec, pin, 5558 err = new_analog_input(spec, pin,
4958 auto_pin_cfg_labels[i], 5559 label, type_idx,
4959 idx, mixer); 5560 idx, mixer);
4960 if (err < 0) 5561 if (err < 0)
4961 return err; 5562 return err;
@@ -4967,12 +5568,8 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec,
4967 idx = get_connection_index(codec, cap1, pin); 5568 idx = get_connection_index(codec, cap1, pin);
4968 if (idx < 0 && cap2) 5569 if (idx < 0 && cap2)
4969 idx = get_connection_index(codec, cap2, pin); 5570 idx = get_connection_index(codec, cap2, pin);
4970 if (idx >= 0) { 5571 if (idx >= 0)
4971 imux->items[imux->num_items].label = 5572 snd_hda_add_imux_item(imux, label, idx, NULL);
4972 auto_pin_cfg_labels[i];
4973 imux->items[imux->num_items].index = idx;
4974 imux->num_items++;
4975 }
4976 } 5573 }
4977 return 0; 5574 return 0;
4978} 5575}
@@ -5044,12 +5641,13 @@ static void alc880_auto_init_extra_out(struct hda_codec *codec)
5044static void alc880_auto_init_analog_input(struct hda_codec *codec) 5641static void alc880_auto_init_analog_input(struct hda_codec *codec)
5045{ 5642{
5046 struct alc_spec *spec = codec->spec; 5643 struct alc_spec *spec = codec->spec;
5644 struct auto_pin_cfg *cfg = &spec->autocfg;
5047 int i; 5645 int i;
5048 5646
5049 for (i = 0; i < AUTO_PIN_LAST; i++) { 5647 for (i = 0; i < cfg->num_inputs; i++) {
5050 hda_nid_t nid = spec->autocfg.input_pins[i]; 5648 hda_nid_t nid = cfg->inputs[i].pin;
5051 if (alc_is_input_pin(codec, nid)) { 5649 if (alc_is_input_pin(codec, nid)) {
5052 alc_set_input_pin(codec, nid, i); 5650 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
5053 if (nid != ALC880_PIN_CD_NID && 5651 if (nid != ALC880_PIN_CD_NID &&
5054 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 5652 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5055 snd_hda_codec_write(codec, nid, 0, 5653 snd_hda_codec_write(codec, nid, 0,
@@ -5078,6 +5676,8 @@ static void alc880_auto_init_input_src(struct hda_codec *codec)
5078 } 5676 }
5079} 5677}
5080 5678
5679static int alc_auto_add_multi_channel_mode(struct hda_codec *codec);
5680
5081/* parse the BIOS configuration and set up the alc_spec */ 5681/* parse the BIOS configuration and set up the alc_spec */
5082/* return 1 if successful, 0 if the proper config is not found, 5682/* return 1 if successful, 0 if the proper config is not found,
5083 * or a negative error code 5683 * or a negative error code
@@ -5086,7 +5686,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
5086{ 5686{
5087 struct alc_spec *spec = codec->spec; 5687 struct alc_spec *spec = codec->spec;
5088 int err; 5688 int err;
5089 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 5689 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5090 5690
5091 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5691 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5092 alc880_ignore); 5692 alc880_ignore);
@@ -5098,6 +5698,9 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
5098 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 5698 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5099 if (err < 0) 5699 if (err < 0)
5100 return err; 5700 return err;
5701 err = alc_auto_add_multi_channel_mode(codec);
5702 if (err < 0)
5703 return err;
5101 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 5704 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5102 if (err < 0) 5705 if (err < 0)
5103 return err; 5706 return err;
@@ -5169,6 +5772,12 @@ static void fixup_automic_adc(struct hda_codec *codec)
5169 spec->capsrc_nids += i; 5772 spec->capsrc_nids += i;
5170 spec->adc_nids += i; 5773 spec->adc_nids += i;
5171 spec->num_adc_nids = 1; 5774 spec->num_adc_nids = 1;
5775 /* optional dock-mic */
5776 eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5777 if (eidx < 0)
5778 spec->dock_mic.pin = 0;
5779 else
5780 spec->dock_mic.mux_idx = eidx;
5172 return; 5781 return;
5173 } 5782 }
5174 snd_printd(KERN_INFO "hda_codec: %s: " 5783 snd_printd(KERN_INFO "hda_codec: %s: "
@@ -5196,6 +5805,8 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5196 struct alc_spec *spec = codec->spec; 5805 struct alc_spec *spec = codec->spec;
5197 int i; 5806 int i;
5198 5807
5808 if (!pin)
5809 return 0;
5199 for (i = 0; i < spec->num_adc_nids; i++) { 5810 for (i = 0; i < spec->num_adc_nids; i++) {
5200 hda_nid_t cap = spec->capsrc_nids ? 5811 hda_nid_t cap = spec->capsrc_nids ?
5201 spec->capsrc_nids[i] : spec->adc_nids[i]; 5812 spec->capsrc_nids[i] : spec->adc_nids[i];
@@ -5214,25 +5825,20 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5214static void fixup_single_adc(struct hda_codec *codec) 5825static void fixup_single_adc(struct hda_codec *codec)
5215{ 5826{
5216 struct alc_spec *spec = codec->spec; 5827 struct alc_spec *spec = codec->spec;
5217 hda_nid_t pin = 0; 5828 struct auto_pin_cfg *cfg = &spec->autocfg;
5218 int i; 5829 int i;
5219 5830
5220 /* search for the input pin; there must be only one */ 5831 /* search for the input pin; there must be only one */
5221 for (i = 0; i < AUTO_PIN_LAST; i++) { 5832 if (cfg->num_inputs != 1)
5222 if (spec->autocfg.input_pins[i]) {
5223 pin = spec->autocfg.input_pins[i];
5224 break;
5225 }
5226 }
5227 if (!pin)
5228 return; 5833 return;
5229 i = init_capsrc_for_pin(codec, pin); 5834 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5230 if (i >= 0) { 5835 if (i >= 0) {
5231 /* use only this ADC */ 5836 /* use only this ADC */
5232 if (spec->capsrc_nids) 5837 if (spec->capsrc_nids)
5233 spec->capsrc_nids += i; 5838 spec->capsrc_nids += i;
5234 spec->adc_nids += i; 5839 spec->adc_nids += i;
5235 spec->num_adc_nids = 1; 5840 spec->num_adc_nids = 1;
5841 spec->single_input_src = 1;
5236 } 5842 }
5237} 5843}
5238 5844
@@ -5241,13 +5847,24 @@ static void fixup_dual_adc_switch(struct hda_codec *codec)
5241{ 5847{
5242 struct alc_spec *spec = codec->spec; 5848 struct alc_spec *spec = codec->spec;
5243 init_capsrc_for_pin(codec, spec->ext_mic.pin); 5849 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5850 init_capsrc_for_pin(codec, spec->dock_mic.pin);
5244 init_capsrc_for_pin(codec, spec->int_mic.pin); 5851 init_capsrc_for_pin(codec, spec->int_mic.pin);
5245} 5852}
5246 5853
5854/* initialize some special cases for input sources */
5855static void alc_init_special_input_src(struct hda_codec *codec)
5856{
5857 struct alc_spec *spec = codec->spec;
5858 if (spec->dual_adc_switch)
5859 fixup_dual_adc_switch(codec);
5860 else if (spec->single_input_src)
5861 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5862}
5863
5247static void set_capture_mixer(struct hda_codec *codec) 5864static void set_capture_mixer(struct hda_codec *codec)
5248{ 5865{
5249 struct alc_spec *spec = codec->spec; 5866 struct alc_spec *spec = codec->spec;
5250 static struct snd_kcontrol_new *caps[2][3] = { 5867 static const struct snd_kcontrol_new *caps[2][3] = {
5251 { alc_capture_mixer_nosrc1, 5868 { alc_capture_mixer_nosrc1,
5252 alc_capture_mixer_nosrc2, 5869 alc_capture_mixer_nosrc2,
5253 alc_capture_mixer_nosrc3 }, 5870 alc_capture_mixer_nosrc3 },
@@ -5259,7 +5876,7 @@ static void set_capture_mixer(struct hda_codec *codec)
5259 int mux = 0; 5876 int mux = 0;
5260 int num_adcs = spec->num_adc_nids; 5877 int num_adcs = spec->num_adc_nids;
5261 if (spec->dual_adc_switch) 5878 if (spec->dual_adc_switch)
5262 fixup_dual_adc_switch(codec); 5879 num_adcs = 1;
5263 else if (spec->auto_mic) 5880 else if (spec->auto_mic)
5264 fixup_automic_adc(codec); 5881 fixup_automic_adc(codec);
5265 else if (spec->input_mux) { 5882 else if (spec->input_mux) {
@@ -5268,17 +5885,16 @@ static void set_capture_mixer(struct hda_codec *codec)
5268 else if (spec->input_mux->num_items == 1) 5885 else if (spec->input_mux->num_items == 1)
5269 fixup_single_adc(codec); 5886 fixup_single_adc(codec);
5270 } 5887 }
5271 if (spec->dual_adc_switch)
5272 num_adcs = 1;
5273 spec->cap_mixer = caps[mux][num_adcs - 1]; 5888 spec->cap_mixer = caps[mux][num_adcs - 1];
5274 } 5889 }
5275} 5890}
5276 5891
5277/* fill adc_nids (and capsrc_nids) containing all active input pins */ 5892/* fill adc_nids (and capsrc_nids) containing all active input pins */
5278static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, 5893static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
5279 int num_nids) 5894 int num_nids)
5280{ 5895{
5281 struct alc_spec *spec = codec->spec; 5896 struct alc_spec *spec = codec->spec;
5897 struct auto_pin_cfg *cfg = &spec->autocfg;
5282 int n; 5898 int n;
5283 hda_nid_t fallback_adc = 0, fallback_cap = 0; 5899 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5284 5900
@@ -5304,10 +5920,8 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5304 fallback_adc = adc; 5920 fallback_adc = adc;
5305 fallback_cap = cap; 5921 fallback_cap = cap;
5306 } 5922 }
5307 for (i = 0; i < AUTO_PIN_LAST; i++) { 5923 for (i = 0; i < cfg->num_inputs; i++) {
5308 hda_nid_t nid = spec->autocfg.input_pins[i]; 5924 hda_nid_t nid = cfg->inputs[i].pin;
5309 if (!nid)
5310 continue;
5311 for (j = 0; j < nconns; j++) { 5925 for (j = 0; j < nconns; j++) {
5312 if (conn[j] == nid) 5926 if (conn[j] == nid)
5313 break; 5927 break;
@@ -5315,7 +5929,7 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5315 if (j >= nconns) 5929 if (j >= nconns)
5316 break; 5930 break;
5317 } 5931 }
5318 if (i >= AUTO_PIN_LAST) { 5932 if (i >= cfg->num_inputs) {
5319 int num_adcs = spec->num_adc_nids; 5933 int num_adcs = spec->num_adc_nids;
5320 spec->private_adc_nids[num_adcs] = adc; 5934 spec->private_adc_nids[num_adcs] = adc;
5321 spec->private_capsrc_nids[num_adcs] = cap; 5935 spec->private_capsrc_nids[num_adcs] = cap;
@@ -5342,9 +5956,11 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5342#define set_beep_amp(spec, nid, idx, dir) \ 5956#define set_beep_amp(spec, nid, idx, dir) \
5343 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 5957 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5344 5958
5345static struct snd_pci_quirk beep_white_list[] = { 5959static const struct snd_pci_quirk beep_white_list[] = {
5346 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), 5960 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5347 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), 5961 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5962 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
5963 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
5348 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), 5964 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5349 {} 5965 {}
5350}; 5966};
@@ -5452,17 +6068,17 @@ static int patch_alc880(struct hda_codec *codec)
5452 * ALC260 support 6068 * ALC260 support
5453 */ 6069 */
5454 6070
5455static hda_nid_t alc260_dac_nids[1] = { 6071static const hda_nid_t alc260_dac_nids[1] = {
5456 /* front */ 6072 /* front */
5457 0x02, 6073 0x02,
5458}; 6074};
5459 6075
5460static hda_nid_t alc260_adc_nids[1] = { 6076static const hda_nid_t alc260_adc_nids[1] = {
5461 /* ADC0 */ 6077 /* ADC0 */
5462 0x04, 6078 0x04,
5463}; 6079};
5464 6080
5465static hda_nid_t alc260_adc_nids_alt[1] = { 6081static const hda_nid_t alc260_adc_nids_alt[1] = {
5466 /* ADC1 */ 6082 /* ADC1 */
5467 0x05, 6083 0x05,
5468}; 6084};
@@ -5470,7 +6086,7 @@ static hda_nid_t alc260_adc_nids_alt[1] = {
5470/* NIDs used when simultaneous access to both ADCs makes sense. Note that 6086/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5471 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 6087 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5472 */ 6088 */
5473static hda_nid_t alc260_dual_adc_nids[2] = { 6089static const hda_nid_t alc260_dual_adc_nids[2] = {
5474 /* ADC0, ADC1 */ 6090 /* ADC0, ADC1 */
5475 0x04, 0x05 6091 0x04, 0x05
5476}; 6092};
@@ -5478,7 +6094,7 @@ static hda_nid_t alc260_dual_adc_nids[2] = {
5478#define ALC260_DIGOUT_NID 0x03 6094#define ALC260_DIGOUT_NID 0x03
5479#define ALC260_DIGIN_NID 0x06 6095#define ALC260_DIGIN_NID 0x06
5480 6096
5481static struct hda_input_mux alc260_capture_source = { 6097static const struct hda_input_mux alc260_capture_source = {
5482 .num_items = 4, 6098 .num_items = 4,
5483 .items = { 6099 .items = {
5484 { "Mic", 0x0 }, 6100 { "Mic", 0x0 },
@@ -5494,7 +6110,7 @@ static struct hda_input_mux alc260_capture_source = {
5494 * recording the mixer output on the second ADC (ADC0 doesn't have a 6110 * recording the mixer output on the second ADC (ADC0 doesn't have a
5495 * connection to the mixer output). 6111 * connection to the mixer output).
5496 */ 6112 */
5497static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 6113static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5498 { 6114 {
5499 .num_items = 3, 6115 .num_items = 3,
5500 .items = { 6116 .items = {
@@ -5518,7 +6134,7 @@ static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5518/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 6134/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5519 * the Fujitsu S702x, but jacks are marked differently. 6135 * the Fujitsu S702x, but jacks are marked differently.
5520 */ 6136 */
5521static struct hda_input_mux alc260_acer_capture_sources[2] = { 6137static const struct hda_input_mux alc260_acer_capture_sources[2] = {
5522 { 6138 {
5523 .num_items = 4, 6139 .num_items = 4,
5524 .items = { 6140 .items = {
@@ -5541,7 +6157,7 @@ static struct hda_input_mux alc260_acer_capture_sources[2] = {
5541}; 6157};
5542 6158
5543/* Maxdata Favorit 100XS */ 6159/* Maxdata Favorit 100XS */
5544static struct hda_input_mux alc260_favorit100_capture_sources[2] = { 6160static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5545 { 6161 {
5546 .num_items = 2, 6162 .num_items = 2,
5547 .items = { 6163 .items = {
@@ -5565,7 +6181,7 @@ static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5565 * element which allows changing the channel mode, so the verb list is 6181 * element which allows changing the channel mode, so the verb list is
5566 * never used. 6182 * never used.
5567 */ 6183 */
5568static struct hda_channel_mode alc260_modes[1] = { 6184static const struct hda_channel_mode alc260_modes[1] = {
5569 { 2, NULL }, 6185 { 2, NULL },
5570}; 6186};
5571 6187
@@ -5579,7 +6195,7 @@ static struct hda_channel_mode alc260_modes[1] = {
5579 * acer: acer + capture 6195 * acer: acer + capture
5580 */ 6196 */
5581 6197
5582static struct snd_kcontrol_new alc260_base_output_mixer[] = { 6198static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
5583 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6199 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5584 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 6200 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5585 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6201 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
@@ -5589,7 +6205,7 @@ static struct snd_kcontrol_new alc260_base_output_mixer[] = {
5589 { } /* end */ 6205 { } /* end */
5590}; 6206};
5591 6207
5592static struct snd_kcontrol_new alc260_input_mixer[] = { 6208static const struct snd_kcontrol_new alc260_input_mixer[] = {
5593 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6209 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5594 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6210 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5595 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 6211 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
@@ -5602,21 +6218,9 @@ static struct snd_kcontrol_new alc260_input_mixer[] = {
5602}; 6218};
5603 6219
5604/* update HP, line and mono out pins according to the master switch */ 6220/* update HP, line and mono out pins according to the master switch */
5605static void alc260_hp_master_update(struct hda_codec *codec, 6221static void alc260_hp_master_update(struct hda_codec *codec)
5606 hda_nid_t hp, hda_nid_t line,
5607 hda_nid_t mono)
5608{ 6222{
5609 struct alc_spec *spec = codec->spec; 6223 update_speakers(codec);
5610 unsigned int val = spec->master_sw ? PIN_HP : 0;
5611 /* change HP and line-out pins */
5612 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5613 val);
5614 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5615 val);
5616 /* mono (speaker) depending on the HP jack sense */
5617 val = (val && !spec->jack_present) ? PIN_OUT : 0;
5618 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5619 val);
5620} 6224}
5621 6225
5622static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, 6226static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
@@ -5624,7 +6228,7 @@ static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5624{ 6228{
5625 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 6229 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5626 struct alc_spec *spec = codec->spec; 6230 struct alc_spec *spec = codec->spec;
5627 *ucontrol->value.integer.value = spec->master_sw; 6231 *ucontrol->value.integer.value = !spec->master_mute;
5628 return 0; 6232 return 0;
5629} 6233}
5630 6234
@@ -5633,20 +6237,16 @@ static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5633{ 6237{
5634 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 6238 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5635 struct alc_spec *spec = codec->spec; 6239 struct alc_spec *spec = codec->spec;
5636 int val = !!*ucontrol->value.integer.value; 6240 int val = !*ucontrol->value.integer.value;
5637 hda_nid_t hp, line, mono;
5638 6241
5639 if (val == spec->master_sw) 6242 if (val == spec->master_mute)
5640 return 0; 6243 return 0;
5641 spec->master_sw = val; 6244 spec->master_mute = val;
5642 hp = (kcontrol->private_value >> 16) & 0xff; 6245 alc260_hp_master_update(codec);
5643 line = (kcontrol->private_value >> 8) & 0xff;
5644 mono = kcontrol->private_value & 0xff;
5645 alc260_hp_master_update(codec, hp, line, mono);
5646 return 1; 6246 return 1;
5647} 6247}
5648 6248
5649static struct snd_kcontrol_new alc260_hp_output_mixer[] = { 6249static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5650 { 6250 {
5651 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5652 .name = "Master Playback Switch", 6252 .name = "Master Playback Switch",
@@ -5654,7 +6254,6 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5654 .info = snd_ctl_boolean_mono_info, 6254 .info = snd_ctl_boolean_mono_info,
5655 .get = alc260_hp_master_sw_get, 6255 .get = alc260_hp_master_sw_get,
5656 .put = alc260_hp_master_sw_put, 6256 .put = alc260_hp_master_sw_put,
5657 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5658 }, 6257 },
5659 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6258 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5660 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 6259 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
@@ -5666,26 +6265,23 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5666 { } /* end */ 6265 { } /* end */
5667}; 6266};
5668 6267
5669static struct hda_verb alc260_hp_unsol_verbs[] = { 6268static const struct hda_verb alc260_hp_unsol_verbs[] = {
5670 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6269 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5671 {}, 6270 {},
5672}; 6271};
5673 6272
5674static void alc260_hp_automute(struct hda_codec *codec) 6273static void alc260_hp_setup(struct hda_codec *codec)
5675{ 6274{
5676 struct alc_spec *spec = codec->spec; 6275 struct alc_spec *spec = codec->spec;
5677 6276
5678 spec->jack_present = snd_hda_jack_detect(codec, 0x10); 6277 spec->autocfg.hp_pins[0] = 0x0f;
5679 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); 6278 spec->autocfg.speaker_pins[0] = 0x10;
5680} 6279 spec->autocfg.speaker_pins[1] = 0x11;
5681 6280 spec->automute = 1;
5682static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) 6281 spec->automute_mode = ALC_AUTOMUTE_PIN;
5683{
5684 if ((res >> 26) == ALC880_HP_EVENT)
5685 alc260_hp_automute(codec);
5686} 6282}
5687 6283
5688static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 6284static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5689 { 6285 {
5690 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6286 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5691 .name = "Master Playback Switch", 6287 .name = "Master Playback Switch",
@@ -5693,7 +6289,6 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5693 .info = snd_ctl_boolean_mono_info, 6289 .info = snd_ctl_boolean_mono_info,
5694 .get = alc260_hp_master_sw_get, 6290 .get = alc260_hp_master_sw_get,
5695 .put = alc260_hp_master_sw_put, 6291 .put = alc260_hp_master_sw_put,
5696 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
5697 }, 6292 },
5698 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6293 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5699 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 6294 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
@@ -5706,7 +6301,18 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5706 { } /* end */ 6301 { } /* end */
5707}; 6302};
5708 6303
5709static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { 6304static void alc260_hp_3013_setup(struct hda_codec *codec)
6305{
6306 struct alc_spec *spec = codec->spec;
6307
6308 spec->autocfg.hp_pins[0] = 0x15;
6309 spec->autocfg.speaker_pins[0] = 0x10;
6310 spec->autocfg.speaker_pins[1] = 0x11;
6311 spec->automute = 1;
6312 spec->automute_mode = ALC_AUTOMUTE_PIN;
6313}
6314
6315static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5710 .ops = &snd_hda_bind_vol, 6316 .ops = &snd_hda_bind_vol,
5711 .values = { 6317 .values = {
5712 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), 6318 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
@@ -5716,7 +6322,7 @@ static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5716 }, 6322 },
5717}; 6323};
5718 6324
5719static struct hda_bind_ctls alc260_dc7600_bind_switch = { 6325static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
5720 .ops = &snd_hda_bind_sw, 6326 .ops = &snd_hda_bind_sw,
5721 .values = { 6327 .values = {
5722 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), 6328 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
@@ -5725,7 +6331,7 @@ static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5725 }, 6331 },
5726}; 6332};
5727 6333
5728static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { 6334static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5729 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), 6335 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5730 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), 6336 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5731 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), 6337 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
@@ -5733,49 +6339,27 @@ static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5733 { } /* end */ 6339 { } /* end */
5734}; 6340};
5735 6341
5736static struct hda_verb alc260_hp_3013_unsol_verbs[] = { 6342static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5737 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6343 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5738 {}, 6344 {},
5739}; 6345};
5740 6346
5741static void alc260_hp_3013_automute(struct hda_codec *codec) 6347static void alc260_hp_3012_setup(struct hda_codec *codec)
5742{ 6348{
5743 struct alc_spec *spec = codec->spec; 6349 struct alc_spec *spec = codec->spec;
5744 6350
5745 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 6351 spec->autocfg.hp_pins[0] = 0x10;
5746 alc260_hp_master_update(codec, 0x15, 0x10, 0x11); 6352 spec->autocfg.speaker_pins[0] = 0x0f;
5747} 6353 spec->autocfg.speaker_pins[1] = 0x11;
5748 6354 spec->autocfg.speaker_pins[2] = 0x15;
5749static void alc260_hp_3013_unsol_event(struct hda_codec *codec, 6355 spec->automute = 1;
5750 unsigned int res) 6356 spec->automute_mode = ALC_AUTOMUTE_PIN;
5751{
5752 if ((res >> 26) == ALC880_HP_EVENT)
5753 alc260_hp_3013_automute(codec);
5754}
5755
5756static void alc260_hp_3012_automute(struct hda_codec *codec)
5757{
5758 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
5759
5760 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5761 bits);
5762 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5763 bits);
5764 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5765 bits);
5766}
5767
5768static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5769 unsigned int res)
5770{
5771 if ((res >> 26) == ALC880_HP_EVENT)
5772 alc260_hp_3012_automute(codec);
5773} 6357}
5774 6358
5775/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 6359/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
5776 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 6360 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5777 */ 6361 */
5778static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 6362static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
5779 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6363 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5780 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 6364 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
5781 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6365 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
@@ -5812,7 +6396,7 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
5812 * controls for such models. On models without a "mono speaker" the control 6396 * controls for such models. On models without a "mono speaker" the control
5813 * won't do anything. 6397 * won't do anything.
5814 */ 6398 */
5815static struct snd_kcontrol_new alc260_acer_mixer[] = { 6399static const struct snd_kcontrol_new alc260_acer_mixer[] = {
5816 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6400 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5817 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 6401 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5818 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 6402 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
@@ -5833,7 +6417,7 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = {
5833 6417
5834/* Maxdata Favorit 100XS: one output and one input (0x12) jack 6418/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5835 */ 6419 */
5836static struct snd_kcontrol_new alc260_favorit100_mixer[] = { 6420static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5837 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6421 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5838 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 6422 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5839 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 6423 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
@@ -5846,7 +6430,7 @@ static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5846/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 6430/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5847 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 6431 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5848 */ 6432 */
5849static struct snd_kcontrol_new alc260_will_mixer[] = { 6433static const struct snd_kcontrol_new alc260_will_mixer[] = {
5850 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6434 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5851 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 6435 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5852 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
@@ -5863,7 +6447,7 @@ static struct snd_kcontrol_new alc260_will_mixer[] = {
5863/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 6447/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5864 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 6448 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5865 */ 6449 */
5866static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 6450static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5867 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6451 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5868 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 6452 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5869 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
@@ -5880,7 +6464,7 @@ static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5880/* 6464/*
5881 * initialization verbs 6465 * initialization verbs
5882 */ 6466 */
5883static struct hda_verb alc260_init_verbs[] = { 6467static const struct hda_verb alc260_init_verbs[] = {
5884 /* Line In pin widget for input */ 6468 /* Line In pin widget for input */
5885 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6469 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5886 /* CD pin widget for input */ 6470 /* CD pin widget for input */
@@ -5944,7 +6528,7 @@ static struct hda_verb alc260_init_verbs[] = {
5944}; 6528};
5945 6529
5946#if 0 /* should be identical with alc260_init_verbs? */ 6530#if 0 /* should be identical with alc260_init_verbs? */
5947static struct hda_verb alc260_hp_init_verbs[] = { 6531static const struct hda_verb alc260_hp_init_verbs[] = {
5948 /* Headphone and output */ 6532 /* Headphone and output */
5949 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 6533 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5950 /* mono output */ 6534 /* mono output */
@@ -5994,7 +6578,7 @@ static struct hda_verb alc260_hp_init_verbs[] = {
5994}; 6578};
5995#endif 6579#endif
5996 6580
5997static struct hda_verb alc260_hp_3013_init_verbs[] = { 6581static const struct hda_verb alc260_hp_3013_init_verbs[] = {
5998 /* Line out and output */ 6582 /* Line out and output */
5999 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6583 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6000 /* mono output */ 6584 /* mono output */
@@ -6047,7 +6631,7 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = {
6047 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 6631 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6048 * audio = 0x16, internal speaker = 0x10. 6632 * audio = 0x16, internal speaker = 0x10.
6049 */ 6633 */
6050static struct hda_verb alc260_fujitsu_init_verbs[] = { 6634static const struct hda_verb alc260_fujitsu_init_verbs[] = {
6051 /* Disable all GPIOs */ 6635 /* Disable all GPIOs */
6052 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 6636 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6053 /* Internal speaker is connected to headphone pin */ 6637 /* Internal speaker is connected to headphone pin */
@@ -6129,7 +6713,7 @@ static struct hda_verb alc260_fujitsu_init_verbs[] = {
6129/* Initialisation sequence for ALC260 as configured in Acer TravelMate and 6713/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6130 * similar laptops (adapted from Fujitsu init verbs). 6714 * similar laptops (adapted from Fujitsu init verbs).
6131 */ 6715 */
6132static struct hda_verb alc260_acer_init_verbs[] = { 6716static const struct hda_verb alc260_acer_init_verbs[] = {
6133 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 6717 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6134 * the headphone jack. Turn this on and rely on the standard mute 6718 * the headphone jack. Turn this on and rely on the standard mute
6135 * methods whenever the user wants to turn these outputs off. 6719 * methods whenever the user wants to turn these outputs off.
@@ -6217,7 +6801,7 @@ static struct hda_verb alc260_acer_init_verbs[] = {
6217/* Initialisation sequence for Maxdata Favorit 100XS 6801/* Initialisation sequence for Maxdata Favorit 100XS
6218 * (adapted from Acer init verbs). 6802 * (adapted from Acer init verbs).
6219 */ 6803 */
6220static struct hda_verb alc260_favorit100_init_verbs[] = { 6804static const struct hda_verb alc260_favorit100_init_verbs[] = {
6221 /* GPIO 0 enables the output jack. 6805 /* GPIO 0 enables the output jack.
6222 * Turn this on and rely on the standard mute 6806 * Turn this on and rely on the standard mute
6223 * methods whenever the user wants to turn these outputs off. 6807 * methods whenever the user wants to turn these outputs off.
@@ -6297,7 +6881,7 @@ static struct hda_verb alc260_favorit100_init_verbs[] = {
6297 { } 6881 { }
6298}; 6882};
6299 6883
6300static struct hda_verb alc260_will_verbs[] = { 6884static const struct hda_verb alc260_will_verbs[] = {
6301 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6885 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6302 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6886 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6303 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 6887 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -6307,7 +6891,7 @@ static struct hda_verb alc260_will_verbs[] = {
6307 {} 6891 {}
6308}; 6892};
6309 6893
6310static struct hda_verb alc260_replacer_672v_verbs[] = { 6894static const struct hda_verb alc260_replacer_672v_verbs[] = {
6311 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6895 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6312 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6896 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6313 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 6897 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
@@ -6349,7 +6933,7 @@ static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6349 alc260_replacer_672v_automute(codec); 6933 alc260_replacer_672v_automute(codec);
6350} 6934}
6351 6935
6352static struct hda_verb alc260_hp_dc7600_verbs[] = { 6936static const struct hda_verb alc260_hp_dc7600_verbs[] = {
6353 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 6937 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6354 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 6938 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6355 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6939 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -6367,17 +6951,17 @@ static struct hda_verb alc260_hp_dc7600_verbs[] = {
6367 * configuration. 6951 * configuration.
6368 */ 6952 */
6369#ifdef CONFIG_SND_DEBUG 6953#ifdef CONFIG_SND_DEBUG
6370static hda_nid_t alc260_test_dac_nids[1] = { 6954static const hda_nid_t alc260_test_dac_nids[1] = {
6371 0x02, 6955 0x02,
6372}; 6956};
6373static hda_nid_t alc260_test_adc_nids[2] = { 6957static const hda_nid_t alc260_test_adc_nids[2] = {
6374 0x04, 0x05, 6958 0x04, 0x05,
6375}; 6959};
6376/* For testing the ALC260, each input MUX needs its own definition since 6960/* For testing the ALC260, each input MUX needs its own definition since
6377 * the signal assignments are different. This assumes that the first ADC 6961 * the signal assignments are different. This assumes that the first ADC
6378 * is NID 0x04. 6962 * is NID 0x04.
6379 */ 6963 */
6380static struct hda_input_mux alc260_test_capture_sources[2] = { 6964static const struct hda_input_mux alc260_test_capture_sources[2] = {
6381 { 6965 {
6382 .num_items = 7, 6966 .num_items = 7,
6383 .items = { 6967 .items = {
@@ -6404,7 +6988,7 @@ static struct hda_input_mux alc260_test_capture_sources[2] = {
6404 }, 6988 },
6405 }, 6989 },
6406}; 6990};
6407static struct snd_kcontrol_new alc260_test_mixer[] = { 6991static const struct snd_kcontrol_new alc260_test_mixer[] = {
6408 /* Output driver widgets */ 6992 /* Output driver widgets */
6409 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 6993 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6410 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 6994 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
@@ -6468,7 +7052,7 @@ static struct snd_kcontrol_new alc260_test_mixer[] = {
6468 7052
6469 { } /* end */ 7053 { } /* end */
6470}; 7054};
6471static struct hda_verb alc260_test_init_verbs[] = { 7055static const struct hda_verb alc260_test_init_verbs[] = {
6472 /* Enable all GPIOs as outputs with an initial value of 0 */ 7056 /* Enable all GPIOs as outputs with an initial value of 0 */
6473 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 7057 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6474 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 7058 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
@@ -6606,7 +7190,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6606 7190
6607 spec->multiout.num_dacs = 1; 7191 spec->multiout.num_dacs = 1;
6608 spec->multiout.dac_nids = spec->private_dac_nids; 7192 spec->multiout.dac_nids = spec->private_dac_nids;
6609 spec->multiout.dac_nids[0] = 0x02; 7193 spec->private_dac_nids[0] = 0x02;
6610 7194
6611 nid = cfg->line_out_pins[0]; 7195 nid = cfg->line_out_pins[0];
6612 if (nid) { 7196 if (nid) {
@@ -6683,12 +7267,13 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
6683static void alc260_auto_init_analog_input(struct hda_codec *codec) 7267static void alc260_auto_init_analog_input(struct hda_codec *codec)
6684{ 7268{
6685 struct alc_spec *spec = codec->spec; 7269 struct alc_spec *spec = codec->spec;
7270 struct auto_pin_cfg *cfg = &spec->autocfg;
6686 int i; 7271 int i;
6687 7272
6688 for (i = 0; i < AUTO_PIN_LAST; i++) { 7273 for (i = 0; i < cfg->num_inputs; i++) {
6689 hda_nid_t nid = spec->autocfg.input_pins[i]; 7274 hda_nid_t nid = cfg->inputs[i].pin;
6690 if (nid >= 0x12) { 7275 if (nid >= 0x12) {
6691 alc_set_input_pin(codec, nid, i); 7276 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
6692 if (nid != ALC260_PIN_CD_NID && 7277 if (nid != ALC260_PIN_CD_NID &&
6693 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 7278 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
6694 snd_hda_codec_write(codec, nid, 0, 7279 snd_hda_codec_write(codec, nid, 0,
@@ -6703,7 +7288,7 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec)
6703/* 7288/*
6704 * generic initialization of ADC, input mixers and output mixers 7289 * generic initialization of ADC, input mixers and output mixers
6705 */ 7290 */
6706static struct hda_verb alc260_volume_init_verbs[] = { 7291static const struct hda_verb alc260_volume_init_verbs[] = {
6707 /* 7292 /*
6708 * Unmute ADC0-1 and set the default input to mic-in 7293 * Unmute ADC0-1 and set the default input to mic-in
6709 */ 7294 */
@@ -6748,7 +7333,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
6748{ 7333{
6749 struct alc_spec *spec = codec->spec; 7334 struct alc_spec *spec = codec->spec;
6750 int err; 7335 int err;
6751 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 7336 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
6752 7337
6753 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 7338 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6754 alc260_ignore); 7339 alc260_ignore);
@@ -6793,7 +7378,7 @@ static void alc260_auto_init(struct hda_codec *codec)
6793} 7378}
6794 7379
6795#ifdef CONFIG_SND_HDA_POWER_SAVE 7380#ifdef CONFIG_SND_HDA_POWER_SAVE
6796static struct hda_amp_list alc260_loopbacks[] = { 7381static const struct hda_amp_list alc260_loopbacks[] = {
6797 { 0x07, HDA_INPUT, 0 }, 7382 { 0x07, HDA_INPUT, 0 },
6798 { 0x07, HDA_INPUT, 1 }, 7383 { 0x07, HDA_INPUT, 1 },
6799 { 0x07, HDA_INPUT, 2 }, 7384 { 0x07, HDA_INPUT, 2 },
@@ -6810,18 +7395,17 @@ enum {
6810 PINFIX_HP_DC5750, 7395 PINFIX_HP_DC5750,
6811}; 7396};
6812 7397
6813static struct alc_pincfg alc260_hp_dc5750_pinfix[] = {
6814 { 0x11, 0x90130110 }, /* speaker */
6815 { }
6816};
6817
6818static const struct alc_fixup alc260_fixups[] = { 7398static const struct alc_fixup alc260_fixups[] = {
6819 [PINFIX_HP_DC5750] = { 7399 [PINFIX_HP_DC5750] = {
6820 .pins = alc260_hp_dc5750_pinfix 7400 .type = ALC_FIXUP_PINS,
7401 .v.pins = (const struct alc_pincfg[]) {
7402 { 0x11, 0x90130110 }, /* speaker */
7403 { }
7404 }
6821 }, 7405 },
6822}; 7406};
6823 7407
6824static struct snd_pci_quirk alc260_fixup_tbl[] = { 7408static const struct snd_pci_quirk alc260_fixup_tbl[] = {
6825 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), 7409 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
6826 {} 7410 {}
6827}; 7411};
@@ -6829,7 +7413,7 @@ static struct snd_pci_quirk alc260_fixup_tbl[] = {
6829/* 7413/*
6830 * ALC260 configurations 7414 * ALC260 configurations
6831 */ 7415 */
6832static const char *alc260_models[ALC260_MODEL_LAST] = { 7416static const char * const alc260_models[ALC260_MODEL_LAST] = {
6833 [ALC260_BASIC] = "basic", 7417 [ALC260_BASIC] = "basic",
6834 [ALC260_HP] = "hp", 7418 [ALC260_HP] = "hp",
6835 [ALC260_HP_3013] = "hp-3013", 7419 [ALC260_HP_3013] = "hp-3013",
@@ -6845,7 +7429,7 @@ static const char *alc260_models[ALC260_MODEL_LAST] = {
6845 [ALC260_AUTO] = "auto", 7429 [ALC260_AUTO] = "auto",
6846}; 7430};
6847 7431
6848static struct snd_pci_quirk alc260_cfg_tbl[] = { 7432static const struct snd_pci_quirk alc260_cfg_tbl[] = {
6849 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 7433 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
6850 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), 7434 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
6851 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 7435 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
@@ -6869,7 +7453,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = {
6869 {} 7453 {}
6870}; 7454};
6871 7455
6872static struct alc_config_preset alc260_presets[] = { 7456static const struct alc_config_preset alc260_presets[] = {
6873 [ALC260_BASIC] = { 7457 [ALC260_BASIC] = {
6874 .mixers = { alc260_base_output_mixer, 7458 .mixers = { alc260_base_output_mixer,
6875 alc260_input_mixer }, 7459 alc260_input_mixer },
@@ -6894,8 +7478,9 @@ static struct alc_config_preset alc260_presets[] = {
6894 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7478 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6895 .channel_mode = alc260_modes, 7479 .channel_mode = alc260_modes,
6896 .input_mux = &alc260_capture_source, 7480 .input_mux = &alc260_capture_source,
6897 .unsol_event = alc260_hp_unsol_event, 7481 .unsol_event = alc_sku_unsol_event,
6898 .init_hook = alc260_hp_automute, 7482 .setup = alc260_hp_setup,
7483 .init_hook = alc_inithook,
6899 }, 7484 },
6900 [ALC260_HP_DC7600] = { 7485 [ALC260_HP_DC7600] = {
6901 .mixers = { alc260_hp_dc7600_mixer, 7486 .mixers = { alc260_hp_dc7600_mixer,
@@ -6909,8 +7494,9 @@ static struct alc_config_preset alc260_presets[] = {
6909 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7494 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6910 .channel_mode = alc260_modes, 7495 .channel_mode = alc260_modes,
6911 .input_mux = &alc260_capture_source, 7496 .input_mux = &alc260_capture_source,
6912 .unsol_event = alc260_hp_3012_unsol_event, 7497 .unsol_event = alc_sku_unsol_event,
6913 .init_hook = alc260_hp_3012_automute, 7498 .setup = alc260_hp_3012_setup,
7499 .init_hook = alc_inithook,
6914 }, 7500 },
6915 [ALC260_HP_3013] = { 7501 [ALC260_HP_3013] = {
6916 .mixers = { alc260_hp_3013_mixer, 7502 .mixers = { alc260_hp_3013_mixer,
@@ -6924,8 +7510,9 @@ static struct alc_config_preset alc260_presets[] = {
6924 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7510 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6925 .channel_mode = alc260_modes, 7511 .channel_mode = alc260_modes,
6926 .input_mux = &alc260_capture_source, 7512 .input_mux = &alc260_capture_source,
6927 .unsol_event = alc260_hp_3013_unsol_event, 7513 .unsol_event = alc_sku_unsol_event,
6928 .init_hook = alc260_hp_3013_automute, 7514 .setup = alc260_hp_3013_setup,
7515 .init_hook = alc_inithook,
6929 }, 7516 },
6930 [ALC260_FUJITSU_S702X] = { 7517 [ALC260_FUJITSU_S702X] = {
6931 .mixers = { alc260_fujitsu_mixer }, 7518 .mixers = { alc260_fujitsu_mixer },
@@ -7025,8 +7612,10 @@ static int patch_alc260(struct hda_codec *codec)
7025 board_config = ALC260_AUTO; 7612 board_config = ALC260_AUTO;
7026 } 7613 }
7027 7614
7028 if (board_config == ALC260_AUTO) 7615 if (board_config == ALC260_AUTO) {
7029 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1); 7616 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7617 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7618 }
7030 7619
7031 if (board_config == ALC260_AUTO) { 7620 if (board_config == ALC260_AUTO) {
7032 /* automatic parse from the BIOS config */ 7621 /* automatic parse from the BIOS config */
@@ -7074,14 +7663,14 @@ static int patch_alc260(struct hda_codec *codec)
7074 set_capture_mixer(codec); 7663 set_capture_mixer(codec);
7075 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 7664 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7076 7665
7077 if (board_config == ALC260_AUTO) 7666 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7078 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0);
7079 7667
7080 spec->vmaster_nid = 0x08; 7668 spec->vmaster_nid = 0x08;
7081 7669
7082 codec->patch_ops = alc_patch_ops; 7670 codec->patch_ops = alc_patch_ops;
7083 if (board_config == ALC260_AUTO) 7671 if (board_config == ALC260_AUTO)
7084 spec->init_hook = alc260_auto_init; 7672 spec->init_hook = alc260_auto_init;
7673 spec->shutup = alc_eapd_shutup;
7085#ifdef CONFIG_SND_HDA_POWER_SAVE 7674#ifdef CONFIG_SND_HDA_POWER_SAVE
7086 if (!spec->loopback.amplist) 7675 if (!spec->loopback.amplist)
7087 spec->loopback.amplist = alc260_loopbacks; 7676 spec->loopback.amplist = alc260_loopbacks;
@@ -7109,12 +7698,12 @@ static int patch_alc260(struct hda_codec *codec)
7109#define ALC1200_DIGOUT_NID 0x10 7698#define ALC1200_DIGOUT_NID 0x10
7110 7699
7111 7700
7112static struct hda_channel_mode alc882_ch_modes[1] = { 7701static const struct hda_channel_mode alc882_ch_modes[1] = {
7113 { 8, NULL } 7702 { 8, NULL }
7114}; 7703};
7115 7704
7116/* DACs */ 7705/* DACs */
7117static hda_nid_t alc882_dac_nids[4] = { 7706static const hda_nid_t alc882_dac_nids[4] = {
7118 /* front, rear, clfe, rear_surr */ 7707 /* front, rear, clfe, rear_surr */
7119 0x02, 0x03, 0x04, 0x05 7708 0x02, 0x03, 0x04, 0x05
7120}; 7709};
@@ -7124,20 +7713,20 @@ static hda_nid_t alc882_dac_nids[4] = {
7124#define alc882_adc_nids alc880_adc_nids 7713#define alc882_adc_nids alc880_adc_nids
7125#define alc882_adc_nids_alt alc880_adc_nids_alt 7714#define alc882_adc_nids_alt alc880_adc_nids_alt
7126#define alc883_adc_nids alc882_adc_nids_alt 7715#define alc883_adc_nids alc882_adc_nids_alt
7127static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; 7716static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7128static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; 7717static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7129#define alc889_adc_nids alc880_adc_nids 7718#define alc889_adc_nids alc880_adc_nids
7130 7719
7131static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; 7720static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7132static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; 7721static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7133#define alc883_capsrc_nids alc882_capsrc_nids_alt 7722#define alc883_capsrc_nids alc882_capsrc_nids_alt
7134static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; 7723static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7135#define alc889_capsrc_nids alc882_capsrc_nids 7724#define alc889_capsrc_nids alc882_capsrc_nids
7136 7725
7137/* input MUX */ 7726/* input MUX */
7138/* FIXME: should be a matrix-type input source selection */ 7727/* FIXME: should be a matrix-type input source selection */
7139 7728
7140static struct hda_input_mux alc882_capture_source = { 7729static const struct hda_input_mux alc882_capture_source = {
7141 .num_items = 4, 7730 .num_items = 4,
7142 .items = { 7731 .items = {
7143 { "Mic", 0x0 }, 7732 { "Mic", 0x0 },
@@ -7149,7 +7738,7 @@ static struct hda_input_mux alc882_capture_source = {
7149 7738
7150#define alc883_capture_source alc882_capture_source 7739#define alc883_capture_source alc882_capture_source
7151 7740
7152static struct hda_input_mux alc889_capture_source = { 7741static const struct hda_input_mux alc889_capture_source = {
7153 .num_items = 3, 7742 .num_items = 3,
7154 .items = { 7743 .items = {
7155 { "Front Mic", 0x0 }, 7744 { "Front Mic", 0x0 },
@@ -7158,7 +7747,7 @@ static struct hda_input_mux alc889_capture_source = {
7158 }, 7747 },
7159}; 7748};
7160 7749
7161static struct hda_input_mux mb5_capture_source = { 7750static const struct hda_input_mux mb5_capture_source = {
7162 .num_items = 3, 7751 .num_items = 3,
7163 .items = { 7752 .items = {
7164 { "Mic", 0x1 }, 7753 { "Mic", 0x1 },
@@ -7167,7 +7756,7 @@ static struct hda_input_mux mb5_capture_source = {
7167 }, 7756 },
7168}; 7757};
7169 7758
7170static struct hda_input_mux macmini3_capture_source = { 7759static const struct hda_input_mux macmini3_capture_source = {
7171 .num_items = 2, 7760 .num_items = 2,
7172 .items = { 7761 .items = {
7173 { "Line", 0x2 }, 7762 { "Line", 0x2 },
@@ -7175,7 +7764,7 @@ static struct hda_input_mux macmini3_capture_source = {
7175 }, 7764 },
7176}; 7765};
7177 7766
7178static struct hda_input_mux alc883_3stack_6ch_intel = { 7767static const struct hda_input_mux alc883_3stack_6ch_intel = {
7179 .num_items = 4, 7768 .num_items = 4,
7180 .items = { 7769 .items = {
7181 { "Mic", 0x1 }, 7770 { "Mic", 0x1 },
@@ -7185,7 +7774,7 @@ static struct hda_input_mux alc883_3stack_6ch_intel = {
7185 }, 7774 },
7186}; 7775};
7187 7776
7188static struct hda_input_mux alc883_lenovo_101e_capture_source = { 7777static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
7189 .num_items = 2, 7778 .num_items = 2,
7190 .items = { 7779 .items = {
7191 { "Mic", 0x1 }, 7780 { "Mic", 0x1 },
@@ -7193,25 +7782,25 @@ static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7193 }, 7782 },
7194}; 7783};
7195 7784
7196static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 7785static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7197 .num_items = 4, 7786 .num_items = 4,
7198 .items = { 7787 .items = {
7199 { "Mic", 0x0 }, 7788 { "Mic", 0x0 },
7200 { "Int Mic", 0x1 }, 7789 { "Internal Mic", 0x1 },
7201 { "Line", 0x2 }, 7790 { "Line", 0x2 },
7202 { "CD", 0x4 }, 7791 { "CD", 0x4 },
7203 }, 7792 },
7204}; 7793};
7205 7794
7206static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { 7795static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7207 .num_items = 2, 7796 .num_items = 2,
7208 .items = { 7797 .items = {
7209 { "Mic", 0x0 }, 7798 { "Mic", 0x0 },
7210 { "Int Mic", 0x1 }, 7799 { "Internal Mic", 0x1 },
7211 }, 7800 },
7212}; 7801};
7213 7802
7214static struct hda_input_mux alc883_lenovo_sky_capture_source = { 7803static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
7215 .num_items = 3, 7804 .num_items = 3,
7216 .items = { 7805 .items = {
7217 { "Mic", 0x0 }, 7806 { "Mic", 0x0 },
@@ -7220,7 +7809,7 @@ static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7220 }, 7809 },
7221}; 7810};
7222 7811
7223static struct hda_input_mux alc883_asus_eee1601_capture_source = { 7812static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
7224 .num_items = 2, 7813 .num_items = 2,
7225 .items = { 7814 .items = {
7226 { "Mic", 0x0 }, 7815 { "Mic", 0x0 },
@@ -7228,7 +7817,7 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7228 }, 7817 },
7229}; 7818};
7230 7819
7231static struct hda_input_mux alc889A_mb31_capture_source = { 7820static const struct hda_input_mux alc889A_mb31_capture_source = {
7232 .num_items = 2, 7821 .num_items = 2,
7233 .items = { 7822 .items = {
7234 { "Mic", 0x0 }, 7823 { "Mic", 0x0 },
@@ -7239,7 +7828,7 @@ static struct hda_input_mux alc889A_mb31_capture_source = {
7239 }, 7828 },
7240}; 7829};
7241 7830
7242static struct hda_input_mux alc889A_imac91_capture_source = { 7831static const struct hda_input_mux alc889A_imac91_capture_source = {
7243 .num_items = 2, 7832 .num_items = 2,
7244 .items = { 7833 .items = {
7245 { "Mic", 0x01 }, 7834 { "Mic", 0x01 },
@@ -7250,14 +7839,14 @@ static struct hda_input_mux alc889A_imac91_capture_source = {
7250/* 7839/*
7251 * 2ch mode 7840 * 2ch mode
7252 */ 7841 */
7253static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 7842static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7254 { 2, NULL } 7843 { 2, NULL }
7255}; 7844};
7256 7845
7257/* 7846/*
7258 * 2ch mode 7847 * 2ch mode
7259 */ 7848 */
7260static struct hda_verb alc882_3ST_ch2_init[] = { 7849static const struct hda_verb alc882_3ST_ch2_init[] = {
7261 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7850 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7262 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7851 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7263 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7852 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
@@ -7268,7 +7857,7 @@ static struct hda_verb alc882_3ST_ch2_init[] = {
7268/* 7857/*
7269 * 4ch mode 7858 * 4ch mode
7270 */ 7859 */
7271static struct hda_verb alc882_3ST_ch4_init[] = { 7860static const struct hda_verb alc882_3ST_ch4_init[] = {
7272 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7861 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7273 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7862 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7274 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7863 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -7280,7 +7869,7 @@ static struct hda_verb alc882_3ST_ch4_init[] = {
7280/* 7869/*
7281 * 6ch mode 7870 * 6ch mode
7282 */ 7871 */
7283static struct hda_verb alc882_3ST_ch6_init[] = { 7872static const struct hda_verb alc882_3ST_ch6_init[] = {
7284 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7873 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7285 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7874 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7286 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7875 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
@@ -7290,7 +7879,7 @@ static struct hda_verb alc882_3ST_ch6_init[] = {
7290 { } /* end */ 7879 { } /* end */
7291}; 7880};
7292 7881
7293static struct hda_channel_mode alc882_3ST_6ch_modes[3] = { 7882static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7294 { 2, alc882_3ST_ch2_init }, 7883 { 2, alc882_3ST_ch2_init },
7295 { 4, alc882_3ST_ch4_init }, 7884 { 4, alc882_3ST_ch4_init },
7296 { 6, alc882_3ST_ch6_init }, 7885 { 6, alc882_3ST_ch6_init },
@@ -7301,7 +7890,7 @@ static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7301/* 7890/*
7302 * 2ch mode 7891 * 2ch mode
7303 */ 7892 */
7304static struct hda_verb alc883_3ST_ch2_clevo_init[] = { 7893static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7305 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 7894 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7306 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7895 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7307 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7896 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
@@ -7313,7 +7902,7 @@ static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7313/* 7902/*
7314 * 4ch mode 7903 * 4ch mode
7315 */ 7904 */
7316static struct hda_verb alc883_3ST_ch4_clevo_init[] = { 7905static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7317 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7906 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7318 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7907 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7319 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7908 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
@@ -7326,7 +7915,7 @@ static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7326/* 7915/*
7327 * 6ch mode 7916 * 6ch mode
7328 */ 7917 */
7329static struct hda_verb alc883_3ST_ch6_clevo_init[] = { 7918static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7330 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7919 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7331 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7920 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7332 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7921 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
@@ -7337,7 +7926,7 @@ static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7337 { } /* end */ 7926 { } /* end */
7338}; 7927};
7339 7928
7340static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { 7929static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7341 { 2, alc883_3ST_ch2_clevo_init }, 7930 { 2, alc883_3ST_ch2_clevo_init },
7342 { 4, alc883_3ST_ch4_clevo_init }, 7931 { 4, alc883_3ST_ch4_clevo_init },
7343 { 6, alc883_3ST_ch6_clevo_init }, 7932 { 6, alc883_3ST_ch6_clevo_init },
@@ -7347,7 +7936,7 @@ static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7347/* 7936/*
7348 * 6ch mode 7937 * 6ch mode
7349 */ 7938 */
7350static struct hda_verb alc882_sixstack_ch6_init[] = { 7939static const struct hda_verb alc882_sixstack_ch6_init[] = {
7351 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7940 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7352 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7941 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7353 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7942 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -7358,7 +7947,7 @@ static struct hda_verb alc882_sixstack_ch6_init[] = {
7358/* 7947/*
7359 * 8ch mode 7948 * 8ch mode
7360 */ 7949 */
7361static struct hda_verb alc882_sixstack_ch8_init[] = { 7950static const struct hda_verb alc882_sixstack_ch8_init[] = {
7362 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7951 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7363 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7952 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7364 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7953 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -7366,7 +7955,7 @@ static struct hda_verb alc882_sixstack_ch8_init[] = {
7366 { } /* end */ 7955 { } /* end */
7367}; 7956};
7368 7957
7369static struct hda_channel_mode alc882_sixstack_modes[2] = { 7958static const struct hda_channel_mode alc882_sixstack_modes[2] = {
7370 { 6, alc882_sixstack_ch6_init }, 7959 { 6, alc882_sixstack_ch6_init },
7371 { 8, alc882_sixstack_ch8_init }, 7960 { 8, alc882_sixstack_ch8_init },
7372}; 7961};
@@ -7374,7 +7963,7 @@ static struct hda_channel_mode alc882_sixstack_modes[2] = {
7374 7963
7375/* Macbook Air 2,1 */ 7964/* Macbook Air 2,1 */
7376 7965
7377static struct hda_channel_mode alc885_mba21_ch_modes[1] = { 7966static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7378 { 2, NULL }, 7967 { 2, NULL },
7379}; 7968};
7380 7969
@@ -7385,7 +7974,7 @@ static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7385/* 7974/*
7386 * 2ch mode 7975 * 2ch mode
7387 */ 7976 */
7388static struct hda_verb alc885_mbp_ch2_init[] = { 7977static const struct hda_verb alc885_mbp_ch2_init[] = {
7389 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7978 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7390 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7979 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7391 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7980 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
@@ -7395,7 +7984,7 @@ static struct hda_verb alc885_mbp_ch2_init[] = {
7395/* 7984/*
7396 * 4ch mode 7985 * 4ch mode
7397 */ 7986 */
7398static struct hda_verb alc885_mbp_ch4_init[] = { 7987static const struct hda_verb alc885_mbp_ch4_init[] = {
7399 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7988 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7400 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7989 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7401 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7990 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
@@ -7404,7 +7993,7 @@ static struct hda_verb alc885_mbp_ch4_init[] = {
7404 { } /* end */ 7993 { } /* end */
7405}; 7994};
7406 7995
7407static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { 7996static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7408 { 2, alc885_mbp_ch2_init }, 7997 { 2, alc885_mbp_ch2_init },
7409 { 4, alc885_mbp_ch4_init }, 7998 { 4, alc885_mbp_ch4_init },
7410}; 7999};
@@ -7414,7 +8003,7 @@ static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7414 * Speakers/Woofer/HP = Front 8003 * Speakers/Woofer/HP = Front
7415 * LineIn = Input 8004 * LineIn = Input
7416 */ 8005 */
7417static struct hda_verb alc885_mb5_ch2_init[] = { 8006static const struct hda_verb alc885_mb5_ch2_init[] = {
7418 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8007 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7419 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8008 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7420 { } /* end */ 8009 { } /* end */
@@ -7426,14 +8015,14 @@ static struct hda_verb alc885_mb5_ch2_init[] = {
7426 * Woofer = LFE 8015 * Woofer = LFE
7427 * LineIn = Surround 8016 * LineIn = Surround
7428 */ 8017 */
7429static struct hda_verb alc885_mb5_ch6_init[] = { 8018static const struct hda_verb alc885_mb5_ch6_init[] = {
7430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8019 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7431 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8020 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7432 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 8021 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7433 { } /* end */ 8022 { } /* end */
7434}; 8023};
7435 8024
7436static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { 8025static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7437 { 2, alc885_mb5_ch2_init }, 8026 { 2, alc885_mb5_ch2_init },
7438 { 6, alc885_mb5_ch6_init }, 8027 { 6, alc885_mb5_ch6_init },
7439}; 8028};
@@ -7443,7 +8032,7 @@ static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7443/* 8032/*
7444 * 2ch mode 8033 * 2ch mode
7445 */ 8034 */
7446static struct hda_verb alc883_4ST_ch2_init[] = { 8035static const struct hda_verb alc883_4ST_ch2_init[] = {
7447 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8036 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7448 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8037 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7449 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 8038 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
@@ -7456,7 +8045,7 @@ static struct hda_verb alc883_4ST_ch2_init[] = {
7456/* 8045/*
7457 * 4ch mode 8046 * 4ch mode
7458 */ 8047 */
7459static struct hda_verb alc883_4ST_ch4_init[] = { 8048static const struct hda_verb alc883_4ST_ch4_init[] = {
7460 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8049 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7461 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8050 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7462 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 8051 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
@@ -7470,7 +8059,7 @@ static struct hda_verb alc883_4ST_ch4_init[] = {
7470/* 8059/*
7471 * 6ch mode 8060 * 6ch mode
7472 */ 8061 */
7473static struct hda_verb alc883_4ST_ch6_init[] = { 8062static const struct hda_verb alc883_4ST_ch6_init[] = {
7474 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8063 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7475 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8064 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7476 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8065 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -7485,7 +8074,7 @@ static struct hda_verb alc883_4ST_ch6_init[] = {
7485/* 8074/*
7486 * 8ch mode 8075 * 8ch mode
7487 */ 8076 */
7488static struct hda_verb alc883_4ST_ch8_init[] = { 8077static const struct hda_verb alc883_4ST_ch8_init[] = {
7489 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8078 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7490 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8079 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7491 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 8080 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
@@ -7498,7 +8087,7 @@ static struct hda_verb alc883_4ST_ch8_init[] = {
7498 { } /* end */ 8087 { } /* end */
7499}; 8088};
7500 8089
7501static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { 8090static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7502 { 2, alc883_4ST_ch2_init }, 8091 { 2, alc883_4ST_ch2_init },
7503 { 4, alc883_4ST_ch4_init }, 8092 { 4, alc883_4ST_ch4_init },
7504 { 6, alc883_4ST_ch6_init }, 8093 { 6, alc883_4ST_ch6_init },
@@ -7509,7 +8098,7 @@ static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7509/* 8098/*
7510 * 2ch mode 8099 * 2ch mode
7511 */ 8100 */
7512static struct hda_verb alc883_3ST_ch2_intel_init[] = { 8101static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
7513 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 8102 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7514 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8103 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7515 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 8104 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
@@ -7520,7 +8109,7 @@ static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7520/* 8109/*
7521 * 4ch mode 8110 * 4ch mode
7522 */ 8111 */
7523static struct hda_verb alc883_3ST_ch4_intel_init[] = { 8112static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
7524 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 8113 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7525 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8114 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7526 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8115 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -7532,7 +8121,7 @@ static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7532/* 8121/*
7533 * 6ch mode 8122 * 6ch mode
7534 */ 8123 */
7535static struct hda_verb alc883_3ST_ch6_intel_init[] = { 8124static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
7536 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8125 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7537 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8126 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7538 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, 8127 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
@@ -7542,7 +8131,7 @@ static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7542 { } /* end */ 8131 { } /* end */
7543}; 8132};
7544 8133
7545static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { 8134static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7546 { 2, alc883_3ST_ch2_intel_init }, 8135 { 2, alc883_3ST_ch2_intel_init },
7547 { 4, alc883_3ST_ch4_intel_init }, 8136 { 4, alc883_3ST_ch4_intel_init },
7548 { 6, alc883_3ST_ch6_intel_init }, 8137 { 6, alc883_3ST_ch6_intel_init },
@@ -7551,7 +8140,7 @@ static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7551/* 8140/*
7552 * 2ch mode 8141 * 2ch mode
7553 */ 8142 */
7554static struct hda_verb alc889_ch2_intel_init[] = { 8143static const struct hda_verb alc889_ch2_intel_init[] = {
7555 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8144 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7556 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8145 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7557 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8146 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
@@ -7564,7 +8153,7 @@ static struct hda_verb alc889_ch2_intel_init[] = {
7564/* 8153/*
7565 * 6ch mode 8154 * 6ch mode
7566 */ 8155 */
7567static struct hda_verb alc889_ch6_intel_init[] = { 8156static const struct hda_verb alc889_ch6_intel_init[] = {
7568 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8157 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7569 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 8158 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7570 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 8159 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
@@ -7577,7 +8166,7 @@ static struct hda_verb alc889_ch6_intel_init[] = {
7577/* 8166/*
7578 * 8ch mode 8167 * 8ch mode
7579 */ 8168 */
7580static struct hda_verb alc889_ch8_intel_init[] = { 8169static const struct hda_verb alc889_ch8_intel_init[] = {
7581 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8170 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7582 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 8171 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7583 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 8172 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
@@ -7588,7 +8177,7 @@ static struct hda_verb alc889_ch8_intel_init[] = {
7588 { } /* end */ 8177 { } /* end */
7589}; 8178};
7590 8179
7591static struct hda_channel_mode alc889_8ch_intel_modes[3] = { 8180static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7592 { 2, alc889_ch2_intel_init }, 8181 { 2, alc889_ch2_intel_init },
7593 { 6, alc889_ch6_intel_init }, 8182 { 6, alc889_ch6_intel_init },
7594 { 8, alc889_ch8_intel_init }, 8183 { 8, alc889_ch8_intel_init },
@@ -7597,7 +8186,7 @@ static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7597/* 8186/*
7598 * 6ch mode 8187 * 6ch mode
7599 */ 8188 */
7600static struct hda_verb alc883_sixstack_ch6_init[] = { 8189static const struct hda_verb alc883_sixstack_ch6_init[] = {
7601 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 8190 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7602 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8191 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7603 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8192 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -7608,7 +8197,7 @@ static struct hda_verb alc883_sixstack_ch6_init[] = {
7608/* 8197/*
7609 * 8ch mode 8198 * 8ch mode
7610 */ 8199 */
7611static struct hda_verb alc883_sixstack_ch8_init[] = { 8200static const struct hda_verb alc883_sixstack_ch8_init[] = {
7612 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8201 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7613 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8202 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7614 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8203 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -7616,7 +8205,7 @@ static struct hda_verb alc883_sixstack_ch8_init[] = {
7616 { } /* end */ 8205 { } /* end */
7617}; 8206};
7618 8207
7619static struct hda_channel_mode alc883_sixstack_modes[2] = { 8208static const struct hda_channel_mode alc883_sixstack_modes[2] = {
7620 { 6, alc883_sixstack_ch6_init }, 8209 { 6, alc883_sixstack_ch6_init },
7621 { 8, alc883_sixstack_ch8_init }, 8210 { 8, alc883_sixstack_ch8_init },
7622}; 8211};
@@ -7625,7 +8214,7 @@ static struct hda_channel_mode alc883_sixstack_modes[2] = {
7625/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 8214/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7626 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 8215 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7627 */ 8216 */
7628static struct snd_kcontrol_new alc882_base_mixer[] = { 8217static const struct snd_kcontrol_new alc882_base_mixer[] = {
7629 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8218 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7630 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8219 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7631 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8220 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -7642,24 +8231,24 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
7642 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7643 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7644 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8233 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7645 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7646 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8235 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7647 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8236 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7648 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8237 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
7649 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8238 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7650 { } /* end */ 8239 { } /* end */
7651}; 8240};
7652 8241
7653/* Macbook Air 2,1 same control for HP and internal Speaker */ 8242/* Macbook Air 2,1 same control for HP and internal Speaker */
7654 8243
7655static struct snd_kcontrol_new alc885_mba21_mixer[] = { 8244static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
7656 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8245 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7657 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT), 8246 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7658 { } 8247 { }
7659}; 8248};
7660 8249
7661 8250
7662static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 8251static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7663 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8252 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7664 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 8253 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7665 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 8254 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
@@ -7669,12 +8258,12 @@ static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7669 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8258 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7670 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 8259 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7671 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 8260 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7672 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 8261 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
7673 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 8262 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
7674 { } /* end */ 8263 { } /* end */
7675}; 8264};
7676 8265
7677static struct snd_kcontrol_new alc885_mb5_mixer[] = { 8266static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
7678 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7679 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 8268 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7680 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 8269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
@@ -7687,12 +8276,12 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7687 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 8276 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7688 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 8277 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7689 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 8278 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7690 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 8279 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7691 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT), 8280 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
7692 { } /* end */ 8281 { } /* end */
7693}; 8282};
7694 8283
7695static struct snd_kcontrol_new alc885_macmini3_mixer[] = { 8284static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7696 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8285 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7697 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 8286 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7698 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 8287 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
@@ -7703,18 +8292,18 @@ static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7703 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 8292 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7704 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 8293 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7705 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 8294 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7706 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 8295 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7707 { } /* end */ 8296 { } /* end */
7708}; 8297};
7709 8298
7710static struct snd_kcontrol_new alc885_imac91_mixer[] = { 8299static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
7711 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8300 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7712 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 8301 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7713 { } /* end */ 8302 { } /* end */
7714}; 8303};
7715 8304
7716 8305
7717static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 8306static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7718 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8307 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7719 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8308 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7720 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8309 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -7722,12 +8311,12 @@ static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7722 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8311 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7723 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8312 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7724 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8313 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7725 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8314 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7726 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7727 { } /* end */ 8316 { } /* end */
7728}; 8317};
7729 8318
7730static struct snd_kcontrol_new alc882_targa_mixer[] = { 8319static const struct snd_kcontrol_new alc882_targa_mixer[] = {
7731 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8320 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7732 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8321 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7733 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8322 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
@@ -7737,17 +8326,17 @@ static struct snd_kcontrol_new alc882_targa_mixer[] = {
7737 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8326 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7738 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8327 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7739 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8328 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7740 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8329 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7741 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8330 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7742 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8331 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7743 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8332 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
7744 { } /* end */ 8333 { } /* end */
7745}; 8334};
7746 8335
7747/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 8336/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7748 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 8337 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7749 */ 8338 */
7750static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 8339static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7751 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8340 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7752 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8341 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7753 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8342 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -7760,11 +8349,11 @@ static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7760 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 8349 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7761 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8350 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7762 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8351 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7763 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8352 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7764 { } /* end */ 8353 { } /* end */
7765}; 8354};
7766 8355
7767static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 8356static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7768 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8357 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7769 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8358 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7770 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8359 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -7773,12 +8362,12 @@ static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7773 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8362 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7774 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8363 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7775 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8364 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7776 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8365 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7777 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8366 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7778 { } /* end */ 8367 { } /* end */
7779}; 8368};
7780 8369
7781static struct snd_kcontrol_new alc882_chmode_mixer[] = { 8370static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
7782 { 8371 {
7783 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8372 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7784 .name = "Channel Mode", 8373 .name = "Channel Mode",
@@ -7789,7 +8378,7 @@ static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7789 { } /* end */ 8378 { } /* end */
7790}; 8379};
7791 8380
7792static struct hda_verb alc882_base_init_verbs[] = { 8381static const struct hda_verb alc882_base_init_verbs[] = {
7793 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8382 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7794 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7795 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8384 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
@@ -7851,7 +8440,7 @@ static struct hda_verb alc882_base_init_verbs[] = {
7851 { } 8440 { }
7852}; 8441};
7853 8442
7854static struct hda_verb alc882_adc1_init_verbs[] = { 8443static const struct hda_verb alc882_adc1_init_verbs[] = {
7855 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8444 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7856 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7857 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
@@ -7863,26 +8452,26 @@ static struct hda_verb alc882_adc1_init_verbs[] = {
7863 { } 8452 { }
7864}; 8453};
7865 8454
7866static struct hda_verb alc882_eapd_verbs[] = { 8455static const struct hda_verb alc882_eapd_verbs[] = {
7867 /* change to EAPD mode */ 8456 /* change to EAPD mode */
7868 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8457 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7869 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 8458 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
7870 { } 8459 { }
7871}; 8460};
7872 8461
7873static struct hda_verb alc889_eapd_verbs[] = { 8462static const struct hda_verb alc889_eapd_verbs[] = {
7874 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8463 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7875 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8464 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7876 { } 8465 { }
7877}; 8466};
7878 8467
7879static struct hda_verb alc_hp15_unsol_verbs[] = { 8468static const struct hda_verb alc_hp15_unsol_verbs[] = {
7880 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 8469 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7881 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8470 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7882 {} 8471 {}
7883}; 8472};
7884 8473
7885static struct hda_verb alc885_init_verbs[] = { 8474static const struct hda_verb alc885_init_verbs[] = {
7886 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8475 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7887 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8476 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7888 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8477 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -7941,7 +8530,7 @@ static struct hda_verb alc885_init_verbs[] = {
7941 { } 8530 { }
7942}; 8531};
7943 8532
7944static struct hda_verb alc885_init_input_verbs[] = { 8533static const struct hda_verb alc885_init_input_verbs[] = {
7945 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8534 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7946 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 8535 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7947 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 8536 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
@@ -7950,7 +8539,7 @@ static struct hda_verb alc885_init_input_verbs[] = {
7950 8539
7951 8540
7952/* Unmute Selector 24h and set the default input to front mic */ 8541/* Unmute Selector 24h and set the default input to front mic */
7953static struct hda_verb alc889_init_input_verbs[] = { 8542static const struct hda_verb alc889_init_input_verbs[] = {
7954 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 8543 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7955 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8544 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7956 { } 8545 { }
@@ -7960,7 +8549,7 @@ static struct hda_verb alc889_init_input_verbs[] = {
7960#define alc883_init_verbs alc882_base_init_verbs 8549#define alc883_init_verbs alc882_base_init_verbs
7961 8550
7962/* Mac Pro test */ 8551/* Mac Pro test */
7963static struct snd_kcontrol_new alc882_macpro_mixer[] = { 8552static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
7964 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8553 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7965 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8554 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7966 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 8555 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
@@ -7973,7 +8562,7 @@ static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7973 { } /* end */ 8562 { } /* end */
7974}; 8563};
7975 8564
7976static struct hda_verb alc882_macpro_init_verbs[] = { 8565static const struct hda_verb alc882_macpro_init_verbs[] = {
7977 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8566 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7978 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8567 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7979 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8568 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -8025,7 +8614,7 @@ static struct hda_verb alc882_macpro_init_verbs[] = {
8025}; 8614};
8026 8615
8027/* Macbook 5,1 */ 8616/* Macbook 5,1 */
8028static struct hda_verb alc885_mb5_init_verbs[] = { 8617static const struct hda_verb alc885_mb5_init_verbs[] = {
8029 /* DACs */ 8618 /* DACs */
8030 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8619 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8031 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8620 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -8074,7 +8663,7 @@ static struct hda_verb alc885_mb5_init_verbs[] = {
8074}; 8663};
8075 8664
8076/* Macmini 3,1 */ 8665/* Macmini 3,1 */
8077static struct hda_verb alc885_macmini3_init_verbs[] = { 8666static const struct hda_verb alc885_macmini3_init_verbs[] = {
8078 /* DACs */ 8667 /* DACs */
8079 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8668 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8080 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8669 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -8121,7 +8710,7 @@ static struct hda_verb alc885_macmini3_init_verbs[] = {
8121}; 8710};
8122 8711
8123 8712
8124static struct hda_verb alc885_mba21_init_verbs[] = { 8713static const struct hda_verb alc885_mba21_init_verbs[] = {
8125 /*Internal and HP Speaker Mixer*/ 8714 /*Internal and HP Speaker Mixer*/
8126 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8127 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8716 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -8144,7 +8733,7 @@ static struct hda_verb alc885_mba21_init_verbs[] = {
8144 8733
8145 8734
8146/* Macbook Pro rev3 */ 8735/* Macbook Pro rev3 */
8147static struct hda_verb alc885_mbp3_init_verbs[] = { 8736static const struct hda_verb alc885_mbp3_init_verbs[] = {
8148 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8737 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8149 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8738 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8150 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8739 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -8208,7 +8797,7 @@ static struct hda_verb alc885_mbp3_init_verbs[] = {
8208}; 8797};
8209 8798
8210/* iMac 9,1 */ 8799/* iMac 9,1 */
8211static struct hda_verb alc885_imac91_init_verbs[] = { 8800static const struct hda_verb alc885_imac91_init_verbs[] = {
8212 /* Internal Speaker Pin (0x0c) */ 8801 /* Internal Speaker Pin (0x0c) */
8213 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8802 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8214 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8803 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -8263,14 +8852,14 @@ static struct hda_verb alc885_imac91_init_verbs[] = {
8263}; 8852};
8264 8853
8265/* iMac 24 mixer. */ 8854/* iMac 24 mixer. */
8266static struct snd_kcontrol_new alc885_imac24_mixer[] = { 8855static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
8267 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8856 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8268 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 8857 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8269 { } /* end */ 8858 { } /* end */
8270}; 8859};
8271 8860
8272/* iMac 24 init verbs. */ 8861/* iMac 24 init verbs. */
8273static struct hda_verb alc885_imac24_init_verbs[] = { 8862static const struct hda_verb alc885_imac24_init_verbs[] = {
8274 /* Internal speakers: output 0 (0x0c) */ 8863 /* Internal speakers: output 0 (0x0c) */
8275 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8864 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8276 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8865 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -8298,6 +8887,8 @@ static void alc885_imac24_setup(struct hda_codec *codec)
8298 spec->autocfg.hp_pins[0] = 0x14; 8887 spec->autocfg.hp_pins[0] = 0x14;
8299 spec->autocfg.speaker_pins[0] = 0x18; 8888 spec->autocfg.speaker_pins[0] = 0x18;
8300 spec->autocfg.speaker_pins[1] = 0x1a; 8889 spec->autocfg.speaker_pins[1] = 0x1a;
8890 spec->automute = 1;
8891 spec->automute_mode = ALC_AUTOMUTE_AMP;
8301} 8892}
8302 8893
8303#define alc885_mb5_setup alc885_imac24_setup 8894#define alc885_mb5_setup alc885_imac24_setup
@@ -8310,6 +8901,8 @@ static void alc885_mba21_setup(struct hda_codec *codec)
8310 8901
8311 spec->autocfg.hp_pins[0] = 0x14; 8902 spec->autocfg.hp_pins[0] = 0x14;
8312 spec->autocfg.speaker_pins[0] = 0x18; 8903 spec->autocfg.speaker_pins[0] = 0x18;
8904 spec->automute = 1;
8905 spec->automute_mode = ALC_AUTOMUTE_AMP;
8313} 8906}
8314 8907
8315 8908
@@ -8320,6 +8913,8 @@ static void alc885_mbp3_setup(struct hda_codec *codec)
8320 8913
8321 spec->autocfg.hp_pins[0] = 0x15; 8914 spec->autocfg.hp_pins[0] = 0x15;
8322 spec->autocfg.speaker_pins[0] = 0x14; 8915 spec->autocfg.speaker_pins[0] = 0x14;
8916 spec->automute = 1;
8917 spec->automute_mode = ALC_AUTOMUTE_AMP;
8323} 8918}
8324 8919
8325static void alc885_imac91_setup(struct hda_codec *codec) 8920static void alc885_imac91_setup(struct hda_codec *codec)
@@ -8329,9 +8924,11 @@ static void alc885_imac91_setup(struct hda_codec *codec)
8329 spec->autocfg.hp_pins[0] = 0x14; 8924 spec->autocfg.hp_pins[0] = 0x14;
8330 spec->autocfg.speaker_pins[0] = 0x18; 8925 spec->autocfg.speaker_pins[0] = 0x18;
8331 spec->autocfg.speaker_pins[1] = 0x1a; 8926 spec->autocfg.speaker_pins[1] = 0x1a;
8927 spec->automute = 1;
8928 spec->automute_mode = ALC_AUTOMUTE_AMP;
8332} 8929}
8333 8930
8334static struct hda_verb alc882_targa_verbs[] = { 8931static const struct hda_verb alc882_targa_verbs[] = {
8335 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8932 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8336 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8933 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8337 8934
@@ -8350,7 +8947,7 @@ static struct hda_verb alc882_targa_verbs[] = {
8350static void alc882_targa_automute(struct hda_codec *codec) 8947static void alc882_targa_automute(struct hda_codec *codec)
8351{ 8948{
8352 struct alc_spec *spec = codec->spec; 8949 struct alc_spec *spec = codec->spec;
8353 alc_automute_amp(codec); 8950 alc_hp_automute(codec);
8354 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 8951 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8355 spec->jack_present ? 1 : 3); 8952 spec->jack_present ? 1 : 3);
8356} 8953}
@@ -8361,6 +8958,8 @@ static void alc882_targa_setup(struct hda_codec *codec)
8361 8958
8362 spec->autocfg.hp_pins[0] = 0x14; 8959 spec->autocfg.hp_pins[0] = 0x14;
8363 spec->autocfg.speaker_pins[0] = 0x1b; 8960 spec->autocfg.speaker_pins[0] = 0x1b;
8961 spec->automute = 1;
8962 spec->automute_mode = ALC_AUTOMUTE_AMP;
8364} 8963}
8365 8964
8366static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 8965static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -8369,7 +8968,7 @@ static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8369 alc882_targa_automute(codec); 8968 alc882_targa_automute(codec);
8370} 8969}
8371 8970
8372static struct hda_verb alc882_asus_a7j_verbs[] = { 8971static const struct hda_verb alc882_asus_a7j_verbs[] = {
8373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8374 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8973 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8375 8974
@@ -8387,7 +8986,7 @@ static struct hda_verb alc882_asus_a7j_verbs[] = {
8387 { } /* end */ 8986 { } /* end */
8388}; 8987};
8389 8988
8390static struct hda_verb alc882_asus_a7m_verbs[] = { 8989static const struct hda_verb alc882_asus_a7m_verbs[] = {
8391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8990 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8991 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8393 8992
@@ -8448,13 +9047,13 @@ static void alc885_macpro_init_hook(struct hda_codec *codec)
8448static void alc885_imac24_init_hook(struct hda_codec *codec) 9047static void alc885_imac24_init_hook(struct hda_codec *codec)
8449{ 9048{
8450 alc885_macpro_init_hook(codec); 9049 alc885_macpro_init_hook(codec);
8451 alc_automute_amp(codec); 9050 alc_hp_automute(codec);
8452} 9051}
8453 9052
8454/* 9053/*
8455 * generic initialization of ADC, input mixers and output mixers 9054 * generic initialization of ADC, input mixers and output mixers
8456 */ 9055 */
8457static struct hda_verb alc883_auto_init_verbs[] = { 9056static const struct hda_verb alc883_auto_init_verbs[] = {
8458 /* 9057 /*
8459 * Unmute ADC0-2 and set the default input to mic-in 9058 * Unmute ADC0-2 and set the default input to mic-in
8460 */ 9059 */
@@ -8494,7 +9093,7 @@ static struct hda_verb alc883_auto_init_verbs[] = {
8494}; 9093};
8495 9094
8496/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ 9095/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8497static struct hda_verb alc889A_mb31_ch2_init[] = { 9096static const struct hda_verb alc889A_mb31_ch2_init[] = {
8498 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 9097 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8499 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 9098 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8500 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 9099 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
@@ -8503,7 +9102,7 @@ static struct hda_verb alc889A_mb31_ch2_init[] = {
8503}; 9102};
8504 9103
8505/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ 9104/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8506static struct hda_verb alc889A_mb31_ch4_init[] = { 9105static const struct hda_verb alc889A_mb31_ch4_init[] = {
8507 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 9106 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8508 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 9107 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8509 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 9108 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
@@ -8512,7 +9111,7 @@ static struct hda_verb alc889A_mb31_ch4_init[] = {
8512}; 9111};
8513 9112
8514/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ 9113/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8515static struct hda_verb alc889A_mb31_ch5_init[] = { 9114static const struct hda_verb alc889A_mb31_ch5_init[] = {
8516 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ 9115 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8517 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 9116 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8518 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 9117 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
@@ -8521,7 +9120,7 @@ static struct hda_verb alc889A_mb31_ch5_init[] = {
8521}; 9120};
8522 9121
8523/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ 9122/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8524static struct hda_verb alc889A_mb31_ch6_init[] = { 9123static const struct hda_verb alc889A_mb31_ch6_init[] = {
8525 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ 9124 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8526 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ 9125 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8527 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 9126 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
@@ -8529,14 +9128,14 @@ static struct hda_verb alc889A_mb31_ch6_init[] = {
8529 { } /* end */ 9128 { } /* end */
8530}; 9129};
8531 9130
8532static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { 9131static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8533 { 2, alc889A_mb31_ch2_init }, 9132 { 2, alc889A_mb31_ch2_init },
8534 { 4, alc889A_mb31_ch4_init }, 9133 { 4, alc889A_mb31_ch4_init },
8535 { 5, alc889A_mb31_ch5_init }, 9134 { 5, alc889A_mb31_ch5_init },
8536 { 6, alc889A_mb31_ch6_init }, 9135 { 6, alc889A_mb31_ch6_init },
8537}; 9136};
8538 9137
8539static struct hda_verb alc883_medion_eapd_verbs[] = { 9138static const struct hda_verb alc883_medion_eapd_verbs[] = {
8540 /* eanable EAPD on medion laptop */ 9139 /* eanable EAPD on medion laptop */
8541 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 9140 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8542 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 9141 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
@@ -8545,7 +9144,7 @@ static struct hda_verb alc883_medion_eapd_verbs[] = {
8545 9144
8546#define alc883_base_mixer alc882_base_mixer 9145#define alc883_base_mixer alc882_base_mixer
8547 9146
8548static struct snd_kcontrol_new alc883_mitac_mixer[] = { 9147static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
8549 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9148 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8550 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9149 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8551 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 9150 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
@@ -8554,43 +9153,43 @@ static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8554 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 9153 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8555 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9154 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8556 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9155 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8557 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9156 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8558 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9157 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8559 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9158 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8560 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 9159 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8561 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9160 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8562 { } /* end */ 9161 { } /* end */
8563}; 9162};
8564 9163
8565static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { 9164static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9165 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8567 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 9166 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8568 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9167 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8569 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 9168 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8570 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8571 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9170 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8572 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9171 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8573 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9172 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8574 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 9173 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8575 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9174 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8576 { } /* end */ 9175 { } /* end */
8577}; 9176};
8578 9177
8579static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { 9178static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8580 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9179 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8581 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 9180 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8582 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9181 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8583 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 9182 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8584 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9183 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8585 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9184 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8586 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9185 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8587 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9186 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8588 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 9187 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8589 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9188 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8590 { } /* end */ 9189 { } /* end */
8591}; 9190};
8592 9191
8593static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 9192static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8594 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9193 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8595 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9194 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8596 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9195 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
@@ -8599,15 +9198,15 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8599 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9198 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8600 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9199 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8601 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9200 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8602 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9201 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8603 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9202 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8604 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9203 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8605 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 9204 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8606 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9205 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8607 { } /* end */ 9206 { } /* end */
8608}; 9207};
8609 9208
8610static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 9209static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8611 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9210 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8612 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9211 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8613 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9212 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -8622,15 +9221,15 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8622 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9221 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8623 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9222 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8624 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9223 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8625 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9224 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8626 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9225 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8627 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9226 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8628 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 9227 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8629 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9228 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8630 { } /* end */ 9229 { } /* end */
8631}; 9230};
8632 9231
8633static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { 9232static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8634 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9233 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8635 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9234 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8636 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9235 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -8646,15 +9245,15 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8646 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9245 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8647 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9246 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8648 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9247 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8649 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 9248 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
8650 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9249 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8651 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9250 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8652 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 9251 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
8653 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9252 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8654 { } /* end */ 9253 { } /* end */
8655}; 9254};
8656 9255
8657static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { 9256static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8658 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9257 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8659 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9258 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8660 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9259 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -8670,15 +9269,15 @@ static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8670 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9269 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8671 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9270 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8672 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 9271 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8673 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT), 9272 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
8674 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 9273 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8675 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9274 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8676 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 9275 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
8677 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9276 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8678 { } /* end */ 9277 { } /* end */
8679}; 9278};
8680 9279
8681static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 9280static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
8682 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9281 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8683 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9282 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8684 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9283 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -8693,15 +9292,15 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
8693 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9292 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8694 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9293 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8695 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9294 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8696 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9295 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8697 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9296 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8698 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9297 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8699 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 9298 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8700 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9299 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8701 { } /* end */ 9300 { } /* end */
8702}; 9301};
8703 9302
8704static struct snd_kcontrol_new alc883_targa_mixer[] = { 9303static const struct snd_kcontrol_new alc883_targa_mixer[] = {
8705 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9304 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8706 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9305 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8707 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9306 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -8717,12 +9316,12 @@ static struct snd_kcontrol_new alc883_targa_mixer[] = {
8717 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9316 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8718 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9317 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9318 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8720 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9319 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8721 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9320 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8722 { } /* end */ 9321 { } /* end */
8723}; 9322};
8724 9323
8725static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { 9324static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
8726 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9325 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8727 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9326 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8728 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9327 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -8730,36 +9329,36 @@ static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
8730 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9329 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8731 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9330 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9331 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8733 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9332 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8734 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9333 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8735 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9334 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8736 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 9335 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8737 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9336 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8738 { } /* end */ 9337 { } /* end */
8739}; 9338};
8740 9339
8741static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { 9340static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8742 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9341 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8743 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 9342 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8744 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9343 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8745 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 9344 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8746 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9345 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8747 { } /* end */ 9346 { } /* end */
8748}; 9347};
8749 9348
8750static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 9349static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8751 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9350 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8752 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9351 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8753 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9352 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8754 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 9353 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9354 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8756 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9355 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8757 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9356 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8758 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9357 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8759 { } /* end */ 9358 { } /* end */
8760}; 9359};
8761 9360
8762static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 9361static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8763 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9362 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8764 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 9363 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8765 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9364 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -8767,25 +9366,12 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8767 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9366 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8768 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9367 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8769 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9368 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8770 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9369 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8771 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9370 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8772 { } /* end */
8773};
8774
8775static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8776 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8777 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8778 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8779 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8780 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8781 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8782 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8783 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8784 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8785 { } /* end */ 9371 { } /* end */
8786}; 9372};
8787 9373
8788static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { 9374static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8789 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9375 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8790 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9376 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8791 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9377 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -8795,7 +9381,7 @@ static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8795 { } /* end */ 9381 { } /* end */
8796}; 9382};
8797 9383
8798static struct hda_verb alc883_medion_wim2160_verbs[] = { 9384static const struct hda_verb alc883_medion_wim2160_verbs[] = {
8799 /* Unmute front mixer */ 9385 /* Unmute front mixer */
8800 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9386 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8801 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9387 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -8819,21 +9405,23 @@ static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8819 9405
8820 spec->autocfg.hp_pins[0] = 0x1a; 9406 spec->autocfg.hp_pins[0] = 0x1a;
8821 spec->autocfg.speaker_pins[0] = 0x15; 9407 spec->autocfg.speaker_pins[0] = 0x15;
9408 spec->automute = 1;
9409 spec->automute_mode = ALC_AUTOMUTE_AMP;
8822} 9410}
8823 9411
8824static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 9412static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8825 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9413 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8826 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9414 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8827 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9415 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8828 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9416 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8829 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9417 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8830 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9418 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8831 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9419 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8832 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9420 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8833 { } /* end */ 9421 { } /* end */
8834}; 9422};
8835 9423
8836static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { 9424static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8837 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9425 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8838 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9426 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8839 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9427 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -8841,12 +9429,12 @@ static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8841 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9429 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8842 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9430 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8843 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9431 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8844 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9432 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8845 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9433 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8846 { } /* end */ 9434 { } /* end */
8847}; 9435};
8848 9436
8849static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { 9437static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8850 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9438 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8851 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9439 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8852 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 9440 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
@@ -8863,15 +9451,15 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8863 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9451 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8864 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9452 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8865 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8866 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9454 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8867 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9455 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8868 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9456 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8869 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 9457 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8870 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9458 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8871 { } /* end */ 9459 { } /* end */
8872}; 9460};
8873 9461
8874static struct snd_kcontrol_new alc889A_mb31_mixer[] = { 9462static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8875 /* Output mixers */ 9463 /* Output mixers */
8876 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 9464 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8877 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 9465 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
@@ -8887,8 +9475,8 @@ static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8887 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), 9475 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8888 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), 9476 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8889 /* Boost mixers */ 9477 /* Boost mixers */
8890 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 9478 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8891 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 9479 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8892 /* Input mixers */ 9480 /* Input mixers */
8893 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 9481 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8894 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 9482 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
@@ -8897,17 +9485,17 @@ static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8897 { } /* end */ 9485 { } /* end */
8898}; 9486};
8899 9487
8900static struct snd_kcontrol_new alc883_vaiott_mixer[] = { 9488static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8901 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9489 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8902 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9490 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8903 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9491 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8904 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9492 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8905 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 9493 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
8906 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9494 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8907 { } /* end */ 9495 { } /* end */
8908}; 9496};
8909 9497
8910static struct hda_bind_ctls alc883_bind_cap_vol = { 9498static const struct hda_bind_ctls alc883_bind_cap_vol = {
8911 .ops = &snd_hda_bind_vol, 9499 .ops = &snd_hda_bind_vol,
8912 .values = { 9500 .values = {
8913 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 9501 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
@@ -8916,7 +9504,7 @@ static struct hda_bind_ctls alc883_bind_cap_vol = {
8916 }, 9504 },
8917}; 9505};
8918 9506
8919static struct hda_bind_ctls alc883_bind_cap_switch = { 9507static const struct hda_bind_ctls alc883_bind_cap_switch = {
8920 .ops = &snd_hda_bind_sw, 9508 .ops = &snd_hda_bind_sw,
8921 .values = { 9509 .values = {
8922 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 9510 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
@@ -8925,19 +9513,19 @@ static struct hda_bind_ctls alc883_bind_cap_switch = {
8925 }, 9513 },
8926}; 9514};
8927 9515
8928static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { 9516static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8929 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9517 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8930 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9518 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8931 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9519 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8932 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9520 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8933 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9521 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8934 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8935 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9523 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8936 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9524 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8937 { } /* end */ 9525 { } /* end */
8938}; 9526};
8939 9527
8940static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { 9528static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8941 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), 9529 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8942 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), 9530 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8943 { 9531 {
@@ -8952,7 +9540,7 @@ static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8952 { } /* end */ 9540 { } /* end */
8953}; 9541};
8954 9542
8955static struct snd_kcontrol_new alc883_chmode_mixer[] = { 9543static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
8956 { 9544 {
8957 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9545 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8958 .name = "Channel Mode", 9546 .name = "Channel Mode",
@@ -8971,19 +9559,11 @@ static void alc883_mitac_setup(struct hda_codec *codec)
8971 spec->autocfg.hp_pins[0] = 0x15; 9559 spec->autocfg.hp_pins[0] = 0x15;
8972 spec->autocfg.speaker_pins[0] = 0x14; 9560 spec->autocfg.speaker_pins[0] = 0x14;
8973 spec->autocfg.speaker_pins[1] = 0x17; 9561 spec->autocfg.speaker_pins[1] = 0x17;
9562 spec->automute = 1;
9563 spec->automute_mode = ALC_AUTOMUTE_AMP;
8974} 9564}
8975 9565
8976/* auto-toggle front mic */ 9566static const struct hda_verb alc883_mitac_verbs[] = {
8977/*
8978static void alc883_mitac_mic_automute(struct hda_codec *codec)
8979{
8980 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
8981
8982 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8983}
8984*/
8985
8986static struct hda_verb alc883_mitac_verbs[] = {
8987 /* HP */ 9567 /* HP */
8988 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9568 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8989 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9569 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -8998,7 +9578,7 @@ static struct hda_verb alc883_mitac_verbs[] = {
8998 { } /* end */ 9578 { } /* end */
8999}; 9579};
9000 9580
9001static struct hda_verb alc883_clevo_m540r_verbs[] = { 9581static const struct hda_verb alc883_clevo_m540r_verbs[] = {
9002 /* HP */ 9582 /* HP */
9003 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9583 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9004 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9584 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -9014,7 +9594,7 @@ static struct hda_verb alc883_clevo_m540r_verbs[] = {
9014 { } /* end */ 9594 { } /* end */
9015}; 9595};
9016 9596
9017static struct hda_verb alc883_clevo_m720_verbs[] = { 9597static const struct hda_verb alc883_clevo_m720_verbs[] = {
9018 /* HP */ 9598 /* HP */
9019 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9599 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9020 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9600 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -9029,7 +9609,7 @@ static struct hda_verb alc883_clevo_m720_verbs[] = {
9029 { } /* end */ 9609 { } /* end */
9030}; 9610};
9031 9611
9032static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { 9612static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9033 /* HP */ 9613 /* HP */
9034 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9614 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9035 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9615 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -9043,7 +9623,7 @@ static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9043 { } /* end */ 9623 { } /* end */
9044}; 9624};
9045 9625
9046static struct hda_verb alc883_targa_verbs[] = { 9626static const struct hda_verb alc883_targa_verbs[] = {
9047 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9627 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9048 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9628 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9049 9629
@@ -9072,14 +9652,14 @@ static struct hda_verb alc883_targa_verbs[] = {
9072 { } /* end */ 9652 { } /* end */
9073}; 9653};
9074 9654
9075static struct hda_verb alc883_lenovo_101e_verbs[] = { 9655static const struct hda_verb alc883_lenovo_101e_verbs[] = {
9076 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9656 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9077 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 9657 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9078 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 9658 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9079 { } /* end */ 9659 { } /* end */
9080}; 9660};
9081 9661
9082static struct hda_verb alc883_lenovo_nb0763_verbs[] = { 9662static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9083 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9663 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9084 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9664 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9085 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9665 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
@@ -9087,7 +9667,7 @@ static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9087 { } /* end */ 9667 { } /* end */
9088}; 9668};
9089 9669
9090static struct hda_verb alc888_lenovo_ms7195_verbs[] = { 9670static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9091 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9671 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9092 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9672 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9093 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9673 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -9096,7 +9676,7 @@ static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9096 { } /* end */ 9676 { } /* end */
9097}; 9677};
9098 9678
9099static struct hda_verb alc883_haier_w66_verbs[] = { 9679static const struct hda_verb alc883_haier_w66_verbs[] = {
9100 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9681 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9102 9682
@@ -9109,7 +9689,7 @@ static struct hda_verb alc883_haier_w66_verbs[] = {
9109 { } /* end */ 9689 { } /* end */
9110}; 9690};
9111 9691
9112static struct hda_verb alc888_lenovo_sky_verbs[] = { 9692static const struct hda_verb alc888_lenovo_sky_verbs[] = {
9113 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9693 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9694 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9115 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9695 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -9121,12 +9701,12 @@ static struct hda_verb alc888_lenovo_sky_verbs[] = {
9121 { } /* end */ 9701 { } /* end */
9122}; 9702};
9123 9703
9124static struct hda_verb alc888_6st_dell_verbs[] = { 9704static const struct hda_verb alc888_6st_dell_verbs[] = {
9125 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9705 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9126 { } 9706 { }
9127}; 9707};
9128 9708
9129static struct hda_verb alc883_vaiott_verbs[] = { 9709static const struct hda_verb alc883_vaiott_verbs[] = {
9130 /* HP */ 9710 /* HP */
9131 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9711 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9132 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9712 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -9145,9 +9725,11 @@ static void alc888_3st_hp_setup(struct hda_codec *codec)
9145 spec->autocfg.speaker_pins[0] = 0x14; 9725 spec->autocfg.speaker_pins[0] = 0x14;
9146 spec->autocfg.speaker_pins[1] = 0x16; 9726 spec->autocfg.speaker_pins[1] = 0x16;
9147 spec->autocfg.speaker_pins[2] = 0x18; 9727 spec->autocfg.speaker_pins[2] = 0x18;
9728 spec->automute = 1;
9729 spec->automute_mode = ALC_AUTOMUTE_AMP;
9148} 9730}
9149 9731
9150static struct hda_verb alc888_3st_hp_verbs[] = { 9732static const struct hda_verb alc888_3st_hp_verbs[] = {
9151 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 9733 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9152 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 9734 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9153 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 9735 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
@@ -9158,7 +9740,7 @@ static struct hda_verb alc888_3st_hp_verbs[] = {
9158/* 9740/*
9159 * 2ch mode 9741 * 2ch mode
9160 */ 9742 */
9161static struct hda_verb alc888_3st_hp_2ch_init[] = { 9743static const struct hda_verb alc888_3st_hp_2ch_init[] = {
9162 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9744 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9163 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9745 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9164 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 9746 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
@@ -9169,7 +9751,7 @@ static struct hda_verb alc888_3st_hp_2ch_init[] = {
9169/* 9751/*
9170 * 4ch mode 9752 * 4ch mode
9171 */ 9753 */
9172static struct hda_verb alc888_3st_hp_4ch_init[] = { 9754static const struct hda_verb alc888_3st_hp_4ch_init[] = {
9173 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9755 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9174 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9756 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9175 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9757 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -9181,7 +9763,7 @@ static struct hda_verb alc888_3st_hp_4ch_init[] = {
9181/* 9763/*
9182 * 6ch mode 9764 * 6ch mode
9183 */ 9765 */
9184static struct hda_verb alc888_3st_hp_6ch_init[] = { 9766static const struct hda_verb alc888_3st_hp_6ch_init[] = {
9185 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9767 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9186 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9768 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9187 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 9769 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
@@ -9191,85 +9773,52 @@ static struct hda_verb alc888_3st_hp_6ch_init[] = {
9191 { } /* end */ 9773 { } /* end */
9192}; 9774};
9193 9775
9194static struct hda_channel_mode alc888_3st_hp_modes[3] = { 9776static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
9195 { 2, alc888_3st_hp_2ch_init }, 9777 { 2, alc888_3st_hp_2ch_init },
9196 { 4, alc888_3st_hp_4ch_init }, 9778 { 4, alc888_3st_hp_4ch_init },
9197 { 6, alc888_3st_hp_6ch_init }, 9779 { 6, alc888_3st_hp_6ch_init },
9198}; 9780};
9199 9781
9200/* toggle front-jack and RCA according to the hp-jack state */ 9782static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
9201static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9202{
9203 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
9204
9205 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9206 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9207 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9208 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9209}
9210
9211/* toggle RCA according to the front-jack state */
9212static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9213{ 9783{
9214 unsigned int present = snd_hda_jack_detect(codec, 0x14); 9784 struct alc_spec *spec = codec->spec;
9215
9216 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9217 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9218}
9219 9785
9220static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, 9786 spec->autocfg.hp_pins[0] = 0x1b;
9221 unsigned int res) 9787 spec->autocfg.line_out_pins[0] = 0x14;
9222{ 9788 spec->autocfg.speaker_pins[0] = 0x15;
9223 if ((res >> 26) == ALC880_HP_EVENT) 9789 spec->automute = 1;
9224 alc888_lenovo_ms7195_front_automute(codec); 9790 spec->automute_mode = ALC_AUTOMUTE_AMP;
9225 if ((res >> 26) == ALC880_FRONT_EVENT)
9226 alc888_lenovo_ms7195_rca_automute(codec);
9227} 9791}
9228 9792
9229static struct hda_verb alc883_medion_md2_verbs[] = {
9230 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9231 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9232
9233 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9234
9235 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9236 { } /* end */
9237};
9238
9239/* toggle speaker-output according to the hp-jack state */ 9793/* toggle speaker-output according to the hp-jack state */
9240static void alc883_medion_md2_setup(struct hda_codec *codec) 9794static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9241{ 9795{
9242 struct alc_spec *spec = codec->spec; 9796 struct alc_spec *spec = codec->spec;
9243 9797
9244 spec->autocfg.hp_pins[0] = 0x14; 9798 spec->autocfg.hp_pins[0] = 0x14;
9245 spec->autocfg.speaker_pins[0] = 0x15; 9799 spec->autocfg.speaker_pins[0] = 0x15;
9800 spec->automute = 1;
9801 spec->automute_mode = ALC_AUTOMUTE_AMP;
9246} 9802}
9247 9803
9248/* toggle speaker-output according to the hp-jack state */ 9804/* toggle speaker-output according to the hp-jack state */
9249#define alc883_targa_init_hook alc882_targa_init_hook 9805#define alc883_targa_init_hook alc882_targa_init_hook
9250#define alc883_targa_unsol_event alc882_targa_unsol_event 9806#define alc883_targa_unsol_event alc882_targa_unsol_event
9251 9807
9252static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9253{
9254 unsigned int present;
9255
9256 present = snd_hda_jack_detect(codec, 0x18);
9257 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9258 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9259}
9260
9261static void alc883_clevo_m720_setup(struct hda_codec *codec) 9808static void alc883_clevo_m720_setup(struct hda_codec *codec)
9262{ 9809{
9263 struct alc_spec *spec = codec->spec; 9810 struct alc_spec *spec = codec->spec;
9264 9811
9265 spec->autocfg.hp_pins[0] = 0x15; 9812 spec->autocfg.hp_pins[0] = 0x15;
9266 spec->autocfg.speaker_pins[0] = 0x14; 9813 spec->autocfg.speaker_pins[0] = 0x14;
9814 spec->automute = 1;
9815 spec->automute_mode = ALC_AUTOMUTE_AMP;
9267} 9816}
9268 9817
9269static void alc883_clevo_m720_init_hook(struct hda_codec *codec) 9818static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9270{ 9819{
9271 alc_automute_amp(codec); 9820 alc_hp_automute(codec);
9272 alc883_clevo_m720_mic_automute(codec); 9821 alc88x_simple_mic_automute(codec);
9273} 9822}
9274 9823
9275static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, 9824static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
@@ -9277,10 +9826,10 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9277{ 9826{
9278 switch (res >> 26) { 9827 switch (res >> 26) {
9279 case ALC880_MIC_EVENT: 9828 case ALC880_MIC_EVENT:
9280 alc883_clevo_m720_mic_automute(codec); 9829 alc88x_simple_mic_automute(codec);
9281 break; 9830 break;
9282 default: 9831 default:
9283 alc_automute_amp_unsol_event(codec, res); 9832 alc_sku_unsol_event(codec, res);
9284 break; 9833 break;
9285 } 9834 }
9286} 9835}
@@ -9292,6 +9841,8 @@ static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9292 9841
9293 spec->autocfg.hp_pins[0] = 0x14; 9842 spec->autocfg.hp_pins[0] = 0x14;
9294 spec->autocfg.speaker_pins[0] = 0x15; 9843 spec->autocfg.speaker_pins[0] = 0x15;
9844 spec->automute = 1;
9845 spec->automute_mode = ALC_AUTOMUTE_AMP;
9295} 9846}
9296 9847
9297static void alc883_haier_w66_setup(struct hda_codec *codec) 9848static void alc883_haier_w66_setup(struct hda_codec *codec)
@@ -9300,33 +9851,21 @@ static void alc883_haier_w66_setup(struct hda_codec *codec)
9300 9851
9301 spec->autocfg.hp_pins[0] = 0x1b; 9852 spec->autocfg.hp_pins[0] = 0x1b;
9302 spec->autocfg.speaker_pins[0] = 0x14; 9853 spec->autocfg.speaker_pins[0] = 0x14;
9854 spec->automute = 1;
9855 spec->automute_mode = ALC_AUTOMUTE_AMP;
9303} 9856}
9304 9857
9305static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 9858static void alc883_lenovo_101e_setup(struct hda_codec *codec)
9306{ 9859{
9307 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0; 9860 struct alc_spec *spec = codec->spec;
9308
9309 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9310 HDA_AMP_MUTE, bits);
9311}
9312
9313static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9314{
9315 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
9316
9317 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9318 HDA_AMP_MUTE, bits);
9319 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9320 HDA_AMP_MUTE, bits);
9321}
9322 9861
9323static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, 9862 spec->autocfg.hp_pins[0] = 0x1b;
9324 unsigned int res) 9863 spec->autocfg.line_out_pins[0] = 0x14;
9325{ 9864 spec->autocfg.speaker_pins[0] = 0x15;
9326 if ((res >> 26) == ALC880_HP_EVENT) 9865 spec->automute = 1;
9327 alc883_lenovo_101e_all_automute(codec); 9866 spec->detect_line = 1;
9328 if ((res >> 26) == ALC880_FRONT_EVENT) 9867 spec->automute_lines = 1;
9329 alc883_lenovo_101e_ispeaker_automute(codec); 9868 spec->automute_mode = ALC_AUTOMUTE_AMP;
9330} 9869}
9331 9870
9332/* toggle speaker-output according to the hp-jack state */ 9871/* toggle speaker-output according to the hp-jack state */
@@ -9337,9 +9876,11 @@ static void alc883_acer_aspire_setup(struct hda_codec *codec)
9337 spec->autocfg.hp_pins[0] = 0x14; 9876 spec->autocfg.hp_pins[0] = 0x14;
9338 spec->autocfg.speaker_pins[0] = 0x15; 9877 spec->autocfg.speaker_pins[0] = 0x15;
9339 spec->autocfg.speaker_pins[1] = 0x16; 9878 spec->autocfg.speaker_pins[1] = 0x16;
9879 spec->automute = 1;
9880 spec->automute_mode = ALC_AUTOMUTE_AMP;
9340} 9881}
9341 9882
9342static struct hda_verb alc883_acer_eapd_verbs[] = { 9883static const struct hda_verb alc883_acer_eapd_verbs[] = {
9343 /* HP Pin: output 0 (0x0c) */ 9884 /* HP Pin: output 0 (0x0c) */
9344 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9885 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9345 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9886 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -9357,13 +9898,6 @@ static struct hda_verb alc883_acer_eapd_verbs[] = {
9357 { } 9898 { }
9358}; 9899};
9359 9900
9360static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9361 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9362 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9363 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9364 { } /* end */
9365};
9366
9367static void alc888_6st_dell_setup(struct hda_codec *codec) 9901static void alc888_6st_dell_setup(struct hda_codec *codec)
9368{ 9902{
9369 struct alc_spec *spec = codec->spec; 9903 struct alc_spec *spec = codec->spec;
@@ -9373,6 +9907,8 @@ static void alc888_6st_dell_setup(struct hda_codec *codec)
9373 spec->autocfg.speaker_pins[1] = 0x15; 9907 spec->autocfg.speaker_pins[1] = 0x15;
9374 spec->autocfg.speaker_pins[2] = 0x16; 9908 spec->autocfg.speaker_pins[2] = 0x16;
9375 spec->autocfg.speaker_pins[3] = 0x17; 9909 spec->autocfg.speaker_pins[3] = 0x17;
9910 spec->automute = 1;
9911 spec->automute_mode = ALC_AUTOMUTE_AMP;
9376} 9912}
9377 9913
9378static void alc888_lenovo_sky_setup(struct hda_codec *codec) 9914static void alc888_lenovo_sky_setup(struct hda_codec *codec)
@@ -9385,6 +9921,8 @@ static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9385 spec->autocfg.speaker_pins[2] = 0x16; 9921 spec->autocfg.speaker_pins[2] = 0x16;
9386 spec->autocfg.speaker_pins[3] = 0x17; 9922 spec->autocfg.speaker_pins[3] = 0x17;
9387 spec->autocfg.speaker_pins[4] = 0x1a; 9923 spec->autocfg.speaker_pins[4] = 0x1a;
9924 spec->automute = 1;
9925 spec->automute_mode = ALC_AUTOMUTE_AMP;
9388} 9926}
9389 9927
9390static void alc883_vaiott_setup(struct hda_codec *codec) 9928static void alc883_vaiott_setup(struct hda_codec *codec)
@@ -9394,9 +9932,11 @@ static void alc883_vaiott_setup(struct hda_codec *codec)
9394 spec->autocfg.hp_pins[0] = 0x15; 9932 spec->autocfg.hp_pins[0] = 0x15;
9395 spec->autocfg.speaker_pins[0] = 0x14; 9933 spec->autocfg.speaker_pins[0] = 0x14;
9396 spec->autocfg.speaker_pins[1] = 0x17; 9934 spec->autocfg.speaker_pins[1] = 0x17;
9935 spec->automute = 1;
9936 spec->automute_mode = ALC_AUTOMUTE_AMP;
9397} 9937}
9398 9938
9399static struct hda_verb alc888_asus_m90v_verbs[] = { 9939static const struct hda_verb alc888_asus_m90v_verbs[] = {
9400 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9940 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9401 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9941 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9402 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9942 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -9419,9 +9959,11 @@ static void alc883_mode2_setup(struct hda_codec *codec)
9419 spec->ext_mic.mux_idx = 0; 9959 spec->ext_mic.mux_idx = 0;
9420 spec->int_mic.mux_idx = 1; 9960 spec->int_mic.mux_idx = 1;
9421 spec->auto_mic = 1; 9961 spec->auto_mic = 1;
9962 spec->automute = 1;
9963 spec->automute_mode = ALC_AUTOMUTE_AMP;
9422} 9964}
9423 9965
9424static struct hda_verb alc888_asus_eee1601_verbs[] = { 9966static const struct hda_verb alc888_asus_eee1601_verbs[] = {
9425 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9967 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9426 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9968 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9427 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9969 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -9440,10 +9982,10 @@ static void alc883_eee1601_inithook(struct hda_codec *codec)
9440 9982
9441 spec->autocfg.hp_pins[0] = 0x14; 9983 spec->autocfg.hp_pins[0] = 0x14;
9442 spec->autocfg.speaker_pins[0] = 0x1b; 9984 spec->autocfg.speaker_pins[0] = 0x1b;
9443 alc_automute_pin(codec); 9985 alc_hp_automute(codec);
9444} 9986}
9445 9987
9446static struct hda_verb alc889A_mb31_verbs[] = { 9988static const struct hda_verb alc889A_mb31_verbs[] = {
9447 /* Init rear pin (used as headphone output) */ 9989 /* Init rear pin (used as headphone output) */
9448 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ 9990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9449 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ 9991 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
@@ -9489,18 +10031,18 @@ static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9489#define alc882_pcm_digital_playback alc880_pcm_digital_playback 10031#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9490#define alc882_pcm_digital_capture alc880_pcm_digital_capture 10032#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9491 10033
9492static hda_nid_t alc883_slave_dig_outs[] = { 10034static const hda_nid_t alc883_slave_dig_outs[] = {
9493 ALC1200_DIGOUT_NID, 0, 10035 ALC1200_DIGOUT_NID, 0,
9494}; 10036};
9495 10037
9496static hda_nid_t alc1200_slave_dig_outs[] = { 10038static const hda_nid_t alc1200_slave_dig_outs[] = {
9497 ALC883_DIGOUT_NID, 0, 10039 ALC883_DIGOUT_NID, 0,
9498}; 10040};
9499 10041
9500/* 10042/*
9501 * configuration and preset 10043 * configuration and preset
9502 */ 10044 */
9503static const char *alc882_models[ALC882_MODEL_LAST] = { 10045static const char * const alc882_models[ALC882_MODEL_LAST] = {
9504 [ALC882_3ST_DIG] = "3stack-dig", 10046 [ALC882_3ST_DIG] = "3stack-dig",
9505 [ALC882_6ST_DIG] = "6stack-dig", 10047 [ALC882_6ST_DIG] = "6stack-dig",
9506 [ALC882_ARIMA] = "arima", 10048 [ALC882_ARIMA] = "arima",
@@ -9529,7 +10071,6 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
9529 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", 10071 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9530 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", 10072 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9531 [ALC883_MEDION] = "medion", 10073 [ALC883_MEDION] = "medion",
9532 [ALC883_MEDION_MD2] = "medion-md2",
9533 [ALC883_MEDION_WIM2160] = "medion-wim2160", 10074 [ALC883_MEDION_WIM2160] = "medion-wim2160",
9534 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 10075 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9535 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 10076 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
@@ -9553,7 +10094,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
9553 [ALC882_AUTO] = "auto", 10094 [ALC882_AUTO] = "auto",
9554}; 10095};
9555 10096
9556static struct snd_pci_quirk alc882_cfg_tbl[] = { 10097static const struct snd_pci_quirk alc882_cfg_tbl[] = {
9557 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 10098 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9558 10099
9559 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 10100 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
@@ -9585,7 +10126,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
9585 10126
9586 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 10127 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9587 10128
9588 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 10129 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
9589 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 10130 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9590 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 10131 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9591 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 10132 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
@@ -9664,7 +10205,6 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
9664 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 10205 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9665 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 10206 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9666 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), 10207 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9667 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
9668 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), 10208 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9669 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 10209 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9670 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 10210 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
@@ -9681,7 +10221,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
9681}; 10221};
9682 10222
9683/* codec SSID table for Intel Mac */ 10223/* codec SSID table for Intel Mac */
9684static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { 10224static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9685 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), 10225 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9686 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), 10226 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9687 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), 10227 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
@@ -9708,7 +10248,7 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9708 {} /* terminator */ 10248 {} /* terminator */
9709}; 10249};
9710 10250
9711static struct alc_config_preset alc882_presets[] = { 10251static const struct alc_config_preset alc882_presets[] = {
9712 [ALC882_3ST_DIG] = { 10252 [ALC882_3ST_DIG] = {
9713 .mixers = { alc882_base_mixer }, 10253 .mixers = { alc882_base_mixer },
9714 .init_verbs = { alc882_base_init_verbs, 10254 .init_verbs = { alc882_base_init_verbs,
@@ -9764,9 +10304,9 @@ static struct alc_config_preset alc882_presets[] = {
9764 .channel_mode = alc885_mba21_ch_modes, 10304 .channel_mode = alc885_mba21_ch_modes,
9765 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 10305 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9766 .input_mux = &alc882_capture_source, 10306 .input_mux = &alc882_capture_source,
9767 .unsol_event = alc_automute_amp_unsol_event, 10307 .unsol_event = alc_sku_unsol_event,
9768 .setup = alc885_mba21_setup, 10308 .setup = alc885_mba21_setup,
9769 .init_hook = alc_automute_amp, 10309 .init_hook = alc_hp_automute,
9770 }, 10310 },
9771 [ALC885_MBP3] = { 10311 [ALC885_MBP3] = {
9772 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 10312 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
@@ -9780,9 +10320,9 @@ static struct alc_config_preset alc882_presets[] = {
9780 .input_mux = &alc882_capture_source, 10320 .input_mux = &alc882_capture_source,
9781 .dig_out_nid = ALC882_DIGOUT_NID, 10321 .dig_out_nid = ALC882_DIGOUT_NID,
9782 .dig_in_nid = ALC882_DIGIN_NID, 10322 .dig_in_nid = ALC882_DIGIN_NID,
9783 .unsol_event = alc_automute_amp_unsol_event, 10323 .unsol_event = alc_sku_unsol_event,
9784 .setup = alc885_mbp3_setup, 10324 .setup = alc885_mbp3_setup,
9785 .init_hook = alc_automute_amp, 10325 .init_hook = alc_hp_automute,
9786 }, 10326 },
9787 [ALC885_MB5] = { 10327 [ALC885_MB5] = {
9788 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, 10328 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
@@ -9795,9 +10335,9 @@ static struct alc_config_preset alc882_presets[] = {
9795 .input_mux = &mb5_capture_source, 10335 .input_mux = &mb5_capture_source,
9796 .dig_out_nid = ALC882_DIGOUT_NID, 10336 .dig_out_nid = ALC882_DIGOUT_NID,
9797 .dig_in_nid = ALC882_DIGIN_NID, 10337 .dig_in_nid = ALC882_DIGIN_NID,
9798 .unsol_event = alc_automute_amp_unsol_event, 10338 .unsol_event = alc_sku_unsol_event,
9799 .setup = alc885_mb5_setup, 10339 .setup = alc885_mb5_setup,
9800 .init_hook = alc_automute_amp, 10340 .init_hook = alc_hp_automute,
9801 }, 10341 },
9802 [ALC885_MACMINI3] = { 10342 [ALC885_MACMINI3] = {
9803 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer }, 10343 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
@@ -9810,9 +10350,9 @@ static struct alc_config_preset alc882_presets[] = {
9810 .input_mux = &macmini3_capture_source, 10350 .input_mux = &macmini3_capture_source,
9811 .dig_out_nid = ALC882_DIGOUT_NID, 10351 .dig_out_nid = ALC882_DIGOUT_NID,
9812 .dig_in_nid = ALC882_DIGIN_NID, 10352 .dig_in_nid = ALC882_DIGIN_NID,
9813 .unsol_event = alc_automute_amp_unsol_event, 10353 .unsol_event = alc_sku_unsol_event,
9814 .setup = alc885_macmini3_setup, 10354 .setup = alc885_macmini3_setup,
9815 .init_hook = alc_automute_amp, 10355 .init_hook = alc_hp_automute,
9816 }, 10356 },
9817 [ALC885_MACPRO] = { 10357 [ALC885_MACPRO] = {
9818 .mixers = { alc882_macpro_mixer }, 10358 .mixers = { alc882_macpro_mixer },
@@ -9836,7 +10376,7 @@ static struct alc_config_preset alc882_presets[] = {
9836 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 10376 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9837 .channel_mode = alc882_ch_modes, 10377 .channel_mode = alc882_ch_modes,
9838 .input_mux = &alc882_capture_source, 10378 .input_mux = &alc882_capture_source,
9839 .unsol_event = alc_automute_amp_unsol_event, 10379 .unsol_event = alc_sku_unsol_event,
9840 .setup = alc885_imac24_setup, 10380 .setup = alc885_imac24_setup,
9841 .init_hook = alc885_imac24_init_hook, 10381 .init_hook = alc885_imac24_init_hook,
9842 }, 10382 },
@@ -9851,9 +10391,9 @@ static struct alc_config_preset alc882_presets[] = {
9851 .input_mux = &alc889A_imac91_capture_source, 10391 .input_mux = &alc889A_imac91_capture_source,
9852 .dig_out_nid = ALC882_DIGOUT_NID, 10392 .dig_out_nid = ALC882_DIGOUT_NID,
9853 .dig_in_nid = ALC882_DIGIN_NID, 10393 .dig_in_nid = ALC882_DIGIN_NID,
9854 .unsol_event = alc_automute_amp_unsol_event, 10394 .unsol_event = alc_sku_unsol_event,
9855 .setup = alc885_imac91_setup, 10395 .setup = alc885_imac91_setup,
9856 .init_hook = alc_automute_amp, 10396 .init_hook = alc_hp_automute,
9857 }, 10397 },
9858 [ALC882_TARGA] = { 10398 [ALC882_TARGA] = {
9859 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 10399 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
@@ -9869,7 +10409,7 @@ static struct alc_config_preset alc882_presets[] = {
9869 .channel_mode = alc882_3ST_6ch_modes, 10409 .channel_mode = alc882_3ST_6ch_modes,
9870 .need_dac_fix = 1, 10410 .need_dac_fix = 1,
9871 .input_mux = &alc882_capture_source, 10411 .input_mux = &alc882_capture_source,
9872 .unsol_event = alc882_targa_unsol_event, 10412 .unsol_event = alc_sku_unsol_event,
9873 .setup = alc882_targa_setup, 10413 .setup = alc882_targa_setup,
9874 .init_hook = alc882_targa_automute, 10414 .init_hook = alc882_targa_automute,
9875 }, 10415 },
@@ -9963,8 +10503,8 @@ static struct alc_config_preset alc882_presets[] = {
9963 .capsrc_nids = alc889_capsrc_nids, 10503 .capsrc_nids = alc889_capsrc_nids,
9964 .input_mux = &alc889_capture_source, 10504 .input_mux = &alc889_capture_source,
9965 .setup = alc889_automute_setup, 10505 .setup = alc889_automute_setup,
9966 .init_hook = alc_automute_amp, 10506 .init_hook = alc_hp_automute,
9967 .unsol_event = alc_automute_amp_unsol_event, 10507 .unsol_event = alc_sku_unsol_event,
9968 .need_dac_fix = 1, 10508 .need_dac_fix = 1,
9969 }, 10509 },
9970 [ALC889_INTEL] = { 10510 [ALC889_INTEL] = {
@@ -9984,7 +10524,7 @@ static struct alc_config_preset alc882_presets[] = {
9984 .input_mux = &alc889_capture_source, 10524 .input_mux = &alc889_capture_source,
9985 .setup = alc889_automute_setup, 10525 .setup = alc889_automute_setup,
9986 .init_hook = alc889_intel_init_hook, 10526 .init_hook = alc889_intel_init_hook,
9987 .unsol_event = alc_automute_amp_unsol_event, 10527 .unsol_event = alc_sku_unsol_event,
9988 .need_dac_fix = 1, 10528 .need_dac_fix = 1,
9989 }, 10529 },
9990 [ALC883_6ST_DIG] = { 10530 [ALC883_6ST_DIG] = {
@@ -10073,12 +10613,12 @@ static struct alc_config_preset alc882_presets[] = {
10073 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10613 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10074 .channel_mode = alc883_3ST_2ch_modes, 10614 .channel_mode = alc883_3ST_2ch_modes,
10075 .input_mux = &alc883_capture_source, 10615 .input_mux = &alc883_capture_source,
10076 .unsol_event = alc_automute_amp_unsol_event, 10616 .unsol_event = alc_sku_unsol_event,
10077 .setup = alc883_acer_aspire_setup, 10617 .setup = alc883_acer_aspire_setup,
10078 .init_hook = alc_automute_amp, 10618 .init_hook = alc_hp_automute,
10079 }, 10619 },
10080 [ALC888_ACER_ASPIRE_4930G] = { 10620 [ALC888_ACER_ASPIRE_4930G] = {
10081 .mixers = { alc888_base_mixer, 10621 .mixers = { alc888_acer_aspire_4930g_mixer,
10082 alc883_chmode_mixer }, 10622 alc883_chmode_mixer },
10083 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10623 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10084 alc888_acer_aspire_4930g_verbs }, 10624 alc888_acer_aspire_4930g_verbs },
@@ -10095,9 +10635,9 @@ static struct alc_config_preset alc882_presets[] = {
10095 .num_mux_defs = 10635 .num_mux_defs =
10096 ARRAY_SIZE(alc888_2_capture_sources), 10636 ARRAY_SIZE(alc888_2_capture_sources),
10097 .input_mux = alc888_2_capture_sources, 10637 .input_mux = alc888_2_capture_sources,
10098 .unsol_event = alc_automute_amp_unsol_event, 10638 .unsol_event = alc_sku_unsol_event,
10099 .setup = alc888_acer_aspire_4930g_setup, 10639 .setup = alc888_acer_aspire_4930g_setup,
10100 .init_hook = alc_automute_amp, 10640 .init_hook = alc_hp_automute,
10101 }, 10641 },
10102 [ALC888_ACER_ASPIRE_6530G] = { 10642 [ALC888_ACER_ASPIRE_6530G] = {
10103 .mixers = { alc888_acer_aspire_6530_mixer }, 10643 .mixers = { alc888_acer_aspire_6530_mixer },
@@ -10114,9 +10654,9 @@ static struct alc_config_preset alc882_presets[] = {
10114 .num_mux_defs = 10654 .num_mux_defs =
10115 ARRAY_SIZE(alc888_2_capture_sources), 10655 ARRAY_SIZE(alc888_2_capture_sources),
10116 .input_mux = alc888_acer_aspire_6530_sources, 10656 .input_mux = alc888_acer_aspire_6530_sources,
10117 .unsol_event = alc_automute_amp_unsol_event, 10657 .unsol_event = alc_sku_unsol_event,
10118 .setup = alc888_acer_aspire_6530g_setup, 10658 .setup = alc888_acer_aspire_6530g_setup,
10119 .init_hook = alc_automute_amp, 10659 .init_hook = alc_hp_automute,
10120 }, 10660 },
10121 [ALC888_ACER_ASPIRE_8930G] = { 10661 [ALC888_ACER_ASPIRE_8930G] = {
10122 .mixers = { alc889_acer_aspire_8930g_mixer, 10662 .mixers = { alc889_acer_aspire_8930g_mixer,
@@ -10137,9 +10677,9 @@ static struct alc_config_preset alc882_presets[] = {
10137 .num_mux_defs = 10677 .num_mux_defs =
10138 ARRAY_SIZE(alc889_capture_sources), 10678 ARRAY_SIZE(alc889_capture_sources),
10139 .input_mux = alc889_capture_sources, 10679 .input_mux = alc889_capture_sources,
10140 .unsol_event = alc_automute_amp_unsol_event, 10680 .unsol_event = alc_sku_unsol_event,
10141 .setup = alc889_acer_aspire_8930g_setup, 10681 .setup = alc889_acer_aspire_8930g_setup,
10142 .init_hook = alc_automute_amp, 10682 .init_hook = alc_hp_automute,
10143#ifdef CONFIG_SND_HDA_POWER_SAVE 10683#ifdef CONFIG_SND_HDA_POWER_SAVE
10144 .power_hook = alc_power_eapd, 10684 .power_hook = alc_power_eapd,
10145#endif 10685#endif
@@ -10160,9 +10700,9 @@ static struct alc_config_preset alc882_presets[] = {
10160 .need_dac_fix = 1, 10700 .need_dac_fix = 1,
10161 .const_channel_count = 6, 10701 .const_channel_count = 6,
10162 .input_mux = &alc883_capture_source, 10702 .input_mux = &alc883_capture_source,
10163 .unsol_event = alc_automute_amp_unsol_event, 10703 .unsol_event = alc_sku_unsol_event,
10164 .setup = alc888_acer_aspire_6530g_setup, 10704 .setup = alc888_acer_aspire_7730g_setup,
10165 .init_hook = alc_automute_amp, 10705 .init_hook = alc_hp_automute,
10166 }, 10706 },
10167 [ALC883_MEDION] = { 10707 [ALC883_MEDION] = {
10168 .mixers = { alc883_fivestack_mixer, 10708 .mixers = { alc883_fivestack_mixer,
@@ -10178,19 +10718,6 @@ static struct alc_config_preset alc882_presets[] = {
10178 .channel_mode = alc883_sixstack_modes, 10718 .channel_mode = alc883_sixstack_modes,
10179 .input_mux = &alc883_capture_source, 10719 .input_mux = &alc883_capture_source,
10180 }, 10720 },
10181 [ALC883_MEDION_MD2] = {
10182 .mixers = { alc883_medion_md2_mixer},
10183 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
10184 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10185 .dac_nids = alc883_dac_nids,
10186 .dig_out_nid = ALC883_DIGOUT_NID,
10187 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10188 .channel_mode = alc883_3ST_2ch_modes,
10189 .input_mux = &alc883_capture_source,
10190 .unsol_event = alc_automute_amp_unsol_event,
10191 .setup = alc883_medion_md2_setup,
10192 .init_hook = alc_automute_amp,
10193 },
10194 [ALC883_MEDION_WIM2160] = { 10721 [ALC883_MEDION_WIM2160] = {
10195 .mixers = { alc883_medion_wim2160_mixer }, 10722 .mixers = { alc883_medion_wim2160_mixer },
10196 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, 10723 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
@@ -10202,9 +10729,9 @@ static struct alc_config_preset alc882_presets[] = {
10202 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10729 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10203 .channel_mode = alc883_3ST_2ch_modes, 10730 .channel_mode = alc883_3ST_2ch_modes,
10204 .input_mux = &alc883_capture_source, 10731 .input_mux = &alc883_capture_source,
10205 .unsol_event = alc_automute_amp_unsol_event, 10732 .unsol_event = alc_sku_unsol_event,
10206 .setup = alc883_medion_wim2160_setup, 10733 .setup = alc883_medion_wim2160_setup,
10207 .init_hook = alc_automute_amp, 10734 .init_hook = alc_hp_automute,
10208 }, 10735 },
10209 [ALC883_LAPTOP_EAPD] = { 10736 [ALC883_LAPTOP_EAPD] = {
10210 .mixers = { alc883_base_mixer }, 10737 .mixers = { alc883_base_mixer },
@@ -10254,8 +10781,9 @@ static struct alc_config_preset alc882_presets[] = {
10254 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10781 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10255 .channel_mode = alc883_3ST_2ch_modes, 10782 .channel_mode = alc883_3ST_2ch_modes,
10256 .input_mux = &alc883_lenovo_101e_capture_source, 10783 .input_mux = &alc883_lenovo_101e_capture_source,
10257 .unsol_event = alc883_lenovo_101e_unsol_event, 10784 .setup = alc883_lenovo_101e_setup,
10258 .init_hook = alc883_lenovo_101e_all_automute, 10785 .unsol_event = alc_sku_unsol_event,
10786 .init_hook = alc_inithook,
10259 }, 10787 },
10260 [ALC883_LENOVO_NB0763] = { 10788 [ALC883_LENOVO_NB0763] = {
10261 .mixers = { alc883_lenovo_nb0763_mixer }, 10789 .mixers = { alc883_lenovo_nb0763_mixer },
@@ -10266,9 +10794,9 @@ static struct alc_config_preset alc882_presets[] = {
10266 .channel_mode = alc883_3ST_2ch_modes, 10794 .channel_mode = alc883_3ST_2ch_modes,
10267 .need_dac_fix = 1, 10795 .need_dac_fix = 1,
10268 .input_mux = &alc883_lenovo_nb0763_capture_source, 10796 .input_mux = &alc883_lenovo_nb0763_capture_source,
10269 .unsol_event = alc_automute_amp_unsol_event, 10797 .unsol_event = alc_sku_unsol_event,
10270 .setup = alc883_medion_md2_setup, 10798 .setup = alc883_lenovo_nb0763_setup,
10271 .init_hook = alc_automute_amp, 10799 .init_hook = alc_hp_automute,
10272 }, 10800 },
10273 [ALC888_LENOVO_MS7195_DIG] = { 10801 [ALC888_LENOVO_MS7195_DIG] = {
10274 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10802 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -10280,8 +10808,9 @@ static struct alc_config_preset alc882_presets[] = {
10280 .channel_mode = alc883_3ST_6ch_modes, 10808 .channel_mode = alc883_3ST_6ch_modes,
10281 .need_dac_fix = 1, 10809 .need_dac_fix = 1,
10282 .input_mux = &alc883_capture_source, 10810 .input_mux = &alc883_capture_source,
10283 .unsol_event = alc883_lenovo_ms7195_unsol_event, 10811 .unsol_event = alc_sku_unsol_event,
10284 .init_hook = alc888_lenovo_ms7195_front_automute, 10812 .setup = alc888_lenovo_ms7195_setup,
10813 .init_hook = alc_inithook,
10285 }, 10814 },
10286 [ALC883_HAIER_W66] = { 10815 [ALC883_HAIER_W66] = {
10287 .mixers = { alc883_targa_2ch_mixer}, 10816 .mixers = { alc883_targa_2ch_mixer},
@@ -10292,9 +10821,9 @@ static struct alc_config_preset alc882_presets[] = {
10292 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10821 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10293 .channel_mode = alc883_3ST_2ch_modes, 10822 .channel_mode = alc883_3ST_2ch_modes,
10294 .input_mux = &alc883_capture_source, 10823 .input_mux = &alc883_capture_source,
10295 .unsol_event = alc_automute_amp_unsol_event, 10824 .unsol_event = alc_sku_unsol_event,
10296 .setup = alc883_haier_w66_setup, 10825 .setup = alc883_haier_w66_setup,
10297 .init_hook = alc_automute_amp, 10826 .init_hook = alc_hp_automute,
10298 }, 10827 },
10299 [ALC888_3ST_HP] = { 10828 [ALC888_3ST_HP] = {
10300 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10829 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -10305,9 +10834,9 @@ static struct alc_config_preset alc882_presets[] = {
10305 .channel_mode = alc888_3st_hp_modes, 10834 .channel_mode = alc888_3st_hp_modes,
10306 .need_dac_fix = 1, 10835 .need_dac_fix = 1,
10307 .input_mux = &alc883_capture_source, 10836 .input_mux = &alc883_capture_source,
10308 .unsol_event = alc_automute_amp_unsol_event, 10837 .unsol_event = alc_sku_unsol_event,
10309 .setup = alc888_3st_hp_setup, 10838 .setup = alc888_3st_hp_setup,
10310 .init_hook = alc_automute_amp, 10839 .init_hook = alc_hp_automute,
10311 }, 10840 },
10312 [ALC888_6ST_DELL] = { 10841 [ALC888_6ST_DELL] = {
10313 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10842 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
@@ -10319,9 +10848,9 @@ static struct alc_config_preset alc882_presets[] = {
10319 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10848 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10320 .channel_mode = alc883_sixstack_modes, 10849 .channel_mode = alc883_sixstack_modes,
10321 .input_mux = &alc883_capture_source, 10850 .input_mux = &alc883_capture_source,
10322 .unsol_event = alc_automute_amp_unsol_event, 10851 .unsol_event = alc_sku_unsol_event,
10323 .setup = alc888_6st_dell_setup, 10852 .setup = alc888_6st_dell_setup,
10324 .init_hook = alc_automute_amp, 10853 .init_hook = alc_hp_automute,
10325 }, 10854 },
10326 [ALC883_MITAC] = { 10855 [ALC883_MITAC] = {
10327 .mixers = { alc883_mitac_mixer }, 10856 .mixers = { alc883_mitac_mixer },
@@ -10331,9 +10860,9 @@ static struct alc_config_preset alc882_presets[] = {
10331 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10860 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10332 .channel_mode = alc883_3ST_2ch_modes, 10861 .channel_mode = alc883_3ST_2ch_modes,
10333 .input_mux = &alc883_capture_source, 10862 .input_mux = &alc883_capture_source,
10334 .unsol_event = alc_automute_amp_unsol_event, 10863 .unsol_event = alc_sku_unsol_event,
10335 .setup = alc883_mitac_setup, 10864 .setup = alc883_mitac_setup,
10336 .init_hook = alc_automute_amp, 10865 .init_hook = alc_hp_automute,
10337 }, 10866 },
10338 [ALC883_FUJITSU_PI2515] = { 10867 [ALC883_FUJITSU_PI2515] = {
10339 .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, 10868 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
@@ -10345,9 +10874,9 @@ static struct alc_config_preset alc882_presets[] = {
10345 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10874 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10346 .channel_mode = alc883_3ST_2ch_modes, 10875 .channel_mode = alc883_3ST_2ch_modes,
10347 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10876 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10348 .unsol_event = alc_automute_amp_unsol_event, 10877 .unsol_event = alc_sku_unsol_event,
10349 .setup = alc883_2ch_fujitsu_pi2515_setup, 10878 .setup = alc883_2ch_fujitsu_pi2515_setup,
10350 .init_hook = alc_automute_amp, 10879 .init_hook = alc_hp_automute,
10351 }, 10880 },
10352 [ALC888_FUJITSU_XA3530] = { 10881 [ALC888_FUJITSU_XA3530] = {
10353 .mixers = { alc888_base_mixer, alc883_chmode_mixer }, 10882 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
@@ -10364,9 +10893,9 @@ static struct alc_config_preset alc882_presets[] = {
10364 .num_mux_defs = 10893 .num_mux_defs =
10365 ARRAY_SIZE(alc888_2_capture_sources), 10894 ARRAY_SIZE(alc888_2_capture_sources),
10366 .input_mux = alc888_2_capture_sources, 10895 .input_mux = alc888_2_capture_sources,
10367 .unsol_event = alc_automute_amp_unsol_event, 10896 .unsol_event = alc_sku_unsol_event,
10368 .setup = alc888_fujitsu_xa3530_setup, 10897 .setup = alc888_fujitsu_xa3530_setup,
10369 .init_hook = alc_automute_amp, 10898 .init_hook = alc_hp_automute,
10370 }, 10899 },
10371 [ALC888_LENOVO_SKY] = { 10900 [ALC888_LENOVO_SKY] = {
10372 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 10901 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
@@ -10378,9 +10907,9 @@ static struct alc_config_preset alc882_presets[] = {
10378 .channel_mode = alc883_sixstack_modes, 10907 .channel_mode = alc883_sixstack_modes,
10379 .need_dac_fix = 1, 10908 .need_dac_fix = 1,
10380 .input_mux = &alc883_lenovo_sky_capture_source, 10909 .input_mux = &alc883_lenovo_sky_capture_source,
10381 .unsol_event = alc_automute_amp_unsol_event, 10910 .unsol_event = alc_sku_unsol_event,
10382 .setup = alc888_lenovo_sky_setup, 10911 .setup = alc888_lenovo_sky_setup,
10383 .init_hook = alc_automute_amp, 10912 .init_hook = alc_hp_automute,
10384 }, 10913 },
10385 [ALC888_ASUS_M90V] = { 10914 [ALC888_ASUS_M90V] = {
10386 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10915 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -10448,9 +10977,9 @@ static struct alc_config_preset alc882_presets[] = {
10448 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10977 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10449 .channel_mode = alc883_3ST_2ch_modes, 10978 .channel_mode = alc883_3ST_2ch_modes,
10450 .input_mux = &alc883_capture_source, 10979 .input_mux = &alc883_capture_source,
10451 .unsol_event = alc_automute_amp_unsol_event, 10980 .unsol_event = alc_sku_unsol_event,
10452 .setup = alc883_vaiott_setup, 10981 .setup = alc883_vaiott_setup,
10453 .init_hook = alc_automute_amp, 10982 .init_hook = alc_hp_automute,
10454 }, 10983 },
10455}; 10984};
10456 10985
@@ -10460,33 +10989,47 @@ static struct alc_config_preset alc882_presets[] = {
10460 */ 10989 */
10461enum { 10990enum {
10462 PINFIX_ABIT_AW9D_MAX, 10991 PINFIX_ABIT_AW9D_MAX,
10992 PINFIX_LENOVO_Y530,
10463 PINFIX_PB_M5210, 10993 PINFIX_PB_M5210,
10464}; 10994 PINFIX_ACER_ASPIRE_7736,
10465
10466static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
10467 { 0x15, 0x01080104 }, /* side */
10468 { 0x16, 0x01011012 }, /* rear */
10469 { 0x17, 0x01016011 }, /* clfe */
10470 { }
10471};
10472
10473static const struct hda_verb pb_m5210_verbs[] = {
10474 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10475 {}
10476}; 10995};
10477 10996
10478static const struct alc_fixup alc882_fixups[] = { 10997static const struct alc_fixup alc882_fixups[] = {
10479 [PINFIX_ABIT_AW9D_MAX] = { 10998 [PINFIX_ABIT_AW9D_MAX] = {
10480 .pins = alc882_abit_aw9d_pinfix 10999 .type = ALC_FIXUP_PINS,
11000 .v.pins = (const struct alc_pincfg[]) {
11001 { 0x15, 0x01080104 }, /* side */
11002 { 0x16, 0x01011012 }, /* rear */
11003 { 0x17, 0x01016011 }, /* clfe */
11004 { }
11005 }
11006 },
11007 [PINFIX_LENOVO_Y530] = {
11008 .type = ALC_FIXUP_PINS,
11009 .v.pins = (const struct alc_pincfg[]) {
11010 { 0x15, 0x99130112 }, /* rear int speakers */
11011 { 0x16, 0x99130111 }, /* subwoofer */
11012 { }
11013 }
10481 }, 11014 },
10482 [PINFIX_PB_M5210] = { 11015 [PINFIX_PB_M5210] = {
10483 .verbs = pb_m5210_verbs 11016 .type = ALC_FIXUP_VERBS,
11017 .v.verbs = (const struct hda_verb[]) {
11018 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
11019 {}
11020 }
11021 },
11022 [PINFIX_ACER_ASPIRE_7736] = {
11023 .type = ALC_FIXUP_SKU,
11024 .v.sku = ALC_FIXUP_SKU_IGNORE,
10484 }, 11025 },
10485}; 11026};
10486 11027
10487static struct snd_pci_quirk alc882_fixup_tbl[] = { 11028static const struct snd_pci_quirk alc882_fixup_tbl[] = {
10488 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), 11029 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
11030 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
10489 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 11031 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
11032 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
10490 {} 11033 {}
10491}; 11034};
10492 11035
@@ -10535,33 +11078,42 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec)
10535{ 11078{
10536 struct alc_spec *spec = codec->spec; 11079 struct alc_spec *spec = codec->spec;
10537 hda_nid_t pin, dac; 11080 hda_nid_t pin, dac;
11081 int i;
10538 11082
10539 pin = spec->autocfg.hp_pins[0]; 11083 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
10540 if (pin) { 11084 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10541 dac = spec->multiout.hp_nid; 11085 pin = spec->autocfg.hp_pins[i];
10542 if (!dac) 11086 if (!pin)
10543 dac = spec->multiout.dac_nids[0]; /* to front */ 11087 break;
10544 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); 11088 dac = spec->multiout.hp_nid;
11089 if (!dac)
11090 dac = spec->multiout.dac_nids[0]; /* to front */
11091 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11092 }
10545 } 11093 }
10546 pin = spec->autocfg.speaker_pins[0]; 11094
10547 if (pin) { 11095 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
10548 dac = spec->multiout.extra_out_nid[0]; 11096 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10549 if (!dac) 11097 pin = spec->autocfg.speaker_pins[i];
10550 dac = spec->multiout.dac_nids[0]; /* to front */ 11098 if (!pin)
10551 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); 11099 break;
11100 dac = spec->multiout.extra_out_nid[0];
11101 if (!dac)
11102 dac = spec->multiout.dac_nids[0]; /* to front */
11103 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11104 }
10552 } 11105 }
10553} 11106}
10554 11107
10555static void alc882_auto_init_analog_input(struct hda_codec *codec) 11108static void alc882_auto_init_analog_input(struct hda_codec *codec)
10556{ 11109{
10557 struct alc_spec *spec = codec->spec; 11110 struct alc_spec *spec = codec->spec;
11111 struct auto_pin_cfg *cfg = &spec->autocfg;
10558 int i; 11112 int i;
10559 11113
10560 for (i = 0; i < AUTO_PIN_LAST; i++) { 11114 for (i = 0; i < cfg->num_inputs; i++) {
10561 hda_nid_t nid = spec->autocfg.input_pins[i]; 11115 hda_nid_t nid = cfg->inputs[i].pin;
10562 if (!nid) 11116 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
10563 continue;
10564 alc_set_input_pin(codec, nid, i);
10565 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) 11117 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10566 snd_hda_codec_write(codec, nid, 0, 11118 snd_hda_codec_write(codec, nid, 0,
10567 AC_VERB_SET_AMP_GAIN_MUTE, 11119 AC_VERB_SET_AMP_GAIN_MUTE,
@@ -10581,6 +11133,11 @@ static void alc882_auto_init_input_src(struct hda_codec *codec)
10581 const struct hda_input_mux *imux; 11133 const struct hda_input_mux *imux;
10582 int conns, mute, idx, item; 11134 int conns, mute, idx, item;
10583 11135
11136 /* mute ADC */
11137 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11138 AC_VERB_SET_AMP_GAIN_MUTE,
11139 AMP_IN_MUTE(0));
11140
10584 conns = snd_hda_get_connections(codec, nid, conn_list, 11141 conns = snd_hda_get_connections(codec, nid, conn_list,
10585 ARRAY_SIZE(conn_list)); 11142 ARRAY_SIZE(conn_list));
10586 if (conns < 0) 11143 if (conns < 0)
@@ -10623,24 +11180,35 @@ static void alc882_auto_init_input_src(struct hda_codec *codec)
10623static int alc_auto_add_mic_boost(struct hda_codec *codec) 11180static int alc_auto_add_mic_boost(struct hda_codec *codec)
10624{ 11181{
10625 struct alc_spec *spec = codec->spec; 11182 struct alc_spec *spec = codec->spec;
10626 int err; 11183 struct auto_pin_cfg *cfg = &spec->autocfg;
11184 int i, err;
11185 int type_idx = 0;
10627 hda_nid_t nid; 11186 hda_nid_t nid;
11187 const char *prev_label = NULL;
10628 11188
10629 nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; 11189 for (i = 0; i < cfg->num_inputs; i++) {
10630 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { 11190 if (cfg->inputs[i].type > AUTO_PIN_MIC)
10631 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11191 break;
10632 "Mic Boost", 11192 nid = cfg->inputs[i].pin;
10633 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 11193 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10634 if (err < 0) 11194 const char *label;
10635 return err; 11195 char boost_label[32];
10636 } 11196
10637 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; 11197 label = hda_get_autocfg_input_label(codec, cfg, i);
10638 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { 11198 if (prev_label && !strcmp(label, prev_label))
10639 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11199 type_idx++;
10640 "Front Mic Boost", 11200 else
11201 type_idx = 0;
11202 prev_label = label;
11203
11204 snprintf(boost_label, sizeof(boost_label),
11205 "%s Boost Volume", label);
11206 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11207 boost_label, type_idx,
10641 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 11208 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10642 if (err < 0) 11209 if (err < 0)
10643 return err; 11210 return err;
11211 }
10644 } 11212 }
10645 return 0; 11213 return 0;
10646} 11214}
@@ -10649,7 +11217,7 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec)
10649static int alc882_parse_auto_config(struct hda_codec *codec) 11217static int alc882_parse_auto_config(struct hda_codec *codec)
10650{ 11218{
10651 struct alc_spec *spec = codec->spec; 11219 struct alc_spec *spec = codec->spec;
10652 static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 11220 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10653 int err; 11221 int err;
10654 11222
10655 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 11223 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
@@ -10662,6 +11230,9 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
10662 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 11230 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10663 if (err < 0) 11231 if (err < 0)
10664 return err; 11232 return err;
11233 err = alc_auto_add_multi_channel_mode(codec);
11234 if (err < 0)
11235 return err;
10665 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 11236 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10666 if (err < 0) 11237 if (err < 0)
10667 return err; 11238 return err;
@@ -10726,8 +11297,6 @@ static int patch_alc882(struct hda_codec *codec)
10726 11297
10727 codec->spec = spec; 11298 codec->spec = spec;
10728 11299
10729 alc_auto_parse_customize_define(codec);
10730
10731 switch (codec->vendor_id) { 11300 switch (codec->vendor_id) {
10732 case 0x10ec0882: 11301 case 0x10ec0882:
10733 case 0x10ec0885: 11302 case 0x10ec0885:
@@ -10752,8 +11321,12 @@ static int patch_alc882(struct hda_codec *codec)
10752 board_config = ALC882_AUTO; 11321 board_config = ALC882_AUTO;
10753 } 11322 }
10754 11323
10755 if (board_config == ALC882_AUTO) 11324 if (board_config == ALC882_AUTO) {
10756 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); 11325 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11326 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11327 }
11328
11329 alc_auto_parse_customize_define(codec);
10757 11330
10758 if (board_config == ALC882_AUTO) { 11331 if (board_config == ALC882_AUTO) {
10759 /* automatic parse from the BIOS config */ 11332 /* automatic parse from the BIOS config */
@@ -10827,14 +11400,15 @@ static int patch_alc882(struct hda_codec *codec)
10827 if (has_cdefine_beep(codec)) 11400 if (has_cdefine_beep(codec))
10828 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 11401 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
10829 11402
10830 if (board_config == ALC882_AUTO) 11403 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
10831 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10832 11404
10833 spec->vmaster_nid = 0x0c; 11405 spec->vmaster_nid = 0x0c;
10834 11406
10835 codec->patch_ops = alc_patch_ops; 11407 codec->patch_ops = alc_patch_ops;
10836 if (board_config == ALC882_AUTO) 11408 if (board_config == ALC882_AUTO)
10837 spec->init_hook = alc882_auto_init; 11409 spec->init_hook = alc882_auto_init;
11410
11411 alc_init_jacks(codec);
10838#ifdef CONFIG_SND_HDA_POWER_SAVE 11412#ifdef CONFIG_SND_HDA_POWER_SAVE
10839 if (!spec->loopback.amplist) 11413 if (!spec->loopback.amplist)
10840 spec->loopback.amplist = alc882_loopbacks; 11414 spec->loopback.amplist = alc882_loopbacks;
@@ -10860,14 +11434,14 @@ static int patch_alc882(struct hda_codec *codec)
10860#define alc262_modes alc260_modes 11434#define alc262_modes alc260_modes
10861#define alc262_capture_source alc882_capture_source 11435#define alc262_capture_source alc882_capture_source
10862 11436
10863static hda_nid_t alc262_dmic_adc_nids[1] = { 11437static const hda_nid_t alc262_dmic_adc_nids[1] = {
10864 /* ADC0 */ 11438 /* ADC0 */
10865 0x09 11439 0x09
10866}; 11440};
10867 11441
10868static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; 11442static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10869 11443
10870static struct snd_kcontrol_new alc262_base_mixer[] = { 11444static const struct snd_kcontrol_new alc262_base_mixer[] = {
10871 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11445 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10872 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11446 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10873 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11447 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -10876,10 +11450,10 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
10876 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11450 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10877 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11451 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10878 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11452 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10879 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11453 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10880 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11454 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10881 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11455 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10882 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11456 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
10883 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 11457 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10884 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11458 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10885 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 11459 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
@@ -10888,71 +11462,30 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
10888}; 11462};
10889 11463
10890/* update HP, line and mono-out pins according to the master switch */ 11464/* update HP, line and mono-out pins according to the master switch */
10891static void alc262_hp_master_update(struct hda_codec *codec) 11465#define alc262_hp_master_update alc260_hp_master_update
10892{
10893 struct alc_spec *spec = codec->spec;
10894 int val = spec->master_sw;
10895 11466
10896 /* HP & line-out */ 11467static void alc262_hp_bpc_setup(struct hda_codec *codec)
10897 snd_hda_codec_write_cache(codec, 0x1b, 0,
10898 AC_VERB_SET_PIN_WIDGET_CONTROL,
10899 val ? PIN_HP : 0);
10900 snd_hda_codec_write_cache(codec, 0x15, 0,
10901 AC_VERB_SET_PIN_WIDGET_CONTROL,
10902 val ? PIN_HP : 0);
10903 /* mono (speaker) depending on the HP jack sense */
10904 val = val && !spec->jack_present;
10905 snd_hda_codec_write_cache(codec, 0x16, 0,
10906 AC_VERB_SET_PIN_WIDGET_CONTROL,
10907 val ? PIN_OUT : 0);
10908}
10909
10910static void alc262_hp_bpc_automute(struct hda_codec *codec)
10911{ 11468{
10912 struct alc_spec *spec = codec->spec; 11469 struct alc_spec *spec = codec->spec;
10913 11470
10914 spec->jack_present = snd_hda_jack_detect(codec, 0x1b); 11471 spec->autocfg.hp_pins[0] = 0x1b;
10915 alc262_hp_master_update(codec); 11472 spec->autocfg.speaker_pins[0] = 0x16;
10916} 11473 spec->automute = 1;
10917 11474 spec->automute_mode = ALC_AUTOMUTE_PIN;
10918static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10919{
10920 if ((res >> 26) != ALC880_HP_EVENT)
10921 return;
10922 alc262_hp_bpc_automute(codec);
10923} 11475}
10924 11476
10925static void alc262_hp_wildwest_automute(struct hda_codec *codec) 11477static void alc262_hp_wildwest_setup(struct hda_codec *codec)
10926{ 11478{
10927 struct alc_spec *spec = codec->spec; 11479 struct alc_spec *spec = codec->spec;
10928 11480
10929 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 11481 spec->autocfg.hp_pins[0] = 0x15;
10930 alc262_hp_master_update(codec); 11482 spec->autocfg.speaker_pins[0] = 0x16;
10931} 11483 spec->automute = 1;
10932 11484 spec->automute_mode = ALC_AUTOMUTE_PIN;
10933static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10934 unsigned int res)
10935{
10936 if ((res >> 26) != ALC880_HP_EVENT)
10937 return;
10938 alc262_hp_wildwest_automute(codec);
10939} 11485}
10940 11486
10941#define alc262_hp_master_sw_get alc260_hp_master_sw_get 11487#define alc262_hp_master_sw_get alc260_hp_master_sw_get
10942 11488#define alc262_hp_master_sw_put alc260_hp_master_sw_put
10943static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10944 struct snd_ctl_elem_value *ucontrol)
10945{
10946 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10947 struct alc_spec *spec = codec->spec;
10948 int val = !!*ucontrol->value.integer.value;
10949
10950 if (val == spec->master_sw)
10951 return 0;
10952 spec->master_sw = val;
10953 alc262_hp_master_update(codec);
10954 return 1;
10955}
10956 11489
10957#define ALC262_HP_MASTER_SWITCH \ 11490#define ALC262_HP_MASTER_SWITCH \
10958 { \ 11491 { \
@@ -10969,7 +11502,7 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10969 } 11502 }
10970 11503
10971 11504
10972static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 11505static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10973 ALC262_HP_MASTER_SWITCH, 11506 ALC262_HP_MASTER_SWITCH,
10974 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11507 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10975 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11508 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -10980,10 +11513,10 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10980 HDA_OUTPUT), 11513 HDA_OUTPUT),
10981 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10982 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11515 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10983 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11516 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10984 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11517 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10985 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11518 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10986 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11519 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
10987 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11520 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10988 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11521 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10989 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11522 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -10993,7 +11526,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10993 { } /* end */ 11526 { } /* end */
10994}; 11527};
10995 11528
10996static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 11529static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
10997 ALC262_HP_MASTER_SWITCH, 11530 ALC262_HP_MASTER_SWITCH,
10998 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11531 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10999 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11532 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
@@ -11005,7 +11538,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11005 HDA_OUTPUT), 11538 HDA_OUTPUT),
11006 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 11539 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11007 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 11540 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11008 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT), 11541 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11009 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 11542 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11010 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 11543 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11011 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11544 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -11013,10 +11546,10 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11013 { } /* end */ 11546 { } /* end */
11014}; 11547};
11015 11548
11016static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 11549static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11017 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11550 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11018 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11551 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11019 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT), 11552 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11020 { } /* end */ 11553 { } /* end */
11021}; 11554};
11022 11555
@@ -11027,20 +11560,22 @@ static void alc262_hp_t5735_setup(struct hda_codec *codec)
11027 11560
11028 spec->autocfg.hp_pins[0] = 0x15; 11561 spec->autocfg.hp_pins[0] = 0x15;
11029 spec->autocfg.speaker_pins[0] = 0x14; 11562 spec->autocfg.speaker_pins[0] = 0x14;
11563 spec->automute = 1;
11564 spec->automute_mode = ALC_AUTOMUTE_PIN;
11030} 11565}
11031 11566
11032static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 11567static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11033 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11568 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11034 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11569 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11035 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11570 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11036 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11571 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11037 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11572 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11038 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11573 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11039 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11574 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11040 { } /* end */ 11575 { } /* end */
11041}; 11576};
11042 11577
11043static struct hda_verb alc262_hp_t5735_verbs[] = { 11578static const struct hda_verb alc262_hp_t5735_verbs[] = {
11044 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11579 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11045 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11580 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11046 11581
@@ -11048,7 +11583,7 @@ static struct hda_verb alc262_hp_t5735_verbs[] = {
11048 { } 11583 { }
11049}; 11584};
11050 11585
11051static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { 11586static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11052 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11587 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11053 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11588 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11054 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 11589 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
@@ -11058,7 +11593,7 @@ static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11058 { } /* end */ 11593 { } /* end */
11059}; 11594};
11060 11595
11061static struct hda_verb alc262_hp_rp5700_verbs[] = { 11596static const struct hda_verb alc262_hp_rp5700_verbs[] = {
11062 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11597 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11063 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11598 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11064 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11599 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -11072,7 +11607,7 @@ static struct hda_verb alc262_hp_rp5700_verbs[] = {
11072 {} 11607 {}
11073}; 11608};
11074 11609
11075static struct hda_input_mux alc262_hp_rp5700_capture_source = { 11610static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
11076 .num_items = 1, 11611 .num_items = 1,
11077 .items = { 11612 .items = {
11078 { "Line", 0x1 }, 11613 { "Line", 0x1 },
@@ -11080,44 +11615,9 @@ static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11080}; 11615};
11081 11616
11082/* bind hp and internal speaker mute (with plug check) as master switch */ 11617/* bind hp and internal speaker mute (with plug check) as master switch */
11083static void alc262_hippo_master_update(struct hda_codec *codec) 11618#define alc262_hippo_master_update alc262_hp_master_update
11084{
11085 struct alc_spec *spec = codec->spec;
11086 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11087 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11088 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11089 unsigned int mute;
11090
11091 /* HP */
11092 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11093 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11094 HDA_AMP_MUTE, mute);
11095 /* mute internal speaker per jack sense */
11096 if (spec->jack_present)
11097 mute = HDA_AMP_MUTE;
11098 if (line_nid)
11099 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11100 HDA_AMP_MUTE, mute);
11101 if (speaker_nid && speaker_nid != line_nid)
11102 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
11103 HDA_AMP_MUTE, mute);
11104}
11105
11106#define alc262_hippo_master_sw_get alc262_hp_master_sw_get 11619#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11107 11620#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
11108static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11109 struct snd_ctl_elem_value *ucontrol)
11110{
11111 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11112 struct alc_spec *spec = codec->spec;
11113 int val = !!*ucontrol->value.integer.value;
11114
11115 if (val == spec->master_sw)
11116 return 0;
11117 spec->master_sw = val;
11118 alc262_hippo_master_update(codec);
11119 return 1;
11120}
11121 11621
11122#define ALC262_HIPPO_MASTER_SWITCH \ 11622#define ALC262_HIPPO_MASTER_SWITCH \
11123 { \ 11623 { \
@@ -11134,7 +11634,7 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11134 (SUBDEV_SPEAKER(0) << 16), \ 11634 (SUBDEV_SPEAKER(0) << 16), \
11135 } 11635 }
11136 11636
11137static struct snd_kcontrol_new alc262_hippo_mixer[] = { 11637static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
11138 ALC262_HIPPO_MASTER_SWITCH, 11638 ALC262_HIPPO_MASTER_SWITCH,
11139 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11639 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11140 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11640 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -11143,15 +11643,15 @@ static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11143 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11643 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11144 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11644 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11645 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11146 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11646 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11147 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11647 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11148 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11648 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11149 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11649 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11150 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11650 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11151 { } /* end */ 11651 { } /* end */
11152}; 11652};
11153 11653
11154static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 11654static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11155 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11655 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11156 ALC262_HIPPO_MASTER_SWITCH, 11656 ALC262_HIPPO_MASTER_SWITCH,
11157 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11657 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -11160,36 +11660,22 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11160 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11660 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11161 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11661 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11162 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11662 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11163 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11663 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11164 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11664 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11165 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11665 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11166 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11666 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11167 { } /* end */ 11667 { } /* end */
11168}; 11668};
11169 11669
11170/* mute/unmute internal speaker according to the hp jack and mute state */ 11670/* mute/unmute internal speaker according to the hp jack and mute state */
11171static void alc262_hippo_automute(struct hda_codec *codec)
11172{
11173 struct alc_spec *spec = codec->spec;
11174 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11175
11176 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
11177 alc262_hippo_master_update(codec);
11178}
11179
11180static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11181{
11182 if ((res >> 26) != ALC880_HP_EVENT)
11183 return;
11184 alc262_hippo_automute(codec);
11185}
11186
11187static void alc262_hippo_setup(struct hda_codec *codec) 11671static void alc262_hippo_setup(struct hda_codec *codec)
11188{ 11672{
11189 struct alc_spec *spec = codec->spec; 11673 struct alc_spec *spec = codec->spec;
11190 11674
11191 spec->autocfg.hp_pins[0] = 0x15; 11675 spec->autocfg.hp_pins[0] = 0x15;
11192 spec->autocfg.speaker_pins[0] = 0x14; 11676 spec->autocfg.speaker_pins[0] = 0x14;
11677 spec->automute = 1;
11678 spec->automute_mode = ALC_AUTOMUTE_AMP;
11193} 11679}
11194 11680
11195static void alc262_hippo1_setup(struct hda_codec *codec) 11681static void alc262_hippo1_setup(struct hda_codec *codec)
@@ -11198,10 +11684,12 @@ static void alc262_hippo1_setup(struct hda_codec *codec)
11198 11684
11199 spec->autocfg.hp_pins[0] = 0x1b; 11685 spec->autocfg.hp_pins[0] = 0x1b;
11200 spec->autocfg.speaker_pins[0] = 0x14; 11686 spec->autocfg.speaker_pins[0] = 0x14;
11687 spec->automute = 1;
11688 spec->automute_mode = ALC_AUTOMUTE_AMP;
11201} 11689}
11202 11690
11203 11691
11204static struct snd_kcontrol_new alc262_sony_mixer[] = { 11692static const struct snd_kcontrol_new alc262_sony_mixer[] = {
11205 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11693 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11206 ALC262_HIPPO_MASTER_SWITCH, 11694 ALC262_HIPPO_MASTER_SWITCH,
11207 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11695 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -11211,7 +11699,7 @@ static struct snd_kcontrol_new alc262_sony_mixer[] = {
11211 { } /* end */ 11699 { } /* end */
11212}; 11700};
11213 11701
11214static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 11702static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11215 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11703 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11216 ALC262_HIPPO_MASTER_SWITCH, 11704 ALC262_HIPPO_MASTER_SWITCH,
11217 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11705 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -11222,7 +11710,7 @@ static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11222 { } /* end */ 11710 { } /* end */
11223}; 11711};
11224 11712
11225static struct snd_kcontrol_new alc262_tyan_mixer[] = { 11713static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
11226 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11714 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11227 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11715 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11228 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), 11716 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
@@ -11231,14 +11719,14 @@ static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11231 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11719 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11232 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11720 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11233 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11721 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11234 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11722 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11235 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11723 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11236 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11724 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11237 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11725 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11238 { } /* end */ 11726 { } /* end */
11239}; 11727};
11240 11728
11241static struct hda_verb alc262_tyan_verbs[] = { 11729static const struct hda_verb alc262_tyan_verbs[] = {
11242 /* Headphone automute */ 11730 /* Headphone automute */
11243 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11731 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11244 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11732 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -11260,6 +11748,8 @@ static void alc262_tyan_setup(struct hda_codec *codec)
11260 11748
11261 spec->autocfg.hp_pins[0] = 0x1b; 11749 spec->autocfg.hp_pins[0] = 0x1b;
11262 spec->autocfg.speaker_pins[0] = 0x15; 11750 spec->autocfg.speaker_pins[0] = 0x15;
11751 spec->automute = 1;
11752 spec->automute_mode = ALC_AUTOMUTE_AMP;
11263} 11753}
11264 11754
11265 11755
@@ -11269,7 +11759,7 @@ static void alc262_tyan_setup(struct hda_codec *codec)
11269/* 11759/*
11270 * generic initialization of ADC, input mixers and output mixers 11760 * generic initialization of ADC, input mixers and output mixers
11271 */ 11761 */
11272static struct hda_verb alc262_init_verbs[] = { 11762static const struct hda_verb alc262_init_verbs[] = {
11273 /* 11763 /*
11274 * Unmute ADC0-2 and set the default input to mic-in 11764 * Unmute ADC0-2 and set the default input to mic-in
11275 */ 11765 */
@@ -11345,13 +11835,13 @@ static struct hda_verb alc262_init_verbs[] = {
11345 { } 11835 { }
11346}; 11836};
11347 11837
11348static struct hda_verb alc262_eapd_verbs[] = { 11838static const struct hda_verb alc262_eapd_verbs[] = {
11349 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11839 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11350 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11840 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11351 { } 11841 { }
11352}; 11842};
11353 11843
11354static struct hda_verb alc262_hippo1_unsol_verbs[] = { 11844static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
11355 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11845 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11356 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11846 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11357 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11847 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
@@ -11361,7 +11851,7 @@ static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11361 {} 11851 {}
11362}; 11852};
11363 11853
11364static struct hda_verb alc262_sony_unsol_verbs[] = { 11854static const struct hda_verb alc262_sony_unsol_verbs[] = {
11365 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11366 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11856 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11367 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 11857 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
@@ -11371,7 +11861,7 @@ static struct hda_verb alc262_sony_unsol_verbs[] = {
11371 {} 11861 {}
11372}; 11862};
11373 11863
11374static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { 11864static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11375 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11865 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11376 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11866 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11377 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11867 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -11380,7 +11870,7 @@ static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11380 { } /* end */ 11870 { } /* end */
11381}; 11871};
11382 11872
11383static struct hda_verb alc262_toshiba_s06_verbs[] = { 11873static const struct hda_verb alc262_toshiba_s06_verbs[] = {
11384 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11874 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11385 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11875 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11386 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11876 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -11403,6 +11893,8 @@ static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11403 spec->int_mic.pin = 0x12; 11893 spec->int_mic.pin = 0x12;
11404 spec->int_mic.mux_idx = 9; 11894 spec->int_mic.mux_idx = 9;
11405 spec->auto_mic = 1; 11895 spec->auto_mic = 1;
11896 spec->automute = 1;
11897 spec->automute_mode = ALC_AUTOMUTE_PIN;
11406} 11898}
11407 11899
11408/* 11900/*
@@ -11412,20 +11904,20 @@ static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11412 * 0x18 = external mic 11904 * 0x18 = external mic
11413 */ 11905 */
11414 11906
11415static struct snd_kcontrol_new alc262_nec_mixer[] = { 11907static const struct snd_kcontrol_new alc262_nec_mixer[] = {
11416 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 11908 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11417 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), 11909 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11418 11910
11419 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11911 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11420 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11912 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11421 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11913 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11422 11914
11423 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11915 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11424 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11916 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11425 { } /* end */ 11917 { } /* end */
11426}; 11918};
11427 11919
11428static struct hda_verb alc262_nec_verbs[] = { 11920static const struct hda_verb alc262_nec_verbs[] = {
11429 /* Unmute Speaker */ 11921 /* Unmute Speaker */
11430 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11922 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11431 11923
@@ -11446,9 +11938,9 @@ static struct hda_verb alc262_nec_verbs[] = {
11446 * 0x1b = port replicator headphone out 11938 * 0x1b = port replicator headphone out
11447 */ 11939 */
11448 11940
11449#define ALC_HP_EVENT 0x37 11941#define ALC_HP_EVENT ALC880_HP_EVENT
11450 11942
11451static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 11943static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11452 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11944 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11453 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11945 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11454 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11946 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
@@ -11456,29 +11948,29 @@ static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11456 {} 11948 {}
11457}; 11949};
11458 11950
11459static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { 11951static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11460 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11952 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11461 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11953 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11462 {} 11954 {}
11463}; 11955};
11464 11956
11465static struct hda_verb alc262_lenovo_3000_init_verbs[] = { 11957static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11466 /* Front Mic pin: input vref at 50% */ 11958 /* Front Mic pin: input vref at 50% */
11467 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 11959 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11468 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11960 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11469 {} 11961 {}
11470}; 11962};
11471 11963
11472static struct hda_input_mux alc262_fujitsu_capture_source = { 11964static const struct hda_input_mux alc262_fujitsu_capture_source = {
11473 .num_items = 3, 11965 .num_items = 3,
11474 .items = { 11966 .items = {
11475 { "Mic", 0x0 }, 11967 { "Mic", 0x0 },
11476 { "Int Mic", 0x1 }, 11968 { "Internal Mic", 0x1 },
11477 { "CD", 0x4 }, 11969 { "CD", 0x4 },
11478 }, 11970 },
11479}; 11971};
11480 11972
11481static struct hda_input_mux alc262_HP_capture_source = { 11973static const struct hda_input_mux alc262_HP_capture_source = {
11482 .num_items = 5, 11974 .num_items = 5,
11483 .items = { 11975 .items = {
11484 { "Mic", 0x0 }, 11976 { "Mic", 0x0 },
@@ -11489,7 +11981,7 @@ static struct hda_input_mux alc262_HP_capture_source = {
11489 }, 11981 },
11490}; 11982};
11491 11983
11492static struct hda_input_mux alc262_HP_D7000_capture_source = { 11984static const struct hda_input_mux alc262_HP_D7000_capture_source = {
11493 .num_items = 4, 11985 .num_items = 4,
11494 .items = { 11986 .items = {
11495 { "Mic", 0x0 }, 11987 { "Mic", 0x0 },
@@ -11499,44 +11991,19 @@ static struct hda_input_mux alc262_HP_D7000_capture_source = {
11499 }, 11991 },
11500}; 11992};
11501 11993
11502/* mute/unmute internal speaker according to the hp jacks and mute state */ 11994static void alc262_fujitsu_setup(struct hda_codec *codec)
11503static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11504{ 11995{
11505 struct alc_spec *spec = codec->spec; 11996 struct alc_spec *spec = codec->spec;
11506 unsigned int mute;
11507
11508 if (force || !spec->sense_updated) {
11509 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11510 snd_hda_jack_detect(codec, 0x1b);
11511 spec->sense_updated = 1;
11512 }
11513 /* unmute internal speaker only if both HPs are unplugged and
11514 * master switch is on
11515 */
11516 if (spec->jack_present)
11517 mute = HDA_AMP_MUTE;
11518 else
11519 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11520 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11521 HDA_AMP_MUTE, mute);
11522}
11523
11524/* unsolicited event for HP jack sensing */
11525static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11526 unsigned int res)
11527{
11528 if ((res >> 26) != ALC_HP_EVENT)
11529 return;
11530 alc262_fujitsu_automute(codec, 1);
11531}
11532 11997
11533static void alc262_fujitsu_init_hook(struct hda_codec *codec) 11998 spec->autocfg.hp_pins[0] = 0x14;
11534{ 11999 spec->autocfg.hp_pins[1] = 0x1b;
11535 alc262_fujitsu_automute(codec, 1); 12000 spec->autocfg.speaker_pins[0] = 0x15;
12001 spec->automute = 1;
12002 spec->automute_mode = ALC_AUTOMUTE_AMP;
11536} 12003}
11537 12004
11538/* bind volumes of both NID 0x0c and 0x0d */ 12005/* bind volumes of both NID 0x0c and 0x0d */
11539static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 12006static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11540 .ops = &snd_hda_bind_vol, 12007 .ops = &snd_hda_bind_vol,
11541 .values = { 12008 .values = {
11542 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 12009 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
@@ -11545,78 +12012,15 @@ static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11545 }, 12012 },
11546}; 12013};
11547 12014
11548/* mute/unmute internal speaker according to the hp jack and mute state */ 12015static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11549static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11550{
11551 struct alc_spec *spec = codec->spec;
11552 unsigned int mute;
11553
11554 if (force || !spec->sense_updated) {
11555 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11556 spec->sense_updated = 1;
11557 }
11558 if (spec->jack_present) {
11559 /* mute internal speaker */
11560 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11561 HDA_AMP_MUTE, HDA_AMP_MUTE);
11562 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11563 HDA_AMP_MUTE, HDA_AMP_MUTE);
11564 } else {
11565 /* unmute internal speaker if necessary */
11566 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11567 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11568 HDA_AMP_MUTE, mute);
11569 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11570 HDA_AMP_MUTE, mute);
11571 }
11572}
11573
11574/* unsolicited event for HP jack sensing */
11575static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11576 unsigned int res)
11577{
11578 if ((res >> 26) != ALC_HP_EVENT)
11579 return;
11580 alc262_lenovo_3000_automute(codec, 1);
11581}
11582
11583static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11584 int dir, int idx, long *valp)
11585{
11586 int i, change = 0;
11587
11588 for (i = 0; i < 2; i++, valp++)
11589 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11590 HDA_AMP_MUTE,
11591 *valp ? 0 : HDA_AMP_MUTE);
11592 return change;
11593}
11594
11595/* bind hp and internal speaker mute (with plug check) */
11596static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11597 struct snd_ctl_elem_value *ucontrol)
11598{
11599 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11600 long *valp = ucontrol->value.integer.value;
11601 int change;
11602
11603 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11604 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11605 if (change)
11606 alc262_fujitsu_automute(codec, 0);
11607 return change;
11608}
11609
11610static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11611 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 12016 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11612 { 12017 {
11613 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12018 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11614 .name = "Master Playback Switch", 12019 .name = "Master Playback Switch",
11615 .subdevice = HDA_SUBDEV_AMP_FLAG, 12020 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11616 .info = snd_hda_mixer_amp_switch_info, 12021 .info = snd_ctl_boolean_mono_info,
11617 .get = snd_hda_mixer_amp_switch_get, 12022 .get = alc262_hp_master_sw_get,
11618 .put = alc262_fujitsu_master_sw_put, 12023 .put = alc262_hp_master_sw_put,
11619 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11620 }, 12024 },
11621 { 12025 {
11622 .iface = NID_MAPPING, 12026 .iface = NID_MAPPING,
@@ -11625,71 +12029,67 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11625 }, 12029 },
11626 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 12030 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11627 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 12031 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11628 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12032 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11629 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 12033 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11630 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 12034 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11631 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 12035 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11632 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 12036 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11633 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 12037 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11634 { } /* end */ 12038 { } /* end */
11635}; 12039};
11636 12040
11637/* bind hp and internal speaker mute (with plug check) */ 12041static void alc262_lenovo_3000_setup(struct hda_codec *codec)
11638static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11639 struct snd_ctl_elem_value *ucontrol)
11640{ 12042{
11641 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 12043 struct alc_spec *spec = codec->spec;
11642 long *valp = ucontrol->value.integer.value;
11643 int change;
11644 12044
11645 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 12045 spec->autocfg.hp_pins[0] = 0x1b;
11646 if (change) 12046 spec->autocfg.speaker_pins[0] = 0x14;
11647 alc262_lenovo_3000_automute(codec, 0); 12047 spec->autocfg.speaker_pins[1] = 0x16;
11648 return change; 12048 spec->automute = 1;
12049 spec->automute_mode = ALC_AUTOMUTE_AMP;
11649} 12050}
11650 12051
11651static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { 12052static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11652 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 12053 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11653 { 12054 {
11654 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12055 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11655 .name = "Master Playback Switch", 12056 .name = "Master Playback Switch",
11656 .subdevice = HDA_SUBDEV_AMP_FLAG, 12057 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11657 .info = snd_hda_mixer_amp_switch_info, 12058 .info = snd_ctl_boolean_mono_info,
11658 .get = snd_hda_mixer_amp_switch_get, 12059 .get = alc262_hp_master_sw_get,
11659 .put = alc262_lenovo_3000_master_sw_put, 12060 .put = alc262_hp_master_sw_put,
11660 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11661 }, 12061 },
11662 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 12062 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11663 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 12063 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11664 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12064 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11665 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 12065 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11666 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 12066 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11667 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 12067 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11668 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 12068 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11669 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 12069 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11670 { } /* end */ 12070 { } /* end */
11671}; 12071};
11672 12072
11673static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { 12073static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11674 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 12074 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11675 ALC262_HIPPO_MASTER_SWITCH, 12075 ALC262_HIPPO_MASTER_SWITCH,
11676 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 12076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11677 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 12077 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11678 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12078 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11679 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 12079 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11680 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 12080 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11681 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 12081 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11682 { } /* end */ 12082 { } /* end */
11683}; 12083};
11684 12084
11685/* additional init verbs for Benq laptops */ 12085/* additional init verbs for Benq laptops */
11686static struct hda_verb alc262_EAPD_verbs[] = { 12086static const struct hda_verb alc262_EAPD_verbs[] = {
11687 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 12087 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11688 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 12088 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11689 {} 12089 {}
11690}; 12090};
11691 12091
11692static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 12092static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11693 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12093 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11694 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12094 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11695 12095
@@ -11699,17 +12099,17 @@ static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11699}; 12099};
11700 12100
11701/* Samsung Q1 Ultra Vista model setup */ 12101/* Samsung Q1 Ultra Vista model setup */
11702static struct snd_kcontrol_new alc262_ultra_mixer[] = { 12102static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
11703 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 12103 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11704 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 12104 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11705 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 12105 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11706 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 12106 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11707 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 12107 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11708 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT), 12108 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
11709 { } /* end */ 12109 { } /* end */
11710}; 12110};
11711 12111
11712static struct hda_verb alc262_ultra_verbs[] = { 12112static const struct hda_verb alc262_ultra_verbs[] = {
11713 /* output mixer */ 12113 /* output mixer */
11714 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
@@ -11772,7 +12172,7 @@ static void alc262_ultra_unsol_event(struct hda_codec *codec,
11772 alc262_ultra_automute(codec); 12172 alc262_ultra_automute(codec);
11773} 12173}
11774 12174
11775static struct hda_input_mux alc262_ultra_capture_source = { 12175static const struct hda_input_mux alc262_ultra_capture_source = {
11776 .num_items = 2, 12176 .num_items = 2,
11777 .items = { 12177 .items = {
11778 { "Mic", 0x1 }, 12178 { "Mic", 0x1 },
@@ -11798,7 +12198,7 @@ static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11798 return ret; 12198 return ret;
11799} 12199}
11800 12200
11801static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { 12201static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11802 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 12202 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11803 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 12203 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11804 { 12204 {
@@ -11831,7 +12231,7 @@ static int alc262_check_volbit(hda_nid_t nid)
11831} 12231}
11832 12232
11833static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, 12233static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11834 const char *pfx, int *vbits) 12234 const char *pfx, int *vbits, int idx)
11835{ 12235{
11836 unsigned long val; 12236 unsigned long val;
11837 int vbit; 12237 int vbit;
@@ -11846,11 +12246,11 @@ static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11846 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT); 12246 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11847 else 12247 else
11848 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT); 12248 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
11849 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val); 12249 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
11850} 12250}
11851 12251
11852static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid, 12252static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11853 const char *pfx) 12253 const char *pfx, int idx)
11854{ 12254{
11855 unsigned long val; 12255 unsigned long val;
11856 12256
@@ -11860,7 +12260,7 @@ static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11860 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 12260 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11861 else 12261 else
11862 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 12262 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
11863 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); 12263 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
11864} 12264}
11865 12265
11866/* add playback controls from the parsed DAC table */ 12266/* add playback controls from the parsed DAC table */
@@ -11869,49 +12269,57 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11869{ 12269{
11870 const char *pfx; 12270 const char *pfx;
11871 int vbits; 12271 int vbits;
11872 int err; 12272 int i, err;
11873 12273
11874 spec->multiout.num_dacs = 1; /* only use one dac */ 12274 spec->multiout.num_dacs = 1; /* only use one dac */
11875 spec->multiout.dac_nids = spec->private_dac_nids; 12275 spec->multiout.dac_nids = spec->private_dac_nids;
11876 spec->multiout.dac_nids[0] = 2; 12276 spec->private_dac_nids[0] = 2;
11877 12277
11878 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) 12278 pfx = alc_get_line_out_pfx(spec, true);
11879 pfx = "Master"; 12279 if (!pfx)
11880 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11881 pfx = "Speaker";
11882 else
11883 pfx = "Front"; 12280 pfx = "Front";
11884 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx); 12281 for (i = 0; i < 2; i++) {
11885 if (err < 0) 12282 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
11886 return err; 12283 if (err < 0)
11887 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker"); 12284 return err;
11888 if (err < 0) 12285 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
11889 return err; 12286 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
11890 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone"); 12287 "Speaker", i);
11891 if (err < 0) 12288 if (err < 0)
11892 return err; 12289 return err;
12290 }
12291 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12292 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12293 "Headphone", i);
12294 if (err < 0)
12295 return err;
12296 }
12297 }
11893 12298
11894 vbits = alc262_check_volbit(cfg->line_out_pins[0]) | 12299 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11895 alc262_check_volbit(cfg->speaker_pins[0]) | 12300 alc262_check_volbit(cfg->speaker_pins[0]) |
11896 alc262_check_volbit(cfg->hp_pins[0]); 12301 alc262_check_volbit(cfg->hp_pins[0]);
11897 if (vbits == 1 || vbits == 2) 12302 if (vbits == 1 || vbits == 2)
11898 pfx = "Master"; /* only one mixer is used */ 12303 pfx = "Master"; /* only one mixer is used */
11899 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11900 pfx = "Speaker";
11901 else
11902 pfx = "Front";
11903 vbits = 0; 12304 vbits = 0;
11904 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits); 12305 for (i = 0; i < 2; i++) {
11905 if (err < 0) 12306 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
11906 return err; 12307 &vbits, i);
11907 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker", 12308 if (err < 0)
11908 &vbits); 12309 return err;
11909 if (err < 0) 12310 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
11910 return err; 12311 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
11911 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone", 12312 "Speaker", &vbits, i);
11912 &vbits); 12313 if (err < 0)
11913 if (err < 0) 12314 return err;
11914 return err; 12315 }
12316 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12317 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12318 "Headphone", &vbits, i);
12319 if (err < 0)
12320 return err;
12321 }
12322 }
11915 return 0; 12323 return 0;
11916} 12324}
11917 12325
@@ -11921,7 +12329,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11921/* 12329/*
11922 * generic initialization of ADC, input mixers and output mixers 12330 * generic initialization of ADC, input mixers and output mixers
11923 */ 12331 */
11924static struct hda_verb alc262_volume_init_verbs[] = { 12332static const struct hda_verb alc262_volume_init_verbs[] = {
11925 /* 12333 /*
11926 * Unmute ADC0-2 and set the default input to mic-in 12334 * Unmute ADC0-2 and set the default input to mic-in
11927 */ 12335 */
@@ -11982,7 +12390,7 @@ static struct hda_verb alc262_volume_init_verbs[] = {
11982 { } 12390 { }
11983}; 12391};
11984 12392
11985static struct hda_verb alc262_HP_BPC_init_verbs[] = { 12393static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
11986 /* 12394 /*
11987 * Unmute ADC0-2 and set the default input to mic-in 12395 * Unmute ADC0-2 and set the default input to mic-in
11988 */ 12396 */
@@ -12086,7 +12494,7 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12086 { } 12494 { }
12087}; 12495};
12088 12496
12089static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 12497static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12090 /* 12498 /*
12091 * Unmute ADC0-2 and set the default input to mic-in 12499 * Unmute ADC0-2 and set the default input to mic-in
12092 */ 12500 */
@@ -12182,7 +12590,7 @@ static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12182 { } 12590 { }
12183}; 12591};
12184 12592
12185static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { 12593static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12186 12594
12187 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ 12595 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12188 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12596 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
@@ -12199,6 +12607,39 @@ static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12199 {} 12607 {}
12200}; 12608};
12201 12609
12610/*
12611 * Pin config fixes
12612 */
12613enum {
12614 PINFIX_FSC_H270,
12615 PINFIX_HP_Z200,
12616};
12617
12618static const struct alc_fixup alc262_fixups[] = {
12619 [PINFIX_FSC_H270] = {
12620 .type = ALC_FIXUP_PINS,
12621 .v.pins = (const struct alc_pincfg[]) {
12622 { 0x14, 0x99130110 }, /* speaker */
12623 { 0x15, 0x0221142f }, /* front HP */
12624 { 0x1b, 0x0121141f }, /* rear HP */
12625 { }
12626 }
12627 },
12628 [PINFIX_HP_Z200] = {
12629 .type = ALC_FIXUP_PINS,
12630 .v.pins = (const struct alc_pincfg[]) {
12631 { 0x16, 0x99130120 }, /* internal speaker */
12632 { }
12633 }
12634 },
12635};
12636
12637static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12638 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
12639 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12640 {}
12641};
12642
12202 12643
12203#ifdef CONFIG_SND_HDA_POWER_SAVE 12644#ifdef CONFIG_SND_HDA_POWER_SAVE
12204#define alc262_loopbacks alc880_loopbacks 12645#define alc262_loopbacks alc880_loopbacks
@@ -12217,7 +12658,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
12217{ 12658{
12218 struct alc_spec *spec = codec->spec; 12659 struct alc_spec *spec = codec->spec;
12219 int err; 12660 int err;
12220 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 12661 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12221 12662
12222 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12663 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12223 alc262_ignore); 12664 alc262_ignore);
@@ -12281,7 +12722,7 @@ static void alc262_auto_init(struct hda_codec *codec)
12281/* 12722/*
12282 * configuration and preset 12723 * configuration and preset
12283 */ 12724 */
12284static const char *alc262_models[ALC262_MODEL_LAST] = { 12725static const char * const alc262_models[ALC262_MODEL_LAST] = {
12285 [ALC262_BASIC] = "basic", 12726 [ALC262_BASIC] = "basic",
12286 [ALC262_HIPPO] = "hippo", 12727 [ALC262_HIPPO] = "hippo",
12287 [ALC262_HIPPO_1] = "hippo_1", 12728 [ALC262_HIPPO_1] = "hippo_1",
@@ -12302,13 +12743,17 @@ static const char *alc262_models[ALC262_MODEL_LAST] = {
12302 [ALC262_AUTO] = "auto", 12743 [ALC262_AUTO] = "auto",
12303}; 12744};
12304 12745
12305static struct snd_pci_quirk alc262_cfg_tbl[] = { 12746static const struct snd_pci_quirk alc262_cfg_tbl[] = {
12306 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 12747 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12307 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), 12748 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12308 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", 12749 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12309 ALC262_HP_BPC), 12750 ALC262_HP_BPC),
12310 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", 12751 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12311 ALC262_HP_BPC), 12752 ALC262_HP_BPC),
12753 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12754 ALC262_HP_BPC),
12755 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12756 ALC262_AUTO),
12312 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", 12757 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12313 ALC262_HP_BPC), 12758 ALC262_HP_BPC),
12314 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 12759 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
@@ -12352,7 +12797,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
12352 {} 12797 {}
12353}; 12798};
12354 12799
12355static struct alc_config_preset alc262_presets[] = { 12800static const struct alc_config_preset alc262_presets[] = {
12356 [ALC262_BASIC] = { 12801 [ALC262_BASIC] = {
12357 .mixers = { alc262_base_mixer }, 12802 .mixers = { alc262_base_mixer },
12358 .init_verbs = { alc262_init_verbs }, 12803 .init_verbs = { alc262_init_verbs },
@@ -12373,9 +12818,9 @@ static struct alc_config_preset alc262_presets[] = {
12373 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12818 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12374 .channel_mode = alc262_modes, 12819 .channel_mode = alc262_modes,
12375 .input_mux = &alc262_capture_source, 12820 .input_mux = &alc262_capture_source,
12376 .unsol_event = alc262_hippo_unsol_event, 12821 .unsol_event = alc_sku_unsol_event,
12377 .setup = alc262_hippo_setup, 12822 .setup = alc262_hippo_setup,
12378 .init_hook = alc262_hippo_automute, 12823 .init_hook = alc_inithook,
12379 }, 12824 },
12380 [ALC262_HIPPO_1] = { 12825 [ALC262_HIPPO_1] = {
12381 .mixers = { alc262_hippo1_mixer }, 12826 .mixers = { alc262_hippo1_mixer },
@@ -12387,9 +12832,9 @@ static struct alc_config_preset alc262_presets[] = {
12387 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12832 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12388 .channel_mode = alc262_modes, 12833 .channel_mode = alc262_modes,
12389 .input_mux = &alc262_capture_source, 12834 .input_mux = &alc262_capture_source,
12390 .unsol_event = alc262_hippo_unsol_event, 12835 .unsol_event = alc_sku_unsol_event,
12391 .setup = alc262_hippo1_setup, 12836 .setup = alc262_hippo1_setup,
12392 .init_hook = alc262_hippo_automute, 12837 .init_hook = alc_inithook,
12393 }, 12838 },
12394 [ALC262_FUJITSU] = { 12839 [ALC262_FUJITSU] = {
12395 .mixers = { alc262_fujitsu_mixer }, 12840 .mixers = { alc262_fujitsu_mixer },
@@ -12402,8 +12847,9 @@ static struct alc_config_preset alc262_presets[] = {
12402 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12847 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12403 .channel_mode = alc262_modes, 12848 .channel_mode = alc262_modes,
12404 .input_mux = &alc262_fujitsu_capture_source, 12849 .input_mux = &alc262_fujitsu_capture_source,
12405 .unsol_event = alc262_fujitsu_unsol_event, 12850 .unsol_event = alc_sku_unsol_event,
12406 .init_hook = alc262_fujitsu_init_hook, 12851 .setup = alc262_fujitsu_setup,
12852 .init_hook = alc_inithook,
12407 }, 12853 },
12408 [ALC262_HP_BPC] = { 12854 [ALC262_HP_BPC] = {
12409 .mixers = { alc262_HP_BPC_mixer }, 12855 .mixers = { alc262_HP_BPC_mixer },
@@ -12414,8 +12860,9 @@ static struct alc_config_preset alc262_presets[] = {
12414 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12860 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12415 .channel_mode = alc262_modes, 12861 .channel_mode = alc262_modes,
12416 .input_mux = &alc262_HP_capture_source, 12862 .input_mux = &alc262_HP_capture_source,
12417 .unsol_event = alc262_hp_bpc_unsol_event, 12863 .unsol_event = alc_sku_unsol_event,
12418 .init_hook = alc262_hp_bpc_automute, 12864 .setup = alc262_hp_bpc_setup,
12865 .init_hook = alc_inithook,
12419 }, 12866 },
12420 [ALC262_HP_BPC_D7000_WF] = { 12867 [ALC262_HP_BPC_D7000_WF] = {
12421 .mixers = { alc262_HP_BPC_WildWest_mixer }, 12868 .mixers = { alc262_HP_BPC_WildWest_mixer },
@@ -12426,8 +12873,9 @@ static struct alc_config_preset alc262_presets[] = {
12426 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12873 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12427 .channel_mode = alc262_modes, 12874 .channel_mode = alc262_modes,
12428 .input_mux = &alc262_HP_D7000_capture_source, 12875 .input_mux = &alc262_HP_D7000_capture_source,
12429 .unsol_event = alc262_hp_wildwest_unsol_event, 12876 .unsol_event = alc_sku_unsol_event,
12430 .init_hook = alc262_hp_wildwest_automute, 12877 .setup = alc262_hp_wildwest_setup,
12878 .init_hook = alc_inithook,
12431 }, 12879 },
12432 [ALC262_HP_BPC_D7000_WL] = { 12880 [ALC262_HP_BPC_D7000_WL] = {
12433 .mixers = { alc262_HP_BPC_WildWest_mixer, 12881 .mixers = { alc262_HP_BPC_WildWest_mixer,
@@ -12439,8 +12887,9 @@ static struct alc_config_preset alc262_presets[] = {
12439 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12887 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12440 .channel_mode = alc262_modes, 12888 .channel_mode = alc262_modes,
12441 .input_mux = &alc262_HP_D7000_capture_source, 12889 .input_mux = &alc262_HP_D7000_capture_source,
12442 .unsol_event = alc262_hp_wildwest_unsol_event, 12890 .unsol_event = alc_sku_unsol_event,
12443 .init_hook = alc262_hp_wildwest_automute, 12891 .setup = alc262_hp_wildwest_setup,
12892 .init_hook = alc_inithook,
12444 }, 12893 },
12445 [ALC262_HP_TC_T5735] = { 12894 [ALC262_HP_TC_T5735] = {
12446 .mixers = { alc262_hp_t5735_mixer }, 12895 .mixers = { alc262_hp_t5735_mixer },
@@ -12483,9 +12932,9 @@ static struct alc_config_preset alc262_presets[] = {
12483 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12932 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12484 .channel_mode = alc262_modes, 12933 .channel_mode = alc262_modes,
12485 .input_mux = &alc262_capture_source, 12934 .input_mux = &alc262_capture_source,
12486 .unsol_event = alc262_hippo_unsol_event, 12935 .unsol_event = alc_sku_unsol_event,
12487 .setup = alc262_hippo_setup, 12936 .setup = alc262_hippo_setup,
12488 .init_hook = alc262_hippo_automute, 12937 .init_hook = alc_inithook,
12489 }, 12938 },
12490 [ALC262_BENQ_T31] = { 12939 [ALC262_BENQ_T31] = {
12491 .mixers = { alc262_benq_t31_mixer }, 12940 .mixers = { alc262_benq_t31_mixer },
@@ -12497,9 +12946,9 @@ static struct alc_config_preset alc262_presets[] = {
12497 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12946 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12498 .channel_mode = alc262_modes, 12947 .channel_mode = alc262_modes,
12499 .input_mux = &alc262_capture_source, 12948 .input_mux = &alc262_capture_source,
12500 .unsol_event = alc262_hippo_unsol_event, 12949 .unsol_event = alc_sku_unsol_event,
12501 .setup = alc262_hippo_setup, 12950 .setup = alc262_hippo_setup,
12502 .init_hook = alc262_hippo_automute, 12951 .init_hook = alc_inithook,
12503 }, 12952 },
12504 [ALC262_ULTRA] = { 12953 [ALC262_ULTRA] = {
12505 .mixers = { alc262_ultra_mixer }, 12954 .mixers = { alc262_ultra_mixer },
@@ -12528,7 +12977,9 @@ static struct alc_config_preset alc262_presets[] = {
12528 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12977 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12529 .channel_mode = alc262_modes, 12978 .channel_mode = alc262_modes,
12530 .input_mux = &alc262_fujitsu_capture_source, 12979 .input_mux = &alc262_fujitsu_capture_source,
12531 .unsol_event = alc262_lenovo_3000_unsol_event, 12980 .unsol_event = alc_sku_unsol_event,
12981 .setup = alc262_lenovo_3000_setup,
12982 .init_hook = alc_inithook,
12532 }, 12983 },
12533 [ALC262_NEC] = { 12984 [ALC262_NEC] = {
12534 .mixers = { alc262_nec_mixer }, 12985 .mixers = { alc262_nec_mixer },
@@ -12565,9 +13016,9 @@ static struct alc_config_preset alc262_presets[] = {
12565 .num_channel_mode = ARRAY_SIZE(alc262_modes), 13016 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12566 .channel_mode = alc262_modes, 13017 .channel_mode = alc262_modes,
12567 .input_mux = &alc262_capture_source, 13018 .input_mux = &alc262_capture_source,
12568 .unsol_event = alc262_hippo_unsol_event, 13019 .unsol_event = alc_sku_unsol_event,
12569 .setup = alc262_hippo_setup, 13020 .setup = alc262_hippo_setup,
12570 .init_hook = alc262_hippo_automute, 13021 .init_hook = alc_inithook,
12571 }, 13022 },
12572 [ALC262_TYAN] = { 13023 [ALC262_TYAN] = {
12573 .mixers = { alc262_tyan_mixer }, 13024 .mixers = { alc262_tyan_mixer },
@@ -12579,9 +13030,9 @@ static struct alc_config_preset alc262_presets[] = {
12579 .num_channel_mode = ARRAY_SIZE(alc262_modes), 13030 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12580 .channel_mode = alc262_modes, 13031 .channel_mode = alc262_modes,
12581 .input_mux = &alc262_capture_source, 13032 .input_mux = &alc262_capture_source,
12582 .unsol_event = alc_automute_amp_unsol_event, 13033 .unsol_event = alc_sku_unsol_event,
12583 .setup = alc262_tyan_setup, 13034 .setup = alc262_tyan_setup,
12584 .init_hook = alc_automute_amp, 13035 .init_hook = alc_hp_automute,
12585 }, 13036 },
12586}; 13037};
12587 13038
@@ -12623,6 +13074,11 @@ static int patch_alc262(struct hda_codec *codec)
12623 } 13074 }
12624 13075
12625 if (board_config == ALC262_AUTO) { 13076 if (board_config == ALC262_AUTO) {
13077 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
13078 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
13079 }
13080
13081 if (board_config == ALC262_AUTO) {
12626 /* automatic parse from the BIOS config */ 13082 /* automatic parse from the BIOS config */
12627 err = alc262_parse_auto_config(codec); 13083 err = alc262_parse_auto_config(codec);
12628 if (err < 0) { 13084 if (err < 0) {
@@ -12690,11 +13146,16 @@ static int patch_alc262(struct hda_codec *codec)
12690 if (!spec->no_analog && has_cdefine_beep(codec)) 13146 if (!spec->no_analog && has_cdefine_beep(codec))
12691 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 13147 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
12692 13148
13149 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
13150
12693 spec->vmaster_nid = 0x0c; 13151 spec->vmaster_nid = 0x0c;
12694 13152
12695 codec->patch_ops = alc_patch_ops; 13153 codec->patch_ops = alc_patch_ops;
12696 if (board_config == ALC262_AUTO) 13154 if (board_config == ALC262_AUTO)
12697 spec->init_hook = alc262_auto_init; 13155 spec->init_hook = alc262_auto_init;
13156 spec->shutup = alc_eapd_shutup;
13157
13158 alc_init_jacks(codec);
12698#ifdef CONFIG_SND_HDA_POWER_SAVE 13159#ifdef CONFIG_SND_HDA_POWER_SAVE
12699 if (!spec->loopback.amplist) 13160 if (!spec->loopback.amplist)
12700 spec->loopback.amplist = alc262_loopbacks; 13161 spec->loopback.amplist = alc262_loopbacks;
@@ -12709,48 +13170,48 @@ static int patch_alc262(struct hda_codec *codec)
12709#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 13170#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12710#define alc268_modes alc260_modes 13171#define alc268_modes alc260_modes
12711 13172
12712static hda_nid_t alc268_dac_nids[2] = { 13173static const hda_nid_t alc268_dac_nids[2] = {
12713 /* front, hp */ 13174 /* front, hp */
12714 0x02, 0x03 13175 0x02, 0x03
12715}; 13176};
12716 13177
12717static hda_nid_t alc268_adc_nids[2] = { 13178static const hda_nid_t alc268_adc_nids[2] = {
12718 /* ADC0-1 */ 13179 /* ADC0-1 */
12719 0x08, 0x07 13180 0x08, 0x07
12720}; 13181};
12721 13182
12722static hda_nid_t alc268_adc_nids_alt[1] = { 13183static const hda_nid_t alc268_adc_nids_alt[1] = {
12723 /* ADC0 */ 13184 /* ADC0 */
12724 0x08 13185 0x08
12725}; 13186};
12726 13187
12727static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; 13188static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12728 13189
12729static struct snd_kcontrol_new alc268_base_mixer[] = { 13190static const struct snd_kcontrol_new alc268_base_mixer[] = {
12730 /* output mixer control */ 13191 /* output mixer control */
12731 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13192 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12732 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13193 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12733 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13194 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12734 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13195 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12735 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13196 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12736 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 13197 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12737 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 13198 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12738 { } 13199 { }
12739}; 13200};
12740 13201
12741static struct snd_kcontrol_new alc268_toshiba_mixer[] = { 13202static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12742 /* output mixer control */ 13203 /* output mixer control */
12743 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13204 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12744 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13205 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12745 ALC262_HIPPO_MASTER_SWITCH, 13206 ALC262_HIPPO_MASTER_SWITCH,
12746 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13207 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12747 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 13208 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12748 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 13209 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12749 { } 13210 { }
12750}; 13211};
12751 13212
12752/* bind Beep switches of both NID 0x0f and 0x10 */ 13213/* bind Beep switches of both NID 0x0f and 0x10 */
12753static struct hda_bind_ctls alc268_bind_beep_sw = { 13214static const struct hda_bind_ctls alc268_bind_beep_sw = {
12754 .ops = &snd_hda_bind_sw, 13215 .ops = &snd_hda_bind_sw,
12755 .values = { 13216 .values = {
12756 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), 13217 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
@@ -12759,27 +13220,27 @@ static struct hda_bind_ctls alc268_bind_beep_sw = {
12759 }, 13220 },
12760}; 13221};
12761 13222
12762static struct snd_kcontrol_new alc268_beep_mixer[] = { 13223static const struct snd_kcontrol_new alc268_beep_mixer[] = {
12763 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), 13224 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12764 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), 13225 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12765 { } 13226 { }
12766}; 13227};
12767 13228
12768static struct hda_verb alc268_eapd_verbs[] = { 13229static const struct hda_verb alc268_eapd_verbs[] = {
12769 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13230 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12770 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13231 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12771 { } 13232 { }
12772}; 13233};
12773 13234
12774/* Toshiba specific */ 13235/* Toshiba specific */
12775static struct hda_verb alc268_toshiba_verbs[] = { 13236static const struct hda_verb alc268_toshiba_verbs[] = {
12776 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13237 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12777 { } /* end */ 13238 { } /* end */
12778}; 13239};
12779 13240
12780/* Acer specific */ 13241/* Acer specific */
12781/* bind volumes of both NID 0x02 and 0x03 */ 13242/* bind volumes of both NID 0x02 and 0x03 */
12782static struct hda_bind_ctls alc268_acer_bind_master_vol = { 13243static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
12783 .ops = &snd_hda_bind_vol, 13244 .ops = &snd_hda_bind_vol,
12784 .values = { 13245 .values = {
12785 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 13246 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
@@ -12788,91 +13249,68 @@ static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12788 }, 13249 },
12789}; 13250};
12790 13251
12791/* mute/unmute internal speaker according to the hp jack and mute state */ 13252static void alc268_acer_setup(struct hda_codec *codec)
12792static void alc268_acer_automute(struct hda_codec *codec, int force)
12793{ 13253{
12794 struct alc_spec *spec = codec->spec; 13254 struct alc_spec *spec = codec->spec;
12795 unsigned int mute;
12796 13255
12797 if (force || !spec->sense_updated) { 13256 spec->autocfg.hp_pins[0] = 0x14;
12798 spec->jack_present = snd_hda_jack_detect(codec, 0x14); 13257 spec->autocfg.speaker_pins[0] = 0x15;
12799 spec->sense_updated = 1; 13258 spec->automute = 1;
12800 } 13259 spec->automute_mode = ALC_AUTOMUTE_AMP;
12801 if (spec->jack_present)
12802 mute = HDA_AMP_MUTE; /* mute internal speaker */
12803 else /* unmute internal speaker if necessary */
12804 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12805 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12806 HDA_AMP_MUTE, mute);
12807} 13260}
12808 13261
13262#define alc268_acer_master_sw_get alc262_hp_master_sw_get
13263#define alc268_acer_master_sw_put alc262_hp_master_sw_put
12809 13264
12810/* bind hp and internal speaker mute (with plug check) */ 13265static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12811static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12812 struct snd_ctl_elem_value *ucontrol)
12813{
12814 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12815 long *valp = ucontrol->value.integer.value;
12816 int change;
12817
12818 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
12819 if (change)
12820 alc268_acer_automute(codec, 0);
12821 return change;
12822}
12823
12824static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12825 /* output mixer control */ 13266 /* output mixer control */
12826 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13267 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12827 { 13268 {
12828 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13269 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12829 .name = "Master Playback Switch", 13270 .name = "Master Playback Switch",
12830 .subdevice = HDA_SUBDEV_AMP_FLAG, 13271 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
12831 .info = snd_hda_mixer_amp_switch_info, 13272 .info = snd_ctl_boolean_mono_info,
12832 .get = snd_hda_mixer_amp_switch_get, 13273 .get = alc268_acer_master_sw_get,
12833 .put = alc268_acer_master_sw_put, 13274 .put = alc268_acer_master_sw_put,
12834 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12835 }, 13275 },
12836 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), 13276 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12837 { } 13277 { }
12838}; 13278};
12839 13279
12840static struct snd_kcontrol_new alc268_acer_mixer[] = { 13280static const struct snd_kcontrol_new alc268_acer_mixer[] = {
12841 /* output mixer control */ 13281 /* output mixer control */
12842 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13282 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12843 { 13283 {
12844 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13284 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12845 .name = "Master Playback Switch", 13285 .name = "Master Playback Switch",
12846 .subdevice = HDA_SUBDEV_AMP_FLAG, 13286 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12847 .info = snd_hda_mixer_amp_switch_info, 13287 .info = snd_ctl_boolean_mono_info,
12848 .get = snd_hda_mixer_amp_switch_get, 13288 .get = alc268_acer_master_sw_get,
12849 .put = alc268_acer_master_sw_put, 13289 .put = alc268_acer_master_sw_put,
12850 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12851 }, 13290 },
12852 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13291 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12853 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 13292 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12854 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 13293 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12855 { } 13294 { }
12856}; 13295};
12857 13296
12858static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { 13297static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12859 /* output mixer control */ 13298 /* output mixer control */
12860 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13299 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12861 { 13300 {
12862 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13301 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12863 .name = "Master Playback Switch", 13302 .name = "Master Playback Switch",
12864 .subdevice = HDA_SUBDEV_AMP_FLAG, 13303 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12865 .info = snd_hda_mixer_amp_switch_info, 13304 .info = snd_ctl_boolean_mono_info,
12866 .get = snd_hda_mixer_amp_switch_get, 13305 .get = alc268_acer_master_sw_get,
12867 .put = alc268_acer_master_sw_put, 13306 .put = alc268_acer_master_sw_put,
12868 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12869 }, 13307 },
12870 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13308 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12871 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 13309 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12872 { } 13310 { }
12873}; 13311};
12874 13312
12875static struct hda_verb alc268_acer_aspire_one_verbs[] = { 13313static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
12876 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13314 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12877 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13315 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12878 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13316 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
@@ -12882,7 +13320,7 @@ static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12882 { } 13320 { }
12883}; 13321};
12884 13322
12885static struct hda_verb alc268_acer_verbs[] = { 13323static const struct hda_verb alc268_acer_verbs[] = {
12886 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ 13324 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12887 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13325 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12888 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -12894,53 +13332,15 @@ static struct hda_verb alc268_acer_verbs[] = {
12894}; 13332};
12895 13333
12896/* unsolicited event for HP jack sensing */ 13334/* unsolicited event for HP jack sensing */
12897#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
12898#define alc268_toshiba_setup alc262_hippo_setup 13335#define alc268_toshiba_setup alc262_hippo_setup
12899#define alc268_toshiba_automute alc262_hippo_automute
12900
12901static void alc268_acer_unsol_event(struct hda_codec *codec,
12902 unsigned int res)
12903{
12904 if ((res >> 26) != ALC880_HP_EVENT)
12905 return;
12906 alc268_acer_automute(codec, 1);
12907}
12908
12909static void alc268_acer_init_hook(struct hda_codec *codec)
12910{
12911 alc268_acer_automute(codec, 1);
12912}
12913
12914/* toggle speaker-output according to the hp-jack state */
12915static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12916{
12917 unsigned int present;
12918 unsigned char bits;
12919
12920 present = snd_hda_jack_detect(codec, 0x15);
12921 bits = present ? HDA_AMP_MUTE : 0;
12922 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
12923 HDA_AMP_MUTE, bits);
12924 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
12925 HDA_AMP_MUTE, bits);
12926}
12927
12928static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12929 unsigned int res)
12930{
12931 switch (res >> 26) {
12932 case ALC880_HP_EVENT:
12933 alc268_aspire_one_speaker_automute(codec);
12934 break;
12935 case ALC880_MIC_EVENT:
12936 alc_mic_automute(codec);
12937 break;
12938 }
12939}
12940 13336
12941static void alc268_acer_lc_setup(struct hda_codec *codec) 13337static void alc268_acer_lc_setup(struct hda_codec *codec)
12942{ 13338{
12943 struct alc_spec *spec = codec->spec; 13339 struct alc_spec *spec = codec->spec;
13340 spec->autocfg.hp_pins[0] = 0x15;
13341 spec->autocfg.speaker_pins[0] = 0x14;
13342 spec->automute = 1;
13343 spec->automute_mode = ALC_AUTOMUTE_AMP;
12944 spec->ext_mic.pin = 0x18; 13344 spec->ext_mic.pin = 0x18;
12945 spec->ext_mic.mux_idx = 0; 13345 spec->ext_mic.mux_idx = 0;
12946 spec->int_mic.pin = 0x12; 13346 spec->int_mic.pin = 0x12;
@@ -12948,24 +13348,18 @@ static void alc268_acer_lc_setup(struct hda_codec *codec)
12948 spec->auto_mic = 1; 13348 spec->auto_mic = 1;
12949} 13349}
12950 13350
12951static void alc268_acer_lc_init_hook(struct hda_codec *codec) 13351static const struct snd_kcontrol_new alc268_dell_mixer[] = {
12952{
12953 alc268_aspire_one_speaker_automute(codec);
12954 alc_mic_automute(codec);
12955}
12956
12957static struct snd_kcontrol_new alc268_dell_mixer[] = {
12958 /* output mixer control */ 13352 /* output mixer control */
12959 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13353 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12960 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13354 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12961 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13355 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12962 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13356 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12963 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13357 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12964 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 13358 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12965 { } 13359 { }
12966}; 13360};
12967 13361
12968static struct hda_verb alc268_dell_verbs[] = { 13362static const struct hda_verb alc268_dell_verbs[] = {
12969 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12970 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13364 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12971 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13365 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
@@ -12985,21 +13379,23 @@ static void alc268_dell_setup(struct hda_codec *codec)
12985 spec->int_mic.pin = 0x19; 13379 spec->int_mic.pin = 0x19;
12986 spec->int_mic.mux_idx = 1; 13380 spec->int_mic.mux_idx = 1;
12987 spec->auto_mic = 1; 13381 spec->auto_mic = 1;
13382 spec->automute = 1;
13383 spec->automute_mode = ALC_AUTOMUTE_PIN;
12988} 13384}
12989 13385
12990static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { 13386static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12991 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13387 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12992 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13388 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12993 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13389 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12994 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13390 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12995 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13391 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12996 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), 13392 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12997 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 13393 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12998 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 13394 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12999 { } 13395 { }
13000}; 13396};
13001 13397
13002static struct hda_verb alc267_quanta_il1_verbs[] = { 13398static const struct hda_verb alc267_quanta_il1_verbs[] = {
13003 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13399 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13004 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 13400 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13005 { } 13401 { }
@@ -13015,12 +13411,14 @@ static void alc267_quanta_il1_setup(struct hda_codec *codec)
13015 spec->int_mic.pin = 0x19; 13411 spec->int_mic.pin = 0x19;
13016 spec->int_mic.mux_idx = 1; 13412 spec->int_mic.mux_idx = 1;
13017 spec->auto_mic = 1; 13413 spec->auto_mic = 1;
13414 spec->automute = 1;
13415 spec->automute_mode = ALC_AUTOMUTE_PIN;
13018} 13416}
13019 13417
13020/* 13418/*
13021 * generic initialization of ADC, input mixers and output mixers 13419 * generic initialization of ADC, input mixers and output mixers
13022 */ 13420 */
13023static struct hda_verb alc268_base_init_verbs[] = { 13421static const struct hda_verb alc268_base_init_verbs[] = {
13024 /* Unmute DAC0-1 and set vol = 0 */ 13422 /* Unmute DAC0-1 and set vol = 0 */
13025 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13423 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13026 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13424 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -13068,7 +13466,7 @@ static struct hda_verb alc268_base_init_verbs[] = {
13068/* 13466/*
13069 * generic initialization of ADC, input mixers and output mixers 13467 * generic initialization of ADC, input mixers and output mixers
13070 */ 13468 */
13071static struct hda_verb alc268_volume_init_verbs[] = { 13469static const struct hda_verb alc268_volume_init_verbs[] = {
13072 /* set output DAC */ 13470 /* set output DAC */
13073 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13471 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13074 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13472 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -13094,20 +13492,20 @@ static struct hda_verb alc268_volume_init_verbs[] = {
13094 { } 13492 { }
13095}; 13493};
13096 13494
13097static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { 13495static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13098 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13496 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13099 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13497 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13100 { } /* end */ 13498 { } /* end */
13101}; 13499};
13102 13500
13103static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 13501static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13104 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13502 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13105 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13503 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13106 _DEFINE_CAPSRC(1), 13504 _DEFINE_CAPSRC(1),
13107 { } /* end */ 13505 { } /* end */
13108}; 13506};
13109 13507
13110static struct snd_kcontrol_new alc268_capture_mixer[] = { 13508static const struct snd_kcontrol_new alc268_capture_mixer[] = {
13111 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13509 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13112 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13510 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13113 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 13511 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
@@ -13116,7 +13514,7 @@ static struct snd_kcontrol_new alc268_capture_mixer[] = {
13116 { } /* end */ 13514 { } /* end */
13117}; 13515};
13118 13516
13119static struct hda_input_mux alc268_capture_source = { 13517static const struct hda_input_mux alc268_capture_source = {
13120 .num_items = 4, 13518 .num_items = 4,
13121 .items = { 13519 .items = {
13122 { "Mic", 0x0 }, 13520 { "Mic", 0x0 },
@@ -13126,7 +13524,7 @@ static struct hda_input_mux alc268_capture_source = {
13126 }, 13524 },
13127}; 13525};
13128 13526
13129static struct hda_input_mux alc268_acer_capture_source = { 13527static const struct hda_input_mux alc268_acer_capture_source = {
13130 .num_items = 3, 13528 .num_items = 3,
13131 .items = { 13529 .items = {
13132 { "Mic", 0x0 }, 13530 { "Mic", 0x0 },
@@ -13135,7 +13533,7 @@ static struct hda_input_mux alc268_acer_capture_source = {
13135 }, 13533 },
13136}; 13534};
13137 13535
13138static struct hda_input_mux alc268_acer_dmic_capture_source = { 13536static const struct hda_input_mux alc268_acer_dmic_capture_source = {
13139 .num_items = 3, 13537 .num_items = 3,
13140 .items = { 13538 .items = {
13141 { "Mic", 0x0 }, 13539 { "Mic", 0x0 },
@@ -13145,7 +13543,7 @@ static struct hda_input_mux alc268_acer_dmic_capture_source = {
13145}; 13543};
13146 13544
13147#ifdef CONFIG_SND_DEBUG 13545#ifdef CONFIG_SND_DEBUG
13148static struct snd_kcontrol_new alc268_test_mixer[] = { 13546static const struct snd_kcontrol_new alc268_test_mixer[] = {
13149 /* Volume widgets */ 13547 /* Volume widgets */
13150 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13548 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13151 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13549 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -13224,7 +13622,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13224 HDA_OUTPUT)); 13622 HDA_OUTPUT));
13225 if (err < 0) 13623 if (err < 0)
13226 return err; 13624 return err;
13227 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 13625 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
13228 } 13626 }
13229 13627
13230 if (nid != 0x16) 13628 if (nid != 0x16)
@@ -13310,8 +13708,10 @@ static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13310static void alc268_auto_init_multi_out(struct hda_codec *codec) 13708static void alc268_auto_init_multi_out(struct hda_codec *codec)
13311{ 13709{
13312 struct alc_spec *spec = codec->spec; 13710 struct alc_spec *spec = codec->spec;
13313 hda_nid_t nid = spec->autocfg.line_out_pins[0]; 13711 int i;
13314 if (nid) { 13712
13713 for (i = 0; i < spec->autocfg.line_outs; i++) {
13714 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13315 int pin_type = get_pin_type(spec->autocfg.line_out_type); 13715 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13316 alc268_auto_set_output_and_unmute(codec, nid, pin_type); 13716 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13317 } 13717 }
@@ -13321,13 +13721,19 @@ static void alc268_auto_init_hp_out(struct hda_codec *codec)
13321{ 13721{
13322 struct alc_spec *spec = codec->spec; 13722 struct alc_spec *spec = codec->spec;
13323 hda_nid_t pin; 13723 hda_nid_t pin;
13724 int i;
13324 13725
13325 pin = spec->autocfg.hp_pins[0]; 13726 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13326 if (pin) 13727 pin = spec->autocfg.hp_pins[i];
13327 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP); 13728 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13328 pin = spec->autocfg.speaker_pins[0]; 13729 }
13329 if (pin) 13730 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13731 pin = spec->autocfg.speaker_pins[i];
13330 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT); 13732 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13733 }
13734 if (spec->autocfg.mono_out_pin)
13735 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13736 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13331} 13737}
13332 13738
13333static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 13739static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
@@ -13389,7 +13795,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
13389{ 13795{
13390 struct alc_spec *spec = codec->spec; 13796 struct alc_spec *spec = codec->spec;
13391 int err; 13797 int err;
13392 static hda_nid_t alc268_ignore[] = { 0 }; 13798 static const hda_nid_t alc268_ignore[] = { 0 };
13393 13799
13394 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13800 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13395 alc268_ignore); 13801 alc268_ignore);
@@ -13435,6 +13841,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
13435} 13841}
13436 13842
13437#define alc268_auto_init_analog_input alc882_auto_init_analog_input 13843#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13844#define alc268_auto_init_input_src alc882_auto_init_input_src
13438 13845
13439/* init callback for auto-configuration model -- overriding the default init */ 13846/* init callback for auto-configuration model -- overriding the default init */
13440static void alc268_auto_init(struct hda_codec *codec) 13847static void alc268_auto_init(struct hda_codec *codec)
@@ -13444,6 +13851,7 @@ static void alc268_auto_init(struct hda_codec *codec)
13444 alc268_auto_init_hp_out(codec); 13851 alc268_auto_init_hp_out(codec);
13445 alc268_auto_init_mono_speaker_out(codec); 13852 alc268_auto_init_mono_speaker_out(codec);
13446 alc268_auto_init_analog_input(codec); 13853 alc268_auto_init_analog_input(codec);
13854 alc268_auto_init_input_src(codec);
13447 alc_auto_init_digital(codec); 13855 alc_auto_init_digital(codec);
13448 if (spec->unsol_event) 13856 if (spec->unsol_event)
13449 alc_inithook(codec); 13857 alc_inithook(codec);
@@ -13452,7 +13860,7 @@ static void alc268_auto_init(struct hda_codec *codec)
13452/* 13860/*
13453 * configuration and preset 13861 * configuration and preset
13454 */ 13862 */
13455static const char *alc268_models[ALC268_MODEL_LAST] = { 13863static const char * const alc268_models[ALC268_MODEL_LAST] = {
13456 [ALC267_QUANTA_IL1] = "quanta-il1", 13864 [ALC267_QUANTA_IL1] = "quanta-il1",
13457 [ALC268_3ST] = "3stack", 13865 [ALC268_3ST] = "3stack",
13458 [ALC268_TOSHIBA] = "toshiba", 13866 [ALC268_TOSHIBA] = "toshiba",
@@ -13467,7 +13875,7 @@ static const char *alc268_models[ALC268_MODEL_LAST] = {
13467 [ALC268_AUTO] = "auto", 13875 [ALC268_AUTO] = "auto",
13468}; 13876};
13469 13877
13470static struct snd_pci_quirk alc268_cfg_tbl[] = { 13878static const struct snd_pci_quirk alc268_cfg_tbl[] = {
13471 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), 13879 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13472 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 13880 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13473 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), 13881 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
@@ -13476,6 +13884,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
13476 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", 13884 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13477 ALC268_ACER_ASPIRE_ONE), 13885 ALC268_ACER_ASPIRE_ONE),
13478 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), 13886 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13887 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
13479 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0, 13888 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13480 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL), 13889 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13481 /* almost compatible with toshiba but with optional digital outs; 13890 /* almost compatible with toshiba but with optional digital outs;
@@ -13486,13 +13895,12 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
13486 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 13895 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13487 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), 13896 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13488 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), 13897 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13489 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
13490 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), 13898 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13491 {} 13899 {}
13492}; 13900};
13493 13901
13494/* Toshiba laptops have no unique PCI SSID but only codec SSID */ 13902/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13495static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { 13903static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13496 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO), 13904 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13497 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO), 13905 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13498 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", 13906 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
@@ -13500,7 +13908,7 @@ static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13500 {} 13908 {}
13501}; 13909};
13502 13910
13503static struct alc_config_preset alc268_presets[] = { 13911static const struct alc_config_preset alc268_presets[] = {
13504 [ALC267_QUANTA_IL1] = { 13912 [ALC267_QUANTA_IL1] = {
13505 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer, 13913 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13506 alc268_capture_nosrc_mixer }, 13914 alc268_capture_nosrc_mixer },
@@ -13546,9 +13954,9 @@ static struct alc_config_preset alc268_presets[] = {
13546 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13954 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13547 .channel_mode = alc268_modes, 13955 .channel_mode = alc268_modes,
13548 .input_mux = &alc268_capture_source, 13956 .input_mux = &alc268_capture_source,
13549 .unsol_event = alc268_toshiba_unsol_event, 13957 .unsol_event = alc_sku_unsol_event,
13550 .setup = alc268_toshiba_setup, 13958 .setup = alc268_toshiba_setup,
13551 .init_hook = alc268_toshiba_automute, 13959 .init_hook = alc_inithook,
13552 }, 13960 },
13553 [ALC268_ACER] = { 13961 [ALC268_ACER] = {
13554 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, 13962 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
@@ -13564,8 +13972,9 @@ static struct alc_config_preset alc268_presets[] = {
13564 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13972 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13565 .channel_mode = alc268_modes, 13973 .channel_mode = alc268_modes,
13566 .input_mux = &alc268_acer_capture_source, 13974 .input_mux = &alc268_acer_capture_source,
13567 .unsol_event = alc268_acer_unsol_event, 13975 .unsol_event = alc_sku_unsol_event,
13568 .init_hook = alc268_acer_init_hook, 13976 .setup = alc268_acer_setup,
13977 .init_hook = alc_inithook,
13569 }, 13978 },
13570 [ALC268_ACER_DMIC] = { 13979 [ALC268_ACER_DMIC] = {
13571 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, 13980 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
@@ -13581,8 +13990,9 @@ static struct alc_config_preset alc268_presets[] = {
13581 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13990 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13582 .channel_mode = alc268_modes, 13991 .channel_mode = alc268_modes,
13583 .input_mux = &alc268_acer_dmic_capture_source, 13992 .input_mux = &alc268_acer_dmic_capture_source,
13584 .unsol_event = alc268_acer_unsol_event, 13993 .unsol_event = alc_sku_unsol_event,
13585 .init_hook = alc268_acer_init_hook, 13994 .setup = alc268_acer_setup,
13995 .init_hook = alc_inithook,
13586 }, 13996 },
13587 [ALC268_ACER_ASPIRE_ONE] = { 13997 [ALC268_ACER_ASPIRE_ONE] = {
13588 .mixers = { alc268_acer_aspire_one_mixer, 13998 .mixers = { alc268_acer_aspire_one_mixer,
@@ -13598,9 +14008,9 @@ static struct alc_config_preset alc268_presets[] = {
13598 .hp_nid = 0x03, 14008 .hp_nid = 0x03,
13599 .num_channel_mode = ARRAY_SIZE(alc268_modes), 14009 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13600 .channel_mode = alc268_modes, 14010 .channel_mode = alc268_modes,
13601 .unsol_event = alc268_acer_lc_unsol_event, 14011 .unsol_event = alc_sku_unsol_event,
13602 .setup = alc268_acer_lc_setup, 14012 .setup = alc268_acer_lc_setup,
13603 .init_hook = alc268_acer_lc_init_hook, 14013 .init_hook = alc_inithook,
13604 }, 14014 },
13605 [ALC268_DELL] = { 14015 [ALC268_DELL] = {
13606 .mixers = { alc268_dell_mixer, alc268_beep_mixer, 14016 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
@@ -13634,8 +14044,9 @@ static struct alc_config_preset alc268_presets[] = {
13634 .num_channel_mode = ARRAY_SIZE(alc268_modes), 14044 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13635 .channel_mode = alc268_modes, 14045 .channel_mode = alc268_modes,
13636 .input_mux = &alc268_capture_source, 14046 .input_mux = &alc268_capture_source,
14047 .unsol_event = alc_sku_unsol_event,
13637 .setup = alc268_toshiba_setup, 14048 .setup = alc268_toshiba_setup,
13638 .init_hook = alc268_toshiba_automute, 14049 .init_hook = alc_inithook,
13639 }, 14050 },
13640#ifdef CONFIG_SND_DEBUG 14051#ifdef CONFIG_SND_DEBUG
13641 [ALC268_TEST] = { 14052 [ALC268_TEST] = {
@@ -13731,7 +14142,6 @@ static int patch_alc268(struct hda_codec *codec)
13731 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { 14142 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
13732 /* check whether NID 0x07 is valid */ 14143 /* check whether NID 0x07 is valid */
13733 unsigned int wcap = get_wcaps(codec, 0x07); 14144 unsigned int wcap = get_wcaps(codec, 0x07);
13734 int i;
13735 14145
13736 spec->capsrc_nids = alc268_capsrc_nids; 14146 spec->capsrc_nids = alc268_capsrc_nids;
13737 /* get type */ 14147 /* get type */
@@ -13751,13 +14161,6 @@ static int patch_alc268(struct hda_codec *codec)
13751 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 14161 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
13752 add_mixer(spec, alc268_capture_mixer); 14162 add_mixer(spec, alc268_capture_mixer);
13753 } 14163 }
13754 /* set default input source */
13755 for (i = 0; i < spec->num_adc_nids; i++)
13756 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13757 0, AC_VERB_SET_CONNECT_SEL,
13758 i < spec->num_mux_defs ?
13759 spec->input_mux[i].items[0].index :
13760 spec->input_mux->items[0].index);
13761 } 14164 }
13762 14165
13763 spec->vmaster_nid = 0x02; 14166 spec->vmaster_nid = 0x02;
@@ -13765,6 +14168,9 @@ static int patch_alc268(struct hda_codec *codec)
13765 codec->patch_ops = alc_patch_ops; 14168 codec->patch_ops = alc_patch_ops;
13766 if (board_config == ALC268_AUTO) 14169 if (board_config == ALC268_AUTO)
13767 spec->init_hook = alc268_auto_init; 14170 spec->init_hook = alc268_auto_init;
14171 spec->shutup = alc_eapd_shutup;
14172
14173 alc_init_jacks(codec);
13768 14174
13769 return 0; 14175 return 0;
13770} 14176}
@@ -13776,48 +14182,48 @@ static int patch_alc268(struct hda_codec *codec)
13776 14182
13777#define alc269_dac_nids alc260_dac_nids 14183#define alc269_dac_nids alc260_dac_nids
13778 14184
13779static hda_nid_t alc269_adc_nids[1] = { 14185static const hda_nid_t alc269_adc_nids[1] = {
13780 /* ADC1 */ 14186 /* ADC1 */
13781 0x08, 14187 0x08,
13782}; 14188};
13783 14189
13784static hda_nid_t alc269_capsrc_nids[1] = { 14190static const hda_nid_t alc269_capsrc_nids[1] = {
13785 0x23, 14191 0x23,
13786}; 14192};
13787 14193
13788static hda_nid_t alc269vb_adc_nids[1] = { 14194static const hda_nid_t alc269vb_adc_nids[1] = {
13789 /* ADC1 */ 14195 /* ADC1 */
13790 0x09, 14196 0x09,
13791}; 14197};
13792 14198
13793static hda_nid_t alc269vb_capsrc_nids[1] = { 14199static const hda_nid_t alc269vb_capsrc_nids[1] = {
13794 0x22, 14200 0x22,
13795}; 14201};
13796 14202
13797static hda_nid_t alc269_adc_candidates[] = { 14203static const hda_nid_t alc269_adc_candidates[] = {
13798 0x08, 0x09, 0x07, 14204 0x08, 0x09, 0x07, 0x11,
13799}; 14205};
13800 14206
13801#define alc269_modes alc260_modes 14207#define alc269_modes alc260_modes
13802#define alc269_capture_source alc880_lg_lw_capture_source 14208#define alc269_capture_source alc880_lg_lw_capture_source
13803 14209
13804static struct snd_kcontrol_new alc269_base_mixer[] = { 14210static const struct snd_kcontrol_new alc269_base_mixer[] = {
13805 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14211 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13806 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14212 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13807 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 14213 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13808 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 14214 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13809 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14215 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13810 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14216 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13811 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14217 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13812 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14218 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13813 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14219 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13814 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 14220 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13815 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14221 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13816 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 14222 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13817 { } /* end */ 14223 { } /* end */
13818}; 14224};
13819 14225
13820static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { 14226static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13821 /* output mixer control */ 14227 /* output mixer control */
13822 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 14228 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13823 { 14229 {
@@ -13831,14 +14237,14 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13831 }, 14237 },
13832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14238 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13833 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14239 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13834 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14240 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13835 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14241 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13836 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14242 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13837 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 14243 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13838 { } 14244 { }
13839}; 14245};
13840 14246
13841static struct snd_kcontrol_new alc269_lifebook_mixer[] = { 14247static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13842 /* output mixer control */ 14248 /* output mixer control */
13843 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 14249 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13844 { 14250 {
@@ -13852,17 +14258,17 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13852 }, 14258 },
13853 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14259 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13854 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14260 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13855 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14261 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13856 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14262 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13857 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14263 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13858 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 14264 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13859 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), 14265 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13860 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), 14266 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13861 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT), 14267 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
13862 { } 14268 { }
13863}; 14269};
13864 14270
13865static struct snd_kcontrol_new alc269_laptop_mixer[] = { 14271static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
13866 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14272 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13867 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14273 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13868 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14274 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -13870,7 +14276,7 @@ static struct snd_kcontrol_new alc269_laptop_mixer[] = {
13870 { } /* end */ 14276 { } /* end */
13871}; 14277};
13872 14278
13873static struct snd_kcontrol_new alc269vb_laptop_mixer[] = { 14279static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13874 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14280 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13875 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14281 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13876 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 14282 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
@@ -13878,47 +14284,47 @@ static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13878 { } /* end */ 14284 { } /* end */
13879}; 14285};
13880 14286
13881static struct snd_kcontrol_new alc269_asus_mixer[] = { 14287static const struct snd_kcontrol_new alc269_asus_mixer[] = {
13882 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14288 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13883 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT), 14289 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
13884 { } /* end */ 14290 { } /* end */
13885}; 14291};
13886 14292
13887/* capture mixer elements */ 14293/* capture mixer elements */
13888static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { 14294static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13889 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14295 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13890 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14296 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13891 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14297 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13892 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), 14298 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13893 { } /* end */ 14299 { } /* end */
13894}; 14300};
13895 14301
13896static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { 14302static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
13897 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14303 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13898 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14304 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13899 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14305 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13900 { } /* end */ 14306 { } /* end */
13901}; 14307};
13902 14308
13903static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { 14309static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13904 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14310 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13905 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14311 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13906 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14312 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13907 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), 14313 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13908 { } /* end */ 14314 { } /* end */
13909}; 14315};
13910 14316
13911static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { 14317static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13912 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14318 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13913 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14319 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13914 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14320 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13915 { } /* end */ 14321 { } /* end */
13916}; 14322};
13917 14323
13918/* FSC amilo */ 14324/* FSC amilo */
13919#define alc269_fujitsu_mixer alc269_laptop_mixer 14325#define alc269_fujitsu_mixer alc269_laptop_mixer
13920 14326
13921static struct hda_verb alc269_quanta_fl1_verbs[] = { 14327static const struct hda_verb alc269_quanta_fl1_verbs[] = {
13922 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14328 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13923 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14329 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13924 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -13928,7 +14334,7 @@ static struct hda_verb alc269_quanta_fl1_verbs[] = {
13928 { } 14334 { }
13929}; 14335};
13930 14336
13931static struct hda_verb alc269_lifebook_verbs[] = { 14337static const struct hda_verb alc269_lifebook_verbs[] = {
13932 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14338 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13933 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 14339 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13934 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14340 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -13945,15 +14351,7 @@ static struct hda_verb alc269_lifebook_verbs[] = {
13945/* toggle speaker-output according to the hp-jack state */ 14351/* toggle speaker-output according to the hp-jack state */
13946static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) 14352static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13947{ 14353{
13948 unsigned int present; 14354 alc_hp_automute(codec);
13949 unsigned char bits;
13950
13951 present = snd_hda_jack_detect(codec, 0x15);
13952 bits = present ? HDA_AMP_MUTE : 0;
13953 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13954 HDA_AMP_MUTE, bits);
13955 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13956 HDA_AMP_MUTE, bits);
13957 14355
13958 snd_hda_codec_write(codec, 0x20, 0, 14356 snd_hda_codec_write(codec, 0x20, 0,
13959 AC_VERB_SET_COEF_INDEX, 0x0c); 14357 AC_VERB_SET_COEF_INDEX, 0x0c);
@@ -13966,34 +14364,8 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13966 AC_VERB_SET_PROC_COEF, 0x480); 14364 AC_VERB_SET_PROC_COEF, 0x480);
13967} 14365}
13968 14366
13969/* toggle speaker-output according to the hp-jacks state */ 14367#define alc269_lifebook_speaker_automute \
13970static void alc269_lifebook_speaker_automute(struct hda_codec *codec) 14368 alc269_quanta_fl1_speaker_automute
13971{
13972 unsigned int present;
13973 unsigned char bits;
13974
13975 /* Check laptop headphone socket */
13976 present = snd_hda_jack_detect(codec, 0x15);
13977
13978 /* Check port replicator headphone socket */
13979 present |= snd_hda_jack_detect(codec, 0x1a);
13980
13981 bits = present ? HDA_AMP_MUTE : 0;
13982 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13983 HDA_AMP_MUTE, bits);
13984 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13985 HDA_AMP_MUTE, bits);
13986
13987 snd_hda_codec_write(codec, 0x20, 0,
13988 AC_VERB_SET_COEF_INDEX, 0x0c);
13989 snd_hda_codec_write(codec, 0x20, 0,
13990 AC_VERB_SET_PROC_COEF, 0x680);
13991
13992 snd_hda_codec_write(codec, 0x20, 0,
13993 AC_VERB_SET_COEF_INDEX, 0x0c);
13994 snd_hda_codec_write(codec, 0x20, 0,
13995 AC_VERB_SET_PROC_COEF, 0x480);
13996}
13997 14369
13998static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) 14370static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13999{ 14371{
@@ -14042,6 +14414,9 @@ static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14042 struct alc_spec *spec = codec->spec; 14414 struct alc_spec *spec = codec->spec;
14043 spec->autocfg.hp_pins[0] = 0x15; 14415 spec->autocfg.hp_pins[0] = 0x15;
14044 spec->autocfg.speaker_pins[0] = 0x14; 14416 spec->autocfg.speaker_pins[0] = 0x14;
14417 spec->automute_mixer_nid[0] = 0x0c;
14418 spec->automute = 1;
14419 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14045 spec->ext_mic.pin = 0x18; 14420 spec->ext_mic.pin = 0x18;
14046 spec->ext_mic.mux_idx = 0; 14421 spec->ext_mic.mux_idx = 0;
14047 spec->int_mic.pin = 0x19; 14422 spec->int_mic.pin = 0x19;
@@ -14055,13 +14430,24 @@ static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14055 alc_mic_automute(codec); 14430 alc_mic_automute(codec);
14056} 14431}
14057 14432
14433static void alc269_lifebook_setup(struct hda_codec *codec)
14434{
14435 struct alc_spec *spec = codec->spec;
14436 spec->autocfg.hp_pins[0] = 0x15;
14437 spec->autocfg.hp_pins[1] = 0x1a;
14438 spec->autocfg.speaker_pins[0] = 0x14;
14439 spec->automute_mixer_nid[0] = 0x0c;
14440 spec->automute = 1;
14441 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14442}
14443
14058static void alc269_lifebook_init_hook(struct hda_codec *codec) 14444static void alc269_lifebook_init_hook(struct hda_codec *codec)
14059{ 14445{
14060 alc269_lifebook_speaker_automute(codec); 14446 alc269_lifebook_speaker_automute(codec);
14061 alc269_lifebook_mic_autoswitch(codec); 14447 alc269_lifebook_mic_autoswitch(codec);
14062} 14448}
14063 14449
14064static struct hda_verb alc269_laptop_dmic_init_verbs[] = { 14450static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14065 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14451 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14066 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 14452 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14067 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14453 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -14072,7 +14458,7 @@ static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14072 {} 14458 {}
14073}; 14459};
14074 14460
14075static struct hda_verb alc269_laptop_amic_init_verbs[] = { 14461static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
14076 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14462 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14077 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 14463 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14078 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14464 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -14082,7 +14468,7 @@ static struct hda_verb alc269_laptop_amic_init_verbs[] = {
14082 {} 14468 {}
14083}; 14469};
14084 14470
14085static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { 14471static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14086 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14472 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14087 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06}, 14473 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14088 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14474 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -14093,7 +14479,7 @@ static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14093 {} 14479 {}
14094}; 14480};
14095 14481
14096static struct hda_verb alc269vb_laptop_amic_init_verbs[] = { 14482static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14097 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14483 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14098 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, 14484 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14099 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14485 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -14104,7 +14490,7 @@ static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14104 {} 14490 {}
14105}; 14491};
14106 14492
14107static struct hda_verb alc271_acer_dmic_verbs[] = { 14493static const struct hda_verb alc271_acer_dmic_verbs[] = {
14108 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, 14494 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14109 {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, 14495 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14110 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14496 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -14118,41 +14504,14 @@ static struct hda_verb alc271_acer_dmic_verbs[] = {
14118 { } 14504 { }
14119}; 14505};
14120 14506
14121/* toggle speaker-output according to the hp-jack state */
14122static void alc269_speaker_automute(struct hda_codec *codec)
14123{
14124 struct alc_spec *spec = codec->spec;
14125 unsigned int nid = spec->autocfg.hp_pins[0];
14126 unsigned int present;
14127 unsigned char bits;
14128
14129 present = snd_hda_jack_detect(codec, nid);
14130 bits = present ? HDA_AMP_MUTE : 0;
14131 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14132 HDA_AMP_MUTE, bits);
14133 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14134 HDA_AMP_MUTE, bits);
14135}
14136
14137/* unsolicited event for HP jack sensing */
14138static void alc269_laptop_unsol_event(struct hda_codec *codec,
14139 unsigned int res)
14140{
14141 switch (res >> 26) {
14142 case ALC880_HP_EVENT:
14143 alc269_speaker_automute(codec);
14144 break;
14145 case ALC880_MIC_EVENT:
14146 alc_mic_automute(codec);
14147 break;
14148 }
14149}
14150
14151static void alc269_laptop_amic_setup(struct hda_codec *codec) 14507static void alc269_laptop_amic_setup(struct hda_codec *codec)
14152{ 14508{
14153 struct alc_spec *spec = codec->spec; 14509 struct alc_spec *spec = codec->spec;
14154 spec->autocfg.hp_pins[0] = 0x15; 14510 spec->autocfg.hp_pins[0] = 0x15;
14155 spec->autocfg.speaker_pins[0] = 0x14; 14511 spec->autocfg.speaker_pins[0] = 0x14;
14512 spec->automute_mixer_nid[0] = 0x0c;
14513 spec->automute = 1;
14514 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14156 spec->ext_mic.pin = 0x18; 14515 spec->ext_mic.pin = 0x18;
14157 spec->ext_mic.mux_idx = 0; 14516 spec->ext_mic.mux_idx = 0;
14158 spec->int_mic.pin = 0x19; 14517 spec->int_mic.pin = 0x19;
@@ -14165,6 +14524,9 @@ static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14165 struct alc_spec *spec = codec->spec; 14524 struct alc_spec *spec = codec->spec;
14166 spec->autocfg.hp_pins[0] = 0x15; 14525 spec->autocfg.hp_pins[0] = 0x15;
14167 spec->autocfg.speaker_pins[0] = 0x14; 14526 spec->autocfg.speaker_pins[0] = 0x14;
14527 spec->automute_mixer_nid[0] = 0x0c;
14528 spec->automute = 1;
14529 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14168 spec->ext_mic.pin = 0x18; 14530 spec->ext_mic.pin = 0x18;
14169 spec->ext_mic.mux_idx = 0; 14531 spec->ext_mic.mux_idx = 0;
14170 spec->int_mic.pin = 0x12; 14532 spec->int_mic.pin = 0x12;
@@ -14177,6 +14539,9 @@ static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14177 struct alc_spec *spec = codec->spec; 14539 struct alc_spec *spec = codec->spec;
14178 spec->autocfg.hp_pins[0] = 0x21; 14540 spec->autocfg.hp_pins[0] = 0x21;
14179 spec->autocfg.speaker_pins[0] = 0x14; 14541 spec->autocfg.speaker_pins[0] = 0x14;
14542 spec->automute_mixer_nid[0] = 0x0c;
14543 spec->automute = 1;
14544 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14180 spec->ext_mic.pin = 0x18; 14545 spec->ext_mic.pin = 0x18;
14181 spec->ext_mic.mux_idx = 0; 14546 spec->ext_mic.mux_idx = 0;
14182 spec->int_mic.pin = 0x19; 14547 spec->int_mic.pin = 0x19;
@@ -14189,6 +14554,9 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14189 struct alc_spec *spec = codec->spec; 14554 struct alc_spec *spec = codec->spec;
14190 spec->autocfg.hp_pins[0] = 0x21; 14555 spec->autocfg.hp_pins[0] = 0x21;
14191 spec->autocfg.speaker_pins[0] = 0x14; 14556 spec->autocfg.speaker_pins[0] = 0x14;
14557 spec->automute_mixer_nid[0] = 0x0c;
14558 spec->automute = 1;
14559 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14192 spec->ext_mic.pin = 0x18; 14560 spec->ext_mic.pin = 0x18;
14193 spec->ext_mic.mux_idx = 0; 14561 spec->ext_mic.mux_idx = 0;
14194 spec->int_mic.pin = 0x12; 14562 spec->int_mic.pin = 0x12;
@@ -14196,16 +14564,10 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14196 spec->auto_mic = 1; 14564 spec->auto_mic = 1;
14197} 14565}
14198 14566
14199static void alc269_laptop_inithook(struct hda_codec *codec)
14200{
14201 alc269_speaker_automute(codec);
14202 alc_mic_automute(codec);
14203}
14204
14205/* 14567/*
14206 * generic initialization of ADC, input mixers and output mixers 14568 * generic initialization of ADC, input mixers and output mixers
14207 */ 14569 */
14208static struct hda_verb alc269_init_verbs[] = { 14570static const struct hda_verb alc269_init_verbs[] = {
14209 /* 14571 /*
14210 * Unmute ADC0 and set the default input to mic-in 14572 * Unmute ADC0 and set the default input to mic-in
14211 */ 14573 */
@@ -14248,7 +14610,7 @@ static struct hda_verb alc269_init_verbs[] = {
14248 { } 14610 { }
14249}; 14611};
14250 14612
14251static struct hda_verb alc269vb_init_verbs[] = { 14613static const struct hda_verb alc269vb_init_verbs[] = {
14252 /* 14614 /*
14253 * Unmute ADC0 and set the default input to mic-in 14615 * Unmute ADC0 and set the default input to mic-in
14254 */ 14616 */
@@ -14306,7 +14668,7 @@ static struct hda_verb alc269vb_init_verbs[] = {
14306#define alc269_pcm_digital_playback alc880_pcm_digital_playback 14668#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14307#define alc269_pcm_digital_capture alc880_pcm_digital_capture 14669#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14308 14670
14309static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 14671static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14310 .substreams = 1, 14672 .substreams = 1,
14311 .channels_min = 2, 14673 .channels_min = 2,
14312 .channels_max = 8, 14674 .channels_max = 8,
@@ -14319,7 +14681,7 @@ static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14319 }, 14681 },
14320}; 14682};
14321 14683
14322static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { 14684static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14323 .substreams = 1, 14685 .substreams = 1,
14324 .channels_min = 2, 14686 .channels_min = 2,
14325 .channels_max = 2, 14687 .channels_max = 2,
@@ -14386,6 +14748,16 @@ static int alc275_setup_dual_adc(struct hda_codec *codec)
14386 return 0; 14748 return 0;
14387} 14749}
14388 14750
14751/* different alc269-variants */
14752enum {
14753 ALC269_TYPE_NORMAL,
14754 ALC269_TYPE_ALC258,
14755 ALC269_TYPE_ALC259,
14756 ALC269_TYPE_ALC269VB,
14757 ALC269_TYPE_ALC270,
14758 ALC269_TYPE_ALC271X,
14759};
14760
14389/* 14761/*
14390 * BIOS auto configuration 14762 * BIOS auto configuration
14391 */ 14763 */
@@ -14393,7 +14765,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
14393{ 14765{
14394 struct alc_spec *spec = codec->spec; 14766 struct alc_spec *spec = codec->spec;
14395 int err; 14767 int err;
14396 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 14768 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14397 14769
14398 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 14770 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14399 alc269_ignore); 14771 alc269_ignore);
@@ -14403,7 +14775,11 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
14403 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg); 14775 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14404 if (err < 0) 14776 if (err < 0)
14405 return err; 14777 return err;
14406 err = alc269_auto_create_input_ctls(codec, &spec->autocfg); 14778 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14779 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14780 else
14781 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14782 0x22, 0);
14407 if (err < 0) 14783 if (err < 0)
14408 return err; 14784 return err;
14409 14785
@@ -14414,7 +14790,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
14414 if (spec->kctls.list) 14790 if (spec->kctls.list)
14415 add_mixer(spec, spec->kctls.list); 14791 add_mixer(spec, spec->kctls.list);
14416 14792
14417 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) { 14793 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
14418 add_verb(spec, alc269vb_init_verbs); 14794 add_verb(spec, alc269vb_init_verbs);
14419 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); 14795 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14420 } else { 14796 } else {
@@ -14429,11 +14805,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
14429 fillup_priv_adc_nids(codec, alc269_adc_candidates, 14805 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14430 sizeof(alc269_adc_candidates)); 14806 sizeof(alc269_adc_candidates));
14431 14807
14432 /* set default input source */
14433 if (!spec->dual_adc_switch)
14434 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14435 spec->input_mux->items[0].index);
14436
14437 err = alc_auto_add_mic_boost(codec); 14808 err = alc_auto_add_mic_boost(codec);
14438 if (err < 0) 14809 if (err < 0)
14439 return err; 14810 return err;
@@ -14447,6 +14818,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
14447#define alc269_auto_init_multi_out alc268_auto_init_multi_out 14818#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14448#define alc269_auto_init_hp_out alc268_auto_init_hp_out 14819#define alc269_auto_init_hp_out alc268_auto_init_hp_out
14449#define alc269_auto_init_analog_input alc882_auto_init_analog_input 14820#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14821#define alc269_auto_init_input_src alc882_auto_init_input_src
14450 14822
14451 14823
14452/* init callback for auto-configuration model -- overriding the default init */ 14824/* init callback for auto-configuration model -- overriding the default init */
@@ -14456,39 +14828,169 @@ static void alc269_auto_init(struct hda_codec *codec)
14456 alc269_auto_init_multi_out(codec); 14828 alc269_auto_init_multi_out(codec);
14457 alc269_auto_init_hp_out(codec); 14829 alc269_auto_init_hp_out(codec);
14458 alc269_auto_init_analog_input(codec); 14830 alc269_auto_init_analog_input(codec);
14831 if (!spec->dual_adc_switch)
14832 alc269_auto_init_input_src(codec);
14459 alc_auto_init_digital(codec); 14833 alc_auto_init_digital(codec);
14460 if (spec->unsol_event) 14834 if (spec->unsol_event)
14461 alc_inithook(codec); 14835 alc_inithook(codec);
14462} 14836}
14463 14837
14838static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14839{
14840 int val = alc_read_coef_idx(codec, 0x04);
14841 if (power_up)
14842 val |= 1 << 11;
14843 else
14844 val &= ~(1 << 11);
14845 alc_write_coef_idx(codec, 0x04, val);
14846}
14847
14848static void alc269_shutup(struct hda_codec *codec)
14849{
14850 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14851 alc269_toggle_power_output(codec, 0);
14852 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14853 alc269_toggle_power_output(codec, 0);
14854 msleep(150);
14855 }
14856}
14857
14858#ifdef SND_HDA_NEEDS_RESUME
14859static int alc269_resume(struct hda_codec *codec)
14860{
14861 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14862 alc269_toggle_power_output(codec, 0);
14863 msleep(150);
14864 }
14865
14866 codec->patch_ops.init(codec);
14867
14868 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14869 alc269_toggle_power_output(codec, 1);
14870 msleep(200);
14871 }
14872
14873 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14874 alc269_toggle_power_output(codec, 1);
14875
14876 snd_hda_codec_resume_amp(codec);
14877 snd_hda_codec_resume_cache(codec);
14878 hda_call_check_power_status(codec, 0x01);
14879 return 0;
14880}
14881#endif /* SND_HDA_NEEDS_RESUME */
14882
14883static void alc269_fixup_hweq(struct hda_codec *codec,
14884 const struct alc_fixup *fix, int action)
14885{
14886 int coef;
14887
14888 if (action != ALC_FIXUP_ACT_INIT)
14889 return;
14890 coef = alc_read_coef_idx(codec, 0x1e);
14891 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14892}
14893
14894static void alc271_fixup_dmic(struct hda_codec *codec,
14895 const struct alc_fixup *fix, int action)
14896{
14897 static const struct hda_verb verbs[] = {
14898 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14899 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14900 {}
14901 };
14902 unsigned int cfg;
14903
14904 if (strcmp(codec->chip_name, "ALC271X"))
14905 return;
14906 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14907 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14908 snd_hda_sequence_write(codec, verbs);
14909}
14910
14464enum { 14911enum {
14465 ALC269_FIXUP_SONY_VAIO, 14912 ALC269_FIXUP_SONY_VAIO,
14913 ALC275_FIXUP_SONY_VAIO_GPIO2,
14466 ALC269_FIXUP_DELL_M101Z, 14914 ALC269_FIXUP_DELL_M101Z,
14467}; 14915 ALC269_FIXUP_SKU_IGNORE,
14468 14916 ALC269_FIXUP_ASUS_G73JW,
14469static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = { 14917 ALC269_FIXUP_LENOVO_EAPD,
14470 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, 14918 ALC275_FIXUP_SONY_HWEQ,
14471 {} 14919 ALC271_FIXUP_DMIC,
14472}; 14920};
14473 14921
14474static const struct alc_fixup alc269_fixups[] = { 14922static const struct alc_fixup alc269_fixups[] = {
14475 [ALC269_FIXUP_SONY_VAIO] = { 14923 [ALC269_FIXUP_SONY_VAIO] = {
14476 .verbs = alc269_sony_vaio_fixup_verbs 14924 .type = ALC_FIXUP_VERBS,
14925 .v.verbs = (const struct hda_verb[]) {
14926 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14927 {}
14928 }
14929 },
14930 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
14931 .type = ALC_FIXUP_VERBS,
14932 .v.verbs = (const struct hda_verb[]) {
14933 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14934 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14935 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14936 { }
14937 },
14938 .chained = true,
14939 .chain_id = ALC269_FIXUP_SONY_VAIO
14477 }, 14940 },
14478 [ALC269_FIXUP_DELL_M101Z] = { 14941 [ALC269_FIXUP_DELL_M101Z] = {
14479 .verbs = (const struct hda_verb[]) { 14942 .type = ALC_FIXUP_VERBS,
14943 .v.verbs = (const struct hda_verb[]) {
14480 /* Enables internal speaker */ 14944 /* Enables internal speaker */
14481 {0x20, AC_VERB_SET_COEF_INDEX, 13}, 14945 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14482 {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, 14946 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14483 {} 14947 {}
14484 } 14948 }
14485 }, 14949 },
14950 [ALC269_FIXUP_SKU_IGNORE] = {
14951 .type = ALC_FIXUP_SKU,
14952 .v.sku = ALC_FIXUP_SKU_IGNORE,
14953 },
14954 [ALC269_FIXUP_ASUS_G73JW] = {
14955 .type = ALC_FIXUP_PINS,
14956 .v.pins = (const struct alc_pincfg[]) {
14957 { 0x17, 0x99130111 }, /* subwoofer */
14958 { }
14959 }
14960 },
14961 [ALC269_FIXUP_LENOVO_EAPD] = {
14962 .type = ALC_FIXUP_VERBS,
14963 .v.verbs = (const struct hda_verb[]) {
14964 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14965 {}
14966 }
14967 },
14968 [ALC275_FIXUP_SONY_HWEQ] = {
14969 .type = ALC_FIXUP_FUNC,
14970 .v.func = alc269_fixup_hweq,
14971 .chained = true,
14972 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
14973 },
14974 [ALC271_FIXUP_DMIC] = {
14975 .type = ALC_FIXUP_FUNC,
14976 .v.func = alc271_fixup_dmic,
14977 },
14486}; 14978};
14487 14979
14488static struct snd_pci_quirk alc269_fixup_tbl[] = { 14980static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14489 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 14981 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14490 SND_PCI_QUIRK(0x104d, 0x9077, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 14982 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14983 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14984 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14491 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 14985 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14986 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
14987 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14988 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14989 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14990 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14991 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
14992 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14993 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14492 {} 14994 {}
14493}; 14995};
14494 14996
@@ -14496,7 +14998,7 @@ static struct snd_pci_quirk alc269_fixup_tbl[] = {
14496/* 14998/*
14497 * configuration and preset 14999 * configuration and preset
14498 */ 15000 */
14499static const char *alc269_models[ALC269_MODEL_LAST] = { 15001static const char * const alc269_models[ALC269_MODEL_LAST] = {
14500 [ALC269_BASIC] = "basic", 15002 [ALC269_BASIC] = "basic",
14501 [ALC269_QUANTA_FL1] = "quanta", 15003 [ALC269_QUANTA_FL1] = "quanta",
14502 [ALC269_AMIC] = "laptop-amic", 15004 [ALC269_AMIC] = "laptop-amic",
@@ -14506,7 +15008,7 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
14506 [ALC269_AUTO] = "auto", 15008 [ALC269_AUTO] = "auto",
14507}; 15009};
14508 15010
14509static struct snd_pci_quirk alc269_cfg_tbl[] = { 15011static const struct snd_pci_quirk alc269_cfg_tbl[] = {
14510 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 15012 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14511 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER), 15013 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14512 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 15014 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
@@ -14520,7 +15022,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = {
14520 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC), 15022 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14521 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC), 15023 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14522 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC), 15024 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14523 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC), 15025 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
14524 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC), 15026 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14525 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC), 15027 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14526 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC), 15028 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
@@ -14564,7 +15066,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = {
14564 {} 15066 {}
14565}; 15067};
14566 15068
14567static struct alc_config_preset alc269_presets[] = { 15069static const struct alc_config_preset alc269_presets[] = {
14568 [ALC269_BASIC] = { 15070 [ALC269_BASIC] = {
14569 .mixers = { alc269_base_mixer }, 15071 .mixers = { alc269_base_mixer },
14570 .init_verbs = { alc269_init_verbs }, 15072 .init_verbs = { alc269_init_verbs },
@@ -14598,9 +15100,9 @@ static struct alc_config_preset alc269_presets[] = {
14598 .hp_nid = 0x03, 15100 .hp_nid = 0x03,
14599 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15101 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14600 .channel_mode = alc269_modes, 15102 .channel_mode = alc269_modes,
14601 .unsol_event = alc269_laptop_unsol_event, 15103 .unsol_event = alc_sku_unsol_event,
14602 .setup = alc269_laptop_amic_setup, 15104 .setup = alc269_laptop_amic_setup,
14603 .init_hook = alc269_laptop_inithook, 15105 .init_hook = alc_inithook,
14604 }, 15106 },
14605 [ALC269_DMIC] = { 15107 [ALC269_DMIC] = {
14606 .mixers = { alc269_laptop_mixer }, 15108 .mixers = { alc269_laptop_mixer },
@@ -14612,9 +15114,9 @@ static struct alc_config_preset alc269_presets[] = {
14612 .hp_nid = 0x03, 15114 .hp_nid = 0x03,
14613 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15115 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14614 .channel_mode = alc269_modes, 15116 .channel_mode = alc269_modes,
14615 .unsol_event = alc269_laptop_unsol_event, 15117 .unsol_event = alc_sku_unsol_event,
14616 .setup = alc269_laptop_dmic_setup, 15118 .setup = alc269_laptop_dmic_setup,
14617 .init_hook = alc269_laptop_inithook, 15119 .init_hook = alc_inithook,
14618 }, 15120 },
14619 [ALC269VB_AMIC] = { 15121 [ALC269VB_AMIC] = {
14620 .mixers = { alc269vb_laptop_mixer }, 15122 .mixers = { alc269vb_laptop_mixer },
@@ -14626,9 +15128,9 @@ static struct alc_config_preset alc269_presets[] = {
14626 .hp_nid = 0x03, 15128 .hp_nid = 0x03,
14627 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15129 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14628 .channel_mode = alc269_modes, 15130 .channel_mode = alc269_modes,
14629 .unsol_event = alc269_laptop_unsol_event, 15131 .unsol_event = alc_sku_unsol_event,
14630 .setup = alc269vb_laptop_amic_setup, 15132 .setup = alc269vb_laptop_amic_setup,
14631 .init_hook = alc269_laptop_inithook, 15133 .init_hook = alc_inithook,
14632 }, 15134 },
14633 [ALC269VB_DMIC] = { 15135 [ALC269VB_DMIC] = {
14634 .mixers = { alc269vb_laptop_mixer }, 15136 .mixers = { alc269vb_laptop_mixer },
@@ -14640,9 +15142,9 @@ static struct alc_config_preset alc269_presets[] = {
14640 .hp_nid = 0x03, 15142 .hp_nid = 0x03,
14641 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15143 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14642 .channel_mode = alc269_modes, 15144 .channel_mode = alc269_modes,
14643 .unsol_event = alc269_laptop_unsol_event, 15145 .unsol_event = alc_sku_unsol_event,
14644 .setup = alc269vb_laptop_dmic_setup, 15146 .setup = alc269vb_laptop_dmic_setup,
14645 .init_hook = alc269_laptop_inithook, 15147 .init_hook = alc_inithook,
14646 }, 15148 },
14647 [ALC269_FUJITSU] = { 15149 [ALC269_FUJITSU] = {
14648 .mixers = { alc269_fujitsu_mixer }, 15150 .mixers = { alc269_fujitsu_mixer },
@@ -14654,9 +15156,9 @@ static struct alc_config_preset alc269_presets[] = {
14654 .hp_nid = 0x03, 15156 .hp_nid = 0x03,
14655 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15157 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14656 .channel_mode = alc269_modes, 15158 .channel_mode = alc269_modes,
14657 .unsol_event = alc269_laptop_unsol_event, 15159 .unsol_event = alc_sku_unsol_event,
14658 .setup = alc269_laptop_dmic_setup, 15160 .setup = alc269_laptop_dmic_setup,
14659 .init_hook = alc269_laptop_inithook, 15161 .init_hook = alc_inithook,
14660 }, 15162 },
14661 [ALC269_LIFEBOOK] = { 15163 [ALC269_LIFEBOOK] = {
14662 .mixers = { alc269_lifebook_mixer }, 15164 .mixers = { alc269_lifebook_mixer },
@@ -14668,6 +15170,7 @@ static struct alc_config_preset alc269_presets[] = {
14668 .channel_mode = alc269_modes, 15170 .channel_mode = alc269_modes,
14669 .input_mux = &alc269_capture_source, 15171 .input_mux = &alc269_capture_source,
14670 .unsol_event = alc269_lifebook_unsol_event, 15172 .unsol_event = alc269_lifebook_unsol_event,
15173 .setup = alc269_lifebook_setup,
14671 .init_hook = alc269_lifebook_init_hook, 15174 .init_hook = alc269_lifebook_init_hook,
14672 }, 15175 },
14673 [ALC271_ACER] = { 15176 [ALC271_ACER] = {
@@ -14689,12 +15192,53 @@ static struct alc_config_preset alc269_presets[] = {
14689 }, 15192 },
14690}; 15193};
14691 15194
15195static int alc269_fill_coef(struct hda_codec *codec)
15196{
15197 int val;
15198
15199 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15200 alc_write_coef_idx(codec, 0xf, 0x960b);
15201 alc_write_coef_idx(codec, 0xe, 0x8817);
15202 }
15203
15204 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15205 alc_write_coef_idx(codec, 0xf, 0x960b);
15206 alc_write_coef_idx(codec, 0xe, 0x8814);
15207 }
15208
15209 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15210 val = alc_read_coef_idx(codec, 0x04);
15211 /* Power up output pin */
15212 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15213 }
15214
15215 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15216 val = alc_read_coef_idx(codec, 0xd);
15217 if ((val & 0x0c00) >> 10 != 0x1) {
15218 /* Capless ramp up clock control */
15219 alc_write_coef_idx(codec, 0xd, val | (1<<10));
15220 }
15221 val = alc_read_coef_idx(codec, 0x17);
15222 if ((val & 0x01c0) >> 6 != 0x4) {
15223 /* Class D power on reset */
15224 alc_write_coef_idx(codec, 0x17, val | (1<<7));
15225 }
15226 }
15227
15228 val = alc_read_coef_idx(codec, 0xd); /* Class D */
15229 alc_write_coef_idx(codec, 0xd, val | (1<<14));
15230
15231 val = alc_read_coef_idx(codec, 0x4); /* HP */
15232 alc_write_coef_idx(codec, 0x4, val | (1<<11));
15233
15234 return 0;
15235}
15236
14692static int patch_alc269(struct hda_codec *codec) 15237static int patch_alc269(struct hda_codec *codec)
14693{ 15238{
14694 struct alc_spec *spec; 15239 struct alc_spec *spec;
14695 int board_config; 15240 int board_config, coef;
14696 int err; 15241 int err;
14697 int is_alc269vb = 0;
14698 15242
14699 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 15243 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14700 if (spec == NULL) 15244 if (spec == NULL)
@@ -14704,15 +15248,29 @@ static int patch_alc269(struct hda_codec *codec)
14704 15248
14705 alc_auto_parse_customize_define(codec); 15249 alc_auto_parse_customize_define(codec);
14706 15250
14707 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ 15251 if (codec->vendor_id == 0x10ec0269) {
14708 if (codec->bus->pci->subsystem_vendor == 0x1025 && 15252 coef = alc_read_coef_idx(codec, 0);
14709 spec->cdefine.platform_type == 1) 15253 if ((coef & 0x00f0) == 0x0010) {
14710 alc_codec_rename(codec, "ALC271X"); 15254 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14711 else 15255 spec->cdefine.platform_type == 1) {
14712 alc_codec_rename(codec, "ALC259"); 15256 alc_codec_rename(codec, "ALC271X");
14713 is_alc269vb = 1; 15257 spec->codec_variant = ALC269_TYPE_ALC271X;
14714 } else 15258 } else if ((coef & 0xf000) == 0x1000) {
14715 alc_fix_pll_init(codec, 0x20, 0x04, 15); 15259 spec->codec_variant = ALC269_TYPE_ALC270;
15260 } else if ((coef & 0xf000) == 0x2000) {
15261 alc_codec_rename(codec, "ALC259");
15262 spec->codec_variant = ALC269_TYPE_ALC259;
15263 } else if ((coef & 0xf000) == 0x3000) {
15264 alc_codec_rename(codec, "ALC258");
15265 spec->codec_variant = ALC269_TYPE_ALC258;
15266 } else {
15267 alc_codec_rename(codec, "ALC269VB");
15268 spec->codec_variant = ALC269_TYPE_ALC269VB;
15269 }
15270 } else
15271 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15272 alc269_fill_coef(codec);
15273 }
14716 15274
14717 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 15275 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14718 alc269_models, 15276 alc269_models,
@@ -14724,8 +15282,10 @@ static int patch_alc269(struct hda_codec *codec)
14724 board_config = ALC269_AUTO; 15282 board_config = ALC269_AUTO;
14725 } 15283 }
14726 15284
14727 if (board_config == ALC269_AUTO) 15285 if (board_config == ALC269_AUTO) {
14728 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1); 15286 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15287 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15288 }
14729 15289
14730 if (board_config == ALC269_AUTO) { 15290 if (board_config == ALC269_AUTO) {
14731 /* automatic parse from the BIOS config */ 15291 /* automatic parse from the BIOS config */
@@ -14770,7 +15330,7 @@ static int patch_alc269(struct hda_codec *codec)
14770 spec->stream_digital_capture = &alc269_pcm_digital_capture; 15330 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14771 15331
14772 if (!spec->adc_nids) { /* wasn't filled automatically? use default */ 15332 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14773 if (!is_alc269vb) { 15333 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
14774 spec->adc_nids = alc269_adc_nids; 15334 spec->adc_nids = alc269_adc_nids;
14775 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 15335 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14776 spec->capsrc_nids = alc269_capsrc_nids; 15336 spec->capsrc_nids = alc269_capsrc_nids;
@@ -14786,14 +15346,19 @@ static int patch_alc269(struct hda_codec *codec)
14786 if (has_cdefine_beep(codec)) 15346 if (has_cdefine_beep(codec))
14787 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 15347 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
14788 15348
14789 if (board_config == ALC269_AUTO) 15349 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
14790 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
14791 15350
14792 spec->vmaster_nid = 0x02; 15351 spec->vmaster_nid = 0x02;
14793 15352
14794 codec->patch_ops = alc_patch_ops; 15353 codec->patch_ops = alc_patch_ops;
15354#ifdef SND_HDA_NEEDS_RESUME
15355 codec->patch_ops.resume = alc269_resume;
15356#endif
14795 if (board_config == ALC269_AUTO) 15357 if (board_config == ALC269_AUTO)
14796 spec->init_hook = alc269_auto_init; 15358 spec->init_hook = alc269_auto_init;
15359 spec->shutup = alc269_shutup;
15360
15361 alc_init_jacks(codec);
14797#ifdef CONFIG_SND_HDA_POWER_SAVE 15362#ifdef CONFIG_SND_HDA_POWER_SAVE
14798 if (!spec->loopback.amplist) 15363 if (!spec->loopback.amplist)
14799 spec->loopback.amplist = alc269_loopbacks; 15364 spec->loopback.amplist = alc269_loopbacks;
@@ -14812,7 +15377,7 @@ static int patch_alc269(struct hda_codec *codec)
14812 * set the path ways for 2 channel output 15377 * set the path ways for 2 channel output
14813 * need to set the codec line out and mic 1 pin widgets to inputs 15378 * need to set the codec line out and mic 1 pin widgets to inputs
14814 */ 15379 */
14815static struct hda_verb alc861_threestack_ch2_init[] = { 15380static const struct hda_verb alc861_threestack_ch2_init[] = {
14816 /* set pin widget 1Ah (line in) for input */ 15381 /* set pin widget 1Ah (line in) for input */
14817 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15382 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14818 /* set pin widget 18h (mic1/2) for input, for mic also enable 15383 /* set pin widget 18h (mic1/2) for input, for mic also enable
@@ -14831,7 +15396,7 @@ static struct hda_verb alc861_threestack_ch2_init[] = {
14831 * 6ch mode 15396 * 6ch mode
14832 * need to set the codec line out and mic 1 pin widgets to outputs 15397 * need to set the codec line out and mic 1 pin widgets to outputs
14833 */ 15398 */
14834static struct hda_verb alc861_threestack_ch6_init[] = { 15399static const struct hda_verb alc861_threestack_ch6_init[] = {
14835 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 15400 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14836 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15401 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14837 /* set pin widget 18h (mic1) for output (CLFE)*/ 15402 /* set pin widget 18h (mic1) for output (CLFE)*/
@@ -14848,30 +15413,30 @@ static struct hda_verb alc861_threestack_ch6_init[] = {
14848 { } /* end */ 15413 { } /* end */
14849}; 15414};
14850 15415
14851static struct hda_channel_mode alc861_threestack_modes[2] = { 15416static const struct hda_channel_mode alc861_threestack_modes[2] = {
14852 { 2, alc861_threestack_ch2_init }, 15417 { 2, alc861_threestack_ch2_init },
14853 { 6, alc861_threestack_ch6_init }, 15418 { 6, alc861_threestack_ch6_init },
14854}; 15419};
14855/* Set mic1 as input and unmute the mixer */ 15420/* Set mic1 as input and unmute the mixer */
14856static struct hda_verb alc861_uniwill_m31_ch2_init[] = { 15421static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14857 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15422 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14858 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 15423 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14859 { } /* end */ 15424 { } /* end */
14860}; 15425};
14861/* Set mic1 as output and mute mixer */ 15426/* Set mic1 as output and mute mixer */
14862static struct hda_verb alc861_uniwill_m31_ch4_init[] = { 15427static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14863 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15428 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14864 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 15429 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14865 { } /* end */ 15430 { } /* end */
14866}; 15431};
14867 15432
14868static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 15433static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14869 { 2, alc861_uniwill_m31_ch2_init }, 15434 { 2, alc861_uniwill_m31_ch2_init },
14870 { 4, alc861_uniwill_m31_ch4_init }, 15435 { 4, alc861_uniwill_m31_ch4_init },
14871}; 15436};
14872 15437
14873/* Set mic1 and line-in as input and unmute the mixer */ 15438/* Set mic1 and line-in as input and unmute the mixer */
14874static struct hda_verb alc861_asus_ch2_init[] = { 15439static const struct hda_verb alc861_asus_ch2_init[] = {
14875 /* set pin widget 1Ah (line in) for input */ 15440 /* set pin widget 1Ah (line in) for input */
14876 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15441 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14877 /* set pin widget 18h (mic1/2) for input, for mic also enable 15442 /* set pin widget 18h (mic1/2) for input, for mic also enable
@@ -14887,7 +15452,7 @@ static struct hda_verb alc861_asus_ch2_init[] = {
14887 { } /* end */ 15452 { } /* end */
14888}; 15453};
14889/* Set mic1 nad line-in as output and mute mixer */ 15454/* Set mic1 nad line-in as output and mute mixer */
14890static struct hda_verb alc861_asus_ch6_init[] = { 15455static const struct hda_verb alc861_asus_ch6_init[] = {
14891 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 15456 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14892 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15457 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14893 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 15458 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
@@ -14905,14 +15470,14 @@ static struct hda_verb alc861_asus_ch6_init[] = {
14905 { } /* end */ 15470 { } /* end */
14906}; 15471};
14907 15472
14908static struct hda_channel_mode alc861_asus_modes[2] = { 15473static const struct hda_channel_mode alc861_asus_modes[2] = {
14909 { 2, alc861_asus_ch2_init }, 15474 { 2, alc861_asus_ch2_init },
14910 { 6, alc861_asus_ch6_init }, 15475 { 6, alc861_asus_ch6_init },
14911}; 15476};
14912 15477
14913/* patch-ALC861 */ 15478/* patch-ALC861 */
14914 15479
14915static struct snd_kcontrol_new alc861_base_mixer[] = { 15480static const struct snd_kcontrol_new alc861_base_mixer[] = {
14916 /* output mixer control */ 15481 /* output mixer control */
14917 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15482 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14918 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15483 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
@@ -14935,7 +15500,7 @@ static struct snd_kcontrol_new alc861_base_mixer[] = {
14935 { } /* end */ 15500 { } /* end */
14936}; 15501};
14937 15502
14938static struct snd_kcontrol_new alc861_3ST_mixer[] = { 15503static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
14939 /* output mixer control */ 15504 /* output mixer control */
14940 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15505 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14941 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15506 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
@@ -14966,7 +15531,7 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = {
14966 { } /* end */ 15531 { } /* end */
14967}; 15532};
14968 15533
14969static struct snd_kcontrol_new alc861_toshiba_mixer[] = { 15534static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
14970 /* output mixer control */ 15535 /* output mixer control */
14971 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15536 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14972 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15537 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
@@ -14975,7 +15540,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
14975 { } /* end */ 15540 { } /* end */
14976}; 15541};
14977 15542
14978static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 15543static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14979 /* output mixer control */ 15544 /* output mixer control */
14980 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15545 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14981 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15546 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
@@ -15006,7 +15571,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15006 { } /* end */ 15571 { } /* end */
15007}; 15572};
15008 15573
15009static struct snd_kcontrol_new alc861_asus_mixer[] = { 15574static const struct snd_kcontrol_new alc861_asus_mixer[] = {
15010 /* output mixer control */ 15575 /* output mixer control */
15011 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15576 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15012 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15577 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
@@ -15038,7 +15603,7 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = {
15038}; 15603};
15039 15604
15040/* additional mixer */ 15605/* additional mixer */
15041static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 15606static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15042 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15607 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15043 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15608 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15044 { } 15609 { }
@@ -15047,7 +15612,7 @@ static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15047/* 15612/*
15048 * generic initialization of ADC, input mixers and output mixers 15613 * generic initialization of ADC, input mixers and output mixers
15049 */ 15614 */
15050static struct hda_verb alc861_base_init_verbs[] = { 15615static const struct hda_verb alc861_base_init_verbs[] = {
15051 /* 15616 /*
15052 * Unmute ADC0 and set the default input to mic-in 15617 * Unmute ADC0 and set the default input to mic-in
15053 */ 15618 */
@@ -15113,7 +15678,7 @@ static struct hda_verb alc861_base_init_verbs[] = {
15113 { } 15678 { }
15114}; 15679};
15115 15680
15116static struct hda_verb alc861_threestack_init_verbs[] = { 15681static const struct hda_verb alc861_threestack_init_verbs[] = {
15117 /* 15682 /*
15118 * Unmute ADC0 and set the default input to mic-in 15683 * Unmute ADC0 and set the default input to mic-in
15119 */ 15684 */
@@ -15174,7 +15739,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = {
15174 { } 15739 { }
15175}; 15740};
15176 15741
15177static struct hda_verb alc861_uniwill_m31_init_verbs[] = { 15742static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15178 /* 15743 /*
15179 * Unmute ADC0 and set the default input to mic-in 15744 * Unmute ADC0 and set the default input to mic-in
15180 */ 15745 */
@@ -15236,7 +15801,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15236 { } 15801 { }
15237}; 15802};
15238 15803
15239static struct hda_verb alc861_asus_init_verbs[] = { 15804static const struct hda_verb alc861_asus_init_verbs[] = {
15240 /* 15805 /*
15241 * Unmute ADC0 and set the default input to mic-in 15806 * Unmute ADC0 and set the default input to mic-in
15242 */ 15807 */
@@ -15302,7 +15867,7 @@ static struct hda_verb alc861_asus_init_verbs[] = {
15302}; 15867};
15303 15868
15304/* additional init verbs for ASUS laptops */ 15869/* additional init verbs for ASUS laptops */
15305static struct hda_verb alc861_asus_laptop_init_verbs[] = { 15870static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
15306 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 15871 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15307 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 15872 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15308 { } 15873 { }
@@ -15311,7 +15876,7 @@ static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15311/* 15876/*
15312 * generic initialization of ADC, input mixers and output mixers 15877 * generic initialization of ADC, input mixers and output mixers
15313 */ 15878 */
15314static struct hda_verb alc861_auto_init_verbs[] = { 15879static const struct hda_verb alc861_auto_init_verbs[] = {
15315 /* 15880 /*
15316 * Unmute ADC0 and set the default input to mic-in 15881 * Unmute ADC0 and set the default input to mic-in
15317 */ 15882 */
@@ -15360,7 +15925,7 @@ static struct hda_verb alc861_auto_init_verbs[] = {
15360 { } 15925 { }
15361}; 15926};
15362 15927
15363static struct hda_verb alc861_toshiba_init_verbs[] = { 15928static const struct hda_verb alc861_toshiba_init_verbs[] = {
15364 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15929 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15365 15930
15366 { } 15931 { }
@@ -15393,26 +15958,26 @@ static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15393 15958
15394#define ALC861_DIGOUT_NID 0x07 15959#define ALC861_DIGOUT_NID 0x07
15395 15960
15396static struct hda_channel_mode alc861_8ch_modes[1] = { 15961static const struct hda_channel_mode alc861_8ch_modes[1] = {
15397 { 8, NULL } 15962 { 8, NULL }
15398}; 15963};
15399 15964
15400static hda_nid_t alc861_dac_nids[4] = { 15965static const hda_nid_t alc861_dac_nids[4] = {
15401 /* front, surround, clfe, side */ 15966 /* front, surround, clfe, side */
15402 0x03, 0x06, 0x05, 0x04 15967 0x03, 0x06, 0x05, 0x04
15403}; 15968};
15404 15969
15405static hda_nid_t alc660_dac_nids[3] = { 15970static const hda_nid_t alc660_dac_nids[3] = {
15406 /* front, clfe, surround */ 15971 /* front, clfe, surround */
15407 0x03, 0x05, 0x06 15972 0x03, 0x05, 0x06
15408}; 15973};
15409 15974
15410static hda_nid_t alc861_adc_nids[1] = { 15975static const hda_nid_t alc861_adc_nids[1] = {
15411 /* ADC0-2 */ 15976 /* ADC0-2 */
15412 0x08, 15977 0x08,
15413}; 15978};
15414 15979
15415static struct hda_input_mux alc861_capture_source = { 15980static const struct hda_input_mux alc861_capture_source = {
15416 .num_items = 5, 15981 .num_items = 5,
15417 .items = { 15982 .items = {
15418 { "Mic", 0x0 }, 15983 { "Mic", 0x0 },
@@ -15462,46 +16027,42 @@ static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
15462 dac = alc861_look_for_dac(codec, nid); 16027 dac = alc861_look_for_dac(codec, nid);
15463 if (!dac) 16028 if (!dac)
15464 continue; 16029 continue;
15465 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 16030 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
15466 } 16031 }
15467 return 0; 16032 return 0;
15468} 16033}
15469 16034
15470static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, 16035static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15471 hda_nid_t nid, unsigned int chs) 16036 hda_nid_t nid, int idx, unsigned int chs)
15472{ 16037{
15473 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, 16038 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
15474 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 16039 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15475} 16040}
15476 16041
16042#define alc861_create_out_sw(codec, pfx, nid, chs) \
16043 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
16044
15477/* add playback controls from the parsed DAC table */ 16045/* add playback controls from the parsed DAC table */
15478static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, 16046static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15479 const struct auto_pin_cfg *cfg) 16047 const struct auto_pin_cfg *cfg)
15480{ 16048{
15481 struct alc_spec *spec = codec->spec; 16049 struct alc_spec *spec = codec->spec;
15482 static const char *chname[4] = { 16050 static const char * const chname[4] = {
15483 "Front", "Surround", NULL /*CLFE*/, "Side" 16051 "Front", "Surround", NULL /*CLFE*/, "Side"
15484 }; 16052 };
16053 const char *pfx = alc_get_line_out_pfx(spec, true);
15485 hda_nid_t nid; 16054 hda_nid_t nid;
15486 int i, err; 16055 int i, err, noutputs;
15487 16056
15488 if (cfg->line_outs == 1) { 16057 noutputs = cfg->line_outs;
15489 const char *pfx = NULL; 16058 if (spec->multi_ios > 0)
15490 if (!cfg->hp_outs) 16059 noutputs += spec->multi_ios;
15491 pfx = "Master";
15492 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15493 pfx = "Speaker";
15494 if (pfx) {
15495 nid = spec->multiout.dac_nids[0];
15496 return alc861_create_out_sw(codec, pfx, nid, 3);
15497 }
15498 }
15499 16060
15500 for (i = 0; i < cfg->line_outs; i++) { 16061 for (i = 0; i < noutputs; i++) {
15501 nid = spec->multiout.dac_nids[i]; 16062 nid = spec->multiout.dac_nids[i];
15502 if (!nid) 16063 if (!nid)
15503 continue; 16064 continue;
15504 if (i == 2) { 16065 if (!pfx && i == 2) {
15505 /* Center/LFE */ 16066 /* Center/LFE */
15506 err = alc861_create_out_sw(codec, "Center", nid, 1); 16067 err = alc861_create_out_sw(codec, "Center", nid, 1);
15507 if (err < 0) 16068 if (err < 0)
@@ -15510,7 +16071,13 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15510 if (err < 0) 16071 if (err < 0)
15511 return err; 16072 return err;
15512 } else { 16073 } else {
15513 err = alc861_create_out_sw(codec, chname[i], nid, 3); 16074 const char *name = pfx;
16075 int index = i;
16076 if (!name) {
16077 name = chname[i];
16078 index = 0;
16079 }
16080 err = __alc861_create_out_sw(codec, name, nid, index, 3);
15514 if (err < 0) 16081 if (err < 0)
15515 return err; 16082 return err;
15516 } 16083 }
@@ -15606,12 +16173,13 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec)
15606static void alc861_auto_init_analog_input(struct hda_codec *codec) 16173static void alc861_auto_init_analog_input(struct hda_codec *codec)
15607{ 16174{
15608 struct alc_spec *spec = codec->spec; 16175 struct alc_spec *spec = codec->spec;
16176 struct auto_pin_cfg *cfg = &spec->autocfg;
15609 int i; 16177 int i;
15610 16178
15611 for (i = 0; i < AUTO_PIN_LAST; i++) { 16179 for (i = 0; i < cfg->num_inputs; i++) {
15612 hda_nid_t nid = spec->autocfg.input_pins[i]; 16180 hda_nid_t nid = cfg->inputs[i].pin;
15613 if (nid >= 0x0c && nid <= 0x11) 16181 if (nid >= 0x0c && nid <= 0x11)
15614 alc_set_input_pin(codec, nid, i); 16182 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
15615 } 16183 }
15616} 16184}
15617 16185
@@ -15623,7 +16191,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
15623{ 16191{
15624 struct alc_spec *spec = codec->spec; 16192 struct alc_spec *spec = codec->spec;
15625 int err; 16193 int err;
15626 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 16194 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15627 16195
15628 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 16196 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15629 alc861_ignore); 16197 alc861_ignore);
@@ -15635,6 +16203,9 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
15635 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg); 16203 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
15636 if (err < 0) 16204 if (err < 0)
15637 return err; 16205 return err;
16206 err = alc_auto_add_multi_channel_mode(codec);
16207 if (err < 0)
16208 return err;
15638 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); 16209 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
15639 if (err < 0) 16210 if (err < 0)
15640 return err; 16211 return err;
@@ -15679,7 +16250,7 @@ static void alc861_auto_init(struct hda_codec *codec)
15679} 16250}
15680 16251
15681#ifdef CONFIG_SND_HDA_POWER_SAVE 16252#ifdef CONFIG_SND_HDA_POWER_SAVE
15682static struct hda_amp_list alc861_loopbacks[] = { 16253static const struct hda_amp_list alc861_loopbacks[] = {
15683 { 0x15, HDA_INPUT, 0 }, 16254 { 0x15, HDA_INPUT, 0 },
15684 { 0x15, HDA_INPUT, 1 }, 16255 { 0x15, HDA_INPUT, 1 },
15685 { 0x15, HDA_INPUT, 2 }, 16256 { 0x15, HDA_INPUT, 2 },
@@ -15692,7 +16263,7 @@ static struct hda_amp_list alc861_loopbacks[] = {
15692/* 16263/*
15693 * configuration and preset 16264 * configuration and preset
15694 */ 16265 */
15695static const char *alc861_models[ALC861_MODEL_LAST] = { 16266static const char * const alc861_models[ALC861_MODEL_LAST] = {
15696 [ALC861_3ST] = "3stack", 16267 [ALC861_3ST] = "3stack",
15697 [ALC660_3ST] = "3stack-660", 16268 [ALC660_3ST] = "3stack-660",
15698 [ALC861_3ST_DIG] = "3stack-dig", 16269 [ALC861_3ST_DIG] = "3stack-dig",
@@ -15704,7 +16275,7 @@ static const char *alc861_models[ALC861_MODEL_LAST] = {
15704 [ALC861_AUTO] = "auto", 16275 [ALC861_AUTO] = "auto",
15705}; 16276};
15706 16277
15707static struct snd_pci_quirk alc861_cfg_tbl[] = { 16278static const struct snd_pci_quirk alc861_cfg_tbl[] = {
15708 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 16279 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
15709 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 16280 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15710 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 16281 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
@@ -15728,7 +16299,7 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = {
15728 {} 16299 {}
15729}; 16300};
15730 16301
15731static struct alc_config_preset alc861_presets[] = { 16302static const struct alc_config_preset alc861_presets[] = {
15732 [ALC861_3ST] = { 16303 [ALC861_3ST] = {
15733 .mixers = { alc861_3ST_mixer }, 16304 .mixers = { alc861_3ST_mixer },
15734 .init_verbs = { alc861_threestack_init_verbs }, 16305 .init_verbs = { alc861_threestack_init_verbs },
@@ -15840,19 +16411,18 @@ enum {
15840 PINFIX_FSC_AMILO_PI1505, 16411 PINFIX_FSC_AMILO_PI1505,
15841}; 16412};
15842 16413
15843static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
15844 { 0x0b, 0x0221101f }, /* HP */
15845 { 0x0f, 0x90170310 }, /* speaker */
15846 { }
15847};
15848
15849static const struct alc_fixup alc861_fixups[] = { 16414static const struct alc_fixup alc861_fixups[] = {
15850 [PINFIX_FSC_AMILO_PI1505] = { 16415 [PINFIX_FSC_AMILO_PI1505] = {
15851 .pins = alc861_fsc_amilo_pi1505_pinfix 16416 .type = ALC_FIXUP_PINS,
16417 .v.pins = (const struct alc_pincfg[]) {
16418 { 0x0b, 0x0221101f }, /* HP */
16419 { 0x0f, 0x90170310 }, /* speaker */
16420 { }
16421 }
15852 }, 16422 },
15853}; 16423};
15854 16424
15855static struct snd_pci_quirk alc861_fixup_tbl[] = { 16425static const struct snd_pci_quirk alc861_fixup_tbl[] = {
15856 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 16426 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15857 {} 16427 {}
15858}; 16428};
@@ -15879,8 +16449,10 @@ static int patch_alc861(struct hda_codec *codec)
15879 board_config = ALC861_AUTO; 16449 board_config = ALC861_AUTO;
15880 } 16450 }
15881 16451
15882 if (board_config == ALC861_AUTO) 16452 if (board_config == ALC861_AUTO) {
15883 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1); 16453 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16454 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16455 }
15884 16456
15885 if (board_config == ALC861_AUTO) { 16457 if (board_config == ALC861_AUTO) {
15886 /* automatic parse from the BIOS config */ 16458 /* automatic parse from the BIOS config */
@@ -15917,8 +16489,7 @@ static int patch_alc861(struct hda_codec *codec)
15917 16489
15918 spec->vmaster_nid = 0x03; 16490 spec->vmaster_nid = 0x03;
15919 16491
15920 if (board_config == ALC861_AUTO) 16492 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15921 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
15922 16493
15923 codec->patch_ops = alc_patch_ops; 16494 codec->patch_ops = alc_patch_ops;
15924 if (board_config == ALC861_AUTO) { 16495 if (board_config == ALC861_AUTO) {
@@ -15944,7 +16515,7 @@ static int patch_alc861(struct hda_codec *codec)
15944 */ 16515 */
15945#define ALC861VD_DIGOUT_NID 0x06 16516#define ALC861VD_DIGOUT_NID 0x06
15946 16517
15947static hda_nid_t alc861vd_dac_nids[4] = { 16518static const hda_nid_t alc861vd_dac_nids[4] = {
15948 /* front, surr, clfe, side surr */ 16519 /* front, surr, clfe, side surr */
15949 0x02, 0x03, 0x04, 0x05 16520 0x02, 0x03, 0x04, 0x05
15950}; 16521};
@@ -15956,21 +16527,21 @@ static hda_nid_t alc861vd_dac_nids[4] = {
15956 * - and it is the same as in 861vd. 16527 * - and it is the same as in 861vd.
15957 * adc_nids in ALC660vd are (is) the same as in 861vd 16528 * adc_nids in ALC660vd are (is) the same as in 861vd
15958 */ 16529 */
15959static hda_nid_t alc660vd_dac_nids[3] = { 16530static const hda_nid_t alc660vd_dac_nids[3] = {
15960 /* front, rear, clfe, rear_surr */ 16531 /* front, rear, clfe, rear_surr */
15961 0x02, 0x04, 0x03 16532 0x02, 0x04, 0x03
15962}; 16533};
15963 16534
15964static hda_nid_t alc861vd_adc_nids[1] = { 16535static const hda_nid_t alc861vd_adc_nids[1] = {
15965 /* ADC0 */ 16536 /* ADC0 */
15966 0x09, 16537 0x09,
15967}; 16538};
15968 16539
15969static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; 16540static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15970 16541
15971/* input MUX */ 16542/* input MUX */
15972/* FIXME: should be a matrix-type input source selection */ 16543/* FIXME: should be a matrix-type input source selection */
15973static struct hda_input_mux alc861vd_capture_source = { 16544static const struct hda_input_mux alc861vd_capture_source = {
15974 .num_items = 4, 16545 .num_items = 4,
15975 .items = { 16546 .items = {
15976 { "Mic", 0x0 }, 16547 { "Mic", 0x0 },
@@ -15980,15 +16551,15 @@ static struct hda_input_mux alc861vd_capture_source = {
15980 }, 16551 },
15981}; 16552};
15982 16553
15983static struct hda_input_mux alc861vd_dallas_capture_source = { 16554static const struct hda_input_mux alc861vd_dallas_capture_source = {
15984 .num_items = 2, 16555 .num_items = 2,
15985 .items = { 16556 .items = {
15986 { "Ext Mic", 0x0 }, 16557 { "Mic", 0x0 },
15987 { "Int Mic", 0x1 }, 16558 { "Internal Mic", 0x1 },
15988 }, 16559 },
15989}; 16560};
15990 16561
15991static struct hda_input_mux alc861vd_hp_capture_source = { 16562static const struct hda_input_mux alc861vd_hp_capture_source = {
15992 .num_items = 2, 16563 .num_items = 2,
15993 .items = { 16564 .items = {
15994 { "Front Mic", 0x0 }, 16565 { "Front Mic", 0x0 },
@@ -15999,14 +16570,14 @@ static struct hda_input_mux alc861vd_hp_capture_source = {
15999/* 16570/*
16000 * 2ch mode 16571 * 2ch mode
16001 */ 16572 */
16002static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 16573static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16003 { 2, NULL } 16574 { 2, NULL }
16004}; 16575};
16005 16576
16006/* 16577/*
16007 * 6ch mode 16578 * 6ch mode
16008 */ 16579 */
16009static struct hda_verb alc861vd_6stack_ch6_init[] = { 16580static const struct hda_verb alc861vd_6stack_ch6_init[] = {
16010 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 16581 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16011 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16582 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16012 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16583 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -16017,7 +16588,7 @@ static struct hda_verb alc861vd_6stack_ch6_init[] = {
16017/* 16588/*
16018 * 8ch mode 16589 * 8ch mode
16019 */ 16590 */
16020static struct hda_verb alc861vd_6stack_ch8_init[] = { 16591static const struct hda_verb alc861vd_6stack_ch8_init[] = {
16021 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16592 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16022 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16593 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16023 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16594 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -16025,12 +16596,12 @@ static struct hda_verb alc861vd_6stack_ch8_init[] = {
16025 { } /* end */ 16596 { } /* end */
16026}; 16597};
16027 16598
16028static struct hda_channel_mode alc861vd_6stack_modes[2] = { 16599static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
16029 { 6, alc861vd_6stack_ch6_init }, 16600 { 6, alc861vd_6stack_ch6_init },
16030 { 8, alc861vd_6stack_ch8_init }, 16601 { 8, alc861vd_6stack_ch8_init },
16031}; 16602};
16032 16603
16033static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 16604static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16034 { 16605 {
16035 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 16606 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16036 .name = "Channel Mode", 16607 .name = "Channel Mode",
@@ -16044,7 +16615,7 @@ static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16044/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 16615/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16045 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 16616 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16046 */ 16617 */
16047static struct snd_kcontrol_new alc861vd_6st_mixer[] = { 16618static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16048 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16619 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16049 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16620 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16050 16621
@@ -16063,11 +16634,11 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16063 16634
16064 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16635 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16065 16636
16066 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16637 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16067 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16638 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16068 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16639 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16069 16640
16070 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16641 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16071 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16642 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16072 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16643 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16073 16644
@@ -16080,17 +16651,17 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16080 { } /* end */ 16651 { } /* end */
16081}; 16652};
16082 16653
16083static struct snd_kcontrol_new alc861vd_3st_mixer[] = { 16654static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16084 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16655 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16085 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16656 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16086 16657
16087 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16658 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16088 16659
16089 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16660 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16090 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16661 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16091 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16662 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16092 16663
16093 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16664 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16094 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16665 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16095 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16666 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16096 16667
@@ -16103,18 +16674,18 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16103 { } /* end */ 16674 { } /* end */
16104}; 16675};
16105 16676
16106static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 16677static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16107 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16678 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16108 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 16679 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16109 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 16680 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16110 16681
16111 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16682 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16112 16683
16113 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16684 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16114 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16685 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16115 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16686 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16116 16687
16117 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16688 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16118 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16689 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16119 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16690 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16120 16691
@@ -16125,26 +16696,26 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16125}; 16696};
16126 16697
16127/* Pin assignment: Speaker=0x14, HP = 0x15, 16698/* Pin assignment: Speaker=0x14, HP = 0x15,
16128 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d 16699 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16129 */ 16700 */
16130static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 16701static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16131 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16702 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16132 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 16703 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16133 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16704 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16134 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16705 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16135 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 16706 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16136 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16137 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16138 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 16709 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16139 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16710 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16140 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16711 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16141 { } /* end */ 16712 { } /* end */
16142}; 16713};
16143 16714
16144/* Pin assignment: Speaker=0x14, Line-out = 0x15, 16715/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16145 * Front Mic=0x18, ATAPI Mic = 0x19, 16716 * Front Mic=0x18, ATAPI Mic = 0x19,
16146 */ 16717 */
16147static struct snd_kcontrol_new alc861vd_hp_mixer[] = { 16718static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16148 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16719 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16149 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16720 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16150 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16721 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -16160,7 +16731,7 @@ static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16160/* 16731/*
16161 * generic initialization of ADC, input mixers and output mixers 16732 * generic initialization of ADC, input mixers and output mixers
16162 */ 16733 */
16163static struct hda_verb alc861vd_volume_init_verbs[] = { 16734static const struct hda_verb alc861vd_volume_init_verbs[] = {
16164 /* 16735 /*
16165 * Unmute ADC0 and set the default input to mic-in 16736 * Unmute ADC0 and set the default input to mic-in
16166 */ 16737 */
@@ -16210,7 +16781,7 @@ static struct hda_verb alc861vd_volume_init_verbs[] = {
16210 * 3-stack pin configuration: 16781 * 3-stack pin configuration:
16211 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 16782 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16212 */ 16783 */
16213static struct hda_verb alc861vd_3stack_init_verbs[] = { 16784static const struct hda_verb alc861vd_3stack_init_verbs[] = {
16214 /* 16785 /*
16215 * Set pin mode and muting 16786 * Set pin mode and muting
16216 */ 16787 */
@@ -16241,7 +16812,7 @@ static struct hda_verb alc861vd_3stack_init_verbs[] = {
16241/* 16812/*
16242 * 6-stack pin configuration: 16813 * 6-stack pin configuration:
16243 */ 16814 */
16244static struct hda_verb alc861vd_6stack_init_verbs[] = { 16815static const struct hda_verb alc861vd_6stack_init_verbs[] = {
16245 /* 16816 /*
16246 * Set pin mode and muting 16817 * Set pin mode and muting
16247 */ 16818 */
@@ -16282,18 +16853,18 @@ static struct hda_verb alc861vd_6stack_init_verbs[] = {
16282 { } 16853 { }
16283}; 16854};
16284 16855
16285static struct hda_verb alc861vd_eapd_verbs[] = { 16856static const struct hda_verb alc861vd_eapd_verbs[] = {
16286 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16857 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16287 { } 16858 { }
16288}; 16859};
16289 16860
16290static struct hda_verb alc660vd_eapd_verbs[] = { 16861static const struct hda_verb alc660vd_eapd_verbs[] = {
16291 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16862 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16292 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16863 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16293 { } 16864 { }
16294}; 16865};
16295 16866
16296static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 16867static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16297 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16868 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16298 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16869 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16299 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 16870 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
@@ -16302,29 +16873,19 @@ static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16302 {} 16873 {}
16303}; 16874};
16304 16875
16305static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16306{
16307 unsigned int present;
16308 unsigned char bits;
16309
16310 present = snd_hda_jack_detect(codec, 0x18);
16311 bits = present ? HDA_AMP_MUTE : 0;
16312
16313 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16314 HDA_AMP_MUTE, bits);
16315}
16316
16317static void alc861vd_lenovo_setup(struct hda_codec *codec) 16876static void alc861vd_lenovo_setup(struct hda_codec *codec)
16318{ 16877{
16319 struct alc_spec *spec = codec->spec; 16878 struct alc_spec *spec = codec->spec;
16320 spec->autocfg.hp_pins[0] = 0x1b; 16879 spec->autocfg.hp_pins[0] = 0x1b;
16321 spec->autocfg.speaker_pins[0] = 0x14; 16880 spec->autocfg.speaker_pins[0] = 0x14;
16881 spec->automute = 1;
16882 spec->automute_mode = ALC_AUTOMUTE_AMP;
16322} 16883}
16323 16884
16324static void alc861vd_lenovo_init_hook(struct hda_codec *codec) 16885static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16325{ 16886{
16326 alc_automute_amp(codec); 16887 alc_hp_automute(codec);
16327 alc861vd_lenovo_mic_automute(codec); 16888 alc88x_simple_mic_automute(codec);
16328} 16889}
16329 16890
16330static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 16891static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
@@ -16332,15 +16893,15 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16332{ 16893{
16333 switch (res >> 26) { 16894 switch (res >> 26) {
16334 case ALC880_MIC_EVENT: 16895 case ALC880_MIC_EVENT:
16335 alc861vd_lenovo_mic_automute(codec); 16896 alc88x_simple_mic_automute(codec);
16336 break; 16897 break;
16337 default: 16898 default:
16338 alc_automute_amp_unsol_event(codec, res); 16899 alc_sku_unsol_event(codec, res);
16339 break; 16900 break;
16340 } 16901 }
16341} 16902}
16342 16903
16343static struct hda_verb alc861vd_dallas_verbs[] = { 16904static const struct hda_verb alc861vd_dallas_verbs[] = {
16344 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16905 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16345 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16906 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16346 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16907 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -16392,6 +16953,8 @@ static void alc861vd_dallas_setup(struct hda_codec *codec)
16392 16953
16393 spec->autocfg.hp_pins[0] = 0x15; 16954 spec->autocfg.hp_pins[0] = 0x15;
16394 spec->autocfg.speaker_pins[0] = 0x14; 16955 spec->autocfg.speaker_pins[0] = 0x14;
16956 spec->automute = 1;
16957 spec->automute_mode = ALC_AUTOMUTE_AMP;
16395} 16958}
16396 16959
16397#ifdef CONFIG_SND_HDA_POWER_SAVE 16960#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -16407,7 +16970,7 @@ static void alc861vd_dallas_setup(struct hda_codec *codec)
16407/* 16970/*
16408 * configuration and preset 16971 * configuration and preset
16409 */ 16972 */
16410static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 16973static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16411 [ALC660VD_3ST] = "3stack-660", 16974 [ALC660VD_3ST] = "3stack-660",
16412 [ALC660VD_3ST_DIG] = "3stack-660-digout", 16975 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16413 [ALC660VD_ASUS_V1S] = "asus-v1s", 16976 [ALC660VD_ASUS_V1S] = "asus-v1s",
@@ -16420,7 +16983,7 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16420 [ALC861VD_AUTO] = "auto", 16983 [ALC861VD_AUTO] = "auto",
16421}; 16984};
16422 16985
16423static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 16986static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16424 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 16987 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16425 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 16988 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16426 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 16989 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
@@ -16439,7 +17002,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16439 {} 17002 {}
16440}; 17003};
16441 17004
16442static struct alc_config_preset alc861vd_presets[] = { 17005static const struct alc_config_preset alc861vd_presets[] = {
16443 [ALC660VD_3ST] = { 17006 [ALC660VD_3ST] = {
16444 .mixers = { alc861vd_3st_mixer }, 17007 .mixers = { alc861vd_3st_mixer },
16445 .init_verbs = { alc861vd_volume_init_verbs, 17008 .init_verbs = { alc861vd_volume_init_verbs,
@@ -16516,9 +17079,9 @@ static struct alc_config_preset alc861vd_presets[] = {
16516 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17079 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16517 .channel_mode = alc861vd_3stack_2ch_modes, 17080 .channel_mode = alc861vd_3stack_2ch_modes,
16518 .input_mux = &alc861vd_dallas_capture_source, 17081 .input_mux = &alc861vd_dallas_capture_source,
16519 .unsol_event = alc_automute_amp_unsol_event, 17082 .unsol_event = alc_sku_unsol_event,
16520 .setup = alc861vd_dallas_setup, 17083 .setup = alc861vd_dallas_setup,
16521 .init_hook = alc_automute_amp, 17084 .init_hook = alc_hp_automute,
16522 }, 17085 },
16523 [ALC861VD_HP] = { 17086 [ALC861VD_HP] = {
16524 .mixers = { alc861vd_hp_mixer }, 17087 .mixers = { alc861vd_hp_mixer },
@@ -16529,9 +17092,9 @@ static struct alc_config_preset alc861vd_presets[] = {
16529 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17092 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16530 .channel_mode = alc861vd_3stack_2ch_modes, 17093 .channel_mode = alc861vd_3stack_2ch_modes,
16531 .input_mux = &alc861vd_hp_capture_source, 17094 .input_mux = &alc861vd_hp_capture_source,
16532 .unsol_event = alc_automute_amp_unsol_event, 17095 .unsol_event = alc_sku_unsol_event,
16533 .setup = alc861vd_dallas_setup, 17096 .setup = alc861vd_dallas_setup,
16534 .init_hook = alc_automute_amp, 17097 .init_hook = alc_hp_automute,
16535 }, 17098 },
16536 [ALC660VD_ASUS_V1S] = { 17099 [ALC660VD_ASUS_V1S] = {
16537 .mixers = { alc861vd_lenovo_mixer }, 17100 .mixers = { alc861vd_lenovo_mixer },
@@ -16557,7 +17120,7 @@ static struct alc_config_preset alc861vd_presets[] = {
16557static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, 17120static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16558 const struct auto_pin_cfg *cfg) 17121 const struct auto_pin_cfg *cfg)
16559{ 17122{
16560 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0); 17123 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
16561} 17124}
16562 17125
16563 17126
@@ -16600,12 +17163,13 @@ static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16600static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 17163static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16601{ 17164{
16602 struct alc_spec *spec = codec->spec; 17165 struct alc_spec *spec = codec->spec;
17166 struct auto_pin_cfg *cfg = &spec->autocfg;
16603 int i; 17167 int i;
16604 17168
16605 for (i = 0; i < AUTO_PIN_LAST; i++) { 17169 for (i = 0; i < cfg->num_inputs; i++) {
16606 hda_nid_t nid = spec->autocfg.input_pins[i]; 17170 hda_nid_t nid = cfg->inputs[i].pin;
16607 if (alc_is_input_pin(codec, nid)) { 17171 if (alc_is_input_pin(codec, nid)) {
16608 alc_set_input_pin(codec, nid, i); 17172 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
16609 if (nid != ALC861VD_PIN_CD_NID && 17173 if (nid != ALC861VD_PIN_CD_NID &&
16610 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 17174 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16611 snd_hda_codec_write(codec, nid, 0, 17175 snd_hda_codec_write(codec, nid, 0,
@@ -16626,11 +17190,18 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16626static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 17190static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16627 const struct auto_pin_cfg *cfg) 17191 const struct auto_pin_cfg *cfg)
16628{ 17192{
16629 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; 17193 static const char * const chname[4] = {
17194 "Front", "Surround", "CLFE", "Side"
17195 };
17196 const char *pfx = alc_get_line_out_pfx(spec, true);
16630 hda_nid_t nid_v, nid_s; 17197 hda_nid_t nid_v, nid_s;
16631 int i, err; 17198 int i, err, noutputs;
16632 17199
16633 for (i = 0; i < cfg->line_outs; i++) { 17200 noutputs = cfg->line_outs;
17201 if (spec->multi_ios > 0)
17202 noutputs += spec->multi_ios;
17203
17204 for (i = 0; i < noutputs; i++) {
16634 if (!spec->multiout.dac_nids[i]) 17205 if (!spec->multiout.dac_nids[i])
16635 continue; 17206 continue;
16636 nid_v = alc861vd_idx_to_mixer_vol( 17207 nid_v = alc861vd_idx_to_mixer_vol(
@@ -16640,7 +17211,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16640 alc880_dac_to_idx( 17211 alc880_dac_to_idx(
16641 spec->multiout.dac_nids[i])); 17212 spec->multiout.dac_nids[i]));
16642 17213
16643 if (i == 2) { 17214 if (!pfx && i == 2) {
16644 /* Center/LFE */ 17215 /* Center/LFE */
16645 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 17216 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16646 "Center", 17217 "Center",
@@ -16667,24 +17238,20 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16667 if (err < 0) 17238 if (err < 0)
16668 return err; 17239 return err;
16669 } else { 17240 } else {
16670 const char *pfx; 17241 const char *name = pfx;
16671 if (cfg->line_outs == 1 && 17242 int index = i;
16672 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 17243 if (!name) {
16673 if (!cfg->hp_pins) 17244 name = chname[i];
16674 pfx = "Speaker"; 17245 index = 0;
16675 else 17246 }
16676 pfx = "PCM"; 17247 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16677 } else 17248 name, index,
16678 pfx = chname[i];
16679 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
16680 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 17249 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16681 HDA_OUTPUT)); 17250 HDA_OUTPUT));
16682 if (err < 0) 17251 if (err < 0)
16683 return err; 17252 return err;
16684 if (cfg->line_outs == 1 && 17253 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16685 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 17254 name, index,
16686 pfx = "Speaker";
16687 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
16688 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 17255 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
16689 HDA_INPUT)); 17256 HDA_INPUT));
16690 if (err < 0) 17257 if (err < 0)
@@ -16747,7 +17314,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
16747{ 17314{
16748 struct alc_spec *spec = codec->spec; 17315 struct alc_spec *spec = codec->spec;
16749 int err; 17316 int err;
16750 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 17317 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16751 17318
16752 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 17319 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16753 alc861vd_ignore); 17320 alc861vd_ignore);
@@ -16759,6 +17326,9 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
16759 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 17326 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16760 if (err < 0) 17327 if (err < 0)
16761 return err; 17328 return err;
17329 err = alc_auto_add_multi_channel_mode(codec);
17330 if (err < 0)
17331 return err;
16762 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 17332 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16763 if (err < 0) 17333 if (err < 0)
16764 return err; 17334 return err;
@@ -16815,20 +17385,19 @@ enum {
16815}; 17385};
16816 17386
16817/* reset GPIO1 */ 17387/* reset GPIO1 */
16818static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
16819 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16820 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16821 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16822 { }
16823};
16824
16825static const struct alc_fixup alc861vd_fixups[] = { 17388static const struct alc_fixup alc861vd_fixups[] = {
16826 [ALC660VD_FIX_ASUS_GPIO1] = { 17389 [ALC660VD_FIX_ASUS_GPIO1] = {
16827 .verbs = alc660vd_fix_asus_gpio1_verbs, 17390 .type = ALC_FIXUP_VERBS,
17391 .v.verbs = (const struct hda_verb[]) {
17392 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17393 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17394 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17395 { }
17396 }
16828 }, 17397 },
16829}; 17398};
16830 17399
16831static struct snd_pci_quirk alc861vd_fixup_tbl[] = { 17400static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16832 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), 17401 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16833 {} 17402 {}
16834}; 17403};
@@ -16854,8 +17423,10 @@ static int patch_alc861vd(struct hda_codec *codec)
16854 board_config = ALC861VD_AUTO; 17423 board_config = ALC861VD_AUTO;
16855 } 17424 }
16856 17425
16857 if (board_config == ALC861VD_AUTO) 17426 if (board_config == ALC861VD_AUTO) {
16858 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1); 17427 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17428 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17429 }
16859 17430
16860 if (board_config == ALC861VD_AUTO) { 17431 if (board_config == ALC861VD_AUTO) {
16861 /* automatic parse from the BIOS config */ 17432 /* automatic parse from the BIOS config */
@@ -16903,13 +17474,13 @@ static int patch_alc861vd(struct hda_codec *codec)
16903 17474
16904 spec->vmaster_nid = 0x02; 17475 spec->vmaster_nid = 0x02;
16905 17476
16906 if (board_config == ALC861VD_AUTO) 17477 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16907 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
16908 17478
16909 codec->patch_ops = alc_patch_ops; 17479 codec->patch_ops = alc_patch_ops;
16910 17480
16911 if (board_config == ALC861VD_AUTO) 17481 if (board_config == ALC861VD_AUTO)
16912 spec->init_hook = alc861vd_auto_init; 17482 spec->init_hook = alc861vd_auto_init;
17483 spec->shutup = alc_eapd_shutup;
16913#ifdef CONFIG_SND_HDA_POWER_SAVE 17484#ifdef CONFIG_SND_HDA_POWER_SAVE
16914 if (!spec->loopback.amplist) 17485 if (!spec->loopback.amplist)
16915 spec->loopback.amplist = alc861vd_loopbacks; 17486 spec->loopback.amplist = alc861vd_loopbacks;
@@ -16932,32 +17503,32 @@ static int patch_alc861vd(struct hda_codec *codec)
16932#define ALC662_DIGOUT_NID 0x06 17503#define ALC662_DIGOUT_NID 0x06
16933#define ALC662_DIGIN_NID 0x0a 17504#define ALC662_DIGIN_NID 0x0a
16934 17505
16935static hda_nid_t alc662_dac_nids[4] = { 17506static const hda_nid_t alc662_dac_nids[3] = {
16936 /* front, rear, clfe, rear_surr */ 17507 /* front, rear, clfe */
16937 0x02, 0x03, 0x04 17508 0x02, 0x03, 0x04
16938}; 17509};
16939 17510
16940static hda_nid_t alc272_dac_nids[2] = { 17511static const hda_nid_t alc272_dac_nids[2] = {
16941 0x02, 0x03 17512 0x02, 0x03
16942}; 17513};
16943 17514
16944static hda_nid_t alc662_adc_nids[2] = { 17515static const hda_nid_t alc662_adc_nids[2] = {
16945 /* ADC1-2 */ 17516 /* ADC1-2 */
16946 0x09, 0x08 17517 0x09, 0x08
16947}; 17518};
16948 17519
16949static hda_nid_t alc272_adc_nids[1] = { 17520static const hda_nid_t alc272_adc_nids[1] = {
16950 /* ADC1-2 */ 17521 /* ADC1-2 */
16951 0x08, 17522 0x08,
16952}; 17523};
16953 17524
16954static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; 17525static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
16955static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; 17526static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16956 17527
16957 17528
16958/* input MUX */ 17529/* input MUX */
16959/* FIXME: should be a matrix-type input source selection */ 17530/* FIXME: should be a matrix-type input source selection */
16960static struct hda_input_mux alc662_capture_source = { 17531static const struct hda_input_mux alc662_capture_source = {
16961 .num_items = 4, 17532 .num_items = 4,
16962 .items = { 17533 .items = {
16963 { "Mic", 0x0 }, 17534 { "Mic", 0x0 },
@@ -16967,7 +17538,7 @@ static struct hda_input_mux alc662_capture_source = {
16967 }, 17538 },
16968}; 17539};
16969 17540
16970static struct hda_input_mux alc662_lenovo_101e_capture_source = { 17541static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
16971 .num_items = 2, 17542 .num_items = 2,
16972 .items = { 17543 .items = {
16973 { "Mic", 0x1 }, 17544 { "Mic", 0x1 },
@@ -16975,7 +17546,7 @@ static struct hda_input_mux alc662_lenovo_101e_capture_source = {
16975 }, 17546 },
16976}; 17547};
16977 17548
16978static struct hda_input_mux alc663_capture_source = { 17549static const struct hda_input_mux alc663_capture_source = {
16979 .num_items = 3, 17550 .num_items = 3,
16980 .items = { 17551 .items = {
16981 { "Mic", 0x0 }, 17552 { "Mic", 0x0 },
@@ -16985,7 +17556,7 @@ static struct hda_input_mux alc663_capture_source = {
16985}; 17556};
16986 17557
16987#if 0 /* set to 1 for testing other input sources below */ 17558#if 0 /* set to 1 for testing other input sources below */
16988static struct hda_input_mux alc272_nc10_capture_source = { 17559static const struct hda_input_mux alc272_nc10_capture_source = {
16989 .num_items = 16, 17560 .num_items = 16,
16990 .items = { 17561 .items = {
16991 { "Autoselect Mic", 0x0 }, 17562 { "Autoselect Mic", 0x0 },
@@ -17011,14 +17582,14 @@ static struct hda_input_mux alc272_nc10_capture_source = {
17011/* 17582/*
17012 * 2ch mode 17583 * 2ch mode
17013 */ 17584 */
17014static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 17585static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17015 { 2, NULL } 17586 { 2, NULL }
17016}; 17587};
17017 17588
17018/* 17589/*
17019 * 2ch mode 17590 * 2ch mode
17020 */ 17591 */
17021static struct hda_verb alc662_3ST_ch2_init[] = { 17592static const struct hda_verb alc662_3ST_ch2_init[] = {
17022 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 17593 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17023 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 17594 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17024 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 17595 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
@@ -17029,7 +17600,7 @@ static struct hda_verb alc662_3ST_ch2_init[] = {
17029/* 17600/*
17030 * 6ch mode 17601 * 6ch mode
17031 */ 17602 */
17032static struct hda_verb alc662_3ST_ch6_init[] = { 17603static const struct hda_verb alc662_3ST_ch6_init[] = {
17033 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17604 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17034 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 17605 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17035 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 17606 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
@@ -17039,7 +17610,7 @@ static struct hda_verb alc662_3ST_ch6_init[] = {
17039 { } /* end */ 17610 { } /* end */
17040}; 17611};
17041 17612
17042static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 17613static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17043 { 2, alc662_3ST_ch2_init }, 17614 { 2, alc662_3ST_ch2_init },
17044 { 6, alc662_3ST_ch6_init }, 17615 { 6, alc662_3ST_ch6_init },
17045}; 17616};
@@ -17047,7 +17618,7 @@ static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17047/* 17618/*
17048 * 2ch mode 17619 * 2ch mode
17049 */ 17620 */
17050static struct hda_verb alc662_sixstack_ch6_init[] = { 17621static const struct hda_verb alc662_sixstack_ch6_init[] = {
17051 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 17622 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17052 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 17623 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17053 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17624 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -17057,14 +17628,14 @@ static struct hda_verb alc662_sixstack_ch6_init[] = {
17057/* 17628/*
17058 * 6ch mode 17629 * 6ch mode
17059 */ 17630 */
17060static struct hda_verb alc662_sixstack_ch8_init[] = { 17631static const struct hda_verb alc662_sixstack_ch8_init[] = {
17061 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17632 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17062 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17633 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17063 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17634 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17064 { } /* end */ 17635 { } /* end */
17065}; 17636};
17066 17637
17067static struct hda_channel_mode alc662_5stack_modes[2] = { 17638static const struct hda_channel_mode alc662_5stack_modes[2] = {
17068 { 2, alc662_sixstack_ch6_init }, 17639 { 2, alc662_sixstack_ch6_init },
17069 { 6, alc662_sixstack_ch8_init }, 17640 { 6, alc662_sixstack_ch8_init },
17070}; 17641};
@@ -17073,7 +17644,7 @@ static struct hda_channel_mode alc662_5stack_modes[2] = {
17073 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 17644 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17074 */ 17645 */
17075 17646
17076static struct snd_kcontrol_new alc662_base_mixer[] = { 17647static const struct snd_kcontrol_new alc662_base_mixer[] = {
17077 /* output mixer control */ 17648 /* output mixer control */
17078 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 17649 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17079 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17650 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
@@ -17097,7 +17668,7 @@ static struct snd_kcontrol_new alc662_base_mixer[] = {
17097 { } /* end */ 17668 { } /* end */
17098}; 17669};
17099 17670
17100static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 17671static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17101 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17672 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17102 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17673 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17103 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17674 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
@@ -17112,7 +17683,7 @@ static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17112 { } /* end */ 17683 { } /* end */
17113}; 17684};
17114 17685
17115static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 17686static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17116 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17687 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17117 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17688 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17118 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17689 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -17133,7 +17704,7 @@ static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17133 { } /* end */ 17704 { } /* end */
17134}; 17705};
17135 17706
17136static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 17707static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17137 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17708 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17138 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 17709 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17139 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17710 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -17146,21 +17717,21 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17146 { } /* end */ 17717 { } /* end */
17147}; 17718};
17148 17719
17149static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 17720static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17150 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17721 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17151 ALC262_HIPPO_MASTER_SWITCH, 17722 ALC262_HIPPO_MASTER_SWITCH,
17152 17723
17153 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), 17724 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17154 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17725 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17155 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17726 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17156 17727
17157 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 17728 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17158 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17729 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17159 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17730 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17160 { } /* end */ 17731 { } /* end */
17161}; 17732};
17162 17733
17163static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { 17734static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17164 ALC262_HIPPO_MASTER_SWITCH, 17735 ALC262_HIPPO_MASTER_SWITCH,
17165 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17736 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17166 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17737 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -17174,7 +17745,7 @@ static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17174 { } /* end */ 17745 { } /* end */
17175}; 17746};
17176 17747
17177static struct hda_bind_ctls alc663_asus_bind_master_vol = { 17748static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
17178 .ops = &snd_hda_bind_vol, 17749 .ops = &snd_hda_bind_vol,
17179 .values = { 17750 .values = {
17180 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17751 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
@@ -17183,7 +17754,7 @@ static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17183 }, 17754 },
17184}; 17755};
17185 17756
17186static struct hda_bind_ctls alc663_asus_one_bind_switch = { 17757static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
17187 .ops = &snd_hda_bind_sw, 17758 .ops = &snd_hda_bind_sw,
17188 .values = { 17759 .values = {
17189 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17760 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
@@ -17192,7 +17763,7 @@ static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17192 }, 17763 },
17193}; 17764};
17194 17765
17195static struct snd_kcontrol_new alc663_m51va_mixer[] = { 17766static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
17196 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17767 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17197 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), 17768 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17198 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -17200,7 +17771,7 @@ static struct snd_kcontrol_new alc663_m51va_mixer[] = {
17200 { } /* end */ 17771 { } /* end */
17201}; 17772};
17202 17773
17203static struct hda_bind_ctls alc663_asus_tree_bind_switch = { 17774static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17204 .ops = &snd_hda_bind_sw, 17775 .ops = &snd_hda_bind_sw,
17205 .values = { 17776 .values = {
17206 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17777 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
@@ -17210,7 +17781,7 @@ static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17210 }, 17781 },
17211}; 17782};
17212 17783
17213static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { 17784static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17214 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17785 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17215 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), 17786 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17216 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17787 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -17221,7 +17792,7 @@ static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17221 { } /* end */ 17792 { } /* end */
17222}; 17793};
17223 17794
17224static struct hda_bind_ctls alc663_asus_four_bind_switch = { 17795static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
17225 .ops = &snd_hda_bind_sw, 17796 .ops = &snd_hda_bind_sw,
17226 .values = { 17797 .values = {
17227 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17798 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
@@ -17231,7 +17802,7 @@ static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17231 }, 17802 },
17232}; 17803};
17233 17804
17234static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { 17805static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17235 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17806 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17236 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), 17807 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17237 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17808 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -17241,7 +17812,7 @@ static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17241 { } /* end */ 17812 { } /* end */
17242}; 17813};
17243 17814
17244static struct snd_kcontrol_new alc662_1bjd_mixer[] = { 17815static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17245 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17816 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17246 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17817 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17247 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17818 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
@@ -17252,7 +17823,7 @@ static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17252 { } /* end */ 17823 { } /* end */
17253}; 17824};
17254 17825
17255static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { 17826static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17256 .ops = &snd_hda_bind_vol, 17827 .ops = &snd_hda_bind_vol,
17257 .values = { 17828 .values = {
17258 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17829 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
@@ -17261,7 +17832,7 @@ static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17261 }, 17832 },
17262}; 17833};
17263 17834
17264static struct hda_bind_ctls alc663_asus_two_bind_switch = { 17835static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
17265 .ops = &snd_hda_bind_sw, 17836 .ops = &snd_hda_bind_sw,
17266 .values = { 17837 .values = {
17267 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17838 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
@@ -17270,7 +17841,7 @@ static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17270 }, 17841 },
17271}; 17842};
17272 17843
17273static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { 17844static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17274 HDA_BIND_VOL("Master Playback Volume", 17845 HDA_BIND_VOL("Master Playback Volume",
17275 &alc663_asus_two_bind_master_vol), 17846 &alc663_asus_two_bind_master_vol),
17276 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17847 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
@@ -17281,7 +17852,7 @@ static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17281 { } /* end */ 17852 { } /* end */
17282}; 17853};
17283 17854
17284static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { 17855static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17285 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17856 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17286 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17857 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17287 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17858 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -17291,7 +17862,7 @@ static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17291 { } /* end */ 17862 { } /* end */
17292}; 17863};
17293 17864
17294static struct snd_kcontrol_new alc663_g71v_mixer[] = { 17865static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
17295 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17866 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17296 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17867 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17297 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17868 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -17300,26 +17871,26 @@ static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17300 17871
17301 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17872 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17873 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17303 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17874 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17304 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17875 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17305 { } /* end */ 17876 { } /* end */
17306}; 17877};
17307 17878
17308static struct snd_kcontrol_new alc663_g50v_mixer[] = { 17879static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
17309 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17880 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17310 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17881 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17311 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17882 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17312 17883
17313 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17884 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17314 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17885 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17315 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17886 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17316 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17887 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17317 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17888 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17318 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17889 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17319 { } /* end */ 17890 { } /* end */
17320}; 17891};
17321 17892
17322static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { 17893static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17323 .ops = &snd_hda_bind_sw, 17894 .ops = &snd_hda_bind_sw,
17324 .values = { 17895 .values = {
17325 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17896 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
@@ -17331,7 +17902,7 @@ static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17331 }, 17902 },
17332}; 17903};
17333 17904
17334static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { 17905static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17335 .ops = &snd_hda_bind_sw, 17906 .ops = &snd_hda_bind_sw,
17336 .values = { 17907 .values = {
17337 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17908 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
@@ -17340,7 +17911,7 @@ static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17340 }, 17911 },
17341}; 17912};
17342 17913
17343static struct snd_kcontrol_new alc663_mode7_mixer[] = { 17914static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
17344 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17915 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17345 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17916 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17346 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17917 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
@@ -17353,7 +17924,7 @@ static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17353 { } /* end */ 17924 { } /* end */
17354}; 17925};
17355 17926
17356static struct snd_kcontrol_new alc663_mode8_mixer[] = { 17927static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
17357 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17928 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17358 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17929 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17359 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17930 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
@@ -17365,7 +17936,7 @@ static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17365}; 17936};
17366 17937
17367 17938
17368static struct snd_kcontrol_new alc662_chmode_mixer[] = { 17939static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
17369 { 17940 {
17370 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 17941 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17371 .name = "Channel Mode", 17942 .name = "Channel Mode",
@@ -17376,7 +17947,7 @@ static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17376 { } /* end */ 17947 { } /* end */
17377}; 17948};
17378 17949
17379static struct hda_verb alc662_init_verbs[] = { 17950static const struct hda_verb alc662_init_verbs[] = {
17380 /* ADC: mute amp left and right */ 17951 /* ADC: mute amp left and right */
17381 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17952 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17382 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 17953 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -17422,55 +17993,36 @@ static struct hda_verb alc662_init_verbs[] = {
17422 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17993 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17423 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17994 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17424 17995
17425 /* always trun on EAPD */
17426 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17427 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17428
17429 { } 17996 { }
17430}; 17997};
17431 17998
17432static struct hda_verb alc663_init_verbs[] = { 17999static const struct hda_verb alc662_eapd_init_verbs[] = {
17433 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 18000 /* always trun on EAPD */
17434 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18001 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17435 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 18002 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17436 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17437 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17438 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17439 { }
17440};
17441
17442static struct hda_verb alc272_init_verbs[] = {
17443 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17444 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17445 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17446 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17447 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17448 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17449 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17450 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17451 { } 18003 { }
17452}; 18004};
17453 18005
17454static struct hda_verb alc662_sue_init_verbs[] = { 18006static const struct hda_verb alc662_sue_init_verbs[] = {
17455 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 18007 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17456 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 18008 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17457 {} 18009 {}
17458}; 18010};
17459 18011
17460static struct hda_verb alc662_eeepc_sue_init_verbs[] = { 18012static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17461 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18013 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17462 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18014 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17463 {} 18015 {}
17464}; 18016};
17465 18017
17466/* Set Unsolicited Event*/ 18018/* Set Unsolicited Event*/
17467static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { 18019static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17468 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 18020 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17469 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18021 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17470 {} 18022 {}
17471}; 18023};
17472 18024
17473static struct hda_verb alc663_m51va_init_verbs[] = { 18025static const struct hda_verb alc663_m51va_init_verbs[] = {
17474 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18026 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17475 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18027 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17476 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18028 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -17483,7 +18035,7 @@ static struct hda_verb alc663_m51va_init_verbs[] = {
17483 {} 18035 {}
17484}; 18036};
17485 18037
17486static struct hda_verb alc663_21jd_amic_init_verbs[] = { 18038static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
17487 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18039 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17488 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18040 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17489 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18041 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
@@ -17494,7 +18046,7 @@ static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17494 {} 18046 {}
17495}; 18047};
17496 18048
17497static struct hda_verb alc662_1bjd_amic_init_verbs[] = { 18049static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17498 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18050 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17499 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18051 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17500 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18052 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -17506,7 +18058,7 @@ static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17506 {} 18058 {}
17507}; 18059};
17508 18060
17509static struct hda_verb alc663_15jd_amic_init_verbs[] = { 18061static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
17510 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18062 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17511 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17512 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18064 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
@@ -17517,7 +18069,7 @@ static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17517 {} 18069 {}
17518}; 18070};
17519 18071
17520static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { 18072static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17521 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18073 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17522 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18074 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17523 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18075 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -17533,7 +18085,7 @@ static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17533 {} 18085 {}
17534}; 18086};
17535 18087
17536static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { 18088static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17537 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18089 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17538 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18090 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17539 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18091 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -17549,7 +18101,7 @@ static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17549 {} 18101 {}
17550}; 18102};
17551 18103
17552static struct hda_verb alc663_g71v_init_verbs[] = { 18104static const struct hda_verb alc663_g71v_init_verbs[] = {
17553 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18105 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17554 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 18106 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17555 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ 18107 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
@@ -17564,7 +18116,7 @@ static struct hda_verb alc663_g71v_init_verbs[] = {
17564 {} 18116 {}
17565}; 18117};
17566 18118
17567static struct hda_verb alc663_g50v_init_verbs[] = { 18119static const struct hda_verb alc663_g50v_init_verbs[] = {
17568 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18120 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17569 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18121 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17570 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 18122 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
@@ -17574,7 +18126,7 @@ static struct hda_verb alc663_g50v_init_verbs[] = {
17574 {} 18126 {}
17575}; 18127};
17576 18128
17577static struct hda_verb alc662_ecs_init_verbs[] = { 18129static const struct hda_verb alc662_ecs_init_verbs[] = {
17578 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, 18130 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17579 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18131 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17580 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18132 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
@@ -17582,7 +18134,7 @@ static struct hda_verb alc662_ecs_init_verbs[] = {
17582 {} 18134 {}
17583}; 18135};
17584 18136
17585static struct hda_verb alc272_dell_zm1_init_verbs[] = { 18137static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
17586 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18138 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17587 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18139 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17588 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18140 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -17597,7 +18149,7 @@ static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17597 {} 18149 {}
17598}; 18150};
17599 18151
17600static struct hda_verb alc272_dell_init_verbs[] = { 18152static const struct hda_verb alc272_dell_init_verbs[] = {
17601 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18153 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17602 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18154 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18155 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -17612,7 +18164,7 @@ static struct hda_verb alc272_dell_init_verbs[] = {
17612 {} 18164 {}
17613}; 18165};
17614 18166
17615static struct hda_verb alc663_mode7_init_verbs[] = { 18167static const struct hda_verb alc663_mode7_init_verbs[] = {
17616 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18168 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17617 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18169 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17618 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 18170 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -17631,7 +18183,7 @@ static struct hda_verb alc663_mode7_init_verbs[] = {
17631 {} 18183 {}
17632}; 18184};
17633 18185
17634static struct hda_verb alc663_mode8_init_verbs[] = { 18186static const struct hda_verb alc663_mode8_init_verbs[] = {
17635 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18187 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17636 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18188 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17637 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18189 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -17651,61 +18203,29 @@ static struct hda_verb alc663_mode8_init_verbs[] = {
17651 {} 18203 {}
17652}; 18204};
17653 18205
17654static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { 18206static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17655 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 18207 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17656 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 18208 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17657 { } /* end */ 18209 { } /* end */
17658}; 18210};
17659 18211
17660static struct snd_kcontrol_new alc272_auto_capture_mixer[] = { 18212static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17661 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 18213 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17662 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 18214 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17663 { } /* end */ 18215 { } /* end */
17664}; 18216};
17665 18217
17666static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 18218static void alc662_lenovo_101e_setup(struct hda_codec *codec)
17667{
17668 unsigned int present;
17669 unsigned char bits;
17670
17671 present = snd_hda_jack_detect(codec, 0x14);
17672 bits = present ? HDA_AMP_MUTE : 0;
17673
17674 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17675 HDA_AMP_MUTE, bits);
17676}
17677
17678static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17679{ 18219{
17680 unsigned int present; 18220 struct alc_spec *spec = codec->spec;
17681 unsigned char bits;
17682
17683 present = snd_hda_jack_detect(codec, 0x1b);
17684 bits = present ? HDA_AMP_MUTE : 0;
17685
17686 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17687 HDA_AMP_MUTE, bits);
17688 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17689 HDA_AMP_MUTE, bits);
17690}
17691
17692static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17693 unsigned int res)
17694{
17695 if ((res >> 26) == ALC880_HP_EVENT)
17696 alc662_lenovo_101e_all_automute(codec);
17697 if ((res >> 26) == ALC880_FRONT_EVENT)
17698 alc662_lenovo_101e_ispeaker_automute(codec);
17699}
17700 18221
17701/* unsolicited event for HP jack sensing */ 18222 spec->autocfg.hp_pins[0] = 0x1b;
17702static void alc662_eeepc_unsol_event(struct hda_codec *codec, 18223 spec->autocfg.line_out_pins[0] = 0x14;
17703 unsigned int res) 18224 spec->autocfg.speaker_pins[0] = 0x15;
17704{ 18225 spec->automute = 1;
17705 if ((res >> 26) == ALC880_MIC_EVENT) 18226 spec->detect_line = 1;
17706 alc_mic_automute(codec); 18227 spec->automute_lines = 1;
17707 else 18228 spec->automute_mode = ALC_AUTOMUTE_AMP;
17708 alc262_hippo_unsol_event(codec, res);
17709} 18229}
17710 18230
17711static void alc662_eeepc_setup(struct hda_codec *codec) 18231static void alc662_eeepc_setup(struct hda_codec *codec)
@@ -17720,180 +18240,24 @@ static void alc662_eeepc_setup(struct hda_codec *codec)
17720 spec->auto_mic = 1; 18240 spec->auto_mic = 1;
17721} 18241}
17722 18242
17723static void alc662_eeepc_inithook(struct hda_codec *codec)
17724{
17725 alc262_hippo_automute(codec);
17726 alc_mic_automute(codec);
17727}
17728
17729static void alc662_eeepc_ep20_setup(struct hda_codec *codec) 18243static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
17730{ 18244{
17731 struct alc_spec *spec = codec->spec; 18245 struct alc_spec *spec = codec->spec;
17732 18246
17733 spec->autocfg.hp_pins[0] = 0x14; 18247 spec->autocfg.hp_pins[0] = 0x14;
17734 spec->autocfg.speaker_pins[0] = 0x1b; 18248 spec->autocfg.speaker_pins[0] = 0x1b;
17735} 18249 spec->automute = 1;
17736 18250 spec->automute_mode = ALC_AUTOMUTE_AMP;
17737#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
17738
17739static void alc663_m51va_speaker_automute(struct hda_codec *codec)
17740{
17741 unsigned int present;
17742 unsigned char bits;
17743
17744 present = snd_hda_jack_detect(codec, 0x21);
17745 bits = present ? HDA_AMP_MUTE : 0;
17746 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17747 HDA_AMP_MUTE, bits);
17748 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17749 HDA_AMP_MUTE, bits);
17750}
17751
17752static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
17753{
17754 unsigned int present;
17755 unsigned char bits;
17756
17757 present = snd_hda_jack_detect(codec, 0x21);
17758 bits = present ? HDA_AMP_MUTE : 0;
17759 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17760 HDA_AMP_MUTE, bits);
17761 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17762 HDA_AMP_MUTE, bits);
17763 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
17764 HDA_AMP_MUTE, bits);
17765 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
17766 HDA_AMP_MUTE, bits);
17767}
17768
17769static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
17770{
17771 unsigned int present;
17772 unsigned char bits;
17773
17774 present = snd_hda_jack_detect(codec, 0x15);
17775 bits = present ? HDA_AMP_MUTE : 0;
17776 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17777 HDA_AMP_MUTE, bits);
17778 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17779 HDA_AMP_MUTE, bits);
17780 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
17781 HDA_AMP_MUTE, bits);
17782 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
17783 HDA_AMP_MUTE, bits);
17784}
17785
17786static void alc662_f5z_speaker_automute(struct hda_codec *codec)
17787{
17788 unsigned int present;
17789 unsigned char bits;
17790
17791 present = snd_hda_jack_detect(codec, 0x1b);
17792 bits = present ? 0 : PIN_OUT;
17793 snd_hda_codec_write(codec, 0x14, 0,
17794 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
17795}
17796
17797static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
17798{
17799 unsigned int present1, present2;
17800
17801 present1 = snd_hda_jack_detect(codec, 0x21);
17802 present2 = snd_hda_jack_detect(codec, 0x15);
17803
17804 if (present1 || present2) {
17805 snd_hda_codec_write_cache(codec, 0x14, 0,
17806 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17807 } else {
17808 snd_hda_codec_write_cache(codec, 0x14, 0,
17809 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17810 }
17811}
17812
17813static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
17814{
17815 unsigned int present1, present2;
17816
17817 present1 = snd_hda_jack_detect(codec, 0x1b);
17818 present2 = snd_hda_jack_detect(codec, 0x15);
17819
17820 if (present1 || present2) {
17821 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17822 HDA_AMP_MUTE, HDA_AMP_MUTE);
17823 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17824 HDA_AMP_MUTE, HDA_AMP_MUTE);
17825 } else {
17826 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17827 HDA_AMP_MUTE, 0);
17828 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17829 HDA_AMP_MUTE, 0);
17830 }
17831}
17832
17833static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
17834{
17835 unsigned int present1, present2;
17836
17837 present1 = snd_hda_codec_read(codec, 0x1b, 0,
17838 AC_VERB_GET_PIN_SENSE, 0)
17839 & AC_PINSENSE_PRESENCE;
17840 present2 = snd_hda_codec_read(codec, 0x21, 0,
17841 AC_VERB_GET_PIN_SENSE, 0)
17842 & AC_PINSENSE_PRESENCE;
17843
17844 if (present1 || present2) {
17845 snd_hda_codec_write_cache(codec, 0x14, 0,
17846 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17847 snd_hda_codec_write_cache(codec, 0x17, 0,
17848 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17849 } else {
17850 snd_hda_codec_write_cache(codec, 0x14, 0,
17851 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17852 snd_hda_codec_write_cache(codec, 0x17, 0,
17853 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17854 }
17855}
17856
17857static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
17858{
17859 unsigned int present1, present2;
17860
17861 present1 = snd_hda_codec_read(codec, 0x21, 0,
17862 AC_VERB_GET_PIN_SENSE, 0)
17863 & AC_PINSENSE_PRESENCE;
17864 present2 = snd_hda_codec_read(codec, 0x15, 0,
17865 AC_VERB_GET_PIN_SENSE, 0)
17866 & AC_PINSENSE_PRESENCE;
17867
17868 if (present1 || present2) {
17869 snd_hda_codec_write_cache(codec, 0x14, 0,
17870 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17871 snd_hda_codec_write_cache(codec, 0x17, 0,
17872 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17873 } else {
17874 snd_hda_codec_write_cache(codec, 0x14, 0,
17875 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17876 snd_hda_codec_write_cache(codec, 0x17, 0,
17877 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17878 }
17879}
17880
17881static void alc663_m51va_unsol_event(struct hda_codec *codec,
17882 unsigned int res)
17883{
17884 switch (res >> 26) {
17885 case ALC880_HP_EVENT:
17886 alc663_m51va_speaker_automute(codec);
17887 break;
17888 case ALC880_MIC_EVENT:
17889 alc_mic_automute(codec);
17890 break;
17891 }
17892} 18251}
17893 18252
17894static void alc663_m51va_setup(struct hda_codec *codec) 18253static void alc663_m51va_setup(struct hda_codec *codec)
17895{ 18254{
17896 struct alc_spec *spec = codec->spec; 18255 struct alc_spec *spec = codec->spec;
18256 spec->autocfg.hp_pins[0] = 0x21;
18257 spec->autocfg.speaker_pins[0] = 0x14;
18258 spec->automute_mixer_nid[0] = 0x0c;
18259 spec->automute = 1;
18260 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17897 spec->ext_mic.pin = 0x18; 18261 spec->ext_mic.pin = 0x18;
17898 spec->ext_mic.mux_idx = 0; 18262 spec->ext_mic.mux_idx = 0;
17899 spec->int_mic.pin = 0x12; 18263 spec->int_mic.pin = 0x12;
@@ -17901,18 +18265,15 @@ static void alc663_m51va_setup(struct hda_codec *codec)
17901 spec->auto_mic = 1; 18265 spec->auto_mic = 1;
17902} 18266}
17903 18267
17904static void alc663_m51va_inithook(struct hda_codec *codec)
17905{
17906 alc663_m51va_speaker_automute(codec);
17907 alc_mic_automute(codec);
17908}
17909
17910/* ***************** Mode1 ******************************/ 18268/* ***************** Mode1 ******************************/
17911#define alc663_mode1_unsol_event alc663_m51va_unsol_event
17912
17913static void alc663_mode1_setup(struct hda_codec *codec) 18269static void alc663_mode1_setup(struct hda_codec *codec)
17914{ 18270{
17915 struct alc_spec *spec = codec->spec; 18271 struct alc_spec *spec = codec->spec;
18272 spec->autocfg.hp_pins[0] = 0x21;
18273 spec->autocfg.speaker_pins[0] = 0x14;
18274 spec->automute_mixer_nid[0] = 0x0c;
18275 spec->automute = 1;
18276 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17916 spec->ext_mic.pin = 0x18; 18277 spec->ext_mic.pin = 0x18;
17917 spec->ext_mic.mux_idx = 0; 18278 spec->ext_mic.mux_idx = 0;
17918 spec->int_mic.pin = 0x19; 18279 spec->int_mic.pin = 0x19;
@@ -17920,256 +18281,171 @@ static void alc663_mode1_setup(struct hda_codec *codec)
17920 spec->auto_mic = 1; 18281 spec->auto_mic = 1;
17921} 18282}
17922 18283
17923#define alc663_mode1_inithook alc663_m51va_inithook
17924
17925/* ***************** Mode2 ******************************/ 18284/* ***************** Mode2 ******************************/
17926static void alc662_mode2_unsol_event(struct hda_codec *codec, 18285static void alc662_mode2_setup(struct hda_codec *codec)
17927 unsigned int res)
17928{ 18286{
17929 switch (res >> 26) { 18287 struct alc_spec *spec = codec->spec;
17930 case ALC880_HP_EVENT: 18288 spec->autocfg.hp_pins[0] = 0x1b;
17931 alc662_f5z_speaker_automute(codec); 18289 spec->autocfg.speaker_pins[0] = 0x14;
17932 break; 18290 spec->automute = 1;
17933 case ALC880_MIC_EVENT: 18291 spec->automute_mode = ALC_AUTOMUTE_PIN;
17934 alc_mic_automute(codec); 18292 spec->ext_mic.pin = 0x18;
17935 break; 18293 spec->ext_mic.mux_idx = 0;
17936 } 18294 spec->int_mic.pin = 0x19;
18295 spec->int_mic.mux_idx = 1;
18296 spec->auto_mic = 1;
17937} 18297}
17938 18298
17939#define alc662_mode2_setup alc663_mode1_setup
17940
17941static void alc662_mode2_inithook(struct hda_codec *codec)
17942{
17943 alc662_f5z_speaker_automute(codec);
17944 alc_mic_automute(codec);
17945}
17946/* ***************** Mode3 ******************************/ 18299/* ***************** Mode3 ******************************/
17947static void alc663_mode3_unsol_event(struct hda_codec *codec, 18300static void alc663_mode3_setup(struct hda_codec *codec)
17948 unsigned int res)
17949{ 18301{
17950 switch (res >> 26) { 18302 struct alc_spec *spec = codec->spec;
17951 case ALC880_HP_EVENT: 18303 spec->autocfg.hp_pins[0] = 0x21;
17952 alc663_two_hp_m1_speaker_automute(codec); 18304 spec->autocfg.hp_pins[0] = 0x15;
17953 break; 18305 spec->autocfg.speaker_pins[0] = 0x14;
17954 case ALC880_MIC_EVENT: 18306 spec->automute = 1;
17955 alc_mic_automute(codec); 18307 spec->automute_mode = ALC_AUTOMUTE_PIN;
17956 break; 18308 spec->ext_mic.pin = 0x18;
17957 } 18309 spec->ext_mic.mux_idx = 0;
18310 spec->int_mic.pin = 0x19;
18311 spec->int_mic.mux_idx = 1;
18312 spec->auto_mic = 1;
17958} 18313}
17959 18314
17960#define alc663_mode3_setup alc663_mode1_setup
17961
17962static void alc663_mode3_inithook(struct hda_codec *codec)
17963{
17964 alc663_two_hp_m1_speaker_automute(codec);
17965 alc_mic_automute(codec);
17966}
17967/* ***************** Mode4 ******************************/ 18315/* ***************** Mode4 ******************************/
17968static void alc663_mode4_unsol_event(struct hda_codec *codec, 18316static void alc663_mode4_setup(struct hda_codec *codec)
17969 unsigned int res)
17970{ 18317{
17971 switch (res >> 26) { 18318 struct alc_spec *spec = codec->spec;
17972 case ALC880_HP_EVENT: 18319 spec->autocfg.hp_pins[0] = 0x21;
17973 alc663_21jd_two_speaker_automute(codec); 18320 spec->autocfg.speaker_pins[0] = 0x14;
17974 break; 18321 spec->autocfg.speaker_pins[1] = 0x16;
17975 case ALC880_MIC_EVENT: 18322 spec->automute_mixer_nid[0] = 0x0c;
17976 alc_mic_automute(codec); 18323 spec->automute_mixer_nid[1] = 0x0e;
17977 break; 18324 spec->automute = 1;
17978 } 18325 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18326 spec->ext_mic.pin = 0x18;
18327 spec->ext_mic.mux_idx = 0;
18328 spec->int_mic.pin = 0x19;
18329 spec->int_mic.mux_idx = 1;
18330 spec->auto_mic = 1;
17979} 18331}
17980 18332
17981#define alc663_mode4_setup alc663_mode1_setup
17982
17983static void alc663_mode4_inithook(struct hda_codec *codec)
17984{
17985 alc663_21jd_two_speaker_automute(codec);
17986 alc_mic_automute(codec);
17987}
17988/* ***************** Mode5 ******************************/ 18333/* ***************** Mode5 ******************************/
17989static void alc663_mode5_unsol_event(struct hda_codec *codec, 18334static void alc663_mode5_setup(struct hda_codec *codec)
17990 unsigned int res)
17991{ 18335{
17992 switch (res >> 26) { 18336 struct alc_spec *spec = codec->spec;
17993 case ALC880_HP_EVENT: 18337 spec->autocfg.hp_pins[0] = 0x15;
17994 alc663_15jd_two_speaker_automute(codec); 18338 spec->autocfg.speaker_pins[0] = 0x14;
17995 break; 18339 spec->autocfg.speaker_pins[1] = 0x16;
17996 case ALC880_MIC_EVENT: 18340 spec->automute_mixer_nid[0] = 0x0c;
17997 alc_mic_automute(codec); 18341 spec->automute_mixer_nid[1] = 0x0e;
17998 break; 18342 spec->automute = 1;
17999 } 18343 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18344 spec->ext_mic.pin = 0x18;
18345 spec->ext_mic.mux_idx = 0;
18346 spec->int_mic.pin = 0x19;
18347 spec->int_mic.mux_idx = 1;
18348 spec->auto_mic = 1;
18000} 18349}
18001 18350
18002#define alc663_mode5_setup alc663_mode1_setup
18003
18004static void alc663_mode5_inithook(struct hda_codec *codec)
18005{
18006 alc663_15jd_two_speaker_automute(codec);
18007 alc_mic_automute(codec);
18008}
18009/* ***************** Mode6 ******************************/ 18351/* ***************** Mode6 ******************************/
18010static void alc663_mode6_unsol_event(struct hda_codec *codec, 18352static void alc663_mode6_setup(struct hda_codec *codec)
18011 unsigned int res)
18012{ 18353{
18013 switch (res >> 26) { 18354 struct alc_spec *spec = codec->spec;
18014 case ALC880_HP_EVENT: 18355 spec->autocfg.hp_pins[0] = 0x1b;
18015 alc663_two_hp_m2_speaker_automute(codec); 18356 spec->autocfg.hp_pins[0] = 0x15;
18016 break; 18357 spec->autocfg.speaker_pins[0] = 0x14;
18017 case ALC880_MIC_EVENT: 18358 spec->automute_mixer_nid[0] = 0x0c;
18018 alc_mic_automute(codec); 18359 spec->automute = 1;
18019 break; 18360 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18020 } 18361 spec->ext_mic.pin = 0x18;
18021} 18362 spec->ext_mic.mux_idx = 0;
18022 18363 spec->int_mic.pin = 0x19;
18023#define alc663_mode6_setup alc663_mode1_setup 18364 spec->int_mic.mux_idx = 1;
18024 18365 spec->auto_mic = 1;
18025static void alc663_mode6_inithook(struct hda_codec *codec)
18026{
18027 alc663_two_hp_m2_speaker_automute(codec);
18028 alc_mic_automute(codec);
18029} 18366}
18030 18367
18031/* ***************** Mode7 ******************************/ 18368/* ***************** Mode7 ******************************/
18032static void alc663_mode7_unsol_event(struct hda_codec *codec, 18369static void alc663_mode7_setup(struct hda_codec *codec)
18033 unsigned int res)
18034{ 18370{
18035 switch (res >> 26) { 18371 struct alc_spec *spec = codec->spec;
18036 case ALC880_HP_EVENT: 18372 spec->autocfg.hp_pins[0] = 0x1b;
18037 alc663_two_hp_m7_speaker_automute(codec); 18373 spec->autocfg.hp_pins[0] = 0x21;
18038 break; 18374 spec->autocfg.speaker_pins[0] = 0x14;
18039 case ALC880_MIC_EVENT: 18375 spec->autocfg.speaker_pins[0] = 0x17;
18040 alc_mic_automute(codec); 18376 spec->automute = 1;
18041 break; 18377 spec->automute_mode = ALC_AUTOMUTE_PIN;
18042 } 18378 spec->ext_mic.pin = 0x18;
18043} 18379 spec->ext_mic.mux_idx = 0;
18044 18380 spec->int_mic.pin = 0x19;
18045#define alc663_mode7_setup alc663_mode1_setup 18381 spec->int_mic.mux_idx = 1;
18046 18382 spec->auto_mic = 1;
18047static void alc663_mode7_inithook(struct hda_codec *codec)
18048{
18049 alc663_two_hp_m7_speaker_automute(codec);
18050 alc_mic_automute(codec);
18051} 18383}
18052 18384
18053/* ***************** Mode8 ******************************/ 18385/* ***************** Mode8 ******************************/
18054static void alc663_mode8_unsol_event(struct hda_codec *codec, 18386static void alc663_mode8_setup(struct hda_codec *codec)
18055 unsigned int res)
18056{
18057 switch (res >> 26) {
18058 case ALC880_HP_EVENT:
18059 alc663_two_hp_m8_speaker_automute(codec);
18060 break;
18061 case ALC880_MIC_EVENT:
18062 alc_mic_automute(codec);
18063 break;
18064 }
18065}
18066
18067#define alc663_mode8_setup alc663_m51va_setup
18068
18069static void alc663_mode8_inithook(struct hda_codec *codec)
18070{
18071 alc663_two_hp_m8_speaker_automute(codec);
18072 alc_mic_automute(codec);
18073}
18074
18075static void alc663_g71v_hp_automute(struct hda_codec *codec)
18076{
18077 unsigned int present;
18078 unsigned char bits;
18079
18080 present = snd_hda_jack_detect(codec, 0x21);
18081 bits = present ? HDA_AMP_MUTE : 0;
18082 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18083 HDA_AMP_MUTE, bits);
18084 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18085 HDA_AMP_MUTE, bits);
18086}
18087
18088static void alc663_g71v_front_automute(struct hda_codec *codec)
18089{
18090 unsigned int present;
18091 unsigned char bits;
18092
18093 present = snd_hda_jack_detect(codec, 0x15);
18094 bits = present ? HDA_AMP_MUTE : 0;
18095 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18096 HDA_AMP_MUTE, bits);
18097}
18098
18099static void alc663_g71v_unsol_event(struct hda_codec *codec,
18100 unsigned int res)
18101{ 18387{
18102 switch (res >> 26) { 18388 struct alc_spec *spec = codec->spec;
18103 case ALC880_HP_EVENT: 18389 spec->autocfg.hp_pins[0] = 0x21;
18104 alc663_g71v_hp_automute(codec); 18390 spec->autocfg.hp_pins[1] = 0x15;
18105 break; 18391 spec->autocfg.speaker_pins[0] = 0x14;
18106 case ALC880_FRONT_EVENT: 18392 spec->autocfg.speaker_pins[0] = 0x17;
18107 alc663_g71v_front_automute(codec); 18393 spec->automute = 1;
18108 break; 18394 spec->automute_mode = ALC_AUTOMUTE_PIN;
18109 case ALC880_MIC_EVENT: 18395 spec->ext_mic.pin = 0x18;
18110 alc_mic_automute(codec); 18396 spec->ext_mic.mux_idx = 0;
18111 break; 18397 spec->int_mic.pin = 0x12;
18112 } 18398 spec->int_mic.mux_idx = 9;
18113} 18399 spec->auto_mic = 1;
18114
18115#define alc663_g71v_setup alc663_m51va_setup
18116
18117static void alc663_g71v_inithook(struct hda_codec *codec)
18118{
18119 alc663_g71v_front_automute(codec);
18120 alc663_g71v_hp_automute(codec);
18121 alc_mic_automute(codec);
18122} 18400}
18123 18401
18124static void alc663_g50v_unsol_event(struct hda_codec *codec, 18402static void alc663_g71v_setup(struct hda_codec *codec)
18125 unsigned int res)
18126{ 18403{
18127 switch (res >> 26) { 18404 struct alc_spec *spec = codec->spec;
18128 case ALC880_HP_EVENT: 18405 spec->autocfg.hp_pins[0] = 0x21;
18129 alc663_m51va_speaker_automute(codec); 18406 spec->autocfg.line_out_pins[0] = 0x15;
18130 break; 18407 spec->autocfg.speaker_pins[0] = 0x14;
18131 case ALC880_MIC_EVENT: 18408 spec->automute = 1;
18132 alc_mic_automute(codec); 18409 spec->automute_mode = ALC_AUTOMUTE_AMP;
18133 break; 18410 spec->detect_line = 1;
18134 } 18411 spec->automute_lines = 1;
18412 spec->ext_mic.pin = 0x18;
18413 spec->ext_mic.mux_idx = 0;
18414 spec->int_mic.pin = 0x12;
18415 spec->int_mic.mux_idx = 9;
18416 spec->auto_mic = 1;
18135} 18417}
18136 18418
18137#define alc663_g50v_setup alc663_m51va_setup 18419#define alc663_g50v_setup alc663_m51va_setup
18138 18420
18139static void alc663_g50v_inithook(struct hda_codec *codec) 18421static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
18140{
18141 alc663_m51va_speaker_automute(codec);
18142 alc_mic_automute(codec);
18143}
18144
18145static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18146 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18422 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18147 ALC262_HIPPO_MASTER_SWITCH, 18423 ALC262_HIPPO_MASTER_SWITCH,
18148 18424
18149 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), 18425 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18150 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), 18426 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18151 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), 18427 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18152 18428
18153 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 18429 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18154 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18430 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18155 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18431 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18156 { } /* end */ 18432 { } /* end */
18157}; 18433};
18158 18434
18159static struct snd_kcontrol_new alc272_nc10_mixer[] = { 18435static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
18160 /* Master Playback automatically created from Speaker and Headphone */ 18436 /* Master Playback automatically created from Speaker and Headphone */
18161 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18437 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18162 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 18438 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18163 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 18439 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18164 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 18440 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18165 18441
18166 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 18442 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18167 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 18443 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18168 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 18444 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18169 18445
18170 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18446 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18171 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18447 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18172 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 18448 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18173 { } /* end */ 18449 { } /* end */
18174}; 18450};
18175 18451
@@ -18187,11 +18463,11 @@ static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18187/* 18463/*
18188 * configuration and preset 18464 * configuration and preset
18189 */ 18465 */
18190static const char *alc662_models[ALC662_MODEL_LAST] = { 18466static const char * const alc662_models[ALC662_MODEL_LAST] = {
18191 [ALC662_3ST_2ch_DIG] = "3stack-dig", 18467 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18192 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 18468 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18193 [ALC662_3ST_6ch] = "3stack-6ch", 18469 [ALC662_3ST_6ch] = "3stack-6ch",
18194 [ALC662_5ST_DIG] = "6stack-dig", 18470 [ALC662_5ST_DIG] = "5stack-dig",
18195 [ALC662_LENOVO_101E] = "lenovo-101e", 18471 [ALC662_LENOVO_101E] = "lenovo-101e",
18196 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 18472 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18197 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", 18473 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
@@ -18214,7 +18490,7 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
18214 [ALC662_AUTO] = "auto", 18490 [ALC662_AUTO] = "auto",
18215}; 18491};
18216 18492
18217static struct snd_pci_quirk alc662_cfg_tbl[] = { 18493static const struct snd_pci_quirk alc662_cfg_tbl[] = {
18218 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), 18494 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18219 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), 18495 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18220 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 18496 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
@@ -18292,13 +18568,14 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
18292 ALC662_3ST_6ch_DIG), 18568 ALC662_3ST_6ch_DIG),
18293 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", 18569 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18294 ALC663_ASUS_H13), 18570 ALC663_ASUS_H13),
18571 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
18295 {} 18572 {}
18296}; 18573};
18297 18574
18298static struct alc_config_preset alc662_presets[] = { 18575static const struct alc_config_preset alc662_presets[] = {
18299 [ALC662_3ST_2ch_DIG] = { 18576 [ALC662_3ST_2ch_DIG] = {
18300 .mixers = { alc662_3ST_2ch_mixer }, 18577 .mixers = { alc662_3ST_2ch_mixer },
18301 .init_verbs = { alc662_init_verbs }, 18578 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18302 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18579 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18303 .dac_nids = alc662_dac_nids, 18580 .dac_nids = alc662_dac_nids,
18304 .dig_out_nid = ALC662_DIGOUT_NID, 18581 .dig_out_nid = ALC662_DIGOUT_NID,
@@ -18309,7 +18586,7 @@ static struct alc_config_preset alc662_presets[] = {
18309 }, 18586 },
18310 [ALC662_3ST_6ch_DIG] = { 18587 [ALC662_3ST_6ch_DIG] = {
18311 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18588 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18312 .init_verbs = { alc662_init_verbs }, 18589 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18313 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18590 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18314 .dac_nids = alc662_dac_nids, 18591 .dac_nids = alc662_dac_nids,
18315 .dig_out_nid = ALC662_DIGOUT_NID, 18592 .dig_out_nid = ALC662_DIGOUT_NID,
@@ -18321,7 +18598,7 @@ static struct alc_config_preset alc662_presets[] = {
18321 }, 18598 },
18322 [ALC662_3ST_6ch] = { 18599 [ALC662_3ST_6ch] = {
18323 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18600 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18324 .init_verbs = { alc662_init_verbs }, 18601 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18325 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18602 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18326 .dac_nids = alc662_dac_nids, 18603 .dac_nids = alc662_dac_nids,
18327 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18604 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
@@ -18331,7 +18608,7 @@ static struct alc_config_preset alc662_presets[] = {
18331 }, 18608 },
18332 [ALC662_5ST_DIG] = { 18609 [ALC662_5ST_DIG] = {
18333 .mixers = { alc662_base_mixer, alc662_chmode_mixer }, 18610 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
18334 .init_verbs = { alc662_init_verbs }, 18611 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18335 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18612 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18336 .dac_nids = alc662_dac_nids, 18613 .dac_nids = alc662_dac_nids,
18337 .dig_out_nid = ALC662_DIGOUT_NID, 18614 .dig_out_nid = ALC662_DIGOUT_NID,
@@ -18342,104 +18619,120 @@ static struct alc_config_preset alc662_presets[] = {
18342 }, 18619 },
18343 [ALC662_LENOVO_101E] = { 18620 [ALC662_LENOVO_101E] = {
18344 .mixers = { alc662_lenovo_101e_mixer }, 18621 .mixers = { alc662_lenovo_101e_mixer },
18345 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 18622 .init_verbs = { alc662_init_verbs,
18623 alc662_eapd_init_verbs,
18624 alc662_sue_init_verbs },
18346 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18625 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18347 .dac_nids = alc662_dac_nids, 18626 .dac_nids = alc662_dac_nids,
18348 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18627 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18349 .channel_mode = alc662_3ST_2ch_modes, 18628 .channel_mode = alc662_3ST_2ch_modes,
18350 .input_mux = &alc662_lenovo_101e_capture_source, 18629 .input_mux = &alc662_lenovo_101e_capture_source,
18351 .unsol_event = alc662_lenovo_101e_unsol_event, 18630 .unsol_event = alc_sku_unsol_event,
18352 .init_hook = alc662_lenovo_101e_all_automute, 18631 .setup = alc662_lenovo_101e_setup,
18632 .init_hook = alc_inithook,
18353 }, 18633 },
18354 [ALC662_ASUS_EEEPC_P701] = { 18634 [ALC662_ASUS_EEEPC_P701] = {
18355 .mixers = { alc662_eeepc_p701_mixer }, 18635 .mixers = { alc662_eeepc_p701_mixer },
18356 .init_verbs = { alc662_init_verbs, 18636 .init_verbs = { alc662_init_verbs,
18637 alc662_eapd_init_verbs,
18357 alc662_eeepc_sue_init_verbs }, 18638 alc662_eeepc_sue_init_verbs },
18358 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18639 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18359 .dac_nids = alc662_dac_nids, 18640 .dac_nids = alc662_dac_nids,
18360 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18641 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18361 .channel_mode = alc662_3ST_2ch_modes, 18642 .channel_mode = alc662_3ST_2ch_modes,
18362 .unsol_event = alc662_eeepc_unsol_event, 18643 .unsol_event = alc_sku_unsol_event,
18363 .setup = alc662_eeepc_setup, 18644 .setup = alc662_eeepc_setup,
18364 .init_hook = alc662_eeepc_inithook, 18645 .init_hook = alc_inithook,
18365 }, 18646 },
18366 [ALC662_ASUS_EEEPC_EP20] = { 18647 [ALC662_ASUS_EEEPC_EP20] = {
18367 .mixers = { alc662_eeepc_ep20_mixer, 18648 .mixers = { alc662_eeepc_ep20_mixer,
18368 alc662_chmode_mixer }, 18649 alc662_chmode_mixer },
18369 .init_verbs = { alc662_init_verbs, 18650 .init_verbs = { alc662_init_verbs,
18651 alc662_eapd_init_verbs,
18370 alc662_eeepc_ep20_sue_init_verbs }, 18652 alc662_eeepc_ep20_sue_init_verbs },
18371 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18653 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18372 .dac_nids = alc662_dac_nids, 18654 .dac_nids = alc662_dac_nids,
18373 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18655 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18374 .channel_mode = alc662_3ST_6ch_modes, 18656 .channel_mode = alc662_3ST_6ch_modes,
18375 .input_mux = &alc662_lenovo_101e_capture_source, 18657 .input_mux = &alc662_lenovo_101e_capture_source,
18376 .unsol_event = alc662_eeepc_unsol_event, 18658 .unsol_event = alc_sku_unsol_event,
18377 .setup = alc662_eeepc_ep20_setup, 18659 .setup = alc662_eeepc_ep20_setup,
18378 .init_hook = alc662_eeepc_ep20_inithook, 18660 .init_hook = alc_inithook,
18379 }, 18661 },
18380 [ALC662_ECS] = { 18662 [ALC662_ECS] = {
18381 .mixers = { alc662_ecs_mixer }, 18663 .mixers = { alc662_ecs_mixer },
18382 .init_verbs = { alc662_init_verbs, 18664 .init_verbs = { alc662_init_verbs,
18665 alc662_eapd_init_verbs,
18383 alc662_ecs_init_verbs }, 18666 alc662_ecs_init_verbs },
18384 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18667 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18385 .dac_nids = alc662_dac_nids, 18668 .dac_nids = alc662_dac_nids,
18386 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18669 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18387 .channel_mode = alc662_3ST_2ch_modes, 18670 .channel_mode = alc662_3ST_2ch_modes,
18388 .unsol_event = alc662_eeepc_unsol_event, 18671 .unsol_event = alc_sku_unsol_event,
18389 .setup = alc662_eeepc_setup, 18672 .setup = alc662_eeepc_setup,
18390 .init_hook = alc662_eeepc_inithook, 18673 .init_hook = alc_inithook,
18391 }, 18674 },
18392 [ALC663_ASUS_M51VA] = { 18675 [ALC663_ASUS_M51VA] = {
18393 .mixers = { alc663_m51va_mixer }, 18676 .mixers = { alc663_m51va_mixer },
18394 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 18677 .init_verbs = { alc662_init_verbs,
18678 alc662_eapd_init_verbs,
18679 alc663_m51va_init_verbs },
18395 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18680 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18396 .dac_nids = alc662_dac_nids, 18681 .dac_nids = alc662_dac_nids,
18397 .dig_out_nid = ALC662_DIGOUT_NID, 18682 .dig_out_nid = ALC662_DIGOUT_NID,
18398 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18683 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18399 .channel_mode = alc662_3ST_2ch_modes, 18684 .channel_mode = alc662_3ST_2ch_modes,
18400 .unsol_event = alc663_m51va_unsol_event, 18685 .unsol_event = alc_sku_unsol_event,
18401 .setup = alc663_m51va_setup, 18686 .setup = alc663_m51va_setup,
18402 .init_hook = alc663_m51va_inithook, 18687 .init_hook = alc_inithook,
18403 }, 18688 },
18404 [ALC663_ASUS_G71V] = { 18689 [ALC663_ASUS_G71V] = {
18405 .mixers = { alc663_g71v_mixer }, 18690 .mixers = { alc663_g71v_mixer },
18406 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, 18691 .init_verbs = { alc662_init_verbs,
18692 alc662_eapd_init_verbs,
18693 alc663_g71v_init_verbs },
18407 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18694 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18408 .dac_nids = alc662_dac_nids, 18695 .dac_nids = alc662_dac_nids,
18409 .dig_out_nid = ALC662_DIGOUT_NID, 18696 .dig_out_nid = ALC662_DIGOUT_NID,
18410 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18697 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18411 .channel_mode = alc662_3ST_2ch_modes, 18698 .channel_mode = alc662_3ST_2ch_modes,
18412 .unsol_event = alc663_g71v_unsol_event, 18699 .unsol_event = alc_sku_unsol_event,
18413 .setup = alc663_g71v_setup, 18700 .setup = alc663_g71v_setup,
18414 .init_hook = alc663_g71v_inithook, 18701 .init_hook = alc_inithook,
18415 }, 18702 },
18416 [ALC663_ASUS_H13] = { 18703 [ALC663_ASUS_H13] = {
18417 .mixers = { alc663_m51va_mixer }, 18704 .mixers = { alc663_m51va_mixer },
18418 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 18705 .init_verbs = { alc662_init_verbs,
18706 alc662_eapd_init_verbs,
18707 alc663_m51va_init_verbs },
18419 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18708 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18420 .dac_nids = alc662_dac_nids, 18709 .dac_nids = alc662_dac_nids,
18421 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18710 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18422 .channel_mode = alc662_3ST_2ch_modes, 18711 .channel_mode = alc662_3ST_2ch_modes,
18423 .unsol_event = alc663_m51va_unsol_event, 18712 .setup = alc663_m51va_setup,
18424 .init_hook = alc663_m51va_inithook, 18713 .unsol_event = alc_sku_unsol_event,
18714 .init_hook = alc_inithook,
18425 }, 18715 },
18426 [ALC663_ASUS_G50V] = { 18716 [ALC663_ASUS_G50V] = {
18427 .mixers = { alc663_g50v_mixer }, 18717 .mixers = { alc663_g50v_mixer },
18428 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, 18718 .init_verbs = { alc662_init_verbs,
18719 alc662_eapd_init_verbs,
18720 alc663_g50v_init_verbs },
18429 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18721 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18430 .dac_nids = alc662_dac_nids, 18722 .dac_nids = alc662_dac_nids,
18431 .dig_out_nid = ALC662_DIGOUT_NID, 18723 .dig_out_nid = ALC662_DIGOUT_NID,
18432 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18724 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18433 .channel_mode = alc662_3ST_6ch_modes, 18725 .channel_mode = alc662_3ST_6ch_modes,
18434 .input_mux = &alc663_capture_source, 18726 .input_mux = &alc663_capture_source,
18435 .unsol_event = alc663_g50v_unsol_event, 18727 .unsol_event = alc_sku_unsol_event,
18436 .setup = alc663_g50v_setup, 18728 .setup = alc663_g50v_setup,
18437 .init_hook = alc663_g50v_inithook, 18729 .init_hook = alc_inithook,
18438 }, 18730 },
18439 [ALC663_ASUS_MODE1] = { 18731 [ALC663_ASUS_MODE1] = {
18440 .mixers = { alc663_m51va_mixer }, 18732 .mixers = { alc663_m51va_mixer },
18441 .cap_mixer = alc662_auto_capture_mixer, 18733 .cap_mixer = alc662_auto_capture_mixer,
18442 .init_verbs = { alc662_init_verbs, 18734 .init_verbs = { alc662_init_verbs,
18735 alc662_eapd_init_verbs,
18443 alc663_21jd_amic_init_verbs }, 18736 alc663_21jd_amic_init_verbs },
18444 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18737 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18445 .hp_nid = 0x03, 18738 .hp_nid = 0x03,
@@ -18447,28 +18740,30 @@ static struct alc_config_preset alc662_presets[] = {
18447 .dig_out_nid = ALC662_DIGOUT_NID, 18740 .dig_out_nid = ALC662_DIGOUT_NID,
18448 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18741 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18449 .channel_mode = alc662_3ST_2ch_modes, 18742 .channel_mode = alc662_3ST_2ch_modes,
18450 .unsol_event = alc663_mode1_unsol_event, 18743 .unsol_event = alc_sku_unsol_event,
18451 .setup = alc663_mode1_setup, 18744 .setup = alc663_mode1_setup,
18452 .init_hook = alc663_mode1_inithook, 18745 .init_hook = alc_inithook,
18453 }, 18746 },
18454 [ALC662_ASUS_MODE2] = { 18747 [ALC662_ASUS_MODE2] = {
18455 .mixers = { alc662_1bjd_mixer }, 18748 .mixers = { alc662_1bjd_mixer },
18456 .cap_mixer = alc662_auto_capture_mixer, 18749 .cap_mixer = alc662_auto_capture_mixer,
18457 .init_verbs = { alc662_init_verbs, 18750 .init_verbs = { alc662_init_verbs,
18751 alc662_eapd_init_verbs,
18458 alc662_1bjd_amic_init_verbs }, 18752 alc662_1bjd_amic_init_verbs },
18459 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18753 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18460 .dac_nids = alc662_dac_nids, 18754 .dac_nids = alc662_dac_nids,
18461 .dig_out_nid = ALC662_DIGOUT_NID, 18755 .dig_out_nid = ALC662_DIGOUT_NID,
18462 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18756 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18463 .channel_mode = alc662_3ST_2ch_modes, 18757 .channel_mode = alc662_3ST_2ch_modes,
18464 .unsol_event = alc662_mode2_unsol_event, 18758 .unsol_event = alc_sku_unsol_event,
18465 .setup = alc662_mode2_setup, 18759 .setup = alc662_mode2_setup,
18466 .init_hook = alc662_mode2_inithook, 18760 .init_hook = alc_inithook,
18467 }, 18761 },
18468 [ALC663_ASUS_MODE3] = { 18762 [ALC663_ASUS_MODE3] = {
18469 .mixers = { alc663_two_hp_m1_mixer }, 18763 .mixers = { alc663_two_hp_m1_mixer },
18470 .cap_mixer = alc662_auto_capture_mixer, 18764 .cap_mixer = alc662_auto_capture_mixer,
18471 .init_verbs = { alc662_init_verbs, 18765 .init_verbs = { alc662_init_verbs,
18766 alc662_eapd_init_verbs,
18472 alc663_two_hp_amic_m1_init_verbs }, 18767 alc663_two_hp_amic_m1_init_verbs },
18473 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18768 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18474 .hp_nid = 0x03, 18769 .hp_nid = 0x03,
@@ -18476,14 +18771,15 @@ static struct alc_config_preset alc662_presets[] = {
18476 .dig_out_nid = ALC662_DIGOUT_NID, 18771 .dig_out_nid = ALC662_DIGOUT_NID,
18477 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18772 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18478 .channel_mode = alc662_3ST_2ch_modes, 18773 .channel_mode = alc662_3ST_2ch_modes,
18479 .unsol_event = alc663_mode3_unsol_event, 18774 .unsol_event = alc_sku_unsol_event,
18480 .setup = alc663_mode3_setup, 18775 .setup = alc663_mode3_setup,
18481 .init_hook = alc663_mode3_inithook, 18776 .init_hook = alc_inithook,
18482 }, 18777 },
18483 [ALC663_ASUS_MODE4] = { 18778 [ALC663_ASUS_MODE4] = {
18484 .mixers = { alc663_asus_21jd_clfe_mixer }, 18779 .mixers = { alc663_asus_21jd_clfe_mixer },
18485 .cap_mixer = alc662_auto_capture_mixer, 18780 .cap_mixer = alc662_auto_capture_mixer,
18486 .init_verbs = { alc662_init_verbs, 18781 .init_verbs = { alc662_init_verbs,
18782 alc662_eapd_init_verbs,
18487 alc663_21jd_amic_init_verbs}, 18783 alc663_21jd_amic_init_verbs},
18488 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18784 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18489 .hp_nid = 0x03, 18785 .hp_nid = 0x03,
@@ -18491,14 +18787,15 @@ static struct alc_config_preset alc662_presets[] = {
18491 .dig_out_nid = ALC662_DIGOUT_NID, 18787 .dig_out_nid = ALC662_DIGOUT_NID,
18492 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18788 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18493 .channel_mode = alc662_3ST_2ch_modes, 18789 .channel_mode = alc662_3ST_2ch_modes,
18494 .unsol_event = alc663_mode4_unsol_event, 18790 .unsol_event = alc_sku_unsol_event,
18495 .setup = alc663_mode4_setup, 18791 .setup = alc663_mode4_setup,
18496 .init_hook = alc663_mode4_inithook, 18792 .init_hook = alc_inithook,
18497 }, 18793 },
18498 [ALC663_ASUS_MODE5] = { 18794 [ALC663_ASUS_MODE5] = {
18499 .mixers = { alc663_asus_15jd_clfe_mixer }, 18795 .mixers = { alc663_asus_15jd_clfe_mixer },
18500 .cap_mixer = alc662_auto_capture_mixer, 18796 .cap_mixer = alc662_auto_capture_mixer,
18501 .init_verbs = { alc662_init_verbs, 18797 .init_verbs = { alc662_init_verbs,
18798 alc662_eapd_init_verbs,
18502 alc663_15jd_amic_init_verbs }, 18799 alc663_15jd_amic_init_verbs },
18503 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18800 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18504 .hp_nid = 0x03, 18801 .hp_nid = 0x03,
@@ -18506,14 +18803,15 @@ static struct alc_config_preset alc662_presets[] = {
18506 .dig_out_nid = ALC662_DIGOUT_NID, 18803 .dig_out_nid = ALC662_DIGOUT_NID,
18507 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18804 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18508 .channel_mode = alc662_3ST_2ch_modes, 18805 .channel_mode = alc662_3ST_2ch_modes,
18509 .unsol_event = alc663_mode5_unsol_event, 18806 .unsol_event = alc_sku_unsol_event,
18510 .setup = alc663_mode5_setup, 18807 .setup = alc663_mode5_setup,
18511 .init_hook = alc663_mode5_inithook, 18808 .init_hook = alc_inithook,
18512 }, 18809 },
18513 [ALC663_ASUS_MODE6] = { 18810 [ALC663_ASUS_MODE6] = {
18514 .mixers = { alc663_two_hp_m2_mixer }, 18811 .mixers = { alc663_two_hp_m2_mixer },
18515 .cap_mixer = alc662_auto_capture_mixer, 18812 .cap_mixer = alc662_auto_capture_mixer,
18516 .init_verbs = { alc662_init_verbs, 18813 .init_verbs = { alc662_init_verbs,
18814 alc662_eapd_init_verbs,
18517 alc663_two_hp_amic_m2_init_verbs }, 18815 alc663_two_hp_amic_m2_init_verbs },
18518 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18816 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18519 .hp_nid = 0x03, 18817 .hp_nid = 0x03,
@@ -18521,14 +18819,15 @@ static struct alc_config_preset alc662_presets[] = {
18521 .dig_out_nid = ALC662_DIGOUT_NID, 18819 .dig_out_nid = ALC662_DIGOUT_NID,
18522 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18820 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18523 .channel_mode = alc662_3ST_2ch_modes, 18821 .channel_mode = alc662_3ST_2ch_modes,
18524 .unsol_event = alc663_mode6_unsol_event, 18822 .unsol_event = alc_sku_unsol_event,
18525 .setup = alc663_mode6_setup, 18823 .setup = alc663_mode6_setup,
18526 .init_hook = alc663_mode6_inithook, 18824 .init_hook = alc_inithook,
18527 }, 18825 },
18528 [ALC663_ASUS_MODE7] = { 18826 [ALC663_ASUS_MODE7] = {
18529 .mixers = { alc663_mode7_mixer }, 18827 .mixers = { alc663_mode7_mixer },
18530 .cap_mixer = alc662_auto_capture_mixer, 18828 .cap_mixer = alc662_auto_capture_mixer,
18531 .init_verbs = { alc662_init_verbs, 18829 .init_verbs = { alc662_init_verbs,
18830 alc662_eapd_init_verbs,
18532 alc663_mode7_init_verbs }, 18831 alc663_mode7_init_verbs },
18533 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18832 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18534 .hp_nid = 0x03, 18833 .hp_nid = 0x03,
@@ -18536,14 +18835,15 @@ static struct alc_config_preset alc662_presets[] = {
18536 .dig_out_nid = ALC662_DIGOUT_NID, 18835 .dig_out_nid = ALC662_DIGOUT_NID,
18537 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18836 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18538 .channel_mode = alc662_3ST_2ch_modes, 18837 .channel_mode = alc662_3ST_2ch_modes,
18539 .unsol_event = alc663_mode7_unsol_event, 18838 .unsol_event = alc_sku_unsol_event,
18540 .setup = alc663_mode7_setup, 18839 .setup = alc663_mode7_setup,
18541 .init_hook = alc663_mode7_inithook, 18840 .init_hook = alc_inithook,
18542 }, 18841 },
18543 [ALC663_ASUS_MODE8] = { 18842 [ALC663_ASUS_MODE8] = {
18544 .mixers = { alc663_mode8_mixer }, 18843 .mixers = { alc663_mode8_mixer },
18545 .cap_mixer = alc662_auto_capture_mixer, 18844 .cap_mixer = alc662_auto_capture_mixer,
18546 .init_verbs = { alc662_init_verbs, 18845 .init_verbs = { alc662_init_verbs,
18846 alc662_eapd_init_verbs,
18547 alc663_mode8_init_verbs }, 18847 alc663_mode8_init_verbs },
18548 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18848 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18549 .hp_nid = 0x03, 18849 .hp_nid = 0x03,
@@ -18551,52 +18851,57 @@ static struct alc_config_preset alc662_presets[] = {
18551 .dig_out_nid = ALC662_DIGOUT_NID, 18851 .dig_out_nid = ALC662_DIGOUT_NID,
18552 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18852 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18553 .channel_mode = alc662_3ST_2ch_modes, 18853 .channel_mode = alc662_3ST_2ch_modes,
18554 .unsol_event = alc663_mode8_unsol_event, 18854 .unsol_event = alc_sku_unsol_event,
18555 .setup = alc663_mode8_setup, 18855 .setup = alc663_mode8_setup,
18556 .init_hook = alc663_mode8_inithook, 18856 .init_hook = alc_inithook,
18557 }, 18857 },
18558 [ALC272_DELL] = { 18858 [ALC272_DELL] = {
18559 .mixers = { alc663_m51va_mixer }, 18859 .mixers = { alc663_m51va_mixer },
18560 .cap_mixer = alc272_auto_capture_mixer, 18860 .cap_mixer = alc272_auto_capture_mixer,
18561 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, 18861 .init_verbs = { alc662_init_verbs,
18862 alc662_eapd_init_verbs,
18863 alc272_dell_init_verbs },
18562 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18864 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18563 .dac_nids = alc662_dac_nids, 18865 .dac_nids = alc272_dac_nids,
18564 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18866 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18565 .adc_nids = alc272_adc_nids, 18867 .adc_nids = alc272_adc_nids,
18566 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), 18868 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18567 .capsrc_nids = alc272_capsrc_nids, 18869 .capsrc_nids = alc272_capsrc_nids,
18568 .channel_mode = alc662_3ST_2ch_modes, 18870 .channel_mode = alc662_3ST_2ch_modes,
18569 .unsol_event = alc663_m51va_unsol_event, 18871 .unsol_event = alc_sku_unsol_event,
18570 .setup = alc663_m51va_setup, 18872 .setup = alc663_m51va_setup,
18571 .init_hook = alc663_m51va_inithook, 18873 .init_hook = alc_inithook,
18572 }, 18874 },
18573 [ALC272_DELL_ZM1] = { 18875 [ALC272_DELL_ZM1] = {
18574 .mixers = { alc663_m51va_mixer }, 18876 .mixers = { alc663_m51va_mixer },
18575 .cap_mixer = alc662_auto_capture_mixer, 18877 .cap_mixer = alc662_auto_capture_mixer,
18576 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, 18878 .init_verbs = { alc662_init_verbs,
18879 alc662_eapd_init_verbs,
18880 alc272_dell_zm1_init_verbs },
18577 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18881 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18578 .dac_nids = alc662_dac_nids, 18882 .dac_nids = alc272_dac_nids,
18579 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18883 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18580 .adc_nids = alc662_adc_nids, 18884 .adc_nids = alc662_adc_nids,
18581 .num_adc_nids = 1, 18885 .num_adc_nids = 1,
18582 .capsrc_nids = alc662_capsrc_nids, 18886 .capsrc_nids = alc662_capsrc_nids,
18583 .channel_mode = alc662_3ST_2ch_modes, 18887 .channel_mode = alc662_3ST_2ch_modes,
18584 .unsol_event = alc663_m51va_unsol_event, 18888 .unsol_event = alc_sku_unsol_event,
18585 .setup = alc663_m51va_setup, 18889 .setup = alc663_m51va_setup,
18586 .init_hook = alc663_m51va_inithook, 18890 .init_hook = alc_inithook,
18587 }, 18891 },
18588 [ALC272_SAMSUNG_NC10] = { 18892 [ALC272_SAMSUNG_NC10] = {
18589 .mixers = { alc272_nc10_mixer }, 18893 .mixers = { alc272_nc10_mixer },
18590 .init_verbs = { alc662_init_verbs, 18894 .init_verbs = { alc662_init_verbs,
18895 alc662_eapd_init_verbs,
18591 alc663_21jd_amic_init_verbs }, 18896 alc663_21jd_amic_init_verbs },
18592 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18897 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18593 .dac_nids = alc272_dac_nids, 18898 .dac_nids = alc272_dac_nids,
18594 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18899 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18595 .channel_mode = alc662_3ST_2ch_modes, 18900 .channel_mode = alc662_3ST_2ch_modes,
18596 /*.input_mux = &alc272_nc10_capture_source,*/ 18901 /*.input_mux = &alc272_nc10_capture_source,*/
18597 .unsol_event = alc663_mode4_unsol_event, 18902 .unsol_event = alc_sku_unsol_event,
18598 .setup = alc663_mode4_setup, 18903 .setup = alc663_mode4_setup,
18599 .init_hook = alc663_mode4_inithook, 18904 .init_hook = alc_inithook,
18600 }, 18905 },
18601}; 18906};
18602 18907
@@ -18606,43 +18911,79 @@ static struct alc_config_preset alc662_presets[] = {
18606 */ 18911 */
18607 18912
18608/* convert from MIX nid to DAC */ 18913/* convert from MIX nid to DAC */
18609static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid) 18914static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
18610{ 18915{
18611 if (nid == 0x0f) 18916 hda_nid_t list[5];
18612 return 0x02; 18917 int i, num;
18613 else if (nid >= 0x0c && nid <= 0x0e) 18918
18614 return nid - 0x0c + 0x02; 18919 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18615 else 18920 for (i = 0; i < num; i++) {
18616 return 0; 18921 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18922 return list[i];
18923 }
18924 return 0;
18925}
18926
18927/* go down to the selector widget before the mixer */
18928static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18929{
18930 hda_nid_t srcs[5];
18931 int num = snd_hda_get_connections(codec, pin, srcs,
18932 ARRAY_SIZE(srcs));
18933 if (num != 1 ||
18934 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18935 return pin;
18936 return srcs[0];
18617} 18937}
18618 18938
18619/* get MIX nid connected to the given pin targeted to DAC */ 18939/* get MIX nid connected to the given pin targeted to DAC */
18620static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, 18940static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18621 hda_nid_t dac) 18941 hda_nid_t dac)
18622{ 18942{
18623 hda_nid_t mix[4]; 18943 hda_nid_t mix[5];
18624 int i, num; 18944 int i, num;
18625 18945
18946 pin = alc_go_down_to_selector(codec, pin);
18626 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); 18947 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18627 for (i = 0; i < num; i++) { 18948 for (i = 0; i < num; i++) {
18628 if (alc662_mix_to_dac(mix[i]) == dac) 18949 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
18629 return mix[i]; 18950 return mix[i];
18630 } 18951 }
18631 return 0; 18952 return 0;
18632} 18953}
18633 18954
18955/* select the connection from pin to DAC if needed */
18956static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18957 hda_nid_t dac)
18958{
18959 hda_nid_t mix[5];
18960 int i, num;
18961
18962 pin = alc_go_down_to_selector(codec, pin);
18963 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18964 if (num < 2)
18965 return 0;
18966 for (i = 0; i < num; i++) {
18967 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18968 snd_hda_codec_update_cache(codec, pin, 0,
18969 AC_VERB_SET_CONNECT_SEL, i);
18970 return 0;
18971 }
18972 }
18973 return 0;
18974}
18975
18634/* look for an empty DAC slot */ 18976/* look for an empty DAC slot */
18635static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 18977static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18636{ 18978{
18637 struct alc_spec *spec = codec->spec; 18979 struct alc_spec *spec = codec->spec;
18638 hda_nid_t srcs[5]; 18980 hda_nid_t srcs[5];
18639 int i, j, num; 18981 int i, j, num;
18640 18982
18983 pin = alc_go_down_to_selector(codec, pin);
18641 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); 18984 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18642 if (num < 0)
18643 return 0;
18644 for (i = 0; i < num; i++) { 18985 for (i = 0; i < num; i++) {
18645 hda_nid_t nid = alc662_mix_to_dac(srcs[i]); 18986 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
18646 if (!nid) 18987 if (!nid)
18647 continue; 18988 continue;
18648 for (j = 0; j < spec->multiout.num_dacs; j++) 18989 for (j = 0; j < spec->multiout.num_dacs; j++)
@@ -18664,28 +19005,32 @@ static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18664 19005
18665 spec->multiout.dac_nids = spec->private_dac_nids; 19006 spec->multiout.dac_nids = spec->private_dac_nids;
18666 for (i = 0; i < cfg->line_outs; i++) { 19007 for (i = 0; i < cfg->line_outs; i++) {
18667 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]); 19008 dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
18668 if (!dac) 19009 if (!dac)
18669 continue; 19010 continue;
18670 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 19011 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
18671 } 19012 }
18672 return 0; 19013 return 0;
18673} 19014}
18674 19015
18675static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, 19016static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18676 hda_nid_t nid, unsigned int chs) 19017 hda_nid_t nid, int idx, unsigned int chs)
18677{ 19018{
18678 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 19019 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
18679 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 19020 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18680} 19021}
18681 19022
18682static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, 19023static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
18683 hda_nid_t nid, unsigned int chs) 19024 hda_nid_t nid, int idx, unsigned int chs)
18684{ 19025{
18685 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 19026 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
18686 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); 19027 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18687} 19028}
18688 19029
19030#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19031 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19032#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19033 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
18689#define alc662_add_stereo_vol(spec, pfx, nid) \ 19034#define alc662_add_stereo_vol(spec, pfx, nid) \
18690 alc662_add_vol_ctl(spec, pfx, nid, 3) 19035 alc662_add_vol_ctl(spec, pfx, nid, 3)
18691#define alc662_add_stereo_sw(spec, pfx, nid) \ 19036#define alc662_add_stereo_sw(spec, pfx, nid) \
@@ -18696,20 +19041,29 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
18696 const struct auto_pin_cfg *cfg) 19041 const struct auto_pin_cfg *cfg)
18697{ 19042{
18698 struct alc_spec *spec = codec->spec; 19043 struct alc_spec *spec = codec->spec;
18699 static const char *chname[4] = { 19044 static const char * const chname[4] = {
18700 "Front", "Surround", NULL /*CLFE*/, "Side" 19045 "Front", "Surround", NULL /*CLFE*/, "Side"
18701 }; 19046 };
18702 hda_nid_t nid, mix; 19047 const char *pfx = alc_get_line_out_pfx(spec, true);
18703 int i, err; 19048 hda_nid_t nid, mix, pin;
19049 int i, err, noutputs;
18704 19050
18705 for (i = 0; i < cfg->line_outs; i++) { 19051 noutputs = cfg->line_outs;
19052 if (spec->multi_ios > 0)
19053 noutputs += spec->multi_ios;
19054
19055 for (i = 0; i < noutputs; i++) {
18706 nid = spec->multiout.dac_nids[i]; 19056 nid = spec->multiout.dac_nids[i];
18707 if (!nid) 19057 if (!nid)
18708 continue; 19058 continue;
18709 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); 19059 if (i >= cfg->line_outs)
19060 pin = spec->multi_io[i - 1].pin;
19061 else
19062 pin = cfg->line_out_pins[i];
19063 mix = alc_auto_dac_to_mix(codec, pin, nid);
18710 if (!mix) 19064 if (!mix)
18711 continue; 19065 continue;
18712 if (i == 2) { 19066 if (!pfx && i == 2) {
18713 /* Center/LFE */ 19067 /* Center/LFE */
18714 err = alc662_add_vol_ctl(spec, "Center", nid, 1); 19068 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
18715 if (err < 0) 19069 if (err < 0)
@@ -18724,22 +19078,16 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
18724 if (err < 0) 19078 if (err < 0)
18725 return err; 19079 return err;
18726 } else { 19080 } else {
18727 const char *pfx; 19081 const char *name = pfx;
18728 if (cfg->line_outs == 1 && 19082 int index = i;
18729 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 19083 if (!name) {
18730 if (cfg->hp_outs) 19084 name = chname[i];
18731 pfx = "Speaker"; 19085 index = 0;
18732 else 19086 }
18733 pfx = "PCM"; 19087 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
18734 } else
18735 pfx = chname[i];
18736 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18737 if (err < 0) 19088 if (err < 0)
18738 return err; 19089 return err;
18739 if (cfg->line_outs == 1 && 19090 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
18740 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18741 pfx = "Speaker";
18742 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18743 if (err < 0) 19091 if (err < 0)
18744 return err; 19092 return err;
18745 } 19093 }
@@ -18758,7 +19106,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
18758 19106
18759 if (!pin) 19107 if (!pin)
18760 return 0; 19108 return 0;
18761 nid = alc662_look_for_dac(codec, pin); 19109 nid = alc_auto_look_for_dac(codec, pin);
18762 if (!nid) { 19110 if (!nid) {
18763 /* the corresponding DAC is already occupied */ 19111 /* the corresponding DAC is already occupied */
18764 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) 19112 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
@@ -18768,7 +19116,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
18768 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 19116 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
18769 } 19117 }
18770 19118
18771 mix = alc662_dac_to_mix(codec, pin, nid); 19119 mix = alc_auto_dac_to_mix(codec, pin, nid);
18772 if (!mix) 19120 if (!mix)
18773 return 0; 19121 return 0;
18774 err = alc662_add_vol_ctl(spec, pfx, nid, 3); 19122 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
@@ -18792,14 +19140,21 @@ static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18792 hda_nid_t srcs[HDA_MAX_CONNECTIONS]; 19140 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
18793 19141
18794 alc_set_pin_output(codec, nid, pin_type); 19142 alc_set_pin_output(codec, nid, pin_type);
18795 /* need the manual connection? */
18796 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); 19143 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18797 if (num <= 1)
18798 return;
18799 for (i = 0; i < num; i++) { 19144 for (i = 0; i < num; i++) {
18800 if (alc662_mix_to_dac(srcs[i]) != dac) 19145 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
18801 continue; 19146 continue;
18802 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); 19147 /* need the manual connection? */
19148 if (num > 1)
19149 snd_hda_codec_write(codec, nid, 0,
19150 AC_VERB_SET_CONNECT_SEL, i);
19151 /* unmute mixer widget inputs */
19152 snd_hda_codec_write(codec, srcs[i], 0,
19153 AC_VERB_SET_AMP_GAIN_MUTE,
19154 AMP_IN_UNMUTE(0));
19155 snd_hda_codec_write(codec, srcs[i], 0,
19156 AC_VERB_SET_AMP_GAIN_MUTE,
19157 AMP_IN_UNMUTE(1));
18803 return; 19158 return;
18804 } 19159 }
18805} 19160}
@@ -18838,12 +19193,13 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec)
18838static void alc662_auto_init_analog_input(struct hda_codec *codec) 19193static void alc662_auto_init_analog_input(struct hda_codec *codec)
18839{ 19194{
18840 struct alc_spec *spec = codec->spec; 19195 struct alc_spec *spec = codec->spec;
19196 struct auto_pin_cfg *cfg = &spec->autocfg;
18841 int i; 19197 int i;
18842 19198
18843 for (i = 0; i < AUTO_PIN_LAST; i++) { 19199 for (i = 0; i < cfg->num_inputs; i++) {
18844 hda_nid_t nid = spec->autocfg.input_pins[i]; 19200 hda_nid_t nid = cfg->inputs[i].pin;
18845 if (alc_is_input_pin(codec, nid)) { 19201 if (alc_is_input_pin(codec, nid)) {
18846 alc_set_input_pin(codec, nid, i); 19202 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
18847 if (nid != ALC662_PIN_CD_NID && 19203 if (nid != ALC662_PIN_CD_NID &&
18848 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 19204 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
18849 snd_hda_codec_write(codec, nid, 0, 19205 snd_hda_codec_write(codec, nid, 0,
@@ -18855,11 +19211,164 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec)
18855 19211
18856#define alc662_auto_init_input_src alc882_auto_init_input_src 19212#define alc662_auto_init_input_src alc882_auto_init_input_src
18857 19213
19214/*
19215 * multi-io helper
19216 */
19217static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19218 unsigned int location)
19219{
19220 struct alc_spec *spec = codec->spec;
19221 struct auto_pin_cfg *cfg = &spec->autocfg;
19222 int type, i, num_pins = 0;
19223
19224 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19225 for (i = 0; i < cfg->num_inputs; i++) {
19226 hda_nid_t nid = cfg->inputs[i].pin;
19227 hda_nid_t dac;
19228 unsigned int defcfg, caps;
19229 if (cfg->inputs[i].type != type)
19230 continue;
19231 defcfg = snd_hda_codec_get_pincfg(codec, nid);
19232 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19233 continue;
19234 if (location && get_defcfg_location(defcfg) != location)
19235 continue;
19236 caps = snd_hda_query_pin_caps(codec, nid);
19237 if (!(caps & AC_PINCAP_OUT))
19238 continue;
19239 dac = alc_auto_look_for_dac(codec, nid);
19240 if (!dac)
19241 continue;
19242 spec->multi_io[num_pins].pin = nid;
19243 spec->multi_io[num_pins].dac = dac;
19244 num_pins++;
19245 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19246 }
19247 }
19248 spec->multiout.num_dacs = 1;
19249 if (num_pins < 2)
19250 return 0;
19251 return num_pins;
19252}
19253
19254static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19255 struct snd_ctl_elem_info *uinfo)
19256{
19257 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19258 struct alc_spec *spec = codec->spec;
19259
19260 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19261 uinfo->count = 1;
19262 uinfo->value.enumerated.items = spec->multi_ios + 1;
19263 if (uinfo->value.enumerated.item > spec->multi_ios)
19264 uinfo->value.enumerated.item = spec->multi_ios;
19265 sprintf(uinfo->value.enumerated.name, "%dch",
19266 (uinfo->value.enumerated.item + 1) * 2);
19267 return 0;
19268}
19269
19270static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19271 struct snd_ctl_elem_value *ucontrol)
19272{
19273 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19274 struct alc_spec *spec = codec->spec;
19275 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19276 return 0;
19277}
19278
19279static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19280{
19281 struct alc_spec *spec = codec->spec;
19282 hda_nid_t nid = spec->multi_io[idx].pin;
19283
19284 if (!spec->multi_io[idx].ctl_in)
19285 spec->multi_io[idx].ctl_in =
19286 snd_hda_codec_read(codec, nid, 0,
19287 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19288 if (output) {
19289 snd_hda_codec_update_cache(codec, nid, 0,
19290 AC_VERB_SET_PIN_WIDGET_CONTROL,
19291 PIN_OUT);
19292 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19293 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19294 HDA_AMP_MUTE, 0);
19295 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19296 } else {
19297 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19298 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19299 HDA_AMP_MUTE, HDA_AMP_MUTE);
19300 snd_hda_codec_update_cache(codec, nid, 0,
19301 AC_VERB_SET_PIN_WIDGET_CONTROL,
19302 spec->multi_io[idx].ctl_in);
19303 }
19304 return 0;
19305}
19306
19307static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19308 struct snd_ctl_elem_value *ucontrol)
19309{
19310 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19311 struct alc_spec *spec = codec->spec;
19312 int i, ch;
19313
19314 ch = ucontrol->value.enumerated.item[0];
19315 if (ch < 0 || ch > spec->multi_ios)
19316 return -EINVAL;
19317 if (ch == (spec->ext_channel_count - 1) / 2)
19318 return 0;
19319 spec->ext_channel_count = (ch + 1) * 2;
19320 for (i = 0; i < spec->multi_ios; i++)
19321 alc_set_multi_io(codec, i, i < ch);
19322 spec->multiout.max_channels = spec->ext_channel_count;
19323 return 1;
19324}
19325
19326static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
19327 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19328 .name = "Channel Mode",
19329 .info = alc_auto_ch_mode_info,
19330 .get = alc_auto_ch_mode_get,
19331 .put = alc_auto_ch_mode_put,
19332};
19333
19334static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19335{
19336 struct alc_spec *spec = codec->spec;
19337 struct auto_pin_cfg *cfg = &spec->autocfg;
19338 unsigned int location, defcfg;
19339 int num_pins;
19340
19341 if (cfg->line_outs != 1 ||
19342 cfg->line_out_type != AUTO_PIN_LINE_OUT)
19343 return 0;
19344
19345 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19346 location = get_defcfg_location(defcfg);
19347
19348 num_pins = alc_auto_fill_multi_ios(codec, location);
19349 if (num_pins > 0) {
19350 struct snd_kcontrol_new *knew;
19351
19352 knew = alc_kcontrol_new(spec);
19353 if (!knew)
19354 return -ENOMEM;
19355 *knew = alc_auto_channel_mode_enum;
19356 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19357 if (!knew->name)
19358 return -ENOMEM;
19359
19360 spec->multi_ios = num_pins;
19361 spec->ext_channel_count = 2;
19362 spec->multiout.num_dacs = num_pins + 1;
19363 }
19364 return 0;
19365}
19366
18858static int alc662_parse_auto_config(struct hda_codec *codec) 19367static int alc662_parse_auto_config(struct hda_codec *codec)
18859{ 19368{
18860 struct alc_spec *spec = codec->spec; 19369 struct alc_spec *spec = codec->spec;
18861 int err; 19370 int err;
18862 static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 19371 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18863 19372
18864 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19373 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18865 alc662_ignore); 19374 alc662_ignore);
@@ -18871,6 +19380,9 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
18871 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg); 19380 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
18872 if (err < 0) 19381 if (err < 0)
18873 return err; 19382 return err;
19383 err = alc_auto_add_multi_channel_mode(codec);
19384 if (err < 0)
19385 return err;
18874 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg); 19386 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
18875 if (err < 0) 19387 if (err < 0)
18876 return err; 19388 return err;
@@ -18901,14 +19413,6 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
18901 spec->num_mux_defs = 1; 19413 spec->num_mux_defs = 1;
18902 spec->input_mux = &spec->private_imux[0]; 19414 spec->input_mux = &spec->private_imux[0];
18903 19415
18904 add_verb(spec, alc662_init_verbs);
18905 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18906 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18907 add_verb(spec, alc663_init_verbs);
18908
18909 if (codec->vendor_id == 0x10ec0272)
18910 add_verb(spec, alc272_init_verbs);
18911
18912 err = alc_auto_add_mic_boost(codec); 19416 err = alc_auto_add_mic_boost(codec);
18913 if (err < 0) 19417 if (err < 0)
18914 return err; 19418 return err;
@@ -18935,10 +19439,82 @@ static void alc662_auto_init(struct hda_codec *codec)
18935 alc_inithook(codec); 19439 alc_inithook(codec);
18936} 19440}
18937 19441
19442static void alc272_fixup_mario(struct hda_codec *codec,
19443 const struct alc_fixup *fix, int action)
19444{
19445 if (action != ALC_FIXUP_ACT_PROBE)
19446 return;
19447 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19448 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19449 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19450 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19451 (0 << AC_AMPCAP_MUTE_SHIFT)))
19452 printk(KERN_WARNING
19453 "hda_codec: failed to override amp caps for NID 0x2\n");
19454}
19455
19456enum {
19457 ALC662_FIXUP_ASPIRE,
19458 ALC662_FIXUP_IDEAPAD,
19459 ALC272_FIXUP_MARIO,
19460 ALC662_FIXUP_CZC_P10T,
19461 ALC662_FIXUP_SKU_IGNORE,
19462};
19463
19464static const struct alc_fixup alc662_fixups[] = {
19465 [ALC662_FIXUP_ASPIRE] = {
19466 .type = ALC_FIXUP_PINS,
19467 .v.pins = (const struct alc_pincfg[]) {
19468 { 0x15, 0x99130112 }, /* subwoofer */
19469 { }
19470 }
19471 },
19472 [ALC662_FIXUP_IDEAPAD] = {
19473 .type = ALC_FIXUP_PINS,
19474 .v.pins = (const struct alc_pincfg[]) {
19475 { 0x17, 0x99130112 }, /* subwoofer */
19476 { }
19477 }
19478 },
19479 [ALC272_FIXUP_MARIO] = {
19480 .type = ALC_FIXUP_FUNC,
19481 .v.func = alc272_fixup_mario,
19482 },
19483 [ALC662_FIXUP_CZC_P10T] = {
19484 .type = ALC_FIXUP_VERBS,
19485 .v.verbs = (const struct hda_verb[]) {
19486 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19487 {}
19488 }
19489 },
19490 [ALC662_FIXUP_SKU_IGNORE] = {
19491 .type = ALC_FIXUP_SKU,
19492 .v.sku = ALC_FIXUP_SKU_IGNORE,
19493 },
19494};
19495
19496static const struct snd_pci_quirk alc662_fixup_tbl[] = {
19497 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
19498 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
19499 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
19500 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19501 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19502 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19503 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
19504 {}
19505};
19506
19507static const struct alc_model_fixup alc662_fixup_models[] = {
19508 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19509 {}
19510};
19511
19512
18938static int patch_alc662(struct hda_codec *codec) 19513static int patch_alc662(struct hda_codec *codec)
18939{ 19514{
18940 struct alc_spec *spec; 19515 struct alc_spec *spec;
18941 int err, board_config; 19516 int err, board_config;
19517 int coef;
18942 19518
18943 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 19519 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18944 if (!spec) 19520 if (!spec)
@@ -18950,12 +19526,15 @@ static int patch_alc662(struct hda_codec *codec)
18950 19526
18951 alc_fix_pll_init(codec, 0x20, 0x04, 15); 19527 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18952 19528
18953 if (alc_read_coef_idx(codec, 0) == 0x8020) 19529 coef = alc_read_coef_idx(codec, 0);
19530 if (coef == 0x8020 || coef == 0x8011)
18954 alc_codec_rename(codec, "ALC661"); 19531 alc_codec_rename(codec, "ALC661");
18955 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) && 19532 else if (coef & (1 << 14) &&
18956 codec->bus->pci->subsystem_vendor == 0x1025 && 19533 codec->bus->pci->subsystem_vendor == 0x1025 &&
18957 spec->cdefine.platform_type == 1) 19534 spec->cdefine.platform_type == 1)
18958 alc_codec_rename(codec, "ALC272X"); 19535 alc_codec_rename(codec, "ALC272X");
19536 else if (coef == 0x4011)
19537 alc_codec_rename(codec, "ALC656");
18959 19538
18960 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 19539 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18961 alc662_models, 19540 alc662_models,
@@ -18967,6 +19546,9 @@ static int patch_alc662(struct hda_codec *codec)
18967 } 19546 }
18968 19547
18969 if (board_config == ALC662_AUTO) { 19548 if (board_config == ALC662_AUTO) {
19549 alc_pick_fixup(codec, alc662_fixup_models,
19550 alc662_fixup_tbl, alc662_fixups);
19551 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
18970 /* automatic parse from the BIOS config */ 19552 /* automatic parse from the BIOS config */
18971 err = alc662_parse_auto_config(codec); 19553 err = alc662_parse_auto_config(codec);
18972 if (err < 0) { 19554 if (err < 0) {
@@ -19024,9 +19606,15 @@ static int patch_alc662(struct hda_codec *codec)
19024 } 19606 }
19025 spec->vmaster_nid = 0x02; 19607 spec->vmaster_nid = 0x02;
19026 19608
19609 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19610
19027 codec->patch_ops = alc_patch_ops; 19611 codec->patch_ops = alc_patch_ops;
19028 if (board_config == ALC662_AUTO) 19612 if (board_config == ALC662_AUTO)
19029 spec->init_hook = alc662_auto_init; 19613 spec->init_hook = alc662_auto_init;
19614 spec->shutup = alc_eapd_shutup;
19615
19616 alc_init_jacks(codec);
19617
19030#ifdef CONFIG_SND_HDA_POWER_SAVE 19618#ifdef CONFIG_SND_HDA_POWER_SAVE
19031 if (!spec->loopback.amplist) 19619 if (!spec->loopback.amplist)
19032 spec->loopback.amplist = alc662_loopbacks; 19620 spec->loopback.amplist = alc662_loopbacks;
@@ -19039,7 +19627,10 @@ static int patch_alc888(struct hda_codec *codec)
19039{ 19627{
19040 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){ 19628 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19041 kfree(codec->chip_name); 19629 kfree(codec->chip_name);
19042 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); 19630 if (codec->vendor_id == 0x10ec0887)
19631 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19632 else
19633 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
19043 if (!codec->chip_name) { 19634 if (!codec->chip_name) {
19044 alc_free(codec); 19635 alc_free(codec);
19045 return -ENOMEM; 19636 return -ENOMEM;
@@ -19049,6 +19640,15 @@ static int patch_alc888(struct hda_codec *codec)
19049 return patch_alc882(codec); 19640 return patch_alc882(codec);
19050} 19641}
19051 19642
19643static int patch_alc899(struct hda_codec *codec)
19644{
19645 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19646 kfree(codec->chip_name);
19647 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19648 }
19649 return patch_alc882(codec);
19650}
19651
19052/* 19652/*
19053 * ALC680 support 19653 * ALC680 support
19054 */ 19654 */
@@ -19056,12 +19656,12 @@ static int patch_alc888(struct hda_codec *codec)
19056#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID 19656#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19057#define alc680_modes alc260_modes 19657#define alc680_modes alc260_modes
19058 19658
19059static hda_nid_t alc680_dac_nids[3] = { 19659static const hda_nid_t alc680_dac_nids[3] = {
19060 /* Lout1, Lout2, hp */ 19660 /* Lout1, Lout2, hp */
19061 0x02, 0x03, 0x04 19661 0x02, 0x03, 0x04
19062}; 19662};
19063 19663
19064static hda_nid_t alc680_adc_nids[3] = { 19664static const hda_nid_t alc680_adc_nids[3] = {
19065 /* ADC0-2 */ 19665 /* ADC0-2 */
19066 /* DMIC, MIC, Line-in*/ 19666 /* DMIC, MIC, Line-in*/
19067 0x07, 0x08, 0x09 19667 0x07, 0x08, 0x09
@@ -19070,6 +19670,38 @@ static hda_nid_t alc680_adc_nids[3] = {
19070/* 19670/*
19071 * Analog capture ADC cgange 19671 * Analog capture ADC cgange
19072 */ 19672 */
19673static void alc680_rec_autoswitch(struct hda_codec *codec)
19674{
19675 struct alc_spec *spec = codec->spec;
19676 struct auto_pin_cfg *cfg = &spec->autocfg;
19677 int pin_found = 0;
19678 int type_found = AUTO_PIN_LAST;
19679 hda_nid_t nid;
19680 int i;
19681
19682 for (i = 0; i < cfg->num_inputs; i++) {
19683 nid = cfg->inputs[i].pin;
19684 if (!is_jack_detectable(codec, nid))
19685 continue;
19686 if (snd_hda_jack_detect(codec, nid)) {
19687 if (cfg->inputs[i].type < type_found) {
19688 type_found = cfg->inputs[i].type;
19689 pin_found = nid;
19690 }
19691 }
19692 }
19693
19694 nid = 0x07;
19695 if (pin_found)
19696 snd_hda_get_connections(codec, pin_found, &nid, 1);
19697
19698 if (nid != spec->cur_adc)
19699 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19700 spec->cur_adc = nid;
19701 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19702 spec->cur_adc_format);
19703}
19704
19073static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 19705static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19074 struct hda_codec *codec, 19706 struct hda_codec *codec,
19075 unsigned int stream_tag, 19707 unsigned int stream_tag,
@@ -19077,24 +19709,12 @@ static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19077 struct snd_pcm_substream *substream) 19709 struct snd_pcm_substream *substream)
19078{ 19710{
19079 struct alc_spec *spec = codec->spec; 19711 struct alc_spec *spec = codec->spec;
19080 struct auto_pin_cfg *cfg = &spec->autocfg;
19081 unsigned int pre_mic, pre_line;
19082
19083 pre_mic = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]);
19084 pre_line = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_LINE]);
19085 19712
19713 spec->cur_adc = 0x07;
19086 spec->cur_adc_stream_tag = stream_tag; 19714 spec->cur_adc_stream_tag = stream_tag;
19087 spec->cur_adc_format = format; 19715 spec->cur_adc_format = format;
19088 19716
19089 if (pre_mic || pre_line) { 19717 alc680_rec_autoswitch(codec);
19090 if (pre_mic)
19091 snd_hda_codec_setup_stream(codec, 0x08, stream_tag, 0,
19092 format);
19093 else
19094 snd_hda_codec_setup_stream(codec, 0x09, stream_tag, 0,
19095 format);
19096 } else
19097 snd_hda_codec_setup_stream(codec, 0x07, stream_tag, 0, format);
19098 return 0; 19718 return 0;
19099} 19719}
19100 19720
@@ -19108,7 +19728,7 @@ static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19108 return 0; 19728 return 0;
19109} 19729}
19110 19730
19111static struct hda_pcm_stream alc680_pcm_analog_auto_capture = { 19731static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19112 .substreams = 1, /* can be overridden */ 19732 .substreams = 1, /* can be overridden */
19113 .channels_min = 2, 19733 .channels_min = 2,
19114 .channels_max = 2, 19734 .channels_max = 2,
@@ -19119,19 +19739,19 @@ static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19119 }, 19739 },
19120}; 19740};
19121 19741
19122static struct snd_kcontrol_new alc680_base_mixer[] = { 19742static const struct snd_kcontrol_new alc680_base_mixer[] = {
19123 /* output mixer control */ 19743 /* output mixer control */
19124 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 19744 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19125 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 19745 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19126 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), 19746 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19127 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), 19747 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19128 HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT), 19748 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19129 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 19749 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19130 HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT), 19750 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19131 { } 19751 { }
19132}; 19752};
19133 19753
19134static struct hda_bind_ctls alc680_bind_cap_vol = { 19754static const struct hda_bind_ctls alc680_bind_cap_vol = {
19135 .ops = &snd_hda_bind_vol, 19755 .ops = &snd_hda_bind_vol,
19136 .values = { 19756 .values = {
19137 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), 19757 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
@@ -19141,7 +19761,7 @@ static struct hda_bind_ctls alc680_bind_cap_vol = {
19141 }, 19761 },
19142}; 19762};
19143 19763
19144static struct hda_bind_ctls alc680_bind_cap_switch = { 19764static const struct hda_bind_ctls alc680_bind_cap_switch = {
19145 .ops = &snd_hda_bind_sw, 19765 .ops = &snd_hda_bind_sw,
19146 .values = { 19766 .values = {
19147 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), 19767 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
@@ -19151,7 +19771,7 @@ static struct hda_bind_ctls alc680_bind_cap_switch = {
19151 }, 19771 },
19152}; 19772};
19153 19773
19154static struct snd_kcontrol_new alc680_master_capture_mixer[] = { 19774static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19155 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol), 19775 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19156 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch), 19776 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19157 { } /* end */ 19777 { } /* end */
@@ -19160,7 +19780,7 @@ static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19160/* 19780/*
19161 * generic initialization of ADC, input mixers and output mixers 19781 * generic initialization of ADC, input mixers and output mixers
19162 */ 19782 */
19163static struct hda_verb alc680_init_verbs[] = { 19783static const struct hda_verb alc680_init_verbs[] = {
19164 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19784 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19165 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19785 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19166 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19786 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -19180,6 +19800,7 @@ static struct hda_verb alc680_init_verbs[] = {
19180 19800
19181 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 19801 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19182 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 19802 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19803 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19183 19804
19184 { } 19805 { }
19185}; 19806};
@@ -19192,39 +19813,27 @@ static void alc680_base_setup(struct hda_codec *codec)
19192 spec->autocfg.hp_pins[0] = 0x16; 19813 spec->autocfg.hp_pins[0] = 0x16;
19193 spec->autocfg.speaker_pins[0] = 0x14; 19814 spec->autocfg.speaker_pins[0] = 0x14;
19194 spec->autocfg.speaker_pins[1] = 0x15; 19815 spec->autocfg.speaker_pins[1] = 0x15;
19195 spec->autocfg.input_pins[AUTO_PIN_MIC] = 0x18; 19816 spec->autocfg.num_inputs = 2;
19196 spec->autocfg.input_pins[AUTO_PIN_LINE] = 0x19; 19817 spec->autocfg.inputs[0].pin = 0x18;
19197} 19818 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19198 19819 spec->autocfg.inputs[1].pin = 0x19;
19199static void alc680_rec_autoswitch(struct hda_codec *codec) 19820 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19200{ 19821 spec->automute = 1;
19201 struct alc_spec *spec = codec->spec; 19822 spec->automute_mode = ALC_AUTOMUTE_AMP;
19202 struct auto_pin_cfg *cfg = &spec->autocfg;
19203 unsigned int present;
19204 hda_nid_t new_adc;
19205
19206 present = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]);
19207
19208 new_adc = present ? 0x8 : 0x7;
19209 __snd_hda_codec_cleanup_stream(codec, !present ? 0x8 : 0x7, 1);
19210 snd_hda_codec_setup_stream(codec, new_adc,
19211 spec->cur_adc_stream_tag, 0,
19212 spec->cur_adc_format);
19213
19214} 19823}
19215 19824
19216static void alc680_unsol_event(struct hda_codec *codec, 19825static void alc680_unsol_event(struct hda_codec *codec,
19217 unsigned int res) 19826 unsigned int res)
19218{ 19827{
19219 if ((res >> 26) == ALC880_HP_EVENT) 19828 if ((res >> 26) == ALC880_HP_EVENT)
19220 alc_automute_amp(codec); 19829 alc_hp_automute(codec);
19221 if ((res >> 26) == ALC880_MIC_EVENT) 19830 if ((res >> 26) == ALC880_MIC_EVENT)
19222 alc680_rec_autoswitch(codec); 19831 alc680_rec_autoswitch(codec);
19223} 19832}
19224 19833
19225static void alc680_inithook(struct hda_codec *codec) 19834static void alc680_inithook(struct hda_codec *codec)
19226{ 19835{
19227 alc_automute_amp(codec); 19836 alc_hp_automute(codec);
19228 alc680_rec_autoswitch(codec); 19837 alc680_rec_autoswitch(codec);
19229} 19838}
19230 19839
@@ -19261,7 +19870,7 @@ static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19261 19870
19262 if (err < 0) 19871 if (err < 0)
19263 return err; 19872 return err;
19264 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 19873 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19265 } 19874 }
19266 19875
19267 return 0; 19876 return 0;
@@ -19347,7 +19956,7 @@ static int alc680_parse_auto_config(struct hda_codec *codec)
19347{ 19956{
19348 struct alc_spec *spec = codec->spec; 19957 struct alc_spec *spec = codec->spec;
19349 int err; 19958 int err;
19350 static hda_nid_t alc680_ignore[] = { 0 }; 19959 static const hda_nid_t alc680_ignore[] = { 0 };
19351 19960
19352 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19961 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19353 alc680_ignore); 19962 alc680_ignore);
@@ -19400,17 +20009,17 @@ static void alc680_auto_init(struct hda_codec *codec)
19400/* 20009/*
19401 * configuration and preset 20010 * configuration and preset
19402 */ 20011 */
19403static const char *alc680_models[ALC680_MODEL_LAST] = { 20012static const char * const alc680_models[ALC680_MODEL_LAST] = {
19404 [ALC680_BASE] = "base", 20013 [ALC680_BASE] = "base",
19405 [ALC680_AUTO] = "auto", 20014 [ALC680_AUTO] = "auto",
19406}; 20015};
19407 20016
19408static struct snd_pci_quirk alc680_cfg_tbl[] = { 20017static const struct snd_pci_quirk alc680_cfg_tbl[] = {
19409 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), 20018 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19410 {} 20019 {}
19411}; 20020};
19412 20021
19413static struct alc_config_preset alc680_presets[] = { 20022static const struct alc_config_preset alc680_presets[] = {
19414 [ALC680_BASE] = { 20023 [ALC680_BASE] = {
19415 .mixers = { alc680_base_mixer }, 20024 .mixers = { alc680_base_mixer },
19416 .cap_mixer = alc680_master_capture_mixer, 20025 .cap_mixer = alc680_master_capture_mixer,
@@ -19491,7 +20100,8 @@ static int patch_alc680(struct hda_codec *codec)
19491/* 20100/*
19492 * patch entries 20101 * patch entries
19493 */ 20102 */
19494static struct hda_codec_preset snd_hda_preset_realtek[] = { 20103static const struct hda_codec_preset snd_hda_preset_realtek[] = {
20104 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
19495 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 20105 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
19496 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 20106 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
19497 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 20107 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
@@ -19500,6 +20110,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
19500 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, 20110 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
19501 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 20111 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
19502 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 20112 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
20113 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
19503 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 20114 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
19504 .patch = patch_alc861 }, 20115 .patch = patch_alc861 },
19505 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 20116 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
@@ -19521,12 +20132,13 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
19521 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 20132 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
19522 .patch = patch_alc882 }, 20133 .patch = patch_alc882 },
19523 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 20134 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
19524 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, 20135 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
19525 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 20136 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
19526 .patch = patch_alc882 }, 20137 .patch = patch_alc882 },
19527 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, 20138 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
19528 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, 20139 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
19529 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, 20140 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
20141 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
19530 {} /* terminator */ 20142 {} /* terminator */
19531}; 20143};
19532 20144
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index f419ee8d75f0..2f55f32876fa 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -130,7 +130,7 @@ static int si3054_switch_put(struct snd_kcontrol *kcontrol,
130} 130}
131 131
132 132
133static struct snd_kcontrol_new si3054_modem_mixer[] = { 133static const struct snd_kcontrol_new si3054_modem_mixer[] = {
134 SI3054_KCONTROL("Off-hook Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_OH), 134 SI3054_KCONTROL("Off-hook Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_OH),
135 SI3054_KCONTROL("Caller ID Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_CID), 135 SI3054_KCONTROL("Caller ID Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_CID),
136 {} 136 {}
@@ -181,7 +181,7 @@ static int si3054_pcm_open(struct hda_pcm_stream *hinfo,
181} 181}
182 182
183 183
184static struct hda_pcm_stream si3054_pcm = { 184static const struct hda_pcm_stream si3054_pcm = {
185 .substreams = 1, 185 .substreams = 1,
186 .channels_min = 1, 186 .channels_min = 1,
187 .channels_max = 1, 187 .channels_max = 1,
@@ -200,12 +200,13 @@ static int si3054_build_pcms(struct hda_codec *codec)
200{ 200{
201 struct si3054_spec *spec = codec->spec; 201 struct si3054_spec *spec = codec->spec;
202 struct hda_pcm *info = &spec->pcm; 202 struct hda_pcm *info = &spec->pcm;
203 si3054_pcm.nid = codec->mfg;
204 codec->num_pcms = 1; 203 codec->num_pcms = 1;
205 codec->pcm_info = info; 204 codec->pcm_info = info;
206 info->name = "Si3054 Modem"; 205 info->name = "Si3054 Modem";
207 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm; 206 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm;
208 info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm; 207 info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm;
208 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = codec->mfg;
209 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = codec->mfg;
209 info->pcm_type = HDA_PCM_TYPE_MODEM; 210 info->pcm_type = HDA_PCM_TYPE_MODEM;
210 return 0; 211 return 0;
211} 212}
@@ -263,7 +264,7 @@ static void si3054_free(struct hda_codec *codec)
263/* 264/*
264 */ 265 */
265 266
266static struct hda_codec_ops si3054_patch_ops = { 267static const struct hda_codec_ops si3054_patch_ops = {
267 .build_controls = si3054_build_controls, 268 .build_controls = si3054_build_controls,
268 .build_pcms = si3054_build_pcms, 269 .build_pcms = si3054_build_pcms,
269 .init = si3054_init, 270 .init = si3054_init,
@@ -283,7 +284,7 @@ static int patch_si3054(struct hda_codec *codec)
283/* 284/*
284 * patch entries 285 * patch entries
285 */ 286 */
286static struct hda_codec_preset snd_hda_preset_si3054[] = { 287static const struct hda_codec_preset snd_hda_preset_si3054[] = {
287 { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 }, 288 { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 },
288 { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 }, 289 { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 },
289 { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 }, 290 { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index c16c5ba0fda0..7f81cc2274f3 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -32,6 +32,7 @@
32#include <sound/core.h> 32#include <sound/core.h>
33#include <sound/asoundef.h> 33#include <sound/asoundef.h>
34#include <sound/jack.h> 34#include <sound/jack.h>
35#include <sound/tlv.h>
35#include "hda_codec.h" 36#include "hda_codec.h"
36#include "hda_local.h" 37#include "hda_local.h"
37#include "hda_beep.h" 38#include "hda_beep.h"
@@ -179,18 +180,16 @@ struct sigmatel_event {
179 int data; 180 int data;
180}; 181};
181 182
182struct sigmatel_jack {
183 hda_nid_t nid;
184 int type;
185 struct snd_jack *jack;
186};
187
188struct sigmatel_mic_route { 183struct sigmatel_mic_route {
189 hda_nid_t pin; 184 hda_nid_t pin;
190 signed char mux_idx; 185 signed char mux_idx;
191 signed char dmux_idx; 186 signed char dmux_idx;
192}; 187};
193 188
189#define MAX_PINS_NUM 16
190#define MAX_ADCS_NUM 4
191#define MAX_DMICS_NUM 4
192
194struct sigmatel_spec { 193struct sigmatel_spec {
195 struct snd_kcontrol_new *mixers[4]; 194 struct snd_kcontrol_new *mixers[4];
196 unsigned int num_mixers; 195 unsigned int num_mixers;
@@ -218,18 +217,15 @@ struct sigmatel_spec {
218 unsigned int stream_delay; 217 unsigned int stream_delay;
219 218
220 /* analog loopback */ 219 /* analog loopback */
221 struct snd_kcontrol_new *aloopback_ctl; 220 const struct snd_kcontrol_new *aloopback_ctl;
222 unsigned char aloopback_mask; 221 unsigned char aloopback_mask;
223 unsigned char aloopback_shift; 222 unsigned char aloopback_shift;
224 223
225 /* power management */ 224 /* power management */
226 unsigned int num_pwrs; 225 unsigned int num_pwrs;
227 unsigned int *pwr_mapping; 226 const unsigned int *pwr_mapping;
228 hda_nid_t *pwr_nids; 227 const hda_nid_t *pwr_nids;
229 hda_nid_t *dac_list; 228 const hda_nid_t *dac_list;
230
231 /* jack detection */
232 struct snd_array jacks;
233 229
234 /* events */ 230 /* events */
235 struct snd_array events; 231 struct snd_array events;
@@ -245,26 +241,27 @@ struct sigmatel_spec {
245 int volume_offset; 241 int volume_offset;
246 242
247 /* capture */ 243 /* capture */
248 hda_nid_t *adc_nids; 244 const hda_nid_t *adc_nids;
249 unsigned int num_adcs; 245 unsigned int num_adcs;
250 hda_nid_t *mux_nids; 246 const hda_nid_t *mux_nids;
251 unsigned int num_muxes; 247 unsigned int num_muxes;
252 hda_nid_t *dmic_nids; 248 const hda_nid_t *dmic_nids;
253 unsigned int num_dmics; 249 unsigned int num_dmics;
254 hda_nid_t *dmux_nids; 250 const hda_nid_t *dmux_nids;
255 unsigned int num_dmuxes; 251 unsigned int num_dmuxes;
256 hda_nid_t *smux_nids; 252 const hda_nid_t *smux_nids;
257 unsigned int num_smuxes; 253 unsigned int num_smuxes;
258 unsigned int num_analog_muxes; 254 unsigned int num_analog_muxes;
259 255
260 unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */ 256 const unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */
261 unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */ 257 const unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */
262 unsigned int num_caps; /* number of capture volume/switch elements */ 258 unsigned int num_caps; /* number of capture volume/switch elements */
263 259
264 struct sigmatel_mic_route ext_mic; 260 struct sigmatel_mic_route ext_mic;
265 struct sigmatel_mic_route int_mic; 261 struct sigmatel_mic_route int_mic;
262 struct sigmatel_mic_route dock_mic;
266 263
267 const char **spdif_labels; 264 const char * const *spdif_labels;
268 265
269 hda_nid_t dig_in_nid; 266 hda_nid_t dig_in_nid;
270 hda_nid_t mono_nid; 267 hda_nid_t mono_nid;
@@ -272,12 +269,12 @@ struct sigmatel_spec {
272 hda_nid_t digbeep_nid; 269 hda_nid_t digbeep_nid;
273 270
274 /* pin widgets */ 271 /* pin widgets */
275 hda_nid_t *pin_nids; 272 const hda_nid_t *pin_nids;
276 unsigned int num_pins; 273 unsigned int num_pins;
277 274
278 /* codec specific stuff */ 275 /* codec specific stuff */
279 struct hda_verb *init; 276 const struct hda_verb *init;
280 struct snd_kcontrol_new *mixer; 277 const struct snd_kcontrol_new *mixer;
281 278
282 /* capture source */ 279 /* capture source */
283 struct hda_input_mux *dinput_mux; 280 struct hda_input_mux *dinput_mux;
@@ -307,54 +304,65 @@ struct sigmatel_spec {
307 struct hda_input_mux private_imux; 304 struct hda_input_mux private_imux;
308 struct hda_input_mux private_smux; 305 struct hda_input_mux private_smux;
309 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];
310}; 318};
311 319
312static hda_nid_t stac9200_adc_nids[1] = { 320static const hda_nid_t stac9200_adc_nids[1] = {
313 0x03, 321 0x03,
314}; 322};
315 323
316static hda_nid_t stac9200_mux_nids[1] = { 324static const hda_nid_t stac9200_mux_nids[1] = {
317 0x0c, 325 0x0c,
318}; 326};
319 327
320static hda_nid_t stac9200_dac_nids[1] = { 328static const hda_nid_t stac9200_dac_nids[1] = {
321 0x02, 329 0x02,
322}; 330};
323 331
324static hda_nid_t stac92hd73xx_pwr_nids[8] = { 332static const hda_nid_t stac92hd73xx_pwr_nids[8] = {
325 0x0a, 0x0b, 0x0c, 0xd, 0x0e, 333 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
326 0x0f, 0x10, 0x11 334 0x0f, 0x10, 0x11
327}; 335};
328 336
329static hda_nid_t stac92hd73xx_slave_dig_outs[2] = { 337static const hda_nid_t stac92hd73xx_slave_dig_outs[2] = {
330 0x26, 0, 338 0x26, 0,
331}; 339};
332 340
333static hda_nid_t stac92hd73xx_adc_nids[2] = { 341static const hda_nid_t stac92hd73xx_adc_nids[2] = {
334 0x1a, 0x1b 342 0x1a, 0x1b
335}; 343};
336 344
337#define STAC92HD73XX_NUM_DMICS 2 345#define STAC92HD73XX_NUM_DMICS 2
338static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { 346static const hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
339 0x13, 0x14, 0 347 0x13, 0x14, 0
340}; 348};
341 349
342#define STAC92HD73_DAC_COUNT 5 350#define STAC92HD73_DAC_COUNT 5
343 351
344static hda_nid_t stac92hd73xx_mux_nids[2] = { 352static const hda_nid_t stac92hd73xx_mux_nids[2] = {
345 0x20, 0x21, 353 0x20, 0x21,
346}; 354};
347 355
348static hda_nid_t stac92hd73xx_dmux_nids[2] = { 356static const hda_nid_t stac92hd73xx_dmux_nids[2] = {
349 0x20, 0x21, 357 0x20, 0x21,
350}; 358};
351 359
352static hda_nid_t stac92hd73xx_smux_nids[2] = { 360static const hda_nid_t stac92hd73xx_smux_nids[2] = {
353 0x22, 0x23, 361 0x22, 0x23,
354}; 362};
355 363
356#define STAC92HD73XX_NUM_CAPS 2 364#define STAC92HD73XX_NUM_CAPS 2
357static unsigned long stac92hd73xx_capvols[] = { 365static const unsigned long stac92hd73xx_capvols[] = {
358 HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT), 366 HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT),
359 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 367 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
360}; 368};
@@ -362,239 +370,222 @@ static unsigned long stac92hd73xx_capvols[] = {
362 370
363#define STAC92HD83_DAC_COUNT 3 371#define STAC92HD83_DAC_COUNT 3
364 372
365static hda_nid_t stac92hd83xxx_mux_nids[2] = { 373static const hda_nid_t stac92hd83xxx_pwr_nids[4] = {
366 0x17, 0x18,
367};
368
369static hda_nid_t stac92hd83xxx_adc_nids[2] = {
370 0x15, 0x16,
371};
372
373static hda_nid_t stac92hd83xxx_pwr_nids[4] = {
374 0xa, 0xb, 0xd, 0xe, 374 0xa, 0xb, 0xd, 0xe,
375}; 375};
376 376
377static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { 377static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = {
378 0x1e, 0, 378 0x1e, 0,
379}; 379};
380 380
381static unsigned int stac92hd83xxx_pwr_mapping[4] = { 381static const unsigned int stac92hd83xxx_pwr_mapping[4] = {
382 0x03, 0x0c, 0x20, 0x40, 382 0x03, 0x0c, 0x20, 0x40,
383}; 383};
384 384
385#define STAC92HD83XXX_NUM_CAPS 2 385static const hda_nid_t stac92hd83xxx_dmic_nids[] = {
386static unsigned long stac92hd83xxx_capvols[] = { 386 0x11, 0x20,
387 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
388 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_OUTPUT),
389}; 387};
390#define stac92hd83xxx_capsws stac92hd83xxx_capvols
391 388
392static hda_nid_t stac92hd71bxx_pwr_nids[3] = { 389static const hda_nid_t stac92hd71bxx_pwr_nids[3] = {
393 0x0a, 0x0d, 0x0f 390 0x0a, 0x0d, 0x0f
394}; 391};
395 392
396static hda_nid_t stac92hd71bxx_adc_nids[2] = { 393static const hda_nid_t stac92hd71bxx_adc_nids[2] = {
397 0x12, 0x13, 394 0x12, 0x13,
398}; 395};
399 396
400static hda_nid_t stac92hd71bxx_mux_nids[2] = { 397static const hda_nid_t stac92hd71bxx_mux_nids[2] = {
401 0x1a, 0x1b 398 0x1a, 0x1b
402}; 399};
403 400
404static hda_nid_t stac92hd71bxx_dmux_nids[2] = { 401static const hda_nid_t stac92hd71bxx_dmux_nids[2] = {
405 0x1c, 0x1d, 402 0x1c, 0x1d,
406}; 403};
407 404
408static hda_nid_t stac92hd71bxx_smux_nids[2] = { 405static const hda_nid_t stac92hd71bxx_smux_nids[2] = {
409 0x24, 0x25, 406 0x24, 0x25,
410}; 407};
411 408
412#define STAC92HD71BXX_NUM_DMICS 2 409#define STAC92HD71BXX_NUM_DMICS 2
413static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { 410static const hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
414 0x18, 0x19, 0 411 0x18, 0x19, 0
415}; 412};
416 413
417static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { 414static const hda_nid_t stac92hd71bxx_dmic_5port_nids[STAC92HD71BXX_NUM_DMICS] = {
415 0x18, 0
416};
417
418static const hda_nid_t stac92hd71bxx_slave_dig_outs[2] = {
418 0x22, 0 419 0x22, 0
419}; 420};
420 421
421#define STAC92HD71BXX_NUM_CAPS 2 422#define STAC92HD71BXX_NUM_CAPS 2
422static unsigned long stac92hd71bxx_capvols[] = { 423static const unsigned long stac92hd71bxx_capvols[] = {
423 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), 424 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
424 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), 425 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
425}; 426};
426#define stac92hd71bxx_capsws stac92hd71bxx_capvols 427#define stac92hd71bxx_capsws stac92hd71bxx_capvols
427 428
428static hda_nid_t stac925x_adc_nids[1] = { 429static const hda_nid_t stac925x_adc_nids[1] = {
429 0x03, 430 0x03,
430}; 431};
431 432
432static hda_nid_t stac925x_mux_nids[1] = { 433static const hda_nid_t stac925x_mux_nids[1] = {
433 0x0f, 434 0x0f,
434}; 435};
435 436
436static hda_nid_t stac925x_dac_nids[1] = { 437static const hda_nid_t stac925x_dac_nids[1] = {
437 0x02, 438 0x02,
438}; 439};
439 440
440#define STAC925X_NUM_DMICS 1 441#define STAC925X_NUM_DMICS 1
441static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = { 442static const hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
442 0x15, 0 443 0x15, 0
443}; 444};
444 445
445static hda_nid_t stac925x_dmux_nids[1] = { 446static const hda_nid_t stac925x_dmux_nids[1] = {
446 0x14, 447 0x14,
447}; 448};
448 449
449static unsigned long stac925x_capvols[] = { 450static const unsigned long stac925x_capvols[] = {
450 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), 451 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
451}; 452};
452static unsigned long stac925x_capsws[] = { 453static const unsigned long stac925x_capsws[] = {
453 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 454 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
454}; 455};
455 456
456static hda_nid_t stac922x_adc_nids[2] = { 457static const hda_nid_t stac922x_adc_nids[2] = {
457 0x06, 0x07, 458 0x06, 0x07,
458}; 459};
459 460
460static hda_nid_t stac922x_mux_nids[2] = { 461static const hda_nid_t stac922x_mux_nids[2] = {
461 0x12, 0x13, 462 0x12, 0x13,
462}; 463};
463 464
464#define STAC922X_NUM_CAPS 2 465#define STAC922X_NUM_CAPS 2
465static unsigned long stac922x_capvols[] = { 466static const unsigned long stac922x_capvols[] = {
466 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT), 467 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT),
467 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), 468 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
468}; 469};
469#define stac922x_capsws stac922x_capvols 470#define stac922x_capsws stac922x_capvols
470 471
471static hda_nid_t stac927x_slave_dig_outs[2] = { 472static const hda_nid_t stac927x_slave_dig_outs[2] = {
472 0x1f, 0, 473 0x1f, 0,
473}; 474};
474 475
475static hda_nid_t stac927x_adc_nids[3] = { 476static const hda_nid_t stac927x_adc_nids[3] = {
476 0x07, 0x08, 0x09 477 0x07, 0x08, 0x09
477}; 478};
478 479
479static hda_nid_t stac927x_mux_nids[3] = { 480static const hda_nid_t stac927x_mux_nids[3] = {
480 0x15, 0x16, 0x17 481 0x15, 0x16, 0x17
481}; 482};
482 483
483static hda_nid_t stac927x_smux_nids[1] = { 484static const hda_nid_t stac927x_smux_nids[1] = {
484 0x21, 485 0x21,
485}; 486};
486 487
487static hda_nid_t stac927x_dac_nids[6] = { 488static const hda_nid_t stac927x_dac_nids[6] = {
488 0x02, 0x03, 0x04, 0x05, 0x06, 0 489 0x02, 0x03, 0x04, 0x05, 0x06, 0
489}; 490};
490 491
491static hda_nid_t stac927x_dmux_nids[1] = { 492static const hda_nid_t stac927x_dmux_nids[1] = {
492 0x1b, 493 0x1b,
493}; 494};
494 495
495#define STAC927X_NUM_DMICS 2 496#define STAC927X_NUM_DMICS 2
496static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { 497static const hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
497 0x13, 0x14, 0 498 0x13, 0x14, 0
498}; 499};
499 500
500#define STAC927X_NUM_CAPS 3 501#define STAC927X_NUM_CAPS 3
501static unsigned long stac927x_capvols[] = { 502static const unsigned long stac927x_capvols[] = {
502 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), 503 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
503 HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT), 504 HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT),
504 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT), 505 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT),
505}; 506};
506static unsigned long stac927x_capsws[] = { 507static const unsigned long stac927x_capsws[] = {
507 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 508 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
508 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), 509 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
509 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), 510 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
510}; 511};
511 512
512static const char *stac927x_spdif_labels[5] = { 513static const char * const stac927x_spdif_labels[5] = {
513 "Digital Playback", "ADAT", "Analog Mux 1", 514 "Digital Playback", "ADAT", "Analog Mux 1",
514 "Analog Mux 2", "Analog Mux 3" 515 "Analog Mux 2", "Analog Mux 3"
515}; 516};
516 517
517static hda_nid_t stac9205_adc_nids[2] = { 518static const hda_nid_t stac9205_adc_nids[2] = {
518 0x12, 0x13 519 0x12, 0x13
519}; 520};
520 521
521static hda_nid_t stac9205_mux_nids[2] = { 522static const hda_nid_t stac9205_mux_nids[2] = {
522 0x19, 0x1a 523 0x19, 0x1a
523}; 524};
524 525
525static hda_nid_t stac9205_dmux_nids[1] = { 526static const hda_nid_t stac9205_dmux_nids[1] = {
526 0x1d, 527 0x1d,
527}; 528};
528 529
529static hda_nid_t stac9205_smux_nids[1] = { 530static const hda_nid_t stac9205_smux_nids[1] = {
530 0x21, 531 0x21,
531}; 532};
532 533
533#define STAC9205_NUM_DMICS 2 534#define STAC9205_NUM_DMICS 2
534static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { 535static const hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
535 0x17, 0x18, 0 536 0x17, 0x18, 0
536}; 537};
537 538
538#define STAC9205_NUM_CAPS 2 539#define STAC9205_NUM_CAPS 2
539static unsigned long stac9205_capvols[] = { 540static const unsigned long stac9205_capvols[] = {
540 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT), 541 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT),
541 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT), 542 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT),
542}; 543};
543static unsigned long stac9205_capsws[] = { 544static const unsigned long stac9205_capsws[] = {
544 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), 545 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
545 HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT), 546 HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT),
546}; 547};
547 548
548static hda_nid_t stac9200_pin_nids[8] = { 549static const hda_nid_t stac9200_pin_nids[8] = {
549 0x08, 0x09, 0x0d, 0x0e, 550 0x08, 0x09, 0x0d, 0x0e,
550 0x0f, 0x10, 0x11, 0x12, 551 0x0f, 0x10, 0x11, 0x12,
551}; 552};
552 553
553static hda_nid_t stac925x_pin_nids[8] = { 554static const hda_nid_t stac925x_pin_nids[8] = {
554 0x07, 0x08, 0x0a, 0x0b, 555 0x07, 0x08, 0x0a, 0x0b,
555 0x0c, 0x0d, 0x10, 0x11, 556 0x0c, 0x0d, 0x10, 0x11,
556}; 557};
557 558
558static hda_nid_t stac922x_pin_nids[10] = { 559static const hda_nid_t stac922x_pin_nids[10] = {
559 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 560 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
560 0x0f, 0x10, 0x11, 0x15, 0x1b, 561 0x0f, 0x10, 0x11, 0x15, 0x1b,
561}; 562};
562 563
563static hda_nid_t stac92hd73xx_pin_nids[13] = { 564static const hda_nid_t stac92hd73xx_pin_nids[13] = {
564 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 565 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
565 0x0f, 0x10, 0x11, 0x12, 0x13, 566 0x0f, 0x10, 0x11, 0x12, 0x13,
566 0x14, 0x22, 0x23 567 0x14, 0x22, 0x23
567}; 568};
568 569
569static hda_nid_t stac92hd83xxx_pin_nids[10] = {
570 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
571 0x0f, 0x10, 0x11, 0x1f, 0x20,
572};
573
574static hda_nid_t stac92hd88xxx_pin_nids[10] = {
575 0x0a, 0x0b, 0x0c, 0x0d,
576 0x0f, 0x11, 0x1f, 0x20,
577};
578
579#define STAC92HD71BXX_NUM_PINS 13 570#define STAC92HD71BXX_NUM_PINS 13
580static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { 571static const hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
581 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 572 0x0a, 0x0b, 0x0c, 0x0d, 0x00,
582 0x00, 0x14, 0x18, 0x19, 0x1e, 573 0x00, 0x14, 0x18, 0x19, 0x1e,
583 0x1f, 0x20, 0x27 574 0x1f, 0x20, 0x27
584}; 575};
585static hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = { 576static const hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = {
586 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 577 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
587 0x0f, 0x14, 0x18, 0x19, 0x1e, 578 0x0f, 0x14, 0x18, 0x19, 0x1e,
588 0x1f, 0x20, 0x27 579 0x1f, 0x20, 0x27
589}; 580};
590 581
591static hda_nid_t stac927x_pin_nids[14] = { 582static const hda_nid_t stac927x_pin_nids[14] = {
592 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 583 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
593 0x0f, 0x10, 0x11, 0x12, 0x13, 584 0x0f, 0x10, 0x11, 0x12, 0x13,
594 0x14, 0x21, 0x22, 0x23, 585 0x14, 0x21, 0x22, 0x23,
595}; 586};
596 587
597static hda_nid_t stac9205_pin_nids[12] = { 588static const hda_nid_t stac9205_pin_nids[12] = {
598 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 589 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
599 0x0f, 0x14, 0x16, 0x17, 0x18, 590 0x0f, 0x14, 0x16, 0x17, 0x18,
600 0x21, 0x22, 591 0x21, 0x22,
@@ -737,7 +728,7 @@ static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
737 struct sigmatel_spec *spec = codec->spec; 728 struct sigmatel_spec *spec = codec->spec;
738 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 729 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
739 const struct hda_input_mux *imux = spec->input_mux; 730 const struct hda_input_mux *imux = spec->input_mux;
740 unsigned int idx, prev_idx; 731 unsigned int idx, prev_idx, didx;
741 732
742 idx = ucontrol->value.enumerated.item[0]; 733 idx = ucontrol->value.enumerated.item[0];
743 if (idx >= imux->num_items) 734 if (idx >= imux->num_items)
@@ -749,7 +740,8 @@ static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
749 snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0, 740 snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0,
750 AC_VERB_SET_CONNECT_SEL, 741 AC_VERB_SET_CONNECT_SEL,
751 imux->items[idx].index); 742 imux->items[idx].index);
752 if (prev_idx >= spec->num_analog_muxes) { 743 if (prev_idx >= spec->num_analog_muxes &&
744 spec->mux_nids[adc_idx] != spec->dmux_nids[adc_idx]) {
753 imux = spec->dinput_mux; 745 imux = spec->dinput_mux;
754 /* 0 = analog */ 746 /* 0 = analog */
755 snd_hda_codec_write_cache(codec, 747 snd_hda_codec_write_cache(codec,
@@ -759,9 +751,13 @@ static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
759 } 751 }
760 } else { 752 } else {
761 imux = spec->dinput_mux; 753 imux = spec->dinput_mux;
754 /* first dimux item is hardcoded to select analog imux,
755 * so lets skip it
756 */
757 didx = idx - spec->num_analog_muxes + 1;
762 snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0, 758 snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0,
763 AC_VERB_SET_CONNECT_SEL, 759 AC_VERB_SET_CONNECT_SEL,
764 imux->items[idx - 1].index); 760 imux->items[didx].index);
765 } 761 }
766 spec->cur_mux[adc_idx] = idx; 762 spec->cur_mux[adc_idx] = idx;
767 return 1; 763 return 1;
@@ -849,45 +845,45 @@ static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
849 return 1; 845 return 1;
850} 846}
851 847
852static struct hda_verb stac9200_core_init[] = { 848static const struct hda_verb stac9200_core_init[] = {
853 /* set dac0mux for dac converter */ 849 /* set dac0mux for dac converter */
854 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 850 { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
855 {} 851 {}
856}; 852};
857 853
858static struct hda_verb stac9200_eapd_init[] = { 854static const struct hda_verb stac9200_eapd_init[] = {
859 /* set dac0mux for dac converter */ 855 /* set dac0mux for dac converter */
860 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 856 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
861 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 857 {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
862 {} 858 {}
863}; 859};
864 860
865static struct hda_verb dell_eq_core_init[] = { 861static const struct hda_verb dell_eq_core_init[] = {
866 /* set master volume to max value without distortion 862 /* set master volume to max value without distortion
867 * and direct control */ 863 * and direct control */
868 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, 864 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
869 {} 865 {}
870}; 866};
871 867
872static struct hda_verb stac92hd73xx_core_init[] = { 868static const struct hda_verb stac92hd73xx_core_init[] = {
873 /* set master volume and direct control */ 869 /* set master volume and direct control */
874 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 870 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
875 {} 871 {}
876}; 872};
877 873
878static struct hda_verb stac92hd83xxx_core_init[] = { 874static const struct hda_verb stac92hd83xxx_core_init[] = {
879 /* power state controls amps */ 875 /* power state controls amps */
880 { 0x01, AC_VERB_SET_EAPD, 1 << 2}, 876 { 0x01, AC_VERB_SET_EAPD, 1 << 2},
881 {} 877 {}
882}; 878};
883 879
884static struct hda_verb stac92hd71bxx_core_init[] = { 880static const struct hda_verb stac92hd71bxx_core_init[] = {
885 /* set master volume and direct control */ 881 /* set master volume and direct control */
886 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 882 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
887 {} 883 {}
888}; 884};
889 885
890static struct hda_verb stac92hd71bxx_unmute_core_init[] = { 886static const struct hda_verb stac92hd71bxx_unmute_core_init[] = {
891 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ 887 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
892 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 888 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
893 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 889 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -895,7 +891,7 @@ static struct hda_verb stac92hd71bxx_unmute_core_init[] = {
895 {} 891 {}
896}; 892};
897 893
898static struct hda_verb stac925x_core_init[] = { 894static const struct hda_verb stac925x_core_init[] = {
899 /* set dac0mux for dac converter */ 895 /* set dac0mux for dac converter */
900 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, 896 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
901 /* mute the master volume */ 897 /* mute the master volume */
@@ -903,13 +899,13 @@ static struct hda_verb stac925x_core_init[] = {
903 {} 899 {}
904}; 900};
905 901
906static struct hda_verb stac922x_core_init[] = { 902static const struct hda_verb stac922x_core_init[] = {
907 /* set master volume and direct control */ 903 /* set master volume and direct control */
908 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 904 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
909 {} 905 {}
910}; 906};
911 907
912static struct hda_verb d965_core_init[] = { 908static const struct hda_verb d965_core_init[] = {
913 /* set master volume and direct control */ 909 /* set master volume and direct control */
914 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 910 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
915 /* unmute node 0x1b */ 911 /* unmute node 0x1b */
@@ -919,7 +915,7 @@ static struct hda_verb d965_core_init[] = {
919 {} 915 {}
920}; 916};
921 917
922static struct hda_verb dell_3st_core_init[] = { 918static const struct hda_verb dell_3st_core_init[] = {
923 /* don't set delta bit */ 919 /* don't set delta bit */
924 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f}, 920 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
925 /* unmute node 0x1b */ 921 /* unmute node 0x1b */
@@ -929,7 +925,7 @@ static struct hda_verb dell_3st_core_init[] = {
929 {} 925 {}
930}; 926};
931 927
932static struct hda_verb stac927x_core_init[] = { 928static const struct hda_verb stac927x_core_init[] = {
933 /* set master volume and direct control */ 929 /* set master volume and direct control */
934 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 930 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
935 /* enable analog pc beep path */ 931 /* enable analog pc beep path */
@@ -937,7 +933,7 @@ static struct hda_verb stac927x_core_init[] = {
937 {} 933 {}
938}; 934};
939 935
940static struct hda_verb stac927x_volknob_core_init[] = { 936static const struct hda_verb stac927x_volknob_core_init[] = {
941 /* don't set delta bit */ 937 /* don't set delta bit */
942 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f}, 938 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
943 /* enable analog pc beep path */ 939 /* enable analog pc beep path */
@@ -945,7 +941,7 @@ static struct hda_verb stac927x_volknob_core_init[] = {
945 {} 941 {}
946}; 942};
947 943
948static struct hda_verb stac9205_core_init[] = { 944static const struct hda_verb stac9205_core_init[] = {
949 /* set master volume and direct control */ 945 /* set master volume and direct control */
950 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 946 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
951 /* enable analog pc beep path */ 947 /* enable analog pc beep path */
@@ -985,46 +981,46 @@ static struct hda_verb stac9205_core_init[] = {
985 .private_value = nid, \ 981 .private_value = nid, \
986 } 982 }
987 983
988static struct snd_kcontrol_new stac9200_mixer[] = { 984static const struct snd_kcontrol_new stac9200_mixer[] = {
989 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), 985 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
990 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), 986 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
991 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), 987 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
992 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), 988 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
993 { } /* end */ 989 { } /* end */
994}; 990};
995 991
996static struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = { 992static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = {
997 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), 993 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
998 {} 994 {}
999}; 995};
1000 996
1001static struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = { 997static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = {
1002 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4), 998 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4),
1003 {} 999 {}
1004}; 1000};
1005 1001
1006static struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = { 1002static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = {
1007 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5), 1003 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5),
1008 {} 1004 {}
1009}; 1005};
1010 1006
1011 1007
1012static struct snd_kcontrol_new stac92hd71bxx_loopback[] = { 1008static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = {
1013 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) 1009 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2)
1014}; 1010};
1015 1011
1016static struct snd_kcontrol_new stac925x_mixer[] = { 1012static const struct snd_kcontrol_new stac925x_mixer[] = {
1017 HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), 1013 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xe, 0, HDA_OUTPUT),
1018 HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), 1014 HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT),
1019 { } /* end */ 1015 { } /* end */
1020}; 1016};
1021 1017
1022static struct snd_kcontrol_new stac9205_loopback[] = { 1018static const struct snd_kcontrol_new stac9205_loopback[] = {
1023 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), 1019 STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1),
1024 {} 1020 {}
1025}; 1021};
1026 1022
1027static struct snd_kcontrol_new stac927x_loopback[] = { 1023static const struct snd_kcontrol_new stac927x_loopback[] = {
1028 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), 1024 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1),
1029 {} 1025 {}
1030}; 1026};
@@ -1047,7 +1043,7 @@ static struct snd_kcontrol_new stac_smux_mixer = {
1047 .put = stac92xx_smux_enum_put, 1043 .put = stac92xx_smux_enum_put,
1048}; 1044};
1049 1045
1050static const char *slave_vols[] = { 1046static const char * const slave_vols[] = {
1051 "Front Playback Volume", 1047 "Front Playback Volume",
1052 "Surround Playback Volume", 1048 "Surround Playback Volume",
1053 "Center Playback Volume", 1049 "Center Playback Volume",
@@ -1058,7 +1054,7 @@ static const char *slave_vols[] = {
1058 NULL 1054 NULL
1059}; 1055};
1060 1056
1061static const char *slave_sws[] = { 1057static const char * const slave_sws[] = {
1062 "Front Playback Switch", 1058 "Front Playback Switch",
1063 "Surround Playback Switch", 1059 "Surround Playback Switch",
1064 "Center Playback Switch", 1060 "Center Playback Switch",
@@ -1105,9 +1101,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1105 struct hda_input_mux *smux = &spec->private_smux; 1101 struct hda_input_mux *smux = &spec->private_smux;
1106 /* check for mute support on SPDIF out */ 1102 /* check for mute support on SPDIF out */
1107 if (wcaps & AC_WCAP_OUT_AMP) { 1103 if (wcaps & AC_WCAP_OUT_AMP) {
1108 smux->items[smux->num_items].label = "Off"; 1104 snd_hda_add_imux_item(smux, "Off", 0, NULL);
1109 smux->items[smux->num_items].index = 0;
1110 smux->num_items++;
1111 spec->spdif_mute = 1; 1105 spec->spdif_mute = 1;
1112 } 1106 }
1113 stac_smux_mixer.count = spec->num_smuxes; 1107 stac_smux_mixer.count = spec->num_smuxes;
@@ -1140,6 +1134,8 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1140 HDA_OUTPUT, vmaster_tlv); 1134 HDA_OUTPUT, vmaster_tlv);
1141 /* correct volume offset */ 1135 /* correct volume offset */
1142 vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset; 1136 vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset;
1137 /* minimum value is actually mute */
1138 vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
1143 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 1139 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1144 vmaster_tlv, slave_vols); 1140 vmaster_tlv, slave_vols);
1145 if (err < 0) 1141 if (err < 0)
@@ -1180,29 +1176,26 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1180 if (err < 0) 1176 if (err < 0)
1181 return err; 1177 return err;
1182 } 1178 }
1183 for (i = 0; i < AUTO_PIN_LAST; i++) { 1179 for (i = 0; i < cfg->num_inputs; i++) {
1184 nid = cfg->input_pins[i]; 1180 nid = cfg->inputs[i].pin;
1185 if (nid) { 1181 err = stac92xx_add_jack(codec, nid, SND_JACK_MICROPHONE);
1186 err = stac92xx_add_jack(codec, nid, 1182 if (err < 0)
1187 SND_JACK_MICROPHONE); 1183 return err;
1188 if (err < 0)
1189 return err;
1190 }
1191 } 1184 }
1192 1185
1193 return 0; 1186 return 0;
1194} 1187}
1195 1188
1196static unsigned int ref9200_pin_configs[8] = { 1189static const unsigned int ref9200_pin_configs[8] = {
1197 0x01c47010, 0x01447010, 0x0221401f, 0x01114010, 1190 0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
1198 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, 1191 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
1199}; 1192};
1200 1193
1201static unsigned int gateway9200_m4_pin_configs[8] = { 1194static const unsigned int gateway9200_m4_pin_configs[8] = {
1202 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, 1195 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010,
1203 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, 1196 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3,
1204}; 1197};
1205static unsigned int gateway9200_m4_2_pin_configs[8] = { 1198static const unsigned int gateway9200_m4_2_pin_configs[8] = {
1206 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, 1199 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010,
1207 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, 1200 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3,
1208}; 1201};
@@ -1213,7 +1206,7 @@ static unsigned int gateway9200_m4_2_pin_configs[8] = {
1213 102801DE 1206 102801DE
1214 102801E8 1207 102801E8
1215*/ 1208*/
1216static unsigned int dell9200_d21_pin_configs[8] = { 1209static const unsigned int dell9200_d21_pin_configs[8] = {
1217 0x400001f0, 0x400001f1, 0x02214030, 0x01014010, 1210 0x400001f0, 0x400001f1, 0x02214030, 0x01014010,
1218 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, 1211 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
1219}; 1212};
@@ -1223,7 +1216,7 @@ static unsigned int dell9200_d21_pin_configs[8] = {
1223 102801C0 1216 102801C0
1224 102801C1 1217 102801C1
1225*/ 1218*/
1226static unsigned int dell9200_d22_pin_configs[8] = { 1219static const unsigned int dell9200_d22_pin_configs[8] = {
1227 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, 1220 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
1228 0x01813020, 0x02a19021, 0x90100140, 0x400001f2, 1221 0x01813020, 0x02a19021, 0x90100140, 0x400001f2,
1229}; 1222};
@@ -1237,7 +1230,7 @@ static unsigned int dell9200_d22_pin_configs[8] = {
1237 102801DA 1230 102801DA
1238 102801E3 1231 102801E3
1239*/ 1232*/
1240static unsigned int dell9200_d23_pin_configs[8] = { 1233static const unsigned int dell9200_d23_pin_configs[8] = {
1241 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, 1234 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
1242 0x01813020, 0x01a19021, 0x90100140, 0x400001f2, 1235 0x01813020, 0x01a19021, 0x90100140, 0x400001f2,
1243}; 1236};
@@ -1248,7 +1241,7 @@ static unsigned int dell9200_d23_pin_configs[8] = {
1248 102801B5 (Dell Inspiron 630m) 1241 102801B5 (Dell Inspiron 630m)
1249 102801D8 (Dell Inspiron 640m) 1242 102801D8 (Dell Inspiron 640m)
1250*/ 1243*/
1251static unsigned int dell9200_m21_pin_configs[8] = { 1244static const unsigned int dell9200_m21_pin_configs[8] = {
1252 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310, 1245 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310,
1253 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd, 1246 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd,
1254}; 1247};
@@ -1261,7 +1254,7 @@ static unsigned int dell9200_m21_pin_configs[8] = {
1261 102801D4 1254 102801D4
1262 102801D6 1255 102801D6
1263*/ 1256*/
1264static unsigned int dell9200_m22_pin_configs[8] = { 1257static const unsigned int dell9200_m22_pin_configs[8] = {
1265 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310, 1258 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310,
1266 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc, 1259 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc,
1267}; 1260};
@@ -1271,7 +1264,7 @@ static unsigned int dell9200_m22_pin_configs[8] = {
1271 102801CE (Dell XPS M1710) 1264 102801CE (Dell XPS M1710)
1272 102801CF (Dell Precision M90) 1265 102801CF (Dell Precision M90)
1273*/ 1266*/
1274static unsigned int dell9200_m23_pin_configs[8] = { 1267static const unsigned int dell9200_m23_pin_configs[8] = {
1275 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310, 1268 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
1276 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc, 1269 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
1277}; 1270};
@@ -1283,7 +1276,7 @@ static unsigned int dell9200_m23_pin_configs[8] = {
1283 102801CB (Dell Latitude 120L) 1276 102801CB (Dell Latitude 120L)
1284 102801D3 1277 102801D3
1285*/ 1278*/
1286static unsigned int dell9200_m24_pin_configs[8] = { 1279static const unsigned int dell9200_m24_pin_configs[8] = {
1287 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310, 1280 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310,
1288 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe, 1281 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe,
1289}; 1282};
@@ -1294,7 +1287,7 @@ static unsigned int dell9200_m24_pin_configs[8] = {
1294 102801EE 1287 102801EE
1295 102801EF 1288 102801EF
1296*/ 1289*/
1297static unsigned int dell9200_m25_pin_configs[8] = { 1290static const unsigned int dell9200_m25_pin_configs[8] = {
1298 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, 1291 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
1299 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd, 1292 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd,
1300}; 1293};
@@ -1304,7 +1297,7 @@ static unsigned int dell9200_m25_pin_configs[8] = {
1304 102801F5 (Dell Inspiron 1501) 1297 102801F5 (Dell Inspiron 1501)
1305 102801F6 1298 102801F6
1306*/ 1299*/
1307static unsigned int dell9200_m26_pin_configs[8] = { 1300static const unsigned int dell9200_m26_pin_configs[8] = {
1308 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310, 1301 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310,
1309 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe, 1302 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe,
1310}; 1303};
@@ -1313,18 +1306,18 @@ static unsigned int dell9200_m26_pin_configs[8] = {
1313 STAC 9200-32 1306 STAC 9200-32
1314 102801CD (Dell Inspiron E1705/9400) 1307 102801CD (Dell Inspiron E1705/9400)
1315*/ 1308*/
1316static unsigned int dell9200_m27_pin_configs[8] = { 1309static const unsigned int dell9200_m27_pin_configs[8] = {
1317 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, 1310 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
1318 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc, 1311 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc,
1319}; 1312};
1320 1313
1321static unsigned int oqo9200_pin_configs[8] = { 1314static const unsigned int oqo9200_pin_configs[8] = {
1322 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210, 1315 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210,
1323 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3, 1316 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3,
1324}; 1317};
1325 1318
1326 1319
1327static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { 1320static const unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
1328 [STAC_REF] = ref9200_pin_configs, 1321 [STAC_REF] = ref9200_pin_configs,
1329 [STAC_9200_OQO] = oqo9200_pin_configs, 1322 [STAC_9200_OQO] = oqo9200_pin_configs,
1330 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs, 1323 [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
@@ -1342,7 +1335,7 @@ static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
1342 [STAC_9200_PANASONIC] = ref9200_pin_configs, 1335 [STAC_9200_PANASONIC] = ref9200_pin_configs,
1343}; 1336};
1344 1337
1345static const char *stac9200_models[STAC_9200_MODELS] = { 1338static const char * const stac9200_models[STAC_9200_MODELS] = {
1346 [STAC_AUTO] = "auto", 1339 [STAC_AUTO] = "auto",
1347 [STAC_REF] = "ref", 1340 [STAC_REF] = "ref",
1348 [STAC_9200_OQO] = "oqo", 1341 [STAC_9200_OQO] = "oqo",
@@ -1361,7 +1354,7 @@ static const char *stac9200_models[STAC_9200_MODELS] = {
1361 [STAC_9200_PANASONIC] = "panasonic", 1354 [STAC_9200_PANASONIC] = "panasonic",
1362}; 1355};
1363 1356
1364static struct snd_pci_quirk stac9200_cfg_tbl[] = { 1357static const struct snd_pci_quirk stac9200_cfg_tbl[] = {
1365 /* SigmaTel reference board */ 1358 /* SigmaTel reference board */
1366 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1359 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1367 "DFI LanParty", STAC_REF), 1360 "DFI LanParty", STAC_REF),
@@ -1437,47 +1430,47 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = {
1437 {} /* terminator */ 1430 {} /* terminator */
1438}; 1431};
1439 1432
1440static unsigned int ref925x_pin_configs[8] = { 1433static const unsigned int ref925x_pin_configs[8] = {
1441 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, 1434 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1442 0x90a70320, 0x02214210, 0x01019020, 0x9033032e, 1435 0x90a70320, 0x02214210, 0x01019020, 0x9033032e,
1443}; 1436};
1444 1437
1445static unsigned int stac925xM1_pin_configs[8] = { 1438static const unsigned int stac925xM1_pin_configs[8] = {
1446 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 1439 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1447 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, 1440 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1448}; 1441};
1449 1442
1450static unsigned int stac925xM1_2_pin_configs[8] = { 1443static const unsigned int stac925xM1_2_pin_configs[8] = {
1451 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 1444 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1452 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, 1445 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1453}; 1446};
1454 1447
1455static unsigned int stac925xM2_pin_configs[8] = { 1448static const unsigned int stac925xM2_pin_configs[8] = {
1456 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 1449 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1457 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, 1450 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1458}; 1451};
1459 1452
1460static unsigned int stac925xM2_2_pin_configs[8] = { 1453static const unsigned int stac925xM2_2_pin_configs[8] = {
1461 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 1454 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1462 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, 1455 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1463}; 1456};
1464 1457
1465static unsigned int stac925xM3_pin_configs[8] = { 1458static const unsigned int stac925xM3_pin_configs[8] = {
1466 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 1459 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1467 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3, 1460 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3,
1468}; 1461};
1469 1462
1470static unsigned int stac925xM5_pin_configs[8] = { 1463static const unsigned int stac925xM5_pin_configs[8] = {
1471 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 1464 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1472 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, 1465 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e,
1473}; 1466};
1474 1467
1475static unsigned int stac925xM6_pin_configs[8] = { 1468static const unsigned int stac925xM6_pin_configs[8] = {
1476 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 1469 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020,
1477 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320, 1470 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320,
1478}; 1471};
1479 1472
1480static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { 1473static const unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
1481 [STAC_REF] = ref925x_pin_configs, 1474 [STAC_REF] = ref925x_pin_configs,
1482 [STAC_M1] = stac925xM1_pin_configs, 1475 [STAC_M1] = stac925xM1_pin_configs,
1483 [STAC_M1_2] = stac925xM1_2_pin_configs, 1476 [STAC_M1_2] = stac925xM1_2_pin_configs,
@@ -1488,7 +1481,7 @@ static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
1488 [STAC_M6] = stac925xM6_pin_configs, 1481 [STAC_M6] = stac925xM6_pin_configs,
1489}; 1482};
1490 1483
1491static const char *stac925x_models[STAC_925x_MODELS] = { 1484static const char * const stac925x_models[STAC_925x_MODELS] = {
1492 [STAC_925x_AUTO] = "auto", 1485 [STAC_925x_AUTO] = "auto",
1493 [STAC_REF] = "ref", 1486 [STAC_REF] = "ref",
1494 [STAC_M1] = "m1", 1487 [STAC_M1] = "m1",
@@ -1500,7 +1493,7 @@ static const char *stac925x_models[STAC_925x_MODELS] = {
1500 [STAC_M6] = "m6", 1493 [STAC_M6] = "m6",
1501}; 1494};
1502 1495
1503static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { 1496static const struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = {
1504 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2), 1497 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2),
1505 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5), 1498 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5),
1506 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1), 1499 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1),
@@ -1514,7 +1507,7 @@ static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = {
1514 {} /* terminator */ 1507 {} /* terminator */
1515}; 1508};
1516 1509
1517static struct snd_pci_quirk stac925x_cfg_tbl[] = { 1510static const struct snd_pci_quirk stac925x_cfg_tbl[] = {
1518 /* SigmaTel reference board */ 1511 /* SigmaTel reference board */
1519 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), 1512 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
1520 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF), 1513 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF),
@@ -1526,33 +1519,33 @@ static struct snd_pci_quirk stac925x_cfg_tbl[] = {
1526 {} /* terminator */ 1519 {} /* terminator */
1527}; 1520};
1528 1521
1529static unsigned int ref92hd73xx_pin_configs[13] = { 1522static const unsigned int ref92hd73xx_pin_configs[13] = {
1530 0x02214030, 0x02a19040, 0x01a19020, 0x02214030, 1523 0x02214030, 0x02a19040, 0x01a19020, 0x02214030,
1531 0x0181302e, 0x01014010, 0x01014020, 0x01014030, 1524 0x0181302e, 0x01014010, 0x01014020, 0x01014030,
1532 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050, 1525 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050,
1533 0x01452050, 1526 0x01452050,
1534}; 1527};
1535 1528
1536static unsigned int dell_m6_pin_configs[13] = { 1529static const unsigned int dell_m6_pin_configs[13] = {
1537 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110, 1530 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110,
1538 0x03a11020, 0x0321101f, 0x4f0000f0, 0x4f0000f0, 1531 0x03a11020, 0x0321101f, 0x4f0000f0, 0x4f0000f0,
1539 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, 1532 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0,
1540 0x4f0000f0, 1533 0x4f0000f0,
1541}; 1534};
1542 1535
1543static unsigned int alienware_m17x_pin_configs[13] = { 1536static const unsigned int alienware_m17x_pin_configs[13] = {
1544 0x0321101f, 0x0321101f, 0x03a11020, 0x03014020, 1537 0x0321101f, 0x0321101f, 0x03a11020, 0x03014020,
1545 0x90170110, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0, 1538 0x90170110, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0,
1546 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, 1539 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0,
1547 0x904601b0, 1540 0x904601b0,
1548}; 1541};
1549 1542
1550static unsigned int intel_dg45id_pin_configs[13] = { 1543static const unsigned int intel_dg45id_pin_configs[13] = {
1551 0x02214230, 0x02A19240, 0x01013214, 0x01014210, 1544 0x02214230, 0x02A19240, 0x01013214, 0x01014210,
1552 0x01A19250, 0x01011212, 0x01016211 1545 0x01A19250, 0x01011212, 0x01016211
1553}; 1546};
1554 1547
1555static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { 1548static const unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1556 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, 1549 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
1557 [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, 1550 [STAC_DELL_M6_AMIC] = dell_m6_pin_configs,
1558 [STAC_DELL_M6_DMIC] = dell_m6_pin_configs, 1551 [STAC_DELL_M6_DMIC] = dell_m6_pin_configs,
@@ -1562,7 +1555,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1562 [STAC_92HD73XX_INTEL] = intel_dg45id_pin_configs, 1555 [STAC_92HD73XX_INTEL] = intel_dg45id_pin_configs,
1563}; 1556};
1564 1557
1565static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { 1558static const char * const stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
1566 [STAC_92HD73XX_AUTO] = "auto", 1559 [STAC_92HD73XX_AUTO] = "auto",
1567 [STAC_92HD73XX_NO_JD] = "no-jd", 1560 [STAC_92HD73XX_NO_JD] = "no-jd",
1568 [STAC_92HD73XX_REF] = "ref", 1561 [STAC_92HD73XX_REF] = "ref",
@@ -1574,7 +1567,7 @@ static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
1574 [STAC_ALIENWARE_M17X] = "alienware", 1567 [STAC_ALIENWARE_M17X] = "alienware",
1575}; 1568};
1576 1569
1577static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { 1570static const struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1578 /* SigmaTel reference board */ 1571 /* SigmaTel reference board */
1579 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1572 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1580 "DFI LanParty", STAC_92HD73XX_REF), 1573 "DFI LanParty", STAC_92HD73XX_REF),
@@ -1611,42 +1604,44 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1611 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe, 1604 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
1612 "Dell Studio XPS 1645", STAC_DELL_M6_BOTH), 1605 "Dell Studio XPS 1645", STAC_DELL_M6_BOTH),
1613 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413, 1606 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
1614 "Dell Studio 1558", STAC_DELL_M6_BOTH), 1607 "Dell Studio 1558", STAC_DELL_M6_DMIC),
1615 {} /* terminator */ 1608 {} /* terminator */
1616}; 1609};
1617 1610
1618static struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { 1611static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {
1619 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1, 1612 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
1620 "Alienware M17x", STAC_ALIENWARE_M17X), 1613 "Alienware M17x", STAC_ALIENWARE_M17X),
1614 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
1615 "Alienware M17x", STAC_ALIENWARE_M17X),
1621 {} /* terminator */ 1616 {} /* terminator */
1622}; 1617};
1623 1618
1624static unsigned int ref92hd83xxx_pin_configs[10] = { 1619static const unsigned int ref92hd83xxx_pin_configs[10] = {
1625 0x02214030, 0x02211010, 0x02a19020, 0x02170130, 1620 0x02214030, 0x02211010, 0x02a19020, 0x02170130,
1626 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, 1621 0x01014050, 0x01819040, 0x01014020, 0x90a3014e,
1627 0x01451160, 0x98560170, 1622 0x01451160, 0x98560170,
1628}; 1623};
1629 1624
1630static unsigned int dell_s14_pin_configs[10] = { 1625static const unsigned int dell_s14_pin_configs[10] = {
1631 0x0221403f, 0x0221101f, 0x02a19020, 0x90170110, 1626 0x0221403f, 0x0221101f, 0x02a19020, 0x90170110,
1632 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160, 1627 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160,
1633 0x40f000f0, 0x40f000f0, 1628 0x40f000f0, 0x40f000f0,
1634}; 1629};
1635 1630
1636static unsigned int hp_dv7_4000_pin_configs[10] = { 1631static const unsigned int hp_dv7_4000_pin_configs[10] = {
1637 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, 1632 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110,
1638 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, 1633 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140,
1639 0x40f000f0, 0x40f000f0, 1634 0x40f000f0, 0x40f000f0,
1640}; 1635};
1641 1636
1642static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { 1637static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
1643 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, 1638 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
1644 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, 1639 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
1645 [STAC_DELL_S14] = dell_s14_pin_configs, 1640 [STAC_DELL_S14] = dell_s14_pin_configs,
1646 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, 1641 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
1647}; 1642};
1648 1643
1649static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { 1644static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1650 [STAC_92HD83XXX_AUTO] = "auto", 1645 [STAC_92HD83XXX_AUTO] = "auto",
1651 [STAC_92HD83XXX_REF] = "ref", 1646 [STAC_92HD83XXX_REF] = "ref",
1652 [STAC_92HD83XXX_PWR_REF] = "mic-ref", 1647 [STAC_92HD83XXX_PWR_REF] = "mic-ref",
@@ -1655,7 +1650,7 @@ static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1655 [STAC_HP_DV7_4000] = "hp-dv7-4000", 1650 [STAC_HP_DV7_4000] = "hp-dv7-4000",
1656}; 1651};
1657 1652
1658static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { 1653static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1659 /* SigmaTel reference board */ 1654 /* SigmaTel reference board */
1660 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1655 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1661 "DFI LanParty", STAC_92HD83XXX_REF), 1656 "DFI LanParty", STAC_92HD83XXX_REF),
@@ -1668,35 +1663,35 @@ static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1668 {} /* terminator */ 1663 {} /* terminator */
1669}; 1664};
1670 1665
1671static unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = { 1666static const unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = {
1672 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, 1667 0x02214030, 0x02a19040, 0x01a19020, 0x01014010,
1673 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, 1668 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0,
1674 0x90a000f0, 0x01452050, 0x01452050, 0x00000000, 1669 0x90a000f0, 0x01452050, 0x01452050, 0x00000000,
1675 0x00000000 1670 0x00000000
1676}; 1671};
1677 1672
1678static unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = { 1673static const unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = {
1679 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, 1674 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110,
1680 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, 1675 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0,
1681 0x40f000f0, 0x4f0000f0, 0x4f0000f0, 0x00000000, 1676 0x40f000f0, 0x4f0000f0, 0x4f0000f0, 0x00000000,
1682 0x00000000 1677 0x00000000
1683}; 1678};
1684 1679
1685static unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = { 1680static const unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = {
1686 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, 1681 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
1687 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, 1682 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0,
1688 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, 1683 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000,
1689 0x00000000 1684 0x00000000
1690}; 1685};
1691 1686
1692static unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = { 1687static const unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = {
1693 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, 1688 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
1694 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0, 1689 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0,
1695 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, 1690 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000,
1696 0x00000000 1691 0x00000000
1697}; 1692};
1698 1693
1699static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { 1694static const unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
1700 [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, 1695 [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs,
1701 [STAC_DELL_M4_1] = dell_m4_1_pin_configs, 1696 [STAC_DELL_M4_1] = dell_m4_1_pin_configs,
1702 [STAC_DELL_M4_2] = dell_m4_2_pin_configs, 1697 [STAC_DELL_M4_2] = dell_m4_2_pin_configs,
@@ -1708,7 +1703,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
1708 [STAC_HP_DV4_1222NR] = NULL, 1703 [STAC_HP_DV4_1222NR] = NULL,
1709}; 1704};
1710 1705
1711static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { 1706static const char * const stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
1712 [STAC_92HD71BXX_AUTO] = "auto", 1707 [STAC_92HD71BXX_AUTO] = "auto",
1713 [STAC_92HD71BXX_REF] = "ref", 1708 [STAC_92HD71BXX_REF] = "ref",
1714 [STAC_DELL_M4_1] = "dell-m4-1", 1709 [STAC_DELL_M4_1] = "dell-m4-1",
@@ -1721,7 +1716,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
1721 [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr", 1716 [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr",
1722}; 1717};
1723 1718
1724static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { 1719static const struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1725 /* SigmaTel reference board */ 1720 /* SigmaTel reference board */
1726 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1721 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1727 "DFI LanParty", STAC_92HD71BXX_REF), 1722 "DFI LanParty", STAC_92HD71BXX_REF),
@@ -1778,7 +1773,7 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1778 {} /* terminator */ 1773 {} /* terminator */
1779}; 1774};
1780 1775
1781static unsigned int ref922x_pin_configs[10] = { 1776static const unsigned int ref922x_pin_configs[10] = {
1782 0x01014010, 0x01016011, 0x01012012, 0x0221401f, 1777 0x01014010, 0x01016011, 0x01012012, 0x0221401f,
1783 0x01813122, 0x01011014, 0x01441030, 0x01c41030, 1778 0x01813122, 0x01011014, 0x01441030, 0x01c41030,
1784 0x40000100, 0x40000100, 1779 0x40000100, 0x40000100,
@@ -1792,7 +1787,7 @@ static unsigned int ref922x_pin_configs[10] = {
1792 102801D1 1787 102801D1
1793 102801D2 1788 102801D2
1794*/ 1789*/
1795static unsigned int dell_922x_d81_pin_configs[10] = { 1790static const unsigned int dell_922x_d81_pin_configs[10] = {
1796 0x02214030, 0x01a19021, 0x01111012, 0x01114010, 1791 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
1797 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1, 1792 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
1798 0x01813122, 0x400001f2, 1793 0x01813122, 0x400001f2,
@@ -1803,7 +1798,7 @@ static unsigned int dell_922x_d81_pin_configs[10] = {
1803 102801AC 1798 102801AC
1804 102801D0 1799 102801D0
1805*/ 1800*/
1806static unsigned int dell_922x_d82_pin_configs[10] = { 1801static const unsigned int dell_922x_d82_pin_configs[10] = {
1807 0x02214030, 0x01a19021, 0x01111012, 0x01114010, 1802 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
1808 0x02a19020, 0x01117011, 0x01451140, 0x400001f0, 1803 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
1809 0x01813122, 0x400001f1, 1804 0x01813122, 0x400001f1,
@@ -1813,7 +1808,7 @@ static unsigned int dell_922x_d82_pin_configs[10] = {
1813 STAC 922X pin configs for 1808 STAC 922X pin configs for
1814 102801BF 1809 102801BF
1815*/ 1810*/
1816static unsigned int dell_922x_m81_pin_configs[10] = { 1811static const unsigned int dell_922x_m81_pin_configs[10] = {
1817 0x0321101f, 0x01112024, 0x01111222, 0x91174220, 1812 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
1818 0x03a11050, 0x01116221, 0x90a70330, 0x01452340, 1813 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
1819 0x40C003f1, 0x405003f0, 1814 0x40C003f1, 0x405003f0,
@@ -1823,61 +1818,61 @@ static unsigned int dell_922x_m81_pin_configs[10] = {
1823 STAC 9221 A1 pin configs for 1818 STAC 9221 A1 pin configs for
1824 102801D7 (Dell XPS M1210) 1819 102801D7 (Dell XPS M1210)
1825*/ 1820*/
1826static unsigned int dell_922x_m82_pin_configs[10] = { 1821static const unsigned int dell_922x_m82_pin_configs[10] = {
1827 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310, 1822 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310,
1828 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 1823 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2,
1829 0x508003f3, 0x405003f4, 1824 0x508003f3, 0x405003f4,
1830}; 1825};
1831 1826
1832static unsigned int d945gtp3_pin_configs[10] = { 1827static const unsigned int d945gtp3_pin_configs[10] = {
1833 0x0221401f, 0x01a19022, 0x01813021, 0x01014010, 1828 0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
1834 0x40000100, 0x40000100, 0x40000100, 0x40000100, 1829 0x40000100, 0x40000100, 0x40000100, 0x40000100,
1835 0x02a19120, 0x40000100, 1830 0x02a19120, 0x40000100,
1836}; 1831};
1837 1832
1838static unsigned int d945gtp5_pin_configs[10] = { 1833static const unsigned int d945gtp5_pin_configs[10] = {
1839 0x0221401f, 0x01011012, 0x01813024, 0x01014010, 1834 0x0221401f, 0x01011012, 0x01813024, 0x01014010,
1840 0x01a19021, 0x01016011, 0x01452130, 0x40000100, 1835 0x01a19021, 0x01016011, 0x01452130, 0x40000100,
1841 0x02a19320, 0x40000100, 1836 0x02a19320, 0x40000100,
1842}; 1837};
1843 1838
1844static unsigned int intel_mac_v1_pin_configs[10] = { 1839static const unsigned int intel_mac_v1_pin_configs[10] = {
1845 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd, 1840 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
1846 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240, 1841 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
1847 0x400000fc, 0x400000fb, 1842 0x400000fc, 0x400000fb,
1848}; 1843};
1849 1844
1850static unsigned int intel_mac_v2_pin_configs[10] = { 1845static const unsigned int intel_mac_v2_pin_configs[10] = {
1851 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, 1846 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
1852 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa, 1847 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
1853 0x400000fc, 0x400000fb, 1848 0x400000fc, 0x400000fb,
1854}; 1849};
1855 1850
1856static unsigned int intel_mac_v3_pin_configs[10] = { 1851static const unsigned int intel_mac_v3_pin_configs[10] = {
1857 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, 1852 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
1858 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240, 1853 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
1859 0x400000fc, 0x400000fb, 1854 0x400000fc, 0x400000fb,
1860}; 1855};
1861 1856
1862static unsigned int intel_mac_v4_pin_configs[10] = { 1857static const unsigned int intel_mac_v4_pin_configs[10] = {
1863 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, 1858 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
1864 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, 1859 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
1865 0x400000fc, 0x400000fb, 1860 0x400000fc, 0x400000fb,
1866}; 1861};
1867 1862
1868static unsigned int intel_mac_v5_pin_configs[10] = { 1863static const unsigned int intel_mac_v5_pin_configs[10] = {
1869 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, 1864 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
1870 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, 1865 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
1871 0x400000fc, 0x400000fb, 1866 0x400000fc, 0x400000fb,
1872}; 1867};
1873 1868
1874static unsigned int ecs202_pin_configs[10] = { 1869static const unsigned int ecs202_pin_configs[10] = {
1875 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010, 1870 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010,
1876 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1, 1871 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1,
1877 0x9037012e, 0x40e000f2, 1872 0x9037012e, 0x40e000f2,
1878}; 1873};
1879 1874
1880static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { 1875static const unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
1881 [STAC_D945_REF] = ref922x_pin_configs, 1876 [STAC_D945_REF] = ref922x_pin_configs,
1882 [STAC_D945GTP3] = d945gtp3_pin_configs, 1877 [STAC_D945GTP3] = d945gtp3_pin_configs,
1883 [STAC_D945GTP5] = d945gtp5_pin_configs, 1878 [STAC_D945GTP5] = d945gtp5_pin_configs,
@@ -1901,7 +1896,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
1901 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs, 1896 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
1902}; 1897};
1903 1898
1904static const char *stac922x_models[STAC_922X_MODELS] = { 1899static const char * const stac922x_models[STAC_922X_MODELS] = {
1905 [STAC_922X_AUTO] = "auto", 1900 [STAC_922X_AUTO] = "auto",
1906 [STAC_D945_REF] = "ref", 1901 [STAC_D945_REF] = "ref",
1907 [STAC_D945GTP5] = "5stack", 1902 [STAC_D945GTP5] = "5stack",
@@ -1926,7 +1921,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = {
1926 [STAC_922X_DELL_M82] = "dell-m82", 1921 [STAC_922X_DELL_M82] = "dell-m82",
1927}; 1922};
1928 1923
1929static struct snd_pci_quirk stac922x_cfg_tbl[] = { 1924static const struct snd_pci_quirk stac922x_cfg_tbl[] = {
1930 /* SigmaTel reference board */ 1925 /* SigmaTel reference board */
1931 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1926 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1932 "DFI LanParty", STAC_D945_REF), 1927 "DFI LanParty", STAC_D945_REF),
@@ -2017,42 +2012,42 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = {
2017 {} /* terminator */ 2012 {} /* terminator */
2018}; 2013};
2019 2014
2020static unsigned int ref927x_pin_configs[14] = { 2015static const unsigned int ref927x_pin_configs[14] = {
2021 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, 2016 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
2022 0x01a19040, 0x01011012, 0x01016011, 0x0101201f, 2017 0x01a19040, 0x01011012, 0x01016011, 0x0101201f,
2023 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070, 2018 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070,
2024 0x01c42190, 0x40000100, 2019 0x01c42190, 0x40000100,
2025}; 2020};
2026 2021
2027static unsigned int d965_3st_pin_configs[14] = { 2022static const unsigned int d965_3st_pin_configs[14] = {
2028 0x0221401f, 0x02a19120, 0x40000100, 0x01014011, 2023 0x0221401f, 0x02a19120, 0x40000100, 0x01014011,
2029 0x01a19021, 0x01813024, 0x40000100, 0x40000100, 2024 0x01a19021, 0x01813024, 0x40000100, 0x40000100,
2030 0x40000100, 0x40000100, 0x40000100, 0x40000100, 2025 0x40000100, 0x40000100, 0x40000100, 0x40000100,
2031 0x40000100, 0x40000100 2026 0x40000100, 0x40000100
2032}; 2027};
2033 2028
2034static unsigned int d965_5st_pin_configs[14] = { 2029static const unsigned int d965_5st_pin_configs[14] = {
2035 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, 2030 0x02214020, 0x02a19080, 0x0181304e, 0x01014010,
2036 0x01a19040, 0x01011012, 0x01016011, 0x40000100, 2031 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
2037 0x40000100, 0x40000100, 0x40000100, 0x01442070, 2032 0x40000100, 0x40000100, 0x40000100, 0x01442070,
2038 0x40000100, 0x40000100 2033 0x40000100, 0x40000100
2039}; 2034};
2040 2035
2041static unsigned int d965_5st_no_fp_pin_configs[14] = { 2036static const unsigned int d965_5st_no_fp_pin_configs[14] = {
2042 0x40000100, 0x40000100, 0x0181304e, 0x01014010, 2037 0x40000100, 0x40000100, 0x0181304e, 0x01014010,
2043 0x01a19040, 0x01011012, 0x01016011, 0x40000100, 2038 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
2044 0x40000100, 0x40000100, 0x40000100, 0x01442070, 2039 0x40000100, 0x40000100, 0x40000100, 0x01442070,
2045 0x40000100, 0x40000100 2040 0x40000100, 0x40000100
2046}; 2041};
2047 2042
2048static unsigned int dell_3st_pin_configs[14] = { 2043static const unsigned int dell_3st_pin_configs[14] = {
2049 0x02211230, 0x02a11220, 0x01a19040, 0x01114210, 2044 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
2050 0x01111212, 0x01116211, 0x01813050, 0x01112214, 2045 0x01111212, 0x01116211, 0x01813050, 0x01112214,
2051 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb, 2046 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb,
2052 0x40c003fc, 0x40000100 2047 0x40c003fc, 0x40000100
2053}; 2048};
2054 2049
2055static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { 2050static const unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
2056 [STAC_D965_REF_NO_JD] = ref927x_pin_configs, 2051 [STAC_D965_REF_NO_JD] = ref927x_pin_configs,
2057 [STAC_D965_REF] = ref927x_pin_configs, 2052 [STAC_D965_REF] = ref927x_pin_configs,
2058 [STAC_D965_3ST] = d965_3st_pin_configs, 2053 [STAC_D965_3ST] = d965_3st_pin_configs,
@@ -2063,7 +2058,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
2063 [STAC_927X_VOLKNOB] = NULL, 2058 [STAC_927X_VOLKNOB] = NULL,
2064}; 2059};
2065 2060
2066static const char *stac927x_models[STAC_927X_MODELS] = { 2061static const char * const stac927x_models[STAC_927X_MODELS] = {
2067 [STAC_927X_AUTO] = "auto", 2062 [STAC_927X_AUTO] = "auto",
2068 [STAC_D965_REF_NO_JD] = "ref-no-jd", 2063 [STAC_D965_REF_NO_JD] = "ref-no-jd",
2069 [STAC_D965_REF] = "ref", 2064 [STAC_D965_REF] = "ref",
@@ -2075,7 +2070,7 @@ static const char *stac927x_models[STAC_927X_MODELS] = {
2075 [STAC_927X_VOLKNOB] = "volknob", 2070 [STAC_927X_VOLKNOB] = "volknob",
2076}; 2071};
2077 2072
2078static struct snd_pci_quirk stac927x_cfg_tbl[] = { 2073static const struct snd_pci_quirk stac927x_cfg_tbl[] = {
2079 /* SigmaTel reference board */ 2074 /* SigmaTel reference board */
2080 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 2075 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2081 "DFI LanParty", STAC_D965_REF), 2076 "DFI LanParty", STAC_D965_REF),
@@ -2113,7 +2108,7 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
2113 {} /* terminator */ 2108 {} /* terminator */
2114}; 2109};
2115 2110
2116static unsigned int ref9205_pin_configs[12] = { 2111static const unsigned int ref9205_pin_configs[12] = {
2117 0x40000100, 0x40000100, 0x01016011, 0x01014010, 2112 0x40000100, 0x40000100, 0x01016011, 0x01014010,
2118 0x01813122, 0x01a19021, 0x01019020, 0x40000100, 2113 0x01813122, 0x01a19021, 0x01019020, 0x40000100,
2119 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030 2114 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
@@ -2130,7 +2125,7 @@ static unsigned int ref9205_pin_configs[12] = {
2130 10280228 (Dell Vostro 1500) 2125 10280228 (Dell Vostro 1500)
2131 10280229 (Dell Vostro 1700) 2126 10280229 (Dell Vostro 1700)
2132*/ 2127*/
2133static unsigned int dell_9205_m42_pin_configs[12] = { 2128static const unsigned int dell_9205_m42_pin_configs[12] = {
2134 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310, 2129 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
2135 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9, 2130 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
2136 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE, 2131 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
@@ -2146,19 +2141,19 @@ static unsigned int dell_9205_m42_pin_configs[12] = {
2146 10280200 2141 10280200
2147 10280201 2142 10280201
2148*/ 2143*/
2149static unsigned int dell_9205_m43_pin_configs[12] = { 2144static const unsigned int dell_9205_m43_pin_configs[12] = {
2150 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310, 2145 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
2151 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9, 2146 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
2152 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8, 2147 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
2153}; 2148};
2154 2149
2155static unsigned int dell_9205_m44_pin_configs[12] = { 2150static const unsigned int dell_9205_m44_pin_configs[12] = {
2156 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310, 2151 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
2157 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9, 2152 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
2158 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe, 2153 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
2159}; 2154};
2160 2155
2161static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { 2156static const unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
2162 [STAC_9205_REF] = ref9205_pin_configs, 2157 [STAC_9205_REF] = ref9205_pin_configs,
2163 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, 2158 [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
2164 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, 2159 [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
@@ -2166,7 +2161,7 @@ static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
2166 [STAC_9205_EAPD] = NULL, 2161 [STAC_9205_EAPD] = NULL,
2167}; 2162};
2168 2163
2169static const char *stac9205_models[STAC_9205_MODELS] = { 2164static const char * const stac9205_models[STAC_9205_MODELS] = {
2170 [STAC_9205_AUTO] = "auto", 2165 [STAC_9205_AUTO] = "auto",
2171 [STAC_9205_REF] = "ref", 2166 [STAC_9205_REF] = "ref",
2172 [STAC_9205_DELL_M42] = "dell-m42", 2167 [STAC_9205_DELL_M42] = "dell-m42",
@@ -2175,7 +2170,7 @@ static const char *stac9205_models[STAC_9205_MODELS] = {
2175 [STAC_9205_EAPD] = "eapd", 2170 [STAC_9205_EAPD] = "eapd",
2176}; 2171};
2177 2172
2178static struct snd_pci_quirk stac9205_cfg_tbl[] = { 2173static const struct snd_pci_quirk stac9205_cfg_tbl[] = {
2179 /* SigmaTel reference board */ 2174 /* SigmaTel reference board */
2180 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 2175 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
2181 "DFI LanParty", STAC_9205_REF), 2176 "DFI LanParty", STAC_9205_REF),
@@ -2223,7 +2218,7 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = {
2223}; 2218};
2224 2219
2225static void stac92xx_set_config_regs(struct hda_codec *codec, 2220static void stac92xx_set_config_regs(struct hda_codec *codec,
2226 unsigned int *pincfgs) 2221 const unsigned int *pincfgs)
2227{ 2222{
2228 int i; 2223 int i;
2229 struct sigmatel_spec *spec = codec->spec; 2224 struct sigmatel_spec *spec = codec->spec;
@@ -2343,7 +2338,7 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2343 return 0; 2338 return 0;
2344} 2339}
2345 2340
2346static struct hda_pcm_stream stac92xx_pcm_digital_playback = { 2341static const struct hda_pcm_stream stac92xx_pcm_digital_playback = {
2347 .substreams = 1, 2342 .substreams = 1,
2348 .channels_min = 2, 2343 .channels_min = 2,
2349 .channels_max = 2, 2344 .channels_max = 2,
@@ -2356,14 +2351,14 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
2356 }, 2351 },
2357}; 2352};
2358 2353
2359static struct hda_pcm_stream stac92xx_pcm_digital_capture = { 2354static const struct hda_pcm_stream stac92xx_pcm_digital_capture = {
2360 .substreams = 1, 2355 .substreams = 1,
2361 .channels_min = 2, 2356 .channels_min = 2,
2362 .channels_max = 2, 2357 .channels_max = 2,
2363 /* NID is set in stac92xx_build_pcms */ 2358 /* NID is set in stac92xx_build_pcms */
2364}; 2359};
2365 2360
2366static struct hda_pcm_stream stac92xx_pcm_analog_playback = { 2361static const struct hda_pcm_stream stac92xx_pcm_analog_playback = {
2367 .substreams = 1, 2362 .substreams = 1,
2368 .channels_min = 2, 2363 .channels_min = 2,
2369 .channels_max = 8, 2364 .channels_max = 8,
@@ -2375,7 +2370,7 @@ static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
2375 }, 2370 },
2376}; 2371};
2377 2372
2378static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = { 2373static const struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
2379 .substreams = 1, 2374 .substreams = 1,
2380 .channels_min = 2, 2375 .channels_min = 2,
2381 .channels_max = 2, 2376 .channels_max = 2,
@@ -2387,7 +2382,7 @@ static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
2387 }, 2382 },
2388}; 2383};
2389 2384
2390static struct hda_pcm_stream stac92xx_pcm_analog_capture = { 2385static const struct hda_pcm_stream stac92xx_pcm_analog_capture = {
2391 .channels_min = 2, 2386 .channels_min = 2,
2392 .channels_max = 2, 2387 .channels_max = 2,
2393 /* NID + .substreams is set in stac92xx_build_pcms */ 2388 /* NID + .substreams is set in stac92xx_build_pcms */
@@ -2484,7 +2479,7 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2484 2479
2485 spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0; 2480 spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0;
2486 2481
2487 /* check to be sure that the ports are upto date with 2482 /* check to be sure that the ports are up to date with
2488 * switch changes 2483 * switch changes
2489 */ 2484 */
2490 stac_issue_unsol_event(codec, nid); 2485 stac_issue_unsol_event(codec, nid);
@@ -2496,7 +2491,7 @@ static int stac92xx_dc_bias_info(struct snd_kcontrol *kcontrol,
2496 struct snd_ctl_elem_info *uinfo) 2491 struct snd_ctl_elem_info *uinfo)
2497{ 2492{
2498 int i; 2493 int i;
2499 static char *texts[] = { 2494 static const char * const texts[] = {
2500 "Mic In", "Line In", "Line Out" 2495 "Mic In", "Line In", "Line Out"
2501 }; 2496 };
2502 2497
@@ -2565,7 +2560,7 @@ static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol,
2565static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol, 2560static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol,
2566 struct snd_ctl_elem_info *uinfo) 2561 struct snd_ctl_elem_info *uinfo)
2567{ 2562{
2568 static char *texts[2]; 2563 char *texts[2];
2569 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2564 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2570 struct sigmatel_spec *spec = codec->spec; 2565 struct sigmatel_spec *spec = codec->spec;
2571 2566
@@ -2696,7 +2691,7 @@ enum {
2696 STAC_CTL_WIDGET_DC_BIAS 2691 STAC_CTL_WIDGET_DC_BIAS
2697}; 2692};
2698 2693
2699static struct snd_kcontrol_new stac92xx_control_templates[] = { 2694static const struct snd_kcontrol_new stac92xx_control_templates[] = {
2700 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2695 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2701 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2696 HDA_CODEC_MUTE(NULL, 0, 0, 0),
2702 HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0), 2697 HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0),
@@ -2710,7 +2705,7 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = {
2710/* add dynamic controls */ 2705/* add dynamic controls */
2711static struct snd_kcontrol_new * 2706static struct snd_kcontrol_new *
2712stac_control_new(struct sigmatel_spec *spec, 2707stac_control_new(struct sigmatel_spec *spec,
2713 struct snd_kcontrol_new *ktemp, 2708 const struct snd_kcontrol_new *ktemp,
2714 const char *name, 2709 const char *name,
2715 unsigned int subdev) 2710 unsigned int subdev)
2716{ 2711{
@@ -2733,7 +2728,7 @@ stac_control_new(struct sigmatel_spec *spec,
2733} 2728}
2734 2729
2735static int stac92xx_add_control_temp(struct sigmatel_spec *spec, 2730static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
2736 struct snd_kcontrol_new *ktemp, 2731 const struct snd_kcontrol_new *ktemp,
2737 int idx, const char *name, 2732 int idx, const char *name,
2738 unsigned long val) 2733 unsigned long val)
2739{ 2734{
@@ -2763,7 +2758,7 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
2763 return stac92xx_add_control_idx(spec, type, 0, name, val); 2758 return stac92xx_add_control_idx(spec, type, 0, name, val);
2764} 2759}
2765 2760
2766static struct snd_kcontrol_new stac_input_src_temp = { 2761static const struct snd_kcontrol_new stac_input_src_temp = {
2767 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2762 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2768 .name = "Input Source", 2763 .name = "Input Source",
2769 .info = stac92xx_mux_enum_info, 2764 .info = stac92xx_mux_enum_info,
@@ -2779,7 +2774,7 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
2779 struct sigmatel_spec *spec = codec->spec; 2774 struct sigmatel_spec *spec = codec->spec;
2780 char name[22]; 2775 char name[22];
2781 2776
2782 if (!((get_defcfg_connect(def_conf)) & AC_JACK_PORT_FIXED)) { 2777 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
2783 if (stac92xx_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD 2778 if (stac92xx_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
2784 && nid == spec->line_switch) 2779 && nid == spec->line_switch)
2785 control = STAC_CTL_WIDGET_IO_SWITCH; 2780 control = STAC_CTL_WIDGET_IO_SWITCH;
@@ -2791,7 +2786,7 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
2791 } 2786 }
2792 2787
2793 if (control) { 2788 if (control) {
2794 strcpy(name, auto_pin_cfg_labels[idx]); 2789 strcpy(name, hda_get_input_pin_label(codec, nid, 1));
2795 return stac92xx_add_control(codec->spec, control, 2790 return stac92xx_add_control(codec->spec, control,
2796 strcat(name, " Jack Mode"), nid); 2791 strcat(name, " Jack Mode"), nid);
2797 } 2792 }
@@ -2823,41 +2818,49 @@ static hda_nid_t check_line_out_switch(struct hda_codec *codec)
2823 struct auto_pin_cfg *cfg = &spec->autocfg; 2818 struct auto_pin_cfg *cfg = &spec->autocfg;
2824 hda_nid_t nid; 2819 hda_nid_t nid;
2825 unsigned int pincap; 2820 unsigned int pincap;
2821 int i;
2826 2822
2827 if (cfg->line_out_type != AUTO_PIN_LINE_OUT) 2823 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
2828 return 0; 2824 return 0;
2829 nid = cfg->input_pins[AUTO_PIN_LINE]; 2825 for (i = 0; i < cfg->num_inputs; i++) {
2830 pincap = snd_hda_query_pin_caps(codec, nid); 2826 if (cfg->inputs[i].type == AUTO_PIN_LINE_IN) {
2831 if (pincap & AC_PINCAP_OUT) 2827 nid = cfg->inputs[i].pin;
2832 return nid; 2828 pincap = snd_hda_query_pin_caps(codec, nid);
2829 if (pincap & AC_PINCAP_OUT)
2830 return nid;
2831 }
2832 }
2833 return 0; 2833 return 0;
2834} 2834}
2835 2835
2836static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid);
2837
2836/* check whether the mic-input can be used as line-out */ 2838/* check whether the mic-input can be used as line-out */
2837static hda_nid_t check_mic_out_switch(struct hda_codec *codec) 2839static hda_nid_t check_mic_out_switch(struct hda_codec *codec, hda_nid_t *dac)
2838{ 2840{
2839 struct sigmatel_spec *spec = codec->spec; 2841 struct sigmatel_spec *spec = codec->spec;
2840 struct auto_pin_cfg *cfg = &spec->autocfg; 2842 struct auto_pin_cfg *cfg = &spec->autocfg;
2841 unsigned int def_conf, pincap; 2843 unsigned int def_conf, pincap;
2842 unsigned int mic_pin; 2844 int i;
2843 2845
2846 *dac = 0;
2844 if (cfg->line_out_type != AUTO_PIN_LINE_OUT) 2847 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
2845 return 0; 2848 return 0;
2846 mic_pin = AUTO_PIN_MIC; 2849 for (i = 0; i < cfg->num_inputs; i++) {
2847 for (;;) { 2850 hda_nid_t nid = cfg->inputs[i].pin;
2848 hda_nid_t nid = cfg->input_pins[mic_pin]; 2851 if (cfg->inputs[i].type != AUTO_PIN_MIC)
2852 continue;
2849 def_conf = snd_hda_codec_get_pincfg(codec, nid); 2853 def_conf = snd_hda_codec_get_pincfg(codec, nid);
2850 /* some laptops have an internal analog microphone 2854 /* some laptops have an internal analog microphone
2851 * which can't be used as a output */ 2855 * which can't be used as a output */
2852 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { 2856 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
2853 pincap = snd_hda_query_pin_caps(codec, nid); 2857 pincap = snd_hda_query_pin_caps(codec, nid);
2854 if (pincap & AC_PINCAP_OUT) 2858 if (pincap & AC_PINCAP_OUT) {
2855 return nid; 2859 *dac = get_unassigned_dac(codec, nid);
2860 if (*dac)
2861 return nid;
2862 }
2856 } 2863 }
2857 if (mic_pin == AUTO_PIN_MIC)
2858 mic_pin = AUTO_PIN_FRONT_MIC;
2859 else
2860 break;
2861 } 2864 }
2862 return 0; 2865 return 0;
2863} 2866}
@@ -3004,17 +3007,14 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
3004 } 3007 }
3005 } 3008 }
3006 /* add mic as output */ 3009 /* add mic as output */
3007 nid = check_mic_out_switch(codec); 3010 nid = check_mic_out_switch(codec, &dac);
3008 if (nid) { 3011 if (nid && dac) {
3009 dac = get_unassigned_dac(codec, nid); 3012 snd_printdd("STAC: Add mic-in 0x%x as output %d\n",
3010 if (dac) { 3013 nid, cfg->line_outs);
3011 snd_printdd("STAC: Add mic-in 0x%x as output %d\n", 3014 cfg->line_out_pins[cfg->line_outs] = nid;
3012 nid, cfg->line_outs); 3015 cfg->line_outs++;
3013 cfg->line_out_pins[cfg->line_outs] = nid; 3016 spec->mic_switch = nid;
3014 cfg->line_outs++; 3017 add_spec_dacs(spec, dac);
3015 spec->mic_switch = nid;
3016 add_spec_dacs(spec, dac);
3017 }
3018 } 3018 }
3019 3019
3020 snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", 3020 snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
@@ -3076,7 +3076,8 @@ static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
3076 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); 3076 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
3077 return 1; 3077 return 1;
3078 } else { 3078 } else {
3079 spec->multiout.dac_nids[spec->multiout.num_dacs] = nid; 3079 snd_BUG_ON(spec->multiout.dac_nids != spec->dac_nids);
3080 spec->dac_nids[spec->multiout.num_dacs] = nid;
3080 spec->multiout.num_dacs++; 3081 spec->multiout.num_dacs++;
3081 } 3082 }
3082 return 0; 3083 return 0;
@@ -3104,7 +3105,7 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
3104 int type) 3105 int type)
3105{ 3106{
3106 struct sigmatel_spec *spec = codec->spec; 3107 struct sigmatel_spec *spec = codec->spec;
3107 static const char *chname[4] = { 3108 static const char * const chname[4] = {
3108 "Front", "Surround", NULL /*CLFE*/, "Side" 3109 "Front", "Surround", NULL /*CLFE*/, "Side"
3109 }; 3110 };
3110 hda_nid_t nid; 3111 hda_nid_t nid;
@@ -3113,8 +3114,7 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
3113 3114
3114 for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) { 3115 for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) {
3115 if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { 3116 if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) {
3116 wid_caps = get_wcaps(codec, pins[i]); 3117 if (is_jack_detectable(codec, pins[i]))
3117 if (wid_caps & AC_WCAP_UNSOL_CAP)
3118 spec->hp_detect = 1; 3118 spec->hp_detect = 1;
3119 } 3119 }
3120 nid = dac_nids[i]; 3120 nid = dac_nids[i];
@@ -3204,13 +3204,13 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
3204 return err; 3204 return err;
3205 } 3205 }
3206 3206
3207 for (idx = AUTO_PIN_MIC; idx <= AUTO_PIN_FRONT_LINE; idx++) { 3207 for (idx = 0; idx < cfg->num_inputs; idx++) {
3208 nid = cfg->input_pins[idx]; 3208 if (cfg->inputs[idx].type > AUTO_PIN_LINE_IN)
3209 if (nid) { 3209 break;
3210 err = stac92xx_add_jack_mode_control(codec, nid, idx); 3210 nid = cfg->inputs[idx].pin;
3211 if (err < 0) 3211 err = stac92xx_add_jack_mode_control(codec, nid, idx);
3212 return err; 3212 if (err < 0)
3213 } 3213 return err;
3214 } 3214 }
3215 3215
3216 return 0; 3216 return 0;
@@ -3237,7 +3237,7 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
3237} 3237}
3238 3238
3239/* labels for mono mux outputs */ 3239/* labels for mono mux outputs */
3240static const char *stac92xx_mono_labels[4] = { 3240static const char * const stac92xx_mono_labels[4] = {
3241 "DAC0", "DAC1", "Mixer", "DAC2" 3241 "DAC0", "DAC1", "Mixer", "DAC2"
3242}; 3242};
3243 3243
@@ -3256,12 +3256,9 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
3256 if (num_cons <= 0 || num_cons > ARRAY_SIZE(stac92xx_mono_labels)) 3256 if (num_cons <= 0 || num_cons > ARRAY_SIZE(stac92xx_mono_labels))
3257 return -EINVAL; 3257 return -EINVAL;
3258 3258
3259 for (i = 0; i < num_cons; i++) { 3259 for (i = 0; i < num_cons; i++)
3260 mono_mux->items[mono_mux->num_items].label = 3260 snd_hda_add_imux_item(mono_mux, stac92xx_mono_labels[i], i,
3261 stac92xx_mono_labels[i]; 3261 NULL);
3262 mono_mux->items[mono_mux->num_items].index = i;
3263 mono_mux->num_items++;
3264 }
3265 3262
3266 return stac92xx_add_control(spec, STAC_CTL_WIDGET_MONO_MUX, 3263 return stac92xx_add_control(spec, STAC_CTL_WIDGET_MONO_MUX,
3267 "Mono Mux", spec->mono_nid); 3264 "Mono Mux", spec->mono_nid);
@@ -3316,7 +3313,7 @@ static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
3316 return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]); 3313 return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]);
3317} 3314}
3318 3315
3319static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = { 3316static const struct snd_kcontrol_new stac92xx_dig_beep_ctrl = {
3320 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3317 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3321 .info = stac92xx_dig_beep_switch_info, 3318 .info = stac92xx_dig_beep_switch_info,
3322 .get = stac92xx_dig_beep_switch_get, 3319 .get = stac92xx_dig_beep_switch_get,
@@ -3364,7 +3361,7 @@ static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec)
3364 return 0; 3361 return 0;
3365}; 3362};
3366 3363
3367static const char *stac92xx_spdif_labels[3] = { 3364static const char * const stac92xx_spdif_labels[3] = {
3368 "Digital Playback", "Analog Mux 1", "Analog Mux 2", 3365 "Digital Playback", "Analog Mux 1", "Analog Mux 2",
3369}; 3366};
3370 3367
@@ -3372,7 +3369,7 @@ static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec)
3372{ 3369{
3373 struct sigmatel_spec *spec = codec->spec; 3370 struct sigmatel_spec *spec = codec->spec;
3374 struct hda_input_mux *spdif_mux = &spec->private_smux; 3371 struct hda_input_mux *spdif_mux = &spec->private_smux;
3375 const char **labels = spec->spdif_labels; 3372 const char * const *labels = spec->spdif_labels;
3376 int i, num_cons; 3373 int i, num_cons;
3377 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; 3374 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
3378 3375
@@ -3386,38 +3383,58 @@ static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec)
3386 if (!labels) 3383 if (!labels)
3387 labels = stac92xx_spdif_labels; 3384 labels = stac92xx_spdif_labels;
3388 3385
3389 for (i = 0; i < num_cons; i++) { 3386 for (i = 0; i < num_cons; i++)
3390 spdif_mux->items[spdif_mux->num_items].label = labels[i]; 3387 snd_hda_add_imux_item(spdif_mux, labels[i], i, NULL);
3391 spdif_mux->items[spdif_mux->num_items].index = i;
3392 spdif_mux->num_items++;
3393 }
3394 3388
3395 return 0; 3389 return 0;
3396} 3390}
3397 3391
3398/* labels for dmic mux inputs */ 3392/* labels for dmic mux inputs */
3399static const char *stac92xx_dmic_labels[5] = { 3393static const char * const stac92xx_dmic_labels[5] = {
3400 "Analog Inputs", "Digital Mic 1", "Digital Mic 2", 3394 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
3401 "Digital Mic 3", "Digital Mic 4" 3395 "Digital Mic 3", "Digital Mic 4"
3402}; 3396};
3403 3397
3398static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux,
3399 int idx)
3400{
3401 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3402 int nums;
3403 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3404 if (idx >= 0 && idx < nums)
3405 return conn[idx];
3406 return 0;
3407}
3408
3404static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 3409static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
3405 hda_nid_t nid) 3410 hda_nid_t nid)
3406{ 3411{
3407 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 3412 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3408 int i, nums; 3413 int i, nums;
3409 3414
3415 if (!(get_wcaps(codec, mux) & AC_WCAP_CONN_LIST))
3416 return -1;
3417
3410 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); 3418 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3411 for (i = 0; i < nums; i++) 3419 for (i = 0; i < nums; i++)
3412 if (conn[i] == nid) 3420 if (conn[i] == nid)
3413 return i; 3421 return i;
3422
3423 for (i = 0; i < nums; i++) {
3424 unsigned int wid_caps = get_wcaps(codec, conn[i]);
3425 unsigned int wid_type = get_wcaps_type(wid_caps);
3426
3427 if (wid_type != AC_WID_PIN && wid_type != AC_WID_AUD_MIX)
3428 if (get_connection_index(codec, conn[i], nid) >= 0)
3429 return i;
3430 }
3414 return -1; 3431 return -1;
3415} 3432}
3416 3433
3417/* create a volume assigned to the given pin (only if supported) */ 3434/* create a volume assigned to the given pin (only if supported) */
3418/* return 1 if the volume control is created */ 3435/* return 1 if the volume control is created */
3419static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid, 3436static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid,
3420 const char *label, int direction) 3437 const char *label, int idx, int direction)
3421{ 3438{
3422 unsigned int caps, nums; 3439 unsigned int caps, nums;
3423 char name[32]; 3440 char name[32];
@@ -3434,8 +3451,8 @@ static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid,
3434 if (!nums) 3451 if (!nums)
3435 return 0; 3452 return 0;
3436 snprintf(name, sizeof(name), "%s Capture Volume", label); 3453 snprintf(name, sizeof(name), "%s Capture Volume", label);
3437 err = stac92xx_add_control(codec->spec, STAC_CTL_WIDGET_VOL, name, 3454 err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx, name,
3438 HDA_COMPOSE_AMP_VAL(nid, 3, 0, direction)); 3455 HDA_COMPOSE_AMP_VAL(nid, 3, 0, direction));
3439 if (err < 0) 3456 if (err < 0)
3440 return err; 3457 return err;
3441 return 1; 3458 return 1;
@@ -3448,27 +3465,14 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3448 struct sigmatel_spec *spec = codec->spec; 3465 struct sigmatel_spec *spec = codec->spec;
3449 struct hda_input_mux *imux = &spec->private_imux; 3466 struct hda_input_mux *imux = &spec->private_imux;
3450 struct hda_input_mux *dimux = &spec->private_dimux; 3467 struct hda_input_mux *dimux = &spec->private_dimux;
3451 int err, i, active_mics; 3468 int err, i;
3452 unsigned int def_conf; 3469 unsigned int def_conf;
3453 3470
3454 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; 3471 snd_hda_add_imux_item(dimux, stac92xx_dmic_labels[0], 0, NULL);
3455 dimux->items[dimux->num_items].index = 0;
3456 dimux->num_items++;
3457
3458 active_mics = 0;
3459 for (i = 0; i < spec->num_dmics; i++) {
3460 /* check the validity: sometimes it's a dead vendor-spec node */
3461 if (get_wcaps_type(get_wcaps(codec, spec->dmic_nids[i]))
3462 != AC_WID_PIN)
3463 continue;
3464 def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]);
3465 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)
3466 active_mics++;
3467 }
3468 3472
3469 for (i = 0; i < spec->num_dmics; i++) { 3473 for (i = 0; i < spec->num_dmics; i++) {
3470 hda_nid_t nid; 3474 hda_nid_t nid;
3471 int index; 3475 int index, type_idx;
3472 const char *label; 3476 const char *label;
3473 3477
3474 nid = spec->dmic_nids[i]; 3478 nid = spec->dmic_nids[i];
@@ -3482,28 +3486,30 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3482 if (index < 0) 3486 if (index < 0)
3483 continue; 3487 continue;
3484 3488
3485 if (active_mics == 1) 3489 label = hda_get_input_pin_label(codec, nid, 1);
3486 label = "Digital Mic"; 3490 snd_hda_add_imux_item(dimux, label, index, &type_idx);
3487 else 3491 if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
3488 label = stac92xx_dmic_labels[dimux->num_items]; 3492 snd_hda_add_imux_item(imux, label, index, &type_idx);
3489 3493
3490 err = create_elem_capture_vol(codec, nid, label, HDA_INPUT); 3494 err = create_elem_capture_vol(codec, nid, label, type_idx,
3495 HDA_INPUT);
3491 if (err < 0) 3496 if (err < 0)
3492 return err; 3497 return err;
3493 if (!err) { 3498 if (!err) {
3494 err = create_elem_capture_vol(codec, nid, label, 3499 err = create_elem_capture_vol(codec, nid, label,
3495 HDA_OUTPUT); 3500 type_idx, HDA_OUTPUT);
3496 if (err < 0) 3501 if (err < 0)
3497 return err; 3502 return err;
3498 } 3503 if (!err) {
3499 3504 nid = get_connected_node(codec,
3500 dimux->items[dimux->num_items].label = label; 3505 spec->dmux_nids[0], index);
3501 dimux->items[dimux->num_items].index = index; 3506 if (nid)
3502 dimux->num_items++; 3507 err = create_elem_capture_vol(codec,
3503 if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) { 3508 nid, label,
3504 imux->items[imux->num_items].label = label; 3509 type_idx, HDA_INPUT);
3505 imux->items[imux->num_items].index = index; 3510 if (err < 0)
3506 imux->num_items++; 3511 return err;
3512 }
3507 } 3513 }
3508 } 3514 }
3509 3515
@@ -3511,22 +3517,37 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3511} 3517}
3512 3518
3513static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid, 3519static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid,
3514 hda_nid_t *fixed, hda_nid_t *ext) 3520 hda_nid_t *fixed, hda_nid_t *ext, hda_nid_t *dock)
3515{ 3521{
3516 unsigned int cfg; 3522 unsigned int cfg;
3523 unsigned int type;
3517 3524
3518 if (!nid) 3525 if (!nid)
3519 return 0; 3526 return 0;
3520 cfg = snd_hda_codec_get_pincfg(codec, nid); 3527 cfg = snd_hda_codec_get_pincfg(codec, nid);
3521 switch (get_defcfg_connect(cfg)) { 3528 type = get_defcfg_device(cfg);
3522 case AC_JACK_PORT_FIXED: 3529 switch (snd_hda_get_input_pin_attr(cfg)) {
3530 case INPUT_PIN_ATTR_INT:
3523 if (*fixed) 3531 if (*fixed)
3524 return 1; /* already occupied */ 3532 return 1; /* already occupied */
3533 if (type != AC_JACK_MIC_IN)
3534 return 1; /* invalid type */
3525 *fixed = nid; 3535 *fixed = nid;
3526 break; 3536 break;
3527 case AC_JACK_PORT_COMPLEX: 3537 case INPUT_PIN_ATTR_UNUSED:
3538 break;
3539 case INPUT_PIN_ATTR_DOCK:
3540 if (*dock)
3541 return 1; /* already occupied */
3542 if (type != AC_JACK_MIC_IN && type != AC_JACK_LINE_IN)
3543 return 1; /* invalid type */
3544 *dock = nid;
3545 break;
3546 default:
3528 if (*ext) 3547 if (*ext)
3529 return 1; /* already occupied */ 3548 return 1; /* already occupied */
3549 if (type != AC_JACK_MIC_IN)
3550 return 1; /* invalid type */
3530 *ext = nid; 3551 *ext = nid;
3531 break; 3552 break;
3532 } 3553 }
@@ -3542,10 +3563,13 @@ static int set_mic_route(struct hda_codec *codec,
3542 int i; 3563 int i;
3543 3564
3544 mic->pin = pin; 3565 mic->pin = pin;
3545 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) 3566 if (pin == 0)
3546 if (pin == cfg->input_pins[i]) 3567 return 0;
3568 for (i = 0; i < cfg->num_inputs; i++) {
3569 if (pin == cfg->inputs[i].pin)
3547 break; 3570 break;
3548 if (i <= AUTO_PIN_FRONT_MIC) { 3571 }
3572 if (i < cfg->num_inputs && cfg->inputs[i].type == AUTO_PIN_MIC) {
3549 /* analog pin */ 3573 /* analog pin */
3550 i = get_connection_index(codec, spec->mux_nids[0], pin); 3574 i = get_connection_index(codec, spec->mux_nids[0], pin);
3551 if (i < 0) 3575 if (i < 0)
@@ -3576,26 +3600,25 @@ static int stac_check_auto_mic(struct hda_codec *codec)
3576{ 3600{
3577 struct sigmatel_spec *spec = codec->spec; 3601 struct sigmatel_spec *spec = codec->spec;
3578 struct auto_pin_cfg *cfg = &spec->autocfg; 3602 struct auto_pin_cfg *cfg = &spec->autocfg;
3579 hda_nid_t fixed, ext; 3603 hda_nid_t fixed, ext, dock;
3580 int i; 3604 int i;
3581 3605
3582 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++) { 3606 fixed = ext = dock = 0;
3583 if (cfg->input_pins[i]) 3607 for (i = 0; i < cfg->num_inputs; i++)
3584 return 0; /* must be exclusively mics */ 3608 if (check_mic_pin(codec, cfg->inputs[i].pin,
3585 } 3609 &fixed, &ext, &dock))
3586 fixed = ext = 0;
3587 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++)
3588 if (check_mic_pin(codec, cfg->input_pins[i], &fixed, &ext))
3589 return 0; 3610 return 0;
3590 for (i = 0; i < spec->num_dmics; i++) 3611 for (i = 0; i < spec->num_dmics; i++)
3591 if (check_mic_pin(codec, spec->dmic_nids[i], &fixed, &ext)) 3612 if (check_mic_pin(codec, spec->dmic_nids[i],
3613 &fixed, &ext, &dock))
3592 return 0; 3614 return 0;
3593 if (!fixed || !ext) 3615 if (!fixed || (!ext && !dock))
3594 return 0; 3616 return 0; /* no input to switch */
3595 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) 3617 if (!is_jack_detectable(codec, ext))
3596 return 0; /* no unsol support */ 3618 return 0; /* no unsol support */
3597 if (set_mic_route(codec, &spec->ext_mic, ext) || 3619 if (set_mic_route(codec, &spec->ext_mic, ext) ||
3598 set_mic_route(codec, &spec->int_mic, fixed)) 3620 set_mic_route(codec, &spec->int_mic, fixed) ||
3621 set_mic_route(codec, &spec->dock_mic, dock))
3599 return 0; /* something is wrong */ 3622 return 0; /* something is wrong */
3600 return 1; 3623 return 1;
3601} 3624}
@@ -3606,13 +3629,12 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
3606 struct sigmatel_spec *spec = codec->spec; 3629 struct sigmatel_spec *spec = codec->spec;
3607 struct hda_input_mux *imux = &spec->private_imux; 3630 struct hda_input_mux *imux = &spec->private_imux;
3608 int i, j; 3631 int i, j;
3632 const char *label;
3609 3633
3610 for (i = 0; i < AUTO_PIN_LAST; i++) { 3634 for (i = 0; i < cfg->num_inputs; i++) {
3611 hda_nid_t nid = cfg->input_pins[i]; 3635 hda_nid_t nid = cfg->inputs[i].pin;
3612 int index, err; 3636 int index, err, type_idx;
3613 3637
3614 if (!nid)
3615 continue;
3616 index = -1; 3638 index = -1;
3617 for (j = 0; j < spec->num_muxes; j++) { 3639 for (j = 0; j < spec->num_muxes; j++) {
3618 index = get_connection_index(codec, spec->mux_nids[j], 3640 index = get_connection_index(codec, spec->mux_nids[j],
@@ -3623,15 +3645,14 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
3623 if (index < 0) 3645 if (index < 0)
3624 continue; 3646 continue;
3625 3647
3648 label = hda_get_autocfg_input_label(codec, cfg, i);
3649 snd_hda_add_imux_item(imux, label, index, &type_idx);
3650
3626 err = create_elem_capture_vol(codec, nid, 3651 err = create_elem_capture_vol(codec, nid,
3627 auto_pin_cfg_labels[i], 3652 label, type_idx,
3628 HDA_INPUT); 3653 HDA_INPUT);
3629 if (err < 0) 3654 if (err < 0)
3630 return err; 3655 return err;
3631
3632 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
3633 imux->items[imux->num_items].index = index;
3634 imux->num_items++;
3635 } 3656 }
3636 spec->num_analog_muxes = imux->num_items; 3657 spec->num_analog_muxes = imux->num_items;
3637 3658
@@ -3908,13 +3929,11 @@ static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
3908{ 3929{
3909 struct sigmatel_spec *spec = codec->spec; 3930 struct sigmatel_spec *spec = codec->spec;
3910 hda_nid_t pin = cfg->hp_pins[0]; 3931 hda_nid_t pin = cfg->hp_pins[0];
3911 unsigned int wid_caps;
3912 3932
3913 if (! pin) 3933 if (! pin)
3914 return 0; 3934 return 0;
3915 3935
3916 wid_caps = get_wcaps(codec, pin); 3936 if (is_jack_detectable(codec, pin))
3917 if (wid_caps & AC_WCAP_UNSOL_CAP)
3918 spec->hp_detect = 1; 3937 spec->hp_detect = 1;
3919 3938
3920 return 0; 3939 return 0;
@@ -4046,21 +4065,10 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
4046 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ 4065 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
4047} 4066}
4048 4067
4049#ifdef CONFIG_SND_HDA_INPUT_JACK
4050static void stac92xx_free_jack_priv(struct snd_jack *jack)
4051{
4052 struct sigmatel_jack *jacks = jack->private_data;
4053 jacks->nid = 0;
4054 jacks->jack = NULL;
4055}
4056#endif
4057
4058static int stac92xx_add_jack(struct hda_codec *codec, 4068static int stac92xx_add_jack(struct hda_codec *codec,
4059 hda_nid_t nid, int type) 4069 hda_nid_t nid, int type)
4060{ 4070{
4061#ifdef CONFIG_SND_HDA_INPUT_JACK 4071#ifdef CONFIG_SND_HDA_INPUT_JACK
4062 struct sigmatel_spec *spec = codec->spec;
4063 struct sigmatel_jack *jack;
4064 int def_conf = snd_hda_codec_get_pincfg(codec, nid); 4072 int def_conf = snd_hda_codec_get_pincfg(codec, nid);
4065 int connectivity = get_defcfg_connect(def_conf); 4073 int connectivity = get_defcfg_connect(def_conf);
4066 char name[32]; 4074 char name[32];
@@ -4069,26 +4077,15 @@ static int stac92xx_add_jack(struct hda_codec *codec,
4069 if (connectivity && connectivity != AC_JACK_PORT_FIXED) 4077 if (connectivity && connectivity != AC_JACK_PORT_FIXED)
4070 return 0; 4078 return 0;
4071 4079
4072 snd_array_init(&spec->jacks, sizeof(*jack), 32);
4073 jack = snd_array_new(&spec->jacks);
4074 if (!jack)
4075 return -ENOMEM;
4076 jack->nid = nid;
4077 jack->type = type;
4078
4079 snprintf(name, sizeof(name), "%s at %s %s Jack", 4080 snprintf(name, sizeof(name), "%s at %s %s Jack",
4080 snd_hda_get_jack_type(def_conf), 4081 snd_hda_get_jack_type(def_conf),
4081 snd_hda_get_jack_connectivity(def_conf), 4082 snd_hda_get_jack_connectivity(def_conf),
4082 snd_hda_get_jack_location(def_conf)); 4083 snd_hda_get_jack_location(def_conf));
4083 4084
4084 err = snd_jack_new(codec->bus->card, name, type, &jack->jack); 4085 err = snd_hda_input_jack_add(codec, nid, type, name);
4085 if (err < 0) { 4086 if (err < 0)
4086 jack->nid = 0;
4087 return err; 4087 return err;
4088 } 4088#endif /* CONFIG_SND_HDA_INPUT_JACK */
4089 jack->jack->private_data = jack;
4090 jack->jack->private_free = stac92xx_free_jack_priv;
4091#endif
4092 return 0; 4089 return 0;
4093} 4090}
4094 4091
@@ -4147,7 +4144,7 @@ static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
4147 struct sigmatel_event *event; 4144 struct sigmatel_event *event;
4148 int tag; 4145 int tag;
4149 4146
4150 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) 4147 if (!is_jack_detectable(codec, nid))
4151 return 0; 4148 return 0;
4152 event = stac_get_event(codec, nid); 4149 event = stac_get_event(codec, nid);
4153 if (event) { 4150 if (event) {
@@ -4180,7 +4177,7 @@ static void stac92xx_power_down(struct hda_codec *codec)
4180 struct sigmatel_spec *spec = codec->spec; 4177 struct sigmatel_spec *spec = codec->spec;
4181 4178
4182 /* power down inactive DACs */ 4179 /* power down inactive DACs */
4183 hda_nid_t *dac; 4180 const hda_nid_t *dac;
4184 for (dac = spec->dac_list; *dac; dac++) 4181 for (dac = spec->dac_list; *dac; dac++)
4185 if (!check_all_dac_nids(spec, *dac)) 4182 if (!check_all_dac_nids(spec, *dac))
4186 snd_hda_codec_write(codec, *dac, 0, 4183 snd_hda_codec_write(codec, *dac, 0,
@@ -4305,38 +4302,38 @@ static int stac92xx_init(struct hda_codec *codec)
4305 AC_VERB_SET_CONNECT_SEL, 0); 4302 AC_VERB_SET_CONNECT_SEL, 0);
4306 if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT)) 4303 if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT))
4307 stac_issue_unsol_event(codec, spec->ext_mic.pin); 4304 stac_issue_unsol_event(codec, spec->ext_mic.pin);
4308 } 4305 if (enable_pin_detect(codec, spec->dock_mic.pin,
4309 for (i = 0; i < AUTO_PIN_LAST; i++) { 4306 STAC_MIC_EVENT))
4310 hda_nid_t nid = cfg->input_pins[i]; 4307 stac_issue_unsol_event(codec, spec->dock_mic.pin);
4311 if (nid) { 4308 }
4312 unsigned int pinctl, conf; 4309 for (i = 0; i < cfg->num_inputs; i++) {
4313 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) { 4310 hda_nid_t nid = cfg->inputs[i].pin;
4314 /* for mic pins, force to initialize */ 4311 int type = cfg->inputs[i].type;
4315 pinctl = stac92xx_get_default_vref(codec, nid); 4312 unsigned int pinctl, conf;
4313 if (type == AUTO_PIN_MIC) {
4314 /* for mic pins, force to initialize */
4315 pinctl = stac92xx_get_default_vref(codec, nid);
4316 pinctl |= AC_PINCTL_IN_EN;
4317 stac92xx_auto_set_pinctl(codec, nid, pinctl);
4318 } else {
4319 pinctl = snd_hda_codec_read(codec, nid, 0,
4320 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4321 /* if PINCTL already set then skip */
4322 /* Also, if both INPUT and OUTPUT are set,
4323 * it must be a BIOS bug; need to override, too
4324 */
4325 if (!(pinctl & AC_PINCTL_IN_EN) ||
4326 (pinctl & AC_PINCTL_OUT_EN)) {
4327 pinctl &= ~AC_PINCTL_OUT_EN;
4316 pinctl |= AC_PINCTL_IN_EN; 4328 pinctl |= AC_PINCTL_IN_EN;
4317 stac92xx_auto_set_pinctl(codec, nid, pinctl); 4329 stac92xx_auto_set_pinctl(codec, nid, pinctl);
4318 } else {
4319 pinctl = snd_hda_codec_read(codec, nid, 0,
4320 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4321 /* if PINCTL already set then skip */
4322 /* Also, if both INPUT and OUTPUT are set,
4323 * it must be a BIOS bug; need to override, too
4324 */
4325 if (!(pinctl & AC_PINCTL_IN_EN) ||
4326 (pinctl & AC_PINCTL_OUT_EN)) {
4327 pinctl &= ~AC_PINCTL_OUT_EN;
4328 pinctl |= AC_PINCTL_IN_EN;
4329 stac92xx_auto_set_pinctl(codec, nid,
4330 pinctl);
4331 }
4332 }
4333 conf = snd_hda_codec_get_pincfg(codec, nid);
4334 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
4335 if (enable_pin_detect(codec, nid,
4336 STAC_INSERT_EVENT))
4337 stac_issue_unsol_event(codec, nid);
4338 } 4330 }
4339 } 4331 }
4332 conf = snd_hda_codec_get_pincfg(codec, nid);
4333 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
4334 if (enable_pin_detect(codec, nid, STAC_INSERT_EVENT))
4335 stac_issue_unsol_event(codec, nid);
4336 }
4340 } 4337 }
4341 for (i = 0; i < spec->num_dmics; i++) 4338 for (i = 0; i < spec->num_dmics; i++)
4342 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], 4339 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
@@ -4383,33 +4380,14 @@ static int stac92xx_init(struct hda_codec *codec)
4383 stac_issue_unsol_event(codec, nid); 4380 stac_issue_unsol_event(codec, nid);
4384 } 4381 }
4385 4382
4386#ifdef CONFIG_SND_HDA_POWER_SAVE
4387 /* sync mute LED */ 4383 /* sync mute LED */
4388 if (spec->gpio_led && codec->patch_ops.check_power_status) 4384 if (spec->gpio_led)
4389 codec->patch_ops.check_power_status(codec, 0x01); 4385 hda_call_check_power_status(codec, 0x01);
4390#endif
4391 if (spec->dac_list) 4386 if (spec->dac_list)
4392 stac92xx_power_down(codec); 4387 stac92xx_power_down(codec);
4393 return 0; 4388 return 0;
4394} 4389}
4395 4390
4396static void stac92xx_free_jacks(struct hda_codec *codec)
4397{
4398#ifdef CONFIG_SND_HDA_INPUT_JACK
4399 /* free jack instances manually when clearing/reconfiguring */
4400 struct sigmatel_spec *spec = codec->spec;
4401 if (!codec->bus->shutdown && spec->jacks.list) {
4402 struct sigmatel_jack *jacks = spec->jacks.list;
4403 int i;
4404 for (i = 0; i < spec->jacks.used; i++, jacks++) {
4405 if (jacks->jack)
4406 snd_device_free(codec->bus->card, jacks->jack);
4407 }
4408 }
4409 snd_array_free(&spec->jacks);
4410#endif
4411}
4412
4413static void stac92xx_free_kctls(struct hda_codec *codec) 4391static void stac92xx_free_kctls(struct hda_codec *codec)
4414{ 4392{
4415 struct sigmatel_spec *spec = codec->spec; 4393 struct sigmatel_spec *spec = codec->spec;
@@ -4443,7 +4421,7 @@ static void stac92xx_free(struct hda_codec *codec)
4443 return; 4421 return;
4444 4422
4445 stac92xx_shutup(codec); 4423 stac92xx_shutup(codec);
4446 stac92xx_free_jacks(codec); 4424 snd_hda_input_jack_free(codec);
4447 snd_array_free(&spec->events); 4425 snd_array_free(&spec->events);
4448 4426
4449 kfree(spec); 4427 kfree(spec);
@@ -4661,31 +4639,34 @@ static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
4661 stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid)); 4639 stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid));
4662} 4640}
4663 4641
4664static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid) 4642/* get the pin connection (fixed, none, etc) */
4643static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx)
4665{ 4644{
4666 struct sigmatel_spec *spec = codec->spec; 4645 struct sigmatel_spec *spec = codec->spec;
4667 struct sigmatel_jack *jacks = spec->jacks.list; 4646 unsigned int cfg;
4668 4647
4669 if (jacks) { 4648 cfg = snd_hda_codec_get_pincfg(codec, spec->pin_nids[idx]);
4670 int i; 4649 return get_defcfg_connect(cfg);
4671 for (i = 0; i < spec->jacks.used; i++) { 4650}
4672 if (jacks->nid == nid) { 4651
4673 unsigned int pin_ctl = 4652static int stac92xx_connected_ports(struct hda_codec *codec,
4674 snd_hda_codec_read(codec, nid, 4653 const hda_nid_t *nids, int num_nids)
4675 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 4654{
4676 0x00); 4655 struct sigmatel_spec *spec = codec->spec;
4677 int type = jacks->type; 4656 int idx, num;
4678 if (type == (SND_JACK_LINEOUT 4657 unsigned int def_conf;
4679 | SND_JACK_HEADPHONE)) 4658
4680 type = (pin_ctl & AC_PINCTL_HP_EN) 4659 for (num = 0; num < num_nids; num++) {
4681 ? SND_JACK_HEADPHONE : SND_JACK_LINEOUT; 4660 for (idx = 0; idx < spec->num_pins; idx++)
4682 snd_jack_report(jacks->jack, 4661 if (spec->pin_nids[idx] == nids[num])
4683 get_pin_presence(codec, nid) 4662 break;
4684 ? type : 0); 4663 if (idx >= spec->num_pins)
4685 } 4664 break;
4686 jacks++; 4665 def_conf = stac_get_defcfg_connect(codec, idx);
4687 } 4666 if (def_conf == AC_JACK_PORT_NONE)
4667 break;
4688 } 4668 }
4669 return num;
4689} 4670}
4690 4671
4691static void stac92xx_mic_detect(struct hda_codec *codec) 4672static void stac92xx_mic_detect(struct hda_codec *codec)
@@ -4695,6 +4676,8 @@ static void stac92xx_mic_detect(struct hda_codec *codec)
4695 4676
4696 if (get_pin_presence(codec, spec->ext_mic.pin)) 4677 if (get_pin_presence(codec, spec->ext_mic.pin))
4697 mic = &spec->ext_mic; 4678 mic = &spec->ext_mic;
4679 else if (get_pin_presence(codec, spec->dock_mic.pin))
4680 mic = &spec->dock_mic;
4698 else 4681 else
4699 mic = &spec->int_mic; 4682 mic = &spec->int_mic;
4700 if (mic->dmux_idx >= 0) 4683 if (mic->dmux_idx >= 0)
@@ -4744,7 +4727,7 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4744 case STAC_PWR_EVENT: 4727 case STAC_PWR_EVENT:
4745 if (spec->num_pwrs > 0) 4728 if (spec->num_pwrs > 0)
4746 stac92xx_pin_sense(codec, event->nid); 4729 stac92xx_pin_sense(codec, event->nid);
4747 stac92xx_report_jack(codec, event->nid); 4730 snd_hda_input_jack_report(codec, event->nid);
4748 4731
4749 switch (codec->subsystem_id) { 4732 switch (codec->subsystem_id) {
4750 case 0x103c308f: 4733 case 0x103c308f:
@@ -4937,11 +4920,9 @@ static int stac92xx_resume(struct hda_codec *codec)
4937 stac_issue_unsol_event(codec, 4920 stac_issue_unsol_event(codec,
4938 spec->autocfg.line_out_pins[0]); 4921 spec->autocfg.line_out_pins[0]);
4939 } 4922 }
4940#ifdef CONFIG_SND_HDA_POWER_SAVE
4941 /* sync mute LED */ 4923 /* sync mute LED */
4942 if (spec->gpio_led && codec->patch_ops.check_power_status) 4924 if (spec->gpio_led)
4943 codec->patch_ops.check_power_status(codec, 0x01); 4925 hda_call_check_power_status(codec, 0x01);
4944#endif
4945 return 0; 4926 return 0;
4946} 4927}
4947 4928
@@ -4993,7 +4974,7 @@ static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
4993} 4974}
4994#endif 4975#endif
4995 4976
4996static struct hda_codec_ops stac92xx_patch_ops = { 4977static const struct hda_codec_ops stac92xx_patch_ops = {
4997 .build_controls = stac92xx_build_controls, 4978 .build_controls = stac92xx_build_controls,
4998 .build_pcms = stac92xx_build_pcms, 4979 .build_pcms = stac92xx_build_pcms,
4999 .init = stac92xx_init, 4980 .init = stac92xx_init,
@@ -5302,6 +5283,145 @@ again:
5302 return 0; 5283 return 0;
5303} 5284}
5304 5285
5286static int hp_bnb2011_with_dock(struct hda_codec *codec)
5287{
5288 if (codec->vendor_id != 0x111d7605 &&
5289 codec->vendor_id != 0x111d76d1)
5290 return 0;
5291
5292 switch (codec->subsystem_id) {
5293 case 0x103c1618:
5294 case 0x103c1619:
5295 case 0x103c161a:
5296 case 0x103c161b:
5297 case 0x103c161c:
5298 case 0x103c161d:
5299 case 0x103c161e:
5300 case 0x103c161f:
5301
5302 case 0x103c162a:
5303 case 0x103c162b:
5304
5305 case 0x103c1630:
5306 case 0x103c1631:
5307
5308 case 0x103c1633:
5309 case 0x103c1634:
5310 case 0x103c1635:
5311
5312 case 0x103c3587:
5313 case 0x103c3588:
5314 case 0x103c3589:
5315 case 0x103c358a:
5316
5317 case 0x103c3667:
5318 case 0x103c3668:
5319 case 0x103c3669:
5320
5321 return 1;
5322 }
5323 return 0;
5324}
5325
5326static void stac92hd8x_add_pin(struct hda_codec *codec, hda_nid_t nid)
5327{
5328 struct sigmatel_spec *spec = codec->spec;
5329 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
5330 int i;
5331
5332 spec->auto_pin_nids[spec->auto_pin_cnt] = nid;
5333 spec->auto_pin_cnt++;
5334
5335 if (get_defcfg_device(def_conf) == AC_JACK_MIC_IN &&
5336 get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) {
5337 for (i = 0; i < ARRAY_SIZE(stac92hd83xxx_dmic_nids); i++) {
5338 if (nid == stac92hd83xxx_dmic_nids[i]) {
5339 spec->auto_dmic_nids[spec->auto_dmic_cnt] = nid;
5340 spec->auto_dmic_cnt++;
5341 }
5342 }
5343 }
5344}
5345
5346static void stac92hd8x_add_adc(struct hda_codec *codec, hda_nid_t nid)
5347{
5348 struct sigmatel_spec *spec = codec->spec;
5349
5350 spec->auto_adc_nids[spec->auto_adc_cnt] = nid;
5351 spec->auto_adc_cnt++;
5352}
5353
5354static void stac92hd8x_add_mux(struct hda_codec *codec, hda_nid_t nid)
5355{
5356 int i, j;
5357 struct sigmatel_spec *spec = codec->spec;
5358
5359 for (i = 0; i < spec->auto_adc_cnt; i++) {
5360 if (get_connection_index(codec,
5361 spec->auto_adc_nids[i], nid) >= 0) {
5362 /* mux and volume for adc_nids[i] */
5363 if (!spec->auto_mux_nids[i]) {
5364 spec->auto_mux_nids[i] = nid;
5365 /* 92hd codecs capture volume is in mux */
5366 spec->auto_capvols[i] = HDA_COMPOSE_AMP_VAL(nid,
5367 3, 0, HDA_OUTPUT);
5368 }
5369 for (j = 0; j < spec->auto_dmic_cnt; j++) {
5370 if (get_connection_index(codec, nid,
5371 spec->auto_dmic_nids[j]) >= 0) {
5372 /* dmux for adc_nids[i] */
5373 if (!spec->auto_dmux_nids[i])
5374 spec->auto_dmux_nids[i] = nid;
5375 break;
5376 }
5377 }
5378 break;
5379 }
5380 }
5381}
5382
5383static void stac92hd8x_fill_auto_spec(struct hda_codec *codec)
5384{
5385 hda_nid_t nid, end_nid;
5386 unsigned int wid_caps, wid_type;
5387 struct sigmatel_spec *spec = codec->spec;
5388
5389 end_nid = codec->start_nid + codec->num_nodes;
5390
5391 for (nid = codec->start_nid; nid < end_nid; nid++) {
5392 wid_caps = get_wcaps(codec, nid);
5393 wid_type = get_wcaps_type(wid_caps);
5394
5395 if (wid_type == AC_WID_PIN)
5396 stac92hd8x_add_pin(codec, nid);
5397
5398 if (wid_type == AC_WID_AUD_IN && !(wid_caps & AC_WCAP_DIGITAL))
5399 stac92hd8x_add_adc(codec, nid);
5400 }
5401
5402 for (nid = codec->start_nid; nid < end_nid; nid++) {
5403 wid_caps = get_wcaps(codec, nid);
5404 wid_type = get_wcaps_type(wid_caps);
5405
5406 if (wid_type == AC_WID_AUD_SEL)
5407 stac92hd8x_add_mux(codec, nid);
5408 }
5409
5410 spec->pin_nids = spec->auto_pin_nids;
5411 spec->num_pins = spec->auto_pin_cnt;
5412 spec->adc_nids = spec->auto_adc_nids;
5413 spec->num_adcs = spec->auto_adc_cnt;
5414 spec->capvols = spec->auto_capvols;
5415 spec->capsws = spec->auto_capvols;
5416 spec->num_caps = spec->auto_adc_cnt;
5417 spec->mux_nids = spec->auto_mux_nids;
5418 spec->num_muxes = spec->auto_adc_cnt;
5419 spec->dmux_nids = spec->auto_dmux_nids;
5420 spec->num_dmuxes = spec->auto_adc_cnt;
5421 spec->dmic_nids = spec->auto_dmic_nids;
5422 spec->num_dmics = spec->auto_dmic_cnt;
5423}
5424
5305static int patch_stac92hd83xxx(struct hda_codec *codec) 5425static int patch_stac92hd83xxx(struct hda_codec *codec)
5306{ 5426{
5307 struct sigmatel_spec *spec; 5427 struct sigmatel_spec *spec;
@@ -5313,26 +5433,27 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5313 if (spec == NULL) 5433 if (spec == NULL)
5314 return -ENOMEM; 5434 return -ENOMEM;
5315 5435
5436 if (hp_bnb2011_with_dock(codec)) {
5437 snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f);
5438 snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
5439 }
5440
5441 /* reset pin power-down; Windows may leave these bits after reboot */
5442 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7EC, 0);
5443 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0);
5316 codec->no_trigger_sense = 1; 5444 codec->no_trigger_sense = 1;
5317 codec->spec = spec; 5445 codec->spec = spec;
5318 spec->linear_tone_beep = 1; 5446
5447 stac92hd8x_fill_auto_spec(codec);
5448
5449 spec->linear_tone_beep = 0;
5319 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; 5450 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
5320 spec->digbeep_nid = 0x21; 5451 spec->digbeep_nid = 0x21;
5321 spec->mux_nids = stac92hd83xxx_mux_nids;
5322 spec->num_muxes = ARRAY_SIZE(stac92hd83xxx_mux_nids);
5323 spec->adc_nids = stac92hd83xxx_adc_nids;
5324 spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids);
5325 spec->pwr_nids = stac92hd83xxx_pwr_nids; 5452 spec->pwr_nids = stac92hd83xxx_pwr_nids;
5326 spec->pwr_mapping = stac92hd83xxx_pwr_mapping; 5453 spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
5327 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); 5454 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
5328 spec->multiout.dac_nids = spec->dac_nids; 5455 spec->multiout.dac_nids = spec->dac_nids;
5329
5330 spec->init = stac92hd83xxx_core_init; 5456 spec->init = stac92hd83xxx_core_init;
5331 spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids);
5332 spec->pin_nids = stac92hd83xxx_pin_nids;
5333 spec->num_caps = STAC92HD83XXX_NUM_CAPS;
5334 spec->capvols = stac92hd83xxx_capvols;
5335 spec->capsws = stac92hd83xxx_capsws;
5336 5457
5337 spec->board_config = snd_hda_check_board_config(codec, 5458 spec->board_config = snd_hda_check_board_config(codec,
5338 STAC_92HD83XXX_MODELS, 5459 STAC_92HD83XXX_MODELS,
@@ -5347,22 +5468,19 @@ again:
5347 stac92hd83xxx_brd_tbl[spec->board_config]); 5468 stac92hd83xxx_brd_tbl[spec->board_config]);
5348 5469
5349 switch (codec->vendor_id) { 5470 switch (codec->vendor_id) {
5471 case 0x111d76d1:
5472 case 0x111d76d9:
5473 case 0x111d76e5:
5350 case 0x111d7666: 5474 case 0x111d7666:
5351 case 0x111d7667: 5475 case 0x111d7667:
5352 case 0x111d7668: 5476 case 0x111d7668:
5353 case 0x111d7669: 5477 case 0x111d7669:
5354 case 0x111d76d1: 5478 case 0x111d76e3:
5355 case 0x111d76d9:
5356 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
5357 spec->pin_nids = stac92hd88xxx_pin_nids;
5358 spec->mono_nid = 0;
5359 spec->digbeep_nid = 0;
5360 spec->num_pwrs = 0;
5361 break;
5362 case 0x111d7604: 5479 case 0x111d7604:
5363 case 0x111d76d4: 5480 case 0x111d76d4:
5364 case 0x111d7605: 5481 case 0x111d7605:
5365 case 0x111d76d5: 5482 case 0x111d76d5:
5483 case 0x111d76e7:
5366 if (spec->board_config == STAC_92HD83XXX_PWR_REF) 5484 if (spec->board_config == STAC_92HD83XXX_PWR_REF)
5367 break; 5485 break;
5368 spec->num_pwrs = 0; 5486 spec->num_pwrs = 0;
@@ -5424,36 +5542,6 @@ again:
5424 return 0; 5542 return 0;
5425} 5543}
5426 5544
5427/* get the pin connection (fixed, none, etc) */
5428static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx)
5429{
5430 struct sigmatel_spec *spec = codec->spec;
5431 unsigned int cfg;
5432
5433 cfg = snd_hda_codec_get_pincfg(codec, spec->pin_nids[idx]);
5434 return get_defcfg_connect(cfg);
5435}
5436
5437static int stac92hd71bxx_connected_ports(struct hda_codec *codec,
5438 hda_nid_t *nids, int num_nids)
5439{
5440 struct sigmatel_spec *spec = codec->spec;
5441 int idx, num;
5442 unsigned int def_conf;
5443
5444 for (num = 0; num < num_nids; num++) {
5445 for (idx = 0; idx < spec->num_pins; idx++)
5446 if (spec->pin_nids[idx] == nids[num])
5447 break;
5448 if (idx >= spec->num_pins)
5449 break;
5450 def_conf = stac_get_defcfg_connect(codec, idx);
5451 if (def_conf == AC_JACK_PORT_NONE)
5452 break;
5453 }
5454 return num;
5455}
5456
5457static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec, 5545static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec,
5458 hda_nid_t dig0pin) 5546 hda_nid_t dig0pin)
5459{ 5547{
@@ -5506,7 +5594,7 @@ static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
5506 return 1; 5594 return 1;
5507} 5595}
5508 5596
5509static struct snd_kcontrol_new stac_hp_bass_sw_ctrl = { 5597static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
5510 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5598 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5511 .info = stac_hp_bass_gpio_info, 5599 .info = stac_hp_bass_gpio_info,
5512 .get = stac_hp_bass_gpio_get, 5600 .get = stac_hp_bass_gpio_get,
@@ -5530,7 +5618,7 @@ static int stac_add_hp_bass_switch(struct hda_codec *codec)
5530static int patch_stac92hd71bxx(struct hda_codec *codec) 5618static int patch_stac92hd71bxx(struct hda_codec *codec)
5531{ 5619{
5532 struct sigmatel_spec *spec; 5620 struct sigmatel_spec *spec;
5533 struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; 5621 const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init;
5534 unsigned int pin_cfg; 5622 unsigned int pin_cfg;
5535 int err = 0; 5623 int err = 0;
5536 5624
@@ -5592,7 +5680,7 @@ again:
5592 case 0x111d76b5: 5680 case 0x111d76b5:
5593 spec->init = stac92hd71bxx_core_init; 5681 spec->init = stac92hd71bxx_core_init;
5594 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; 5682 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
5595 spec->num_dmics = stac92hd71bxx_connected_ports(codec, 5683 spec->num_dmics = stac92xx_connected_ports(codec,
5596 stac92hd71bxx_dmic_nids, 5684 stac92hd71bxx_dmic_nids,
5597 STAC92HD71BXX_NUM_DMICS); 5685 STAC92HD71BXX_NUM_DMICS);
5598 break; 5686 break;
@@ -5623,9 +5711,9 @@ again:
5623 unmute_init++; 5711 unmute_init++;
5624 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); 5712 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
5625 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); 5713 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
5626 stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS - 1] = 0; 5714 spec->dmic_nids = stac92hd71bxx_dmic_5port_nids;
5627 spec->num_dmics = stac92hd71bxx_connected_ports(codec, 5715 spec->num_dmics = stac92xx_connected_ports(codec,
5628 stac92hd71bxx_dmic_nids, 5716 stac92hd71bxx_dmic_5port_nids,
5629 STAC92HD71BXX_NUM_DMICS - 1); 5717 STAC92HD71BXX_NUM_DMICS - 1);
5630 break; 5718 break;
5631 case 0x111d7603: /* 6 Port with Analog Mixer */ 5719 case 0x111d7603: /* 6 Port with Analog Mixer */
@@ -5638,7 +5726,7 @@ again:
5638 default: 5726 default:
5639 spec->init = stac92hd71bxx_core_init; 5727 spec->init = stac92hd71bxx_core_init;
5640 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; 5728 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
5641 spec->num_dmics = stac92hd71bxx_connected_ports(codec, 5729 spec->num_dmics = stac92xx_connected_ports(codec,
5642 stac92hd71bxx_dmic_nids, 5730 stac92hd71bxx_dmic_nids,
5643 STAC92HD71BXX_NUM_DMICS); 5731 STAC92HD71BXX_NUM_DMICS);
5644 break; 5732 break;
@@ -5647,15 +5735,6 @@ again:
5647 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) 5735 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
5648 snd_hda_sequence_write_cache(codec, unmute_init); 5736 snd_hda_sequence_write_cache(codec, unmute_init);
5649 5737
5650 /* Some HP machines seem to have unstable codec communications
5651 * especially with ATI fglrx driver. For recovering from the
5652 * CORB/RIRB stall, allow the BUS reset and keep always sync
5653 */
5654 if (spec->board_config == STAC_HP_DV5) {
5655 codec->bus->sync_write = 1;
5656 codec->bus->allow_bus_reset = 1;
5657 }
5658
5659 spec->aloopback_ctl = stac92hd71bxx_loopback; 5738 spec->aloopback_ctl = stac92hd71bxx_loopback;
5660 spec->aloopback_mask = 0x50; 5739 spec->aloopback_mask = 0x50;
5661 spec->aloopback_shift = 0; 5740 spec->aloopback_shift = 0;
@@ -6141,46 +6220,46 @@ static int patch_stac9205(struct hda_codec *codec)
6141 * STAC9872 hack 6220 * STAC9872 hack
6142 */ 6221 */
6143 6222
6144static struct hda_verb stac9872_core_init[] = { 6223static const struct hda_verb stac9872_core_init[] = {
6145 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ 6224 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
6146 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ 6225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
6147 {} 6226 {}
6148}; 6227};
6149 6228
6150static hda_nid_t stac9872_pin_nids[] = { 6229static const hda_nid_t stac9872_pin_nids[] = {
6151 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 6230 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
6152 0x11, 0x13, 0x14, 6231 0x11, 0x13, 0x14,
6153}; 6232};
6154 6233
6155static hda_nid_t stac9872_adc_nids[] = { 6234static const hda_nid_t stac9872_adc_nids[] = {
6156 0x8 /*,0x6*/ 6235 0x8 /*,0x6*/
6157}; 6236};
6158 6237
6159static hda_nid_t stac9872_mux_nids[] = { 6238static const hda_nid_t stac9872_mux_nids[] = {
6160 0x15 6239 0x15
6161}; 6240};
6162 6241
6163static unsigned long stac9872_capvols[] = { 6242static const unsigned long stac9872_capvols[] = {
6164 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 6243 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
6165}; 6244};
6166#define stac9872_capsws stac9872_capvols 6245#define stac9872_capsws stac9872_capvols
6167 6246
6168static unsigned int stac9872_vaio_pin_configs[9] = { 6247static const unsigned int stac9872_vaio_pin_configs[9] = {
6169 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030, 6248 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030,
6170 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0, 6249 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0,
6171 0x90a7013e 6250 0x90a7013e
6172}; 6251};
6173 6252
6174static const char *stac9872_models[STAC_9872_MODELS] = { 6253static const char * const stac9872_models[STAC_9872_MODELS] = {
6175 [STAC_9872_AUTO] = "auto", 6254 [STAC_9872_AUTO] = "auto",
6176 [STAC_9872_VAIO] = "vaio", 6255 [STAC_9872_VAIO] = "vaio",
6177}; 6256};
6178 6257
6179static unsigned int *stac9872_brd_tbl[STAC_9872_MODELS] = { 6258static const unsigned int *stac9872_brd_tbl[STAC_9872_MODELS] = {
6180 [STAC_9872_VAIO] = stac9872_vaio_pin_configs, 6259 [STAC_9872_VAIO] = stac9872_vaio_pin_configs,
6181}; 6260};
6182 6261
6183static struct snd_pci_quirk stac9872_cfg_tbl[] = { 6262static const struct snd_pci_quirk stac9872_cfg_tbl[] = {
6184 SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0, 6263 SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0,
6185 "Sony VAIO F/S", STAC_9872_VAIO), 6264 "Sony VAIO F/S", STAC_9872_VAIO),
6186 {} /* terminator */ 6265 {} /* terminator */
@@ -6234,7 +6313,7 @@ static int patch_stac9872(struct hda_codec *codec)
6234/* 6313/*
6235 * patch entries 6314 * patch entries
6236 */ 6315 */
6237static struct hda_codec_preset snd_hda_preset_sigmatel[] = { 6316static const struct hda_codec_preset snd_hda_preset_sigmatel[] = {
6238 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 }, 6317 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
6239 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x }, 6318 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
6240 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x }, 6319 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
@@ -6320,6 +6399,10 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
6320 { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx }, 6399 { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx },
6321 { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx }, 6400 { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx },
6322 { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx }, 6401 { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx },
6402 { .id = 0x111d76e0, .name = "92HD91BXX", .patch = patch_stac92hd83xxx},
6403 { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx},
6404 { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx},
6405 { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx},
6323 {} /* terminator */ 6406 {} /* terminator */
6324}; 6407};
6325 6408
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index ae3acb2b42d1..f43bb0eaed8b 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -98,24 +98,30 @@ enum VIA_HDA_CODEC {
98 VT1716S, 98 VT1716S,
99 VT2002P, 99 VT2002P,
100 VT1812, 100 VT1812,
101 VT1802,
101 CODEC_TYPES, 102 CODEC_TYPES,
102}; 103};
103 104
105#define VT2002P_COMPATIBLE(spec) \
106 ((spec)->codec_type == VT2002P ||\
107 (spec)->codec_type == VT1812 ||\
108 (spec)->codec_type == VT1802)
109
104struct via_spec { 110struct via_spec {
105 /* codec parameterization */ 111 /* codec parameterization */
106 struct snd_kcontrol_new *mixers[6]; 112 const struct snd_kcontrol_new *mixers[6];
107 unsigned int num_mixers; 113 unsigned int num_mixers;
108 114
109 struct hda_verb *init_verbs[5]; 115 const struct hda_verb *init_verbs[5];
110 unsigned int num_iverbs; 116 unsigned int num_iverbs;
111 117
112 char *stream_name_analog; 118 char *stream_name_analog;
113 struct hda_pcm_stream *stream_analog_playback; 119 const struct hda_pcm_stream *stream_analog_playback;
114 struct hda_pcm_stream *stream_analog_capture; 120 const struct hda_pcm_stream *stream_analog_capture;
115 121
116 char *stream_name_digital; 122 char *stream_name_digital;
117 struct hda_pcm_stream *stream_digital_playback; 123 const struct hda_pcm_stream *stream_digital_playback;
118 struct hda_pcm_stream *stream_digital_capture; 124 const struct hda_pcm_stream *stream_digital_capture;
119 125
120 /* playback */ 126 /* playback */
121 struct hda_multi_out multiout; 127 struct hda_multi_out multiout;
@@ -123,7 +129,7 @@ struct via_spec {
123 129
124 /* capture */ 130 /* capture */
125 unsigned int num_adc_nids; 131 unsigned int num_adc_nids;
126 hda_nid_t *adc_nids; 132 const hda_nid_t *adc_nids;
127 hda_nid_t mux_nids[3]; 133 hda_nid_t mux_nids[3];
128 hda_nid_t dig_in_nid; 134 hda_nid_t dig_in_nid;
129 hda_nid_t dig_in_pin; 135 hda_nid_t dig_in_pin;
@@ -154,11 +160,15 @@ struct via_spec {
154 struct delayed_work vt1708_hp_work; 160 struct delayed_work vt1708_hp_work;
155 int vt1708_jack_detectect; 161 int vt1708_jack_detectect;
156 int vt1708_hp_present; 162 int vt1708_hp_present;
163
164 void (*set_widgets_power_state)(struct hda_codec *codec);
165
157#ifdef CONFIG_SND_HDA_POWER_SAVE 166#ifdef CONFIG_SND_HDA_POWER_SAVE
158 struct hda_loopback_check loopback; 167 struct hda_loopback_check loopback;
159#endif 168#endif
160}; 169};
161 170
171static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
162static struct via_spec * via_new_spec(struct hda_codec *codec) 172static struct via_spec * via_new_spec(struct hda_codec *codec)
163{ 173{
164 struct via_spec *spec; 174 struct via_spec *spec;
@@ -169,6 +179,10 @@ static struct via_spec * via_new_spec(struct hda_codec *codec)
169 179
170 codec->spec = spec; 180 codec->spec = spec;
171 spec->codec = codec; 181 spec->codec = codec;
182 spec->codec_type = get_codec_type(codec);
183 /* VT1708BCE & VT1708S are almost same */
184 if (spec->codec_type == VT1708BCE)
185 spec->codec_type = VT1708S;
172 return spec; 186 return spec;
173} 187}
174 188
@@ -213,17 +227,19 @@ static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
213 codec_type = VT1812; 227 codec_type = VT1812;
214 else if (dev_id == 0x0440) 228 else if (dev_id == 0x0440)
215 codec_type = VT1708S; 229 codec_type = VT1708S;
230 else if ((dev_id & 0xfff) == 0x446)
231 codec_type = VT1802;
216 else 232 else
217 codec_type = UNKNOWN; 233 codec_type = UNKNOWN;
218 return codec_type; 234 return codec_type;
219}; 235};
220 236
237#define VIA_JACK_EVENT 0x20
221#define VIA_HP_EVENT 0x01 238#define VIA_HP_EVENT 0x01
222#define VIA_GPIO_EVENT 0x02 239#define VIA_GPIO_EVENT 0x02
223#define VIA_JACK_EVENT 0x04 240#define VIA_MONO_EVENT 0x03
224#define VIA_MONO_EVENT 0x08 241#define VIA_SPEAKER_EVENT 0x04
225#define VIA_SPEAKER_EVENT 0x10 242#define VIA_BIND_HP_EVENT 0x05
226#define VIA_BIND_HP_EVENT 0x20
227 243
228enum { 244enum {
229 VIA_CTL_WIDGET_VOL, 245 VIA_CTL_WIDGET_VOL,
@@ -240,7 +256,6 @@ enum {
240}; 256};
241 257
242static void analog_low_current_mode(struct hda_codec *codec, int stream_idle); 258static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
243static void set_jack_power_state(struct hda_codec *codec);
244static int is_aa_path_mute(struct hda_codec *codec); 259static int is_aa_path_mute(struct hda_codec *codec);
245 260
246static void vt1708_start_hp_work(struct via_spec *spec) 261static void vt1708_start_hp_work(struct via_spec *spec)
@@ -263,10 +278,15 @@ static void vt1708_stop_hp_work(struct via_spec *spec)
263 return; 278 return;
264 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 279 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
265 !spec->vt1708_jack_detectect); 280 !spec->vt1708_jack_detectect);
266 cancel_delayed_work(&spec->vt1708_hp_work); 281 cancel_delayed_work_sync(&spec->vt1708_hp_work);
267 flush_scheduled_work();
268} 282}
269 283
284static void set_widgets_power_state(struct hda_codec *codec)
285{
286 struct via_spec *spec = codec->spec;
287 if (spec->set_widgets_power_state)
288 spec->set_widgets_power_state(codec);
289}
270 290
271static int analog_input_switch_put(struct snd_kcontrol *kcontrol, 291static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
272 struct snd_ctl_elem_value *ucontrol) 292 struct snd_ctl_elem_value *ucontrol)
@@ -274,7 +294,7 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
274 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 294 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
275 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 295 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
276 296
277 set_jack_power_state(codec); 297 set_widgets_power_state(codec);
278 analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1); 298 analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1);
279 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { 299 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
280 if (is_aa_path_mute(codec)) 300 if (is_aa_path_mute(codec))
@@ -390,62 +410,62 @@ static int bind_pin_switch_put(struct snd_kcontrol *kcontrol,
390 .put = bind_pin_switch_put, \ 410 .put = bind_pin_switch_put, \
391 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) } 411 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
392 412
393static struct snd_kcontrol_new via_control_templates[] = { 413static const struct snd_kcontrol_new via_control_templates[] = {
394 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 414 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
395 HDA_CODEC_MUTE(NULL, 0, 0, 0), 415 HDA_CODEC_MUTE(NULL, 0, 0, 0),
396 ANALOG_INPUT_MUTE, 416 ANALOG_INPUT_MUTE,
397 BIND_PIN_MUTE, 417 BIND_PIN_MUTE,
398}; 418};
399 419
400static hda_nid_t vt1708_adc_nids[2] = { 420static const hda_nid_t vt1708_adc_nids[2] = {
401 /* ADC1-2 */ 421 /* ADC1-2 */
402 0x15, 0x27 422 0x15, 0x27
403}; 423};
404 424
405static hda_nid_t vt1709_adc_nids[3] = { 425static const hda_nid_t vt1709_adc_nids[3] = {
406 /* ADC1-2 */ 426 /* ADC1-2 */
407 0x14, 0x15, 0x16 427 0x14, 0x15, 0x16
408}; 428};
409 429
410static hda_nid_t vt1708B_adc_nids[2] = { 430static const hda_nid_t vt1708B_adc_nids[2] = {
411 /* ADC1-2 */ 431 /* ADC1-2 */
412 0x13, 0x14 432 0x13, 0x14
413}; 433};
414 434
415static hda_nid_t vt1708S_adc_nids[2] = { 435static const hda_nid_t vt1708S_adc_nids[2] = {
416 /* ADC1-2 */ 436 /* ADC1-2 */
417 0x13, 0x14 437 0x13, 0x14
418}; 438};
419 439
420static hda_nid_t vt1702_adc_nids[3] = { 440static const hda_nid_t vt1702_adc_nids[3] = {
421 /* ADC1-2 */ 441 /* ADC1-2 */
422 0x12, 0x20, 0x1F 442 0x12, 0x20, 0x1F
423}; 443};
424 444
425static hda_nid_t vt1718S_adc_nids[2] = { 445static const hda_nid_t vt1718S_adc_nids[2] = {
426 /* ADC1-2 */ 446 /* ADC1-2 */
427 0x10, 0x11 447 0x10, 0x11
428}; 448};
429 449
430static hda_nid_t vt1716S_adc_nids[2] = { 450static const hda_nid_t vt1716S_adc_nids[2] = {
431 /* ADC1-2 */ 451 /* ADC1-2 */
432 0x13, 0x14 452 0x13, 0x14
433}; 453};
434 454
435static hda_nid_t vt2002P_adc_nids[2] = { 455static const hda_nid_t vt2002P_adc_nids[2] = {
436 /* ADC1-2 */ 456 /* ADC1-2 */
437 0x10, 0x11 457 0x10, 0x11
438}; 458};
439 459
440static hda_nid_t vt1812_adc_nids[2] = { 460static const hda_nid_t vt1812_adc_nids[2] = {
441 /* ADC1-2 */ 461 /* ADC1-2 */
442 0x10, 0x11 462 0x10, 0x11
443}; 463};
444 464
445 465
446/* add dynamic controls */ 466/* add dynamic controls */
447static int via_add_control(struct via_spec *spec, int type, const char *name, 467static int __via_add_control(struct via_spec *spec, int type, const char *name,
448 unsigned long val) 468 int idx, unsigned long val)
449{ 469{
450 struct snd_kcontrol_new *knew; 470 struct snd_kcontrol_new *knew;
451 471
@@ -463,8 +483,11 @@ static int via_add_control(struct via_spec *spec, int type, const char *name,
463 return 0; 483 return 0;
464} 484}
465 485
486#define via_add_control(spec, type, name, val) \
487 __via_add_control(spec, type, name, 0, val)
488
466static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, 489static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
467 struct snd_kcontrol_new *tmpl) 490 const struct snd_kcontrol_new *tmpl)
468{ 491{
469 struct snd_kcontrol_new *knew; 492 struct snd_kcontrol_new *knew;
470 493
@@ -494,18 +517,18 @@ static void via_free_kctls(struct hda_codec *codec)
494 517
495/* create input playback/capture controls for the given pin */ 518/* create input playback/capture controls for the given pin */
496static int via_new_analog_input(struct via_spec *spec, const char *ctlname, 519static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
497 int idx, int mix_nid) 520 int type_idx, int idx, int mix_nid)
498{ 521{
499 char name[32]; 522 char name[32];
500 int err; 523 int err;
501 524
502 sprintf(name, "%s Playback Volume", ctlname); 525 sprintf(name, "%s Playback Volume", ctlname);
503 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 526 err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
504 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 527 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
505 if (err < 0) 528 if (err < 0)
506 return err; 529 return err;
507 sprintf(name, "%s Playback Switch", ctlname); 530 sprintf(name, "%s Playback Switch", ctlname);
508 err = via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name, 531 err = __via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name, type_idx,
509 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 532 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
510 if (err < 0) 533 if (err < 0)
511 return err; 534 return err;
@@ -557,17 +580,15 @@ static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
557static void via_auto_init_analog_input(struct hda_codec *codec) 580static void via_auto_init_analog_input(struct hda_codec *codec)
558{ 581{
559 struct via_spec *spec = codec->spec; 582 struct via_spec *spec = codec->spec;
583 const struct auto_pin_cfg *cfg = &spec->autocfg;
560 unsigned int ctl; 584 unsigned int ctl;
561 int i; 585 int i;
562 586
563 for (i = 0; i < AUTO_PIN_LAST; i++) { 587 for (i = 0; i < cfg->num_inputs; i++) {
564 hda_nid_t nid = spec->autocfg.input_pins[i]; 588 hda_nid_t nid = cfg->inputs[i].pin;
565 if (!nid)
566 continue;
567
568 if (spec->smart51_enabled && is_smart51_pins(spec, nid)) 589 if (spec->smart51_enabled && is_smart51_pins(spec, nid))
569 ctl = PIN_OUT; 590 ctl = PIN_OUT;
570 else if (i <= AUTO_PIN_FRONT_MIC) 591 else if (cfg->inputs[i].type == AUTO_PIN_MIC)
571 ctl = PIN_VREF50; 592 ctl = PIN_VREF50;
572 else 593 else
573 ctl = PIN_IN; 594 ctl = PIN_IN;
@@ -597,482 +618,6 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
597 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); 618 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
598} 619}
599 620
600static void set_jack_power_state(struct hda_codec *codec)
601{
602 struct via_spec *spec = codec->spec;
603 int imux_is_smixer;
604 unsigned int parm;
605
606 if (spec->codec_type == VT1702) {
607 imux_is_smixer = snd_hda_codec_read(
608 codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
609 /* inputs */
610 /* PW 1/2/5 (14h/15h/18h) */
611 parm = AC_PWRST_D3;
612 set_pin_power_state(codec, 0x14, &parm);
613 set_pin_power_state(codec, 0x15, &parm);
614 set_pin_power_state(codec, 0x18, &parm);
615 if (imux_is_smixer)
616 parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */
617 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
618 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
619 parm);
620 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE,
621 parm);
622 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
623 parm);
624 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE,
625 parm);
626
627 /* outputs */
628 /* PW 3/4 (16h/17h) */
629 parm = AC_PWRST_D3;
630 set_pin_power_state(codec, 0x16, &parm);
631 set_pin_power_state(codec, 0x17, &parm);
632 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
633 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
634 imux_is_smixer ? AC_PWRST_D0 : parm);
635 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
636 parm);
637 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE,
638 parm);
639 } else if (spec->codec_type == VT1708B_8CH
640 || spec->codec_type == VT1708B_4CH
641 || spec->codec_type == VT1708S) {
642 /* SW0 (17h) = stereo mixer */
643 int is_8ch = spec->codec_type != VT1708B_4CH;
644 imux_is_smixer = snd_hda_codec_read(
645 codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
646 == ((spec->codec_type == VT1708S) ? 5 : 0);
647 /* inputs */
648 /* PW 1/2/5 (1ah/1bh/1eh) */
649 parm = AC_PWRST_D3;
650 set_pin_power_state(codec, 0x1a, &parm);
651 set_pin_power_state(codec, 0x1b, &parm);
652 set_pin_power_state(codec, 0x1e, &parm);
653 if (imux_is_smixer)
654 parm = AC_PWRST_D0;
655 /* SW0 (17h), AIW 0/1 (13h/14h) */
656 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
657 parm);
658 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
659 parm);
660 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
661 parm);
662
663 /* outputs */
664 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
665 parm = AC_PWRST_D3;
666 set_pin_power_state(codec, 0x19, &parm);
667 if (spec->smart51_enabled)
668 parm = AC_PWRST_D0;
669 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
670 parm);
671 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
672 parm);
673
674 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
675 if (is_8ch) {
676 parm = AC_PWRST_D3;
677 set_pin_power_state(codec, 0x22, &parm);
678 if (spec->smart51_enabled)
679 parm = AC_PWRST_D0;
680 snd_hda_codec_write(codec, 0x26, 0,
681 AC_VERB_SET_POWER_STATE, parm);
682 snd_hda_codec_write(codec, 0x24, 0,
683 AC_VERB_SET_POWER_STATE, parm);
684 }
685
686 /* PW 3/4/7 (1ch/1dh/23h) */
687 parm = AC_PWRST_D3;
688 /* force to D0 for internal Speaker */
689 set_pin_power_state(codec, 0x1c, &parm);
690 set_pin_power_state(codec, 0x1d, &parm);
691 if (is_8ch)
692 set_pin_power_state(codec, 0x23, &parm);
693 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
694 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
695 imux_is_smixer ? AC_PWRST_D0 : parm);
696 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
697 parm);
698 if (is_8ch) {
699 snd_hda_codec_write(codec, 0x25, 0,
700 AC_VERB_SET_POWER_STATE, parm);
701 snd_hda_codec_write(codec, 0x27, 0,
702 AC_VERB_SET_POWER_STATE, parm);
703 }
704 } else if (spec->codec_type == VT1718S) {
705 /* MUX6 (1eh) = stereo mixer */
706 imux_is_smixer = snd_hda_codec_read(
707 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
708 /* inputs */
709 /* PW 5/6/7 (29h/2ah/2bh) */
710 parm = AC_PWRST_D3;
711 set_pin_power_state(codec, 0x29, &parm);
712 set_pin_power_state(codec, 0x2a, &parm);
713 set_pin_power_state(codec, 0x2b, &parm);
714 if (imux_is_smixer)
715 parm = AC_PWRST_D0;
716 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
717 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE,
718 parm);
719 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
720 parm);
721 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
722 parm);
723 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
724 parm);
725
726 /* outputs */
727 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
728 parm = AC_PWRST_D3;
729 set_pin_power_state(codec, 0x27, &parm);
730 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
731 parm);
732 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE,
733 parm);
734
735 /* PW2 (26h), AOW2 (ah) */
736 parm = AC_PWRST_D3;
737 set_pin_power_state(codec, 0x26, &parm);
738 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE,
739 parm);
740
741 /* PW0/1 (24h/25h) */
742 parm = AC_PWRST_D3;
743 set_pin_power_state(codec, 0x24, &parm);
744 set_pin_power_state(codec, 0x25, &parm);
745 if (!spec->hp_independent_mode) /* check for redirected HP */
746 set_pin_power_state(codec, 0x28, &parm);
747 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE,
748 parm);
749 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE,
750 parm);
751 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
752 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
753 imux_is_smixer ? AC_PWRST_D0 : parm);
754 if (spec->hp_independent_mode) {
755 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
756 parm = AC_PWRST_D3;
757 set_pin_power_state(codec, 0x28, &parm);
758 snd_hda_codec_write(codec, 0x1b, 0,
759 AC_VERB_SET_POWER_STATE, parm);
760 snd_hda_codec_write(codec, 0x34, 0,
761 AC_VERB_SET_POWER_STATE, parm);
762 snd_hda_codec_write(codec, 0xc, 0,
763 AC_VERB_SET_POWER_STATE, parm);
764 }
765 } else if (spec->codec_type == VT1716S) {
766 unsigned int mono_out, present;
767 /* SW0 (17h) = stereo mixer */
768 imux_is_smixer = snd_hda_codec_read(
769 codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
770 /* inputs */
771 /* PW 1/2/5 (1ah/1bh/1eh) */
772 parm = AC_PWRST_D3;
773 set_pin_power_state(codec, 0x1a, &parm);
774 set_pin_power_state(codec, 0x1b, &parm);
775 set_pin_power_state(codec, 0x1e, &parm);
776 if (imux_is_smixer)
777 parm = AC_PWRST_D0;
778 /* SW0 (17h), AIW0(13h) */
779 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
780 parm);
781 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
782 parm);
783
784 parm = AC_PWRST_D3;
785 set_pin_power_state(codec, 0x1e, &parm);
786 /* PW11 (22h) */
787 if (spec->dmic_enabled)
788 set_pin_power_state(codec, 0x22, &parm);
789 else
790 snd_hda_codec_write(
791 codec, 0x22, 0,
792 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
793
794 /* SW2(26h), AIW1(14h) */
795 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE,
796 parm);
797 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
798 parm);
799
800 /* outputs */
801 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
802 parm = AC_PWRST_D3;
803 set_pin_power_state(codec, 0x19, &parm);
804 /* Smart 5.1 PW2(1bh) */
805 if (spec->smart51_enabled)
806 set_pin_power_state(codec, 0x1b, &parm);
807 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
808 parm);
809 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
810 parm);
811
812 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
813 parm = AC_PWRST_D3;
814 set_pin_power_state(codec, 0x23, &parm);
815 /* Smart 5.1 PW1(1ah) */
816 if (spec->smart51_enabled)
817 set_pin_power_state(codec, 0x1a, &parm);
818 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE,
819 parm);
820
821 /* Smart 5.1 PW5(1eh) */
822 if (spec->smart51_enabled)
823 set_pin_power_state(codec, 0x1e, &parm);
824 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE,
825 parm);
826
827 /* Mono out */
828 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
829 present = snd_hda_jack_detect(codec, 0x1c);
830 if (present)
831 mono_out = 0;
832 else {
833 present = snd_hda_jack_detect(codec, 0x1d);
834 if (!spec->hp_independent_mode && present)
835 mono_out = 0;
836 else
837 mono_out = 1;
838 }
839 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
840 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE,
841 parm);
842 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE,
843 parm);
844 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE,
845 parm);
846
847 /* PW 3/4 (1ch/1dh) */
848 parm = AC_PWRST_D3;
849 set_pin_power_state(codec, 0x1c, &parm);
850 set_pin_power_state(codec, 0x1d, &parm);
851 /* HP Independent Mode, power on AOW3 */
852 if (spec->hp_independent_mode)
853 snd_hda_codec_write(codec, 0x25, 0,
854 AC_VERB_SET_POWER_STATE, parm);
855
856 /* force to D0 for internal Speaker */
857 /* MW0 (16h), AOW0 (10h) */
858 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
859 imux_is_smixer ? AC_PWRST_D0 : parm);
860 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
861 mono_out ? AC_PWRST_D0 : parm);
862 } else if (spec->codec_type == VT2002P) {
863 unsigned int present;
864 /* MUX9 (1eh) = stereo mixer */
865 imux_is_smixer = snd_hda_codec_read(
866 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
867 /* inputs */
868 /* PW 5/6/7 (29h/2ah/2bh) */
869 parm = AC_PWRST_D3;
870 set_pin_power_state(codec, 0x29, &parm);
871 set_pin_power_state(codec, 0x2a, &parm);
872 set_pin_power_state(codec, 0x2b, &parm);
873 if (imux_is_smixer)
874 parm = AC_PWRST_D0;
875 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
876 snd_hda_codec_write(codec, 0x1e, 0,
877 AC_VERB_SET_POWER_STATE, parm);
878 snd_hda_codec_write(codec, 0x1f, 0,
879 AC_VERB_SET_POWER_STATE, parm);
880 snd_hda_codec_write(codec, 0x10, 0,
881 AC_VERB_SET_POWER_STATE, parm);
882 snd_hda_codec_write(codec, 0x11, 0,
883 AC_VERB_SET_POWER_STATE, parm);
884
885 /* outputs */
886 /* AOW0 (8h)*/
887 snd_hda_codec_write(codec, 0x8, 0,
888 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
889
890 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
891 parm = AC_PWRST_D3;
892 set_pin_power_state(codec, 0x26, &parm);
893 snd_hda_codec_write(codec, 0x1c, 0,
894 AC_VERB_SET_POWER_STATE, parm);
895 snd_hda_codec_write(codec, 0x37,
896 0, AC_VERB_SET_POWER_STATE, parm);
897
898 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
899 parm = AC_PWRST_D3;
900 set_pin_power_state(codec, 0x25, &parm);
901 snd_hda_codec_write(codec, 0x19, 0,
902 AC_VERB_SET_POWER_STATE, parm);
903 snd_hda_codec_write(codec, 0x35, 0,
904 AC_VERB_SET_POWER_STATE, parm);
905 if (spec->hp_independent_mode) {
906 snd_hda_codec_write(codec, 0x9, 0,
907 AC_VERB_SET_POWER_STATE, parm);
908 }
909
910 /* Class-D */
911 /* PW0 (24h), MW0(18h), MUX0(34h) */
912 present = snd_hda_jack_detect(codec, 0x25);
913 parm = AC_PWRST_D3;
914 set_pin_power_state(codec, 0x24, &parm);
915 if (present) {
916 snd_hda_codec_write(
917 codec, 0x18, 0,
918 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
919 snd_hda_codec_write(
920 codec, 0x34, 0,
921 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
922 } else {
923 snd_hda_codec_write(
924 codec, 0x18, 0,
925 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
926 snd_hda_codec_write(
927 codec, 0x34, 0,
928 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
929 }
930
931 /* Mono Out */
932 /* PW15 (31h), MW8(17h), MUX8(3bh) */
933 present = snd_hda_jack_detect(codec, 0x26);
934 parm = AC_PWRST_D3;
935 set_pin_power_state(codec, 0x31, &parm);
936 if (present) {
937 snd_hda_codec_write(
938 codec, 0x17, 0,
939 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
940 snd_hda_codec_write(
941 codec, 0x3b, 0,
942 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
943 } else {
944 snd_hda_codec_write(
945 codec, 0x17, 0,
946 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
947 snd_hda_codec_write(
948 codec, 0x3b, 0,
949 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
950 }
951
952 /* MW9 (21h) */
953 if (imux_is_smixer || !is_aa_path_mute(codec))
954 snd_hda_codec_write(
955 codec, 0x21, 0,
956 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
957 else
958 snd_hda_codec_write(
959 codec, 0x21, 0,
960 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
961 } else if (spec->codec_type == VT1812) {
962 unsigned int present;
963 /* MUX10 (1eh) = stereo mixer */
964 imux_is_smixer = snd_hda_codec_read(
965 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
966 /* inputs */
967 /* PW 5/6/7 (29h/2ah/2bh) */
968 parm = AC_PWRST_D3;
969 set_pin_power_state(codec, 0x29, &parm);
970 set_pin_power_state(codec, 0x2a, &parm);
971 set_pin_power_state(codec, 0x2b, &parm);
972 if (imux_is_smixer)
973 parm = AC_PWRST_D0;
974 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
975 snd_hda_codec_write(codec, 0x1e, 0,
976 AC_VERB_SET_POWER_STATE, parm);
977 snd_hda_codec_write(codec, 0x1f, 0,
978 AC_VERB_SET_POWER_STATE, parm);
979 snd_hda_codec_write(codec, 0x10, 0,
980 AC_VERB_SET_POWER_STATE, parm);
981 snd_hda_codec_write(codec, 0x11, 0,
982 AC_VERB_SET_POWER_STATE, parm);
983
984 /* outputs */
985 /* AOW0 (8h)*/
986 snd_hda_codec_write(codec, 0x8, 0,
987 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
988
989 /* PW4 (28h), MW4 (18h), MUX4(38h) */
990 parm = AC_PWRST_D3;
991 set_pin_power_state(codec, 0x28, &parm);
992 snd_hda_codec_write(codec, 0x18, 0,
993 AC_VERB_SET_POWER_STATE, parm);
994 snd_hda_codec_write(codec, 0x38, 0,
995 AC_VERB_SET_POWER_STATE, parm);
996
997 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
998 parm = AC_PWRST_D3;
999 set_pin_power_state(codec, 0x25, &parm);
1000 snd_hda_codec_write(codec, 0x15, 0,
1001 AC_VERB_SET_POWER_STATE, parm);
1002 snd_hda_codec_write(codec, 0x35, 0,
1003 AC_VERB_SET_POWER_STATE, parm);
1004 if (spec->hp_independent_mode) {
1005 snd_hda_codec_write(codec, 0x9, 0,
1006 AC_VERB_SET_POWER_STATE, parm);
1007 }
1008
1009 /* Internal Speaker */
1010 /* PW0 (24h), MW0(14h), MUX0(34h) */
1011 present = snd_hda_jack_detect(codec, 0x25);
1012 parm = AC_PWRST_D3;
1013 set_pin_power_state(codec, 0x24, &parm);
1014 if (present) {
1015 snd_hda_codec_write(codec, 0x14, 0,
1016 AC_VERB_SET_POWER_STATE,
1017 AC_PWRST_D3);
1018 snd_hda_codec_write(codec, 0x34, 0,
1019 AC_VERB_SET_POWER_STATE,
1020 AC_PWRST_D3);
1021 } else {
1022 snd_hda_codec_write(codec, 0x14, 0,
1023 AC_VERB_SET_POWER_STATE,
1024 AC_PWRST_D0);
1025 snd_hda_codec_write(codec, 0x34, 0,
1026 AC_VERB_SET_POWER_STATE,
1027 AC_PWRST_D0);
1028 }
1029 /* Mono Out */
1030 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
1031 present = snd_hda_jack_detect(codec, 0x28);
1032 parm = AC_PWRST_D3;
1033 set_pin_power_state(codec, 0x31, &parm);
1034 if (present) {
1035 snd_hda_codec_write(codec, 0x1c, 0,
1036 AC_VERB_SET_POWER_STATE,
1037 AC_PWRST_D3);
1038 snd_hda_codec_write(codec, 0x3c, 0,
1039 AC_VERB_SET_POWER_STATE,
1040 AC_PWRST_D3);
1041 snd_hda_codec_write(codec, 0x3e, 0,
1042 AC_VERB_SET_POWER_STATE,
1043 AC_PWRST_D3);
1044 } else {
1045 snd_hda_codec_write(codec, 0x1c, 0,
1046 AC_VERB_SET_POWER_STATE,
1047 AC_PWRST_D0);
1048 snd_hda_codec_write(codec, 0x3c, 0,
1049 AC_VERB_SET_POWER_STATE,
1050 AC_PWRST_D0);
1051 snd_hda_codec_write(codec, 0x3e, 0,
1052 AC_VERB_SET_POWER_STATE,
1053 AC_PWRST_D0);
1054 }
1055
1056 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
1057 parm = AC_PWRST_D3;
1058 set_pin_power_state(codec, 0x33, &parm);
1059 snd_hda_codec_write(codec, 0x1d, 0,
1060 AC_VERB_SET_POWER_STATE, parm);
1061 snd_hda_codec_write(codec, 0x3d, 0,
1062 AC_VERB_SET_POWER_STATE, parm);
1063
1064 /* MW9 (21h) */
1065 if (imux_is_smixer || !is_aa_path_mute(codec))
1066 snd_hda_codec_write(
1067 codec, 0x21, 0,
1068 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1069 else
1070 snd_hda_codec_write(
1071 codec, 0x21, 0,
1072 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1073 }
1074}
1075
1076/* 621/*
1077 * input MUX handling 622 * input MUX handling
1078 */ 623 */
@@ -1101,6 +646,7 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
1101 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1102 struct via_spec *spec = codec->spec; 647 struct via_spec *spec = codec->spec;
1103 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 648 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
649 int ret;
1104 650
1105 if (!spec->mux_nids[adc_idx]) 651 if (!spec->mux_nids[adc_idx])
1106 return -EINVAL; 652 return -EINVAL;
@@ -1109,12 +655,14 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
1109 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0) 655 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
1110 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0, 656 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
1111 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 657 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1112 /* update jack power state */
1113 set_jack_power_state(codec);
1114 658
1115 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 659 ret = snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
1116 spec->mux_nids[adc_idx], 660 spec->mux_nids[adc_idx],
1117 &spec->cur_mux[adc_idx]); 661 &spec->cur_mux[adc_idx]);
662 /* update jack power state */
663 set_widgets_power_state(codec);
664
665 return ret;
1118} 666}
1119 667
1120static int via_independent_hp_info(struct snd_kcontrol *kcontrol, 668static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
@@ -1160,6 +708,9 @@ static hda_nid_t side_mute_channel(struct via_spec *spec)
1160 case VT1709_10CH: return 0x29; 708 case VT1709_10CH: return 0x29;
1161 case VT1708B_8CH: /* fall thru */ 709 case VT1708B_8CH: /* fall thru */
1162 case VT1708S: return 0x27; 710 case VT1708S: return 0x27;
711 case VT2002P: return 0x19;
712 case VT1802: return 0x15;
713 case VT1812: return 0x15;
1163 default: return 0; 714 default: return 0;
1164 } 715 }
1165} 716}
@@ -1168,13 +719,22 @@ static int update_side_mute_status(struct hda_codec *codec)
1168{ 719{
1169 /* mute side channel */ 720 /* mute side channel */
1170 struct via_spec *spec = codec->spec; 721 struct via_spec *spec = codec->spec;
1171 unsigned int parm = spec->hp_independent_mode 722 unsigned int parm;
1172 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
1173 hda_nid_t sw3 = side_mute_channel(spec); 723 hda_nid_t sw3 = side_mute_channel(spec);
1174 724
1175 if (sw3) 725 if (sw3) {
1176 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE, 726 if (VT2002P_COMPATIBLE(spec))
1177 parm); 727 parm = spec->hp_independent_mode ?
728 AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1);
729 else
730 parm = spec->hp_independent_mode ?
731 AMP_OUT_MUTE : AMP_OUT_UNMUTE;
732 snd_hda_codec_write(codec, sw3, 0,
733 AC_VERB_SET_AMP_GAIN_MUTE, parm);
734 if (spec->codec_type == VT1812)
735 snd_hda_codec_write(codec, 0x1d, 0,
736 AC_VERB_SET_AMP_GAIN_MUTE, parm);
737 }
1178 return 0; 738 return 0;
1179} 739}
1180 740
@@ -1185,11 +745,30 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1185 struct via_spec *spec = codec->spec; 745 struct via_spec *spec = codec->spec;
1186 hda_nid_t nid = kcontrol->private_value; 746 hda_nid_t nid = kcontrol->private_value;
1187 unsigned int pinsel = ucontrol->value.enumerated.item[0]; 747 unsigned int pinsel = ucontrol->value.enumerated.item[0];
748 unsigned int parm0, parm1;
1188 /* Get Independent Mode index of headphone pin widget */ 749 /* Get Independent Mode index of headphone pin widget */
1189 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel 750 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
1190 ? 1 : 0; 751 ? 1 : 0;
1191 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel); 752 if (spec->codec_type == VT1718S) {
753 snd_hda_codec_write(codec, nid, 0,
754 AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0);
755 /* Set correct mute switch for MW3 */
756 parm0 = spec->hp_independent_mode ?
757 AMP_IN_UNMUTE(0) : AMP_IN_MUTE(0);
758 parm1 = spec->hp_independent_mode ?
759 AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1);
760 snd_hda_codec_write(codec, 0x1b, 0,
761 AC_VERB_SET_AMP_GAIN_MUTE, parm0);
762 snd_hda_codec_write(codec, 0x1b, 0,
763 AC_VERB_SET_AMP_GAIN_MUTE, parm1);
764 }
765 else
766 snd_hda_codec_write(codec, nid, 0,
767 AC_VERB_SET_CONNECT_SEL, pinsel);
1192 768
769 if (spec->codec_type == VT1812)
770 snd_hda_codec_write(codec, 0x35, 0,
771 AC_VERB_SET_CONNECT_SEL, pinsel);
1193 if (spec->multiout.hp_nid && spec->multiout.hp_nid 772 if (spec->multiout.hp_nid && spec->multiout.hp_nid
1194 != spec->multiout.dac_nids[HDA_FRONT]) 773 != spec->multiout.dac_nids[HDA_FRONT])
1195 snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid, 774 snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid,
@@ -1201,17 +780,18 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1201 || spec->codec_type == VT1702 780 || spec->codec_type == VT1702
1202 || spec->codec_type == VT1718S 781 || spec->codec_type == VT1718S
1203 || spec->codec_type == VT1716S 782 || spec->codec_type == VT1716S
1204 || spec->codec_type == VT2002P 783 || VT2002P_COMPATIBLE(spec)) {
1205 || spec->codec_type == VT1812) {
1206 activate_ctl(codec, "Headphone Playback Volume", 784 activate_ctl(codec, "Headphone Playback Volume",
1207 spec->hp_independent_mode); 785 spec->hp_independent_mode);
1208 activate_ctl(codec, "Headphone Playback Switch", 786 activate_ctl(codec, "Headphone Playback Switch",
1209 spec->hp_independent_mode); 787 spec->hp_independent_mode);
1210 } 788 }
789 /* update jack power state */
790 set_widgets_power_state(codec);
1211 return 0; 791 return 0;
1212} 792}
1213 793
1214static struct snd_kcontrol_new via_hp_mixer[2] = { 794static const struct snd_kcontrol_new via_hp_mixer[2] = {
1215 { 795 {
1216 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 796 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1217 .name = "Independent HP", 797 .name = "Independent HP",
@@ -1238,6 +818,7 @@ static int via_hp_build(struct hda_codec *codec)
1238 nid = 0x34; 818 nid = 0x34;
1239 break; 819 break;
1240 case VT2002P: 820 case VT2002P:
821 case VT1802:
1241 nid = 0x35; 822 nid = 0x35;
1242 break; 823 break;
1243 case VT1812: 824 case VT1812:
@@ -1248,9 +829,12 @@ static int via_hp_build(struct hda_codec *codec)
1248 break; 829 break;
1249 } 830 }
1250 831
1251 nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS); 832 if (spec->codec_type != VT1708) {
1252 if (nums <= 1) 833 nums = snd_hda_get_connections(codec, nid,
1253 return 0; 834 conn, HDA_MAX_CONNECTIONS);
835 if (nums <= 1)
836 return 0;
837 }
1254 838
1255 knew = via_clone_control(spec, &via_hp_mixer[0]); 839 knew = via_clone_control(spec, &via_hp_mixer[0]);
1256 if (knew == NULL) 840 if (knew == NULL)
@@ -1259,10 +843,13 @@ static int via_hp_build(struct hda_codec *codec)
1259 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; 843 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
1260 knew->private_value = nid; 844 knew->private_value = nid;
1261 845
1262 knew = via_clone_control(spec, &via_hp_mixer[1]); 846 nid = side_mute_channel(spec);
1263 if (knew == NULL) 847 if (nid) {
1264 return -ENOMEM; 848 knew = via_clone_control(spec, &via_hp_mixer[1]);
1265 knew->subdevice = side_mute_channel(spec); 849 if (knew == NULL)
850 return -ENOMEM;
851 knew->subdevice = nid;
852 }
1266 853
1267 return 0; 854 return 0;
1268} 855}
@@ -1271,14 +858,18 @@ static void notify_aa_path_ctls(struct hda_codec *codec)
1271{ 858{
1272 int i; 859 int i;
1273 struct snd_ctl_elem_id id; 860 struct snd_ctl_elem_id id;
1274 const char *labels[] = {"Mic", "Front Mic", "Line"}; 861 const char *labels[] = {"Mic", "Front Mic", "Line", "Rear Mic"};
862 struct snd_kcontrol *ctl;
1275 863
1276 memset(&id, 0, sizeof(id)); 864 memset(&id, 0, sizeof(id));
1277 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 865 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1278 for (i = 0; i < ARRAY_SIZE(labels); i++) { 866 for (i = 0; i < ARRAY_SIZE(labels); i++) {
1279 sprintf(id.name, "%s Playback Volume", labels[i]); 867 sprintf(id.name, "%s Playback Volume", labels[i]);
1280 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE, 868 ctl = snd_hda_find_mixer_ctl(codec, id.name);
1281 &id); 869 if (ctl)
870 snd_ctl_notify(codec->bus->card,
871 SNDRV_CTL_EVENT_MASK_VALUE,
872 &ctl->id);
1282 } 873 }
1283} 874}
1284 875
@@ -1310,6 +901,11 @@ static void mute_aa_path(struct hda_codec *codec, int mute)
1310 start_idx = 2; 901 start_idx = 2;
1311 end_idx = 4; 902 end_idx = 4;
1312 break; 903 break;
904 case VT1718S:
905 nid_mixer = 0x21;
906 start_idx = 1;
907 end_idx = 3;
908 break;
1313 default: 909 default:
1314 return; 910 return;
1315 } 911 }
@@ -1322,15 +918,14 @@ static void mute_aa_path(struct hda_codec *codec, int mute)
1322} 918}
1323static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin) 919static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin)
1324{ 920{
1325 int res = 0; 921 const struct auto_pin_cfg *cfg = &spec->autocfg;
1326 int index; 922 int i;
1327 for (index = AUTO_PIN_MIC; index < AUTO_PIN_FRONT_LINE; index++) { 923
1328 if (pin == spec->autocfg.input_pins[index]) { 924 for (i = 0; i < cfg->num_inputs; i++) {
1329 res = 1; 925 if (pin == cfg->inputs[i].pin)
1330 break; 926 return cfg->inputs[i].type <= AUTO_PIN_LINE_IN;
1331 }
1332 } 927 }
1333 return res; 928 return 0;
1334} 929}
1335 930
1336static int via_smart51_info(struct snd_kcontrol *kcontrol, 931static int via_smart51_info(struct snd_kcontrol *kcontrol,
@@ -1348,25 +943,21 @@ static int via_smart51_get(struct snd_kcontrol *kcontrol,
1348{ 943{
1349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 944 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1350 struct via_spec *spec = codec->spec; 945 struct via_spec *spec = codec->spec;
1351 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE }; 946 const struct auto_pin_cfg *cfg = &spec->autocfg;
1352 int on = 1; 947 int on = 1;
1353 int i; 948 int i;
1354 949
1355 for (i = 0; i < ARRAY_SIZE(index); i++) { 950 for (i = 0; i < cfg->num_inputs; i++) {
1356 hda_nid_t nid = spec->autocfg.input_pins[index[i]]; 951 hda_nid_t nid = cfg->inputs[i].pin;
1357 if (nid) { 952 int ctl = snd_hda_codec_read(codec, nid, 0,
1358 int ctl = 953 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1359 snd_hda_codec_read(codec, nid, 0, 954 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1360 AC_VERB_GET_PIN_WIDGET_CONTROL, 955 continue;
1361 0); 956 if (cfg->inputs[i].type == AUTO_PIN_MIC &&
1362 if (i == AUTO_PIN_FRONT_MIC 957 spec->hp_independent_mode && spec->codec_type != VT1718S)
1363 && spec->hp_independent_mode 958 continue; /* ignore FMic for independent HP */
1364 && spec->codec_type != VT1718S) 959 if ((ctl & AC_PINCTL_IN_EN) && !(ctl & AC_PINCTL_OUT_EN))
1365 continue; /* ignore FMic for independent HP */ 960 on = 0;
1366 if (ctl & AC_PINCTL_IN_EN
1367 && !(ctl & AC_PINCTL_OUT_EN))
1368 on = 0;
1369 }
1370 } 961 }
1371 *ucontrol->value.integer.value = on; 962 *ucontrol->value.integer.value = on;
1372 return 0; 963 return 0;
@@ -1377,36 +968,38 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
1377{ 968{
1378 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 969 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1379 struct via_spec *spec = codec->spec; 970 struct via_spec *spec = codec->spec;
971 const struct auto_pin_cfg *cfg = &spec->autocfg;
1380 int out_in = *ucontrol->value.integer.value 972 int out_in = *ucontrol->value.integer.value
1381 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN; 973 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
1382 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1383 int i; 974 int i;
1384 975
1385 for (i = 0; i < ARRAY_SIZE(index); i++) { 976 for (i = 0; i < cfg->num_inputs; i++) {
1386 hda_nid_t nid = spec->autocfg.input_pins[index[i]]; 977 hda_nid_t nid = cfg->inputs[i].pin;
1387 if (i == AUTO_PIN_FRONT_MIC 978 unsigned int parm;
1388 && spec->hp_independent_mode 979
1389 && spec->codec_type != VT1718S) 980 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
981 continue;
982 if (cfg->inputs[i].type == AUTO_PIN_MIC &&
983 spec->hp_independent_mode && spec->codec_type != VT1718S)
1390 continue; /* don't retask FMic for independent HP */ 984 continue; /* don't retask FMic for independent HP */
1391 if (nid) { 985
1392 unsigned int parm = snd_hda_codec_read( 986 parm = snd_hda_codec_read(codec, nid, 0,
1393 codec, nid, 0, 987 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1394 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 988 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
1395 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); 989 parm |= out_in;
1396 parm |= out_in; 990 snd_hda_codec_write(codec, nid, 0,
1397 snd_hda_codec_write(codec, nid, 0, 991 AC_VERB_SET_PIN_WIDGET_CONTROL,
1398 AC_VERB_SET_PIN_WIDGET_CONTROL, 992 parm);
1399 parm); 993 if (out_in == AC_PINCTL_OUT_EN) {
1400 if (out_in == AC_PINCTL_OUT_EN) { 994 mute_aa_path(codec, 1);
1401 mute_aa_path(codec, 1); 995 notify_aa_path_ctls(codec);
1402 notify_aa_path_ctls(codec); 996 }
1403 } 997 if (spec->codec_type == VT1718S) {
1404 if (spec->codec_type == VT1718S) 998 snd_hda_codec_amp_stereo(
1405 snd_hda_codec_amp_stereo(
1406 codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE, 999 codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE,
1407 HDA_AMP_UNMUTE); 1000 HDA_AMP_UNMUTE);
1408 } 1001 }
1409 if (i == AUTO_PIN_FRONT_MIC) { 1002 if (cfg->inputs[i].type == AUTO_PIN_MIC) {
1410 if (spec->codec_type == VT1708S 1003 if (spec->codec_type == VT1708S
1411 || spec->codec_type == VT1716S) { 1004 || spec->codec_type == VT1716S) {
1412 /* input = index 1 (AOW3) */ 1005 /* input = index 1 (AOW3) */
@@ -1420,11 +1013,11 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
1420 } 1013 }
1421 } 1014 }
1422 spec->smart51_enabled = *ucontrol->value.integer.value; 1015 spec->smart51_enabled = *ucontrol->value.integer.value;
1423 set_jack_power_state(codec); 1016 set_widgets_power_state(codec);
1424 return 1; 1017 return 1;
1425} 1018}
1426 1019
1427static struct snd_kcontrol_new via_smart51_mixer[2] = { 1020static const struct snd_kcontrol_new via_smart51_mixer[2] = {
1428 { 1021 {
1429 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1022 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1430 .name = "Smart 5.1", 1023 .name = "Smart 5.1",
@@ -1442,21 +1035,27 @@ static struct snd_kcontrol_new via_smart51_mixer[2] = {
1442static int via_smart51_build(struct via_spec *spec) 1035static int via_smart51_build(struct via_spec *spec)
1443{ 1036{
1444 struct snd_kcontrol_new *knew; 1037 struct snd_kcontrol_new *knew;
1445 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE }; 1038 const struct auto_pin_cfg *cfg = &spec->autocfg;
1446 hda_nid_t nid; 1039 hda_nid_t nid;
1447 int i; 1040 int i;
1448 1041
1042 if (!cfg)
1043 return 0;
1044 if (cfg->line_outs > 2)
1045 return 0;
1046
1449 knew = via_clone_control(spec, &via_smart51_mixer[0]); 1047 knew = via_clone_control(spec, &via_smart51_mixer[0]);
1450 if (knew == NULL) 1048 if (knew == NULL)
1451 return -ENOMEM; 1049 return -ENOMEM;
1452 1050
1453 for (i = 0; i < ARRAY_SIZE(index); i++) { 1051 for (i = 0; i < cfg->num_inputs; i++) {
1454 nid = spec->autocfg.input_pins[index[i]]; 1052 nid = cfg->inputs[i].pin;
1455 if (nid) { 1053 if (cfg->inputs[i].type <= AUTO_PIN_LINE_IN) {
1456 knew = via_clone_control(spec, &via_smart51_mixer[1]); 1054 knew = via_clone_control(spec, &via_smart51_mixer[1]);
1457 if (knew == NULL) 1055 if (knew == NULL)
1458 return -ENOMEM; 1056 return -ENOMEM;
1459 knew->subdevice = nid; 1057 knew->subdevice = nid;
1058 break;
1460 } 1059 }
1461 } 1060 }
1462 1061
@@ -1464,7 +1063,7 @@ static int via_smart51_build(struct via_spec *spec)
1464} 1063}
1465 1064
1466/* capture mixer elements */ 1065/* capture mixer elements */
1467static struct snd_kcontrol_new vt1708_capture_mixer[] = { 1066static const struct snd_kcontrol_new vt1708_capture_mixer[] = {
1468 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), 1067 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
1469 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT), 1068 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
1470 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT), 1069 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
@@ -1515,6 +1114,7 @@ static int is_aa_path_mute(struct hda_codec *codec)
1515 break; 1114 break;
1516 case VT2002P: 1115 case VT2002P:
1517 case VT1812: 1116 case VT1812:
1117 case VT1802:
1518 nid_mixer = 0x21; 1118 nid_mixer = 0x21;
1519 start_idx = 0; 1119 start_idx = 0;
1520 end_idx = 2; 1120 end_idx = 2;
@@ -1579,6 +1179,7 @@ static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1579 break; 1179 break;
1580 case VT2002P: 1180 case VT2002P:
1581 case VT1812: 1181 case VT1812:
1182 case VT1802:
1582 verb = 0xf93; 1183 verb = 0xf93;
1583 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */ 1184 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
1584 break; 1185 break;
@@ -1592,7 +1193,7 @@ static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1592/* 1193/*
1593 * generic initialization of ADC, input mixers and output mixers 1194 * generic initialization of ADC, input mixers and output mixers
1594 */ 1195 */
1595static struct hda_verb vt1708_volume_init_verbs[] = { 1196static const struct hda_verb vt1708_volume_init_verbs[] = {
1596 /* 1197 /*
1597 * Unmute ADC0-1 and set the default input to mic-in 1198 * Unmute ADC0-1 and set the default input to mic-in
1598 */ 1199 */
@@ -1622,6 +1223,8 @@ static struct hda_verb vt1708_volume_init_verbs[] = {
1622 {0x20, AC_VERB_SET_CONNECT_SEL, 0}, 1223 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1623 /* PW9 Output enable */ 1224 /* PW9 Output enable */
1624 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 1225 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1226 /* power down jack detect function */
1227 {0x1, 0xf81, 0x1},
1625 { } 1228 { }
1626}; 1229};
1627 1230
@@ -1644,7 +1247,7 @@ static void playback_multi_pcm_prep_0(struct hda_codec *codec,
1644{ 1247{
1645 struct via_spec *spec = codec->spec; 1248 struct via_spec *spec = codec->spec;
1646 struct hda_multi_out *mout = &spec->multiout; 1249 struct hda_multi_out *mout = &spec->multiout;
1647 hda_nid_t *nids = mout->dac_nids; 1250 const hda_nid_t *nids = mout->dac_nids;
1648 int chs = substream->runtime->channels; 1251 int chs = substream->runtime->channels;
1649 int i; 1252 int i;
1650 1253
@@ -1713,7 +1316,7 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1713{ 1316{
1714 struct via_spec *spec = codec->spec; 1317 struct via_spec *spec = codec->spec;
1715 struct hda_multi_out *mout = &spec->multiout; 1318 struct hda_multi_out *mout = &spec->multiout;
1716 hda_nid_t *nids = mout->dac_nids; 1319 const hda_nid_t *nids = mout->dac_nids;
1717 1320
1718 if (substream->number == 0) 1321 if (substream->number == 0)
1719 playback_multi_pcm_prep_0(codec, stream_tag, format, 1322 playback_multi_pcm_prep_0(codec, stream_tag, format,
@@ -1734,7 +1337,7 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1734{ 1337{
1735 struct via_spec *spec = codec->spec; 1338 struct via_spec *spec = codec->spec;
1736 struct hda_multi_out *mout = &spec->multiout; 1339 struct hda_multi_out *mout = &spec->multiout;
1737 hda_nid_t *nids = mout->dac_nids; 1340 const hda_nid_t *nids = mout->dac_nids;
1738 int i; 1341 int i;
1739 1342
1740 if (substream->number == 0) { 1343 if (substream->number == 0) {
@@ -1832,7 +1435,7 @@ static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1832 return 0; 1435 return 0;
1833} 1436}
1834 1437
1835static struct hda_pcm_stream vt1708_pcm_analog_playback = { 1438static const struct hda_pcm_stream vt1708_pcm_analog_playback = {
1836 .substreams = 2, 1439 .substreams = 2,
1837 .channels_min = 2, 1440 .channels_min = 2,
1838 .channels_max = 8, 1441 .channels_max = 8,
@@ -1844,7 +1447,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_playback = {
1844 }, 1447 },
1845}; 1448};
1846 1449
1847static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { 1450static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1848 .substreams = 2, 1451 .substreams = 2,
1849 .channels_min = 2, 1452 .channels_min = 2,
1850 .channels_max = 8, 1453 .channels_max = 8,
@@ -1861,7 +1464,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1861 }, 1464 },
1862}; 1465};
1863 1466
1864static struct hda_pcm_stream vt1708_pcm_analog_capture = { 1467static const struct hda_pcm_stream vt1708_pcm_analog_capture = {
1865 .substreams = 2, 1468 .substreams = 2,
1866 .channels_min = 2, 1469 .channels_min = 2,
1867 .channels_max = 2, 1470 .channels_max = 2,
@@ -1872,7 +1475,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_capture = {
1872 }, 1475 },
1873}; 1476};
1874 1477
1875static struct hda_pcm_stream vt1708_pcm_digital_playback = { 1478static const struct hda_pcm_stream vt1708_pcm_digital_playback = {
1876 .substreams = 1, 1479 .substreams = 1,
1877 .channels_min = 2, 1480 .channels_min = 2,
1878 .channels_max = 2, 1481 .channels_max = 2,
@@ -1885,7 +1488,7 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = {
1885 }, 1488 },
1886}; 1489};
1887 1490
1888static struct hda_pcm_stream vt1708_pcm_digital_capture = { 1491static const struct hda_pcm_stream vt1708_pcm_digital_capture = {
1889 .substreams = 1, 1492 .substreams = 1,
1890 .channels_min = 2, 1493 .channels_min = 2,
1891 .channels_max = 2, 1494 .channels_max = 2,
@@ -1895,7 +1498,7 @@ static int via_build_controls(struct hda_codec *codec)
1895{ 1498{
1896 struct via_spec *spec = codec->spec; 1499 struct via_spec *spec = codec->spec;
1897 struct snd_kcontrol *kctl; 1500 struct snd_kcontrol *kctl;
1898 struct snd_kcontrol_new *knew; 1501 const struct snd_kcontrol_new *knew;
1899 int err, i; 1502 int err, i;
1900 1503
1901 for (i = 0; i < spec->num_mixers; i++) { 1504 for (i = 0; i < spec->num_mixers; i++) {
@@ -1943,7 +1546,7 @@ static int via_build_controls(struct hda_codec *codec)
1943 } 1546 }
1944 1547
1945 /* init power states */ 1548 /* init power states */
1946 set_jack_power_state(codec); 1549 set_widgets_power_state(codec);
1947 analog_low_current_mode(codec, 1); 1550 analog_low_current_mode(codec, 1);
1948 1551
1949 via_free_kctls(codec); /* no longer needed */ 1552 via_free_kctls(codec); /* no longer needed */
@@ -2107,7 +1710,7 @@ static void via_speaker_automute(struct hda_codec *codec)
2107 unsigned int hp_present; 1710 unsigned int hp_present;
2108 struct via_spec *spec = codec->spec; 1711 struct via_spec *spec = codec->spec;
2109 1712
2110 if (spec->codec_type != VT2002P && spec->codec_type != VT1812) 1713 if (!VT2002P_COMPATIBLE(spec))
2111 return; 1714 return;
2112 1715
2113 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); 1716 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
@@ -2166,17 +1769,21 @@ static void via_unsol_event(struct hda_codec *codec,
2166 unsigned int res) 1769 unsigned int res)
2167{ 1770{
2168 res >>= 26; 1771 res >>= 26;
2169 if (res & VIA_HP_EVENT) 1772
1773 if (res & VIA_JACK_EVENT)
1774 set_widgets_power_state(codec);
1775
1776 res &= ~VIA_JACK_EVENT;
1777
1778 if (res == VIA_HP_EVENT)
2170 via_hp_automute(codec); 1779 via_hp_automute(codec);
2171 if (res & VIA_GPIO_EVENT) 1780 else if (res == VIA_GPIO_EVENT)
2172 via_gpio_control(codec); 1781 via_gpio_control(codec);
2173 if (res & VIA_JACK_EVENT) 1782 else if (res == VIA_MONO_EVENT)
2174 set_jack_power_state(codec);
2175 if (res & VIA_MONO_EVENT)
2176 via_mono_automute(codec); 1783 via_mono_automute(codec);
2177 if (res & VIA_SPEAKER_EVENT) 1784 else if (res == VIA_SPEAKER_EVENT)
2178 via_speaker_automute(codec); 1785 via_speaker_automute(codec);
2179 if (res & VIA_BIND_HP_EVENT) 1786 else if (res == VIA_BIND_HP_EVENT)
2180 via_hp_bind_automute(codec); 1787 via_hp_bind_automute(codec);
2181} 1788}
2182 1789
@@ -2187,10 +1794,6 @@ static int via_init(struct hda_codec *codec)
2187 for (i = 0; i < spec->num_iverbs; i++) 1794 for (i = 0; i < spec->num_iverbs; i++)
2188 snd_hda_sequence_write(codec, spec->init_verbs[i]); 1795 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2189 1796
2190 spec->codec_type = get_codec_type(codec);
2191 if (spec->codec_type == VT1708BCE)
2192 spec->codec_type = VT1708S; /* VT1708BCE & VT1708S are almost
2193 same */
2194 /* Lydia Add for EAPD enable */ 1797 /* Lydia Add for EAPD enable */
2195 if (!spec->dig_in_nid) { /* No Digital In connection */ 1798 if (!spec->dig_in_nid) { /* No Digital In connection */
2196 if (spec->dig_in_pin) { 1799 if (spec->dig_in_pin) {
@@ -2230,7 +1833,7 @@ static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2230 1833
2231/* 1834/*
2232 */ 1835 */
2233static struct hda_codec_ops via_patch_ops = { 1836static const struct hda_codec_ops via_patch_ops = {
2234 .build_controls = via_build_controls, 1837 .build_controls = via_build_controls,
2235 .build_pcms = via_build_pcms, 1838 .build_pcms = via_build_pcms,
2236 .init = via_init, 1839 .init = via_init,
@@ -2260,16 +1863,16 @@ static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
2260 /* config dac list */ 1863 /* config dac list */
2261 switch (i) { 1864 switch (i) {
2262 case AUTO_SEQ_FRONT: 1865 case AUTO_SEQ_FRONT:
2263 spec->multiout.dac_nids[i] = 0x10; 1866 spec->private_dac_nids[i] = 0x10;
2264 break; 1867 break;
2265 case AUTO_SEQ_CENLFE: 1868 case AUTO_SEQ_CENLFE:
2266 spec->multiout.dac_nids[i] = 0x12; 1869 spec->private_dac_nids[i] = 0x12;
2267 break; 1870 break;
2268 case AUTO_SEQ_SURROUND: 1871 case AUTO_SEQ_SURROUND:
2269 spec->multiout.dac_nids[i] = 0x11; 1872 spec->private_dac_nids[i] = 0x11;
2270 break; 1873 break;
2271 case AUTO_SEQ_SIDE: 1874 case AUTO_SEQ_SIDE:
2272 spec->multiout.dac_nids[i] = 0x13; 1875 spec->private_dac_nids[i] = 0x13;
2273 break; 1876 break;
2274 } 1877 }
2275 } 1878 }
@@ -2283,7 +1886,9 @@ static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
2283 const struct auto_pin_cfg *cfg) 1886 const struct auto_pin_cfg *cfg)
2284{ 1887{
2285 char name[32]; 1888 char name[32];
2286 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 1889 static const char * const chname[4] = {
1890 "Front", "Surround", "C/LFE", "Side"
1891 };
2287 hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b}; 1892 hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b};
2288 int i, err; 1893 int i, err;
2289 1894
@@ -2372,16 +1977,11 @@ static void create_hp_imux(struct via_spec *spec)
2372{ 1977{
2373 int i; 1978 int i;
2374 struct hda_input_mux *imux = &spec->private_imux[1]; 1979 struct hda_input_mux *imux = &spec->private_imux[1];
2375 static const char *texts[] = { "OFF", "ON", NULL}; 1980 static const char * const texts[] = { "OFF", "ON", NULL};
2376 1981
2377 /* for hp mode select */ 1982 /* for hp mode select */
2378 i = 0; 1983 for (i = 0; texts[i]; i++)
2379 while (texts[i] != NULL) { 1984 snd_hda_add_imux_item(imux, texts[i], i, NULL);
2380 imux->items[imux->num_items].label = texts[i];
2381 imux->items[imux->num_items].index = i;
2382 imux->num_items++;
2383 i++;
2384 }
2385 1985
2386 spec->hp_mux = &spec->private_imux[1]; 1986 spec->hp_mux = &spec->private_imux[1];
2387} 1987}
@@ -2413,53 +2013,63 @@ static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2413} 2013}
2414 2014
2415/* create playback/capture controls for input pins */ 2015/* create playback/capture controls for input pins */
2416static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec, 2016static int vt_auto_create_analog_input_ctls(struct hda_codec *codec,
2417 const struct auto_pin_cfg *cfg) 2017 const struct auto_pin_cfg *cfg,
2018 hda_nid_t cap_nid,
2019 const hda_nid_t pin_idxs[],
2020 int num_idxs)
2418{ 2021{
2419 static char *labels[] = { 2022 struct via_spec *spec = codec->spec;
2420 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
2421 };
2422 struct hda_input_mux *imux = &spec->private_imux[0]; 2023 struct hda_input_mux *imux = &spec->private_imux[0];
2423 int i, err, idx = 0; 2024 int i, err, idx, type, type_idx = 0;
2424 2025
2425 /* for internal loopback recording select */ 2026 /* for internal loopback recording select */
2426 imux->items[imux->num_items].label = "Stereo Mixer"; 2027 for (idx = 0; idx < num_idxs; idx++) {
2427 imux->items[imux->num_items].index = idx; 2028 if (pin_idxs[idx] == 0xff) {
2428 imux->num_items++; 2029 snd_hda_add_imux_item(imux, "Stereo Mixer", idx, NULL);
2429
2430 for (i = 0; i < AUTO_PIN_LAST; i++) {
2431 if (!cfg->input_pins[i])
2432 continue;
2433
2434 switch (cfg->input_pins[i]) {
2435 case 0x1d: /* Mic */
2436 idx = 2;
2437 break;
2438
2439 case 0x1e: /* Line In */
2440 idx = 3;
2441 break;
2442
2443 case 0x21: /* Front Mic */
2444 idx = 4;
2445 break;
2446
2447 case 0x24: /* CD */
2448 idx = 1;
2449 break; 2030 break;
2450 } 2031 }
2451 err = via_new_analog_input(spec, labels[i], idx, 0x17); 2032 }
2033
2034 for (i = 0; i < cfg->num_inputs; i++) {
2035 const char *label;
2036 type = cfg->inputs[i].type;
2037 for (idx = 0; idx < num_idxs; idx++)
2038 if (pin_idxs[idx] == cfg->inputs[i].pin)
2039 break;
2040 if (idx >= num_idxs)
2041 continue;
2042 if (i > 0 && type == cfg->inputs[i - 1].type)
2043 type_idx++;
2044 else
2045 type_idx = 0;
2046 label = hda_get_autocfg_input_label(codec, cfg, i);
2047 if (spec->codec_type == VT1708S ||
2048 spec->codec_type == VT1702 ||
2049 spec->codec_type == VT1716S)
2050 err = via_new_analog_input(spec, label, type_idx,
2051 idx+1, cap_nid);
2052 else
2053 err = via_new_analog_input(spec, label, type_idx,
2054 idx, cap_nid);
2452 if (err < 0) 2055 if (err < 0)
2453 return err; 2056 return err;
2454 imux->items[imux->num_items].label = labels[i]; 2057 snd_hda_add_imux_item(imux, label, idx, NULL);
2455 imux->items[imux->num_items].index = idx;
2456 imux->num_items++;
2457 } 2058 }
2458 return 0; 2059 return 0;
2459} 2060}
2460 2061
2062/* create playback/capture controls for input pins */
2063static int vt1708_auto_create_analog_input_ctls(struct hda_codec *codec,
2064 const struct auto_pin_cfg *cfg)
2065{
2066 static const hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 };
2067 return vt_auto_create_analog_input_ctls(codec, cfg, 0x17, pin_idxs,
2068 ARRAY_SIZE(pin_idxs));
2069}
2070
2461#ifdef CONFIG_SND_HDA_POWER_SAVE 2071#ifdef CONFIG_SND_HDA_POWER_SAVE
2462static struct hda_amp_list vt1708_loopbacks[] = { 2072static const struct hda_amp_list vt1708_loopbacks[] = {
2463 { 0x17, HDA_INPUT, 1 }, 2073 { 0x17, HDA_INPUT, 1 },
2464 { 0x17, HDA_INPUT, 2 }, 2074 { 0x17, HDA_INPUT, 2 },
2465 { 0x17, HDA_INPUT, 3 }, 2075 { 0x17, HDA_INPUT, 3 },
@@ -2518,7 +2128,7 @@ static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol,
2518 return change; 2128 return change;
2519} 2129}
2520 2130
2521static struct snd_kcontrol_new vt1708_jack_detectect[] = { 2131static const struct snd_kcontrol_new vt1708_jack_detectect[] = {
2522 { 2132 {
2523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2133 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2524 .name = "Jack Detect", 2134 .name = "Jack Detect",
@@ -2554,7 +2164,7 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
2554 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 2164 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2555 if (err < 0) 2165 if (err < 0)
2556 return err; 2166 return err;
2557 err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg); 2167 err = vt1708_auto_create_analog_input_ctls(codec, &spec->autocfg);
2558 if (err < 0) 2168 if (err < 0)
2559 return err; 2169 return err;
2560 /* add jack detect on/off control */ 2170 /* add jack detect on/off control */
@@ -2593,7 +2203,8 @@ static int via_auto_init(struct hda_codec *codec)
2593 via_auto_init_multi_out(codec); 2203 via_auto_init_multi_out(codec);
2594 via_auto_init_hp_out(codec); 2204 via_auto_init_hp_out(codec);
2595 via_auto_init_analog_input(codec); 2205 via_auto_init_analog_input(codec);
2596 if (spec->codec_type == VT2002P || spec->codec_type == VT1812) { 2206
2207 if (VT2002P_COMPATIBLE(spec)) {
2597 via_hp_bind_automute(codec); 2208 via_hp_bind_automute(codec);
2598 } else { 2209 } else {
2599 via_hp_automute(codec); 2210 via_hp_automute(codec);
@@ -2697,7 +2308,7 @@ static int patch_vt1708(struct hda_codec *codec)
2697} 2308}
2698 2309
2699/* capture mixer elements */ 2310/* capture mixer elements */
2700static struct snd_kcontrol_new vt1709_capture_mixer[] = { 2311static const struct snd_kcontrol_new vt1709_capture_mixer[] = {
2701 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT), 2312 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
2702 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT), 2313 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
2703 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT), 2314 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
@@ -2719,7 +2330,7 @@ static struct snd_kcontrol_new vt1709_capture_mixer[] = {
2719 { } /* end */ 2330 { } /* end */
2720}; 2331};
2721 2332
2722static struct hda_verb vt1709_uniwill_init_verbs[] = { 2333static const struct hda_verb vt1709_uniwill_init_verbs[] = {
2723 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 2334 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE,
2724 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 2335 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
2725 { } 2336 { }
@@ -2728,7 +2339,7 @@ static struct hda_verb vt1709_uniwill_init_verbs[] = {
2728/* 2339/*
2729 * generic initialization of ADC, input mixers and output mixers 2340 * generic initialization of ADC, input mixers and output mixers
2730 */ 2341 */
2731static struct hda_verb vt1709_10ch_volume_init_verbs[] = { 2342static const struct hda_verb vt1709_10ch_volume_init_verbs[] = {
2732 /* 2343 /*
2733 * Unmute ADC0-2 and set the default input to mic-in 2344 * Unmute ADC0-2 and set the default input to mic-in
2734 */ 2345 */
@@ -2768,7 +2379,7 @@ static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
2768 { } 2379 { }
2769}; 2380};
2770 2381
2771static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = { 2382static const struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
2772 .substreams = 1, 2383 .substreams = 1,
2773 .channels_min = 2, 2384 .channels_min = 2,
2774 .channels_max = 10, 2385 .channels_max = 10,
@@ -2780,7 +2391,7 @@ static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
2780 }, 2391 },
2781}; 2392};
2782 2393
2783static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = { 2394static const struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
2784 .substreams = 1, 2395 .substreams = 1,
2785 .channels_min = 2, 2396 .channels_min = 2,
2786 .channels_max = 6, 2397 .channels_max = 6,
@@ -2792,7 +2403,7 @@ static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
2792 }, 2403 },
2793}; 2404};
2794 2405
2795static struct hda_pcm_stream vt1709_pcm_analog_capture = { 2406static const struct hda_pcm_stream vt1709_pcm_analog_capture = {
2796 .substreams = 2, 2407 .substreams = 2,
2797 .channels_min = 2, 2408 .channels_min = 2,
2798 .channels_max = 2, 2409 .channels_max = 2,
@@ -2803,7 +2414,7 @@ static struct hda_pcm_stream vt1709_pcm_analog_capture = {
2803 }, 2414 },
2804}; 2415};
2805 2416
2806static struct hda_pcm_stream vt1709_pcm_digital_playback = { 2417static const struct hda_pcm_stream vt1709_pcm_digital_playback = {
2807 .substreams = 1, 2418 .substreams = 1,
2808 .channels_min = 2, 2419 .channels_min = 2,
2809 .channels_max = 2, 2420 .channels_max = 2,
@@ -2814,7 +2425,7 @@ static struct hda_pcm_stream vt1709_pcm_digital_playback = {
2814 }, 2425 },
2815}; 2426};
2816 2427
2817static struct hda_pcm_stream vt1709_pcm_digital_capture = { 2428static const struct hda_pcm_stream vt1709_pcm_digital_capture = {
2818 .substreams = 1, 2429 .substreams = 1,
2819 .channels_min = 2, 2430 .channels_min = 2,
2820 .channels_max = 2, 2431 .channels_max = 2,
@@ -2841,26 +2452,26 @@ static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
2841 switch (i) { 2452 switch (i) {
2842 case AUTO_SEQ_FRONT: 2453 case AUTO_SEQ_FRONT:
2843 /* AOW0 */ 2454 /* AOW0 */
2844 spec->multiout.dac_nids[i] = 0x10; 2455 spec->private_dac_nids[i] = 0x10;
2845 break; 2456 break;
2846 case AUTO_SEQ_CENLFE: 2457 case AUTO_SEQ_CENLFE:
2847 /* AOW2 */ 2458 /* AOW2 */
2848 spec->multiout.dac_nids[i] = 0x12; 2459 spec->private_dac_nids[i] = 0x12;
2849 break; 2460 break;
2850 case AUTO_SEQ_SURROUND: 2461 case AUTO_SEQ_SURROUND:
2851 /* AOW3 */ 2462 /* AOW3 */
2852 spec->multiout.dac_nids[i] = 0x11; 2463 spec->private_dac_nids[i] = 0x11;
2853 break; 2464 break;
2854 case AUTO_SEQ_SIDE: 2465 case AUTO_SEQ_SIDE:
2855 /* AOW1 */ 2466 /* AOW1 */
2856 spec->multiout.dac_nids[i] = 0x27; 2467 spec->private_dac_nids[i] = 0x27;
2857 break; 2468 break;
2858 default: 2469 default:
2859 break; 2470 break;
2860 } 2471 }
2861 } 2472 }
2862 } 2473 }
2863 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */ 2474 spec->private_dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
2864 2475
2865 } else if (cfg->line_outs == 3) { /* 6 channels */ 2476 } else if (cfg->line_outs == 3) { /* 6 channels */
2866 for (i = 0; i < cfg->line_outs; i++) { 2477 for (i = 0; i < cfg->line_outs; i++) {
@@ -2870,15 +2481,15 @@ static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
2870 switch (i) { 2481 switch (i) {
2871 case AUTO_SEQ_FRONT: 2482 case AUTO_SEQ_FRONT:
2872 /* AOW0 */ 2483 /* AOW0 */
2873 spec->multiout.dac_nids[i] = 0x10; 2484 spec->private_dac_nids[i] = 0x10;
2874 break; 2485 break;
2875 case AUTO_SEQ_CENLFE: 2486 case AUTO_SEQ_CENLFE:
2876 /* AOW2 */ 2487 /* AOW2 */
2877 spec->multiout.dac_nids[i] = 0x12; 2488 spec->private_dac_nids[i] = 0x12;
2878 break; 2489 break;
2879 case AUTO_SEQ_SURROUND: 2490 case AUTO_SEQ_SURROUND:
2880 /* AOW1 */ 2491 /* AOW1 */
2881 spec->multiout.dac_nids[i] = 0x11; 2492 spec->private_dac_nids[i] = 0x11;
2882 break; 2493 break;
2883 default: 2494 default:
2884 break; 2495 break;
@@ -2895,7 +2506,9 @@ static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
2895 const struct auto_pin_cfg *cfg) 2506 const struct auto_pin_cfg *cfg)
2896{ 2507{
2897 char name[32]; 2508 char name[32];
2898 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 2509 static const char * const chname[4] = {
2510 "Front", "Surround", "C/LFE", "Side"
2511 };
2899 hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29}; 2512 hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29};
2900 int i, err; 2513 int i, err;
2901 2514
@@ -3021,49 +2634,12 @@ static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3021} 2634}
3022 2635
3023/* create playback/capture controls for input pins */ 2636/* create playback/capture controls for input pins */
3024static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec, 2637static int vt1709_auto_create_analog_input_ctls(struct hda_codec *codec,
3025 const struct auto_pin_cfg *cfg) 2638 const struct auto_pin_cfg *cfg)
3026{ 2639{
3027 static char *labels[] = { 2640 static const hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 };
3028 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 2641 return vt_auto_create_analog_input_ctls(codec, cfg, 0x18, pin_idxs,
3029 }; 2642 ARRAY_SIZE(pin_idxs));
3030 struct hda_input_mux *imux = &spec->private_imux[0];
3031 int i, err, idx = 0;
3032
3033 /* for internal loopback recording select */
3034 imux->items[imux->num_items].label = "Stereo Mixer";
3035 imux->items[imux->num_items].index = idx;
3036 imux->num_items++;
3037
3038 for (i = 0; i < AUTO_PIN_LAST; i++) {
3039 if (!cfg->input_pins[i])
3040 continue;
3041
3042 switch (cfg->input_pins[i]) {
3043 case 0x1d: /* Mic */
3044 idx = 2;
3045 break;
3046
3047 case 0x1e: /* Line In */
3048 idx = 3;
3049 break;
3050
3051 case 0x21: /* Front Mic */
3052 idx = 4;
3053 break;
3054
3055 case 0x23: /* CD */
3056 idx = 1;
3057 break;
3058 }
3059 err = via_new_analog_input(spec, labels[i], idx, 0x18);
3060 if (err < 0)
3061 return err;
3062 imux->items[imux->num_items].label = labels[i];
3063 imux->items[imux->num_items].index = idx;
3064 imux->num_items++;
3065 }
3066 return 0;
3067} 2643}
3068 2644
3069static int vt1709_parse_auto_config(struct hda_codec *codec) 2645static int vt1709_parse_auto_config(struct hda_codec *codec)
@@ -3086,7 +2662,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
3086 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 2662 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3087 if (err < 0) 2663 if (err < 0)
3088 return err; 2664 return err;
3089 err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg); 2665 err = vt1709_auto_create_analog_input_ctls(codec, &spec->autocfg);
3090 if (err < 0) 2666 if (err < 0)
3091 return err; 2667 return err;
3092 2668
@@ -3111,7 +2687,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
3111} 2687}
3112 2688
3113#ifdef CONFIG_SND_HDA_POWER_SAVE 2689#ifdef CONFIG_SND_HDA_POWER_SAVE
3114static struct hda_amp_list vt1709_loopbacks[] = { 2690static const struct hda_amp_list vt1709_loopbacks[] = {
3115 { 0x18, HDA_INPUT, 1 }, 2691 { 0x18, HDA_INPUT, 1 },
3116 { 0x18, HDA_INPUT, 2 }, 2692 { 0x18, HDA_INPUT, 2 },
3117 { 0x18, HDA_INPUT, 3 }, 2693 { 0x18, HDA_INPUT, 3 },
@@ -3172,7 +2748,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
3172/* 2748/*
3173 * generic initialization of ADC, input mixers and output mixers 2749 * generic initialization of ADC, input mixers and output mixers
3174 */ 2750 */
3175static struct hda_verb vt1709_6ch_volume_init_verbs[] = { 2751static const struct hda_verb vt1709_6ch_volume_init_verbs[] = {
3176 /* 2752 /*
3177 * Unmute ADC0-2 and set the default input to mic-in 2753 * Unmute ADC0-2 and set the default input to mic-in
3178 */ 2754 */
@@ -3262,7 +2838,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
3262} 2838}
3263 2839
3264/* capture mixer elements */ 2840/* capture mixer elements */
3265static struct snd_kcontrol_new vt1708B_capture_mixer[] = { 2841static const struct snd_kcontrol_new vt1708B_capture_mixer[] = {
3266 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), 2842 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3267 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), 2843 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3268 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), 2844 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
@@ -3284,7 +2860,7 @@ static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
3284/* 2860/*
3285 * generic initialization of ADC, input mixers and output mixers 2861 * generic initialization of ADC, input mixers and output mixers
3286 */ 2862 */
3287static struct hda_verb vt1708B_8ch_volume_init_verbs[] = { 2863static const struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
3288 /* 2864 /*
3289 * Unmute ADC0-1 and set the default input to mic-in 2865 * Unmute ADC0-1 and set the default input to mic-in
3290 */ 2866 */
@@ -3319,7 +2895,7 @@ static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
3319 { } 2895 { }
3320}; 2896};
3321 2897
3322static struct hda_verb vt1708B_4ch_volume_init_verbs[] = { 2898static const struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
3323 /* 2899 /*
3324 * Unmute ADC0-1 and set the default input to mic-in 2900 * Unmute ADC0-1 and set the default input to mic-in
3325 */ 2901 */
@@ -3354,7 +2930,7 @@ static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
3354 { } 2930 { }
3355}; 2931};
3356 2932
3357static struct hda_verb vt1708B_uniwill_init_verbs[] = { 2933static const struct hda_verb vt1708B_uniwill_init_verbs[] = {
3358 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 2934 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3359 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 2935 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3360 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 2936 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -3378,7 +2954,7 @@ static int via_pcm_open_close(struct hda_pcm_stream *hinfo,
3378 return 0; 2954 return 0;
3379} 2955}
3380 2956
3381static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { 2957static const struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
3382 .substreams = 2, 2958 .substreams = 2,
3383 .channels_min = 2, 2959 .channels_min = 2,
3384 .channels_max = 8, 2960 .channels_max = 8,
@@ -3391,7 +2967,7 @@ static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
3391 }, 2967 },
3392}; 2968};
3393 2969
3394static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { 2970static const struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
3395 .substreams = 2, 2971 .substreams = 2,
3396 .channels_min = 2, 2972 .channels_min = 2,
3397 .channels_max = 4, 2973 .channels_max = 4,
@@ -3403,7 +2979,7 @@ static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
3403 }, 2979 },
3404}; 2980};
3405 2981
3406static struct hda_pcm_stream vt1708B_pcm_analog_capture = { 2982static const struct hda_pcm_stream vt1708B_pcm_analog_capture = {
3407 .substreams = 2, 2983 .substreams = 2,
3408 .channels_min = 2, 2984 .channels_min = 2,
3409 .channels_max = 2, 2985 .channels_max = 2,
@@ -3416,7 +2992,7 @@ static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
3416 }, 2992 },
3417}; 2993};
3418 2994
3419static struct hda_pcm_stream vt1708B_pcm_digital_playback = { 2995static const struct hda_pcm_stream vt1708B_pcm_digital_playback = {
3420 .substreams = 1, 2996 .substreams = 1,
3421 .channels_min = 2, 2997 .channels_min = 2,
3422 .channels_max = 2, 2998 .channels_max = 2,
@@ -3429,7 +3005,7 @@ static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
3429 }, 3005 },
3430}; 3006};
3431 3007
3432static struct hda_pcm_stream vt1708B_pcm_digital_capture = { 3008static const struct hda_pcm_stream vt1708B_pcm_digital_capture = {
3433 .substreams = 1, 3009 .substreams = 1,
3434 .channels_min = 2, 3010 .channels_min = 2,
3435 .channels_max = 2, 3011 .channels_max = 2,
@@ -3452,16 +3028,16 @@ static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
3452 /* config dac list */ 3028 /* config dac list */
3453 switch (i) { 3029 switch (i) {
3454 case AUTO_SEQ_FRONT: 3030 case AUTO_SEQ_FRONT:
3455 spec->multiout.dac_nids[i] = 0x10; 3031 spec->private_dac_nids[i] = 0x10;
3456 break; 3032 break;
3457 case AUTO_SEQ_CENLFE: 3033 case AUTO_SEQ_CENLFE:
3458 spec->multiout.dac_nids[i] = 0x24; 3034 spec->private_dac_nids[i] = 0x24;
3459 break; 3035 break;
3460 case AUTO_SEQ_SURROUND: 3036 case AUTO_SEQ_SURROUND:
3461 spec->multiout.dac_nids[i] = 0x11; 3037 spec->private_dac_nids[i] = 0x11;
3462 break; 3038 break;
3463 case AUTO_SEQ_SIDE: 3039 case AUTO_SEQ_SIDE:
3464 spec->multiout.dac_nids[i] = 0x25; 3040 spec->private_dac_nids[i] = 0x25;
3465 break; 3041 break;
3466 } 3042 }
3467 } 3043 }
@@ -3475,7 +3051,9 @@ static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
3475 const struct auto_pin_cfg *cfg) 3051 const struct auto_pin_cfg *cfg)
3476{ 3052{
3477 char name[32]; 3053 char name[32];
3478 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 3054 static const char * const chname[4] = {
3055 "Front", "Surround", "C/LFE", "Side"
3056 };
3479 hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27}; 3057 hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
3480 hda_nid_t nid, nid_vol = 0; 3058 hda_nid_t nid, nid_vol = 0;
3481 int i, err; 3059 int i, err;
@@ -3588,49 +3166,12 @@ static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3588} 3166}
3589 3167
3590/* create playback/capture controls for input pins */ 3168/* create playback/capture controls for input pins */
3591static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec, 3169static int vt1708B_auto_create_analog_input_ctls(struct hda_codec *codec,
3592 const struct auto_pin_cfg *cfg) 3170 const struct auto_pin_cfg *cfg)
3593{ 3171{
3594 static char *labels[] = { 3172 static const hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e };
3595 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 3173 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
3596 }; 3174 ARRAY_SIZE(pin_idxs));
3597 struct hda_input_mux *imux = &spec->private_imux[0];
3598 int i, err, idx = 0;
3599
3600 /* for internal loopback recording select */
3601 imux->items[imux->num_items].label = "Stereo Mixer";
3602 imux->items[imux->num_items].index = idx;
3603 imux->num_items++;
3604
3605 for (i = 0; i < AUTO_PIN_LAST; i++) {
3606 if (!cfg->input_pins[i])
3607 continue;
3608
3609 switch (cfg->input_pins[i]) {
3610 case 0x1a: /* Mic */
3611 idx = 2;
3612 break;
3613
3614 case 0x1b: /* Line In */
3615 idx = 3;
3616 break;
3617
3618 case 0x1e: /* Front Mic */
3619 idx = 4;
3620 break;
3621
3622 case 0x1f: /* CD */
3623 idx = 1;
3624 break;
3625 }
3626 err = via_new_analog_input(spec, labels[i], idx, 0x16);
3627 if (err < 0)
3628 return err;
3629 imux->items[imux->num_items].label = labels[i];
3630 imux->items[imux->num_items].index = idx;
3631 imux->num_items++;
3632 }
3633 return 0;
3634} 3175}
3635 3176
3636static int vt1708B_parse_auto_config(struct hda_codec *codec) 3177static int vt1708B_parse_auto_config(struct hda_codec *codec)
@@ -3653,7 +3194,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
3653 err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 3194 err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3654 if (err < 0) 3195 if (err < 0)
3655 return err; 3196 return err;
3656 err = vt1708B_auto_create_analog_input_ctls(spec, &spec->autocfg); 3197 err = vt1708B_auto_create_analog_input_ctls(codec, &spec->autocfg);
3657 if (err < 0) 3198 if (err < 0)
3658 return err; 3199 return err;
3659 3200
@@ -3678,7 +3219,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
3678} 3219}
3679 3220
3680#ifdef CONFIG_SND_HDA_POWER_SAVE 3221#ifdef CONFIG_SND_HDA_POWER_SAVE
3681static struct hda_amp_list vt1708B_loopbacks[] = { 3222static const struct hda_amp_list vt1708B_loopbacks[] = {
3682 { 0x16, HDA_INPUT, 1 }, 3223 { 0x16, HDA_INPUT, 1 },
3683 { 0x16, HDA_INPUT, 2 }, 3224 { 0x16, HDA_INPUT, 2 },
3684 { 0x16, HDA_INPUT, 3 }, 3225 { 0x16, HDA_INPUT, 3 },
@@ -3686,6 +3227,87 @@ static struct hda_amp_list vt1708B_loopbacks[] = {
3686 { } /* end */ 3227 { } /* end */
3687}; 3228};
3688#endif 3229#endif
3230
3231static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
3232{
3233 struct via_spec *spec = codec->spec;
3234 int imux_is_smixer;
3235 unsigned int parm;
3236 int is_8ch = 0;
3237 if ((spec->codec_type != VT1708B_4CH) &&
3238 (codec->vendor_id != 0x11064397))
3239 is_8ch = 1;
3240
3241 /* SW0 (17h) = stereo mixer */
3242 imux_is_smixer =
3243 (snd_hda_codec_read(codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
3244 == ((spec->codec_type == VT1708S) ? 5 : 0));
3245 /* inputs */
3246 /* PW 1/2/5 (1ah/1bh/1eh) */
3247 parm = AC_PWRST_D3;
3248 set_pin_power_state(codec, 0x1a, &parm);
3249 set_pin_power_state(codec, 0x1b, &parm);
3250 set_pin_power_state(codec, 0x1e, &parm);
3251 if (imux_is_smixer)
3252 parm = AC_PWRST_D0;
3253 /* SW0 (17h), AIW 0/1 (13h/14h) */
3254 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
3255 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
3256 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
3257
3258 /* outputs */
3259 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
3260 parm = AC_PWRST_D3;
3261 set_pin_power_state(codec, 0x19, &parm);
3262 if (spec->smart51_enabled)
3263 set_pin_power_state(codec, 0x1b, &parm);
3264 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
3265 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
3266
3267 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
3268 if (is_8ch) {
3269 parm = AC_PWRST_D3;
3270 set_pin_power_state(codec, 0x22, &parm);
3271 if (spec->smart51_enabled)
3272 set_pin_power_state(codec, 0x1a, &parm);
3273 snd_hda_codec_write(codec, 0x26, 0,
3274 AC_VERB_SET_POWER_STATE, parm);
3275 snd_hda_codec_write(codec, 0x24, 0,
3276 AC_VERB_SET_POWER_STATE, parm);
3277 } else if (codec->vendor_id == 0x11064397) {
3278 /* PW7(23h), SW2(27h), AOW2(25h) */
3279 parm = AC_PWRST_D3;
3280 set_pin_power_state(codec, 0x23, &parm);
3281 if (spec->smart51_enabled)
3282 set_pin_power_state(codec, 0x1a, &parm);
3283 snd_hda_codec_write(codec, 0x27, 0,
3284 AC_VERB_SET_POWER_STATE, parm);
3285 snd_hda_codec_write(codec, 0x25, 0,
3286 AC_VERB_SET_POWER_STATE, parm);
3287 }
3288
3289 /* PW 3/4/7 (1ch/1dh/23h) */
3290 parm = AC_PWRST_D3;
3291 /* force to D0 for internal Speaker */
3292 set_pin_power_state(codec, 0x1c, &parm);
3293 set_pin_power_state(codec, 0x1d, &parm);
3294 if (is_8ch)
3295 set_pin_power_state(codec, 0x23, &parm);
3296
3297 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
3298 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
3299 imux_is_smixer ? AC_PWRST_D0 : parm);
3300 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
3301 if (is_8ch) {
3302 snd_hda_codec_write(codec, 0x25, 0,
3303 AC_VERB_SET_POWER_STATE, parm);
3304 snd_hda_codec_write(codec, 0x27, 0,
3305 AC_VERB_SET_POWER_STATE, parm);
3306 } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode)
3307 snd_hda_codec_write(codec, 0x25, 0,
3308 AC_VERB_SET_POWER_STATE, parm);
3309}
3310
3689static int patch_vt1708S(struct hda_codec *codec); 3311static int patch_vt1708S(struct hda_codec *codec);
3690static int patch_vt1708B_8ch(struct hda_codec *codec) 3312static int patch_vt1708B_8ch(struct hda_codec *codec)
3691{ 3313{
@@ -3736,6 +3358,8 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
3736 spec->loopback.amplist = vt1708B_loopbacks; 3358 spec->loopback.amplist = vt1708B_loopbacks;
3737#endif 3359#endif
3738 3360
3361 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
3362
3739 return 0; 3363 return 0;
3740} 3364}
3741 3365
@@ -3786,13 +3410,15 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
3786 spec->loopback.amplist = vt1708B_loopbacks; 3410 spec->loopback.amplist = vt1708B_loopbacks;
3787#endif 3411#endif
3788 3412
3413 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
3414
3789 return 0; 3415 return 0;
3790} 3416}
3791 3417
3792/* Patch for VT1708S */ 3418/* Patch for VT1708S */
3793 3419
3794/* capture mixer elements */ 3420/* capture mixer elements */
3795static struct snd_kcontrol_new vt1708S_capture_mixer[] = { 3421static const struct snd_kcontrol_new vt1708S_capture_mixer[] = {
3796 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), 3422 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3797 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), 3423 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3798 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), 3424 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
@@ -3815,7 +3441,7 @@ static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
3815 { } /* end */ 3441 { } /* end */
3816}; 3442};
3817 3443
3818static struct hda_verb vt1708S_volume_init_verbs[] = { 3444static const struct hda_verb vt1708S_volume_init_verbs[] = {
3819 /* Unmute ADC0-1 and set the default input to mic-in */ 3445 /* Unmute ADC0-1 and set the default input to mic-in */
3820 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3446 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3821 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3447 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -3841,7 +3467,7 @@ static struct hda_verb vt1708S_volume_init_verbs[] = {
3841 { } 3467 { }
3842}; 3468};
3843 3469
3844static struct hda_verb vt1708S_uniwill_init_verbs[] = { 3470static const struct hda_verb vt1708S_uniwill_init_verbs[] = {
3845 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 3471 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3846 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 3472 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3847 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3473 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -3854,7 +3480,19 @@ static struct hda_verb vt1708S_uniwill_init_verbs[] = {
3854 { } 3480 { }
3855}; 3481};
3856 3482
3857static struct hda_pcm_stream vt1708S_pcm_analog_playback = { 3483static const struct hda_verb vt1705_uniwill_init_verbs[] = {
3484 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3485 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3486 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3487 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3488 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3489 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3490 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3491 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3492 { }
3493};
3494
3495static const struct hda_pcm_stream vt1708S_pcm_analog_playback = {
3858 .substreams = 2, 3496 .substreams = 2,
3859 .channels_min = 2, 3497 .channels_min = 2,
3860 .channels_max = 8, 3498 .channels_max = 8,
@@ -3867,7 +3505,20 @@ static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
3867 }, 3505 },
3868}; 3506};
3869 3507
3870static struct hda_pcm_stream vt1708S_pcm_analog_capture = { 3508static const struct hda_pcm_stream vt1705_pcm_analog_playback = {
3509 .substreams = 2,
3510 .channels_min = 2,
3511 .channels_max = 6,
3512 .nid = 0x10, /* NID to query formats and rates */
3513 .ops = {
3514 .open = via_playback_pcm_open,
3515 .prepare = via_playback_multi_pcm_prepare,
3516 .cleanup = via_playback_multi_pcm_cleanup,
3517 .close = via_pcm_open_close
3518 },
3519};
3520
3521static const struct hda_pcm_stream vt1708S_pcm_analog_capture = {
3871 .substreams = 2, 3522 .substreams = 2,
3872 .channels_min = 2, 3523 .channels_min = 2,
3873 .channels_max = 2, 3524 .channels_max = 2,
@@ -3880,7 +3531,7 @@ static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
3880 }, 3531 },
3881}; 3532};
3882 3533
3883static struct hda_pcm_stream vt1708S_pcm_digital_playback = { 3534static const struct hda_pcm_stream vt1708S_pcm_digital_playback = {
3884 .substreams = 1, 3535 .substreams = 1,
3885 .channels_min = 2, 3536 .channels_min = 2,
3886 .channels_max = 2, 3537 .channels_max = 2,
@@ -3910,16 +3561,19 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3910 /* config dac list */ 3561 /* config dac list */
3911 switch (i) { 3562 switch (i) {
3912 case AUTO_SEQ_FRONT: 3563 case AUTO_SEQ_FRONT:
3913 spec->multiout.dac_nids[i] = 0x10; 3564 spec->private_dac_nids[i] = 0x10;
3914 break; 3565 break;
3915 case AUTO_SEQ_CENLFE: 3566 case AUTO_SEQ_CENLFE:
3916 spec->multiout.dac_nids[i] = 0x24; 3567 if (spec->codec->vendor_id == 0x11064397)
3568 spec->private_dac_nids[i] = 0x25;
3569 else
3570 spec->private_dac_nids[i] = 0x24;
3917 break; 3571 break;
3918 case AUTO_SEQ_SURROUND: 3572 case AUTO_SEQ_SURROUND:
3919 spec->multiout.dac_nids[i] = 0x11; 3573 spec->private_dac_nids[i] = 0x11;
3920 break; 3574 break;
3921 case AUTO_SEQ_SIDE: 3575 case AUTO_SEQ_SIDE:
3922 spec->multiout.dac_nids[i] = 0x25; 3576 spec->private_dac_nids[i] = 0x25;
3923 break; 3577 break;
3924 } 3578 }
3925 } 3579 }
@@ -3928,21 +3582,29 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3928 /* for Smart 5.1, line/mic inputs double as output pins */ 3582 /* for Smart 5.1, line/mic inputs double as output pins */
3929 if (cfg->line_outs == 1) { 3583 if (cfg->line_outs == 1) {
3930 spec->multiout.num_dacs = 3; 3584 spec->multiout.num_dacs = 3;
3931 spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11; 3585 spec->private_dac_nids[AUTO_SEQ_SURROUND] = 0x11;
3932 spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24; 3586 if (spec->codec->vendor_id == 0x11064397)
3587 spec->private_dac_nids[AUTO_SEQ_CENLFE] = 0x25;
3588 else
3589 spec->private_dac_nids[AUTO_SEQ_CENLFE] = 0x24;
3933 } 3590 }
3934 3591
3935 return 0; 3592 return 0;
3936} 3593}
3937 3594
3938/* add playback controls from the parsed DAC table */ 3595/* add playback controls from the parsed DAC table */
3939static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, 3596static int vt1708S_auto_create_multi_out_ctls(struct hda_codec *codec,
3940 const struct auto_pin_cfg *cfg) 3597 const struct auto_pin_cfg *cfg)
3941{ 3598{
3599 struct via_spec *spec = codec->spec;
3942 char name[32]; 3600 char name[32];
3943 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 3601 static const char * const chname[4] = {
3944 hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25}; 3602 "Front", "Surround", "C/LFE", "Side"
3945 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27}; 3603 };
3604 hda_nid_t nid_vols[2][4] = { {0x10, 0x11, 0x24, 0x25},
3605 {0x10, 0x11, 0x25, 0} };
3606 hda_nid_t nid_mutes[2][4] = { {0x1C, 0x18, 0x26, 0x27},
3607 {0x1C, 0x18, 0x27, 0} };
3946 hda_nid_t nid, nid_vol, nid_mute; 3608 hda_nid_t nid, nid_vol, nid_mute;
3947 int i, err; 3609 int i, err;
3948 3610
@@ -3953,8 +3615,15 @@ static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
3953 if (!nid && i > AUTO_SEQ_CENLFE) 3615 if (!nid && i > AUTO_SEQ_CENLFE)
3954 continue; 3616 continue;
3955 3617
3956 nid_vol = nid_vols[i]; 3618 if (codec->vendor_id == 0x11064397) {
3957 nid_mute = nid_mutes[i]; 3619 nid_vol = nid_vols[1][i];
3620 nid_mute = nid_mutes[1][i];
3621 } else {
3622 nid_vol = nid_vols[0][i];
3623 nid_mute = nid_mutes[0][i];
3624 }
3625 if (!nid_vol && !nid_mute)
3626 continue;
3958 3627
3959 if (i == AUTO_SEQ_CENLFE) { 3628 if (i == AUTO_SEQ_CENLFE) {
3960 /* Center/LFE */ 3629 /* Center/LFE */
@@ -4061,49 +3730,12 @@ static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4061} 3730}
4062 3731
4063/* create playback/capture controls for input pins */ 3732/* create playback/capture controls for input pins */
4064static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec, 3733static int vt1708S_auto_create_analog_input_ctls(struct hda_codec *codec,
4065 const struct auto_pin_cfg *cfg) 3734 const struct auto_pin_cfg *cfg)
4066{ 3735{
4067 static char *labels[] = { 3736 static const hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
4068 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 3737 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
4069 }; 3738 ARRAY_SIZE(pin_idxs));
4070 struct hda_input_mux *imux = &spec->private_imux[0];
4071 int i, err, idx = 0;
4072
4073 /* for internal loopback recording select */
4074 imux->items[imux->num_items].label = "Stereo Mixer";
4075 imux->items[imux->num_items].index = 5;
4076 imux->num_items++;
4077
4078 for (i = 0; i < AUTO_PIN_LAST; i++) {
4079 if (!cfg->input_pins[i])
4080 continue;
4081
4082 switch (cfg->input_pins[i]) {
4083 case 0x1a: /* Mic */
4084 idx = 2;
4085 break;
4086
4087 case 0x1b: /* Line In */
4088 idx = 3;
4089 break;
4090
4091 case 0x1e: /* Front Mic */
4092 idx = 4;
4093 break;
4094
4095 case 0x1f: /* CD */
4096 idx = 1;
4097 break;
4098 }
4099 err = via_new_analog_input(spec, labels[i], idx, 0x16);
4100 if (err < 0)
4101 return err;
4102 imux->items[imux->num_items].label = labels[i];
4103 imux->items[imux->num_items].index = idx-1;
4104 imux->num_items++;
4105 }
4106 return 0;
4107} 3739}
4108 3740
4109/* fill out digital output widgets; one for master and one for slave outputs */ 3741/* fill out digital output widgets; one for master and one for slave outputs */
@@ -4145,13 +3777,13 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
4145 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 3777 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4146 return 0; /* can't find valid BIOS pin config */ 3778 return 0; /* can't find valid BIOS pin config */
4147 3779
4148 err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg); 3780 err = vt1708S_auto_create_multi_out_ctls(codec, &spec->autocfg);
4149 if (err < 0) 3781 if (err < 0)
4150 return err; 3782 return err;
4151 err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 3783 err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4152 if (err < 0) 3784 if (err < 0)
4153 return err; 3785 return err;
4154 err = vt1708S_auto_create_analog_input_ctls(spec, &spec->autocfg); 3786 err = vt1708S_auto_create_analog_input_ctls(codec, &spec->autocfg);
4155 if (err < 0) 3787 if (err < 0)
4156 return err; 3788 return err;
4157 3789
@@ -4172,7 +3804,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
4172} 3804}
4173 3805
4174#ifdef CONFIG_SND_HDA_POWER_SAVE 3806#ifdef CONFIG_SND_HDA_POWER_SAVE
4175static struct hda_amp_list vt1708S_loopbacks[] = { 3807static const struct hda_amp_list vt1708S_loopbacks[] = {
4176 { 0x16, HDA_INPUT, 1 }, 3808 { 0x16, HDA_INPUT, 1 },
4177 { 0x16, HDA_INPUT, 2 }, 3809 { 0x16, HDA_INPUT, 2 },
4178 { 0x16, HDA_INPUT, 3 }, 3810 { 0x16, HDA_INPUT, 3 },
@@ -4212,17 +3844,29 @@ static int patch_vt1708S(struct hda_codec *codec)
4212 } 3844 }
4213 3845
4214 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs; 3846 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
4215 spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs; 3847 if (codec->vendor_id == 0x11064397)
3848 spec->init_verbs[spec->num_iverbs++] =
3849 vt1705_uniwill_init_verbs;
3850 else
3851 spec->init_verbs[spec->num_iverbs++] =
3852 vt1708S_uniwill_init_verbs;
4216 3853
4217 if (codec->vendor_id == 0x11060440) 3854 if (codec->vendor_id == 0x11060440)
4218 spec->stream_name_analog = "VT1818S Analog"; 3855 spec->stream_name_analog = "VT1818S Analog";
3856 else if (codec->vendor_id == 0x11064397)
3857 spec->stream_name_analog = "VT1705 Analog";
4219 else 3858 else
4220 spec->stream_name_analog = "VT1708S Analog"; 3859 spec->stream_name_analog = "VT1708S Analog";
4221 spec->stream_analog_playback = &vt1708S_pcm_analog_playback; 3860 if (codec->vendor_id == 0x11064397)
3861 spec->stream_analog_playback = &vt1705_pcm_analog_playback;
3862 else
3863 spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
4222 spec->stream_analog_capture = &vt1708S_pcm_analog_capture; 3864 spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
4223 3865
4224 if (codec->vendor_id == 0x11060440) 3866 if (codec->vendor_id == 0x11060440)
4225 spec->stream_name_digital = "VT1818S Digital"; 3867 spec->stream_name_digital = "VT1818S Digital";
3868 else if (codec->vendor_id == 0x11064397)
3869 spec->stream_name_digital = "VT1705 Digital";
4226 else 3870 else
4227 spec->stream_name_digital = "VT1708S Digital"; 3871 spec->stream_name_digital = "VT1708S Digital";
4228 spec->stream_digital_playback = &vt1708S_pcm_digital_playback; 3872 spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
@@ -4255,13 +3899,27 @@ static int patch_vt1708S(struct hda_codec *codec)
4255 spec->stream_name_analog = "VT1708BCE Analog"; 3899 spec->stream_name_analog = "VT1708BCE Analog";
4256 spec->stream_name_digital = "VT1708BCE Digital"; 3900 spec->stream_name_digital = "VT1708BCE Digital";
4257 } 3901 }
3902 /* correct names for VT1818S */
3903 if (codec->vendor_id == 0x11060440) {
3904 spec->stream_name_analog = "VT1818S Analog";
3905 spec->stream_name_digital = "VT1818S Digital";
3906 }
3907 /* correct names for VT1705 */
3908 if (codec->vendor_id == 0x11064397) {
3909 kfree(codec->chip_name);
3910 codec->chip_name = kstrdup("VT1705", GFP_KERNEL);
3911 snprintf(codec->bus->card->mixername,
3912 sizeof(codec->bus->card->mixername),
3913 "%s %s", codec->vendor_name, codec->chip_name);
3914 }
3915 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
4258 return 0; 3916 return 0;
4259} 3917}
4260 3918
4261/* Patch for VT1702 */ 3919/* Patch for VT1702 */
4262 3920
4263/* capture mixer elements */ 3921/* capture mixer elements */
4264static struct snd_kcontrol_new vt1702_capture_mixer[] = { 3922static const struct snd_kcontrol_new vt1702_capture_mixer[] = {
4265 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT), 3923 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
4266 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT), 3924 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
4267 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT), 3925 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
@@ -4285,7 +3943,7 @@ static struct snd_kcontrol_new vt1702_capture_mixer[] = {
4285 { } /* end */ 3943 { } /* end */
4286}; 3944};
4287 3945
4288static struct hda_verb vt1702_volume_init_verbs[] = { 3946static const struct hda_verb vt1702_volume_init_verbs[] = {
4289 /* 3947 /*
4290 * Unmute ADC0-1 and set the default input to mic-in 3948 * Unmute ADC0-1 and set the default input to mic-in
4291 */ 3949 */
@@ -4316,7 +3974,7 @@ static struct hda_verb vt1702_volume_init_verbs[] = {
4316 { } 3974 { }
4317}; 3975};
4318 3976
4319static struct hda_verb vt1702_uniwill_init_verbs[] = { 3977static const struct hda_verb vt1702_uniwill_init_verbs[] = {
4320 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, 3978 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE,
4321 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 3979 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4322 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3980 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -4326,7 +3984,7 @@ static struct hda_verb vt1702_uniwill_init_verbs[] = {
4326 { } 3984 { }
4327}; 3985};
4328 3986
4329static struct hda_pcm_stream vt1702_pcm_analog_playback = { 3987static const struct hda_pcm_stream vt1702_pcm_analog_playback = {
4330 .substreams = 2, 3988 .substreams = 2,
4331 .channels_min = 2, 3989 .channels_min = 2,
4332 .channels_max = 2, 3990 .channels_max = 2,
@@ -4339,7 +3997,7 @@ static struct hda_pcm_stream vt1702_pcm_analog_playback = {
4339 }, 3997 },
4340}; 3998};
4341 3999
4342static struct hda_pcm_stream vt1702_pcm_analog_capture = { 4000static const struct hda_pcm_stream vt1702_pcm_analog_capture = {
4343 .substreams = 3, 4001 .substreams = 3,
4344 .channels_min = 2, 4002 .channels_min = 2,
4345 .channels_max = 2, 4003 .channels_max = 2,
@@ -4352,7 +4010,7 @@ static struct hda_pcm_stream vt1702_pcm_analog_capture = {
4352 }, 4010 },
4353}; 4011};
4354 4012
4355static struct hda_pcm_stream vt1702_pcm_digital_playback = { 4013static const struct hda_pcm_stream vt1702_pcm_digital_playback = {
4356 .substreams = 2, 4014 .substreams = 2,
4357 .channels_min = 2, 4015 .channels_min = 2,
4358 .channels_max = 2, 4016 .channels_max = 2,
@@ -4374,7 +4032,7 @@ static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
4374 4032
4375 if (cfg->line_out_pins[0]) { 4033 if (cfg->line_out_pins[0]) {
4376 /* config dac list */ 4034 /* config dac list */
4377 spec->multiout.dac_nids[0] = 0x10; 4035 spec->private_dac_nids[0] = 0x10;
4378 } 4036 }
4379 4037
4380 return 0; 4038 return 0;
@@ -4420,7 +4078,7 @@ static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4420{ 4078{
4421 int err, i; 4079 int err, i;
4422 struct hda_input_mux *imux; 4080 struct hda_input_mux *imux;
4423 static const char *texts[] = { "ON", "OFF", NULL}; 4081 static const char * const texts[] = { "ON", "OFF", NULL};
4424 if (!pin) 4082 if (!pin)
4425 return 0; 4083 return 0;
4426 spec->multiout.hp_nid = 0x1D; 4084 spec->multiout.hp_nid = 0x1D;
@@ -4441,58 +4099,20 @@ static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4441 imux = &spec->private_imux[1]; 4099 imux = &spec->private_imux[1];
4442 4100
4443 /* for hp mode select */ 4101 /* for hp mode select */
4444 i = 0; 4102 for (i = 0; texts[i]; i++)
4445 while (texts[i] != NULL) { 4103 snd_hda_add_imux_item(imux, texts[i], i, NULL);
4446 imux->items[imux->num_items].label = texts[i];
4447 imux->items[imux->num_items].index = i;
4448 imux->num_items++;
4449 i++;
4450 }
4451 4104
4452 spec->hp_mux = &spec->private_imux[1]; 4105 spec->hp_mux = &spec->private_imux[1];
4453 return 0; 4106 return 0;
4454} 4107}
4455 4108
4456/* create playback/capture controls for input pins */ 4109/* create playback/capture controls for input pins */
4457static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec, 4110static int vt1702_auto_create_analog_input_ctls(struct hda_codec *codec,
4458 const struct auto_pin_cfg *cfg) 4111 const struct auto_pin_cfg *cfg)
4459{ 4112{
4460 static char *labels[] = { 4113 static const hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff };
4461 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 4114 return vt_auto_create_analog_input_ctls(codec, cfg, 0x1a, pin_idxs,
4462 }; 4115 ARRAY_SIZE(pin_idxs));
4463 struct hda_input_mux *imux = &spec->private_imux[0];
4464 int i, err, idx = 0;
4465
4466 /* for internal loopback recording select */
4467 imux->items[imux->num_items].label = "Stereo Mixer";
4468 imux->items[imux->num_items].index = 3;
4469 imux->num_items++;
4470
4471 for (i = 0; i < AUTO_PIN_LAST; i++) {
4472 if (!cfg->input_pins[i])
4473 continue;
4474
4475 switch (cfg->input_pins[i]) {
4476 case 0x14: /* Mic */
4477 idx = 1;
4478 break;
4479
4480 case 0x15: /* Line In */
4481 idx = 2;
4482 break;
4483
4484 case 0x18: /* Front Mic */
4485 idx = 3;
4486 break;
4487 }
4488 err = via_new_analog_input(spec, labels[i], idx, 0x1A);
4489 if (err < 0)
4490 return err;
4491 imux->items[imux->num_items].label = labels[i];
4492 imux->items[imux->num_items].index = idx-1;
4493 imux->num_items++;
4494 }
4495 return 0;
4496} 4116}
4497 4117
4498static int vt1702_parse_auto_config(struct hda_codec *codec) 4118static int vt1702_parse_auto_config(struct hda_codec *codec)
@@ -4521,7 +4141,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
4521 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 4141 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4522 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) | 4142 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4523 (1 << AC_AMPCAP_MUTE_SHIFT)); 4143 (1 << AC_AMPCAP_MUTE_SHIFT));
4524 err = vt1702_auto_create_analog_input_ctls(spec, &spec->autocfg); 4144 err = vt1702_auto_create_analog_input_ctls(codec, &spec->autocfg);
4525 if (err < 0) 4145 if (err < 0)
4526 return err; 4146 return err;
4527 4147
@@ -4541,7 +4161,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
4541} 4161}
4542 4162
4543#ifdef CONFIG_SND_HDA_POWER_SAVE 4163#ifdef CONFIG_SND_HDA_POWER_SAVE
4544static struct hda_amp_list vt1702_loopbacks[] = { 4164static const struct hda_amp_list vt1702_loopbacks[] = {
4545 { 0x1A, HDA_INPUT, 1 }, 4165 { 0x1A, HDA_INPUT, 1 },
4546 { 0x1A, HDA_INPUT, 2 }, 4166 { 0x1A, HDA_INPUT, 2 },
4547 { 0x1A, HDA_INPUT, 3 }, 4167 { 0x1A, HDA_INPUT, 3 },
@@ -4550,6 +4170,37 @@ static struct hda_amp_list vt1702_loopbacks[] = {
4550}; 4170};
4551#endif 4171#endif
4552 4172
4173static void set_widgets_power_state_vt1702(struct hda_codec *codec)
4174{
4175 int imux_is_smixer =
4176 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
4177 unsigned int parm;
4178 /* inputs */
4179 /* PW 1/2/5 (14h/15h/18h) */
4180 parm = AC_PWRST_D3;
4181 set_pin_power_state(codec, 0x14, &parm);
4182 set_pin_power_state(codec, 0x15, &parm);
4183 set_pin_power_state(codec, 0x18, &parm);
4184 if (imux_is_smixer)
4185 parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */
4186 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
4187 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
4188 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm);
4189 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
4190 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm);
4191
4192 /* outputs */
4193 /* PW 3/4 (16h/17h) */
4194 parm = AC_PWRST_D3;
4195 set_pin_power_state(codec, 0x17, &parm);
4196 set_pin_power_state(codec, 0x16, &parm);
4197 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
4198 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
4199 imux_is_smixer ? AC_PWRST_D0 : parm);
4200 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
4201 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
4202}
4203
4553static int patch_vt1702(struct hda_codec *codec) 4204static int patch_vt1702(struct hda_codec *codec)
4554{ 4205{
4555 struct via_spec *spec; 4206 struct via_spec *spec;
@@ -4596,13 +4247,14 @@ static int patch_vt1702(struct hda_codec *codec)
4596 spec->loopback.amplist = vt1702_loopbacks; 4247 spec->loopback.amplist = vt1702_loopbacks;
4597#endif 4248#endif
4598 4249
4250 spec->set_widgets_power_state = set_widgets_power_state_vt1702;
4599 return 0; 4251 return 0;
4600} 4252}
4601 4253
4602/* Patch for VT1718S */ 4254/* Patch for VT1718S */
4603 4255
4604/* capture mixer elements */ 4256/* capture mixer elements */
4605static struct snd_kcontrol_new vt1718S_capture_mixer[] = { 4257static const struct snd_kcontrol_new vt1718S_capture_mixer[] = {
4606 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), 4258 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
4607 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), 4259 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
4608 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), 4260 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
@@ -4624,14 +4276,15 @@ static struct snd_kcontrol_new vt1718S_capture_mixer[] = {
4624 { } /* end */ 4276 { } /* end */
4625}; 4277};
4626 4278
4627static struct hda_verb vt1718S_volume_init_verbs[] = { 4279static const struct hda_verb vt1718S_volume_init_verbs[] = {
4628 /* 4280 /*
4629 * Unmute ADC0-1 and set the default input to mic-in 4281 * Unmute ADC0-1 and set the default input to mic-in
4630 */ 4282 */
4631 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4283 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4632 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4284 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4633 4285
4634 4286 /* Enable MW0 adjust Gain 5 */
4287 {0x1, 0xfb2, 0x10},
4635 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 4288 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4636 * mixer widget 4289 * mixer widget
4637 */ 4290 */
@@ -4640,10 +4293,7 @@ static struct hda_verb vt1718S_volume_init_verbs[] = {
4640 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4293 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4641 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4294 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4642 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4295 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4643 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 4296 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
4644
4645 /* Setup default input of Front HP to MW9 */
4646 {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
4647 /* PW9 PW10 Output enable */ 4297 /* PW9 PW10 Output enable */
4648 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN}, 4298 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4649 {0x2e, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN}, 4299 {0x2e, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
@@ -4652,10 +4302,10 @@ static struct hda_verb vt1718S_volume_init_verbs[] = {
4652 /* Enable Boost Volume backdoor */ 4302 /* Enable Boost Volume backdoor */
4653 {0x1, 0xf88, 0x8}, 4303 {0x1, 0xf88, 0x8},
4654 /* MW0/1/2/3/4: un-mute index 0 (AOWx), mute index 1 (MW9) */ 4304 /* MW0/1/2/3/4: un-mute index 0 (AOWx), mute index 1 (MW9) */
4655 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4305 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4656 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4306 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4657 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4307 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4658 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4308 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4659 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4309 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4660 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4310 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4661 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4311 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
@@ -4665,13 +4315,11 @@ static struct hda_verb vt1718S_volume_init_verbs[] = {
4665 /* set MUX1 = 2 (AOW4), MUX2 = 1 (AOW3) */ 4315 /* set MUX1 = 2 (AOW4), MUX2 = 1 (AOW3) */
4666 {0x34, AC_VERB_SET_CONNECT_SEL, 0x2}, 4316 {0x34, AC_VERB_SET_CONNECT_SEL, 0x2},
4667 {0x35, AC_VERB_SET_CONNECT_SEL, 0x1}, 4317 {0x35, AC_VERB_SET_CONNECT_SEL, 0x1},
4668 /* Unmute MW4's index 0 */
4669 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4670 { } 4318 { }
4671}; 4319};
4672 4320
4673 4321
4674static struct hda_verb vt1718S_uniwill_init_verbs[] = { 4322static const struct hda_verb vt1718S_uniwill_init_verbs[] = {
4675 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE, 4323 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
4676 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 4324 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4677 {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4325 {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -4684,7 +4332,7 @@ static struct hda_verb vt1718S_uniwill_init_verbs[] = {
4684 { } 4332 { }
4685}; 4333};
4686 4334
4687static struct hda_pcm_stream vt1718S_pcm_analog_playback = { 4335static const struct hda_pcm_stream vt1718S_pcm_analog_playback = {
4688 .substreams = 2, 4336 .substreams = 2,
4689 .channels_min = 2, 4337 .channels_min = 2,
4690 .channels_max = 10, 4338 .channels_max = 10,
@@ -4697,7 +4345,7 @@ static struct hda_pcm_stream vt1718S_pcm_analog_playback = {
4697 }, 4345 },
4698}; 4346};
4699 4347
4700static struct hda_pcm_stream vt1718S_pcm_analog_capture = { 4348static const struct hda_pcm_stream vt1718S_pcm_analog_capture = {
4701 .substreams = 2, 4349 .substreams = 2,
4702 .channels_min = 2, 4350 .channels_min = 2,
4703 .channels_max = 2, 4351 .channels_max = 2,
@@ -4710,7 +4358,7 @@ static struct hda_pcm_stream vt1718S_pcm_analog_capture = {
4710 }, 4358 },
4711}; 4359};
4712 4360
4713static struct hda_pcm_stream vt1718S_pcm_digital_playback = { 4361static const struct hda_pcm_stream vt1718S_pcm_digital_playback = {
4714 .substreams = 2, 4362 .substreams = 2,
4715 .channels_min = 2, 4363 .channels_min = 2,
4716 .channels_max = 2, 4364 .channels_max = 2,
@@ -4723,7 +4371,7 @@ static struct hda_pcm_stream vt1718S_pcm_digital_playback = {
4723 }, 4371 },
4724}; 4372};
4725 4373
4726static struct hda_pcm_stream vt1718S_pcm_digital_capture = { 4374static const struct hda_pcm_stream vt1718S_pcm_digital_capture = {
4727 .substreams = 1, 4375 .substreams = 1,
4728 .channels_min = 2, 4376 .channels_min = 2,
4729 .channels_max = 2, 4377 .channels_max = 2,
@@ -4746,16 +4394,16 @@ static int vt1718S_auto_fill_dac_nids(struct via_spec *spec,
4746 /* config dac list */ 4394 /* config dac list */
4747 switch (i) { 4395 switch (i) {
4748 case AUTO_SEQ_FRONT: 4396 case AUTO_SEQ_FRONT:
4749 spec->multiout.dac_nids[i] = 0x8; 4397 spec->private_dac_nids[i] = 0x8;
4750 break; 4398 break;
4751 case AUTO_SEQ_CENLFE: 4399 case AUTO_SEQ_CENLFE:
4752 spec->multiout.dac_nids[i] = 0xa; 4400 spec->private_dac_nids[i] = 0xa;
4753 break; 4401 break;
4754 case AUTO_SEQ_SURROUND: 4402 case AUTO_SEQ_SURROUND:
4755 spec->multiout.dac_nids[i] = 0x9; 4403 spec->private_dac_nids[i] = 0x9;
4756 break; 4404 break;
4757 case AUTO_SEQ_SIDE: 4405 case AUTO_SEQ_SIDE:
4758 spec->multiout.dac_nids[i] = 0xb; 4406 spec->private_dac_nids[i] = 0xb;
4759 break; 4407 break;
4760 } 4408 }
4761 } 4409 }
@@ -4769,7 +4417,9 @@ static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec,
4769 const struct auto_pin_cfg *cfg) 4417 const struct auto_pin_cfg *cfg)
4770{ 4418{
4771 char name[32]; 4419 char name[32];
4772 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 4420 static const char * const chname[4] = {
4421 "Front", "Surround", "C/LFE", "Side"
4422 };
4773 hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb}; 4423 hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb};
4774 hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27}; 4424 hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27};
4775 hda_nid_t nid, nid_vol, nid_mute = 0; 4425 hda_nid_t nid, nid_vol, nid_mute = 0;
@@ -4812,6 +4462,19 @@ static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec,
4812 if (err < 0) 4462 if (err < 0)
4813 return err; 4463 return err;
4814 } else if (i == AUTO_SEQ_FRONT) { 4464 } else if (i == AUTO_SEQ_FRONT) {
4465 /* add control to mixer index 0 */
4466 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4467 "Master Front Playback Volume",
4468 HDA_COMPOSE_AMP_VAL(0x21, 3, 5,
4469 HDA_INPUT));
4470 if (err < 0)
4471 return err;
4472 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4473 "Master Front Playback Switch",
4474 HDA_COMPOSE_AMP_VAL(0x21, 3, 5,
4475 HDA_INPUT));
4476 if (err < 0)
4477 return err;
4815 /* Front */ 4478 /* Front */
4816 sprintf(name, "%s Playback Volume", chname[i]); 4479 sprintf(name, "%s Playback Volume", chname[i]);
4817 err = via_add_control( 4480 err = via_add_control(
@@ -4872,49 +4535,12 @@ static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4872} 4535}
4873 4536
4874/* create playback/capture controls for input pins */ 4537/* create playback/capture controls for input pins */
4875static int vt1718S_auto_create_analog_input_ctls(struct via_spec *spec, 4538static int vt1718S_auto_create_analog_input_ctls(struct hda_codec *codec,
4876 const struct auto_pin_cfg *cfg) 4539 const struct auto_pin_cfg *cfg)
4877{ 4540{
4878 static char *labels[] = { 4541 static const hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff };
4879 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 4542 return vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
4880 }; 4543 ARRAY_SIZE(pin_idxs));
4881 struct hda_input_mux *imux = &spec->private_imux[0];
4882 int i, err, idx = 0;
4883
4884 /* for internal loopback recording select */
4885 imux->items[imux->num_items].label = "Stereo Mixer";
4886 imux->items[imux->num_items].index = 5;
4887 imux->num_items++;
4888
4889 for (i = 0; i < AUTO_PIN_LAST; i++) {
4890 if (!cfg->input_pins[i])
4891 continue;
4892
4893 switch (cfg->input_pins[i]) {
4894 case 0x2b: /* Mic */
4895 idx = 1;
4896 break;
4897
4898 case 0x2a: /* Line In */
4899 idx = 2;
4900 break;
4901
4902 case 0x29: /* Front Mic */
4903 idx = 3;
4904 break;
4905
4906 case 0x2c: /* CD */
4907 idx = 0;
4908 break;
4909 }
4910 err = via_new_analog_input(spec, labels[i], idx, 0x21);
4911 if (err < 0)
4912 return err;
4913 imux->items[imux->num_items].label = labels[i];
4914 imux->items[imux->num_items].index = idx;
4915 imux->num_items++;
4916 }
4917 return 0;
4918} 4544}
4919 4545
4920static int vt1718S_parse_auto_config(struct hda_codec *codec) 4546static int vt1718S_parse_auto_config(struct hda_codec *codec)
@@ -4938,7 +4564,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
4938 err = vt1718S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 4564 err = vt1718S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4939 if (err < 0) 4565 if (err < 0)
4940 return err; 4566 return err;
4941 err = vt1718S_auto_create_analog_input_ctls(spec, &spec->autocfg); 4567 err = vt1718S_auto_create_analog_input_ctls(codec, &spec->autocfg);
4942 if (err < 0) 4568 if (err < 0)
4943 return err; 4569 return err;
4944 4570
@@ -4963,7 +4589,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
4963} 4589}
4964 4590
4965#ifdef CONFIG_SND_HDA_POWER_SAVE 4591#ifdef CONFIG_SND_HDA_POWER_SAVE
4966static struct hda_amp_list vt1718S_loopbacks[] = { 4592static const struct hda_amp_list vt1718S_loopbacks[] = {
4967 { 0x21, HDA_INPUT, 1 }, 4593 { 0x21, HDA_INPUT, 1 },
4968 { 0x21, HDA_INPUT, 2 }, 4594 { 0x21, HDA_INPUT, 2 },
4969 { 0x21, HDA_INPUT, 3 }, 4595 { 0x21, HDA_INPUT, 3 },
@@ -4972,6 +4598,72 @@ static struct hda_amp_list vt1718S_loopbacks[] = {
4972}; 4598};
4973#endif 4599#endif
4974 4600
4601static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
4602{
4603 struct via_spec *spec = codec->spec;
4604 int imux_is_smixer;
4605 unsigned int parm;
4606 /* MUX6 (1eh) = stereo mixer */
4607 imux_is_smixer =
4608 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
4609 /* inputs */
4610 /* PW 5/6/7 (29h/2ah/2bh) */
4611 parm = AC_PWRST_D3;
4612 set_pin_power_state(codec, 0x29, &parm);
4613 set_pin_power_state(codec, 0x2a, &parm);
4614 set_pin_power_state(codec, 0x2b, &parm);
4615 if (imux_is_smixer)
4616 parm = AC_PWRST_D0;
4617 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
4618 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
4619 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
4620 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
4621 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
4622
4623 /* outputs */
4624 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
4625 parm = AC_PWRST_D3;
4626 set_pin_power_state(codec, 0x27, &parm);
4627 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm);
4628 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm);
4629
4630 /* PW2 (26h), AOW2 (ah) */
4631 parm = AC_PWRST_D3;
4632 set_pin_power_state(codec, 0x26, &parm);
4633 if (spec->smart51_enabled)
4634 set_pin_power_state(codec, 0x2b, &parm);
4635 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm);
4636
4637 /* PW0 (24h), AOW0 (8h) */
4638 parm = AC_PWRST_D3;
4639 set_pin_power_state(codec, 0x24, &parm);
4640 if (!spec->hp_independent_mode) /* check for redirected HP */
4641 set_pin_power_state(codec, 0x28, &parm);
4642 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
4643 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
4644 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
4645 imux_is_smixer ? AC_PWRST_D0 : parm);
4646
4647 /* PW1 (25h), AOW1 (9h) */
4648 parm = AC_PWRST_D3;
4649 set_pin_power_state(codec, 0x25, &parm);
4650 if (spec->smart51_enabled)
4651 set_pin_power_state(codec, 0x2a, &parm);
4652 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm);
4653
4654 if (spec->hp_independent_mode) {
4655 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
4656 parm = AC_PWRST_D3;
4657 set_pin_power_state(codec, 0x28, &parm);
4658 snd_hda_codec_write(codec, 0x1b, 0,
4659 AC_VERB_SET_POWER_STATE, parm);
4660 snd_hda_codec_write(codec, 0x34, 0,
4661 AC_VERB_SET_POWER_STATE, parm);
4662 snd_hda_codec_write(codec, 0xc, 0,
4663 AC_VERB_SET_POWER_STATE, parm);
4664 }
4665}
4666
4975static int patch_vt1718S(struct hda_codec *codec) 4667static int patch_vt1718S(struct hda_codec *codec)
4976{ 4668{
4977 struct via_spec *spec; 4669 struct via_spec *spec;
@@ -5033,6 +4725,8 @@ static int patch_vt1718S(struct hda_codec *codec)
5033 spec->loopback.amplist = vt1718S_loopbacks; 4725 spec->loopback.amplist = vt1718S_loopbacks;
5034#endif 4726#endif
5035 4727
4728 spec->set_widgets_power_state = set_widgets_power_state_vt1718S;
4729
5036 return 0; 4730 return 0;
5037} 4731}
5038 4732
@@ -5072,13 +4766,12 @@ static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
5072 snd_hda_codec_write(codec, 0x26, 0, 4766 snd_hda_codec_write(codec, 0x26, 0,
5073 AC_VERB_SET_CONNECT_SEL, index); 4767 AC_VERB_SET_CONNECT_SEL, index);
5074 spec->dmic_enabled = index; 4768 spec->dmic_enabled = index;
5075 set_jack_power_state(codec); 4769 set_widgets_power_state(codec);
5076
5077 return 1; 4770 return 1;
5078} 4771}
5079 4772
5080/* capture mixer elements */ 4773/* capture mixer elements */
5081static struct snd_kcontrol_new vt1716S_capture_mixer[] = { 4774static const struct snd_kcontrol_new vt1716S_capture_mixer[] = {
5082 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), 4775 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
5083 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), 4776 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
5084 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), 4777 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
@@ -5097,7 +4790,7 @@ static struct snd_kcontrol_new vt1716S_capture_mixer[] = {
5097 { } /* end */ 4790 { } /* end */
5098}; 4791};
5099 4792
5100static struct snd_kcontrol_new vt1716s_dmic_mixer[] = { 4793static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
5101 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT), 4794 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
5102 { 4795 {
5103 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4796 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -5113,12 +4806,12 @@ static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
5113 4806
5114 4807
5115/* mono-out mixer elements */ 4808/* mono-out mixer elements */
5116static struct snd_kcontrol_new vt1716S_mono_out_mixer[] = { 4809static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
5117 HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT), 4810 HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
5118 { } /* end */ 4811 { } /* end */
5119}; 4812};
5120 4813
5121static struct hda_verb vt1716S_volume_init_verbs[] = { 4814static const struct hda_verb vt1716S_volume_init_verbs[] = {
5122 /* 4815 /*
5123 * Unmute ADC0-1 and set the default input to mic-in 4816 * Unmute ADC0-1 and set the default input to mic-in
5124 */ 4817 */
@@ -5167,7 +4860,7 @@ static struct hda_verb vt1716S_volume_init_verbs[] = {
5167}; 4860};
5168 4861
5169 4862
5170static struct hda_verb vt1716S_uniwill_init_verbs[] = { 4863static const struct hda_verb vt1716S_uniwill_init_verbs[] = {
5171 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 4864 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
5172 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 4865 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
5173 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4866 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -5180,7 +4873,7 @@ static struct hda_verb vt1716S_uniwill_init_verbs[] = {
5180 { } 4873 { }
5181}; 4874};
5182 4875
5183static struct hda_pcm_stream vt1716S_pcm_analog_playback = { 4876static const struct hda_pcm_stream vt1716S_pcm_analog_playback = {
5184 .substreams = 2, 4877 .substreams = 2,
5185 .channels_min = 2, 4878 .channels_min = 2,
5186 .channels_max = 6, 4879 .channels_max = 6,
@@ -5193,7 +4886,7 @@ static struct hda_pcm_stream vt1716S_pcm_analog_playback = {
5193 }, 4886 },
5194}; 4887};
5195 4888
5196static struct hda_pcm_stream vt1716S_pcm_analog_capture = { 4889static const struct hda_pcm_stream vt1716S_pcm_analog_capture = {
5197 .substreams = 2, 4890 .substreams = 2,
5198 .channels_min = 2, 4891 .channels_min = 2,
5199 .channels_max = 2, 4892 .channels_max = 2,
@@ -5206,7 +4899,7 @@ static struct hda_pcm_stream vt1716S_pcm_analog_capture = {
5206 }, 4899 },
5207}; 4900};
5208 4901
5209static struct hda_pcm_stream vt1716S_pcm_digital_playback = { 4902static const struct hda_pcm_stream vt1716S_pcm_digital_playback = {
5210 .substreams = 2, 4903 .substreams = 2,
5211 .channels_min = 2, 4904 .channels_min = 2,
5212 .channels_max = 2, 4905 .channels_max = 2,
@@ -5235,13 +4928,13 @@ static int vt1716S_auto_fill_dac_nids(struct via_spec *spec,
5235 /* config dac list */ 4928 /* config dac list */
5236 switch (i) { 4929 switch (i) {
5237 case AUTO_SEQ_FRONT: 4930 case AUTO_SEQ_FRONT:
5238 spec->multiout.dac_nids[i] = 0x10; 4931 spec->private_dac_nids[i] = 0x10;
5239 break; 4932 break;
5240 case AUTO_SEQ_CENLFE: 4933 case AUTO_SEQ_CENLFE:
5241 spec->multiout.dac_nids[i] = 0x25; 4934 spec->private_dac_nids[i] = 0x25;
5242 break; 4935 break;
5243 case AUTO_SEQ_SURROUND: 4936 case AUTO_SEQ_SURROUND:
5244 spec->multiout.dac_nids[i] = 0x11; 4937 spec->private_dac_nids[i] = 0x11;
5245 break; 4938 break;
5246 } 4939 }
5247 } 4940 }
@@ -5255,7 +4948,9 @@ static int vt1716S_auto_create_multi_out_ctls(struct via_spec *spec,
5255 const struct auto_pin_cfg *cfg) 4948 const struct auto_pin_cfg *cfg)
5256{ 4949{
5257 char name[32]; 4950 char name[32];
5258 static const char *chname[3] = { "Front", "Surround", "C/LFE" }; 4951 static const char * const chname[3] = {
4952 "Front", "Surround", "C/LFE"
4953 };
5259 hda_nid_t nid_vols[] = {0x10, 0x11, 0x25}; 4954 hda_nid_t nid_vols[] = {0x10, 0x11, 0x25};
5260 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x27}; 4955 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x27};
5261 hda_nid_t nid, nid_vol, nid_mute; 4956 hda_nid_t nid, nid_vol, nid_mute;
@@ -5371,49 +5066,12 @@ static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5371} 5066}
5372 5067
5373/* create playback/capture controls for input pins */ 5068/* create playback/capture controls for input pins */
5374static int vt1716S_auto_create_analog_input_ctls(struct via_spec *spec, 5069static int vt1716S_auto_create_analog_input_ctls(struct hda_codec *codec,
5375 const struct auto_pin_cfg *cfg) 5070 const struct auto_pin_cfg *cfg)
5376{ 5071{
5377 static char *labels[] = { 5072 static const hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
5378 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 5073 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
5379 }; 5074 ARRAY_SIZE(pin_idxs));
5380 struct hda_input_mux *imux = &spec->private_imux[0];
5381 int i, err, idx = 0;
5382
5383 /* for internal loopback recording select */
5384 imux->items[imux->num_items].label = "Stereo Mixer";
5385 imux->items[imux->num_items].index = 5;
5386 imux->num_items++;
5387
5388 for (i = 0; i < AUTO_PIN_LAST; i++) {
5389 if (!cfg->input_pins[i])
5390 continue;
5391
5392 switch (cfg->input_pins[i]) {
5393 case 0x1a: /* Mic */
5394 idx = 2;
5395 break;
5396
5397 case 0x1b: /* Line In */
5398 idx = 3;
5399 break;
5400
5401 case 0x1e: /* Front Mic */
5402 idx = 4;
5403 break;
5404
5405 case 0x1f: /* CD */
5406 idx = 1;
5407 break;
5408 }
5409 err = via_new_analog_input(spec, labels[i], idx, 0x16);
5410 if (err < 0)
5411 return err;
5412 imux->items[imux->num_items].label = labels[i];
5413 imux->items[imux->num_items].index = idx-1;
5414 imux->num_items++;
5415 }
5416 return 0;
5417} 5075}
5418 5076
5419static int vt1716S_parse_auto_config(struct hda_codec *codec) 5077static int vt1716S_parse_auto_config(struct hda_codec *codec)
@@ -5436,7 +5094,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
5436 err = vt1716S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 5094 err = vt1716S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5437 if (err < 0) 5095 if (err < 0)
5438 return err; 5096 return err;
5439 err = vt1716S_auto_create_analog_input_ctls(spec, &spec->autocfg); 5097 err = vt1716S_auto_create_analog_input_ctls(codec, &spec->autocfg);
5440 if (err < 0) 5098 if (err < 0)
5441 return err; 5099 return err;
5442 5100
@@ -5458,7 +5116,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
5458} 5116}
5459 5117
5460#ifdef CONFIG_SND_HDA_POWER_SAVE 5118#ifdef CONFIG_SND_HDA_POWER_SAVE
5461static struct hda_amp_list vt1716S_loopbacks[] = { 5119static const struct hda_amp_list vt1716S_loopbacks[] = {
5462 { 0x16, HDA_INPUT, 1 }, 5120 { 0x16, HDA_INPUT, 1 },
5463 { 0x16, HDA_INPUT, 2 }, 5121 { 0x16, HDA_INPUT, 2 },
5464 { 0x16, HDA_INPUT, 3 }, 5122 { 0x16, HDA_INPUT, 3 },
@@ -5467,6 +5125,99 @@ static struct hda_amp_list vt1716S_loopbacks[] = {
5467}; 5125};
5468#endif 5126#endif
5469 5127
5128static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
5129{
5130 struct via_spec *spec = codec->spec;
5131 int imux_is_smixer;
5132 unsigned int parm;
5133 unsigned int mono_out, present;
5134 /* SW0 (17h) = stereo mixer */
5135 imux_is_smixer =
5136 (snd_hda_codec_read(codec, 0x17, 0,
5137 AC_VERB_GET_CONNECT_SEL, 0x00) == 5);
5138 /* inputs */
5139 /* PW 1/2/5 (1ah/1bh/1eh) */
5140 parm = AC_PWRST_D3;
5141 set_pin_power_state(codec, 0x1a, &parm);
5142 set_pin_power_state(codec, 0x1b, &parm);
5143 set_pin_power_state(codec, 0x1e, &parm);
5144 if (imux_is_smixer)
5145 parm = AC_PWRST_D0;
5146 /* SW0 (17h), AIW0(13h) */
5147 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
5148 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
5149
5150 parm = AC_PWRST_D3;
5151 set_pin_power_state(codec, 0x1e, &parm);
5152 /* PW11 (22h) */
5153 if (spec->dmic_enabled)
5154 set_pin_power_state(codec, 0x22, &parm);
5155 else
5156 snd_hda_codec_write(codec, 0x22, 0,
5157 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5158
5159 /* SW2(26h), AIW1(14h) */
5160 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm);
5161 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
5162
5163 /* outputs */
5164 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
5165 parm = AC_PWRST_D3;
5166 set_pin_power_state(codec, 0x19, &parm);
5167 /* Smart 5.1 PW2(1bh) */
5168 if (spec->smart51_enabled)
5169 set_pin_power_state(codec, 0x1b, &parm);
5170 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
5171 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
5172
5173 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
5174 parm = AC_PWRST_D3;
5175 set_pin_power_state(codec, 0x23, &parm);
5176 /* Smart 5.1 PW1(1ah) */
5177 if (spec->smart51_enabled)
5178 set_pin_power_state(codec, 0x1a, &parm);
5179 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm);
5180
5181 /* Smart 5.1 PW5(1eh) */
5182 if (spec->smart51_enabled)
5183 set_pin_power_state(codec, 0x1e, &parm);
5184 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm);
5185
5186 /* Mono out */
5187 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
5188 present = snd_hda_jack_detect(codec, 0x1c);
5189
5190 if (present)
5191 mono_out = 0;
5192 else {
5193 present = snd_hda_jack_detect(codec, 0x1d);
5194 if (!spec->hp_independent_mode && present)
5195 mono_out = 0;
5196 else
5197 mono_out = 1;
5198 }
5199 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
5200 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm);
5201 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm);
5202 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm);
5203
5204 /* PW 3/4 (1ch/1dh) */
5205 parm = AC_PWRST_D3;
5206 set_pin_power_state(codec, 0x1c, &parm);
5207 set_pin_power_state(codec, 0x1d, &parm);
5208 /* HP Independent Mode, power on AOW3 */
5209 if (spec->hp_independent_mode)
5210 snd_hda_codec_write(codec, 0x25, 0,
5211 AC_VERB_SET_POWER_STATE, parm);
5212
5213 /* force to D0 for internal Speaker */
5214 /* MW0 (16h), AOW0 (10h) */
5215 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
5216 imux_is_smixer ? AC_PWRST_D0 : parm);
5217 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
5218 mono_out ? AC_PWRST_D0 : parm);
5219}
5220
5470static int patch_vt1716S(struct hda_codec *codec) 5221static int patch_vt1716S(struct hda_codec *codec)
5471{ 5222{
5472 struct via_spec *spec; 5223 struct via_spec *spec;
@@ -5521,13 +5272,14 @@ static int patch_vt1716S(struct hda_codec *codec)
5521 spec->loopback.amplist = vt1716S_loopbacks; 5272 spec->loopback.amplist = vt1716S_loopbacks;
5522#endif 5273#endif
5523 5274
5275 spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
5524 return 0; 5276 return 0;
5525} 5277}
5526 5278
5527/* for vt2002P */ 5279/* for vt2002P */
5528 5280
5529/* capture mixer elements */ 5281/* capture mixer elements */
5530static struct snd_kcontrol_new vt2002P_capture_mixer[] = { 5282static const struct snd_kcontrol_new vt2002P_capture_mixer[] = {
5531 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), 5283 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5532 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), 5284 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5533 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), 5285 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
@@ -5550,7 +5302,11 @@ static struct snd_kcontrol_new vt2002P_capture_mixer[] = {
5550 { } /* end */ 5302 { } /* end */
5551}; 5303};
5552 5304
5553static struct hda_verb vt2002P_volume_init_verbs[] = { 5305static const struct hda_verb vt2002P_volume_init_verbs[] = {
5306 /* Class-D speaker related verbs */
5307 {0x1, 0xfe0, 0x4},
5308 {0x1, 0xfe9, 0x80},
5309 {0x1, 0xfe2, 0x22},
5554 /* 5310 /*
5555 * Unmute ADC0-1 and set the default input to mic-in 5311 * Unmute ADC0-1 and set the default input to mic-in
5556 */ 5312 */
@@ -5601,9 +5357,60 @@ static struct hda_verb vt2002P_volume_init_verbs[] = {
5601 {0x1, 0xfb8, 0x88}, 5357 {0x1, 0xfb8, 0x88},
5602 { } 5358 { }
5603}; 5359};
5360static const struct hda_verb vt1802_volume_init_verbs[] = {
5361 /*
5362 * Unmute ADC0-1 and set the default input to mic-in
5363 */
5364 {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5365 {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5604 5366
5605 5367
5606static struct hda_verb vt2002P_uniwill_init_verbs[] = { 5368 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5369 * mixer widget
5370 */
5371 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5372 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5373 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5374 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5375 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5376 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5377
5378 /* MUX Indices: Mic = 0 */
5379 {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5380 {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5381
5382 /* PW9 Output enable */
5383 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5384
5385 /* Enable Boost Volume backdoor */
5386 {0x1, 0xfb9, 0x24},
5387
5388 /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5389 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5390 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5391 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5392 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5393 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5394 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5395 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5396 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5397
5398 /* set MUX0/1/4/8 = 0 (AOW0) */
5399 {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5400 {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5401 {0x38, AC_VERB_SET_CONNECT_SEL, 0},
5402 {0x3c, AC_VERB_SET_CONNECT_SEL, 0},
5403
5404 /* set PW0 index=0 (MW0) */
5405 {0x24, AC_VERB_SET_CONNECT_SEL, 0},
5406
5407 /* Enable AOW0 to MW9 */
5408 {0x1, 0xfb8, 0x88},
5409 { }
5410};
5411
5412
5413static const struct hda_verb vt2002P_uniwill_init_verbs[] = {
5607 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, 5414 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
5608 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, 5415 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5609 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE, 5416 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE,
@@ -5613,8 +5420,18 @@ static struct hda_verb vt2002P_uniwill_init_verbs[] = {
5613 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 5420 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5614 { } 5421 { }
5615}; 5422};
5423static const struct hda_verb vt1802_uniwill_init_verbs[] = {
5424 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
5425 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5426 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
5427 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5428 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5429 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5430 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5431 { }
5432};
5616 5433
5617static struct hda_pcm_stream vt2002P_pcm_analog_playback = { 5434static const struct hda_pcm_stream vt2002P_pcm_analog_playback = {
5618 .substreams = 2, 5435 .substreams = 2,
5619 .channels_min = 2, 5436 .channels_min = 2,
5620 .channels_max = 2, 5437 .channels_max = 2,
@@ -5627,7 +5444,7 @@ static struct hda_pcm_stream vt2002P_pcm_analog_playback = {
5627 }, 5444 },
5628}; 5445};
5629 5446
5630static struct hda_pcm_stream vt2002P_pcm_analog_capture = { 5447static const struct hda_pcm_stream vt2002P_pcm_analog_capture = {
5631 .substreams = 2, 5448 .substreams = 2,
5632 .channels_min = 2, 5449 .channels_min = 2,
5633 .channels_max = 2, 5450 .channels_max = 2,
@@ -5640,7 +5457,7 @@ static struct hda_pcm_stream vt2002P_pcm_analog_capture = {
5640 }, 5457 },
5641}; 5458};
5642 5459
5643static struct hda_pcm_stream vt2002P_pcm_digital_playback = { 5460static const struct hda_pcm_stream vt2002P_pcm_digital_playback = {
5644 .substreams = 1, 5461 .substreams = 1,
5645 .channels_min = 2, 5462 .channels_min = 2,
5646 .channels_max = 2, 5463 .channels_max = 2,
@@ -5660,7 +5477,7 @@ static int vt2002P_auto_fill_dac_nids(struct via_spec *spec,
5660 spec->multiout.num_dacs = 1; 5477 spec->multiout.num_dacs = 1;
5661 spec->multiout.dac_nids = spec->private_dac_nids; 5478 spec->multiout.dac_nids = spec->private_dac_nids;
5662 if (cfg->line_out_pins[0]) 5479 if (cfg->line_out_pins[0])
5663 spec->multiout.dac_nids[0] = 0x8; 5480 spec->private_dac_nids[0] = 0x8;
5664 return 0; 5481 return 0;
5665} 5482}
5666 5483
@@ -5669,10 +5486,15 @@ static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec,
5669 const struct auto_pin_cfg *cfg) 5486 const struct auto_pin_cfg *cfg)
5670{ 5487{
5671 int err; 5488 int err;
5489 hda_nid_t sw_nid;
5672 5490
5673 if (!cfg->line_out_pins[0]) 5491 if (!cfg->line_out_pins[0])
5674 return -1; 5492 return -1;
5675 5493
5494 if (spec->codec_type == VT1802)
5495 sw_nid = 0x28;
5496 else
5497 sw_nid = 0x26;
5676 5498
5677 /* Line-Out: PortE */ 5499 /* Line-Out: PortE */
5678 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 5500 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
@@ -5682,7 +5504,7 @@ static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec,
5682 return err; 5504 return err;
5683 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, 5505 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
5684 "Master Front Playback Switch", 5506 "Master Front Playback Switch",
5685 HDA_COMPOSE_AMP_VAL(0x26, 3, 0, HDA_OUTPUT)); 5507 HDA_COMPOSE_AMP_VAL(sw_nid, 3, 0, HDA_OUTPUT));
5686 if (err < 0) 5508 if (err < 0)
5687 return err; 5509 return err;
5688 5510
@@ -5717,54 +5539,25 @@ static int vt2002P_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5717} 5539}
5718 5540
5719/* create playback/capture controls for input pins */ 5541/* create playback/capture controls for input pins */
5720static int vt2002P_auto_create_analog_input_ctls(struct via_spec *spec, 5542static int vt2002P_auto_create_analog_input_ctls(struct hda_codec *codec,
5721 const struct auto_pin_cfg *cfg) 5543 const struct auto_pin_cfg *cfg)
5722{ 5544{
5723 static char *labels[] = { 5545 struct via_spec *spec = codec->spec;
5724 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
5725 };
5726 struct hda_input_mux *imux = &spec->private_imux[0]; 5546 struct hda_input_mux *imux = &spec->private_imux[0];
5727 int i, err, idx = 0; 5547 static const hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff };
5728 5548 int err;
5729 for (i = 0; i < AUTO_PIN_LAST; i++) {
5730 if (!cfg->input_pins[i])
5731 continue;
5732
5733 switch (cfg->input_pins[i]) {
5734 case 0x2b: /* Mic */
5735 idx = 0;
5736 break;
5737
5738 case 0x2a: /* Line In */
5739 idx = 1;
5740 break;
5741
5742 case 0x29: /* Front Mic */
5743 idx = 2;
5744 break;
5745 }
5746 err = via_new_analog_input(spec, labels[i], idx, 0x21);
5747 if (err < 0)
5748 return err;
5749 imux->items[imux->num_items].label = labels[i];
5750 imux->items[imux->num_items].index = idx;
5751 imux->num_items++;
5752 }
5753 5549
5550 err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
5551 ARRAY_SIZE(pin_idxs));
5552 if (err < 0)
5553 return err;
5754 /* build volume/mute control of loopback */ 5554 /* build volume/mute control of loopback */
5755 err = via_new_analog_input(spec, "Stereo Mixer", 3, 0x21); 5555 err = via_new_analog_input(spec, "Stereo Mixer", 0, 3, 0x21);
5756 if (err < 0) 5556 if (err < 0)
5757 return err; 5557 return err;
5758 5558
5759 /* for internal loopback recording select */
5760 imux->items[imux->num_items].label = "Stereo Mixer";
5761 imux->items[imux->num_items].index = 3;
5762 imux->num_items++;
5763
5764 /* for digital mic select */ 5559 /* for digital mic select */
5765 imux->items[imux->num_items].label = "Digital Mic"; 5560 snd_hda_add_imux_item(imux, "Digital Mic", 4, NULL);
5766 imux->items[imux->num_items].index = 4;
5767 imux->num_items++;
5768 5561
5769 return 0; 5562 return 0;
5770} 5563}
@@ -5792,7 +5585,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
5792 err = vt2002P_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 5585 err = vt2002P_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5793 if (err < 0) 5586 if (err < 0)
5794 return err; 5587 return err;
5795 err = vt2002P_auto_create_analog_input_ctls(spec, &spec->autocfg); 5588 err = vt2002P_auto_create_analog_input_ctls(codec, &spec->autocfg);
5796 if (err < 0) 5589 if (err < 0)
5797 return err; 5590 return err;
5798 5591
@@ -5812,7 +5605,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
5812} 5605}
5813 5606
5814#ifdef CONFIG_SND_HDA_POWER_SAVE 5607#ifdef CONFIG_SND_HDA_POWER_SAVE
5815static struct hda_amp_list vt2002P_loopbacks[] = { 5608static const struct hda_amp_list vt2002P_loopbacks[] = {
5816 { 0x21, HDA_INPUT, 0 }, 5609 { 0x21, HDA_INPUT, 0 },
5817 { 0x21, HDA_INPUT, 1 }, 5610 { 0x21, HDA_INPUT, 1 },
5818 { 0x21, HDA_INPUT, 2 }, 5611 { 0x21, HDA_INPUT, 2 },
@@ -5820,6 +5613,116 @@ static struct hda_amp_list vt2002P_loopbacks[] = {
5820}; 5613};
5821#endif 5614#endif
5822 5615
5616static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
5617{
5618 struct via_spec *spec = codec->spec;
5619 int imux_is_smixer;
5620 unsigned int parm;
5621 unsigned int present;
5622 /* MUX9 (1eh) = stereo mixer */
5623 imux_is_smixer =
5624 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
5625 /* inputs */
5626 /* PW 5/6/7 (29h/2ah/2bh) */
5627 parm = AC_PWRST_D3;
5628 set_pin_power_state(codec, 0x29, &parm);
5629 set_pin_power_state(codec, 0x2a, &parm);
5630 set_pin_power_state(codec, 0x2b, &parm);
5631 parm = AC_PWRST_D0;
5632 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
5633 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
5634 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
5635 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
5636 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
5637
5638 /* outputs */
5639 /* AOW0 (8h)*/
5640 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
5641
5642 if (spec->codec_type == VT1802) {
5643 /* PW4 (28h), MW4 (18h), MUX4(38h) */
5644 parm = AC_PWRST_D3;
5645 set_pin_power_state(codec, 0x28, &parm);
5646 snd_hda_codec_write(codec, 0x18, 0,
5647 AC_VERB_SET_POWER_STATE, parm);
5648 snd_hda_codec_write(codec, 0x38, 0,
5649 AC_VERB_SET_POWER_STATE, parm);
5650 } else {
5651 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
5652 parm = AC_PWRST_D3;
5653 set_pin_power_state(codec, 0x26, &parm);
5654 snd_hda_codec_write(codec, 0x1c, 0,
5655 AC_VERB_SET_POWER_STATE, parm);
5656 snd_hda_codec_write(codec, 0x37, 0,
5657 AC_VERB_SET_POWER_STATE, parm);
5658 }
5659
5660 if (spec->codec_type == VT1802) {
5661 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
5662 parm = AC_PWRST_D3;
5663 set_pin_power_state(codec, 0x25, &parm);
5664 snd_hda_codec_write(codec, 0x15, 0,
5665 AC_VERB_SET_POWER_STATE, parm);
5666 snd_hda_codec_write(codec, 0x35, 0,
5667 AC_VERB_SET_POWER_STATE, parm);
5668 } else {
5669 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
5670 parm = AC_PWRST_D3;
5671 set_pin_power_state(codec, 0x25, &parm);
5672 snd_hda_codec_write(codec, 0x19, 0,
5673 AC_VERB_SET_POWER_STATE, parm);
5674 snd_hda_codec_write(codec, 0x35, 0,
5675 AC_VERB_SET_POWER_STATE, parm);
5676 }
5677
5678 if (spec->hp_independent_mode)
5679 snd_hda_codec_write(codec, 0x9, 0,
5680 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
5681
5682 /* Class-D */
5683 /* PW0 (24h), MW0(18h/14h), MUX0(34h) */
5684 present = snd_hda_jack_detect(codec, 0x25);
5685
5686 parm = AC_PWRST_D3;
5687 set_pin_power_state(codec, 0x24, &parm);
5688 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
5689 if (spec->codec_type == VT1802)
5690 snd_hda_codec_write(codec, 0x14, 0,
5691 AC_VERB_SET_POWER_STATE, parm);
5692 else
5693 snd_hda_codec_write(codec, 0x18, 0,
5694 AC_VERB_SET_POWER_STATE, parm);
5695 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm);
5696
5697 /* Mono Out */
5698 present = snd_hda_jack_detect(codec, 0x26);
5699
5700 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
5701 if (spec->codec_type == VT1802) {
5702 /* PW15 (33h), MW8(1ch), MUX8(3ch) */
5703 snd_hda_codec_write(codec, 0x33, 0,
5704 AC_VERB_SET_POWER_STATE, parm);
5705 snd_hda_codec_write(codec, 0x1c, 0,
5706 AC_VERB_SET_POWER_STATE, parm);
5707 snd_hda_codec_write(codec, 0x3c, 0,
5708 AC_VERB_SET_POWER_STATE, parm);
5709 } else {
5710 /* PW15 (31h), MW8(17h), MUX8(3bh) */
5711 snd_hda_codec_write(codec, 0x31, 0,
5712 AC_VERB_SET_POWER_STATE, parm);
5713 snd_hda_codec_write(codec, 0x17, 0,
5714 AC_VERB_SET_POWER_STATE, parm);
5715 snd_hda_codec_write(codec, 0x3b, 0,
5716 AC_VERB_SET_POWER_STATE, parm);
5717 }
5718 /* MW9 (21h) */
5719 if (imux_is_smixer || !is_aa_path_mute(codec))
5720 snd_hda_codec_write(codec, 0x21, 0,
5721 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
5722 else
5723 snd_hda_codec_write(codec, 0x21, 0,
5724 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5725}
5823 5726
5824/* patch for vt2002P */ 5727/* patch for vt2002P */
5825static int patch_vt2002P(struct hda_codec *codec) 5728static int patch_vt2002P(struct hda_codec *codec)
@@ -5842,14 +5745,31 @@ static int patch_vt2002P(struct hda_codec *codec)
5842 "from BIOS. Using genenic mode...\n"); 5745 "from BIOS. Using genenic mode...\n");
5843 } 5746 }
5844 5747
5845 spec->init_verbs[spec->num_iverbs++] = vt2002P_volume_init_verbs; 5748 if (spec->codec_type == VT1802)
5846 spec->init_verbs[spec->num_iverbs++] = vt2002P_uniwill_init_verbs; 5749 spec->init_verbs[spec->num_iverbs++] =
5750 vt1802_volume_init_verbs;
5751 else
5752 spec->init_verbs[spec->num_iverbs++] =
5753 vt2002P_volume_init_verbs;
5754
5755 if (spec->codec_type == VT1802)
5756 spec->init_verbs[spec->num_iverbs++] =
5757 vt1802_uniwill_init_verbs;
5758 else
5759 spec->init_verbs[spec->num_iverbs++] =
5760 vt2002P_uniwill_init_verbs;
5847 5761
5848 spec->stream_name_analog = "VT2002P Analog"; 5762 if (spec->codec_type == VT1802)
5763 spec->stream_name_analog = "VT1802 Analog";
5764 else
5765 spec->stream_name_analog = "VT2002P Analog";
5849 spec->stream_analog_playback = &vt2002P_pcm_analog_playback; 5766 spec->stream_analog_playback = &vt2002P_pcm_analog_playback;
5850 spec->stream_analog_capture = &vt2002P_pcm_analog_capture; 5767 spec->stream_analog_capture = &vt2002P_pcm_analog_capture;
5851 5768
5852 spec->stream_name_digital = "VT2002P Digital"; 5769 if (spec->codec_type == VT1802)
5770 spec->stream_name_digital = "VT1802 Digital";
5771 else
5772 spec->stream_name_digital = "VT2002P Digital";
5853 spec->stream_digital_playback = &vt2002P_pcm_digital_playback; 5773 spec->stream_digital_playback = &vt2002P_pcm_digital_playback;
5854 5774
5855 if (!spec->adc_nids && spec->input_mux) { 5775 if (!spec->adc_nids && spec->input_mux) {
@@ -5871,13 +5791,14 @@ static int patch_vt2002P(struct hda_codec *codec)
5871 spec->loopback.amplist = vt2002P_loopbacks; 5791 spec->loopback.amplist = vt2002P_loopbacks;
5872#endif 5792#endif
5873 5793
5794 spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
5874 return 0; 5795 return 0;
5875} 5796}
5876 5797
5877/* for vt1812 */ 5798/* for vt1812 */
5878 5799
5879/* capture mixer elements */ 5800/* capture mixer elements */
5880static struct snd_kcontrol_new vt1812_capture_mixer[] = { 5801static const struct snd_kcontrol_new vt1812_capture_mixer[] = {
5881 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), 5802 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5882 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), 5803 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5883 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), 5804 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
@@ -5899,7 +5820,7 @@ static struct snd_kcontrol_new vt1812_capture_mixer[] = {
5899 { } /* end */ 5820 { } /* end */
5900}; 5821};
5901 5822
5902static struct hda_verb vt1812_volume_init_verbs[] = { 5823static const struct hda_verb vt1812_volume_init_verbs[] = {
5903 /* 5824 /*
5904 * Unmute ADC0-1 and set the default input to mic-in 5825 * Unmute ADC0-1 and set the default input to mic-in
5905 */ 5826 */
@@ -5952,7 +5873,7 @@ static struct hda_verb vt1812_volume_init_verbs[] = {
5952}; 5873};
5953 5874
5954 5875
5955static struct hda_verb vt1812_uniwill_init_verbs[] = { 5876static const struct hda_verb vt1812_uniwill_init_verbs[] = {
5956 {0x33, AC_VERB_SET_UNSOLICITED_ENABLE, 5877 {0x33, AC_VERB_SET_UNSOLICITED_ENABLE,
5957 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, 5878 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5958 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT }, 5879 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT },
@@ -5964,7 +5885,7 @@ static struct hda_verb vt1812_uniwill_init_verbs[] = {
5964 { } 5885 { }
5965}; 5886};
5966 5887
5967static struct hda_pcm_stream vt1812_pcm_analog_playback = { 5888static const struct hda_pcm_stream vt1812_pcm_analog_playback = {
5968 .substreams = 2, 5889 .substreams = 2,
5969 .channels_min = 2, 5890 .channels_min = 2,
5970 .channels_max = 2, 5891 .channels_max = 2,
@@ -5977,7 +5898,7 @@ static struct hda_pcm_stream vt1812_pcm_analog_playback = {
5977 }, 5898 },
5978}; 5899};
5979 5900
5980static struct hda_pcm_stream vt1812_pcm_analog_capture = { 5901static const struct hda_pcm_stream vt1812_pcm_analog_capture = {
5981 .substreams = 2, 5902 .substreams = 2,
5982 .channels_min = 2, 5903 .channels_min = 2,
5983 .channels_max = 2, 5904 .channels_max = 2,
@@ -5990,7 +5911,7 @@ static struct hda_pcm_stream vt1812_pcm_analog_capture = {
5990 }, 5911 },
5991}; 5912};
5992 5913
5993static struct hda_pcm_stream vt1812_pcm_digital_playback = { 5914static const struct hda_pcm_stream vt1812_pcm_digital_playback = {
5994 .substreams = 1, 5915 .substreams = 1,
5995 .channels_min = 2, 5916 .channels_min = 2,
5996 .channels_max = 2, 5917 .channels_max = 2,
@@ -6009,7 +5930,7 @@ static int vt1812_auto_fill_dac_nids(struct via_spec *spec,
6009 spec->multiout.num_dacs = 1; 5930 spec->multiout.num_dacs = 1;
6010 spec->multiout.dac_nids = spec->private_dac_nids; 5931 spec->multiout.dac_nids = spec->private_dac_nids;
6011 if (cfg->line_out_pins[0]) 5932 if (cfg->line_out_pins[0])
6012 spec->multiout.dac_nids[0] = 0x8; 5933 spec->private_dac_nids[0] = 0x8;
6013 return 0; 5934 return 0;
6014} 5935}
6015 5936
@@ -6067,53 +5988,26 @@ static int vt1812_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
6067} 5988}
6068 5989
6069/* create playback/capture controls for input pins */ 5990/* create playback/capture controls for input pins */
6070static int vt1812_auto_create_analog_input_ctls(struct via_spec *spec, 5991static int vt1812_auto_create_analog_input_ctls(struct hda_codec *codec,
6071 const struct auto_pin_cfg *cfg) 5992 const struct auto_pin_cfg *cfg)
6072{ 5993{
6073 static char *labels[] = { 5994 struct via_spec *spec = codec->spec;
6074 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
6075 };
6076 struct hda_input_mux *imux = &spec->private_imux[0]; 5995 struct hda_input_mux *imux = &spec->private_imux[0];
6077 int i, err, idx = 0; 5996 static const hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff };
6078 5997 int err;
6079 for (i = 0; i < AUTO_PIN_LAST; i++) {
6080 if (!cfg->input_pins[i])
6081 continue;
6082
6083 switch (cfg->input_pins[i]) {
6084 case 0x2b: /* Mic */
6085 idx = 0;
6086 break;
6087 5998
6088 case 0x2a: /* Line In */ 5999 err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
6089 idx = 1; 6000 ARRAY_SIZE(pin_idxs));
6090 break; 6001 if (err < 0)
6002 return err;
6091 6003
6092 case 0x29: /* Front Mic */
6093 idx = 2;
6094 break;
6095 }
6096 err = via_new_analog_input(spec, labels[i], idx, 0x21);
6097 if (err < 0)
6098 return err;
6099 imux->items[imux->num_items].label = labels[i];
6100 imux->items[imux->num_items].index = idx;
6101 imux->num_items++;
6102 }
6103 /* build volume/mute control of loopback */ 6004 /* build volume/mute control of loopback */
6104 err = via_new_analog_input(spec, "Stereo Mixer", 5, 0x21); 6005 err = via_new_analog_input(spec, "Stereo Mixer", 0, 5, 0x21);
6105 if (err < 0) 6006 if (err < 0)
6106 return err; 6007 return err;
6107 6008
6108 /* for internal loopback recording select */
6109 imux->items[imux->num_items].label = "Stereo Mixer";
6110 imux->items[imux->num_items].index = 5;
6111 imux->num_items++;
6112
6113 /* for digital mic select */ 6009 /* for digital mic select */
6114 imux->items[imux->num_items].label = "Digital Mic"; 6010 snd_hda_add_imux_item(imux, "Digital Mic", 6, NULL);
6115 imux->items[imux->num_items].index = 6;
6116 imux->num_items++;
6117 6011
6118 return 0; 6012 return 0;
6119} 6013}
@@ -6141,7 +6035,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
6141 err = vt1812_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 6035 err = vt1812_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
6142 if (err < 0) 6036 if (err < 0)
6143 return err; 6037 return err;
6144 err = vt1812_auto_create_analog_input_ctls(spec, &spec->autocfg); 6038 err = vt1812_auto_create_analog_input_ctls(codec, &spec->autocfg);
6145 if (err < 0) 6039 if (err < 0)
6146 return err; 6040 return err;
6147 6041
@@ -6161,7 +6055,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
6161} 6055}
6162 6056
6163#ifdef CONFIG_SND_HDA_POWER_SAVE 6057#ifdef CONFIG_SND_HDA_POWER_SAVE
6164static struct hda_amp_list vt1812_loopbacks[] = { 6058static const struct hda_amp_list vt1812_loopbacks[] = {
6165 { 0x21, HDA_INPUT, 0 }, 6059 { 0x21, HDA_INPUT, 0 },
6166 { 0x21, HDA_INPUT, 1 }, 6060 { 0x21, HDA_INPUT, 1 },
6167 { 0x21, HDA_INPUT, 2 }, 6061 { 0x21, HDA_INPUT, 2 },
@@ -6169,6 +6063,97 @@ static struct hda_amp_list vt1812_loopbacks[] = {
6169}; 6063};
6170#endif 6064#endif
6171 6065
6066static void set_widgets_power_state_vt1812(struct hda_codec *codec)
6067{
6068 struct via_spec *spec = codec->spec;
6069 int imux_is_smixer =
6070 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
6071 unsigned int parm;
6072 unsigned int present;
6073 /* MUX10 (1eh) = stereo mixer */
6074 imux_is_smixer =
6075 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
6076 /* inputs */
6077 /* PW 5/6/7 (29h/2ah/2bh) */
6078 parm = AC_PWRST_D3;
6079 set_pin_power_state(codec, 0x29, &parm);
6080 set_pin_power_state(codec, 0x2a, &parm);
6081 set_pin_power_state(codec, 0x2b, &parm);
6082 parm = AC_PWRST_D0;
6083 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
6084 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
6085 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
6086 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
6087 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
6088
6089 /* outputs */
6090 /* AOW0 (8h)*/
6091 snd_hda_codec_write(codec, 0x8, 0,
6092 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
6093
6094 /* PW4 (28h), MW4 (18h), MUX4(38h) */
6095 parm = AC_PWRST_D3;
6096 set_pin_power_state(codec, 0x28, &parm);
6097 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
6098 snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm);
6099
6100 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
6101 parm = AC_PWRST_D3;
6102 set_pin_power_state(codec, 0x25, &parm);
6103 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm);
6104 snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm);
6105 if (spec->hp_independent_mode)
6106 snd_hda_codec_write(codec, 0x9, 0,
6107 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
6108
6109 /* Internal Speaker */
6110 /* PW0 (24h), MW0(14h), MUX0(34h) */
6111 present = snd_hda_jack_detect(codec, 0x25);
6112
6113 parm = AC_PWRST_D3;
6114 set_pin_power_state(codec, 0x24, &parm);
6115 if (present) {
6116 snd_hda_codec_write(codec, 0x14, 0,
6117 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
6118 snd_hda_codec_write(codec, 0x34, 0,
6119 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
6120 } else {
6121 snd_hda_codec_write(codec, 0x14, 0,
6122 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
6123 snd_hda_codec_write(codec, 0x34, 0,
6124 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
6125 }
6126
6127
6128 /* Mono Out */
6129 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
6130 present = snd_hda_jack_detect(codec, 0x28);
6131
6132 parm = AC_PWRST_D3;
6133 set_pin_power_state(codec, 0x31, &parm);
6134 if (present) {
6135 snd_hda_codec_write(codec, 0x1c, 0,
6136 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
6137 snd_hda_codec_write(codec, 0x3c, 0,
6138 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
6139 snd_hda_codec_write(codec, 0x3e, 0,
6140 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
6141 } else {
6142 snd_hda_codec_write(codec, 0x1c, 0,
6143 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
6144 snd_hda_codec_write(codec, 0x3c, 0,
6145 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
6146 snd_hda_codec_write(codec, 0x3e, 0,
6147 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
6148 }
6149
6150 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
6151 parm = AC_PWRST_D3;
6152 set_pin_power_state(codec, 0x33, &parm);
6153 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
6154 snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm);
6155
6156}
6172 6157
6173/* patch for vt1812 */ 6158/* patch for vt1812 */
6174static int patch_vt1812(struct hda_codec *codec) 6159static int patch_vt1812(struct hda_codec *codec)
@@ -6222,13 +6207,14 @@ static int patch_vt1812(struct hda_codec *codec)
6222 spec->loopback.amplist = vt1812_loopbacks; 6207 spec->loopback.amplist = vt1812_loopbacks;
6223#endif 6208#endif
6224 6209
6210 spec->set_widgets_power_state = set_widgets_power_state_vt1812;
6225 return 0; 6211 return 0;
6226} 6212}
6227 6213
6228/* 6214/*
6229 * patch entries 6215 * patch entries
6230 */ 6216 */
6231static struct hda_codec_preset snd_hda_preset_via[] = { 6217static const struct hda_codec_preset snd_hda_preset_via[] = {
6232 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708}, 6218 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
6233 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708}, 6219 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
6234 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708}, 6220 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
@@ -6273,7 +6259,7 @@ static struct hda_codec_preset snd_hda_preset_via[] = {
6273 .patch = patch_vt1708S}, 6259 .patch = patch_vt1708S},
6274 { .id = 0x11063397, .name = "VT1708S", 6260 { .id = 0x11063397, .name = "VT1708S",
6275 .patch = patch_vt1708S}, 6261 .patch = patch_vt1708S},
6276 { .id = 0x11064397, .name = "VT1708S", 6262 { .id = 0x11064397, .name = "VT1705",
6277 .patch = patch_vt1708S}, 6263 .patch = patch_vt1708S},
6278 { .id = 0x11065397, .name = "VT1708S", 6264 { .id = 0x11065397, .name = "VT1708S",
6279 .patch = patch_vt1708S}, 6265 .patch = patch_vt1708S},
@@ -6314,6 +6300,10 @@ static struct hda_codec_preset snd_hda_preset_via[] = {
6314 { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812}, 6300 { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
6315 { .id = 0x11060440, .name = "VT1818S", 6301 { .id = 0x11060440, .name = "VT1818S",
6316 .patch = patch_vt1708S}, 6302 .patch = patch_vt1708S},
6303 { .id = 0x11060446, .name = "VT1802",
6304 .patch = patch_vt2002P},
6305 { .id = 0x11068446, .name = "VT1802",
6306 .patch = patch_vt2002P},
6317 {} /* terminator */ 6307 {} /* terminator */
6318}; 6308};
6319 6309
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 2f6252266a02..3e4f8c12ffce 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -148,7 +148,7 @@ static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
148 udelay(100); 148 udelay(100);
149 /* 149 /*
150 * send device address, command and value, 150 * send device address, command and value,
151 * skipping ack cycles inbetween 151 * skipping ack cycles in between
152 */ 152 */
153 for (j = 0; j < 3; j++) { 153 for (j = 0; j < 3; j++) {
154 switch (j) { 154 switch (j) {
@@ -2143,7 +2143,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2143 ice->num_total_adcs = 2; 2143 ice->num_total_adcs = 2;
2144 } 2144 }
2145 2145
2146 /* to remeber the register values of CS8415 */ 2146 /* to remember the register values of CS8415 */
2147 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); 2147 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2148 if (!ice->akm) 2148 if (!ice->akm)
2149 return -ENOMEM; 2149 return -ENOMEM;
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index d216362626d0..20c6b079d0df 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -96,6 +96,11 @@ static unsigned char ap_cs8427_codec_select(struct snd_ice1712 *ice)
96 tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC; 96 tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC;
97 tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL; 97 tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL;
98 break; 98 break;
99 case ICE1712_SUBDEVICE_DELTA66E:
100 tmp |= ICE1712_DELTA_66E_CCLK | ICE1712_DELTA_66E_CS_CHIP_A |
101 ICE1712_DELTA_66E_CS_CHIP_B;
102 tmp &= ~ICE1712_DELTA_66E_CS_CS8427;
103 break;
99 case ICE1712_SUBDEVICE_VX442: 104 case ICE1712_SUBDEVICE_VX442:
100 tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B; 105 tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B;
101 tmp &= ~ICE1712_VX442_CS_DIGITAL; 106 tmp &= ~ICE1712_VX442_CS_DIGITAL;
@@ -119,6 +124,9 @@ static void ap_cs8427_codec_deassert(struct snd_ice1712 *ice, unsigned char tmp)
119 case ICE1712_SUBDEVICE_DELTA410: 124 case ICE1712_SUBDEVICE_DELTA410:
120 tmp |= ICE1712_DELTA_AP_CS_DIGITAL; 125 tmp |= ICE1712_DELTA_AP_CS_DIGITAL;
121 break; 126 break;
127 case ICE1712_SUBDEVICE_DELTA66E:
128 tmp |= ICE1712_DELTA_66E_CS_CS8427;
129 break;
122 case ICE1712_SUBDEVICE_VX442: 130 case ICE1712_SUBDEVICE_VX442:
123 tmp |= ICE1712_VX442_CS_DIGITAL; 131 tmp |= ICE1712_VX442_CS_DIGITAL;
124 break; 132 break;
@@ -276,6 +284,20 @@ static void delta1010lt_ak4524_lock(struct snd_akm4xxx *ak, int chip)
276} 284}
277 285
278/* 286/*
287 * AK4524 on Delta66 rev E to choose the chip address
288 */
289static void delta66e_ak4524_lock(struct snd_akm4xxx *ak, int chip)
290{
291 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
292 struct snd_ice1712 *ice = ak->private_data[0];
293
294 snd_ice1712_save_gpio_status(ice);
295 priv->cs_mask =
296 priv->cs_addr = chip == 0 ? ICE1712_DELTA_66E_CS_CHIP_A :
297 ICE1712_DELTA_66E_CS_CHIP_B;
298}
299
300/*
279 * AK4528 on VX442 to choose the chip mask 301 * AK4528 on VX442 to choose the chip mask
280 */ 302 */
281static void vx442_ak4524_lock(struct snd_akm4xxx *ak, int chip) 303static void vx442_ak4524_lock(struct snd_akm4xxx *ak, int chip)
@@ -487,6 +509,29 @@ static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
487 .mask_flags = 0, 509 .mask_flags = 0,
488}; 510};
489 511
512static struct snd_akm4xxx akm_delta66e __devinitdata = {
513 .type = SND_AK4524,
514 .num_adcs = 4,
515 .num_dacs = 4,
516 .ops = {
517 .lock = delta66e_ak4524_lock,
518 .set_rate_val = delta_ak4524_set_rate_val
519 }
520};
521
522static struct snd_ak4xxx_private akm_delta66e_priv __devinitdata = {
523 .caddr = 2,
524 .cif = 0, /* the default level of the CIF pin from AK4524 */
525 .data_mask = ICE1712_DELTA_66E_DOUT,
526 .clk_mask = ICE1712_DELTA_66E_CCLK,
527 .cs_mask = 0,
528 .cs_addr = 0, /* set later */
529 .cs_none = 0,
530 .add_flags = 0,
531 .mask_flags = 0,
532};
533
534
490static struct snd_akm4xxx akm_delta44 __devinitdata = { 535static struct snd_akm4xxx akm_delta44 __devinitdata = {
491 .type = SND_AK4524, 536 .type = SND_AK4524,
492 .num_adcs = 4, 537 .num_adcs = 4,
@@ -535,6 +580,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
535{ 580{
536 int err; 581 int err;
537 struct snd_akm4xxx *ak; 582 struct snd_akm4xxx *ak;
583 unsigned char tmp;
538 584
539 if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA1010 && 585 if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA1010 &&
540 ice->eeprom.gpiodir == 0x7b) 586 ice->eeprom.gpiodir == 0x7b)
@@ -563,6 +609,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
563 case ICE1712_SUBDEVICE_DELTA1010E: 609 case ICE1712_SUBDEVICE_DELTA1010E:
564 case ICE1712_SUBDEVICE_DELTA1010LT: 610 case ICE1712_SUBDEVICE_DELTA1010LT:
565 case ICE1712_SUBDEVICE_MEDIASTATION: 611 case ICE1712_SUBDEVICE_MEDIASTATION:
612 case ICE1712_SUBDEVICE_EDIROLDA2496:
566 ice->num_total_dacs = 8; 613 ice->num_total_dacs = 8;
567 ice->num_total_adcs = 8; 614 ice->num_total_adcs = 8;
568 break; 615 break;
@@ -576,6 +623,12 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
576 break; 623 break;
577 } 624 }
578 625
626 /* initialize the SPI clock to high */
627 tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
628 tmp |= ICE1712_DELTA_AP_CCLK;
629 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
630 udelay(5);
631
579 /* initialize spdif */ 632 /* initialize spdif */
580 switch (ice->eeprom.subvendor) { 633 switch (ice->eeprom.subvendor) {
581 case ICE1712_SUBDEVICE_AUDIOPHILE: 634 case ICE1712_SUBDEVICE_AUDIOPHILE:
@@ -635,6 +688,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
635 err = snd_ice1712_akm4xxx_init(ak, &akm_delta410, &akm_delta410_priv, ice); 688 err = snd_ice1712_akm4xxx_init(ak, &akm_delta410, &akm_delta410_priv, ice);
636 break; 689 break;
637 case ICE1712_SUBDEVICE_DELTA1010LT: 690 case ICE1712_SUBDEVICE_DELTA1010LT:
691 case ICE1712_SUBDEVICE_EDIROLDA2496:
638 err = snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, &akm_delta1010lt_priv, ice); 692 err = snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, &akm_delta1010lt_priv, ice);
639 break; 693 break;
640 case ICE1712_SUBDEVICE_DELTA66: 694 case ICE1712_SUBDEVICE_DELTA66:
@@ -642,9 +696,11 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
642 err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice); 696 err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice);
643 break; 697 break;
644 case ICE1712_SUBDEVICE_VX442: 698 case ICE1712_SUBDEVICE_VX442:
645 case ICE1712_SUBDEVICE_DELTA66E:
646 err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice); 699 err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice);
647 break; 700 break;
701 case ICE1712_SUBDEVICE_DELTA66E:
702 err = snd_ice1712_akm4xxx_init(ak, &akm_delta66e, &akm_delta66e_priv, ice);
703 break;
648 default: 704 default:
649 snd_BUG(); 705 snd_BUG();
650 return -EINVAL; 706 return -EINVAL;
@@ -734,6 +790,7 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)
734 case ICE1712_SUBDEVICE_DELTA66: 790 case ICE1712_SUBDEVICE_DELTA66:
735 case ICE1712_SUBDEVICE_VX442: 791 case ICE1712_SUBDEVICE_VX442:
736 case ICE1712_SUBDEVICE_DELTA66E: 792 case ICE1712_SUBDEVICE_DELTA66E:
793 case ICE1712_SUBDEVICE_EDIROLDA2496:
737 err = snd_ice1712_akm4xxx_build_controls(ice); 794 err = snd_ice1712_akm4xxx_build_controls(ice);
738 if (err < 0) 795 if (err < 0)
739 return err; 796 return err;
@@ -813,5 +870,12 @@ struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
813 .chip_init = snd_ice1712_delta_init, 870 .chip_init = snd_ice1712_delta_init,
814 .build_controls = snd_ice1712_delta_add_controls, 871 .build_controls = snd_ice1712_delta_add_controls,
815 }, 872 },
873 {
874 .subvendor = ICE1712_SUBDEVICE_EDIROLDA2496,
875 .name = "Edirol DA2496",
876 .model = "da2496",
877 .chip_init = snd_ice1712_delta_init,
878 .build_controls = snd_ice1712_delta_add_controls,
879 },
816 { } /* terminator */ 880 { } /* terminator */
817}; 881};
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
index f7f14df81f26..11a9c3a76507 100644
--- a/sound/pci/ice1712/delta.h
+++ b/sound/pci/ice1712/delta.h
@@ -34,7 +34,8 @@
34 "{MidiMan M Audio,Delta 410},"\ 34 "{MidiMan M Audio,Delta 410},"\
35 "{MidiMan M Audio,Audiophile 24/96},"\ 35 "{MidiMan M Audio,Audiophile 24/96},"\
36 "{Digigram,VX442},"\ 36 "{Digigram,VX442},"\
37 "{Lionstracs,Mediastation}," 37 "{Lionstracs,Mediastation},"\
38 "{Edirol,DA2496},"
38 39
39#define ICE1712_SUBDEVICE_DELTA1010 0x121430d6 40#define ICE1712_SUBDEVICE_DELTA1010 0x121430d6
40#define ICE1712_SUBDEVICE_DELTA1010E 0xff1430d6 41#define ICE1712_SUBDEVICE_DELTA1010E 0xff1430d6
@@ -47,6 +48,7 @@
47#define ICE1712_SUBDEVICE_DELTA1010LT 0x12143bd6 48#define ICE1712_SUBDEVICE_DELTA1010LT 0x12143bd6
48#define ICE1712_SUBDEVICE_VX442 0x12143cd6 49#define ICE1712_SUBDEVICE_VX442 0x12143cd6
49#define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100 50#define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100
51#define ICE1712_SUBDEVICE_EDIROLDA2496 0xce164010
50 52
51/* entry point */ 53/* entry point */
52extern struct snd_ice1712_card_info snd_ice1712_delta_cards[]; 54extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
@@ -142,6 +144,17 @@ extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
142#define ICE1712_DELTA_1010LT_CS_NONE 0x50 /* nothing */ 144#define ICE1712_DELTA_1010LT_CS_NONE 0x50 /* nothing */
143#define ICE1712_DELTA_1010LT_WORDCLOCK 0x80 /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */ 145#define ICE1712_DELTA_1010LT_WORDCLOCK 0x80 /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */
144 146
147/* M-Audio Delta 66 rev. E definitions.
148 * Newer revisions of Delta 66 have CS8427 over SPI for
149 * S/PDIF transceiver instead of CS8404/CS8414. */
150/* 0x01 = DFS */
151#define ICE1712_DELTA_66E_CCLK 0x02 /* SPI clock */
152#define ICE1712_DELTA_66E_DIN 0x04 /* data input */
153#define ICE1712_DELTA_66E_DOUT 0x08 /* data output */
154#define ICE1712_DELTA_66E_CS_CS8427 0x10 /* chip select, low = CS8427 */
155#define ICE1712_DELTA_66E_CS_CHIP_A 0x20 /* AK4524 #0 */
156#define ICE1712_DELTA_66E_CS_CHIP_B 0x40 /* AK4524 #1 */
157
145/* Digigram VX442 definitions */ 158/* Digigram VX442 definitions */
146#define ICE1712_VX442_CCLK 0x02 /* SPI clock */ 159#define ICE1712_VX442_CCLK 0x02 /* SPI clock */
147#define ICE1712_VX442_DIN 0x04 /* data input */ 160#define ICE1712_VX442_DIN 0x04 /* data input */
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 4fc6d8bc637e..f4594d76b6ea 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2755,7 +2755,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2755 return err; 2755 return err;
2756 } 2756 }
2757 if (c->mpu401_1_name) 2757 if (c->mpu401_1_name)
2758 /* Prefered name available in card_info */ 2758 /* Preferred name available in card_info */
2759 snprintf(ice->rmidi[0]->name, 2759 snprintf(ice->rmidi[0]->name,
2760 sizeof(ice->rmidi[0]->name), 2760 sizeof(ice->rmidi[0]->name),
2761 "%s %d", c->mpu401_1_name, card->number); 2761 "%s %d", c->mpu401_1_name, card->number);
@@ -2772,7 +2772,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2772 return err; 2772 return err;
2773 } 2773 }
2774 if (c->mpu401_2_name) 2774 if (c->mpu401_2_name)
2775 /* Prefered name available in card_info */ 2775 /* Preferred name available in card_info */
2776 snprintf(ice->rmidi[1]->name, 2776 snprintf(ice->rmidi[1]->name,
2777 sizeof(ice->rmidi[1]->name), 2777 sizeof(ice->rmidi[1]->name),
2778 "%s %d", c->mpu401_2_name, 2778 "%s %d", c->mpu401_2_name,
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index 6bc3f91b7281..92c1160d7ab5 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -638,7 +638,7 @@ static struct snd_kcontrol_new pontis_controls[] __devinitdata = {
638 */ 638 */
639static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 639static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
640{ 640{
641 struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; 641 struct snd_ice1712 *ice = entry->private_data;
642 char line[64]; 642 char line[64];
643 unsigned int reg, val; 643 unsigned int reg, val;
644 mutex_lock(&ice->gpio_mutex); 644 mutex_lock(&ice->gpio_mutex);
@@ -653,7 +653,7 @@ static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buf
653 653
654static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 654static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
655{ 655{
656 struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; 656 struct snd_ice1712 *ice = entry->private_data;
657 int reg, val; 657 int reg, val;
658 658
659 mutex_lock(&ice->gpio_mutex); 659 mutex_lock(&ice->gpio_mutex);
@@ -676,7 +676,7 @@ static void wm_proc_init(struct snd_ice1712 *ice)
676 676
677static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 677static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
678{ 678{
679 struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; 679 struct snd_ice1712 *ice = entry->private_data;
680 int reg, val; 680 int reg, val;
681 681
682 mutex_lock(&ice->gpio_mutex); 682 mutex_lock(&ice->gpio_mutex);
@@ -768,7 +768,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice)
768 ice->num_total_dacs = 2; 768 ice->num_total_dacs = 2;
769 ice->num_total_adcs = 2; 769 ice->num_total_adcs = 2;
770 770
771 /* to remeber the register values */ 771 /* to remember the register values */
772 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); 772 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
773 if (! ice->akm) 773 if (! ice->akm)
774 return -ENOMEM; 774 return -ENOMEM;
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
index 2a8e5cd8f2d8..e36ddb94c382 100644
--- a/sound/pci/ice1712/prodigy192.c
+++ b/sound/pci/ice1712/prodigy192.c
@@ -654,7 +654,7 @@ static int prodigy192_ak4114_init(struct snd_ice1712 *ice)
654static void stac9460_proc_regs_read(struct snd_info_entry *entry, 654static void stac9460_proc_regs_read(struct snd_info_entry *entry,
655 struct snd_info_buffer *buffer) 655 struct snd_info_buffer *buffer)
656{ 656{
657 struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; 657 struct snd_ice1712 *ice = entry->private_data;
658 int reg, val; 658 int reg, val;
659 /* registers 0x0 - 0x14 */ 659 /* registers 0x0 - 0x14 */
660 for (reg = 0; reg <= 0x15; reg++) { 660 for (reg = 0; reg <= 0x15; reg++) {
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c
index 6a9fee3ee78f..764cc93dbca4 100644
--- a/sound/pci/ice1712/prodigy_hifi.c
+++ b/sound/pci/ice1712/prodigy_hifi.c
@@ -1046,7 +1046,7 @@ static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice)
1046 * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten 1046 * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
1047 */ 1047 */
1048 ice->gpio.saved[0] = 0; 1048 ice->gpio.saved[0] = 0;
1049 /* to remeber the register values */ 1049 /* to remember the register values */
1050 1050
1051 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); 1051 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1052 if (! ice->akm) 1052 if (! ice->akm)
@@ -1128,7 +1128,7 @@ static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)
1128 * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten 1128 * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
1129 */ 1129 */
1130 ice->gpio.saved[0] = 0; 1130 ice->gpio.saved[0] = 0;
1131 /* to remeber the register values */ 1131 /* to remember the register values */
1132 1132
1133 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); 1133 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1134 if (! ice->akm) 1134 if (! ice->akm)
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 467749249576..6c896dbfd796 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -534,7 +534,7 @@ static int snd_intel8x0_codec_semaphore(struct intel8x0 *chip, unsigned int code
534 udelay(10); 534 udelay(10);
535 } while (time--); 535 } while (time--);
536 536
537 /* access to some forbidden (non existant) ac97 registers will not 537 /* access to some forbidden (non existent) ac97 registers will not
538 * reset the semaphore. So even if you don't get the semaphore, still 538 * reset the semaphore. So even if you don't get the semaphore, still
539 * continue the access. We don't need the semaphore anyway. */ 539 * continue the access. We don't need the semaphore anyway. */
540 snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n", 540 snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
@@ -716,7 +716,7 @@ static void snd_intel8x0_setup_periods(struct intel8x0 *chip, struct ichdev *ich
716 * Intel 82443MX running a 100MHz processor system bus has a hardware bug, 716 * Intel 82443MX running a 100MHz processor system bus has a hardware bug,
717 * which aborts PCI busmaster for audio transfer. A workaround is to set 717 * which aborts PCI busmaster for audio transfer. A workaround is to set
718 * the pages as non-cached. For details, see the errata in 718 * the pages as non-cached. For details, see the errata in
719 * http://www.intel.com/design/chipsets/specupdt/245051.htm 719 * http://download.intel.com/design/chipsets/specupdt/24505108.pdf
720 */ 720 */
721static void fill_nocache(void *buf, int size, int nocache) 721static void fill_nocache(void *buf, int size, int nocache)
722{ 722{
@@ -1866,6 +1866,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
1866 }, 1866 },
1867 { 1867 {
1868 .subvendor = 0x1028, 1868 .subvendor = 0x1028,
1869 .subdevice = 0x0182,
1870 .name = "Dell Latitude D610", /* STAC9750/51 */
1871 .type = AC97_TUNE_HP_ONLY
1872 },
1873 {
1874 .subvendor = 0x1028,
1869 .subdevice = 0x0186, 1875 .subdevice = 0x0186,
1870 .name = "Dell Latitude D810", /* cf. Malone #41015 */ 1876 .name = "Dell Latitude D810", /* cf. Malone #41015 */
1871 .type = AC97_TUNE_HP_MUTE_LED 1877 .type = AC97_TUNE_HP_MUTE_LED
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 13cec1e5ced9..f3353b49c785 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -235,8 +235,8 @@ static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0m_ids) = {
235 { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */ 235 { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */
236 { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */ 236 { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */
237 { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */ 237 { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */
238 { PCI_VDEVICE(AMD, 0x746e), DEVICE_INTEL }, /* AMD8111 */
238#if 0 239#if 0
239 { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */
240 { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */ 240 { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */
241#endif 241#endif
242 { 0, } 242 { 0, }
@@ -331,7 +331,7 @@ static int snd_intel8x0m_codec_semaphore(struct intel8x0m *chip, unsigned int co
331 udelay(10); 331 udelay(10);
332 } while (time--); 332 } while (time--);
333 333
334 /* access to some forbidden (non existant) ac97 registers will not 334 /* access to some forbidden (non existent) ac97 registers will not
335 * reset the semaphore. So even if you don't get the semaphore, still 335 * reset the semaphore. So even if you don't get the semaphore, still
336 * continue the access. We don't need the semaphore anyway. */ 336 * continue the access. We don't need the semaphore anyway. */
337 snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n", 337 snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
@@ -341,9 +341,9 @@ static int snd_intel8x0m_codec_semaphore(struct intel8x0m *chip, unsigned int co
341 return -EBUSY; 341 return -EBUSY;
342} 342}
343 343
344static void snd_intel8x0_codec_write(struct snd_ac97 *ac97, 344static void snd_intel8x0m_codec_write(struct snd_ac97 *ac97,
345 unsigned short reg, 345 unsigned short reg,
346 unsigned short val) 346 unsigned short val)
347{ 347{
348 struct intel8x0m *chip = ac97->private_data; 348 struct intel8x0m *chip = ac97->private_data;
349 349
@@ -354,8 +354,8 @@ static void snd_intel8x0_codec_write(struct snd_ac97 *ac97,
354 iaputword(chip, reg + ac97->num * 0x80, val); 354 iaputword(chip, reg + ac97->num * 0x80, val);
355} 355}
356 356
357static unsigned short snd_intel8x0_codec_read(struct snd_ac97 *ac97, 357static unsigned short snd_intel8x0m_codec_read(struct snd_ac97 *ac97,
358 unsigned short reg) 358 unsigned short reg)
359{ 359{
360 struct intel8x0m *chip = ac97->private_data; 360 struct intel8x0m *chip = ac97->private_data;
361 unsigned short res; 361 unsigned short res;
@@ -385,7 +385,7 @@ static unsigned short snd_intel8x0_codec_read(struct snd_ac97 *ac97,
385/* 385/*
386 * DMA I/O 386 * DMA I/O
387 */ 387 */
388static void snd_intel8x0_setup_periods(struct intel8x0m *chip, struct ichdev *ichdev) 388static void snd_intel8x0m_setup_periods(struct intel8x0m *chip, struct ichdev *ichdev)
389{ 389{
390 int idx; 390 int idx;
391 u32 *bdbar = ichdev->bdbar; 391 u32 *bdbar = ichdev->bdbar;
@@ -437,7 +437,7 @@ static void snd_intel8x0_setup_periods(struct intel8x0m *chip, struct ichdev *ic
437 * Interrupt handler 437 * Interrupt handler
438 */ 438 */
439 439
440static inline void snd_intel8x0_update(struct intel8x0m *chip, struct ichdev *ichdev) 440static inline void snd_intel8x0m_update(struct intel8x0m *chip, struct ichdev *ichdev)
441{ 441{
442 unsigned long port = ichdev->reg_offset; 442 unsigned long port = ichdev->reg_offset;
443 int civ, i, step; 443 int civ, i, step;
@@ -489,7 +489,7 @@ static inline void snd_intel8x0_update(struct intel8x0m *chip, struct ichdev *ic
489 iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI); 489 iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
490} 490}
491 491
492static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id) 492static irqreturn_t snd_intel8x0m_interrupt(int irq, void *dev_id)
493{ 493{
494 struct intel8x0m *chip = dev_id; 494 struct intel8x0m *chip = dev_id;
495 struct ichdev *ichdev; 495 struct ichdev *ichdev;
@@ -512,7 +512,7 @@ static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id)
512 for (i = 0; i < chip->bdbars_count; i++) { 512 for (i = 0; i < chip->bdbars_count; i++) {
513 ichdev = &chip->ichd[i]; 513 ichdev = &chip->ichd[i];
514 if (status & ichdev->int_sta_mask) 514 if (status & ichdev->int_sta_mask)
515 snd_intel8x0_update(chip, ichdev); 515 snd_intel8x0m_update(chip, ichdev);
516 } 516 }
517 517
518 /* ack them */ 518 /* ack them */
@@ -526,7 +526,7 @@ static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id)
526 * PCM part 526 * PCM part
527 */ 527 */
528 528
529static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 529static int snd_intel8x0m_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
530{ 530{
531 struct intel8x0m *chip = snd_pcm_substream_chip(substream); 531 struct intel8x0m *chip = snd_pcm_substream_chip(substream);
532 struct ichdev *ichdev = get_ichdev(substream); 532 struct ichdev *ichdev = get_ichdev(substream);
@@ -561,18 +561,18 @@ static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd
561 return 0; 561 return 0;
562} 562}
563 563
564static int snd_intel8x0_hw_params(struct snd_pcm_substream *substream, 564static int snd_intel8x0m_hw_params(struct snd_pcm_substream *substream,
565 struct snd_pcm_hw_params *hw_params) 565 struct snd_pcm_hw_params *hw_params)
566{ 566{
567 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); 567 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
568} 568}
569 569
570static int snd_intel8x0_hw_free(struct snd_pcm_substream *substream) 570static int snd_intel8x0m_hw_free(struct snd_pcm_substream *substream)
571{ 571{
572 return snd_pcm_lib_free_pages(substream); 572 return snd_pcm_lib_free_pages(substream);
573} 573}
574 574
575static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *substream) 575static snd_pcm_uframes_t snd_intel8x0m_pcm_pointer(struct snd_pcm_substream *substream)
576{ 576{
577 struct intel8x0m *chip = snd_pcm_substream_chip(substream); 577 struct intel8x0m *chip = snd_pcm_substream_chip(substream);
578 struct ichdev *ichdev = get_ichdev(substream); 578 struct ichdev *ichdev = get_ichdev(substream);
@@ -600,7 +600,7 @@ static int snd_intel8x0m_pcm_prepare(struct snd_pcm_substream *substream)
600 ichdev->fragsize = snd_pcm_lib_period_bytes(substream); 600 ichdev->fragsize = snd_pcm_lib_period_bytes(substream);
601 snd_ac97_write(ichdev->ac97, AC97_LINE1_RATE, runtime->rate); 601 snd_ac97_write(ichdev->ac97, AC97_LINE1_RATE, runtime->rate);
602 snd_ac97_write(ichdev->ac97, AC97_LINE1_LEVEL, 0); 602 snd_ac97_write(ichdev->ac97, AC97_LINE1_LEVEL, 0);
603 snd_intel8x0_setup_periods(chip, ichdev); 603 snd_intel8x0m_setup_periods(chip, ichdev);
604 return 0; 604 return 0;
605} 605}
606 606
@@ -682,22 +682,22 @@ static struct snd_pcm_ops snd_intel8x0m_playback_ops = {
682 .open = snd_intel8x0m_playback_open, 682 .open = snd_intel8x0m_playback_open,
683 .close = snd_intel8x0m_playback_close, 683 .close = snd_intel8x0m_playback_close,
684 .ioctl = snd_pcm_lib_ioctl, 684 .ioctl = snd_pcm_lib_ioctl,
685 .hw_params = snd_intel8x0_hw_params, 685 .hw_params = snd_intel8x0m_hw_params,
686 .hw_free = snd_intel8x0_hw_free, 686 .hw_free = snd_intel8x0m_hw_free,
687 .prepare = snd_intel8x0m_pcm_prepare, 687 .prepare = snd_intel8x0m_pcm_prepare,
688 .trigger = snd_intel8x0_pcm_trigger, 688 .trigger = snd_intel8x0m_pcm_trigger,
689 .pointer = snd_intel8x0_pcm_pointer, 689 .pointer = snd_intel8x0m_pcm_pointer,
690}; 690};
691 691
692static struct snd_pcm_ops snd_intel8x0m_capture_ops = { 692static struct snd_pcm_ops snd_intel8x0m_capture_ops = {
693 .open = snd_intel8x0m_capture_open, 693 .open = snd_intel8x0m_capture_open,
694 .close = snd_intel8x0m_capture_close, 694 .close = snd_intel8x0m_capture_close,
695 .ioctl = snd_pcm_lib_ioctl, 695 .ioctl = snd_pcm_lib_ioctl,
696 .hw_params = snd_intel8x0_hw_params, 696 .hw_params = snd_intel8x0m_hw_params,
697 .hw_free = snd_intel8x0_hw_free, 697 .hw_free = snd_intel8x0m_hw_free,
698 .prepare = snd_intel8x0m_pcm_prepare, 698 .prepare = snd_intel8x0m_pcm_prepare,
699 .trigger = snd_intel8x0_pcm_trigger, 699 .trigger = snd_intel8x0m_pcm_trigger,
700 .pointer = snd_intel8x0_pcm_pointer, 700 .pointer = snd_intel8x0m_pcm_pointer,
701}; 701};
702 702
703 703
@@ -710,7 +710,7 @@ struct ich_pcm_table {
710 int ac97_idx; 710 int ac97_idx;
711}; 711};
712 712
713static int __devinit snd_intel8x0_pcm1(struct intel8x0m *chip, int device, 713static int __devinit snd_intel8x0m_pcm1(struct intel8x0m *chip, int device,
714 struct ich_pcm_table *rec) 714 struct ich_pcm_table *rec)
715{ 715{
716 struct snd_pcm *pcm; 716 struct snd_pcm *pcm;
@@ -759,7 +759,7 @@ static struct ich_pcm_table intel_pcms[] __devinitdata = {
759 }, 759 },
760}; 760};
761 761
762static int __devinit snd_intel8x0_pcm(struct intel8x0m *chip) 762static int __devinit snd_intel8x0m_pcm(struct intel8x0m *chip)
763{ 763{
764 int i, tblsize, device, err; 764 int i, tblsize, device, err;
765 struct ich_pcm_table *tbl, *rec; 765 struct ich_pcm_table *tbl, *rec;
@@ -791,7 +791,7 @@ static int __devinit snd_intel8x0_pcm(struct intel8x0m *chip)
791 if (! chip->ichd[rec->ac97_idx].ac97) 791 if (! chip->ichd[rec->ac97_idx].ac97)
792 continue; 792 continue;
793 } 793 }
794 err = snd_intel8x0_pcm1(chip, device, rec); 794 err = snd_intel8x0m_pcm1(chip, device, rec);
795 if (err < 0) 795 if (err < 0)
796 return err; 796 return err;
797 device++; 797 device++;
@@ -806,20 +806,20 @@ static int __devinit snd_intel8x0_pcm(struct intel8x0m *chip)
806 * Mixer part 806 * Mixer part
807 */ 807 */
808 808
809static void snd_intel8x0_mixer_free_ac97_bus(struct snd_ac97_bus *bus) 809static void snd_intel8x0m_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
810{ 810{
811 struct intel8x0m *chip = bus->private_data; 811 struct intel8x0m *chip = bus->private_data;
812 chip->ac97_bus = NULL; 812 chip->ac97_bus = NULL;
813} 813}
814 814
815static void snd_intel8x0_mixer_free_ac97(struct snd_ac97 *ac97) 815static void snd_intel8x0m_mixer_free_ac97(struct snd_ac97 *ac97)
816{ 816{
817 struct intel8x0m *chip = ac97->private_data; 817 struct intel8x0m *chip = ac97->private_data;
818 chip->ac97 = NULL; 818 chip->ac97 = NULL;
819} 819}
820 820
821 821
822static int __devinit snd_intel8x0_mixer(struct intel8x0m *chip, int ac97_clock) 822static int __devinit snd_intel8x0m_mixer(struct intel8x0m *chip, int ac97_clock)
823{ 823{
824 struct snd_ac97_bus *pbus; 824 struct snd_ac97_bus *pbus;
825 struct snd_ac97_template ac97; 825 struct snd_ac97_template ac97;
@@ -827,22 +827,22 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0m *chip, int ac97_clock)
827 int err; 827 int err;
828 unsigned int glob_sta = 0; 828 unsigned int glob_sta = 0;
829 static struct snd_ac97_bus_ops ops = { 829 static struct snd_ac97_bus_ops ops = {
830 .write = snd_intel8x0_codec_write, 830 .write = snd_intel8x0m_codec_write,
831 .read = snd_intel8x0_codec_read, 831 .read = snd_intel8x0m_codec_read,
832 }; 832 };
833 833
834 chip->in_ac97_init = 1; 834 chip->in_ac97_init = 1;
835 835
836 memset(&ac97, 0, sizeof(ac97)); 836 memset(&ac97, 0, sizeof(ac97));
837 ac97.private_data = chip; 837 ac97.private_data = chip;
838 ac97.private_free = snd_intel8x0_mixer_free_ac97; 838 ac97.private_free = snd_intel8x0m_mixer_free_ac97;
839 ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE; 839 ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
840 840
841 glob_sta = igetdword(chip, ICHREG(GLOB_STA)); 841 glob_sta = igetdword(chip, ICHREG(GLOB_STA));
842 842
843 if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0) 843 if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
844 goto __err; 844 goto __err;
845 pbus->private_free = snd_intel8x0_mixer_free_ac97_bus; 845 pbus->private_free = snd_intel8x0m_mixer_free_ac97_bus;
846 if (ac97_clock >= 8000 && ac97_clock <= 48000) 846 if (ac97_clock >= 8000 && ac97_clock <= 48000)
847 pbus->clock = ac97_clock; 847 pbus->clock = ac97_clock;
848 chip->ac97_bus = pbus; 848 chip->ac97_bus = pbus;
@@ -894,7 +894,8 @@ static int snd_intel8x0m_ich_chip_init(struct intel8x0m *chip, int probing)
894 /* finish cold or do warm reset */ 894 /* finish cold or do warm reset */
895 cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM; 895 cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM;
896 iputdword(chip, ICHREG(GLOB_CNT), cnt); 896 iputdword(chip, ICHREG(GLOB_CNT), cnt);
897 end_time = (jiffies + (HZ / 4)) + 1; 897 usleep_range(500, 1000); /* give warm reset some time */
898 end_time = jiffies + HZ / 4;
898 do { 899 do {
899 if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0) 900 if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0)
900 goto __ok; 901 goto __ok;
@@ -959,7 +960,7 @@ static int snd_intel8x0m_ich_chip_init(struct intel8x0m *chip, int probing)
959 return 0; 960 return 0;
960} 961}
961 962
962static int snd_intel8x0_chip_init(struct intel8x0m *chip, int probing) 963static int snd_intel8x0m_chip_init(struct intel8x0m *chip, int probing)
963{ 964{
964 unsigned int i; 965 unsigned int i;
965 int err; 966 int err;
@@ -980,7 +981,7 @@ static int snd_intel8x0_chip_init(struct intel8x0m *chip, int probing)
980 return 0; 981 return 0;
981} 982}
982 983
983static int snd_intel8x0_free(struct intel8x0m *chip) 984static int snd_intel8x0m_free(struct intel8x0m *chip)
984{ 985{
985 unsigned int i; 986 unsigned int i;
986 987
@@ -1045,7 +1046,7 @@ static int intel8x0m_resume(struct pci_dev *pci)
1045 return -EIO; 1046 return -EIO;
1046 } 1047 }
1047 pci_set_master(pci); 1048 pci_set_master(pci);
1048 if (request_irq(pci->irq, snd_intel8x0_interrupt, 1049 if (request_irq(pci->irq, snd_intel8x0m_interrupt,
1049 IRQF_SHARED, card->shortname, chip)) { 1050 IRQF_SHARED, card->shortname, chip)) {
1050 printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, " 1051 printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, "
1051 "disabling device\n", pci->irq); 1052 "disabling device\n", pci->irq);
@@ -1053,7 +1054,7 @@ static int intel8x0m_resume(struct pci_dev *pci)
1053 return -EIO; 1054 return -EIO;
1054 } 1055 }
1055 chip->irq = pci->irq; 1056 chip->irq = pci->irq;
1056 snd_intel8x0_chip_init(chip, 0); 1057 snd_intel8x0m_chip_init(chip, 0);
1057 snd_ac97_resume(chip->ac97); 1058 snd_ac97_resume(chip->ac97);
1058 1059
1059 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1060 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -1094,10 +1095,10 @@ static void __devinit snd_intel8x0m_proc_init(struct intel8x0m * chip)
1094#endif /* CONFIG_PROC_FS */ 1095#endif /* CONFIG_PROC_FS */
1095 1096
1096 1097
1097static int snd_intel8x0_dev_free(struct snd_device *device) 1098static int snd_intel8x0m_dev_free(struct snd_device *device)
1098{ 1099{
1099 struct intel8x0m *chip = device->device_data; 1100 struct intel8x0m *chip = device->device_data;
1100 return snd_intel8x0_free(chip); 1101 return snd_intel8x0m_free(chip);
1101} 1102}
1102 1103
1103struct ich_reg_info { 1104struct ich_reg_info {
@@ -1108,7 +1109,7 @@ struct ich_reg_info {
1108static int __devinit snd_intel8x0m_create(struct snd_card *card, 1109static int __devinit snd_intel8x0m_create(struct snd_card *card,
1109 struct pci_dev *pci, 1110 struct pci_dev *pci,
1110 unsigned long device_type, 1111 unsigned long device_type,
1111 struct intel8x0m ** r_intel8x0) 1112 struct intel8x0m **r_intel8x0m)
1112{ 1113{
1113 struct intel8x0m *chip; 1114 struct intel8x0m *chip;
1114 int err; 1115 int err;
@@ -1116,7 +1117,7 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
1116 unsigned int int_sta_masks; 1117 unsigned int int_sta_masks;
1117 struct ichdev *ichdev; 1118 struct ichdev *ichdev;
1118 static struct snd_device_ops ops = { 1119 static struct snd_device_ops ops = {
1119 .dev_free = snd_intel8x0_dev_free, 1120 .dev_free = snd_intel8x0m_dev_free,
1120 }; 1121 };
1121 static struct ich_reg_info intel_regs[2] = { 1122 static struct ich_reg_info intel_regs[2] = {
1122 { ICH_MIINT, 0 }, 1123 { ICH_MIINT, 0 },
@@ -1124,7 +1125,7 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
1124 }; 1125 };
1125 struct ich_reg_info *tbl; 1126 struct ich_reg_info *tbl;
1126 1127
1127 *r_intel8x0 = NULL; 1128 *r_intel8x0m = NULL;
1128 1129
1129 if ((err = pci_enable_device(pci)) < 0) 1130 if ((err = pci_enable_device(pci)) < 0)
1130 return err; 1131 return err;
@@ -1158,7 +1159,7 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
1158 chip->addr = pci_iomap(pci, 0, 0); 1159 chip->addr = pci_iomap(pci, 0, 0);
1159 if (!chip->addr) { 1160 if (!chip->addr) {
1160 snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); 1161 snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
1161 snd_intel8x0_free(chip); 1162 snd_intel8x0m_free(chip);
1162 return -EIO; 1163 return -EIO;
1163 } 1164 }
1164 if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) /* ICH4 */ 1165 if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) /* ICH4 */
@@ -1167,15 +1168,15 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
1167 chip->bmaddr = pci_iomap(pci, 1, 0); 1168 chip->bmaddr = pci_iomap(pci, 1, 0);
1168 if (!chip->bmaddr) { 1169 if (!chip->bmaddr) {
1169 snd_printk(KERN_ERR "Controller space ioremap problem\n"); 1170 snd_printk(KERN_ERR "Controller space ioremap problem\n");
1170 snd_intel8x0_free(chip); 1171 snd_intel8x0m_free(chip);
1171 return -EIO; 1172 return -EIO;
1172 } 1173 }
1173 1174
1174 port_inited: 1175 port_inited:
1175 if (request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_SHARED, 1176 if (request_irq(pci->irq, snd_intel8x0m_interrupt, IRQF_SHARED,
1176 card->shortname, chip)) { 1177 card->shortname, chip)) {
1177 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1178 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1178 snd_intel8x0_free(chip); 1179 snd_intel8x0m_free(chip);
1179 return -EBUSY; 1180 return -EBUSY;
1180 } 1181 }
1181 chip->irq = pci->irq; 1182 chip->irq = pci->irq;
@@ -1210,7 +1211,7 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
1210 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1211 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1211 chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2, 1212 chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2,
1212 &chip->bdbars) < 0) { 1213 &chip->bdbars) < 0) {
1213 snd_intel8x0_free(chip); 1214 snd_intel8x0m_free(chip);
1214 return -ENOMEM; 1215 return -ENOMEM;
1215 } 1216 }
1216 /* tables must be aligned to 8 bytes here, but the kernel pages 1217 /* tables must be aligned to 8 bytes here, but the kernel pages
@@ -1225,19 +1226,19 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
1225 chip->int_sta_reg = ICH_REG_GLOB_STA; 1226 chip->int_sta_reg = ICH_REG_GLOB_STA;
1226 chip->int_sta_mask = int_sta_masks; 1227 chip->int_sta_mask = int_sta_masks;
1227 1228
1228 if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) { 1229 if ((err = snd_intel8x0m_chip_init(chip, 1)) < 0) {
1229 snd_intel8x0_free(chip); 1230 snd_intel8x0m_free(chip);
1230 return err; 1231 return err;
1231 } 1232 }
1232 1233
1233 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 1234 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1234 snd_intel8x0_free(chip); 1235 snd_intel8x0m_free(chip);
1235 return err; 1236 return err;
1236 } 1237 }
1237 1238
1238 snd_card_set_dev(card, &pci->dev); 1239 snd_card_set_dev(card, &pci->dev);
1239 1240
1240 *r_intel8x0 = chip; 1241 *r_intel8x0m = chip;
1241 return 0; 1242 return 0;
1242} 1243}
1243 1244
@@ -1260,9 +1261,9 @@ static struct shortname_table {
1260 { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" }, 1261 { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" },
1261 { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" }, 1262 { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" },
1262 { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" }, 1263 { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" },
1264 { 0x746e, "AMD AMD8111" },
1263#if 0 1265#if 0
1264 { 0x5455, "ALi M5455" }, 1266 { 0x5455, "ALi M5455" },
1265 { 0x746d, "AMD AMD8111" },
1266#endif 1267#endif
1267 { 0 }, 1268 { 0 },
1268}; 1269};
@@ -1295,11 +1296,11 @@ static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
1295 } 1296 }
1296 card->private_data = chip; 1297 card->private_data = chip;
1297 1298
1298 if ((err = snd_intel8x0_mixer(chip, ac97_clock)) < 0) { 1299 if ((err = snd_intel8x0m_mixer(chip, ac97_clock)) < 0) {
1299 snd_card_free(card); 1300 snd_card_free(card);
1300 return err; 1301 return err;
1301 } 1302 }
1302 if ((err = snd_intel8x0_pcm(chip)) < 0) { 1303 if ((err = snd_intel8x0m_pcm(chip)) < 0) {
1303 snd_card_free(card); 1304 snd_card_free(card);
1304 return err; 1305 return err;
1305 } 1306 }
diff --git a/sound/pci/lola/Makefile b/sound/pci/lola/Makefile
new file mode 100644
index 000000000000..8178a2a59d00
--- /dev/null
+++ b/sound/pci/lola/Makefile
@@ -0,0 +1,4 @@
1snd-lola-y := lola.o lola_pcm.o lola_clock.o lola_mixer.o
2snd-lola-$(CONFIG_SND_DEBUG) += lola_proc.o
3
4obj-$(CONFIG_SND_LOLA) += snd-lola.o
diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c
new file mode 100644
index 000000000000..2692e5ae5f2d
--- /dev/null
+++ b/sound/pci/lola/lola.c
@@ -0,0 +1,791 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/moduleparam.h>
24#include <linux/dma-mapping.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/slab.h>
28#include <linux/pci.h>
29#include <sound/core.h>
30#include <sound/control.h>
31#include <sound/pcm.h>
32#include <sound/initval.h>
33#include "lola.h"
34
35/* Standard options */
36static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
37static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
38static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
39
40module_param_array(index, int, NULL, 0444);
41MODULE_PARM_DESC(index, "Index value for Digigram Lola driver.");
42module_param_array(id, charp, NULL, 0444);
43MODULE_PARM_DESC(id, "ID string for Digigram Lola driver.");
44module_param_array(enable, bool, NULL, 0444);
45MODULE_PARM_DESC(enable, "Enable Digigram Lola driver.");
46
47/* Lola-specific options */
48
49/* for instance use always max granularity which is compatible
50 * with all sample rates
51 */
52static int granularity[SNDRV_CARDS] = {
53 [0 ... (SNDRV_CARDS - 1)] = LOLA_GRANULARITY_MAX
54};
55
56/* below a sample_rate of 16kHz the analogue audio quality is NOT excellent */
57static int sample_rate_min[SNDRV_CARDS] = {
58 [0 ... (SNDRV_CARDS - 1) ] = 16000
59};
60
61module_param_array(granularity, int, NULL, 0444);
62MODULE_PARM_DESC(granularity, "Granularity value");
63module_param_array(sample_rate_min, int, NULL, 0444);
64MODULE_PARM_DESC(sample_rate_min, "Minimal sample rate");
65
66/*
67 */
68
69MODULE_LICENSE("GPL");
70MODULE_SUPPORTED_DEVICE("{{Digigram, Lola}}");
71MODULE_DESCRIPTION("Digigram Lola driver");
72MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
73
74#ifdef CONFIG_SND_DEBUG_VERBOSE
75static int debug;
76module_param(debug, int, 0644);
77#define verbose_debug(fmt, args...) \
78 do { if (debug > 1) printk(KERN_DEBUG SFX fmt, ##args); } while (0)
79#else
80#define verbose_debug(fmt, args...)
81#endif
82
83/*
84 * pseudo-codec read/write via CORB/RIRB
85 */
86
87static int corb_send_verb(struct lola *chip, unsigned int nid,
88 unsigned int verb, unsigned int data,
89 unsigned int extdata)
90{
91 unsigned long flags;
92 int ret = -EIO;
93
94 chip->last_cmd_nid = nid;
95 chip->last_verb = verb;
96 chip->last_data = data;
97 chip->last_extdata = extdata;
98 data |= (nid << 20) | (verb << 8);
99
100 spin_lock_irqsave(&chip->reg_lock, flags);
101 if (chip->rirb.cmds < LOLA_CORB_ENTRIES - 1) {
102 unsigned int wp = chip->corb.wp + 1;
103 wp %= LOLA_CORB_ENTRIES;
104 chip->corb.wp = wp;
105 chip->corb.buf[wp * 2] = cpu_to_le32(data);
106 chip->corb.buf[wp * 2 + 1] = cpu_to_le32(extdata);
107 lola_writew(chip, BAR0, CORBWP, wp);
108 chip->rirb.cmds++;
109 smp_wmb();
110 ret = 0;
111 }
112 spin_unlock_irqrestore(&chip->reg_lock, flags);
113 return ret;
114}
115
116static void lola_queue_unsol_event(struct lola *chip, unsigned int res,
117 unsigned int res_ex)
118{
119 lola_update_ext_clock_freq(chip, res);
120}
121
122/* retrieve RIRB entry - called from interrupt handler */
123static void lola_update_rirb(struct lola *chip)
124{
125 unsigned int rp, wp;
126 u32 res, res_ex;
127
128 wp = lola_readw(chip, BAR0, RIRBWP);
129 if (wp == chip->rirb.wp)
130 return;
131 chip->rirb.wp = wp;
132
133 while (chip->rirb.rp != wp) {
134 chip->rirb.rp++;
135 chip->rirb.rp %= LOLA_CORB_ENTRIES;
136
137 rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
138 res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
139 res = le32_to_cpu(chip->rirb.buf[rp]);
140 if (res_ex & LOLA_RIRB_EX_UNSOL_EV)
141 lola_queue_unsol_event(chip, res, res_ex);
142 else if (chip->rirb.cmds) {
143 chip->res = res;
144 chip->res_ex = res_ex;
145 smp_wmb();
146 chip->rirb.cmds--;
147 }
148 }
149}
150
151static int rirb_get_response(struct lola *chip, unsigned int *val,
152 unsigned int *extval)
153{
154 unsigned long timeout;
155
156 again:
157 timeout = jiffies + msecs_to_jiffies(1000);
158 for (;;) {
159 if (chip->polling_mode) {
160 spin_lock_irq(&chip->reg_lock);
161 lola_update_rirb(chip);
162 spin_unlock_irq(&chip->reg_lock);
163 }
164 if (!chip->rirb.cmds) {
165 *val = chip->res;
166 if (extval)
167 *extval = chip->res_ex;
168 verbose_debug("get_response: %x, %x\n",
169 chip->res, chip->res_ex);
170 if (chip->res_ex & LOLA_RIRB_EX_ERROR) {
171 printk(KERN_WARNING SFX "RIRB ERROR: "
172 "NID=%x, verb=%x, data=%x, ext=%x\n",
173 chip->last_cmd_nid,
174 chip->last_verb, chip->last_data,
175 chip->last_extdata);
176 return -EIO;
177 }
178 return 0;
179 }
180 if (time_after(jiffies, timeout))
181 break;
182 udelay(20);
183 cond_resched();
184 }
185 printk(KERN_WARNING SFX "RIRB response error\n");
186 if (!chip->polling_mode) {
187 printk(KERN_WARNING SFX "switching to polling mode\n");
188 chip->polling_mode = 1;
189 goto again;
190 }
191 return -EIO;
192}
193
194/* aynchronous write of a codec verb with data */
195int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
196 unsigned int data, unsigned int extdata)
197{
198 verbose_debug("codec_write NID=%x, verb=%x, data=%x, ext=%x\n",
199 nid, verb, data, extdata);
200 return corb_send_verb(chip, nid, verb, data, extdata);
201}
202
203/* write a codec verb with data and read the returned status */
204int lola_codec_read(struct lola *chip, unsigned int nid, unsigned int verb,
205 unsigned int data, unsigned int extdata,
206 unsigned int *val, unsigned int *extval)
207{
208 int err;
209
210 verbose_debug("codec_read NID=%x, verb=%x, data=%x, ext=%x\n",
211 nid, verb, data, extdata);
212 err = corb_send_verb(chip, nid, verb, data, extdata);
213 if (err < 0)
214 return err;
215 err = rirb_get_response(chip, val, extval);
216 return err;
217}
218
219/* flush all pending codec writes */
220int lola_codec_flush(struct lola *chip)
221{
222 unsigned int tmp;
223 return rirb_get_response(chip, &tmp, NULL);
224}
225
226/*
227 * interrupt handler
228 */
229static irqreturn_t lola_interrupt(int irq, void *dev_id)
230{
231 struct lola *chip = dev_id;
232 unsigned int notify_ins, notify_outs, error_ins, error_outs;
233 int handled = 0;
234 int i;
235
236 notify_ins = notify_outs = error_ins = error_outs = 0;
237 spin_lock(&chip->reg_lock);
238 for (;;) {
239 unsigned int status, in_sts, out_sts;
240 unsigned int reg;
241
242 status = lola_readl(chip, BAR1, DINTSTS);
243 if (!status || status == -1)
244 break;
245
246 in_sts = lola_readl(chip, BAR1, DIINTSTS);
247 out_sts = lola_readl(chip, BAR1, DOINTSTS);
248
249 /* clear Input Interrupts */
250 for (i = 0; in_sts && i < chip->pcm[CAPT].num_streams; i++) {
251 if (!(in_sts & (1 << i)))
252 continue;
253 in_sts &= ~(1 << i);
254 reg = lola_dsd_read(chip, i, STS);
255 if (reg & LOLA_DSD_STS_DESE) /* error */
256 error_ins |= (1 << i);
257 if (reg & LOLA_DSD_STS_BCIS) /* notify */
258 notify_ins |= (1 << i);
259 /* clear */
260 lola_dsd_write(chip, i, STS, reg);
261 }
262
263 /* clear Output Interrupts */
264 for (i = 0; out_sts && i < chip->pcm[PLAY].num_streams; i++) {
265 if (!(out_sts & (1 << i)))
266 continue;
267 out_sts &= ~(1 << i);
268 reg = lola_dsd_read(chip, i + MAX_STREAM_IN_COUNT, STS);
269 if (reg & LOLA_DSD_STS_DESE) /* error */
270 error_outs |= (1 << i);
271 if (reg & LOLA_DSD_STS_BCIS) /* notify */
272 notify_outs |= (1 << i);
273 lola_dsd_write(chip, i + MAX_STREAM_IN_COUNT, STS, reg);
274 }
275
276 if (status & LOLA_DINT_CTRL) {
277 unsigned char rbsts; /* ring status is byte access */
278 rbsts = lola_readb(chip, BAR0, RIRBSTS);
279 rbsts &= LOLA_RIRB_INT_MASK;
280 if (rbsts)
281 lola_writeb(chip, BAR0, RIRBSTS, rbsts);
282 rbsts = lola_readb(chip, BAR0, CORBSTS);
283 rbsts &= LOLA_CORB_INT_MASK;
284 if (rbsts)
285 lola_writeb(chip, BAR0, CORBSTS, rbsts);
286
287 lola_update_rirb(chip);
288 }
289
290 if (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR)) {
291 /* clear global fifo error interrupt */
292 lola_writel(chip, BAR1, DINTSTS,
293 (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR)));
294 }
295 handled = 1;
296 }
297 spin_unlock(&chip->reg_lock);
298
299 lola_pcm_update(chip, &chip->pcm[CAPT], notify_ins);
300 lola_pcm_update(chip, &chip->pcm[PLAY], notify_outs);
301
302 return IRQ_RETVAL(handled);
303}
304
305
306/*
307 * controller
308 */
309static int reset_controller(struct lola *chip)
310{
311 unsigned int gctl = lola_readl(chip, BAR0, GCTL);
312 unsigned long end_time;
313
314 if (gctl) {
315 /* to be sure */
316 lola_writel(chip, BAR1, BOARD_MODE, 0);
317 return 0;
318 }
319
320 chip->cold_reset = 1;
321 lola_writel(chip, BAR0, GCTL, LOLA_GCTL_RESET);
322 end_time = jiffies + msecs_to_jiffies(200);
323 do {
324 msleep(1);
325 gctl = lola_readl(chip, BAR0, GCTL);
326 if (gctl)
327 break;
328 } while (time_before(jiffies, end_time));
329 if (!gctl) {
330 printk(KERN_ERR SFX "cannot reset controller\n");
331 return -EIO;
332 }
333 return 0;
334}
335
336static void lola_irq_enable(struct lola *chip)
337{
338 unsigned int val;
339
340 /* enalbe all I/O streams */
341 val = (1 << chip->pcm[PLAY].num_streams) - 1;
342 lola_writel(chip, BAR1, DOINTCTL, val);
343 val = (1 << chip->pcm[CAPT].num_streams) - 1;
344 lola_writel(chip, BAR1, DIINTCTL, val);
345
346 /* enable global irqs */
347 val = LOLA_DINT_GLOBAL | LOLA_DINT_CTRL | LOLA_DINT_FIFOERR |
348 LOLA_DINT_MUERR;
349 lola_writel(chip, BAR1, DINTCTL, val);
350}
351
352static void lola_irq_disable(struct lola *chip)
353{
354 lola_writel(chip, BAR1, DINTCTL, 0);
355 lola_writel(chip, BAR1, DIINTCTL, 0);
356 lola_writel(chip, BAR1, DOINTCTL, 0);
357}
358
359static int setup_corb_rirb(struct lola *chip)
360{
361 int err;
362 unsigned char tmp;
363 unsigned long end_time;
364
365 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
366 snd_dma_pci_data(chip->pci),
367 PAGE_SIZE, &chip->rb);
368 if (err < 0)
369 return err;
370
371 chip->corb.addr = chip->rb.addr;
372 chip->corb.buf = (u32 *)chip->rb.area;
373 chip->rirb.addr = chip->rb.addr + 2048;
374 chip->rirb.buf = (u32 *)(chip->rb.area + 2048);
375
376 /* disable ringbuffer DMAs */
377 lola_writeb(chip, BAR0, RIRBCTL, 0);
378 lola_writeb(chip, BAR0, CORBCTL, 0);
379
380 end_time = jiffies + msecs_to_jiffies(200);
381 do {
382 if (!lola_readb(chip, BAR0, RIRBCTL) &&
383 !lola_readb(chip, BAR0, CORBCTL))
384 break;
385 msleep(1);
386 } while (time_before(jiffies, end_time));
387
388 /* CORB set up */
389 lola_writel(chip, BAR0, CORBLBASE, (u32)chip->corb.addr);
390 lola_writel(chip, BAR0, CORBUBASE, upper_32_bits(chip->corb.addr));
391 /* set the corb size to 256 entries */
392 lola_writeb(chip, BAR0, CORBSIZE, 0x02);
393 /* set the corb write pointer to 0 */
394 lola_writew(chip, BAR0, CORBWP, 0);
395 /* reset the corb hw read pointer */
396 lola_writew(chip, BAR0, CORBRP, LOLA_RBRWP_CLR);
397 /* enable corb dma */
398 lola_writeb(chip, BAR0, CORBCTL, LOLA_RBCTL_DMA_EN);
399 /* clear flags if set */
400 tmp = lola_readb(chip, BAR0, CORBSTS) & LOLA_CORB_INT_MASK;
401 if (tmp)
402 lola_writeb(chip, BAR0, CORBSTS, tmp);
403 chip->corb.wp = 0;
404
405 /* RIRB set up */
406 lola_writel(chip, BAR0, RIRBLBASE, (u32)chip->rirb.addr);
407 lola_writel(chip, BAR0, RIRBUBASE, upper_32_bits(chip->rirb.addr));
408 /* set the rirb size to 256 entries */
409 lola_writeb(chip, BAR0, RIRBSIZE, 0x02);
410 /* reset the rirb hw write pointer */
411 lola_writew(chip, BAR0, RIRBWP, LOLA_RBRWP_CLR);
412 /* set N=1, get RIRB response interrupt for new entry */
413 lola_writew(chip, BAR0, RINTCNT, 1);
414 /* enable rirb dma and response irq */
415 lola_writeb(chip, BAR0, RIRBCTL, LOLA_RBCTL_DMA_EN | LOLA_RBCTL_IRQ_EN);
416 /* clear flags if set */
417 tmp = lola_readb(chip, BAR0, RIRBSTS) & LOLA_RIRB_INT_MASK;
418 if (tmp)
419 lola_writeb(chip, BAR0, RIRBSTS, tmp);
420 chip->rirb.rp = chip->rirb.cmds = 0;
421
422 return 0;
423}
424
425static void stop_corb_rirb(struct lola *chip)
426{
427 /* disable ringbuffer DMAs */
428 lola_writeb(chip, BAR0, RIRBCTL, 0);
429 lola_writeb(chip, BAR0, CORBCTL, 0);
430}
431
432static void lola_reset_setups(struct lola *chip)
433{
434 /* update the granularity */
435 lola_set_granularity(chip, chip->granularity, true);
436 /* update the sample clock */
437 lola_set_clock_index(chip, chip->clock.cur_index);
438 /* enable unsolicited events of the clock widget */
439 lola_enable_clock_events(chip);
440 /* update the analog gains */
441 lola_setup_all_analog_gains(chip, CAPT, false); /* input, update */
442 /* update SRC configuration if applicable */
443 lola_set_src_config(chip, chip->input_src_mask, false);
444 /* update the analog outputs */
445 lola_setup_all_analog_gains(chip, PLAY, false); /* output, update */
446}
447
448static int __devinit lola_parse_tree(struct lola *chip)
449{
450 unsigned int val;
451 int nid, err;
452
453 err = lola_read_param(chip, 0, LOLA_PAR_VENDOR_ID, &val);
454 if (err < 0) {
455 printk(KERN_ERR SFX "Can't read VENDOR_ID\n");
456 return err;
457 }
458 val >>= 16;
459 if (val != 0x1369) {
460 printk(KERN_ERR SFX "Unknown codec vendor 0x%x\n", val);
461 return -EINVAL;
462 }
463
464 err = lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val);
465 if (err < 0) {
466 printk(KERN_ERR SFX "Can't read FUNCTION_TYPE for 0x%x\n", nid);
467 return err;
468 }
469 if (val != 1) {
470 printk(KERN_ERR SFX "Unknown function type %d\n", val);
471 return -EINVAL;
472 }
473
474 err = lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val);
475 if (err < 0) {
476 printk(KERN_ERR SFX "Can't read SPECCAPS\n");
477 return err;
478 }
479 chip->lola_caps = val;
480 chip->pin[CAPT].num_pins = LOLA_AFG_INPUT_PIN_COUNT(chip->lola_caps);
481 chip->pin[PLAY].num_pins = LOLA_AFG_OUTPUT_PIN_COUNT(chip->lola_caps);
482 snd_printdd(SFX "speccaps=0x%x, pins in=%d, out=%d\n",
483 chip->lola_caps,
484 chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins);
485
486 if (chip->pin[CAPT].num_pins > MAX_AUDIO_INOUT_COUNT ||
487 chip->pin[PLAY].num_pins > MAX_AUDIO_INOUT_COUNT) {
488 printk(KERN_ERR SFX "Invalid Lola-spec caps 0x%x\n", val);
489 return -EINVAL;
490 }
491
492 nid = 0x02;
493 err = lola_init_pcm(chip, CAPT, &nid);
494 if (err < 0)
495 return err;
496 err = lola_init_pcm(chip, PLAY, &nid);
497 if (err < 0)
498 return err;
499
500 err = lola_init_pins(chip, CAPT, &nid);
501 if (err < 0)
502 return err;
503 err = lola_init_pins(chip, PLAY, &nid);
504 if (err < 0)
505 return err;
506
507 if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) {
508 err = lola_init_clock_widget(chip, nid);
509 if (err < 0)
510 return err;
511 nid++;
512 }
513 if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) {
514 err = lola_init_mixer_widget(chip, nid);
515 if (err < 0)
516 return err;
517 nid++;
518 }
519
520 /* enable unsolicited events of the clock widget */
521 err = lola_enable_clock_events(chip);
522 if (err < 0)
523 return err;
524
525 /* if last ResetController was not a ColdReset, we don't know
526 * the state of the card; initialize here again
527 */
528 if (!chip->cold_reset) {
529 lola_reset_setups(chip);
530 chip->cold_reset = 1;
531 } else {
532 /* set the granularity if it is not the default */
533 if (chip->granularity != LOLA_GRANULARITY_MIN)
534 lola_set_granularity(chip, chip->granularity, true);
535 }
536
537 return 0;
538}
539
540static void lola_stop_hw(struct lola *chip)
541{
542 stop_corb_rirb(chip);
543 lola_irq_disable(chip);
544}
545
546static void lola_free(struct lola *chip)
547{
548 if (chip->initialized)
549 lola_stop_hw(chip);
550 lola_free_pcm(chip);
551 lola_free_mixer(chip);
552 if (chip->irq >= 0)
553 free_irq(chip->irq, (void *)chip);
554 if (chip->bar[0].remap_addr)
555 iounmap(chip->bar[0].remap_addr);
556 if (chip->bar[1].remap_addr)
557 iounmap(chip->bar[1].remap_addr);
558 if (chip->rb.area)
559 snd_dma_free_pages(&chip->rb);
560 pci_release_regions(chip->pci);
561 pci_disable_device(chip->pci);
562 kfree(chip);
563}
564
565static int lola_dev_free(struct snd_device *device)
566{
567 lola_free(device->device_data);
568 return 0;
569}
570
571static int __devinit lola_create(struct snd_card *card, struct pci_dev *pci,
572 int dev, struct lola **rchip)
573{
574 struct lola *chip;
575 int err;
576 unsigned int dever;
577 static struct snd_device_ops ops = {
578 .dev_free = lola_dev_free,
579 };
580
581 *rchip = NULL;
582
583 err = pci_enable_device(pci);
584 if (err < 0)
585 return err;
586
587 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
588 if (!chip) {
589 snd_printk(KERN_ERR SFX "cannot allocate chip\n");
590 pci_disable_device(pci);
591 return -ENOMEM;
592 }
593
594 spin_lock_init(&chip->reg_lock);
595 mutex_init(&chip->open_mutex);
596 chip->card = card;
597 chip->pci = pci;
598 chip->irq = -1;
599
600 chip->granularity = granularity[dev];
601 switch (chip->granularity) {
602 case 8:
603 chip->sample_rate_max = 48000;
604 break;
605 case 16:
606 chip->sample_rate_max = 96000;
607 break;
608 case 32:
609 chip->sample_rate_max = 192000;
610 break;
611 default:
612 snd_printk(KERN_WARNING SFX
613 "Invalid granularity %d, reset to %d\n",
614 chip->granularity, LOLA_GRANULARITY_MAX);
615 chip->granularity = LOLA_GRANULARITY_MAX;
616 chip->sample_rate_max = 192000;
617 break;
618 }
619 chip->sample_rate_min = sample_rate_min[dev];
620 if (chip->sample_rate_min > chip->sample_rate_max) {
621 snd_printk(KERN_WARNING SFX
622 "Invalid sample_rate_min %d, reset to 16000\n",
623 chip->sample_rate_min);
624 chip->sample_rate_min = 16000;
625 }
626
627 err = pci_request_regions(pci, DRVNAME);
628 if (err < 0) {
629 kfree(chip);
630 pci_disable_device(pci);
631 return err;
632 }
633
634 chip->bar[0].addr = pci_resource_start(pci, 0);
635 chip->bar[0].remap_addr = pci_ioremap_bar(pci, 0);
636 chip->bar[1].addr = pci_resource_start(pci, 2);
637 chip->bar[1].remap_addr = pci_ioremap_bar(pci, 2);
638 if (!chip->bar[0].remap_addr || !chip->bar[1].remap_addr) {
639 snd_printk(KERN_ERR SFX "ioremap error\n");
640 err = -ENXIO;
641 goto errout;
642 }
643
644 pci_set_master(pci);
645
646 err = reset_controller(chip);
647 if (err < 0)
648 goto errout;
649
650 if (request_irq(pci->irq, lola_interrupt, IRQF_SHARED,
651 DRVNAME, chip)) {
652 printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq);
653 err = -EBUSY;
654 goto errout;
655 }
656 chip->irq = pci->irq;
657 synchronize_irq(chip->irq);
658
659 dever = lola_readl(chip, BAR1, DEVER);
660 chip->pcm[CAPT].num_streams = (dever >> 0) & 0x3ff;
661 chip->pcm[PLAY].num_streams = (dever >> 10) & 0x3ff;
662 chip->version = (dever >> 24) & 0xff;
663 snd_printdd(SFX "streams in=%d, out=%d, version=0x%x\n",
664 chip->pcm[CAPT].num_streams, chip->pcm[PLAY].num_streams,
665 chip->version);
666
667 /* Test LOLA_BAR1_DEVER */
668 if (chip->pcm[CAPT].num_streams > MAX_STREAM_IN_COUNT ||
669 chip->pcm[PLAY].num_streams > MAX_STREAM_OUT_COUNT ||
670 (!chip->pcm[CAPT].num_streams &&
671 !chip->pcm[PLAY].num_streams)) {
672 printk(KERN_ERR SFX "invalid DEVER = %x\n", dever);
673 err = -EINVAL;
674 goto errout;
675 }
676
677 err = setup_corb_rirb(chip);
678 if (err < 0)
679 goto errout;
680
681 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
682 if (err < 0) {
683 snd_printk(KERN_ERR SFX "Error creating device [card]!\n");
684 goto errout;
685 }
686
687 strcpy(card->driver, "Lola");
688 strlcpy(card->shortname, "Digigram Lola", sizeof(card->shortname));
689 snprintf(card->longname, sizeof(card->longname),
690 "%s at 0x%lx irq %i",
691 card->shortname, chip->bar[0].addr, chip->irq);
692 strcpy(card->mixername, card->shortname);
693
694 lola_irq_enable(chip);
695
696 chip->initialized = 1;
697 *rchip = chip;
698 return 0;
699
700 errout:
701 lola_free(chip);
702 return err;
703}
704
705static int __devinit lola_probe(struct pci_dev *pci,
706 const struct pci_device_id *pci_id)
707{
708 static int dev;
709 struct snd_card *card;
710 struct lola *chip;
711 int err;
712
713 if (dev >= SNDRV_CARDS)
714 return -ENODEV;
715 if (!enable[dev]) {
716 dev++;
717 return -ENOENT;
718 }
719
720 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
721 if (err < 0) {
722 snd_printk(KERN_ERR SFX "Error creating card!\n");
723 return err;
724 }
725
726 snd_card_set_dev(card, &pci->dev);
727
728 err = lola_create(card, pci, dev, &chip);
729 if (err < 0)
730 goto out_free;
731 card->private_data = chip;
732
733 err = lola_parse_tree(chip);
734 if (err < 0)
735 goto out_free;
736
737 err = lola_create_pcm(chip);
738 if (err < 0)
739 goto out_free;
740
741 err = lola_create_mixer(chip);
742 if (err < 0)
743 goto out_free;
744
745 lola_proc_debug_new(chip);
746
747 err = snd_card_register(card);
748 if (err < 0)
749 goto out_free;
750
751 pci_set_drvdata(pci, card);
752 dev++;
753 return err;
754out_free:
755 snd_card_free(card);
756 return err;
757}
758
759static void __devexit lola_remove(struct pci_dev *pci)
760{
761 snd_card_free(pci_get_drvdata(pci));
762 pci_set_drvdata(pci, NULL);
763}
764
765/* PCI IDs */
766static DEFINE_PCI_DEVICE_TABLE(lola_ids) = {
767 { PCI_VDEVICE(DIGIGRAM, 0x0001) },
768 { 0, }
769};
770MODULE_DEVICE_TABLE(pci, lola_ids);
771
772/* pci_driver definition */
773static struct pci_driver driver = {
774 .name = DRVNAME,
775 .id_table = lola_ids,
776 .probe = lola_probe,
777 .remove = __devexit_p(lola_remove),
778};
779
780static int __init alsa_card_lola_init(void)
781{
782 return pci_register_driver(&driver);
783}
784
785static void __exit alsa_card_lola_exit(void)
786{
787 pci_unregister_driver(&driver);
788}
789
790module_init(alsa_card_lola_init)
791module_exit(alsa_card_lola_exit)
diff --git a/sound/pci/lola/lola.h b/sound/pci/lola/lola.h
new file mode 100644
index 000000000000..d5708e29b16d
--- /dev/null
+++ b/sound/pci/lola/lola.h
@@ -0,0 +1,527 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#ifndef _LOLA_H
22#define _LOLA_H
23
24#define DRVNAME "snd-lola"
25#define SFX DRVNAME ": "
26
27/*
28 * Lola HD Audio Registers BAR0
29 */
30#define LOLA_BAR0_GCAP 0x00
31#define LOLA_BAR0_VMIN 0x02
32#define LOLA_BAR0_VMAJ 0x03
33#define LOLA_BAR0_OUTPAY 0x04
34#define LOLA_BAR0_INPAY 0x06
35#define LOLA_BAR0_GCTL 0x08
36#define LOLA_BAR0_WAKEEN 0x0c
37#define LOLA_BAR0_STATESTS 0x0e
38#define LOLA_BAR0_GSTS 0x10
39#define LOLA_BAR0_OUTSTRMPAY 0x18
40#define LOLA_BAR0_INSTRMPAY 0x1a
41#define LOLA_BAR0_INTCTL 0x20
42#define LOLA_BAR0_INTSTS 0x24
43#define LOLA_BAR0_WALCLK 0x30
44#define LOLA_BAR0_SSYNC 0x38
45
46#define LOLA_BAR0_CORBLBASE 0x40
47#define LOLA_BAR0_CORBUBASE 0x44
48#define LOLA_BAR0_CORBWP 0x48 /* no ULONG access */
49#define LOLA_BAR0_CORBRP 0x4a /* no ULONG access */
50#define LOLA_BAR0_CORBCTL 0x4c /* no ULONG access */
51#define LOLA_BAR0_CORBSTS 0x4d /* UCHAR access only */
52#define LOLA_BAR0_CORBSIZE 0x4e /* no ULONG access */
53
54#define LOLA_BAR0_RIRBLBASE 0x50
55#define LOLA_BAR0_RIRBUBASE 0x54
56#define LOLA_BAR0_RIRBWP 0x58
57#define LOLA_BAR0_RINTCNT 0x5a /* no ULONG access */
58#define LOLA_BAR0_RIRBCTL 0x5c
59#define LOLA_BAR0_RIRBSTS 0x5d /* UCHAR access only */
60#define LOLA_BAR0_RIRBSIZE 0x5e /* no ULONG access */
61
62#define LOLA_BAR0_ICW 0x60
63#define LOLA_BAR0_IRR 0x64
64#define LOLA_BAR0_ICS 0x68
65#define LOLA_BAR0_DPLBASE 0x70
66#define LOLA_BAR0_DPUBASE 0x74
67
68/* stream register offsets from stream base 0x80 */
69#define LOLA_BAR0_SD0_OFFSET 0x80
70#define LOLA_REG0_SD_CTL 0x00
71#define LOLA_REG0_SD_STS 0x03
72#define LOLA_REG0_SD_LPIB 0x04
73#define LOLA_REG0_SD_CBL 0x08
74#define LOLA_REG0_SD_LVI 0x0c
75#define LOLA_REG0_SD_FIFOW 0x0e
76#define LOLA_REG0_SD_FIFOSIZE 0x10
77#define LOLA_REG0_SD_FORMAT 0x12
78#define LOLA_REG0_SD_BDLPL 0x18
79#define LOLA_REG0_SD_BDLPU 0x1c
80
81/*
82 * Lola Digigram Registers BAR1
83 */
84#define LOLA_BAR1_FPGAVER 0x00
85#define LOLA_BAR1_DEVER 0x04
86#define LOLA_BAR1_UCBMV 0x08
87#define LOLA_BAR1_JTAG 0x0c
88#define LOLA_BAR1_UARTRX 0x10
89#define LOLA_BAR1_UARTTX 0x14
90#define LOLA_BAR1_UARTCR 0x18
91#define LOLA_BAR1_NVRAMVER 0x1c
92#define LOLA_BAR1_CTRLSPI 0x20
93#define LOLA_BAR1_DSPI 0x24
94#define LOLA_BAR1_AISPI 0x28
95#define LOLA_BAR1_GRAN 0x2c
96
97#define LOLA_BAR1_DINTCTL 0x80
98#define LOLA_BAR1_DIINTCTL 0x84
99#define LOLA_BAR1_DOINTCTL 0x88
100#define LOLA_BAR1_LRC 0x90
101#define LOLA_BAR1_DINTSTS 0x94
102#define LOLA_BAR1_DIINTSTS 0x98
103#define LOLA_BAR1_DOINTSTS 0x9c
104
105#define LOLA_BAR1_DSD0_OFFSET 0xa0
106#define LOLA_BAR1_DSD_SIZE 0x18
107
108#define LOLA_BAR1_DSDnSTS 0x00
109#define LOLA_BAR1_DSDnLPIB 0x04
110#define LOLA_BAR1_DSDnCTL 0x08
111#define LOLA_BAR1_DSDnLVI 0x0c
112#define LOLA_BAR1_DSDnBDPL 0x10
113#define LOLA_BAR1_DSDnBDPU 0x14
114
115#define LOLA_BAR1_SSYNC 0x03e8
116
117#define LOLA_BAR1_BOARD_CTRL 0x0f00
118#define LOLA_BAR1_BOARD_MODE 0x0f02
119
120#define LOLA_BAR1_SOURCE_GAIN_ENABLE 0x1000
121#define LOLA_BAR1_DEST00_MIX_GAIN_ENABLE 0x1004
122#define LOLA_BAR1_DEST31_MIX_GAIN_ENABLE 0x1080
123#define LOLA_BAR1_SOURCE00_01_GAIN 0x1084
124#define LOLA_BAR1_SOURCE30_31_GAIN 0x10c0
125#define LOLA_BAR1_SOURCE_GAIN(src) \
126 (LOLA_BAR1_SOURCE00_01_GAIN + (src) * 2)
127#define LOLA_BAR1_DEST00_MIX00_01_GAIN 0x10c4
128#define LOLA_BAR1_DEST00_MIX30_31_GAIN 0x1100
129#define LOLA_BAR1_DEST01_MIX00_01_GAIN 0x1104
130#define LOLA_BAR1_DEST01_MIX30_31_GAIN 0x1140
131#define LOLA_BAR1_DEST31_MIX00_01_GAIN 0x1884
132#define LOLA_BAR1_DEST31_MIX30_31_GAIN 0x18c0
133#define LOLA_BAR1_MIX_GAIN(dest, mix) \
134 (LOLA_BAR1_DEST00_MIX00_01_GAIN + (dest) * 0x40 + (mix) * 2)
135#define LOLA_BAR1_ANALOG_CLIP_IN 0x18c4
136#define LOLA_BAR1_PEAKMETERS_SOURCE00_01 0x18c8
137#define LOLA_BAR1_PEAKMETERS_SOURCE30_31 0x1904
138#define LOLA_BAR1_PEAKMETERS_SOURCE(src) \
139 (LOLA_BAR1_PEAKMETERS_SOURCE00_01 + (src) * 2)
140#define LOLA_BAR1_PEAKMETERS_DEST00_01 0x1908
141#define LOLA_BAR1_PEAKMETERS_DEST30_31 0x1944
142#define LOLA_BAR1_PEAKMETERS_DEST(dest) \
143 (LOLA_BAR1_PEAKMETERS_DEST00_01 + (dest) * 2)
144#define LOLA_BAR1_PEAKMETERS_AGC00_01 0x1948
145#define LOLA_BAR1_PEAKMETERS_AGC14_15 0x1964
146#define LOLA_BAR1_PEAKMETERS_AGC(x) \
147 (LOLA_BAR1_PEAKMETERS_AGC00_01 + (x) * 2)
148
149/* GCTL reset bit */
150#define LOLA_GCTL_RESET (1 << 0)
151/* GCTL unsolicited response enable bit */
152#define LOLA_GCTL_UREN (1 << 8)
153
154/* CORB/RIRB control, read/write pointer */
155#define LOLA_RBCTL_DMA_EN 0x02 /* enable DMA */
156#define LOLA_RBCTL_IRQ_EN 0x01 /* enable IRQ */
157#define LOLA_RBRWP_CLR 0x8000 /* read/write pointer clear */
158
159#define LOLA_RIRB_EX_UNSOL_EV 0x40000000
160#define LOLA_RIRB_EX_ERROR 0x80000000
161
162/* CORB int mask: CMEI[0] */
163#define LOLA_CORB_INT_CMEI 0x01
164#define LOLA_CORB_INT_MASK LOLA_CORB_INT_CMEI
165
166/* RIRB int mask: overrun[2], response[0] */
167#define LOLA_RIRB_INT_RESPONSE 0x01
168#define LOLA_RIRB_INT_OVERRUN 0x04
169#define LOLA_RIRB_INT_MASK (LOLA_RIRB_INT_RESPONSE | LOLA_RIRB_INT_OVERRUN)
170
171/* DINTCTL and DINTSTS */
172#define LOLA_DINT_GLOBAL 0x80000000 /* global interrupt enable bit */
173#define LOLA_DINT_CTRL 0x40000000 /* controller interrupt enable bit */
174#define LOLA_DINT_FIFOERR 0x20000000 /* global fifo error enable bit */
175#define LOLA_DINT_MUERR 0x10000000 /* global microcontroller underrun error */
176
177/* DSDnCTL bits */
178#define LOLA_DSD_CTL_SRST 0x01 /* stream reset bit */
179#define LOLA_DSD_CTL_SRUN 0x02 /* stream DMA start bit */
180#define LOLA_DSD_CTL_IOCE 0x04 /* interrupt on completion enable */
181#define LOLA_DSD_CTL_DEIE 0x10 /* descriptor error interrupt enable */
182#define LOLA_DSD_CTL_VLRCV 0x20 /* valid LRCountValue information in bits 8..31 */
183#define LOLA_LRC_MASK 0xffffff00
184
185/* DSDnSTS */
186#define LOLA_DSD_STS_BCIS 0x04 /* buffer completion interrupt status */
187#define LOLA_DSD_STS_DESE 0x10 /* descriptor error interrupt */
188#define LOLA_DSD_STS_FIFORDY 0x20 /* fifo ready */
189
190#define LOLA_CORB_ENTRIES 256
191
192#define MAX_STREAM_IN_COUNT 16
193#define MAX_STREAM_OUT_COUNT 16
194#define MAX_STREAM_COUNT 16
195#define MAX_PINS MAX_STREAM_COUNT
196#define MAX_STREAM_BUFFER_COUNT 16
197#define MAX_AUDIO_INOUT_COUNT 16
198
199#define LOLA_CLOCK_TYPE_INTERNAL 0
200#define LOLA_CLOCK_TYPE_AES 1
201#define LOLA_CLOCK_TYPE_AES_SYNC 2
202#define LOLA_CLOCK_TYPE_WORDCLOCK 3
203#define LOLA_CLOCK_TYPE_ETHERSOUND 4
204#define LOLA_CLOCK_TYPE_VIDEO 5
205
206#define LOLA_CLOCK_FORMAT_NONE 0
207#define LOLA_CLOCK_FORMAT_NTSC 1
208#define LOLA_CLOCK_FORMAT_PAL 2
209
210#define MAX_SAMPLE_CLOCK_COUNT 48
211
212/* parameters used with mixer widget's mixer capabilities */
213#define LOLA_PEAK_METER_CAN_AGC_MASK 1
214#define LOLA_PEAK_METER_CAN_ANALOG_CLIP_MASK 2
215
216struct lola_bar {
217 unsigned long addr;
218 void __iomem *remap_addr;
219};
220
221/* CORB/RIRB */
222struct lola_rb {
223 u32 *buf; /* CORB/RIRB buffer, 8 byte per each entry */
224 dma_addr_t addr; /* physical address of CORB/RIRB buffer */
225 unsigned short rp, wp; /* read/write pointers */
226 int cmds; /* number of pending requests */
227};
228
229/* Pin widget setup */
230struct lola_pin {
231 unsigned int nid;
232 bool is_analog;
233 unsigned int amp_mute;
234 unsigned int amp_step_size;
235 unsigned int amp_num_steps;
236 unsigned int amp_offset;
237 unsigned int max_level;
238 unsigned int config_default_reg;
239 unsigned int fixed_gain_list_len;
240 unsigned int cur_gain_step;
241};
242
243struct lola_pin_array {
244 unsigned int num_pins;
245 unsigned int num_analog_pins;
246 struct lola_pin pins[MAX_PINS];
247};
248
249/* Clock widget setup */
250struct lola_sample_clock {
251 unsigned int type;
252 unsigned int format;
253 unsigned int freq;
254};
255
256struct lola_clock_widget {
257 unsigned int nid;
258 unsigned int items;
259 unsigned int cur_index;
260 unsigned int cur_freq;
261 bool cur_valid;
262 struct lola_sample_clock sample_clock[MAX_SAMPLE_CLOCK_COUNT];
263 unsigned int idx_lookup[MAX_SAMPLE_CLOCK_COUNT];
264};
265
266#define LOLA_MIXER_DIM 32
267struct lola_mixer_array {
268 u32 src_gain_enable;
269 u32 dest_mix_gain_enable[LOLA_MIXER_DIM];
270 u16 src_gain[LOLA_MIXER_DIM];
271 u16 dest_mix_gain[LOLA_MIXER_DIM][LOLA_MIXER_DIM];
272};
273
274/* Mixer widget setup */
275struct lola_mixer_widget {
276 unsigned int nid;
277 unsigned int caps;
278 struct lola_mixer_array __user *array;
279 struct lola_mixer_array *array_saved;
280 unsigned int src_stream_outs;
281 unsigned int src_phys_ins;
282 unsigned int dest_stream_ins;
283 unsigned int dest_phys_outs;
284 unsigned int src_stream_out_ofs;
285 unsigned int dest_phys_out_ofs;
286 unsigned int src_mask;
287 unsigned int dest_mask;
288};
289
290/* Audio stream */
291struct lola_stream {
292 unsigned int nid; /* audio widget NID */
293 unsigned int index; /* array index */
294 unsigned int dsd; /* DSD index */
295 bool can_float;
296 struct snd_pcm_substream *substream; /* assigned PCM substream */
297 struct lola_stream *master; /* master stream (for multi-channel) */
298
299 /* buffer setup */
300 unsigned int bufsize;
301 unsigned int period_bytes;
302 unsigned int frags;
303
304 /* format + channel setup */
305 unsigned int format_verb;
306
307 /* flags */
308 unsigned int opened:1;
309 unsigned int prepared:1;
310 unsigned int paused:1;
311 unsigned int running:1;
312};
313
314#define PLAY SNDRV_PCM_STREAM_PLAYBACK
315#define CAPT SNDRV_PCM_STREAM_CAPTURE
316
317struct lola_pcm {
318 unsigned int num_streams;
319 struct snd_dma_buffer bdl; /* BDL buffer */
320 struct lola_stream streams[MAX_STREAM_COUNT];
321};
322
323/* card instance */
324struct lola {
325 struct snd_card *card;
326 struct pci_dev *pci;
327
328 /* pci resources */
329 struct lola_bar bar[2];
330 int irq;
331
332 /* locks */
333 spinlock_t reg_lock;
334 struct mutex open_mutex;
335
336 /* CORB/RIRB */
337 struct lola_rb corb;
338 struct lola_rb rirb;
339 unsigned int res, res_ex; /* last read values */
340 /* last command (for debugging) */
341 unsigned int last_cmd_nid, last_verb, last_data, last_extdata;
342
343 /* CORB/RIRB buffers */
344 struct snd_dma_buffer rb;
345
346 /* unsolicited events */
347 unsigned int last_unsol_res;
348
349 /* streams */
350 struct lola_pcm pcm[2];
351
352 /* input src */
353 unsigned int input_src_caps_mask;
354 unsigned int input_src_mask;
355
356 /* pins */
357 struct lola_pin_array pin[2];
358
359 /* clock */
360 struct lola_clock_widget clock;
361 int ref_count_rate;
362 unsigned int sample_rate;
363
364 /* mixer */
365 struct lola_mixer_widget mixer;
366
367 /* hw info */
368 unsigned int version;
369 unsigned int lola_caps;
370
371 /* parameters */
372 unsigned int granularity;
373 unsigned int sample_rate_min;
374 unsigned int sample_rate_max;
375
376 /* flags */
377 unsigned int initialized:1;
378 unsigned int cold_reset:1;
379 unsigned int polling_mode:1;
380
381 /* for debugging */
382 unsigned int debug_res;
383 unsigned int debug_res_ex;
384};
385
386#define BAR0 0
387#define BAR1 1
388
389/* Helper macros */
390#define lola_readl(chip, idx, name) \
391 readl((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
392#define lola_readw(chip, idx, name) \
393 readw((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
394#define lola_readb(chip, idx, name) \
395 readb((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
396#define lola_writel(chip, idx, name, val) \
397 writel((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
398#define lola_writew(chip, idx, name, val) \
399 writew((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
400#define lola_writeb(chip, idx, name, val) \
401 writeb((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
402
403#define lola_dsd_read(chip, dsd, name) \
404 readl((chip)->bar[BAR1].remap_addr + LOLA_BAR1_DSD0_OFFSET + \
405 (LOLA_BAR1_DSD_SIZE * (dsd)) + LOLA_BAR1_DSDn##name)
406#define lola_dsd_write(chip, dsd, name, val) \
407 writel((val), (chip)->bar[BAR1].remap_addr + LOLA_BAR1_DSD0_OFFSET + \
408 (LOLA_BAR1_DSD_SIZE * (dsd)) + LOLA_BAR1_DSDn##name)
409
410/* GET verbs HDAudio */
411#define LOLA_VERB_GET_STREAM_FORMAT 0xa00
412#define LOLA_VERB_GET_AMP_GAIN_MUTE 0xb00
413#define LOLA_VERB_PARAMETERS 0xf00
414#define LOLA_VERB_GET_POWER_STATE 0xf05
415#define LOLA_VERB_GET_CONV 0xf06
416#define LOLA_VERB_GET_UNSOLICITED_RESPONSE 0xf08
417#define LOLA_VERB_GET_DIGI_CONVERT_1 0xf0d
418#define LOLA_VERB_GET_CONFIG_DEFAULT 0xf1c
419#define LOLA_VERB_GET_SUBSYSTEM_ID 0xf20
420/* GET verbs Digigram */
421#define LOLA_VERB_GET_FIXED_GAIN 0xfc0
422#define LOLA_VERB_GET_GAIN_SELECT 0xfc1
423#define LOLA_VERB_GET_MAX_LEVEL 0xfc2
424#define LOLA_VERB_GET_CLOCK_LIST 0xfc3
425#define LOLA_VERB_GET_CLOCK_SELECT 0xfc4
426#define LOLA_VERB_GET_CLOCK_STATUS 0xfc5
427
428/* SET verbs HDAudio */
429#define LOLA_VERB_SET_STREAM_FORMAT 0x200
430#define LOLA_VERB_SET_AMP_GAIN_MUTE 0x300
431#define LOLA_VERB_SET_POWER_STATE 0x705
432#define LOLA_VERB_SET_CHANNEL_STREAMID 0x706
433#define LOLA_VERB_SET_UNSOLICITED_ENABLE 0x708
434#define LOLA_VERB_SET_DIGI_CONVERT_1 0x70d
435/* SET verbs Digigram */
436#define LOLA_VERB_SET_GAIN_SELECT 0xf81
437#define LOLA_VERB_SET_CLOCK_SELECT 0xf84
438#define LOLA_VERB_SET_GRANULARITY_STEPS 0xf86
439#define LOLA_VERB_SET_SOURCE_GAIN 0xf87
440#define LOLA_VERB_SET_MIX_GAIN 0xf88
441#define LOLA_VERB_SET_DESTINATION_GAIN 0xf89
442#define LOLA_VERB_SET_SRC 0xf8a
443
444/* Parameter IDs used with LOLA_VERB_PARAMETERS */
445#define LOLA_PAR_VENDOR_ID 0x00
446#define LOLA_PAR_FUNCTION_TYPE 0x05
447#define LOLA_PAR_AUDIO_WIDGET_CAP 0x09
448#define LOLA_PAR_PCM 0x0a
449#define LOLA_PAR_STREAM_FORMATS 0x0b
450#define LOLA_PAR_PIN_CAP 0x0c
451#define LOLA_PAR_AMP_IN_CAP 0x0d
452#define LOLA_PAR_CONNLIST_LEN 0x0e
453#define LOLA_PAR_POWER_STATE 0x0f
454#define LOLA_PAR_GPIO_CAP 0x11
455#define LOLA_PAR_AMP_OUT_CAP 0x12
456#define LOLA_PAR_SPECIFIC_CAPS 0x80
457#define LOLA_PAR_FIXED_GAIN_LIST 0x81
458
459/* extract results of LOLA_PAR_SPECIFIC_CAPS */
460#define LOLA_AFG_MIXER_WIDGET_PRESENT(res) ((res & (1 << 21)) != 0)
461#define LOLA_AFG_CLOCK_WIDGET_PRESENT(res) ((res & (1 << 20)) != 0)
462#define LOLA_AFG_INPUT_PIN_COUNT(res) ((res >> 10) & 0x2ff)
463#define LOLA_AFG_OUTPUT_PIN_COUNT(res) ((res) & 0x2ff)
464
465/* extract results of LOLA_PAR_AMP_IN_CAP / LOLA_PAR_AMP_OUT_CAP */
466#define LOLA_AMP_MUTE_CAPABLE(res) ((res & (1 << 31)) != 0)
467#define LOLA_AMP_STEP_SIZE(res) ((res >> 24) & 0x7f)
468#define LOLA_AMP_NUM_STEPS(res) ((res >> 12) & 0x3ff)
469#define LOLA_AMP_OFFSET(res) ((res) & 0x3ff)
470
471#define LOLA_GRANULARITY_MIN 8
472#define LOLA_GRANULARITY_MAX 32
473#define LOLA_GRANULARITY_STEP 8
474
475/* parameters used with unsolicited command/response */
476#define LOLA_UNSOLICITED_TAG_MASK 0x3f
477#define LOLA_UNSOLICITED_TAG 0x1a
478#define LOLA_UNSOLICITED_ENABLE 0x80
479#define LOLA_UNSOL_RESP_TAG_OFFSET 26
480
481/* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */
482#define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res) ((res >> 2) & 0x1f)
483#define LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(res) ((res >> 7) & 0x1f)
484
485int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
486 unsigned int data, unsigned int extdata);
487int lola_codec_read(struct lola *chip, unsigned int nid, unsigned int verb,
488 unsigned int data, unsigned int extdata,
489 unsigned int *val, unsigned int *extval);
490int lola_codec_flush(struct lola *chip);
491#define lola_read_param(chip, nid, param, val) \
492 lola_codec_read(chip, nid, LOLA_VERB_PARAMETERS, param, 0, val, NULL)
493
494/* PCM */
495int lola_create_pcm(struct lola *chip);
496void lola_free_pcm(struct lola *chip);
497int lola_init_pcm(struct lola *chip, int dir, int *nidp);
498void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits);
499
500/* clock */
501int lola_init_clock_widget(struct lola *chip, int nid);
502int lola_set_granularity(struct lola *chip, unsigned int val, bool force);
503int lola_enable_clock_events(struct lola *chip);
504int lola_set_clock_index(struct lola *chip, unsigned int idx);
505int lola_set_clock(struct lola *chip, int idx);
506int lola_set_sample_rate(struct lola *chip, int rate);
507bool lola_update_ext_clock_freq(struct lola *chip, unsigned int val);
508unsigned int lola_sample_rate_convert(unsigned int coded);
509
510/* mixer */
511int lola_init_pins(struct lola *chip, int dir, int *nidp);
512int lola_init_mixer_widget(struct lola *chip, int nid);
513void lola_free_mixer(struct lola *chip);
514int lola_create_mixer(struct lola *chip);
515int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute);
516void lola_save_mixer(struct lola *chip);
517void lola_restore_mixer(struct lola *chip);
518int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update);
519
520/* proc */
521#ifdef CONFIG_SND_DEBUG
522void lola_proc_debug_new(struct lola *chip);
523#else
524#define lola_proc_debug_new(chip)
525#endif
526
527#endif /* _LOLA_H */
diff --git a/sound/pci/lola/lola_clock.c b/sound/pci/lola/lola_clock.c
new file mode 100644
index 000000000000..72f8ef0ac865
--- /dev/null
+++ b/sound/pci/lola/lola_clock.c
@@ -0,0 +1,323 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include "lola.h"
27
28unsigned int lola_sample_rate_convert(unsigned int coded)
29{
30 unsigned int freq;
31
32 /* base frequency */
33 switch (coded & 0x3) {
34 case 0: freq = 48000; break;
35 case 1: freq = 44100; break;
36 case 2: freq = 32000; break;
37 default: return 0; /* error */
38 }
39
40 /* multiplier / devisor */
41 switch (coded & 0x1c) {
42 case (0 << 2): break;
43 case (4 << 2): break;
44 case (1 << 2): freq *= 2; break;
45 case (2 << 2): freq *= 4; break;
46 case (5 << 2): freq /= 2; break;
47 case (6 << 2): freq /= 4; break;
48 default: return 0; /* error */
49 }
50
51 /* ajustement */
52 switch (coded & 0x60) {
53 case (0 << 5): break;
54 case (1 << 5): freq = (freq * 999) / 1000; break;
55 case (2 << 5): freq = (freq * 1001) / 1000; break;
56 default: return 0; /* error */
57 }
58 return freq;
59}
60
61/*
62 * Granualrity
63 */
64
65#define LOLA_MAXFREQ_AT_GRANULARITY_MIN 48000
66#define LOLA_MAXFREQ_AT_GRANULARITY_BELOW_MAX 96000
67
68static bool check_gran_clock_compatibility(struct lola *chip,
69 unsigned int val,
70 unsigned int freq)
71{
72 if (!chip->granularity)
73 return true;
74
75 if (val < LOLA_GRANULARITY_MIN || val > LOLA_GRANULARITY_MAX ||
76 (val % LOLA_GRANULARITY_STEP) != 0)
77 return false;
78
79 if (val == LOLA_GRANULARITY_MIN) {
80 if (freq > LOLA_MAXFREQ_AT_GRANULARITY_MIN)
81 return false;
82 } else if (val < LOLA_GRANULARITY_MAX) {
83 if (freq > LOLA_MAXFREQ_AT_GRANULARITY_BELOW_MAX)
84 return false;
85 }
86 return true;
87}
88
89int lola_set_granularity(struct lola *chip, unsigned int val, bool force)
90{
91 int err;
92
93 if (!force) {
94 if (val == chip->granularity)
95 return 0;
96#if 0
97 /* change Gran only if there are no streams allocated ! */
98 if (chip->audio_in_alloc_mask || chip->audio_out_alloc_mask)
99 return -EBUSY;
100#endif
101 if (!check_gran_clock_compatibility(chip, val,
102 chip->clock.cur_freq))
103 return -EINVAL;
104 }
105
106 chip->granularity = val;
107 val /= LOLA_GRANULARITY_STEP;
108
109 /* audio function group */
110 err = lola_codec_write(chip, 1, LOLA_VERB_SET_GRANULARITY_STEPS,
111 val, 0);
112 if (err < 0)
113 return err;
114 /* this can be a very slow function !!! */
115 usleep_range(400 * val, 20000);
116 return lola_codec_flush(chip);
117}
118
119/*
120 * Clock widget handling
121 */
122
123int __devinit lola_init_clock_widget(struct lola *chip, int nid)
124{
125 unsigned int val;
126 int i, j, nitems, nb_verbs, idx, idx_list;
127 int err;
128
129 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
130 if (err < 0) {
131 printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
132 return err;
133 }
134
135 if ((val & 0xfff00000) != 0x01f00000) { /* test SubType and Type */
136 snd_printdd("No valid clock widget\n");
137 return 0;
138 }
139
140 chip->clock.nid = nid;
141 chip->clock.items = val & 0xff;
142 snd_printdd("clock_list nid=%x, entries=%d\n", nid,
143 chip->clock.items);
144 if (chip->clock.items > MAX_SAMPLE_CLOCK_COUNT) {
145 printk(KERN_ERR SFX "CLOCK_LIST too big: %d\n",
146 chip->clock.items);
147 return -EINVAL;
148 }
149
150 nitems = chip->clock.items;
151 nb_verbs = (nitems + 3) / 4;
152 idx = 0;
153 idx_list = 0;
154 for (i = 0; i < nb_verbs; i++) {
155 unsigned int res_ex;
156 unsigned short items[4];
157
158 err = lola_codec_read(chip, nid, LOLA_VERB_GET_CLOCK_LIST,
159 idx, 0, &val, &res_ex);
160 if (err < 0) {
161 printk(KERN_ERR SFX "Can't read CLOCK_LIST\n");
162 return -EINVAL;
163 }
164
165 items[0] = val & 0xfff;
166 items[1] = (val >> 16) & 0xfff;
167 items[2] = res_ex & 0xfff;
168 items[3] = (res_ex >> 16) & 0xfff;
169
170 for (j = 0; j < 4; j++) {
171 unsigned char type = items[j] >> 8;
172 unsigned int freq = items[j] & 0xff;
173 int format = LOLA_CLOCK_FORMAT_NONE;
174 bool add_clock = true;
175 if (type == LOLA_CLOCK_TYPE_INTERNAL) {
176 freq = lola_sample_rate_convert(freq);
177 if (freq < chip->sample_rate_min)
178 add_clock = false;
179 else if (freq == 48000) {
180 chip->clock.cur_index = idx_list;
181 chip->clock.cur_freq = 48000;
182 chip->clock.cur_valid = true;
183 }
184 } else if (type == LOLA_CLOCK_TYPE_VIDEO) {
185 freq = lola_sample_rate_convert(freq);
186 if (freq < chip->sample_rate_min)
187 add_clock = false;
188 /* video clock has a format (0:NTSC, 1:PAL)*/
189 if (items[j] & 0x80)
190 format = LOLA_CLOCK_FORMAT_NTSC;
191 else
192 format = LOLA_CLOCK_FORMAT_PAL;
193 }
194 if (add_clock) {
195 struct lola_sample_clock *sc;
196 sc = &chip->clock.sample_clock[idx_list];
197 sc->type = type;
198 sc->format = format;
199 sc->freq = freq;
200 /* keep the index used with the board */
201 chip->clock.idx_lookup[idx_list] = idx;
202 idx_list++;
203 } else {
204 chip->clock.items--;
205 }
206 if (++idx >= nitems)
207 break;
208 }
209 }
210 return 0;
211}
212
213/* enable unsolicited events of the clock widget */
214int lola_enable_clock_events(struct lola *chip)
215{
216 unsigned int res;
217 int err;
218
219 err = lola_codec_read(chip, chip->clock.nid,
220 LOLA_VERB_SET_UNSOLICITED_ENABLE,
221 LOLA_UNSOLICITED_ENABLE | LOLA_UNSOLICITED_TAG,
222 0, &res, NULL);
223 if (err < 0)
224 return err;
225 if (res) {
226 printk(KERN_WARNING SFX "error in enable_clock_events %d\n",
227 res);
228 return -EINVAL;
229 }
230 return 0;
231}
232
233int lola_set_clock_index(struct lola *chip, unsigned int idx)
234{
235 unsigned int res;
236 int err;
237
238 err = lola_codec_read(chip, chip->clock.nid,
239 LOLA_VERB_SET_CLOCK_SELECT,
240 chip->clock.idx_lookup[idx],
241 0, &res, NULL);
242 if (err < 0)
243 return err;
244 if (res) {
245 printk(KERN_WARNING SFX "error in set_clock %d\n", res);
246 return -EINVAL;
247 }
248 return 0;
249}
250
251bool lola_update_ext_clock_freq(struct lola *chip, unsigned int val)
252{
253 unsigned int tag;
254
255 /* the current EXTERNAL clock information gets updated by interrupt
256 * with an unsolicited response
257 */
258 if (!val)
259 return false;
260 tag = (val >> LOLA_UNSOL_RESP_TAG_OFFSET) & LOLA_UNSOLICITED_TAG_MASK;
261 if (tag != LOLA_UNSOLICITED_TAG)
262 return false;
263
264 /* only for current = external clocks */
265 if (chip->clock.sample_clock[chip->clock.cur_index].type !=
266 LOLA_CLOCK_TYPE_INTERNAL) {
267 chip->clock.cur_freq = lola_sample_rate_convert(val & 0x7f);
268 chip->clock.cur_valid = (val & 0x100) != 0;
269 }
270 return true;
271}
272
273int lola_set_clock(struct lola *chip, int idx)
274{
275 int freq = 0;
276 bool valid = false;
277
278 if (idx == chip->clock.cur_index) {
279 /* current clock is allowed */
280 freq = chip->clock.cur_freq;
281 valid = chip->clock.cur_valid;
282 } else if (chip->clock.sample_clock[idx].type ==
283 LOLA_CLOCK_TYPE_INTERNAL) {
284 /* internal clocks allowed */
285 freq = chip->clock.sample_clock[idx].freq;
286 valid = true;
287 }
288
289 if (!freq || !valid)
290 return -EINVAL;
291
292 if (!check_gran_clock_compatibility(chip, chip->granularity, freq))
293 return -EINVAL;
294
295 if (idx != chip->clock.cur_index) {
296 int err = lola_set_clock_index(chip, idx);
297 if (err < 0)
298 return err;
299 /* update new settings */
300 chip->clock.cur_index = idx;
301 chip->clock.cur_freq = freq;
302 chip->clock.cur_valid = true;
303 }
304 return 0;
305}
306
307int lola_set_sample_rate(struct lola *chip, int rate)
308{
309 int i;
310
311 if (chip->clock.cur_freq == rate && chip->clock.cur_valid)
312 return 0;
313 /* search for new dwClockIndex */
314 for (i = 0; i < chip->clock.items; i++) {
315 if (chip->clock.sample_clock[i].type == LOLA_CLOCK_TYPE_INTERNAL &&
316 chip->clock.sample_clock[i].freq == rate)
317 break;
318 }
319 if (i >= chip->clock.items)
320 return -EINVAL;
321 return lola_set_clock(chip, i);
322}
323
diff --git a/sound/pci/lola/lola_mixer.c b/sound/pci/lola/lola_mixer.c
new file mode 100644
index 000000000000..5d518f1a712c
--- /dev/null
+++ b/sound/pci/lola/lola_mixer.c
@@ -0,0 +1,839 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/vmalloc.h>
24#include <linux/io.h>
25#include <sound/core.h>
26#include <sound/control.h>
27#include <sound/pcm.h>
28#include <sound/tlv.h>
29#include "lola.h"
30
31static int __devinit lola_init_pin(struct lola *chip, struct lola_pin *pin,
32 int dir, int nid)
33{
34 unsigned int val;
35 int err;
36
37 pin->nid = nid;
38 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
39 if (err < 0) {
40 printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
41 return err;
42 }
43 val &= 0x00f00fff; /* test TYPE and bits 0..11 */
44 if (val == 0x00400200) /* Type = 4, Digital = 1 */
45 pin->is_analog = false;
46 else if (val == 0x0040000a && dir == CAPT) /* Dig=0, InAmp/ovrd */
47 pin->is_analog = true;
48 else if (val == 0x0040000c && dir == PLAY) /* Dig=0, OutAmp/ovrd */
49 pin->is_analog = true;
50 else {
51 printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n", val, nid);
52 return -EINVAL;
53 }
54
55 /* analog parameters only following, so continue in case of Digital pin
56 */
57 if (!pin->is_analog)
58 return 0;
59
60 if (dir == PLAY)
61 err = lola_read_param(chip, nid, LOLA_PAR_AMP_OUT_CAP, &val);
62 else
63 err = lola_read_param(chip, nid, LOLA_PAR_AMP_IN_CAP, &val);
64 if (err < 0) {
65 printk(KERN_ERR SFX "Can't read AMP-caps for 0x%x\n", nid);
66 return err;
67 }
68
69 pin->amp_mute = LOLA_AMP_MUTE_CAPABLE(val);
70 pin->amp_step_size = LOLA_AMP_STEP_SIZE(val);
71 pin->amp_num_steps = LOLA_AMP_NUM_STEPS(val);
72 if (pin->amp_num_steps) {
73 /* zero as mute state */
74 pin->amp_num_steps++;
75 pin->amp_step_size++;
76 }
77 pin->amp_offset = LOLA_AMP_OFFSET(val);
78
79 err = lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val,
80 NULL);
81 if (err < 0) {
82 printk(KERN_ERR SFX "Can't get MAX_LEVEL 0x%x\n", nid);
83 return err;
84 }
85 pin->max_level = val & 0x3ff; /* 10 bits */
86
87 pin->config_default_reg = 0;
88 pin->fixed_gain_list_len = 0;
89 pin->cur_gain_step = 0;
90
91 return 0;
92}
93
94int __devinit lola_init_pins(struct lola *chip, int dir, int *nidp)
95{
96 int i, err, nid;
97 nid = *nidp;
98 for (i = 0; i < chip->pin[dir].num_pins; i++, nid++) {
99 err = lola_init_pin(chip, &chip->pin[dir].pins[i], dir, nid);
100 if (err < 0)
101 return err;
102 if (chip->pin[dir].pins[i].is_analog)
103 chip->pin[dir].num_analog_pins++;
104 }
105 *nidp = nid;
106 return 0;
107}
108
109void lola_free_mixer(struct lola *chip)
110{
111 if (chip->mixer.array_saved)
112 vfree(chip->mixer.array_saved);
113}
114
115int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
116{
117 unsigned int val;
118 int err;
119
120 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
121 if (err < 0) {
122 printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
123 return err;
124 }
125
126 if ((val & 0xfff00000) != 0x02f00000) { /* test SubType and Type */
127 snd_printdd("No valid mixer widget\n");
128 return 0;
129 }
130
131 chip->mixer.nid = nid;
132 chip->mixer.caps = val;
133 chip->mixer.array = (struct lola_mixer_array __iomem *)
134 (chip->bar[BAR1].remap_addr + LOLA_BAR1_SOURCE_GAIN_ENABLE);
135
136 /* reserve memory to copy mixer data for sleep mode transitions */
137 chip->mixer.array_saved = vmalloc(sizeof(struct lola_mixer_array));
138
139 /* mixer matrix sources are physical input data and play streams */
140 chip->mixer.src_stream_outs = chip->pcm[PLAY].num_streams;
141 chip->mixer.src_phys_ins = chip->pin[CAPT].num_pins;
142
143 /* mixer matrix destinations are record streams and physical output */
144 chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
145 chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;
146
147 /* mixer matrix can have unused areas between PhysIn and
148 * Play or Record and PhysOut zones
149 */
150 chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
151 LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
152 chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
153 LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(val);
154
155 /* example : MixerMatrix of LoLa881
156 * 0-------8------16-------8------16
157 * | | | | |
158 * | INPUT | | INPUT | |
159 * | -> |unused | -> |unused |
160 * | RECORD| | OUTPUT| |
161 * | | | | |
162 * 8--------------------------------
163 * | | | | |
164 * | | | | |
165 * |unused |unused |unused |unused |
166 * | | | | |
167 * | | | | |
168 * 16-------------------------------
169 * | | | | |
170 * | PLAY | | PLAY | |
171 * | -> |unused | -> |unused |
172 * | RECORD| | OUTPUT| |
173 * | | | | |
174 * 8--------------------------------
175 * | | | | |
176 * | | | | |
177 * |unused |unused |unused |unused |
178 * | | | | |
179 * | | | | |
180 * 16-------------------------------
181 */
182 if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
183 chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) {
184 printk(KERN_ERR SFX "Invalid mixer widget size\n");
185 return -EINVAL;
186 }
187
188 chip->mixer.src_mask = ((1U << chip->mixer.src_phys_ins) - 1) |
189 (((1U << chip->mixer.src_stream_outs) - 1)
190 << chip->mixer.src_stream_out_ofs);
191 chip->mixer.dest_mask = ((1U << chip->mixer.dest_stream_ins) - 1) |
192 (((1U << chip->mixer.dest_phys_outs) - 1)
193 << chip->mixer.dest_phys_out_ofs);
194
195 return 0;
196}
197
198static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
199 unsigned short gain, bool on)
200{
201 unsigned int oldval, val;
202
203 if (!(chip->mixer.src_mask & (1 << id)))
204 return -EINVAL;
205 writew(gain, &chip->mixer.array->src_gain[id]);
206 oldval = val = readl(&chip->mixer.array->src_gain_enable);
207 if (on)
208 val |= (1 << id);
209 else
210 val &= ~(1 << id);
211 writel(val, &chip->mixer.array->src_gain_enable);
212 lola_codec_flush(chip);
213 /* inform micro-controller about the new source gain */
214 return lola_codec_write(chip, chip->mixer.nid,
215 LOLA_VERB_SET_SOURCE_GAIN, id, 0);
216}
217
218#if 0 /* not used */
219static int lola_mixer_set_src_gains(struct lola *chip, unsigned int mask,
220 unsigned short *gains)
221{
222 int i;
223
224 if ((chip->mixer.src_mask & mask) != mask)
225 return -EINVAL;
226 for (i = 0; i < LOLA_MIXER_DIM; i++) {
227 if (mask & (1 << i)) {
228 writew(*gains, &chip->mixer.array->src_gain[i]);
229 gains++;
230 }
231 }
232 writel(mask, &chip->mixer.array->src_gain_enable);
233 lola_codec_flush(chip);
234 if (chip->mixer.caps & LOLA_PEAK_METER_CAN_AGC_MASK) {
235 /* update for all srcs at once */
236 return lola_codec_write(chip, chip->mixer.nid,
237 LOLA_VERB_SET_SOURCE_GAIN, 0x80, 0);
238 }
239 /* update manually */
240 for (i = 0; i < LOLA_MIXER_DIM; i++) {
241 if (mask & (1 << i)) {
242 lola_codec_write(chip, chip->mixer.nid,
243 LOLA_VERB_SET_SOURCE_GAIN, i, 0);
244 }
245 }
246 return 0;
247}
248#endif /* not used */
249
250static int lola_mixer_set_mapping_gain(struct lola *chip,
251 unsigned int src, unsigned int dest,
252 unsigned short gain, bool on)
253{
254 unsigned int val;
255
256 if (!(chip->mixer.src_mask & (1 << src)) ||
257 !(chip->mixer.dest_mask & (1 << dest)))
258 return -EINVAL;
259 if (on)
260 writew(gain, &chip->mixer.array->dest_mix_gain[dest][src]);
261 val = readl(&chip->mixer.array->dest_mix_gain_enable[dest]);
262 if (on)
263 val |= (1 << src);
264 else
265 val &= ~(1 << src);
266 writel(val, &chip->mixer.array->dest_mix_gain_enable[dest]);
267 lola_codec_flush(chip);
268 return lola_codec_write(chip, chip->mixer.nid, LOLA_VERB_SET_MIX_GAIN,
269 src, dest);
270}
271
272static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
273 unsigned int mask, unsigned short *gains)
274{
275 int i;
276
277 if (!(chip->mixer.dest_mask & (1 << id)) ||
278 (chip->mixer.src_mask & mask) != mask)
279 return -EINVAL;
280 for (i = 0; i < LOLA_MIXER_DIM; i++) {
281 if (mask & (1 << i)) {
282 writew(*gains, &chip->mixer.array->dest_mix_gain[id][i]);
283 gains++;
284 }
285 }
286 writel(mask, &chip->mixer.array->dest_mix_gain_enable[id]);
287 lola_codec_flush(chip);
288 /* update for all dests at once */
289 return lola_codec_write(chip, chip->mixer.nid,
290 LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
291}
292
293/*
294 */
295
296static int set_analog_volume(struct lola *chip, int dir,
297 unsigned int idx, unsigned int val,
298 bool external_call);
299
300int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute)
301{
302 struct lola_pin *pin;
303 int idx, max_idx;
304
305 pin = chip->pin[dir].pins;
306 max_idx = chip->pin[dir].num_pins;
307 for (idx = 0; idx < max_idx; idx++) {
308 if (pin[idx].is_analog) {
309 unsigned int val = mute ? 0 : pin[idx].cur_gain_step;
310 /* set volume and do not save the value */
311 set_analog_volume(chip, dir, idx, val, false);
312 }
313 }
314 return lola_codec_flush(chip);
315}
316
317void lola_save_mixer(struct lola *chip)
318{
319 /* mute analog output */
320 if (chip->mixer.array_saved) {
321 /* store contents of mixer array */
322 memcpy_fromio(chip->mixer.array_saved, chip->mixer.array,
323 sizeof(*chip->mixer.array));
324 }
325 lola_setup_all_analog_gains(chip, PLAY, true); /* output mute */
326}
327
328void lola_restore_mixer(struct lola *chip)
329{
330 int i;
331
332 /*lola_reset_setups(chip);*/
333 if (chip->mixer.array_saved) {
334 /* restore contents of mixer array */
335 memcpy_toio(chip->mixer.array, chip->mixer.array_saved,
336 sizeof(*chip->mixer.array));
337 /* inform micro-controller about all restored values
338 * and ignore return values
339 */
340 for (i = 0; i < chip->mixer.src_phys_ins; i++)
341 lola_codec_write(chip, chip->mixer.nid,
342 LOLA_VERB_SET_SOURCE_GAIN,
343 i, 0);
344 for (i = 0; i < chip->mixer.src_stream_outs; i++)
345 lola_codec_write(chip, chip->mixer.nid,
346 LOLA_VERB_SET_SOURCE_GAIN,
347 chip->mixer.src_stream_out_ofs + i, 0);
348 for (i = 0; i < chip->mixer.dest_stream_ins; i++)
349 lola_codec_write(chip, chip->mixer.nid,
350 LOLA_VERB_SET_DESTINATION_GAIN,
351 i, 0);
352 for (i = 0; i < chip->mixer.dest_phys_outs; i++)
353 lola_codec_write(chip, chip->mixer.nid,
354 LOLA_VERB_SET_DESTINATION_GAIN,
355 chip->mixer.dest_phys_out_ofs + i, 0);
356 lola_codec_flush(chip);
357 }
358}
359
360/*
361 */
362
363static int set_analog_volume(struct lola *chip, int dir,
364 unsigned int idx, unsigned int val,
365 bool external_call)
366{
367 struct lola_pin *pin;
368 int err;
369
370 if (idx >= chip->pin[dir].num_pins)
371 return -EINVAL;
372 pin = &chip->pin[dir].pins[idx];
373 if (!pin->is_analog || pin->amp_num_steps <= val)
374 return -EINVAL;
375 if (external_call && pin->cur_gain_step == val)
376 return 0;
377 if (external_call)
378 lola_codec_flush(chip);
379 err = lola_codec_write(chip, pin->nid,
380 LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
381 if (err < 0)
382 return err;
383 if (external_call)
384 pin->cur_gain_step = val;
385 return 0;
386}
387
388int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update)
389{
390 int ret = 0;
391 int success = 0;
392 int n, err;
393
394 /* SRC can be activated and the dwInputSRCMask is valid? */
395 if ((chip->input_src_caps_mask & src_mask) != src_mask)
396 return -EINVAL;
397 /* handle all even Inputs - SRC is a stereo setting !!! */
398 for (n = 0; n < chip->pin[CAPT].num_pins; n += 2) {
399 unsigned int mask = 3U << n; /* handle the stereo case */
400 unsigned int new_src, src_state;
401 if (!(chip->input_src_caps_mask & mask))
402 continue;
403 /* if one IO needs SRC, both stereo IO will get SRC */
404 new_src = (src_mask & mask) != 0;
405 if (update) {
406 src_state = (chip->input_src_mask & mask) != 0;
407 if (src_state == new_src)
408 continue; /* nothing to change for this IO */
409 }
410 err = lola_codec_write(chip, chip->pcm[CAPT].streams[n].nid,
411 LOLA_VERB_SET_SRC, new_src, 0);
412 if (!err)
413 success++;
414 else
415 ret = err;
416 }
417 if (success)
418 ret = lola_codec_flush(chip);
419 if (!ret)
420 chip->input_src_mask = src_mask;
421 return ret;
422}
423
424/*
425 */
426static int init_mixer_values(struct lola *chip)
427{
428 int i;
429
430 /* all src on */
431 lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);
432
433 /* clear all matrix */
434 memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
435 /* set src gain to 0dB */
436 for (i = 0; i < chip->mixer.src_phys_ins; i++)
437 lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */
438 for (i = 0; i < chip->mixer.src_stream_outs; i++)
439 lola_mixer_set_src_gain(chip,
440 i + chip->mixer.src_stream_out_ofs,
441 336, true); /* 0dB */
442 /* set 1:1 dest gain */
443 for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
444 int src = i % chip->mixer.src_phys_ins;
445 lola_mixer_set_mapping_gain(chip, src, i, 336, true);
446 }
447 for (i = 0; i < chip->mixer.src_stream_outs; i++) {
448 int src = chip->mixer.src_stream_out_ofs + i;
449 int dst = chip->mixer.dest_phys_out_ofs +
450 i % chip->mixer.dest_phys_outs;
451 lola_mixer_set_mapping_gain(chip, src, dst, 336, true);
452 }
453 return 0;
454}
455
456/*
457 * analog mixer control element
458 */
459static int lola_analog_vol_info(struct snd_kcontrol *kcontrol,
460 struct snd_ctl_elem_info *uinfo)
461{
462 struct lola *chip = snd_kcontrol_chip(kcontrol);
463 int dir = kcontrol->private_value;
464
465 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
466 uinfo->count = chip->pin[dir].num_pins;
467 uinfo->value.integer.min = 0;
468 uinfo->value.integer.max = chip->pin[dir].pins[0].amp_num_steps;
469 return 0;
470}
471
472static int lola_analog_vol_get(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_value *ucontrol)
474{
475 struct lola *chip = snd_kcontrol_chip(kcontrol);
476 int dir = kcontrol->private_value;
477 int i;
478
479 for (i = 0; i < chip->pin[dir].num_pins; i++)
480 ucontrol->value.integer.value[i] =
481 chip->pin[dir].pins[i].cur_gain_step;
482 return 0;
483}
484
485static int lola_analog_vol_put(struct snd_kcontrol *kcontrol,
486 struct snd_ctl_elem_value *ucontrol)
487{
488 struct lola *chip = snd_kcontrol_chip(kcontrol);
489 int dir = kcontrol->private_value;
490 int i, err;
491
492 for (i = 0; i < chip->pin[dir].num_pins; i++) {
493 err = set_analog_volume(chip, dir, i,
494 ucontrol->value.integer.value[i],
495 true);
496 if (err < 0)
497 return err;
498 }
499 return 0;
500}
501
502static int lola_analog_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
503 unsigned int size, unsigned int __user *tlv)
504{
505 struct lola *chip = snd_kcontrol_chip(kcontrol);
506 int dir = kcontrol->private_value;
507 unsigned int val1, val2;
508 struct lola_pin *pin;
509
510 if (size < 4 * sizeof(unsigned int))
511 return -ENOMEM;
512 pin = &chip->pin[dir].pins[0];
513
514 val2 = pin->amp_step_size * 25;
515 val1 = -1 * (int)pin->amp_offset * (int)val2;
516#ifdef TLV_DB_SCALE_MUTE
517 val2 |= TLV_DB_SCALE_MUTE;
518#endif
519 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, tlv))
520 return -EFAULT;
521 if (put_user(2 * sizeof(unsigned int), tlv + 1))
522 return -EFAULT;
523 if (put_user(val1, tlv + 2))
524 return -EFAULT;
525 if (put_user(val2, tlv + 3))
526 return -EFAULT;
527 return 0;
528}
529
530static struct snd_kcontrol_new lola_analog_mixer __devinitdata = {
531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
532 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
533 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
534 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK),
535 .info = lola_analog_vol_info,
536 .get = lola_analog_vol_get,
537 .put = lola_analog_vol_put,
538 .tlv.c = lola_analog_vol_tlv,
539};
540
541static int __devinit create_analog_mixer(struct lola *chip, int dir, char *name)
542{
543 if (!chip->pin[dir].num_pins)
544 return 0;
545 /* no analog volumes on digital only adapters */
546 if (chip->pin[dir].num_pins != chip->pin[dir].num_analog_pins)
547 return 0;
548 lola_analog_mixer.name = name;
549 lola_analog_mixer.private_value = dir;
550 return snd_ctl_add(chip->card,
551 snd_ctl_new1(&lola_analog_mixer, chip));
552}
553
554/*
555 * Hardware sample rate converter on digital input
556 */
557static int lola_input_src_info(struct snd_kcontrol *kcontrol,
558 struct snd_ctl_elem_info *uinfo)
559{
560 struct lola *chip = snd_kcontrol_chip(kcontrol);
561
562 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
563 uinfo->count = chip->pin[CAPT].num_pins;
564 uinfo->value.integer.min = 0;
565 uinfo->value.integer.max = 1;
566 return 0;
567}
568
569static int lola_input_src_get(struct snd_kcontrol *kcontrol,
570 struct snd_ctl_elem_value *ucontrol)
571{
572 struct lola *chip = snd_kcontrol_chip(kcontrol);
573 int i;
574
575 for (i = 0; i < chip->pin[CAPT].num_pins; i++)
576 ucontrol->value.integer.value[i] =
577 !!(chip->input_src_mask & (1 << i));
578 return 0;
579}
580
581static int lola_input_src_put(struct snd_kcontrol *kcontrol,
582 struct snd_ctl_elem_value *ucontrol)
583{
584 struct lola *chip = snd_kcontrol_chip(kcontrol);
585 int i;
586 unsigned int mask;
587
588 mask = 0;
589 for (i = 0; i < chip->pin[CAPT].num_pins; i++)
590 if (ucontrol->value.integer.value[i])
591 mask |= 1 << i;
592 return lola_set_src_config(chip, mask, true);
593}
594
595static struct snd_kcontrol_new lola_input_src_mixer __devinitdata = {
596 .name = "Digital SRC Capture Switch",
597 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
598 .info = lola_input_src_info,
599 .get = lola_input_src_get,
600 .put = lola_input_src_put,
601};
602
603/*
604 * Lola16161 or Lola881 can have Hardware sample rate converters
605 * on its digital input pins
606 */
607static int __devinit create_input_src_mixer(struct lola *chip)
608{
609 if (!chip->input_src_caps_mask)
610 return 0;
611
612 return snd_ctl_add(chip->card,
613 snd_ctl_new1(&lola_input_src_mixer, chip));
614}
615
616/*
617 * src gain mixer
618 */
619static int lola_src_gain_info(struct snd_kcontrol *kcontrol,
620 struct snd_ctl_elem_info *uinfo)
621{
622 unsigned int count = (kcontrol->private_value >> 8) & 0xff;
623
624 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
625 uinfo->count = count;
626 uinfo->value.integer.min = 0;
627 uinfo->value.integer.max = 409;
628 return 0;
629}
630
631static int lola_src_gain_get(struct snd_kcontrol *kcontrol,
632 struct snd_ctl_elem_value *ucontrol)
633{
634 struct lola *chip = snd_kcontrol_chip(kcontrol);
635 unsigned int ofs = kcontrol->private_value & 0xff;
636 unsigned int count = (kcontrol->private_value >> 8) & 0xff;
637 unsigned int mask, i;
638
639 mask = readl(&chip->mixer.array->src_gain_enable);
640 for (i = 0; i < count; i++) {
641 unsigned int idx = ofs + i;
642 unsigned short val;
643 if (!(chip->mixer.src_mask & (1 << idx)))
644 return -EINVAL;
645 if (mask & (1 << idx))
646 val = readw(&chip->mixer.array->src_gain[idx]) + 1;
647 else
648 val = 0;
649 ucontrol->value.integer.value[i] = val;
650 }
651 return 0;
652}
653
654static int lola_src_gain_put(struct snd_kcontrol *kcontrol,
655 struct snd_ctl_elem_value *ucontrol)
656{
657 struct lola *chip = snd_kcontrol_chip(kcontrol);
658 unsigned int ofs = kcontrol->private_value & 0xff;
659 unsigned int count = (kcontrol->private_value >> 8) & 0xff;
660 int i, err;
661
662 for (i = 0; i < count; i++) {
663 unsigned int idx = ofs + i;
664 unsigned short val = ucontrol->value.integer.value[i];
665 if (val)
666 val--;
667 err = lola_mixer_set_src_gain(chip, idx, val, !!val);
668 if (err < 0)
669 return err;
670 }
671 return 0;
672}
673
674/* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */
675static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv, -8425, 25, 1);
676
677static struct snd_kcontrol_new lola_src_gain_mixer __devinitdata = {
678 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
679 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
680 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
681 .info = lola_src_gain_info,
682 .get = lola_src_gain_get,
683 .put = lola_src_gain_put,
684 .tlv.p = lola_src_gain_tlv,
685};
686
687static int __devinit create_src_gain_mixer(struct lola *chip,
688 int num, int ofs, char *name)
689{
690 lola_src_gain_mixer.name = name;
691 lola_src_gain_mixer.private_value = ofs + (num << 8);
692 return snd_ctl_add(chip->card,
693 snd_ctl_new1(&lola_src_gain_mixer, chip));
694}
695
696/*
697 * destination gain (matrix-like) mixer
698 */
699static int lola_dest_gain_info(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_info *uinfo)
701{
702 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
703
704 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
705 uinfo->count = src_num;
706 uinfo->value.integer.min = 0;
707 uinfo->value.integer.max = 433;
708 return 0;
709}
710
711static int lola_dest_gain_get(struct snd_kcontrol *kcontrol,
712 struct snd_ctl_elem_value *ucontrol)
713{
714 struct lola *chip = snd_kcontrol_chip(kcontrol);
715 unsigned int src_ofs = kcontrol->private_value & 0xff;
716 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
717 unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
718 unsigned int dst, mask, i;
719
720 dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
721 mask = readl(&chip->mixer.array->dest_mix_gain_enable[dst]);
722 for (i = 0; i < src_num; i++) {
723 unsigned int src = src_ofs + i;
724 unsigned short val;
725 if (!(chip->mixer.src_mask & (1 << src)))
726 return -EINVAL;
727 if (mask & (1 << dst))
728 val = readw(&chip->mixer.array->dest_mix_gain[dst][src]) + 1;
729 else
730 val = 0;
731 ucontrol->value.integer.value[i] = val;
732 }
733 return 0;
734}
735
736static int lola_dest_gain_put(struct snd_kcontrol *kcontrol,
737 struct snd_ctl_elem_value *ucontrol)
738{
739 struct lola *chip = snd_kcontrol_chip(kcontrol);
740 unsigned int src_ofs = kcontrol->private_value & 0xff;
741 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
742 unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
743 unsigned int dst, mask;
744 unsigned short gains[MAX_STREAM_COUNT];
745 int i, num;
746
747 mask = 0;
748 num = 0;
749 for (i = 0; i < src_num; i++) {
750 unsigned short val = ucontrol->value.integer.value[i];
751 if (val) {
752 gains[num++] = val - 1;
753 mask |= 1 << i;
754 }
755 }
756 mask <<= src_ofs;
757 dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
758 return lola_mixer_set_dest_gains(chip, dst, mask, gains);
759}
760
761static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv, -8425, 25, 1);
762
763static struct snd_kcontrol_new lola_dest_gain_mixer __devinitdata = {
764 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
765 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
766 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
767 .info = lola_dest_gain_info,
768 .get = lola_dest_gain_get,
769 .put = lola_dest_gain_put,
770 .tlv.p = lola_dest_gain_tlv,
771};
772
773static int __devinit create_dest_gain_mixer(struct lola *chip,
774 int src_num, int src_ofs,
775 int num, int ofs, char *name)
776{
777 lola_dest_gain_mixer.count = num;
778 lola_dest_gain_mixer.name = name;
779 lola_dest_gain_mixer.private_value =
780 src_ofs + (src_num << 8) + (ofs << 16) + (num << 24);
781 return snd_ctl_add(chip->card,
782 snd_ctl_new1(&lola_dest_gain_mixer, chip));
783}
784
785/*
786 */
787int __devinit lola_create_mixer(struct lola *chip)
788{
789 int err;
790
791 err = create_analog_mixer(chip, PLAY, "Analog Playback Volume");
792 if (err < 0)
793 return err;
794 err = create_analog_mixer(chip, CAPT, "Analog Capture Volume");
795 if (err < 0)
796 return err;
797 err = create_input_src_mixer(chip);
798 if (err < 0)
799 return err;
800 err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
801 "Line Source Gain Volume");
802 if (err < 0)
803 return err;
804 err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
805 chip->mixer.src_stream_out_ofs,
806 "Stream Source Gain Volume");
807 if (err < 0)
808 return err;
809 err = create_dest_gain_mixer(chip,
810 chip->mixer.src_phys_ins, 0,
811 chip->mixer.dest_stream_ins, 0,
812 "Line Capture Volume");
813 if (err < 0)
814 return err;
815 err = create_dest_gain_mixer(chip,
816 chip->mixer.src_stream_outs,
817 chip->mixer.src_stream_out_ofs,
818 chip->mixer.dest_stream_ins, 0,
819 "Stream-Loopback Capture Volume");
820 if (err < 0)
821 return err;
822 err = create_dest_gain_mixer(chip,
823 chip->mixer.src_phys_ins, 0,
824 chip->mixer.dest_phys_outs,
825 chip->mixer.dest_phys_out_ofs,
826 "Line-Loopback Playback Volume");
827 if (err < 0)
828 return err;
829 err = create_dest_gain_mixer(chip,
830 chip->mixer.src_stream_outs,
831 chip->mixer.src_stream_out_ofs,
832 chip->mixer.dest_phys_outs,
833 chip->mixer.dest_phys_out_ofs,
834 "Stream Playback Volume");
835 if (err < 0)
836 return err;
837
838 return init_mixer_values(chip);
839}
diff --git a/sound/pci/lola/lola_pcm.c b/sound/pci/lola/lola_pcm.c
new file mode 100644
index 000000000000..c44db68eecb5
--- /dev/null
+++ b/sound/pci/lola/lola_pcm.c
@@ -0,0 +1,706 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/dma-mapping.h>
24#include <linux/pci.h>
25#include <linux/delay.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include "lola.h"
29
30#define LOLA_MAX_BDL_ENTRIES 8
31#define LOLA_MAX_BUF_SIZE (1024*1024*1024)
32#define LOLA_BDL_ENTRY_SIZE (16 * 16)
33
34static struct lola_pcm *lola_get_pcm(struct snd_pcm_substream *substream)
35{
36 struct lola *chip = snd_pcm_substream_chip(substream);
37 return &chip->pcm[substream->stream];
38}
39
40static struct lola_stream *lola_get_stream(struct snd_pcm_substream *substream)
41{
42 struct lola_pcm *pcm = lola_get_pcm(substream);
43 unsigned int idx = substream->number;
44 return &pcm->streams[idx];
45}
46
47static unsigned int lola_get_lrc(struct lola *chip)
48{
49 return lola_readl(chip, BAR1, LRC);
50}
51
52static unsigned int lola_get_tstamp(struct lola *chip, bool quick_no_sync)
53{
54 unsigned int tstamp = lola_get_lrc(chip) >> 8;
55 if (chip->granularity) {
56 unsigned int wait_banks = quick_no_sync ? 0 : 8;
57 tstamp += (wait_banks + 1) * chip->granularity - 1;
58 tstamp -= tstamp % chip->granularity;
59 }
60 return tstamp << 8;
61}
62
63/* clear any pending interrupt status */
64static void lola_stream_clear_pending_irq(struct lola *chip,
65 struct lola_stream *str)
66{
67 unsigned int val = lola_dsd_read(chip, str->dsd, STS);
68 val &= LOLA_DSD_STS_DESE | LOLA_DSD_STS_BCIS;
69 if (val)
70 lola_dsd_write(chip, str->dsd, STS, val);
71}
72
73static void lola_stream_start(struct lola *chip, struct lola_stream *str,
74 unsigned int tstamp)
75{
76 lola_stream_clear_pending_irq(chip, str);
77 lola_dsd_write(chip, str->dsd, CTL,
78 LOLA_DSD_CTL_SRUN |
79 LOLA_DSD_CTL_IOCE |
80 LOLA_DSD_CTL_DEIE |
81 LOLA_DSD_CTL_VLRCV |
82 tstamp);
83}
84
85static void lola_stream_stop(struct lola *chip, struct lola_stream *str,
86 unsigned int tstamp)
87{
88 lola_dsd_write(chip, str->dsd, CTL,
89 LOLA_DSD_CTL_IOCE |
90 LOLA_DSD_CTL_DEIE |
91 LOLA_DSD_CTL_VLRCV |
92 tstamp);
93 lola_stream_clear_pending_irq(chip, str);
94}
95
96static void wait_for_srst_clear(struct lola *chip, struct lola_stream *str)
97{
98 unsigned long end_time = jiffies + msecs_to_jiffies(200);
99 while (time_before(jiffies, end_time)) {
100 unsigned int val;
101 val = lola_dsd_read(chip, str->dsd, CTL);
102 if (!(val & LOLA_DSD_CTL_SRST))
103 return;
104 msleep(1);
105 }
106 printk(KERN_WARNING SFX "SRST not clear (stream %d)\n", str->dsd);
107}
108
109static int lola_stream_wait_for_fifo(struct lola *chip,
110 struct lola_stream *str,
111 bool ready)
112{
113 unsigned int val = ready ? LOLA_DSD_STS_FIFORDY : 0;
114 unsigned long end_time = jiffies + msecs_to_jiffies(200);
115 while (time_before(jiffies, end_time)) {
116 unsigned int reg = lola_dsd_read(chip, str->dsd, STS);
117 if ((reg & LOLA_DSD_STS_FIFORDY) == val)
118 return 0;
119 msleep(1);
120 }
121 printk(KERN_WARNING SFX "FIFO not ready (stream %d)\n", str->dsd);
122 return -EIO;
123}
124
125/* sync for FIFO ready/empty for all linked streams;
126 * clear paused flag when FIFO gets ready again
127 */
128static int lola_sync_wait_for_fifo(struct lola *chip,
129 struct snd_pcm_substream *substream,
130 bool ready)
131{
132 unsigned int val = ready ? LOLA_DSD_STS_FIFORDY : 0;
133 unsigned long end_time = jiffies + msecs_to_jiffies(200);
134 struct snd_pcm_substream *s;
135 int pending = 0;
136
137 while (time_before(jiffies, end_time)) {
138 pending = 0;
139 snd_pcm_group_for_each_entry(s, substream) {
140 struct lola_stream *str;
141 if (s->pcm->card != substream->pcm->card)
142 continue;
143 str = lola_get_stream(s);
144 if (str->prepared && str->paused) {
145 unsigned int reg;
146 reg = lola_dsd_read(chip, str->dsd, STS);
147 if ((reg & LOLA_DSD_STS_FIFORDY) != val) {
148 pending = str->dsd + 1;
149 break;
150 }
151 if (ready)
152 str->paused = 0;
153 }
154 }
155 if (!pending)
156 return 0;
157 msleep(1);
158 }
159 printk(KERN_WARNING SFX "FIFO not ready (pending %d)\n", pending - 1);
160 return -EIO;
161}
162
163/* finish pause - prepare for a new resume */
164static void lola_sync_pause(struct lola *chip,
165 struct snd_pcm_substream *substream)
166{
167 struct snd_pcm_substream *s;
168
169 lola_sync_wait_for_fifo(chip, substream, false);
170 snd_pcm_group_for_each_entry(s, substream) {
171 struct lola_stream *str;
172 if (s->pcm->card != substream->pcm->card)
173 continue;
174 str = lola_get_stream(s);
175 if (str->paused && str->prepared)
176 lola_dsd_write(chip, str->dsd, CTL, LOLA_DSD_CTL_SRUN |
177 LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE);
178 }
179 lola_sync_wait_for_fifo(chip, substream, true);
180}
181
182static void lola_stream_reset(struct lola *chip, struct lola_stream *str)
183{
184 if (str->prepared) {
185 if (str->paused)
186 lola_sync_pause(chip, str->substream);
187 str->prepared = 0;
188 lola_dsd_write(chip, str->dsd, CTL,
189 LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE);
190 lola_stream_wait_for_fifo(chip, str, false);
191 lola_stream_clear_pending_irq(chip, str);
192 lola_dsd_write(chip, str->dsd, CTL, LOLA_DSD_CTL_SRST);
193 lola_dsd_write(chip, str->dsd, LVI, 0);
194 lola_dsd_write(chip, str->dsd, BDPU, 0);
195 lola_dsd_write(chip, str->dsd, BDPL, 0);
196 wait_for_srst_clear(chip, str);
197 }
198}
199
200static struct snd_pcm_hardware lola_pcm_hw = {
201 .info = (SNDRV_PCM_INFO_MMAP |
202 SNDRV_PCM_INFO_INTERLEAVED |
203 SNDRV_PCM_INFO_BLOCK_TRANSFER |
204 SNDRV_PCM_INFO_MMAP_VALID |
205 SNDRV_PCM_INFO_PAUSE),
206 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
207 SNDRV_PCM_FMTBIT_S24_LE |
208 SNDRV_PCM_FMTBIT_S32_LE |
209 SNDRV_PCM_FMTBIT_FLOAT_LE),
210 .rates = SNDRV_PCM_RATE_8000_192000,
211 .rate_min = 8000,
212 .rate_max = 192000,
213 .channels_min = 1,
214 .channels_max = 2,
215 .buffer_bytes_max = LOLA_MAX_BUF_SIZE,
216 .period_bytes_min = 128,
217 .period_bytes_max = LOLA_MAX_BUF_SIZE / 2,
218 .periods_min = 2,
219 .periods_max = LOLA_MAX_BDL_ENTRIES,
220 .fifo_size = 0,
221};
222
223static int lola_pcm_open(struct snd_pcm_substream *substream)
224{
225 struct lola *chip = snd_pcm_substream_chip(substream);
226 struct lola_pcm *pcm = lola_get_pcm(substream);
227 struct lola_stream *str = lola_get_stream(substream);
228 struct snd_pcm_runtime *runtime = substream->runtime;
229
230 mutex_lock(&chip->open_mutex);
231 if (str->opened) {
232 mutex_unlock(&chip->open_mutex);
233 return -EBUSY;
234 }
235 str->substream = substream;
236 str->master = NULL;
237 str->opened = 1;
238 runtime->hw = lola_pcm_hw;
239 runtime->hw.channels_max = pcm->num_streams - str->index;
240 if (chip->sample_rate) {
241 /* sample rate is locked */
242 runtime->hw.rate_min = chip->sample_rate;
243 runtime->hw.rate_max = chip->sample_rate;
244 } else {
245 runtime->hw.rate_min = chip->sample_rate_min;
246 runtime->hw.rate_max = chip->sample_rate_max;
247 }
248 chip->ref_count_rate++;
249 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
250 /* period size = multiple of chip->granularity (8, 16 or 32 frames)*/
251 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
252 chip->granularity);
253 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
254 chip->granularity);
255 mutex_unlock(&chip->open_mutex);
256 return 0;
257}
258
259static void lola_cleanup_slave_streams(struct lola_pcm *pcm,
260 struct lola_stream *str)
261{
262 int i;
263 for (i = str->index + 1; i < pcm->num_streams; i++) {
264 struct lola_stream *s = &pcm->streams[i];
265 if (s->master != str)
266 break;
267 s->master = NULL;
268 s->opened = 0;
269 }
270}
271
272static int lola_pcm_close(struct snd_pcm_substream *substream)
273{
274 struct lola *chip = snd_pcm_substream_chip(substream);
275 struct lola_stream *str = lola_get_stream(substream);
276
277 mutex_lock(&chip->open_mutex);
278 if (str->substream == substream) {
279 str->substream = NULL;
280 str->opened = 0;
281 }
282 if (--chip->ref_count_rate == 0) {
283 /* release sample rate */
284 chip->sample_rate = 0;
285 }
286 mutex_unlock(&chip->open_mutex);
287 return 0;
288}
289
290static int lola_pcm_hw_params(struct snd_pcm_substream *substream,
291 struct snd_pcm_hw_params *hw_params)
292{
293 struct lola_stream *str = lola_get_stream(substream);
294
295 str->bufsize = 0;
296 str->period_bytes = 0;
297 str->format_verb = 0;
298 return snd_pcm_lib_malloc_pages(substream,
299 params_buffer_bytes(hw_params));
300}
301
302static int lola_pcm_hw_free(struct snd_pcm_substream *substream)
303{
304 struct lola *chip = snd_pcm_substream_chip(substream);
305 struct lola_pcm *pcm = lola_get_pcm(substream);
306 struct lola_stream *str = lola_get_stream(substream);
307
308 mutex_lock(&chip->open_mutex);
309 lola_stream_reset(chip, str);
310 lola_cleanup_slave_streams(pcm, str);
311 mutex_unlock(&chip->open_mutex);
312 return snd_pcm_lib_free_pages(substream);
313}
314
315/*
316 * set up a BDL entry
317 */
318static int setup_bdle(struct snd_pcm_substream *substream,
319 struct lola_stream *str, u32 **bdlp,
320 int ofs, int size)
321{
322 u32 *bdl = *bdlp;
323
324 while (size > 0) {
325 dma_addr_t addr;
326 int chunk;
327
328 if (str->frags >= LOLA_MAX_BDL_ENTRIES)
329 return -EINVAL;
330
331 addr = snd_pcm_sgbuf_get_addr(substream, ofs);
332 /* program the address field of the BDL entry */
333 bdl[0] = cpu_to_le32((u32)addr);
334 bdl[1] = cpu_to_le32(upper_32_bits(addr));
335 /* program the size field of the BDL entry */
336 chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size);
337 bdl[2] = cpu_to_le32(chunk);
338 /* program the IOC to enable interrupt
339 * only when the whole fragment is processed
340 */
341 size -= chunk;
342 bdl[3] = size ? 0 : cpu_to_le32(0x01);
343 bdl += 4;
344 str->frags++;
345 ofs += chunk;
346 }
347 *bdlp = bdl;
348 return ofs;
349}
350
351/*
352 * set up BDL entries
353 */
354static int lola_setup_periods(struct lola *chip, struct lola_pcm *pcm,
355 struct snd_pcm_substream *substream,
356 struct lola_stream *str)
357{
358 u32 *bdl;
359 int i, ofs, periods, period_bytes;
360
361 period_bytes = str->period_bytes;
362 periods = str->bufsize / period_bytes;
363
364 /* program the initial BDL entries */
365 bdl = (u32 *)(pcm->bdl.area + LOLA_BDL_ENTRY_SIZE * str->index);
366 ofs = 0;
367 str->frags = 0;
368 for (i = 0; i < periods; i++) {
369 ofs = setup_bdle(substream, str, &bdl, ofs, period_bytes);
370 if (ofs < 0)
371 goto error;
372 }
373 return 0;
374
375 error:
376 snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n",
377 str->bufsize, period_bytes);
378 return -EINVAL;
379}
380
381static unsigned int lola_get_format_verb(struct snd_pcm_substream *substream)
382{
383 unsigned int verb;
384
385 switch (substream->runtime->format) {
386 case SNDRV_PCM_FORMAT_S16_LE:
387 verb = 0x00000000;
388 break;
389 case SNDRV_PCM_FORMAT_S24_LE:
390 verb = 0x00000200;
391 break;
392 case SNDRV_PCM_FORMAT_S32_LE:
393 verb = 0x00000300;
394 break;
395 case SNDRV_PCM_FORMAT_FLOAT_LE:
396 verb = 0x00001300;
397 break;
398 default:
399 return 0;
400 }
401 verb |= substream->runtime->channels;
402 return verb;
403}
404
405static int lola_set_stream_config(struct lola *chip,
406 struct lola_stream *str,
407 int channels)
408{
409 int i, err;
410 unsigned int verb, val;
411
412 /* set format info for all channels
413 * (with only one command for the first channel)
414 */
415 err = lola_codec_read(chip, str->nid, LOLA_VERB_SET_STREAM_FORMAT,
416 str->format_verb, 0, &val, NULL);
417 if (err < 0) {
418 printk(KERN_ERR SFX "Cannot set stream format 0x%x\n",
419 str->format_verb);
420 return err;
421 }
422
423 /* update stream - channel config */
424 for (i = 0; i < channels; i++) {
425 verb = (str->index << 6) | i;
426 err = lola_codec_read(chip, str[i].nid,
427 LOLA_VERB_SET_CHANNEL_STREAMID, 0, verb,
428 &val, NULL);
429 if (err < 0) {
430 printk(KERN_ERR SFX "Cannot set stream channel %d\n", i);
431 return err;
432 }
433 }
434 return 0;
435}
436
437/*
438 * set up the SD for streaming
439 */
440static int lola_setup_controller(struct lola *chip, struct lola_pcm *pcm,
441 struct lola_stream *str)
442{
443 dma_addr_t bdl;
444
445 if (str->prepared)
446 return -EINVAL;
447
448 /* set up BDL */
449 bdl = pcm->bdl.addr + LOLA_BDL_ENTRY_SIZE * str->index;
450 lola_dsd_write(chip, str->dsd, BDPL, (u32)bdl);
451 lola_dsd_write(chip, str->dsd, BDPU, upper_32_bits(bdl));
452 /* program the stream LVI (last valid index) of the BDL */
453 lola_dsd_write(chip, str->dsd, LVI, str->frags - 1);
454 lola_stream_clear_pending_irq(chip, str);
455
456 lola_dsd_write(chip, str->dsd, CTL,
457 LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE | LOLA_DSD_CTL_SRUN);
458
459 str->prepared = 1;
460
461 return lola_stream_wait_for_fifo(chip, str, true);
462}
463
464static int lola_pcm_prepare(struct snd_pcm_substream *substream)
465{
466 struct lola *chip = snd_pcm_substream_chip(substream);
467 struct lola_pcm *pcm = lola_get_pcm(substream);
468 struct lola_stream *str = lola_get_stream(substream);
469 struct snd_pcm_runtime *runtime = substream->runtime;
470 unsigned int bufsize, period_bytes, format_verb;
471 int i, err;
472
473 mutex_lock(&chip->open_mutex);
474 lola_stream_reset(chip, str);
475 lola_cleanup_slave_streams(pcm, str);
476 if (str->index + runtime->channels > pcm->num_streams) {
477 mutex_unlock(&chip->open_mutex);
478 return -EINVAL;
479 }
480 for (i = 1; i < runtime->channels; i++) {
481 str[i].master = str;
482 str[i].opened = 1;
483 }
484 mutex_unlock(&chip->open_mutex);
485
486 bufsize = snd_pcm_lib_buffer_bytes(substream);
487 period_bytes = snd_pcm_lib_period_bytes(substream);
488 format_verb = lola_get_format_verb(substream);
489
490 str->bufsize = bufsize;
491 str->period_bytes = period_bytes;
492 str->format_verb = format_verb;
493
494 err = lola_setup_periods(chip, pcm, substream, str);
495 if (err < 0)
496 return err;
497
498 err = lola_set_sample_rate(chip, runtime->rate);
499 if (err < 0)
500 return err;
501 chip->sample_rate = runtime->rate; /* sample rate gets locked */
502
503 err = lola_set_stream_config(chip, str, runtime->channels);
504 if (err < 0)
505 return err;
506
507 err = lola_setup_controller(chip, pcm, str);
508 if (err < 0) {
509 lola_stream_reset(chip, str);
510 return err;
511 }
512
513 return 0;
514}
515
516static int lola_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
517{
518 struct lola *chip = snd_pcm_substream_chip(substream);
519 struct lola_stream *str;
520 struct snd_pcm_substream *s;
521 unsigned int start;
522 unsigned int tstamp;
523 bool sync_streams;
524
525 switch (cmd) {
526 case SNDRV_PCM_TRIGGER_START:
527 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
528 case SNDRV_PCM_TRIGGER_RESUME:
529 start = 1;
530 break;
531 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
532 case SNDRV_PCM_TRIGGER_SUSPEND:
533 case SNDRV_PCM_TRIGGER_STOP:
534 start = 0;
535 break;
536 default:
537 return -EINVAL;
538 }
539
540 /*
541 * sample correct synchronization is only needed starting several
542 * streams. On stop or if only one stream do as quick as possible
543 */
544 sync_streams = (start && snd_pcm_stream_linked(substream));
545 tstamp = lola_get_tstamp(chip, !sync_streams);
546 spin_lock(&chip->reg_lock);
547 snd_pcm_group_for_each_entry(s, substream) {
548 if (s->pcm->card != substream->pcm->card)
549 continue;
550 str = lola_get_stream(s);
551 if (start)
552 lola_stream_start(chip, str, tstamp);
553 else
554 lola_stream_stop(chip, str, tstamp);
555 str->running = start;
556 str->paused = !start;
557 snd_pcm_trigger_done(s, substream);
558 }
559 spin_unlock(&chip->reg_lock);
560 return 0;
561}
562
563static snd_pcm_uframes_t lola_pcm_pointer(struct snd_pcm_substream *substream)
564{
565 struct lola *chip = snd_pcm_substream_chip(substream);
566 struct lola_stream *str = lola_get_stream(substream);
567 unsigned int pos = lola_dsd_read(chip, str->dsd, LPIB);
568
569 if (pos >= str->bufsize)
570 pos = 0;
571 return bytes_to_frames(substream->runtime, pos);
572}
573
574void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits)
575{
576 int i;
577
578 for (i = 0; bits && i < pcm->num_streams; i++) {
579 if (bits & (1 << i)) {
580 struct lola_stream *str = &pcm->streams[i];
581 if (str->substream && str->running)
582 snd_pcm_period_elapsed(str->substream);
583 bits &= ~(1 << i);
584 }
585 }
586}
587
588static struct snd_pcm_ops lola_pcm_ops = {
589 .open = lola_pcm_open,
590 .close = lola_pcm_close,
591 .ioctl = snd_pcm_lib_ioctl,
592 .hw_params = lola_pcm_hw_params,
593 .hw_free = lola_pcm_hw_free,
594 .prepare = lola_pcm_prepare,
595 .trigger = lola_pcm_trigger,
596 .pointer = lola_pcm_pointer,
597 .page = snd_pcm_sgbuf_ops_page,
598};
599
600int __devinit lola_create_pcm(struct lola *chip)
601{
602 struct snd_pcm *pcm;
603 int i, err;
604
605 for (i = 0; i < 2; i++) {
606 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
607 snd_dma_pci_data(chip->pci),
608 PAGE_SIZE, &chip->pcm[i].bdl);
609 if (err < 0)
610 return err;
611 }
612
613 err = snd_pcm_new(chip->card, "Digigram Lola", 0,
614 chip->pcm[SNDRV_PCM_STREAM_PLAYBACK].num_streams,
615 chip->pcm[SNDRV_PCM_STREAM_CAPTURE].num_streams,
616 &pcm);
617 if (err < 0)
618 return err;
619 strlcpy(pcm->name, "Digigram Lola", sizeof(pcm->name));
620 pcm->private_data = chip;
621 for (i = 0; i < 2; i++) {
622 if (chip->pcm[i].num_streams)
623 snd_pcm_set_ops(pcm, i, &lola_pcm_ops);
624 }
625 /* buffer pre-allocation */
626 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
627 snd_dma_pci_data(chip->pci),
628 1024 * 64, 32 * 1024 * 1024);
629 return 0;
630}
631
632void lola_free_pcm(struct lola *chip)
633{
634 snd_dma_free_pages(&chip->pcm[0].bdl);
635 snd_dma_free_pages(&chip->pcm[1].bdl);
636}
637
638/*
639 */
640
641static int lola_init_stream(struct lola *chip, struct lola_stream *str,
642 int idx, int nid, int dir)
643{
644 unsigned int val;
645 int err;
646
647 str->nid = nid;
648 str->index = idx;
649 str->dsd = idx;
650 if (dir == PLAY)
651 str->dsd += MAX_STREAM_IN_COUNT;
652 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
653 if (err < 0) {
654 printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
655 return err;
656 }
657 if (dir == PLAY) {
658 /* test TYPE and bits 0..11 (no test bit9 : Digital = 0/1) */
659 if ((val & 0x00f00dff) != 0x00000010) {
660 printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n",
661 val, nid);
662 return -EINVAL;
663 }
664 } else {
665 /* test TYPE and bits 0..11 (no test bit9 : Digital = 0/1)
666 * (bug : ignore bit8: Conn list = 0/1)
667 */
668 if ((val & 0x00f00cff) != 0x00100010) {
669 printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n",
670 val, nid);
671 return -EINVAL;
672 }
673 /* test bit9:DIGITAL and bit12:SRC_PRESENT*/
674 if ((val & 0x00001200) == 0x00001200)
675 chip->input_src_caps_mask |= (1 << idx);
676 }
677
678 err = lola_read_param(chip, nid, LOLA_PAR_STREAM_FORMATS, &val);
679 if (err < 0) {
680 printk(KERN_ERR SFX "Can't read FORMATS 0x%x\n", nid);
681 return err;
682 }
683 val &= 3;
684 if (val == 3)
685 str->can_float = true;
686 if (!(val & 1)) {
687 printk(KERN_ERR SFX "Invalid formats 0x%x for 0x%x", val, nid);
688 return -EINVAL;
689 }
690 return 0;
691}
692
693int __devinit lola_init_pcm(struct lola *chip, int dir, int *nidp)
694{
695 struct lola_pcm *pcm = &chip->pcm[dir];
696 int i, nid, err;
697
698 nid = *nidp;
699 for (i = 0; i < pcm->num_streams; i++, nid++) {
700 err = lola_init_stream(chip, &pcm->streams[i], i, nid, dir);
701 if (err < 0)
702 return err;
703 }
704 *nidp = nid;
705 return 0;
706}
diff --git a/sound/pci/lola/lola_proc.c b/sound/pci/lola/lola_proc.c
new file mode 100644
index 000000000000..9d7daf897c9d
--- /dev/null
+++ b/sound/pci/lola/lola_proc.c
@@ -0,0 +1,222 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/io.h>
24#include <sound/core.h>
25#include <sound/info.h>
26#include <sound/pcm.h>
27#include "lola.h"
28
29static void print_audio_widget(struct snd_info_buffer *buffer,
30 struct lola *chip, int nid, const char *name)
31{
32 unsigned int val;
33
34 lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
35 snd_iprintf(buffer, "Node 0x%02x %s wcaps 0x%x\n", nid, name, val);
36 lola_read_param(chip, nid, LOLA_PAR_STREAM_FORMATS, &val);
37 snd_iprintf(buffer, " Formats: 0x%x\n", val);
38}
39
40static void print_pin_widget(struct snd_info_buffer *buffer,
41 struct lola *chip, int nid, unsigned int ampcap,
42 const char *name)
43{
44 unsigned int val;
45
46 lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
47 snd_iprintf(buffer, "Node 0x%02x %s wcaps 0x%x\n", nid, name, val);
48 if (val == 0x00400200)
49 return;
50 lola_read_param(chip, nid, ampcap, &val);
51 snd_iprintf(buffer, " Amp-Caps: 0x%x\n", val);
52 snd_iprintf(buffer, " mute=%d, step-size=%d, steps=%d, ofs=%d\n",
53 LOLA_AMP_MUTE_CAPABLE(val),
54 LOLA_AMP_STEP_SIZE(val),
55 LOLA_AMP_NUM_STEPS(val),
56 LOLA_AMP_OFFSET(val));
57 lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val, NULL);
58 snd_iprintf(buffer, " Max-level: 0x%x\n", val);
59}
60
61static void print_clock_widget(struct snd_info_buffer *buffer,
62 struct lola *chip, int nid)
63{
64 int i, j, num_clocks;
65 unsigned int val;
66
67 lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
68 snd_iprintf(buffer, "Node 0x%02x [Clock] wcaps 0x%x\n", nid, val);
69 num_clocks = val & 0xff;
70 for (i = 0; i < num_clocks; i += 4) {
71 unsigned int res_ex;
72 unsigned short items[4];
73 const char *name;
74
75 lola_codec_read(chip, nid, LOLA_VERB_GET_CLOCK_LIST,
76 i, 0, &val, &res_ex);
77 items[0] = val & 0xfff;
78 items[1] = (val >> 16) & 0xfff;
79 items[2] = res_ex & 0xfff;
80 items[3] = (res_ex >> 16) & 0xfff;
81 for (j = 0; j < 4; j++) {
82 unsigned char type = items[j] >> 8;
83 unsigned int freq = items[j] & 0xff;
84 if (i + j >= num_clocks)
85 break;
86 if (type == LOLA_CLOCK_TYPE_INTERNAL) {
87 name = "Internal";
88 freq = lola_sample_rate_convert(freq);
89 } else if (type == LOLA_CLOCK_TYPE_VIDEO) {
90 name = "Video";
91 freq = lola_sample_rate_convert(freq);
92 } else {
93 name = "Other";
94 }
95 snd_iprintf(buffer, " Clock %d: Type %d:%s, freq=%d\n",
96 i + j, type, name, freq);
97 }
98 }
99}
100
101static void print_mixer_widget(struct snd_info_buffer *buffer,
102 struct lola *chip, int nid)
103{
104 unsigned int val;
105
106 lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
107 snd_iprintf(buffer, "Node 0x%02x [Mixer] wcaps 0x%x\n", nid, val);
108}
109
110static void lola_proc_codec_read(struct snd_info_entry *entry,
111 struct snd_info_buffer *buffer)
112{
113 struct lola *chip = entry->private_data;
114 unsigned int val;
115 int i, nid;
116
117 lola_read_param(chip, 0, LOLA_PAR_VENDOR_ID, &val);
118 snd_iprintf(buffer, "Vendor: 0x%08x\n", val);
119 lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val);
120 snd_iprintf(buffer, "Function Type: %d\n", val);
121 lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val);
122 snd_iprintf(buffer, "Specific-Caps: 0x%08x\n", val);
123 snd_iprintf(buffer, " Pins-In %d, Pins-Out %d\n",
124 chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins);
125 nid = 2;
126 for (i = 0; i < chip->pcm[CAPT].num_streams; i++, nid++)
127 print_audio_widget(buffer, chip, nid, "[Audio-In]");
128 for (i = 0; i < chip->pcm[PLAY].num_streams; i++, nid++)
129 print_audio_widget(buffer, chip, nid, "[Audio-Out]");
130 for (i = 0; i < chip->pin[CAPT].num_pins; i++, nid++)
131 print_pin_widget(buffer, chip, nid, LOLA_PAR_AMP_IN_CAP,
132 "[Pin-In]");
133 for (i = 0; i < chip->pin[PLAY].num_pins; i++, nid++)
134 print_pin_widget(buffer, chip, nid, LOLA_PAR_AMP_OUT_CAP,
135 "[Pin-Out]");
136 if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) {
137 print_clock_widget(buffer, chip, nid);
138 nid++;
139 }
140 if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) {
141 print_mixer_widget(buffer, chip, nid);
142 nid++;
143 }
144}
145
146/* direct codec access for debugging */
147static void lola_proc_codec_rw_write(struct snd_info_entry *entry,
148 struct snd_info_buffer *buffer)
149{
150 struct lola *chip = entry->private_data;
151 char line[64];
152 unsigned int id, verb, data, extdata;
153 while (!snd_info_get_line(buffer, line, sizeof(line))) {
154 if (sscanf(line, "%i %i %i %i", &id, &verb, &data, &extdata) != 4)
155 continue;
156 lola_codec_read(chip, id, verb, data, extdata,
157 &chip->debug_res,
158 &chip->debug_res_ex);
159 }
160}
161
162static void lola_proc_codec_rw_read(struct snd_info_entry *entry,
163 struct snd_info_buffer *buffer)
164{
165 struct lola *chip = entry->private_data;
166 snd_iprintf(buffer, "0x%x 0x%x\n", chip->debug_res, chip->debug_res_ex);
167}
168
169/*
170 * dump some registers
171 */
172static void lola_proc_regs_read(struct snd_info_entry *entry,
173 struct snd_info_buffer *buffer)
174{
175 struct lola *chip = entry->private_data;
176 int i;
177
178 for (i = 0; i < 0x40; i += 4) {
179 snd_iprintf(buffer, "BAR0 %02x: %08x\n", i,
180 readl(chip->bar[BAR0].remap_addr + i));
181 }
182 snd_iprintf(buffer, "\n");
183 for (i = 0; i < 0x30; i += 4) {
184 snd_iprintf(buffer, "BAR1 %02x: %08x\n", i,
185 readl(chip->bar[BAR1].remap_addr + i));
186 }
187 snd_iprintf(buffer, "\n");
188 for (i = 0x80; i < 0xa0; i += 4) {
189 snd_iprintf(buffer, "BAR1 %02x: %08x\n", i,
190 readl(chip->bar[BAR1].remap_addr + i));
191 }
192 snd_iprintf(buffer, "\n");
193 for (i = 0; i < 32; i++) {
194 snd_iprintf(buffer, "DSD %02x STS %08x\n", i,
195 lola_dsd_read(chip, i, STS));
196 snd_iprintf(buffer, "DSD %02x LPIB %08x\n", i,
197 lola_dsd_read(chip, i, LPIB));
198 snd_iprintf(buffer, "DSD %02x CTL %08x\n", i,
199 lola_dsd_read(chip, i, CTL));
200 snd_iprintf(buffer, "DSD %02x LVIL %08x\n", i,
201 lola_dsd_read(chip, i, LVI));
202 snd_iprintf(buffer, "DSD %02x BDPL %08x\n", i,
203 lola_dsd_read(chip, i, BDPL));
204 snd_iprintf(buffer, "DSD %02x BDPU %08x\n", i,
205 lola_dsd_read(chip, i, BDPU));
206 }
207}
208
209void __devinit lola_proc_debug_new(struct lola *chip)
210{
211 struct snd_info_entry *entry;
212
213 if (!snd_card_proc_new(chip->card, "codec", &entry))
214 snd_info_set_text_ops(entry, chip, lola_proc_codec_read);
215 if (!snd_card_proc_new(chip->card, "codec_rw", &entry)) {
216 snd_info_set_text_ops(entry, chip, lola_proc_codec_rw_read);
217 entry->mode |= S_IWUSR;
218 entry->c.text.write = lola_proc_codec_rw_write;
219 }
220 if (!snd_card_proc_new(chip->card, "regs", &entry))
221 snd_info_set_text_ops(entry, chip, lola_proc_regs_read);
222}
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index ef9af3f4ace2..1bd7a540fd49 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -425,7 +425,7 @@ exit:
425static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream) 425static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream)
426{ 426{
427 struct snd_pcm_substream *substream = lx_stream->stream; 427 struct snd_pcm_substream *substream = lx_stream->stream;
428 const int is_capture = lx_stream->is_capture; 428 const unsigned int is_capture = lx_stream->is_capture;
429 429
430 int err; 430 int err;
431 431
@@ -473,7 +473,7 @@ static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream)
473 473
474static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream) 474static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream)
475{ 475{
476 const int is_capture = lx_stream->is_capture; 476 const unsigned int is_capture = lx_stream->is_capture;
477 int err; 477 int err;
478 478
479 snd_printd(LXP "stopping: stopping stream\n"); 479 snd_printd(LXP "stopping: stopping stream\n");
diff --git a/sound/pci/lx6464es/lx6464es.h b/sound/pci/lx6464es/lx6464es.h
index 51afc048961d..aea621eafbb5 100644
--- a/sound/pci/lx6464es/lx6464es.h
+++ b/sound/pci/lx6464es/lx6464es.h
@@ -60,7 +60,7 @@ struct lx_stream {
60 snd_pcm_uframes_t frame_pos; 60 snd_pcm_uframes_t frame_pos;
61 enum lx_stream_status status; /* free, open, running, draining 61 enum lx_stream_status status; /* free, open, running, draining
62 * pause */ 62 * pause */
63 int is_capture:1; 63 unsigned int is_capture:1;
64}; 64};
65 65
66 66
diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c
index 3086b751da4a..617f98b0cbae 100644
--- a/sound/pci/lx6464es/lx_core.c
+++ b/sound/pci/lx6464es/lx_core.c
@@ -1152,7 +1152,7 @@ static int lx_interrupt_request_new_buffer(struct lx6464es *chip,
1152 struct lx_stream *lx_stream) 1152 struct lx_stream *lx_stream)
1153{ 1153{
1154 struct snd_pcm_substream *substream = lx_stream->stream; 1154 struct snd_pcm_substream *substream = lx_stream->stream;
1155 int is_capture = lx_stream->is_capture; 1155 const unsigned int is_capture = lx_stream->is_capture;
1156 int err; 1156 int err;
1157 unsigned long flags; 1157 unsigned long flags;
1158 1158
diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c
index d3350f383966..3df0f530f67c 100644
--- a/sound/pci/mixart/mixart_core.c
+++ b/sound/pci/mixart/mixart_core.c
@@ -265,7 +265,7 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int
265 if (! timeout) { 265 if (! timeout) {
266 /* error - no ack */ 266 /* error - no ack */
267 mutex_unlock(&mgr->msg_mutex); 267 mutex_unlock(&mgr->msg_mutex);
268 snd_printk(KERN_ERR "error: no reponse on msg %x\n", msg_frame); 268 snd_printk(KERN_ERR "error: no response on msg %x\n", msg_frame);
269 return -EIO; 269 return -EIO;
270 } 270 }
271 271
@@ -278,7 +278,7 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int
278 err = get_msg(mgr, &resp, msg_frame); 278 err = get_msg(mgr, &resp, msg_frame);
279 279
280 if( request->message_id != resp.message_id ) 280 if( request->message_id != resp.message_id )
281 snd_printk(KERN_ERR "REPONSE ERROR!\n"); 281 snd_printk(KERN_ERR "RESPONSE ERROR!\n");
282 282
283 mutex_unlock(&mgr->msg_mutex); 283 mutex_unlock(&mgr->msg_mutex);
284 return err; 284 return err;
diff --git a/sound/pci/mixart/mixart_hwdep.h b/sound/pci/mixart/mixart_hwdep.h
index a46f5083db99..812e288ef2e7 100644
--- a/sound/pci/mixart/mixart_hwdep.h
+++ b/sound/pci/mixart/mixart_hwdep.h
@@ -25,11 +25,21 @@
25 25
26#include <sound/hwdep.h> 26#include <sound/hwdep.h>
27 27
28#ifndef readl_be
28#define readl_be(x) be32_to_cpu(__raw_readl(x)) 29#define readl_be(x) be32_to_cpu(__raw_readl(x))
30#endif
31
32#ifndef writel_be
29#define writel_be(data,addr) __raw_writel(cpu_to_be32(data),addr) 33#define writel_be(data,addr) __raw_writel(cpu_to_be32(data),addr)
34#endif
30 35
36#ifndef readl_le
31#define readl_le(x) le32_to_cpu(__raw_readl(x)) 37#define readl_le(x) le32_to_cpu(__raw_readl(x))
38#endif
39
40#ifndef writel_le
32#define writel_le(data,addr) __raw_writel(cpu_to_le32(data),addr) 41#define writel_le(data,addr) __raw_writel(cpu_to_le32(data),addr)
42#endif
33 43
34#define MIXART_MEM(mgr,x) ((mgr)->mem[0].virt + (x)) 44#define MIXART_MEM(mgr,x) ((mgr)->mem[0].virt + (x))
35#define MIXART_REG(mgr,x) ((mgr)->mem[1].virt + (x)) 45#define MIXART_REG(mgr,x) ((mgr)->mem[1].virt + (x))
diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile
index acd8f15f7bff..0f8726551fde 100644
--- a/sound/pci/oxygen/Makefile
+++ b/sound/pci/oxygen/Makefile
@@ -1,10 +1,8 @@
1snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o 1snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o
2snd-hifier-objs := hifier.o 2snd-oxygen-objs := oxygen.o xonar_dg.o
3snd-oxygen-objs := oxygen.o
4snd-virtuoso-objs := virtuoso.o xonar_lib.o \ 3snd-virtuoso-objs := virtuoso.o xonar_lib.o \
5 xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o 4 xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o
6 5
7obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o 6obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o
8obj-$(CONFIG_SND_HIFIER) += snd-hifier.o
9obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o 7obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o
10obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o 8obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o
diff --git a/sound/pci/oxygen/cs4245.h b/sound/pci/oxygen/cs4245.h
new file mode 100644
index 000000000000..5e0197e07dd1
--- /dev/null
+++ b/sound/pci/oxygen/cs4245.h
@@ -0,0 +1,107 @@
1#define CS4245_CHIP_ID 0x01
2#define CS4245_POWER_CTRL 0x02
3#define CS4245_DAC_CTRL_1 0x03
4#define CS4245_ADC_CTRL 0x04
5#define CS4245_MCLK_FREQ 0x05
6#define CS4245_SIGNAL_SEL 0x06
7#define CS4245_PGA_B_CTRL 0x07
8#define CS4245_PGA_A_CTRL 0x08
9#define CS4245_ANALOG_IN 0x09
10#define CS4245_DAC_A_CTRL 0x0a
11#define CS4245_DAC_B_CTRL 0x0b
12#define CS4245_DAC_CTRL_2 0x0c
13#define CS4245_INT_STATUS 0x0d
14#define CS4245_INT_MASK 0x0e
15#define CS4245_INT_MODE_MSB 0x0f
16#define CS4245_INT_MODE_LSB 0x10
17
18/* Chip ID */
19#define CS4245_CHIP_PART_MASK 0xf0
20#define CS4245_CHIP_REV_MASK 0x0f
21
22/* Power Control */
23#define CS4245_FREEZE 0x80
24#define CS4245_PDN_MIC 0x08
25#define CS4245_PDN_ADC 0x04
26#define CS4245_PDN_DAC 0x02
27#define CS4245_PDN 0x01
28
29/* DAC Control */
30#define CS4245_DAC_FM_MASK 0xc0
31#define CS4245_DAC_FM_SINGLE 0x00
32#define CS4245_DAC_FM_DOUBLE 0x40
33#define CS4245_DAC_FM_QUAD 0x80
34#define CS4245_DAC_DIF_MASK 0x30
35#define CS4245_DAC_DIF_LJUST 0x00
36#define CS4245_DAC_DIF_I2S 0x10
37#define CS4245_DAC_DIF_RJUST_16 0x20
38#define CS4245_DAC_DIF_RJUST_24 0x30
39#define CS4245_RESERVED_1 0x08
40#define CS4245_MUTE_DAC 0x04
41#define CS4245_DEEMPH 0x02
42#define CS4245_DAC_MASTER 0x01
43
44/* ADC Control */
45#define CS4245_ADC_FM_MASK 0xc0
46#define CS4245_ADC_FM_SINGLE 0x00
47#define CS4245_ADC_FM_DOUBLE 0x40
48#define CS4245_ADC_FM_QUAD 0x80
49#define CS4245_ADC_DIF_MASK 0x10
50#define CS4245_ADC_DIF_LJUST 0x00
51#define CS4245_ADC_DIF_I2S 0x10
52#define CS4245_MUTE_ADC 0x04
53#define CS4245_HPF_FREEZE 0x02
54#define CS4245_ADC_MASTER 0x01
55
56/* MCLK Frequency */
57#define CS4245_MCLK1_MASK 0x70
58#define CS4245_MCLK1_SHIFT 4
59#define CS4245_MCLK2_MASK 0x07
60#define CS4245_MCLK2_SHIFT 0
61#define CS4245_MCLK_1 0
62#define CS4245_MCLK_1_5 1
63#define CS4245_MCLK_2 2
64#define CS4245_MCLK_3 3
65#define CS4245_MCLK_4 4
66
67/* Signal Selection */
68#define CS4245_A_OUT_SEL_MASK 0x60
69#define CS4245_A_OUT_SEL_HIZ 0x00
70#define CS4245_A_OUT_SEL_DAC 0x20
71#define CS4245_A_OUT_SEL_PGA 0x40
72#define CS4245_LOOP 0x02
73#define CS4245_ASYNCH 0x01
74
75/* Channel B/A PGA Control */
76#define CS4245_PGA_GAIN_MASK 0x3f
77
78/* ADC Input Control */
79#define CS4245_PGA_SOFT 0x10
80#define CS4245_PGA_ZERO 0x08
81#define CS4245_SEL_MASK 0x07
82#define CS4245_SEL_MIC 0x00
83#define CS4245_SEL_INPUT_1 0x01
84#define CS4245_SEL_INPUT_2 0x02
85#define CS4245_SEL_INPUT_3 0x03
86#define CS4245_SEL_INPUT_4 0x04
87#define CS4245_SEL_INPUT_5 0x05
88#define CS4245_SEL_INPUT_6 0x06
89
90/* DAC Channel A/B Volume Control */
91#define CS4245_VOL_MASK 0xff
92
93/* DAC Control 2 */
94#define CS4245_DAC_SOFT 0x80
95#define CS4245_DAC_ZERO 0x40
96#define CS4245_INVERT_DAC 0x20
97#define CS4245_INT_ACTIVE_HIGH 0x01
98
99/* Interrupt Status/Mask/Mode */
100#define CS4245_ADC_CLK_ERR 0x08
101#define CS4245_DAC_CLK_ERR 0x04
102#define CS4245_ADC_OVFL 0x02
103#define CS4245_ADC_UNDRFL 0x01
104
105
106#define CS4245_SPI_ADDRESS (0x9e << 16)
107#define CS4245_SPI_WRITE (0 << 16)
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
deleted file mode 100644
index 5a87d683691f..000000000000
--- a/sound/pci/oxygen/hifier.c
+++ /dev/null
@@ -1,239 +0,0 @@
1/*
2 * C-Media CMI8788 driver for the MediaTek/TempoTec HiFier Fantasia
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
9 *
10 * This driver is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this driver; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20/*
21 * CMI8788:
22 *
23 * SPI 0 -> AK4396
24 */
25
26#include <linux/delay.h>
27#include <linux/pci.h>
28#include <sound/control.h>
29#include <sound/core.h>
30#include <sound/initval.h>
31#include <sound/pcm.h>
32#include <sound/tlv.h>
33#include "oxygen.h"
34#include "ak4396.h"
35
36MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
37MODULE_DESCRIPTION("TempoTec HiFier driver");
38MODULE_LICENSE("GPL v2");
39
40static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
41static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
42static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
43
44module_param_array(index, int, NULL, 0444);
45MODULE_PARM_DESC(index, "card index");
46module_param_array(id, charp, NULL, 0444);
47MODULE_PARM_DESC(id, "ID string");
48module_param_array(enable, bool, NULL, 0444);
49MODULE_PARM_DESC(enable, "enable card");
50
51static DEFINE_PCI_DEVICE_TABLE(hifier_ids) = {
52 { OXYGEN_PCI_SUBID(0x14c3, 0x1710) },
53 { OXYGEN_PCI_SUBID(0x14c3, 0x1711) },
54 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
55 { }
56};
57MODULE_DEVICE_TABLE(pci, hifier_ids);
58
59struct hifier_data {
60 u8 ak4396_regs[5];
61};
62
63static void ak4396_write(struct oxygen *chip, u8 reg, u8 value)
64{
65 struct hifier_data *data = chip->model_data;
66
67 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
68 OXYGEN_SPI_DATA_LENGTH_2 |
69 OXYGEN_SPI_CLOCK_160 |
70 (0 << OXYGEN_SPI_CODEC_SHIFT) |
71 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
72 AK4396_WRITE | (reg << 8) | value);
73 data->ak4396_regs[reg] = value;
74}
75
76static void ak4396_write_cached(struct oxygen *chip, u8 reg, u8 value)
77{
78 struct hifier_data *data = chip->model_data;
79
80 if (value != data->ak4396_regs[reg])
81 ak4396_write(chip, reg, value);
82}
83
84static void hifier_registers_init(struct oxygen *chip)
85{
86 struct hifier_data *data = chip->model_data;
87
88 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
89 ak4396_write(chip, AK4396_CONTROL_2,
90 data->ak4396_regs[AK4396_CONTROL_2]);
91 ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM);
92 ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
93 ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
94}
95
96static void hifier_init(struct oxygen *chip)
97{
98 struct hifier_data *data = chip->model_data;
99
100 data->ak4396_regs[AK4396_CONTROL_2] =
101 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
102 hifier_registers_init(chip);
103
104 snd_component_add(chip->card, "AK4396");
105 snd_component_add(chip->card, "CS5340");
106}
107
108static void hifier_cleanup(struct oxygen *chip)
109{
110}
111
112static void hifier_resume(struct oxygen *chip)
113{
114 hifier_registers_init(chip);
115}
116
117static void set_ak4396_params(struct oxygen *chip,
118 struct snd_pcm_hw_params *params)
119{
120 struct hifier_data *data = chip->model_data;
121 u8 value;
122
123 value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_DFS_MASK;
124 if (params_rate(params) <= 54000)
125 value |= AK4396_DFS_NORMAL;
126 else if (params_rate(params) <= 108000)
127 value |= AK4396_DFS_DOUBLE;
128 else
129 value |= AK4396_DFS_QUAD;
130
131 msleep(1); /* wait for the new MCLK to become stable */
132
133 if (value != data->ak4396_regs[AK4396_CONTROL_2]) {
134 ak4396_write(chip, AK4396_CONTROL_1,
135 AK4396_DIF_24_MSB);
136 ak4396_write(chip, AK4396_CONTROL_2, value);
137 ak4396_write(chip, AK4396_CONTROL_1,
138 AK4396_DIF_24_MSB | AK4396_RSTN);
139 }
140}
141
142static void update_ak4396_volume(struct oxygen *chip)
143{
144 ak4396_write_cached(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
145 ak4396_write_cached(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
146}
147
148static void update_ak4396_mute(struct oxygen *chip)
149{
150 struct hifier_data *data = chip->model_data;
151 u8 value;
152
153 value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_SMUTE;
154 if (chip->dac_mute)
155 value |= AK4396_SMUTE;
156 ak4396_write_cached(chip, AK4396_CONTROL_2, value);
157}
158
159static void set_cs5340_params(struct oxygen *chip,
160 struct snd_pcm_hw_params *params)
161{
162}
163
164static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
165
166static const struct oxygen_model model_hifier = {
167 .shortname = "C-Media CMI8787",
168 .longname = "C-Media Oxygen HD Audio",
169 .chip = "CMI8788",
170 .init = hifier_init,
171 .cleanup = hifier_cleanup,
172 .resume = hifier_resume,
173 .get_i2s_mclk = oxygen_default_i2s_mclk,
174 .set_dac_params = set_ak4396_params,
175 .set_adc_params = set_cs5340_params,
176 .update_dac_volume = update_ak4396_volume,
177 .update_dac_mute = update_ak4396_mute,
178 .dac_tlv = ak4396_db_scale,
179 .model_data_size = sizeof(struct hifier_data),
180 .device_config = PLAYBACK_0_TO_I2S |
181 PLAYBACK_1_TO_SPDIF |
182 CAPTURE_0_FROM_I2S_1,
183 .dac_channels = 2,
184 .dac_volume_min = 0,
185 .dac_volume_max = 255,
186 .function_flags = OXYGEN_FUNCTION_SPI,
187 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
188 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
189};
190
191static int __devinit get_hifier_model(struct oxygen *chip,
192 const struct pci_device_id *id)
193{
194 chip->model = model_hifier;
195 return 0;
196}
197
198static int __devinit hifier_probe(struct pci_dev *pci,
199 const struct pci_device_id *pci_id)
200{
201 static int dev;
202 int err;
203
204 if (dev >= SNDRV_CARDS)
205 return -ENODEV;
206 if (!enable[dev]) {
207 ++dev;
208 return -ENOENT;
209 }
210 err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
211 hifier_ids, get_hifier_model);
212 if (err >= 0)
213 ++dev;
214 return err;
215}
216
217static struct pci_driver hifier_driver = {
218 .name = "CMI8787HiFier",
219 .id_table = hifier_ids,
220 .probe = hifier_probe,
221 .remove = __devexit_p(oxygen_pci_remove),
222#ifdef CONFIG_PM
223 .suspend = oxygen_pci_suspend,
224 .resume = oxygen_pci_resume,
225#endif
226};
227
228static int __init alsa_card_hifier_init(void)
229{
230 return pci_register_driver(&hifier_driver);
231}
232
233static void __exit alsa_card_hifier_exit(void)
234{
235 pci_unregister_driver(&hifier_driver);
236}
237
238module_init(alsa_card_hifier_init)
239module_exit(alsa_card_hifier_exit)
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 6c0a11adb2a8..d7e8ddd9a67b 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -20,19 +20,32 @@
20/* 20/*
21 * CMI8788: 21 * CMI8788:
22 * 22 *
23 * SPI 0 -> 1st AK4396 (front) 23 * SPI 0 -> 1st AK4396 (front)
24 * SPI 1 -> 2nd AK4396 (surround) 24 * SPI 1 -> 2nd AK4396 (surround)
25 * SPI 2 -> 3rd AK4396 (center/LFE) 25 * SPI 2 -> 3rd AK4396 (center/LFE)
26 * SPI 3 -> WM8785 26 * SPI 3 -> WM8785
27 * SPI 4 -> 4th AK4396 (back) 27 * SPI 4 -> 4th AK4396 (back)
28 * 28 *
29 * GPIO 0 -> DFS0 of AK5385 29 * GPIO 0 -> DFS0 of AK5385
30 * GPIO 1 -> DFS1 of AK5385 30 * GPIO 1 -> DFS1 of AK5385
31 * GPIO 8 -> enable headphone amplifier on HT-Omega models 31 *
32 * X-Meridian models:
33 * GPIO 4 -> enable extension S/PDIF input
34 * GPIO 6 -> enable on-board S/PDIF input
35 *
36 * Claro models:
37 * GPIO 6 -> S/PDIF from optical (0) or coaxial (1) input
38 * GPIO 8 -> enable headphone amplifier
32 * 39 *
33 * CM9780: 40 * CM9780:
34 * 41 *
35 * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input 42 * LINE_OUT -> input of ADC
43 *
44 * AUX_IN <- aux
45 * CD_IN <- CD
46 * MIC_IN <- mic
47 *
48 * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input
36 */ 49 */
37 50
38#include <linux/delay.h> 51#include <linux/delay.h>
@@ -41,18 +54,22 @@
41#include <sound/ac97_codec.h> 54#include <sound/ac97_codec.h>
42#include <sound/control.h> 55#include <sound/control.h>
43#include <sound/core.h> 56#include <sound/core.h>
57#include <sound/info.h>
44#include <sound/initval.h> 58#include <sound/initval.h>
45#include <sound/pcm.h> 59#include <sound/pcm.h>
46#include <sound/pcm_params.h> 60#include <sound/pcm_params.h>
47#include <sound/tlv.h> 61#include <sound/tlv.h>
48#include "oxygen.h" 62#include "oxygen.h"
63#include "xonar_dg.h"
49#include "ak4396.h" 64#include "ak4396.h"
50#include "wm8785.h" 65#include "wm8785.h"
51 66
52MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 67MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
53MODULE_DESCRIPTION("C-Media CMI8788 driver"); 68MODULE_DESCRIPTION("C-Media CMI8788 driver");
54MODULE_LICENSE("GPL v2"); 69MODULE_LICENSE("GPL v2");
55MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8788}}"); 70MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8786}"
71 ",{C-Media,CMI8787}"
72 ",{C-Media,CMI8788}}");
56 73
57static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 74static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
58static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 75static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
@@ -66,14 +83,22 @@ module_param_array(enable, bool, NULL, 0444);
66MODULE_PARM_DESC(enable, "enable card"); 83MODULE_PARM_DESC(enable, "enable card");
67 84
68enum { 85enum {
69 MODEL_CMEDIA_REF, /* C-Media's reference design */ 86 MODEL_CMEDIA_REF,
70 MODEL_MERIDIAN, /* AuzenTech X-Meridian */ 87 MODEL_MERIDIAN,
71 MODEL_CLARO, /* HT-Omega Claro */ 88 MODEL_MERIDIAN_2G,
72 MODEL_CLARO_HALO, /* HT-Omega Claro halo */ 89 MODEL_CLARO,
90 MODEL_CLARO_HALO,
91 MODEL_FANTASIA,
92 MODEL_SERENADE,
93 MODEL_2CH_OUTPUT,
94 MODEL_HG2PCI,
95 MODEL_XONAR_DG,
73}; 96};
74 97
75static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { 98static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
99 /* C-Media's reference design */
76 { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF }, 100 { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF },
101 { OXYGEN_PCI_SUBID(0x10b0, 0x0217), .driver_data = MODEL_CMEDIA_REF },
77 { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF }, 102 { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF },
78 { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF }, 103 { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF },
79 { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF }, 104 { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF },
@@ -81,8 +106,23 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
81 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, 106 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF },
82 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, 107 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF },
83 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, 108 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
109 /* Asus Xonar DG */
110 { OXYGEN_PCI_SUBID(0x1043, 0x8467), .driver_data = MODEL_XONAR_DG },
111 /* PCI 2.0 HD Audio */
112 { OXYGEN_PCI_SUBID(0x13f6, 0x8782), .driver_data = MODEL_2CH_OUTPUT },
113 /* Kuroutoshikou CMI8787-HG2PCI */
114 { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_HG2PCI },
115 /* TempoTec HiFier Fantasia */
116 { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_FANTASIA },
117 /* TempoTec HiFier Serenade */
118 { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_SERENADE },
119 /* AuzenTech X-Meridian */
84 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, 120 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
121 /* AuzenTech X-Meridian 2G */
122 { OXYGEN_PCI_SUBID(0x5431, 0x017a), .driver_data = MODEL_MERIDIAN_2G },
123 /* HT-Omega Claro */
85 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO }, 124 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO },
125 /* HT-Omega Claro halo */
86 { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_CLARO_HALO }, 126 { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_CLARO_HALO },
87 { } 127 { }
88}; 128};
@@ -94,9 +134,15 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
94#define GPIO_AK5385_DFS_DOUBLE 0x0001 134#define GPIO_AK5385_DFS_DOUBLE 0x0001
95#define GPIO_AK5385_DFS_QUAD 0x0002 135#define GPIO_AK5385_DFS_QUAD 0x0002
96 136
137#define GPIO_MERIDIAN_DIG_MASK 0x0050
138#define GPIO_MERIDIAN_DIG_EXT 0x0010
139#define GPIO_MERIDIAN_DIG_BOARD 0x0040
140
141#define GPIO_CLARO_DIG_COAX 0x0040
97#define GPIO_CLARO_HP 0x0100 142#define GPIO_CLARO_HP 0x0100
98 143
99struct generic_data { 144struct generic_data {
145 unsigned int dacs;
100 u8 ak4396_regs[4][5]; 146 u8 ak4396_regs[4][5];
101 u16 wm8785_regs[3]; 147 u16 wm8785_regs[3];
102}; 148};
@@ -147,7 +193,7 @@ static void ak4396_registers_init(struct oxygen *chip)
147 struct generic_data *data = chip->model_data; 193 struct generic_data *data = chip->model_data;
148 unsigned int i; 194 unsigned int i;
149 195
150 for (i = 0; i < 4; ++i) { 196 for (i = 0; i < data->dacs; ++i) {
151 ak4396_write(chip, i, AK4396_CONTROL_1, 197 ak4396_write(chip, i, AK4396_CONTROL_1,
152 AK4396_DIF_24_MSB | AK4396_RSTN); 198 AK4396_DIF_24_MSB | AK4396_RSTN);
153 ak4396_write(chip, i, AK4396_CONTROL_2, 199 ak4396_write(chip, i, AK4396_CONTROL_2,
@@ -165,6 +211,7 @@ static void ak4396_init(struct oxygen *chip)
165{ 211{
166 struct generic_data *data = chip->model_data; 212 struct generic_data *data = chip->model_data;
167 213
214 data->dacs = chip->model.dac_channels_pcm / 2;
168 data->ak4396_regs[0][AK4396_CONTROL_2] = 215 data->ak4396_regs[0][AK4396_CONTROL_2] =
169 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; 216 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
170 ak4396_registers_init(chip); 217 ak4396_registers_init(chip);
@@ -206,6 +253,10 @@ static void generic_init(struct oxygen *chip)
206 253
207static void meridian_init(struct oxygen *chip) 254static void meridian_init(struct oxygen *chip)
208{ 255{
256 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
257 GPIO_MERIDIAN_DIG_MASK);
258 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
259 GPIO_MERIDIAN_DIG_BOARD, GPIO_MERIDIAN_DIG_MASK);
209 ak4396_init(chip); 260 ak4396_init(chip);
210 ak5385_init(chip); 261 ak5385_init(chip);
211} 262}
@@ -219,6 +270,8 @@ static void claro_enable_hp(struct oxygen *chip)
219 270
220static void claro_init(struct oxygen *chip) 271static void claro_init(struct oxygen *chip)
221{ 272{
273 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_DIG_COAX);
274 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_DIG_COAX);
222 ak4396_init(chip); 275 ak4396_init(chip);
223 wm8785_init(chip); 276 wm8785_init(chip);
224 claro_enable_hp(chip); 277 claro_enable_hp(chip);
@@ -226,11 +279,24 @@ static void claro_init(struct oxygen *chip)
226 279
227static void claro_halo_init(struct oxygen *chip) 280static void claro_halo_init(struct oxygen *chip)
228{ 281{
282 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_DIG_COAX);
283 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_DIG_COAX);
229 ak4396_init(chip); 284 ak4396_init(chip);
230 ak5385_init(chip); 285 ak5385_init(chip);
231 claro_enable_hp(chip); 286 claro_enable_hp(chip);
232} 287}
233 288
289static void fantasia_init(struct oxygen *chip)
290{
291 ak4396_init(chip);
292 snd_component_add(chip->card, "CS5340");
293}
294
295static void stereo_output_init(struct oxygen *chip)
296{
297 ak4396_init(chip);
298}
299
234static void generic_cleanup(struct oxygen *chip) 300static void generic_cleanup(struct oxygen *chip)
235{ 301{
236} 302}
@@ -267,6 +333,11 @@ static void claro_resume(struct oxygen *chip)
267 claro_enable_hp(chip); 333 claro_enable_hp(chip);
268} 334}
269 335
336static void stereo_resume(struct oxygen *chip)
337{
338 ak4396_registers_init(chip);
339}
340
270static void set_ak4396_params(struct oxygen *chip, 341static void set_ak4396_params(struct oxygen *chip,
271 struct snd_pcm_hw_params *params) 342 struct snd_pcm_hw_params *params)
272{ 343{
@@ -285,7 +356,7 @@ static void set_ak4396_params(struct oxygen *chip,
285 msleep(1); /* wait for the new MCLK to become stable */ 356 msleep(1); /* wait for the new MCLK to become stable */
286 357
287 if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) { 358 if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) {
288 for (i = 0; i < 4; ++i) { 359 for (i = 0; i < data->dacs; ++i) {
289 ak4396_write(chip, i, AK4396_CONTROL_1, 360 ak4396_write(chip, i, AK4396_CONTROL_1,
290 AK4396_DIF_24_MSB); 361 AK4396_DIF_24_MSB);
291 ak4396_write(chip, i, AK4396_CONTROL_2, value); 362 ak4396_write(chip, i, AK4396_CONTROL_2, value);
@@ -297,9 +368,10 @@ static void set_ak4396_params(struct oxygen *chip,
297 368
298static void update_ak4396_volume(struct oxygen *chip) 369static void update_ak4396_volume(struct oxygen *chip)
299{ 370{
371 struct generic_data *data = chip->model_data;
300 unsigned int i; 372 unsigned int i;
301 373
302 for (i = 0; i < 4; ++i) { 374 for (i = 0; i < data->dacs; ++i) {
303 ak4396_write_cached(chip, i, AK4396_LCH_ATT, 375 ak4396_write_cached(chip, i, AK4396_LCH_ATT,
304 chip->dac_volume[i * 2]); 376 chip->dac_volume[i * 2]);
305 ak4396_write_cached(chip, i, AK4396_RCH_ATT, 377 ak4396_write_cached(chip, i, AK4396_RCH_ATT,
@@ -316,7 +388,7 @@ static void update_ak4396_mute(struct oxygen *chip)
316 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE; 388 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE;
317 if (chip->dac_mute) 389 if (chip->dac_mute)
318 value |= AK4396_SMUTE; 390 value |= AK4396_SMUTE;
319 for (i = 0; i < 4; ++i) 391 for (i = 0; i < data->dacs; ++i)
320 ak4396_write_cached(chip, i, AK4396_CONTROL_2, value); 392 ak4396_write_cached(chip, i, AK4396_CONTROL_2, value);
321} 393}
322 394
@@ -355,6 +427,10 @@ static void set_ak5385_params(struct oxygen *chip,
355 value, GPIO_AK5385_DFS_MASK); 427 value, GPIO_AK5385_DFS_MASK);
356} 428}
357 429
430static void set_no_params(struct oxygen *chip, struct snd_pcm_hw_params *params)
431{
432}
433
358static int rolloff_info(struct snd_kcontrol *ctl, 434static int rolloff_info(struct snd_kcontrol *ctl,
359 struct snd_ctl_elem_info *info) 435 struct snd_ctl_elem_info *info)
360{ 436{
@@ -362,13 +438,7 @@ static int rolloff_info(struct snd_kcontrol *ctl,
362 "Sharp Roll-off", "Slow Roll-off" 438 "Sharp Roll-off", "Slow Roll-off"
363 }; 439 };
364 440
365 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 441 return snd_ctl_enum_info(info, 1, 2, names);
366 info->count = 1;
367 info->value.enumerated.items = 2;
368 if (info->value.enumerated.item >= 2)
369 info->value.enumerated.item = 1;
370 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
371 return 0;
372} 442}
373 443
374static int rolloff_get(struct snd_kcontrol *ctl, 444static int rolloff_get(struct snd_kcontrol *ctl,
@@ -399,7 +469,7 @@ static int rolloff_put(struct snd_kcontrol *ctl,
399 reg &= ~AK4396_SLOW; 469 reg &= ~AK4396_SLOW;
400 changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2]; 470 changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2];
401 if (changed) { 471 if (changed) {
402 for (i = 0; i < 4; ++i) 472 for (i = 0; i < data->dacs; ++i)
403 ak4396_write(chip, i, AK4396_CONTROL_2, reg); 473 ak4396_write(chip, i, AK4396_CONTROL_2, reg);
404 } 474 }
405 mutex_unlock(&chip->mutex); 475 mutex_unlock(&chip->mutex);
@@ -420,13 +490,7 @@ static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
420 "None", "High-pass Filter" 490 "None", "High-pass Filter"
421 }; 491 };
422 492
423 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 493 return snd_ctl_enum_info(info, 1, 2, names);
424 info->count = 1;
425 info->value.enumerated.items = 2;
426 if (info->value.enumerated.item >= 2)
427 info->value.enumerated.item = 1;
428 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
429 return 0;
430} 494}
431 495
432static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 496static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
@@ -465,6 +529,100 @@ static const struct snd_kcontrol_new hpf_control = {
465 .put = hpf_put, 529 .put = hpf_put,
466}; 530};
467 531
532static int meridian_dig_source_info(struct snd_kcontrol *ctl,
533 struct snd_ctl_elem_info *info)
534{
535 static const char *const names[2] = { "On-board", "Extension" };
536
537 return snd_ctl_enum_info(info, 1, 2, names);
538}
539
540static int claro_dig_source_info(struct snd_kcontrol *ctl,
541 struct snd_ctl_elem_info *info)
542{
543 static const char *const names[2] = { "Optical", "Coaxial" };
544
545 return snd_ctl_enum_info(info, 1, 2, names);
546}
547
548static int meridian_dig_source_get(struct snd_kcontrol *ctl,
549 struct snd_ctl_elem_value *value)
550{
551 struct oxygen *chip = ctl->private_data;
552
553 value->value.enumerated.item[0] =
554 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
555 GPIO_MERIDIAN_DIG_EXT);
556 return 0;
557}
558
559static int claro_dig_source_get(struct snd_kcontrol *ctl,
560 struct snd_ctl_elem_value *value)
561{
562 struct oxygen *chip = ctl->private_data;
563
564 value->value.enumerated.item[0] =
565 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
566 GPIO_CLARO_DIG_COAX);
567 return 0;
568}
569
570static int meridian_dig_source_put(struct snd_kcontrol *ctl,
571 struct snd_ctl_elem_value *value)
572{
573 struct oxygen *chip = ctl->private_data;
574 u16 old_reg, new_reg;
575 int changed;
576
577 mutex_lock(&chip->mutex);
578 old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA);
579 new_reg = old_reg & ~GPIO_MERIDIAN_DIG_MASK;
580 if (value->value.enumerated.item[0] == 0)
581 new_reg |= GPIO_MERIDIAN_DIG_BOARD;
582 else
583 new_reg |= GPIO_MERIDIAN_DIG_EXT;
584 changed = new_reg != old_reg;
585 if (changed)
586 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg);
587 mutex_unlock(&chip->mutex);
588 return changed;
589}
590
591static int claro_dig_source_put(struct snd_kcontrol *ctl,
592 struct snd_ctl_elem_value *value)
593{
594 struct oxygen *chip = ctl->private_data;
595 u16 old_reg, new_reg;
596 int changed;
597
598 mutex_lock(&chip->mutex);
599 old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA);
600 new_reg = old_reg & ~GPIO_CLARO_DIG_COAX;
601 if (value->value.enumerated.item[0])
602 new_reg |= GPIO_CLARO_DIG_COAX;
603 changed = new_reg != old_reg;
604 if (changed)
605 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg);
606 mutex_unlock(&chip->mutex);
607 return changed;
608}
609
610static const struct snd_kcontrol_new meridian_dig_source_control = {
611 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
612 .name = "IEC958 Source Capture Enum",
613 .info = meridian_dig_source_info,
614 .get = meridian_dig_source_get,
615 .put = meridian_dig_source_put,
616};
617
618static const struct snd_kcontrol_new claro_dig_source_control = {
619 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
620 .name = "IEC958 Source Capture Enum",
621 .info = claro_dig_source_info,
622 .get = claro_dig_source_get,
623 .put = claro_dig_source_put,
624};
625
468static int generic_mixer_init(struct oxygen *chip) 626static int generic_mixer_init(struct oxygen *chip)
469{ 627{
470 return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip)); 628 return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip));
@@ -483,6 +641,81 @@ static int generic_wm8785_mixer_init(struct oxygen *chip)
483 return 0; 641 return 0;
484} 642}
485 643
644static int meridian_mixer_init(struct oxygen *chip)
645{
646 int err;
647
648 err = generic_mixer_init(chip);
649 if (err < 0)
650 return err;
651 err = snd_ctl_add(chip->card,
652 snd_ctl_new1(&meridian_dig_source_control, chip));
653 if (err < 0)
654 return err;
655 return 0;
656}
657
658static int claro_mixer_init(struct oxygen *chip)
659{
660 int err;
661
662 err = generic_wm8785_mixer_init(chip);
663 if (err < 0)
664 return err;
665 err = snd_ctl_add(chip->card,
666 snd_ctl_new1(&claro_dig_source_control, chip));
667 if (err < 0)
668 return err;
669 return 0;
670}
671
672static int claro_halo_mixer_init(struct oxygen *chip)
673{
674 int err;
675
676 err = generic_mixer_init(chip);
677 if (err < 0)
678 return err;
679 err = snd_ctl_add(chip->card,
680 snd_ctl_new1(&claro_dig_source_control, chip));
681 if (err < 0)
682 return err;
683 return 0;
684}
685
686static void dump_ak4396_registers(struct oxygen *chip,
687 struct snd_info_buffer *buffer)
688{
689 struct generic_data *data = chip->model_data;
690 unsigned int dac, i;
691
692 for (dac = 0; dac < data->dacs; ++dac) {
693 snd_iprintf(buffer, "\nAK4396 %u:", dac + 1);
694 for (i = 0; i < 5; ++i)
695 snd_iprintf(buffer, " %02x", data->ak4396_regs[dac][i]);
696 }
697 snd_iprintf(buffer, "\n");
698}
699
700static void dump_wm8785_registers(struct oxygen *chip,
701 struct snd_info_buffer *buffer)
702{
703 struct generic_data *data = chip->model_data;
704 unsigned int i;
705
706 snd_iprintf(buffer, "\nWM8785:");
707 for (i = 0; i < 3; ++i)
708 snd_iprintf(buffer, " %03x", data->wm8785_regs[i]);
709 snd_iprintf(buffer, "\n");
710}
711
712static void dump_oxygen_registers(struct oxygen *chip,
713 struct snd_info_buffer *buffer)
714{
715 dump_ak4396_registers(chip, buffer);
716 dump_wm8785_registers(chip, buffer);
717}
718
486static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); 719static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
487 720
488static const struct oxygen_model model_generic = { 721static const struct oxygen_model model_generic = {
@@ -493,11 +726,11 @@ static const struct oxygen_model model_generic = {
493 .mixer_init = generic_wm8785_mixer_init, 726 .mixer_init = generic_wm8785_mixer_init,
494 .cleanup = generic_cleanup, 727 .cleanup = generic_cleanup,
495 .resume = generic_resume, 728 .resume = generic_resume,
496 .get_i2s_mclk = oxygen_default_i2s_mclk,
497 .set_dac_params = set_ak4396_params, 729 .set_dac_params = set_ak4396_params,
498 .set_adc_params = set_wm8785_params, 730 .set_adc_params = set_wm8785_params,
499 .update_dac_volume = update_ak4396_volume, 731 .update_dac_volume = update_ak4396_volume,
500 .update_dac_mute = update_ak4396_mute, 732 .update_dac_mute = update_ak4396_mute,
733 .dump_registers = dump_oxygen_registers,
501 .dac_tlv = ak4396_db_scale, 734 .dac_tlv = ak4396_db_scale,
502 .model_data_size = sizeof(struct generic_data), 735 .model_data_size = sizeof(struct generic_data),
503 .device_config = PLAYBACK_0_TO_I2S | 736 .device_config = PLAYBACK_0_TO_I2S |
@@ -505,12 +738,16 @@ static const struct oxygen_model model_generic = {
505 PLAYBACK_2_TO_AC97_1 | 738 PLAYBACK_2_TO_AC97_1 |
506 CAPTURE_0_FROM_I2S_1 | 739 CAPTURE_0_FROM_I2S_1 |
507 CAPTURE_1_FROM_SPDIF | 740 CAPTURE_1_FROM_SPDIF |
508 CAPTURE_2_FROM_AC97_1, 741 CAPTURE_2_FROM_AC97_1 |
509 .dac_channels = 8, 742 AC97_CD_INPUT,
743 .dac_channels_pcm = 8,
744 .dac_channels_mixer = 8,
510 .dac_volume_min = 0, 745 .dac_volume_min = 0,
511 .dac_volume_max = 255, 746 .dac_volume_max = 255,
512 .function_flags = OXYGEN_FUNCTION_SPI | 747 .function_flags = OXYGEN_FUNCTION_SPI |
513 OXYGEN_FUNCTION_ENABLE_SPI_4_5, 748 OXYGEN_FUNCTION_ENABLE_SPI_4_5,
749 .dac_mclks = OXYGEN_MCLKS(256, 128, 128),
750 .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
514 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 751 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
515 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 752 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
516}; 753};
@@ -518,42 +755,87 @@ static const struct oxygen_model model_generic = {
518static int __devinit get_oxygen_model(struct oxygen *chip, 755static int __devinit get_oxygen_model(struct oxygen *chip,
519 const struct pci_device_id *id) 756 const struct pci_device_id *id)
520{ 757{
758 static const char *const names[] = {
759 [MODEL_MERIDIAN] = "AuzenTech X-Meridian",
760 [MODEL_MERIDIAN_2G] = "AuzenTech X-Meridian 2G",
761 [MODEL_CLARO] = "HT-Omega Claro",
762 [MODEL_CLARO_HALO] = "HT-Omega Claro halo",
763 [MODEL_FANTASIA] = "TempoTec HiFier Fantasia",
764 [MODEL_SERENADE] = "TempoTec HiFier Serenade",
765 [MODEL_HG2PCI] = "CMI8787-HG2PCI",
766 };
767
521 chip->model = model_generic; 768 chip->model = model_generic;
522 switch (id->driver_data) { 769 switch (id->driver_data) {
523 case MODEL_MERIDIAN: 770 case MODEL_MERIDIAN:
771 case MODEL_MERIDIAN_2G:
524 chip->model.init = meridian_init; 772 chip->model.init = meridian_init;
525 chip->model.mixer_init = generic_mixer_init; 773 chip->model.mixer_init = meridian_mixer_init;
526 chip->model.resume = meridian_resume; 774 chip->model.resume = meridian_resume;
527 chip->model.set_adc_params = set_ak5385_params; 775 chip->model.set_adc_params = set_ak5385_params;
776 chip->model.dump_registers = dump_ak4396_registers;
528 chip->model.device_config = PLAYBACK_0_TO_I2S | 777 chip->model.device_config = PLAYBACK_0_TO_I2S |
529 PLAYBACK_1_TO_SPDIF | 778 PLAYBACK_1_TO_SPDIF |
530 CAPTURE_0_FROM_I2S_2 | 779 CAPTURE_0_FROM_I2S_2 |
531 CAPTURE_1_FROM_SPDIF; 780 CAPTURE_1_FROM_SPDIF;
781 if (id->driver_data == MODEL_MERIDIAN)
782 chip->model.device_config |= AC97_CD_INPUT;
532 break; 783 break;
533 case MODEL_CLARO: 784 case MODEL_CLARO:
534 chip->model.init = claro_init; 785 chip->model.init = claro_init;
786 chip->model.mixer_init = claro_mixer_init;
535 chip->model.cleanup = claro_cleanup; 787 chip->model.cleanup = claro_cleanup;
536 chip->model.suspend = claro_suspend; 788 chip->model.suspend = claro_suspend;
537 chip->model.resume = claro_resume; 789 chip->model.resume = claro_resume;
538 break; 790 break;
539 case MODEL_CLARO_HALO: 791 case MODEL_CLARO_HALO:
540 chip->model.init = claro_halo_init; 792 chip->model.init = claro_halo_init;
541 chip->model.mixer_init = generic_mixer_init; 793 chip->model.mixer_init = claro_halo_mixer_init;
542 chip->model.cleanup = claro_cleanup; 794 chip->model.cleanup = claro_cleanup;
543 chip->model.suspend = claro_suspend; 795 chip->model.suspend = claro_suspend;
544 chip->model.resume = claro_resume; 796 chip->model.resume = claro_resume;
545 chip->model.set_adc_params = set_ak5385_params; 797 chip->model.set_adc_params = set_ak5385_params;
798 chip->model.dump_registers = dump_ak4396_registers;
546 chip->model.device_config = PLAYBACK_0_TO_I2S | 799 chip->model.device_config = PLAYBACK_0_TO_I2S |
547 PLAYBACK_1_TO_SPDIF | 800 PLAYBACK_1_TO_SPDIF |
548 CAPTURE_0_FROM_I2S_2 | 801 CAPTURE_0_FROM_I2S_2 |
549 CAPTURE_1_FROM_SPDIF; 802 CAPTURE_1_FROM_SPDIF;
550 break; 803 break;
804 case MODEL_FANTASIA:
805 case MODEL_SERENADE:
806 case MODEL_2CH_OUTPUT:
807 case MODEL_HG2PCI:
808 chip->model.shortname = "C-Media CMI8787";
809 chip->model.chip = "CMI8787";
810 if (id->driver_data == MODEL_FANTASIA)
811 chip->model.init = fantasia_init;
812 else
813 chip->model.init = stereo_output_init;
814 chip->model.resume = stereo_resume;
815 chip->model.mixer_init = generic_mixer_init;
816 chip->model.set_adc_params = set_no_params;
817 chip->model.dump_registers = dump_ak4396_registers;
818 chip->model.device_config = PLAYBACK_0_TO_I2S |
819 PLAYBACK_1_TO_SPDIF;
820 if (id->driver_data == MODEL_FANTASIA) {
821 chip->model.device_config |= CAPTURE_0_FROM_I2S_1;
822 chip->model.adc_mclks = OXYGEN_MCLKS(256, 128, 128);
823 }
824 chip->model.dac_channels_pcm = 2;
825 chip->model.dac_channels_mixer = 2;
826 break;
827 case MODEL_XONAR_DG:
828 chip->model = model_xonar_dg;
829 break;
551 } 830 }
552 if (id->driver_data == MODEL_MERIDIAN || 831 if (id->driver_data == MODEL_MERIDIAN ||
832 id->driver_data == MODEL_MERIDIAN_2G ||
553 id->driver_data == MODEL_CLARO_HALO) { 833 id->driver_data == MODEL_CLARO_HALO) {
554 chip->model.misc_flags = OXYGEN_MISC_MIDI; 834 chip->model.misc_flags = OXYGEN_MISC_MIDI;
555 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT; 835 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT;
556 } 836 }
837 if (id->driver_data < ARRAY_SIZE(names) && names[id->driver_data])
838 chip->model.shortname = names[id->driver_data];
557 return 0; 839 return 0;
558} 840}
559 841
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index a3409edcfb50..f53897a708b4 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -16,6 +16,10 @@
16#define PCM_AC97 5 16#define PCM_AC97 5
17#define PCM_COUNT 6 17#define PCM_COUNT 6
18 18
19#define OXYGEN_MCLKS(f_single, f_double, f_quad) ((MCLK_##f_single << 0) | \
20 (MCLK_##f_double << 2) | \
21 (MCLK_##f_quad << 4))
22
19#define OXYGEN_IO_SIZE 0x100 23#define OXYGEN_IO_SIZE 0x100
20 24
21#define OXYGEN_EEPROM_ID 0x434d /* "CM" */ 25#define OXYGEN_EEPROM_ID 0x434d /* "CM" */
@@ -34,6 +38,8 @@
34 /* CAPTURE_3_FROM_I2S_3 not implemented */ 38 /* CAPTURE_3_FROM_I2S_3 not implemented */
35#define MIDI_OUTPUT 0x0800 39#define MIDI_OUTPUT 0x0800
36#define MIDI_INPUT 0x1000 40#define MIDI_INPUT 0x1000
41#define AC97_CD_INPUT 0x2000
42#define AC97_FMIC_SWITCH 0x4000
37 43
38enum { 44enum {
39 CONTROL_SPDIF_PCM, 45 CONTROL_SPDIF_PCM,
@@ -64,6 +70,7 @@ struct snd_pcm_hardware;
64struct snd_pcm_hw_params; 70struct snd_pcm_hw_params;
65struct snd_kcontrol_new; 71struct snd_kcontrol_new;
66struct snd_rawmidi; 72struct snd_rawmidi;
73struct snd_info_buffer;
67struct oxygen; 74struct oxygen;
68 75
69struct oxygen_model { 76struct oxygen_model {
@@ -78,8 +85,6 @@ struct oxygen_model {
78 void (*resume)(struct oxygen *chip); 85 void (*resume)(struct oxygen *chip);
79 void (*pcm_hardware_filter)(unsigned int channel, 86 void (*pcm_hardware_filter)(unsigned int channel,
80 struct snd_pcm_hardware *hardware); 87 struct snd_pcm_hardware *hardware);
81 unsigned int (*get_i2s_mclk)(struct oxygen *chip, unsigned int channel,
82 struct snd_pcm_hw_params *hw_params);
83 void (*set_dac_params)(struct oxygen *chip, 88 void (*set_dac_params)(struct oxygen *chip,
84 struct snd_pcm_hw_params *params); 89 struct snd_pcm_hw_params *params);
85 void (*set_adc_params)(struct oxygen *chip, 90 void (*set_adc_params)(struct oxygen *chip,
@@ -87,19 +92,25 @@ struct oxygen_model {
87 void (*update_dac_volume)(struct oxygen *chip); 92 void (*update_dac_volume)(struct oxygen *chip);
88 void (*update_dac_mute)(struct oxygen *chip); 93 void (*update_dac_mute)(struct oxygen *chip);
89 void (*update_center_lfe_mix)(struct oxygen *chip, bool mixed); 94 void (*update_center_lfe_mix)(struct oxygen *chip, bool mixed);
95 unsigned int (*adjust_dac_routing)(struct oxygen *chip,
96 unsigned int play_routing);
90 void (*gpio_changed)(struct oxygen *chip); 97 void (*gpio_changed)(struct oxygen *chip);
91 void (*uart_input)(struct oxygen *chip); 98 void (*uart_input)(struct oxygen *chip);
92 void (*ac97_switch)(struct oxygen *chip, 99 void (*ac97_switch)(struct oxygen *chip,
93 unsigned int reg, unsigned int mute); 100 unsigned int reg, unsigned int mute);
101 void (*dump_registers)(struct oxygen *chip,
102 struct snd_info_buffer *buffer);
94 const unsigned int *dac_tlv; 103 const unsigned int *dac_tlv;
95 unsigned long private_data;
96 size_t model_data_size; 104 size_t model_data_size;
97 unsigned int device_config; 105 unsigned int device_config;
98 u8 dac_channels; 106 u8 dac_channels_pcm;
107 u8 dac_channels_mixer;
99 u8 dac_volume_min; 108 u8 dac_volume_min;
100 u8 dac_volume_max; 109 u8 dac_volume_max;
101 u8 misc_flags; 110 u8 misc_flags;
102 u8 function_flags; 111 u8 function_flags;
112 u8 dac_mclks;
113 u8 adc_mclks;
103 u16 dac_i2s_format; 114 u16 dac_i2s_format;
104 u16 adc_i2s_format; 115 u16 adc_i2s_format;
105}; 116};
@@ -120,7 +131,6 @@ struct oxygen {
120 u8 pcm_running; 131 u8 pcm_running;
121 u8 dac_routing; 132 u8 dac_routing;
122 u8 spdif_playback_enable; 133 u8 spdif_playback_enable;
123 u8 revision;
124 u8 has_ac97_0; 134 u8 has_ac97_0;
125 u8 has_ac97_1; 135 u8 has_ac97_1;
126 u32 spdif_bits; 136 u32 spdif_bits;
@@ -166,8 +176,6 @@ void oxygen_update_spdif_source(struct oxygen *chip);
166/* oxygen_pcm.c */ 176/* oxygen_pcm.c */
167 177
168int oxygen_pcm_init(struct oxygen *chip); 178int oxygen_pcm_init(struct oxygen *chip);
169unsigned int oxygen_default_i2s_mclk(struct oxygen *chip, unsigned int channel,
170 struct snd_pcm_hw_params *hw_params);
171 179
172/* oxygen_io.c */ 180/* oxygen_io.c */
173 181
diff --git a/sound/pci/oxygen/oxygen_io.c b/sound/pci/oxygen/oxygen_io.c
index 09b2b2a36df5..f5164b1e1c80 100644
--- a/sound/pci/oxygen/oxygen_io.c
+++ b/sound/pci/oxygen/oxygen_io.c
@@ -197,11 +197,11 @@ void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data)
197{ 197{
198 unsigned int count; 198 unsigned int count;
199 199
200 /* should not need more than 7.68 us (24 * 320 ns) */ 200 /* should not need more than 30.72 us (24 * 1.28 us) */
201 count = 10; 201 count = 10;
202 while ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) & OXYGEN_SPI_BUSY) 202 while ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) & OXYGEN_SPI_BUSY)
203 && count > 0) { 203 && count > 0) {
204 udelay(1); 204 udelay(4);
205 --count; 205 --count;
206 } 206 }
207 207
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 7e93cf884437..70b739816fcc 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -202,7 +202,13 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
202 struct oxygen *chip = entry->private_data; 202 struct oxygen *chip = entry->private_data;
203 int i, j; 203 int i, j;
204 204
205 snd_iprintf(buffer, "CMI8788\n\n"); 205 switch (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_PACKAGE_ID_MASK) {
206 case OXYGEN_PACKAGE_ID_8786: i = '6'; break;
207 case OXYGEN_PACKAGE_ID_8787: i = '7'; break;
208 case OXYGEN_PACKAGE_ID_8788: i = '8'; break;
209 default: i = '?'; break;
210 }
211 snd_iprintf(buffer, "CMI878%c:\n", i);
206 for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) { 212 for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) {
207 snd_iprintf(buffer, "%02x:", i); 213 snd_iprintf(buffer, "%02x:", i);
208 for (j = 0; j < 0x10; ++j) 214 for (j = 0; j < 0x10; ++j)
@@ -212,7 +218,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
212 if (mutex_lock_interruptible(&chip->mutex) < 0) 218 if (mutex_lock_interruptible(&chip->mutex) < 0)
213 return; 219 return;
214 if (chip->has_ac97_0) { 220 if (chip->has_ac97_0) {
215 snd_iprintf(buffer, "\nAC97\n"); 221 snd_iprintf(buffer, "\nAC97:\n");
216 for (i = 0; i < 0x80; i += 0x10) { 222 for (i = 0; i < 0x80; i += 0x10) {
217 snd_iprintf(buffer, "%02x:", i); 223 snd_iprintf(buffer, "%02x:", i);
218 for (j = 0; j < 0x10; j += 2) 224 for (j = 0; j < 0x10; j += 2)
@@ -222,7 +228,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
222 } 228 }
223 } 229 }
224 if (chip->has_ac97_1) { 230 if (chip->has_ac97_1) {
225 snd_iprintf(buffer, "\nAC97 2\n"); 231 snd_iprintf(buffer, "\nAC97 2:\n");
226 for (i = 0; i < 0x80; i += 0x10) { 232 for (i = 0; i < 0x80; i += 0x10) {
227 snd_iprintf(buffer, "%02x:", i); 233 snd_iprintf(buffer, "%02x:", i);
228 for (j = 0; j < 0x10; j += 2) 234 for (j = 0; j < 0x10; j += 2)
@@ -232,13 +238,15 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
232 } 238 }
233 } 239 }
234 mutex_unlock(&chip->mutex); 240 mutex_unlock(&chip->mutex);
241 if (chip->model.dump_registers)
242 chip->model.dump_registers(chip, buffer);
235} 243}
236 244
237static void oxygen_proc_init(struct oxygen *chip) 245static void oxygen_proc_init(struct oxygen *chip)
238{ 246{
239 struct snd_info_entry *entry; 247 struct snd_info_entry *entry;
240 248
241 if (!snd_card_proc_new(chip->card, "cmi8788", &entry)) 249 if (!snd_card_proc_new(chip->card, "oxygen", &entry))
242 snd_info_set_text_ops(entry, chip, oxygen_proc_read); 250 snd_info_set_text_ops(entry, chip, oxygen_proc_read);
243} 251}
244#else 252#else
@@ -262,7 +270,7 @@ oxygen_search_pci_id(struct oxygen *chip, const struct pci_device_id ids[])
262 */ 270 */
263 subdevice = oxygen_read_eeprom(chip, 2); 271 subdevice = oxygen_read_eeprom(chip, 2);
264 /* use default ID if EEPROM is missing */ 272 /* use default ID if EEPROM is missing */
265 if (subdevice == 0xffff) 273 if (subdevice == 0xffff && oxygen_read_eeprom(chip, 1) == 0xffff)
266 subdevice = 0x8788; 274 subdevice = 0x8788;
267 /* 275 /*
268 * We use only the subsystem device ID for searching because it is 276 * We use only the subsystem device ID for searching because it is
@@ -308,25 +316,46 @@ static void oxygen_restore_eeprom(struct oxygen *chip,
308 } 316 }
309} 317}
310 318
311static void pci_bridge_magic(void) 319static void configure_pcie_bridge(struct pci_dev *pci)
312{ 320{
313 struct pci_dev *pci = NULL; 321 enum { PEX811X, PI7C9X110 };
322 static const struct pci_device_id bridge_ids[] = {
323 { PCI_VDEVICE(PLX, 0x8111), .driver_data = PEX811X },
324 { PCI_VDEVICE(PLX, 0x8112), .driver_data = PEX811X },
325 { PCI_DEVICE(0x12d8, 0xe110), .driver_data = PI7C9X110 },
326 { }
327 };
328 struct pci_dev *bridge;
329 const struct pci_device_id *id;
314 u32 tmp; 330 u32 tmp;
315 331
316 for (;;) { 332 if (!pci->bus || !pci->bus->self)
317 /* If there is any Pericom PI7C9X110 PCI-E/PCI bridge ... */ 333 return;
318 pci = pci_get_device(0x12d8, 0xe110, pci); 334 bridge = pci->bus->self;
319 if (!pci) 335
320 break; 336 id = pci_match_id(bridge_ids, bridge);
321 /* 337 if (!id)
322 * ... configure its secondary internal arbiter to park to 338 return;
323 * the secondary port, instead of to the last master. 339
324 */ 340 switch (id->driver_data) {
325 if (!pci_read_config_dword(pci, 0x40, &tmp)) { 341 case PEX811X: /* PLX PEX8111/PEX8112 PCIe/PCI bridge */
326 tmp |= 1; 342 pci_read_config_dword(bridge, 0x48, &tmp);
327 pci_write_config_dword(pci, 0x40, tmp); 343 tmp |= 1; /* enable blind prefetching */
328 } 344 tmp |= 1 << 11; /* enable beacon generation */
329 /* Why? Try asking C-Media. */ 345 pci_write_config_dword(bridge, 0x48, tmp);
346
347 pci_write_config_dword(bridge, 0x84, 0x0c);
348 pci_read_config_dword(bridge, 0x88, &tmp);
349 tmp &= ~(7 << 27);
350 tmp |= 2 << 27; /* set prefetch size to 128 bytes */
351 pci_write_config_dword(bridge, 0x88, tmp);
352 break;
353
354 case PI7C9X110: /* Pericom PI7C9X110 PCIe/PCI bridge */
355 pci_read_config_dword(bridge, 0x40, &tmp);
356 tmp |= 1; /* park the PCI arbiter to the sound chip */
357 pci_write_config_dword(bridge, 0x40, tmp);
358 break;
330 } 359 }
331} 360}
332 361
@@ -343,12 +372,7 @@ static void oxygen_init(struct oxygen *chip)
343 (IEC958_AES1_CON_PCM_CODER << OXYGEN_SPDIF_CATEGORY_SHIFT); 372 (IEC958_AES1_CON_PCM_CODER << OXYGEN_SPDIF_CATEGORY_SHIFT);
344 chip->spdif_pcm_bits = chip->spdif_bits; 373 chip->spdif_pcm_bits = chip->spdif_bits;
345 374
346 if (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_REVISION_2) 375 if (!(oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_REVISION_2))
347 chip->revision = 2;
348 else
349 chip->revision = 1;
350
351 if (chip->revision == 1)
352 oxygen_set_bits8(chip, OXYGEN_MISC, 376 oxygen_set_bits8(chip, OXYGEN_MISC,
353 OXYGEN_MISC_PCI_MEM_W_1_CLOCK); 377 OXYGEN_MISC_PCI_MEM_W_1_CLOCK);
354 378
@@ -385,28 +409,40 @@ static void oxygen_init(struct oxygen *chip)
385 (OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT)); 409 (OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT));
386 oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2); 410 oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2);
387 oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT, 411 oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT,
388 OXYGEN_RATE_48000 | chip->model.dac_i2s_format | 412 OXYGEN_RATE_48000 |
389 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | 413 chip->model.dac_i2s_format |
390 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 414 OXYGEN_I2S_MCLK(chip->model.dac_mclks) |
415 OXYGEN_I2S_BITS_16 |
416 OXYGEN_I2S_MASTER |
417 OXYGEN_I2S_BCLK_64);
391 if (chip->model.device_config & CAPTURE_0_FROM_I2S_1) 418 if (chip->model.device_config & CAPTURE_0_FROM_I2S_1)
392 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, 419 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
393 OXYGEN_RATE_48000 | chip->model.adc_i2s_format | 420 OXYGEN_RATE_48000 |
394 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | 421 chip->model.adc_i2s_format |
395 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 422 OXYGEN_I2S_MCLK(chip->model.adc_mclks) |
423 OXYGEN_I2S_BITS_16 |
424 OXYGEN_I2S_MASTER |
425 OXYGEN_I2S_BCLK_64);
396 else 426 else
397 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, 427 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
398 OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); 428 OXYGEN_I2S_MASTER |
429 OXYGEN_I2S_MUTE_MCLK);
399 if (chip->model.device_config & (CAPTURE_0_FROM_I2S_2 | 430 if (chip->model.device_config & (CAPTURE_0_FROM_I2S_2 |
400 CAPTURE_2_FROM_I2S_2)) 431 CAPTURE_2_FROM_I2S_2))
401 oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, 432 oxygen_write16(chip, OXYGEN_I2S_B_FORMAT,
402 OXYGEN_RATE_48000 | chip->model.adc_i2s_format | 433 OXYGEN_RATE_48000 |
403 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | 434 chip->model.adc_i2s_format |
404 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 435 OXYGEN_I2S_MCLK(chip->model.adc_mclks) |
436 OXYGEN_I2S_BITS_16 |
437 OXYGEN_I2S_MASTER |
438 OXYGEN_I2S_BCLK_64);
405 else 439 else
406 oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, 440 oxygen_write16(chip, OXYGEN_I2S_B_FORMAT,
407 OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); 441 OXYGEN_I2S_MASTER |
442 OXYGEN_I2S_MUTE_MCLK);
408 oxygen_write16(chip, OXYGEN_I2S_C_FORMAT, 443 oxygen_write16(chip, OXYGEN_I2S_C_FORMAT,
409 OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); 444 OXYGEN_I2S_MASTER |
445 OXYGEN_I2S_MUTE_MCLK);
410 oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, 446 oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
411 OXYGEN_SPDIF_OUT_ENABLE | 447 OXYGEN_SPDIF_OUT_ENABLE |
412 OXYGEN_SPDIF_LOOPBACK); 448 OXYGEN_SPDIF_LOOPBACK);
@@ -536,7 +572,8 @@ static void oxygen_card_free(struct snd_card *card)
536 oxygen_shutdown(chip); 572 oxygen_shutdown(chip);
537 if (chip->irq >= 0) 573 if (chip->irq >= 0)
538 free_irq(chip->irq, chip); 574 free_irq(chip->irq, chip);
539 flush_scheduled_work(); 575 flush_work_sync(&chip->spdif_input_bits_work);
576 flush_work_sync(&chip->gpio_work);
540 chip->model.cleanup(chip); 577 chip->model.cleanup(chip);
541 kfree(chip->model_data); 578 kfree(chip->model_data);
542 mutex_destroy(&chip->mutex); 579 mutex_destroy(&chip->mutex);
@@ -613,7 +650,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
613 snd_card_set_dev(card, &pci->dev); 650 snd_card_set_dev(card, &pci->dev);
614 card->private_free = oxygen_card_free; 651 card->private_free = oxygen_card_free;
615 652
616 pci_bridge_magic(); 653 configure_pcie_bridge(pci);
617 oxygen_init(chip); 654 oxygen_init(chip);
618 chip->model.init(chip); 655 chip->model.init(chip);
619 656
@@ -627,8 +664,8 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
627 664
628 strcpy(card->driver, chip->model.chip); 665 strcpy(card->driver, chip->model.chip);
629 strcpy(card->shortname, chip->model.shortname); 666 strcpy(card->shortname, chip->model.shortname);
630 sprintf(card->longname, "%s (rev %u) at %#lx, irq %i", 667 sprintf(card->longname, "%s at %#lx, irq %i",
631 chip->model.longname, chip->revision, chip->addr, chip->irq); 668 chip->model.longname, chip->addr, chip->irq);
632 strcpy(card->mixername, chip->model.chip); 669 strcpy(card->mixername, chip->model.chip);
633 snd_component_add(card, chip->model.chip); 670 snd_component_add(card, chip->model.chip);
634 671
@@ -712,7 +749,8 @@ int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state)
712 spin_unlock_irq(&chip->reg_lock); 749 spin_unlock_irq(&chip->reg_lock);
713 750
714 synchronize_irq(chip->irq); 751 synchronize_irq(chip->irq);
715 flush_scheduled_work(); 752 flush_work_sync(&chip->spdif_input_bits_work);
753 flush_work_sync(&chip->gpio_work);
716 chip->interrupt_mask = saved_interrupt_mask; 754 chip->interrupt_mask = saved_interrupt_mask;
717 755
718 pci_disable_device(pci); 756 pci_disable_device(pci);
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index f375b8a27862..26c7e8bcb229 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -31,7 +31,7 @@ static int dac_volume_info(struct snd_kcontrol *ctl,
31 struct oxygen *chip = ctl->private_data; 31 struct oxygen *chip = ctl->private_data;
32 32
33 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 33 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
34 info->count = chip->model.dac_channels; 34 info->count = chip->model.dac_channels_mixer;
35 info->value.integer.min = chip->model.dac_volume_min; 35 info->value.integer.min = chip->model.dac_volume_min;
36 info->value.integer.max = chip->model.dac_volume_max; 36 info->value.integer.max = chip->model.dac_volume_max;
37 return 0; 37 return 0;
@@ -44,7 +44,7 @@ static int dac_volume_get(struct snd_kcontrol *ctl,
44 unsigned int i; 44 unsigned int i;
45 45
46 mutex_lock(&chip->mutex); 46 mutex_lock(&chip->mutex);
47 for (i = 0; i < chip->model.dac_channels; ++i) 47 for (i = 0; i < chip->model.dac_channels_mixer; ++i)
48 value->value.integer.value[i] = chip->dac_volume[i]; 48 value->value.integer.value[i] = chip->dac_volume[i];
49 mutex_unlock(&chip->mutex); 49 mutex_unlock(&chip->mutex);
50 return 0; 50 return 0;
@@ -59,7 +59,7 @@ static int dac_volume_put(struct snd_kcontrol *ctl,
59 59
60 changed = 0; 60 changed = 0;
61 mutex_lock(&chip->mutex); 61 mutex_lock(&chip->mutex);
62 for (i = 0; i < chip->model.dac_channels; ++i) 62 for (i = 0; i < chip->model.dac_channels_mixer; ++i)
63 if (value->value.integer.value[i] != chip->dac_volume[i]) { 63 if (value->value.integer.value[i] != chip->dac_volume[i]) {
64 chip->dac_volume[i] = value->value.integer.value[i]; 64 chip->dac_volume[i] = value->value.integer.value[i];
65 changed = 1; 65 changed = 1;
@@ -97,6 +97,16 @@ static int dac_mute_put(struct snd_kcontrol *ctl,
97 return changed; 97 return changed;
98} 98}
99 99
100static unsigned int upmix_item_count(struct oxygen *chip)
101{
102 if (chip->model.dac_channels_pcm < 8)
103 return 2;
104 else if (chip->model.update_center_lfe_mix)
105 return 5;
106 else
107 return 3;
108}
109
100static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) 110static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
101{ 111{
102 static const char *const names[5] = { 112 static const char *const names[5] = {
@@ -107,15 +117,9 @@ static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
107 "Front+Surround+Center/LFE+Back", 117 "Front+Surround+Center/LFE+Back",
108 }; 118 };
109 struct oxygen *chip = ctl->private_data; 119 struct oxygen *chip = ctl->private_data;
110 unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3; 120 unsigned int count = upmix_item_count(chip);
111 121
112 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 122 return snd_ctl_enum_info(info, 1, count, names);
113 info->count = 1;
114 info->value.enumerated.items = count;
115 if (info->value.enumerated.item >= count)
116 info->value.enumerated.item = count - 1;
117 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
118 return 0;
119} 123}
120 124
121static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 125static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
@@ -176,6 +180,8 @@ void oxygen_update_dac_routing(struct oxygen *chip)
176 (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) | 180 (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
177 (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) | 181 (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
178 (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT); 182 (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT);
183 if (chip->model.adjust_dac_routing)
184 reg_value = chip->model.adjust_dac_routing(chip, reg_value);
179 oxygen_write16_masked(chip, OXYGEN_PLAY_ROUTING, reg_value, 185 oxygen_write16_masked(chip, OXYGEN_PLAY_ROUTING, reg_value,
180 OXYGEN_PLAY_DAC0_SOURCE_MASK | 186 OXYGEN_PLAY_DAC0_SOURCE_MASK |
181 OXYGEN_PLAY_DAC1_SOURCE_MASK | 187 OXYGEN_PLAY_DAC1_SOURCE_MASK |
@@ -188,7 +194,7 @@ void oxygen_update_dac_routing(struct oxygen *chip)
188static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 194static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
189{ 195{
190 struct oxygen *chip = ctl->private_data; 196 struct oxygen *chip = ctl->private_data;
191 unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3; 197 unsigned int count = upmix_item_count(chip);
192 int changed; 198 int changed;
193 199
194 if (value->value.enumerated.item[0] >= count) 200 if (value->value.enumerated.item[0] >= count)
@@ -430,30 +436,31 @@ static int spdif_input_default_get(struct snd_kcontrol *ctl,
430 return 0; 436 return 0;
431} 437}
432 438
433static int spdif_loopback_get(struct snd_kcontrol *ctl, 439static int spdif_bit_switch_get(struct snd_kcontrol *ctl,
434 struct snd_ctl_elem_value *value) 440 struct snd_ctl_elem_value *value)
435{ 441{
436 struct oxygen *chip = ctl->private_data; 442 struct oxygen *chip = ctl->private_data;
443 u32 bit = ctl->private_value;
437 444
438 value->value.integer.value[0] = 445 value->value.integer.value[0] =
439 !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) 446 !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) & bit);
440 & OXYGEN_SPDIF_LOOPBACK);
441 return 0; 447 return 0;
442} 448}
443 449
444static int spdif_loopback_put(struct snd_kcontrol *ctl, 450static int spdif_bit_switch_put(struct snd_kcontrol *ctl,
445 struct snd_ctl_elem_value *value) 451 struct snd_ctl_elem_value *value)
446{ 452{
447 struct oxygen *chip = ctl->private_data; 453 struct oxygen *chip = ctl->private_data;
454 u32 bit = ctl->private_value;
448 u32 oldreg, newreg; 455 u32 oldreg, newreg;
449 int changed; 456 int changed;
450 457
451 spin_lock_irq(&chip->reg_lock); 458 spin_lock_irq(&chip->reg_lock);
452 oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL); 459 oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
453 if (value->value.integer.value[0]) 460 if (value->value.integer.value[0])
454 newreg = oldreg | OXYGEN_SPDIF_LOOPBACK; 461 newreg = oldreg | bit;
455 else 462 else
456 newreg = oldreg & ~OXYGEN_SPDIF_LOOPBACK; 463 newreg = oldreg & ~bit;
457 changed = newreg != oldreg; 464 changed = newreg != oldreg;
458 if (changed) 465 if (changed)
459 oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg); 466 oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg);
@@ -644,6 +651,46 @@ static int ac97_volume_put(struct snd_kcontrol *ctl,
644 return change; 651 return change;
645} 652}
646 653
654static int mic_fmic_source_info(struct snd_kcontrol *ctl,
655 struct snd_ctl_elem_info *info)
656{
657 static const char *const names[] = { "Mic Jack", "Front Panel" };
658
659 return snd_ctl_enum_info(info, 1, 2, names);
660}
661
662static int mic_fmic_source_get(struct snd_kcontrol *ctl,
663 struct snd_ctl_elem_value *value)
664{
665 struct oxygen *chip = ctl->private_data;
666
667 mutex_lock(&chip->mutex);
668 value->value.enumerated.item[0] =
669 !!(oxygen_read_ac97(chip, 0, CM9780_JACK) & CM9780_FMIC2MIC);
670 mutex_unlock(&chip->mutex);
671 return 0;
672}
673
674static int mic_fmic_source_put(struct snd_kcontrol *ctl,
675 struct snd_ctl_elem_value *value)
676{
677 struct oxygen *chip = ctl->private_data;
678 u16 oldreg, newreg;
679 int change;
680
681 mutex_lock(&chip->mutex);
682 oldreg = oxygen_read_ac97(chip, 0, CM9780_JACK);
683 if (value->value.enumerated.item[0])
684 newreg = oldreg | CM9780_FMIC2MIC;
685 else
686 newreg = oldreg & ~CM9780_FMIC2MIC;
687 change = newreg != oldreg;
688 if (change)
689 oxygen_write_ac97(chip, 0, CM9780_JACK, newreg);
690 mutex_unlock(&chip->mutex);
691 return change;
692}
693
647static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl, 694static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl,
648 struct snd_ctl_elem_info *info) 695 struct snd_ctl_elem_info *info)
649{ 696{
@@ -708,7 +755,7 @@ static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl,
708 .private_value = ((codec) << 24) | ((stereo) << 16) | (index), \ 755 .private_value = ((codec) << 24) | ((stereo) << 16) | (index), \
709 } 756 }
710 757
711static DECLARE_TLV_DB_SCALE(monitor_db_scale, -1000, 1000, 0); 758static DECLARE_TLV_DB_SCALE(monitor_db_scale, -600, 600, 0);
712static DECLARE_TLV_DB_SCALE(ac97_db_scale, -3450, 150, 0); 759static DECLARE_TLV_DB_SCALE(ac97_db_scale, -3450, 150, 0);
713static DECLARE_TLV_DB_SCALE(ac97_rec_db_scale, 0, 150, 0); 760static DECLARE_TLV_DB_SCALE(ac97_rec_db_scale, 0, 150, 0);
714 761
@@ -791,8 +838,17 @@ static const struct snd_kcontrol_new spdif_input_controls[] = {
791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 838 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
792 .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH), 839 .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH),
793 .info = snd_ctl_boolean_mono_info, 840 .info = snd_ctl_boolean_mono_info,
794 .get = spdif_loopback_get, 841 .get = spdif_bit_switch_get,
795 .put = spdif_loopback_put, 842 .put = spdif_bit_switch_put,
843 .private_value = OXYGEN_SPDIF_LOOPBACK,
844 },
845 {
846 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
847 .name = SNDRV_CTL_NAME_IEC958("Validity Check ",CAPTURE,SWITCH),
848 .info = snd_ctl_boolean_mono_info,
849 .get = spdif_bit_switch_get,
850 .put = spdif_bit_switch_put,
851 .private_value = OXYGEN_SPDIF_SPDVALID,
796 }, 852 },
797}; 853};
798 854
@@ -908,6 +964,13 @@ static const struct snd_kcontrol_new ac97_controls[] = {
908 AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0), 964 AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0),
909 AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1), 965 AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1),
910 AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0), 966 AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0),
967 {
968 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
969 .name = "Mic Source Capture Enum",
970 .info = mic_fmic_source_info,
971 .get = mic_fmic_source_get,
972 .put = mic_fmic_source_put,
973 },
911 AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1), 974 AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1),
912 AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1), 975 AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1),
913 AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1), 976 AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1),
@@ -970,7 +1033,13 @@ static int add_controls(struct oxygen *chip,
970 continue; 1033 continue;
971 } 1034 }
972 if (!strcmp(template.name, "Stereo Upmixing") && 1035 if (!strcmp(template.name, "Stereo Upmixing") &&
973 chip->model.dac_channels == 2) 1036 chip->model.dac_channels_pcm == 2)
1037 continue;
1038 if (!strcmp(template.name, "Mic Source Capture Enum") &&
1039 !(chip->model.device_config & AC97_FMIC_SWITCH))
1040 continue;
1041 if (!strncmp(template.name, "CD Capture ", 11) &&
1042 !(chip->model.device_config & AC97_CD_INPUT))
974 continue; 1043 continue;
975 if (!strcmp(template.name, "Master Playback Volume") && 1044 if (!strcmp(template.name, "Master Playback Volume") &&
976 chip->model.dac_tlv) { 1045 chip->model.dac_tlv) {
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index 9dff6954c397..d5533e34ece9 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -39,7 +39,8 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = {
39 SNDRV_PCM_INFO_MMAP_VALID | 39 SNDRV_PCM_INFO_MMAP_VALID |
40 SNDRV_PCM_INFO_INTERLEAVED | 40 SNDRV_PCM_INFO_INTERLEAVED |
41 SNDRV_PCM_INFO_PAUSE | 41 SNDRV_PCM_INFO_PAUSE |
42 SNDRV_PCM_INFO_SYNC_START, 42 SNDRV_PCM_INFO_SYNC_START |
43 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
43 .formats = SNDRV_PCM_FMTBIT_S16_LE | 44 .formats = SNDRV_PCM_FMTBIT_S16_LE |
44 SNDRV_PCM_FMTBIT_S32_LE, 45 SNDRV_PCM_FMTBIT_S32_LE,
45 .rates = SNDRV_PCM_RATE_32000 | 46 .rates = SNDRV_PCM_RATE_32000 |
@@ -56,8 +57,8 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = {
56 .channels_max = 2, 57 .channels_max = 2,
57 .buffer_bytes_max = BUFFER_BYTES_MAX, 58 .buffer_bytes_max = BUFFER_BYTES_MAX,
58 .period_bytes_min = PERIOD_BYTES_MIN, 59 .period_bytes_min = PERIOD_BYTES_MIN,
59 .period_bytes_max = BUFFER_BYTES_MAX / 2, 60 .period_bytes_max = BUFFER_BYTES_MAX,
60 .periods_min = 2, 61 .periods_min = 1,
61 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, 62 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
62}; 63};
63static const struct snd_pcm_hardware oxygen_multichannel_hardware = { 64static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
@@ -65,7 +66,8 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
65 SNDRV_PCM_INFO_MMAP_VALID | 66 SNDRV_PCM_INFO_MMAP_VALID |
66 SNDRV_PCM_INFO_INTERLEAVED | 67 SNDRV_PCM_INFO_INTERLEAVED |
67 SNDRV_PCM_INFO_PAUSE | 68 SNDRV_PCM_INFO_PAUSE |
68 SNDRV_PCM_INFO_SYNC_START, 69 SNDRV_PCM_INFO_SYNC_START |
70 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
69 .formats = SNDRV_PCM_FMTBIT_S16_LE | 71 .formats = SNDRV_PCM_FMTBIT_S16_LE |
70 SNDRV_PCM_FMTBIT_S32_LE, 72 SNDRV_PCM_FMTBIT_S32_LE,
71 .rates = SNDRV_PCM_RATE_32000 | 73 .rates = SNDRV_PCM_RATE_32000 |
@@ -82,8 +84,8 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
82 .channels_max = 8, 84 .channels_max = 8,
83 .buffer_bytes_max = BUFFER_BYTES_MAX_MULTICH, 85 .buffer_bytes_max = BUFFER_BYTES_MAX_MULTICH,
84 .period_bytes_min = PERIOD_BYTES_MIN, 86 .period_bytes_min = PERIOD_BYTES_MIN,
85 .period_bytes_max = BUFFER_BYTES_MAX_MULTICH / 2, 87 .period_bytes_max = BUFFER_BYTES_MAX_MULTICH,
86 .periods_min = 2, 88 .periods_min = 1,
87 .periods_max = BUFFER_BYTES_MAX_MULTICH / PERIOD_BYTES_MIN, 89 .periods_max = BUFFER_BYTES_MAX_MULTICH / PERIOD_BYTES_MIN,
88}; 90};
89static const struct snd_pcm_hardware oxygen_ac97_hardware = { 91static const struct snd_pcm_hardware oxygen_ac97_hardware = {
@@ -91,7 +93,8 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = {
91 SNDRV_PCM_INFO_MMAP_VALID | 93 SNDRV_PCM_INFO_MMAP_VALID |
92 SNDRV_PCM_INFO_INTERLEAVED | 94 SNDRV_PCM_INFO_INTERLEAVED |
93 SNDRV_PCM_INFO_PAUSE | 95 SNDRV_PCM_INFO_PAUSE |
94 SNDRV_PCM_INFO_SYNC_START, 96 SNDRV_PCM_INFO_SYNC_START |
97 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
95 .formats = SNDRV_PCM_FMTBIT_S16_LE, 98 .formats = SNDRV_PCM_FMTBIT_S16_LE,
96 .rates = SNDRV_PCM_RATE_48000, 99 .rates = SNDRV_PCM_RATE_48000,
97 .rate_min = 48000, 100 .rate_min = 48000,
@@ -100,8 +103,8 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = {
100 .channels_max = 2, 103 .channels_max = 2,
101 .buffer_bytes_max = BUFFER_BYTES_MAX, 104 .buffer_bytes_max = BUFFER_BYTES_MAX,
102 .period_bytes_min = PERIOD_BYTES_MIN, 105 .period_bytes_min = PERIOD_BYTES_MIN,
103 .period_bytes_max = BUFFER_BYTES_MAX / 2, 106 .period_bytes_max = BUFFER_BYTES_MAX,
104 .periods_min = 2, 107 .periods_min = 1,
105 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, 108 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
106}; 109};
107 110
@@ -140,7 +143,7 @@ static int oxygen_open(struct snd_pcm_substream *substream,
140 runtime->hw.rate_min = 44100; 143 runtime->hw.rate_min = 44100;
141 break; 144 break;
142 case PCM_MULTICH: 145 case PCM_MULTICH:
143 runtime->hw.channels_max = chip->model.dac_channels; 146 runtime->hw.channels_max = chip->model.dac_channels_pcm;
144 break; 147 break;
145 } 148 }
146 if (chip->model.pcm_hardware_filter) 149 if (chip->model.pcm_hardware_filter)
@@ -271,17 +274,6 @@ static unsigned int oxygen_rate(struct snd_pcm_hw_params *hw_params)
271 } 274 }
272} 275}
273 276
274unsigned int oxygen_default_i2s_mclk(struct oxygen *chip,
275 unsigned int channel,
276 struct snd_pcm_hw_params *hw_params)
277{
278 if (params_rate(hw_params) <= 96000)
279 return OXYGEN_I2S_MCLK_256;
280 else
281 return OXYGEN_I2S_MCLK_128;
282}
283EXPORT_SYMBOL(oxygen_default_i2s_mclk);
284
285static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params) 277static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params)
286{ 278{
287 if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE) 279 if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE)
@@ -341,6 +333,26 @@ static int oxygen_hw_params(struct snd_pcm_substream *substream,
341 return 0; 333 return 0;
342} 334}
343 335
336static u16 get_mclk(struct oxygen *chip, unsigned int channel,
337 struct snd_pcm_hw_params *params)
338{
339 unsigned int mclks, shift;
340
341 if (channel == PCM_MULTICH)
342 mclks = chip->model.dac_mclks;
343 else
344 mclks = chip->model.adc_mclks;
345
346 if (params_rate(params) <= 48000)
347 shift = 0;
348 else if (params_rate(params) <= 96000)
349 shift = 2;
350 else
351 shift = 4;
352
353 return OXYGEN_I2S_MCLK(mclks >> shift);
354}
355
344static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream, 356static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
345 struct snd_pcm_hw_params *hw_params) 357 struct snd_pcm_hw_params *hw_params)
346{ 358{
@@ -357,8 +369,8 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
357 OXYGEN_REC_FORMAT_A_MASK); 369 OXYGEN_REC_FORMAT_A_MASK);
358 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, 370 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
359 oxygen_rate(hw_params) | 371 oxygen_rate(hw_params) |
360 chip->model.get_i2s_mclk(chip, PCM_A, hw_params) |
361 chip->model.adc_i2s_format | 372 chip->model.adc_i2s_format |
373 get_mclk(chip, PCM_A, hw_params) |
362 oxygen_i2s_bits(hw_params), 374 oxygen_i2s_bits(hw_params),
363 OXYGEN_I2S_RATE_MASK | 375 OXYGEN_I2S_RATE_MASK |
364 OXYGEN_I2S_FORMAT_MASK | 376 OXYGEN_I2S_FORMAT_MASK |
@@ -393,9 +405,8 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
393 if (!is_ac97) 405 if (!is_ac97)
394 oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT, 406 oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
395 oxygen_rate(hw_params) | 407 oxygen_rate(hw_params) |
396 chip->model.get_i2s_mclk(chip, PCM_B,
397 hw_params) |
398 chip->model.adc_i2s_format | 408 chip->model.adc_i2s_format |
409 get_mclk(chip, PCM_B, hw_params) |
399 oxygen_i2s_bits(hw_params), 410 oxygen_i2s_bits(hw_params),
400 OXYGEN_I2S_RATE_MASK | 411 OXYGEN_I2S_RATE_MASK |
401 OXYGEN_I2S_FORMAT_MASK | 412 OXYGEN_I2S_FORMAT_MASK |
@@ -476,8 +487,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
476 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, 487 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
477 oxygen_rate(hw_params) | 488 oxygen_rate(hw_params) |
478 chip->model.dac_i2s_format | 489 chip->model.dac_i2s_format |
479 chip->model.get_i2s_mclk(chip, PCM_MULTICH, 490 get_mclk(chip, PCM_MULTICH, hw_params) |
480 hw_params) |
481 oxygen_i2s_bits(hw_params), 491 oxygen_i2s_bits(hw_params),
482 OXYGEN_I2S_RATE_MASK | 492 OXYGEN_I2S_RATE_MASK |
483 OXYGEN_I2S_FORMAT_MASK | 493 OXYGEN_I2S_FORMAT_MASK |
@@ -530,7 +540,10 @@ static int oxygen_prepare(struct snd_pcm_substream *substream)
530 oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); 540 oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
531 oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); 541 oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
532 542
533 chip->interrupt_mask |= channel_mask; 543 if (substream->runtime->no_period_wakeup)
544 chip->interrupt_mask &= ~channel_mask;
545 else
546 chip->interrupt_mask |= channel_mask;
534 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask); 547 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
535 spin_unlock_irq(&chip->reg_lock); 548 spin_unlock_irq(&chip->reg_lock);
536 return 0; 549 return 0;
diff --git a/sound/pci/oxygen/oxygen_regs.h b/sound/pci/oxygen/oxygen_regs.h
index 72de159d4567..63dc7a0ab555 100644
--- a/sound/pci/oxygen/oxygen_regs.h
+++ b/sound/pci/oxygen/oxygen_regs.h
@@ -139,9 +139,11 @@
139#define OXYGEN_I2S_FORMAT_I2S 0x0000 139#define OXYGEN_I2S_FORMAT_I2S 0x0000
140#define OXYGEN_I2S_FORMAT_LJUST 0x0008 140#define OXYGEN_I2S_FORMAT_LJUST 0x0008
141#define OXYGEN_I2S_MCLK_MASK 0x0030 /* MCLK/LRCK */ 141#define OXYGEN_I2S_MCLK_MASK 0x0030 /* MCLK/LRCK */
142#define OXYGEN_I2S_MCLK_128 0x0000 142#define OXYGEN_I2S_MCLK_SHIFT 4
143#define OXYGEN_I2S_MCLK_256 0x0010 143#define MCLK_128 0
144#define OXYGEN_I2S_MCLK_512 0x0020 144#define MCLK_256 1
145#define MCLK_512 2
146#define OXYGEN_I2S_MCLK(f) (((f) & 3) << OXYGEN_I2S_MCLK_SHIFT)
145#define OXYGEN_I2S_BITS_MASK 0x00c0 147#define OXYGEN_I2S_BITS_MASK 0x00c0
146#define OXYGEN_I2S_BITS_16 0x0000 148#define OXYGEN_I2S_BITS_16 0x0000
147#define OXYGEN_I2S_BITS_20 0x0040 149#define OXYGEN_I2S_BITS_20 0x0040
@@ -238,11 +240,11 @@
238#define OXYGEN_SPI_DATA_LENGTH_MASK 0x02 240#define OXYGEN_SPI_DATA_LENGTH_MASK 0x02
239#define OXYGEN_SPI_DATA_LENGTH_2 0x00 241#define OXYGEN_SPI_DATA_LENGTH_2 0x00
240#define OXYGEN_SPI_DATA_LENGTH_3 0x02 242#define OXYGEN_SPI_DATA_LENGTH_3 0x02
241#define OXYGEN_SPI_CLOCK_MASK 0xc0 243#define OXYGEN_SPI_CLOCK_MASK 0x0c
242#define OXYGEN_SPI_CLOCK_160 0x00 /* ns */ 244#define OXYGEN_SPI_CLOCK_160 0x00 /* ns */
243#define OXYGEN_SPI_CLOCK_320 0x40 245#define OXYGEN_SPI_CLOCK_320 0x04
244#define OXYGEN_SPI_CLOCK_640 0x80 246#define OXYGEN_SPI_CLOCK_640 0x08
245#define OXYGEN_SPI_CLOCK_1280 0xc0 247#define OXYGEN_SPI_CLOCK_1280 0x0c
246#define OXYGEN_SPI_CODEC_MASK 0x70 /* 0..5 */ 248#define OXYGEN_SPI_CODEC_MASK 0x70 /* 0..5 */
247#define OXYGEN_SPI_CODEC_SHIFT 4 249#define OXYGEN_SPI_CODEC_SHIFT 4
248#define OXYGEN_SPI_CEN_MASK 0x80 250#define OXYGEN_SPI_CEN_MASK 0x80
@@ -436,13 +438,15 @@
436/* OXYGEN_CHANNEL_* */ 438/* OXYGEN_CHANNEL_* */
437 439
438#define OXYGEN_CODEC_VERSION 0xe4 440#define OXYGEN_CODEC_VERSION 0xe4
439#define OXYGEN_XCID_MASK 0x07 441#define OXYGEN_CODEC_ID_MASK 0x07
440 442
441#define OXYGEN_REVISION 0xe6 443#define OXYGEN_REVISION 0xe6
442#define OXYGEN_REVISION_XPKGID_MASK 0x0007 444#define OXYGEN_PACKAGE_ID_MASK 0x0007
445#define OXYGEN_PACKAGE_ID_8786 0x0004
446#define OXYGEN_PACKAGE_ID_8787 0x0006
447#define OXYGEN_PACKAGE_ID_8788 0x0007
443#define OXYGEN_REVISION_MASK 0xfff8 448#define OXYGEN_REVISION_MASK 0xfff8
444#define OXYGEN_REVISION_2 0x0008 /* bit flag */ 449#define OXYGEN_REVISION_2 0x0008
445#define OXYGEN_REVISION_8787 0x0014 /* 8 bits */
446 450
447#define OXYGEN_OFFSIN_48K 0xe8 451#define OXYGEN_OFFSIN_48K 0xe8
448#define OXYGEN_OFFSBASE_48K 0xe9 452#define OXYGEN_OFFSBASE_48K 0xe9
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 06c863e86e3d..469010a8b849 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -25,9 +25,9 @@
25#include "xonar.h" 25#include "xonar.h"
26 26
27MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 27MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
28MODULE_DESCRIPTION("Asus AVx00 driver"); 28MODULE_DESCRIPTION("Asus Virtuoso driver");
29MODULE_LICENSE("GPL v2"); 29MODULE_LICENSE("GPL v2");
30MODULE_SUPPORTED_DEVICE("{{Asus,AV100},{Asus,AV200}}"); 30MODULE_SUPPORTED_DEVICE("{{Asus,AV66},{Asus,AV100},{Asus,AV200}}");
31 31
32static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 32static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
33static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 33static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
@@ -49,6 +49,7 @@ static DEFINE_PCI_DEVICE_TABLE(xonar_ids) = {
49 { OXYGEN_PCI_SUBID(0x1043, 0x834f) }, 49 { OXYGEN_PCI_SUBID(0x1043, 0x834f) },
50 { OXYGEN_PCI_SUBID(0x1043, 0x835c) }, 50 { OXYGEN_PCI_SUBID(0x1043, 0x835c) },
51 { OXYGEN_PCI_SUBID(0x1043, 0x835d) }, 51 { OXYGEN_PCI_SUBID(0x1043, 0x835d) },
52 { OXYGEN_PCI_SUBID(0x1043, 0x835e) },
52 { OXYGEN_PCI_SUBID(0x1043, 0x838e) }, 53 { OXYGEN_PCI_SUBID(0x1043, 0x838e) },
53 { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, 54 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
54 { } 55 { }
diff --git a/sound/pci/oxygen/xonar.h b/sound/pci/oxygen/xonar.h
index b35343b0a9a5..0434c207e811 100644
--- a/sound/pci/oxygen/xonar.h
+++ b/sound/pci/oxygen/xonar.h
@@ -24,6 +24,8 @@ void xonar_init_ext_power(struct oxygen *chip);
24void xonar_init_cs53x1(struct oxygen *chip); 24void xonar_init_cs53x1(struct oxygen *chip);
25void xonar_set_cs53x1_params(struct oxygen *chip, 25void xonar_set_cs53x1_params(struct oxygen *chip,
26 struct snd_pcm_hw_params *params); 26 struct snd_pcm_hw_params *params);
27
28#define XONAR_GPIO_BIT_INVERT (1 << 16)
27int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl, 29int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
28 struct snd_ctl_elem_value *value); 30 struct snd_ctl_elem_value *value);
29int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl, 31int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c
index 7c4986b27f2b..252719101c42 100644
--- a/sound/pci/oxygen/xonar_cs43xx.c
+++ b/sound/pci/oxygen/xonar_cs43xx.c
@@ -22,29 +22,28 @@
22 * 22 *
23 * CMI8788: 23 * CMI8788:
24 * 24 *
25 * I²C <-> CS4398 (front) 25 * I²C <-> CS4398 (addr 1001111) (front)
26 * <-> CS4362A (surround, center/LFE, back) 26 * <-> CS4362A (addr 0011000) (surround, center/LFE, back)
27 * 27 *
28 * GPI 0 <- external power present (DX only) 28 * GPI 0 <- external power present (DX only)
29 * 29 *
30 * GPIO 0 -> enable output to speakers 30 * GPIO 0 -> enable output to speakers
31 * GPIO 1 -> enable front panel I/O 31 * GPIO 1 -> route output to front panel
32 * GPIO 2 -> M0 of CS5361 32 * GPIO 2 -> M0 of CS5361
33 * GPIO 3 -> M1 of CS5361 33 * GPIO 3 -> M1 of CS5361
34 * GPIO 8 -> route input jack to line-in (0) or mic-in (1) 34 * GPIO 6 -> ?
35 * GPIO 7 -> ?
36 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
35 * 37 *
36 * CS4398: 38 * CM9780:
37 *
38 * AD0 <- 1
39 * AD1 <- 1
40 *
41 * CS4362A:
42 * 39 *
43 * AD0 <- 0 40 * LINE_OUT -> input of ADC
44 * 41 *
45 * CM9780: 42 * AUX_IN <- aux
43 * MIC_IN <- mic
44 * FMIC_IN <- front mic
46 * 45 *
47 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input 46 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input
48 */ 47 */
49 48
50#include <linux/pci.h> 49#include <linux/pci.h>
@@ -63,6 +62,7 @@
63#define GPI_EXT_POWER 0x01 62#define GPI_EXT_POWER 0x01
64#define GPIO_D1_OUTPUT_ENABLE 0x0001 63#define GPIO_D1_OUTPUT_ENABLE 0x0001
65#define GPIO_D1_FRONT_PANEL 0x0002 64#define GPIO_D1_FRONT_PANEL 0x0002
65#define GPIO_D1_MAGIC 0x00c0
66#define GPIO_D1_INPUT_ROUTE 0x0100 66#define GPIO_D1_INPUT_ROUTE 0x0100
67 67
68#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */ 68#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
@@ -169,12 +169,12 @@ static void xonar_d1_init(struct oxygen *chip)
169 cs43xx_registers_init(chip); 169 cs43xx_registers_init(chip);
170 170
171 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 171 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
172 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); 172 GPIO_D1_FRONT_PANEL |
173 GPIO_D1_MAGIC |
174 GPIO_D1_INPUT_ROUTE);
173 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, 175 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
174 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); 176 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
175 177
176 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
177
178 xonar_init_cs53x1(chip); 178 xonar_init_cs53x1(chip);
179 xonar_enable_output(chip); 179 xonar_enable_output(chip);
180 180
@@ -284,7 +284,7 @@ static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed)
284 284
285static const struct snd_kcontrol_new front_panel_switch = { 285static const struct snd_kcontrol_new front_panel_switch = {
286 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 286 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
287 .name = "Front Panel Switch", 287 .name = "Front Panel Playback Switch",
288 .info = snd_ctl_boolean_mono_info, 288 .info = snd_ctl_boolean_mono_info,
289 .get = xonar_gpio_bit_switch_get, 289 .get = xonar_gpio_bit_switch_get,
290 .put = xonar_gpio_bit_switch_put, 290 .put = xonar_gpio_bit_switch_put,
@@ -298,13 +298,7 @@ static int rolloff_info(struct snd_kcontrol *ctl,
298 "Fast Roll-off", "Slow Roll-off" 298 "Fast Roll-off", "Slow Roll-off"
299 }; 299 };
300 300
301 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 301 return snd_ctl_enum_info(info, 1, 2, names);
302 info->count = 1;
303 info->value.enumerated.items = 2;
304 if (info->value.enumerated.item >= 2)
305 info->value.enumerated.item = 1;
306 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
307 return 0;
308} 302}
309 303
310static int rolloff_get(struct snd_kcontrol *ctl, 304static int rolloff_get(struct snd_kcontrol *ctl,
@@ -367,13 +361,6 @@ static void xonar_d1_line_mic_ac97_switch(struct oxygen *chip,
367 361
368static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -6000, 100, 0); 362static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -6000, 100, 0);
369 363
370static int xonar_d1_control_filter(struct snd_kcontrol_new *template)
371{
372 if (!strncmp(template->name, "CD Capture ", 11))
373 return 1; /* no CD input */
374 return 0;
375}
376
377static int xonar_d1_mixer_init(struct oxygen *chip) 364static int xonar_d1_mixer_init(struct oxygen *chip)
378{ 365{
379 int err; 366 int err;
@@ -387,31 +374,58 @@ static int xonar_d1_mixer_init(struct oxygen *chip)
387 return 0; 374 return 0;
388} 375}
389 376
377static void dump_cs4362a_registers(struct xonar_cs43xx *data,
378 struct snd_info_buffer *buffer)
379{
380 unsigned int i;
381
382 snd_iprintf(buffer, "\nCS4362A:");
383 for (i = 1; i <= 14; ++i)
384 snd_iprintf(buffer, " %02x", data->cs4362a_regs[i]);
385 snd_iprintf(buffer, "\n");
386}
387
388static void dump_d1_registers(struct oxygen *chip,
389 struct snd_info_buffer *buffer)
390{
391 struct xonar_cs43xx *data = chip->model_data;
392 unsigned int i;
393
394 snd_iprintf(buffer, "\nCS4398: 7?");
395 for (i = 2; i < 8; ++i)
396 snd_iprintf(buffer, " %02x", data->cs4398_regs[i]);
397 snd_iprintf(buffer, "\n");
398 dump_cs4362a_registers(data, buffer);
399}
400
390static const struct oxygen_model model_xonar_d1 = { 401static const struct oxygen_model model_xonar_d1 = {
391 .longname = "Asus Virtuoso 100", 402 .longname = "Asus Virtuoso 100",
392 .chip = "AV200", 403 .chip = "AV200",
393 .init = xonar_d1_init, 404 .init = xonar_d1_init,
394 .control_filter = xonar_d1_control_filter,
395 .mixer_init = xonar_d1_mixer_init, 405 .mixer_init = xonar_d1_mixer_init,
396 .cleanup = xonar_d1_cleanup, 406 .cleanup = xonar_d1_cleanup,
397 .suspend = xonar_d1_suspend, 407 .suspend = xonar_d1_suspend,
398 .resume = xonar_d1_resume, 408 .resume = xonar_d1_resume,
399 .get_i2s_mclk = oxygen_default_i2s_mclk,
400 .set_dac_params = set_cs43xx_params, 409 .set_dac_params = set_cs43xx_params,
401 .set_adc_params = xonar_set_cs53x1_params, 410 .set_adc_params = xonar_set_cs53x1_params,
402 .update_dac_volume = update_cs43xx_volume, 411 .update_dac_volume = update_cs43xx_volume,
403 .update_dac_mute = update_cs43xx_mute, 412 .update_dac_mute = update_cs43xx_mute,
404 .update_center_lfe_mix = update_cs43xx_center_lfe_mix, 413 .update_center_lfe_mix = update_cs43xx_center_lfe_mix,
405 .ac97_switch = xonar_d1_line_mic_ac97_switch, 414 .ac97_switch = xonar_d1_line_mic_ac97_switch,
415 .dump_registers = dump_d1_registers,
406 .dac_tlv = cs4362a_db_scale, 416 .dac_tlv = cs4362a_db_scale,
407 .model_data_size = sizeof(struct xonar_cs43xx), 417 .model_data_size = sizeof(struct xonar_cs43xx),
408 .device_config = PLAYBACK_0_TO_I2S | 418 .device_config = PLAYBACK_0_TO_I2S |
409 PLAYBACK_1_TO_SPDIF | 419 PLAYBACK_1_TO_SPDIF |
410 CAPTURE_0_FROM_I2S_2, 420 CAPTURE_0_FROM_I2S_2 |
411 .dac_channels = 8, 421 AC97_FMIC_SWITCH,
422 .dac_channels_pcm = 8,
423 .dac_channels_mixer = 8,
412 .dac_volume_min = 127 - 60, 424 .dac_volume_min = 127 - 60,
413 .dac_volume_max = 127, 425 .dac_volume_max = 127,
414 .function_flags = OXYGEN_FUNCTION_2WIRE, 426 .function_flags = OXYGEN_FUNCTION_2WIRE,
427 .dac_mclks = OXYGEN_MCLKS(256, 128, 128),
428 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
415 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 429 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
416 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 430 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
417}; 431};
diff --git a/sound/pci/oxygen/xonar_dg.c b/sound/pci/oxygen/xonar_dg.c
new file mode 100644
index 000000000000..bc6eb58be380
--- /dev/null
+++ b/sound/pci/oxygen/xonar_dg.c
@@ -0,0 +1,608 @@
1/*
2 * card driver for the Xonar DG
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
9 *
10 * This driver is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this driver; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19/*
20 * Xonar DG
21 * --------
22 *
23 * CMI8788:
24 *
25 * SPI 0 -> CS4245
26 *
27 * I²S 1 -> CS4245
28 * I²S 2 -> CS4361 (center/LFE)
29 * I²S 3 -> CS4361 (surround)
30 * I²S 4 -> CS4361 (front)
31 *
32 * GPIO 3 <- ?
33 * GPIO 4 <- headphone detect
34 * GPIO 5 -> route input jack to line-in (0) or mic-in (1)
35 * GPIO 6 -> route input jack to line-in (0) or mic-in (1)
36 * GPIO 7 -> enable rear headphone amp
37 * GPIO 8 -> enable output to speakers
38 *
39 * CS4245:
40 *
41 * input 1 <- aux
42 * input 2 <- front mic
43 * input 4 <- line/mic
44 * DAC out -> headphones
45 * aux out -> front panel headphones
46 */
47
48#include <linux/pci.h>
49#include <linux/delay.h>
50#include <sound/control.h>
51#include <sound/core.h>
52#include <sound/info.h>
53#include <sound/pcm.h>
54#include <sound/tlv.h>
55#include "oxygen.h"
56#include "xonar_dg.h"
57#include "cs4245.h"
58
59#define GPIO_MAGIC 0x0008
60#define GPIO_HP_DETECT 0x0010
61#define GPIO_INPUT_ROUTE 0x0060
62#define GPIO_HP_REAR 0x0080
63#define GPIO_OUTPUT_ENABLE 0x0100
64
65struct dg {
66 unsigned int output_sel;
67 s8 input_vol[4][2];
68 unsigned int input_sel;
69 u8 hp_vol_att;
70 u8 cs4245_regs[0x11];
71};
72
73static void cs4245_write(struct oxygen *chip, unsigned int reg, u8 value)
74{
75 struct dg *data = chip->model_data;
76
77 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
78 OXYGEN_SPI_DATA_LENGTH_3 |
79 OXYGEN_SPI_CLOCK_1280 |
80 (0 << OXYGEN_SPI_CODEC_SHIFT) |
81 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
82 CS4245_SPI_ADDRESS |
83 CS4245_SPI_WRITE |
84 (reg << 8) | value);
85 data->cs4245_regs[reg] = value;
86}
87
88static void cs4245_write_cached(struct oxygen *chip, unsigned int reg, u8 value)
89{
90 struct dg *data = chip->model_data;
91
92 if (value != data->cs4245_regs[reg])
93 cs4245_write(chip, reg, value);
94}
95
96static void cs4245_registers_init(struct oxygen *chip)
97{
98 struct dg *data = chip->model_data;
99
100 cs4245_write(chip, CS4245_POWER_CTRL, CS4245_PDN);
101 cs4245_write(chip, CS4245_DAC_CTRL_1,
102 data->cs4245_regs[CS4245_DAC_CTRL_1]);
103 cs4245_write(chip, CS4245_ADC_CTRL,
104 data->cs4245_regs[CS4245_ADC_CTRL]);
105 cs4245_write(chip, CS4245_SIGNAL_SEL,
106 data->cs4245_regs[CS4245_SIGNAL_SEL]);
107 cs4245_write(chip, CS4245_PGA_B_CTRL,
108 data->cs4245_regs[CS4245_PGA_B_CTRL]);
109 cs4245_write(chip, CS4245_PGA_A_CTRL,
110 data->cs4245_regs[CS4245_PGA_A_CTRL]);
111 cs4245_write(chip, CS4245_ANALOG_IN,
112 data->cs4245_regs[CS4245_ANALOG_IN]);
113 cs4245_write(chip, CS4245_DAC_A_CTRL,
114 data->cs4245_regs[CS4245_DAC_A_CTRL]);
115 cs4245_write(chip, CS4245_DAC_B_CTRL,
116 data->cs4245_regs[CS4245_DAC_B_CTRL]);
117 cs4245_write(chip, CS4245_DAC_CTRL_2,
118 CS4245_DAC_SOFT | CS4245_DAC_ZERO | CS4245_INVERT_DAC);
119 cs4245_write(chip, CS4245_INT_MASK, 0);
120 cs4245_write(chip, CS4245_POWER_CTRL, 0);
121}
122
123static void cs4245_init(struct oxygen *chip)
124{
125 struct dg *data = chip->model_data;
126
127 data->cs4245_regs[CS4245_DAC_CTRL_1] =
128 CS4245_DAC_FM_SINGLE | CS4245_DAC_DIF_LJUST;
129 data->cs4245_regs[CS4245_ADC_CTRL] =
130 CS4245_ADC_FM_SINGLE | CS4245_ADC_DIF_LJUST;
131 data->cs4245_regs[CS4245_SIGNAL_SEL] =
132 CS4245_A_OUT_SEL_HIZ | CS4245_ASYNCH;
133 data->cs4245_regs[CS4245_PGA_B_CTRL] = 0;
134 data->cs4245_regs[CS4245_PGA_A_CTRL] = 0;
135 data->cs4245_regs[CS4245_ANALOG_IN] =
136 CS4245_PGA_SOFT | CS4245_PGA_ZERO | CS4245_SEL_INPUT_4;
137 data->cs4245_regs[CS4245_DAC_A_CTRL] = 0;
138 data->cs4245_regs[CS4245_DAC_B_CTRL] = 0;
139 cs4245_registers_init(chip);
140 snd_component_add(chip->card, "CS4245");
141}
142
143static void dg_output_enable(struct oxygen *chip)
144{
145 msleep(2500);
146 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
147}
148
149static void dg_init(struct oxygen *chip)
150{
151 struct dg *data = chip->model_data;
152
153 data->output_sel = 0;
154 data->input_sel = 3;
155 data->hp_vol_att = 2 * 16;
156
157 cs4245_init(chip);
158
159 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
160 GPIO_MAGIC | GPIO_HP_DETECT);
161 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
162 GPIO_INPUT_ROUTE | GPIO_HP_REAR | GPIO_OUTPUT_ENABLE);
163 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
164 GPIO_INPUT_ROUTE | GPIO_HP_REAR);
165 dg_output_enable(chip);
166}
167
168static void dg_cleanup(struct oxygen *chip)
169{
170 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
171}
172
173static void dg_suspend(struct oxygen *chip)
174{
175 dg_cleanup(chip);
176}
177
178static void dg_resume(struct oxygen *chip)
179{
180 cs4245_registers_init(chip);
181 dg_output_enable(chip);
182}
183
184static void set_cs4245_dac_params(struct oxygen *chip,
185 struct snd_pcm_hw_params *params)
186{
187 struct dg *data = chip->model_data;
188 u8 value;
189
190 value = data->cs4245_regs[CS4245_DAC_CTRL_1] & ~CS4245_DAC_FM_MASK;
191 if (params_rate(params) <= 50000)
192 value |= CS4245_DAC_FM_SINGLE;
193 else if (params_rate(params) <= 100000)
194 value |= CS4245_DAC_FM_DOUBLE;
195 else
196 value |= CS4245_DAC_FM_QUAD;
197 cs4245_write_cached(chip, CS4245_DAC_CTRL_1, value);
198}
199
200static void set_cs4245_adc_params(struct oxygen *chip,
201 struct snd_pcm_hw_params *params)
202{
203 struct dg *data = chip->model_data;
204 u8 value;
205
206 value = data->cs4245_regs[CS4245_ADC_CTRL] & ~CS4245_ADC_FM_MASK;
207 if (params_rate(params) <= 50000)
208 value |= CS4245_ADC_FM_SINGLE;
209 else if (params_rate(params) <= 100000)
210 value |= CS4245_ADC_FM_DOUBLE;
211 else
212 value |= CS4245_ADC_FM_QUAD;
213 cs4245_write_cached(chip, CS4245_ADC_CTRL, value);
214}
215
216static inline unsigned int shift_bits(unsigned int value,
217 unsigned int shift_from,
218 unsigned int shift_to,
219 unsigned int mask)
220{
221 if (shift_from < shift_to)
222 return (value << (shift_to - shift_from)) & mask;
223 else
224 return (value >> (shift_from - shift_to)) & mask;
225}
226
227static unsigned int adjust_dg_dac_routing(struct oxygen *chip,
228 unsigned int play_routing)
229{
230 return (play_routing & OXYGEN_PLAY_DAC0_SOURCE_MASK) |
231 shift_bits(play_routing,
232 OXYGEN_PLAY_DAC2_SOURCE_SHIFT,
233 OXYGEN_PLAY_DAC1_SOURCE_SHIFT,
234 OXYGEN_PLAY_DAC1_SOURCE_MASK) |
235 shift_bits(play_routing,
236 OXYGEN_PLAY_DAC1_SOURCE_SHIFT,
237 OXYGEN_PLAY_DAC2_SOURCE_SHIFT,
238 OXYGEN_PLAY_DAC2_SOURCE_MASK) |
239 shift_bits(play_routing,
240 OXYGEN_PLAY_DAC0_SOURCE_SHIFT,
241 OXYGEN_PLAY_DAC3_SOURCE_SHIFT,
242 OXYGEN_PLAY_DAC3_SOURCE_MASK);
243}
244
245static int output_switch_info(struct snd_kcontrol *ctl,
246 struct snd_ctl_elem_info *info)
247{
248 static const char *const names[3] = {
249 "Speakers", "Headphones", "FP Headphones"
250 };
251
252 return snd_ctl_enum_info(info, 1, 3, names);
253}
254
255static int output_switch_get(struct snd_kcontrol *ctl,
256 struct snd_ctl_elem_value *value)
257{
258 struct oxygen *chip = ctl->private_data;
259 struct dg *data = chip->model_data;
260
261 mutex_lock(&chip->mutex);
262 value->value.enumerated.item[0] = data->output_sel;
263 mutex_unlock(&chip->mutex);
264 return 0;
265}
266
267static int output_switch_put(struct snd_kcontrol *ctl,
268 struct snd_ctl_elem_value *value)
269{
270 struct oxygen *chip = ctl->private_data;
271 struct dg *data = chip->model_data;
272 u8 reg;
273 int changed;
274
275 if (value->value.enumerated.item[0] > 2)
276 return -EINVAL;
277
278 mutex_lock(&chip->mutex);
279 changed = value->value.enumerated.item[0] != data->output_sel;
280 if (changed) {
281 data->output_sel = value->value.enumerated.item[0];
282
283 reg = data->cs4245_regs[CS4245_SIGNAL_SEL] &
284 ~CS4245_A_OUT_SEL_MASK;
285 reg |= data->output_sel == 2 ?
286 CS4245_A_OUT_SEL_DAC : CS4245_A_OUT_SEL_HIZ;
287 cs4245_write_cached(chip, CS4245_SIGNAL_SEL, reg);
288
289 cs4245_write_cached(chip, CS4245_DAC_A_CTRL,
290 data->output_sel ? data->hp_vol_att : 0);
291 cs4245_write_cached(chip, CS4245_DAC_B_CTRL,
292 data->output_sel ? data->hp_vol_att : 0);
293
294 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
295 data->output_sel == 1 ? GPIO_HP_REAR : 0,
296 GPIO_HP_REAR);
297 }
298 mutex_unlock(&chip->mutex);
299 return changed;
300}
301
302static int hp_volume_offset_info(struct snd_kcontrol *ctl,
303 struct snd_ctl_elem_info *info)
304{
305 static const char *const names[3] = {
306 "< 64 ohms", "64-150 ohms", "150-300 ohms"
307 };
308
309 return snd_ctl_enum_info(info, 1, 3, names);
310}
311
312static int hp_volume_offset_get(struct snd_kcontrol *ctl,
313 struct snd_ctl_elem_value *value)
314{
315 struct oxygen *chip = ctl->private_data;
316 struct dg *data = chip->model_data;
317
318 mutex_lock(&chip->mutex);
319 if (data->hp_vol_att > 2 * 7)
320 value->value.enumerated.item[0] = 0;
321 else if (data->hp_vol_att > 0)
322 value->value.enumerated.item[0] = 1;
323 else
324 value->value.enumerated.item[0] = 2;
325 mutex_unlock(&chip->mutex);
326 return 0;
327}
328
329static int hp_volume_offset_put(struct snd_kcontrol *ctl,
330 struct snd_ctl_elem_value *value)
331{
332 static const s8 atts[3] = { 2 * 16, 2 * 7, 0 };
333 struct oxygen *chip = ctl->private_data;
334 struct dg *data = chip->model_data;
335 s8 att;
336 int changed;
337
338 if (value->value.enumerated.item[0] > 2)
339 return -EINVAL;
340 att = atts[value->value.enumerated.item[0]];
341 mutex_lock(&chip->mutex);
342 changed = att != data->hp_vol_att;
343 if (changed) {
344 data->hp_vol_att = att;
345 if (data->output_sel) {
346 cs4245_write_cached(chip, CS4245_DAC_A_CTRL, att);
347 cs4245_write_cached(chip, CS4245_DAC_B_CTRL, att);
348 }
349 }
350 mutex_unlock(&chip->mutex);
351 return changed;
352}
353
354static int input_vol_info(struct snd_kcontrol *ctl,
355 struct snd_ctl_elem_info *info)
356{
357 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
358 info->count = 2;
359 info->value.integer.min = 2 * -12;
360 info->value.integer.max = 2 * 12;
361 return 0;
362}
363
364static int input_vol_get(struct snd_kcontrol *ctl,
365 struct snd_ctl_elem_value *value)
366{
367 struct oxygen *chip = ctl->private_data;
368 struct dg *data = chip->model_data;
369 unsigned int idx = ctl->private_value;
370
371 mutex_lock(&chip->mutex);
372 value->value.integer.value[0] = data->input_vol[idx][0];
373 value->value.integer.value[1] = data->input_vol[idx][1];
374 mutex_unlock(&chip->mutex);
375 return 0;
376}
377
378static int input_vol_put(struct snd_kcontrol *ctl,
379 struct snd_ctl_elem_value *value)
380{
381 struct oxygen *chip = ctl->private_data;
382 struct dg *data = chip->model_data;
383 unsigned int idx = ctl->private_value;
384 int changed = 0;
385
386 if (value->value.integer.value[0] < 2 * -12 ||
387 value->value.integer.value[0] > 2 * 12 ||
388 value->value.integer.value[1] < 2 * -12 ||
389 value->value.integer.value[1] > 2 * 12)
390 return -EINVAL;
391 mutex_lock(&chip->mutex);
392 changed = data->input_vol[idx][0] != value->value.integer.value[0] ||
393 data->input_vol[idx][1] != value->value.integer.value[1];
394 if (changed) {
395 data->input_vol[idx][0] = value->value.integer.value[0];
396 data->input_vol[idx][1] = value->value.integer.value[1];
397 if (idx == data->input_sel) {
398 cs4245_write_cached(chip, CS4245_PGA_A_CTRL,
399 data->input_vol[idx][0]);
400 cs4245_write_cached(chip, CS4245_PGA_B_CTRL,
401 data->input_vol[idx][1]);
402 }
403 }
404 mutex_unlock(&chip->mutex);
405 return changed;
406}
407
408static DECLARE_TLV_DB_SCALE(cs4245_pga_db_scale, -1200, 50, 0);
409
410static int input_sel_info(struct snd_kcontrol *ctl,
411 struct snd_ctl_elem_info *info)
412{
413 static const char *const names[4] = {
414 "Mic", "Aux", "Front Mic", "Line"
415 };
416
417 return snd_ctl_enum_info(info, 1, 4, names);
418}
419
420static int input_sel_get(struct snd_kcontrol *ctl,
421 struct snd_ctl_elem_value *value)
422{
423 struct oxygen *chip = ctl->private_data;
424 struct dg *data = chip->model_data;
425
426 mutex_lock(&chip->mutex);
427 value->value.enumerated.item[0] = data->input_sel;
428 mutex_unlock(&chip->mutex);
429 return 0;
430}
431
432static int input_sel_put(struct snd_kcontrol *ctl,
433 struct snd_ctl_elem_value *value)
434{
435 static const u8 sel_values[4] = {
436 CS4245_SEL_MIC,
437 CS4245_SEL_INPUT_1,
438 CS4245_SEL_INPUT_2,
439 CS4245_SEL_INPUT_4
440 };
441 struct oxygen *chip = ctl->private_data;
442 struct dg *data = chip->model_data;
443 int changed;
444
445 if (value->value.enumerated.item[0] > 3)
446 return -EINVAL;
447
448 mutex_lock(&chip->mutex);
449 changed = value->value.enumerated.item[0] != data->input_sel;
450 if (changed) {
451 data->input_sel = value->value.enumerated.item[0];
452
453 cs4245_write(chip, CS4245_ANALOG_IN,
454 (data->cs4245_regs[CS4245_ANALOG_IN] &
455 ~CS4245_SEL_MASK) |
456 sel_values[data->input_sel]);
457
458 cs4245_write_cached(chip, CS4245_PGA_A_CTRL,
459 data->input_vol[data->input_sel][0]);
460 cs4245_write_cached(chip, CS4245_PGA_B_CTRL,
461 data->input_vol[data->input_sel][1]);
462
463 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
464 data->input_sel ? 0 : GPIO_INPUT_ROUTE,
465 GPIO_INPUT_ROUTE);
466 }
467 mutex_unlock(&chip->mutex);
468 return changed;
469}
470
471static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
472{
473 static const char *const names[2] = { "Active", "Frozen" };
474
475 return snd_ctl_enum_info(info, 1, 2, names);
476}
477
478static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
479{
480 struct oxygen *chip = ctl->private_data;
481 struct dg *data = chip->model_data;
482
483 value->value.enumerated.item[0] =
484 !!(data->cs4245_regs[CS4245_ADC_CTRL] & CS4245_HPF_FREEZE);
485 return 0;
486}
487
488static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
489{
490 struct oxygen *chip = ctl->private_data;
491 struct dg *data = chip->model_data;
492 u8 reg;
493 int changed;
494
495 mutex_lock(&chip->mutex);
496 reg = data->cs4245_regs[CS4245_ADC_CTRL] & ~CS4245_HPF_FREEZE;
497 if (value->value.enumerated.item[0])
498 reg |= CS4245_HPF_FREEZE;
499 changed = reg != data->cs4245_regs[CS4245_ADC_CTRL];
500 if (changed)
501 cs4245_write(chip, CS4245_ADC_CTRL, reg);
502 mutex_unlock(&chip->mutex);
503 return changed;
504}
505
506#define INPUT_VOLUME(xname, index) { \
507 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
508 .name = xname, \
509 .info = input_vol_info, \
510 .get = input_vol_get, \
511 .put = input_vol_put, \
512 .tlv = { .p = cs4245_pga_db_scale }, \
513 .private_value = index, \
514}
515static const struct snd_kcontrol_new dg_controls[] = {
516 {
517 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
518 .name = "Analog Output Playback Enum",
519 .info = output_switch_info,
520 .get = output_switch_get,
521 .put = output_switch_put,
522 },
523 {
524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
525 .name = "Headphones Impedance Playback Enum",
526 .info = hp_volume_offset_info,
527 .get = hp_volume_offset_get,
528 .put = hp_volume_offset_put,
529 },
530 INPUT_VOLUME("Mic Capture Volume", 0),
531 INPUT_VOLUME("Aux Capture Volume", 1),
532 INPUT_VOLUME("Front Mic Capture Volume", 2),
533 INPUT_VOLUME("Line Capture Volume", 3),
534 {
535 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
536 .name = "Capture Source",
537 .info = input_sel_info,
538 .get = input_sel_get,
539 .put = input_sel_put,
540 },
541 {
542 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
543 .name = "ADC High-pass Filter Capture Enum",
544 .info = hpf_info,
545 .get = hpf_get,
546 .put = hpf_put,
547 },
548};
549
550static int dg_control_filter(struct snd_kcontrol_new *template)
551{
552 if (!strncmp(template->name, "Master Playback ", 16))
553 return 1;
554 return 0;
555}
556
557static int dg_mixer_init(struct oxygen *chip)
558{
559 unsigned int i;
560 int err;
561
562 for (i = 0; i < ARRAY_SIZE(dg_controls); ++i) {
563 err = snd_ctl_add(chip->card,
564 snd_ctl_new1(&dg_controls[i], chip));
565 if (err < 0)
566 return err;
567 }
568 return 0;
569}
570
571static void dump_cs4245_registers(struct oxygen *chip,
572 struct snd_info_buffer *buffer)
573{
574 struct dg *data = chip->model_data;
575 unsigned int i;
576
577 snd_iprintf(buffer, "\nCS4245:");
578 for (i = 1; i <= 0x10; ++i)
579 snd_iprintf(buffer, " %02x", data->cs4245_regs[i]);
580 snd_iprintf(buffer, "\n");
581}
582
583struct oxygen_model model_xonar_dg = {
584 .shortname = "Xonar DG",
585 .longname = "C-Media Oxygen HD Audio",
586 .chip = "CMI8786",
587 .init = dg_init,
588 .control_filter = dg_control_filter,
589 .mixer_init = dg_mixer_init,
590 .cleanup = dg_cleanup,
591 .suspend = dg_suspend,
592 .resume = dg_resume,
593 .set_dac_params = set_cs4245_dac_params,
594 .set_adc_params = set_cs4245_adc_params,
595 .adjust_dac_routing = adjust_dg_dac_routing,
596 .dump_registers = dump_cs4245_registers,
597 .model_data_size = sizeof(struct dg),
598 .device_config = PLAYBACK_0_TO_I2S |
599 PLAYBACK_1_TO_SPDIF |
600 CAPTURE_0_FROM_I2S_2,
601 .dac_channels_pcm = 6,
602 .dac_channels_mixer = 0,
603 .function_flags = OXYGEN_FUNCTION_SPI,
604 .dac_mclks = OXYGEN_MCLKS(256, 128, 128),
605 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
606 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
607 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
608};
diff --git a/sound/pci/oxygen/xonar_dg.h b/sound/pci/oxygen/xonar_dg.h
new file mode 100644
index 000000000000..5688d78609a9
--- /dev/null
+++ b/sound/pci/oxygen/xonar_dg.h
@@ -0,0 +1,8 @@
1#ifndef XONAR_DG_H_INCLUDED
2#define XONAR_DG_H_INCLUDED
3
4#include "oxygen.h"
5
6extern struct oxygen_model model_xonar_dg;
7
8#endif
diff --git a/sound/pci/oxygen/xonar_hdmi.c b/sound/pci/oxygen/xonar_hdmi.c
index b12db1f1cea9..136dac6a3964 100644
--- a/sound/pci/oxygen/xonar_hdmi.c
+++ b/sound/pci/oxygen/xonar_hdmi.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * helper functions for HDMI models (Xonar HDAV1.3) 2 * helper functions for HDMI models (Xonar HDAV1.3/HDAV1.3 Slim)
3 * 3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * 5 *
diff --git a/sound/pci/oxygen/xonar_lib.c b/sound/pci/oxygen/xonar_lib.c
index b3ff71316653..0ebe7f5916f9 100644
--- a/sound/pci/oxygen/xonar_lib.c
+++ b/sound/pci/oxygen/xonar_lib.c
@@ -104,9 +104,10 @@ int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
104{ 104{
105 struct oxygen *chip = ctl->private_data; 105 struct oxygen *chip = ctl->private_data;
106 u16 bit = ctl->private_value; 106 u16 bit = ctl->private_value;
107 bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT;
107 108
108 value->value.integer.value[0] = 109 value->value.integer.value[0] =
109 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit); 110 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit) ^ invert;
110 return 0; 111 return 0;
111} 112}
112 113
@@ -115,12 +116,13 @@ int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
115{ 116{
116 struct oxygen *chip = ctl->private_data; 117 struct oxygen *chip = ctl->private_data;
117 u16 bit = ctl->private_value; 118 u16 bit = ctl->private_value;
119 bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT;
118 u16 old_bits, new_bits; 120 u16 old_bits, new_bits;
119 int changed; 121 int changed;
120 122
121 spin_lock_irq(&chip->reg_lock); 123 spin_lock_irq(&chip->reg_lock);
122 old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); 124 old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
123 if (value->value.integer.value[0]) 125 if (!!value->value.integer.value[0] ^ invert)
124 new_bits = old_bits | bit; 126 new_bits = old_bits | bit;
125 else 127 else
126 new_bits = old_bits & ~bit; 128 new_bits = old_bits & ~bit;
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index ba18fb546b4f..54cad38ec30a 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -22,20 +22,26 @@
22 * 22 *
23 * CMI8788: 23 * CMI8788:
24 * 24 *
25 * SPI 0 -> 1st PCM1796 (front) 25 * SPI 0 -> 1st PCM1796 (front)
26 * SPI 1 -> 2nd PCM1796 (surround) 26 * SPI 1 -> 2nd PCM1796 (surround)
27 * SPI 2 -> 3rd PCM1796 (center/LFE) 27 * SPI 2 -> 3rd PCM1796 (center/LFE)
28 * SPI 4 -> 4th PCM1796 (back) 28 * SPI 4 -> 4th PCM1796 (back)
29 * 29 *
30 * GPIO 2 -> M0 of CS5381 30 * GPIO 2 -> M0 of CS5381
31 * GPIO 3 -> M1 of CS5381 31 * GPIO 3 -> M1 of CS5381
32 * GPIO 5 <- external power present (D2X only) 32 * GPIO 5 <- external power present (D2X only)
33 * GPIO 7 -> ALT 33 * GPIO 7 -> ALT
34 * GPIO 8 -> enable output to speakers 34 * GPIO 8 -> enable output to speakers
35 * 35 *
36 * CM9780: 36 * CM9780:
37 * 37 *
38 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input 38 * LINE_OUT -> input of ADC
39 *
40 * AUX_IN <- aux
41 * VIDEO_IN <- CD
42 * FMIC_IN <- mic
43 *
44 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
39 */ 45 */
40 46
41/* 47/*
@@ -44,52 +50,53 @@
44 * 50 *
45 * CMI8788: 51 * CMI8788:
46 * 52 *
47 * I²C <-> PCM1796 (front) 53 * I²C <-> PCM1796 (addr 1001100) (front)
48 * 54 *
49 * GPI 0 <- external power present 55 * GPI 0 <- external power present
50 * 56 *
51 * GPIO 0 -> enable output to speakers 57 * GPIO 0 -> enable HDMI (0) or speaker (1) output
52 * GPIO 2 -> M0 of CS5381 58 * GPIO 2 -> M0 of CS5381
53 * GPIO 3 -> M1 of CS5381 59 * GPIO 3 -> M1 of CS5381
54 * GPIO 8 -> route input jack to line-in (0) or mic-in (1) 60 * GPIO 4 <- daughterboard detection
61 * GPIO 5 <- daughterboard detection
62 * GPIO 6 -> ?
63 * GPIO 7 -> ?
64 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
55 * 65 *
56 * TXD -> HDMI controller 66 * UART <-> HDMI controller
57 * RXD <- HDMI controller
58 *
59 * PCM1796 front: AD1,0 <- 0,0
60 * 67 *
61 * CM9780: 68 * CM9780:
62 * 69 *
63 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input 70 * LINE_OUT -> input of ADC
71 *
72 * AUX_IN <- aux
73 * CD_IN <- CD
74 * MIC_IN <- mic
75 *
76 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
64 * 77 *
65 * no daughterboard 78 * no daughterboard
66 * ---------------- 79 * ----------------
67 * 80 *
68 * GPIO 4 <- 1 81 * GPIO 4 <- 1
69 * 82 *
70 * H6 daughterboard 83 * H6 daughterboard
71 * ---------------- 84 * ----------------
72 * 85 *
73 * GPIO 4 <- 0 86 * GPIO 4 <- 0
74 * GPIO 5 <- 0 87 * GPIO 5 <- 0
75 *
76 * I²C <-> PCM1796 (surround)
77 * <-> PCM1796 (center/LFE)
78 * <-> PCM1796 (back)
79 * 88 *
80 * PCM1796 surround: AD1,0 <- 0,1 89 * I²C <-> PCM1796 (addr 1001101) (surround)
81 * PCM1796 center/LFE: AD1,0 <- 1,0 90 * <-> PCM1796 (addr 1001110) (center/LFE)
82 * PCM1796 back: AD1,0 <- 1,1 91 * <-> PCM1796 (addr 1001111) (back)
83 * 92 *
84 * unknown daughterboard 93 * unknown daughterboard
85 * --------------------- 94 * ---------------------
86 * 95 *
87 * GPIO 4 <- 0 96 * GPIO 4 <- 0
88 * GPIO 5 <- 1 97 * GPIO 5 <- 1
89 *
90 * I²C <-> CS4362A (surround, center/LFE, back)
91 * 98 *
92 * CS4362A: AD0 <- 0 99 * I²C <-> CS4362A (addr 0011000) (surround, center/LFE, back)
93 */ 100 */
94 101
95/* 102/*
@@ -98,32 +105,35 @@
98 * 105 *
99 * CMI8788: 106 * CMI8788:
100 * 107 *
101 * I²C <-> PCM1792A 108 * I²C <-> PCM1792A (addr 1001100)
102 * <-> CS2000 (ST only) 109 * <-> CS2000 (addr 1001110) (ST only)
103 * 110 *
104 * ADC1 MCLK -> REF_CLK of CS2000 (ST only) 111 * ADC1 MCLK -> REF_CLK of CS2000 (ST only)
105 * 112 *
106 * GPI 0 <- external power present (STX only) 113 * GPI 0 <- external power present (STX only)
107 * 114 *
108 * GPIO 0 -> enable output to speakers 115 * GPIO 0 -> enable output to speakers
109 * GPIO 1 -> route HP to front panel (0) or rear jack (1) 116 * GPIO 1 -> route HP to front panel (0) or rear jack (1)
110 * GPIO 2 -> M0 of CS5381 117 * GPIO 2 -> M0 of CS5381
111 * GPIO 3 -> M1 of CS5381 118 * GPIO 3 -> M1 of CS5381
112 * GPIO 7 -> route output to speaker jacks (0) or HP (1) 119 * GPIO 4 <- daughterboard detection
113 * GPIO 8 -> route input jack to line-in (0) or mic-in (1) 120 * GPIO 5 <- daughterboard detection
121 * GPIO 6 -> ?
122 * GPIO 7 -> route output to speaker jacks (0) or HP (1)
123 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
114 * 124 *
115 * PCM1792A: 125 * PCM1792A:
116 * 126 *
117 * AD1,0 <- 0,0 127 * SCK <- CLK_OUT of CS2000 (ST only)
118 * SCK <- CLK_OUT of CS2000 (ST only)
119 * 128 *
120 * CS2000: 129 * CM9780:
121 * 130 *
122 * AD0 <- 0 131 * LINE_OUT -> input of ADC
123 * 132 *
124 * CM9780: 133 * AUX_IN <- aux
134 * MIC_IN <- mic
125 * 135 *
126 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input 136 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
127 * 137 *
128 * H6 daughterboard 138 * H6 daughterboard
129 * ---------------- 139 * ----------------
@@ -132,12 +142,49 @@
132 * GPIO 5 <- 0 142 * GPIO 5 <- 0
133 */ 143 */
134 144
145/*
146 * Xonar Xense
147 * -----------
148 *
149 * CMI8788:
150 *
151 * I²C <-> PCM1796 (addr 1001100) (front)
152 * <-> CS4362A (addr 0011000) (surround, center/LFE, back)
153 * <-> CS2000 (addr 1001110)
154 *
155 * ADC1 MCLK -> REF_CLK of CS2000
156 *
157 * GPI 0 <- external power present
158 *
159 * GPIO 0 -> enable output
160 * GPIO 1 -> route HP to front panel (0) or rear jack (1)
161 * GPIO 2 -> M0 of CS5381
162 * GPIO 3 -> M1 of CS5381
163 * GPIO 4 -> enable output
164 * GPIO 5 -> enable output
165 * GPIO 6 -> ?
166 * GPIO 7 -> route output to HP (0) or speaker (1)
167 * GPIO 8 -> route input jack to mic-in (0) or line-in (1)
168 *
169 * CM9780:
170 *
171 * LINE_OUT -> input of ADC
172 *
173 * AUX_IN <- aux
174 * VIDEO_IN <- ?
175 * FMIC_IN <- mic
176 *
177 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
178 * GPO 1 -> route mic-in from input jack (0) or front panel header (1)
179 */
180
135#include <linux/pci.h> 181#include <linux/pci.h>
136#include <linux/delay.h> 182#include <linux/delay.h>
137#include <linux/mutex.h> 183#include <linux/mutex.h>
138#include <sound/ac97_codec.h> 184#include <sound/ac97_codec.h>
139#include <sound/control.h> 185#include <sound/control.h>
140#include <sound/core.h> 186#include <sound/core.h>
187#include <sound/info.h>
141#include <sound/pcm.h> 188#include <sound/pcm.h>
142#include <sound/pcm_params.h> 189#include <sound/pcm_params.h>
143#include <sound/tlv.h> 190#include <sound/tlv.h>
@@ -155,12 +202,14 @@
155#define GPIO_INPUT_ROUTE 0x0100 202#define GPIO_INPUT_ROUTE 0x0100
156 203
157#define GPIO_HDAV_OUTPUT_ENABLE 0x0001 204#define GPIO_HDAV_OUTPUT_ENABLE 0x0001
205#define GPIO_HDAV_MAGIC 0x00c0
158 206
159#define GPIO_DB_MASK 0x0030 207#define GPIO_DB_MASK 0x0030
160#define GPIO_DB_H6 0x0000 208#define GPIO_DB_H6 0x0000
161 209
162#define GPIO_ST_OUTPUT_ENABLE 0x0001 210#define GPIO_ST_OUTPUT_ENABLE 0x0001
163#define GPIO_ST_HP_REAR 0x0002 211#define GPIO_ST_HP_REAR 0x0002
212#define GPIO_ST_MAGIC 0x0040
164#define GPIO_ST_HP 0x0080 213#define GPIO_ST_HP 0x0080
165 214
166#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */ 215#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */
@@ -174,11 +223,12 @@ struct xonar_pcm179x {
174 unsigned int dacs; 223 unsigned int dacs;
175 u8 pcm1796_regs[4][5]; 224 u8 pcm1796_regs[4][5];
176 unsigned int current_rate; 225 unsigned int current_rate;
177 bool os_128; 226 bool h6;
178 bool hp_active; 227 bool hp_active;
179 s8 hp_gain_offset; 228 s8 hp_gain_offset;
180 bool has_cs2000; 229 bool has_cs2000;
181 u8 cs2000_fun_cfg_1; 230 u8 cs2000_regs[0x1f];
231 bool broken_i2c;
182}; 232};
183 233
184struct xonar_hdav { 234struct xonar_hdav {
@@ -237,16 +287,14 @@ static void cs2000_write(struct oxygen *chip, u8 reg, u8 value)
237 struct xonar_pcm179x *data = chip->model_data; 287 struct xonar_pcm179x *data = chip->model_data;
238 288
239 oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value); 289 oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value);
240 if (reg == CS2000_FUN_CFG_1) 290 data->cs2000_regs[reg] = value;
241 data->cs2000_fun_cfg_1 = value;
242} 291}
243 292
244static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value) 293static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value)
245{ 294{
246 struct xonar_pcm179x *data = chip->model_data; 295 struct xonar_pcm179x *data = chip->model_data;
247 296
248 if (reg != CS2000_FUN_CFG_1 || 297 if (value != data->cs2000_regs[reg])
249 value != data->cs2000_fun_cfg_1)
250 cs2000_write(chip, reg, value); 298 cs2000_write(chip, reg, value);
251} 299}
252 300
@@ -256,6 +304,7 @@ static void pcm1796_registers_init(struct oxygen *chip)
256 unsigned int i; 304 unsigned int i;
257 s8 gain_offset; 305 s8 gain_offset;
258 306
307 msleep(1);
259 gain_offset = data->hp_active ? data->hp_gain_offset : 0; 308 gain_offset = data->hp_active ? data->hp_gain_offset : 0;
260 for (i = 0; i < data->dacs; ++i) { 309 for (i = 0; i < data->dacs; ++i) {
261 /* set ATLD before ATL/ATR */ 310 /* set ATLD before ATL/ATR */
@@ -270,6 +319,7 @@ static void pcm1796_registers_init(struct oxygen *chip)
270 pcm1796_write(chip, i, 20, 319 pcm1796_write(chip, i, 20,
271 data->pcm1796_regs[0][20 - PCM1796_REG_BASE]); 320 data->pcm1796_regs[0][20 - PCM1796_REG_BASE]);
272 pcm1796_write(chip, i, 21, 0); 321 pcm1796_write(chip, i, 21, 0);
322 gain_offset = 0;
273 } 323 }
274} 324}
275 325
@@ -278,10 +328,11 @@ static void pcm1796_init(struct oxygen *chip)
278 struct xonar_pcm179x *data = chip->model_data; 328 struct xonar_pcm179x *data = chip->model_data;
279 329
280 data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE | 330 data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE |
281 PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD; 331 PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
282 data->pcm1796_regs[0][19 - PCM1796_REG_BASE] = 332 data->pcm1796_regs[0][19 - PCM1796_REG_BASE] =
283 PCM1796_FLT_SHARP | PCM1796_ATS_1; 333 PCM1796_FLT_SHARP | PCM1796_ATS_1;
284 data->pcm1796_regs[0][20 - PCM1796_REG_BASE] = PCM1796_OS_64; 334 data->pcm1796_regs[0][20 - PCM1796_REG_BASE] =
335 data->h6 ? PCM1796_OS_64 : PCM1796_OS_128;
285 pcm1796_registers_init(chip); 336 pcm1796_registers_init(chip);
286 data->current_rate = 48000; 337 data->current_rate = 48000;
287} 338}
@@ -327,18 +378,20 @@ static void xonar_hdav_init(struct oxygen *chip)
327 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, 378 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
328 OXYGEN_2WIRE_LENGTH_8 | 379 OXYGEN_2WIRE_LENGTH_8 |
329 OXYGEN_2WIRE_INTERRUPT_MASK | 380 OXYGEN_2WIRE_INTERRUPT_MASK |
330 OXYGEN_2WIRE_SPEED_FAST); 381 OXYGEN_2WIRE_SPEED_STANDARD);
331 382
332 data->pcm179x.generic.anti_pop_delay = 100; 383 data->pcm179x.generic.anti_pop_delay = 100;
333 data->pcm179x.generic.output_enable_bit = GPIO_HDAV_OUTPUT_ENABLE; 384 data->pcm179x.generic.output_enable_bit = GPIO_HDAV_OUTPUT_ENABLE;
334 data->pcm179x.generic.ext_power_reg = OXYGEN_GPI_DATA; 385 data->pcm179x.generic.ext_power_reg = OXYGEN_GPI_DATA;
335 data->pcm179x.generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; 386 data->pcm179x.generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
336 data->pcm179x.generic.ext_power_bit = GPI_EXT_POWER; 387 data->pcm179x.generic.ext_power_bit = GPI_EXT_POWER;
337 data->pcm179x.dacs = chip->model.private_data ? 4 : 1; 388 data->pcm179x.dacs = chip->model.dac_channels_mixer / 2;
389 data->pcm179x.h6 = chip->model.dac_channels_mixer > 2;
338 390
339 pcm1796_init(chip); 391 pcm1796_init(chip);
340 392
341 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_INPUT_ROUTE); 393 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
394 GPIO_HDAV_MAGIC | GPIO_INPUT_ROUTE);
342 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE); 395 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE);
343 396
344 xonar_init_cs53x1(chip); 397 xonar_init_cs53x1(chip);
@@ -355,22 +408,22 @@ static void xonar_st_init_i2c(struct oxygen *chip)
355 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, 408 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
356 OXYGEN_2WIRE_LENGTH_8 | 409 OXYGEN_2WIRE_LENGTH_8 |
357 OXYGEN_2WIRE_INTERRUPT_MASK | 410 OXYGEN_2WIRE_INTERRUPT_MASK |
358 OXYGEN_2WIRE_SPEED_FAST); 411 OXYGEN_2WIRE_SPEED_STANDARD);
359} 412}
360 413
361static void xonar_st_init_common(struct oxygen *chip) 414static void xonar_st_init_common(struct oxygen *chip)
362{ 415{
363 struct xonar_pcm179x *data = chip->model_data; 416 struct xonar_pcm179x *data = chip->model_data;
364 417
365 data->generic.anti_pop_delay = 100;
366 data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE; 418 data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE;
367 data->dacs = chip->model.private_data ? 4 : 1; 419 data->dacs = chip->model.dac_channels_mixer / 2;
368 data->hp_gain_offset = 2*-18; 420 data->hp_gain_offset = 2*-18;
369 421
370 pcm1796_init(chip); 422 pcm1796_init(chip);
371 423
372 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 424 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
373 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP); 425 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR |
426 GPIO_ST_MAGIC | GPIO_ST_HP);
374 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, 427 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
375 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP); 428 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
376 429
@@ -399,22 +452,30 @@ static void cs2000_registers_init(struct oxygen *chip)
399 cs2000_write(chip, CS2000_RATIO_0 + 1, 0x10); 452 cs2000_write(chip, CS2000_RATIO_0 + 1, 0x10);
400 cs2000_write(chip, CS2000_RATIO_0 + 2, 0x00); 453 cs2000_write(chip, CS2000_RATIO_0 + 2, 0x00);
401 cs2000_write(chip, CS2000_RATIO_0 + 3, 0x00); 454 cs2000_write(chip, CS2000_RATIO_0 + 3, 0x00);
402 cs2000_write(chip, CS2000_FUN_CFG_1, data->cs2000_fun_cfg_1); 455 cs2000_write(chip, CS2000_FUN_CFG_1,
456 data->cs2000_regs[CS2000_FUN_CFG_1]);
403 cs2000_write(chip, CS2000_FUN_CFG_2, 0); 457 cs2000_write(chip, CS2000_FUN_CFG_2, 0);
404 cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2); 458 cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2);
459 msleep(3); /* PLL lock delay */
405} 460}
406 461
407static void xonar_st_init(struct oxygen *chip) 462static void xonar_st_init(struct oxygen *chip)
408{ 463{
409 struct xonar_pcm179x *data = chip->model_data; 464 struct xonar_pcm179x *data = chip->model_data;
410 465
466 data->generic.anti_pop_delay = 100;
467 data->h6 = chip->model.dac_channels_mixer > 2;
411 data->has_cs2000 = 1; 468 data->has_cs2000 = 1;
412 data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1; 469 data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1;
470 data->broken_i2c = true;
413 471
414 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, 472 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
415 OXYGEN_RATE_48000 | OXYGEN_I2S_FORMAT_I2S | 473 OXYGEN_RATE_48000 |
416 OXYGEN_I2S_MCLK_128 | OXYGEN_I2S_BITS_16 | 474 OXYGEN_I2S_FORMAT_I2S |
417 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 475 OXYGEN_I2S_MCLK(data->h6 ? MCLK_256 : MCLK_512) |
476 OXYGEN_I2S_BITS_16 |
477 OXYGEN_I2S_MASTER |
478 OXYGEN_I2S_BCLK_64);
418 479
419 xonar_st_init_i2c(chip); 480 xonar_st_init_i2c(chip);
420 cs2000_registers_init(chip); 481 cs2000_registers_init(chip);
@@ -428,6 +489,7 @@ static void xonar_stx_init(struct oxygen *chip)
428 struct xonar_pcm179x *data = chip->model_data; 489 struct xonar_pcm179x *data = chip->model_data;
429 490
430 xonar_st_init_i2c(chip); 491 xonar_st_init_i2c(chip);
492 data->generic.anti_pop_delay = 800;
431 data->generic.ext_power_reg = OXYGEN_GPI_DATA; 493 data->generic.ext_power_reg = OXYGEN_GPI_DATA;
432 data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; 494 data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
433 data->generic.ext_power_bit = GPI_EXT_POWER; 495 data->generic.ext_power_bit = GPI_EXT_POWER;
@@ -494,44 +556,16 @@ static void xonar_st_resume(struct oxygen *chip)
494 xonar_stx_resume(chip); 556 xonar_stx_resume(chip);
495} 557}
496 558
497static unsigned int mclk_from_rate(struct oxygen *chip, unsigned int rate)
498{
499 struct xonar_pcm179x *data = chip->model_data;
500
501 if (rate <= 32000)
502 return OXYGEN_I2S_MCLK_512;
503 else if (rate <= 48000 && data->os_128)
504 return OXYGEN_I2S_MCLK_512;
505 else if (rate <= 96000)
506 return OXYGEN_I2S_MCLK_256;
507 else
508 return OXYGEN_I2S_MCLK_128;
509}
510
511static unsigned int get_pcm1796_i2s_mclk(struct oxygen *chip,
512 unsigned int channel,
513 struct snd_pcm_hw_params *params)
514{
515 if (channel == PCM_MULTICH)
516 return mclk_from_rate(chip, params_rate(params));
517 else
518 return oxygen_default_i2s_mclk(chip, channel, params);
519}
520
521static void update_pcm1796_oversampling(struct oxygen *chip) 559static void update_pcm1796_oversampling(struct oxygen *chip)
522{ 560{
523 struct xonar_pcm179x *data = chip->model_data; 561 struct xonar_pcm179x *data = chip->model_data;
524 unsigned int i; 562 unsigned int i;
525 u8 reg; 563 u8 reg;
526 564
527 if (data->current_rate <= 32000) 565 if (data->current_rate <= 48000 && !data->h6)
528 reg = PCM1796_OS_128; 566 reg = PCM1796_OS_128;
529 else if (data->current_rate <= 48000 && data->os_128)
530 reg = PCM1796_OS_128;
531 else if (data->current_rate <= 96000 || data->os_128)
532 reg = PCM1796_OS_64;
533 else 567 else
534 reg = PCM1796_OS_32; 568 reg = PCM1796_OS_64;
535 for (i = 0; i < data->dacs; ++i) 569 for (i = 0; i < data->dacs; ++i)
536 pcm1796_write_cached(chip, i, 20, reg); 570 pcm1796_write_cached(chip, i, 20, reg);
537} 571}
@@ -541,6 +575,7 @@ static void set_pcm1796_params(struct oxygen *chip,
541{ 575{
542 struct xonar_pcm179x *data = chip->model_data; 576 struct xonar_pcm179x *data = chip->model_data;
543 577
578 msleep(1);
544 data->current_rate = params_rate(params); 579 data->current_rate = params_rate(params);
545 update_pcm1796_oversampling(chip); 580 update_pcm1796_oversampling(chip);
546} 581}
@@ -557,6 +592,7 @@ static void update_pcm1796_volume(struct oxygen *chip)
557 + gain_offset); 592 + gain_offset);
558 pcm1796_write_cached(chip, i, 17, chip->dac_volume[i * 2 + 1] 593 pcm1796_write_cached(chip, i, 17, chip->dac_volume[i * 2 + 1]
559 + gain_offset); 594 + gain_offset);
595 gain_offset = 0;
560 } 596 }
561} 597}
562 598
@@ -566,7 +602,7 @@ static void update_pcm1796_mute(struct oxygen *chip)
566 unsigned int i; 602 unsigned int i;
567 u8 value; 603 u8 value;
568 604
569 value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD; 605 value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
570 if (chip->dac_mute) 606 if (chip->dac_mute)
571 value |= PCM1796_MUTE; 607 value |= PCM1796_MUTE;
572 for (i = 0; i < data->dacs; ++i) 608 for (i = 0; i < data->dacs; ++i)
@@ -579,45 +615,35 @@ static void update_cs2000_rate(struct oxygen *chip, unsigned int rate)
579 u8 rate_mclk, reg; 615 u8 rate_mclk, reg;
580 616
581 switch (rate) { 617 switch (rate) {
582 /* XXX Why is the I2S A MCLK half the actual I2S MCLK? */
583 case 32000: 618 case 32000:
584 rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256;
585 break;
586 case 44100:
587 if (data->os_128)
588 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256;
589 else
590 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_128;
591 break;
592 default: /* 48000 */
593 if (data->os_128)
594 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256;
595 else
596 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_128;
597 break;
598 case 64000: 619 case 64000:
599 rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256; 620 rate_mclk = OXYGEN_RATE_32000;
600 break; 621 break;
622 case 44100:
601 case 88200: 623 case 88200:
602 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256;
603 break;
604 case 96000:
605 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256;
606 break;
607 case 176400: 624 case 176400:
608 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; 625 rate_mclk = OXYGEN_RATE_44100;
609 break; 626 break;
627 default:
628 case 48000:
629 case 96000:
610 case 192000: 630 case 192000:
611 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; 631 rate_mclk = OXYGEN_RATE_48000;
612 break; 632 break;
613 } 633 }
614 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk, 634
615 OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK); 635 if (rate <= 96000 && (rate > 48000 || data->h6)) {
616 if ((rate_mclk & OXYGEN_I2S_MCLK_MASK) <= OXYGEN_I2S_MCLK_128) 636 rate_mclk |= OXYGEN_I2S_MCLK(MCLK_256);
617 reg = CS2000_REF_CLK_DIV_1; 637 reg = CS2000_REF_CLK_DIV_1;
618 else 638 } else {
639 rate_mclk |= OXYGEN_I2S_MCLK(MCLK_512);
619 reg = CS2000_REF_CLK_DIV_2; 640 reg = CS2000_REF_CLK_DIV_2;
641 }
642
643 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk,
644 OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK);
620 cs2000_write_cached(chip, CS2000_FUN_CFG_1, reg); 645 cs2000_write_cached(chip, CS2000_FUN_CFG_1, reg);
646 msleep(3); /* PLL lock delay */
621} 647}
622 648
623static void set_st_params(struct oxygen *chip, 649static void set_st_params(struct oxygen *chip,
@@ -652,13 +678,7 @@ static int rolloff_info(struct snd_kcontrol *ctl,
652 "Sharp Roll-off", "Slow Roll-off" 678 "Sharp Roll-off", "Slow Roll-off"
653 }; 679 };
654 680
655 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 681 return snd_ctl_enum_info(info, 1, 2, names);
656 info->count = 1;
657 info->value.enumerated.items = 2;
658 if (info->value.enumerated.item >= 2)
659 info->value.enumerated.item = 1;
660 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
661 return 0;
662} 682}
663 683
664static int rolloff_get(struct snd_kcontrol *ctl, 684static int rolloff_get(struct snd_kcontrol *ctl,
@@ -706,57 +726,13 @@ static const struct snd_kcontrol_new rolloff_control = {
706 .put = rolloff_put, 726 .put = rolloff_put,
707}; 727};
708 728
709static int os_128_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) 729static const struct snd_kcontrol_new hdav_hdmi_control = {
710{
711 static const char *const names[2] = { "64x", "128x" };
712
713 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
714 info->count = 1;
715 info->value.enumerated.items = 2;
716 if (info->value.enumerated.item >= 2)
717 info->value.enumerated.item = 1;
718 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
719 return 0;
720}
721
722static int os_128_get(struct snd_kcontrol *ctl,
723 struct snd_ctl_elem_value *value)
724{
725 struct oxygen *chip = ctl->private_data;
726 struct xonar_pcm179x *data = chip->model_data;
727
728 value->value.enumerated.item[0] = data->os_128;
729 return 0;
730}
731
732static int os_128_put(struct snd_kcontrol *ctl,
733 struct snd_ctl_elem_value *value)
734{
735 struct oxygen *chip = ctl->private_data;
736 struct xonar_pcm179x *data = chip->model_data;
737 int changed;
738
739 mutex_lock(&chip->mutex);
740 changed = value->value.enumerated.item[0] != data->os_128;
741 if (changed) {
742 data->os_128 = value->value.enumerated.item[0];
743 if (data->has_cs2000)
744 update_cs2000_rate(chip, data->current_rate);
745 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
746 mclk_from_rate(chip, data->current_rate),
747 OXYGEN_I2S_MCLK_MASK);
748 update_pcm1796_oversampling(chip);
749 }
750 mutex_unlock(&chip->mutex);
751 return changed;
752}
753
754static const struct snd_kcontrol_new os_128_control = {
755 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 730 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
756 .name = "DAC Oversampling Playback Enum", 731 .name = "HDMI Playback Switch",
757 .info = os_128_info, 732 .info = snd_ctl_boolean_mono_info,
758 .get = os_128_get, 733 .get = xonar_gpio_bit_switch_get,
759 .put = os_128_put, 734 .put = xonar_gpio_bit_switch_put,
735 .private_value = GPIO_HDAV_OUTPUT_ENABLE | XONAR_GPIO_BIT_INVERT,
760}; 736};
761 737
762static int st_output_switch_info(struct snd_kcontrol *ctl, 738static int st_output_switch_info(struct snd_kcontrol *ctl,
@@ -766,13 +742,7 @@ static int st_output_switch_info(struct snd_kcontrol *ctl,
766 "Speakers", "Headphones", "FP Headphones" 742 "Speakers", "Headphones", "FP Headphones"
767 }; 743 };
768 744
769 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 745 return snd_ctl_enum_info(info, 1, 3, names);
770 info->count = 1;
771 info->value.enumerated.items = 3;
772 if (info->value.enumerated.item >= 3)
773 info->value.enumerated.item = 2;
774 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
775 return 0;
776} 746}
777 747
778static int st_output_switch_get(struct snd_kcontrol *ctl, 748static int st_output_switch_get(struct snd_kcontrol *ctl,
@@ -827,13 +797,7 @@ static int st_hp_volume_offset_info(struct snd_kcontrol *ctl,
827 "< 64 ohms", "64-300 ohms", "300-600 ohms" 797 "< 64 ohms", "64-300 ohms", "300-600 ohms"
828 }; 798 };
829 799
830 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 800 return snd_ctl_enum_info(info, 1, 3, names);
831 info->count = 1;
832 info->value.enumerated.items = 3;
833 if (info->value.enumerated.item > 2)
834 info->value.enumerated.item = 2;
835 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
836 return 0;
837} 801}
838 802
839static int st_hp_volume_offset_get(struct snd_kcontrol *ctl, 803static int st_hp_volume_offset_get(struct snd_kcontrol *ctl,
@@ -915,23 +879,25 @@ static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
915 return 0; 879 return 0;
916} 880}
917 881
918static int xonar_st_control_filter(struct snd_kcontrol_new *template) 882static int xonar_st_h6_control_filter(struct snd_kcontrol_new *template)
919{ 883{
920 if (!strncmp(template->name, "CD Capture ", 11)) 884 if (!strncmp(template->name, "Master Playback ", 16))
921 return 1; /* no CD input */ 885 /* no volume/mute, as I²C to the third DAC does not work */
886 return 1;
922 return 0; 887 return 0;
923} 888}
924 889
925static int add_pcm1796_controls(struct oxygen *chip) 890static int add_pcm1796_controls(struct oxygen *chip)
926{ 891{
892 struct xonar_pcm179x *data = chip->model_data;
927 int err; 893 int err;
928 894
929 err = snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip)); 895 if (!data->broken_i2c) {
930 if (err < 0) 896 err = snd_ctl_add(chip->card,
931 return err; 897 snd_ctl_new1(&rolloff_control, chip));
932 err = snd_ctl_add(chip->card, snd_ctl_new1(&os_128_control, chip)); 898 if (err < 0)
933 if (err < 0) 899 return err;
934 return err; 900 }
935 return 0; 901 return 0;
936} 902}
937 903
@@ -950,7 +916,15 @@ static int xonar_d2_mixer_init(struct oxygen *chip)
950 916
951static int xonar_hdav_mixer_init(struct oxygen *chip) 917static int xonar_hdav_mixer_init(struct oxygen *chip)
952{ 918{
953 return add_pcm1796_controls(chip); 919 int err;
920
921 err = snd_ctl_add(chip->card, snd_ctl_new1(&hdav_hdmi_control, chip));
922 if (err < 0)
923 return err;
924 err = add_pcm1796_controls(chip);
925 if (err < 0)
926 return err;
927 return 0;
954} 928}
955 929
956static int xonar_st_mixer_init(struct oxygen *chip) 930static int xonar_st_mixer_init(struct oxygen *chip)
@@ -970,6 +944,45 @@ static int xonar_st_mixer_init(struct oxygen *chip)
970 return 0; 944 return 0;
971} 945}
972 946
947static void dump_pcm1796_registers(struct oxygen *chip,
948 struct snd_info_buffer *buffer)
949{
950 struct xonar_pcm179x *data = chip->model_data;
951 unsigned int dac, i;
952
953 for (dac = 0; dac < data->dacs; ++dac) {
954 snd_iprintf(buffer, "\nPCM1796 %u:", dac + 1);
955 for (i = 0; i < 5; ++i)
956 snd_iprintf(buffer, " %02x",
957 data->pcm1796_regs[dac][i]);
958 }
959 snd_iprintf(buffer, "\n");
960}
961
962static void dump_cs2000_registers(struct oxygen *chip,
963 struct snd_info_buffer *buffer)
964{
965 struct xonar_pcm179x *data = chip->model_data;
966 unsigned int i;
967
968 if (data->has_cs2000) {
969 snd_iprintf(buffer, "\nCS2000:\n00: ");
970 for (i = 1; i < 0x10; ++i)
971 snd_iprintf(buffer, " %02x", data->cs2000_regs[i]);
972 snd_iprintf(buffer, "\n10:");
973 for (i = 0x10; i < 0x1f; ++i)
974 snd_iprintf(buffer, " %02x", data->cs2000_regs[i]);
975 snd_iprintf(buffer, "\n");
976 }
977}
978
979static void dump_st_registers(struct oxygen *chip,
980 struct snd_info_buffer *buffer)
981{
982 dump_pcm1796_registers(chip, buffer);
983 dump_cs2000_registers(chip, buffer);
984}
985
973static const struct oxygen_model model_xonar_d2 = { 986static const struct oxygen_model model_xonar_d2 = {
974 .longname = "Asus Virtuoso 200", 987 .longname = "Asus Virtuoso 200",
975 .chip = "AV200", 988 .chip = "AV200",
@@ -979,11 +992,11 @@ static const struct oxygen_model model_xonar_d2 = {
979 .cleanup = xonar_d2_cleanup, 992 .cleanup = xonar_d2_cleanup,
980 .suspend = xonar_d2_suspend, 993 .suspend = xonar_d2_suspend,
981 .resume = xonar_d2_resume, 994 .resume = xonar_d2_resume,
982 .get_i2s_mclk = get_pcm1796_i2s_mclk,
983 .set_dac_params = set_pcm1796_params, 995 .set_dac_params = set_pcm1796_params,
984 .set_adc_params = xonar_set_cs53x1_params, 996 .set_adc_params = xonar_set_cs53x1_params,
985 .update_dac_volume = update_pcm1796_volume, 997 .update_dac_volume = update_pcm1796_volume,
986 .update_dac_mute = update_pcm1796_mute, 998 .update_dac_mute = update_pcm1796_mute,
999 .dump_registers = dump_pcm1796_registers,
987 .dac_tlv = pcm1796_db_scale, 1000 .dac_tlv = pcm1796_db_scale,
988 .model_data_size = sizeof(struct xonar_pcm179x), 1001 .model_data_size = sizeof(struct xonar_pcm179x),
989 .device_config = PLAYBACK_0_TO_I2S | 1002 .device_config = PLAYBACK_0_TO_I2S |
@@ -991,14 +1004,18 @@ static const struct oxygen_model model_xonar_d2 = {
991 CAPTURE_0_FROM_I2S_2 | 1004 CAPTURE_0_FROM_I2S_2 |
992 CAPTURE_1_FROM_SPDIF | 1005 CAPTURE_1_FROM_SPDIF |
993 MIDI_OUTPUT | 1006 MIDI_OUTPUT |
994 MIDI_INPUT, 1007 MIDI_INPUT |
995 .dac_channels = 8, 1008 AC97_CD_INPUT,
1009 .dac_channels_pcm = 8,
1010 .dac_channels_mixer = 8,
996 .dac_volume_min = 255 - 2*60, 1011 .dac_volume_min = 255 - 2*60,
997 .dac_volume_max = 255, 1012 .dac_volume_max = 255,
998 .misc_flags = OXYGEN_MISC_MIDI, 1013 .misc_flags = OXYGEN_MISC_MIDI,
999 .function_flags = OXYGEN_FUNCTION_SPI | 1014 .function_flags = OXYGEN_FUNCTION_SPI |
1000 OXYGEN_FUNCTION_ENABLE_SPI_4_5, 1015 OXYGEN_FUNCTION_ENABLE_SPI_4_5,
1001 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1016 .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
1017 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
1018 .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
1002 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1019 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1003}; 1020};
1004 1021
@@ -1011,25 +1028,28 @@ static const struct oxygen_model model_xonar_hdav = {
1011 .suspend = xonar_hdav_suspend, 1028 .suspend = xonar_hdav_suspend,
1012 .resume = xonar_hdav_resume, 1029 .resume = xonar_hdav_resume,
1013 .pcm_hardware_filter = xonar_hdmi_pcm_hardware_filter, 1030 .pcm_hardware_filter = xonar_hdmi_pcm_hardware_filter,
1014 .get_i2s_mclk = get_pcm1796_i2s_mclk,
1015 .set_dac_params = set_hdav_params, 1031 .set_dac_params = set_hdav_params,
1016 .set_adc_params = xonar_set_cs53x1_params, 1032 .set_adc_params = xonar_set_cs53x1_params,
1017 .update_dac_volume = update_pcm1796_volume, 1033 .update_dac_volume = update_pcm1796_volume,
1018 .update_dac_mute = update_pcm1796_mute, 1034 .update_dac_mute = update_pcm1796_mute,
1019 .uart_input = xonar_hdmi_uart_input, 1035 .uart_input = xonar_hdmi_uart_input,
1020 .ac97_switch = xonar_line_mic_ac97_switch, 1036 .ac97_switch = xonar_line_mic_ac97_switch,
1037 .dump_registers = dump_pcm1796_registers,
1021 .dac_tlv = pcm1796_db_scale, 1038 .dac_tlv = pcm1796_db_scale,
1022 .model_data_size = sizeof(struct xonar_hdav), 1039 .model_data_size = sizeof(struct xonar_hdav),
1023 .device_config = PLAYBACK_0_TO_I2S | 1040 .device_config = PLAYBACK_0_TO_I2S |
1024 PLAYBACK_1_TO_SPDIF | 1041 PLAYBACK_1_TO_SPDIF |
1025 CAPTURE_0_FROM_I2S_2 | 1042 CAPTURE_0_FROM_I2S_2 |
1026 CAPTURE_1_FROM_SPDIF, 1043 CAPTURE_1_FROM_SPDIF,
1027 .dac_channels = 8, 1044 .dac_channels_pcm = 8,
1045 .dac_channels_mixer = 2,
1028 .dac_volume_min = 255 - 2*60, 1046 .dac_volume_min = 255 - 2*60,
1029 .dac_volume_max = 255, 1047 .dac_volume_max = 255,
1030 .misc_flags = OXYGEN_MISC_MIDI, 1048 .misc_flags = OXYGEN_MISC_MIDI,
1031 .function_flags = OXYGEN_FUNCTION_2WIRE, 1049 .function_flags = OXYGEN_FUNCTION_2WIRE,
1032 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1050 .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
1051 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
1052 .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
1033 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1053 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1034}; 1054};
1035 1055
@@ -1037,27 +1057,30 @@ static const struct oxygen_model model_xonar_st = {
1037 .longname = "Asus Virtuoso 100", 1057 .longname = "Asus Virtuoso 100",
1038 .chip = "AV200", 1058 .chip = "AV200",
1039 .init = xonar_st_init, 1059 .init = xonar_st_init,
1040 .control_filter = xonar_st_control_filter,
1041 .mixer_init = xonar_st_mixer_init, 1060 .mixer_init = xonar_st_mixer_init,
1042 .cleanup = xonar_st_cleanup, 1061 .cleanup = xonar_st_cleanup,
1043 .suspend = xonar_st_suspend, 1062 .suspend = xonar_st_suspend,
1044 .resume = xonar_st_resume, 1063 .resume = xonar_st_resume,
1045 .get_i2s_mclk = get_pcm1796_i2s_mclk,
1046 .set_dac_params = set_st_params, 1064 .set_dac_params = set_st_params,
1047 .set_adc_params = xonar_set_cs53x1_params, 1065 .set_adc_params = xonar_set_cs53x1_params,
1048 .update_dac_volume = update_pcm1796_volume, 1066 .update_dac_volume = update_pcm1796_volume,
1049 .update_dac_mute = update_pcm1796_mute, 1067 .update_dac_mute = update_pcm1796_mute,
1050 .ac97_switch = xonar_line_mic_ac97_switch, 1068 .ac97_switch = xonar_line_mic_ac97_switch,
1069 .dump_registers = dump_st_registers,
1051 .dac_tlv = pcm1796_db_scale, 1070 .dac_tlv = pcm1796_db_scale,
1052 .model_data_size = sizeof(struct xonar_pcm179x), 1071 .model_data_size = sizeof(struct xonar_pcm179x),
1053 .device_config = PLAYBACK_0_TO_I2S | 1072 .device_config = PLAYBACK_0_TO_I2S |
1054 PLAYBACK_1_TO_SPDIF | 1073 PLAYBACK_1_TO_SPDIF |
1055 CAPTURE_0_FROM_I2S_2, 1074 CAPTURE_0_FROM_I2S_2 |
1056 .dac_channels = 2, 1075 AC97_FMIC_SWITCH,
1076 .dac_channels_pcm = 2,
1077 .dac_channels_mixer = 2,
1057 .dac_volume_min = 255 - 2*60, 1078 .dac_volume_min = 255 - 2*60,
1058 .dac_volume_max = 255, 1079 .dac_volume_max = 255,
1059 .function_flags = OXYGEN_FUNCTION_2WIRE, 1080 .function_flags = OXYGEN_FUNCTION_2WIRE,
1060 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1081 .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
1082 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
1083 .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
1061 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1084 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1062}; 1085};
1063 1086
@@ -1083,7 +1106,8 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
1083 break; 1106 break;
1084 case GPIO_DB_H6: 1107 case GPIO_DB_H6:
1085 chip->model.shortname = "Xonar HDAV1.3+H6"; 1108 chip->model.shortname = "Xonar HDAV1.3+H6";
1086 chip->model.private_data = 1; 1109 chip->model.dac_channels_mixer = 8;
1110 chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
1087 break; 1111 break;
1088 } 1112 }
1089 break; 1113 break;
@@ -1096,8 +1120,10 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
1096 break; 1120 break;
1097 case GPIO_DB_H6: 1121 case GPIO_DB_H6:
1098 chip->model.shortname = "Xonar ST+H6"; 1122 chip->model.shortname = "Xonar ST+H6";
1099 chip->model.dac_channels = 8; 1123 chip->model.control_filter = xonar_st_h6_control_filter;
1100 chip->model.private_data = 1; 1124 chip->model.dac_channels_pcm = 8;
1125 chip->model.dac_channels_mixer = 8;
1126 chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
1101 break; 1127 break;
1102 } 1128 }
1103 break; 1129 break;
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index b82c1cfa96f5..42d1ab136217 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * card driver for models with WM8776/WM8766 DACs (Xonar DS) 2 * card driver for models with WM8776/WM8766 DACs (Xonar DS/HDAV1.3 Slim)
3 * 3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * 5 *
@@ -22,19 +22,49 @@
22 * 22 *
23 * CMI8788: 23 * CMI8788:
24 * 24 *
25 * SPI 0 -> WM8766 (surround, center/LFE, back) 25 * SPI 0 -> WM8766 (surround, center/LFE, back)
26 * SPI 1 -> WM8776 (front, input) 26 * SPI 1 -> WM8776 (front, input)
27 * 27 *
28 * GPIO 4 <- headphone detect 28 * GPIO 4 <- headphone detect, 0 = plugged
29 * GPIO 6 -> route input jack to input 1/2 (1/0) 29 * GPIO 6 -> route input jack to mic-in (0) or line-in (1)
30 * GPIO 7 -> enable output to speakers 30 * GPIO 7 -> enable output to front L/R speaker channels
31 * GPIO 8 -> enable output to speakers 31 * GPIO 8 -> enable output to other speaker channels and front panel headphone
32 *
33 * WM8776:
34 *
35 * input 1 <- line
36 * input 2 <- mic
37 * input 3 <- front mic
38 * input 4 <- aux
39 */
40
41/*
42 * Xonar HDAV1.3 Slim
43 * ------------------
44 *
45 * CMI8788:
46 *
47 * I²C <-> WM8776 (addr 0011010)
48 *
49 * GPIO 0 -> disable HDMI output
50 * GPIO 1 -> enable HP output
51 * GPIO 6 -> firmware EEPROM I²C clock
52 * GPIO 7 <-> firmware EEPROM I²C data
53 *
54 * UART <-> HDMI controller
55 *
56 * WM8776:
57 *
58 * input 1 <- mic
59 * input 2 <- aux
32 */ 60 */
33 61
34#include <linux/pci.h> 62#include <linux/pci.h>
35#include <linux/delay.h> 63#include <linux/delay.h>
36#include <sound/control.h> 64#include <sound/control.h>
37#include <sound/core.h> 65#include <sound/core.h>
66#include <sound/info.h>
67#include <sound/jack.h>
38#include <sound/pcm.h> 68#include <sound/pcm.h>
39#include <sound/pcm_params.h> 69#include <sound/pcm_params.h>
40#include <sound/tlv.h> 70#include <sound/tlv.h>
@@ -44,7 +74,15 @@
44 74
45#define GPIO_DS_HP_DETECT 0x0010 75#define GPIO_DS_HP_DETECT 0x0010
46#define GPIO_DS_INPUT_ROUTE 0x0040 76#define GPIO_DS_INPUT_ROUTE 0x0040
47#define GPIO_DS_OUTPUT_ENABLE 0x0180 77#define GPIO_DS_OUTPUT_FRONTLR 0x0080
78#define GPIO_DS_OUTPUT_ENABLE 0x0100
79
80#define GPIO_SLIM_HDMI_DISABLE 0x0001
81#define GPIO_SLIM_OUTPUT_ENABLE 0x0002
82#define GPIO_SLIM_FIRMWARE_CLK 0x0040
83#define GPIO_SLIM_FIRMWARE_DATA 0x0080
84
85#define I2C_DEVICE_WM8776 0x34 /* 001101, 0, /W=0 */
48 86
49#define LC_CONTROL_LIMITER 0x40000000 87#define LC_CONTROL_LIMITER 0x40000000
50#define LC_CONTROL_ALC 0x20000000 88#define LC_CONTROL_ALC 0x20000000
@@ -56,19 +94,38 @@ struct xonar_wm87x6 {
56 struct snd_kcontrol *line_adcmux_control; 94 struct snd_kcontrol *line_adcmux_control;
57 struct snd_kcontrol *mic_adcmux_control; 95 struct snd_kcontrol *mic_adcmux_control;
58 struct snd_kcontrol *lc_controls[13]; 96 struct snd_kcontrol *lc_controls[13];
97 struct snd_jack *hp_jack;
98 struct xonar_hdmi hdmi;
59}; 99};
60 100
61static void wm8776_write(struct oxygen *chip, 101static void wm8776_write_spi(struct oxygen *chip,
62 unsigned int reg, unsigned int value) 102 unsigned int reg, unsigned int value)
63{ 103{
64 struct xonar_wm87x6 *data = chip->model_data;
65
66 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 104 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
67 OXYGEN_SPI_DATA_LENGTH_2 | 105 OXYGEN_SPI_DATA_LENGTH_2 |
68 OXYGEN_SPI_CLOCK_160 | 106 OXYGEN_SPI_CLOCK_160 |
69 (1 << OXYGEN_SPI_CODEC_SHIFT) | 107 (1 << OXYGEN_SPI_CODEC_SHIFT) |
70 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 108 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
71 (reg << 9) | value); 109 (reg << 9) | value);
110}
111
112static void wm8776_write_i2c(struct oxygen *chip,
113 unsigned int reg, unsigned int value)
114{
115 oxygen_write_i2c(chip, I2C_DEVICE_WM8776,
116 (reg << 1) | (value >> 8), value);
117}
118
119static void wm8776_write(struct oxygen *chip,
120 unsigned int reg, unsigned int value)
121{
122 struct xonar_wm87x6 *data = chip->model_data;
123
124 if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) ==
125 OXYGEN_FUNCTION_SPI)
126 wm8776_write_spi(chip, reg, value);
127 else
128 wm8776_write_i2c(chip, reg, value);
72 if (reg < ARRAY_SIZE(data->wm8776_regs)) { 129 if (reg < ARRAY_SIZE(data->wm8776_regs)) {
73 if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER) 130 if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER)
74 value &= ~WM8776_UPDATE; 131 value &= ~WM8776_UPDATE;
@@ -97,8 +154,12 @@ static void wm8766_write(struct oxygen *chip,
97 (0 << OXYGEN_SPI_CODEC_SHIFT) | 154 (0 << OXYGEN_SPI_CODEC_SHIFT) |
98 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 155 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
99 (reg << 9) | value); 156 (reg << 9) | value);
100 if (reg < ARRAY_SIZE(data->wm8766_regs)) 157 if (reg < ARRAY_SIZE(data->wm8766_regs)) {
158 if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) ||
159 (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA))
160 value &= ~WM8766_UPDATE;
101 data->wm8766_regs[reg] = value; 161 data->wm8766_regs[reg] = value;
162 }
102} 163}
103 164
104static void wm8766_write_cached(struct oxygen *chip, 165static void wm8766_write_cached(struct oxygen *chip,
@@ -107,12 +168,8 @@ static void wm8766_write_cached(struct oxygen *chip,
107 struct xonar_wm87x6 *data = chip->model_data; 168 struct xonar_wm87x6 *data = chip->model_data;
108 169
109 if (reg >= ARRAY_SIZE(data->wm8766_regs) || 170 if (reg >= ARRAY_SIZE(data->wm8766_regs) ||
110 value != data->wm8766_regs[reg]) { 171 value != data->wm8766_regs[reg])
111 if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) ||
112 (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA))
113 value &= ~WM8766_UPDATE;
114 wm8766_write(chip, reg, value); 172 wm8766_write(chip, reg, value);
115 }
116} 173}
117 174
118static void wm8776_registers_init(struct oxygen *chip) 175static void wm8776_registers_init(struct oxygen *chip)
@@ -141,7 +198,10 @@ static void wm8776_registers_init(struct oxygen *chip)
141 198
142static void wm8766_registers_init(struct oxygen *chip) 199static void wm8766_registers_init(struct oxygen *chip)
143{ 200{
201 struct xonar_wm87x6 *data = chip->model_data;
202
144 wm8766_write(chip, WM8766_RESET, 0); 203 wm8766_write(chip, WM8766_RESET, 0);
204 wm8766_write(chip, WM8766_DAC_CTRL, data->wm8766_regs[WM8766_DAC_CTRL]);
145 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24); 205 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24);
146 wm8766_write(chip, WM8766_DAC_CTRL2, 206 wm8766_write(chip, WM8766_DAC_CTRL2,
147 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); 207 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
@@ -170,6 +230,40 @@ static void wm8776_init(struct oxygen *chip)
170 wm8776_registers_init(chip); 230 wm8776_registers_init(chip);
171} 231}
172 232
233static void wm8766_init(struct oxygen *chip)
234{
235 struct xonar_wm87x6 *data = chip->model_data;
236
237 data->wm8766_regs[WM8766_DAC_CTRL] =
238 WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
239 wm8766_registers_init(chip);
240}
241
242static void xonar_ds_handle_hp_jack(struct oxygen *chip)
243{
244 struct xonar_wm87x6 *data = chip->model_data;
245 bool hp_plugged;
246 unsigned int reg;
247
248 mutex_lock(&chip->mutex);
249
250 hp_plugged = !(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
251 GPIO_DS_HP_DETECT);
252
253 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
254 hp_plugged ? 0 : GPIO_DS_OUTPUT_FRONTLR,
255 GPIO_DS_OUTPUT_FRONTLR);
256
257 reg = data->wm8766_regs[WM8766_DAC_CTRL] & ~WM8766_MUTEALL;
258 if (hp_plugged)
259 reg |= WM8766_MUTEALL;
260 wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
261
262 snd_jack_report(data->hp_jack, hp_plugged ? SND_JACK_HEADPHONE : 0);
263
264 mutex_unlock(&chip->mutex);
265}
266
173static void xonar_ds_init(struct oxygen *chip) 267static void xonar_ds_init(struct oxygen *chip)
174{ 268{
175 struct xonar_wm87x6 *data = chip->model_data; 269 struct xonar_wm87x6 *data = chip->model_data;
@@ -178,36 +272,85 @@ static void xonar_ds_init(struct oxygen *chip)
178 data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE; 272 data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE;
179 273
180 wm8776_init(chip); 274 wm8776_init(chip);
181 wm8766_registers_init(chip); 275 wm8766_init(chip);
182 276
183 oxygen_write16_masked(chip, OXYGEN_GPIO_CONTROL, GPIO_DS_INPUT_ROUTE, 277 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
184 GPIO_DS_HP_DETECT | GPIO_DS_INPUT_ROUTE); 278 GPIO_DS_INPUT_ROUTE | GPIO_DS_OUTPUT_FRONTLR);
279 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
280 GPIO_DS_HP_DETECT);
185 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE); 281 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE);
186 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT); 282 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT);
187 chip->interrupt_mask |= OXYGEN_INT_GPIO; 283 chip->interrupt_mask |= OXYGEN_INT_GPIO;
188 284
189 xonar_enable_output(chip); 285 xonar_enable_output(chip);
190 286
287 snd_jack_new(chip->card, "Headphone",
288 SND_JACK_HEADPHONE, &data->hp_jack);
289 xonar_ds_handle_hp_jack(chip);
290
191 snd_component_add(chip->card, "WM8776"); 291 snd_component_add(chip->card, "WM8776");
192 snd_component_add(chip->card, "WM8766"); 292 snd_component_add(chip->card, "WM8766");
193} 293}
194 294
295static void xonar_hdav_slim_init(struct oxygen *chip)
296{
297 struct xonar_wm87x6 *data = chip->model_data;
298
299 data->generic.anti_pop_delay = 300;
300 data->generic.output_enable_bit = GPIO_SLIM_OUTPUT_ENABLE;
301
302 wm8776_init(chip);
303
304 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
305 GPIO_SLIM_HDMI_DISABLE |
306 GPIO_SLIM_FIRMWARE_CLK |
307 GPIO_SLIM_FIRMWARE_DATA);
308
309 xonar_hdmi_init(chip, &data->hdmi);
310 xonar_enable_output(chip);
311
312 snd_component_add(chip->card, "WM8776");
313}
314
195static void xonar_ds_cleanup(struct oxygen *chip) 315static void xonar_ds_cleanup(struct oxygen *chip)
196{ 316{
197 xonar_disable_output(chip); 317 xonar_disable_output(chip);
198 wm8776_write(chip, WM8776_RESET, 0); 318 wm8776_write(chip, WM8776_RESET, 0);
199} 319}
200 320
321static void xonar_hdav_slim_cleanup(struct oxygen *chip)
322{
323 xonar_hdmi_cleanup(chip);
324 xonar_disable_output(chip);
325 wm8776_write(chip, WM8776_RESET, 0);
326 msleep(2);
327}
328
201static void xonar_ds_suspend(struct oxygen *chip) 329static void xonar_ds_suspend(struct oxygen *chip)
202{ 330{
203 xonar_ds_cleanup(chip); 331 xonar_ds_cleanup(chip);
204} 332}
205 333
334static void xonar_hdav_slim_suspend(struct oxygen *chip)
335{
336 xonar_hdav_slim_cleanup(chip);
337}
338
206static void xonar_ds_resume(struct oxygen *chip) 339static void xonar_ds_resume(struct oxygen *chip)
207{ 340{
208 wm8776_registers_init(chip); 341 wm8776_registers_init(chip);
209 wm8766_registers_init(chip); 342 wm8766_registers_init(chip);
210 xonar_enable_output(chip); 343 xonar_enable_output(chip);
344 xonar_ds_handle_hp_jack(chip);
345}
346
347static void xonar_hdav_slim_resume(struct oxygen *chip)
348{
349 struct xonar_wm87x6 *data = chip->model_data;
350
351 wm8776_registers_init(chip);
352 xonar_hdmi_resume(chip, &data->hdmi);
353 xonar_enable_output(chip);
211} 354}
212 355
213static void wm8776_adc_hardware_filter(unsigned int channel, 356static void wm8776_adc_hardware_filter(unsigned int channel,
@@ -224,6 +367,13 @@ static void wm8776_adc_hardware_filter(unsigned int channel,
224 } 367 }
225} 368}
226 369
370static void xonar_hdav_slim_hardware_filter(unsigned int channel,
371 struct snd_pcm_hardware *hardware)
372{
373 wm8776_adc_hardware_filter(channel, hardware);
374 xonar_hdmi_pcm_hardware_filter(channel, hardware);
375}
376
227static void set_wm87x6_dac_params(struct oxygen *chip, 377static void set_wm87x6_dac_params(struct oxygen *chip,
228 struct snd_pcm_hw_params *params) 378 struct snd_pcm_hw_params *params)
229{ 379{
@@ -240,6 +390,14 @@ static void set_wm8776_adc_params(struct oxygen *chip,
240 wm8776_write_cached(chip, WM8776_MSTRCTRL, reg); 390 wm8776_write_cached(chip, WM8776_MSTRCTRL, reg);
241} 391}
242 392
393static void set_hdav_slim_dac_params(struct oxygen *chip,
394 struct snd_pcm_hw_params *params)
395{
396 struct xonar_wm87x6 *data = chip->model_data;
397
398 xonar_set_hdmi_params(chip, &data->hdmi, params);
399}
400
243static void update_wm8776_volume(struct oxygen *chip) 401static void update_wm8776_volume(struct oxygen *chip)
244{ 402{
245 struct xonar_wm87x6 *data = chip->model_data; 403 struct xonar_wm87x6 *data = chip->model_data;
@@ -323,12 +481,27 @@ static void update_wm87x6_mute(struct oxygen *chip)
323 (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); 481 (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
324} 482}
325 483
326static void xonar_ds_gpio_changed(struct oxygen *chip) 484static void update_wm8766_center_lfe_mix(struct oxygen *chip, bool mixed)
327{ 485{
328 u16 bits; 486 struct xonar_wm87x6 *data = chip->model_data;
487 unsigned int reg;
488
489 /*
490 * The WM8766 can mix left and right channels, but this setting
491 * applies to all three stereo pairs.
492 */
493 reg = data->wm8766_regs[WM8766_DAC_CTRL] &
494 ~(WM8766_PL_LEFT_MASK | WM8766_PL_RIGHT_MASK);
495 if (mixed)
496 reg |= WM8766_PL_LEFT_LRMIX | WM8766_PL_RIGHT_LRMIX;
497 else
498 reg |= WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
499 wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
500}
329 501
330 bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); 502static void xonar_ds_gpio_changed(struct oxygen *chip)
331 snd_printk(KERN_INFO "HP detect: %d\n", !!(bits & GPIO_DS_HP_DETECT)); 503{
504 xonar_ds_handle_hp_jack(chip);
332} 505}
333 506
334static int wm8776_bit_switch_get(struct snd_kcontrol *ctl, 507static int wm8776_bit_switch_get(struct snd_kcontrol *ctl,
@@ -404,11 +577,6 @@ static int wm8776_field_enum_info(struct snd_kcontrol *ctl,
404 const char *const *names; 577 const char *const *names;
405 578
406 max = (ctl->private_value >> 12) & 0xf; 579 max = (ctl->private_value >> 12) & 0xf;
407 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
408 info->count = 1;
409 info->value.enumerated.items = max + 1;
410 if (info->value.enumerated.item > max)
411 info->value.enumerated.item = max;
412 switch ((ctl->private_value >> 24) & 0x1f) { 580 switch ((ctl->private_value >> 24) & 0x1f) {
413 case WM8776_ALCCTRL2: 581 case WM8776_ALCCTRL2:
414 names = hld; 582 names = hld;
@@ -432,8 +600,7 @@ static int wm8776_field_enum_info(struct snd_kcontrol *ctl,
432 default: 600 default:
433 return -ENXIO; 601 return -ENXIO;
434 } 602 }
435 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); 603 return snd_ctl_enum_info(info, 1, max + 1, names);
436 return 0;
437} 604}
438 605
439static int wm8776_field_volume_info(struct snd_kcontrol *ctl, 606static int wm8776_field_volume_info(struct snd_kcontrol *ctl,
@@ -690,13 +857,8 @@ static int wm8776_level_control_info(struct snd_kcontrol *ctl,
690 static const char *const names[3] = { 857 static const char *const names[3] = {
691 "None", "Peak Limiter", "Automatic Level Control" 858 "None", "Peak Limiter", "Automatic Level Control"
692 }; 859 };
693 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 860
694 info->count = 1; 861 return snd_ctl_enum_info(info, 1, 3, names);
695 info->value.enumerated.items = 3;
696 if (info->value.enumerated.item >= 3)
697 info->value.enumerated.item = 2;
698 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
699 return 0;
700} 862}
701 863
702static int wm8776_level_control_get(struct snd_kcontrol *ctl, 864static int wm8776_level_control_get(struct snd_kcontrol *ctl,
@@ -782,13 +944,7 @@ static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
782 "None", "High-pass Filter" 944 "None", "High-pass Filter"
783 }; 945 };
784 946
785 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 947 return snd_ctl_enum_info(info, 1, 2, names);
786 info->count = 1;
787 info->value.enumerated.items = 2;
788 if (info->value.enumerated.item >= 2)
789 info->value.enumerated.item = 1;
790 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
791 return 0;
792} 948}
793 949
794static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 950static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
@@ -896,7 +1052,57 @@ static const struct snd_kcontrol_new ds_controls[] = {
896 .put = wm8776_input_mux_put, 1052 .put = wm8776_input_mux_put,
897 .private_value = 1 << 1, 1053 .private_value = 1 << 1,
898 }, 1054 },
899 WM8776_BIT_SWITCH("Aux", WM8776_ADCMUX, 1 << 2, 0, 0), 1055 WM8776_BIT_SWITCH("Front Mic Capture Switch",
1056 WM8776_ADCMUX, 1 << 2, 0, 0),
1057 WM8776_BIT_SWITCH("Aux Capture Switch",
1058 WM8776_ADCMUX, 1 << 3, 0, 0),
1059 {
1060 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1061 .name = "ADC Filter Capture Enum",
1062 .info = hpf_info,
1063 .get = hpf_get,
1064 .put = hpf_put,
1065 },
1066 {
1067 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1068 .name = "Level Control Capture Enum",
1069 .info = wm8776_level_control_info,
1070 .get = wm8776_level_control_get,
1071 .put = wm8776_level_control_put,
1072 .private_value = 0,
1073 },
1074};
1075static const struct snd_kcontrol_new hdav_slim_controls[] = {
1076 {
1077 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1078 .name = "HDMI Playback Switch",
1079 .info = snd_ctl_boolean_mono_info,
1080 .get = xonar_gpio_bit_switch_get,
1081 .put = xonar_gpio_bit_switch_put,
1082 .private_value = GPIO_SLIM_HDMI_DISABLE | XONAR_GPIO_BIT_INVERT,
1083 },
1084 {
1085 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1086 .name = "Headphone Playback Volume",
1087 .info = wm8776_hp_vol_info,
1088 .get = wm8776_hp_vol_get,
1089 .put = wm8776_hp_vol_put,
1090 .tlv = { .p = wm8776_hp_db_scale },
1091 },
1092 WM8776_BIT_SWITCH("Headphone Playback Switch",
1093 WM8776_PWRDOWN, WM8776_HPPD, 1, 0),
1094 {
1095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1096 .name = "Input Capture Volume",
1097 .info = wm8776_input_vol_info,
1098 .get = wm8776_input_vol_get,
1099 .put = wm8776_input_vol_put,
1100 .tlv = { .p = wm8776_adc_db_scale },
1101 },
1102 WM8776_BIT_SWITCH("Mic Capture Switch",
1103 WM8776_ADCMUX, 1 << 0, 0, 0),
1104 WM8776_BIT_SWITCH("Aux Capture Switch",
1105 WM8776_ADCMUX, 1 << 1, 0, 0),
900 { 1106 {
901 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1107 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
902 .name = "ADC Filter Capture Enum", 1108 .name = "ADC Filter Capture Enum",
@@ -956,10 +1162,23 @@ static const struct snd_kcontrol_new lc_controls[] = {
956 LC_CONTROL_ALC, wm8776_ngth_db_scale), 1162 LC_CONTROL_ALC, wm8776_ngth_db_scale),
957}; 1163};
958 1164
959static int xonar_ds_control_filter(struct snd_kcontrol_new *template) 1165static int add_lc_controls(struct oxygen *chip)
960{ 1166{
961 if (!strncmp(template->name, "CD Capture ", 11)) 1167 struct xonar_wm87x6 *data = chip->model_data;
962 return 1; /* no CD input */ 1168 unsigned int i;
1169 struct snd_kcontrol *ctl;
1170 int err;
1171
1172 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls));
1173 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) {
1174 ctl = snd_ctl_new1(&lc_controls[i], chip);
1175 if (!ctl)
1176 return -ENOMEM;
1177 err = snd_ctl_add(chip->card, ctl);
1178 if (err < 0)
1179 return err;
1180 data->lc_controls[i] = ctl;
1181 }
963 return 0; 1182 return 0;
964} 1183}
965 1184
@@ -984,45 +1203,117 @@ static int xonar_ds_mixer_init(struct oxygen *chip)
984 } 1203 }
985 if (!data->line_adcmux_control || !data->mic_adcmux_control) 1204 if (!data->line_adcmux_control || !data->mic_adcmux_control)
986 return -ENXIO; 1205 return -ENXIO;
987 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls)); 1206
988 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) { 1207 return add_lc_controls(chip);
989 ctl = snd_ctl_new1(&lc_controls[i], chip); 1208}
1209
1210static int xonar_hdav_slim_mixer_init(struct oxygen *chip)
1211{
1212 unsigned int i;
1213 struct snd_kcontrol *ctl;
1214 int err;
1215
1216 for (i = 0; i < ARRAY_SIZE(hdav_slim_controls); ++i) {
1217 ctl = snd_ctl_new1(&hdav_slim_controls[i], chip);
990 if (!ctl) 1218 if (!ctl)
991 return -ENOMEM; 1219 return -ENOMEM;
992 err = snd_ctl_add(chip->card, ctl); 1220 err = snd_ctl_add(chip->card, ctl);
993 if (err < 0) 1221 if (err < 0)
994 return err; 1222 return err;
995 data->lc_controls[i] = ctl;
996 } 1223 }
997 return 0; 1224
1225 return add_lc_controls(chip);
1226}
1227
1228static void dump_wm8776_registers(struct oxygen *chip,
1229 struct snd_info_buffer *buffer)
1230{
1231 struct xonar_wm87x6 *data = chip->model_data;
1232 unsigned int i;
1233
1234 snd_iprintf(buffer, "\nWM8776:\n00:");
1235 for (i = 0; i < 0x10; ++i)
1236 snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
1237 snd_iprintf(buffer, "\n10:");
1238 for (i = 0x10; i < 0x17; ++i)
1239 snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
1240 snd_iprintf(buffer, "\n");
1241}
1242
1243static void dump_wm87x6_registers(struct oxygen *chip,
1244 struct snd_info_buffer *buffer)
1245{
1246 struct xonar_wm87x6 *data = chip->model_data;
1247 unsigned int i;
1248
1249 dump_wm8776_registers(chip, buffer);
1250 snd_iprintf(buffer, "\nWM8766:\n00:");
1251 for (i = 0; i < 0x10; ++i)
1252 snd_iprintf(buffer, " %03x", data->wm8766_regs[i]);
1253 snd_iprintf(buffer, "\n");
998} 1254}
999 1255
1000static const struct oxygen_model model_xonar_ds = { 1256static const struct oxygen_model model_xonar_ds = {
1001 .shortname = "Xonar DS", 1257 .shortname = "Xonar DS",
1002 .longname = "Asus Virtuoso 200", 1258 .longname = "Asus Virtuoso 66",
1003 .chip = "AV200", 1259 .chip = "AV200",
1004 .init = xonar_ds_init, 1260 .init = xonar_ds_init,
1005 .control_filter = xonar_ds_control_filter,
1006 .mixer_init = xonar_ds_mixer_init, 1261 .mixer_init = xonar_ds_mixer_init,
1007 .cleanup = xonar_ds_cleanup, 1262 .cleanup = xonar_ds_cleanup,
1008 .suspend = xonar_ds_suspend, 1263 .suspend = xonar_ds_suspend,
1009 .resume = xonar_ds_resume, 1264 .resume = xonar_ds_resume,
1010 .pcm_hardware_filter = wm8776_adc_hardware_filter, 1265 .pcm_hardware_filter = wm8776_adc_hardware_filter,
1011 .get_i2s_mclk = oxygen_default_i2s_mclk,
1012 .set_dac_params = set_wm87x6_dac_params, 1266 .set_dac_params = set_wm87x6_dac_params,
1013 .set_adc_params = set_wm8776_adc_params, 1267 .set_adc_params = set_wm8776_adc_params,
1014 .update_dac_volume = update_wm87x6_volume, 1268 .update_dac_volume = update_wm87x6_volume,
1015 .update_dac_mute = update_wm87x6_mute, 1269 .update_dac_mute = update_wm87x6_mute,
1270 .update_center_lfe_mix = update_wm8766_center_lfe_mix,
1016 .gpio_changed = xonar_ds_gpio_changed, 1271 .gpio_changed = xonar_ds_gpio_changed,
1272 .dump_registers = dump_wm87x6_registers,
1017 .dac_tlv = wm87x6_dac_db_scale, 1273 .dac_tlv = wm87x6_dac_db_scale,
1018 .model_data_size = sizeof(struct xonar_wm87x6), 1274 .model_data_size = sizeof(struct xonar_wm87x6),
1019 .device_config = PLAYBACK_0_TO_I2S | 1275 .device_config = PLAYBACK_0_TO_I2S |
1020 PLAYBACK_1_TO_SPDIF | 1276 PLAYBACK_1_TO_SPDIF |
1021 CAPTURE_0_FROM_I2S_1, 1277 CAPTURE_0_FROM_I2S_1,
1022 .dac_channels = 8, 1278 .dac_channels_pcm = 8,
1279 .dac_channels_mixer = 8,
1023 .dac_volume_min = 255 - 2*60, 1280 .dac_volume_min = 255 - 2*60,
1024 .dac_volume_max = 255, 1281 .dac_volume_max = 255,
1025 .function_flags = OXYGEN_FUNCTION_SPI, 1282 .function_flags = OXYGEN_FUNCTION_SPI,
1283 .dac_mclks = OXYGEN_MCLKS(256, 256, 128),
1284 .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
1285 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1286 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1287};
1288
1289static const struct oxygen_model model_xonar_hdav_slim = {
1290 .shortname = "Xonar HDAV1.3 Slim",
1291 .longname = "Asus Virtuoso 200",
1292 .chip = "AV200",
1293 .init = xonar_hdav_slim_init,
1294 .mixer_init = xonar_hdav_slim_mixer_init,
1295 .cleanup = xonar_hdav_slim_cleanup,
1296 .suspend = xonar_hdav_slim_suspend,
1297 .resume = xonar_hdav_slim_resume,
1298 .pcm_hardware_filter = xonar_hdav_slim_hardware_filter,
1299 .set_dac_params = set_hdav_slim_dac_params,
1300 .set_adc_params = set_wm8776_adc_params,
1301 .update_dac_volume = update_wm8776_volume,
1302 .update_dac_mute = update_wm8776_mute,
1303 .uart_input = xonar_hdmi_uart_input,
1304 .dump_registers = dump_wm8776_registers,
1305 .dac_tlv = wm87x6_dac_db_scale,
1306 .model_data_size = sizeof(struct xonar_wm87x6),
1307 .device_config = PLAYBACK_0_TO_I2S |
1308 PLAYBACK_1_TO_SPDIF |
1309 CAPTURE_0_FROM_I2S_1,
1310 .dac_channels_pcm = 8,
1311 .dac_channels_mixer = 2,
1312 .dac_volume_min = 255 - 2*60,
1313 .dac_volume_max = 255,
1314 .function_flags = OXYGEN_FUNCTION_2WIRE,
1315 .dac_mclks = OXYGEN_MCLKS(256, 256, 128),
1316 .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
1026 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1317 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1027 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1318 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1028}; 1319};
@@ -1034,6 +1325,9 @@ int __devinit get_xonar_wm87x6_model(struct oxygen *chip,
1034 case 0x838e: 1325 case 0x838e:
1035 chip->model = model_xonar_ds; 1326 chip->model = model_xonar_ds;
1036 break; 1327 break;
1328 case 0x835e:
1329 chip->model = model_xonar_hdav_slim;
1330 break;
1037 default: 1331 default:
1038 return -EINVAL; 1332 return -EINVAL;
1039 } 1333 }
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c
index 833e7180ad2d..304411c1fe4b 100644
--- a/sound/pci/pcxhr/pcxhr_core.c
+++ b/sound/pci/pcxhr/pcxhr_core.c
@@ -1042,11 +1042,11 @@ void pcxhr_msg_tasklet(unsigned long arg)
1042 int i, j; 1042 int i, j;
1043 1043
1044 if (mgr->src_it_dsp & PCXHR_IRQ_FREQ_CHANGE) 1044 if (mgr->src_it_dsp & PCXHR_IRQ_FREQ_CHANGE)
1045 snd_printdd("TASKLET : PCXHR_IRQ_FREQ_CHANGE event occured\n"); 1045 snd_printdd("TASKLET : PCXHR_IRQ_FREQ_CHANGE event occurred\n");
1046 if (mgr->src_it_dsp & PCXHR_IRQ_TIME_CODE) 1046 if (mgr->src_it_dsp & PCXHR_IRQ_TIME_CODE)
1047 snd_printdd("TASKLET : PCXHR_IRQ_TIME_CODE event occured\n"); 1047 snd_printdd("TASKLET : PCXHR_IRQ_TIME_CODE event occurred\n");
1048 if (mgr->src_it_dsp & PCXHR_IRQ_NOTIFY) 1048 if (mgr->src_it_dsp & PCXHR_IRQ_NOTIFY)
1049 snd_printdd("TASKLET : PCXHR_IRQ_NOTIFY event occured\n"); 1049 snd_printdd("TASKLET : PCXHR_IRQ_NOTIFY event occurred\n");
1050 if (mgr->src_it_dsp & (PCXHR_IRQ_FREQ_CHANGE | PCXHR_IRQ_TIME_CODE)) { 1050 if (mgr->src_it_dsp & (PCXHR_IRQ_FREQ_CHANGE | PCXHR_IRQ_TIME_CODE)) {
1051 /* clear events FREQ_CHANGE and TIME_CODE */ 1051 /* clear events FREQ_CHANGE and TIME_CODE */
1052 pcxhr_init_rmh(prmh, CMD_TEST_IT); 1052 pcxhr_init_rmh(prmh, CMD_TEST_IT);
@@ -1055,7 +1055,7 @@ void pcxhr_msg_tasklet(unsigned long arg)
1055 err, prmh->stat[0]); 1055 err, prmh->stat[0]);
1056 } 1056 }
1057 if (mgr->src_it_dsp & PCXHR_IRQ_ASYNC) { 1057 if (mgr->src_it_dsp & PCXHR_IRQ_ASYNC) {
1058 snd_printdd("TASKLET : PCXHR_IRQ_ASYNC event occured\n"); 1058 snd_printdd("TASKLET : PCXHR_IRQ_ASYNC event occurred\n");
1059 1059
1060 pcxhr_init_rmh(prmh, CMD_ASYNC); 1060 pcxhr_init_rmh(prmh, CMD_ASYNC);
1061 prmh->cmd[0] |= 1; /* add SEL_ASYNC_EVENTS */ 1061 prmh->cmd[0] |= 1; /* add SEL_ASYNC_EVENTS */
@@ -1233,7 +1233,7 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1233 reg = PCXHR_INPL(mgr, PCXHR_PLX_L2PCIDB); 1233 reg = PCXHR_INPL(mgr, PCXHR_PLX_L2PCIDB);
1234 PCXHR_OUTPL(mgr, PCXHR_PLX_L2PCIDB, reg); 1234 PCXHR_OUTPL(mgr, PCXHR_PLX_L2PCIDB, reg);
1235 1235
1236 /* timer irq occured */ 1236 /* timer irq occurred */
1237 if (reg & PCXHR_IRQ_TIMER) { 1237 if (reg & PCXHR_IRQ_TIMER) {
1238 int timer_toggle = reg & PCXHR_IRQ_TIMER; 1238 int timer_toggle = reg & PCXHR_IRQ_TIMER;
1239 /* is a 24 bit counter */ 1239 /* is a 24 bit counter */
@@ -1288,7 +1288,7 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1288 if (reg & PCXHR_IRQ_MASK) { 1288 if (reg & PCXHR_IRQ_MASK) {
1289 if (reg & PCXHR_IRQ_ASYNC) { 1289 if (reg & PCXHR_IRQ_ASYNC) {
1290 /* as we didn't request any async notifications, 1290 /* as we didn't request any async notifications,
1291 * some kind of xrun error will probably occured 1291 * some kind of xrun error will probably occurred
1292 */ 1292 */
1293 /* better resynchronize all streams next interrupt : */ 1293 /* better resynchronize all streams next interrupt : */
1294 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID; 1294 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index d19dc052c391..9ff247fc8871 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -150,7 +150,7 @@ MODULE_PARM_DESC(enable, "Enable RME Digi96 soundcard.");
150#define RME96_RCR_BITPOS_F1 28 150#define RME96_RCR_BITPOS_F1 28
151#define RME96_RCR_BITPOS_F2 29 151#define RME96_RCR_BITPOS_F2 29
152 152
153/* Additonal register bits */ 153/* Additional register bits */
154#define RME96_AR_WSEL (1 << 0) 154#define RME96_AR_WSEL (1 << 0)
155#define RME96_AR_ANALOG (1 << 1) 155#define RME96_AR_ANALOG (1 << 1)
156#define RME96_AR_FREQPAD_0 (1 << 2) 156#define RME96_AR_FREQPAD_0 (1 << 2)
@@ -1527,14 +1527,14 @@ snd_rme96_free(void *private_data)
1527static void 1527static void
1528snd_rme96_free_spdif_pcm(struct snd_pcm *pcm) 1528snd_rme96_free_spdif_pcm(struct snd_pcm *pcm)
1529{ 1529{
1530 struct rme96 *rme96 = (struct rme96 *) pcm->private_data; 1530 struct rme96 *rme96 = pcm->private_data;
1531 rme96->spdif_pcm = NULL; 1531 rme96->spdif_pcm = NULL;
1532} 1532}
1533 1533
1534static void 1534static void
1535snd_rme96_free_adat_pcm(struct snd_pcm *pcm) 1535snd_rme96_free_adat_pcm(struct snd_pcm *pcm)
1536{ 1536{
1537 struct rme96 *rme96 = (struct rme96 *) pcm->private_data; 1537 struct rme96 *rme96 = pcm->private_data;
1538 rme96->adat_pcm = NULL; 1538 rme96->adat_pcm = NULL;
1539} 1539}
1540 1540
@@ -1661,7 +1661,7 @@ static void
1661snd_rme96_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 1661snd_rme96_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
1662{ 1662{
1663 int n; 1663 int n;
1664 struct rme96 *rme96 = (struct rme96 *)entry->private_data; 1664 struct rme96 *rme96 = entry->private_data;
1665 1665
1666 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER); 1666 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1667 1667
@@ -2348,7 +2348,7 @@ snd_rme96_probe(struct pci_dev *pci,
2348 if (err < 0) 2348 if (err < 0)
2349 return err; 2349 return err;
2350 card->private_free = snd_rme96_card_free; 2350 card->private_free = snd_rme96_card_free;
2351 rme96 = (struct rme96 *)card->private_data; 2351 rme96 = card->private_data;
2352 rme96->card = card; 2352 rme96->card = card;
2353 rme96->pci = pci; 2353 rme96->pci = pci;
2354 snd_card_set_dev(card, &pci->dev); 2354 snd_card_set_dev(card, &pci->dev);
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index d6fa7bfd9aa1..2d8332416c83 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -60,6 +60,7 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
60 "{RME HDSP-9652}," 60 "{RME HDSP-9652},"
61 "{RME HDSP-9632}}"); 61 "{RME HDSP-9632}}");
62#ifdef HDSP_FW_LOADER 62#ifdef HDSP_FW_LOADER
63MODULE_FIRMWARE("rpm_firmware.bin");
63MODULE_FIRMWARE("multiface_firmware.bin"); 64MODULE_FIRMWARE("multiface_firmware.bin");
64MODULE_FIRMWARE("multiface_firmware_rev11.bin"); 65MODULE_FIRMWARE("multiface_firmware_rev11.bin");
65MODULE_FIRMWARE("digiface_firmware.bin"); 66MODULE_FIRMWARE("digiface_firmware.bin");
@@ -81,6 +82,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
81#define H9632_SS_CHANNELS 12 82#define H9632_SS_CHANNELS 12
82#define H9632_DS_CHANNELS 8 83#define H9632_DS_CHANNELS 8
83#define H9632_QS_CHANNELS 4 84#define H9632_QS_CHANNELS 4
85#define RPM_CHANNELS 6
84 86
85/* Write registers. These are defined as byte-offsets from the iobase value. 87/* Write registers. These are defined as byte-offsets from the iobase value.
86 */ 88 */
@@ -191,6 +193,25 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
191#define HDSP_PhoneGain1 (1<<30) 193#define HDSP_PhoneGain1 (1<<30)
192#define HDSP_QuadSpeed (1<<31) 194#define HDSP_QuadSpeed (1<<31)
193 195
196/* RPM uses some of the registers for special purposes */
197#define HDSP_RPM_Inp12 0x04A00
198#define HDSP_RPM_Inp12_Phon_6dB 0x00800 /* Dolby */
199#define HDSP_RPM_Inp12_Phon_0dB 0x00000 /* .. */
200#define HDSP_RPM_Inp12_Phon_n6dB 0x04000 /* inp_0 */
201#define HDSP_RPM_Inp12_Line_0dB 0x04200 /* Dolby+PRO */
202#define HDSP_RPM_Inp12_Line_n6dB 0x00200 /* PRO */
203
204#define HDSP_RPM_Inp34 0x32000
205#define HDSP_RPM_Inp34_Phon_6dB 0x20000 /* SyncRef1 */
206#define HDSP_RPM_Inp34_Phon_0dB 0x00000 /* .. */
207#define HDSP_RPM_Inp34_Phon_n6dB 0x02000 /* SyncRef2 */
208#define HDSP_RPM_Inp34_Line_0dB 0x30000 /* SyncRef1+SyncRef0 */
209#define HDSP_RPM_Inp34_Line_n6dB 0x10000 /* SyncRef0 */
210
211#define HDSP_RPM_Bypass 0x01000
212
213#define HDSP_RPM_Disconnect 0x00001
214
194#define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1) 215#define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1)
195#define HDSP_ADGainMinus10dBV HDSP_ADGainMask 216#define HDSP_ADGainMinus10dBV HDSP_ADGainMask
196#define HDSP_ADGainPlus4dBu (HDSP_ADGain0) 217#define HDSP_ADGainPlus4dBu (HDSP_ADGain0)
@@ -450,7 +471,7 @@ struct hdsp {
450 u32 creg_spdif; 471 u32 creg_spdif;
451 u32 creg_spdif_stream; 472 u32 creg_spdif_stream;
452 int clock_source_locked; 473 int clock_source_locked;
453 char *card_name; /* digiface/multiface */ 474 char *card_name; /* digiface/multiface/rpm */
454 enum HDSP_IO_Type io_type; /* ditto, but for code use */ 475 enum HDSP_IO_Type io_type; /* ditto, but for code use */
455 unsigned short firmware_rev; 476 unsigned short firmware_rev;
456 unsigned short state; /* stores state bits */ 477 unsigned short state; /* stores state bits */
@@ -612,6 +633,7 @@ static int hdsp_playback_to_output_key (struct hdsp *hdsp, int in, int out)
612 switch (hdsp->io_type) { 633 switch (hdsp->io_type) {
613 case Multiface: 634 case Multiface:
614 case Digiface: 635 case Digiface:
636 case RPM:
615 default: 637 default:
616 if (hdsp->firmware_rev == 0xa) 638 if (hdsp->firmware_rev == 0xa)
617 return (64 * out) + (32 + (in)); 639 return (64 * out) + (32 + (in));
@@ -629,6 +651,7 @@ static int hdsp_input_to_output_key (struct hdsp *hdsp, int in, int out)
629 switch (hdsp->io_type) { 651 switch (hdsp->io_type) {
630 case Multiface: 652 case Multiface:
631 case Digiface: 653 case Digiface:
654 case RPM:
632 default: 655 default:
633 if (hdsp->firmware_rev == 0xa) 656 if (hdsp->firmware_rev == 0xa)
634 return (64 * out) + in; 657 return (64 * out) + in;
@@ -655,7 +678,7 @@ static int hdsp_check_for_iobox (struct hdsp *hdsp)
655{ 678{
656 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; 679 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
657 if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) { 680 if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) {
658 snd_printk ("Hammerfall-DSP: no Digiface or Multiface connected!\n"); 681 snd_printk("Hammerfall-DSP: no IO box connected!\n");
659 hdsp->state &= ~HDSP_FirmwareLoaded; 682 hdsp->state &= ~HDSP_FirmwareLoaded;
660 return -EIO; 683 return -EIO;
661 } 684 }
@@ -680,7 +703,7 @@ static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops,
680 } 703 }
681 } 704 }
682 705
683 snd_printk("Hammerfall-DSP: no Digiface or Multiface connected!\n"); 706 snd_printk("Hammerfall-DSP: no IO box connected!\n");
684 hdsp->state &= ~HDSP_FirmwareLoaded; 707 hdsp->state &= ~HDSP_FirmwareLoaded;
685 return -EIO; 708 return -EIO;
686} 709}
@@ -752,17 +775,21 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp)
752 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); 775 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
753 hdsp_write (hdsp, HDSP_fifoData, 0); 776 hdsp_write (hdsp, HDSP_fifoData, 0);
754 777
755 if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT)) { 778 if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) {
756 hdsp->io_type = Multiface; 779 hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT);
757 hdsp_write (hdsp, HDSP_control2Reg, HDSP_VERSION_BIT); 780 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
758 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); 781 if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT))
759 hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT); 782 hdsp->io_type = RPM;
783 else
784 hdsp->io_type = Multiface;
760 } else { 785 } else {
761 hdsp->io_type = Digiface; 786 hdsp->io_type = Digiface;
762 } 787 }
763 } else { 788 } else {
764 /* firmware was already loaded, get iobox type */ 789 /* firmware was already loaded, get iobox type */
765 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) 790 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
791 hdsp->io_type = RPM;
792 else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
766 hdsp->io_type = Multiface; 793 hdsp->io_type = Multiface;
767 else 794 else
768 hdsp->io_type = Digiface; 795 hdsp->io_type = Digiface;
@@ -1184,6 +1211,7 @@ static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally)
1184 hdsp->channel_map = channel_map_ds; 1211 hdsp->channel_map = channel_map_ds;
1185 } else { 1212 } else {
1186 switch (hdsp->io_type) { 1213 switch (hdsp->io_type) {
1214 case RPM:
1187 case Multiface: 1215 case Multiface:
1188 hdsp->channel_map = channel_map_mf_ss; 1216 hdsp->channel_map = channel_map_mf_ss;
1189 break; 1217 break;
@@ -3231,6 +3259,318 @@ HDSP_PRECISE_POINTER("Precise Pointer", 0),
3231HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), 3259HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0),
3232}; 3260};
3233 3261
3262
3263static int hdsp_rpm_input12(struct hdsp *hdsp)
3264{
3265 switch (hdsp->control_register & HDSP_RPM_Inp12) {
3266 case HDSP_RPM_Inp12_Phon_6dB:
3267 return 0;
3268 case HDSP_RPM_Inp12_Phon_n6dB:
3269 return 2;
3270 case HDSP_RPM_Inp12_Line_0dB:
3271 return 3;
3272 case HDSP_RPM_Inp12_Line_n6dB:
3273 return 4;
3274 }
3275 return 1;
3276}
3277
3278
3279static int snd_hdsp_get_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3280{
3281 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3282
3283 ucontrol->value.enumerated.item[0] = hdsp_rpm_input12(hdsp);
3284 return 0;
3285}
3286
3287
3288static int hdsp_set_rpm_input12(struct hdsp *hdsp, int mode)
3289{
3290 hdsp->control_register &= ~HDSP_RPM_Inp12;
3291 switch (mode) {
3292 case 0:
3293 hdsp->control_register |= HDSP_RPM_Inp12_Phon_6dB;
3294 break;
3295 case 1:
3296 break;
3297 case 2:
3298 hdsp->control_register |= HDSP_RPM_Inp12_Phon_n6dB;
3299 break;
3300 case 3:
3301 hdsp->control_register |= HDSP_RPM_Inp12_Line_0dB;
3302 break;
3303 case 4:
3304 hdsp->control_register |= HDSP_RPM_Inp12_Line_n6dB;
3305 break;
3306 default:
3307 return -1;
3308 }
3309
3310 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3311 return 0;
3312}
3313
3314
3315static int snd_hdsp_put_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3316{
3317 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3318 int change;
3319 int val;
3320
3321 if (!snd_hdsp_use_is_exclusive(hdsp))
3322 return -EBUSY;
3323 val = ucontrol->value.enumerated.item[0];
3324 if (val < 0)
3325 val = 0;
3326 if (val > 4)
3327 val = 4;
3328 spin_lock_irq(&hdsp->lock);
3329 if (val != hdsp_rpm_input12(hdsp))
3330 change = (hdsp_set_rpm_input12(hdsp, val) == 0) ? 1 : 0;
3331 else
3332 change = 0;
3333 spin_unlock_irq(&hdsp->lock);
3334 return change;
3335}
3336
3337
3338static int snd_hdsp_info_rpm_input(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
3339{
3340 static char *texts[] = {"Phono +6dB", "Phono 0dB", "Phono -6dB", "Line 0dB", "Line -6dB"};
3341
3342 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3343 uinfo->count = 1;
3344 uinfo->value.enumerated.items = 5;
3345 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3346 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
3347 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3348 return 0;
3349}
3350
3351
3352static int hdsp_rpm_input34(struct hdsp *hdsp)
3353{
3354 switch (hdsp->control_register & HDSP_RPM_Inp34) {
3355 case HDSP_RPM_Inp34_Phon_6dB:
3356 return 0;
3357 case HDSP_RPM_Inp34_Phon_n6dB:
3358 return 2;
3359 case HDSP_RPM_Inp34_Line_0dB:
3360 return 3;
3361 case HDSP_RPM_Inp34_Line_n6dB:
3362 return 4;
3363 }
3364 return 1;
3365}
3366
3367
3368static int snd_hdsp_get_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3369{
3370 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3371
3372 ucontrol->value.enumerated.item[0] = hdsp_rpm_input34(hdsp);
3373 return 0;
3374}
3375
3376
3377static int hdsp_set_rpm_input34(struct hdsp *hdsp, int mode)
3378{
3379 hdsp->control_register &= ~HDSP_RPM_Inp34;
3380 switch (mode) {
3381 case 0:
3382 hdsp->control_register |= HDSP_RPM_Inp34_Phon_6dB;
3383 break;
3384 case 1:
3385 break;
3386 case 2:
3387 hdsp->control_register |= HDSP_RPM_Inp34_Phon_n6dB;
3388 break;
3389 case 3:
3390 hdsp->control_register |= HDSP_RPM_Inp34_Line_0dB;
3391 break;
3392 case 4:
3393 hdsp->control_register |= HDSP_RPM_Inp34_Line_n6dB;
3394 break;
3395 default:
3396 return -1;
3397 }
3398
3399 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3400 return 0;
3401}
3402
3403
3404static int snd_hdsp_put_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3405{
3406 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3407 int change;
3408 int val;
3409
3410 if (!snd_hdsp_use_is_exclusive(hdsp))
3411 return -EBUSY;
3412 val = ucontrol->value.enumerated.item[0];
3413 if (val < 0)
3414 val = 0;
3415 if (val > 4)
3416 val = 4;
3417 spin_lock_irq(&hdsp->lock);
3418 if (val != hdsp_rpm_input34(hdsp))
3419 change = (hdsp_set_rpm_input34(hdsp, val) == 0) ? 1 : 0;
3420 else
3421 change = 0;
3422 spin_unlock_irq(&hdsp->lock);
3423 return change;
3424}
3425
3426
3427/* RPM Bypass switch */
3428static int hdsp_rpm_bypass(struct hdsp *hdsp)
3429{
3430 return (hdsp->control_register & HDSP_RPM_Bypass) ? 1 : 0;
3431}
3432
3433
3434static int snd_hdsp_get_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3435{
3436 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3437
3438 ucontrol->value.integer.value[0] = hdsp_rpm_bypass(hdsp);
3439 return 0;
3440}
3441
3442
3443static int hdsp_set_rpm_bypass(struct hdsp *hdsp, int on)
3444{
3445 if (on)
3446 hdsp->control_register |= HDSP_RPM_Bypass;
3447 else
3448 hdsp->control_register &= ~HDSP_RPM_Bypass;
3449 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3450 return 0;
3451}
3452
3453
3454static int snd_hdsp_put_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3455{
3456 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3457 int change;
3458 unsigned int val;
3459
3460 if (!snd_hdsp_use_is_exclusive(hdsp))
3461 return -EBUSY;
3462 val = ucontrol->value.integer.value[0] & 1;
3463 spin_lock_irq(&hdsp->lock);
3464 change = (int)val != hdsp_rpm_bypass(hdsp);
3465 hdsp_set_rpm_bypass(hdsp, val);
3466 spin_unlock_irq(&hdsp->lock);
3467 return change;
3468}
3469
3470
3471static int snd_hdsp_info_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
3472{
3473 static char *texts[] = {"On", "Off"};
3474
3475 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3476 uinfo->count = 1;
3477 uinfo->value.enumerated.items = 2;
3478 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3479 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
3480 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3481 return 0;
3482}
3483
3484
3485/* RPM Disconnect switch */
3486static int hdsp_rpm_disconnect(struct hdsp *hdsp)
3487{
3488 return (hdsp->control_register & HDSP_RPM_Disconnect) ? 1 : 0;
3489}
3490
3491
3492static int snd_hdsp_get_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3493{
3494 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3495
3496 ucontrol->value.integer.value[0] = hdsp_rpm_disconnect(hdsp);
3497 return 0;
3498}
3499
3500
3501static int hdsp_set_rpm_disconnect(struct hdsp *hdsp, int on)
3502{
3503 if (on)
3504 hdsp->control_register |= HDSP_RPM_Disconnect;
3505 else
3506 hdsp->control_register &= ~HDSP_RPM_Disconnect;
3507 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3508 return 0;
3509}
3510
3511
3512static int snd_hdsp_put_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3513{
3514 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3515 int change;
3516 unsigned int val;
3517
3518 if (!snd_hdsp_use_is_exclusive(hdsp))
3519 return -EBUSY;
3520 val = ucontrol->value.integer.value[0] & 1;
3521 spin_lock_irq(&hdsp->lock);
3522 change = (int)val != hdsp_rpm_disconnect(hdsp);
3523 hdsp_set_rpm_disconnect(hdsp, val);
3524 spin_unlock_irq(&hdsp->lock);
3525 return change;
3526}
3527
3528static int snd_hdsp_info_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
3529{
3530 static char *texts[] = {"On", "Off"};
3531
3532 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3533 uinfo->count = 1;
3534 uinfo->value.enumerated.items = 2;
3535 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3536 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
3537 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3538 return 0;
3539}
3540
3541static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = {
3542 {
3543 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3544 .name = "RPM Bypass",
3545 .get = snd_hdsp_get_rpm_bypass,
3546 .put = snd_hdsp_put_rpm_bypass,
3547 .info = snd_hdsp_info_rpm_bypass
3548 },
3549 {
3550 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3551 .name = "RPM Disconnect",
3552 .get = snd_hdsp_get_rpm_disconnect,
3553 .put = snd_hdsp_put_rpm_disconnect,
3554 .info = snd_hdsp_info_rpm_disconnect
3555 },
3556 {
3557 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3558 .name = "Input 1/2",
3559 .get = snd_hdsp_get_rpm_input12,
3560 .put = snd_hdsp_put_rpm_input12,
3561 .info = snd_hdsp_info_rpm_input
3562 },
3563 {
3564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3565 .name = "Input 3/4",
3566 .get = snd_hdsp_get_rpm_input34,
3567 .put = snd_hdsp_put_rpm_input34,
3568 .info = snd_hdsp_info_rpm_input
3569 },
3570 HDSP_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
3571 HDSP_MIXER("Mixer", 0)
3572};
3573
3234static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0); 3574static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0);
3235static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; 3575static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK;
3236 3576
@@ -3240,6 +3580,16 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
3240 int err; 3580 int err;
3241 struct snd_kcontrol *kctl; 3581 struct snd_kcontrol *kctl;
3242 3582
3583 if (hdsp->io_type == RPM) {
3584 /* RPM Bypass, Disconnect and Input switches */
3585 for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_rpm_controls); idx++) {
3586 err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_rpm_controls[idx], hdsp));
3587 if (err < 0)
3588 return err;
3589 }
3590 return 0;
3591 }
3592
3243 for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) { 3593 for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) {
3244 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0) 3594 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0)
3245 return err; 3595 return err;
@@ -3284,7 +3634,7 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
3284static void 3634static void
3285snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 3635snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3286{ 3636{
3287 struct hdsp *hdsp = (struct hdsp *) entry->private_data; 3637 struct hdsp *hdsp = entry->private_data;
3288 unsigned int status; 3638 unsigned int status;
3289 unsigned int status2; 3639 unsigned int status2;
3290 char *pref_sync_ref; 3640 char *pref_sync_ref;
@@ -3459,48 +3809,102 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3459 3809
3460 snd_iprintf(buffer, "\n"); 3810 snd_iprintf(buffer, "\n");
3461 3811
3462 switch (hdsp_spdif_in(hdsp)) { 3812 if (hdsp->io_type != RPM) {
3463 case HDSP_SPDIFIN_OPTICAL: 3813 switch (hdsp_spdif_in(hdsp)) {
3464 snd_iprintf(buffer, "IEC958 input: Optical\n"); 3814 case HDSP_SPDIFIN_OPTICAL:
3465 break; 3815 snd_iprintf(buffer, "IEC958 input: Optical\n");
3466 case HDSP_SPDIFIN_COAXIAL: 3816 break;
3467 snd_iprintf(buffer, "IEC958 input: Coaxial\n"); 3817 case HDSP_SPDIFIN_COAXIAL:
3468 break; 3818 snd_iprintf(buffer, "IEC958 input: Coaxial\n");
3469 case HDSP_SPDIFIN_INTERNAL: 3819 break;
3470 snd_iprintf(buffer, "IEC958 input: Internal\n"); 3820 case HDSP_SPDIFIN_INTERNAL:
3471 break; 3821 snd_iprintf(buffer, "IEC958 input: Internal\n");
3472 case HDSP_SPDIFIN_AES: 3822 break;
3473 snd_iprintf(buffer, "IEC958 input: AES\n"); 3823 case HDSP_SPDIFIN_AES:
3474 break; 3824 snd_iprintf(buffer, "IEC958 input: AES\n");
3475 default: 3825 break;
3476 snd_iprintf(buffer, "IEC958 input: ???\n"); 3826 default:
3477 break; 3827 snd_iprintf(buffer, "IEC958 input: ???\n");
3828 break;
3829 }
3478 } 3830 }
3479 3831
3480 if (hdsp->control_register & HDSP_SPDIFOpticalOut) 3832 if (RPM == hdsp->io_type) {
3481 snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n"); 3833 if (hdsp->control_register & HDSP_RPM_Bypass)
3482 else 3834 snd_iprintf(buffer, "RPM Bypass: disabled\n");
3483 snd_iprintf(buffer, "IEC958 output: Coaxial only\n"); 3835 else
3836 snd_iprintf(buffer, "RPM Bypass: enabled\n");
3837 if (hdsp->control_register & HDSP_RPM_Disconnect)
3838 snd_iprintf(buffer, "RPM disconnected\n");
3839 else
3840 snd_iprintf(buffer, "RPM connected\n");
3484 3841
3485 if (hdsp->control_register & HDSP_SPDIFProfessional) 3842 switch (hdsp->control_register & HDSP_RPM_Inp12) {
3486 snd_iprintf(buffer, "IEC958 quality: Professional\n"); 3843 case HDSP_RPM_Inp12_Phon_6dB:
3487 else 3844 snd_iprintf(buffer, "Input 1/2: Phono, 6dB\n");
3488 snd_iprintf(buffer, "IEC958 quality: Consumer\n"); 3845 break;
3846 case HDSP_RPM_Inp12_Phon_0dB:
3847 snd_iprintf(buffer, "Input 1/2: Phono, 0dB\n");
3848 break;
3849 case HDSP_RPM_Inp12_Phon_n6dB:
3850 snd_iprintf(buffer, "Input 1/2: Phono, -6dB\n");
3851 break;
3852 case HDSP_RPM_Inp12_Line_0dB:
3853 snd_iprintf(buffer, "Input 1/2: Line, 0dB\n");
3854 break;
3855 case HDSP_RPM_Inp12_Line_n6dB:
3856 snd_iprintf(buffer, "Input 1/2: Line, -6dB\n");
3857 break;
3858 default:
3859 snd_iprintf(buffer, "Input 1/2: ???\n");
3860 }
3489 3861
3490 if (hdsp->control_register & HDSP_SPDIFEmphasis) 3862 switch (hdsp->control_register & HDSP_RPM_Inp34) {
3491 snd_iprintf(buffer, "IEC958 emphasis: on\n"); 3863 case HDSP_RPM_Inp34_Phon_6dB:
3492 else 3864 snd_iprintf(buffer, "Input 3/4: Phono, 6dB\n");
3493 snd_iprintf(buffer, "IEC958 emphasis: off\n"); 3865 break;
3866 case HDSP_RPM_Inp34_Phon_0dB:
3867 snd_iprintf(buffer, "Input 3/4: Phono, 0dB\n");
3868 break;
3869 case HDSP_RPM_Inp34_Phon_n6dB:
3870 snd_iprintf(buffer, "Input 3/4: Phono, -6dB\n");
3871 break;
3872 case HDSP_RPM_Inp34_Line_0dB:
3873 snd_iprintf(buffer, "Input 3/4: Line, 0dB\n");
3874 break;
3875 case HDSP_RPM_Inp34_Line_n6dB:
3876 snd_iprintf(buffer, "Input 3/4: Line, -6dB\n");
3877 break;
3878 default:
3879 snd_iprintf(buffer, "Input 3/4: ???\n");
3880 }
3494 3881
3495 if (hdsp->control_register & HDSP_SPDIFNonAudio) 3882 } else {
3496 snd_iprintf(buffer, "IEC958 NonAudio: on\n"); 3883 if (hdsp->control_register & HDSP_SPDIFOpticalOut)
3497 else 3884 snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
3498 snd_iprintf(buffer, "IEC958 NonAudio: off\n"); 3885 else
3499 if ((x = hdsp_spdif_sample_rate (hdsp)) != 0) 3886 snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
3500 snd_iprintf (buffer, "IEC958 sample rate: %d\n", x); 3887
3501 else 3888 if (hdsp->control_register & HDSP_SPDIFProfessional)
3502 snd_iprintf (buffer, "IEC958 sample rate: Error flag set\n"); 3889 snd_iprintf(buffer, "IEC958 quality: Professional\n");
3890 else
3891 snd_iprintf(buffer, "IEC958 quality: Consumer\n");
3892
3893 if (hdsp->control_register & HDSP_SPDIFEmphasis)
3894 snd_iprintf(buffer, "IEC958 emphasis: on\n");
3895 else
3896 snd_iprintf(buffer, "IEC958 emphasis: off\n");
3503 3897
3898 if (hdsp->control_register & HDSP_SPDIFNonAudio)
3899 snd_iprintf(buffer, "IEC958 NonAudio: on\n");
3900 else
3901 snd_iprintf(buffer, "IEC958 NonAudio: off\n");
3902 x = hdsp_spdif_sample_rate(hdsp);
3903 if (x != 0)
3904 snd_iprintf(buffer, "IEC958 sample rate: %d\n", x);
3905 else
3906 snd_iprintf(buffer, "IEC958 sample rate: Error flag set\n");
3907 }
3504 snd_iprintf(buffer, "\n"); 3908 snd_iprintf(buffer, "\n");
3505 3909
3506 /* Sync Check */ 3910 /* Sync Check */
@@ -3765,7 +4169,7 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id)
3765 snd_hdsp_midi_input_read (&hdsp->midi[0]); 4169 snd_hdsp_midi_input_read (&hdsp->midi[0]);
3766 } 4170 }
3767 } 4171 }
3768 if (hdsp->io_type != Multiface && hdsp->io_type != H9632 && midi1 && midi1status) { 4172 if (hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632 && midi1 && midi1status) {
3769 if (hdsp->use_midi_tasklet) { 4173 if (hdsp->use_midi_tasklet) {
3770 /* we disable interrupts for this input until processing is done */ 4174 /* we disable interrupts for this input until processing is done */
3771 hdsp->control_register &= ~HDSP_Midi1InterruptEnable; 4175 hdsp->control_register &= ~HDSP_Midi1InterruptEnable;
@@ -4093,7 +4497,7 @@ static struct snd_pcm_hardware snd_hdsp_playback_subinfo =
4093 SNDRV_PCM_RATE_96000), 4497 SNDRV_PCM_RATE_96000),
4094 .rate_min = 32000, 4498 .rate_min = 32000,
4095 .rate_max = 96000, 4499 .rate_max = 96000,
4096 .channels_min = 14, 4500 .channels_min = 6,
4097 .channels_max = HDSP_MAX_CHANNELS, 4501 .channels_max = HDSP_MAX_CHANNELS,
4098 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS, 4502 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
4099 .period_bytes_min = (64 * 4) * 10, 4503 .period_bytes_min = (64 * 4) * 10,
@@ -4122,7 +4526,7 @@ static struct snd_pcm_hardware snd_hdsp_capture_subinfo =
4122 SNDRV_PCM_RATE_96000), 4526 SNDRV_PCM_RATE_96000),
4123 .rate_min = 32000, 4527 .rate_min = 32000,
4124 .rate_max = 96000, 4528 .rate_max = 96000,
4125 .channels_min = 14, 4529 .channels_min = 5,
4126 .channels_max = HDSP_MAX_CHANNELS, 4530 .channels_max = HDSP_MAX_CHANNELS,
4127 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS, 4531 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
4128 .period_bytes_min = (64 * 4) * 10, 4532 .period_bytes_min = (64 * 4) * 10,
@@ -4357,10 +4761,12 @@ static int snd_hdsp_playback_open(struct snd_pcm_substream *substream)
4357 snd_hdsp_hw_rule_rate_out_channels, hdsp, 4761 snd_hdsp_hw_rule_rate_out_channels, hdsp,
4358 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 4762 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4359 4763
4360 hdsp->creg_spdif_stream = hdsp->creg_spdif; 4764 if (RPM != hdsp->io_type) {
4361 hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 4765 hdsp->creg_spdif_stream = hdsp->creg_spdif;
4362 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | 4766 hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
4363 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); 4767 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
4768 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
4769 }
4364 return 0; 4770 return 0;
4365} 4771}
4366 4772
@@ -4375,9 +4781,11 @@ static int snd_hdsp_playback_release(struct snd_pcm_substream *substream)
4375 4781
4376 spin_unlock_irq(&hdsp->lock); 4782 spin_unlock_irq(&hdsp->lock);
4377 4783
4378 hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; 4784 if (RPM != hdsp->io_type) {
4379 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | 4785 hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
4380 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); 4786 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
4787 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
4788 }
4381 return 0; 4789 return 0;
4382} 4790}
4383 4791
@@ -4566,7 +4974,7 @@ static int hdsp_get_peak(struct hdsp *hdsp, struct hdsp_peak_rms __user *peak_rm
4566 4974
4567static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg) 4975static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg)
4568{ 4976{
4569 struct hdsp *hdsp = (struct hdsp *)hw->private_data; 4977 struct hdsp *hdsp = hw->private_data;
4570 void __user *argp = (void __user *)arg; 4978 void __user *argp = (void __user *)arg;
4571 int err; 4979 int err;
4572 4980
@@ -4616,7 +5024,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
4616 if (hdsp->io_type != H9632) 5024 if (hdsp->io_type != H9632)
4617 info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp); 5025 info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp);
4618 info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp); 5026 info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp);
4619 for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i) 5027 for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i)
4620 info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i); 5028 info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
4621 info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp); 5029 info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
4622 info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp); 5030 info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp);
@@ -4636,6 +5044,9 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
4636 info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp); 5044 info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp);
4637 info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp); 5045 info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp);
4638 5046
5047 } else if (hdsp->io_type == RPM) {
5048 info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp);
5049 info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp);
4639 } 5050 }
4640 if (hdsp->io_type == H9632 || hdsp->io_type == H9652) 5051 if (hdsp->io_type == H9632 || hdsp->io_type == H9652)
4641 info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp); 5052 info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
@@ -4844,6 +5255,14 @@ static void snd_hdsp_initialize_channels(struct hdsp *hdsp)
4844 hdsp->ds_in_channels = hdsp->ds_out_channels = MULTIFACE_DS_CHANNELS; 5255 hdsp->ds_in_channels = hdsp->ds_out_channels = MULTIFACE_DS_CHANNELS;
4845 break; 5256 break;
4846 5257
5258 case RPM:
5259 hdsp->card_name = "RME Hammerfall DSP + RPM";
5260 hdsp->ss_in_channels = RPM_CHANNELS-1;
5261 hdsp->ss_out_channels = RPM_CHANNELS;
5262 hdsp->ds_in_channels = RPM_CHANNELS-1;
5263 hdsp->ds_out_channels = RPM_CHANNELS;
5264 break;
5265
4847 default: 5266 default:
4848 /* should never get here */ 5267 /* should never get here */
4849 break; 5268 break;
@@ -4930,6 +5349,9 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp)
4930 5349
4931 /* caution: max length of firmware filename is 30! */ 5350 /* caution: max length of firmware filename is 30! */
4932 switch (hdsp->io_type) { 5351 switch (hdsp->io_type) {
5352 case RPM:
5353 fwfile = "rpm_firmware.bin";
5354 break;
4933 case Multiface: 5355 case Multiface:
4934 if (hdsp->firmware_rev == 0xa) 5356 if (hdsp->firmware_rev == 0xa)
4935 fwfile = "multiface_firmware.bin"; 5357 fwfile = "multiface_firmware.bin";
@@ -5100,7 +5522,9 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
5100 return 0; 5522 return 0;
5101 } else { 5523 } else {
5102 snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n"); 5524 snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n");
5103 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) 5525 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
5526 hdsp->io_type = RPM;
5527 else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
5104 hdsp->io_type = Multiface; 5528 hdsp->io_type = Multiface;
5105 else 5529 else
5106 hdsp->io_type = Digiface; 5530 hdsp->io_type = Digiface;
@@ -5156,7 +5580,7 @@ static int snd_hdsp_free(struct hdsp *hdsp)
5156 5580
5157static void snd_hdsp_card_free(struct snd_card *card) 5581static void snd_hdsp_card_free(struct snd_card *card)
5158{ 5582{
5159 struct hdsp *hdsp = (struct hdsp *) card->private_data; 5583 struct hdsp *hdsp = card->private_data;
5160 5584
5161 if (hdsp) 5585 if (hdsp)
5162 snd_hdsp_free(hdsp); 5586 snd_hdsp_free(hdsp);
@@ -5182,7 +5606,7 @@ static int __devinit snd_hdsp_probe(struct pci_dev *pci,
5182 if (err < 0) 5606 if (err < 0)
5183 return err; 5607 return err;
5184 5608
5185 hdsp = (struct hdsp *) card->private_data; 5609 hdsp = card->private_data;
5186 card->private_free = snd_hdsp_card_free; 5610 card->private_free = snd_hdsp_card_free;
5187 hdsp->dev = dev; 5611 hdsp->dev = dev;
5188 hdsp->pci = pci; 5612 hdsp->pci = pci;
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 0c98ef9156d8..c8e402fc3782 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -8,6 +8,21 @@
8 * Modified 2006-06-01 for AES32 support by Remy Bruno 8 * Modified 2006-06-01 for AES32 support by Remy Bruno
9 * <remy.bruno@trinnov.com> 9 * <remy.bruno@trinnov.com>
10 * 10 *
11 * Modified 2009-04-13 for proper metering by Florian Faber
12 * <faber@faberman.de>
13 *
14 * Modified 2009-04-14 for native float support by Florian Faber
15 * <faber@faberman.de>
16 *
17 * Modified 2009-04-26 fixed bug in rms metering by Florian Faber
18 * <faber@faberman.de>
19 *
20 * Modified 2009-04-30 added hw serial number support by Florian Faber
21 *
22 * Modified 2011-01-14 added S/PDIF input on RayDATs by Adrian Knoth
23 *
24 * Modified 2011-01-25 variable period sizes on RayDAT/AIO by Adrian Knoth
25 *
11 * This program is free software; you can redistribute it and/or modify 26 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 27 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 28 * the Free Software Foundation; either version 2 of the License, or
@@ -35,6 +50,7 @@
35#include <sound/core.h> 50#include <sound/core.h>
36#include <sound/control.h> 51#include <sound/control.h>
37#include <sound/pcm.h> 52#include <sound/pcm.h>
53#include <sound/pcm_params.h>
38#include <sound/info.h> 54#include <sound/info.h>
39#include <sound/asoundef.h> 55#include <sound/asoundef.h>
40#include <sound/rawmidi.h> 56#include <sound/rawmidi.h>
@@ -47,15 +63,6 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
47static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 63static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
48static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ 64static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
49 65
50/* Disable precise pointer at start */
51static int precise_ptr[SNDRV_CARDS];
52
53/* Send all playback to line outs */
54static int line_outs_monitor[SNDRV_CARDS];
55
56/* Enable Analog Outs on Channel 63/64 by default */
57static int enable_monitor[SNDRV_CARDS];
58
59module_param_array(index, int, NULL, 0444); 66module_param_array(index, int, NULL, 0444);
60MODULE_PARM_DESC(index, "Index value for RME HDSPM interface."); 67MODULE_PARM_DESC(index, "Index value for RME HDSPM interface.");
61 68
@@ -65,42 +72,39 @@ MODULE_PARM_DESC(id, "ID string for RME HDSPM interface.");
65module_param_array(enable, bool, NULL, 0444); 72module_param_array(enable, bool, NULL, 0444);
66MODULE_PARM_DESC(enable, "Enable/disable specific HDSPM soundcards."); 73MODULE_PARM_DESC(enable, "Enable/disable specific HDSPM soundcards.");
67 74
68module_param_array(precise_ptr, bool, NULL, 0444);
69MODULE_PARM_DESC(precise_ptr, "Enable or disable precise pointer.");
70
71module_param_array(line_outs_monitor, bool, NULL, 0444);
72MODULE_PARM_DESC(line_outs_monitor,
73 "Send playback streams to analog outs by default.");
74
75module_param_array(enable_monitor, bool, NULL, 0444);
76MODULE_PARM_DESC(enable_monitor,
77 "Enable Analog Out on Channel 63/64 by default.");
78 75
79MODULE_AUTHOR 76MODULE_AUTHOR
80 ("Winfried Ritsch <ritsch_AT_iem.at>, " 77(
81 "Paul Davis <paul@linuxaudiosystems.com>, " 78 "Winfried Ritsch <ritsch_AT_iem.at>, "
82 "Marcus Andersson, Thomas Charbonnel <thomas@undata.org>, " 79 "Paul Davis <paul@linuxaudiosystems.com>, "
83 "Remy Bruno <remy.bruno@trinnov.com>"); 80 "Marcus Andersson, Thomas Charbonnel <thomas@undata.org>, "
81 "Remy Bruno <remy.bruno@trinnov.com>, "
82 "Florian Faber <faberman@linuxproaudio.org>, "
83 "Adrian Knoth <adi@drcomp.erfurt.thur.de>"
84);
84MODULE_DESCRIPTION("RME HDSPM"); 85MODULE_DESCRIPTION("RME HDSPM");
85MODULE_LICENSE("GPL"); 86MODULE_LICENSE("GPL");
86MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); 87MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
87 88
88/* --- Write registers. --- 89/* --- Write registers. ---
89 These are defined as byte-offsets from the iobase value. */ 90 These are defined as byte-offsets from the iobase value. */
90 91
92#define HDSPM_WR_SETTINGS 0
93#define HDSPM_outputBufferAddress 32
94#define HDSPM_inputBufferAddress 36
91#define HDSPM_controlRegister 64 95#define HDSPM_controlRegister 64
92#define HDSPM_interruptConfirmation 96 96#define HDSPM_interruptConfirmation 96
93#define HDSPM_control2Reg 256 /* not in specs ???????? */ 97#define HDSPM_control2Reg 256 /* not in specs ???????? */
94#define HDSPM_freqReg 256 /* for AES32 */ 98#define HDSPM_freqReg 256 /* for AES32 */
95#define HDSPM_midiDataOut0 352 /* just believe in old code */ 99#define HDSPM_midiDataOut0 352 /* just believe in old code */
96#define HDSPM_midiDataOut1 356 100#define HDSPM_midiDataOut1 356
97#define HDSPM_eeprom_wr 384 /* for AES32 */ 101#define HDSPM_eeprom_wr 384 /* for AES32 */
98 102
99/* DMA enable for 64 channels, only Bit 0 is relevant */ 103/* DMA enable for 64 channels, only Bit 0 is relevant */
100#define HDSPM_outputEnableBase 512 /* 512-767 input DMA */ 104#define HDSPM_outputEnableBase 512 /* 512-767 input DMA */
101#define HDSPM_inputEnableBase 768 /* 768-1023 output DMA */ 105#define HDSPM_inputEnableBase 768 /* 768-1023 output DMA */
102 106
103/* 16 page addresses for each of the 64 channels DMA buffer in and out 107/* 16 page addresses for each of the 64 channels DMA buffer in and out
104 (each 64k=16*4k) Buffer must be 4k aligned (which is default i386 ????) */ 108 (each 64k=16*4k) Buffer must be 4k aligned (which is default i386 ????) */
105#define HDSPM_pageAddressBufferOut 8192 109#define HDSPM_pageAddressBufferOut 8192
106#define HDSPM_pageAddressBufferIn (HDSPM_pageAddressBufferOut+64*16*4) 110#define HDSPM_pageAddressBufferIn (HDSPM_pageAddressBufferOut+64*16*4)
@@ -119,22 +123,84 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
119#define HDSPM_statusRegister2 192 123#define HDSPM_statusRegister2 192
120#define HDSPM_timecodeRegister 128 124#define HDSPM_timecodeRegister 128
121 125
126/* AIO, RayDAT */
127#define HDSPM_RD_STATUS_0 0
128#define HDSPM_RD_STATUS_1 64
129#define HDSPM_RD_STATUS_2 128
130#define HDSPM_RD_STATUS_3 192
131
132#define HDSPM_RD_TCO 256
133#define HDSPM_RD_PLL_FREQ 512
134#define HDSPM_WR_TCO 128
135
136#define HDSPM_TCO1_TCO_lock 0x00000001
137#define HDSPM_TCO1_WCK_Input_Range_LSB 0x00000002
138#define HDSPM_TCO1_WCK_Input_Range_MSB 0x00000004
139#define HDSPM_TCO1_LTC_Input_valid 0x00000008
140#define HDSPM_TCO1_WCK_Input_valid 0x00000010
141#define HDSPM_TCO1_Video_Input_Format_NTSC 0x00000020
142#define HDSPM_TCO1_Video_Input_Format_PAL 0x00000040
143
144#define HDSPM_TCO1_set_TC 0x00000100
145#define HDSPM_TCO1_set_drop_frame_flag 0x00000200
146#define HDSPM_TCO1_LTC_Format_LSB 0x00000400
147#define HDSPM_TCO1_LTC_Format_MSB 0x00000800
148
149#define HDSPM_TCO2_TC_run 0x00010000
150#define HDSPM_TCO2_WCK_IO_ratio_LSB 0x00020000
151#define HDSPM_TCO2_WCK_IO_ratio_MSB 0x00040000
152#define HDSPM_TCO2_set_num_drop_frames_LSB 0x00080000
153#define HDSPM_TCO2_set_num_drop_frames_MSB 0x00100000
154#define HDSPM_TCO2_set_jam_sync 0x00200000
155#define HDSPM_TCO2_set_flywheel 0x00400000
156
157#define HDSPM_TCO2_set_01_4 0x01000000
158#define HDSPM_TCO2_set_pull_down 0x02000000
159#define HDSPM_TCO2_set_pull_up 0x04000000
160#define HDSPM_TCO2_set_freq 0x08000000
161#define HDSPM_TCO2_set_term_75R 0x10000000
162#define HDSPM_TCO2_set_input_LSB 0x20000000
163#define HDSPM_TCO2_set_input_MSB 0x40000000
164#define HDSPM_TCO2_set_freq_from_app 0x80000000
165
166
167#define HDSPM_midiDataOut0 352
168#define HDSPM_midiDataOut1 356
169#define HDSPM_midiDataOut2 368
170
122#define HDSPM_midiDataIn0 360 171#define HDSPM_midiDataIn0 360
123#define HDSPM_midiDataIn1 364 172#define HDSPM_midiDataIn1 364
173#define HDSPM_midiDataIn2 372
174#define HDSPM_midiDataIn3 376
124 175
125/* status is data bytes in MIDI-FIFO (0-128) */ 176/* status is data bytes in MIDI-FIFO (0-128) */
126#define HDSPM_midiStatusOut0 384 177#define HDSPM_midiStatusOut0 384
127#define HDSPM_midiStatusOut1 388 178#define HDSPM_midiStatusOut1 388
128#define HDSPM_midiStatusIn0 392 179#define HDSPM_midiStatusOut2 400
129#define HDSPM_midiStatusIn1 396 180
181#define HDSPM_midiStatusIn0 392
182#define HDSPM_midiStatusIn1 396
183#define HDSPM_midiStatusIn2 404
184#define HDSPM_midiStatusIn3 408
130 185
131 186
132/* the meters are regular i/o-mapped registers, but offset 187/* the meters are regular i/o-mapped registers, but offset
133 considerably from the rest. the peak registers are reset 188 considerably from the rest. the peak registers are reset
134 when read; the least-significant 4 bits are full-scale counters; 189 when read; the least-significant 4 bits are full-scale counters;
135 the actual peak value is in the most-significant 24 bits. 190 the actual peak value is in the most-significant 24 bits.
136*/ 191*/
137#define HDSPM_MADI_peakrmsbase 4096 /* 4096-8191 2x64x32Bit Meters */ 192
193#define HDSPM_MADI_INPUT_PEAK 4096
194#define HDSPM_MADI_PLAYBACK_PEAK 4352
195#define HDSPM_MADI_OUTPUT_PEAK 4608
196
197#define HDSPM_MADI_INPUT_RMS_L 6144
198#define HDSPM_MADI_PLAYBACK_RMS_L 6400
199#define HDSPM_MADI_OUTPUT_RMS_L 6656
200
201#define HDSPM_MADI_INPUT_RMS_H 7168
202#define HDSPM_MADI_PLAYBACK_RMS_H 7424
203#define HDSPM_MADI_OUTPUT_RMS_H 7680
138 204
139/* --- Control Register bits --------- */ 205/* --- Control Register bits --------- */
140#define HDSPM_Start (1<<0) /* start engine */ 206#define HDSPM_Start (1<<0) /* start engine */
@@ -143,7 +209,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
143#define HDSPM_Latency1 (1<<2) /* where n is defined */ 209#define HDSPM_Latency1 (1<<2) /* where n is defined */
144#define HDSPM_Latency2 (1<<3) /* by Latency{2,1,0} */ 210#define HDSPM_Latency2 (1<<3) /* by Latency{2,1,0} */
145 211
146#define HDSPM_ClockModeMaster (1<<4) /* 1=Master, 0=Slave/Autosync */ 212#define HDSPM_ClockModeMaster (1<<4) /* 1=Master, 0=Autosync */
213#define HDSPM_c0Master 0x1 /* Master clock bit in settings
214 register [RayDAT, AIO] */
147 215
148#define HDSPM_AudioInterruptEnable (1<<5) /* what do you think ? */ 216#define HDSPM_AudioInterruptEnable (1<<5) /* what do you think ? */
149 217
@@ -157,7 +225,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
157 56channelMODE=0 */ /* MADI ONLY*/ 225 56channelMODE=0 */ /* MADI ONLY*/
158#define HDSPM_Emphasis (1<<10) /* Emphasis */ /* AES32 ONLY */ 226#define HDSPM_Emphasis (1<<10) /* Emphasis */ /* AES32 ONLY */
159 227
160#define HDSPM_AutoInp (1<<11) /* Auto Input (takeover) == Safe Mode, 228#define HDSPM_AutoInp (1<<11) /* Auto Input (takeover) == Safe Mode,
161 0=off, 1=on */ /* MADI ONLY */ 229 0=off, 1=on */ /* MADI ONLY */
162#define HDSPM_Dolby (1<<11) /* Dolby = "NonAudio" ?? */ /* AES32 ONLY */ 230#define HDSPM_Dolby (1<<11) /* Dolby = "NonAudio" ?? */ /* AES32 ONLY */
163 231
@@ -166,22 +234,23 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
166 */ 234 */
167#define HDSPM_InputSelect1 (1<<15) /* should be 0 */ 235#define HDSPM_InputSelect1 (1<<15) /* should be 0 */
168 236
169#define HDSPM_SyncRef0 (1<<16) /* 0=WOrd, 1=MADI */
170#define HDSPM_SyncRef1 (1<<17) /* for AES32: SyncRefN codes the AES # */
171#define HDSPM_SyncRef2 (1<<13) 237#define HDSPM_SyncRef2 (1<<13)
172#define HDSPM_SyncRef3 (1<<25) 238#define HDSPM_SyncRef3 (1<<25)
173 239
174#define HDSPM_SMUX (1<<18) /* Frame ??? */ /* MADI ONY */ 240#define HDSPM_SMUX (1<<18) /* Frame ??? */ /* MADI ONY */
175#define HDSPM_clr_tms (1<<19) /* clear track marker, do not use 241#define HDSPM_clr_tms (1<<19) /* clear track marker, do not use
176 AES additional bits in 242 AES additional bits in
177 lower 5 Audiodatabits ??? */ 243 lower 5 Audiodatabits ??? */
178#define HDSPM_taxi_reset (1<<20) /* ??? */ /* MADI ONLY ? */ 244#define HDSPM_taxi_reset (1<<20) /* ??? */ /* MADI ONLY ? */
179#define HDSPM_WCK48 (1<<20) /* Frame ??? = HDSPM_SMUX */ /* AES32 ONLY */ 245#define HDSPM_WCK48 (1<<20) /* Frame ??? = HDSPM_SMUX */ /* AES32 ONLY */
180 246
181#define HDSPM_Midi0InterruptEnable (1<<22) 247#define HDSPM_Midi0InterruptEnable 0x0400000
182#define HDSPM_Midi1InterruptEnable (1<<23) 248#define HDSPM_Midi1InterruptEnable 0x0800000
249#define HDSPM_Midi2InterruptEnable 0x0200000
250#define HDSPM_Midi3InterruptEnable 0x4000000
183 251
184#define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */ 252#define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */
253#define HDSPe_FLOAT_FORMAT 0x2000000
185 254
186#define HDSPM_DS_DoubleWire (1<<26) /* AES32 ONLY */ 255#define HDSPM_DS_DoubleWire (1<<26) /* AES32 ONLY */
187#define HDSPM_QS_DoubleWire (1<<27) /* AES32 ONLY */ 256#define HDSPM_QS_DoubleWire (1<<27) /* AES32 ONLY */
@@ -198,11 +267,18 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
198#define HDSPM_InputCoaxial (HDSPM_InputSelect0) 267#define HDSPM_InputCoaxial (HDSPM_InputSelect0)
199#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|\ 268#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|\
200 HDSPM_SyncRef2|HDSPM_SyncRef3) 269 HDSPM_SyncRef2|HDSPM_SyncRef3)
201#define HDSPM_SyncRef_Word 0
202#define HDSPM_SyncRef_MADI (HDSPM_SyncRef0)
203 270
204#define HDSPM_SYNC_FROM_WORD 0 /* Preferred sync reference */ 271#define HDSPM_c0_SyncRef0 0x2
205#define HDSPM_SYNC_FROM_MADI 1 /* choices - used by "pref_sync_ref" */ 272#define HDSPM_c0_SyncRef1 0x4
273#define HDSPM_c0_SyncRef2 0x8
274#define HDSPM_c0_SyncRef3 0x10
275#define HDSPM_c0_SyncRefMask (HDSPM_c0_SyncRef0 | HDSPM_c0_SyncRef1 |\
276 HDSPM_c0_SyncRef2 | HDSPM_c0_SyncRef3)
277
278#define HDSPM_SYNC_FROM_WORD 0 /* Preferred sync reference */
279#define HDSPM_SYNC_FROM_MADI 1 /* choices - used by "pref_sync_ref" */
280#define HDSPM_SYNC_FROM_TCO 2
281#define HDSPM_SYNC_FROM_SYNC_IN 3
206 282
207#define HDSPM_Frequency32KHz HDSPM_Frequency0 283#define HDSPM_Frequency32KHz HDSPM_Frequency0
208#define HDSPM_Frequency44_1KHz HDSPM_Frequency1 284#define HDSPM_Frequency44_1KHz HDSPM_Frequency1
@@ -216,17 +292,6 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
216#define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|\ 292#define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|\
217 HDSPM_Frequency0) 293 HDSPM_Frequency0)
218 294
219/* --- for internal discrimination */
220#define HDSPM_CLOCK_SOURCE_AUTOSYNC 0 /* Sample Clock Sources */
221#define HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ 1
222#define HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ 2
223#define HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ 3
224#define HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ 4
225#define HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ 5
226#define HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ 6
227#define HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ 7
228#define HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ 8
229#define HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ 9
230 295
231/* Synccheck Status */ 296/* Synccheck Status */
232#define HDSPM_SYNC_CHECK_NO_LOCK 0 297#define HDSPM_SYNC_CHECK_NO_LOCK 0
@@ -236,14 +301,16 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
236/* AutoSync References - used by "autosync_ref" control switch */ 301/* AutoSync References - used by "autosync_ref" control switch */
237#define HDSPM_AUTOSYNC_FROM_WORD 0 302#define HDSPM_AUTOSYNC_FROM_WORD 0
238#define HDSPM_AUTOSYNC_FROM_MADI 1 303#define HDSPM_AUTOSYNC_FROM_MADI 1
239#define HDSPM_AUTOSYNC_FROM_NONE 2 304#define HDSPM_AUTOSYNC_FROM_TCO 2
305#define HDSPM_AUTOSYNC_FROM_SYNC_IN 3
306#define HDSPM_AUTOSYNC_FROM_NONE 4
240 307
241/* Possible sources of MADI input */ 308/* Possible sources of MADI input */
242#define HDSPM_OPTICAL 0 /* optical */ 309#define HDSPM_OPTICAL 0 /* optical */
243#define HDSPM_COAXIAL 1 /* BNC */ 310#define HDSPM_COAXIAL 1 /* BNC */
244 311
245#define hdspm_encode_latency(x) (((x)<<1) & HDSPM_LatencyMask) 312#define hdspm_encode_latency(x) (((x)<<1) & HDSPM_LatencyMask)
246#define hdspm_decode_latency(x) (((x) & HDSPM_LatencyMask)>>1) 313#define hdspm_decode_latency(x) ((((x) & HDSPM_LatencyMask)>>1))
247 314
248#define hdspm_encode_in(x) (((x)&0x3)<<14) 315#define hdspm_encode_in(x) (((x)&0x3)<<14)
249#define hdspm_decode_in(x) (((x)>>14)&0x3) 316#define hdspm_decode_in(x) (((x)>>14)&0x3)
@@ -270,13 +337,21 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
270#define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1 337#define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1
271 * (like inp0) 338 * (like inp0)
272 */ 339 */
340
273#define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */ 341#define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */
342#define HDSPM_madiSync (1<<18) /* MADI is in sync */
343
344#define HDSPM_tcoLock 0x00000020 /* Optional TCO locked status FOR HDSPe MADI! */
345#define HDSPM_tcoSync 0x10000000 /* Optional TCO sync status */
346
347#define HDSPM_syncInLock 0x00010000 /* Sync In lock status FOR HDSPe MADI! */
348#define HDSPM_syncInSync 0x00020000 /* Sync In sync status FOR HDSPe MADI! */
274 349
275#define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */ 350#define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */
276 /* since 64byte accurate last 6 bits 351 /* since 64byte accurate, last 6 bits are not used */
277 are not used */ 352
353
278 354
279#define HDSPM_madiSync (1<<18) /* MADI is in sync */
280#define HDSPM_DoubleSpeedStatus (1<<19) /* (input) card in double speed */ 355#define HDSPM_DoubleSpeedStatus (1<<19) /* (input) card in double speed */
281 356
282#define HDSPM_madiFreq0 (1<<22) /* system freq 0=error */ 357#define HDSPM_madiFreq0 (1<<22) /* system freq 0=error */
@@ -287,8 +362,19 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
287#define HDSPM_BufferID (1<<26) /* (Double)Buffer ID toggles with 362#define HDSPM_BufferID (1<<26) /* (Double)Buffer ID toggles with
288 * Interrupt 363 * Interrupt
289 */ 364 */
290#define HDSPM_midi0IRQPending (1<<30) /* MIDI IRQ is pending */ 365#define HDSPM_tco_detect 0x08000000
291#define HDSPM_midi1IRQPending (1<<31) /* and aktiv */ 366#define HDSPM_tco_lock 0x20000000
367
368#define HDSPM_s2_tco_detect 0x00000040
369#define HDSPM_s2_AEBO_D 0x00000080
370#define HDSPM_s2_AEBI_D 0x00000100
371
372
373#define HDSPM_midi0IRQPending 0x40000000
374#define HDSPM_midi1IRQPending 0x80000000
375#define HDSPM_midi2IRQPending 0x20000000
376#define HDSPM_midi2IRQPendingAES 0x00000020
377#define HDSPM_midi3IRQPending 0x00200000
292 378
293/* --- status bit helpers */ 379/* --- status bit helpers */
294#define HDSPM_madiFreqMask (HDSPM_madiFreq0|HDSPM_madiFreq1|\ 380#define HDSPM_madiFreqMask (HDSPM_madiFreq0|HDSPM_madiFreq1|\
@@ -305,7 +391,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
305 391
306/* Status2 Register bits */ /* MADI ONLY */ 392/* Status2 Register bits */ /* MADI ONLY */
307 393
308#define HDSPM_version0 (1<<0) /* not realy defined but I guess */ 394#define HDSPM_version0 (1<<0) /* not really defined but I guess */
309#define HDSPM_version1 (1<<1) /* in former cards it was ??? */ 395#define HDSPM_version1 (1<<1) /* in former cards it was ??? */
310#define HDSPM_version2 (1<<2) 396#define HDSPM_version2 (1<<2)
311 397
@@ -317,7 +403,10 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
317#define HDSPM_wc_freq2 (1<<7) /* 100=64, 101=88.2, 110=96, */ 403#define HDSPM_wc_freq2 (1<<7) /* 100=64, 101=88.2, 110=96, */
318/* missing Bit for 111=128, 1000=176.4, 1001=192 */ 404/* missing Bit for 111=128, 1000=176.4, 1001=192 */
319 405
320#define HDSPM_SelSyncRef0 (1<<8) /* Sync Source in slave mode */ 406#define HDSPM_SyncRef0 0x10000 /* Sync Reference */
407#define HDSPM_SyncRef1 0x20000
408
409#define HDSPM_SelSyncRef0 (1<<8) /* AutoSync Source */
321#define HDSPM_SelSyncRef1 (1<<9) /* 000=word, 001=MADI, */ 410#define HDSPM_SelSyncRef1 (1<<9) /* 000=word, 001=MADI, */
322#define HDSPM_SelSyncRef2 (1<<10) /* 111=no valid signal */ 411#define HDSPM_SelSyncRef2 (1<<10) /* 111=no valid signal */
323 412
@@ -331,11 +420,19 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
331#define HDSPM_wcFreq88_2 (HDSPM_wc_freq0|HDSPM_wc_freq2) 420#define HDSPM_wcFreq88_2 (HDSPM_wc_freq0|HDSPM_wc_freq2)
332#define HDSPM_wcFreq96 (HDSPM_wc_freq1|HDSPM_wc_freq2) 421#define HDSPM_wcFreq96 (HDSPM_wc_freq1|HDSPM_wc_freq2)
333 422
423#define HDSPM_status1_F_0 0x0400000
424#define HDSPM_status1_F_1 0x0800000
425#define HDSPM_status1_F_2 0x1000000
426#define HDSPM_status1_F_3 0x2000000
427#define HDSPM_status1_freqMask (HDSPM_status1_F_0|HDSPM_status1_F_1|HDSPM_status1_F_2|HDSPM_status1_F_3)
428
334 429
335#define HDSPM_SelSyncRefMask (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\ 430#define HDSPM_SelSyncRefMask (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\
336 HDSPM_SelSyncRef2) 431 HDSPM_SelSyncRef2)
337#define HDSPM_SelSyncRef_WORD 0 432#define HDSPM_SelSyncRef_WORD 0
338#define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0) 433#define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0)
434#define HDSPM_SelSyncRef_TCO (HDSPM_SelSyncRef1)
435#define HDSPM_SelSyncRef_SyncIn (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1)
339#define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\ 436#define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\
340 HDSPM_SelSyncRef2) 437 HDSPM_SelSyncRef2)
341 438
@@ -345,7 +442,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
345/* status */ 442/* status */
346#define HDSPM_AES32_wcLock 0x0200000 443#define HDSPM_AES32_wcLock 0x0200000
347#define HDSPM_AES32_wcFreq_bit 22 444#define HDSPM_AES32_wcFreq_bit 22
348/* (status >> HDSPM_AES32_wcFreq_bit) & 0xF gives WC frequency (cf function 445/* (status >> HDSPM_AES32_wcFreq_bit) & 0xF gives WC frequency (cf function
349 HDSPM_bit2freq */ 446 HDSPM_bit2freq */
350#define HDSPM_AES32_syncref_bit 16 447#define HDSPM_AES32_syncref_bit 16
351/* (status >> HDSPM_AES32_syncref_bit) & 0xF gives sync source */ 448/* (status >> HDSPM_AES32_syncref_bit) & 0xF gives sync source */
@@ -398,28 +495,349 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
398#define MADI_DS_CHANNELS 32 495#define MADI_DS_CHANNELS 32
399#define MADI_QS_CHANNELS 16 496#define MADI_QS_CHANNELS 16
400 497
498#define RAYDAT_SS_CHANNELS 36
499#define RAYDAT_DS_CHANNELS 20
500#define RAYDAT_QS_CHANNELS 12
501
502#define AIO_IN_SS_CHANNELS 14
503#define AIO_IN_DS_CHANNELS 10
504#define AIO_IN_QS_CHANNELS 8
505#define AIO_OUT_SS_CHANNELS 16
506#define AIO_OUT_DS_CHANNELS 12
507#define AIO_OUT_QS_CHANNELS 10
508
509#define AES32_CHANNELS 16
510
401/* the size of a substream (1 mono data stream) */ 511/* the size of a substream (1 mono data stream) */
402#define HDSPM_CHANNEL_BUFFER_SAMPLES (16*1024) 512#define HDSPM_CHANNEL_BUFFER_SAMPLES (16*1024)
403#define HDSPM_CHANNEL_BUFFER_BYTES (4*HDSPM_CHANNEL_BUFFER_SAMPLES) 513#define HDSPM_CHANNEL_BUFFER_BYTES (4*HDSPM_CHANNEL_BUFFER_SAMPLES)
404 514
405/* the size of the area we need to allocate for DMA transfers. the 515/* the size of the area we need to allocate for DMA transfers. the
406 size is the same regardless of the number of channels, and 516 size is the same regardless of the number of channels, and
407 also the latency to use. 517 also the latency to use.
408 for one direction !!! 518 for one direction !!!
409*/ 519*/
410#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) 520#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
411#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) 521#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
412 522
413/* revisions >= 230 indicate AES32 card */ 523/* revisions >= 230 indicate AES32 card */
414#define HDSPM_AESREVISION 230 524#define HDSPM_MADI_OLD_REV 207
525#define HDSPM_MADI_REV 210
526#define HDSPM_RAYDAT_REV 211
527#define HDSPM_AIO_REV 212
528#define HDSPM_MADIFACE_REV 213
529#define HDSPM_AES_REV 240
530#define HDSPM_AES32_REV 234
531#define HDSPM_AES32_OLD_REV 233
415 532
416/* speed factor modes */ 533/* speed factor modes */
417#define HDSPM_SPEED_SINGLE 0 534#define HDSPM_SPEED_SINGLE 0
418#define HDSPM_SPEED_DOUBLE 1 535#define HDSPM_SPEED_DOUBLE 1
419#define HDSPM_SPEED_QUAD 2 536#define HDSPM_SPEED_QUAD 2
537
420/* names for speed modes */ 538/* names for speed modes */
421static char *hdspm_speed_names[] = { "single", "double", "quad" }; 539static char *hdspm_speed_names[] = { "single", "double", "quad" };
422 540
541static char *texts_autosync_aes_tco[] = { "Word Clock",
542 "AES1", "AES2", "AES3", "AES4",
543 "AES5", "AES6", "AES7", "AES8",
544 "TCO" };
545static char *texts_autosync_aes[] = { "Word Clock",
546 "AES1", "AES2", "AES3", "AES4",
547 "AES5", "AES6", "AES7", "AES8" };
548static char *texts_autosync_madi_tco[] = { "Word Clock",
549 "MADI", "TCO", "Sync In" };
550static char *texts_autosync_madi[] = { "Word Clock",
551 "MADI", "Sync In" };
552
553static char *texts_autosync_raydat_tco[] = {
554 "Word Clock",
555 "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4",
556 "AES", "SPDIF", "TCO", "Sync In"
557};
558static char *texts_autosync_raydat[] = {
559 "Word Clock",
560 "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4",
561 "AES", "SPDIF", "Sync In"
562};
563static char *texts_autosync_aio_tco[] = {
564 "Word Clock",
565 "ADAT", "AES", "SPDIF", "TCO", "Sync In"
566};
567static char *texts_autosync_aio[] = { "Word Clock",
568 "ADAT", "AES", "SPDIF", "Sync In" };
569
570static char *texts_freq[] = {
571 "No Lock",
572 "32 kHz",
573 "44.1 kHz",
574 "48 kHz",
575 "64 kHz",
576 "88.2 kHz",
577 "96 kHz",
578 "128 kHz",
579 "176.4 kHz",
580 "192 kHz"
581};
582
583static char *texts_ports_madi[] = {
584 "MADI.1", "MADI.2", "MADI.3", "MADI.4", "MADI.5", "MADI.6",
585 "MADI.7", "MADI.8", "MADI.9", "MADI.10", "MADI.11", "MADI.12",
586 "MADI.13", "MADI.14", "MADI.15", "MADI.16", "MADI.17", "MADI.18",
587 "MADI.19", "MADI.20", "MADI.21", "MADI.22", "MADI.23", "MADI.24",
588 "MADI.25", "MADI.26", "MADI.27", "MADI.28", "MADI.29", "MADI.30",
589 "MADI.31", "MADI.32", "MADI.33", "MADI.34", "MADI.35", "MADI.36",
590 "MADI.37", "MADI.38", "MADI.39", "MADI.40", "MADI.41", "MADI.42",
591 "MADI.43", "MADI.44", "MADI.45", "MADI.46", "MADI.47", "MADI.48",
592 "MADI.49", "MADI.50", "MADI.51", "MADI.52", "MADI.53", "MADI.54",
593 "MADI.55", "MADI.56", "MADI.57", "MADI.58", "MADI.59", "MADI.60",
594 "MADI.61", "MADI.62", "MADI.63", "MADI.64",
595};
596
597
598static char *texts_ports_raydat_ss[] = {
599 "ADAT1.1", "ADAT1.2", "ADAT1.3", "ADAT1.4", "ADAT1.5", "ADAT1.6",
600 "ADAT1.7", "ADAT1.8", "ADAT2.1", "ADAT2.2", "ADAT2.3", "ADAT2.4",
601 "ADAT2.5", "ADAT2.6", "ADAT2.7", "ADAT2.8", "ADAT3.1", "ADAT3.2",
602 "ADAT3.3", "ADAT3.4", "ADAT3.5", "ADAT3.6", "ADAT3.7", "ADAT3.8",
603 "ADAT4.1", "ADAT4.2", "ADAT4.3", "ADAT4.4", "ADAT4.5", "ADAT4.6",
604 "ADAT4.7", "ADAT4.8",
605 "AES.L", "AES.R",
606 "SPDIF.L", "SPDIF.R"
607};
608
609static char *texts_ports_raydat_ds[] = {
610 "ADAT1.1", "ADAT1.2", "ADAT1.3", "ADAT1.4",
611 "ADAT2.1", "ADAT2.2", "ADAT2.3", "ADAT2.4",
612 "ADAT3.1", "ADAT3.2", "ADAT3.3", "ADAT3.4",
613 "ADAT4.1", "ADAT4.2", "ADAT4.3", "ADAT4.4",
614 "AES.L", "AES.R",
615 "SPDIF.L", "SPDIF.R"
616};
617
618static char *texts_ports_raydat_qs[] = {
619 "ADAT1.1", "ADAT1.2",
620 "ADAT2.1", "ADAT2.2",
621 "ADAT3.1", "ADAT3.2",
622 "ADAT4.1", "ADAT4.2",
623 "AES.L", "AES.R",
624 "SPDIF.L", "SPDIF.R"
625};
626
627
628static char *texts_ports_aio_in_ss[] = {
629 "Analogue.L", "Analogue.R",
630 "AES.L", "AES.R",
631 "SPDIF.L", "SPDIF.R",
632 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6",
633 "ADAT.7", "ADAT.8"
634};
635
636static char *texts_ports_aio_out_ss[] = {
637 "Analogue.L", "Analogue.R",
638 "AES.L", "AES.R",
639 "SPDIF.L", "SPDIF.R",
640 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6",
641 "ADAT.7", "ADAT.8",
642 "Phone.L", "Phone.R"
643};
644
645static char *texts_ports_aio_in_ds[] = {
646 "Analogue.L", "Analogue.R",
647 "AES.L", "AES.R",
648 "SPDIF.L", "SPDIF.R",
649 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4"
650};
651
652static char *texts_ports_aio_out_ds[] = {
653 "Analogue.L", "Analogue.R",
654 "AES.L", "AES.R",
655 "SPDIF.L", "SPDIF.R",
656 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
657 "Phone.L", "Phone.R"
658};
659
660static char *texts_ports_aio_in_qs[] = {
661 "Analogue.L", "Analogue.R",
662 "AES.L", "AES.R",
663 "SPDIF.L", "SPDIF.R",
664 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4"
665};
666
667static char *texts_ports_aio_out_qs[] = {
668 "Analogue.L", "Analogue.R",
669 "AES.L", "AES.R",
670 "SPDIF.L", "SPDIF.R",
671 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
672 "Phone.L", "Phone.R"
673};
674
675static char *texts_ports_aes32[] = {
676 "AES.1", "AES.2", "AES.3", "AES.4", "AES.5", "AES.6", "AES.7",
677 "AES.8", "AES.9.", "AES.10", "AES.11", "AES.12", "AES.13", "AES.14",
678 "AES.15", "AES.16"
679};
680
681/* These tables map the ALSA channels 1..N to the channels that we
682 need to use in order to find the relevant channel buffer. RME
683 refers to this kind of mapping as between "the ADAT channel and
684 the DMA channel." We index it using the logical audio channel,
685 and the value is the DMA channel (i.e. channel buffer number)
686 where the data for that channel can be read/written from/to.
687*/
688
689static char channel_map_unity_ss[HDSPM_MAX_CHANNELS] = {
690 0, 1, 2, 3, 4, 5, 6, 7,
691 8, 9, 10, 11, 12, 13, 14, 15,
692 16, 17, 18, 19, 20, 21, 22, 23,
693 24, 25, 26, 27, 28, 29, 30, 31,
694 32, 33, 34, 35, 36, 37, 38, 39,
695 40, 41, 42, 43, 44, 45, 46, 47,
696 48, 49, 50, 51, 52, 53, 54, 55,
697 56, 57, 58, 59, 60, 61, 62, 63
698};
699
700static char channel_map_raydat_ss[HDSPM_MAX_CHANNELS] = {
701 4, 5, 6, 7, 8, 9, 10, 11, /* ADAT 1 */
702 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT 2 */
703 20, 21, 22, 23, 24, 25, 26, 27, /* ADAT 3 */
704 28, 29, 30, 31, 32, 33, 34, 35, /* ADAT 4 */
705 0, 1, /* AES */
706 2, 3, /* SPDIF */
707 -1, -1, -1, -1,
708 -1, -1, -1, -1, -1, -1, -1, -1,
709 -1, -1, -1, -1, -1, -1, -1, -1,
710 -1, -1, -1, -1, -1, -1, -1, -1,
711};
712
713static char channel_map_raydat_ds[HDSPM_MAX_CHANNELS] = {
714 4, 5, 6, 7, /* ADAT 1 */
715 8, 9, 10, 11, /* ADAT 2 */
716 12, 13, 14, 15, /* ADAT 3 */
717 16, 17, 18, 19, /* ADAT 4 */
718 0, 1, /* AES */
719 2, 3, /* SPDIF */
720 -1, -1, -1, -1,
721 -1, -1, -1, -1, -1, -1, -1, -1,
722 -1, -1, -1, -1, -1, -1, -1, -1,
723 -1, -1, -1, -1, -1, -1, -1, -1,
724 -1, -1, -1, -1, -1, -1, -1, -1,
725 -1, -1, -1, -1, -1, -1, -1, -1,
726};
727
728static char channel_map_raydat_qs[HDSPM_MAX_CHANNELS] = {
729 4, 5, /* ADAT 1 */
730 6, 7, /* ADAT 2 */
731 8, 9, /* ADAT 3 */
732 10, 11, /* ADAT 4 */
733 0, 1, /* AES */
734 2, 3, /* SPDIF */
735 -1, -1, -1, -1,
736 -1, -1, -1, -1, -1, -1, -1, -1,
737 -1, -1, -1, -1, -1, -1, -1, -1,
738 -1, -1, -1, -1, -1, -1, -1, -1,
739 -1, -1, -1, -1, -1, -1, -1, -1,
740 -1, -1, -1, -1, -1, -1, -1, -1,
741 -1, -1, -1, -1, -1, -1, -1, -1,
742};
743
744static char channel_map_aio_in_ss[HDSPM_MAX_CHANNELS] = {
745 0, 1, /* line in */
746 8, 9, /* aes in, */
747 10, 11, /* spdif in */
748 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT in */
749 -1, -1,
750 -1, -1, -1, -1, -1, -1, -1, -1,
751 -1, -1, -1, -1, -1, -1, -1, -1,
752 -1, -1, -1, -1, -1, -1, -1, -1,
753 -1, -1, -1, -1, -1, -1, -1, -1,
754 -1, -1, -1, -1, -1, -1, -1, -1,
755 -1, -1, -1, -1, -1, -1, -1, -1,
756};
757
758static char channel_map_aio_out_ss[HDSPM_MAX_CHANNELS] = {
759 0, 1, /* line out */
760 8, 9, /* aes out */
761 10, 11, /* spdif out */
762 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT out */
763 6, 7, /* phone out */
764 -1, -1, -1, -1, -1, -1, -1, -1,
765 -1, -1, -1, -1, -1, -1, -1, -1,
766 -1, -1, -1, -1, -1, -1, -1, -1,
767 -1, -1, -1, -1, -1, -1, -1, -1,
768 -1, -1, -1, -1, -1, -1, -1, -1,
769 -1, -1, -1, -1, -1, -1, -1, -1,
770};
771
772static char channel_map_aio_in_ds[HDSPM_MAX_CHANNELS] = {
773 0, 1, /* line in */
774 8, 9, /* aes in */
775 10, 11, /* spdif in */
776 12, 14, 16, 18, /* adat in */
777 -1, -1, -1, -1, -1, -1,
778 -1, -1, -1, -1, -1, -1, -1, -1,
779 -1, -1, -1, -1, -1, -1, -1, -1,
780 -1, -1, -1, -1, -1, -1, -1, -1,
781 -1, -1, -1, -1, -1, -1, -1, -1,
782 -1, -1, -1, -1, -1, -1, -1, -1,
783 -1, -1, -1, -1, -1, -1, -1, -1
784};
785
786static char channel_map_aio_out_ds[HDSPM_MAX_CHANNELS] = {
787 0, 1, /* line out */
788 8, 9, /* aes out */
789 10, 11, /* spdif out */
790 12, 14, 16, 18, /* adat out */
791 6, 7, /* phone out */
792 -1, -1, -1, -1,
793 -1, -1, -1, -1, -1, -1, -1, -1,
794 -1, -1, -1, -1, -1, -1, -1, -1,
795 -1, -1, -1, -1, -1, -1, -1, -1,
796 -1, -1, -1, -1, -1, -1, -1, -1,
797 -1, -1, -1, -1, -1, -1, -1, -1,
798 -1, -1, -1, -1, -1, -1, -1, -1
799};
800
801static char channel_map_aio_in_qs[HDSPM_MAX_CHANNELS] = {
802 0, 1, /* line in */
803 8, 9, /* aes in */
804 10, 11, /* spdif in */
805 12, 16, /* adat in */
806 -1, -1, -1, -1, -1, -1, -1, -1,
807 -1, -1, -1, -1, -1, -1, -1, -1,
808 -1, -1, -1, -1, -1, -1, -1, -1,
809 -1, -1, -1, -1, -1, -1, -1, -1,
810 -1, -1, -1, -1, -1, -1, -1, -1,
811 -1, -1, -1, -1, -1, -1, -1, -1,
812 -1, -1, -1, -1, -1, -1, -1, -1
813};
814
815static char channel_map_aio_out_qs[HDSPM_MAX_CHANNELS] = {
816 0, 1, /* line out */
817 8, 9, /* aes out */
818 10, 11, /* spdif out */
819 12, 16, /* adat out */
820 6, 7, /* phone out */
821 -1, -1, -1, -1, -1, -1,
822 -1, -1, -1, -1, -1, -1, -1, -1,
823 -1, -1, -1, -1, -1, -1, -1, -1,
824 -1, -1, -1, -1, -1, -1, -1, -1,
825 -1, -1, -1, -1, -1, -1, -1, -1,
826 -1, -1, -1, -1, -1, -1, -1, -1,
827 -1, -1, -1, -1, -1, -1, -1, -1
828};
829
830static char channel_map_aes32[HDSPM_MAX_CHANNELS] = {
831 0, 1, 2, 3, 4, 5, 6, 7,
832 8, 9, 10, 11, 12, 13, 14, 15,
833 -1, -1, -1, -1, -1, -1, -1, -1,
834 -1, -1, -1, -1, -1, -1, -1, -1,
835 -1, -1, -1, -1, -1, -1, -1, -1,
836 -1, -1, -1, -1, -1, -1, -1, -1,
837 -1, -1, -1, -1, -1, -1, -1, -1,
838 -1, -1, -1, -1, -1, -1, -1, -1
839};
840
423struct hdspm_midi { 841struct hdspm_midi {
424 struct hdspm *hdspm; 842 struct hdspm *hdspm;
425 int id; 843 int id;
@@ -430,6 +848,21 @@ struct hdspm_midi {
430 struct timer_list timer; 848 struct timer_list timer;
431 spinlock_t lock; 849 spinlock_t lock;
432 int pending; 850 int pending;
851 int dataIn;
852 int statusIn;
853 int dataOut;
854 int statusOut;
855 int ie;
856 int irq;
857};
858
859struct hdspm_tco {
860 int input;
861 int framerate;
862 int wordclock;
863 int samplerate;
864 int pull;
865 int term; /* 0 = off, 1 = on */
433}; 866};
434 867
435struct hdspm { 868struct hdspm {
@@ -441,21 +874,39 @@ struct hdspm {
441 char *card_name; /* for procinfo */ 874 char *card_name; /* for procinfo */
442 unsigned short firmware_rev; /* dont know if relevant (yes if AES32)*/ 875 unsigned short firmware_rev; /* dont know if relevant (yes if AES32)*/
443 876
444 unsigned char is_aes32; /* indicates if card is AES32 */ 877 uint8_t io_type;
445 878
446 int precise_ptr; /* use precise pointers, to be tested */
447 int monitor_outs; /* set up monitoring outs init flag */ 879 int monitor_outs; /* set up monitoring outs init flag */
448 880
449 u32 control_register; /* cached value */ 881 u32 control_register; /* cached value */
450 u32 control2_register; /* cached value */ 882 u32 control2_register; /* cached value */
883 u32 settings_register;
451 884
452 struct hdspm_midi midi[2]; 885 struct hdspm_midi midi[4];
453 struct tasklet_struct midi_tasklet; 886 struct tasklet_struct midi_tasklet;
454 887
455 size_t period_bytes; 888 size_t period_bytes;
456 unsigned char ss_channels; /* channels of card in single speed */ 889 unsigned char ss_in_channels;
457 unsigned char ds_channels; /* Double Speed */ 890 unsigned char ds_in_channels;
458 unsigned char qs_channels; /* Quad Speed */ 891 unsigned char qs_in_channels;
892 unsigned char ss_out_channels;
893 unsigned char ds_out_channels;
894 unsigned char qs_out_channels;
895
896 unsigned char max_channels_in;
897 unsigned char max_channels_out;
898
899 signed char *channel_map_in;
900 signed char *channel_map_out;
901
902 signed char *channel_map_in_ss, *channel_map_in_ds, *channel_map_in_qs;
903 signed char *channel_map_out_ss, *channel_map_out_ds, *channel_map_out_qs;
904
905 char **port_names_in;
906 char **port_names_out;
907
908 char **port_names_in_ss, **port_names_in_ds, **port_names_in_qs;
909 char **port_names_out_ss, **port_names_out_ds, **port_names_out_qs;
459 910
460 unsigned char *playback_buffer; /* suitably aligned address */ 911 unsigned char *playback_buffer; /* suitably aligned address */
461 unsigned char *capture_buffer; /* suitably aligned address */ 912 unsigned char *capture_buffer; /* suitably aligned address */
@@ -468,14 +919,13 @@ struct hdspm {
468 int last_internal_sample_rate; 919 int last_internal_sample_rate;
469 int system_sample_rate; 920 int system_sample_rate;
470 921
471 char *channel_map; /* channel map for DS and Quadspeed */
472
473 int dev; /* Hardware vars... */ 922 int dev; /* Hardware vars... */
474 int irq; 923 int irq;
475 unsigned long port; 924 unsigned long port;
476 void __iomem *iobase; 925 void __iomem *iobase;
477 926
478 int irq_count; /* for debug */ 927 int irq_count; /* for debug */
928 int midiPorts;
479 929
480 struct snd_card *card; /* one card */ 930 struct snd_card *card; /* one card */
481 struct snd_pcm *pcm; /* has one pcm */ 931 struct snd_pcm *pcm; /* has one pcm */
@@ -487,28 +937,17 @@ struct hdspm {
487 struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS]; 937 struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS];
488 /* but input to much, so not used */ 938 /* but input to much, so not used */
489 struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS]; 939 struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS];
490 /* full mixer accessable over mixer ioctl or hwdep-device */ 940 /* full mixer accessible over mixer ioctl or hwdep-device */
491 struct hdspm_mixer *mixer; 941 struct hdspm_mixer *mixer;
492 942
493}; 943 struct hdspm_tco *tco; /* NULL if no TCO detected */
494 944
495/* These tables map the ALSA channels 1..N to the channels that we 945 char **texts_autosync;
496 need to use in order to find the relevant channel buffer. RME 946 int texts_autosync_items;
497 refer to this kind of mapping as between "the ADAT channel and 947
498 the DMA channel." We index it using the logical audio channel, 948 cycles_t last_interrupt;
499 and the value is the DMA channel (i.e. channel buffer number)
500 where the data for that channel can be read/written from/to.
501*/
502 949
503static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = { 950 struct hdspm_peak_rms peak_rms;
504 0, 1, 2, 3, 4, 5, 6, 7,
505 8, 9, 10, 11, 12, 13, 14, 15,
506 16, 17, 18, 19, 20, 21, 22, 23,
507 24, 25, 26, 27, 28, 29, 30, 31,
508 32, 33, 34, 35, 36, 37, 38, 39,
509 40, 41, 42, 43, 44, 45, 46, 47,
510 48, 49, 50, 51, 52, 53, 54, 55,
511 56, 57, 58, 59, 60, 61, 62, 63
512}; 951};
513 952
514 953
@@ -532,11 +971,11 @@ static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
532static int __devinit snd_hdspm_create_pcm(struct snd_card *card, 971static int __devinit snd_hdspm_create_pcm(struct snd_card *card,
533 struct hdspm * hdspm); 972 struct hdspm * hdspm);
534 973
535static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm); 974static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm);
536static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm); 975static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm);
537static int hdspm_autosync_ref(struct hdspm * hdspm); 976static int hdspm_autosync_ref(struct hdspm *hdspm);
538static int snd_hdspm_set_defaults(struct hdspm * hdspm); 977static int snd_hdspm_set_defaults(struct hdspm *hdspm);
539static void hdspm_set_sgbuf(struct hdspm * hdspm, 978static void hdspm_set_sgbuf(struct hdspm *hdspm,
540 struct snd_pcm_substream *substream, 979 struct snd_pcm_substream *substream,
541 unsigned int reg, int channels); 980 unsigned int reg, int channels);
542 981
@@ -564,8 +1003,8 @@ static inline unsigned int hdspm_read(struct hdspm * hdspm, unsigned int reg)
564 return readl(hdspm->iobase + reg); 1003 return readl(hdspm->iobase + reg);
565} 1004}
566 1005
567/* for each output channel (chan) I have an Input (in) and Playback (pb) Fader 1006/* for each output channel (chan) I have an Input (in) and Playback (pb) Fader
568 mixer is write only on hardware so we have to cache him for read 1007 mixer is write only on hardware so we have to cache him for read
569 each fader is a u32, but uses only the first 16 bit */ 1008 each fader is a u32, but uses only the first 16 bit */
570 1009
571static inline int hdspm_read_in_gain(struct hdspm * hdspm, unsigned int chan, 1010static inline int hdspm_read_in_gain(struct hdspm * hdspm, unsigned int chan,
@@ -641,37 +1080,75 @@ static int snd_hdspm_use_is_exclusive(struct hdspm *hdspm)
641/* check for external sample rate */ 1080/* check for external sample rate */
642static int hdspm_external_sample_rate(struct hdspm *hdspm) 1081static int hdspm_external_sample_rate(struct hdspm *hdspm)
643{ 1082{
644 if (hdspm->is_aes32) { 1083 unsigned int status, status2, timecode;
645 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 1084 int syncref, rate = 0, rate_bits;
646 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
647 unsigned int timecode =
648 hdspm_read(hdspm, HDSPM_timecodeRegister);
649 1085
650 int syncref = hdspm_autosync_ref(hdspm); 1086 switch (hdspm->io_type) {
1087 case AES32:
1088 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
1089 status = hdspm_read(hdspm, HDSPM_statusRegister);
1090 timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
1091
1092 syncref = hdspm_autosync_ref(hdspm);
651 1093
652 if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD && 1094 if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD &&
653 status & HDSPM_AES32_wcLock) 1095 status & HDSPM_AES32_wcLock)
654 return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) 1096 return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF);
655 & 0xF); 1097
656 if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 && 1098 if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 &&
657 syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 && 1099 syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 &&
658 status2 & (HDSPM_LockAES >> 1100 status2 & (HDSPM_LockAES >>
659 (syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1))) 1101 (syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1)))
660 return HDSPM_bit2freq((timecode >> 1102 return HDSPM_bit2freq((timecode >> (4*(syncref-HDSPM_AES32_AUTOSYNC_FROM_AES1))) & 0xF);
661 (4*(syncref-HDSPM_AES32_AUTOSYNC_FROM_AES1))) & 0xF);
662 return 0; 1103 return 0;
663 } else { 1104 break;
664 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 1105
665 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); 1106 case MADIface:
666 unsigned int rate_bits; 1107 status = hdspm_read(hdspm, HDSPM_statusRegister);
667 int rate = 0; 1108
1109 if (!(status & HDSPM_madiLock)) {
1110 rate = 0; /* no lock */
1111 } else {
1112 switch (status & (HDSPM_status1_freqMask)) {
1113 case HDSPM_status1_F_0*1:
1114 rate = 32000; break;
1115 case HDSPM_status1_F_0*2:
1116 rate = 44100; break;
1117 case HDSPM_status1_F_0*3:
1118 rate = 48000; break;
1119 case HDSPM_status1_F_0*4:
1120 rate = 64000; break;
1121 case HDSPM_status1_F_0*5:
1122 rate = 88200; break;
1123 case HDSPM_status1_F_0*6:
1124 rate = 96000; break;
1125 case HDSPM_status1_F_0*7:
1126 rate = 128000; break;
1127 case HDSPM_status1_F_0*8:
1128 rate = 176400; break;
1129 case HDSPM_status1_F_0*9:
1130 rate = 192000; break;
1131 default:
1132 rate = 0; break;
1133 }
1134 }
1135
1136 break;
1137
1138 case MADI:
1139 case AIO:
1140 case RayDAT:
1141 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
1142 status = hdspm_read(hdspm, HDSPM_statusRegister);
1143 rate = 0;
668 1144
669 /* if wordclock has synced freq and wordclock is valid */ 1145 /* if wordclock has synced freq and wordclock is valid */
670 if ((status2 & HDSPM_wcLock) != 0 && 1146 if ((status2 & HDSPM_wcLock) != 0 &&
671 (status & HDSPM_SelSyncRef0) == 0) { 1147 (status2 & HDSPM_SelSyncRef0) == 0) {
672 1148
673 rate_bits = status2 & HDSPM_wcFreqMask; 1149 rate_bits = status2 & HDSPM_wcFreqMask;
674 1150
1151
675 switch (rate_bits) { 1152 switch (rate_bits) {
676 case HDSPM_wcFreq32: 1153 case HDSPM_wcFreq32:
677 rate = 32000; 1154 rate = 32000;
@@ -691,7 +1168,6 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
691 case HDSPM_wcFreq96: 1168 case HDSPM_wcFreq96:
692 rate = 96000; 1169 rate = 96000;
693 break; 1170 break;
694 /* Quadspeed Bit missing ???? */
695 default: 1171 default:
696 rate = 0; 1172 rate = 0;
697 break; 1173 break;
@@ -702,10 +1178,10 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
702 * word has priority to MADI 1178 * word has priority to MADI
703 */ 1179 */
704 if (rate != 0 && 1180 if (rate != 0 &&
705 (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD) 1181 (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD)
706 return rate; 1182 return rate;
707 1183
708 /* maby a madi input (which is taken if sel sync is madi) */ 1184 /* maybe a madi input (which is taken if sel sync is madi) */
709 if (status & HDSPM_madiLock) { 1185 if (status & HDSPM_madiLock) {
710 rate_bits = status & HDSPM_madiFreqMask; 1186 rate_bits = status & HDSPM_madiFreqMask;
711 1187
@@ -742,36 +1218,35 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
742 break; 1218 break;
743 } 1219 }
744 } 1220 }
745 return rate; 1221 break;
746 } 1222 }
1223
1224 return rate;
747} 1225}
748 1226
749/* Latency function */ 1227/* Latency function */
750static inline void hdspm_compute_period_size(struct hdspm * hdspm) 1228static inline void hdspm_compute_period_size(struct hdspm *hdspm)
751{ 1229{
752 hdspm->period_bytes = 1230 hdspm->period_bytes = 1 << ((hdspm_decode_latency(hdspm->control_register) + 8));
753 1 << ((hdspm_decode_latency(hdspm->control_register) + 8));
754} 1231}
755 1232
756static snd_pcm_uframes_t hdspm_hw_pointer(struct hdspm * hdspm) 1233
1234static snd_pcm_uframes_t hdspm_hw_pointer(struct hdspm *hdspm)
757{ 1235{
758 int position; 1236 int position;
759 1237
760 position = hdspm_read(hdspm, HDSPM_statusRegister); 1238 position = hdspm_read(hdspm, HDSPM_statusRegister);
761 1239
762 if (!hdspm->precise_ptr) 1240 switch (hdspm->io_type) {
763 return (position & HDSPM_BufferID) ? 1241 case RayDAT:
1242 case AIO:
1243 position &= HDSPM_BufferPositionMask;
1244 position /= 4; /* Bytes per sample */
1245 break;
1246 default:
1247 position = (position & HDSPM_BufferID) ?
764 (hdspm->period_bytes / 4) : 0; 1248 (hdspm->period_bytes / 4) : 0;
765 1249 }
766 /* hwpointer comes in bytes and is 64Bytes accurate (by docu since
767 PCI Burst)
768 i have experimented that it is at most 64 Byte to much for playing
769 so substraction of 64 byte should be ok for ALSA, but use it only
770 for application where you know what you do since if you come to
771 near with record pointer it can be a disaster */
772
773 position &= HDSPM_BufferPositionMask;
774 position = ((position - 64) % (2 * hdspm->period_bytes)) / 4;
775 1250
776 return position; 1251 return position;
777} 1252}
@@ -805,7 +1280,7 @@ static void hdspm_silence_playback(struct hdspm *hdspm)
805 } 1280 }
806} 1281}
807 1282
808static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames) 1283static int hdspm_set_interrupt_interval(struct hdspm *s, unsigned int frames)
809{ 1284{
810 int n; 1285 int n;
811 1286
@@ -829,21 +1304,53 @@ static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames)
829 return 0; 1304 return 0;
830} 1305}
831 1306
1307static u64 hdspm_calc_dds_value(struct hdspm *hdspm, u64 period)
1308{
1309 u64 freq_const;
1310
1311 if (period == 0)
1312 return 0;
1313
1314 switch (hdspm->io_type) {
1315 case MADI:
1316 case AES32:
1317 freq_const = 110069313433624ULL;
1318 break;
1319 case RayDAT:
1320 case AIO:
1321 freq_const = 104857600000000ULL;
1322 break;
1323 case MADIface:
1324 freq_const = 131072000000000ULL;
1325 }
1326
1327 return div_u64(freq_const, period);
1328}
1329
1330
832static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) 1331static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
833{ 1332{
834 u64 n; 1333 u64 n;
835 1334
836 if (rate >= 112000) 1335 if (rate >= 112000)
837 rate /= 4; 1336 rate /= 4;
838 else if (rate >= 56000) 1337 else if (rate >= 56000)
839 rate /= 2; 1338 rate /= 2;
840 1339
841 /* RME says n = 104857600000000, but in the windows MADI driver, I see: 1340 switch (hdspm->io_type) {
842// return 104857600000000 / rate; // 100 MHz 1341 case MADIface:
843 return 110100480000000 / rate; // 105 MHz 1342 n = 131072000000000ULL; /* 125 MHz */
844 */ 1343 break;
845 /* n = 104857600000000ULL; */ /* = 2^20 * 10^8 */ 1344 case MADI:
846 n = 110100480000000ULL; /* Value checked for AES32 and MADI */ 1345 case AES32:
1346 n = 110069313433624ULL; /* 105 MHz */
1347 break;
1348 case RayDAT:
1349 case AIO:
1350 n = 104857600000000ULL; /* 100 MHz */
1351 break;
1352 }
1353
847 n = div_u64(n, rate); 1354 n = div_u64(n, rate);
848 /* n should be less than 2^32 for being written to FREQ register */ 1355 /* n should be less than 2^32 for being written to FREQ register */
849 snd_BUG_ON(n >> 32); 1356 snd_BUG_ON(n >> 32);
@@ -864,13 +1371,13 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
864 1371
865 if (!(hdspm->control_register & HDSPM_ClockModeMaster)) { 1372 if (!(hdspm->control_register & HDSPM_ClockModeMaster)) {
866 1373
867 /* SLAVE --- */ 1374 /* SLAVE --- */
868 if (called_internally) { 1375 if (called_internally) {
869 1376
870 /* request from ctl or card initialization 1377 /* request from ctl or card initialization
871 just make a warning an remember setting 1378 just make a warning an remember setting
872 for future master mode switching */ 1379 for future master mode switching */
873 1380
874 snd_printk(KERN_WARNING "HDSPM: " 1381 snd_printk(KERN_WARNING "HDSPM: "
875 "Warning: device is not running " 1382 "Warning: device is not running "
876 "as a clock master.\n"); 1383 "as a clock master.\n");
@@ -907,7 +1414,7 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
907 1414
908 Note that a similar but essentially insoluble problem exists for 1415 Note that a similar but essentially insoluble problem exists for
909 externally-driven rate changes. All we can do is to flag rate 1416 externally-driven rate changes. All we can do is to flag rate
910 changes in the read/write routines. 1417 changes in the read/write routines.
911 */ 1418 */
912 1419
913 if (current_rate <= 48000) 1420 if (current_rate <= 48000)
@@ -975,16 +1482,35 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
975 /* For AES32, need to set DDS value in FREQ register 1482 /* For AES32, need to set DDS value in FREQ register
976 For MADI, also apparently */ 1483 For MADI, also apparently */
977 hdspm_set_dds_value(hdspm, rate); 1484 hdspm_set_dds_value(hdspm, rate);
978 1485
979 if (hdspm->is_aes32 && rate != current_rate) 1486 if (AES32 == hdspm->io_type && rate != current_rate)
980 hdspm_write(hdspm, HDSPM_eeprom_wr, 0); 1487 hdspm_write(hdspm, HDSPM_eeprom_wr, 0);
981
982 /* For AES32 and for MADI (at least rev 204), channel_map needs to
983 * always be channel_map_madi_ss, whatever the sample rate */
984 hdspm->channel_map = channel_map_madi_ss;
985 1488
986 hdspm->system_sample_rate = rate; 1489 hdspm->system_sample_rate = rate;
987 1490
1491 if (rate <= 48000) {
1492 hdspm->channel_map_in = hdspm->channel_map_in_ss;
1493 hdspm->channel_map_out = hdspm->channel_map_out_ss;
1494 hdspm->max_channels_in = hdspm->ss_in_channels;
1495 hdspm->max_channels_out = hdspm->ss_out_channels;
1496 hdspm->port_names_in = hdspm->port_names_in_ss;
1497 hdspm->port_names_out = hdspm->port_names_out_ss;
1498 } else if (rate <= 96000) {
1499 hdspm->channel_map_in = hdspm->channel_map_in_ds;
1500 hdspm->channel_map_out = hdspm->channel_map_out_ds;
1501 hdspm->max_channels_in = hdspm->ds_in_channels;
1502 hdspm->max_channels_out = hdspm->ds_out_channels;
1503 hdspm->port_names_in = hdspm->port_names_in_ds;
1504 hdspm->port_names_out = hdspm->port_names_out_ds;
1505 } else {
1506 hdspm->channel_map_in = hdspm->channel_map_in_qs;
1507 hdspm->channel_map_out = hdspm->channel_map_out_qs;
1508 hdspm->max_channels_in = hdspm->qs_in_channels;
1509 hdspm->max_channels_out = hdspm->qs_out_channels;
1510 hdspm->port_names_in = hdspm->port_names_in_qs;
1511 hdspm->port_names_out = hdspm->port_names_out_qs;
1512 }
1513
988 if (not_set != 0) 1514 if (not_set != 0)
989 return -1; 1515 return -1;
990 1516
@@ -1019,39 +1545,26 @@ static inline unsigned char snd_hdspm_midi_read_byte (struct hdspm *hdspm,
1019 int id) 1545 int id)
1020{ 1546{
1021 /* the hardware already does the relevant bit-mask with 0xff */ 1547 /* the hardware already does the relevant bit-mask with 0xff */
1022 if (id) 1548 return hdspm_read(hdspm, hdspm->midi[id].dataIn);
1023 return hdspm_read(hdspm, HDSPM_midiDataIn1);
1024 else
1025 return hdspm_read(hdspm, HDSPM_midiDataIn0);
1026} 1549}
1027 1550
1028static inline void snd_hdspm_midi_write_byte (struct hdspm *hdspm, int id, 1551static inline void snd_hdspm_midi_write_byte (struct hdspm *hdspm, int id,
1029 int val) 1552 int val)
1030{ 1553{
1031 /* the hardware already does the relevant bit-mask with 0xff */ 1554 /* the hardware already does the relevant bit-mask with 0xff */
1032 if (id) 1555 return hdspm_write(hdspm, hdspm->midi[id].dataOut, val);
1033 hdspm_write(hdspm, HDSPM_midiDataOut1, val);
1034 else
1035 hdspm_write(hdspm, HDSPM_midiDataOut0, val);
1036} 1556}
1037 1557
1038static inline int snd_hdspm_midi_input_available (struct hdspm *hdspm, int id) 1558static inline int snd_hdspm_midi_input_available (struct hdspm *hdspm, int id)
1039{ 1559{
1040 if (id) 1560 return hdspm_read(hdspm, hdspm->midi[id].statusIn) & 0xFF;
1041 return (hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xff);
1042 else
1043 return (hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xff);
1044} 1561}
1045 1562
1046static inline int snd_hdspm_midi_output_possible (struct hdspm *hdspm, int id) 1563static inline int snd_hdspm_midi_output_possible (struct hdspm *hdspm, int id)
1047{ 1564{
1048 int fifo_bytes_used; 1565 int fifo_bytes_used;
1049 1566
1050 if (id) 1567 fifo_bytes_used = hdspm_read(hdspm, hdspm->midi[id].statusOut) & 0xFF;
1051 fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut1);
1052 else
1053 fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut0);
1054 fifo_bytes_used &= 0xff;
1055 1568
1056 if (fifo_bytes_used < 128) 1569 if (fifo_bytes_used < 128)
1057 return 128 - fifo_bytes_used; 1570 return 128 - fifo_bytes_used;
@@ -1074,7 +1587,7 @@ static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
1074 unsigned char buf[128]; 1587 unsigned char buf[128];
1075 1588
1076 /* Output is not interrupt driven */ 1589 /* Output is not interrupt driven */
1077 1590
1078 spin_lock_irqsave (&hmidi->lock, flags); 1591 spin_lock_irqsave (&hmidi->lock, flags);
1079 if (hmidi->output && 1592 if (hmidi->output &&
1080 !snd_rawmidi_transmit_empty (hmidi->output)) { 1593 !snd_rawmidi_transmit_empty (hmidi->output)) {
@@ -1083,11 +1596,11 @@ static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
1083 if (n_pending > 0) { 1596 if (n_pending > 0) {
1084 if (n_pending > (int)sizeof (buf)) 1597 if (n_pending > (int)sizeof (buf))
1085 n_pending = sizeof (buf); 1598 n_pending = sizeof (buf);
1086 1599
1087 to_write = snd_rawmidi_transmit (hmidi->output, buf, 1600 to_write = snd_rawmidi_transmit (hmidi->output, buf,
1088 n_pending); 1601 n_pending);
1089 if (to_write > 0) { 1602 if (to_write > 0) {
1090 for (i = 0; i < to_write; ++i) 1603 for (i = 0; i < to_write; ++i)
1091 snd_hdspm_midi_write_byte (hmidi->hdspm, 1604 snd_hdspm_midi_write_byte (hmidi->hdspm,
1092 hmidi->id, 1605 hmidi->id,
1093 buf[i]); 1606 buf[i]);
@@ -1127,13 +1640,14 @@ static int snd_hdspm_midi_input_read (struct hdspm_midi *hmidi)
1127 } 1640 }
1128 } 1641 }
1129 hmidi->pending = 0; 1642 hmidi->pending = 0;
1130 if (hmidi->id) 1643 spin_unlock_irqrestore(&hmidi->lock, flags);
1131 hmidi->hdspm->control_register |= HDSPM_Midi1InterruptEnable; 1644
1132 else 1645 spin_lock_irqsave(&hmidi->hdspm->lock, flags);
1133 hmidi->hdspm->control_register |= HDSPM_Midi0InterruptEnable; 1646 hmidi->hdspm->control_register |= hmidi->ie;
1134 hdspm_write(hmidi->hdspm, HDSPM_controlRegister, 1647 hdspm_write(hmidi->hdspm, HDSPM_controlRegister,
1135 hmidi->hdspm->control_register); 1648 hmidi->hdspm->control_register);
1136 spin_unlock_irqrestore (&hmidi->lock, flags); 1649 spin_unlock_irqrestore(&hmidi->hdspm->lock, flags);
1650
1137 return snd_hdspm_midi_output_write (hmidi); 1651 return snd_hdspm_midi_output_write (hmidi);
1138} 1652}
1139 1653
@@ -1143,20 +1657,18 @@ snd_hdspm_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
1143 struct hdspm *hdspm; 1657 struct hdspm *hdspm;
1144 struct hdspm_midi *hmidi; 1658 struct hdspm_midi *hmidi;
1145 unsigned long flags; 1659 unsigned long flags;
1146 u32 ie;
1147 1660
1148 hmidi = substream->rmidi->private_data; 1661 hmidi = substream->rmidi->private_data;
1149 hdspm = hmidi->hdspm; 1662 hdspm = hmidi->hdspm;
1150 ie = hmidi->id ? 1663
1151 HDSPM_Midi1InterruptEnable : HDSPM_Midi0InterruptEnable;
1152 spin_lock_irqsave (&hdspm->lock, flags); 1664 spin_lock_irqsave (&hdspm->lock, flags);
1153 if (up) { 1665 if (up) {
1154 if (!(hdspm->control_register & ie)) { 1666 if (!(hdspm->control_register & hmidi->ie)) {
1155 snd_hdspm_flush_midi_input (hdspm, hmidi->id); 1667 snd_hdspm_flush_midi_input (hdspm, hmidi->id);
1156 hdspm->control_register |= ie; 1668 hdspm->control_register |= hmidi->ie;
1157 } 1669 }
1158 } else { 1670 } else {
1159 hdspm->control_register &= ~ie; 1671 hdspm->control_register &= ~hmidi->ie;
1160 } 1672 }
1161 1673
1162 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); 1674 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
@@ -1167,14 +1679,14 @@ static void snd_hdspm_midi_output_timer(unsigned long data)
1167{ 1679{
1168 struct hdspm_midi *hmidi = (struct hdspm_midi *) data; 1680 struct hdspm_midi *hmidi = (struct hdspm_midi *) data;
1169 unsigned long flags; 1681 unsigned long flags;
1170 1682
1171 snd_hdspm_midi_output_write(hmidi); 1683 snd_hdspm_midi_output_write(hmidi);
1172 spin_lock_irqsave (&hmidi->lock, flags); 1684 spin_lock_irqsave (&hmidi->lock, flags);
1173 1685
1174 /* this does not bump hmidi->istimer, because the 1686 /* this does not bump hmidi->istimer, because the
1175 kernel automatically removed the timer when it 1687 kernel automatically removed the timer when it
1176 expired, and we are now adding it back, thus 1688 expired, and we are now adding it back, thus
1177 leaving istimer wherever it was set before. 1689 leaving istimer wherever it was set before.
1178 */ 1690 */
1179 1691
1180 if (hmidi->istimer) { 1692 if (hmidi->istimer) {
@@ -1288,22 +1800,103 @@ static int __devinit snd_hdspm_create_midi (struct snd_card *card,
1288 hdspm->midi[id].hdspm = hdspm; 1800 hdspm->midi[id].hdspm = hdspm;
1289 spin_lock_init (&hdspm->midi[id].lock); 1801 spin_lock_init (&hdspm->midi[id].lock);
1290 1802
1291 sprintf (buf, "%s MIDI %d", card->shortname, id+1); 1803 if (0 == id) {
1292 err = snd_rawmidi_new (card, buf, id, 1, 1, &hdspm->midi[id].rmidi); 1804 if (MADIface == hdspm->io_type) {
1293 if (err < 0) 1805 /* MIDI-over-MADI on HDSPe MADIface */
1294 return err; 1806 hdspm->midi[0].dataIn = HDSPM_midiDataIn2;
1807 hdspm->midi[0].statusIn = HDSPM_midiStatusIn2;
1808 hdspm->midi[0].dataOut = HDSPM_midiDataOut2;
1809 hdspm->midi[0].statusOut = HDSPM_midiStatusOut2;
1810 hdspm->midi[0].ie = HDSPM_Midi2InterruptEnable;
1811 hdspm->midi[0].irq = HDSPM_midi2IRQPending;
1812 } else {
1813 hdspm->midi[0].dataIn = HDSPM_midiDataIn0;
1814 hdspm->midi[0].statusIn = HDSPM_midiStatusIn0;
1815 hdspm->midi[0].dataOut = HDSPM_midiDataOut0;
1816 hdspm->midi[0].statusOut = HDSPM_midiStatusOut0;
1817 hdspm->midi[0].ie = HDSPM_Midi0InterruptEnable;
1818 hdspm->midi[0].irq = HDSPM_midi0IRQPending;
1819 }
1820 } else if (1 == id) {
1821 hdspm->midi[1].dataIn = HDSPM_midiDataIn1;
1822 hdspm->midi[1].statusIn = HDSPM_midiStatusIn1;
1823 hdspm->midi[1].dataOut = HDSPM_midiDataOut1;
1824 hdspm->midi[1].statusOut = HDSPM_midiStatusOut1;
1825 hdspm->midi[1].ie = HDSPM_Midi1InterruptEnable;
1826 hdspm->midi[1].irq = HDSPM_midi1IRQPending;
1827 } else if ((2 == id) && (MADI == hdspm->io_type)) {
1828 /* MIDI-over-MADI on HDSPe MADI */
1829 hdspm->midi[2].dataIn = HDSPM_midiDataIn2;
1830 hdspm->midi[2].statusIn = HDSPM_midiStatusIn2;
1831 hdspm->midi[2].dataOut = HDSPM_midiDataOut2;
1832 hdspm->midi[2].statusOut = HDSPM_midiStatusOut2;
1833 hdspm->midi[2].ie = HDSPM_Midi2InterruptEnable;
1834 hdspm->midi[2].irq = HDSPM_midi2IRQPending;
1835 } else if (2 == id) {
1836 /* TCO MTC, read only */
1837 hdspm->midi[2].dataIn = HDSPM_midiDataIn2;
1838 hdspm->midi[2].statusIn = HDSPM_midiStatusIn2;
1839 hdspm->midi[2].dataOut = -1;
1840 hdspm->midi[2].statusOut = -1;
1841 hdspm->midi[2].ie = HDSPM_Midi2InterruptEnable;
1842 hdspm->midi[2].irq = HDSPM_midi2IRQPendingAES;
1843 } else if (3 == id) {
1844 /* TCO MTC on HDSPe MADI */
1845 hdspm->midi[3].dataIn = HDSPM_midiDataIn3;
1846 hdspm->midi[3].statusIn = HDSPM_midiStatusIn3;
1847 hdspm->midi[3].dataOut = -1;
1848 hdspm->midi[3].statusOut = -1;
1849 hdspm->midi[3].ie = HDSPM_Midi3InterruptEnable;
1850 hdspm->midi[3].irq = HDSPM_midi3IRQPending;
1851 }
1295 1852
1296 sprintf(hdspm->midi[id].rmidi->name, "HDSPM MIDI %d", id+1); 1853 if ((id < 2) || ((2 == id) && ((MADI == hdspm->io_type) ||
1297 hdspm->midi[id].rmidi->private_data = &hdspm->midi[id]; 1854 (MADIface == hdspm->io_type)))) {
1855 if ((id == 0) && (MADIface == hdspm->io_type)) {
1856 sprintf(buf, "%s MIDIoverMADI", card->shortname);
1857 } else if ((id == 2) && (MADI == hdspm->io_type)) {
1858 sprintf(buf, "%s MIDIoverMADI", card->shortname);
1859 } else {
1860 sprintf(buf, "%s MIDI %d", card->shortname, id+1);
1861 }
1862 err = snd_rawmidi_new(card, buf, id, 1, 1,
1863 &hdspm->midi[id].rmidi);
1864 if (err < 0)
1865 return err;
1298 1866
1299 snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 1867 sprintf(hdspm->midi[id].rmidi->name, "%s MIDI %d",
1300 &snd_hdspm_midi_output); 1868 card->id, id+1);
1301 snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_INPUT, 1869 hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
1302 &snd_hdspm_midi_input); 1870
1871 snd_rawmidi_set_ops(hdspm->midi[id].rmidi,
1872 SNDRV_RAWMIDI_STREAM_OUTPUT,
1873 &snd_hdspm_midi_output);
1874 snd_rawmidi_set_ops(hdspm->midi[id].rmidi,
1875 SNDRV_RAWMIDI_STREAM_INPUT,
1876 &snd_hdspm_midi_input);
1877
1878 hdspm->midi[id].rmidi->info_flags |=
1879 SNDRV_RAWMIDI_INFO_OUTPUT |
1880 SNDRV_RAWMIDI_INFO_INPUT |
1881 SNDRV_RAWMIDI_INFO_DUPLEX;
1882 } else {
1883 /* TCO MTC, read only */
1884 sprintf(buf, "%s MTC %d", card->shortname, id+1);
1885 err = snd_rawmidi_new(card, buf, id, 1, 1,
1886 &hdspm->midi[id].rmidi);
1887 if (err < 0)
1888 return err;
1889
1890 sprintf(hdspm->midi[id].rmidi->name,
1891 "%s MTC %d", card->id, id+1);
1892 hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
1893
1894 snd_rawmidi_set_ops(hdspm->midi[id].rmidi,
1895 SNDRV_RAWMIDI_STREAM_INPUT,
1896 &snd_hdspm_midi_input);
1303 1897
1304 hdspm->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | 1898 hdspm->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
1305 SNDRV_RAWMIDI_INFO_INPUT | 1899 }
1306 SNDRV_RAWMIDI_INFO_DUPLEX;
1307 1900
1308 return 0; 1901 return 0;
1309} 1902}
@@ -1312,12 +1905,15 @@ static int __devinit snd_hdspm_create_midi (struct snd_card *card,
1312static void hdspm_midi_tasklet(unsigned long arg) 1905static void hdspm_midi_tasklet(unsigned long arg)
1313{ 1906{
1314 struct hdspm *hdspm = (struct hdspm *)arg; 1907 struct hdspm *hdspm = (struct hdspm *)arg;
1315 1908 int i = 0;
1316 if (hdspm->midi[0].pending) 1909
1317 snd_hdspm_midi_input_read (&hdspm->midi[0]); 1910 while (i < hdspm->midiPorts) {
1318 if (hdspm->midi[1].pending) 1911 if (hdspm->midi[i].pending)
1319 snd_hdspm_midi_input_read (&hdspm->midi[1]); 1912 snd_hdspm_midi_input_read(&hdspm->midi[i]);
1320} 1913
1914 i++;
1915 }
1916}
1321 1917
1322 1918
1323/*----------------------------------------------------------------------------- 1919/*-----------------------------------------------------------------------------
@@ -1326,6 +1922,22 @@ static void hdspm_midi_tasklet(unsigned long arg)
1326 1922
1327/* get the system sample rate which is set */ 1923/* get the system sample rate which is set */
1328 1924
1925
1926/**
1927 * Calculate the real sample rate from the
1928 * current DDS value.
1929 **/
1930static int hdspm_get_system_sample_rate(struct hdspm *hdspm)
1931{
1932 unsigned int period, rate;
1933
1934 period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ);
1935 rate = hdspm_calc_dds_value(hdspm, period);
1936
1937 return rate;
1938}
1939
1940
1329#define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \ 1941#define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \
1330{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 1942{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1331 .name = xname, \ 1943 .name = xname, \
@@ -1340,112 +1952,274 @@ static int snd_hdspm_info_system_sample_rate(struct snd_kcontrol *kcontrol,
1340{ 1952{
1341 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1953 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1342 uinfo->count = 1; 1954 uinfo->count = 1;
1955 uinfo->value.integer.min = 27000;
1956 uinfo->value.integer.max = 207000;
1957 uinfo->value.integer.step = 1;
1343 return 0; 1958 return 0;
1344} 1959}
1345 1960
1961
1346static int snd_hdspm_get_system_sample_rate(struct snd_kcontrol *kcontrol, 1962static int snd_hdspm_get_system_sample_rate(struct snd_kcontrol *kcontrol,
1347 struct snd_ctl_elem_value * 1963 struct snd_ctl_elem_value *
1348 ucontrol) 1964 ucontrol)
1349{ 1965{
1350 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 1966 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1351 1967
1352 ucontrol->value.enumerated.item[0] = hdspm->system_sample_rate; 1968 ucontrol->value.integer.value[0] = hdspm_get_system_sample_rate(hdspm);
1969 return 0;
1970}
1971
1972
1973/**
1974 * Returns the WordClock sample rate class for the given card.
1975 **/
1976static int hdspm_get_wc_sample_rate(struct hdspm *hdspm)
1977{
1978 int status;
1979
1980 switch (hdspm->io_type) {
1981 case RayDAT:
1982 case AIO:
1983 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
1984 return (status >> 16) & 0xF;
1985 break;
1986 default:
1987 break;
1988 }
1989
1990
1991 return 0;
1992}
1993
1994
1995/**
1996 * Returns the TCO sample rate class for the given card.
1997 **/
1998static int hdspm_get_tco_sample_rate(struct hdspm *hdspm)
1999{
2000 int status;
2001
2002 if (hdspm->tco) {
2003 switch (hdspm->io_type) {
2004 case RayDAT:
2005 case AIO:
2006 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
2007 return (status >> 20) & 0xF;
2008 break;
2009 default:
2010 break;
2011 }
2012 }
2013
2014 return 0;
2015}
2016
2017
2018/**
2019 * Returns the SYNC_IN sample rate class for the given card.
2020 **/
2021static int hdspm_get_sync_in_sample_rate(struct hdspm *hdspm)
2022{
2023 int status;
2024
2025 if (hdspm->tco) {
2026 switch (hdspm->io_type) {
2027 case RayDAT:
2028 case AIO:
2029 status = hdspm_read(hdspm, HDSPM_RD_STATUS_2);
2030 return (status >> 12) & 0xF;
2031 break;
2032 default:
2033 break;
2034 }
2035 }
2036
1353 return 0; 2037 return 0;
1354} 2038}
1355 2039
2040
2041/**
2042 * Returns the sample rate class for input source <idx> for
2043 * 'new style' cards like the AIO and RayDAT.
2044 **/
2045static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx)
2046{
2047 int status = hdspm_read(hdspm, HDSPM_RD_STATUS_2);
2048
2049 return (status >> (idx*4)) & 0xF;
2050}
2051
2052
2053
1356#define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ 2054#define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \
1357{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2055{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1358 .name = xname, \ 2056 .name = xname, \
1359 .index = xindex, \ 2057 .private_value = xindex, \
1360 .access = SNDRV_CTL_ELEM_ACCESS_READ, \ 2058 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
1361 .info = snd_hdspm_info_autosync_sample_rate, \ 2059 .info = snd_hdspm_info_autosync_sample_rate, \
1362 .get = snd_hdspm_get_autosync_sample_rate \ 2060 .get = snd_hdspm_get_autosync_sample_rate \
1363} 2061}
1364 2062
2063
1365static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol, 2064static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol,
1366 struct snd_ctl_elem_info *uinfo) 2065 struct snd_ctl_elem_info *uinfo)
1367{ 2066{
1368 static char *texts[] = { "32000", "44100", "48000",
1369 "64000", "88200", "96000",
1370 "128000", "176400", "192000",
1371 "None"
1372 };
1373 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2067 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1374 uinfo->count = 1; 2068 uinfo->count = 1;
1375 uinfo->value.enumerated.items = 10; 2069 uinfo->value.enumerated.items = 10;
2070
1376 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 2071 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1377 uinfo->value.enumerated.item = 2072 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1378 uinfo->value.enumerated.items - 1;
1379 strcpy(uinfo->value.enumerated.name, 2073 strcpy(uinfo->value.enumerated.name,
1380 texts[uinfo->value.enumerated.item]); 2074 texts_freq[uinfo->value.enumerated.item]);
1381 return 0; 2075 return 0;
1382} 2076}
1383 2077
2078
1384static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol, 2079static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol,
1385 struct snd_ctl_elem_value * 2080 struct snd_ctl_elem_value *
1386 ucontrol) 2081 ucontrol)
1387{ 2082{
1388 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2083 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1389 2084
1390 switch (hdspm_external_sample_rate(hdspm)) { 2085 switch (hdspm->io_type) {
1391 case 32000: 2086 case RayDAT:
1392 ucontrol->value.enumerated.item[0] = 0; 2087 switch (kcontrol->private_value) {
1393 break; 2088 case 0:
1394 case 44100: 2089 ucontrol->value.enumerated.item[0] =
1395 ucontrol->value.enumerated.item[0] = 1; 2090 hdspm_get_wc_sample_rate(hdspm);
1396 break; 2091 break;
1397 case 48000: 2092 case 7:
1398 ucontrol->value.enumerated.item[0] = 2; 2093 ucontrol->value.enumerated.item[0] =
1399 break; 2094 hdspm_get_tco_sample_rate(hdspm);
1400 case 64000: 2095 break;
1401 ucontrol->value.enumerated.item[0] = 3; 2096 case 8:
1402 break; 2097 ucontrol->value.enumerated.item[0] =
1403 case 88200: 2098 hdspm_get_sync_in_sample_rate(hdspm);
1404 ucontrol->value.enumerated.item[0] = 4; 2099 break;
1405 break; 2100 default:
1406 case 96000: 2101 ucontrol->value.enumerated.item[0] =
1407 ucontrol->value.enumerated.item[0] = 5; 2102 hdspm_get_s1_sample_rate(hdspm,
1408 break; 2103 kcontrol->private_value-1);
1409 case 128000: 2104 }
1410 ucontrol->value.enumerated.item[0] = 6; 2105
1411 break; 2106 case AIO:
1412 case 176400: 2107 switch (kcontrol->private_value) {
1413 ucontrol->value.enumerated.item[0] = 7; 2108 case 0: /* WC */
1414 break; 2109 ucontrol->value.enumerated.item[0] =
1415 case 192000: 2110 hdspm_get_wc_sample_rate(hdspm);
1416 ucontrol->value.enumerated.item[0] = 8; 2111 break;
1417 break; 2112 case 4: /* TCO */
2113 ucontrol->value.enumerated.item[0] =
2114 hdspm_get_tco_sample_rate(hdspm);
2115 break;
2116 case 5: /* SYNC_IN */
2117 ucontrol->value.enumerated.item[0] =
2118 hdspm_get_sync_in_sample_rate(hdspm);
2119 break;
2120 default:
2121 ucontrol->value.enumerated.item[0] =
2122 hdspm_get_s1_sample_rate(hdspm,
2123 ucontrol->id.index-1);
2124 }
1418 2125
2126 case AES32:
2127
2128 switch (kcontrol->private_value) {
2129 case 0: /* WC */
2130 ucontrol->value.enumerated.item[0] =
2131 hdspm_get_wc_sample_rate(hdspm);
2132 break;
2133 case 9: /* TCO */
2134 ucontrol->value.enumerated.item[0] =
2135 hdspm_get_tco_sample_rate(hdspm);
2136 break;
2137 case 10: /* SYNC_IN */
2138 ucontrol->value.enumerated.item[0] =
2139 hdspm_get_sync_in_sample_rate(hdspm);
2140 break;
2141 default: /* AES1 to AES8 */
2142 ucontrol->value.enumerated.item[0] =
2143 hdspm_get_s1_sample_rate(hdspm,
2144 kcontrol->private_value-1);
2145 break;
2146
2147 }
1419 default: 2148 default:
1420 ucontrol->value.enumerated.item[0] = 9; 2149 break;
1421 } 2150 }
2151
1422 return 0; 2152 return 0;
1423} 2153}
1424 2154
2155
1425#define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex) \ 2156#define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex) \
1426{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2157{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1427 .name = xname, \ 2158 .name = xname, \
1428 .index = xindex, \ 2159 .index = xindex, \
1429 .access = SNDRV_CTL_ELEM_ACCESS_READ, \ 2160 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
1430 .info = snd_hdspm_info_system_clock_mode, \ 2161 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
1431 .get = snd_hdspm_get_system_clock_mode, \ 2162 .info = snd_hdspm_info_system_clock_mode, \
1432} 2163 .get = snd_hdspm_get_system_clock_mode, \
2164 .put = snd_hdspm_put_system_clock_mode, \
2165}
2166
2167
2168/**
2169 * Returns the system clock mode for the given card.
2170 * @returns 0 - master, 1 - slave
2171 **/
2172static int hdspm_system_clock_mode(struct hdspm *hdspm)
2173{
2174 switch (hdspm->io_type) {
2175 case AIO:
2176 case RayDAT:
2177 if (hdspm->settings_register & HDSPM_c0Master)
2178 return 0;
2179 break;
2180
2181 default:
2182 if (hdspm->control_register & HDSPM_ClockModeMaster)
2183 return 0;
2184 }
1433 2185
2186 return 1;
2187}
1434 2188
1435 2189
1436static int hdspm_system_clock_mode(struct hdspm * hdspm) 2190/**
2191 * Sets the system clock mode.
2192 * @param mode 0 - master, 1 - slave
2193 **/
2194static void hdspm_set_system_clock_mode(struct hdspm *hdspm, int mode)
1437{ 2195{
1438 /* Always reflect the hardware info, rme is never wrong !!!! */ 2196 switch (hdspm->io_type) {
2197 case AIO:
2198 case RayDAT:
2199 if (0 == mode)
2200 hdspm->settings_register |= HDSPM_c0Master;
2201 else
2202 hdspm->settings_register &= ~HDSPM_c0Master;
1439 2203
1440 if (hdspm->control_register & HDSPM_ClockModeMaster) 2204 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
1441 return 0; 2205 break;
1442 return 1; 2206
2207 default:
2208 if (0 == mode)
2209 hdspm->control_register |= HDSPM_ClockModeMaster;
2210 else
2211 hdspm->control_register &= ~HDSPM_ClockModeMaster;
2212
2213 hdspm_write(hdspm, HDSPM_controlRegister,
2214 hdspm->control_register);
2215 }
1443} 2216}
1444 2217
2218
1445static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol, 2219static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol,
1446 struct snd_ctl_elem_info *uinfo) 2220 struct snd_ctl_elem_info *uinfo)
1447{ 2221{
1448 static char *texts[] = { "Master", "Slave" }; 2222 static char *texts[] = { "Master", "AutoSync" };
1449 2223
1450 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2224 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1451 uinfo->count = 1; 2225 uinfo->count = 1;
@@ -1463,96 +2237,83 @@ static int snd_hdspm_get_system_clock_mode(struct snd_kcontrol *kcontrol,
1463{ 2237{
1464 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2238 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1465 2239
1466 ucontrol->value.enumerated.item[0] = 2240 ucontrol->value.enumerated.item[0] = hdspm_system_clock_mode(hdspm);
1467 hdspm_system_clock_mode(hdspm);
1468 return 0; 2241 return 0;
1469} 2242}
1470 2243
1471#define HDSPM_CLOCK_SOURCE(xname, xindex) \ 2244static int snd_hdspm_put_system_clock_mode(struct snd_kcontrol *kcontrol,
1472{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2245 struct snd_ctl_elem_value *ucontrol)
1473 .name = xname, \ 2246{
1474 .index = xindex, \ 2247 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1475 .info = snd_hdspm_info_clock_source, \ 2248 int val;
1476 .get = snd_hdspm_get_clock_source, \ 2249
1477 .put = snd_hdspm_put_clock_source \ 2250 if (!snd_hdspm_use_is_exclusive(hdspm))
2251 return -EBUSY;
2252
2253 val = ucontrol->value.enumerated.item[0];
2254 if (val < 0)
2255 val = 0;
2256 else if (val > 1)
2257 val = 1;
2258
2259 hdspm_set_system_clock_mode(hdspm, val);
2260
2261 return 0;
1478} 2262}
1479 2263
2264
2265#define HDSPM_INTERNAL_CLOCK(xname, xindex) \
2266{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2267 .name = xname, \
2268 .index = xindex, \
2269 .info = snd_hdspm_info_clock_source, \
2270 .get = snd_hdspm_get_clock_source, \
2271 .put = snd_hdspm_put_clock_source \
2272}
2273
2274
1480static int hdspm_clock_source(struct hdspm * hdspm) 2275static int hdspm_clock_source(struct hdspm * hdspm)
1481{ 2276{
1482 if (hdspm->control_register & HDSPM_ClockModeMaster) { 2277 switch (hdspm->system_sample_rate) {
1483 switch (hdspm->system_sample_rate) { 2278 case 32000: return 0;
1484 case 32000: 2279 case 44100: return 1;
1485 return 1; 2280 case 48000: return 2;
1486 case 44100: 2281 case 64000: return 3;
1487 return 2; 2282 case 88200: return 4;
1488 case 48000: 2283 case 96000: return 5;
1489 return 3; 2284 case 128000: return 6;
1490 case 64000: 2285 case 176400: return 7;
1491 return 4; 2286 case 192000: return 8;
1492 case 88200:
1493 return 5;
1494 case 96000:
1495 return 6;
1496 case 128000:
1497 return 7;
1498 case 176400:
1499 return 8;
1500 case 192000:
1501 return 9;
1502 default:
1503 return 3;
1504 }
1505 } else {
1506 return 0;
1507 } 2287 }
2288
2289 return -1;
1508} 2290}
1509 2291
1510static int hdspm_set_clock_source(struct hdspm * hdspm, int mode) 2292static int hdspm_set_clock_source(struct hdspm * hdspm, int mode)
1511{ 2293{
1512 int rate; 2294 int rate;
1513 switch (mode) { 2295 switch (mode) {
1514 2296 case 0:
1515 case HDSPM_CLOCK_SOURCE_AUTOSYNC: 2297 rate = 32000; break;
1516 if (hdspm_external_sample_rate(hdspm) != 0) { 2298 case 1:
1517 hdspm->control_register &= ~HDSPM_ClockModeMaster; 2299 rate = 44100; break;
1518 hdspm_write(hdspm, HDSPM_controlRegister, 2300 case 2:
1519 hdspm->control_register); 2301 rate = 48000; break;
1520 return 0; 2302 case 3:
1521 } 2303 rate = 64000; break;
1522 return -1; 2304 case 4:
1523 case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ: 2305 rate = 88200; break;
1524 rate = 32000; 2306 case 5:
1525 break; 2307 rate = 96000; break;
1526 case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ: 2308 case 6:
1527 rate = 44100; 2309 rate = 128000; break;
1528 break; 2310 case 7:
1529 case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ: 2311 rate = 176400; break;
1530 rate = 48000; 2312 case 8:
1531 break; 2313 rate = 192000; break;
1532 case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ:
1533 rate = 64000;
1534 break;
1535 case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ:
1536 rate = 88200;
1537 break;
1538 case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ:
1539 rate = 96000;
1540 break;
1541 case HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ:
1542 rate = 128000;
1543 break;
1544 case HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ:
1545 rate = 176400;
1546 break;
1547 case HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ:
1548 rate = 192000;
1549 break;
1550
1551 default: 2314 default:
1552 rate = 44100; 2315 rate = 48000;
1553 } 2316 }
1554 hdspm->control_register |= HDSPM_ClockModeMaster;
1555 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
1556 hdspm_set_rate(hdspm, rate, 1); 2317 hdspm_set_rate(hdspm, rate, 1);
1557 return 0; 2318 return 0;
1558} 2319}
@@ -1560,25 +2321,16 @@ static int hdspm_set_clock_source(struct hdspm * hdspm, int mode)
1560static int snd_hdspm_info_clock_source(struct snd_kcontrol *kcontrol, 2321static int snd_hdspm_info_clock_source(struct snd_kcontrol *kcontrol,
1561 struct snd_ctl_elem_info *uinfo) 2322 struct snd_ctl_elem_info *uinfo)
1562{ 2323{
1563 static char *texts[] = { "AutoSync",
1564 "Internal 32.0 kHz", "Internal 44.1 kHz",
1565 "Internal 48.0 kHz",
1566 "Internal 64.0 kHz", "Internal 88.2 kHz",
1567 "Internal 96.0 kHz",
1568 "Internal 128.0 kHz", "Internal 176.4 kHz",
1569 "Internal 192.0 kHz"
1570 };
1571
1572 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2324 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1573 uinfo->count = 1; 2325 uinfo->count = 1;
1574 uinfo->value.enumerated.items = 10; 2326 uinfo->value.enumerated.items = 9;
1575 2327
1576 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 2328 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1577 uinfo->value.enumerated.item = 2329 uinfo->value.enumerated.item =
1578 uinfo->value.enumerated.items - 1; 2330 uinfo->value.enumerated.items - 1;
1579 2331
1580 strcpy(uinfo->value.enumerated.name, 2332 strcpy(uinfo->value.enumerated.name,
1581 texts[uinfo->value.enumerated.item]); 2333 texts_freq[uinfo->value.enumerated.item+1]);
1582 2334
1583 return 0; 2335 return 0;
1584} 2336}
@@ -1615,134 +2367,301 @@ static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol,
1615 return change; 2367 return change;
1616} 2368}
1617 2369
1618#define HDSPM_PREF_SYNC_REF(xname, xindex) \
1619{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1620 .name = xname, \
1621 .index = xindex, \
1622 .info = snd_hdspm_info_pref_sync_ref, \
1623 .get = snd_hdspm_get_pref_sync_ref, \
1624 .put = snd_hdspm_put_pref_sync_ref \
1625}
1626 2370
2371#define HDSPM_PREF_SYNC_REF(xname, xindex) \
2372{.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2373 .name = xname, \
2374 .index = xindex, \
2375 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
2376 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2377 .info = snd_hdspm_info_pref_sync_ref, \
2378 .get = snd_hdspm_get_pref_sync_ref, \
2379 .put = snd_hdspm_put_pref_sync_ref \
2380}
2381
2382
2383/**
2384 * Returns the current preferred sync reference setting.
2385 * The semantics of the return value are depending on the
2386 * card, please see the comments for clarification.
2387 **/
1627static int hdspm_pref_sync_ref(struct hdspm * hdspm) 2388static int hdspm_pref_sync_ref(struct hdspm * hdspm)
1628{ 2389{
1629 /* Notice that this looks at the requested sync source, 2390 switch (hdspm->io_type) {
1630 not the one actually in use. 2391 case AES32:
1631 */
1632 if (hdspm->is_aes32) {
1633 switch (hdspm->control_register & HDSPM_SyncRefMask) { 2392 switch (hdspm->control_register & HDSPM_SyncRefMask) {
1634 /* number gives AES index, except for 0 which 2393 case 0: return 0; /* WC */
1635 corresponds to WordClock */ 2394 case HDSPM_SyncRef0: return 1; /* AES 1 */
1636 case 0: return 0; 2395 case HDSPM_SyncRef1: return 2; /* AES 2 */
1637 case HDSPM_SyncRef0: return 1; 2396 case HDSPM_SyncRef1+HDSPM_SyncRef0: return 3; /* AES 3 */
1638 case HDSPM_SyncRef1: return 2; 2397 case HDSPM_SyncRef2: return 4; /* AES 4 */
1639 case HDSPM_SyncRef1+HDSPM_SyncRef0: return 3; 2398 case HDSPM_SyncRef2+HDSPM_SyncRef0: return 5; /* AES 5 */
1640 case HDSPM_SyncRef2: return 4; 2399 case HDSPM_SyncRef2+HDSPM_SyncRef1: return 6; /* AES 6 */
1641 case HDSPM_SyncRef2+HDSPM_SyncRef0: return 5; 2400 case HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0:
1642 case HDSPM_SyncRef2+HDSPM_SyncRef1: return 6; 2401 return 7; /* AES 7 */
1643 case HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0: return 7; 2402 case HDSPM_SyncRef3: return 8; /* AES 8 */
1644 case HDSPM_SyncRef3: return 8; 2403 case HDSPM_SyncRef3+HDSPM_SyncRef0: return 9; /* TCO */
1645 } 2404 }
1646 } else { 2405 break;
1647 switch (hdspm->control_register & HDSPM_SyncRefMask) { 2406
1648 case HDSPM_SyncRef_Word: 2407 case MADI:
1649 return HDSPM_SYNC_FROM_WORD; 2408 case MADIface:
1650 case HDSPM_SyncRef_MADI: 2409 if (hdspm->tco) {
1651 return HDSPM_SYNC_FROM_MADI; 2410 switch (hdspm->control_register & HDSPM_SyncRefMask) {
2411 case 0: return 0; /* WC */
2412 case HDSPM_SyncRef0: return 1; /* MADI */
2413 case HDSPM_SyncRef1: return 2; /* TCO */
2414 case HDSPM_SyncRef1+HDSPM_SyncRef0:
2415 return 3; /* SYNC_IN */
2416 }
2417 } else {
2418 switch (hdspm->control_register & HDSPM_SyncRefMask) {
2419 case 0: return 0; /* WC */
2420 case HDSPM_SyncRef0: return 1; /* MADI */
2421 case HDSPM_SyncRef1+HDSPM_SyncRef0:
2422 return 2; /* SYNC_IN */
2423 }
2424 }
2425 break;
2426
2427 case RayDAT:
2428 if (hdspm->tco) {
2429 switch ((hdspm->settings_register &
2430 HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
2431 case 0: return 0; /* WC */
2432 case 3: return 1; /* ADAT 1 */
2433 case 4: return 2; /* ADAT 2 */
2434 case 5: return 3; /* ADAT 3 */
2435 case 6: return 4; /* ADAT 4 */
2436 case 1: return 5; /* AES */
2437 case 2: return 6; /* SPDIF */
2438 case 9: return 7; /* TCO */
2439 case 10: return 8; /* SYNC_IN */
2440 }
2441 } else {
2442 switch ((hdspm->settings_register &
2443 HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
2444 case 0: return 0; /* WC */
2445 case 3: return 1; /* ADAT 1 */
2446 case 4: return 2; /* ADAT 2 */
2447 case 5: return 3; /* ADAT 3 */
2448 case 6: return 4; /* ADAT 4 */
2449 case 1: return 5; /* AES */
2450 case 2: return 6; /* SPDIF */
2451 case 10: return 7; /* SYNC_IN */
2452 }
1652 } 2453 }
2454
2455 break;
2456
2457 case AIO:
2458 if (hdspm->tco) {
2459 switch ((hdspm->settings_register &
2460 HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
2461 case 0: return 0; /* WC */
2462 case 3: return 1; /* ADAT */
2463 case 1: return 2; /* AES */
2464 case 2: return 3; /* SPDIF */
2465 case 9: return 4; /* TCO */
2466 case 10: return 5; /* SYNC_IN */
2467 }
2468 } else {
2469 switch ((hdspm->settings_register &
2470 HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
2471 case 0: return 0; /* WC */
2472 case 3: return 1; /* ADAT */
2473 case 1: return 2; /* AES */
2474 case 2: return 3; /* SPDIF */
2475 case 10: return 4; /* SYNC_IN */
2476 }
2477 }
2478
2479 break;
1653 } 2480 }
1654 2481
1655 return HDSPM_SYNC_FROM_WORD; 2482 return -1;
1656} 2483}
1657 2484
2485
2486/**
2487 * Set the preferred sync reference to <pref>. The semantics
2488 * of <pref> are depending on the card type, see the comments
2489 * for clarification.
2490 **/
1658static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref) 2491static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref)
1659{ 2492{
1660 hdspm->control_register &= ~HDSPM_SyncRefMask; 2493 int p = 0;
1661 2494
1662 if (hdspm->is_aes32) { 2495 switch (hdspm->io_type) {
2496 case AES32:
2497 hdspm->control_register &= ~HDSPM_SyncRefMask;
1663 switch (pref) { 2498 switch (pref) {
1664 case 0: 2499 case 0: /* WC */
1665 hdspm->control_register |= 0; 2500 break;
1666 break; 2501 case 1: /* AES 1 */
1667 case 1: 2502 hdspm->control_register |= HDSPM_SyncRef0;
1668 hdspm->control_register |= HDSPM_SyncRef0; 2503 break;
1669 break; 2504 case 2: /* AES 2 */
1670 case 2: 2505 hdspm->control_register |= HDSPM_SyncRef1;
1671 hdspm->control_register |= HDSPM_SyncRef1; 2506 break;
1672 break; 2507 case 3: /* AES 3 */
1673 case 3: 2508 hdspm->control_register |=
1674 hdspm->control_register |= HDSPM_SyncRef1+HDSPM_SyncRef0; 2509 HDSPM_SyncRef1+HDSPM_SyncRef0;
1675 break; 2510 break;
1676 case 4: 2511 case 4: /* AES 4 */
1677 hdspm->control_register |= HDSPM_SyncRef2; 2512 hdspm->control_register |= HDSPM_SyncRef2;
1678 break;
1679 case 5:
1680 hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef0;
1681 break;
1682 case 6:
1683 hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef1;
1684 break;
1685 case 7:
1686 hdspm->control_register |=
1687 HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0;
1688 break;
1689 case 8:
1690 hdspm->control_register |= HDSPM_SyncRef3;
1691 break;
1692 default:
1693 return -1;
1694 }
1695 } else {
1696 switch (pref) {
1697 case HDSPM_SYNC_FROM_MADI:
1698 hdspm->control_register |= HDSPM_SyncRef_MADI;
1699 break; 2513 break;
1700 case HDSPM_SYNC_FROM_WORD: 2514 case 5: /* AES 5 */
1701 hdspm->control_register |= HDSPM_SyncRef_Word; 2515 hdspm->control_register |=
2516 HDSPM_SyncRef2+HDSPM_SyncRef0;
2517 break;
2518 case 6: /* AES 6 */
2519 hdspm->control_register |=
2520 HDSPM_SyncRef2+HDSPM_SyncRef1;
2521 break;
2522 case 7: /* AES 7 */
2523 hdspm->control_register |=
2524 HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0;
2525 break;
2526 case 8: /* AES 8 */
2527 hdspm->control_register |= HDSPM_SyncRef3;
2528 break;
2529 case 9: /* TCO */
2530 hdspm->control_register |=
2531 HDSPM_SyncRef3+HDSPM_SyncRef0;
1702 break; 2532 break;
1703 default: 2533 default:
1704 return -1; 2534 return -1;
1705 } 2535 }
2536
2537 break;
2538
2539 case MADI:
2540 case MADIface:
2541 hdspm->control_register &= ~HDSPM_SyncRefMask;
2542 if (hdspm->tco) {
2543 switch (pref) {
2544 case 0: /* WC */
2545 break;
2546 case 1: /* MADI */
2547 hdspm->control_register |= HDSPM_SyncRef0;
2548 break;
2549 case 2: /* TCO */
2550 hdspm->control_register |= HDSPM_SyncRef1;
2551 break;
2552 case 3: /* SYNC_IN */
2553 hdspm->control_register |=
2554 HDSPM_SyncRef0+HDSPM_SyncRef1;
2555 break;
2556 default:
2557 return -1;
2558 }
2559 } else {
2560 switch (pref) {
2561 case 0: /* WC */
2562 break;
2563 case 1: /* MADI */
2564 hdspm->control_register |= HDSPM_SyncRef0;
2565 break;
2566 case 2: /* SYNC_IN */
2567 hdspm->control_register |=
2568 HDSPM_SyncRef0+HDSPM_SyncRef1;
2569 break;
2570 default:
2571 return -1;
2572 }
2573 }
2574
2575 break;
2576
2577 case RayDAT:
2578 if (hdspm->tco) {
2579 switch (pref) {
2580 case 0: p = 0; break; /* WC */
2581 case 1: p = 3; break; /* ADAT 1 */
2582 case 2: p = 4; break; /* ADAT 2 */
2583 case 3: p = 5; break; /* ADAT 3 */
2584 case 4: p = 6; break; /* ADAT 4 */
2585 case 5: p = 1; break; /* AES */
2586 case 6: p = 2; break; /* SPDIF */
2587 case 7: p = 9; break; /* TCO */
2588 case 8: p = 10; break; /* SYNC_IN */
2589 default: return -1;
2590 }
2591 } else {
2592 switch (pref) {
2593 case 0: p = 0; break; /* WC */
2594 case 1: p = 3; break; /* ADAT 1 */
2595 case 2: p = 4; break; /* ADAT 2 */
2596 case 3: p = 5; break; /* ADAT 3 */
2597 case 4: p = 6; break; /* ADAT 4 */
2598 case 5: p = 1; break; /* AES */
2599 case 6: p = 2; break; /* SPDIF */
2600 case 7: p = 10; break; /* SYNC_IN */
2601 default: return -1;
2602 }
2603 }
2604 break;
2605
2606 case AIO:
2607 if (hdspm->tco) {
2608 switch (pref) {
2609 case 0: p = 0; break; /* WC */
2610 case 1: p = 3; break; /* ADAT */
2611 case 2: p = 1; break; /* AES */
2612 case 3: p = 2; break; /* SPDIF */
2613 case 4: p = 9; break; /* TCO */
2614 case 5: p = 10; break; /* SYNC_IN */
2615 default: return -1;
2616 }
2617 } else {
2618 switch (pref) {
2619 case 0: p = 0; break; /* WC */
2620 case 1: p = 3; break; /* ADAT */
2621 case 2: p = 1; break; /* AES */
2622 case 3: p = 2; break; /* SPDIF */
2623 case 4: p = 10; break; /* SYNC_IN */
2624 default: return -1;
2625 }
2626 }
2627 break;
1706 } 2628 }
1707 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); 2629
2630 switch (hdspm->io_type) {
2631 case RayDAT:
2632 case AIO:
2633 hdspm->settings_register &= ~HDSPM_c0_SyncRefMask;
2634 hdspm->settings_register |= HDSPM_c0_SyncRef0 * p;
2635 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
2636 break;
2637
2638 case MADI:
2639 case MADIface:
2640 case AES32:
2641 hdspm_write(hdspm, HDSPM_controlRegister,
2642 hdspm->control_register);
2643 }
2644
1708 return 0; 2645 return 0;
1709} 2646}
1710 2647
2648
1711static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol, 2649static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol,
1712 struct snd_ctl_elem_info *uinfo) 2650 struct snd_ctl_elem_info *uinfo)
1713{ 2651{
1714 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2652 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1715 2653
1716 if (hdspm->is_aes32) { 2654 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1717 static char *texts[] = { "Word", "AES1", "AES2", "AES3", 2655 uinfo->count = 1;
1718 "AES4", "AES5", "AES6", "AES7", "AES8" }; 2656 uinfo->value.enumerated.items = hdspm->texts_autosync_items;
1719
1720 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1721 uinfo->count = 1;
1722
1723 uinfo->value.enumerated.items = 9;
1724
1725 if (uinfo->value.enumerated.item >=
1726 uinfo->value.enumerated.items)
1727 uinfo->value.enumerated.item =
1728 uinfo->value.enumerated.items - 1;
1729 strcpy(uinfo->value.enumerated.name,
1730 texts[uinfo->value.enumerated.item]);
1731 } else {
1732 static char *texts[] = { "Word", "MADI" };
1733 2657
1734 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2658 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1735 uinfo->count = 1; 2659 uinfo->value.enumerated.item =
2660 uinfo->value.enumerated.items - 1;
1736 2661
1737 uinfo->value.enumerated.items = 2; 2662 strcpy(uinfo->value.enumerated.name,
2663 hdspm->texts_autosync[uinfo->value.enumerated.item]);
1738 2664
1739 if (uinfo->value.enumerated.item >=
1740 uinfo->value.enumerated.items)
1741 uinfo->value.enumerated.item =
1742 uinfo->value.enumerated.items - 1;
1743 strcpy(uinfo->value.enumerated.name,
1744 texts[uinfo->value.enumerated.item]);
1745 }
1746 return 0; 2665 return 0;
1747} 2666}
1748 2667
@@ -1750,32 +2669,41 @@ static int snd_hdspm_get_pref_sync_ref(struct snd_kcontrol *kcontrol,
1750 struct snd_ctl_elem_value *ucontrol) 2669 struct snd_ctl_elem_value *ucontrol)
1751{ 2670{
1752 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2671 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2672 int psf = hdspm_pref_sync_ref(hdspm);
1753 2673
1754 ucontrol->value.enumerated.item[0] = hdspm_pref_sync_ref(hdspm); 2674 if (psf >= 0) {
1755 return 0; 2675 ucontrol->value.enumerated.item[0] = psf;
2676 return 0;
2677 }
2678
2679 return -1;
1756} 2680}
1757 2681
1758static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol, 2682static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
1759 struct snd_ctl_elem_value *ucontrol) 2683 struct snd_ctl_elem_value *ucontrol)
1760{ 2684{
1761 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2685 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1762 int change, max; 2686 int val, change = 0;
1763 unsigned int val;
1764
1765 max = hdspm->is_aes32 ? 9 : 2;
1766 2687
1767 if (!snd_hdspm_use_is_exclusive(hdspm)) 2688 if (!snd_hdspm_use_is_exclusive(hdspm))
1768 return -EBUSY; 2689 return -EBUSY;
1769 2690
1770 val = ucontrol->value.enumerated.item[0] % max; 2691 val = ucontrol->value.enumerated.item[0];
2692
2693 if (val < 0)
2694 val = 0;
2695 else if (val >= hdspm->texts_autosync_items)
2696 val = hdspm->texts_autosync_items-1;
1771 2697
1772 spin_lock_irq(&hdspm->lock); 2698 spin_lock_irq(&hdspm->lock);
1773 change = (int) val != hdspm_pref_sync_ref(hdspm); 2699 if (val != hdspm_pref_sync_ref(hdspm))
1774 hdspm_set_pref_sync_ref(hdspm, val); 2700 change = (0 == hdspm_set_pref_sync_ref(hdspm, val)) ? 1 : 0;
2701
1775 spin_unlock_irq(&hdspm->lock); 2702 spin_unlock_irq(&hdspm->lock);
1776 return change; 2703 return change;
1777} 2704}
1778 2705
2706
1779#define HDSPM_AUTOSYNC_REF(xname, xindex) \ 2707#define HDSPM_AUTOSYNC_REF(xname, xindex) \
1780{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2708{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1781 .name = xname, \ 2709 .name = xname, \
@@ -1785,18 +2713,18 @@ static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
1785 .get = snd_hdspm_get_autosync_ref, \ 2713 .get = snd_hdspm_get_autosync_ref, \
1786} 2714}
1787 2715
1788static int hdspm_autosync_ref(struct hdspm * hdspm) 2716static int hdspm_autosync_ref(struct hdspm *hdspm)
1789{ 2717{
1790 if (hdspm->is_aes32) { 2718 if (AES32 == hdspm->io_type) {
1791 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); 2719 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
1792 unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & 2720 unsigned int syncref =
1793 0xF; 2721 (status >> HDSPM_AES32_syncref_bit) & 0xF;
1794 if (syncref == 0) 2722 if (syncref == 0)
1795 return HDSPM_AES32_AUTOSYNC_FROM_WORD; 2723 return HDSPM_AES32_AUTOSYNC_FROM_WORD;
1796 if (syncref <= 8) 2724 if (syncref <= 8)
1797 return syncref; 2725 return syncref;
1798 return HDSPM_AES32_AUTOSYNC_FROM_NONE; 2726 return HDSPM_AES32_AUTOSYNC_FROM_NONE;
1799 } else { 2727 } else if (MADI == hdspm->io_type) {
1800 /* This looks at the autosync selected sync reference */ 2728 /* This looks at the autosync selected sync reference */
1801 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 2729 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
1802 2730
@@ -1805,22 +2733,27 @@ static int hdspm_autosync_ref(struct hdspm * hdspm)
1805 return HDSPM_AUTOSYNC_FROM_WORD; 2733 return HDSPM_AUTOSYNC_FROM_WORD;
1806 case HDSPM_SelSyncRef_MADI: 2734 case HDSPM_SelSyncRef_MADI:
1807 return HDSPM_AUTOSYNC_FROM_MADI; 2735 return HDSPM_AUTOSYNC_FROM_MADI;
2736 case HDSPM_SelSyncRef_TCO:
2737 return HDSPM_AUTOSYNC_FROM_TCO;
2738 case HDSPM_SelSyncRef_SyncIn:
2739 return HDSPM_AUTOSYNC_FROM_SYNC_IN;
1808 case HDSPM_SelSyncRef_NVALID: 2740 case HDSPM_SelSyncRef_NVALID:
1809 return HDSPM_AUTOSYNC_FROM_NONE; 2741 return HDSPM_AUTOSYNC_FROM_NONE;
1810 default: 2742 default:
1811 return 0; 2743 return 0;
1812 } 2744 }
1813 2745
1814 return 0;
1815 } 2746 }
2747 return 0;
1816} 2748}
1817 2749
2750
1818static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol, 2751static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol,
1819 struct snd_ctl_elem_info *uinfo) 2752 struct snd_ctl_elem_info *uinfo)
1820{ 2753{
1821 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2754 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1822 2755
1823 if (hdspm->is_aes32) { 2756 if (AES32 == hdspm->io_type) {
1824 static char *texts[] = { "WordClock", "AES1", "AES2", "AES3", 2757 static char *texts[] = { "WordClock", "AES1", "AES2", "AES3",
1825 "AES4", "AES5", "AES6", "AES7", "AES8", "None"}; 2758 "AES4", "AES5", "AES6", "AES7", "AES8", "None"};
1826 2759
@@ -1833,14 +2766,15 @@ static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol,
1833 uinfo->value.enumerated.items - 1; 2766 uinfo->value.enumerated.items - 1;
1834 strcpy(uinfo->value.enumerated.name, 2767 strcpy(uinfo->value.enumerated.name,
1835 texts[uinfo->value.enumerated.item]); 2768 texts[uinfo->value.enumerated.item]);
1836 } else { 2769 } else if (MADI == hdspm->io_type) {
1837 static char *texts[] = { "WordClock", "MADI", "None" }; 2770 static char *texts[] = {"Word Clock", "MADI", "TCO",
2771 "Sync In", "None" };
1838 2772
1839 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2773 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1840 uinfo->count = 1; 2774 uinfo->count = 1;
1841 uinfo->value.enumerated.items = 3; 2775 uinfo->value.enumerated.items = 5;
1842 if (uinfo->value.enumerated.item >= 2776 if (uinfo->value.enumerated.item >=
1843 uinfo->value.enumerated.items) 2777 uinfo->value.enumerated.items)
1844 uinfo->value.enumerated.item = 2778 uinfo->value.enumerated.item =
1845 uinfo->value.enumerated.items - 1; 2779 uinfo->value.enumerated.items - 1;
1846 strcpy(uinfo->value.enumerated.name, 2780 strcpy(uinfo->value.enumerated.name,
@@ -1858,6 +2792,7 @@ static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol,
1858 return 0; 2792 return 0;
1859} 2793}
1860 2794
2795
1861#define HDSPM_LINE_OUT(xname, xindex) \ 2796#define HDSPM_LINE_OUT(xname, xindex) \
1862{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2797{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1863 .name = xname, \ 2798 .name = xname, \
@@ -1914,6 +2849,7 @@ static int snd_hdspm_put_line_out(struct snd_kcontrol *kcontrol,
1914 return change; 2849 return change;
1915} 2850}
1916 2851
2852
1917#define HDSPM_TX_64(xname, xindex) \ 2853#define HDSPM_TX_64(xname, xindex) \
1918{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2854{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1919 .name = xname, \ 2855 .name = xname, \
@@ -1969,6 +2905,7 @@ static int snd_hdspm_put_tx_64(struct snd_kcontrol *kcontrol,
1969 return change; 2905 return change;
1970} 2906}
1971 2907
2908
1972#define HDSPM_C_TMS(xname, xindex) \ 2909#define HDSPM_C_TMS(xname, xindex) \
1973{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2910{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1974 .name = xname, \ 2911 .name = xname, \
@@ -2024,6 +2961,7 @@ static int snd_hdspm_put_c_tms(struct snd_kcontrol *kcontrol,
2024 return change; 2961 return change;
2025} 2962}
2026 2963
2964
2027#define HDSPM_SAFE_MODE(xname, xindex) \ 2965#define HDSPM_SAFE_MODE(xname, xindex) \
2028{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2966{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2029 .name = xname, \ 2967 .name = xname, \
@@ -2079,6 +3017,7 @@ static int snd_hdspm_put_safe_mode(struct snd_kcontrol *kcontrol,
2079 return change; 3017 return change;
2080} 3018}
2081 3019
3020
2082#define HDSPM_EMPHASIS(xname, xindex) \ 3021#define HDSPM_EMPHASIS(xname, xindex) \
2083{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3022{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2084 .name = xname, \ 3023 .name = xname, \
@@ -2134,6 +3073,7 @@ static int snd_hdspm_put_emphasis(struct snd_kcontrol *kcontrol,
2134 return change; 3073 return change;
2135} 3074}
2136 3075
3076
2137#define HDSPM_DOLBY(xname, xindex) \ 3077#define HDSPM_DOLBY(xname, xindex) \
2138{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3078{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2139 .name = xname, \ 3079 .name = xname, \
@@ -2189,6 +3129,7 @@ static int snd_hdspm_put_dolby(struct snd_kcontrol *kcontrol,
2189 return change; 3129 return change;
2190} 3130}
2191 3131
3132
2192#define HDSPM_PROFESSIONAL(xname, xindex) \ 3133#define HDSPM_PROFESSIONAL(xname, xindex) \
2193{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3134{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2194 .name = xname, \ 3135 .name = xname, \
@@ -2315,6 +3256,7 @@ static int snd_hdspm_put_input_select(struct snd_kcontrol *kcontrol,
2315 return change; 3256 return change;
2316} 3257}
2317 3258
3259
2318#define HDSPM_DS_WIRE(xname, xindex) \ 3260#define HDSPM_DS_WIRE(xname, xindex) \
2319{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3261{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2320 .name = xname, \ 3262 .name = xname, \
@@ -2386,6 +3328,7 @@ static int snd_hdspm_put_ds_wire(struct snd_kcontrol *kcontrol,
2386 return change; 3328 return change;
2387} 3329}
2388 3330
3331
2389#define HDSPM_QS_WIRE(xname, xindex) \ 3332#define HDSPM_QS_WIRE(xname, xindex) \
2390{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3333{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2391 .name = xname, \ 3334 .name = xname, \
@@ -2472,15 +3415,6 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
2472 return change; 3415 return change;
2473} 3416}
2474 3417
2475/* Simple Mixer
2476 deprecated since to much faders ???
2477 MIXER interface says output (source, destination, value)
2478 where source > MAX_channels are playback channels
2479 on MADICARD
2480 - playback mixer matrix: [channelout+64] [output] [value]
2481 - input(thru) mixer matrix: [channelin] [output] [value]
2482 (better do 2 kontrols for separation ?)
2483*/
2484 3418
2485#define HDSPM_MIXER(xname, xindex) \ 3419#define HDSPM_MIXER(xname, xindex) \
2486{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ 3420{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
@@ -2586,7 +3520,7 @@ static int snd_hdspm_put_mixer(struct snd_kcontrol *kcontrol,
2586 3520
2587/* The simple mixer control(s) provide gain control for the 3521/* The simple mixer control(s) provide gain control for the
2588 basic 1:1 mappings of playback streams to output 3522 basic 1:1 mappings of playback streams to output
2589 streams. 3523 streams.
2590*/ 3524*/
2591 3525
2592#define HDSPM_PLAYBACK_MIXER \ 3526#define HDSPM_PLAYBACK_MIXER \
@@ -2604,7 +3538,7 @@ static int snd_hdspm_info_playback_mixer(struct snd_kcontrol *kcontrol,
2604 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 3538 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2605 uinfo->count = 1; 3539 uinfo->count = 1;
2606 uinfo->value.integer.min = 0; 3540 uinfo->value.integer.min = 0;
2607 uinfo->value.integer.max = 65536; 3541 uinfo->value.integer.max = 64;
2608 uinfo->value.integer.step = 1; 3542 uinfo->value.integer.step = 1;
2609 return 0; 3543 return 0;
2610} 3544}
@@ -2614,28 +3548,17 @@ static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol,
2614{ 3548{
2615 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 3549 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2616 int channel; 3550 int channel;
2617 int mapped_channel;
2618 3551
2619 channel = ucontrol->id.index - 1; 3552 channel = ucontrol->id.index - 1;
2620 3553
2621 if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS)) 3554 if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
2622 return -EINVAL; 3555 return -EINVAL;
2623 3556
2624 mapped_channel = hdspm->channel_map[channel];
2625 if (mapped_channel < 0)
2626 return -EINVAL;
2627
2628 spin_lock_irq(&hdspm->lock); 3557 spin_lock_irq(&hdspm->lock);
2629 ucontrol->value.integer.value[0] = 3558 ucontrol->value.integer.value[0] =
2630 hdspm_read_pb_gain(hdspm, mapped_channel, mapped_channel); 3559 (hdspm_read_pb_gain(hdspm, channel, channel)*64)/UNITY_GAIN;
2631 spin_unlock_irq(&hdspm->lock); 3560 spin_unlock_irq(&hdspm->lock);
2632 3561
2633 /*
2634 snd_printdd("get pb mixer index %d, channel %d, mapped_channel %d, "
2635 "value %d\n",
2636 ucontrol->id.index, channel, mapped_channel,
2637 ucontrol->value.integer.value[0]);
2638 */
2639 return 0; 3562 return 0;
2640} 3563}
2641 3564
@@ -2645,7 +3568,6 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
2645 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 3568 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2646 int change; 3569 int change;
2647 int channel; 3570 int channel;
2648 int mapped_channel;
2649 int gain; 3571 int gain;
2650 3572
2651 if (!snd_hdspm_use_is_exclusive(hdspm)) 3573 if (!snd_hdspm_use_is_exclusive(hdspm))
@@ -2656,59 +3578,60 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
2656 if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS)) 3578 if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
2657 return -EINVAL; 3579 return -EINVAL;
2658 3580
2659 mapped_channel = hdspm->channel_map[channel]; 3581 gain = ucontrol->value.integer.value[0]*UNITY_GAIN/64;
2660 if (mapped_channel < 0)
2661 return -EINVAL;
2662
2663 gain = ucontrol->value.integer.value[0];
2664 3582
2665 spin_lock_irq(&hdspm->lock); 3583 spin_lock_irq(&hdspm->lock);
2666 change = 3584 change =
2667 gain != hdspm_read_pb_gain(hdspm, mapped_channel, 3585 gain != hdspm_read_pb_gain(hdspm, channel,
2668 mapped_channel); 3586 channel);
2669 if (change) 3587 if (change)
2670 hdspm_write_pb_gain(hdspm, mapped_channel, mapped_channel, 3588 hdspm_write_pb_gain(hdspm, channel, channel,
2671 gain); 3589 gain);
2672 spin_unlock_irq(&hdspm->lock); 3590 spin_unlock_irq(&hdspm->lock);
2673 return change; 3591 return change;
2674} 3592}
2675 3593
2676#define HDSPM_WC_SYNC_CHECK(xname, xindex) \ 3594#define HDSPM_SYNC_CHECK(xname, xindex) \
2677{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3595{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2678 .name = xname, \ 3596 .name = xname, \
2679 .index = xindex, \ 3597 .private_value = xindex, \
2680 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ 3598 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2681 .info = snd_hdspm_info_sync_check, \ 3599 .info = snd_hdspm_info_sync_check, \
2682 .get = snd_hdspm_get_wc_sync_check \ 3600 .get = snd_hdspm_get_sync_check \
2683} 3601}
2684 3602
3603
2685static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol, 3604static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol,
2686 struct snd_ctl_elem_info *uinfo) 3605 struct snd_ctl_elem_info *uinfo)
2687{ 3606{
2688 static char *texts[] = { "No Lock", "Lock", "Sync" }; 3607 static char *texts[] = { "No Lock", "Lock", "Sync", "N/A" };
2689 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3608 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2690 uinfo->count = 1; 3609 uinfo->count = 1;
2691 uinfo->value.enumerated.items = 3; 3610 uinfo->value.enumerated.items = 4;
2692 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 3611 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2693 uinfo->value.enumerated.item = 3612 uinfo->value.enumerated.item =
2694 uinfo->value.enumerated.items - 1; 3613 uinfo->value.enumerated.items - 1;
2695 strcpy(uinfo->value.enumerated.name, 3614 strcpy(uinfo->value.enumerated.name,
2696 texts[uinfo->value.enumerated.item]); 3615 texts[uinfo->value.enumerated.item]);
2697 return 0; 3616 return 0;
2698} 3617}
2699 3618
2700static int hdspm_wc_sync_check(struct hdspm * hdspm) 3619static int hdspm_wc_sync_check(struct hdspm *hdspm)
2701{ 3620{
2702 if (hdspm->is_aes32) { 3621 int status, status2;
2703 int status = hdspm_read(hdspm, HDSPM_statusRegister); 3622
2704 if (status & HDSPM_AES32_wcLock) { 3623 switch (hdspm->io_type) {
2705 /* I don't know how to differenciate sync from lock. 3624 case AES32:
2706 Doing as if sync for now */ 3625 status = hdspm_read(hdspm, HDSPM_statusRegister);
3626 if (status & HDSPM_wcSync)
2707 return 2; 3627 return 2;
2708 } 3628 else if (status & HDSPM_wcLock)
3629 return 1;
2709 return 0; 3630 return 0;
2710 } else { 3631 break;
2711 int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 3632
3633 case MADI:
3634 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
2712 if (status2 & HDSPM_wcLock) { 3635 if (status2 & HDSPM_wcLock) {
2713 if (status2 & HDSPM_wcSync) 3636 if (status2 & HDSPM_wcSync)
2714 return 2; 3637 return 2;
@@ -2716,29 +3639,30 @@ static int hdspm_wc_sync_check(struct hdspm * hdspm)
2716 return 1; 3639 return 1;
2717 } 3640 }
2718 return 0; 3641 return 0;
2719 } 3642 break;
2720}
2721 3643
2722static int snd_hdspm_get_wc_sync_check(struct snd_kcontrol *kcontrol, 3644 case RayDAT:
2723 struct snd_ctl_elem_value *ucontrol) 3645 case AIO:
2724{ 3646 status = hdspm_read(hdspm, HDSPM_statusRegister);
2725 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2726 3647
2727 ucontrol->value.enumerated.item[0] = hdspm_wc_sync_check(hdspm); 3648 if (status & 0x2000000)
2728 return 0; 3649 return 2;
2729} 3650 else if (status & 0x1000000)
3651 return 1;
3652 return 0;
2730 3653
3654 break;
2731 3655
2732#define HDSPM_MADI_SYNC_CHECK(xname, xindex) \ 3656 case MADIface:
2733{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3657 break;
2734 .name = xname, \ 3658 }
2735 .index = xindex, \ 3659
2736 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ 3660
2737 .info = snd_hdspm_info_sync_check, \ 3661 return 3;
2738 .get = snd_hdspm_get_madisync_sync_check \
2739} 3662}
2740 3663
2741static int hdspm_madisync_sync_check(struct hdspm * hdspm) 3664
3665static int hdspm_madi_sync_check(struct hdspm *hdspm)
2742{ 3666{
2743 int status = hdspm_read(hdspm, HDSPM_statusRegister); 3667 int status = hdspm_read(hdspm, HDSPM_statusRegister);
2744 if (status & HDSPM_madiLock) { 3668 if (status & HDSPM_madiLock) {
@@ -2750,89 +3674,726 @@ static int hdspm_madisync_sync_check(struct hdspm * hdspm)
2750 return 0; 3674 return 0;
2751} 3675}
2752 3676
2753static int snd_hdspm_get_madisync_sync_check(struct snd_kcontrol *kcontrol, 3677
2754 struct snd_ctl_elem_value * 3678static int hdspm_s1_sync_check(struct hdspm *hdspm, int idx)
2755 ucontrol)
2756{ 3679{
2757 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 3680 int status, lock, sync;
3681
3682 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
2758 3683
2759 ucontrol->value.enumerated.item[0] = 3684 lock = (status & (0x1<<idx)) ? 1 : 0;
2760 hdspm_madisync_sync_check(hdspm); 3685 sync = (status & (0x100<<idx)) ? 1 : 0;
3686
3687 if (lock && sync)
3688 return 2;
3689 else if (lock)
3690 return 1;
2761 return 0; 3691 return 0;
2762} 3692}
2763 3693
2764 3694
2765#define HDSPM_AES_SYNC_CHECK(xname, xindex) \ 3695static int hdspm_sync_in_sync_check(struct hdspm *hdspm)
2766{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3696{
2767 .name = xname, \ 3697 int status, lock = 0, sync = 0;
2768 .index = xindex, \ 3698
2769 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ 3699 switch (hdspm->io_type) {
2770 .info = snd_hdspm_info_sync_check, \ 3700 case RayDAT:
2771 .get = snd_hdspm_get_aes_sync_check \ 3701 case AIO:
3702 status = hdspm_read(hdspm, HDSPM_RD_STATUS_3);
3703 lock = (status & 0x400) ? 1 : 0;
3704 sync = (status & 0x800) ? 1 : 0;
3705 break;
3706
3707 case MADI:
3708 case AES32:
3709 status = hdspm_read(hdspm, HDSPM_statusRegister2);
3710 lock = (status & HDSPM_syncInLock) ? 1 : 0;
3711 sync = (status & HDSPM_syncInSync) ? 1 : 0;
3712 break;
3713
3714 case MADIface:
3715 break;
3716 }
3717
3718 if (lock && sync)
3719 return 2;
3720 else if (lock)
3721 return 1;
3722
3723 return 0;
2772} 3724}
2773 3725
2774static int hdspm_aes_sync_check(struct hdspm * hdspm, int idx) 3726static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx)
2775{ 3727{
2776 int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 3728 int status2, lock, sync;
2777 if (status2 & (HDSPM_LockAES >> idx)) { 3729 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
2778 /* I don't know how to differenciate sync from lock. 3730
2779 Doing as if sync for now */ 3731 lock = (status2 & (0x0080 >> idx)) ? 1 : 0;
3732 sync = (status2 & (0x8000 >> idx)) ? 1 : 0;
3733
3734 if (sync)
2780 return 2; 3735 return 2;
3736 else if (lock)
3737 return 1;
3738 return 0;
3739}
3740
3741
3742static int hdspm_tco_sync_check(struct hdspm *hdspm)
3743{
3744 int status;
3745
3746 if (hdspm->tco) {
3747 switch (hdspm->io_type) {
3748 case MADI:
3749 case AES32:
3750 status = hdspm_read(hdspm, HDSPM_statusRegister);
3751 if (status & HDSPM_tcoLock) {
3752 if (status & HDSPM_tcoSync)
3753 return 2;
3754 else
3755 return 1;
3756 }
3757 return 0;
3758
3759 break;
3760
3761 case RayDAT:
3762 case AIO:
3763 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
3764
3765 if (status & 0x8000000)
3766 return 2; /* Sync */
3767 if (status & 0x4000000)
3768 return 1; /* Lock */
3769 return 0; /* No signal */
3770 break;
3771
3772 default:
3773 break;
3774 }
3775 }
3776
3777 return 3; /* N/A */
3778}
3779
3780
3781static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol,
3782 struct snd_ctl_elem_value *ucontrol)
3783{
3784 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
3785 int val = -1;
3786
3787 switch (hdspm->io_type) {
3788 case RayDAT:
3789 switch (kcontrol->private_value) {
3790 case 0: /* WC */
3791 val = hdspm_wc_sync_check(hdspm); break;
3792 case 7: /* TCO */
3793 val = hdspm_tco_sync_check(hdspm); break;
3794 case 8: /* SYNC IN */
3795 val = hdspm_sync_in_sync_check(hdspm); break;
3796 default:
3797 val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1);
3798 }
3799
3800 case AIO:
3801 switch (kcontrol->private_value) {
3802 case 0: /* WC */
3803 val = hdspm_wc_sync_check(hdspm); break;
3804 case 4: /* TCO */
3805 val = hdspm_tco_sync_check(hdspm); break;
3806 case 5: /* SYNC IN */
3807 val = hdspm_sync_in_sync_check(hdspm); break;
3808 default:
3809 val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1);
3810 }
3811
3812 case MADI:
3813 switch (kcontrol->private_value) {
3814 case 0: /* WC */
3815 val = hdspm_wc_sync_check(hdspm); break;
3816 case 1: /* MADI */
3817 val = hdspm_madi_sync_check(hdspm); break;
3818 case 2: /* TCO */
3819 val = hdspm_tco_sync_check(hdspm); break;
3820 case 3: /* SYNC_IN */
3821 val = hdspm_sync_in_sync_check(hdspm); break;
3822 }
3823
3824 case MADIface:
3825 val = hdspm_madi_sync_check(hdspm); /* MADI */
3826 break;
3827
3828 case AES32:
3829 switch (kcontrol->private_value) {
3830 case 0: /* WC */
3831 val = hdspm_wc_sync_check(hdspm); break;
3832 case 9: /* TCO */
3833 val = hdspm_tco_sync_check(hdspm); break;
3834 case 10 /* SYNC IN */:
3835 val = hdspm_sync_in_sync_check(hdspm); break;
3836 default: /* AES1 to AES8 */
3837 val = hdspm_aes_sync_check(hdspm,
3838 kcontrol->private_value-1);
3839 }
3840
2781 } 3841 }
3842
3843 if (-1 == val)
3844 val = 3;
3845
3846 ucontrol->value.enumerated.item[0] = val;
2782 return 0; 3847 return 0;
2783} 3848}
2784 3849
2785static int snd_hdspm_get_aes_sync_check(struct snd_kcontrol *kcontrol, 3850
3851
3852/**
3853 * TCO controls
3854 **/
3855static void hdspm_tco_write(struct hdspm *hdspm)
3856{
3857 unsigned int tc[4] = { 0, 0, 0, 0};
3858
3859 switch (hdspm->tco->input) {
3860 case 0:
3861 tc[2] |= HDSPM_TCO2_set_input_MSB;
3862 break;
3863 case 1:
3864 tc[2] |= HDSPM_TCO2_set_input_LSB;
3865 break;
3866 default:
3867 break;
3868 }
3869
3870 switch (hdspm->tco->framerate) {
3871 case 1:
3872 tc[1] |= HDSPM_TCO1_LTC_Format_LSB;
3873 break;
3874 case 2:
3875 tc[1] |= HDSPM_TCO1_LTC_Format_MSB;
3876 break;
3877 case 3:
3878 tc[1] |= HDSPM_TCO1_LTC_Format_MSB +
3879 HDSPM_TCO1_set_drop_frame_flag;
3880 break;
3881 case 4:
3882 tc[1] |= HDSPM_TCO1_LTC_Format_LSB +
3883 HDSPM_TCO1_LTC_Format_MSB;
3884 break;
3885 case 5:
3886 tc[1] |= HDSPM_TCO1_LTC_Format_LSB +
3887 HDSPM_TCO1_LTC_Format_MSB +
3888 HDSPM_TCO1_set_drop_frame_flag;
3889 break;
3890 default:
3891 break;
3892 }
3893
3894 switch (hdspm->tco->wordclock) {
3895 case 1:
3896 tc[2] |= HDSPM_TCO2_WCK_IO_ratio_LSB;
3897 break;
3898 case 2:
3899 tc[2] |= HDSPM_TCO2_WCK_IO_ratio_MSB;
3900 break;
3901 default:
3902 break;
3903 }
3904
3905 switch (hdspm->tco->samplerate) {
3906 case 1:
3907 tc[2] |= HDSPM_TCO2_set_freq;
3908 break;
3909 case 2:
3910 tc[2] |= HDSPM_TCO2_set_freq_from_app;
3911 break;
3912 default:
3913 break;
3914 }
3915
3916 switch (hdspm->tco->pull) {
3917 case 1:
3918 tc[2] |= HDSPM_TCO2_set_pull_up;
3919 break;
3920 case 2:
3921 tc[2] |= HDSPM_TCO2_set_pull_down;
3922 break;
3923 case 3:
3924 tc[2] |= HDSPM_TCO2_set_pull_up + HDSPM_TCO2_set_01_4;
3925 break;
3926 case 4:
3927 tc[2] |= HDSPM_TCO2_set_pull_down + HDSPM_TCO2_set_01_4;
3928 break;
3929 default:
3930 break;
3931 }
3932
3933 if (1 == hdspm->tco->term) {
3934 tc[2] |= HDSPM_TCO2_set_term_75R;
3935 }
3936
3937 hdspm_write(hdspm, HDSPM_WR_TCO, tc[0]);
3938 hdspm_write(hdspm, HDSPM_WR_TCO+4, tc[1]);
3939 hdspm_write(hdspm, HDSPM_WR_TCO+8, tc[2]);
3940 hdspm_write(hdspm, HDSPM_WR_TCO+12, tc[3]);
3941}
3942
3943
3944#define HDSPM_TCO_SAMPLE_RATE(xname, xindex) \
3945{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3946 .name = xname, \
3947 .index = xindex, \
3948 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
3949 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
3950 .info = snd_hdspm_info_tco_sample_rate, \
3951 .get = snd_hdspm_get_tco_sample_rate, \
3952 .put = snd_hdspm_put_tco_sample_rate \
3953}
3954
3955static int snd_hdspm_info_tco_sample_rate(struct snd_kcontrol *kcontrol,
3956 struct snd_ctl_elem_info *uinfo)
3957{
3958 static char *texts[] = { "44.1 kHz", "48 kHz" };
3959 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3960 uinfo->count = 1;
3961 uinfo->value.enumerated.items = 2;
3962
3963 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3964 uinfo->value.enumerated.item =
3965 uinfo->value.enumerated.items - 1;
3966
3967 strcpy(uinfo->value.enumerated.name,
3968 texts[uinfo->value.enumerated.item]);
3969
3970 return 0;
3971}
3972
3973static int snd_hdspm_get_tco_sample_rate(struct snd_kcontrol *kcontrol,
3974 struct snd_ctl_elem_value *ucontrol)
3975{
3976 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
3977
3978 ucontrol->value.enumerated.item[0] = hdspm->tco->samplerate;
3979
3980 return 0;
3981}
3982
3983static int snd_hdspm_put_tco_sample_rate(struct snd_kcontrol *kcontrol,
3984 struct snd_ctl_elem_value *ucontrol)
3985{
3986 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
3987
3988 if (hdspm->tco->samplerate != ucontrol->value.enumerated.item[0]) {
3989 hdspm->tco->samplerate = ucontrol->value.enumerated.item[0];
3990
3991 hdspm_tco_write(hdspm);
3992
3993 return 1;
3994 }
3995
3996 return 0;
3997}
3998
3999
4000#define HDSPM_TCO_PULL(xname, xindex) \
4001{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4002 .name = xname, \
4003 .index = xindex, \
4004 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4005 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4006 .info = snd_hdspm_info_tco_pull, \
4007 .get = snd_hdspm_get_tco_pull, \
4008 .put = snd_hdspm_put_tco_pull \
4009}
4010
4011static int snd_hdspm_info_tco_pull(struct snd_kcontrol *kcontrol,
4012 struct snd_ctl_elem_info *uinfo)
4013{
4014 static char *texts[] = { "0", "+ 0.1 %", "- 0.1 %", "+ 4 %", "- 4 %" };
4015 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4016 uinfo->count = 1;
4017 uinfo->value.enumerated.items = 5;
4018
4019 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
4020 uinfo->value.enumerated.item =
4021 uinfo->value.enumerated.items - 1;
4022
4023 strcpy(uinfo->value.enumerated.name,
4024 texts[uinfo->value.enumerated.item]);
4025
4026 return 0;
4027}
4028
4029static int snd_hdspm_get_tco_pull(struct snd_kcontrol *kcontrol,
4030 struct snd_ctl_elem_value *ucontrol)
4031{
4032 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4033
4034 ucontrol->value.enumerated.item[0] = hdspm->tco->pull;
4035
4036 return 0;
4037}
4038
4039static int snd_hdspm_put_tco_pull(struct snd_kcontrol *kcontrol,
4040 struct snd_ctl_elem_value *ucontrol)
4041{
4042 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4043
4044 if (hdspm->tco->pull != ucontrol->value.enumerated.item[0]) {
4045 hdspm->tco->pull = ucontrol->value.enumerated.item[0];
4046
4047 hdspm_tco_write(hdspm);
4048
4049 return 1;
4050 }
4051
4052 return 0;
4053}
4054
4055#define HDSPM_TCO_WCK_CONVERSION(xname, xindex) \
4056{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4057 .name = xname, \
4058 .index = xindex, \
4059 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4060 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4061 .info = snd_hdspm_info_tco_wck_conversion, \
4062 .get = snd_hdspm_get_tco_wck_conversion, \
4063 .put = snd_hdspm_put_tco_wck_conversion \
4064}
4065
4066static int snd_hdspm_info_tco_wck_conversion(struct snd_kcontrol *kcontrol,
4067 struct snd_ctl_elem_info *uinfo)
4068{
4069 static char *texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" };
4070 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4071 uinfo->count = 1;
4072 uinfo->value.enumerated.items = 3;
4073
4074 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
4075 uinfo->value.enumerated.item =
4076 uinfo->value.enumerated.items - 1;
4077
4078 strcpy(uinfo->value.enumerated.name,
4079 texts[uinfo->value.enumerated.item]);
4080
4081 return 0;
4082}
4083
4084static int snd_hdspm_get_tco_wck_conversion(struct snd_kcontrol *kcontrol,
4085 struct snd_ctl_elem_value *ucontrol)
4086{
4087 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4088
4089 ucontrol->value.enumerated.item[0] = hdspm->tco->wordclock;
4090
4091 return 0;
4092}
4093
4094static int snd_hdspm_put_tco_wck_conversion(struct snd_kcontrol *kcontrol,
4095 struct snd_ctl_elem_value *ucontrol)
4096{
4097 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4098
4099 if (hdspm->tco->wordclock != ucontrol->value.enumerated.item[0]) {
4100 hdspm->tco->wordclock = ucontrol->value.enumerated.item[0];
4101
4102 hdspm_tco_write(hdspm);
4103
4104 return 1;
4105 }
4106
4107 return 0;
4108}
4109
4110
4111#define HDSPM_TCO_FRAME_RATE(xname, xindex) \
4112{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4113 .name = xname, \
4114 .index = xindex, \
4115 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4116 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4117 .info = snd_hdspm_info_tco_frame_rate, \
4118 .get = snd_hdspm_get_tco_frame_rate, \
4119 .put = snd_hdspm_put_tco_frame_rate \
4120}
4121
4122static int snd_hdspm_info_tco_frame_rate(struct snd_kcontrol *kcontrol,
4123 struct snd_ctl_elem_info *uinfo)
4124{
4125 static char *texts[] = { "24 fps", "25 fps", "29.97fps",
4126 "29.97 dfps", "30 fps", "30 dfps" };
4127 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4128 uinfo->count = 1;
4129 uinfo->value.enumerated.items = 6;
4130
4131 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
4132 uinfo->value.enumerated.item =
4133 uinfo->value.enumerated.items - 1;
4134
4135 strcpy(uinfo->value.enumerated.name,
4136 texts[uinfo->value.enumerated.item]);
4137
4138 return 0;
4139}
4140
4141static int snd_hdspm_get_tco_frame_rate(struct snd_kcontrol *kcontrol,
2786 struct snd_ctl_elem_value *ucontrol) 4142 struct snd_ctl_elem_value *ucontrol)
2787{ 4143{
2788 int offset;
2789 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 4144 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2790 4145
2791 offset = ucontrol->id.index - 1; 4146 ucontrol->value.enumerated.item[0] = hdspm->tco->framerate;
2792 if (offset < 0 || offset >= 8)
2793 return -EINVAL;
2794 4147
2795 ucontrol->value.enumerated.item[0] =
2796 hdspm_aes_sync_check(hdspm, offset);
2797 return 0; 4148 return 0;
2798} 4149}
2799 4150
4151static int snd_hdspm_put_tco_frame_rate(struct snd_kcontrol *kcontrol,
4152 struct snd_ctl_elem_value *ucontrol)
4153{
4154 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2800 4155
2801static struct snd_kcontrol_new snd_hdspm_controls_madi[] = { 4156 if (hdspm->tco->framerate != ucontrol->value.enumerated.item[0]) {
4157 hdspm->tco->framerate = ucontrol->value.enumerated.item[0];
2802 4158
2803 HDSPM_MIXER("Mixer", 0), 4159 hdspm_tco_write(hdspm);
2804/* 'Sample Clock Source' complies with the alsa control naming scheme */ 4160
2805 HDSPM_CLOCK_SOURCE("Sample Clock Source", 0), 4161 return 1;
4162 }
4163
4164 return 0;
4165}
2806 4166
4167
4168#define HDSPM_TCO_SYNC_SOURCE(xname, xindex) \
4169{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4170 .name = xname, \
4171 .index = xindex, \
4172 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4173 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4174 .info = snd_hdspm_info_tco_sync_source, \
4175 .get = snd_hdspm_get_tco_sync_source, \
4176 .put = snd_hdspm_put_tco_sync_source \
4177}
4178
4179static int snd_hdspm_info_tco_sync_source(struct snd_kcontrol *kcontrol,
4180 struct snd_ctl_elem_info *uinfo)
4181{
4182 static char *texts[] = { "LTC", "Video", "WCK" };
4183 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4184 uinfo->count = 1;
4185 uinfo->value.enumerated.items = 3;
4186
4187 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
4188 uinfo->value.enumerated.item =
4189 uinfo->value.enumerated.items - 1;
4190
4191 strcpy(uinfo->value.enumerated.name,
4192 texts[uinfo->value.enumerated.item]);
4193
4194 return 0;
4195}
4196
4197static int snd_hdspm_get_tco_sync_source(struct snd_kcontrol *kcontrol,
4198 struct snd_ctl_elem_value *ucontrol)
4199{
4200 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4201
4202 ucontrol->value.enumerated.item[0] = hdspm->tco->input;
4203
4204 return 0;
4205}
4206
4207static int snd_hdspm_put_tco_sync_source(struct snd_kcontrol *kcontrol,
4208 struct snd_ctl_elem_value *ucontrol)
4209{
4210 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4211
4212 if (hdspm->tco->input != ucontrol->value.enumerated.item[0]) {
4213 hdspm->tco->input = ucontrol->value.enumerated.item[0];
4214
4215 hdspm_tco_write(hdspm);
4216
4217 return 1;
4218 }
4219
4220 return 0;
4221}
4222
4223
4224#define HDSPM_TCO_WORD_TERM(xname, xindex) \
4225{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4226 .name = xname, \
4227 .index = xindex, \
4228 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4229 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4230 .info = snd_hdspm_info_tco_word_term, \
4231 .get = snd_hdspm_get_tco_word_term, \
4232 .put = snd_hdspm_put_tco_word_term \
4233}
4234
4235static int snd_hdspm_info_tco_word_term(struct snd_kcontrol *kcontrol,
4236 struct snd_ctl_elem_info *uinfo)
4237{
4238 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
4239 uinfo->count = 1;
4240 uinfo->value.integer.min = 0;
4241 uinfo->value.integer.max = 1;
4242
4243 return 0;
4244}
4245
4246
4247static int snd_hdspm_get_tco_word_term(struct snd_kcontrol *kcontrol,
4248 struct snd_ctl_elem_value *ucontrol)
4249{
4250 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4251
4252 ucontrol->value.enumerated.item[0] = hdspm->tco->term;
4253
4254 return 0;
4255}
4256
4257
4258static int snd_hdspm_put_tco_word_term(struct snd_kcontrol *kcontrol,
4259 struct snd_ctl_elem_value *ucontrol)
4260{
4261 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4262
4263 if (hdspm->tco->term != ucontrol->value.enumerated.item[0]) {
4264 hdspm->tco->term = ucontrol->value.enumerated.item[0];
4265
4266 hdspm_tco_write(hdspm);
4267
4268 return 1;
4269 }
4270
4271 return 0;
4272}
4273
4274
4275
4276
4277static struct snd_kcontrol_new snd_hdspm_controls_madi[] = {
4278 HDSPM_MIXER("Mixer", 0),
4279 HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
2807 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), 4280 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
2808 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), 4281 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
2809 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), 4282 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
2810 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), 4283 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
2811/* 'External Rate' complies with the alsa control naming scheme */ 4284 HDSPM_SYNC_CHECK("WC SyncCheck", 0),
2812 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), 4285 HDSPM_SYNC_CHECK("MADI SyncCheck", 1),
2813 HDSPM_WC_SYNC_CHECK("Word Clock Lock Status", 0), 4286 HDSPM_SYNC_CHECK("TCO SyncCHeck", 2),
2814 HDSPM_MADI_SYNC_CHECK("MADI Sync Lock Status", 0), 4287 HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 3),
2815 HDSPM_LINE_OUT("Line Out", 0), 4288 HDSPM_LINE_OUT("Line Out", 0),
2816 HDSPM_TX_64("TX 64 channels mode", 0), 4289 HDSPM_TX_64("TX 64 channels mode", 0),
2817 HDSPM_C_TMS("Clear Track Marker", 0), 4290 HDSPM_C_TMS("Clear Track Marker", 0),
2818 HDSPM_SAFE_MODE("Safe Mode", 0), 4291 HDSPM_SAFE_MODE("Safe Mode", 0),
2819 HDSPM_INPUT_SELECT("Input Select", 0), 4292 HDSPM_INPUT_SELECT("Input Select", 0)
2820}; 4293};
2821 4294
2822static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = {
2823 4295
4296static struct snd_kcontrol_new snd_hdspm_controls_madiface[] = {
2824 HDSPM_MIXER("Mixer", 0), 4297 HDSPM_MIXER("Mixer", 0),
2825/* 'Sample Clock Source' complies with the alsa control naming scheme */ 4298 HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
2826 HDSPM_CLOCK_SOURCE("Sample Clock Source", 0), 4299 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
4300 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
4301 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
4302 HDSPM_SYNC_CHECK("MADI SyncCheck", 0),
4303 HDSPM_TX_64("TX 64 channels mode", 0),
4304 HDSPM_C_TMS("Clear Track Marker", 0),
4305 HDSPM_SAFE_MODE("Safe Mode", 0)
4306};
2827 4307
4308static struct snd_kcontrol_new snd_hdspm_controls_aio[] = {
4309 HDSPM_MIXER("Mixer", 0),
4310 HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
2828 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), 4311 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
2829 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), 4312 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
2830 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), 4313 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
2831 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), 4314 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
2832/* 'External Rate' complies with the alsa control naming scheme */
2833 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), 4315 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
2834 HDSPM_WC_SYNC_CHECK("Word Clock Lock Status", 0), 4316 HDSPM_SYNC_CHECK("WC SyncCheck", 0),
2835/* HDSPM_AES_SYNC_CHECK("AES Lock Status", 0),*/ /* created in snd_hdspm_create_controls() */ 4317 HDSPM_SYNC_CHECK("AES SyncCheck", 1),
4318 HDSPM_SYNC_CHECK("SPDIF SyncCheck", 2),
4319 HDSPM_SYNC_CHECK("ADAT SyncCheck", 3),
4320 HDSPM_SYNC_CHECK("TCO SyncCheck", 4),
4321 HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 5),
4322 HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0),
4323 HDSPM_AUTOSYNC_SAMPLE_RATE("AES Frequency", 1),
4324 HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2),
4325 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT Frequency", 3),
4326 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 4),
4327 HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 5)
4328
4329 /*
4330 HDSPM_INPUT_SELECT("Input Select", 0),
4331 HDSPM_SPDIF_OPTICAL("SPDIF Out Optical", 0),
4332 HDSPM_PROFESSIONAL("SPDIF Out Professional", 0);
4333 HDSPM_SPDIF_IN("SPDIF In", 0);
4334 HDSPM_BREAKOUT_CABLE("Breakout Cable", 0);
4335 HDSPM_INPUT_LEVEL("Input Level", 0);
4336 HDSPM_OUTPUT_LEVEL("Output Level", 0);
4337 HDSPM_PHONES("Phones", 0);
4338 */
4339};
4340
4341static struct snd_kcontrol_new snd_hdspm_controls_raydat[] = {
4342 HDSPM_MIXER("Mixer", 0),
4343 HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
4344 HDSPM_SYSTEM_CLOCK_MODE("Clock Mode", 0),
4345 HDSPM_PREF_SYNC_REF("Pref Sync Ref", 0),
4346 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
4347 HDSPM_SYNC_CHECK("WC SyncCheck", 0),
4348 HDSPM_SYNC_CHECK("AES SyncCheck", 1),
4349 HDSPM_SYNC_CHECK("SPDIF SyncCheck", 2),
4350 HDSPM_SYNC_CHECK("ADAT1 SyncCheck", 3),
4351 HDSPM_SYNC_CHECK("ADAT2 SyncCheck", 4),
4352 HDSPM_SYNC_CHECK("ADAT3 SyncCheck", 5),
4353 HDSPM_SYNC_CHECK("ADAT4 SyncCheck", 6),
4354 HDSPM_SYNC_CHECK("TCO SyncCheck", 7),
4355 HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 8),
4356 HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0),
4357 HDSPM_AUTOSYNC_SAMPLE_RATE("AES Frequency", 1),
4358 HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2),
4359 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT1 Frequency", 3),
4360 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT2 Frequency", 4),
4361 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT3 Frequency", 5),
4362 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT4 Frequency", 6),
4363 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 7),
4364 HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 8)
4365};
4366
4367static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = {
4368 HDSPM_MIXER("Mixer", 0),
4369 HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
4370 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
4371 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
4372 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
4373 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
4374 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
4375 HDSPM_SYNC_CHECK("WC Sync Check", 0),
4376 HDSPM_SYNC_CHECK("AES1 Sync Check", 1),
4377 HDSPM_SYNC_CHECK("AES2 Sync Check", 2),
4378 HDSPM_SYNC_CHECK("AES3 Sync Check", 3),
4379 HDSPM_SYNC_CHECK("AES4 Sync Check", 4),
4380 HDSPM_SYNC_CHECK("AES5 Sync Check", 5),
4381 HDSPM_SYNC_CHECK("AES6 Sync Check", 6),
4382 HDSPM_SYNC_CHECK("AES7 Sync Check", 7),
4383 HDSPM_SYNC_CHECK("AES8 Sync Check", 8),
4384 HDSPM_SYNC_CHECK("TCO Sync Check", 9),
4385 HDSPM_SYNC_CHECK("SYNC IN Sync Check", 10),
4386 HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0),
4387 HDSPM_AUTOSYNC_SAMPLE_RATE("AES1 Frequency", 1),
4388 HDSPM_AUTOSYNC_SAMPLE_RATE("AES2 Frequency", 2),
4389 HDSPM_AUTOSYNC_SAMPLE_RATE("AES3 Frequency", 3),
4390 HDSPM_AUTOSYNC_SAMPLE_RATE("AES4 Frequency", 4),
4391 HDSPM_AUTOSYNC_SAMPLE_RATE("AES5 Frequency", 5),
4392 HDSPM_AUTOSYNC_SAMPLE_RATE("AES6 Frequency", 6),
4393 HDSPM_AUTOSYNC_SAMPLE_RATE("AES7 Frequency", 7),
4394 HDSPM_AUTOSYNC_SAMPLE_RATE("AES8 Frequency", 8),
4395 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 9),
4396 HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 10),
2836 HDSPM_LINE_OUT("Line Out", 0), 4397 HDSPM_LINE_OUT("Line Out", 0),
2837 HDSPM_EMPHASIS("Emphasis", 0), 4398 HDSPM_EMPHASIS("Emphasis", 0),
2838 HDSPM_DOLBY("Non Audio", 0), 4399 HDSPM_DOLBY("Non Audio", 0),
@@ -2842,6 +4403,19 @@ static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = {
2842 HDSPM_QS_WIRE("Quad Speed Wire Mode", 0), 4403 HDSPM_QS_WIRE("Quad Speed Wire Mode", 0),
2843}; 4404};
2844 4405
4406
4407
4408/* Control elements for the optional TCO module */
4409static struct snd_kcontrol_new snd_hdspm_controls_tco[] = {
4410 HDSPM_TCO_SAMPLE_RATE("TCO Sample Rate", 0),
4411 HDSPM_TCO_PULL("TCO Pull", 0),
4412 HDSPM_TCO_WCK_CONVERSION("TCO WCK Conversion", 0),
4413 HDSPM_TCO_FRAME_RATE("TCO Frame Rate", 0),
4414 HDSPM_TCO_SYNC_SOURCE("TCO Sync Source", 0),
4415 HDSPM_TCO_WORD_TERM("TCO Word Term", 0)
4416};
4417
4418
2845static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER; 4419static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER;
2846 4420
2847 4421
@@ -2849,78 +4423,76 @@ static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm)
2849{ 4423{
2850 int i; 4424 int i;
2851 4425
2852 for (i = hdspm->ds_channels; i < hdspm->ss_channels; ++i) { 4426 for (i = hdspm->ds_out_channels; i < hdspm->ss_out_channels; ++i) {
2853 if (hdspm->system_sample_rate > 48000) { 4427 if (hdspm->system_sample_rate > 48000) {
2854 hdspm->playback_mixer_ctls[i]->vd[0].access = 4428 hdspm->playback_mixer_ctls[i]->vd[0].access =
2855 SNDRV_CTL_ELEM_ACCESS_INACTIVE | 4429 SNDRV_CTL_ELEM_ACCESS_INACTIVE |
2856 SNDRV_CTL_ELEM_ACCESS_READ | 4430 SNDRV_CTL_ELEM_ACCESS_READ |
2857 SNDRV_CTL_ELEM_ACCESS_VOLATILE; 4431 SNDRV_CTL_ELEM_ACCESS_VOLATILE;
2858 } else { 4432 } else {
2859 hdspm->playback_mixer_ctls[i]->vd[0].access = 4433 hdspm->playback_mixer_ctls[i]->vd[0].access =
2860 SNDRV_CTL_ELEM_ACCESS_READWRITE | 4434 SNDRV_CTL_ELEM_ACCESS_READWRITE |
2861 SNDRV_CTL_ELEM_ACCESS_VOLATILE; 4435 SNDRV_CTL_ELEM_ACCESS_VOLATILE;
2862 } 4436 }
2863 snd_ctl_notify(hdspm->card, SNDRV_CTL_EVENT_MASK_VALUE | 4437 snd_ctl_notify(hdspm->card, SNDRV_CTL_EVENT_MASK_VALUE |
2864 SNDRV_CTL_EVENT_MASK_INFO, 4438 SNDRV_CTL_EVENT_MASK_INFO,
2865 &hdspm->playback_mixer_ctls[i]->id); 4439 &hdspm->playback_mixer_ctls[i]->id);
2866 } 4440 }
2867 4441
2868 return 0; 4442 return 0;
2869} 4443}
2870 4444
2871 4445
2872static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm) 4446static int snd_hdspm_create_controls(struct snd_card *card,
4447 struct hdspm *hdspm)
2873{ 4448{
2874 unsigned int idx, limit; 4449 unsigned int idx, limit;
2875 int err; 4450 int err;
2876 struct snd_kcontrol *kctl; 4451 struct snd_kcontrol *kctl;
4452 struct snd_kcontrol_new *list = NULL;
2877 4453
2878 /* add control list first */ 4454 switch (hdspm->io_type) {
2879 if (hdspm->is_aes32) { 4455 case MADI:
2880 struct snd_kcontrol_new aes_sync_ctl = 4456 list = snd_hdspm_controls_madi;
2881 HDSPM_AES_SYNC_CHECK("AES Lock Status", 0); 4457 limit = ARRAY_SIZE(snd_hdspm_controls_madi);
4458 break;
4459 case MADIface:
4460 list = snd_hdspm_controls_madiface;
4461 limit = ARRAY_SIZE(snd_hdspm_controls_madiface);
4462 break;
4463 case AIO:
4464 list = snd_hdspm_controls_aio;
4465 limit = ARRAY_SIZE(snd_hdspm_controls_aio);
4466 break;
4467 case RayDAT:
4468 list = snd_hdspm_controls_raydat;
4469 limit = ARRAY_SIZE(snd_hdspm_controls_raydat);
4470 break;
4471 case AES32:
4472 list = snd_hdspm_controls_aes32;
4473 limit = ARRAY_SIZE(snd_hdspm_controls_aes32);
4474 break;
4475 }
2882 4476
2883 for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls_aes32); 4477 if (NULL != list) {
2884 idx++) { 4478 for (idx = 0; idx < limit; idx++) {
2885 err = snd_ctl_add(card,
2886 snd_ctl_new1(&snd_hdspm_controls_aes32[idx],
2887 hdspm));
2888 if (err < 0)
2889 return err;
2890 }
2891 for (idx = 1; idx <= 8; idx++) {
2892 aes_sync_ctl.index = idx;
2893 err = snd_ctl_add(card,
2894 snd_ctl_new1(&aes_sync_ctl, hdspm));
2895 if (err < 0)
2896 return err;
2897 }
2898 } else {
2899 for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls_madi);
2900 idx++) {
2901 err = snd_ctl_add(card, 4479 err = snd_ctl_add(card,
2902 snd_ctl_new1(&snd_hdspm_controls_madi[idx], 4480 snd_ctl_new1(&list[idx], hdspm));
2903 hdspm));
2904 if (err < 0) 4481 if (err < 0)
2905 return err; 4482 return err;
2906 } 4483 }
2907 } 4484 }
2908 4485
2909 /* Channel playback mixer as default control
2910 Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders,
2911 thats too * big for any alsamixer they are accesible via special
2912 IOCTL on hwdep and the mixer 2dimensional mixer control
2913 */
2914 4486
4487 /* create simple 1:1 playback mixer controls */
2915 snd_hdspm_playback_mixer.name = "Chn"; 4488 snd_hdspm_playback_mixer.name = "Chn";
2916 limit = HDSPM_MAX_CHANNELS; 4489 if (hdspm->system_sample_rate >= 128000) {
2917 4490 limit = hdspm->qs_out_channels;
2918 /* The index values are one greater than the channel ID so that 4491 } else if (hdspm->system_sample_rate >= 64000) {
2919 * alsamixer will display them correctly. We want to use the index 4492 limit = hdspm->ds_out_channels;
2920 * for fast lookup of the relevant channel, but if we use it at all, 4493 } else {
2921 * most ALSA software does the wrong thing with it ... 4494 limit = hdspm->ss_out_channels;
2922 */ 4495 }
2923
2924 for (idx = 0; idx < limit; ++idx) { 4496 for (idx = 0; idx < limit; ++idx) {
2925 snd_hdspm_playback_mixer.index = idx + 1; 4497 snd_hdspm_playback_mixer.index = idx + 1;
2926 kctl = snd_ctl_new1(&snd_hdspm_playback_mixer, hdspm); 4498 kctl = snd_ctl_new1(&snd_hdspm_playback_mixer, hdspm);
@@ -2930,11 +4502,24 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm
2930 hdspm->playback_mixer_ctls[idx] = kctl; 4502 hdspm->playback_mixer_ctls[idx] = kctl;
2931 } 4503 }
2932 4504
4505
4506 if (hdspm->tco) {
4507 /* add tco control elements */
4508 list = snd_hdspm_controls_tco;
4509 limit = ARRAY_SIZE(snd_hdspm_controls_tco);
4510 for (idx = 0; idx < limit; idx++) {
4511 err = snd_ctl_add(card,
4512 snd_ctl_new1(&list[idx], hdspm));
4513 if (err < 0)
4514 return err;
4515 }
4516 }
4517
2933 return 0; 4518 return 0;
2934} 4519}
2935 4520
2936/*------------------------------------------------------------ 4521/*------------------------------------------------------------
2937 /proc interface 4522 /proc interface
2938 ------------------------------------------------------------*/ 4523 ------------------------------------------------------------*/
2939 4524
2940static void 4525static void
@@ -2942,72 +4527,178 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
2942 struct snd_info_buffer *buffer) 4527 struct snd_info_buffer *buffer)
2943{ 4528{
2944 struct hdspm *hdspm = entry->private_data; 4529 struct hdspm *hdspm = entry->private_data;
2945 unsigned int status; 4530 unsigned int status, status2, control, freq;
2946 unsigned int status2; 4531
2947 char *pref_sync_ref; 4532 char *pref_sync_ref;
2948 char *autosync_ref; 4533 char *autosync_ref;
2949 char *system_clock_mode; 4534 char *system_clock_mode;
2950 char *clock_source;
2951 char *insel; 4535 char *insel;
2952 char *syncref;
2953 int x, x2; 4536 int x, x2;
2954 4537
4538 /* TCO stuff */
4539 int a, ltc, frames, seconds, minutes, hours;
4540 unsigned int period;
4541 u64 freq_const = 0;
4542 u32 rate;
4543
2955 status = hdspm_read(hdspm, HDSPM_statusRegister); 4544 status = hdspm_read(hdspm, HDSPM_statusRegister);
2956 status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 4545 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
4546 control = hdspm->control_register;
4547 freq = hdspm_read(hdspm, HDSPM_timecodeRegister);
2957 4548
2958 snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n", 4549 snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n",
2959 hdspm->card_name, hdspm->card->number + 1, 4550 hdspm->card_name, hdspm->card->number + 1,
2960 hdspm->firmware_rev, 4551 hdspm->firmware_rev,
2961 (status2 & HDSPM_version0) | 4552 (status2 & HDSPM_version0) |
2962 (status2 & HDSPM_version1) | (status2 & 4553 (status2 & HDSPM_version1) | (status2 &
2963 HDSPM_version2)); 4554 HDSPM_version2));
4555
4556 snd_iprintf(buffer, "HW Serial: 0x%06x%06x\n",
4557 (hdspm_read(hdspm, HDSPM_midiStatusIn1)>>8) & 0xFFFFFF,
4558 (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF);
2964 4559
2965 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n", 4560 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
2966 hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase); 4561 hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
2967 4562
2968 snd_iprintf(buffer, "--- System ---\n"); 4563 snd_iprintf(buffer, "--- System ---\n");
2969 4564
2970 snd_iprintf(buffer, 4565 snd_iprintf(buffer,
2971 "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n", 4566 "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
2972 status & HDSPM_audioIRQPending, 4567 status & HDSPM_audioIRQPending,
2973 (status & HDSPM_midi0IRQPending) ? 1 : 0, 4568 (status & HDSPM_midi0IRQPending) ? 1 : 0,
2974 (status & HDSPM_midi1IRQPending) ? 1 : 0, 4569 (status & HDSPM_midi1IRQPending) ? 1 : 0,
2975 hdspm->irq_count); 4570 hdspm->irq_count);
2976 snd_iprintf(buffer, 4571 snd_iprintf(buffer,
2977 "HW pointer: id = %d, rawptr = %d (%d->%d) " 4572 "HW pointer: id = %d, rawptr = %d (%d->%d) "
2978 "estimated= %ld (bytes)\n", 4573 "estimated= %ld (bytes)\n",
2979 ((status & HDSPM_BufferID) ? 1 : 0), 4574 ((status & HDSPM_BufferID) ? 1 : 0),
2980 (status & HDSPM_BufferPositionMask), 4575 (status & HDSPM_BufferPositionMask),
2981 (status & HDSPM_BufferPositionMask) % 4576 (status & HDSPM_BufferPositionMask) %
2982 (2 * (int)hdspm->period_bytes), 4577 (2 * (int)hdspm->period_bytes),
2983 ((status & HDSPM_BufferPositionMask) - 64) % 4578 ((status & HDSPM_BufferPositionMask) - 64) %
2984 (2 * (int)hdspm->period_bytes), 4579 (2 * (int)hdspm->period_bytes),
2985 (long) hdspm_hw_pointer(hdspm) * 4); 4580 (long) hdspm_hw_pointer(hdspm) * 4);
2986 4581
2987 snd_iprintf(buffer, 4582 snd_iprintf(buffer,
2988 "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n", 4583 "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
2989 hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF, 4584 hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF,
2990 hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF, 4585 hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF,
2991 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, 4586 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
2992 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); 4587 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
2993 snd_iprintf(buffer, 4588 snd_iprintf(buffer,
2994 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, " 4589 "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n",
2995 "status2=0x%x\n", 4590 hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF,
2996 hdspm->control_register, hdspm->control2_register, 4591 hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF);
2997 status, status2); 4592 snd_iprintf(buffer,
4593 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
4594 "status2=0x%x\n",
4595 hdspm->control_register, hdspm->control2_register,
4596 status, status2);
4597 if (status & HDSPM_tco_detect) {
4598 snd_iprintf(buffer, "TCO module detected.\n");
4599 a = hdspm_read(hdspm, HDSPM_RD_TCO+4);
4600 if (a & HDSPM_TCO1_LTC_Input_valid) {
4601 snd_iprintf(buffer, " LTC valid, ");
4602 switch (a & (HDSPM_TCO1_LTC_Format_LSB |
4603 HDSPM_TCO1_LTC_Format_MSB)) {
4604 case 0:
4605 snd_iprintf(buffer, "24 fps, ");
4606 break;
4607 case HDSPM_TCO1_LTC_Format_LSB:
4608 snd_iprintf(buffer, "25 fps, ");
4609 break;
4610 case HDSPM_TCO1_LTC_Format_MSB:
4611 snd_iprintf(buffer, "29.97 fps, ");
4612 break;
4613 default:
4614 snd_iprintf(buffer, "30 fps, ");
4615 break;
4616 }
4617 if (a & HDSPM_TCO1_set_drop_frame_flag) {
4618 snd_iprintf(buffer, "drop frame\n");
4619 } else {
4620 snd_iprintf(buffer, "full frame\n");
4621 }
4622 } else {
4623 snd_iprintf(buffer, " no LTC\n");
4624 }
4625 if (a & HDSPM_TCO1_Video_Input_Format_NTSC) {
4626 snd_iprintf(buffer, " Video: NTSC\n");
4627 } else if (a & HDSPM_TCO1_Video_Input_Format_PAL) {
4628 snd_iprintf(buffer, " Video: PAL\n");
4629 } else {
4630 snd_iprintf(buffer, " No video\n");
4631 }
4632 if (a & HDSPM_TCO1_TCO_lock) {
4633 snd_iprintf(buffer, " Sync: lock\n");
4634 } else {
4635 snd_iprintf(buffer, " Sync: no lock\n");
4636 }
4637
4638 switch (hdspm->io_type) {
4639 case MADI:
4640 case AES32:
4641 freq_const = 110069313433624ULL;
4642 break;
4643 case RayDAT:
4644 case AIO:
4645 freq_const = 104857600000000ULL;
4646 break;
4647 case MADIface:
4648 break; /* no TCO possible */
4649 }
4650
4651 period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ);
4652 snd_iprintf(buffer, " period: %u\n", period);
4653
4654
4655 /* rate = freq_const/period; */
4656 rate = div_u64(freq_const, period);
4657
4658 if (control & HDSPM_QuadSpeed) {
4659 rate *= 4;
4660 } else if (control & HDSPM_DoubleSpeed) {
4661 rate *= 2;
4662 }
4663
4664 snd_iprintf(buffer, " Frequency: %u Hz\n",
4665 (unsigned int) rate);
4666
4667 ltc = hdspm_read(hdspm, HDSPM_RD_TCO);
4668 frames = ltc & 0xF;
4669 ltc >>= 4;
4670 frames += (ltc & 0x3) * 10;
4671 ltc >>= 4;
4672 seconds = ltc & 0xF;
4673 ltc >>= 4;
4674 seconds += (ltc & 0x7) * 10;
4675 ltc >>= 4;
4676 minutes = ltc & 0xF;
4677 ltc >>= 4;
4678 minutes += (ltc & 0x7) * 10;
4679 ltc >>= 4;
4680 hours = ltc & 0xF;
4681 ltc >>= 4;
4682 hours += (ltc & 0x3) * 10;
4683 snd_iprintf(buffer,
4684 " LTC In: %02d:%02d:%02d:%02d\n",
4685 hours, minutes, seconds, frames);
4686
4687 } else {
4688 snd_iprintf(buffer, "No TCO module detected.\n");
4689 }
2998 4690
2999 snd_iprintf(buffer, "--- Settings ---\n"); 4691 snd_iprintf(buffer, "--- Settings ---\n");
3000 4692
3001 x = 1 << (6 + hdspm_decode_latency(hdspm->control_register & 4693 x = 1 << (6 + hdspm_decode_latency(hdspm->control_register &
3002 HDSPM_LatencyMask)); 4694 HDSPM_LatencyMask));
3003 4695
3004 snd_iprintf(buffer, 4696 snd_iprintf(buffer,
3005 "Size (Latency): %d samples (2 periods of %lu bytes)\n", 4697 "Size (Latency): %d samples (2 periods of %lu bytes)\n",
3006 x, (unsigned long) hdspm->period_bytes); 4698 x, (unsigned long) hdspm->period_bytes);
3007 4699
3008 snd_iprintf(buffer, "Line out: %s, Precise Pointer: %s\n", 4700 snd_iprintf(buffer, "Line out: %s\n",
3009 (hdspm->control_register & HDSPM_LineOut) ? "on " : "off", 4701 (hdspm->control_register & HDSPM_LineOut) ? "on " : "off");
3010 (hdspm->precise_ptr) ? "on" : "off");
3011 4702
3012 switch (hdspm->control_register & HDSPM_InputMask) { 4703 switch (hdspm->control_register & HDSPM_InputMask) {
3013 case HDSPM_InputOptical: 4704 case HDSPM_InputOptical:
@@ -3017,63 +4708,22 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
3017 insel = "Coaxial"; 4708 insel = "Coaxial";
3018 break; 4709 break;
3019 default: 4710 default:
3020 insel = "Unknown"; 4711 insel = "Unkown";
3021 }
3022
3023 switch (hdspm->control_register & HDSPM_SyncRefMask) {
3024 case HDSPM_SyncRef_Word:
3025 syncref = "WordClock";
3026 break;
3027 case HDSPM_SyncRef_MADI:
3028 syncref = "MADI";
3029 break;
3030 default:
3031 syncref = "Unknown";
3032 } 4712 }
3033 snd_iprintf(buffer, "Inputsel = %s, SyncRef = %s\n", insel,
3034 syncref);
3035 4713
3036 snd_iprintf(buffer, 4714 snd_iprintf(buffer,
3037 "ClearTrackMarker = %s, Transmit in %s Channel Mode, " 4715 "ClearTrackMarker = %s, Transmit in %s Channel Mode, "
3038 "Auto Input %s\n", 4716 "Auto Input %s\n",
3039 (hdspm-> 4717 (hdspm->control_register & HDSPM_clr_tms) ? "on" : "off",
3040 control_register & HDSPM_clr_tms) ? "on" : "off", 4718 (hdspm->control_register & HDSPM_TX_64ch) ? "64" : "56",
3041 (hdspm-> 4719 (hdspm->control_register & HDSPM_AutoInp) ? "on" : "off");
3042 control_register & HDSPM_TX_64ch) ? "64" : "56", 4720
3043 (hdspm->
3044 control_register & HDSPM_AutoInp) ? "on" : "off");
3045 4721
3046 switch (hdspm_clock_source(hdspm)) {
3047 case HDSPM_CLOCK_SOURCE_AUTOSYNC:
3048 clock_source = "AutoSync";
3049 break;
3050 case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ:
3051 clock_source = "Internal 32 kHz";
3052 break;
3053 case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ:
3054 clock_source = "Internal 44.1 kHz";
3055 break;
3056 case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ:
3057 clock_source = "Internal 48 kHz";
3058 break;
3059 case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ:
3060 clock_source = "Internal 64 kHz";
3061 break;
3062 case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ:
3063 clock_source = "Internal 88.2 kHz";
3064 break;
3065 case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ:
3066 clock_source = "Internal 96 kHz";
3067 break;
3068 default:
3069 clock_source = "Error";
3070 }
3071 snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source);
3072 if (!(hdspm->control_register & HDSPM_ClockModeMaster)) 4722 if (!(hdspm->control_register & HDSPM_ClockModeMaster))
3073 system_clock_mode = "Slave"; 4723 system_clock_mode = "AutoSync";
3074 else 4724 else
3075 system_clock_mode = "Master"; 4725 system_clock_mode = "Master";
3076 snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode); 4726 snd_iprintf(buffer, "AutoSync Reference: %s\n", system_clock_mode);
3077 4727
3078 switch (hdspm_pref_sync_ref(hdspm)) { 4728 switch (hdspm_pref_sync_ref(hdspm)) {
3079 case HDSPM_SYNC_FROM_WORD: 4729 case HDSPM_SYNC_FROM_WORD:
@@ -3082,15 +4732,21 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
3082 case HDSPM_SYNC_FROM_MADI: 4732 case HDSPM_SYNC_FROM_MADI:
3083 pref_sync_ref = "MADI Sync"; 4733 pref_sync_ref = "MADI Sync";
3084 break; 4734 break;
4735 case HDSPM_SYNC_FROM_TCO:
4736 pref_sync_ref = "TCO";
4737 break;
4738 case HDSPM_SYNC_FROM_SYNC_IN:
4739 pref_sync_ref = "Sync In";
4740 break;
3085 default: 4741 default:
3086 pref_sync_ref = "XXXX Clock"; 4742 pref_sync_ref = "XXXX Clock";
3087 break; 4743 break;
3088 } 4744 }
3089 snd_iprintf(buffer, "Preferred Sync Reference: %s\n", 4745 snd_iprintf(buffer, "Preferred Sync Reference: %s\n",
3090 pref_sync_ref); 4746 pref_sync_ref);
3091 4747
3092 snd_iprintf(buffer, "System Clock Frequency: %d\n", 4748 snd_iprintf(buffer, "System Clock Frequency: %d\n",
3093 hdspm->system_sample_rate); 4749 hdspm->system_sample_rate);
3094 4750
3095 4751
3096 snd_iprintf(buffer, "--- Status:\n"); 4752 snd_iprintf(buffer, "--- Status:\n");
@@ -3099,12 +4755,18 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
3099 x2 = status2 & HDSPM_wcSync; 4755 x2 = status2 & HDSPM_wcSync;
3100 4756
3101 snd_iprintf(buffer, "Inputs MADI=%s, WordClock=%s\n", 4757 snd_iprintf(buffer, "Inputs MADI=%s, WordClock=%s\n",
3102 (status & HDSPM_madiLock) ? (x ? "Sync" : "Lock") : 4758 (status & HDSPM_madiLock) ? (x ? "Sync" : "Lock") :
3103 "NoLock", 4759 "NoLock",
3104 (status2 & HDSPM_wcLock) ? (x2 ? "Sync" : "Lock") : 4760 (status2 & HDSPM_wcLock) ? (x2 ? "Sync" : "Lock") :
3105 "NoLock"); 4761 "NoLock");
3106 4762
3107 switch (hdspm_autosync_ref(hdspm)) { 4763 switch (hdspm_autosync_ref(hdspm)) {
4764 case HDSPM_AUTOSYNC_FROM_SYNC_IN:
4765 autosync_ref = "Sync In";
4766 break;
4767 case HDSPM_AUTOSYNC_FROM_TCO:
4768 autosync_ref = "TCO";
4769 break;
3108 case HDSPM_AUTOSYNC_FROM_WORD: 4770 case HDSPM_AUTOSYNC_FROM_WORD:
3109 autosync_ref = "Word Clock"; 4771 autosync_ref = "Word Clock";
3110 break; 4772 break;
@@ -3119,15 +4781,15 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
3119 break; 4781 break;
3120 } 4782 }
3121 snd_iprintf(buffer, 4783 snd_iprintf(buffer,
3122 "AutoSync: Reference= %s, Freq=%d (MADI = %d, Word = %d)\n", 4784 "AutoSync: Reference= %s, Freq=%d (MADI = %d, Word = %d)\n",
3123 autosync_ref, hdspm_external_sample_rate(hdspm), 4785 autosync_ref, hdspm_external_sample_rate(hdspm),
3124 (status & HDSPM_madiFreqMask) >> 22, 4786 (status & HDSPM_madiFreqMask) >> 22,
3125 (status2 & HDSPM_wcFreqMask) >> 5); 4787 (status2 & HDSPM_wcFreqMask) >> 5);
3126 4788
3127 snd_iprintf(buffer, "Input: %s, Mode=%s\n", 4789 snd_iprintf(buffer, "Input: %s, Mode=%s\n",
3128 (status & HDSPM_AB_int) ? "Coax" : "Optical", 4790 (status & HDSPM_AB_int) ? "Coax" : "Optical",
3129 (status & HDSPM_RX_64ch) ? "64 channels" : 4791 (status & HDSPM_RX_64ch) ? "64 channels" :
3130 "56 channels"); 4792 "56 channels");
3131 4793
3132 snd_iprintf(buffer, "\n"); 4794 snd_iprintf(buffer, "\n");
3133} 4795}
@@ -3142,8 +4804,6 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
3142 unsigned int timecode; 4804 unsigned int timecode;
3143 int pref_syncref; 4805 int pref_syncref;
3144 char *autosync_ref; 4806 char *autosync_ref;
3145 char *system_clock_mode;
3146 char *clock_source;
3147 int x; 4807 int x;
3148 4808
3149 status = hdspm_read(hdspm, HDSPM_statusRegister); 4809 status = hdspm_read(hdspm, HDSPM_statusRegister);
@@ -3183,24 +4843,27 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
3183 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, 4843 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
3184 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); 4844 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
3185 snd_iprintf(buffer, 4845 snd_iprintf(buffer,
3186 "Register: ctrl1=0x%x, status1=0x%x, status2=0x%x, " 4846 "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n",
3187 "timecode=0x%x\n", 4847 hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF,
3188 hdspm->control_register, 4848 hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF);
3189 status, status2, timecode); 4849 snd_iprintf(buffer,
4850 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
4851 "status2=0x%x\n",
4852 hdspm->control_register, hdspm->control2_register,
4853 status, status2);
3190 4854
3191 snd_iprintf(buffer, "--- Settings ---\n"); 4855 snd_iprintf(buffer, "--- Settings ---\n");
3192 4856
3193 x = 1 << (6 + hdspm_decode_latency(hdspm->control_register & 4857 x = 1 << (6 + hdspm_decode_latency(hdspm->control_register &
3194 HDSPM_LatencyMask)); 4858 HDSPM_LatencyMask));
3195 4859
3196 snd_iprintf(buffer, 4860 snd_iprintf(buffer,
3197 "Size (Latency): %d samples (2 periods of %lu bytes)\n", 4861 "Size (Latency): %d samples (2 periods of %lu bytes)\n",
3198 x, (unsigned long) hdspm->period_bytes); 4862 x, (unsigned long) hdspm->period_bytes);
3199 4863
3200 snd_iprintf(buffer, "Line out: %s, Precise Pointer: %s\n", 4864 snd_iprintf(buffer, "Line out: %s\n",
3201 (hdspm-> 4865 (hdspm->
3202 control_register & HDSPM_LineOut) ? "on " : "off", 4866 control_register & HDSPM_LineOut) ? "on " : "off");
3203 (hdspm->precise_ptr) ? "on" : "off");
3204 4867
3205 snd_iprintf(buffer, 4868 snd_iprintf(buffer,
3206 "ClearTrackMarker %s, Emphasis %s, Dolby %s\n", 4869 "ClearTrackMarker %s, Emphasis %s, Dolby %s\n",
@@ -3211,46 +4874,6 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
3211 (hdspm-> 4874 (hdspm->
3212 control_register & HDSPM_Dolby) ? "on" : "off"); 4875 control_register & HDSPM_Dolby) ? "on" : "off");
3213 4876
3214 switch (hdspm_clock_source(hdspm)) {
3215 case HDSPM_CLOCK_SOURCE_AUTOSYNC:
3216 clock_source = "AutoSync";
3217 break;
3218 case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ:
3219 clock_source = "Internal 32 kHz";
3220 break;
3221 case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ:
3222 clock_source = "Internal 44.1 kHz";
3223 break;
3224 case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ:
3225 clock_source = "Internal 48 kHz";
3226 break;
3227 case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ:
3228 clock_source = "Internal 64 kHz";
3229 break;
3230 case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ:
3231 clock_source = "Internal 88.2 kHz";
3232 break;
3233 case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ:
3234 clock_source = "Internal 96 kHz";
3235 break;
3236 case HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ:
3237 clock_source = "Internal 128 kHz";
3238 break;
3239 case HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ:
3240 clock_source = "Internal 176.4 kHz";
3241 break;
3242 case HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ:
3243 clock_source = "Internal 192 kHz";
3244 break;
3245 default:
3246 clock_source = "Error";
3247 }
3248 snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source);
3249 if (!(hdspm->control_register & HDSPM_ClockModeMaster))
3250 system_clock_mode = "Slave";
3251 else
3252 system_clock_mode = "Master";
3253 snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode);
3254 4877
3255 pref_syncref = hdspm_pref_sync_ref(hdspm); 4878 pref_syncref = hdspm_pref_sync_ref(hdspm);
3256 if (pref_syncref == 0) 4879 if (pref_syncref == 0)
@@ -3274,38 +4897,108 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
3274 snd_iprintf(buffer, "--- Status:\n"); 4897 snd_iprintf(buffer, "--- Status:\n");
3275 4898
3276 snd_iprintf(buffer, "Word: %s Frequency: %d\n", 4899 snd_iprintf(buffer, "Word: %s Frequency: %d\n",
3277 (status & HDSPM_AES32_wcLock)? "Sync " : "No Lock", 4900 (status & HDSPM_AES32_wcLock) ? "Sync " : "No Lock",
3278 HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF)); 4901 HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF));
3279 4902
3280 for (x = 0; x < 8; x++) { 4903 for (x = 0; x < 8; x++) {
3281 snd_iprintf(buffer, "AES%d: %s Frequency: %d\n", 4904 snd_iprintf(buffer, "AES%d: %s Frequency: %d\n",
3282 x+1, 4905 x+1,
3283 (status2 & (HDSPM_LockAES >> x)) ? 4906 (status2 & (HDSPM_LockAES >> x)) ?
3284 "Sync ": "No Lock", 4907 "Sync " : "No Lock",
3285 HDSPM_bit2freq((timecode >> (4*x)) & 0xF)); 4908 HDSPM_bit2freq((timecode >> (4*x)) & 0xF));
3286 } 4909 }
3287 4910
3288 switch (hdspm_autosync_ref(hdspm)) { 4911 switch (hdspm_autosync_ref(hdspm)) {
3289 case HDSPM_AES32_AUTOSYNC_FROM_NONE: autosync_ref="None"; break; 4912 case HDSPM_AES32_AUTOSYNC_FROM_NONE:
3290 case HDSPM_AES32_AUTOSYNC_FROM_WORD: autosync_ref="Word Clock"; break; 4913 autosync_ref = "None"; break;
3291 case HDSPM_AES32_AUTOSYNC_FROM_AES1: autosync_ref="AES1"; break; 4914 case HDSPM_AES32_AUTOSYNC_FROM_WORD:
3292 case HDSPM_AES32_AUTOSYNC_FROM_AES2: autosync_ref="AES2"; break; 4915 autosync_ref = "Word Clock"; break;
3293 case HDSPM_AES32_AUTOSYNC_FROM_AES3: autosync_ref="AES3"; break; 4916 case HDSPM_AES32_AUTOSYNC_FROM_AES1:
3294 case HDSPM_AES32_AUTOSYNC_FROM_AES4: autosync_ref="AES4"; break; 4917 autosync_ref = "AES1"; break;
3295 case HDSPM_AES32_AUTOSYNC_FROM_AES5: autosync_ref="AES5"; break; 4918 case HDSPM_AES32_AUTOSYNC_FROM_AES2:
3296 case HDSPM_AES32_AUTOSYNC_FROM_AES6: autosync_ref="AES6"; break; 4919 autosync_ref = "AES2"; break;
3297 case HDSPM_AES32_AUTOSYNC_FROM_AES7: autosync_ref="AES7"; break; 4920 case HDSPM_AES32_AUTOSYNC_FROM_AES3:
3298 case HDSPM_AES32_AUTOSYNC_FROM_AES8: autosync_ref="AES8"; break; 4921 autosync_ref = "AES3"; break;
3299 default: autosync_ref = "---"; break; 4922 case HDSPM_AES32_AUTOSYNC_FROM_AES4:
4923 autosync_ref = "AES4"; break;
4924 case HDSPM_AES32_AUTOSYNC_FROM_AES5:
4925 autosync_ref = "AES5"; break;
4926 case HDSPM_AES32_AUTOSYNC_FROM_AES6:
4927 autosync_ref = "AES6"; break;
4928 case HDSPM_AES32_AUTOSYNC_FROM_AES7:
4929 autosync_ref = "AES7"; break;
4930 case HDSPM_AES32_AUTOSYNC_FROM_AES8:
4931 autosync_ref = "AES8"; break;
4932 default:
4933 autosync_ref = "---"; break;
3300 } 4934 }
3301 snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref); 4935 snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref);
3302 4936
3303 snd_iprintf(buffer, "\n"); 4937 snd_iprintf(buffer, "\n");
3304} 4938}
3305 4939
4940static void
4941snd_hdspm_proc_read_raydat(struct snd_info_entry *entry,
4942 struct snd_info_buffer *buffer)
4943{
4944 struct hdspm *hdspm = entry->private_data;
4945 unsigned int status1, status2, status3, control, i;
4946 unsigned int lock, sync;
4947
4948 status1 = hdspm_read(hdspm, HDSPM_RD_STATUS_1); /* s1 */
4949 status2 = hdspm_read(hdspm, HDSPM_RD_STATUS_2); /* freq */
4950 status3 = hdspm_read(hdspm, HDSPM_RD_STATUS_3); /* s2 */
4951
4952 control = hdspm->control_register;
4953
4954 snd_iprintf(buffer, "STATUS1: 0x%08x\n", status1);
4955 snd_iprintf(buffer, "STATUS2: 0x%08x\n", status2);
4956 snd_iprintf(buffer, "STATUS3: 0x%08x\n", status3);
4957
4958
4959 snd_iprintf(buffer, "\n*** CLOCK MODE\n\n");
4960
4961 snd_iprintf(buffer, "Clock mode : %s\n",
4962 (hdspm_system_clock_mode(hdspm) == 0) ? "master" : "slave");
4963 snd_iprintf(buffer, "System frequency: %d Hz\n",
4964 hdspm_get_system_sample_rate(hdspm));
4965
4966 snd_iprintf(buffer, "\n*** INPUT STATUS\n\n");
4967
4968 lock = 0x1;
4969 sync = 0x100;
4970
4971 for (i = 0; i < 8; i++) {
4972 snd_iprintf(buffer, "s1_input %d: Lock %d, Sync %d, Freq %s\n",
4973 i,
4974 (status1 & lock) ? 1 : 0,
4975 (status1 & sync) ? 1 : 0,
4976 texts_freq[(status2 >> (i * 4)) & 0xF]);
4977
4978 lock = lock<<1;
4979 sync = sync<<1;
4980 }
4981
4982 snd_iprintf(buffer, "WC input: Lock %d, Sync %d, Freq %s\n",
4983 (status1 & 0x1000000) ? 1 : 0,
4984 (status1 & 0x2000000) ? 1 : 0,
4985 texts_freq[(status1 >> 16) & 0xF]);
4986
4987 snd_iprintf(buffer, "TCO input: Lock %d, Sync %d, Freq %s\n",
4988 (status1 & 0x4000000) ? 1 : 0,
4989 (status1 & 0x8000000) ? 1 : 0,
4990 texts_freq[(status1 >> 20) & 0xF]);
4991
4992 snd_iprintf(buffer, "SYNC IN: Lock %d, Sync %d, Freq %s\n",
4993 (status3 & 0x400) ? 1 : 0,
4994 (status3 & 0x800) ? 1 : 0,
4995 texts_freq[(status2 >> 12) & 0xF]);
4996
4997}
4998
3306#ifdef CONFIG_SND_DEBUG 4999#ifdef CONFIG_SND_DEBUG
3307static void 5000static void
3308snd_hdspm_proc_read_debug(struct snd_info_entry * entry, 5001snd_hdspm_proc_read_debug(struct snd_info_entry *entry,
3309 struct snd_info_buffer *buffer) 5002 struct snd_info_buffer *buffer)
3310{ 5003{
3311 struct hdspm *hdspm = entry->private_data; 5004 struct hdspm *hdspm = entry->private_data;
@@ -3322,16 +5015,68 @@ snd_hdspm_proc_read_debug(struct snd_info_entry * entry,
3322#endif 5015#endif
3323 5016
3324 5017
5018static void snd_hdspm_proc_ports_in(struct snd_info_entry *entry,
5019 struct snd_info_buffer *buffer)
5020{
5021 struct hdspm *hdspm = entry->private_data;
5022 int i;
5023
5024 snd_iprintf(buffer, "# generated by hdspm\n");
3325 5025
3326static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm) 5026 for (i = 0; i < hdspm->max_channels_in; i++) {
5027 snd_iprintf(buffer, "%d=%s\n", i+1, hdspm->port_names_in[i]);
5028 }
5029}
5030
5031static void snd_hdspm_proc_ports_out(struct snd_info_entry *entry,
5032 struct snd_info_buffer *buffer)
5033{
5034 struct hdspm *hdspm = entry->private_data;
5035 int i;
5036
5037 snd_iprintf(buffer, "# generated by hdspm\n");
5038
5039 for (i = 0; i < hdspm->max_channels_out; i++) {
5040 snd_iprintf(buffer, "%d=%s\n", i+1, hdspm->port_names_out[i]);
5041 }
5042}
5043
5044
5045static void __devinit snd_hdspm_proc_init(struct hdspm *hdspm)
3327{ 5046{
3328 struct snd_info_entry *entry; 5047 struct snd_info_entry *entry;
3329 5048
3330 if (!snd_card_proc_new(hdspm->card, "hdspm", &entry)) 5049 if (!snd_card_proc_new(hdspm->card, "hdspm", &entry)) {
3331 snd_info_set_text_ops(entry, hdspm, 5050 switch (hdspm->io_type) {
3332 hdspm->is_aes32 ? 5051 case AES32:
3333 snd_hdspm_proc_read_aes32 : 5052 snd_info_set_text_ops(entry, hdspm,
3334 snd_hdspm_proc_read_madi); 5053 snd_hdspm_proc_read_aes32);
5054 break;
5055 case MADI:
5056 snd_info_set_text_ops(entry, hdspm,
5057 snd_hdspm_proc_read_madi);
5058 break;
5059 case MADIface:
5060 /* snd_info_set_text_ops(entry, hdspm,
5061 snd_hdspm_proc_read_madiface); */
5062 break;
5063 case RayDAT:
5064 snd_info_set_text_ops(entry, hdspm,
5065 snd_hdspm_proc_read_raydat);
5066 break;
5067 case AIO:
5068 break;
5069 }
5070 }
5071
5072 if (!snd_card_proc_new(hdspm->card, "ports.in", &entry)) {
5073 snd_info_set_text_ops(entry, hdspm, snd_hdspm_proc_ports_in);
5074 }
5075
5076 if (!snd_card_proc_new(hdspm->card, "ports.out", &entry)) {
5077 snd_info_set_text_ops(entry, hdspm, snd_hdspm_proc_ports_out);
5078 }
5079
3335#ifdef CONFIG_SND_DEBUG 5080#ifdef CONFIG_SND_DEBUG
3336 /* debug file to read all hdspm registers */ 5081 /* debug file to read all hdspm registers */
3337 if (!snd_card_proc_new(hdspm->card, "debug", &entry)) 5082 if (!snd_card_proc_new(hdspm->card, "debug", &entry))
@@ -3341,47 +5086,48 @@ static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm)
3341} 5086}
3342 5087
3343/*------------------------------------------------------------ 5088/*------------------------------------------------------------
3344 hdspm intitialize 5089 hdspm intitialize
3345 ------------------------------------------------------------*/ 5090 ------------------------------------------------------------*/
3346 5091
3347static int snd_hdspm_set_defaults(struct hdspm * hdspm) 5092static int snd_hdspm_set_defaults(struct hdspm * hdspm)
3348{ 5093{
3349 unsigned int i;
3350
3351 /* ASSUMPTION: hdspm->lock is either held, or there is no need to 5094 /* ASSUMPTION: hdspm->lock is either held, or there is no need to
3352 hold it (e.g. during module initialization). 5095 hold it (e.g. during module initialization).
3353 */ 5096 */
3354 5097
3355 /* set defaults: */ 5098 /* set defaults: */
3356 5099
3357 if (hdspm->is_aes32) 5100 hdspm->settings_register = 0;
5101
5102 switch (hdspm->io_type) {
5103 case MADI:
5104 case MADIface:
5105 hdspm->control_register =
5106 0x2 + 0x8 + 0x10 + 0x80 + 0x400 + 0x4000 + 0x1000000;
5107 break;
5108
5109 case RayDAT:
5110 case AIO:
5111 hdspm->settings_register = 0x1 + 0x1000;
5112 /* Magic values are: LAT_0, LAT_2, Master, freq1, tx64ch, inp_0,
5113 * line_out */
5114 hdspm->control_register =
5115 0x2 + 0x8 + 0x10 + 0x80 + 0x400 + 0x4000 + 0x1000000;
5116 break;
5117
5118 case AES32:
3358 hdspm->control_register = 5119 hdspm->control_register =
3359 HDSPM_ClockModeMaster | /* Master Cloack Mode on */ 5120 HDSPM_ClockModeMaster | /* Master Cloack Mode on */
3360 hdspm_encode_latency(7) | /* latency maximum = 5121 hdspm_encode_latency(7) | /* latency max=8192samples */
3361 * 8192 samples
3362 */
3363 HDSPM_SyncRef0 | /* AES1 is syncclock */ 5122 HDSPM_SyncRef0 | /* AES1 is syncclock */
3364 HDSPM_LineOut | /* Analog output in */ 5123 HDSPM_LineOut | /* Analog output in */
3365 HDSPM_Professional; /* Professional mode */ 5124 HDSPM_Professional; /* Professional mode */
3366 else 5125 break;
3367 hdspm->control_register = 5126 }
3368 HDSPM_ClockModeMaster | /* Master Cloack Mode on */
3369 hdspm_encode_latency(7) | /* latency maximum =
3370 * 8192 samples
3371 */
3372 HDSPM_InputCoaxial | /* Input Coax not Optical */
3373 HDSPM_SyncRef_MADI | /* Madi is syncclock */
3374 HDSPM_LineOut | /* Analog output in */
3375 HDSPM_TX_64ch | /* transmit in 64ch mode */
3376 HDSPM_AutoInp; /* AutoInput chossing (takeover) */
3377
3378 /* ! HDSPM_Frequency0|HDSPM_Frequency1 = 44.1khz */
3379 /* ! HDSPM_DoubleSpeed HDSPM_QuadSpeed = normal speed */
3380 /* ! HDSPM_clr_tms = do not clear bits in track marks */
3381 5127
3382 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); 5128 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
3383 5129
3384 if (!hdspm->is_aes32) { 5130 if (AES32 == hdspm->io_type) {
3385 /* No control2 register for AES32 */ 5131 /* No control2 register for AES32 */
3386#ifdef SNDRV_BIG_ENDIAN 5132#ifdef SNDRV_BIG_ENDIAN
3387 hdspm->control2_register = HDSPM_BIGENDIAN_MODE; 5133 hdspm->control2_register = HDSPM_BIGENDIAN_MODE;
@@ -3397,57 +5143,59 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm)
3397 5143
3398 all_in_all_mixer(hdspm, 0 * UNITY_GAIN); 5144 all_in_all_mixer(hdspm, 0 * UNITY_GAIN);
3399 5145
3400 if (line_outs_monitor[hdspm->dev]) { 5146 if (hdspm->io_type == AIO || hdspm->io_type == RayDAT) {
3401 5147 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
3402 snd_printk(KERN_INFO "HDSPM: "
3403 "sending all playback streams to line outs.\n");
3404
3405 for (i = 0; i < HDSPM_MIXER_CHANNELS; i++) {
3406 if (hdspm_write_pb_gain(hdspm, i, i, UNITY_GAIN))
3407 return -EIO;
3408 }
3409 } 5148 }
3410 5149
3411 /* set a default rate so that the channel map is set up. */ 5150 /* set a default rate so that the channel map is set up. */
3412 hdspm->channel_map = channel_map_madi_ss; 5151 hdspm_set_rate(hdspm, 48000, 1);
3413 hdspm_set_rate(hdspm, 44100, 1);
3414 5152
3415 return 0; 5153 return 0;
3416} 5154}
3417 5155
3418 5156
3419/*------------------------------------------------------------ 5157/*------------------------------------------------------------
3420 interrupt 5158 interrupt
3421 ------------------------------------------------------------*/ 5159 ------------------------------------------------------------*/
3422 5160
3423static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id) 5161static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id)
3424{ 5162{
3425 struct hdspm *hdspm = (struct hdspm *) dev_id; 5163 struct hdspm *hdspm = (struct hdspm *) dev_id;
3426 unsigned int status; 5164 unsigned int status;
3427 int audio; 5165 int i, audio, midi, schedule = 0;
3428 int midi0; 5166 /* cycles_t now; */
3429 int midi1;
3430 unsigned int midi0status;
3431 unsigned int midi1status;
3432 int schedule = 0;
3433 5167
3434 status = hdspm_read(hdspm, HDSPM_statusRegister); 5168 status = hdspm_read(hdspm, HDSPM_statusRegister);
3435 5169
3436 audio = status & HDSPM_audioIRQPending; 5170 audio = status & HDSPM_audioIRQPending;
3437 midi0 = status & HDSPM_midi0IRQPending; 5171 midi = status & (HDSPM_midi0IRQPending | HDSPM_midi1IRQPending |
3438 midi1 = status & HDSPM_midi1IRQPending; 5172 HDSPM_midi2IRQPending | HDSPM_midi3IRQPending);
5173
5174 /* now = get_cycles(); */
5175 /**
5176 * LAT_2..LAT_0 period counter (win) counter (mac)
5177 * 6 4096 ~256053425 ~514672358
5178 * 5 2048 ~128024983 ~257373821
5179 * 4 1024 ~64023706 ~128718089
5180 * 3 512 ~32005945 ~64385999
5181 * 2 256 ~16003039 ~32260176
5182 * 1 128 ~7998738 ~16194507
5183 * 0 64 ~3998231 ~8191558
5184 **/
5185 /*
5186 snd_printk(KERN_INFO "snd_hdspm_interrupt %llu @ %llx\n",
5187 now-hdspm->last_interrupt, status & 0xFFC0);
5188 hdspm->last_interrupt = now;
5189 */
3439 5190
3440 if (!audio && !midi0 && !midi1) 5191 if (!audio && !midi)
3441 return IRQ_NONE; 5192 return IRQ_NONE;
3442 5193
3443 hdspm_write(hdspm, HDSPM_interruptConfirmation, 0); 5194 hdspm_write(hdspm, HDSPM_interruptConfirmation, 0);
3444 hdspm->irq_count++; 5195 hdspm->irq_count++;
3445 5196
3446 midi0status = hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xff;
3447 midi1status = hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xff;
3448 5197
3449 if (audio) { 5198 if (audio) {
3450
3451 if (hdspm->capture_substream) 5199 if (hdspm->capture_substream)
3452 snd_pcm_period_elapsed(hdspm->capture_substream); 5200 snd_pcm_period_elapsed(hdspm->capture_substream);
3453 5201
@@ -3455,118 +5203,44 @@ static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id)
3455 snd_pcm_period_elapsed(hdspm->playback_substream); 5203 snd_pcm_period_elapsed(hdspm->playback_substream);
3456 } 5204 }
3457 5205
3458 if (midi0 && midi0status) { 5206 if (midi) {
3459 /* we disable interrupts for this input until processing 5207 i = 0;
3460 * is done 5208 while (i < hdspm->midiPorts) {
3461 */ 5209 if ((hdspm_read(hdspm,
3462 hdspm->control_register &= ~HDSPM_Midi0InterruptEnable; 5210 hdspm->midi[i].statusIn) & 0xff) &&
3463 hdspm_write(hdspm, HDSPM_controlRegister, 5211 (status & hdspm->midi[i].irq)) {
3464 hdspm->control_register); 5212 /* we disable interrupts for this input until
3465 hdspm->midi[0].pending = 1; 5213 * processing is done
3466 schedule = 1; 5214 */
3467 } 5215 hdspm->control_register &= ~hdspm->midi[i].ie;
3468 if (midi1 && midi1status) { 5216 hdspm_write(hdspm, HDSPM_controlRegister,
3469 /* we disable interrupts for this input until processing 5217 hdspm->control_register);
3470 * is done 5218 hdspm->midi[i].pending = 1;
3471 */ 5219 schedule = 1;
3472 hdspm->control_register &= ~HDSPM_Midi1InterruptEnable; 5220 }
3473 hdspm_write(hdspm, HDSPM_controlRegister, 5221
3474 hdspm->control_register); 5222 i++;
3475 hdspm->midi[1].pending = 1; 5223 }
3476 schedule = 1; 5224
5225 if (schedule)
5226 tasklet_hi_schedule(&hdspm->midi_tasklet);
3477 } 5227 }
3478 if (schedule) 5228
3479 tasklet_schedule(&hdspm->midi_tasklet);
3480 return IRQ_HANDLED; 5229 return IRQ_HANDLED;
3481} 5230}
3482 5231
3483/*------------------------------------------------------------ 5232/*------------------------------------------------------------
3484 pcm interface 5233 pcm interface
3485 ------------------------------------------------------------*/ 5234 ------------------------------------------------------------*/
3486 5235
3487 5236
3488static snd_pcm_uframes_t snd_hdspm_hw_pointer(struct snd_pcm_substream * 5237static snd_pcm_uframes_t snd_hdspm_hw_pointer(struct snd_pcm_substream
3489 substream) 5238 *substream)
3490{ 5239{
3491 struct hdspm *hdspm = snd_pcm_substream_chip(substream); 5240 struct hdspm *hdspm = snd_pcm_substream_chip(substream);
3492 return hdspm_hw_pointer(hdspm); 5241 return hdspm_hw_pointer(hdspm);
3493} 5242}
3494 5243
3495static char *hdspm_channel_buffer_location(struct hdspm * hdspm,
3496 int stream, int channel)
3497{
3498 int mapped_channel;
3499
3500 if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
3501 return NULL;
3502
3503 mapped_channel = hdspm->channel_map[channel];
3504 if (mapped_channel < 0)
3505 return NULL;
3506
3507 if (stream == SNDRV_PCM_STREAM_CAPTURE)
3508 return hdspm->capture_buffer +
3509 mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
3510 else
3511 return hdspm->playback_buffer +
3512 mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
3513}
3514
3515
3516/* dont know why need it ??? */
3517static int snd_hdspm_playback_copy(struct snd_pcm_substream *substream,
3518 int channel, snd_pcm_uframes_t pos,
3519 void __user *src, snd_pcm_uframes_t count)
3520{
3521 struct hdspm *hdspm = snd_pcm_substream_chip(substream);
3522 char *channel_buf;
3523
3524 if (snd_BUG_ON(pos + count > HDSPM_CHANNEL_BUFFER_BYTES / 4))
3525 return -EINVAL;
3526
3527 channel_buf =
3528 hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
3529 channel);
3530
3531 if (snd_BUG_ON(!channel_buf))
3532 return -EIO;
3533
3534 return copy_from_user(channel_buf + pos * 4, src, count * 4);
3535}
3536
3537static int snd_hdspm_capture_copy(struct snd_pcm_substream *substream,
3538 int channel, snd_pcm_uframes_t pos,
3539 void __user *dst, snd_pcm_uframes_t count)
3540{
3541 struct hdspm *hdspm = snd_pcm_substream_chip(substream);
3542 char *channel_buf;
3543
3544 if (snd_BUG_ON(pos + count > HDSPM_CHANNEL_BUFFER_BYTES / 4))
3545 return -EINVAL;
3546
3547 channel_buf =
3548 hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
3549 channel);
3550 if (snd_BUG_ON(!channel_buf))
3551 return -EIO;
3552 return copy_to_user(dst, channel_buf + pos * 4, count * 4);
3553}
3554
3555static int snd_hdspm_hw_silence(struct snd_pcm_substream *substream,
3556 int channel, snd_pcm_uframes_t pos,
3557 snd_pcm_uframes_t count)
3558{
3559 struct hdspm *hdspm = snd_pcm_substream_chip(substream);
3560 char *channel_buf;
3561
3562 channel_buf =
3563 hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
3564 channel);
3565 if (snd_BUG_ON(!channel_buf))
3566 return -EIO;
3567 memset(channel_buf + pos * 4, 0, count * 4);
3568 return 0;
3569}
3570 5244
3571static int snd_hdspm_reset(struct snd_pcm_substream *substream) 5245static int snd_hdspm_reset(struct snd_pcm_substream *substream)
3572{ 5246{
@@ -3589,7 +5263,7 @@ static int snd_hdspm_reset(struct snd_pcm_substream *substream)
3589 snd_pcm_group_for_each_entry(s, substream) { 5263 snd_pcm_group_for_each_entry(s, substream) {
3590 if (s == other) { 5264 if (s == other) {
3591 oruntime->status->hw_ptr = 5265 oruntime->status->hw_ptr =
3592 runtime->status->hw_ptr; 5266 runtime->status->hw_ptr;
3593 break; 5267 break;
3594 } 5268 }
3595 } 5269 }
@@ -3621,19 +5295,19 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
3621 /* The other stream is open, and not by the same 5295 /* The other stream is open, and not by the same
3622 task as this one. Make sure that the parameters 5296 task as this one. Make sure that the parameters
3623 that matter are the same. 5297 that matter are the same.
3624 */ 5298 */
3625 5299
3626 if (params_rate(params) != hdspm->system_sample_rate) { 5300 if (params_rate(params) != hdspm->system_sample_rate) {
3627 spin_unlock_irq(&hdspm->lock); 5301 spin_unlock_irq(&hdspm->lock);
3628 _snd_pcm_hw_param_setempty(params, 5302 _snd_pcm_hw_param_setempty(params,
3629 SNDRV_PCM_HW_PARAM_RATE); 5303 SNDRV_PCM_HW_PARAM_RATE);
3630 return -EBUSY; 5304 return -EBUSY;
3631 } 5305 }
3632 5306
3633 if (params_period_size(params) != hdspm->period_bytes / 4) { 5307 if (params_period_size(params) != hdspm->period_bytes / 4) {
3634 spin_unlock_irq(&hdspm->lock); 5308 spin_unlock_irq(&hdspm->lock);
3635 _snd_pcm_hw_param_setempty(params, 5309 _snd_pcm_hw_param_setempty(params,
3636 SNDRV_PCM_HW_PARAM_PERIOD_SIZE); 5310 SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
3637 return -EBUSY; 5311 return -EBUSY;
3638 } 5312 }
3639 5313
@@ -3646,18 +5320,20 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
3646 spin_lock_irq(&hdspm->lock); 5320 spin_lock_irq(&hdspm->lock);
3647 err = hdspm_set_rate(hdspm, params_rate(params), 0); 5321 err = hdspm_set_rate(hdspm, params_rate(params), 0);
3648 if (err < 0) { 5322 if (err < 0) {
5323 snd_printk(KERN_INFO "err on hdspm_set_rate: %d\n", err);
3649 spin_unlock_irq(&hdspm->lock); 5324 spin_unlock_irq(&hdspm->lock);
3650 _snd_pcm_hw_param_setempty(params, 5325 _snd_pcm_hw_param_setempty(params,
3651 SNDRV_PCM_HW_PARAM_RATE); 5326 SNDRV_PCM_HW_PARAM_RATE);
3652 return err; 5327 return err;
3653 } 5328 }
3654 spin_unlock_irq(&hdspm->lock); 5329 spin_unlock_irq(&hdspm->lock);
3655 5330
3656 err = hdspm_set_interrupt_interval(hdspm, 5331 err = hdspm_set_interrupt_interval(hdspm,
3657 params_period_size(params)); 5332 params_period_size(params));
3658 if (err < 0) { 5333 if (err < 0) {
5334 snd_printk(KERN_INFO "err on hdspm_set_interrupt_interval: %d\n", err);
3659 _snd_pcm_hw_param_setempty(params, 5335 _snd_pcm_hw_param_setempty(params,
3660 SNDRV_PCM_HW_PARAM_PERIOD_SIZE); 5336 SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
3661 return err; 5337 return err;
3662 } 5338 }
3663 5339
@@ -3667,10 +5343,13 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
3667 /* malloc all buffer even if not enabled to get sure */ 5343 /* malloc all buffer even if not enabled to get sure */
3668 /* Update for MADI rev 204: we need to allocate for all channels, 5344 /* Update for MADI rev 204: we need to allocate for all channels,
3669 * otherwise it doesn't work at 96kHz */ 5345 * otherwise it doesn't work at 96kHz */
5346
3670 err = 5347 err =
3671 snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES); 5348 snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES);
3672 if (err < 0) 5349 if (err < 0) {
5350 snd_printk(KERN_INFO "err on snd_pcm_lib_malloc_pages: %d\n", err);
3673 return err; 5351 return err;
5352 }
3674 5353
3675 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 5354 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3676 5355
@@ -3681,7 +5360,7 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
3681 snd_hdspm_enable_out(hdspm, i, 1); 5360 snd_hdspm_enable_out(hdspm, i, 1);
3682 5361
3683 hdspm->playback_buffer = 5362 hdspm->playback_buffer =
3684 (unsigned char *) substream->runtime->dma_area; 5363 (unsigned char *) substream->runtime->dma_area;
3685 snd_printdd("Allocated sample buffer for playback at %p\n", 5364 snd_printdd("Allocated sample buffer for playback at %p\n",
3686 hdspm->playback_buffer); 5365 hdspm->playback_buffer);
3687 } else { 5366 } else {
@@ -3692,23 +5371,40 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
3692 snd_hdspm_enable_in(hdspm, i, 1); 5371 snd_hdspm_enable_in(hdspm, i, 1);
3693 5372
3694 hdspm->capture_buffer = 5373 hdspm->capture_buffer =
3695 (unsigned char *) substream->runtime->dma_area; 5374 (unsigned char *) substream->runtime->dma_area;
3696 snd_printdd("Allocated sample buffer for capture at %p\n", 5375 snd_printdd("Allocated sample buffer for capture at %p\n",
3697 hdspm->capture_buffer); 5376 hdspm->capture_buffer);
3698 } 5377 }
5378
3699 /* 5379 /*
3700 snd_printdd("Allocated sample buffer for %s at 0x%08X\n", 5380 snd_printdd("Allocated sample buffer for %s at 0x%08X\n",
3701 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 5381 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
3702 "playback" : "capture", 5382 "playback" : "capture",
3703 snd_pcm_sgbuf_get_addr(substream, 0)); 5383 snd_pcm_sgbuf_get_addr(substream, 0));
3704 */ 5384 */
3705 /* 5385 /*
3706 snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n", 5386 snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n",
3707 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 5387 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
3708 "playback" : "capture", 5388 "playback" : "capture",
3709 params_rate(params), params_channels(params), 5389 params_rate(params), params_channels(params),
3710 params_buffer_size(params)); 5390 params_buffer_size(params));
3711 */ 5391 */
5392
5393
5394 /* Switch to native float format if requested */
5395 if (SNDRV_PCM_FORMAT_FLOAT_LE == params_format(params)) {
5396 if (!(hdspm->control_register & HDSPe_FLOAT_FORMAT))
5397 snd_printk(KERN_INFO "hdspm: Switching to native 32bit LE float format.\n");
5398
5399 hdspm->control_register |= HDSPe_FLOAT_FORMAT;
5400 } else if (SNDRV_PCM_FORMAT_S32_LE == params_format(params)) {
5401 if (hdspm->control_register & HDSPe_FLOAT_FORMAT)
5402 snd_printk(KERN_INFO "hdspm: Switching to native 32bit LE integer format.\n");
5403
5404 hdspm->control_register &= ~HDSPe_FLOAT_FORMAT;
5405 }
5406 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
5407
3712 return 0; 5408 return 0;
3713} 5409}
3714 5410
@@ -3719,14 +5415,14 @@ static int snd_hdspm_hw_free(struct snd_pcm_substream *substream)
3719 5415
3720 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 5416 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3721 5417
3722 /* params_channels(params) should be enough, 5418 /* params_channels(params) should be enough,
3723 but to get sure in case of error */ 5419 but to get sure in case of error */
3724 for (i = 0; i < HDSPM_MAX_CHANNELS; ++i) 5420 for (i = 0; i < hdspm->max_channels_out; ++i)
3725 snd_hdspm_enable_out(hdspm, i, 0); 5421 snd_hdspm_enable_out(hdspm, i, 0);
3726 5422
3727 hdspm->playback_buffer = NULL; 5423 hdspm->playback_buffer = NULL;
3728 } else { 5424 } else {
3729 for (i = 0; i < HDSPM_MAX_CHANNELS; ++i) 5425 for (i = 0; i < hdspm->max_channels_in; ++i)
3730 snd_hdspm_enable_in(hdspm, i, 0); 5426 snd_hdspm_enable_in(hdspm, i, 0);
3731 5427
3732 hdspm->capture_buffer = NULL; 5428 hdspm->capture_buffer = NULL;
@@ -3738,37 +5434,58 @@ static int snd_hdspm_hw_free(struct snd_pcm_substream *substream)
3738 return 0; 5434 return 0;
3739} 5435}
3740 5436
5437
3741static int snd_hdspm_channel_info(struct snd_pcm_substream *substream, 5438static int snd_hdspm_channel_info(struct snd_pcm_substream *substream,
3742 struct snd_pcm_channel_info * info) 5439 struct snd_pcm_channel_info *info)
3743{ 5440{
3744 struct hdspm *hdspm = snd_pcm_substream_chip(substream); 5441 struct hdspm *hdspm = snd_pcm_substream_chip(substream);
3745 int mapped_channel;
3746 5442
3747 if (snd_BUG_ON(info->channel >= HDSPM_MAX_CHANNELS)) 5443 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3748 return -EINVAL; 5444 if (snd_BUG_ON(info->channel >= hdspm->max_channels_out)) {
5445 snd_printk(KERN_INFO "snd_hdspm_channel_info: output channel out of range (%d)\n", info->channel);
5446 return -EINVAL;
5447 }
3749 5448
3750 mapped_channel = hdspm->channel_map[info->channel]; 5449 if (hdspm->channel_map_out[info->channel] < 0) {
3751 if (mapped_channel < 0) 5450 snd_printk(KERN_INFO "snd_hdspm_channel_info: output channel %d mapped out\n", info->channel);
3752 return -EINVAL; 5451 return -EINVAL;
5452 }
5453
5454 info->offset = hdspm->channel_map_out[info->channel] *
5455 HDSPM_CHANNEL_BUFFER_BYTES;
5456 } else {
5457 if (snd_BUG_ON(info->channel >= hdspm->max_channels_in)) {
5458 snd_printk(KERN_INFO "snd_hdspm_channel_info: input channel out of range (%d)\n", info->channel);
5459 return -EINVAL;
5460 }
5461
5462 if (hdspm->channel_map_in[info->channel] < 0) {
5463 snd_printk(KERN_INFO "snd_hdspm_channel_info: input channel %d mapped out\n", info->channel);
5464 return -EINVAL;
5465 }
5466
5467 info->offset = hdspm->channel_map_in[info->channel] *
5468 HDSPM_CHANNEL_BUFFER_BYTES;
5469 }
3753 5470
3754 info->offset = mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
3755 info->first = 0; 5471 info->first = 0;
3756 info->step = 32; 5472 info->step = 32;
3757 return 0; 5473 return 0;
3758} 5474}
3759 5475
5476
3760static int snd_hdspm_ioctl(struct snd_pcm_substream *substream, 5477static int snd_hdspm_ioctl(struct snd_pcm_substream *substream,
3761 unsigned int cmd, void *arg) 5478 unsigned int cmd, void *arg)
3762{ 5479{
3763 switch (cmd) { 5480 switch (cmd) {
3764 case SNDRV_PCM_IOCTL1_RESET: 5481 case SNDRV_PCM_IOCTL1_RESET:
3765 return snd_hdspm_reset(substream); 5482 return snd_hdspm_reset(substream);
3766 5483
3767 case SNDRV_PCM_IOCTL1_CHANNEL_INFO: 5484 case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
3768 { 5485 {
3769 struct snd_pcm_channel_info *info = arg; 5486 struct snd_pcm_channel_info *info = arg;
3770 return snd_hdspm_channel_info(substream, info); 5487 return snd_hdspm_channel_info(substream, info);
3771 } 5488 }
3772 default: 5489 default:
3773 break; 5490 break;
3774 } 5491 }
@@ -3815,19 +5532,19 @@ static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd)
3815 } 5532 }
3816 if (cmd == SNDRV_PCM_TRIGGER_START) { 5533 if (cmd == SNDRV_PCM_TRIGGER_START) {
3817 if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) 5534 if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK))
3818 && substream->stream == 5535 && substream->stream ==
3819 SNDRV_PCM_STREAM_CAPTURE) 5536 SNDRV_PCM_STREAM_CAPTURE)
3820 hdspm_silence_playback(hdspm); 5537 hdspm_silence_playback(hdspm);
3821 } else { 5538 } else {
3822 if (running && 5539 if (running &&
3823 substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 5540 substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
3824 hdspm_silence_playback(hdspm); 5541 hdspm_silence_playback(hdspm);
3825 } 5542 }
3826 } else { 5543 } else {
3827 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 5544 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
3828 hdspm_silence_playback(hdspm); 5545 hdspm_silence_playback(hdspm);
3829 } 5546 }
3830 _ok: 5547_ok:
3831 snd_pcm_trigger_done(substream, substream); 5548 snd_pcm_trigger_done(substream, substream);
3832 if (!hdspm->running && running) 5549 if (!hdspm->running && running)
3833 hdspm_start_audio(hdspm); 5550 hdspm_start_audio(hdspm);
@@ -3844,8 +5561,18 @@ static int snd_hdspm_prepare(struct snd_pcm_substream *substream)
3844 return 0; 5561 return 0;
3845} 5562}
3846 5563
3847static unsigned int period_sizes[] = 5564static unsigned int period_sizes_old[] = {
3848 { 64, 128, 256, 512, 1024, 2048, 4096, 8192 }; 5565 64, 128, 256, 512, 1024, 2048, 4096
5566};
5567
5568static unsigned int period_sizes_new[] = {
5569 32, 64, 128, 256, 512, 1024, 2048, 4096
5570};
5571
5572/* RayDAT and AIO always have a buffer of 16384 samples per channel */
5573static unsigned int raydat_aio_buffer_sizes[] = {
5574 16384
5575};
3849 5576
3850static struct snd_pcm_hardware snd_hdspm_playback_subinfo = { 5577static struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
3851 .info = (SNDRV_PCM_INFO_MMAP | 5578 .info = (SNDRV_PCM_INFO_MMAP |
@@ -3866,9 +5593,9 @@ static struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
3866 .buffer_bytes_max = 5593 .buffer_bytes_max =
3867 HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS, 5594 HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
3868 .period_bytes_min = (64 * 4), 5595 .period_bytes_min = (64 * 4),
3869 .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS, 5596 .period_bytes_max = (4096 * 4) * HDSPM_MAX_CHANNELS,
3870 .periods_min = 2, 5597 .periods_min = 2,
3871 .periods_max = 2, 5598 .periods_max = 512,
3872 .fifo_size = 0 5599 .fifo_size = 0
3873}; 5600};
3874 5601
@@ -3891,20 +5618,66 @@ static struct snd_pcm_hardware snd_hdspm_capture_subinfo = {
3891 .buffer_bytes_max = 5618 .buffer_bytes_max =
3892 HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS, 5619 HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
3893 .period_bytes_min = (64 * 4), 5620 .period_bytes_min = (64 * 4),
3894 .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS, 5621 .period_bytes_max = (4096 * 4) * HDSPM_MAX_CHANNELS,
3895 .periods_min = 2, 5622 .periods_min = 2,
3896 .periods_max = 2, 5623 .periods_max = 512,
3897 .fifo_size = 0 5624 .fifo_size = 0
3898}; 5625};
3899 5626
3900static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = { 5627static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes_old = {
3901 .count = ARRAY_SIZE(period_sizes), 5628 .count = ARRAY_SIZE(period_sizes_old),
3902 .list = period_sizes, 5629 .list = period_sizes_old,
3903 .mask = 0 5630 .mask = 0
3904}; 5631};
3905 5632
5633static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes_new = {
5634 .count = ARRAY_SIZE(period_sizes_new),
5635 .list = period_sizes_new,
5636 .mask = 0
5637};
3906 5638
3907static int snd_hdspm_hw_rule_channels_rate(struct snd_pcm_hw_params *params, 5639static struct snd_pcm_hw_constraint_list hw_constraints_raydat_io_buffer = {
5640 .count = ARRAY_SIZE(raydat_aio_buffer_sizes),
5641 .list = raydat_aio_buffer_sizes,
5642 .mask = 0
5643};
5644
5645static int snd_hdspm_hw_rule_in_channels_rate(struct snd_pcm_hw_params *params,
5646 struct snd_pcm_hw_rule *rule)
5647{
5648 struct hdspm *hdspm = rule->private;
5649 struct snd_interval *c =
5650 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
5651 struct snd_interval *r =
5652 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
5653
5654 if (r->min > 96000 && r->max <= 192000) {
5655 struct snd_interval t = {
5656 .min = hdspm->qs_in_channels,
5657 .max = hdspm->qs_in_channels,
5658 .integer = 1,
5659 };
5660 return snd_interval_refine(c, &t);
5661 } else if (r->min > 48000 && r->max <= 96000) {
5662 struct snd_interval t = {
5663 .min = hdspm->ds_in_channels,
5664 .max = hdspm->ds_in_channels,
5665 .integer = 1,
5666 };
5667 return snd_interval_refine(c, &t);
5668 } else if (r->max < 64000) {
5669 struct snd_interval t = {
5670 .min = hdspm->ss_in_channels,
5671 .max = hdspm->ss_in_channels,
5672 .integer = 1,
5673 };
5674 return snd_interval_refine(c, &t);
5675 }
5676
5677 return 0;
5678}
5679
5680static int snd_hdspm_hw_rule_out_channels_rate(struct snd_pcm_hw_params *params,
3908 struct snd_pcm_hw_rule * rule) 5681 struct snd_pcm_hw_rule * rule)
3909{ 5682{
3910 struct hdspm *hdspm = rule->private; 5683 struct hdspm *hdspm = rule->private;
@@ -3913,25 +5686,33 @@ static int snd_hdspm_hw_rule_channels_rate(struct snd_pcm_hw_params *params,
3913 struct snd_interval *r = 5686 struct snd_interval *r =
3914 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 5687 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
3915 5688
3916 if (r->min > 48000 && r->max <= 96000) { 5689 if (r->min > 96000 && r->max <= 192000) {
3917 struct snd_interval t = { 5690 struct snd_interval t = {
3918 .min = hdspm->ds_channels, 5691 .min = hdspm->qs_out_channels,
3919 .max = hdspm->ds_channels, 5692 .max = hdspm->qs_out_channels,
5693 .integer = 1,
5694 };
5695 return snd_interval_refine(c, &t);
5696 } else if (r->min > 48000 && r->max <= 96000) {
5697 struct snd_interval t = {
5698 .min = hdspm->ds_out_channels,
5699 .max = hdspm->ds_out_channels,
3920 .integer = 1, 5700 .integer = 1,
3921 }; 5701 };
3922 return snd_interval_refine(c, &t); 5702 return snd_interval_refine(c, &t);
3923 } else if (r->max < 64000) { 5703 } else if (r->max < 64000) {
3924 struct snd_interval t = { 5704 struct snd_interval t = {
3925 .min = hdspm->ss_channels, 5705 .min = hdspm->ss_out_channels,
3926 .max = hdspm->ss_channels, 5706 .max = hdspm->ss_out_channels,
3927 .integer = 1, 5707 .integer = 1,
3928 }; 5708 };
3929 return snd_interval_refine(c, &t); 5709 return snd_interval_refine(c, &t);
5710 } else {
3930 } 5711 }
3931 return 0; 5712 return 0;
3932} 5713}
3933 5714
3934static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params, 5715static int snd_hdspm_hw_rule_rate_in_channels(struct snd_pcm_hw_params *params,
3935 struct snd_pcm_hw_rule * rule) 5716 struct snd_pcm_hw_rule * rule)
3936{ 5717{
3937 struct hdspm *hdspm = rule->private; 5718 struct hdspm *hdspm = rule->private;
@@ -3940,42 +5721,92 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params,
3940 struct snd_interval *r = 5721 struct snd_interval *r =
3941 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 5722 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
3942 5723
3943 if (c->min >= hdspm->ss_channels) { 5724 if (c->min >= hdspm->ss_in_channels) {
3944 struct snd_interval t = { 5725 struct snd_interval t = {
3945 .min = 32000, 5726 .min = 32000,
3946 .max = 48000, 5727 .max = 48000,
3947 .integer = 1, 5728 .integer = 1,
3948 }; 5729 };
3949 return snd_interval_refine(r, &t); 5730 return snd_interval_refine(r, &t);
3950 } else if (c->max <= hdspm->ds_channels) { 5731 } else if (c->max <= hdspm->qs_in_channels) {
5732 struct snd_interval t = {
5733 .min = 128000,
5734 .max = 192000,
5735 .integer = 1,
5736 };
5737 return snd_interval_refine(r, &t);
5738 } else if (c->max <= hdspm->ds_in_channels) {
3951 struct snd_interval t = { 5739 struct snd_interval t = {
3952 .min = 64000, 5740 .min = 64000,
3953 .max = 96000, 5741 .max = 96000,
3954 .integer = 1, 5742 .integer = 1,
3955 }; 5743 };
5744 return snd_interval_refine(r, &t);
5745 }
3956 5746
5747 return 0;
5748}
5749static int snd_hdspm_hw_rule_rate_out_channels(struct snd_pcm_hw_params *params,
5750 struct snd_pcm_hw_rule *rule)
5751{
5752 struct hdspm *hdspm = rule->private;
5753 struct snd_interval *c =
5754 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
5755 struct snd_interval *r =
5756 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
5757
5758 if (c->min >= hdspm->ss_out_channels) {
5759 struct snd_interval t = {
5760 .min = 32000,
5761 .max = 48000,
5762 .integer = 1,
5763 };
5764 return snd_interval_refine(r, &t);
5765 } else if (c->max <= hdspm->qs_out_channels) {
5766 struct snd_interval t = {
5767 .min = 128000,
5768 .max = 192000,
5769 .integer = 1,
5770 };
5771 return snd_interval_refine(r, &t);
5772 } else if (c->max <= hdspm->ds_out_channels) {
5773 struct snd_interval t = {
5774 .min = 64000,
5775 .max = 96000,
5776 .integer = 1,
5777 };
3957 return snd_interval_refine(r, &t); 5778 return snd_interval_refine(r, &t);
3958 } 5779 }
5780
3959 return 0; 5781 return 0;
3960} 5782}
3961 5783
3962static int snd_hdspm_hw_rule_channels(struct snd_pcm_hw_params *params, 5784static int snd_hdspm_hw_rule_in_channels(struct snd_pcm_hw_params *params,
3963 struct snd_pcm_hw_rule *rule) 5785 struct snd_pcm_hw_rule *rule)
3964{ 5786{
3965 unsigned int list[3]; 5787 unsigned int list[3];
3966 struct hdspm *hdspm = rule->private; 5788 struct hdspm *hdspm = rule->private;
3967 struct snd_interval *c = hw_param_interval(params, 5789 struct snd_interval *c = hw_param_interval(params,
3968 SNDRV_PCM_HW_PARAM_CHANNELS); 5790 SNDRV_PCM_HW_PARAM_CHANNELS);
3969 if (hdspm->is_aes32) { 5791
3970 list[0] = hdspm->qs_channels; 5792 list[0] = hdspm->qs_in_channels;
3971 list[1] = hdspm->ds_channels; 5793 list[1] = hdspm->ds_in_channels;
3972 list[2] = hdspm->ss_channels; 5794 list[2] = hdspm->ss_in_channels;
3973 return snd_interval_list(c, 3, list, 0); 5795 return snd_interval_list(c, 3, list, 0);
3974 } else { 5796}
3975 list[0] = hdspm->ds_channels; 5797
3976 list[1] = hdspm->ss_channels; 5798static int snd_hdspm_hw_rule_out_channels(struct snd_pcm_hw_params *params,
3977 return snd_interval_list(c, 2, list, 0); 5799 struct snd_pcm_hw_rule *rule)
3978 } 5800{
5801 unsigned int list[3];
5802 struct hdspm *hdspm = rule->private;
5803 struct snd_interval *c = hw_param_interval(params,
5804 SNDRV_PCM_HW_PARAM_CHANNELS);
5805
5806 list[0] = hdspm->qs_out_channels;
5807 list[1] = hdspm->ds_out_channels;
5808 list[2] = hdspm->ss_out_channels;
5809 return snd_interval_list(c, 3, list, 0);
3979} 5810}
3980 5811
3981 5812
@@ -3999,6 +5830,7 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream)
3999 5830
4000 snd_pcm_set_sync(substream); 5831 snd_pcm_set_sync(substream);
4001 5832
5833
4002 runtime->hw = snd_hdspm_playback_subinfo; 5834 runtime->hw = snd_hdspm_playback_subinfo;
4003 5835
4004 if (hdspm->capture_substream == NULL) 5836 if (hdspm->capture_substream == NULL)
@@ -4011,25 +5843,41 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream)
4011 5843
4012 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 5844 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
4013 5845
4014 snd_pcm_hw_constraint_list(runtime, 0, 5846 switch (hdspm->io_type) {
4015 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 5847 case AIO:
4016 &hw_constraints_period_sizes); 5848 case RayDAT:
5849 snd_pcm_hw_constraint_list(runtime, 0,
5850 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
5851 &hw_constraints_period_sizes_new);
5852 snd_pcm_hw_constraint_list(runtime, 0,
5853 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
5854 &hw_constraints_raydat_io_buffer);
5855
5856 break;
5857
5858 default:
5859 snd_pcm_hw_constraint_list(runtime, 0,
5860 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
5861 &hw_constraints_period_sizes_old);
5862 }
4017 5863
4018 if (hdspm->is_aes32) { 5864 if (AES32 == hdspm->io_type) {
4019 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 5865 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
4020 &hdspm_hw_constraints_aes32_sample_rates); 5866 &hdspm_hw_constraints_aes32_sample_rates);
4021 } else { 5867 } else {
4022 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4023 snd_hdspm_hw_rule_channels, hdspm,
4024 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4025 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4026 snd_hdspm_hw_rule_channels_rate, hdspm,
4027 SNDRV_PCM_HW_PARAM_RATE, -1);
4028
4029 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 5868 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
4030 snd_hdspm_hw_rule_rate_channels, hdspm, 5869 snd_hdspm_hw_rule_rate_out_channels, hdspm,
4031 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 5870 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4032 } 5871 }
5872
5873 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
5874 snd_hdspm_hw_rule_out_channels, hdspm,
5875 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
5876
5877 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
5878 snd_hdspm_hw_rule_out_channels_rate, hdspm,
5879 SNDRV_PCM_HW_PARAM_RATE, -1);
5880
4033 return 0; 5881 return 0;
4034} 5882}
4035 5883
@@ -4066,24 +5914,40 @@ static int snd_hdspm_capture_open(struct snd_pcm_substream *substream)
4066 spin_unlock_irq(&hdspm->lock); 5914 spin_unlock_irq(&hdspm->lock);
4067 5915
4068 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 5916 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
4069 snd_pcm_hw_constraint_list(runtime, 0, 5917 switch (hdspm->io_type) {
4070 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 5918 case AIO:
4071 &hw_constraints_period_sizes); 5919 case RayDAT:
4072 if (hdspm->is_aes32) { 5920 snd_pcm_hw_constraint_list(runtime, 0,
5921 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
5922 &hw_constraints_period_sizes_new);
5923 snd_pcm_hw_constraint_list(runtime, 0,
5924 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
5925 &hw_constraints_raydat_io_buffer);
5926 break;
5927
5928 default:
5929 snd_pcm_hw_constraint_list(runtime, 0,
5930 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
5931 &hw_constraints_period_sizes_old);
5932 }
5933
5934 if (AES32 == hdspm->io_type) {
4073 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 5935 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
4074 &hdspm_hw_constraints_aes32_sample_rates); 5936 &hdspm_hw_constraints_aes32_sample_rates);
4075 } else { 5937 } else {
4076 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4077 snd_hdspm_hw_rule_channels, hdspm,
4078 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4079 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4080 snd_hdspm_hw_rule_channels_rate, hdspm,
4081 SNDRV_PCM_HW_PARAM_RATE, -1);
4082
4083 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 5938 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
4084 snd_hdspm_hw_rule_rate_channels, hdspm, 5939 snd_hdspm_hw_rule_rate_in_channels, hdspm,
4085 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 5940 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4086 } 5941 }
5942
5943 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
5944 snd_hdspm_hw_rule_in_channels, hdspm,
5945 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
5946
5947 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
5948 snd_hdspm_hw_rule_in_channels_rate, hdspm,
5949 SNDRV_PCM_HW_PARAM_RATE, -1);
5950
4087 return 0; 5951 return 0;
4088} 5952}
4089 5953
@@ -4100,32 +5964,129 @@ static int snd_hdspm_capture_release(struct snd_pcm_substream *substream)
4100 return 0; 5964 return 0;
4101} 5965}
4102 5966
4103static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file, 5967static int snd_hdspm_hwdep_dummy_op(struct snd_hwdep *hw, struct file *file)
4104 unsigned int cmd, unsigned long arg) 5968{
5969 /* we have nothing to initialize but the call is required */
5970 return 0;
5971}
5972
5973static inline int copy_u32_le(void __user *dest, void __iomem *src)
4105{ 5974{
5975 u32 val = readl(src);
5976 return copy_to_user(dest, &val, 4);
5977}
5978
5979static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
5980 unsigned int cmd, unsigned long __user arg)
5981{
5982 void __user *argp = (void __user *)arg;
4106 struct hdspm *hdspm = hw->private_data; 5983 struct hdspm *hdspm = hw->private_data;
4107 struct hdspm_mixer_ioctl mixer; 5984 struct hdspm_mixer_ioctl mixer;
4108 struct hdspm_config_info info; 5985 struct hdspm_config info;
5986 struct hdspm_status status;
4109 struct hdspm_version hdspm_version; 5987 struct hdspm_version hdspm_version;
4110 struct hdspm_peak_rms_ioctl rms; 5988 struct hdspm_peak_rms *levels;
5989 struct hdspm_ltc ltc;
5990 unsigned int statusregister;
5991 long unsigned int s;
5992 int i = 0;
4111 5993
4112 switch (cmd) { 5994 switch (cmd) {
4113 5995
4114 case SNDRV_HDSPM_IOCTL_GET_PEAK_RMS: 5996 case SNDRV_HDSPM_IOCTL_GET_PEAK_RMS:
4115 if (copy_from_user(&rms, (void __user *)arg, sizeof(rms))) 5997 levels = &hdspm->peak_rms;
5998 for (i = 0; i < HDSPM_MAX_CHANNELS; i++) {
5999 levels->input_peaks[i] =
6000 readl(hdspm->iobase +
6001 HDSPM_MADI_INPUT_PEAK + i*4);
6002 levels->playback_peaks[i] =
6003 readl(hdspm->iobase +
6004 HDSPM_MADI_PLAYBACK_PEAK + i*4);
6005 levels->output_peaks[i] =
6006 readl(hdspm->iobase +
6007 HDSPM_MADI_OUTPUT_PEAK + i*4);
6008
6009 levels->input_rms[i] =
6010 ((uint64_t) readl(hdspm->iobase +
6011 HDSPM_MADI_INPUT_RMS_H + i*4) << 32) |
6012 (uint64_t) readl(hdspm->iobase +
6013 HDSPM_MADI_INPUT_RMS_L + i*4);
6014 levels->playback_rms[i] =
6015 ((uint64_t)readl(hdspm->iobase +
6016 HDSPM_MADI_PLAYBACK_RMS_H+i*4) << 32) |
6017 (uint64_t)readl(hdspm->iobase +
6018 HDSPM_MADI_PLAYBACK_RMS_L + i*4);
6019 levels->output_rms[i] =
6020 ((uint64_t)readl(hdspm->iobase +
6021 HDSPM_MADI_OUTPUT_RMS_H + i*4) << 32) |
6022 (uint64_t)readl(hdspm->iobase +
6023 HDSPM_MADI_OUTPUT_RMS_L + i*4);
6024 }
6025
6026 if (hdspm->system_sample_rate > 96000) {
6027 levels->speed = qs;
6028 } else if (hdspm->system_sample_rate > 48000) {
6029 levels->speed = ds;
6030 } else {
6031 levels->speed = ss;
6032 }
6033 levels->status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
6034
6035 s = copy_to_user(argp, levels, sizeof(struct hdspm_peak_rms));
6036 if (0 != s) {
6037 /* snd_printk(KERN_ERR "copy_to_user(.., .., %lu): %lu
6038 [Levels]\n", sizeof(struct hdspm_peak_rms), s);
6039 */
4116 return -EFAULT; 6040 return -EFAULT;
4117 /* maybe there is a chance to memorymap in future 6041 }
4118 * so dont touch just copy 6042 break;
4119 */ 6043
4120 if(copy_to_user_fromio((void __user *)rms.peak, 6044 case SNDRV_HDSPM_IOCTL_GET_LTC:
4121 hdspm->iobase+HDSPM_MADI_peakrmsbase, 6045 ltc.ltc = hdspm_read(hdspm, HDSPM_RD_TCO);
4122 sizeof(struct hdspm_peak_rms)) != 0 ) 6046 i = hdspm_read(hdspm, HDSPM_RD_TCO + 4);
6047 if (i & HDSPM_TCO1_LTC_Input_valid) {
6048 switch (i & (HDSPM_TCO1_LTC_Format_LSB |
6049 HDSPM_TCO1_LTC_Format_MSB)) {
6050 case 0:
6051 ltc.format = fps_24;
6052 break;
6053 case HDSPM_TCO1_LTC_Format_LSB:
6054 ltc.format = fps_25;
6055 break;
6056 case HDSPM_TCO1_LTC_Format_MSB:
6057 ltc.format = fps_2997;
6058 break;
6059 default:
6060 ltc.format = 30;
6061 break;
6062 }
6063 if (i & HDSPM_TCO1_set_drop_frame_flag) {
6064 ltc.frame = drop_frame;
6065 } else {
6066 ltc.frame = full_frame;
6067 }
6068 } else {
6069 ltc.format = format_invalid;
6070 ltc.frame = frame_invalid;
6071 }
6072 if (i & HDSPM_TCO1_Video_Input_Format_NTSC) {
6073 ltc.input_format = ntsc;
6074 } else if (i & HDSPM_TCO1_Video_Input_Format_PAL) {
6075 ltc.input_format = pal;
6076 } else {
6077 ltc.input_format = no_video;
6078 }
6079
6080 s = copy_to_user(argp, &ltc, sizeof(struct hdspm_ltc));
6081 if (0 != s) {
6082 /*
6083 snd_printk(KERN_ERR "copy_to_user(.., .., %lu): %lu [LTC]\n", sizeof(struct hdspm_ltc), s); */
4123 return -EFAULT; 6084 return -EFAULT;
6085 }
4124 6086
4125 break; 6087 break;
4126
4127 6088
4128 case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO: 6089 case SNDRV_HDSPM_IOCTL_GET_CONFIG:
4129 6090
4130 memset(&info, 0, sizeof(info)); 6091 memset(&info, 0, sizeof(info));
4131 spin_lock_irq(&hdspm->lock); 6092 spin_lock_irq(&hdspm->lock);
@@ -4134,7 +6095,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
4134 6095
4135 info.system_sample_rate = hdspm->system_sample_rate; 6096 info.system_sample_rate = hdspm->system_sample_rate;
4136 info.autosync_sample_rate = 6097 info.autosync_sample_rate =
4137 hdspm_external_sample_rate(hdspm); 6098 hdspm_external_sample_rate(hdspm);
4138 info.system_clock_mode = hdspm_system_clock_mode(hdspm); 6099 info.system_clock_mode = hdspm_system_clock_mode(hdspm);
4139 info.clock_source = hdspm_clock_source(hdspm); 6100 info.clock_source = hdspm_clock_source(hdspm);
4140 info.autosync_ref = hdspm_autosync_ref(hdspm); 6101 info.autosync_ref = hdspm_autosync_ref(hdspm);
@@ -4145,10 +6106,58 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
4145 return -EFAULT; 6106 return -EFAULT;
4146 break; 6107 break;
4147 6108
6109 case SNDRV_HDSPM_IOCTL_GET_STATUS:
6110 status.card_type = hdspm->io_type;
6111
6112 status.autosync_source = hdspm_autosync_ref(hdspm);
6113
6114 status.card_clock = 110069313433624ULL;
6115 status.master_period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ);
6116
6117 switch (hdspm->io_type) {
6118 case MADI:
6119 case MADIface:
6120 status.card_specific.madi.sync_wc =
6121 hdspm_wc_sync_check(hdspm);
6122 status.card_specific.madi.sync_madi =
6123 hdspm_madi_sync_check(hdspm);
6124 status.card_specific.madi.sync_tco =
6125 hdspm_tco_sync_check(hdspm);
6126 status.card_specific.madi.sync_in =
6127 hdspm_sync_in_sync_check(hdspm);
6128
6129 statusregister =
6130 hdspm_read(hdspm, HDSPM_statusRegister);
6131 status.card_specific.madi.madi_input =
6132 (statusregister & HDSPM_AB_int) ? 1 : 0;
6133 status.card_specific.madi.channel_format =
6134 (statusregister & HDSPM_TX_64ch) ? 1 : 0;
6135 /* TODO: Mac driver sets it when f_s>48kHz */
6136 status.card_specific.madi.frame_format = 0;
6137
6138 default:
6139 break;
6140 }
6141
6142 if (copy_to_user((void __user *) arg, &status, sizeof(status)))
6143 return -EFAULT;
6144
6145
6146 break;
6147
4148 case SNDRV_HDSPM_IOCTL_GET_VERSION: 6148 case SNDRV_HDSPM_IOCTL_GET_VERSION:
6149 hdspm_version.card_type = hdspm->io_type;
6150 strncpy(hdspm_version.cardname, hdspm->card_name,
6151 sizeof(hdspm_version.cardname));
6152 hdspm_version.serial = (hdspm_read(hdspm,
6153 HDSPM_midiStatusIn0)>>8) & 0xFFFFFF;
4149 hdspm_version.firmware_rev = hdspm->firmware_rev; 6154 hdspm_version.firmware_rev = hdspm->firmware_rev;
6155 hdspm_version.addons = 0;
6156 if (hdspm->tco)
6157 hdspm_version.addons |= HDSPM_ADDON_TCO;
6158
4150 if (copy_to_user((void __user *) arg, &hdspm_version, 6159 if (copy_to_user((void __user *) arg, &hdspm_version,
4151 sizeof(hdspm_version))) 6160 sizeof(hdspm_version)))
4152 return -EFAULT; 6161 return -EFAULT;
4153 break; 6162 break;
4154 6163
@@ -4156,7 +6165,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
4156 if (copy_from_user(&mixer, (void __user *)arg, sizeof(mixer))) 6165 if (copy_from_user(&mixer, (void __user *)arg, sizeof(mixer)))
4157 return -EFAULT; 6166 return -EFAULT;
4158 if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer, 6167 if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer,
4159 sizeof(struct hdspm_mixer))) 6168 sizeof(struct hdspm_mixer)))
4160 return -EFAULT; 6169 return -EFAULT;
4161 break; 6170 break;
4162 6171
@@ -4175,8 +6184,6 @@ static struct snd_pcm_ops snd_hdspm_playback_ops = {
4175 .prepare = snd_hdspm_prepare, 6184 .prepare = snd_hdspm_prepare,
4176 .trigger = snd_hdspm_trigger, 6185 .trigger = snd_hdspm_trigger,
4177 .pointer = snd_hdspm_hw_pointer, 6186 .pointer = snd_hdspm_hw_pointer,
4178 .copy = snd_hdspm_playback_copy,
4179 .silence = snd_hdspm_hw_silence,
4180 .page = snd_pcm_sgbuf_ops_page, 6187 .page = snd_pcm_sgbuf_ops_page,
4181}; 6188};
4182 6189
@@ -4189,7 +6196,6 @@ static struct snd_pcm_ops snd_hdspm_capture_ops = {
4189 .prepare = snd_hdspm_prepare, 6196 .prepare = snd_hdspm_prepare,
4190 .trigger = snd_hdspm_trigger, 6197 .trigger = snd_hdspm_trigger,
4191 .pointer = snd_hdspm_hw_pointer, 6198 .pointer = snd_hdspm_hw_pointer,
4192 .copy = snd_hdspm_capture_copy,
4193 .page = snd_pcm_sgbuf_ops_page, 6199 .page = snd_pcm_sgbuf_ops_page,
4194}; 6200};
4195 6201
@@ -4207,16 +6213,18 @@ static int __devinit snd_hdspm_create_hwdep(struct snd_card *card,
4207 hw->private_data = hdspm; 6213 hw->private_data = hdspm;
4208 strcpy(hw->name, "HDSPM hwdep interface"); 6214 strcpy(hw->name, "HDSPM hwdep interface");
4209 6215
6216 hw->ops.open = snd_hdspm_hwdep_dummy_op;
4210 hw->ops.ioctl = snd_hdspm_hwdep_ioctl; 6217 hw->ops.ioctl = snd_hdspm_hwdep_ioctl;
6218 hw->ops.release = snd_hdspm_hwdep_dummy_op;
4211 6219
4212 return 0; 6220 return 0;
4213} 6221}
4214 6222
4215 6223
4216/*------------------------------------------------------------ 6224/*------------------------------------------------------------
4217 memory interface 6225 memory interface
4218 ------------------------------------------------------------*/ 6226 ------------------------------------------------------------*/
4219static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm) 6227static int __devinit snd_hdspm_preallocate_memory(struct hdspm *hdspm)
4220{ 6228{
4221 int err; 6229 int err;
4222 struct snd_pcm *pcm; 6230 struct snd_pcm *pcm;
@@ -4228,7 +6236,7 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm)
4228 6236
4229 err = 6237 err =
4230 snd_pcm_lib_preallocate_pages_for_all(pcm, 6238 snd_pcm_lib_preallocate_pages_for_all(pcm,
4231 SNDRV_DMA_TYPE_DEV_SG, 6239 SNDRV_DMA_TYPE_DEV_SG,
4232 snd_dma_pci_data(hdspm->pci), 6240 snd_dma_pci_data(hdspm->pci),
4233 wanted, 6241 wanted,
4234 wanted); 6242 wanted);
@@ -4242,19 +6250,23 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm)
4242 return 0; 6250 return 0;
4243} 6251}
4244 6252
4245static void hdspm_set_sgbuf(struct hdspm * hdspm, 6253
6254static void hdspm_set_sgbuf(struct hdspm *hdspm,
4246 struct snd_pcm_substream *substream, 6255 struct snd_pcm_substream *substream,
4247 unsigned int reg, int channels) 6256 unsigned int reg, int channels)
4248{ 6257{
4249 int i; 6258 int i;
6259
6260 /* continuous memory segment */
4250 for (i = 0; i < (channels * 16); i++) 6261 for (i = 0; i < (channels * 16); i++)
4251 hdspm_write(hdspm, reg + 4 * i, 6262 hdspm_write(hdspm, reg + 4 * i,
4252 snd_pcm_sgbuf_get_addr(substream, 4096 * i)); 6263 snd_pcm_sgbuf_get_addr(substream, 4096 * i));
4253} 6264}
4254 6265
6266
4255/* ------------- ALSA Devices ---------------------------- */ 6267/* ------------- ALSA Devices ---------------------------- */
4256static int __devinit snd_hdspm_create_pcm(struct snd_card *card, 6268static int __devinit snd_hdspm_create_pcm(struct snd_card *card,
4257 struct hdspm * hdspm) 6269 struct hdspm *hdspm)
4258{ 6270{
4259 struct snd_pcm *pcm; 6271 struct snd_pcm *pcm;
4260 int err; 6272 int err;
@@ -4283,27 +6295,30 @@ static int __devinit snd_hdspm_create_pcm(struct snd_card *card,
4283 6295
4284static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm) 6296static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm)
4285{ 6297{
4286 snd_hdspm_flush_midi_input(hdspm, 0); 6298 int i;
4287 snd_hdspm_flush_midi_input(hdspm, 1); 6299
6300 for (i = 0; i < hdspm->midiPorts; i++)
6301 snd_hdspm_flush_midi_input(hdspm, i);
4288} 6302}
4289 6303
4290static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card, 6304static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
4291 struct hdspm * hdspm) 6305 struct hdspm * hdspm)
4292{ 6306{
4293 int err; 6307 int err, i;
4294 6308
4295 snd_printdd("Create card...\n"); 6309 snd_printdd("Create card...\n");
4296 err = snd_hdspm_create_pcm(card, hdspm); 6310 err = snd_hdspm_create_pcm(card, hdspm);
4297 if (err < 0) 6311 if (err < 0)
4298 return err; 6312 return err;
4299 6313
4300 err = snd_hdspm_create_midi(card, hdspm, 0); 6314 i = 0;
4301 if (err < 0) 6315 while (i < hdspm->midiPorts) {
4302 return err; 6316 err = snd_hdspm_create_midi(card, hdspm, i);
4303 6317 if (err < 0) {
4304 err = snd_hdspm_create_midi(card, hdspm, 1); 6318 return err;
4305 if (err < 0) 6319 }
4306 return err; 6320 i++;
6321 }
4307 6322
4308 err = snd_hdspm_create_controls(card, hdspm); 6323 err = snd_hdspm_create_controls(card, hdspm);
4309 if (err < 0) 6324 if (err < 0)
@@ -4346,37 +6361,56 @@ static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
4346} 6361}
4347 6362
4348static int __devinit snd_hdspm_create(struct snd_card *card, 6363static int __devinit snd_hdspm_create(struct snd_card *card,
4349 struct hdspm *hdspm, 6364 struct hdspm *hdspm) {
4350 int precise_ptr, int enable_monitor) 6365
4351{
4352 struct pci_dev *pci = hdspm->pci; 6366 struct pci_dev *pci = hdspm->pci;
4353 int err; 6367 int err;
4354 unsigned long io_extent; 6368 unsigned long io_extent;
4355 6369
4356 hdspm->irq = -1; 6370 hdspm->irq = -1;
4357
4358 spin_lock_init(&hdspm->midi[0].lock);
4359 spin_lock_init(&hdspm->midi[1].lock);
4360
4361 hdspm->card = card; 6371 hdspm->card = card;
4362 6372
4363 spin_lock_init(&hdspm->lock); 6373 spin_lock_init(&hdspm->lock);
4364 6374
4365 tasklet_init(&hdspm->midi_tasklet,
4366 hdspm_midi_tasklet, (unsigned long) hdspm);
4367
4368 pci_read_config_word(hdspm->pci, 6375 pci_read_config_word(hdspm->pci,
4369 PCI_CLASS_REVISION, &hdspm->firmware_rev); 6376 PCI_CLASS_REVISION, &hdspm->firmware_rev);
4370
4371 hdspm->is_aes32 = (hdspm->firmware_rev >= HDSPM_AESREVISION);
4372 6377
4373 strcpy(card->mixername, "Xilinx FPGA"); 6378 strcpy(card->mixername, "Xilinx FPGA");
4374 if (hdspm->is_aes32) { 6379 strcpy(card->driver, "HDSPM");
4375 strcpy(card->driver, "HDSPAES32"); 6380
4376 hdspm->card_name = "RME HDSPM AES32"; 6381 switch (hdspm->firmware_rev) {
4377 } else { 6382 case HDSPM_MADI_REV:
4378 strcpy(card->driver, "HDSPM"); 6383 case HDSPM_MADI_OLD_REV:
4379 hdspm->card_name = "RME HDSPM MADI"; 6384 hdspm->io_type = MADI;
6385 hdspm->card_name = "RME MADI";
6386 hdspm->midiPorts = 3;
6387 break;
6388 case HDSPM_RAYDAT_REV:
6389 hdspm->io_type = RayDAT;
6390 hdspm->card_name = "RME RayDAT";
6391 hdspm->midiPorts = 2;
6392 break;
6393 case HDSPM_AIO_REV:
6394 hdspm->io_type = AIO;
6395 hdspm->card_name = "RME AIO";
6396 hdspm->midiPorts = 1;
6397 break;
6398 case HDSPM_MADIFACE_REV:
6399 hdspm->io_type = MADIface;
6400 hdspm->card_name = "RME MADIface";
6401 hdspm->midiPorts = 1;
6402 break;
6403 case HDSPM_AES_REV:
6404 case HDSPM_AES32_REV:
6405 case HDSPM_AES32_OLD_REV:
6406 hdspm->io_type = AES32;
6407 hdspm->card_name = "RME AES32";
6408 hdspm->midiPorts = 2;
6409 break;
6410 default:
6411 snd_printk(KERN_ERR "HDSPM: unknown firmware revision %x\n",
6412 hdspm->firmware_rev);
6413 return -ENODEV;
4380 } 6414 }
4381 6415
4382 err = pci_enable_device(pci); 6416 err = pci_enable_device(pci);
@@ -4393,22 +6427,21 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
4393 io_extent = pci_resource_len(pci, 0); 6427 io_extent = pci_resource_len(pci, 0);
4394 6428
4395 snd_printdd("grabbed memory region 0x%lx-0x%lx\n", 6429 snd_printdd("grabbed memory region 0x%lx-0x%lx\n",
4396 hdspm->port, hdspm->port + io_extent - 1); 6430 hdspm->port, hdspm->port + io_extent - 1);
4397
4398 6431
4399 hdspm->iobase = ioremap_nocache(hdspm->port, io_extent); 6432 hdspm->iobase = ioremap_nocache(hdspm->port, io_extent);
4400 if (!hdspm->iobase) { 6433 if (!hdspm->iobase) {
4401 snd_printk(KERN_ERR "HDSPM: " 6434 snd_printk(KERN_ERR "HDSPM: "
4402 "unable to remap region 0x%lx-0x%lx\n", 6435 "unable to remap region 0x%lx-0x%lx\n",
4403 hdspm->port, hdspm->port + io_extent - 1); 6436 hdspm->port, hdspm->port + io_extent - 1);
4404 return -EBUSY; 6437 return -EBUSY;
4405 } 6438 }
4406 snd_printdd("remapped region (0x%lx) 0x%lx-0x%lx\n", 6439 snd_printdd("remapped region (0x%lx) 0x%lx-0x%lx\n",
4407 (unsigned long)hdspm->iobase, hdspm->port, 6440 (unsigned long)hdspm->iobase, hdspm->port,
4408 hdspm->port + io_extent - 1); 6441 hdspm->port + io_extent - 1);
4409 6442
4410 if (request_irq(pci->irq, snd_hdspm_interrupt, 6443 if (request_irq(pci->irq, snd_hdspm_interrupt,
4411 IRQF_SHARED, "hdspm", hdspm)) { 6444 IRQF_SHARED, "hdspm", hdspm)) {
4412 snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq); 6445 snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq);
4413 return -EBUSY; 6446 return -EBUSY;
4414 } 6447 }
@@ -4416,23 +6449,219 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
4416 snd_printdd("use IRQ %d\n", pci->irq); 6449 snd_printdd("use IRQ %d\n", pci->irq);
4417 6450
4418 hdspm->irq = pci->irq; 6451 hdspm->irq = pci->irq;
4419 hdspm->precise_ptr = precise_ptr;
4420
4421 hdspm->monitor_outs = enable_monitor;
4422 6452
4423 snd_printdd("kmalloc Mixer memory of %zd Bytes\n", 6453 snd_printdd("kmalloc Mixer memory of %zd Bytes\n",
4424 sizeof(struct hdspm_mixer)); 6454 sizeof(struct hdspm_mixer));
4425 hdspm->mixer = kzalloc(sizeof(struct hdspm_mixer), GFP_KERNEL); 6455 hdspm->mixer = kzalloc(sizeof(struct hdspm_mixer), GFP_KERNEL);
4426 if (!hdspm->mixer) { 6456 if (!hdspm->mixer) {
4427 snd_printk(KERN_ERR "HDSPM: " 6457 snd_printk(KERN_ERR "HDSPM: "
4428 "unable to kmalloc Mixer memory of %d Bytes\n", 6458 "unable to kmalloc Mixer memory of %d Bytes\n",
4429 (int)sizeof(struct hdspm_mixer)); 6459 (int)sizeof(struct hdspm_mixer));
4430 return err; 6460 return err;
4431 } 6461 }
4432 6462
4433 hdspm->ss_channels = MADI_SS_CHANNELS; 6463 hdspm->port_names_in = NULL;
4434 hdspm->ds_channels = MADI_DS_CHANNELS; 6464 hdspm->port_names_out = NULL;
4435 hdspm->qs_channels = MADI_QS_CHANNELS; 6465
6466 switch (hdspm->io_type) {
6467 case AES32:
6468 hdspm->ss_in_channels = hdspm->ss_out_channels = AES32_CHANNELS;
6469 hdspm->ds_in_channels = hdspm->ds_out_channels = AES32_CHANNELS;
6470 hdspm->qs_in_channels = hdspm->qs_out_channels = AES32_CHANNELS;
6471
6472 hdspm->channel_map_in_ss = hdspm->channel_map_out_ss =
6473 channel_map_aes32;
6474 hdspm->channel_map_in_ds = hdspm->channel_map_out_ds =
6475 channel_map_aes32;
6476 hdspm->channel_map_in_qs = hdspm->channel_map_out_qs =
6477 channel_map_aes32;
6478 hdspm->port_names_in_ss = hdspm->port_names_out_ss =
6479 texts_ports_aes32;
6480 hdspm->port_names_in_ds = hdspm->port_names_out_ds =
6481 texts_ports_aes32;
6482 hdspm->port_names_in_qs = hdspm->port_names_out_qs =
6483 texts_ports_aes32;
6484
6485 hdspm->max_channels_out = hdspm->max_channels_in =
6486 AES32_CHANNELS;
6487 hdspm->port_names_in = hdspm->port_names_out =
6488 texts_ports_aes32;
6489 hdspm->channel_map_in = hdspm->channel_map_out =
6490 channel_map_aes32;
6491
6492 break;
6493
6494 case MADI:
6495 case MADIface:
6496 hdspm->ss_in_channels = hdspm->ss_out_channels =
6497 MADI_SS_CHANNELS;
6498 hdspm->ds_in_channels = hdspm->ds_out_channels =
6499 MADI_DS_CHANNELS;
6500 hdspm->qs_in_channels = hdspm->qs_out_channels =
6501 MADI_QS_CHANNELS;
6502
6503 hdspm->channel_map_in_ss = hdspm->channel_map_out_ss =
6504 channel_map_unity_ss;
6505 hdspm->channel_map_in_ds = hdspm->channel_map_out_ds =
6506 channel_map_unity_ss;
6507 hdspm->channel_map_in_qs = hdspm->channel_map_out_qs =
6508 channel_map_unity_ss;
6509
6510 hdspm->port_names_in_ss = hdspm->port_names_out_ss =
6511 texts_ports_madi;
6512 hdspm->port_names_in_ds = hdspm->port_names_out_ds =
6513 texts_ports_madi;
6514 hdspm->port_names_in_qs = hdspm->port_names_out_qs =
6515 texts_ports_madi;
6516 break;
6517
6518 case AIO:
6519 if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBI_D)) {
6520 snd_printk(KERN_INFO "HDSPM: AEB input board found, but not supported\n");
6521 }
6522
6523 hdspm->ss_in_channels = AIO_IN_SS_CHANNELS;
6524 hdspm->ds_in_channels = AIO_IN_DS_CHANNELS;
6525 hdspm->qs_in_channels = AIO_IN_QS_CHANNELS;
6526 hdspm->ss_out_channels = AIO_OUT_SS_CHANNELS;
6527 hdspm->ds_out_channels = AIO_OUT_DS_CHANNELS;
6528 hdspm->qs_out_channels = AIO_OUT_QS_CHANNELS;
6529
6530 hdspm->channel_map_out_ss = channel_map_aio_out_ss;
6531 hdspm->channel_map_out_ds = channel_map_aio_out_ds;
6532 hdspm->channel_map_out_qs = channel_map_aio_out_qs;
6533
6534 hdspm->channel_map_in_ss = channel_map_aio_in_ss;
6535 hdspm->channel_map_in_ds = channel_map_aio_in_ds;
6536 hdspm->channel_map_in_qs = channel_map_aio_in_qs;
6537
6538 hdspm->port_names_in_ss = texts_ports_aio_in_ss;
6539 hdspm->port_names_out_ss = texts_ports_aio_out_ss;
6540 hdspm->port_names_in_ds = texts_ports_aio_in_ds;
6541 hdspm->port_names_out_ds = texts_ports_aio_out_ds;
6542 hdspm->port_names_in_qs = texts_ports_aio_in_qs;
6543 hdspm->port_names_out_qs = texts_ports_aio_out_qs;
6544
6545 break;
6546
6547 case RayDAT:
6548 hdspm->ss_in_channels = hdspm->ss_out_channels =
6549 RAYDAT_SS_CHANNELS;
6550 hdspm->ds_in_channels = hdspm->ds_out_channels =
6551 RAYDAT_DS_CHANNELS;
6552 hdspm->qs_in_channels = hdspm->qs_out_channels =
6553 RAYDAT_QS_CHANNELS;
6554
6555 hdspm->max_channels_in = RAYDAT_SS_CHANNELS;
6556 hdspm->max_channels_out = RAYDAT_SS_CHANNELS;
6557
6558 hdspm->channel_map_in_ss = hdspm->channel_map_out_ss =
6559 channel_map_raydat_ss;
6560 hdspm->channel_map_in_ds = hdspm->channel_map_out_ds =
6561 channel_map_raydat_ds;
6562 hdspm->channel_map_in_qs = hdspm->channel_map_out_qs =
6563 channel_map_raydat_qs;
6564 hdspm->channel_map_in = hdspm->channel_map_out =
6565 channel_map_raydat_ss;
6566
6567 hdspm->port_names_in_ss = hdspm->port_names_out_ss =
6568 texts_ports_raydat_ss;
6569 hdspm->port_names_in_ds = hdspm->port_names_out_ds =
6570 texts_ports_raydat_ds;
6571 hdspm->port_names_in_qs = hdspm->port_names_out_qs =
6572 texts_ports_raydat_qs;
6573
6574
6575 break;
6576
6577 }
6578
6579 /* TCO detection */
6580 switch (hdspm->io_type) {
6581 case AIO:
6582 case RayDAT:
6583 if (hdspm_read(hdspm, HDSPM_statusRegister2) &
6584 HDSPM_s2_tco_detect) {
6585 hdspm->midiPorts++;
6586 hdspm->tco = kzalloc(sizeof(struct hdspm_tco),
6587 GFP_KERNEL);
6588 if (NULL != hdspm->tco) {
6589 hdspm_tco_write(hdspm);
6590 }
6591 snd_printk(KERN_INFO "HDSPM: AIO/RayDAT TCO module found\n");
6592 } else {
6593 hdspm->tco = NULL;
6594 }
6595 break;
6596
6597 case MADI:
6598 if (hdspm_read(hdspm, HDSPM_statusRegister) & HDSPM_tco_detect) {
6599 hdspm->midiPorts++;
6600 hdspm->tco = kzalloc(sizeof(struct hdspm_tco),
6601 GFP_KERNEL);
6602 if (NULL != hdspm->tco) {
6603 hdspm_tco_write(hdspm);
6604 }
6605 snd_printk(KERN_INFO "HDSPM: MADI TCO module found\n");
6606 } else {
6607 hdspm->tco = NULL;
6608 }
6609 break;
6610
6611 default:
6612 hdspm->tco = NULL;
6613 }
6614
6615 /* texts */
6616 switch (hdspm->io_type) {
6617 case AES32:
6618 if (hdspm->tco) {
6619 hdspm->texts_autosync = texts_autosync_aes_tco;
6620 hdspm->texts_autosync_items = 10;
6621 } else {
6622 hdspm->texts_autosync = texts_autosync_aes;
6623 hdspm->texts_autosync_items = 9;
6624 }
6625 break;
6626
6627 case MADI:
6628 if (hdspm->tco) {
6629 hdspm->texts_autosync = texts_autosync_madi_tco;
6630 hdspm->texts_autosync_items = 4;
6631 } else {
6632 hdspm->texts_autosync = texts_autosync_madi;
6633 hdspm->texts_autosync_items = 3;
6634 }
6635 break;
6636
6637 case MADIface:
6638
6639 break;
6640
6641 case RayDAT:
6642 if (hdspm->tco) {
6643 hdspm->texts_autosync = texts_autosync_raydat_tco;
6644 hdspm->texts_autosync_items = 9;
6645 } else {
6646 hdspm->texts_autosync = texts_autosync_raydat;
6647 hdspm->texts_autosync_items = 8;
6648 }
6649 break;
6650
6651 case AIO:
6652 if (hdspm->tco) {
6653 hdspm->texts_autosync = texts_autosync_aio_tco;
6654 hdspm->texts_autosync_items = 6;
6655 } else {
6656 hdspm->texts_autosync = texts_autosync_aio;
6657 hdspm->texts_autosync_items = 5;
6658 }
6659 break;
6660
6661 }
6662
6663 tasklet_init(&hdspm->midi_tasklet,
6664 hdspm_midi_tasklet, (unsigned long) hdspm);
4436 6665
4437 snd_printdd("create alsa devices.\n"); 6666 snd_printdd("create alsa devices.\n");
4438 err = snd_hdspm_create_alsa_devices(card, hdspm); 6667 err = snd_hdspm_create_alsa_devices(card, hdspm);
@@ -4444,6 +6673,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
4444 return 0; 6673 return 0;
4445} 6674}
4446 6675
6676
4447static int snd_hdspm_free(struct hdspm * hdspm) 6677static int snd_hdspm_free(struct hdspm * hdspm)
4448{ 6678{
4449 6679
@@ -4452,7 +6682,8 @@ static int snd_hdspm_free(struct hdspm * hdspm)
4452 /* stop th audio, and cancel all interrupts */ 6682 /* stop th audio, and cancel all interrupts */
4453 hdspm->control_register &= 6683 hdspm->control_register &=
4454 ~(HDSPM_Start | HDSPM_AudioInterruptEnable | 6684 ~(HDSPM_Start | HDSPM_AudioInterruptEnable |
4455 HDSPM_Midi0InterruptEnable | HDSPM_Midi1InterruptEnable); 6685 HDSPM_Midi0InterruptEnable | HDSPM_Midi1InterruptEnable |
6686 HDSPM_Midi2InterruptEnable | HDSPM_Midi3InterruptEnable);
4456 hdspm_write(hdspm, HDSPM_controlRegister, 6687 hdspm_write(hdspm, HDSPM_controlRegister,
4457 hdspm->control_register); 6688 hdspm->control_register);
4458 } 6689 }
@@ -4472,6 +6703,7 @@ static int snd_hdspm_free(struct hdspm * hdspm)
4472 return 0; 6703 return 0;
4473} 6704}
4474 6705
6706
4475static void snd_hdspm_card_free(struct snd_card *card) 6707static void snd_hdspm_card_free(struct snd_card *card)
4476{ 6708{
4477 struct hdspm *hdspm = card->private_data; 6709 struct hdspm *hdspm = card->private_data;
@@ -4480,6 +6712,7 @@ static void snd_hdspm_card_free(struct snd_card *card)
4480 snd_hdspm_free(hdspm); 6712 snd_hdspm_free(hdspm);
4481} 6713}
4482 6714
6715
4483static int __devinit snd_hdspm_probe(struct pci_dev *pci, 6716static int __devinit snd_hdspm_probe(struct pci_dev *pci,
4484 const struct pci_device_id *pci_id) 6717 const struct pci_device_id *pci_id)
4485{ 6718{
@@ -4496,7 +6729,7 @@ static int __devinit snd_hdspm_probe(struct pci_dev *pci,
4496 } 6729 }
4497 6730
4498 err = snd_card_create(index[dev], id[dev], 6731 err = snd_card_create(index[dev], id[dev],
4499 THIS_MODULE, sizeof(struct hdspm), &card); 6732 THIS_MODULE, sizeof(struct hdspm), &card);
4500 if (err < 0) 6733 if (err < 0)
4501 return err; 6734 return err;
4502 6735
@@ -4507,16 +6740,25 @@ static int __devinit snd_hdspm_probe(struct pci_dev *pci,
4507 6740
4508 snd_card_set_dev(card, &pci->dev); 6741 snd_card_set_dev(card, &pci->dev);
4509 6742
4510 err = snd_hdspm_create(card, hdspm, precise_ptr[dev], 6743 err = snd_hdspm_create(card, hdspm);
4511 enable_monitor[dev]);
4512 if (err < 0) { 6744 if (err < 0) {
4513 snd_card_free(card); 6745 snd_card_free(card);
4514 return err; 6746 return err;
4515 } 6747 }
4516 6748
4517 strcpy(card->shortname, "HDSPM MADI"); 6749 if (hdspm->io_type != MADIface) {
4518 sprintf(card->longname, "%s at 0x%lx, irq %d", hdspm->card_name, 6750 sprintf(card->shortname, "%s_%x",
4519 hdspm->port, hdspm->irq); 6751 hdspm->card_name,
6752 (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF);
6753 sprintf(card->longname, "%s S/N 0x%x at 0x%lx, irq %d",
6754 hdspm->card_name,
6755 (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF,
6756 hdspm->port, hdspm->irq);
6757 } else {
6758 sprintf(card->shortname, "%s", hdspm->card_name);
6759 sprintf(card->longname, "%s at 0x%lx, irq %d",
6760 hdspm->card_name, hdspm->port, hdspm->irq);
6761 }
4520 6762
4521 err = snd_card_register(card); 6763 err = snd_card_register(card);
4522 if (err < 0) { 6764 if (err < 0) {
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 1b8f6742b5fa..2b5c7a95ae1f 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -308,7 +308,7 @@ static irqreturn_t sis_interrupt(int irq, void *dev)
308 u32 intr, status; 308 u32 intr, status;
309 309
310 /* We only use the DMA interrupts, and we don't enable any other 310 /* We only use the DMA interrupts, and we don't enable any other
311 * source of interrupts. But, it is possible to see an interupt 311 * source of interrupts. But, it is possible to see an interrupt
312 * status that didn't actually interrupt us, so eliminate anything 312 * status that didn't actually interrupt us, so eliminate anything
313 * we're not expecting to avoid falsely claiming an IRQ, and an 313 * we're not expecting to avoid falsely claiming an IRQ, and an
314 * ensuing endless loop. 314 * ensuing endless loop.
@@ -773,7 +773,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
773 vperiod = 0; 773 vperiod = 0;
774 } 774 }
775 775
776 /* The interrupt handler implements the timing syncronization, so 776 /* The interrupt handler implements the timing synchronization, so
777 * setup its state. 777 * setup its state.
778 */ 778 */
779 timing->flags |= VOICE_SYNC_TIMING; 779 timing->flags |= VOICE_SYNC_TIMING;
@@ -1139,7 +1139,7 @@ static int sis_chip_init(struct sis7019 *sis)
1139 */ 1139 */
1140 outl(SIS_DMA_CSR_PCI_SETTINGS, io + SIS_DMA_CSR); 1140 outl(SIS_DMA_CSR_PCI_SETTINGS, io + SIS_DMA_CSR);
1141 1141
1142 /* Reset the syncronization groups for all of the channels 1142 /* Reset the synchronization groups for all of the channels
1143 * to be asyncronous. If we start doing SPDIF or 5.1 sound, etc. 1143 * to be asyncronous. If we start doing SPDIF or 5.1 sound, etc.
1144 * we'll need to change how we handle these. Until then, we just 1144 * we'll need to change how we handle these. Until then, we just
1145 * assign sub-mixer 0 to all playback channels, and avoid any 1145 * assign sub-mixer 0 to all playback channels, and avoid any
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 5518371db13f..c94c051ad0c8 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -1389,15 +1389,9 @@ static struct snd_kcontrol_new snd_ymfpci_spdif_stream __devinitdata =
1389 1389
1390static int snd_ymfpci_drec_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *info) 1390static int snd_ymfpci_drec_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *info)
1391{ 1391{
1392 static char *texts[3] = {"AC'97", "IEC958", "ZV Port"}; 1392 static const char *const texts[3] = {"AC'97", "IEC958", "ZV Port"};
1393 1393
1394 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1394 return snd_ctl_enum_info(info, 1, 3, texts);
1395 info->count = 1;
1396 info->value.enumerated.items = 3;
1397 if (info->value.enumerated.item > 2)
1398 info->value.enumerated.item = 2;
1399 strcpy(info->value.enumerated.name, texts[info->value.enumerated.item]);
1400 return 0;
1401} 1395}
1402 1396
1403static int snd_ymfpci_drec_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) 1397static int snd_ymfpci_drec_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value)