diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-07 20:07:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-07 20:07:31 -0400 |
commit | faa38b5e0e092914764cdba9f83d31a3f794d182 (patch) | |
tree | b3e5921bdc36378033b4910eb4f29cb0dfc486e0 /sound/pci | |
parent | 78417334b5cb6e1f915b8fdcc4fce3f1a1b4420c (diff) | |
parent | 74bf40f0793fed9e01eb6164c2ce63e8c27ca205 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (214 commits)
ALSA: hda - Add pin-fix for HP dc5750
ALSA: als4000: Fix potentially invalid DMA mode setup
ALSA: als4000: enable burst mode
ALSA: hda - Fix initial capsrc selection in patch_alc269()
ASoC: TWL4030: Capture route runtime DAPM ordering fix
ALSA: hda - Add PC-beep whitelist for an Intel board
ALSA: hda - More relax for pending period handling
ALSA: hda - Define AC_FMT_* constants
ALSA: hda - Fix beep frequency on IDT 92HD73xx and 92HD71Bxx codecs
ALSA: hda - Add support for HDMI HBR passthrough
ALSA: hda - Set Stream Type in Stream Format according to AES0
ALSA: hda - Fix Thinkpad X300 so SPDIF is not exposed
ALSA: hda - FIX to not expose SPDIF on Thinkpad X301, since it does not have the ability to use SPDIF
ASoC: wm9081: fix resource reclaim in wm9081_register error path
ASoC: wm8978: fix a memory leak if a wm8978_register fail
ASoC: wm8974: fix a memory leak if another WM8974 is registered
ASoC: wm8961: fix resource reclaim in wm8961_register error path
ASoC: wm8955: fix resource reclaim in wm8955_register error path
ASoC: wm8940: fix a memory leak if wm8940_register return error
ASoC: wm8904: fix resource reclaim in wm8904_register error path
...
Diffstat (limited to 'sound/pci')
28 files changed, 1246 insertions, 360 deletions
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 6cf1de8042e8..0e247cb90ecc 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c | |||
@@ -763,9 +763,9 @@ static void snd_als4000_configure(struct snd_sb *chip) | |||
763 | /* SPECS_PAGE: 39 */ | 763 | /* SPECS_PAGE: 39 */ |
764 | for (i = ALS4K_GCR91_DMA0_ADDR; i <= ALS4K_GCR96_DMA3_MODE_COUNT; ++i) | 764 | for (i = ALS4K_GCR91_DMA0_ADDR; i <= ALS4K_GCR96_DMA3_MODE_COUNT; ++i) |
765 | snd_als4k_gcr_write(chip, i, 0); | 765 | snd_als4k_gcr_write(chip, i, 0); |
766 | 766 | /* enable burst mode to prevent dropouts during high PCI bus usage */ | |
767 | snd_als4k_gcr_write(chip, ALS4K_GCR99_DMA_EMULATION_CTRL, | 767 | snd_als4k_gcr_write(chip, ALS4K_GCR99_DMA_EMULATION_CTRL, |
768 | snd_als4k_gcr_read(chip, ALS4K_GCR99_DMA_EMULATION_CTRL)); | 768 | (snd_als4k_gcr_read(chip, ALS4K_GCR99_DMA_EMULATION_CTRL) & ~0x07) | 0x04); |
769 | spin_unlock_irq(&chip->reg_lock); | 769 | spin_unlock_irq(&chip->reg_lock); |
770 | } | 770 | } |
771 | 771 | ||
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 1db586af4f9c..c80b0b863c54 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c | |||
@@ -460,6 +460,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
460 | struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); | 460 | struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); |
461 | int err; | 461 | int err; |
462 | u16 format; | 462 | u16 format; |
463 | int width; | ||
463 | unsigned int bytes_per_sec; | 464 | unsigned int bytes_per_sec; |
464 | 465 | ||
465 | print_hwparams(params); | 466 | print_hwparams(params); |
@@ -512,9 +513,10 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
512 | dpcm->hpi_buffer_attached); | 513 | dpcm->hpi_buffer_attached); |
513 | } | 514 | } |
514 | bytes_per_sec = params_rate(params) * params_channels(params); | 515 | bytes_per_sec = params_rate(params) * params_channels(params); |
515 | bytes_per_sec *= snd_pcm_format_width(params_format(params)); | 516 | width = snd_pcm_format_width(params_format(params)); |
517 | bytes_per_sec *= width; | ||
516 | bytes_per_sec /= 8; | 518 | bytes_per_sec /= 8; |
517 | if (bytes_per_sec <= 0) | 519 | if (width < 0 || bytes_per_sec == 0) |
518 | return -EINVAL; | 520 | return -EINVAL; |
519 | 521 | ||
520 | dpcm->bytes_per_sec = bytes_per_sec; | 522 | dpcm->bytes_per_sec = bytes_per_sec; |
@@ -1383,7 +1385,7 @@ static char *asihpi_src_names[] = | |||
1383 | 1385 | ||
1384 | compile_time_assert( | 1386 | compile_time_assert( |
1385 | (ARRAY_SIZE(asihpi_src_names) == | 1387 | (ARRAY_SIZE(asihpi_src_names) == |
1386 | (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_BASE+1)), | 1388 | (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)), |
1387 | assert_src_names_size); | 1389 | assert_src_names_size); |
1388 | 1390 | ||
1389 | #if ASI_STYLE_NAMES | 1391 | #if ASI_STYLE_NAMES |
@@ -1414,7 +1416,7 @@ static char *asihpi_dst_names[] = | |||
1414 | 1416 | ||
1415 | compile_time_assert( | 1417 | compile_time_assert( |
1416 | (ARRAY_SIZE(asihpi_dst_names) == | 1418 | (ARRAY_SIZE(asihpi_dst_names) == |
1417 | (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_BASE+1)), | 1419 | (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)), |
1418 | assert_dst_names_size); | 1420 | assert_dst_names_size); |
1419 | 1421 | ||
1420 | static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl, | 1422 | static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl, |
@@ -2171,7 +2173,7 @@ static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol, | |||
2171 | &src_node_type, &src_node_index); | 2173 | &src_node_type, &src_node_index); |
2172 | 2174 | ||
2173 | sprintf(uinfo->value.enumerated.name, "%s %d", | 2175 | sprintf(uinfo->value.enumerated.name, "%s %d", |
2174 | asihpi_src_names[src_node_type - HPI_SOURCENODE_BASE], | 2176 | asihpi_src_names[src_node_type - HPI_SOURCENODE_NONE], |
2175 | src_node_index); | 2177 | src_node_index); |
2176 | return 0; | 2178 | return 0; |
2177 | } | 2179 | } |
@@ -2603,8 +2605,8 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) | |||
2603 | 2605 | ||
2604 | } | 2606 | } |
2605 | 2607 | ||
2606 | hpi_ctl.src_node_type -= HPI_SOURCENODE_BASE; | 2608 | hpi_ctl.src_node_type -= HPI_SOURCENODE_NONE; |
2607 | hpi_ctl.dst_node_type -= HPI_DESTNODE_BASE; | 2609 | hpi_ctl.dst_node_type -= HPI_DESTNODE_NONE; |
2608 | 2610 | ||
2609 | /* ASI50xx in SSX mode has multiple meters on the same node. | 2611 | /* ASI50xx in SSX mode has multiple meters on the same node. |
2610 | Use subindex to create distinct ALSA controls | 2612 | Use subindex to create distinct ALSA controls |
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h index 0173bbe62b67..23399d02f666 100644 --- a/sound/pci/asihpi/hpi.h +++ b/sound/pci/asihpi/hpi.h | |||
@@ -50,7 +50,8 @@ i.e 3.05.02 is a development version | |||
50 | #define HPI_VER_RELEASE(v) ((int)(v & 0xFF)) | 50 | #define HPI_VER_RELEASE(v) ((int)(v & 0xFF)) |
51 | 51 | ||
52 | /* Use single digits for versions less that 10 to avoid octal. */ | 52 | /* Use single digits for versions less that 10 to avoid octal. */ |
53 | #define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 3, 25) | 53 | #define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 4, 1) |
54 | #define HPI_VER_STRING "4.04.01" | ||
54 | 55 | ||
55 | /* Library version as documented in hpi-api-versions.txt */ | 56 | /* Library version as documented in hpi-api-versions.txt */ |
56 | #define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0) | 57 | #define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0) |
@@ -203,8 +204,6 @@ enum HPI_SOURCENODES { | |||
203 | exists on a destination node can be searched for using a source | 204 | exists on a destination node can be searched for using a source |
204 | node value of either 0, or HPI_SOURCENODE_NONE */ | 205 | node value of either 0, or HPI_SOURCENODE_NONE */ |
205 | HPI_SOURCENODE_NONE = 100, | 206 | HPI_SOURCENODE_NONE = 100, |
206 | /** \deprecated Use HPI_SOURCENODE_NONE instead. */ | ||
207 | HPI_SOURCENODE_BASE = 100, | ||
208 | /** Out Stream (Play) node. */ | 207 | /** Out Stream (Play) node. */ |
209 | HPI_SOURCENODE_OSTREAM = 101, | 208 | HPI_SOURCENODE_OSTREAM = 101, |
210 | /** Line in node - could be analog, AES/EBU or network. */ | 209 | /** Line in node - could be analog, AES/EBU or network. */ |
@@ -235,8 +234,6 @@ enum HPI_DESTNODES { | |||
235 | exists on a source node can be searched for using a destination | 234 | exists on a source node can be searched for using a destination |
236 | node value of either 0, or HPI_DESTNODE_NONE */ | 235 | node value of either 0, or HPI_DESTNODE_NONE */ |
237 | HPI_DESTNODE_NONE = 200, | 236 | HPI_DESTNODE_NONE = 200, |
238 | /** \deprecated Use HPI_DESTNODE_NONE instead. */ | ||
239 | HPI_DESTNODE_BASE = 200, | ||
240 | /** In Stream (Record) node. */ | 237 | /** In Stream (Record) node. */ |
241 | HPI_DESTNODE_ISTREAM = 201, | 238 | HPI_DESTNODE_ISTREAM = 201, |
242 | HPI_DESTNODE_LINEOUT = 202, /**< line out node. */ | 239 | HPI_DESTNODE_LINEOUT = 202, /**< line out node. */ |
@@ -432,7 +429,18 @@ Property 2 - adapter can do stream grouping (supports SSX2) | |||
432 | Property 1 - adapter can do samplerate conversion (MRX) | 429 | Property 1 - adapter can do samplerate conversion (MRX) |
433 | Property 2 - adapter can do timestretch (TSX) | 430 | Property 2 - adapter can do timestretch (TSX) |
434 | */ | 431 | */ |
435 | HPI_ADAPTER_PROPERTY_CAPS2 = 269 | 432 | HPI_ADAPTER_PROPERTY_CAPS2 = 269, |
433 | |||
434 | /** Readonly adapter sync header connection count. | ||
435 | */ | ||
436 | HPI_ADAPTER_PROPERTY_SYNC_HEADER_CONNECTIONS = 270, | ||
437 | /** Readonly supports SSX2 property. | ||
438 | Indicates the adapter supports SSX2 in some mode setting. The | ||
439 | return value is true (1) or false (0). If the current adapter | ||
440 | mode is MONO SSX2 is disabled, even though this property will | ||
441 | return true. | ||
442 | */ | ||
443 | HPI_ADAPTER_PROPERTY_SUPPORTS_SSX2 = 271 | ||
436 | }; | 444 | }; |
437 | 445 | ||
438 | /** Adapter mode commands | 446 | /** Adapter mode commands |
@@ -813,8 +821,6 @@ enum HPI_SAMPLECLOCK_SOURCES { | |||
813 | /** The sampleclock output is derived from its local samplerate generator. | 821 | /** The sampleclock output is derived from its local samplerate generator. |
814 | The local samplerate may be set using HPI_SampleClock_SetLocalRate(). */ | 822 | The local samplerate may be set using HPI_SampleClock_SetLocalRate(). */ |
815 | HPI_SAMPLECLOCK_SOURCE_LOCAL = 1, | 823 | HPI_SAMPLECLOCK_SOURCE_LOCAL = 1, |
816 | /** \deprecated Use HPI_SAMPLECLOCK_SOURCE_LOCAL instead */ | ||
817 | HPI_SAMPLECLOCK_SOURCE_ADAPTER = 1, | ||
818 | /** The adapter is clocked from a dedicated AES/EBU SampleClock input.*/ | 824 | /** The adapter is clocked from a dedicated AES/EBU SampleClock input.*/ |
819 | HPI_SAMPLECLOCK_SOURCE_AESEBU_SYNC = 2, | 825 | HPI_SAMPLECLOCK_SOURCE_AESEBU_SYNC = 2, |
820 | /** From external wordclock connector */ | 826 | /** From external wordclock connector */ |
@@ -825,10 +831,6 @@ enum HPI_SAMPLECLOCK_SOURCES { | |||
825 | HPI_SAMPLECLOCK_SOURCE_SMPTE = 5, | 831 | HPI_SAMPLECLOCK_SOURCE_SMPTE = 5, |
826 | /** One of the aesebu inputs */ | 832 | /** One of the aesebu inputs */ |
827 | HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT = 6, | 833 | HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT = 6, |
828 | /** \deprecated The first aesebu input with a valid signal | ||
829 | Superseded by separate Auto enable flag | ||
830 | */ | ||
831 | HPI_SAMPLECLOCK_SOURCE_AESEBU_AUTO = 7, | ||
832 | /** From a network interface e.g. Cobranet or Livewire at either 48 or 96kHz */ | 834 | /** From a network interface e.g. Cobranet or Livewire at either 48 or 96kHz */ |
833 | HPI_SAMPLECLOCK_SOURCE_NETWORK = 8, | 835 | HPI_SAMPLECLOCK_SOURCE_NETWORK = 8, |
834 | /** From previous adjacent module (ASI2416 only)*/ | 836 | /** From previous adjacent module (ASI2416 only)*/ |
@@ -1015,8 +1017,6 @@ enum HPI_ERROR_CODES { | |||
1015 | HPI_ERROR_CONTROL_DISABLED = 404, | 1017 | HPI_ERROR_CONTROL_DISABLED = 404, |
1016 | /** I2C transaction failed due to a missing ACK. */ | 1018 | /** I2C transaction failed due to a missing ACK. */ |
1017 | HPI_ERROR_CONTROL_I2C_MISSING_ACK = 405, | 1019 | HPI_ERROR_CONTROL_I2C_MISSING_ACK = 405, |
1018 | /** Control attribute is valid, but not supported by this hardware. */ | ||
1019 | HPI_ERROR_UNSUPPORTED_CONTROL_ATTRIBUTE = 406, | ||
1020 | /** Control is busy, or coming out of | 1020 | /** Control is busy, or coming out of |
1021 | reset and cannot be accessed at this time. */ | 1021 | reset and cannot be accessed at this time. */ |
1022 | HPI_ERROR_CONTROL_NOT_READY = 407, | 1022 | HPI_ERROR_CONTROL_NOT_READY = 407, |
@@ -1827,13 +1827,41 @@ u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys, | |||
1827 | Compressor Expander control | 1827 | Compressor Expander control |
1828 | *******************************/ | 1828 | *******************************/ |
1829 | 1829 | ||
1830 | u16 hpi_compander_set(const struct hpi_hsubsys *ph_subsys, u32 h_control, | 1830 | u16 hpi_compander_set_enable(const struct hpi_hsubsys *ph_subsys, |
1831 | u16 attack, u16 decay, short ratio100, short threshold0_01dB, | 1831 | u32 h_control, u32 on); |
1832 | short makeup_gain0_01dB); | 1832 | |
1833 | u16 hpi_compander_get_enable(const struct hpi_hsubsys *ph_subsys, | ||
1834 | u32 h_control, u32 *pon); | ||
1835 | |||
1836 | u16 hpi_compander_set_makeup_gain(const struct hpi_hsubsys *ph_subsys, | ||
1837 | u32 h_control, short makeup_gain0_01dB); | ||
1838 | |||
1839 | u16 hpi_compander_get_makeup_gain(const struct hpi_hsubsys *ph_subsys, | ||
1840 | u32 h_control, short *pn_makeup_gain0_01dB); | ||
1841 | |||
1842 | u16 hpi_compander_set_attack_time_constant(const struct hpi_hsubsys | ||
1843 | *ph_subsys, u32 h_control, u32 index, u32 attack); | ||
1844 | |||
1845 | u16 hpi_compander_get_attack_time_constant(const struct hpi_hsubsys | ||
1846 | *ph_subsys, u32 h_control, u32 index, u32 *pw_attack); | ||
1847 | |||
1848 | u16 hpi_compander_set_decay_time_constant(const struct hpi_hsubsys *ph_subsys, | ||
1849 | u32 h_control, u32 index, u32 decay); | ||
1850 | |||
1851 | u16 hpi_compander_get_decay_time_constant(const struct hpi_hsubsys *ph_subsys, | ||
1852 | u32 h_control, u32 index, u32 *pw_decay); | ||
1853 | |||
1854 | u16 hpi_compander_set_threshold(const struct hpi_hsubsys *ph_subsys, | ||
1855 | u32 h_control, u32 index, short threshold0_01dB); | ||
1856 | |||
1857 | u16 hpi_compander_get_threshold(const struct hpi_hsubsys *ph_subsys, | ||
1858 | u32 h_control, u32 index, short *pn_threshold0_01dB); | ||
1859 | |||
1860 | u16 hpi_compander_set_ratio(const struct hpi_hsubsys *ph_subsys, | ||
1861 | u32 h_control, u32 index, u32 ratio100); | ||
1833 | 1862 | ||
1834 | u16 hpi_compander_get(const struct hpi_hsubsys *ph_subsys, u32 h_control, | 1863 | u16 hpi_compander_get_ratio(const struct hpi_hsubsys *ph_subsys, |
1835 | u16 *pw_attack, u16 *pw_decay, short *pw_ratio100, | 1864 | u32 h_control, u32 index, u32 *pw_ratio100); |
1836 | short *pn_threshold0_01dB, short *pn_makeup_gain0_01dB); | ||
1837 | 1865 | ||
1838 | /******************************* | 1866 | /******************************* |
1839 | Cobranet HMI control | 1867 | Cobranet HMI control |
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index 12dab5e4892c..f7e374ec4414 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c | |||
@@ -687,6 +687,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
687 | switch (pao->pci.subsys_device_id) { | 687 | switch (pao->pci.subsys_device_id) { |
688 | case 0x5100: | 688 | case 0x5100: |
689 | case 0x5110: /* ASI5100 revB or higher with C6711D */ | 689 | case 0x5110: /* ASI5100 revB or higher with C6711D */ |
690 | case 0x5200: /* ASI5200 PC_ie version of ASI5100 */ | ||
690 | case 0x6100: | 691 | case 0x6100: |
691 | case 0x6200: | 692 | case 0x6200: |
692 | boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); | 693 | boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); |
@@ -1133,6 +1134,12 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1133 | subsys_device_id) == | 1134 | subsys_device_id) == |
1134 | HPI_ADAPTER_FAMILY_ASI(0x5100)) | 1135 | HPI_ADAPTER_FAMILY_ASI(0x5100)) |
1135 | mask = 0x00000000L; | 1136 | mask = 0x00000000L; |
1137 | /* ASI5200 uses AX6 code, */ | ||
1138 | /* but has no PLD r/w register to test */ | ||
1139 | if (HPI_ADAPTER_FAMILY_ASI(pao->pci. | ||
1140 | subsys_device_id) == | ||
1141 | HPI_ADAPTER_FAMILY_ASI(0x5200)) | ||
1142 | mask = 0x00000000L; | ||
1136 | break; | 1143 | break; |
1137 | case HPI_ADAPTER_FAMILY_ASI(0x8800): | 1144 | case HPI_ADAPTER_FAMILY_ASI(0x8800): |
1138 | /* ASI8800 has 16bit path to FPGA */ | 1145 | /* ASI8800 has 16bit path to FPGA */ |
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h index fdd0ce02aa68..16f502d459de 100644 --- a/sound/pci/asihpi/hpi_internal.h +++ b/sound/pci/asihpi/hpi_internal.h | |||
@@ -104,9 +104,9 @@ typedef void hpi_handler_func(struct hpi_message *, struct hpi_response *); | |||
104 | #define STR_ROLE_FIELD_MAX 255U | 104 | #define STR_ROLE_FIELD_MAX 255U |
105 | 105 | ||
106 | struct hpi_entity_str { | 106 | struct hpi_entity_str { |
107 | uint16_t size; | 107 | u16 size; |
108 | uint8_t type; | 108 | u8 type; |
109 | uint8_t role; | 109 | u8 role; |
110 | }; | 110 | }; |
111 | 111 | ||
112 | #if defined(_MSC_VER) | 112 | #if defined(_MSC_VER) |
@@ -119,11 +119,11 @@ struct hpi_entity { | |||
119 | #if ! defined(HPI_OS_DSP_C6000) || (defined(HPI_OS_DSP_C6000) && (__TI_COMPILER_VERSION__ > 6000008)) | 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 | 120 | /* DSP C6000 compiler v6.0.8 and lower |
121 | do not support flexible array member */ | 121 | do not support flexible array member */ |
122 | uint8_t value[]; | 122 | u8 value[]; |
123 | #else | 123 | #else |
124 | /* NOTE! Using sizeof(struct hpi_entity) will give erroneous results */ | 124 | /* NOTE! Using sizeof(struct hpi_entity) will give erroneous results */ |
125 | #define HPI_INTERNAL_WARN_ABOUT_ENTITY_VALUE | 125 | #define HPI_INTERNAL_WARN_ABOUT_ENTITY_VALUE |
126 | uint8_t value[1]; | 126 | u8 value[1]; |
127 | #endif | 127 | #endif |
128 | }; | 128 | }; |
129 | 129 | ||
@@ -142,12 +142,15 @@ enum HPI_BUSES { | |||
142 | /******************************************* CONTROL ATTRIBUTES ****/ | 142 | /******************************************* CONTROL ATTRIBUTES ****/ |
143 | /* (in order of control type ID */ | 143 | /* (in order of control type ID */ |
144 | 144 | ||
145 | /* This allows for 255 control types, 256 unique attributes each */ | 145 | /* This allows for 255 control types, 256 unique attributes each */ |
146 | #define HPI_CTL_ATTR(ctl, ai) (HPI_CONTROL_##ctl * 0x100 + ai) | 146 | #define HPI_CTL_ATTR(ctl, ai) (HPI_CONTROL_##ctl * 0x100 + ai) |
147 | 147 | ||
148 | /* Get the sub-index of the attribute for a control type */ | 148 | /* Get the sub-index of the attribute for a control type */ |
149 | #define HPI_CTL_ATTR_INDEX(i) (i&0xff) | 149 | #define HPI_CTL_ATTR_INDEX(i) (i&0xff) |
150 | 150 | ||
151 | /* Extract the control from the control attribute */ | ||
152 | #define HPI_CTL_ATTR_CONTROL(i) (i>>8) | ||
153 | |||
151 | /* Generic control attributes. */ | 154 | /* Generic control attributes. */ |
152 | 155 | ||
153 | /** Enable a control. | 156 | /** Enable a control. |
@@ -311,8 +314,7 @@ Used for HPI_ChannelModeSet/Get() | |||
311 | /* Microphone control attributes */ | 314 | /* Microphone control attributes */ |
312 | #define HPI_MICROPHONE_PHANTOM_POWER HPI_CTL_ATTR(MICROPHONE, 1) | 315 | #define HPI_MICROPHONE_PHANTOM_POWER HPI_CTL_ATTR(MICROPHONE, 1) |
313 | 316 | ||
314 | /** Equalizer control attributes | 317 | /** Equalizer control attributes */ |
315 | */ | ||
316 | /** Used to get number of filters in an EQ. (Can't set) */ | 318 | /** Used to get number of filters in an EQ. (Can't set) */ |
317 | #define HPI_EQUALIZER_NUM_FILTERS HPI_CTL_ATTR(EQUALIZER, 1) | 319 | #define HPI_EQUALIZER_NUM_FILTERS HPI_CTL_ATTR(EQUALIZER, 1) |
318 | /** Set/get the filter by type, freq, Q, gain */ | 320 | /** Set/get the filter by type, freq, Q, gain */ |
@@ -320,13 +322,15 @@ Used for HPI_ChannelModeSet/Get() | |||
320 | /** Get the biquad coefficients */ | 322 | /** Get the biquad coefficients */ |
321 | #define HPI_EQUALIZER_COEFFICIENTS HPI_CTL_ATTR(EQUALIZER, 3) | 323 | #define HPI_EQUALIZER_COEFFICIENTS HPI_CTL_ATTR(EQUALIZER, 3) |
322 | 324 | ||
323 | #define HPI_COMPANDER_PARAMS HPI_CTL_ATTR(COMPANDER, 1) | 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) | ||
324 | 332 | ||
325 | /* Cobranet control attributes. | 333 | /* Cobranet control attributes. */ |
326 | MUST be distinct from all other control attributes. | ||
327 | This is so that host side processing can easily identify a Cobranet control | ||
328 | and apply additional host side operations (like copying data) as required. | ||
329 | */ | ||
330 | #define HPI_COBRANET_SET HPI_CTL_ATTR(COBRANET, 1) | 334 | #define HPI_COBRANET_SET HPI_CTL_ATTR(COBRANET, 1) |
331 | #define HPI_COBRANET_GET HPI_CTL_ATTR(COBRANET, 2) | 335 | #define HPI_COBRANET_GET HPI_CTL_ATTR(COBRANET, 2) |
332 | #define HPI_COBRANET_SET_DATA HPI_CTL_ATTR(COBRANET, 3) | 336 | #define HPI_COBRANET_SET_DATA HPI_CTL_ATTR(COBRANET, 3) |
@@ -1512,11 +1516,11 @@ struct hpi_control_cache_single { | |||
1512 | struct hpi_control_cache_info i; | 1516 | struct hpi_control_cache_info i; |
1513 | union { | 1517 | union { |
1514 | struct { /* volume */ | 1518 | struct { /* volume */ |
1515 | u16 an_log[2]; | 1519 | short an_log[2]; |
1516 | } v; | 1520 | } v; |
1517 | struct { /* peak meter */ | 1521 | struct { /* peak meter */ |
1518 | u16 an_log_peak[2]; | 1522 | short an_log_peak[2]; |
1519 | u16 an_logRMS[2]; | 1523 | short an_logRMS[2]; |
1520 | } p; | 1524 | } p; |
1521 | struct { /* channel mode */ | 1525 | struct { /* channel mode */ |
1522 | u16 mode; | 1526 | u16 mode; |
@@ -1526,7 +1530,7 @@ struct hpi_control_cache_single { | |||
1526 | u16 source_node_index; | 1530 | u16 source_node_index; |
1527 | } x; | 1531 | } x; |
1528 | struct { /* level/trim */ | 1532 | struct { /* level/trim */ |
1529 | u16 an_log[2]; | 1533 | short an_log[2]; |
1530 | } l; | 1534 | } l; |
1531 | struct { /* tuner - partial caching. | 1535 | struct { /* tuner - partial caching. |
1532 | some attributes go to the DSP. */ | 1536 | some attributes go to the DSP. */ |
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index fcd64539d9ef..dda4f1c6f658 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c | |||
@@ -353,7 +353,12 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, | |||
353 | phr->u.c.param1 = pC->u.t.band; | 353 | phr->u.c.param1 = pC->u.t.band; |
354 | else if ((phm->u.c.attribute == HPI_TUNER_LEVEL) | 354 | else if ((phm->u.c.attribute == HPI_TUNER_LEVEL) |
355 | && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE)) | 355 | && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE)) |
356 | phr->u.c.param1 = pC->u.t.level; | 356 | if (pC->u.t.level == HPI_ERROR_ILLEGAL_CACHE_VALUE) { |
357 | phr->u.c.param1 = 0; | ||
358 | phr->error = | ||
359 | HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; | ||
360 | } else | ||
361 | phr->u.c.param1 = pC->u.t.level; | ||
357 | else | 362 | else |
358 | found = 0; | 363 | found = 0; |
359 | break; | 364 | break; |
@@ -397,7 +402,8 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, | |||
397 | if (pC->u.clk.source_index == | 402 | if (pC->u.clk.source_index == |
398 | HPI_ERROR_ILLEGAL_CACHE_VALUE) { | 403 | HPI_ERROR_ILLEGAL_CACHE_VALUE) { |
399 | phr->u.c.param1 = 0; | 404 | phr->u.c.param1 = 0; |
400 | phr->error = HPI_ERROR_INVALID_OPERATION; | 405 | phr->error = |
406 | HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; | ||
401 | } else | 407 | } else |
402 | phr->u.c.param1 = pC->u.clk.source_index; | 408 | phr->u.c.param1 = pC->u.clk.source_index; |
403 | } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE) | 409 | } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE) |
diff --git a/sound/pci/asihpi/hpidebug.c b/sound/pci/asihpi/hpidebug.c index 4cd85a401b34..949836ec913a 100644 --- a/sound/pci/asihpi/hpidebug.c +++ b/sound/pci/asihpi/hpidebug.c | |||
@@ -111,7 +111,7 @@ make_treenode_from_array(hpi_control_type_strings, HPI_CONTROL_TYPE_STRINGS) | |||
111 | &hpi_profile_strings,\ | 111 | &hpi_profile_strings,\ |
112 | &hpi_control_strings, \ | 112 | &hpi_control_strings, \ |
113 | &hpi_asyncevent_strings \ | 113 | &hpi_asyncevent_strings \ |
114 | }; | 114 | } |
115 | make_treenode_from_array(hpi_function_strings, HPI_FUNCTION_STRINGS) | 115 | make_treenode_from_array(hpi_function_strings, HPI_FUNCTION_STRINGS) |
116 | 116 | ||
117 | compile_time_assert(HPI_OBJ_MAXINDEX == 14, obj_list_doesnt_match); | 117 | compile_time_assert(HPI_OBJ_MAXINDEX == 14, obj_list_doesnt_match); |
diff --git a/sound/pci/asihpi/hpidebug.h b/sound/pci/asihpi/hpidebug.h index 44dccadcc25b..a2f0952a99f0 100644 --- a/sound/pci/asihpi/hpidebug.h +++ b/sound/pci/asihpi/hpidebug.h | |||
@@ -356,7 +356,7 @@ compile_time_assert((HPI_CONTROL_LAST_INDEX + 1 == 27), | |||
356 | "HPI_SOURCENODE_ADAPTER" \ | 356 | "HPI_SOURCENODE_ADAPTER" \ |
357 | } | 357 | } |
358 | 358 | ||
359 | compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_BASE + 1) == | 359 | compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_NONE + 1) == |
360 | (12), sourcenode_strings_match_defs); | 360 | (12), sourcenode_strings_match_defs); |
361 | 361 | ||
362 | #define HPI_DESTNODE_STRINGS \ | 362 | #define HPI_DESTNODE_STRINGS \ |
@@ -370,7 +370,7 @@ compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_BASE + 1) == | |||
370 | "HPI_DESTNODE_COBRANET", \ | 370 | "HPI_DESTNODE_COBRANET", \ |
371 | "HPI_DESTNODE_ANALOG" \ | 371 | "HPI_DESTNODE_ANALOG" \ |
372 | } | 372 | } |
373 | compile_time_assert((HPI_DESTNODE_LAST_INDEX - HPI_DESTNODE_BASE + 1) == (8), | 373 | compile_time_assert((HPI_DESTNODE_LAST_INDEX - HPI_DESTNODE_NONE + 1) == (8), |
374 | destnode_strings_match_defs); | 374 | destnode_strings_match_defs); |
375 | 375 | ||
376 | #define HPI_CONTROL_CHANNEL_MODE_STRINGS \ | 376 | #define HPI_CONTROL_CHANNEL_MODE_STRINGS \ |
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c index 298eef3e20e9..1e92eb6dd509 100644 --- a/sound/pci/asihpi/hpifunc.c +++ b/sound/pci/asihpi/hpifunc.c | |||
@@ -96,8 +96,7 @@ void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR) | |||
96 | 96 | ||
97 | static struct hpi_hsubsys gh_subsys; | 97 | static struct hpi_hsubsys gh_subsys; |
98 | 98 | ||
99 | struct hpi_hsubsys *hpi_subsys_create(void | 99 | struct hpi_hsubsys *hpi_subsys_create(void) |
100 | ) | ||
101 | { | 100 | { |
102 | struct hpi_message hm; | 101 | struct hpi_message hm; |
103 | struct hpi_response hr; | 102 | struct hpi_response hr; |
@@ -302,6 +301,7 @@ u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys, | |||
302 | { | 301 | { |
303 | struct hpi_message hm; | 302 | struct hpi_message hm; |
304 | struct hpi_response hr; | 303 | struct hpi_response hr; |
304 | |||
305 | hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, | 305 | hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, |
306 | HPI_ADAPTER_SET_MODE); | 306 | HPI_ADAPTER_SET_MODE); |
307 | hm.adapter_index = adapter_index; | 307 | hm.adapter_index = adapter_index; |
@@ -510,7 +510,7 @@ u16 hpi_adapter_debug_read(const struct hpi_hsubsys *ph_subsys, | |||
510 | hm.adapter_index = adapter_index; | 510 | hm.adapter_index = adapter_index; |
511 | hm.u.ax.debug_read.dsp_address = dsp_address; | 511 | hm.u.ax.debug_read.dsp_address = dsp_address; |
512 | 512 | ||
513 | if (*count_bytes > sizeof(hr.u.bytes)) | 513 | if (*count_bytes > (int)sizeof(hr.u.bytes)) |
514 | *count_bytes = sizeof(hr.u.bytes); | 514 | *count_bytes = sizeof(hr.u.bytes); |
515 | 515 | ||
516 | hm.u.ax.debug_read.count_bytes = *count_bytes; | 516 | hm.u.ax.debug_read.count_bytes = *count_bytes; |
@@ -976,6 +976,7 @@ u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys, | |||
976 | { | 976 | { |
977 | struct hpi_message hm; | 977 | struct hpi_message hm; |
978 | struct hpi_response hr; | 978 | struct hpi_response hr; |
979 | |||
979 | hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, | 980 | hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, |
980 | HPI_OSTREAM_ANC_READ); | 981 | HPI_OSTREAM_ANC_READ); |
981 | u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); | 982 | u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); |
@@ -1581,6 +1582,7 @@ u16 hpi_control_param_set(const struct hpi_hsubsys *ph_subsys, | |||
1581 | { | 1582 | { |
1582 | struct hpi_message hm; | 1583 | struct hpi_message hm; |
1583 | struct hpi_response hr; | 1584 | struct hpi_response hr; |
1585 | |||
1584 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | 1586 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, |
1585 | HPI_CONTROL_SET_STATE); | 1587 | HPI_CONTROL_SET_STATE); |
1586 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 1588 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -1591,6 +1593,22 @@ u16 hpi_control_param_set(const struct hpi_hsubsys *ph_subsys, | |||
1591 | return hr.error; | 1593 | return hr.error; |
1592 | } | 1594 | } |
1593 | 1595 | ||
1596 | static u16 hpi_control_log_set2(u32 h_control, u16 attrib, short sv0, | ||
1597 | short sv1) | ||
1598 | { | ||
1599 | struct hpi_message hm; | ||
1600 | struct hpi_response hr; | ||
1601 | |||
1602 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | ||
1603 | HPI_CONTROL_SET_STATE); | ||
1604 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | ||
1605 | hm.u.c.attribute = attrib; | ||
1606 | hm.u.c.an_log_value[0] = sv0; | ||
1607 | hm.u.c.an_log_value[1] = sv1; | ||
1608 | hpi_send_recv(&hm, &hr); | ||
1609 | return hr.error; | ||
1610 | } | ||
1611 | |||
1594 | static | 1612 | static |
1595 | u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys, | 1613 | u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys, |
1596 | const u32 h_control, const u16 attrib, u32 param1, u32 param2, | 1614 | const u32 h_control, const u16 attrib, u32 param1, u32 param2, |
@@ -1598,6 +1616,7 @@ u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys, | |||
1598 | { | 1616 | { |
1599 | struct hpi_message hm; | 1617 | struct hpi_message hm; |
1600 | struct hpi_response hr; | 1618 | struct hpi_response hr; |
1619 | |||
1601 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | 1620 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, |
1602 | HPI_CONTROL_GET_STATE); | 1621 | HPI_CONTROL_GET_STATE); |
1603 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 1622 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -1605,8 +1624,8 @@ u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys, | |||
1605 | hm.u.c.param1 = param1; | 1624 | hm.u.c.param1 = param1; |
1606 | hm.u.c.param2 = param2; | 1625 | hm.u.c.param2 = param2; |
1607 | hpi_send_recv(&hm, &hr); | 1626 | hpi_send_recv(&hm, &hr); |
1608 | if (pparam1) | 1627 | |
1609 | *pparam1 = hr.u.c.param1; | 1628 | *pparam1 = hr.u.c.param1; |
1610 | if (pparam2) | 1629 | if (pparam2) |
1611 | *pparam2 = hr.u.c.param2; | 1630 | *pparam2 = hr.u.c.param2; |
1612 | 1631 | ||
@@ -1617,10 +1636,23 @@ u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys, | |||
1617 | hpi_control_param_get(s, h, a, 0, 0, p1, NULL) | 1636 | hpi_control_param_get(s, h, a, 0, 0, p1, NULL) |
1618 | #define hpi_control_param2_get(s, h, a, p1, p2) \ | 1637 | #define hpi_control_param2_get(s, h, a, p1, p2) \ |
1619 | hpi_control_param_get(s, h, a, 0, 0, p1, p2) | 1638 | hpi_control_param_get(s, h, a, 0, 0, p1, p2) |
1620 | #define hpi_control_ex_param1_get(s, h, a, p1) \ | 1639 | |
1621 | hpi_control_ex_param_get(s, h, a, 0, 0, p1, NULL) | 1640 | static u16 hpi_control_log_get2(const struct hpi_hsubsys *ph_subsys, |
1622 | #define hpi_control_ex_param2_get(s, h, a, p1, p2) \ | 1641 | u32 h_control, u16 attrib, short *sv0, short *sv1) |
1623 | hpi_control_ex_param_get(s, h, a, 0, 0, p1, p2) | 1642 | { |
1643 | struct hpi_message hm; | ||
1644 | struct hpi_response hr; | ||
1645 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | ||
1646 | HPI_CONTROL_GET_STATE); | ||
1647 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | ||
1648 | hm.u.c.attribute = attrib; | ||
1649 | |||
1650 | hpi_send_recv(&hm, &hr); | ||
1651 | *sv0 = hr.u.c.an_log_value[0]; | ||
1652 | if (sv1) | ||
1653 | *sv1 = hr.u.c.an_log_value[1]; | ||
1654 | return hr.error; | ||
1655 | } | ||
1624 | 1656 | ||
1625 | static | 1657 | static |
1626 | u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys, | 1658 | u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys, |
@@ -1629,6 +1661,7 @@ u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys, | |||
1629 | { | 1661 | { |
1630 | struct hpi_message hm; | 1662 | struct hpi_message hm; |
1631 | struct hpi_response hr; | 1663 | struct hpi_response hr; |
1664 | |||
1632 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | 1665 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, |
1633 | HPI_CONTROL_GET_INFO); | 1666 | HPI_CONTROL_GET_INFO); |
1634 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 1667 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -1643,9 +1676,8 @@ u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys, | |||
1643 | return hr.error; | 1676 | return hr.error; |
1644 | } | 1677 | } |
1645 | 1678 | ||
1646 | static u16 hpi_control_get_string(const struct hpi_hsubsys *ph_subsys, | 1679 | static u16 hpi_control_get_string(const u32 h_control, const u16 attribute, |
1647 | const u32 h_control, const u16 attribute, char *psz_string, | 1680 | char *psz_string, const u32 string_length) |
1648 | const u32 string_length) | ||
1649 | { | 1681 | { |
1650 | unsigned int sub_string_index = 0, j = 0; | 1682 | unsigned int sub_string_index = 0, j = 0; |
1651 | char c = 0; | 1683 | char c = 0; |
@@ -1916,6 +1948,7 @@ u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control, | |||
1916 | { | 1948 | { |
1917 | struct hpi_message hm; | 1949 | struct hpi_message hm; |
1918 | struct hpi_response hr; | 1950 | struct hpi_response hr; |
1951 | |||
1919 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, | 1952 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, |
1920 | HPI_CONTROL_SET_STATE); | 1953 | HPI_CONTROL_SET_STATE); |
1921 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 1954 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -1941,6 +1974,7 @@ u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control, | |||
1941 | { | 1974 | { |
1942 | struct hpi_message hm; | 1975 | struct hpi_message hm; |
1943 | struct hpi_response hr; | 1976 | struct hpi_response hr; |
1977 | |||
1944 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, | 1978 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, |
1945 | HPI_CONTROL_GET_STATE); | 1979 | HPI_CONTROL_GET_STATE); |
1946 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 1980 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -1980,6 +2014,7 @@ u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys, | |||
1980 | { | 2014 | { |
1981 | struct hpi_message hm; | 2015 | struct hpi_message hm; |
1982 | struct hpi_response hr; | 2016 | struct hpi_response hr; |
2017 | |||
1983 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, | 2018 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, |
1984 | HPI_CONTROL_GET_STATE); | 2019 | HPI_CONTROL_GET_STATE); |
1985 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 2020 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -2006,6 +2041,7 @@ u16 hpi_cobranet_getI_paddress(const struct hpi_hsubsys *ph_subsys, | |||
2006 | u32 byte_count; | 2041 | u32 byte_count; |
2007 | u32 iP; | 2042 | u32 iP; |
2008 | u16 error; | 2043 | u16 error; |
2044 | |||
2009 | error = hpi_cobranet_hmi_read(ph_subsys, h_control, | 2045 | error = hpi_cobranet_hmi_read(ph_subsys, h_control, |
2010 | HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, &byte_count, | 2046 | HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, &byte_count, |
2011 | (u8 *)&iP); | 2047 | (u8 *)&iP); |
@@ -2082,6 +2118,7 @@ u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys, | |||
2082 | u32 byte_count; | 2118 | u32 byte_count; |
2083 | u16 error; | 2119 | u16 error; |
2084 | u32 mAC; | 2120 | u32 mAC; |
2121 | |||
2085 | error = hpi_cobranet_hmi_read(ph_subsys, h_control, | 2122 | error = hpi_cobranet_hmi_read(ph_subsys, h_control, |
2086 | HPI_COBRANET_HMI_cobra_if_phy_address, 4, &byte_count, | 2123 | HPI_COBRANET_HMI_cobra_if_phy_address, 4, &byte_count, |
2087 | (u8 *)&mAC); | 2124 | (u8 *)&mAC); |
@@ -2103,53 +2140,111 @@ u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys, | |||
2103 | return error; | 2140 | return error; |
2104 | } | 2141 | } |
2105 | 2142 | ||
2106 | u16 hpi_compander_set(const struct hpi_hsubsys *ph_subsys, u32 h_control, | 2143 | u16 hpi_compander_set_enable(const struct hpi_hsubsys *ph_subsys, |
2107 | u16 attack, u16 decay, short ratio100, short threshold0_01dB, | 2144 | u32 h_control, u32 enable) |
2108 | short makeup_gain0_01dB) | 2145 | { |
2146 | return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE, | ||
2147 | enable, 0); | ||
2148 | } | ||
2149 | |||
2150 | u16 hpi_compander_get_enable(const struct hpi_hsubsys *ph_subsys, | ||
2151 | u32 h_control, u32 *enable) | ||
2152 | { | ||
2153 | return hpi_control_param1_get(ph_subsys, h_control, | ||
2154 | HPI_GENERIC_ENABLE, enable); | ||
2155 | } | ||
2156 | |||
2157 | u16 hpi_compander_set_makeup_gain(const struct hpi_hsubsys *ph_subsys, | ||
2158 | u32 h_control, short makeup_gain0_01dB) | ||
2159 | { | ||
2160 | return hpi_control_log_set2(h_control, HPI_COMPANDER_MAKEUPGAIN, | ||
2161 | makeup_gain0_01dB, 0); | ||
2162 | } | ||
2163 | |||
2164 | u16 hpi_compander_get_makeup_gain(const struct hpi_hsubsys *ph_subsys, | ||
2165 | u32 h_control, short *makeup_gain0_01dB) | ||
2166 | { | ||
2167 | return hpi_control_log_get2(ph_subsys, h_control, | ||
2168 | HPI_COMPANDER_MAKEUPGAIN, makeup_gain0_01dB, NULL); | ||
2169 | } | ||
2170 | |||
2171 | u16 hpi_compander_set_attack_time_constant(const struct hpi_hsubsys | ||
2172 | *ph_subsys, u32 h_control, unsigned int index, u32 attack) | ||
2173 | { | ||
2174 | return hpi_control_param_set(ph_subsys, h_control, | ||
2175 | HPI_COMPANDER_ATTACK, attack, index); | ||
2176 | } | ||
2177 | |||
2178 | u16 hpi_compander_get_attack_time_constant(const struct hpi_hsubsys | ||
2179 | *ph_subsys, u32 h_control, unsigned int index, u32 *attack) | ||
2180 | { | ||
2181 | return hpi_control_param_get(ph_subsys, h_control, | ||
2182 | HPI_COMPANDER_ATTACK, 0, index, attack, NULL); | ||
2183 | } | ||
2184 | |||
2185 | u16 hpi_compander_set_decay_time_constant(const struct hpi_hsubsys *ph_subsys, | ||
2186 | u32 h_control, unsigned int index, u32 decay) | ||
2187 | { | ||
2188 | return hpi_control_param_set(ph_subsys, h_control, | ||
2189 | HPI_COMPANDER_DECAY, decay, index); | ||
2190 | } | ||
2191 | |||
2192 | u16 hpi_compander_get_decay_time_constant(const struct hpi_hsubsys *ph_subsys, | ||
2193 | u32 h_control, unsigned int index, u32 *decay) | ||
2194 | { | ||
2195 | return hpi_control_param_get(ph_subsys, h_control, | ||
2196 | HPI_COMPANDER_DECAY, 0, index, decay, NULL); | ||
2197 | |||
2198 | } | ||
2199 | |||
2200 | u16 hpi_compander_set_threshold(const struct hpi_hsubsys *ph_subsys, | ||
2201 | u32 h_control, unsigned int index, short threshold0_01dB) | ||
2109 | { | 2202 | { |
2110 | struct hpi_message hm; | 2203 | struct hpi_message hm; |
2111 | struct hpi_response hr; | 2204 | struct hpi_response hr; |
2205 | |||
2112 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | 2206 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, |
2113 | HPI_CONTROL_SET_STATE); | 2207 | HPI_CONTROL_SET_STATE); |
2114 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 2208 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
2115 | 2209 | hm.u.c.attribute = HPI_COMPANDER_THRESHOLD; | |
2116 | hm.u.c.param1 = attack + ((u32)ratio100 << 16); | 2210 | hm.u.c.param2 = index; |
2117 | hm.u.c.param2 = (decay & 0xFFFFL); | ||
2118 | hm.u.c.an_log_value[0] = threshold0_01dB; | 2211 | hm.u.c.an_log_value[0] = threshold0_01dB; |
2119 | hm.u.c.an_log_value[1] = makeup_gain0_01dB; | ||
2120 | hm.u.c.attribute = HPI_COMPANDER_PARAMS; | ||
2121 | 2212 | ||
2122 | hpi_send_recv(&hm, &hr); | 2213 | hpi_send_recv(&hm, &hr); |
2123 | 2214 | ||
2124 | return hr.error; | 2215 | return hr.error; |
2125 | } | 2216 | } |
2126 | 2217 | ||
2127 | u16 hpi_compander_get(const struct hpi_hsubsys *ph_subsys, u32 h_control, | 2218 | u16 hpi_compander_get_threshold(const struct hpi_hsubsys *ph_subsys, |
2128 | u16 *pw_attack, u16 *pw_decay, short *pw_ratio100, | 2219 | u32 h_control, unsigned int index, short *threshold0_01dB) |
2129 | short *pn_threshold0_01dB, short *pn_makeup_gain0_01dB) | ||
2130 | { | 2220 | { |
2131 | struct hpi_message hm; | 2221 | struct hpi_message hm; |
2132 | struct hpi_response hr; | 2222 | struct hpi_response hr; |
2223 | |||
2133 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | 2224 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, |
2134 | HPI_CONTROL_GET_STATE); | 2225 | HPI_CONTROL_GET_STATE); |
2135 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 2226 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
2136 | hm.u.c.attribute = HPI_COMPANDER_PARAMS; | 2227 | hm.u.c.attribute = HPI_COMPANDER_THRESHOLD; |
2228 | hm.u.c.param2 = index; | ||
2137 | 2229 | ||
2138 | hpi_send_recv(&hm, &hr); | 2230 | hpi_send_recv(&hm, &hr); |
2231 | *threshold0_01dB = hr.u.c.an_log_value[0]; | ||
2139 | 2232 | ||
2140 | if (pw_attack) | 2233 | return hr.error; |
2141 | *pw_attack = (short)(hr.u.c.param1 & 0xFFFF); | 2234 | } |
2142 | if (pw_decay) | ||
2143 | *pw_decay = (short)(hr.u.c.param2 & 0xFFFF); | ||
2144 | if (pw_ratio100) | ||
2145 | *pw_ratio100 = (short)(hr.u.c.param1 >> 16); | ||
2146 | 2235 | ||
2147 | if (pn_threshold0_01dB) | 2236 | u16 hpi_compander_set_ratio(const struct hpi_hsubsys *ph_subsys, |
2148 | *pn_threshold0_01dB = hr.u.c.an_log_value[0]; | 2237 | u32 h_control, u32 index, u32 ratio100) |
2149 | if (pn_makeup_gain0_01dB) | 2238 | { |
2150 | *pn_makeup_gain0_01dB = hr.u.c.an_log_value[1]; | 2239 | return hpi_control_param_set(ph_subsys, h_control, |
2240 | HPI_COMPANDER_RATIO, ratio100, index); | ||
2241 | } | ||
2151 | 2242 | ||
2152 | return hr.error; | 2243 | u16 hpi_compander_get_ratio(const struct hpi_hsubsys *ph_subsys, |
2244 | u32 h_control, u32 index, u32 *ratio100) | ||
2245 | { | ||
2246 | return hpi_control_param_get(ph_subsys, h_control, | ||
2247 | HPI_COMPANDER_RATIO, 0, index, ratio100, NULL); | ||
2153 | } | 2248 | } |
2154 | 2249 | ||
2155 | u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, | 2250 | u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, |
@@ -2157,6 +2252,7 @@ u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, | |||
2157 | { | 2252 | { |
2158 | struct hpi_message hm; | 2253 | struct hpi_message hm; |
2159 | struct hpi_response hr; | 2254 | struct hpi_response hr; |
2255 | |||
2160 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | 2256 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, |
2161 | HPI_CONTROL_GET_STATE); | 2257 | HPI_CONTROL_GET_STATE); |
2162 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 2258 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -2181,37 +2277,16 @@ u16 hpi_level_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, | |||
2181 | short an_gain0_01dB[HPI_MAX_CHANNELS] | 2277 | short an_gain0_01dB[HPI_MAX_CHANNELS] |
2182 | ) | 2278 | ) |
2183 | { | 2279 | { |
2184 | struct hpi_message hm; | 2280 | return hpi_control_log_set2(h_control, HPI_LEVEL_GAIN, |
2185 | struct hpi_response hr; | 2281 | an_gain0_01dB[0], an_gain0_01dB[1]); |
2186 | |||
2187 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | ||
2188 | HPI_CONTROL_SET_STATE); | ||
2189 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | ||
2190 | memcpy(hm.u.c.an_log_value, an_gain0_01dB, | ||
2191 | sizeof(short) * HPI_MAX_CHANNELS); | ||
2192 | hm.u.c.attribute = HPI_LEVEL_GAIN; | ||
2193 | |||
2194 | hpi_send_recv(&hm, &hr); | ||
2195 | |||
2196 | return hr.error; | ||
2197 | } | 2282 | } |
2198 | 2283 | ||
2199 | u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, | 2284 | u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, |
2200 | short an_gain0_01dB[HPI_MAX_CHANNELS] | 2285 | short an_gain0_01dB[HPI_MAX_CHANNELS] |
2201 | ) | 2286 | ) |
2202 | { | 2287 | { |
2203 | struct hpi_message hm; | 2288 | return hpi_control_log_get2(ph_subsys, h_control, HPI_LEVEL_GAIN, |
2204 | struct hpi_response hr; | 2289 | &an_gain0_01dB[0], &an_gain0_01dB[1]); |
2205 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | ||
2206 | HPI_CONTROL_GET_STATE); | ||
2207 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | ||
2208 | hm.u.c.attribute = HPI_LEVEL_GAIN; | ||
2209 | |||
2210 | hpi_send_recv(&hm, &hr); | ||
2211 | |||
2212 | memcpy(an_gain0_01dB, hr.u.c.an_log_value, | ||
2213 | sizeof(short) * HPI_MAX_CHANNELS); | ||
2214 | return hr.error; | ||
2215 | } | 2290 | } |
2216 | 2291 | ||
2217 | u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys, | 2292 | u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys, |
@@ -2413,6 +2488,7 @@ u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys, | |||
2413 | { | 2488 | { |
2414 | struct hpi_message hm; | 2489 | struct hpi_message hm; |
2415 | struct hpi_response hr; | 2490 | struct hpi_response hr; |
2491 | |||
2416 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | 2492 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, |
2417 | HPI_CONTROL_GET_STATE); | 2493 | HPI_CONTROL_GET_STATE); |
2418 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 2494 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -2439,6 +2515,7 @@ u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys, | |||
2439 | { | 2515 | { |
2440 | struct hpi_message hm; | 2516 | struct hpi_message hm; |
2441 | struct hpi_response hr; | 2517 | struct hpi_response hr; |
2518 | |||
2442 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | 2519 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, |
2443 | HPI_CONTROL_SET_STATE); | 2520 | HPI_CONTROL_SET_STATE); |
2444 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 2521 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -2460,6 +2537,7 @@ u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys, | |||
2460 | { | 2537 | { |
2461 | struct hpi_message hm; | 2538 | struct hpi_message hm; |
2462 | struct hpi_response hr; | 2539 | struct hpi_response hr; |
2540 | |||
2463 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | 2541 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, |
2464 | HPI_CONTROL_GET_STATE); | 2542 | HPI_CONTROL_GET_STATE); |
2465 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 2543 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -2623,8 +2701,8 @@ u16 hpi_tone_detector_get_frequency(const struct hpi_hsubsys *ph_subsys, | |||
2623 | u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys, | 2701 | u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys, |
2624 | u32 h_control, u32 *state) | 2702 | u32 h_control, u32 *state) |
2625 | { | 2703 | { |
2626 | return hpi_control_param_get(ph_subsys, h_control, | 2704 | return hpi_control_param1_get(ph_subsys, h_control, |
2627 | HPI_TONEDETECTOR_STATE, 0, 0, (u32 *)state, NULL); | 2705 | HPI_TONEDETECTOR_STATE, state); |
2628 | } | 2706 | } |
2629 | 2707 | ||
2630 | u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys, | 2708 | u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys, |
@@ -2637,8 +2715,8 @@ u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys, | |||
2637 | u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys, | 2715 | u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys, |
2638 | u32 h_control, u32 *enable) | 2716 | u32 h_control, u32 *enable) |
2639 | { | 2717 | { |
2640 | return hpi_control_param_get(ph_subsys, h_control, HPI_GENERIC_ENABLE, | 2718 | return hpi_control_param1_get(ph_subsys, h_control, |
2641 | 0, 0, (u32 *)enable, NULL); | 2719 | HPI_GENERIC_ENABLE, enable); |
2642 | } | 2720 | } |
2643 | 2721 | ||
2644 | u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, | 2722 | u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, |
@@ -2651,8 +2729,8 @@ u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, | |||
2651 | u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys, | 2729 | u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys, |
2652 | u32 h_control, u32 *event_enable) | 2730 | u32 h_control, u32 *event_enable) |
2653 | { | 2731 | { |
2654 | return hpi_control_param_get(ph_subsys, h_control, | 2732 | return hpi_control_param1_get(ph_subsys, h_control, |
2655 | HPI_GENERIC_EVENT_ENABLE, 0, 0, (u32 *)event_enable, NULL); | 2733 | HPI_GENERIC_EVENT_ENABLE, event_enable); |
2656 | } | 2734 | } |
2657 | 2735 | ||
2658 | u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, | 2736 | u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, |
@@ -2665,15 +2743,15 @@ u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, | |||
2665 | u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys, | 2743 | u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys, |
2666 | u32 h_control, int *threshold) | 2744 | u32 h_control, int *threshold) |
2667 | { | 2745 | { |
2668 | return hpi_control_param_get(ph_subsys, h_control, | 2746 | return hpi_control_param1_get(ph_subsys, h_control, |
2669 | HPI_TONEDETECTOR_THRESHOLD, 0, 0, (u32 *)threshold, NULL); | 2747 | HPI_TONEDETECTOR_THRESHOLD, (u32 *)threshold); |
2670 | } | 2748 | } |
2671 | 2749 | ||
2672 | u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys, | 2750 | u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys, |
2673 | u32 h_control, u32 *state) | 2751 | u32 h_control, u32 *state) |
2674 | { | 2752 | { |
2675 | return hpi_control_param_get(ph_subsys, h_control, | 2753 | return hpi_control_param1_get(ph_subsys, h_control, |
2676 | HPI_SILENCEDETECTOR_STATE, 0, 0, (u32 *)state, NULL); | 2754 | HPI_SILENCEDETECTOR_STATE, state); |
2677 | } | 2755 | } |
2678 | 2756 | ||
2679 | u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys, | 2757 | u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys, |
@@ -2686,50 +2764,50 @@ u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys, | |||
2686 | u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys, | 2764 | u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys, |
2687 | u32 h_control, u32 *enable) | 2765 | u32 h_control, u32 *enable) |
2688 | { | 2766 | { |
2689 | return hpi_control_param_get(ph_subsys, h_control, HPI_GENERIC_ENABLE, | 2767 | return hpi_control_param1_get(ph_subsys, h_control, |
2690 | 0, 0, (u32 *)enable, NULL); | 2768 | HPI_GENERIC_ENABLE, enable); |
2691 | } | 2769 | } |
2692 | 2770 | ||
2693 | u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, | 2771 | u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, |
2694 | u32 h_control, u32 event_enable) | 2772 | u32 h_control, u32 event_enable) |
2695 | { | 2773 | { |
2696 | return hpi_control_param_set(ph_subsys, h_control, | 2774 | return hpi_control_param_set(ph_subsys, h_control, |
2697 | HPI_GENERIC_EVENT_ENABLE, (u32)event_enable, 0); | 2775 | HPI_GENERIC_EVENT_ENABLE, event_enable, 0); |
2698 | } | 2776 | } |
2699 | 2777 | ||
2700 | u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys, | 2778 | u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys, |
2701 | u32 h_control, u32 *event_enable) | 2779 | u32 h_control, u32 *event_enable) |
2702 | { | 2780 | { |
2703 | return hpi_control_param_get(ph_subsys, h_control, | 2781 | return hpi_control_param1_get(ph_subsys, h_control, |
2704 | HPI_GENERIC_EVENT_ENABLE, 0, 0, (u32 *)event_enable, NULL); | 2782 | HPI_GENERIC_EVENT_ENABLE, event_enable); |
2705 | } | 2783 | } |
2706 | 2784 | ||
2707 | u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys, | 2785 | u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys, |
2708 | u32 h_control, u32 delay) | 2786 | u32 h_control, u32 delay) |
2709 | { | 2787 | { |
2710 | return hpi_control_param_set(ph_subsys, h_control, | 2788 | return hpi_control_param_set(ph_subsys, h_control, |
2711 | HPI_SILENCEDETECTOR_DELAY, (u32)delay, 0); | 2789 | HPI_SILENCEDETECTOR_DELAY, delay, 0); |
2712 | } | 2790 | } |
2713 | 2791 | ||
2714 | u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys, | 2792 | u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys, |
2715 | u32 h_control, u32 *delay) | 2793 | u32 h_control, u32 *delay) |
2716 | { | 2794 | { |
2717 | return hpi_control_param_get(ph_subsys, h_control, | 2795 | return hpi_control_param1_get(ph_subsys, h_control, |
2718 | HPI_SILENCEDETECTOR_DELAY, 0, 0, (u32 *)delay, NULL); | 2796 | HPI_SILENCEDETECTOR_DELAY, delay); |
2719 | } | 2797 | } |
2720 | 2798 | ||
2721 | u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, | 2799 | u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, |
2722 | u32 h_control, int threshold) | 2800 | u32 h_control, int threshold) |
2723 | { | 2801 | { |
2724 | return hpi_control_param_set(ph_subsys, h_control, | 2802 | return hpi_control_param_set(ph_subsys, h_control, |
2725 | HPI_SILENCEDETECTOR_THRESHOLD, (u32)threshold, 0); | 2803 | HPI_SILENCEDETECTOR_THRESHOLD, threshold, 0); |
2726 | } | 2804 | } |
2727 | 2805 | ||
2728 | u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys, | 2806 | u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys, |
2729 | u32 h_control, int *threshold) | 2807 | u32 h_control, int *threshold) |
2730 | { | 2808 | { |
2731 | return hpi_control_param_get(ph_subsys, h_control, | 2809 | return hpi_control_param1_get(ph_subsys, h_control, |
2732 | HPI_SILENCEDETECTOR_THRESHOLD, 0, 0, (u32 *)threshold, NULL); | 2810 | HPI_SILENCEDETECTOR_THRESHOLD, (u32 *)threshold); |
2733 | } | 2811 | } |
2734 | 2812 | ||
2735 | u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys, | 2813 | u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys, |
@@ -2822,6 +2900,7 @@ u16 hpi_tuner_getRF_level(const struct hpi_hsubsys *ph_subsys, u32 h_control, | |||
2822 | { | 2900 | { |
2823 | struct hpi_message hm; | 2901 | struct hpi_message hm; |
2824 | struct hpi_response hr; | 2902 | struct hpi_response hr; |
2903 | |||
2825 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | 2904 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, |
2826 | HPI_CONTROL_GET_STATE); | 2905 | HPI_CONTROL_GET_STATE); |
2827 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 2906 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -2838,6 +2917,7 @@ u16 hpi_tuner_get_rawRF_level(const struct hpi_hsubsys *ph_subsys, | |||
2838 | { | 2917 | { |
2839 | struct hpi_message hm; | 2918 | struct hpi_message hm; |
2840 | struct hpi_response hr; | 2919 | struct hpi_response hr; |
2920 | |||
2841 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | 2921 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, |
2842 | HPI_CONTROL_GET_STATE); | 2922 | HPI_CONTROL_GET_STATE); |
2843 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 2923 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -2894,14 +2974,14 @@ u16 hpi_tuner_get_program(const struct hpi_hsubsys *ph_subsys, u32 h_control, | |||
2894 | u16 hpi_tuner_get_hd_radio_dsp_version(const struct hpi_hsubsys *ph_subsys, | 2974 | u16 hpi_tuner_get_hd_radio_dsp_version(const struct hpi_hsubsys *ph_subsys, |
2895 | u32 h_control, char *psz_dsp_version, const u32 string_size) | 2975 | u32 h_control, char *psz_dsp_version, const u32 string_size) |
2896 | { | 2976 | { |
2897 | return hpi_control_get_string(ph_subsys, h_control, | 2977 | return hpi_control_get_string(h_control, |
2898 | HPI_TUNER_HDRADIO_DSP_VERSION, psz_dsp_version, string_size); | 2978 | HPI_TUNER_HDRADIO_DSP_VERSION, psz_dsp_version, string_size); |
2899 | } | 2979 | } |
2900 | 2980 | ||
2901 | u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys, | 2981 | u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys, |
2902 | u32 h_control, char *psz_sdk_version, const u32 string_size) | 2982 | u32 h_control, char *psz_sdk_version, const u32 string_size) |
2903 | { | 2983 | { |
2904 | return hpi_control_get_string(ph_subsys, h_control, | 2984 | return hpi_control_get_string(h_control, |
2905 | HPI_TUNER_HDRADIO_SDK_VERSION, psz_sdk_version, string_size); | 2985 | HPI_TUNER_HDRADIO_SDK_VERSION, psz_sdk_version, string_size); |
2906 | } | 2986 | } |
2907 | 2987 | ||
@@ -2942,15 +3022,15 @@ u16 hpi_tuner_get_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control, | |||
2942 | u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys, | 3022 | u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys, |
2943 | u32 h_control, u32 *pquality) | 3023 | u32 h_control, u32 *pquality) |
2944 | { | 3024 | { |
2945 | return hpi_control_param_get(ph_subsys, h_control, | 3025 | return hpi_control_param1_get(ph_subsys, h_control, |
2946 | HPI_TUNER_HDRADIO_SIGNAL_QUALITY, 0, 0, pquality, NULL); | 3026 | HPI_TUNER_HDRADIO_SIGNAL_QUALITY, pquality); |
2947 | } | 3027 | } |
2948 | 3028 | ||
2949 | u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, | 3029 | u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, |
2950 | u32 h_control, u32 *pblend) | 3030 | u32 h_control, u32 *pblend) |
2951 | { | 3031 | { |
2952 | return hpi_control_param_get(ph_subsys, h_control, | 3032 | return hpi_control_param1_get(ph_subsys, h_control, |
2953 | HPI_TUNER_HDRADIO_BLEND, 0, 0, pblend, NULL); | 3033 | HPI_TUNER_HDRADIO_BLEND, pblend); |
2954 | } | 3034 | } |
2955 | 3035 | ||
2956 | u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, | 3036 | u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, |
@@ -2965,6 +3045,7 @@ u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control, | |||
2965 | { | 3045 | { |
2966 | struct hpi_message hm; | 3046 | struct hpi_message hm; |
2967 | struct hpi_response hr; | 3047 | struct hpi_response hr; |
3048 | |||
2968 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | 3049 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, |
2969 | HPI_CONTROL_GET_STATE); | 3050 | HPI_CONTROL_GET_STATE); |
2970 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 3051 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -2981,43 +3062,43 @@ u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control, | |||
2981 | u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys, | 3062 | u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys, |
2982 | u32 h_control, char *psz_string, const u32 data_length) | 3063 | u32 h_control, char *psz_string, const u32 data_length) |
2983 | { | 3064 | { |
2984 | return hpi_control_get_string(ph_subsys, h_control, | 3065 | return hpi_control_get_string(h_control, HPI_PAD_CHANNEL_NAME, |
2985 | HPI_PAD_CHANNEL_NAME, psz_string, data_length); | 3066 | psz_string, data_length); |
2986 | } | 3067 | } |
2987 | 3068 | ||
2988 | u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control, | 3069 | u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control, |
2989 | char *psz_string, const u32 data_length) | 3070 | char *psz_string, const u32 data_length) |
2990 | { | 3071 | { |
2991 | return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_ARTIST, | 3072 | return hpi_control_get_string(h_control, HPI_PAD_ARTIST, psz_string, |
2992 | psz_string, data_length); | 3073 | data_length); |
2993 | } | 3074 | } |
2994 | 3075 | ||
2995 | u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control, | 3076 | u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control, |
2996 | char *psz_string, const u32 data_length) | 3077 | char *psz_string, const u32 data_length) |
2997 | { | 3078 | { |
2998 | return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_TITLE, | 3079 | return hpi_control_get_string(h_control, HPI_PAD_TITLE, psz_string, |
2999 | psz_string, data_length); | 3080 | data_length); |
3000 | } | 3081 | } |
3001 | 3082 | ||
3002 | u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control, | 3083 | u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control, |
3003 | char *psz_string, const u32 data_length) | 3084 | char *psz_string, const u32 data_length) |
3004 | { | 3085 | { |
3005 | return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_COMMENT, | 3086 | return hpi_control_get_string(h_control, HPI_PAD_COMMENT, psz_string, |
3006 | psz_string, data_length); | 3087 | data_length); |
3007 | } | 3088 | } |
3008 | 3089 | ||
3009 | u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys, | 3090 | u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys, |
3010 | u32 h_control, u32 *ppTY) | 3091 | u32 h_control, u32 *ppTY) |
3011 | { | 3092 | { |
3012 | return hpi_control_param_get(ph_subsys, h_control, | 3093 | return hpi_control_param1_get(ph_subsys, h_control, |
3013 | HPI_PAD_PROGRAM_TYPE, 0, 0, ppTY, NULL); | 3094 | HPI_PAD_PROGRAM_TYPE, ppTY); |
3014 | } | 3095 | } |
3015 | 3096 | ||
3016 | u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control, | 3097 | u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control, |
3017 | u32 *ppI) | 3098 | u32 *ppI) |
3018 | { | 3099 | { |
3019 | return hpi_control_param_get(ph_subsys, h_control, HPI_PAD_PROGRAM_ID, | 3100 | return hpi_control_param1_get(ph_subsys, h_control, |
3020 | 0, 0, ppI, NULL); | 3101 | HPI_PAD_PROGRAM_ID, ppI); |
3021 | } | 3102 | } |
3022 | 3103 | ||
3023 | u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys, | 3104 | u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys, |
@@ -3031,36 +3112,16 @@ u16 hpi_volume_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, | |||
3031 | short an_log_gain[HPI_MAX_CHANNELS] | 3112 | short an_log_gain[HPI_MAX_CHANNELS] |
3032 | ) | 3113 | ) |
3033 | { | 3114 | { |
3034 | struct hpi_message hm; | 3115 | return hpi_control_log_set2(h_control, HPI_VOLUME_GAIN, |
3035 | struct hpi_response hr; | 3116 | an_log_gain[0], an_log_gain[1]); |
3036 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | ||
3037 | HPI_CONTROL_SET_STATE); | ||
3038 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | ||
3039 | memcpy(hm.u.c.an_log_value, an_log_gain, | ||
3040 | sizeof(short) * HPI_MAX_CHANNELS); | ||
3041 | hm.u.c.attribute = HPI_VOLUME_GAIN; | ||
3042 | |||
3043 | hpi_send_recv(&hm, &hr); | ||
3044 | |||
3045 | return hr.error; | ||
3046 | } | 3117 | } |
3047 | 3118 | ||
3048 | u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, | 3119 | u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, |
3049 | short an_log_gain[HPI_MAX_CHANNELS] | 3120 | short an_log_gain[HPI_MAX_CHANNELS] |
3050 | ) | 3121 | ) |
3051 | { | 3122 | { |
3052 | struct hpi_message hm; | 3123 | return hpi_control_log_get2(ph_subsys, h_control, HPI_VOLUME_GAIN, |
3053 | struct hpi_response hr; | 3124 | &an_log_gain[0], &an_log_gain[1]); |
3054 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | ||
3055 | HPI_CONTROL_GET_STATE); | ||
3056 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | ||
3057 | hm.u.c.attribute = HPI_VOLUME_GAIN; | ||
3058 | |||
3059 | hpi_send_recv(&hm, &hr); | ||
3060 | |||
3061 | memcpy(an_log_gain, hr.u.c.an_log_value, | ||
3062 | sizeof(short) * HPI_MAX_CHANNELS); | ||
3063 | return hr.error; | ||
3064 | } | 3125 | } |
3065 | 3126 | ||
3066 | u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, | 3127 | u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, |
@@ -3068,6 +3129,7 @@ u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, | |||
3068 | { | 3129 | { |
3069 | struct hpi_message hm; | 3130 | struct hpi_message hm; |
3070 | struct hpi_response hr; | 3131 | struct hpi_response hr; |
3132 | |||
3071 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | 3133 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, |
3072 | HPI_CONTROL_GET_STATE); | 3134 | HPI_CONTROL_GET_STATE); |
3073 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 3135 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -3094,6 +3156,7 @@ u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys, | |||
3094 | { | 3156 | { |
3095 | struct hpi_message hm; | 3157 | struct hpi_message hm; |
3096 | struct hpi_response hr; | 3158 | struct hpi_response hr; |
3159 | |||
3097 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, | 3160 | hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, |
3098 | HPI_CONTROL_SET_STATE); | 3161 | HPI_CONTROL_SET_STATE); |
3099 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); | 3162 | u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); |
@@ -3170,43 +3233,42 @@ static size_t entity_type_to_size[LAST_ENTITY_TYPE] = { | |||
3170 | 6 * sizeof(char), | 3233 | 6 * sizeof(char), |
3171 | }; | 3234 | }; |
3172 | 3235 | ||
3173 | inline size_t hpi_entity_size(struct hpi_entity *entity_ptr) | 3236 | static inline size_t hpi_entity_size(struct hpi_entity *entity_ptr) |
3174 | { | 3237 | { |
3175 | return entity_ptr->header.size; | 3238 | return entity_ptr->header.size; |
3176 | } | 3239 | } |
3177 | 3240 | ||
3178 | inline size_t hpi_entity_header_size(struct hpi_entity *entity_ptr) | 3241 | static inline size_t hpi_entity_header_size(struct hpi_entity *entity_ptr) |
3179 | { | 3242 | { |
3180 | return sizeof(entity_ptr->header); | 3243 | return sizeof(entity_ptr->header); |
3181 | } | 3244 | } |
3182 | 3245 | ||
3183 | inline size_t hpi_entity_value_size(struct hpi_entity *entity_ptr) | 3246 | static inline size_t hpi_entity_value_size(struct hpi_entity *entity_ptr) |
3184 | { | 3247 | { |
3185 | return hpi_entity_size(entity_ptr) - | 3248 | return hpi_entity_size(entity_ptr) - |
3186 | hpi_entity_header_size(entity_ptr); | 3249 | hpi_entity_header_size(entity_ptr); |
3187 | } | 3250 | } |
3188 | 3251 | ||
3189 | inline size_t hpi_entity_item_count(struct hpi_entity *entity_ptr) | 3252 | static inline size_t hpi_entity_item_count(struct hpi_entity *entity_ptr) |
3190 | { | 3253 | { |
3191 | return hpi_entity_value_size(entity_ptr) / | 3254 | return hpi_entity_value_size(entity_ptr) / |
3192 | entity_type_to_size[entity_ptr->header.type]; | 3255 | entity_type_to_size[entity_ptr->header.type]; |
3193 | } | 3256 | } |
3194 | 3257 | ||
3195 | inline struct hpi_entity *hpi_entity_ptr_to_next(struct hpi_entity | 3258 | static inline struct hpi_entity *hpi_entity_ptr_to_next(struct hpi_entity |
3196 | *entity_ptr) | 3259 | *entity_ptr) |
3197 | { | 3260 | { |
3198 | return (void *)(((uint8_t *) entity_ptr) + | 3261 | return (void *)(((u8 *)entity_ptr) + hpi_entity_size(entity_ptr)); |
3199 | hpi_entity_size(entity_ptr)); | ||
3200 | } | 3262 | } |
3201 | 3263 | ||
3202 | inline u16 hpi_entity_check_type(const enum e_entity_type t) | 3264 | static inline u16 hpi_entity_check_type(const enum e_entity_type t) |
3203 | { | 3265 | { |
3204 | if (t >= 0 && t < STR_TYPE_FIELD_MAX) | 3266 | if (t >= 0 && t < STR_TYPE_FIELD_MAX) |
3205 | return 0; | 3267 | return 0; |
3206 | return HPI_ERROR_ENTITY_TYPE_INVALID; | 3268 | return HPI_ERROR_ENTITY_TYPE_INVALID; |
3207 | } | 3269 | } |
3208 | 3270 | ||
3209 | inline u16 hpi_entity_check_role(const enum e_entity_role r) | 3271 | static inline u16 hpi_entity_check_role(const enum e_entity_role r) |
3210 | { | 3272 | { |
3211 | if (r >= 0 && r < STR_ROLE_FIELD_MAX) | 3273 | if (r >= 0 && r < STR_ROLE_FIELD_MAX) |
3212 | return 0; | 3274 | return 0; |
@@ -3624,6 +3686,7 @@ u16 hpi_async_event_wait(const struct hpi_hsubsys *ph_subsys, u32 h_async, | |||
3624 | u16 maximum_events, struct hpi_async_event *p_events, | 3686 | u16 maximum_events, struct hpi_async_event *p_events, |
3625 | u16 *pw_number_returned) | 3687 | u16 *pw_number_returned) |
3626 | { | 3688 | { |
3689 | |||
3627 | return 0; | 3690 | return 0; |
3628 | } | 3691 | } |
3629 | 3692 | ||
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c index 2ee90dc3d897..f01ab964f602 100644 --- a/sound/pci/asihpi/hpimsgx.c +++ b/sound/pci/asihpi/hpimsgx.c | |||
@@ -741,7 +741,7 @@ static void HPIMSGX__reset(u16 adapter_index) | |||
741 | hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM, | 741 | hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM, |
742 | HPI_SUBSYS_FIND_ADAPTERS, 0); | 742 | HPI_SUBSYS_FIND_ADAPTERS, 0); |
743 | memcpy(&gRESP_HPI_SUBSYS_FIND_ADAPTERS, &hr, | 743 | memcpy(&gRESP_HPI_SUBSYS_FIND_ADAPTERS, &hr, |
744 | sizeof(&gRESP_HPI_SUBSYS_FIND_ADAPTERS)); | 744 | sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS)); |
745 | 745 | ||
746 | for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) { | 746 | for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) { |
747 | 747 | ||
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c index 7396ac54e99f..62895a719fcb 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.c | |||
@@ -121,11 +121,17 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
121 | phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg; | 121 | phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg; |
122 | 122 | ||
123 | /* Read the message and response pointers from user space. */ | 123 | /* Read the message and response pointers from user space. */ |
124 | get_user(puhm, &phpi_ioctl_data->phm); | 124 | if (get_user(puhm, &phpi_ioctl_data->phm) || |
125 | get_user(puhr, &phpi_ioctl_data->phr); | 125 | get_user(puhr, &phpi_ioctl_data->phr)) { |
126 | err = -EFAULT; | ||
127 | goto out; | ||
128 | } | ||
126 | 129 | ||
127 | /* Now read the message size and data from user space. */ | 130 | /* Now read the message size and data from user space. */ |
128 | get_user(hm->h.size, (u16 __user *)puhm); | 131 | if (get_user(hm->h.size, (u16 __user *)puhm)) { |
132 | err = -EFAULT; | ||
133 | goto out; | ||
134 | } | ||
129 | if (hm->h.size > sizeof(*hm)) | 135 | if (hm->h.size > sizeof(*hm)) |
130 | hm->h.size = sizeof(*hm); | 136 | hm->h.size = sizeof(*hm); |
131 | 137 | ||
@@ -138,7 +144,10 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
138 | goto out; | 144 | goto out; |
139 | } | 145 | } |
140 | 146 | ||
141 | get_user(res_max_size, (u16 __user *)puhr); | 147 | if (get_user(res_max_size, (u16 __user *)puhr)) { |
148 | err = -EFAULT; | ||
149 | goto out; | ||
150 | } | ||
142 | /* printk(KERN_INFO "user response size %d\n", res_max_size); */ | 151 | /* printk(KERN_INFO "user response size %d\n", res_max_size); */ |
143 | if (res_max_size < sizeof(struct hpi_response_header)) { | 152 | if (res_max_size < sizeof(struct hpi_response_header)) { |
144 | HPI_DEBUG_LOG(WARNING, "small res size %d\n", res_max_size); | 153 | HPI_DEBUG_LOG(WARNING, "small res size %d\n", res_max_size); |
@@ -464,9 +473,7 @@ void __init asihpi_init(void) | |||
464 | 473 | ||
465 | memset(adapters, 0, sizeof(adapters)); | 474 | memset(adapters, 0, sizeof(adapters)); |
466 | 475 | ||
467 | printk(KERN_INFO "ASIHPI driver %d.%02d.%02d\n", | 476 | printk(KERN_INFO "ASIHPI driver " HPI_VER_STRING "\n"); |
468 | HPI_VER_MAJOR(HPI_VER), HPI_VER_MINOR(HPI_VER), | ||
469 | HPI_VER_RELEASE(HPI_VER)); | ||
470 | 477 | ||
471 | hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, | 478 | hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, |
472 | HPI_SUBSYS_DRIVER_LOAD); | 479 | HPI_SUBSYS_DRIVER_LOAD); |
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 668a5ec04499..20763dd03fa0 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c | |||
@@ -2250,6 +2250,8 @@ static int snd_echo_resume(struct pci_dev *pci) | |||
2250 | DE_INIT(("resume start\n")); | 2250 | DE_INIT(("resume start\n")); |
2251 | pci_restore_state(pci); | 2251 | pci_restore_state(pci); |
2252 | commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL); | 2252 | commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL); |
2253 | if (commpage_bak == NULL) | ||
2254 | return -ENOMEM; | ||
2253 | commpage = chip->comm_page; | 2255 | commpage = chip->comm_page; |
2254 | memcpy(commpage_bak, commpage, sizeof(struct comm_page)); | 2256 | memcpy(commpage_bak, commpage, sizeof(struct comm_page)); |
2255 | 2257 | ||
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index ba2098d20ccc..a7802b99436c 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -396,15 +396,18 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
396 | } | 396 | } |
397 | for (n = prev_nid + 1; n <= val; n++) { | 397 | for (n = prev_nid + 1; n <= val; n++) { |
398 | if (conns >= max_conns) { | 398 | if (conns >= max_conns) { |
399 | snd_printk(KERN_ERR | 399 | snd_printk(KERN_ERR "hda_codec: " |
400 | "Too many connections\n"); | 400 | "Too many connections %d for NID 0x%x\n", |
401 | conns, nid); | ||
401 | return -EINVAL; | 402 | return -EINVAL; |
402 | } | 403 | } |
403 | conn_list[conns++] = n; | 404 | conn_list[conns++] = n; |
404 | } | 405 | } |
405 | } else { | 406 | } else { |
406 | if (conns >= max_conns) { | 407 | if (conns >= max_conns) { |
407 | snd_printk(KERN_ERR "Too many connections\n"); | 408 | snd_printk(KERN_ERR "hda_codec: " |
409 | "Too many connections %d for NID 0x%x\n", | ||
410 | conns, nid); | ||
408 | return -EINVAL; | 411 | return -EINVAL; |
409 | } | 412 | } |
410 | conn_list[conns++] = val; | 413 | conn_list[conns++] = val; |
@@ -730,15 +733,17 @@ static void /*__devinit*/ setup_fg_nodes(struct hda_codec *codec) | |||
730 | total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); | 733 | total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); |
731 | for (i = 0; i < total_nodes; i++, nid++) { | 734 | for (i = 0; i < total_nodes; i++, nid++) { |
732 | function_id = snd_hda_param_read(codec, nid, | 735 | function_id = snd_hda_param_read(codec, nid, |
733 | AC_PAR_FUNCTION_TYPE) & 0xff; | 736 | AC_PAR_FUNCTION_TYPE); |
734 | switch (function_id) { | 737 | switch (function_id & 0xff) { |
735 | case AC_GRP_AUDIO_FUNCTION: | 738 | case AC_GRP_AUDIO_FUNCTION: |
736 | codec->afg = nid; | 739 | codec->afg = nid; |
737 | codec->function_id = function_id; | 740 | codec->afg_function_id = function_id & 0xff; |
741 | codec->afg_unsol = (function_id >> 8) & 1; | ||
738 | break; | 742 | break; |
739 | case AC_GRP_MODEM_FUNCTION: | 743 | case AC_GRP_MODEM_FUNCTION: |
740 | codec->mfg = nid; | 744 | codec->mfg = nid; |
741 | codec->function_id = function_id; | 745 | codec->mfg_function_id = function_id & 0xff; |
746 | codec->mfg_unsol = (function_id >> 8) & 1; | ||
742 | break; | 747 | break; |
743 | default: | 748 | default: |
744 | break; | 749 | break; |
@@ -1565,6 +1570,17 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec) | |||
1565 | EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp); | 1570 | EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp); |
1566 | #endif /* SND_HDA_NEEDS_RESUME */ | 1571 | #endif /* SND_HDA_NEEDS_RESUME */ |
1567 | 1572 | ||
1573 | static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir, | ||
1574 | unsigned int ofs) | ||
1575 | { | ||
1576 | u32 caps = query_amp_caps(codec, nid, dir); | ||
1577 | /* get num steps */ | ||
1578 | caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; | ||
1579 | if (ofs < caps) | ||
1580 | caps -= ofs; | ||
1581 | return caps; | ||
1582 | } | ||
1583 | |||
1568 | /** | 1584 | /** |
1569 | * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer | 1585 | * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer |
1570 | * | 1586 | * |
@@ -1579,23 +1595,17 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, | |||
1579 | u8 chs = get_amp_channels(kcontrol); | 1595 | u8 chs = get_amp_channels(kcontrol); |
1580 | int dir = get_amp_direction(kcontrol); | 1596 | int dir = get_amp_direction(kcontrol); |
1581 | unsigned int ofs = get_amp_offset(kcontrol); | 1597 | unsigned int ofs = get_amp_offset(kcontrol); |
1582 | u32 caps; | ||
1583 | 1598 | ||
1584 | caps = query_amp_caps(codec, nid, dir); | 1599 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
1585 | /* num steps */ | 1600 | uinfo->count = chs == 3 ? 2 : 1; |
1586 | caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; | 1601 | uinfo->value.integer.min = 0; |
1587 | if (!caps) { | 1602 | uinfo->value.integer.max = get_amp_max_value(codec, nid, dir, ofs); |
1603 | if (!uinfo->value.integer.max) { | ||
1588 | printk(KERN_WARNING "hda_codec: " | 1604 | printk(KERN_WARNING "hda_codec: " |
1589 | "num_steps = 0 for NID=0x%x (ctl = %s)\n", nid, | 1605 | "num_steps = 0 for NID=0x%x (ctl = %s)\n", nid, |
1590 | kcontrol->id.name); | 1606 | kcontrol->id.name); |
1591 | return -EINVAL; | 1607 | return -EINVAL; |
1592 | } | 1608 | } |
1593 | if (ofs < caps) | ||
1594 | caps -= ofs; | ||
1595 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1596 | uinfo->count = chs == 3 ? 2 : 1; | ||
1597 | uinfo->value.integer.min = 0; | ||
1598 | uinfo->value.integer.max = caps; | ||
1599 | return 0; | 1609 | return 0; |
1600 | } | 1610 | } |
1601 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info); | 1611 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info); |
@@ -1620,8 +1630,14 @@ update_amp_value(struct hda_codec *codec, hda_nid_t nid, | |||
1620 | int ch, int dir, int idx, unsigned int ofs, | 1630 | int ch, int dir, int idx, unsigned int ofs, |
1621 | unsigned int val) | 1631 | unsigned int val) |
1622 | { | 1632 | { |
1633 | unsigned int maxval; | ||
1634 | |||
1623 | if (val > 0) | 1635 | if (val > 0) |
1624 | val += ofs; | 1636 | val += ofs; |
1637 | /* ofs = 0: raw max value */ | ||
1638 | maxval = get_amp_max_value(codec, nid, dir, 0); | ||
1639 | if (val > maxval) | ||
1640 | val = maxval; | ||
1625 | return snd_hda_codec_amp_update(codec, nid, ch, dir, idx, | 1641 | return snd_hda_codec_amp_update(codec, nid, ch, dir, idx, |
1626 | HDA_AMP_VOLMASK, val); | 1642 | HDA_AMP_VOLMASK, val); |
1627 | } | 1643 | } |
@@ -2999,26 +3015,31 @@ struct hda_rate_tbl { | |||
2999 | unsigned int hda_fmt; | 3015 | unsigned int hda_fmt; |
3000 | }; | 3016 | }; |
3001 | 3017 | ||
3018 | /* rate = base * mult / div */ | ||
3019 | #define HDA_RATE(base, mult, div) \ | ||
3020 | (AC_FMT_BASE_##base##K | (((mult) - 1) << AC_FMT_MULT_SHIFT) | \ | ||
3021 | (((div) - 1) << AC_FMT_DIV_SHIFT)) | ||
3022 | |||
3002 | static struct hda_rate_tbl rate_bits[] = { | 3023 | static struct hda_rate_tbl rate_bits[] = { |
3003 | /* rate in Hz, ALSA rate bitmask, HDA format value */ | 3024 | /* rate in Hz, ALSA rate bitmask, HDA format value */ |
3004 | 3025 | ||
3005 | /* autodetected value used in snd_hda_query_supported_pcm */ | 3026 | /* autodetected value used in snd_hda_query_supported_pcm */ |
3006 | { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */ | 3027 | { 8000, SNDRV_PCM_RATE_8000, HDA_RATE(48, 1, 6) }, |
3007 | { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */ | 3028 | { 11025, SNDRV_PCM_RATE_11025, HDA_RATE(44, 1, 4) }, |
3008 | { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */ | 3029 | { 16000, SNDRV_PCM_RATE_16000, HDA_RATE(48, 1, 3) }, |
3009 | { 22050, SNDRV_PCM_RATE_22050, 0x4100 }, /* 1/2 x 44 */ | 3030 | { 22050, SNDRV_PCM_RATE_22050, HDA_RATE(44, 1, 2) }, |
3010 | { 32000, SNDRV_PCM_RATE_32000, 0x0a00 }, /* 2/3 x 48 */ | 3031 | { 32000, SNDRV_PCM_RATE_32000, HDA_RATE(48, 2, 3) }, |
3011 | { 44100, SNDRV_PCM_RATE_44100, 0x4000 }, /* 44 */ | 3032 | { 44100, SNDRV_PCM_RATE_44100, HDA_RATE(44, 1, 1) }, |
3012 | { 48000, SNDRV_PCM_RATE_48000, 0x0000 }, /* 48 */ | 3033 | { 48000, SNDRV_PCM_RATE_48000, HDA_RATE(48, 1, 1) }, |
3013 | { 88200, SNDRV_PCM_RATE_88200, 0x4800 }, /* 2 x 44 */ | 3034 | { 88200, SNDRV_PCM_RATE_88200, HDA_RATE(44, 2, 1) }, |
3014 | { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ | 3035 | { 96000, SNDRV_PCM_RATE_96000, HDA_RATE(48, 2, 1) }, |
3015 | { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ | 3036 | { 176400, SNDRV_PCM_RATE_176400, HDA_RATE(44, 4, 1) }, |
3016 | { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ | 3037 | { 192000, SNDRV_PCM_RATE_192000, HDA_RATE(48, 4, 1) }, |
3017 | #define AC_PAR_PCM_RATE_BITS 11 | 3038 | #define AC_PAR_PCM_RATE_BITS 11 |
3018 | /* up to bits 10, 384kHZ isn't supported properly */ | 3039 | /* up to bits 10, 384kHZ isn't supported properly */ |
3019 | 3040 | ||
3020 | /* not autodetected value */ | 3041 | /* not autodetected value */ |
3021 | { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */ | 3042 | { 9600, SNDRV_PCM_RATE_KNOT, HDA_RATE(48, 1, 5) }, |
3022 | 3043 | ||
3023 | { 0 } /* terminator */ | 3044 | { 0 } /* terminator */ |
3024 | }; | 3045 | }; |
@@ -3037,7 +3058,8 @@ static struct hda_rate_tbl rate_bits[] = { | |||
3037 | unsigned int snd_hda_calc_stream_format(unsigned int rate, | 3058 | unsigned int snd_hda_calc_stream_format(unsigned int rate, |
3038 | unsigned int channels, | 3059 | unsigned int channels, |
3039 | unsigned int format, | 3060 | unsigned int format, |
3040 | unsigned int maxbps) | 3061 | unsigned int maxbps, |
3062 | unsigned short spdif_ctls) | ||
3041 | { | 3063 | { |
3042 | int i; | 3064 | int i; |
3043 | unsigned int val = 0; | 3065 | unsigned int val = 0; |
@@ -3060,20 +3082,20 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, | |||
3060 | 3082 | ||
3061 | switch (snd_pcm_format_width(format)) { | 3083 | switch (snd_pcm_format_width(format)) { |
3062 | case 8: | 3084 | case 8: |
3063 | val |= 0x00; | 3085 | val |= AC_FMT_BITS_8; |
3064 | break; | 3086 | break; |
3065 | case 16: | 3087 | case 16: |
3066 | val |= 0x10; | 3088 | val |= AC_FMT_BITS_16; |
3067 | break; | 3089 | break; |
3068 | case 20: | 3090 | case 20: |
3069 | case 24: | 3091 | case 24: |
3070 | case 32: | 3092 | case 32: |
3071 | if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE) | 3093 | if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE) |
3072 | val |= 0x40; | 3094 | val |= AC_FMT_BITS_32; |
3073 | else if (maxbps >= 24) | 3095 | else if (maxbps >= 24) |
3074 | val |= 0x30; | 3096 | val |= AC_FMT_BITS_24; |
3075 | else | 3097 | else |
3076 | val |= 0x20; | 3098 | val |= AC_FMT_BITS_20; |
3077 | break; | 3099 | break; |
3078 | default: | 3100 | default: |
3079 | snd_printdd("invalid format width %d\n", | 3101 | snd_printdd("invalid format width %d\n", |
@@ -3081,6 +3103,9 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, | |||
3081 | return 0; | 3103 | return 0; |
3082 | } | 3104 | } |
3083 | 3105 | ||
3106 | if (spdif_ctls & AC_DIG1_NONAUDIO) | ||
3107 | val |= AC_FMT_TYPE_NON_PCM; | ||
3108 | |||
3084 | return val; | 3109 | return val; |
3085 | } | 3110 | } |
3086 | EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); | 3111 | EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 5991d14e1ec0..0328cf55cdba 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -224,6 +224,27 @@ enum { | |||
224 | /* Input converter SDI select */ | 224 | /* Input converter SDI select */ |
225 | #define AC_SDI_SELECT (0xf<<0) | 225 | #define AC_SDI_SELECT (0xf<<0) |
226 | 226 | ||
227 | /* stream format id */ | ||
228 | #define AC_FMT_CHAN_SHIFT 0 | ||
229 | #define AC_FMT_CHAN_MASK (0x0f << 0) | ||
230 | #define AC_FMT_BITS_SHIFT 4 | ||
231 | #define AC_FMT_BITS_MASK (7 << 4) | ||
232 | #define AC_FMT_BITS_8 (0 << 4) | ||
233 | #define AC_FMT_BITS_16 (1 << 4) | ||
234 | #define AC_FMT_BITS_20 (2 << 4) | ||
235 | #define AC_FMT_BITS_24 (3 << 4) | ||
236 | #define AC_FMT_BITS_32 (4 << 4) | ||
237 | #define AC_FMT_DIV_SHIFT 8 | ||
238 | #define AC_FMT_DIV_MASK (7 << 8) | ||
239 | #define AC_FMT_MULT_SHIFT 11 | ||
240 | #define AC_FMT_MULT_MASK (7 << 11) | ||
241 | #define AC_FMT_BASE_SHIFT 14 | ||
242 | #define AC_FMT_BASE_48K (0 << 14) | ||
243 | #define AC_FMT_BASE_44K (1 << 14) | ||
244 | #define AC_FMT_TYPE_SHIFT 15 | ||
245 | #define AC_FMT_TYPE_PCM (0 << 15) | ||
246 | #define AC_FMT_TYPE_NON_PCM (1 << 15) | ||
247 | |||
227 | /* Unsolicited response control */ | 248 | /* Unsolicited response control */ |
228 | #define AC_UNSOL_TAG (0x3f<<0) | 249 | #define AC_UNSOL_TAG (0x3f<<0) |
229 | #define AC_UNSOL_ENABLED (1<<7) | 250 | #define AC_UNSOL_ENABLED (1<<7) |
@@ -364,6 +385,9 @@ enum { | |||
364 | #define AC_DIG2_CC (0x7f<<0) | 385 | #define AC_DIG2_CC (0x7f<<0) |
365 | 386 | ||
366 | /* Pin widget control - 8bit */ | 387 | /* Pin widget control - 8bit */ |
388 | #define AC_PINCTL_EPT (0x3<<0) | ||
389 | #define AC_PINCTL_EPT_NATIVE 0 | ||
390 | #define AC_PINCTL_EPT_HBR 3 | ||
367 | #define AC_PINCTL_VREFEN (0x7<<0) | 391 | #define AC_PINCTL_VREFEN (0x7<<0) |
368 | #define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */ | 392 | #define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */ |
369 | #define AC_PINCTL_VREF_50 1 /* 50% */ | 393 | #define AC_PINCTL_VREF_50 1 /* 50% */ |
@@ -760,7 +784,10 @@ struct hda_codec { | |||
760 | hda_nid_t mfg; /* MFG node id */ | 784 | hda_nid_t mfg; /* MFG node id */ |
761 | 785 | ||
762 | /* ids */ | 786 | /* ids */ |
763 | u32 function_id; | 787 | u8 afg_function_id; |
788 | u8 mfg_function_id; | ||
789 | u8 afg_unsol; | ||
790 | u8 mfg_unsol; | ||
764 | u32 vendor_id; | 791 | u32 vendor_id; |
765 | u32 subsystem_id; | 792 | u32 subsystem_id; |
766 | u32 revision_id; | 793 | u32 revision_id; |
@@ -928,7 +955,8 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid); | |||
928 | unsigned int snd_hda_calc_stream_format(unsigned int rate, | 955 | unsigned int snd_hda_calc_stream_format(unsigned int rate, |
929 | unsigned int channels, | 956 | unsigned int channels, |
930 | unsigned int format, | 957 | unsigned int format, |
931 | unsigned int maxbps); | 958 | unsigned int maxbps, |
959 | unsigned short spdif_ctls); | ||
932 | int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, | 960 | int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, |
933 | unsigned int format); | 961 | unsigned int format); |
934 | 962 | ||
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index a1fc83753cc6..bf3ced51e0f8 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c | |||
@@ -649,7 +649,9 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus, | |||
649 | *codecp = NULL; | 649 | *codecp = NULL; |
650 | if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) { | 650 | if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) { |
651 | list_for_each_entry(codec, &bus->codec_list, list) { | 651 | list_for_each_entry(codec, &bus->codec_list, list) { |
652 | if (codec->addr == caddr) { | 652 | if (codec->vendor_id == vendorid && |
653 | codec->subsystem_id == subid && | ||
654 | codec->addr == caddr) { | ||
653 | *codecp = codec; | 655 | *codecp = codec; |
654 | break; | 656 | break; |
655 | } | 657 | } |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 1df25cf5ce38..66d420212d9a 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -1653,7 +1653,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
1653 | format_val = snd_hda_calc_stream_format(runtime->rate, | 1653 | format_val = snd_hda_calc_stream_format(runtime->rate, |
1654 | runtime->channels, | 1654 | runtime->channels, |
1655 | runtime->format, | 1655 | runtime->format, |
1656 | hinfo->maxbps); | 1656 | hinfo->maxbps, |
1657 | apcm->codec->spdif_ctls); | ||
1657 | if (!format_val) { | 1658 | if (!format_val) { |
1658 | snd_printk(KERN_ERR SFX | 1659 | snd_printk(KERN_ERR SFX |
1659 | "invalid format_val, rate=%d, ch=%d, format=%d\n", | 1660 | "invalid format_val, rate=%d, ch=%d, format=%d\n", |
@@ -1960,7 +1961,7 @@ static void azx_irq_pending_work(struct work_struct *work) | |||
1960 | spin_unlock_irq(&chip->reg_lock); | 1961 | spin_unlock_irq(&chip->reg_lock); |
1961 | if (!pending) | 1962 | if (!pending) |
1962 | return; | 1963 | return; |
1963 | cond_resched(); | 1964 | msleep(1); |
1964 | } | 1965 | } |
1965 | } | 1966 | } |
1966 | 1967 | ||
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index f97d35de66c4..f025200f2a62 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
@@ -557,7 +557,12 @@ static void print_codec_info(struct snd_info_entry *entry, | |||
557 | else | 557 | else |
558 | snd_iprintf(buffer, "Not Set\n"); | 558 | snd_iprintf(buffer, "Not Set\n"); |
559 | snd_iprintf(buffer, "Address: %d\n", codec->addr); | 559 | snd_iprintf(buffer, "Address: %d\n", codec->addr); |
560 | snd_iprintf(buffer, "Function Id: 0x%x\n", codec->function_id); | 560 | if (codec->afg) |
561 | snd_iprintf(buffer, "AFG Function Id: 0x%x (unsol %u)\n", | ||
562 | codec->afg_function_id, codec->afg_unsol); | ||
563 | if (codec->mfg) | ||
564 | snd_iprintf(buffer, "MFG Function Id: 0x%x (unsol %u)\n", | ||
565 | codec->mfg_function_id, codec->mfg_unsol); | ||
561 | snd_iprintf(buffer, "Vendor Id: 0x%08x\n", codec->vendor_id); | 566 | snd_iprintf(buffer, "Vendor Id: 0x%08x\n", codec->vendor_id); |
562 | snd_iprintf(buffer, "Subsystem Id: 0x%08x\n", codec->subsystem_id); | 567 | snd_iprintf(buffer, "Subsystem Id: 0x%08x\n", codec->subsystem_id); |
563 | snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id); | 568 | snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id); |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index afbe314a5bf3..b697fd2a6f8b 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -3662,7 +3662,12 @@ static int patch_ad1984(struct hda_codec *codec) | |||
3662 | codec->patch_ops.build_pcms = ad1984_build_pcms; | 3662 | codec->patch_ops.build_pcms = ad1984_build_pcms; |
3663 | break; | 3663 | break; |
3664 | case AD1984_THINKPAD: | 3664 | case AD1984_THINKPAD: |
3665 | spec->multiout.dig_out_nid = AD1884_SPDIF_OUT; | 3665 | if (codec->subsystem_id == 0x17aa20fb) { |
3666 | /* Thinpad X300 does not have the ability to do SPDIF, | ||
3667 | or attach to docking station to use SPDIF */ | ||
3668 | spec->multiout.dig_out_nid = 0; | ||
3669 | } else | ||
3670 | spec->multiout.dig_out_nid = AD1884_SPDIF_OUT; | ||
3666 | spec->input_mux = &ad1984_thinkpad_capture_source; | 3671 | spec->input_mux = &ad1984_thinkpad_capture_source; |
3667 | spec->mixers[0] = ad1984_thinkpad_mixers; | 3672 | spec->mixers[0] = ad1984_thinkpad_mixers; |
3668 | spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs; | 3673 | spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs; |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 2bf2cb5da956..df8b19b17308 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -131,6 +131,8 @@ struct conexant_spec { | |||
131 | unsigned int dc_enable; | 131 | unsigned int dc_enable; |
132 | unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */ | 132 | unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */ |
133 | unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ | 133 | unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ |
134 | |||
135 | unsigned int beep_amp; | ||
134 | }; | 136 | }; |
135 | 137 | ||
136 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, | 138 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, |
@@ -515,6 +517,15 @@ static struct snd_kcontrol_new cxt_capture_mixers[] = { | |||
515 | {} | 517 | {} |
516 | }; | 518 | }; |
517 | 519 | ||
520 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
521 | /* additional beep mixers; the actual parameters are overwritten at build */ | ||
522 | static struct snd_kcontrol_new cxt_beep_mixer[] = { | ||
523 | HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), | ||
524 | HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), | ||
525 | { } /* end */ | ||
526 | }; | ||
527 | #endif | ||
528 | |||
518 | static const char *slave_vols[] = { | 529 | static const char *slave_vols[] = { |
519 | "Headphone Playback Volume", | 530 | "Headphone Playback Volume", |
520 | "Speaker Playback Volume", | 531 | "Speaker Playback Volume", |
@@ -580,16 +591,52 @@ static int conexant_build_controls(struct hda_codec *codec) | |||
580 | return err; | 591 | return err; |
581 | } | 592 | } |
582 | 593 | ||
594 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
595 | /* create beep controls if needed */ | ||
596 | if (spec->beep_amp) { | ||
597 | struct snd_kcontrol_new *knew; | ||
598 | for (knew = cxt_beep_mixer; knew->name; knew++) { | ||
599 | struct snd_kcontrol *kctl; | ||
600 | kctl = snd_ctl_new1(knew, codec); | ||
601 | if (!kctl) | ||
602 | return -ENOMEM; | ||
603 | kctl->private_value = spec->beep_amp; | ||
604 | err = snd_hda_ctl_add(codec, 0, kctl); | ||
605 | if (err < 0) | ||
606 | return err; | ||
607 | } | ||
608 | } | ||
609 | #endif | ||
610 | |||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
615 | static int conexant_suspend(struct hda_codec *codec, pm_message_t state) | ||
616 | { | ||
617 | snd_hda_shutup_pins(codec); | ||
583 | return 0; | 618 | return 0; |
584 | } | 619 | } |
620 | #endif | ||
585 | 621 | ||
586 | static struct hda_codec_ops conexant_patch_ops = { | 622 | static struct hda_codec_ops conexant_patch_ops = { |
587 | .build_controls = conexant_build_controls, | 623 | .build_controls = conexant_build_controls, |
588 | .build_pcms = conexant_build_pcms, | 624 | .build_pcms = conexant_build_pcms, |
589 | .init = conexant_init, | 625 | .init = conexant_init, |
590 | .free = conexant_free, | 626 | .free = conexant_free, |
627 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
628 | .suspend = conexant_suspend, | ||
629 | #endif | ||
630 | .reboot_notify = snd_hda_shutup_pins, | ||
591 | }; | 631 | }; |
592 | 632 | ||
633 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
634 | #define set_beep_amp(spec, nid, idx, dir) \ | ||
635 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) | ||
636 | #else | ||
637 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | ||
638 | #endif | ||
639 | |||
593 | /* | 640 | /* |
594 | * EAPD control | 641 | * EAPD control |
595 | * the private value = nid | (invert << 8) | 642 | * the private value = nid | (invert << 8) |
@@ -1130,9 +1177,10 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
1130 | spec->num_init_verbs = 1; | 1177 | spec->num_init_verbs = 1; |
1131 | spec->init_verbs[0] = cxt5045_init_verbs; | 1178 | spec->init_verbs[0] = cxt5045_init_verbs; |
1132 | spec->spdif_route = 0; | 1179 | spec->spdif_route = 0; |
1133 | spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes), | 1180 | spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes); |
1134 | spec->channel_mode = cxt5045_modes, | 1181 | spec->channel_mode = cxt5045_modes; |
1135 | 1182 | ||
1183 | set_beep_amp(spec, 0x16, 0, 1); | ||
1136 | 1184 | ||
1137 | codec->patch_ops = conexant_patch_ops; | 1185 | codec->patch_ops = conexant_patch_ops; |
1138 | 1186 | ||
@@ -1211,6 +1259,9 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
1211 | break; | 1259 | break; |
1212 | } | 1260 | } |
1213 | 1261 | ||
1262 | if (spec->beep_amp) | ||
1263 | snd_hda_attach_beep_device(codec, spec->beep_amp); | ||
1264 | |||
1214 | return 0; | 1265 | return 0; |
1215 | } | 1266 | } |
1216 | 1267 | ||
@@ -1632,6 +1683,11 @@ static void cxt5051_update_speaker(struct hda_codec *codec) | |||
1632 | pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; | 1683 | pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; |
1633 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 1684 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
1634 | pinctl); | 1685 | pinctl); |
1686 | /* on ideapad there is an aditional speaker (subwoofer) to mute */ | ||
1687 | if (spec->ideapad) | ||
1688 | snd_hda_codec_write(codec, 0x1b, 0, | ||
1689 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1690 | pinctl); | ||
1635 | } | 1691 | } |
1636 | 1692 | ||
1637 | /* turn on/off EAPD (+ mute HP) as a master switch */ | 1693 | /* turn on/off EAPD (+ mute HP) as a master switch */ |
@@ -1888,6 +1944,13 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid, | |||
1888 | #endif | 1944 | #endif |
1889 | } | 1945 | } |
1890 | 1946 | ||
1947 | static struct hda_verb cxt5051_ideapad_init_verbs[] = { | ||
1948 | /* Subwoofer */ | ||
1949 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1950 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1951 | { } /* end */ | ||
1952 | }; | ||
1953 | |||
1891 | /* initialize jack-sensing, too */ | 1954 | /* initialize jack-sensing, too */ |
1892 | static int cxt5051_init(struct hda_codec *codec) | 1955 | static int cxt5051_init(struct hda_codec *codec) |
1893 | { | 1956 | { |
@@ -1917,6 +1980,7 @@ enum { | |||
1917 | CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */ | 1980 | CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */ |
1918 | CXT5051_F700, /* HP Compaq Presario F700 */ | 1981 | CXT5051_F700, /* HP Compaq Presario F700 */ |
1919 | CXT5051_TOSHIBA, /* Toshiba M300 & co */ | 1982 | CXT5051_TOSHIBA, /* Toshiba M300 & co */ |
1983 | CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */ | ||
1920 | CXT5051_MODELS | 1984 | CXT5051_MODELS |
1921 | }; | 1985 | }; |
1922 | 1986 | ||
@@ -1927,6 +1991,7 @@ static const char *cxt5051_models[CXT5051_MODELS] = { | |||
1927 | [CXT5051_LENOVO_X200] = "lenovo-x200", | 1991 | [CXT5051_LENOVO_X200] = "lenovo-x200", |
1928 | [CXT5051_F700] = "hp-700", | 1992 | [CXT5051_F700] = "hp-700", |
1929 | [CXT5051_TOSHIBA] = "toshiba", | 1993 | [CXT5051_TOSHIBA] = "toshiba", |
1994 | [CXT5051_IDEAPAD] = "ideapad", | ||
1930 | }; | 1995 | }; |
1931 | 1996 | ||
1932 | static struct snd_pci_quirk cxt5051_cfg_tbl[] = { | 1997 | static struct snd_pci_quirk cxt5051_cfg_tbl[] = { |
@@ -1938,6 +2003,7 @@ static struct snd_pci_quirk cxt5051_cfg_tbl[] = { | |||
1938 | CXT5051_LAPTOP), | 2003 | CXT5051_LAPTOP), |
1939 | SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), | 2004 | SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), |
1940 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), | 2005 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), |
2006 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD), | ||
1941 | {} | 2007 | {} |
1942 | }; | 2008 | }; |
1943 | 2009 | ||
@@ -1972,6 +2038,8 @@ static int patch_cxt5051(struct hda_codec *codec) | |||
1972 | spec->cur_adc = 0; | 2038 | spec->cur_adc = 0; |
1973 | spec->cur_adc_idx = 0; | 2039 | spec->cur_adc_idx = 0; |
1974 | 2040 | ||
2041 | set_beep_amp(spec, 0x13, 0, HDA_OUTPUT); | ||
2042 | |||
1975 | codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; | 2043 | codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; |
1976 | 2044 | ||
1977 | board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, | 2045 | board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, |
@@ -1989,6 +2057,10 @@ static int patch_cxt5051(struct hda_codec *codec) | |||
1989 | break; | 2057 | break; |
1990 | case CXT5051_LENOVO_X200: | 2058 | case CXT5051_LENOVO_X200: |
1991 | spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; | 2059 | spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; |
2060 | /* Thinkpad X301 does not have S/PDIF wired and no ability | ||
2061 | to use a docking station. */ | ||
2062 | if (codec->subsystem_id == 0x17aa211f) | ||
2063 | spec->multiout.dig_out_nid = 0; | ||
1992 | break; | 2064 | break; |
1993 | case CXT5051_F700: | 2065 | case CXT5051_F700: |
1994 | spec->init_verbs[0] = cxt5051_f700_init_verbs; | 2066 | spec->init_verbs[0] = cxt5051_f700_init_verbs; |
@@ -1999,8 +2071,16 @@ static int patch_cxt5051(struct hda_codec *codec) | |||
1999 | spec->mixers[0] = cxt5051_toshiba_mixers; | 2071 | spec->mixers[0] = cxt5051_toshiba_mixers; |
2000 | spec->auto_mic = AUTO_MIC_PORTB; | 2072 | spec->auto_mic = AUTO_MIC_PORTB; |
2001 | break; | 2073 | break; |
2074 | case CXT5051_IDEAPAD: | ||
2075 | spec->init_verbs[spec->num_init_verbs++] = | ||
2076 | cxt5051_ideapad_init_verbs; | ||
2077 | spec->ideapad = 1; | ||
2078 | break; | ||
2002 | } | 2079 | } |
2003 | 2080 | ||
2081 | if (spec->beep_amp) | ||
2082 | snd_hda_attach_beep_device(codec, spec->beep_amp); | ||
2083 | |||
2004 | return 0; | 2084 | return 0; |
2005 | } | 2085 | } |
2006 | 2086 | ||
@@ -2616,7 +2696,6 @@ static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { | |||
2616 | .put = cxt5066_mic_boost_mux_enum_put, | 2696 | .put = cxt5066_mic_boost_mux_enum_put, |
2617 | .private_value = 0x23 | 0x100, | 2697 | .private_value = 0x23 | 0x100, |
2618 | }, | 2698 | }, |
2619 | HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), | ||
2620 | {} | 2699 | {} |
2621 | }; | 2700 | }; |
2622 | 2701 | ||
@@ -2977,8 +3056,10 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
2977 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), | 3056 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), |
2978 | SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), | 3057 | SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), |
2979 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), | 3058 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), |
3059 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), | ||
3060 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD), | ||
3061 | SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G series (AMD)", CXT5066_IDEAPAD), | ||
2980 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), | 3062 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), |
2981 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), | ||
2982 | {} | 3063 | {} |
2983 | }; | 3064 | }; |
2984 | 3065 | ||
@@ -3014,6 +3095,8 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
3014 | spec->cur_adc = 0; | 3095 | spec->cur_adc = 0; |
3015 | spec->cur_adc_idx = 0; | 3096 | spec->cur_adc_idx = 0; |
3016 | 3097 | ||
3098 | set_beep_amp(spec, 0x13, 0, HDA_OUTPUT); | ||
3099 | |||
3017 | board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, | 3100 | board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, |
3018 | cxt5066_models, cxt5066_cfg_tbl); | 3101 | cxt5066_models, cxt5066_cfg_tbl); |
3019 | switch (board_config) { | 3102 | switch (board_config) { |
@@ -3062,7 +3145,6 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
3062 | spec->port_d_mode = 0; | 3145 | spec->port_d_mode = 0; |
3063 | spec->dell_vostro = 1; | 3146 | spec->dell_vostro = 1; |
3064 | spec->mic_boost = 3; /* default 30dB gain */ | 3147 | spec->mic_boost = 3; /* default 30dB gain */ |
3065 | snd_hda_attach_beep_device(codec, 0x13); | ||
3066 | 3148 | ||
3067 | /* no S/PDIF out */ | 3149 | /* no S/PDIF out */ |
3068 | spec->multiout.dig_out_nid = 0; | 3150 | spec->multiout.dig_out_nid = 0; |
@@ -3104,6 +3186,9 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
3104 | break; | 3186 | break; |
3105 | } | 3187 | } |
3106 | 3188 | ||
3189 | if (spec->beep_amp) | ||
3190 | snd_hda_attach_beep_device(codec, spec->beep_amp); | ||
3191 | |||
3107 | return 0; | 3192 | return 0; |
3108 | } | 3193 | } |
3109 | 3194 | ||
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 2fc53961054e..522e0748ee99 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -698,11 +698,51 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res) | |||
698 | * Callbacks | 698 | * Callbacks |
699 | */ | 699 | */ |
700 | 700 | ||
701 | static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, | 701 | /* HBR should be Non-PCM, 8 channels */ |
702 | #define is_hbr_format(format) \ | ||
703 | ((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7) | ||
704 | |||
705 | static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, | ||
702 | u32 stream_tag, int format) | 706 | u32 stream_tag, int format) |
703 | { | 707 | { |
708 | struct hdmi_spec *spec = codec->spec; | ||
704 | int tag; | 709 | int tag; |
705 | int fmt; | 710 | int fmt; |
711 | int pinctl; | ||
712 | int new_pinctl = 0; | ||
713 | int i; | ||
714 | |||
715 | for (i = 0; i < spec->num_pins; i++) { | ||
716 | if (spec->pin_cvt[i] != nid) | ||
717 | continue; | ||
718 | if (!(snd_hda_query_pin_caps(codec, spec->pin[i]) & AC_PINCAP_HBR)) | ||
719 | continue; | ||
720 | |||
721 | pinctl = snd_hda_codec_read(codec, spec->pin[i], 0, | ||
722 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
723 | |||
724 | new_pinctl = pinctl & ~AC_PINCTL_EPT; | ||
725 | if (is_hbr_format(format)) | ||
726 | new_pinctl |= AC_PINCTL_EPT_HBR; | ||
727 | else | ||
728 | new_pinctl |= AC_PINCTL_EPT_NATIVE; | ||
729 | |||
730 | snd_printdd("hdmi_setup_stream: " | ||
731 | "NID=0x%x, %spinctl=0x%x\n", | ||
732 | spec->pin[i], | ||
733 | pinctl == new_pinctl ? "" : "new-", | ||
734 | new_pinctl); | ||
735 | |||
736 | if (pinctl != new_pinctl) | ||
737 | snd_hda_codec_write(codec, spec->pin[i], 0, | ||
738 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
739 | new_pinctl); | ||
740 | } | ||
741 | |||
742 | if (is_hbr_format(format) && !new_pinctl) { | ||
743 | snd_printdd("hdmi_setup_stream: HBR is not supported\n"); | ||
744 | return -EINVAL; | ||
745 | } | ||
706 | 746 | ||
707 | tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4; | 747 | tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4; |
708 | fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0); | 748 | fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0); |
@@ -722,6 +762,7 @@ static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
722 | if (fmt != format) | 762 | if (fmt != format) |
723 | snd_hda_codec_write(codec, nid, 0, | 763 | snd_hda_codec_write(codec, nid, 0, |
724 | AC_VERB_SET_STREAM_FORMAT, format); | 764 | AC_VERB_SET_STREAM_FORMAT, format); |
765 | return 0; | ||
725 | } | 766 | } |
726 | 767 | ||
727 | /* | 768 | /* |
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c index b81d23e42ace..5972d5e7d01f 100644 --- a/sound/pci/hda/patch_intelhdmi.c +++ b/sound/pci/hda/patch_intelhdmi.c | |||
@@ -66,8 +66,7 @@ static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
66 | 66 | ||
67 | hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); | 67 | hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); |
68 | 68 | ||
69 | hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); | 69 | return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); |
70 | return 0; | ||
71 | } | 70 | } |
72 | 71 | ||
73 | static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 72 | static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index b0652acee9b2..a281836fd472 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c | |||
@@ -202,8 +202,7 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch_89(struct hda_pcm_stream *hinfo, | |||
202 | 202 | ||
203 | hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); | 203 | hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); |
204 | 204 | ||
205 | hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); | 205 | return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); |
206 | return 0; | ||
207 | } | 206 | } |
208 | 207 | ||
209 | static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, | 208 | static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 596ea2f12cf6..6ac53f7de549 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -256,6 +256,13 @@ enum { | |||
256 | ALC882_MODEL_LAST, | 256 | ALC882_MODEL_LAST, |
257 | }; | 257 | }; |
258 | 258 | ||
259 | /* ALC680 models */ | ||
260 | enum { | ||
261 | ALC680_BASE, | ||
262 | ALC680_AUTO, | ||
263 | ALC680_MODEL_LAST, | ||
264 | }; | ||
265 | |||
259 | /* for GPIO Poll */ | 266 | /* for GPIO Poll */ |
260 | #define GPIO_MASK 0x03 | 267 | #define GPIO_MASK 0x03 |
261 | 268 | ||
@@ -326,6 +333,12 @@ struct alc_spec { | |||
326 | hda_nid_t *capsrc_nids; | 333 | hda_nid_t *capsrc_nids; |
327 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ | 334 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ |
328 | 335 | ||
336 | /* capture setup for dynamic dual-adc switch */ | ||
337 | unsigned int cur_adc_idx; | ||
338 | hda_nid_t cur_adc; | ||
339 | unsigned int cur_adc_stream_tag; | ||
340 | unsigned int cur_adc_format; | ||
341 | |||
329 | /* capture source */ | 342 | /* capture source */ |
330 | unsigned int num_mux_defs; | 343 | unsigned int num_mux_defs; |
331 | const struct hda_input_mux *input_mux; | 344 | const struct hda_input_mux *input_mux; |
@@ -367,6 +380,7 @@ struct alc_spec { | |||
367 | 380 | ||
368 | /* other flags */ | 381 | /* other flags */ |
369 | unsigned int no_analog :1; /* digital I/O only */ | 382 | unsigned int no_analog :1; /* digital I/O only */ |
383 | unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ | ||
370 | int init_amp; | 384 | int init_amp; |
371 | 385 | ||
372 | /* for virtual master */ | 386 | /* for virtual master */ |
@@ -833,9 +847,13 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, | |||
833 | 847 | ||
834 | if (auto_pin_type <= AUTO_PIN_FRONT_MIC) { | 848 | if (auto_pin_type <= AUTO_PIN_FRONT_MIC) { |
835 | unsigned int pincap; | 849 | unsigned int pincap; |
850 | unsigned int oldval; | ||
851 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
852 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
836 | pincap = snd_hda_query_pin_caps(codec, nid); | 853 | pincap = snd_hda_query_pin_caps(codec, nid); |
837 | pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; | 854 | pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; |
838 | if (pincap & AC_PINCAP_VREF_80) | 855 | /* if the default pin setup is vref50, we give it priority */ |
856 | if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50) | ||
839 | val = PIN_VREF80; | 857 | val = PIN_VREF80; |
840 | else if (pincap & AC_PINCAP_VREF_50) | 858 | else if (pincap & AC_PINCAP_VREF_50) |
841 | val = PIN_VREF50; | 859 | val = PIN_VREF50; |
@@ -1003,6 +1021,29 @@ static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, | |||
1003 | return -1; | 1021 | return -1; |
1004 | } | 1022 | } |
1005 | 1023 | ||
1024 | /* switch the current ADC according to the jack state */ | ||
1025 | static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec) | ||
1026 | { | ||
1027 | struct alc_spec *spec = codec->spec; | ||
1028 | unsigned int present; | ||
1029 | hda_nid_t new_adc; | ||
1030 | |||
1031 | present = snd_hda_jack_detect(codec, spec->ext_mic.pin); | ||
1032 | if (present) | ||
1033 | spec->cur_adc_idx = 1; | ||
1034 | else | ||
1035 | spec->cur_adc_idx = 0; | ||
1036 | new_adc = spec->adc_nids[spec->cur_adc_idx]; | ||
1037 | if (spec->cur_adc && spec->cur_adc != new_adc) { | ||
1038 | /* stream is running, let's swap the current ADC */ | ||
1039 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); | ||
1040 | spec->cur_adc = new_adc; | ||
1041 | snd_hda_codec_setup_stream(codec, new_adc, | ||
1042 | spec->cur_adc_stream_tag, 0, | ||
1043 | spec->cur_adc_format); | ||
1044 | } | ||
1045 | } | ||
1046 | |||
1006 | static void alc_mic_automute(struct hda_codec *codec) | 1047 | static void alc_mic_automute(struct hda_codec *codec) |
1007 | { | 1048 | { |
1008 | struct alc_spec *spec = codec->spec; | 1049 | struct alc_spec *spec = codec->spec; |
@@ -1017,6 +1058,11 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
1017 | if (snd_BUG_ON(!spec->adc_nids)) | 1058 | if (snd_BUG_ON(!spec->adc_nids)) |
1018 | return; | 1059 | return; |
1019 | 1060 | ||
1061 | if (spec->dual_adc_switch) { | ||
1062 | alc_dual_mic_adc_auto_switch(codec); | ||
1063 | return; | ||
1064 | } | ||
1065 | |||
1020 | cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; | 1066 | cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; |
1021 | 1067 | ||
1022 | present = snd_hda_jack_detect(codec, spec->ext_mic.pin); | 1068 | present = snd_hda_jack_detect(codec, spec->ext_mic.pin); |
@@ -1499,6 +1545,63 @@ static int alc_read_coef_idx(struct hda_codec *codec, | |||
1499 | return val; | 1545 | return val; |
1500 | } | 1546 | } |
1501 | 1547 | ||
1548 | /* set right pin controls for digital I/O */ | ||
1549 | static void alc_auto_init_digital(struct hda_codec *codec) | ||
1550 | { | ||
1551 | struct alc_spec *spec = codec->spec; | ||
1552 | int i; | ||
1553 | hda_nid_t pin; | ||
1554 | |||
1555 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
1556 | pin = spec->autocfg.dig_out_pins[i]; | ||
1557 | if (pin) { | ||
1558 | snd_hda_codec_write(codec, pin, 0, | ||
1559 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1560 | PIN_OUT); | ||
1561 | } | ||
1562 | } | ||
1563 | pin = spec->autocfg.dig_in_pin; | ||
1564 | if (pin) | ||
1565 | snd_hda_codec_write(codec, pin, 0, | ||
1566 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1567 | PIN_IN); | ||
1568 | } | ||
1569 | |||
1570 | /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */ | ||
1571 | static void alc_auto_parse_digital(struct hda_codec *codec) | ||
1572 | { | ||
1573 | struct alc_spec *spec = codec->spec; | ||
1574 | int i, err; | ||
1575 | hda_nid_t dig_nid; | ||
1576 | |||
1577 | /* support multiple SPDIFs; the secondary is set up as a slave */ | ||
1578 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
1579 | err = snd_hda_get_connections(codec, | ||
1580 | spec->autocfg.dig_out_pins[i], | ||
1581 | &dig_nid, 1); | ||
1582 | if (err < 0) | ||
1583 | continue; | ||
1584 | if (!i) { | ||
1585 | spec->multiout.dig_out_nid = dig_nid; | ||
1586 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | ||
1587 | } else { | ||
1588 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | ||
1589 | if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) | ||
1590 | break; | ||
1591 | spec->slave_dig_outs[i - 1] = dig_nid; | ||
1592 | } | ||
1593 | } | ||
1594 | |||
1595 | if (spec->autocfg.dig_in_pin) { | ||
1596 | hda_nid_t dig_nid; | ||
1597 | err = snd_hda_get_connections(codec, | ||
1598 | spec->autocfg.dig_in_pin, | ||
1599 | &dig_nid, 1); | ||
1600 | if (err > 0) | ||
1601 | spec->dig_in_nid = dig_nid; | ||
1602 | } | ||
1603 | } | ||
1604 | |||
1502 | /* | 1605 | /* |
1503 | * ALC888 | 1606 | * ALC888 |
1504 | */ | 1607 | */ |
@@ -3607,6 +3710,41 @@ static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
3607 | return 0; | 3710 | return 0; |
3608 | } | 3711 | } |
3609 | 3712 | ||
3713 | /* analog capture with dynamic dual-adc changes */ | ||
3714 | static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
3715 | struct hda_codec *codec, | ||
3716 | unsigned int stream_tag, | ||
3717 | unsigned int format, | ||
3718 | struct snd_pcm_substream *substream) | ||
3719 | { | ||
3720 | struct alc_spec *spec = codec->spec; | ||
3721 | spec->cur_adc = spec->adc_nids[spec->cur_adc_idx]; | ||
3722 | spec->cur_adc_stream_tag = stream_tag; | ||
3723 | spec->cur_adc_format = format; | ||
3724 | snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); | ||
3725 | return 0; | ||
3726 | } | ||
3727 | |||
3728 | static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
3729 | struct hda_codec *codec, | ||
3730 | struct snd_pcm_substream *substream) | ||
3731 | { | ||
3732 | struct alc_spec *spec = codec->spec; | ||
3733 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); | ||
3734 | spec->cur_adc = 0; | ||
3735 | return 0; | ||
3736 | } | ||
3737 | |||
3738 | static struct hda_pcm_stream dualmic_pcm_analog_capture = { | ||
3739 | .substreams = 1, | ||
3740 | .channels_min = 2, | ||
3741 | .channels_max = 2, | ||
3742 | .nid = 0, /* fill later */ | ||
3743 | .ops = { | ||
3744 | .prepare = dualmic_capture_pcm_prepare, | ||
3745 | .cleanup = dualmic_capture_pcm_cleanup | ||
3746 | }, | ||
3747 | }; | ||
3610 | 3748 | ||
3611 | /* | 3749 | /* |
3612 | */ | 3750 | */ |
@@ -4936,7 +5074,7 @@ static void alc880_auto_init_input_src(struct hda_codec *codec) | |||
4936 | static int alc880_parse_auto_config(struct hda_codec *codec) | 5074 | static int alc880_parse_auto_config(struct hda_codec *codec) |
4937 | { | 5075 | { |
4938 | struct alc_spec *spec = codec->spec; | 5076 | struct alc_spec *spec = codec->spec; |
4939 | int i, err; | 5077 | int err; |
4940 | static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; | 5078 | static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; |
4941 | 5079 | ||
4942 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 5080 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
@@ -4967,25 +5105,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
4967 | 5105 | ||
4968 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 5106 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
4969 | 5107 | ||
4970 | /* check multiple SPDIF-out (for recent codecs) */ | 5108 | alc_auto_parse_digital(codec); |
4971 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
4972 | hda_nid_t dig_nid; | ||
4973 | err = snd_hda_get_connections(codec, | ||
4974 | spec->autocfg.dig_out_pins[i], | ||
4975 | &dig_nid, 1); | ||
4976 | if (err < 0) | ||
4977 | continue; | ||
4978 | if (!i) | ||
4979 | spec->multiout.dig_out_nid = dig_nid; | ||
4980 | else { | ||
4981 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | ||
4982 | if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) | ||
4983 | break; | ||
4984 | spec->slave_dig_outs[i - 1] = dig_nid; | ||
4985 | } | ||
4986 | } | ||
4987 | if (spec->autocfg.dig_in_pin) | ||
4988 | spec->dig_in_nid = ALC880_DIGIN_NID; | ||
4989 | 5109 | ||
4990 | if (spec->kctls.list) | 5110 | if (spec->kctls.list) |
4991 | add_mixer(spec, spec->kctls.list); | 5111 | add_mixer(spec, spec->kctls.list); |
@@ -5008,6 +5128,7 @@ static void alc880_auto_init(struct hda_codec *codec) | |||
5008 | alc880_auto_init_extra_out(codec); | 5128 | alc880_auto_init_extra_out(codec); |
5009 | alc880_auto_init_analog_input(codec); | 5129 | alc880_auto_init_analog_input(codec); |
5010 | alc880_auto_init_input_src(codec); | 5130 | alc880_auto_init_input_src(codec); |
5131 | alc_auto_init_digital(codec); | ||
5011 | if (spec->unsol_event) | 5132 | if (spec->unsol_event) |
5012 | alc_inithook(codec); | 5133 | alc_inithook(codec); |
5013 | } | 5134 | } |
@@ -5045,6 +5166,39 @@ static void fixup_automic_adc(struct hda_codec *codec) | |||
5045 | spec->auto_mic = 0; /* disable auto-mic to be sure */ | 5166 | spec->auto_mic = 0; /* disable auto-mic to be sure */ |
5046 | } | 5167 | } |
5047 | 5168 | ||
5169 | /* select or unmute the given capsrc route */ | ||
5170 | static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap, | ||
5171 | int idx) | ||
5172 | { | ||
5173 | if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { | ||
5174 | snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, | ||
5175 | HDA_AMP_MUTE, 0); | ||
5176 | } else { | ||
5177 | snd_hda_codec_write_cache(codec, cap, 0, | ||
5178 | AC_VERB_SET_CONNECT_SEL, idx); | ||
5179 | } | ||
5180 | } | ||
5181 | |||
5182 | /* set the default connection to that pin */ | ||
5183 | static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) | ||
5184 | { | ||
5185 | struct alc_spec *spec = codec->spec; | ||
5186 | int i; | ||
5187 | |||
5188 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
5189 | hda_nid_t cap = spec->capsrc_nids ? | ||
5190 | spec->capsrc_nids[i] : spec->adc_nids[i]; | ||
5191 | int idx; | ||
5192 | |||
5193 | idx = get_connection_index(codec, cap, pin); | ||
5194 | if (idx < 0) | ||
5195 | continue; | ||
5196 | select_or_unmute_capsrc(codec, cap, idx); | ||
5197 | return i; /* return the found index */ | ||
5198 | } | ||
5199 | return -1; /* not found */ | ||
5200 | } | ||
5201 | |||
5048 | /* choose the ADC/MUX containing the input pin and initialize the setup */ | 5202 | /* choose the ADC/MUX containing the input pin and initialize the setup */ |
5049 | static void fixup_single_adc(struct hda_codec *codec) | 5203 | static void fixup_single_adc(struct hda_codec *codec) |
5050 | { | 5204 | { |
@@ -5061,33 +5215,24 @@ static void fixup_single_adc(struct hda_codec *codec) | |||
5061 | } | 5215 | } |
5062 | if (!pin) | 5216 | if (!pin) |
5063 | return; | 5217 | return; |
5064 | 5218 | i = init_capsrc_for_pin(codec, pin); | |
5065 | /* set the default connection to that pin */ | 5219 | if (i >= 0) { |
5066 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
5067 | hda_nid_t cap = spec->capsrc_nids ? | ||
5068 | spec->capsrc_nids[i] : spec->adc_nids[i]; | ||
5069 | int idx; | ||
5070 | |||
5071 | idx = get_connection_index(codec, cap, pin); | ||
5072 | if (idx < 0) | ||
5073 | continue; | ||
5074 | /* use only this ADC */ | 5220 | /* use only this ADC */ |
5075 | if (spec->capsrc_nids) | 5221 | if (spec->capsrc_nids) |
5076 | spec->capsrc_nids += i; | 5222 | spec->capsrc_nids += i; |
5077 | spec->adc_nids += i; | 5223 | spec->adc_nids += i; |
5078 | spec->num_adc_nids = 1; | 5224 | spec->num_adc_nids = 1; |
5079 | /* select or unmute this route */ | ||
5080 | if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { | ||
5081 | snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, | ||
5082 | HDA_AMP_MUTE, 0); | ||
5083 | } else { | ||
5084 | snd_hda_codec_write_cache(codec, cap, 0, | ||
5085 | AC_VERB_SET_CONNECT_SEL, idx); | ||
5086 | } | ||
5087 | return; | ||
5088 | } | 5225 | } |
5089 | } | 5226 | } |
5090 | 5227 | ||
5228 | /* initialize dual adcs */ | ||
5229 | static void fixup_dual_adc_switch(struct hda_codec *codec) | ||
5230 | { | ||
5231 | struct alc_spec *spec = codec->spec; | ||
5232 | init_capsrc_for_pin(codec, spec->ext_mic.pin); | ||
5233 | init_capsrc_for_pin(codec, spec->int_mic.pin); | ||
5234 | } | ||
5235 | |||
5091 | static void set_capture_mixer(struct hda_codec *codec) | 5236 | static void set_capture_mixer(struct hda_codec *codec) |
5092 | { | 5237 | { |
5093 | struct alc_spec *spec = codec->spec; | 5238 | struct alc_spec *spec = codec->spec; |
@@ -5101,7 +5246,10 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
5101 | }; | 5246 | }; |
5102 | if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { | 5247 | if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { |
5103 | int mux = 0; | 5248 | int mux = 0; |
5104 | if (spec->auto_mic) | 5249 | int num_adcs = spec->num_adc_nids; |
5250 | if (spec->dual_adc_switch) | ||
5251 | fixup_dual_adc_switch(codec); | ||
5252 | else if (spec->auto_mic) | ||
5105 | fixup_automic_adc(codec); | 5253 | fixup_automic_adc(codec); |
5106 | else if (spec->input_mux) { | 5254 | else if (spec->input_mux) { |
5107 | if (spec->input_mux->num_items > 1) | 5255 | if (spec->input_mux->num_items > 1) |
@@ -5109,7 +5257,9 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
5109 | else if (spec->input_mux->num_items == 1) | 5257 | else if (spec->input_mux->num_items == 1) |
5110 | fixup_single_adc(codec); | 5258 | fixup_single_adc(codec); |
5111 | } | 5259 | } |
5112 | spec->cap_mixer = caps[mux][spec->num_adc_nids - 1]; | 5260 | if (spec->dual_adc_switch) |
5261 | num_adcs = 1; | ||
5262 | spec->cap_mixer = caps[mux][num_adcs - 1]; | ||
5113 | } | 5263 | } |
5114 | } | 5264 | } |
5115 | 5265 | ||
@@ -5183,6 +5333,7 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | |||
5183 | 5333 | ||
5184 | static struct snd_pci_quirk beep_white_list[] = { | 5334 | static struct snd_pci_quirk beep_white_list[] = { |
5185 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), | 5335 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), |
5336 | SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), | ||
5186 | {} | 5337 | {} |
5187 | }; | 5338 | }; |
5188 | 5339 | ||
@@ -6624,6 +6775,7 @@ static void alc260_auto_init(struct hda_codec *codec) | |||
6624 | alc260_auto_init_multi_out(codec); | 6775 | alc260_auto_init_multi_out(codec); |
6625 | alc260_auto_init_analog_input(codec); | 6776 | alc260_auto_init_analog_input(codec); |
6626 | alc260_auto_init_input_src(codec); | 6777 | alc260_auto_init_input_src(codec); |
6778 | alc_auto_init_digital(codec); | ||
6627 | if (spec->unsol_event) | 6779 | if (spec->unsol_event) |
6628 | alc_inithook(codec); | 6780 | alc_inithook(codec); |
6629 | } | 6781 | } |
@@ -6640,6 +6792,29 @@ static struct hda_amp_list alc260_loopbacks[] = { | |||
6640 | #endif | 6792 | #endif |
6641 | 6793 | ||
6642 | /* | 6794 | /* |
6795 | * Pin config fixes | ||
6796 | */ | ||
6797 | enum { | ||
6798 | PINFIX_HP_DC5750, | ||
6799 | }; | ||
6800 | |||
6801 | static struct alc_pincfg alc260_hp_dc5750_pinfix[] = { | ||
6802 | { 0x11, 0x90130110 }, /* speaker */ | ||
6803 | { } | ||
6804 | }; | ||
6805 | |||
6806 | static const struct alc_fixup alc260_fixups[] = { | ||
6807 | [PINFIX_HP_DC5750] = { | ||
6808 | .pins = alc260_hp_dc5750_pinfix | ||
6809 | }, | ||
6810 | }; | ||
6811 | |||
6812 | static struct snd_pci_quirk alc260_fixup_tbl[] = { | ||
6813 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), | ||
6814 | {} | ||
6815 | }; | ||
6816 | |||
6817 | /* | ||
6643 | * ALC260 configurations | 6818 | * ALC260 configurations |
6644 | */ | 6819 | */ |
6645 | static const char *alc260_models[ALC260_MODEL_LAST] = { | 6820 | static const char *alc260_models[ALC260_MODEL_LAST] = { |
@@ -6838,6 +7013,9 @@ static int patch_alc260(struct hda_codec *codec) | |||
6838 | board_config = ALC260_AUTO; | 7013 | board_config = ALC260_AUTO; |
6839 | } | 7014 | } |
6840 | 7015 | ||
7016 | if (board_config == ALC260_AUTO) | ||
7017 | alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1); | ||
7018 | |||
6841 | if (board_config == ALC260_AUTO) { | 7019 | if (board_config == ALC260_AUTO) { |
6842 | /* automatic parse from the BIOS config */ | 7020 | /* automatic parse from the BIOS config */ |
6843 | err = alc260_parse_auto_config(codec); | 7021 | err = alc260_parse_auto_config(codec); |
@@ -6883,6 +7061,9 @@ static int patch_alc260(struct hda_codec *codec) | |||
6883 | set_capture_mixer(codec); | 7061 | set_capture_mixer(codec); |
6884 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); | 7062 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); |
6885 | 7063 | ||
7064 | if (board_config == ALC260_AUTO) | ||
7065 | alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0); | ||
7066 | |||
6886 | spec->vmaster_nid = 0x08; | 7067 | spec->vmaster_nid = 0x08; |
6887 | 7068 | ||
6888 | codec->patch_ops = alc_patch_ops; | 7069 | codec->patch_ops = alc_patch_ops; |
@@ -7003,7 +7184,7 @@ static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { | |||
7003 | .num_items = 4, | 7184 | .num_items = 4, |
7004 | .items = { | 7185 | .items = { |
7005 | { "Mic", 0x0 }, | 7186 | { "Mic", 0x0 }, |
7006 | { "iMic", 0x1 }, | 7187 | { "Int Mic", 0x1 }, |
7007 | { "Line", 0x2 }, | 7188 | { "Line", 0x2 }, |
7008 | { "CD", 0x4 }, | 7189 | { "CD", 0x4 }, |
7009 | }, | 7190 | }, |
@@ -8573,8 +8754,8 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { | |||
8573 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 8754 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
8574 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 8755 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
8575 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 8756 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
8576 | HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 8757 | HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
8577 | HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 8758 | HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
8578 | { } /* end */ | 8759 | { } /* end */ |
8579 | }; | 8760 | }; |
8580 | 8761 | ||
@@ -10265,7 +10446,8 @@ static struct alc_config_preset alc882_presets[] = { | |||
10265 | * Pin config fixes | 10446 | * Pin config fixes |
10266 | */ | 10447 | */ |
10267 | enum { | 10448 | enum { |
10268 | PINFIX_ABIT_AW9D_MAX | 10449 | PINFIX_ABIT_AW9D_MAX, |
10450 | PINFIX_PB_M5210, | ||
10269 | }; | 10451 | }; |
10270 | 10452 | ||
10271 | static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { | 10453 | static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { |
@@ -10275,13 +10457,22 @@ static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { | |||
10275 | { } | 10457 | { } |
10276 | }; | 10458 | }; |
10277 | 10459 | ||
10460 | static const struct hda_verb pb_m5210_verbs[] = { | ||
10461 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, | ||
10462 | {} | ||
10463 | }; | ||
10464 | |||
10278 | static const struct alc_fixup alc882_fixups[] = { | 10465 | static const struct alc_fixup alc882_fixups[] = { |
10279 | [PINFIX_ABIT_AW9D_MAX] = { | 10466 | [PINFIX_ABIT_AW9D_MAX] = { |
10280 | .pins = alc882_abit_aw9d_pinfix | 10467 | .pins = alc882_abit_aw9d_pinfix |
10281 | }, | 10468 | }, |
10469 | [PINFIX_PB_M5210] = { | ||
10470 | .verbs = pb_m5210_verbs | ||
10471 | }, | ||
10282 | }; | 10472 | }; |
10283 | 10473 | ||
10284 | static struct snd_pci_quirk alc882_fixup_tbl[] = { | 10474 | static struct snd_pci_quirk alc882_fixup_tbl[] = { |
10475 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), | ||
10285 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), | 10476 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), |
10286 | {} | 10477 | {} |
10287 | }; | 10478 | }; |
@@ -10446,7 +10637,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
10446 | { | 10637 | { |
10447 | struct alc_spec *spec = codec->spec; | 10638 | struct alc_spec *spec = codec->spec; |
10448 | static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; | 10639 | static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; |
10449 | int i, err; | 10640 | int err; |
10450 | 10641 | ||
10451 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 10642 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
10452 | alc882_ignore); | 10643 | alc882_ignore); |
@@ -10476,25 +10667,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
10476 | 10667 | ||
10477 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 10668 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
10478 | 10669 | ||
10479 | /* check multiple SPDIF-out (for recent codecs) */ | 10670 | alc_auto_parse_digital(codec); |
10480 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
10481 | hda_nid_t dig_nid; | ||
10482 | err = snd_hda_get_connections(codec, | ||
10483 | spec->autocfg.dig_out_pins[i], | ||
10484 | &dig_nid, 1); | ||
10485 | if (err < 0) | ||
10486 | continue; | ||
10487 | if (!i) | ||
10488 | spec->multiout.dig_out_nid = dig_nid; | ||
10489 | else { | ||
10490 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | ||
10491 | if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) | ||
10492 | break; | ||
10493 | spec->slave_dig_outs[i - 1] = dig_nid; | ||
10494 | } | ||
10495 | } | ||
10496 | if (spec->autocfg.dig_in_pin) | ||
10497 | spec->dig_in_nid = ALC880_DIGIN_NID; | ||
10498 | 10671 | ||
10499 | if (spec->kctls.list) | 10672 | if (spec->kctls.list) |
10500 | add_mixer(spec, spec->kctls.list); | 10673 | add_mixer(spec, spec->kctls.list); |
@@ -10524,6 +10697,7 @@ static void alc882_auto_init(struct hda_codec *codec) | |||
10524 | alc882_auto_init_hp_out(codec); | 10697 | alc882_auto_init_hp_out(codec); |
10525 | alc882_auto_init_analog_input(codec); | 10698 | alc882_auto_init_analog_input(codec); |
10526 | alc882_auto_init_input_src(codec); | 10699 | alc882_auto_init_input_src(codec); |
10700 | alc_auto_init_digital(codec); | ||
10527 | if (spec->unsol_event) | 10701 | if (spec->unsol_event) |
10528 | alc_inithook(codec); | 10702 | alc_inithook(codec); |
10529 | } | 10703 | } |
@@ -12054,12 +12228,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
12054 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 12228 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
12055 | 12229 | ||
12056 | dig_only: | 12230 | dig_only: |
12057 | if (spec->autocfg.dig_outs) { | 12231 | alc_auto_parse_digital(codec); |
12058 | spec->multiout.dig_out_nid = ALC262_DIGOUT_NID; | ||
12059 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | ||
12060 | } | ||
12061 | if (spec->autocfg.dig_in_pin) | ||
12062 | spec->dig_in_nid = ALC262_DIGIN_NID; | ||
12063 | 12232 | ||
12064 | if (spec->kctls.list) | 12233 | if (spec->kctls.list) |
12065 | add_mixer(spec, spec->kctls.list); | 12234 | add_mixer(spec, spec->kctls.list); |
@@ -12091,6 +12260,7 @@ static void alc262_auto_init(struct hda_codec *codec) | |||
12091 | alc262_auto_init_hp_out(codec); | 12260 | alc262_auto_init_hp_out(codec); |
12092 | alc262_auto_init_analog_input(codec); | 12261 | alc262_auto_init_analog_input(codec); |
12093 | alc262_auto_init_input_src(codec); | 12262 | alc262_auto_init_input_src(codec); |
12263 | alc_auto_init_digital(codec); | ||
12094 | if (spec->unsol_event) | 12264 | if (spec->unsol_event) |
12095 | alc_inithook(codec); | 12265 | alc_inithook(codec); |
12096 | } | 12266 | } |
@@ -13024,10 +13194,14 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | |||
13024 | dac = 0x02; | 13194 | dac = 0x02; |
13025 | break; | 13195 | break; |
13026 | case 0x15: | 13196 | case 0x15: |
13197 | case 0x1a: /* ALC259/269 only */ | ||
13198 | case 0x1b: /* ALC259/269 only */ | ||
13027 | case 0x21: /* ALC269vb has this pin, too */ | 13199 | case 0x21: /* ALC269vb has this pin, too */ |
13028 | dac = 0x03; | 13200 | dac = 0x03; |
13029 | break; | 13201 | break; |
13030 | default: | 13202 | default: |
13203 | snd_printd(KERN_WARNING "hda_codec: " | ||
13204 | "ignoring pin 0x%x as unknown\n", nid); | ||
13031 | return 0; | 13205 | return 0; |
13032 | } | 13206 | } |
13033 | if (spec->multiout.dac_nids[0] != dac && | 13207 | if (spec->multiout.dac_nids[0] != dac && |
@@ -13078,7 +13252,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
13078 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | 13252 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); |
13079 | if (err < 0) | 13253 | if (err < 0) |
13080 | return err; | 13254 | return err; |
13081 | } else { | 13255 | } else if (nid) { |
13082 | err = alc268_new_analog_output(spec, nid, "Speaker", 0); | 13256 | err = alc268_new_analog_output(spec, nid, "Speaker", 0); |
13083 | if (err < 0) | 13257 | if (err < 0) |
13084 | return err; | 13258 | return err; |
@@ -13227,10 +13401,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
13227 | 13401 | ||
13228 | dig_only: | 13402 | dig_only: |
13229 | /* digital only support output */ | 13403 | /* digital only support output */ |
13230 | if (spec->autocfg.dig_outs) { | 13404 | alc_auto_parse_digital(codec); |
13231 | spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; | ||
13232 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | ||
13233 | } | ||
13234 | if (spec->kctls.list) | 13405 | if (spec->kctls.list) |
13235 | add_mixer(spec, spec->kctls.list); | 13406 | add_mixer(spec, spec->kctls.list); |
13236 | 13407 | ||
@@ -13260,6 +13431,7 @@ static void alc268_auto_init(struct hda_codec *codec) | |||
13260 | alc268_auto_init_hp_out(codec); | 13431 | alc268_auto_init_hp_out(codec); |
13261 | alc268_auto_init_mono_speaker_out(codec); | 13432 | alc268_auto_init_mono_speaker_out(codec); |
13262 | alc268_auto_init_analog_input(codec); | 13433 | alc268_auto_init_analog_input(codec); |
13434 | alc_auto_init_digital(codec); | ||
13263 | if (spec->unsol_event) | 13435 | if (spec->unsol_event) |
13264 | alc_inithook(codec); | 13436 | alc_inithook(codec); |
13265 | } | 13437 | } |
@@ -14152,6 +14324,36 @@ static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid) | |||
14152 | } | 14324 | } |
14153 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ | 14325 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ |
14154 | 14326 | ||
14327 | static int alc275_setup_dual_adc(struct hda_codec *codec) | ||
14328 | { | ||
14329 | struct alc_spec *spec = codec->spec; | ||
14330 | |||
14331 | if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic) | ||
14332 | return 0; | ||
14333 | if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) || | ||
14334 | (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) { | ||
14335 | if (spec->ext_mic.pin <= 0x12) { | ||
14336 | spec->private_adc_nids[0] = 0x08; | ||
14337 | spec->private_adc_nids[1] = 0x11; | ||
14338 | spec->private_capsrc_nids[0] = 0x23; | ||
14339 | spec->private_capsrc_nids[1] = 0x22; | ||
14340 | } else { | ||
14341 | spec->private_adc_nids[0] = 0x11; | ||
14342 | spec->private_adc_nids[1] = 0x08; | ||
14343 | spec->private_capsrc_nids[0] = 0x22; | ||
14344 | spec->private_capsrc_nids[1] = 0x23; | ||
14345 | } | ||
14346 | spec->adc_nids = spec->private_adc_nids; | ||
14347 | spec->capsrc_nids = spec->private_capsrc_nids; | ||
14348 | spec->num_adc_nids = 2; | ||
14349 | spec->dual_adc_switch = 1; | ||
14350 | snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n", | ||
14351 | spec->adc_nids[0], spec->adc_nids[1]); | ||
14352 | return 1; | ||
14353 | } | ||
14354 | return 0; | ||
14355 | } | ||
14356 | |||
14155 | /* | 14357 | /* |
14156 | * BIOS auto configuration | 14358 | * BIOS auto configuration |
14157 | */ | 14359 | */ |
@@ -14175,8 +14377,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
14175 | 14377 | ||
14176 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 14378 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
14177 | 14379 | ||
14178 | if (spec->autocfg.dig_outs) | 14380 | alc_auto_parse_digital(codec); |
14179 | spec->multiout.dig_out_nid = ALC269_DIGOUT_NID; | ||
14180 | 14381 | ||
14181 | if (spec->kctls.list) | 14382 | if (spec->kctls.list) |
14182 | add_mixer(spec, spec->kctls.list); | 14383 | add_mixer(spec, spec->kctls.list); |
@@ -14191,13 +14392,15 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
14191 | 14392 | ||
14192 | spec->num_mux_defs = 1; | 14393 | spec->num_mux_defs = 1; |
14193 | spec->input_mux = &spec->private_imux[0]; | 14394 | spec->input_mux = &spec->private_imux[0]; |
14194 | fillup_priv_adc_nids(codec, alc269_adc_candidates, | 14395 | |
14195 | sizeof(alc269_adc_candidates)); | 14396 | if (!alc275_setup_dual_adc(codec)) |
14397 | fillup_priv_adc_nids(codec, alc269_adc_candidates, | ||
14398 | sizeof(alc269_adc_candidates)); | ||
14196 | 14399 | ||
14197 | /* set default input source */ | 14400 | /* set default input source */ |
14198 | snd_hda_codec_write_cache(codec, spec->capsrc_nids[0], | 14401 | if (!spec->dual_adc_switch) |
14199 | 0, AC_VERB_SET_CONNECT_SEL, | 14402 | select_or_unmute_capsrc(codec, spec->capsrc_nids[0], |
14200 | spec->input_mux->items[0].index); | 14403 | spec->input_mux->items[0].index); |
14201 | 14404 | ||
14202 | err = alc_auto_add_mic_boost(codec); | 14405 | err = alc_auto_add_mic_boost(codec); |
14203 | if (err < 0) | 14406 | if (err < 0) |
@@ -14221,6 +14424,7 @@ static void alc269_auto_init(struct hda_codec *codec) | |||
14221 | alc269_auto_init_multi_out(codec); | 14424 | alc269_auto_init_multi_out(codec); |
14222 | alc269_auto_init_hp_out(codec); | 14425 | alc269_auto_init_hp_out(codec); |
14223 | alc269_auto_init_analog_input(codec); | 14426 | alc269_auto_init_analog_input(codec); |
14427 | alc_auto_init_digital(codec); | ||
14224 | if (spec->unsol_event) | 14428 | if (spec->unsol_event) |
14225 | alc_inithook(codec); | 14429 | alc_inithook(codec); |
14226 | } | 14430 | } |
@@ -14493,6 +14697,10 @@ static int patch_alc269(struct hda_codec *codec) | |||
14493 | */ | 14697 | */ |
14494 | spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; | 14698 | spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; |
14495 | spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; | 14699 | spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; |
14700 | } else if (spec->dual_adc_switch) { | ||
14701 | spec->stream_analog_playback = &alc269_pcm_analog_playback; | ||
14702 | /* switch ADC dynamically */ | ||
14703 | spec->stream_analog_capture = &dualmic_pcm_analog_capture; | ||
14496 | } else { | 14704 | } else { |
14497 | spec->stream_analog_playback = &alc269_pcm_analog_playback; | 14705 | spec->stream_analog_playback = &alc269_pcm_analog_playback; |
14498 | spec->stream_analog_capture = &alc269_pcm_analog_capture; | 14706 | spec->stream_analog_capture = &alc269_pcm_analog_capture; |
@@ -15378,8 +15586,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
15378 | 15586 | ||
15379 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 15587 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
15380 | 15588 | ||
15381 | if (spec->autocfg.dig_outs) | 15589 | alc_auto_parse_digital(codec); |
15382 | spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; | ||
15383 | 15590 | ||
15384 | if (spec->kctls.list) | 15591 | if (spec->kctls.list) |
15385 | add_mixer(spec, spec->kctls.list); | 15592 | add_mixer(spec, spec->kctls.list); |
@@ -15405,6 +15612,7 @@ static void alc861_auto_init(struct hda_codec *codec) | |||
15405 | alc861_auto_init_multi_out(codec); | 15612 | alc861_auto_init_multi_out(codec); |
15406 | alc861_auto_init_hp_out(codec); | 15613 | alc861_auto_init_hp_out(codec); |
15407 | alc861_auto_init_analog_input(codec); | 15614 | alc861_auto_init_analog_input(codec); |
15615 | alc_auto_init_digital(codec); | ||
15408 | if (spec->unsol_event) | 15616 | if (spec->unsol_event) |
15409 | alc_inithook(codec); | 15617 | alc_inithook(codec); |
15410 | } | 15618 | } |
@@ -16509,8 +16717,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
16509 | 16717 | ||
16510 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 16718 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
16511 | 16719 | ||
16512 | if (spec->autocfg.dig_outs) | 16720 | alc_auto_parse_digital(codec); |
16513 | spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; | ||
16514 | 16721 | ||
16515 | if (spec->kctls.list) | 16722 | if (spec->kctls.list) |
16516 | add_mixer(spec, spec->kctls.list); | 16723 | add_mixer(spec, spec->kctls.list); |
@@ -16537,6 +16744,7 @@ static void alc861vd_auto_init(struct hda_codec *codec) | |||
16537 | alc861vd_auto_init_hp_out(codec); | 16744 | alc861vd_auto_init_hp_out(codec); |
16538 | alc861vd_auto_init_analog_input(codec); | 16745 | alc861vd_auto_init_analog_input(codec); |
16539 | alc861vd_auto_init_input_src(codec); | 16746 | alc861vd_auto_init_input_src(codec); |
16747 | alc_auto_init_digital(codec); | ||
16540 | if (spec->unsol_event) | 16748 | if (spec->unsol_event) |
16541 | alc_inithook(codec); | 16749 | alc_inithook(codec); |
16542 | } | 16750 | } |
@@ -18520,7 +18728,7 @@ static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, | |||
18520 | hda_nid_t dac) | 18728 | hda_nid_t dac) |
18521 | { | 18729 | { |
18522 | int i, num; | 18730 | int i, num; |
18523 | hda_nid_t srcs[4]; | 18731 | hda_nid_t srcs[HDA_MAX_CONNECTIONS]; |
18524 | 18732 | ||
18525 | alc_set_pin_output(codec, nid, pin_type); | 18733 | alc_set_pin_output(codec, nid, pin_type); |
18526 | /* need the manual connection? */ | 18734 | /* need the manual connection? */ |
@@ -18624,8 +18832,7 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
18624 | 18832 | ||
18625 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 18833 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
18626 | 18834 | ||
18627 | if (spec->autocfg.dig_outs) | 18835 | alc_auto_parse_digital(codec); |
18628 | spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; | ||
18629 | 18836 | ||
18630 | if (spec->kctls.list) | 18837 | if (spec->kctls.list) |
18631 | add_mixer(spec, spec->kctls.list); | 18838 | add_mixer(spec, spec->kctls.list); |
@@ -18635,7 +18842,7 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
18635 | 18842 | ||
18636 | add_verb(spec, alc662_init_verbs); | 18843 | add_verb(spec, alc662_init_verbs); |
18637 | if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || | 18844 | if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || |
18638 | codec->vendor_id == 0x10ec0665) | 18845 | codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) |
18639 | add_verb(spec, alc663_init_verbs); | 18846 | add_verb(spec, alc663_init_verbs); |
18640 | 18847 | ||
18641 | if (codec->vendor_id == 0x10ec0272) | 18848 | if (codec->vendor_id == 0x10ec0272) |
@@ -18662,6 +18869,7 @@ static void alc662_auto_init(struct hda_codec *codec) | |||
18662 | alc662_auto_init_hp_out(codec); | 18869 | alc662_auto_init_hp_out(codec); |
18663 | alc662_auto_init_analog_input(codec); | 18870 | alc662_auto_init_analog_input(codec); |
18664 | alc662_auto_init_input_src(codec); | 18871 | alc662_auto_init_input_src(codec); |
18872 | alc_auto_init_digital(codec); | ||
18665 | if (spec->unsol_event) | 18873 | if (spec->unsol_event) |
18666 | alc_inithook(codec); | 18874 | alc_inithook(codec); |
18667 | } | 18875 | } |
@@ -18781,6 +18989,333 @@ static int patch_alc888(struct hda_codec *codec) | |||
18781 | } | 18989 | } |
18782 | 18990 | ||
18783 | /* | 18991 | /* |
18992 | * ALC680 support | ||
18993 | */ | ||
18994 | #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID | ||
18995 | #define alc680_modes alc260_modes | ||
18996 | |||
18997 | static hda_nid_t alc680_dac_nids[3] = { | ||
18998 | /* Lout1, Lout2, hp */ | ||
18999 | 0x02, 0x03, 0x04 | ||
19000 | }; | ||
19001 | |||
19002 | static hda_nid_t alc680_adc_nids[3] = { | ||
19003 | /* ADC0-2 */ | ||
19004 | /* DMIC, MIC, Line-in*/ | ||
19005 | 0x07, 0x08, 0x09 | ||
19006 | }; | ||
19007 | |||
19008 | static struct snd_kcontrol_new alc680_base_mixer[] = { | ||
19009 | /* output mixer control */ | ||
19010 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | ||
19011 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
19012 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), | ||
19013 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), | ||
19014 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
19015 | { } | ||
19016 | }; | ||
19017 | |||
19018 | static struct snd_kcontrol_new alc680_capture_mixer[] = { | ||
19019 | HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), | ||
19020 | HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), | ||
19021 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), | ||
19022 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), | ||
19023 | HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), | ||
19024 | HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), | ||
19025 | { } /* end */ | ||
19026 | }; | ||
19027 | |||
19028 | /* | ||
19029 | * generic initialization of ADC, input mixers and output mixers | ||
19030 | */ | ||
19031 | static struct hda_verb alc680_init_verbs[] = { | ||
19032 | /* Unmute DAC0-1 and set vol = 0 */ | ||
19033 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
19034 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
19035 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
19036 | |||
19037 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
19038 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
19039 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | ||
19040 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
19041 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
19042 | |||
19043 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
19044 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
19045 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
19046 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
19047 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
19048 | { } | ||
19049 | }; | ||
19050 | |||
19051 | /* create input playback/capture controls for the given pin */ | ||
19052 | static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | ||
19053 | const char *ctlname, int idx) | ||
19054 | { | ||
19055 | hda_nid_t dac; | ||
19056 | int err; | ||
19057 | |||
19058 | switch (nid) { | ||
19059 | case 0x14: | ||
19060 | dac = 0x02; | ||
19061 | break; | ||
19062 | case 0x15: | ||
19063 | dac = 0x03; | ||
19064 | break; | ||
19065 | case 0x16: | ||
19066 | dac = 0x04; | ||
19067 | break; | ||
19068 | default: | ||
19069 | return 0; | ||
19070 | } | ||
19071 | if (spec->multiout.dac_nids[0] != dac && | ||
19072 | spec->multiout.dac_nids[1] != dac) { | ||
19073 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, | ||
19074 | HDA_COMPOSE_AMP_VAL(dac, 3, idx, | ||
19075 | HDA_OUTPUT)); | ||
19076 | if (err < 0) | ||
19077 | return err; | ||
19078 | |||
19079 | err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, | ||
19080 | HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); | ||
19081 | |||
19082 | if (err < 0) | ||
19083 | return err; | ||
19084 | spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; | ||
19085 | } | ||
19086 | |||
19087 | return 0; | ||
19088 | } | ||
19089 | |||
19090 | /* add playback controls from the parsed DAC table */ | ||
19091 | static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec, | ||
19092 | const struct auto_pin_cfg *cfg) | ||
19093 | { | ||
19094 | hda_nid_t nid; | ||
19095 | int err; | ||
19096 | |||
19097 | spec->multiout.dac_nids = spec->private_dac_nids; | ||
19098 | |||
19099 | nid = cfg->line_out_pins[0]; | ||
19100 | if (nid) { | ||
19101 | const char *name; | ||
19102 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
19103 | name = "Speaker"; | ||
19104 | else | ||
19105 | name = "Front"; | ||
19106 | err = alc680_new_analog_output(spec, nid, name, 0); | ||
19107 | if (err < 0) | ||
19108 | return err; | ||
19109 | } | ||
19110 | |||
19111 | nid = cfg->speaker_pins[0]; | ||
19112 | if (nid) { | ||
19113 | err = alc680_new_analog_output(spec, nid, "Speaker", 0); | ||
19114 | if (err < 0) | ||
19115 | return err; | ||
19116 | } | ||
19117 | nid = cfg->hp_pins[0]; | ||
19118 | if (nid) { | ||
19119 | err = alc680_new_analog_output(spec, nid, "Headphone", 0); | ||
19120 | if (err < 0) | ||
19121 | return err; | ||
19122 | } | ||
19123 | |||
19124 | return 0; | ||
19125 | } | ||
19126 | |||
19127 | static void alc680_auto_set_output_and_unmute(struct hda_codec *codec, | ||
19128 | hda_nid_t nid, int pin_type) | ||
19129 | { | ||
19130 | alc_set_pin_output(codec, nid, pin_type); | ||
19131 | } | ||
19132 | |||
19133 | static void alc680_auto_init_multi_out(struct hda_codec *codec) | ||
19134 | { | ||
19135 | struct alc_spec *spec = codec->spec; | ||
19136 | hda_nid_t nid = spec->autocfg.line_out_pins[0]; | ||
19137 | if (nid) { | ||
19138 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
19139 | alc680_auto_set_output_and_unmute(codec, nid, pin_type); | ||
19140 | } | ||
19141 | } | ||
19142 | |||
19143 | static void alc680_auto_init_hp_out(struct hda_codec *codec) | ||
19144 | { | ||
19145 | struct alc_spec *spec = codec->spec; | ||
19146 | hda_nid_t pin; | ||
19147 | |||
19148 | pin = spec->autocfg.hp_pins[0]; | ||
19149 | if (pin) | ||
19150 | alc680_auto_set_output_and_unmute(codec, pin, PIN_HP); | ||
19151 | pin = spec->autocfg.speaker_pins[0]; | ||
19152 | if (pin) | ||
19153 | alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT); | ||
19154 | } | ||
19155 | |||
19156 | /* pcm configuration: identical with ALC880 */ | ||
19157 | #define alc680_pcm_analog_playback alc880_pcm_analog_playback | ||
19158 | #define alc680_pcm_analog_capture alc880_pcm_analog_capture | ||
19159 | #define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture | ||
19160 | #define alc680_pcm_digital_playback alc880_pcm_digital_playback | ||
19161 | |||
19162 | static struct hda_input_mux alc680_capture_source = { | ||
19163 | .num_items = 1, | ||
19164 | .items = { | ||
19165 | { "Mic", 0x0 }, | ||
19166 | }, | ||
19167 | }; | ||
19168 | |||
19169 | /* | ||
19170 | * BIOS auto configuration | ||
19171 | */ | ||
19172 | static int alc680_parse_auto_config(struct hda_codec *codec) | ||
19173 | { | ||
19174 | struct alc_spec *spec = codec->spec; | ||
19175 | int err; | ||
19176 | static hda_nid_t alc680_ignore[] = { 0 }; | ||
19177 | |||
19178 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | ||
19179 | alc680_ignore); | ||
19180 | if (err < 0) | ||
19181 | return err; | ||
19182 | if (!spec->autocfg.line_outs) { | ||
19183 | if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { | ||
19184 | spec->multiout.max_channels = 2; | ||
19185 | spec->no_analog = 1; | ||
19186 | goto dig_only; | ||
19187 | } | ||
19188 | return 0; /* can't find valid BIOS pin config */ | ||
19189 | } | ||
19190 | err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg); | ||
19191 | if (err < 0) | ||
19192 | return err; | ||
19193 | |||
19194 | spec->multiout.max_channels = 2; | ||
19195 | |||
19196 | dig_only: | ||
19197 | /* digital only support output */ | ||
19198 | alc_auto_parse_digital(codec); | ||
19199 | if (spec->kctls.list) | ||
19200 | add_mixer(spec, spec->kctls.list); | ||
19201 | |||
19202 | add_verb(spec, alc680_init_verbs); | ||
19203 | spec->num_mux_defs = 1; | ||
19204 | spec->input_mux = &alc680_capture_source; | ||
19205 | |||
19206 | err = alc_auto_add_mic_boost(codec); | ||
19207 | if (err < 0) | ||
19208 | return err; | ||
19209 | |||
19210 | return 1; | ||
19211 | } | ||
19212 | |||
19213 | #define alc680_auto_init_analog_input alc882_auto_init_analog_input | ||
19214 | |||
19215 | /* init callback for auto-configuration model -- overriding the default init */ | ||
19216 | static void alc680_auto_init(struct hda_codec *codec) | ||
19217 | { | ||
19218 | struct alc_spec *spec = codec->spec; | ||
19219 | alc680_auto_init_multi_out(codec); | ||
19220 | alc680_auto_init_hp_out(codec); | ||
19221 | alc680_auto_init_analog_input(codec); | ||
19222 | alc_auto_init_digital(codec); | ||
19223 | if (spec->unsol_event) | ||
19224 | alc_inithook(codec); | ||
19225 | } | ||
19226 | |||
19227 | /* | ||
19228 | * configuration and preset | ||
19229 | */ | ||
19230 | static const char *alc680_models[ALC680_MODEL_LAST] = { | ||
19231 | [ALC680_BASE] = "base", | ||
19232 | [ALC680_AUTO] = "auto", | ||
19233 | }; | ||
19234 | |||
19235 | static struct snd_pci_quirk alc680_cfg_tbl[] = { | ||
19236 | SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), | ||
19237 | {} | ||
19238 | }; | ||
19239 | |||
19240 | static struct alc_config_preset alc680_presets[] = { | ||
19241 | [ALC680_BASE] = { | ||
19242 | .mixers = { alc680_base_mixer }, | ||
19243 | .cap_mixer = alc680_capture_mixer, | ||
19244 | .init_verbs = { alc680_init_verbs }, | ||
19245 | .num_dacs = ARRAY_SIZE(alc680_dac_nids), | ||
19246 | .dac_nids = alc680_dac_nids, | ||
19247 | .num_adc_nids = ARRAY_SIZE(alc680_adc_nids), | ||
19248 | .adc_nids = alc680_adc_nids, | ||
19249 | .hp_nid = 0x04, | ||
19250 | .dig_out_nid = ALC680_DIGOUT_NID, | ||
19251 | .num_channel_mode = ARRAY_SIZE(alc680_modes), | ||
19252 | .channel_mode = alc680_modes, | ||
19253 | .input_mux = &alc680_capture_source, | ||
19254 | }, | ||
19255 | }; | ||
19256 | |||
19257 | static int patch_alc680(struct hda_codec *codec) | ||
19258 | { | ||
19259 | struct alc_spec *spec; | ||
19260 | int board_config; | ||
19261 | int err; | ||
19262 | |||
19263 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
19264 | if (spec == NULL) | ||
19265 | return -ENOMEM; | ||
19266 | |||
19267 | codec->spec = spec; | ||
19268 | |||
19269 | board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST, | ||
19270 | alc680_models, | ||
19271 | alc680_cfg_tbl); | ||
19272 | |||
19273 | if (board_config < 0 || board_config >= ALC680_MODEL_LAST) { | ||
19274 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
19275 | codec->chip_name); | ||
19276 | board_config = ALC680_AUTO; | ||
19277 | } | ||
19278 | |||
19279 | if (board_config == ALC680_AUTO) { | ||
19280 | /* automatic parse from the BIOS config */ | ||
19281 | err = alc680_parse_auto_config(codec); | ||
19282 | if (err < 0) { | ||
19283 | alc_free(codec); | ||
19284 | return err; | ||
19285 | } else if (!err) { | ||
19286 | printk(KERN_INFO | ||
19287 | "hda_codec: Cannot set up configuration " | ||
19288 | "from BIOS. Using base mode...\n"); | ||
19289 | board_config = ALC680_BASE; | ||
19290 | } | ||
19291 | } | ||
19292 | |||
19293 | if (board_config != ALC680_AUTO) | ||
19294 | setup_preset(codec, &alc680_presets[board_config]); | ||
19295 | |||
19296 | spec->stream_analog_playback = &alc680_pcm_analog_playback; | ||
19297 | spec->stream_analog_capture = &alc680_pcm_analog_capture; | ||
19298 | spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture; | ||
19299 | spec->stream_digital_playback = &alc680_pcm_digital_playback; | ||
19300 | |||
19301 | if (!spec->adc_nids) { | ||
19302 | spec->adc_nids = alc680_adc_nids; | ||
19303 | spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids); | ||
19304 | } | ||
19305 | |||
19306 | if (!spec->cap_mixer) | ||
19307 | set_capture_mixer(codec); | ||
19308 | |||
19309 | spec->vmaster_nid = 0x02; | ||
19310 | |||
19311 | codec->patch_ops = alc_patch_ops; | ||
19312 | if (board_config == ALC680_AUTO) | ||
19313 | spec->init_hook = alc680_auto_init; | ||
19314 | |||
19315 | return 0; | ||
19316 | } | ||
19317 | |||
19318 | /* | ||
18784 | * patch entries | 19319 | * patch entries |
18785 | */ | 19320 | */ |
18786 | static struct hda_codec_preset snd_hda_preset_realtek[] = { | 19321 | static struct hda_codec_preset snd_hda_preset_realtek[] = { |
@@ -18804,6 +19339,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
18804 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, | 19339 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, |
18805 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, | 19340 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, |
18806 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, | 19341 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, |
19342 | { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, | ||
18807 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, | 19343 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, |
18808 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, | 19344 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, |
18809 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, | 19345 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index f1e7babd6920..b8d730c47df1 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -202,6 +202,7 @@ struct sigmatel_spec { | |||
202 | unsigned int spdif_mute: 1; | 202 | unsigned int spdif_mute: 1; |
203 | unsigned int check_volume_offset:1; | 203 | unsigned int check_volume_offset:1; |
204 | unsigned int auto_mic:1; | 204 | unsigned int auto_mic:1; |
205 | unsigned int linear_tone_beep:1; | ||
205 | 206 | ||
206 | /* gpio lines */ | 207 | /* gpio lines */ |
207 | unsigned int eapd_mask; | 208 | unsigned int eapd_mask; |
@@ -3802,7 +3803,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3802 | return err; | 3803 | return err; |
3803 | if (codec->beep) { | 3804 | if (codec->beep) { |
3804 | /* IDT/STAC codecs have linear beep tone parameter */ | 3805 | /* IDT/STAC codecs have linear beep tone parameter */ |
3805 | codec->beep->linear_tone = 1; | 3806 | codec->beep->linear_tone = spec->linear_tone_beep; |
3806 | /* if no beep switch is available, make its own one */ | 3807 | /* if no beep switch is available, make its own one */ |
3807 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); | 3808 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); |
3808 | if (!(caps & AC_AMPCAP_MUTE)) { | 3809 | if (!(caps & AC_AMPCAP_MUTE)) { |
@@ -5005,6 +5006,7 @@ static int patch_stac9200(struct hda_codec *codec) | |||
5005 | 5006 | ||
5006 | codec->no_trigger_sense = 1; | 5007 | codec->no_trigger_sense = 1; |
5007 | codec->spec = spec; | 5008 | codec->spec = spec; |
5009 | spec->linear_tone_beep = 1; | ||
5008 | spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); | 5010 | spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); |
5009 | spec->pin_nids = stac9200_pin_nids; | 5011 | spec->pin_nids = stac9200_pin_nids; |
5010 | spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, | 5012 | spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, |
@@ -5068,6 +5070,7 @@ static int patch_stac925x(struct hda_codec *codec) | |||
5068 | 5070 | ||
5069 | codec->no_trigger_sense = 1; | 5071 | codec->no_trigger_sense = 1; |
5070 | codec->spec = spec; | 5072 | codec->spec = spec; |
5073 | spec->linear_tone_beep = 1; | ||
5071 | spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); | 5074 | spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); |
5072 | spec->pin_nids = stac925x_pin_nids; | 5075 | spec->pin_nids = stac925x_pin_nids; |
5073 | 5076 | ||
@@ -5153,6 +5156,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec) | |||
5153 | 5156 | ||
5154 | codec->no_trigger_sense = 1; | 5157 | codec->no_trigger_sense = 1; |
5155 | codec->spec = spec; | 5158 | codec->spec = spec; |
5159 | spec->linear_tone_beep = 0; | ||
5156 | codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; | 5160 | codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; |
5157 | spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); | 5161 | spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); |
5158 | spec->pin_nids = stac92hd73xx_pin_nids; | 5162 | spec->pin_nids = stac92hd73xx_pin_nids; |
@@ -5300,6 +5304,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
5300 | 5304 | ||
5301 | codec->no_trigger_sense = 1; | 5305 | codec->no_trigger_sense = 1; |
5302 | codec->spec = spec; | 5306 | codec->spec = spec; |
5307 | spec->linear_tone_beep = 1; | ||
5303 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; | 5308 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; |
5304 | spec->digbeep_nid = 0x21; | 5309 | spec->digbeep_nid = 0x21; |
5305 | spec->mux_nids = stac92hd83xxx_mux_nids; | 5310 | spec->mux_nids = stac92hd83xxx_mux_nids; |
@@ -5522,6 +5527,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) | |||
5522 | 5527 | ||
5523 | codec->no_trigger_sense = 1; | 5528 | codec->no_trigger_sense = 1; |
5524 | codec->spec = spec; | 5529 | codec->spec = spec; |
5530 | spec->linear_tone_beep = 0; | ||
5525 | codec->patch_ops = stac92xx_patch_ops; | 5531 | codec->patch_ops = stac92xx_patch_ops; |
5526 | spec->num_pins = STAC92HD71BXX_NUM_PINS; | 5532 | spec->num_pins = STAC92HD71BXX_NUM_PINS; |
5527 | switch (codec->vendor_id) { | 5533 | switch (codec->vendor_id) { |
@@ -5779,6 +5785,7 @@ static int patch_stac922x(struct hda_codec *codec) | |||
5779 | 5785 | ||
5780 | codec->no_trigger_sense = 1; | 5786 | codec->no_trigger_sense = 1; |
5781 | codec->spec = spec; | 5787 | codec->spec = spec; |
5788 | spec->linear_tone_beep = 1; | ||
5782 | spec->num_pins = ARRAY_SIZE(stac922x_pin_nids); | 5789 | spec->num_pins = ARRAY_SIZE(stac922x_pin_nids); |
5783 | spec->pin_nids = stac922x_pin_nids; | 5790 | spec->pin_nids = stac922x_pin_nids; |
5784 | spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, | 5791 | spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, |
@@ -5883,6 +5890,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5883 | 5890 | ||
5884 | codec->no_trigger_sense = 1; | 5891 | codec->no_trigger_sense = 1; |
5885 | codec->spec = spec; | 5892 | codec->spec = spec; |
5893 | spec->linear_tone_beep = 1; | ||
5886 | codec->slave_dig_outs = stac927x_slave_dig_outs; | 5894 | codec->slave_dig_outs = stac927x_slave_dig_outs; |
5887 | spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); | 5895 | spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); |
5888 | spec->pin_nids = stac927x_pin_nids; | 5896 | spec->pin_nids = stac927x_pin_nids; |
@@ -6018,6 +6026,7 @@ static int patch_stac9205(struct hda_codec *codec) | |||
6018 | 6026 | ||
6019 | codec->no_trigger_sense = 1; | 6027 | codec->no_trigger_sense = 1; |
6020 | codec->spec = spec; | 6028 | codec->spec = spec; |
6029 | spec->linear_tone_beep = 1; | ||
6021 | spec->num_pins = ARRAY_SIZE(stac9205_pin_nids); | 6030 | spec->num_pins = ARRAY_SIZE(stac9205_pin_nids); |
6022 | spec->pin_nids = stac9205_pin_nids; | 6031 | spec->pin_nids = stac9205_pin_nids; |
6023 | spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, | 6032 | spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, |
@@ -6174,6 +6183,7 @@ static int patch_stac9872(struct hda_codec *codec) | |||
6174 | return -ENOMEM; | 6183 | return -ENOMEM; |
6175 | codec->no_trigger_sense = 1; | 6184 | codec->no_trigger_sense = 1; |
6176 | codec->spec = spec; | 6185 | codec->spec = spec; |
6186 | spec->linear_tone_beep = 1; | ||
6177 | spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); | 6187 | spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); |
6178 | spec->pin_nids = stac9872_pin_nids; | 6188 | spec->pin_nids = stac9872_pin_nids; |
6179 | 6189 | ||
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 73453814e098..ae3acb2b42d1 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -552,24 +552,30 @@ static void via_auto_init_hp_out(struct hda_codec *codec) | |||
552 | } | 552 | } |
553 | } | 553 | } |
554 | 554 | ||
555 | static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin); | ||
556 | |||
555 | static void via_auto_init_analog_input(struct hda_codec *codec) | 557 | static void via_auto_init_analog_input(struct hda_codec *codec) |
556 | { | 558 | { |
557 | struct via_spec *spec = codec->spec; | 559 | struct via_spec *spec = codec->spec; |
560 | unsigned int ctl; | ||
558 | int i; | 561 | int i; |
559 | 562 | ||
560 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 563 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
561 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 564 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
565 | if (!nid) | ||
566 | continue; | ||
562 | 567 | ||
568 | if (spec->smart51_enabled && is_smart51_pins(spec, nid)) | ||
569 | ctl = PIN_OUT; | ||
570 | else if (i <= AUTO_PIN_FRONT_MIC) | ||
571 | ctl = PIN_VREF50; | ||
572 | else | ||
573 | ctl = PIN_IN; | ||
563 | snd_hda_codec_write(codec, nid, 0, | 574 | snd_hda_codec_write(codec, nid, 0, |
564 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 575 | AC_VERB_SET_PIN_WIDGET_CONTROL, ctl); |
565 | (i <= AUTO_PIN_FRONT_MIC ? | ||
566 | PIN_VREF50 : PIN_IN)); | ||
567 | |||
568 | } | 576 | } |
569 | } | 577 | } |
570 | 578 | ||
571 | static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin); | ||
572 | |||
573 | static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, | 579 | static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, |
574 | unsigned int *affected_parm) | 580 | unsigned int *affected_parm) |
575 | { | 581 | { |
@@ -658,6 +664,8 @@ static void set_jack_power_state(struct hda_codec *codec) | |||
658 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ | 664 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ |
659 | parm = AC_PWRST_D3; | 665 | parm = AC_PWRST_D3; |
660 | set_pin_power_state(codec, 0x19, &parm); | 666 | set_pin_power_state(codec, 0x19, &parm); |
667 | if (spec->smart51_enabled) | ||
668 | parm = AC_PWRST_D0; | ||
661 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, | 669 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, |
662 | parm); | 670 | parm); |
663 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, | 671 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, |
@@ -667,6 +675,8 @@ static void set_jack_power_state(struct hda_codec *codec) | |||
667 | if (is_8ch) { | 675 | if (is_8ch) { |
668 | parm = AC_PWRST_D3; | 676 | parm = AC_PWRST_D3; |
669 | set_pin_power_state(codec, 0x22, &parm); | 677 | set_pin_power_state(codec, 0x22, &parm); |
678 | if (spec->smart51_enabled) | ||
679 | parm = AC_PWRST_D0; | ||
670 | snd_hda_codec_write(codec, 0x26, 0, | 680 | snd_hda_codec_write(codec, 0x26, 0, |
671 | AC_VERB_SET_POWER_STATE, parm); | 681 | AC_VERB_SET_POWER_STATE, parm); |
672 | snd_hda_codec_write(codec, 0x24, 0, | 682 | snd_hda_codec_write(codec, 0x24, 0, |
@@ -3915,6 +3925,13 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, | |||
3915 | } | 3925 | } |
3916 | } | 3926 | } |
3917 | 3927 | ||
3928 | /* for Smart 5.1, line/mic inputs double as output pins */ | ||
3929 | if (cfg->line_outs == 1) { | ||
3930 | spec->multiout.num_dacs = 3; | ||
3931 | spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11; | ||
3932 | spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24; | ||
3933 | } | ||
3934 | |||
3918 | return 0; | 3935 | return 0; |
3919 | } | 3936 | } |
3920 | 3937 | ||
@@ -3932,7 +3949,8 @@ static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, | |||
3932 | for (i = 0; i <= AUTO_SEQ_SIDE; i++) { | 3949 | for (i = 0; i <= AUTO_SEQ_SIDE; i++) { |
3933 | nid = cfg->line_out_pins[i]; | 3950 | nid = cfg->line_out_pins[i]; |
3934 | 3951 | ||
3935 | if (!nid) | 3952 | /* for Smart 5.1, there are always at least six channels */ |
3953 | if (!nid && i > AUTO_SEQ_CENLFE) | ||
3936 | continue; | 3954 | continue; |
3937 | 3955 | ||
3938 | nid_vol = nid_vols[i]; | 3956 | nid_vol = nid_vols[i]; |
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index ad4462677615..f64fb7d988cb 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c | |||
@@ -97,6 +97,7 @@ | |||
97 | #include <linux/gameport.h> | 97 | #include <linux/gameport.h> |
98 | #include <linux/device.h> | 98 | #include <linux/device.h> |
99 | #include <linux/firmware.h> | 99 | #include <linux/firmware.h> |
100 | #include <linux/kernel.h> | ||
100 | #include <asm/io.h> | 101 | #include <asm/io.h> |
101 | #include <sound/core.h> | 102 | #include <sound/core.h> |
102 | #include <sound/info.h> | 103 | #include <sound/info.h> |
@@ -667,13 +668,12 @@ static u32 atoh(const unsigned char *in, unsigned int len) | |||
667 | unsigned char c; | 668 | unsigned char c; |
668 | 669 | ||
669 | while (len) { | 670 | while (len) { |
671 | int value; | ||
672 | |||
670 | c = in[len - 1]; | 673 | c = in[len - 1]; |
671 | if ((c >= '0') && (c <= '9')) | 674 | value = hex_to_bin(c); |
672 | sum += mult * (c - '0'); | 675 | if (value >= 0) |
673 | else if ((c >= 'A') && (c <= 'F')) | 676 | sum += mult * value; |
674 | sum += mult * (c - ('A' - 10)); | ||
675 | else if ((c >= 'a') && (c <= 'f')) | ||
676 | sum += mult * (c - ('a' - 10)); | ||
677 | mult *= 16; | 677 | mult *= 16; |
678 | --len; | 678 | --len; |
679 | } | 679 | } |
@@ -1615,7 +1615,10 @@ static int snd_riptide_playback_open(struct snd_pcm_substream *substream) | |||
1615 | 1615 | ||
1616 | chip->playback_substream[sub_num] = substream; | 1616 | chip->playback_substream[sub_num] = substream; |
1617 | runtime->hw = snd_riptide_playback; | 1617 | runtime->hw = snd_riptide_playback; |
1618 | |||
1618 | data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL); | 1619 | data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL); |
1620 | if (data == NULL) | ||
1621 | return -ENOMEM; | ||
1619 | data->paths = lbus_play_paths[sub_num]; | 1622 | data->paths = lbus_play_paths[sub_num]; |
1620 | data->id = play_ids[sub_num]; | 1623 | data->id = play_ids[sub_num]; |
1621 | data->source = play_sources[sub_num]; | 1624 | data->source = play_sources[sub_num]; |
@@ -1635,7 +1638,10 @@ static int snd_riptide_capture_open(struct snd_pcm_substream *substream) | |||
1635 | 1638 | ||
1636 | chip->capture_substream = substream; | 1639 | chip->capture_substream = substream; |
1637 | runtime->hw = snd_riptide_capture; | 1640 | runtime->hw = snd_riptide_capture; |
1641 | |||
1638 | data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL); | 1642 | data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL); |
1643 | if (data == NULL) | ||
1644 | return -ENOMEM; | ||
1639 | data->paths = lbus_rec_path; | 1645 | data->paths = lbus_rec_path; |
1640 | data->id = PADC; | 1646 | data->id = PADC; |
1641 | data->source = ACLNK2PADC; | 1647 | data->source = ACLNK2PADC; |
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index 9cc1b5aa0148..1b8f6742b5fa 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c | |||
@@ -264,11 +264,13 @@ static void sis_update_voice(struct voice *voice) | |||
264 | * if using small periods. | 264 | * if using small periods. |
265 | * | 265 | * |
266 | * If we're less than 9 samples behind, we're on target. | 266 | * If we're less than 9 samples behind, we're on target. |
267 | * Otherwise, shorten the next vperiod by the amount we've | ||
268 | * been delayed. | ||
267 | */ | 269 | */ |
268 | if (sync > -9) | 270 | if (sync > -9) |
269 | voice->vperiod = voice->sync_period_size + 1; | 271 | voice->vperiod = voice->sync_period_size + 1; |
270 | else | 272 | else |
271 | voice->vperiod = voice->sync_period_size - 4; | 273 | voice->vperiod = voice->sync_period_size + sync + 10; |
272 | 274 | ||
273 | if (voice->vperiod < voice->buffer_size) { | 275 | if (voice->vperiod < voice->buffer_size) { |
274 | sis_update_sso(voice, voice->vperiod); | 276 | sis_update_sso(voice, voice->vperiod); |
@@ -736,7 +738,7 @@ static void sis_prepare_timing_voice(struct voice *voice, | |||
736 | period_size = buffer_size; | 738 | period_size = buffer_size; |
737 | 739 | ||
738 | /* Initially, we want to interrupt just a bit behind the end of | 740 | /* Initially, we want to interrupt just a bit behind the end of |
739 | * the period we're clocking out. 10 samples seems to give a good | 741 | * the period we're clocking out. 12 samples seems to give a good |
740 | * delay. | 742 | * delay. |
741 | * | 743 | * |
742 | * We want to spread our interrupts throughout the virtual period, | 744 | * We want to spread our interrupts throughout the virtual period, |
@@ -747,7 +749,7 @@ static void sis_prepare_timing_voice(struct voice *voice, | |||
747 | * | 749 | * |
748 | * This is all moot if we don't need to use virtual periods. | 750 | * This is all moot if we don't need to use virtual periods. |
749 | */ | 751 | */ |
750 | vperiod = runtime->period_size + 10; | 752 | vperiod = runtime->period_size + 12; |
751 | if (vperiod > period_size) { | 753 | if (vperiod > period_size) { |
752 | u16 tail = vperiod % period_size; | 754 | u16 tail = vperiod % period_size; |
753 | u16 quarter_period = period_size / 4; | 755 | u16 quarter_period = period_size / 4; |
@@ -776,7 +778,7 @@ static void sis_prepare_timing_voice(struct voice *voice, | |||
776 | */ | 778 | */ |
777 | timing->flags |= VOICE_SYNC_TIMING; | 779 | timing->flags |= VOICE_SYNC_TIMING; |
778 | timing->sync_base = voice->ctrl_base; | 780 | timing->sync_base = voice->ctrl_base; |
779 | timing->sync_cso = runtime->period_size - 1; | 781 | timing->sync_cso = runtime->period_size; |
780 | timing->sync_period_size = runtime->period_size; | 782 | timing->sync_period_size = runtime->period_size; |
781 | timing->sync_buffer_size = runtime->buffer_size; | 783 | timing->sync_buffer_size = runtime->buffer_size; |
782 | timing->period_size = period_size; | 784 | timing->period_size = period_size; |
@@ -1047,7 +1049,7 @@ static int sis_chip_free(struct sis7019 *sis) | |||
1047 | /* Reset the chip, and disable all interrputs. | 1049 | /* Reset the chip, and disable all interrputs. |
1048 | */ | 1050 | */ |
1049 | outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR); | 1051 | outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR); |
1050 | udelay(10); | 1052 | udelay(25); |
1051 | outl(0, sis->ioport + SIS_GCR); | 1053 | outl(0, sis->ioport + SIS_GCR); |
1052 | outl(0, sis->ioport + SIS_GIER); | 1054 | outl(0, sis->ioport + SIS_GIER); |
1053 | 1055 | ||
@@ -1083,7 +1085,7 @@ static int sis_chip_init(struct sis7019 *sis) | |||
1083 | /* Reset the audio controller | 1085 | /* Reset the audio controller |
1084 | */ | 1086 | */ |
1085 | outl(SIS_GCR_SOFTWARE_RESET, io + SIS_GCR); | 1087 | outl(SIS_GCR_SOFTWARE_RESET, io + SIS_GCR); |
1086 | udelay(10); | 1088 | udelay(25); |
1087 | outl(0, io + SIS_GCR); | 1089 | outl(0, io + SIS_GCR); |
1088 | 1090 | ||
1089 | /* Get the AC-link semaphore, and reset the codecs | 1091 | /* Get the AC-link semaphore, and reset the codecs |
@@ -1096,7 +1098,7 @@ static int sis_chip_init(struct sis7019 *sis) | |||
1096 | return -EIO; | 1098 | return -EIO; |
1097 | 1099 | ||
1098 | outl(SIS_AC97_CMD_CODEC_COLD_RESET, io + SIS_AC97_CMD); | 1100 | outl(SIS_AC97_CMD_CODEC_COLD_RESET, io + SIS_AC97_CMD); |
1099 | udelay(10); | 1101 | udelay(250); |
1100 | 1102 | ||
1101 | count = 0xffff; | 1103 | count = 0xffff; |
1102 | while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) | 1104 | while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) |
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 7e494b6a1d0e..8c5f8b5a59f0 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -85,6 +85,7 @@ static int joystick; | |||
85 | static int ac97_clock = 48000; | 85 | static int ac97_clock = 48000; |
86 | static char *ac97_quirk; | 86 | static char *ac97_quirk; |
87 | static int dxs_support; | 87 | static int dxs_support; |
88 | static int dxs_init_volume = 31; | ||
88 | static int nodelay; | 89 | static int nodelay; |
89 | 90 | ||
90 | module_param(index, int, 0444); | 91 | module_param(index, int, 0444); |
@@ -103,6 +104,8 @@ module_param(ac97_quirk, charp, 0444); | |||
103 | MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); | 104 | MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); |
104 | module_param(dxs_support, int, 0444); | 105 | module_param(dxs_support, int, 0444); |
105 | MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)"); | 106 | MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)"); |
107 | module_param(dxs_init_volume, int, 0644); | ||
108 | MODULE_PARM_DESC(dxs_init_volume, "initial DXS volume (0-31)"); | ||
106 | module_param(nodelay, int, 0444); | 109 | module_param(nodelay, int, 0444); |
107 | MODULE_PARM_DESC(nodelay, "Disable 500ms init delay"); | 110 | MODULE_PARM_DESC(nodelay, "Disable 500ms init delay"); |
108 | 111 | ||
@@ -1245,8 +1248,10 @@ static int snd_via8233_playback_open(struct snd_pcm_substream *substream) | |||
1245 | return err; | 1248 | return err; |
1246 | stream = viadev->reg_offset / 0x10; | 1249 | stream = viadev->reg_offset / 0x10; |
1247 | if (chip->dxs_controls[stream]) { | 1250 | if (chip->dxs_controls[stream]) { |
1248 | chip->playback_volume[stream][0] = 0; | 1251 | chip->playback_volume[stream][0] = |
1249 | chip->playback_volume[stream][1] = 0; | 1252 | VIA_DXS_MAX_VOLUME - (dxs_init_volume & 31); |
1253 | chip->playback_volume[stream][1] = | ||
1254 | VIA_DXS_MAX_VOLUME - (dxs_init_volume & 31); | ||
1250 | chip->dxs_controls[stream]->vd[0].access &= | 1255 | chip->dxs_controls[stream]->vd[0].access &= |
1251 | ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; | 1256 | ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; |
1252 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE | | 1257 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE | |