aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/pcm.h10
-rw-r--r--include/sound/pcm_oss.h2
-rw-r--r--include/sound/version.h2
-rw-r--r--sound/core/oss/pcm_oss.c32
-rw-r--r--sound/core/pcm.c4
-rw-r--r--sound/core/pcm_lib.c418
-rw-r--r--sound/core/pcm_native.c8
-rw-r--r--sound/pci/ac97/ac97_patch.c17
-rw-r--r--sound/pci/hda/hda_codec.c79
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_generic.c3
-rw-r--r--sound/pci/hda/hda_local.h16
-rw-r--r--sound/pci/hda/hda_proc.c31
-rw-r--r--sound/pci/hda/patch_analog.c37
-rw-r--r--sound/pci/hda/patch_cirrus.c10
-rw-r--r--sound/pci/hda/patch_cmedia.c12
-rw-r--r--sound/pci/hda/patch_conexant.c1
-rw-r--r--sound/pci/hda/patch_realtek.c125
-rw-r--r--sound/pci/hda/patch_si3054.c1
-rw-r--r--sound/pci/hda/patch_sigmatel.c7
-rw-r--r--sound/pci/hda/patch_via.c275
21 files changed, 720 insertions, 371 deletions
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 0ad2d28f2360..1d4ca2aae50d 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -262,6 +262,8 @@ struct snd_pcm_hw_constraint_list {
262 unsigned int mask; 262 unsigned int mask;
263}; 263};
264 264
265struct snd_pcm_hwptr_log;
266
265struct snd_pcm_runtime { 267struct snd_pcm_runtime {
266 /* -- Status -- */ 268 /* -- Status -- */
267 struct snd_pcm_substream *trigger_master; 269 struct snd_pcm_substream *trigger_master;
@@ -269,7 +271,6 @@ struct snd_pcm_runtime {
269 int overrange; 271 int overrange;
270 snd_pcm_uframes_t avail_max; 272 snd_pcm_uframes_t avail_max;
271 snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */ 273 snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */
272 snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */
273 unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */ 274 unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */
274 snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */ 275 snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */
275 276
@@ -310,6 +311,7 @@ struct snd_pcm_runtime {
310 struct snd_pcm_mmap_control *control; 311 struct snd_pcm_mmap_control *control;
311 312
312 /* -- locking / scheduling -- */ 313 /* -- locking / scheduling -- */
314 unsigned int nowake: 1; /* no wakeup (data-copy in progress) */
313 wait_queue_head_t sleep; 315 wait_queue_head_t sleep;
314 struct fasync_struct *fasync; 316 struct fasync_struct *fasync;
315 317
@@ -340,6 +342,10 @@ struct snd_pcm_runtime {
340 /* -- OSS things -- */ 342 /* -- OSS things -- */
341 struct snd_pcm_oss_runtime oss; 343 struct snd_pcm_oss_runtime oss;
342#endif 344#endif
345
346#ifdef CONFIG_SND_PCM_XRUN_DEBUG
347 struct snd_pcm_hwptr_log *hwptr_log;
348#endif
343}; 349};
344 350
345struct snd_pcm_group { /* keep linked substreams */ 351struct snd_pcm_group { /* keep linked substreams */
@@ -834,6 +840,8 @@ void snd_pcm_set_sync(struct snd_pcm_substream *substream);
834int snd_pcm_lib_interleave_len(struct snd_pcm_substream *substream); 840int snd_pcm_lib_interleave_len(struct snd_pcm_substream *substream);
835int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, 841int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
836 unsigned int cmd, void *arg); 842 unsigned int cmd, void *arg);
843int snd_pcm_update_state(struct snd_pcm_substream *substream,
844 struct snd_pcm_runtime *runtime);
837int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream); 845int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream);
838int snd_pcm_playback_xrun_check(struct snd_pcm_substream *substream); 846int snd_pcm_playback_xrun_check(struct snd_pcm_substream *substream);
839int snd_pcm_capture_xrun_check(struct snd_pcm_substream *substream); 847int snd_pcm_capture_xrun_check(struct snd_pcm_substream *substream);
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h
index cc4e226f35fd..760c969d885d 100644
--- a/include/sound/pcm_oss.h
+++ b/include/sound/pcm_oss.h
@@ -61,7 +61,7 @@ struct snd_pcm_oss_runtime {
61 struct snd_pcm_plugin *plugin_first; 61 struct snd_pcm_plugin *plugin_first;
62 struct snd_pcm_plugin *plugin_last; 62 struct snd_pcm_plugin *plugin_last;
63#endif 63#endif
64 unsigned int prev_hw_ptr_interrupt; 64 unsigned int prev_hw_ptr_period;
65}; 65};
66 66
67struct snd_pcm_oss_file { 67struct snd_pcm_oss_file {
diff --git a/include/sound/version.h b/include/sound/version.h
index 1f5d4872d623..7fed23442db8 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
1/* include/version.h */ 1/* include/version.h */
2#define CONFIG_SND_VERSION "1.0.22" 2#define CONFIG_SND_VERSION "1.0.22.1"
3#define CONFIG_SND_DATE "" 3#define CONFIG_SND_DATE ""
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index d9c96353121a..255ad910077a 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -632,6 +632,13 @@ static long snd_pcm_alsa_frames(struct snd_pcm_substream *substream, long bytes)
632 return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes); 632 return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes);
633} 633}
634 634
635static inline
636snd_pcm_uframes_t get_hw_ptr_period(struct snd_pcm_runtime *runtime)
637{
638 snd_pcm_uframes_t ptr = runtime->status->hw_ptr;
639 return ptr - (ptr % runtime->period_size);
640}
641
635/* define extended formats in the recent OSS versions (if any) */ 642/* define extended formats in the recent OSS versions (if any) */
636/* linear formats */ 643/* linear formats */
637#define AFMT_S32_LE 0x00001000 644#define AFMT_S32_LE 0x00001000
@@ -1102,7 +1109,7 @@ static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream)
1102 return err; 1109 return err;
1103 } 1110 }
1104 runtime->oss.prepare = 0; 1111 runtime->oss.prepare = 0;
1105 runtime->oss.prev_hw_ptr_interrupt = 0; 1112 runtime->oss.prev_hw_ptr_period = 0;
1106 runtime->oss.period_ptr = 0; 1113 runtime->oss.period_ptr = 0;
1107 runtime->oss.buffer_used = 0; 1114 runtime->oss.buffer_used = 0;
1108 1115
@@ -1950,7 +1957,8 @@ static int snd_pcm_oss_get_caps(struct snd_pcm_oss_file *pcm_oss_file)
1950 return result; 1957 return result;
1951} 1958}
1952 1959
1953static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream, snd_pcm_uframes_t hw_ptr) 1960static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream,
1961 snd_pcm_uframes_t hw_ptr)
1954{ 1962{
1955 struct snd_pcm_runtime *runtime = substream->runtime; 1963 struct snd_pcm_runtime *runtime = substream->runtime;
1956 snd_pcm_uframes_t appl_ptr; 1964 snd_pcm_uframes_t appl_ptr;
@@ -1986,7 +1994,8 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1986 if (runtime->oss.trigger) 1994 if (runtime->oss.trigger)
1987 goto _skip1; 1995 goto _skip1;
1988 if (atomic_read(&psubstream->mmap_count)) 1996 if (atomic_read(&psubstream->mmap_count))
1989 snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt); 1997 snd_pcm_oss_simulate_fill(psubstream,
1998 get_hw_ptr_period(runtime));
1990 runtime->oss.trigger = 1; 1999 runtime->oss.trigger = 1;
1991 runtime->start_threshold = 1; 2000 runtime->start_threshold = 1;
1992 cmd = SNDRV_PCM_IOCTL_START; 2001 cmd = SNDRV_PCM_IOCTL_START;
@@ -2105,11 +2114,12 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream
2105 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size); 2114 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size);
2106 if (atomic_read(&substream->mmap_count)) { 2115 if (atomic_read(&substream->mmap_count)) {
2107 snd_pcm_sframes_t n; 2116 snd_pcm_sframes_t n;
2108 n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt; 2117 delay = get_hw_ptr_period(runtime);
2118 n = delay - runtime->oss.prev_hw_ptr_period;
2109 if (n < 0) 2119 if (n < 0)
2110 n += runtime->boundary; 2120 n += runtime->boundary;
2111 info.blocks = n / runtime->period_size; 2121 info.blocks = n / runtime->period_size;
2112 runtime->oss.prev_hw_ptr_interrupt = delay; 2122 runtime->oss.prev_hw_ptr_period = delay;
2113 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 2123 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2114 snd_pcm_oss_simulate_fill(substream, delay); 2124 snd_pcm_oss_simulate_fill(substream, delay);
2115 info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX; 2125 info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX;
@@ -2673,18 +2683,22 @@ static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
2673{ 2683{
2674 struct snd_pcm_runtime *runtime = substream->runtime; 2684 struct snd_pcm_runtime *runtime = substream->runtime;
2675 if (atomic_read(&substream->mmap_count)) 2685 if (atomic_read(&substream->mmap_count))
2676 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2686 return runtime->oss.prev_hw_ptr_period !=
2687 get_hw_ptr_period(runtime);
2677 else 2688 else
2678 return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames; 2689 return snd_pcm_playback_avail(runtime) >=
2690 runtime->oss.period_frames;
2679} 2691}
2680 2692
2681static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream) 2693static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream)
2682{ 2694{
2683 struct snd_pcm_runtime *runtime = substream->runtime; 2695 struct snd_pcm_runtime *runtime = substream->runtime;
2684 if (atomic_read(&substream->mmap_count)) 2696 if (atomic_read(&substream->mmap_count))
2685 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2697 return runtime->oss.prev_hw_ptr_period !=
2698 get_hw_ptr_period(runtime);
2686 else 2699 else
2687 return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames; 2700 return snd_pcm_capture_avail(runtime) >=
2701 runtime->oss.period_frames;
2688} 2702}
2689 2703
2690static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait) 2704static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait)
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 6884ae031f6f..df57a0e30bf2 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -921,6 +921,10 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
921 snd_free_pages((void*)runtime->control, 921 snd_free_pages((void*)runtime->control,
922 PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))); 922 PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
923 kfree(runtime->hw_constraints.rules); 923 kfree(runtime->hw_constraints.rules);
924#ifdef CONFIG_SND_PCM_XRUN_DEBUG
925 if (runtime->hwptr_log)
926 kfree(runtime->hwptr_log);
927#endif
924 kfree(runtime); 928 kfree(runtime);
925 substream->runtime = NULL; 929 substream->runtime = NULL;
926 put_pid(substream->pid); 930 put_pid(substream->pid);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index b07cc361afb1..0403a7d55f0c 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -126,17 +126,6 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
126 } 126 }
127} 127}
128 128
129#ifdef CONFIG_SND_PCM_XRUN_DEBUG
130#define xrun_debug(substream, mask) ((substream)->pstr->xrun_debug & (mask))
131#else
132#define xrun_debug(substream, mask) 0
133#endif
134
135#define dump_stack_on_xrun(substream) do { \
136 if (xrun_debug(substream, 2)) \
137 dump_stack(); \
138 } while (0)
139
140static void pcm_debug_name(struct snd_pcm_substream *substream, 129static void pcm_debug_name(struct snd_pcm_substream *substream,
141 char *name, size_t len) 130 char *name, size_t len)
142{ 131{
@@ -147,6 +136,24 @@ static void pcm_debug_name(struct snd_pcm_substream *substream,
147 substream->number); 136 substream->number);
148} 137}
149 138
139#define XRUN_DEBUG_BASIC (1<<0)
140#define XRUN_DEBUG_STACK (1<<1) /* dump also stack */
141#define XRUN_DEBUG_JIFFIESCHECK (1<<2) /* do jiffies check */
142#define XRUN_DEBUG_PERIODUPDATE (1<<3) /* full period update info */
143#define XRUN_DEBUG_HWPTRUPDATE (1<<4) /* full hwptr update info */
144#define XRUN_DEBUG_LOG (1<<5) /* show last 10 positions on err */
145#define XRUN_DEBUG_LOGONCE (1<<6) /* do above only once */
146
147#ifdef CONFIG_SND_PCM_XRUN_DEBUG
148
149#define xrun_debug(substream, mask) \
150 ((substream)->pstr->xrun_debug & (mask))
151
152#define dump_stack_on_xrun(substream) do { \
153 if (xrun_debug(substream, XRUN_DEBUG_STACK)) \
154 dump_stack(); \
155 } while (0)
156
150static void xrun(struct snd_pcm_substream *substream) 157static void xrun(struct snd_pcm_substream *substream)
151{ 158{
152 struct snd_pcm_runtime *runtime = substream->runtime; 159 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -154,7 +161,7 @@ static void xrun(struct snd_pcm_substream *substream)
154 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) 161 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
155 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); 162 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
156 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); 163 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
157 if (xrun_debug(substream, 1)) { 164 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) {
158 char name[16]; 165 char name[16];
159 pcm_debug_name(substream, name, sizeof(name)); 166 pcm_debug_name(substream, name, sizeof(name));
160 snd_printd(KERN_DEBUG "XRUN: %s\n", name); 167 snd_printd(KERN_DEBUG "XRUN: %s\n", name);
@@ -162,32 +169,102 @@ static void xrun(struct snd_pcm_substream *substream)
162 } 169 }
163} 170}
164 171
165static snd_pcm_uframes_t 172#define hw_ptr_error(substream, fmt, args...) \
166snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream, 173 do { \
167 struct snd_pcm_runtime *runtime) 174 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \
168{ 175 xrun_log_show(substream); \
176 if (printk_ratelimit()) { \
177 snd_printd("PCM: " fmt, ##args); \
178 } \
179 dump_stack_on_xrun(substream); \
180 } \
181 } while (0)
182
183#define XRUN_LOG_CNT 10
184
185struct hwptr_log_entry {
186 unsigned long jiffies;
169 snd_pcm_uframes_t pos; 187 snd_pcm_uframes_t pos;
188 snd_pcm_uframes_t period_size;
189 snd_pcm_uframes_t buffer_size;
190 snd_pcm_uframes_t old_hw_ptr;
191 snd_pcm_uframes_t hw_ptr_base;
192};
170 193
171 pos = substream->ops->pointer(substream); 194struct snd_pcm_hwptr_log {
172 if (pos == SNDRV_PCM_POS_XRUN) 195 unsigned int idx;
173 return pos; /* XRUN */ 196 unsigned int hit: 1;
174 if (pos >= runtime->buffer_size) { 197 struct hwptr_log_entry entries[XRUN_LOG_CNT];
175 if (printk_ratelimit()) { 198};
176 char name[16]; 199
177 pcm_debug_name(substream, name, sizeof(name)); 200static void xrun_log(struct snd_pcm_substream *substream,
178 snd_printd(KERN_ERR "BUG: %s, pos = 0x%lx, " 201 snd_pcm_uframes_t pos)
179 "buffer size = 0x%lx, period size = 0x%lx\n", 202{
180 name, pos, runtime->buffer_size, 203 struct snd_pcm_runtime *runtime = substream->runtime;
181 runtime->period_size); 204 struct snd_pcm_hwptr_log *log = runtime->hwptr_log;
182 } 205 struct hwptr_log_entry *entry;
183 pos = 0; 206
207 if (log == NULL) {
208 log = kzalloc(sizeof(*log), GFP_ATOMIC);
209 if (log == NULL)
210 return;
211 runtime->hwptr_log = log;
212 } else {
213 if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit)
214 return;
184 } 215 }
185 pos -= pos % runtime->min_align; 216 entry = &log->entries[log->idx];
186 return pos; 217 entry->jiffies = jiffies;
218 entry->pos = pos;
219 entry->period_size = runtime->period_size;
220 entry->buffer_size = runtime->buffer_size;;
221 entry->old_hw_ptr = runtime->status->hw_ptr;
222 entry->hw_ptr_base = runtime->hw_ptr_base;
223 log->idx = (log->idx + 1) % XRUN_LOG_CNT;
187} 224}
188 225
189static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream, 226static void xrun_log_show(struct snd_pcm_substream *substream)
190 struct snd_pcm_runtime *runtime) 227{
228 struct snd_pcm_hwptr_log *log = substream->runtime->hwptr_log;
229 struct hwptr_log_entry *entry;
230 char name[16];
231 unsigned int idx;
232 int cnt;
233
234 if (log == NULL)
235 return;
236 if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit)
237 return;
238 pcm_debug_name(substream, name, sizeof(name));
239 for (cnt = 0, idx = log->idx; cnt < XRUN_LOG_CNT; cnt++) {
240 entry = &log->entries[idx];
241 if (entry->period_size == 0)
242 break;
243 snd_printd("hwptr log: %s: j=%lu, pos=%ld/%ld/%ld, "
244 "hwptr=%ld/%ld\n",
245 name, entry->jiffies, (unsigned long)entry->pos,
246 (unsigned long)entry->period_size,
247 (unsigned long)entry->buffer_size,
248 (unsigned long)entry->old_hw_ptr,
249 (unsigned long)entry->hw_ptr_base);
250 idx++;
251 idx %= XRUN_LOG_CNT;
252 }
253 log->hit = 1;
254}
255
256#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */
257
258#define xrun_debug(substream, mask) 0
259#define xrun(substream) do { } while (0)
260#define hw_ptr_error(substream, fmt, args...) do { } while (0)
261#define xrun_log(substream, pos) do { } while (0)
262#define xrun_log_show(substream) do { } while (0)
263
264#endif
265
266int snd_pcm_update_state(struct snd_pcm_substream *substream,
267 struct snd_pcm_runtime *runtime)
191{ 268{
192 snd_pcm_uframes_t avail; 269 snd_pcm_uframes_t avail;
193 270
@@ -208,89 +285,96 @@ static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream,
208 return -EPIPE; 285 return -EPIPE;
209 } 286 }
210 } 287 }
211 if (avail >= runtime->control->avail_min) 288 if (!runtime->nowake && avail >= runtime->control->avail_min)
212 wake_up(&runtime->sleep); 289 wake_up(&runtime->sleep);
213 return 0; 290 return 0;
214} 291}
215 292
216#define hw_ptr_error(substream, fmt, args...) \ 293static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
217 do { \ 294 unsigned int in_interrupt)
218 if (xrun_debug(substream, 1)) { \
219 if (printk_ratelimit()) { \
220 snd_printd("PCM: " fmt, ##args); \
221 } \
222 dump_stack_on_xrun(substream); \
223 } \
224 } while (0)
225
226static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
227{ 295{
228 struct snd_pcm_runtime *runtime = substream->runtime; 296 struct snd_pcm_runtime *runtime = substream->runtime;
229 snd_pcm_uframes_t pos; 297 snd_pcm_uframes_t pos;
230 snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_ptr_interrupt, hw_base; 298 snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base;
231 snd_pcm_sframes_t hdelta, delta; 299 snd_pcm_sframes_t hdelta, delta;
232 unsigned long jdelta; 300 unsigned long jdelta;
233 301
234 old_hw_ptr = runtime->status->hw_ptr; 302 old_hw_ptr = runtime->status->hw_ptr;
235 pos = snd_pcm_update_hw_ptr_pos(substream, runtime); 303 pos = substream->ops->pointer(substream);
236 if (pos == SNDRV_PCM_POS_XRUN) { 304 if (pos == SNDRV_PCM_POS_XRUN) {
237 xrun(substream); 305 xrun(substream);
238 return -EPIPE; 306 return -EPIPE;
239 } 307 }
240 if (xrun_debug(substream, 8)) { 308 if (pos >= runtime->buffer_size) {
241 char name[16]; 309 if (printk_ratelimit()) {
242 pcm_debug_name(substream, name, sizeof(name)); 310 char name[16];
243 snd_printd("period_update: %s: pos=0x%x/0x%x/0x%x, " 311 pcm_debug_name(substream, name, sizeof(name));
244 "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n", 312 xrun_log_show(substream);
245 name, (unsigned int)pos, 313 snd_printd(KERN_ERR "BUG: %s, pos = %ld, "
246 (unsigned int)runtime->period_size, 314 "buffer size = %ld, period size = %ld\n",
247 (unsigned int)runtime->buffer_size, 315 name, pos, runtime->buffer_size,
248 (unsigned long)old_hw_ptr, 316 runtime->period_size);
249 (unsigned long)runtime->hw_ptr_base, 317 }
250 (unsigned long)runtime->hw_ptr_interrupt); 318 pos = 0;
251 } 319 }
320 pos -= pos % runtime->min_align;
321 if (xrun_debug(substream, XRUN_DEBUG_LOG))
322 xrun_log(substream, pos);
252 hw_base = runtime->hw_ptr_base; 323 hw_base = runtime->hw_ptr_base;
253 new_hw_ptr = hw_base + pos; 324 new_hw_ptr = hw_base + pos;
254 hw_ptr_interrupt = runtime->hw_ptr_interrupt + runtime->period_size; 325 if (in_interrupt) {
255 delta = new_hw_ptr - hw_ptr_interrupt; 326 /* we know that one period was processed */
256 if (hw_ptr_interrupt >= runtime->boundary) { 327 /* delta = "expected next hw_ptr" for in_interrupt != 0 */
257 hw_ptr_interrupt -= runtime->boundary; 328 delta = old_hw_ptr - (old_hw_ptr % runtime->period_size)
258 if (hw_base < runtime->boundary / 2) 329 + runtime->period_size;
259 /* hw_base was already lapped; recalc delta */ 330 if (delta > new_hw_ptr) {
260 delta = new_hw_ptr - hw_ptr_interrupt;
261 }
262 if (delta < 0) {
263 if (runtime->periods == 1 || new_hw_ptr < old_hw_ptr)
264 delta += runtime->buffer_size;
265 if (delta < 0) {
266 hw_ptr_error(substream,
267 "Unexpected hw_pointer value "
268 "(stream=%i, pos=%ld, intr_ptr=%ld)\n",
269 substream->stream, (long)pos,
270 (long)hw_ptr_interrupt);
271#if 1
272 /* simply skipping the hwptr update seems more
273 * robust in some cases, e.g. on VMware with
274 * inaccurate timer source
275 */
276 return 0; /* skip this update */
277#else
278 /* rebase to interrupt position */
279 hw_base = new_hw_ptr = hw_ptr_interrupt;
280 /* align hw_base to buffer_size */
281 hw_base -= hw_base % runtime->buffer_size;
282 delta = 0;
283#endif
284 } else {
285 hw_base += runtime->buffer_size; 331 hw_base += runtime->buffer_size;
286 if (hw_base >= runtime->boundary) 332 if (hw_base >= runtime->boundary)
287 hw_base = 0; 333 hw_base = 0;
288 new_hw_ptr = hw_base + pos; 334 new_hw_ptr = hw_base + pos;
335 goto __delta;
289 } 336 }
290 } 337 }
338 /* new_hw_ptr might be lower than old_hw_ptr in case when */
339 /* pointer crosses the end of the ring buffer */
340 if (new_hw_ptr < old_hw_ptr) {
341 hw_base += runtime->buffer_size;
342 if (hw_base >= runtime->boundary)
343 hw_base = 0;
344 new_hw_ptr = hw_base + pos;
345 }
346 __delta:
347 delta = (new_hw_ptr - old_hw_ptr) % runtime->boundary;
348 if (xrun_debug(substream, in_interrupt ?
349 XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) {
350 char name[16];
351 pcm_debug_name(substream, name, sizeof(name));
352 snd_printd("%s_update: %s: pos=%u/%u/%u, "
353 "hwptr=%ld/%ld/%ld/%ld\n",
354 in_interrupt ? "period" : "hwptr",
355 name,
356 (unsigned int)pos,
357 (unsigned int)runtime->period_size,
358 (unsigned int)runtime->buffer_size,
359 (unsigned long)delta,
360 (unsigned long)old_hw_ptr,
361 (unsigned long)new_hw_ptr,
362 (unsigned long)runtime->hw_ptr_base);
363 }
364 /* something must be really wrong */
365 if (delta >= runtime->buffer_size + runtime->period_size) {
366 hw_ptr_error(substream,
367 "Unexpected hw_pointer value %s"
368 "(stream=%i, pos=%ld, new_hw_ptr=%ld, "
369 "old_hw_ptr=%ld)\n",
370 in_interrupt ? "[Q] " : "[P]",
371 substream->stream, (long)pos,
372 (long)new_hw_ptr, (long)old_hw_ptr);
373 return 0;
374 }
291 375
292 /* Do jiffies check only in xrun_debug mode */ 376 /* Do jiffies check only in xrun_debug mode */
293 if (!xrun_debug(substream, 4)) 377 if (!xrun_debug(substream, XRUN_DEBUG_JIFFIESCHECK))
294 goto no_jiffies_check; 378 goto no_jiffies_check;
295 379
296 /* Skip the jiffies check for hardwares with BATCH flag. 380 /* Skip the jiffies check for hardwares with BATCH flag.
@@ -299,7 +383,7 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
299 */ 383 */
300 if (runtime->hw.info & SNDRV_PCM_INFO_BATCH) 384 if (runtime->hw.info & SNDRV_PCM_INFO_BATCH)
301 goto no_jiffies_check; 385 goto no_jiffies_check;
302 hdelta = new_hw_ptr - old_hw_ptr; 386 hdelta = delta;
303 if (hdelta < runtime->delay) 387 if (hdelta < runtime->delay)
304 goto no_jiffies_check; 388 goto no_jiffies_check;
305 hdelta -= runtime->delay; 389 hdelta -= runtime->delay;
@@ -308,130 +392,62 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
308 delta = jdelta / 392 delta = jdelta /
309 (((runtime->period_size * HZ) / runtime->rate) 393 (((runtime->period_size * HZ) / runtime->rate)
310 + HZ/100); 394 + HZ/100);
395 /* move new_hw_ptr according jiffies not pos variable */
396 new_hw_ptr = old_hw_ptr;
397 /* use loop to avoid checks for delta overflows */
398 /* the delta value is small or zero in most cases */
399 while (delta > 0) {
400 new_hw_ptr += runtime->period_size;
401 if (new_hw_ptr >= runtime->boundary)
402 new_hw_ptr -= runtime->boundary;
403 delta--;
404 }
405 /* align hw_base to buffer_size */
406 hw_base = new_hw_ptr - (new_hw_ptr % runtime->buffer_size);
407 delta = 0;
311 hw_ptr_error(substream, 408 hw_ptr_error(substream,
312 "hw_ptr skipping! [Q] " 409 "hw_ptr skipping! %s"
313 "(pos=%ld, delta=%ld, period=%ld, " 410 "(pos=%ld, delta=%ld, period=%ld, "
314 "jdelta=%lu/%lu/%lu)\n", 411 "jdelta=%lu/%lu/%lu, hw_ptr=%ld/%ld)\n",
412 in_interrupt ? "[Q] " : "",
315 (long)pos, (long)hdelta, 413 (long)pos, (long)hdelta,
316 (long)runtime->period_size, jdelta, 414 (long)runtime->period_size, jdelta,
317 ((hdelta * HZ) / runtime->rate), delta); 415 ((hdelta * HZ) / runtime->rate), delta,
318 hw_ptr_interrupt = runtime->hw_ptr_interrupt + 416 (unsigned long)old_hw_ptr,
319 runtime->period_size * delta; 417 (unsigned long)new_hw_ptr);
320 if (hw_ptr_interrupt >= runtime->boundary)
321 hw_ptr_interrupt -= runtime->boundary;
322 /* rebase to interrupt position */
323 hw_base = new_hw_ptr = hw_ptr_interrupt;
324 /* align hw_base to buffer_size */
325 hw_base -= hw_base % runtime->buffer_size;
326 delta = 0;
327 } 418 }
328 no_jiffies_check: 419 no_jiffies_check:
329 if (delta > runtime->period_size + runtime->period_size / 2) { 420 if (delta > runtime->period_size + runtime->period_size / 2) {
330 hw_ptr_error(substream, 421 hw_ptr_error(substream,
331 "Lost interrupts? " 422 "Lost interrupts? %s"
332 "(stream=%i, delta=%ld, intr_ptr=%ld)\n", 423 "(stream=%i, delta=%ld, new_hw_ptr=%ld, "
424 "old_hw_ptr=%ld)\n",
425 in_interrupt ? "[Q] " : "",
333 substream->stream, (long)delta, 426 substream->stream, (long)delta,
334 (long)hw_ptr_interrupt); 427 (long)new_hw_ptr,
335 /* rebase hw_ptr_interrupt */ 428 (long)old_hw_ptr);
336 hw_ptr_interrupt =
337 new_hw_ptr - new_hw_ptr % runtime->period_size;
338 } 429 }
339 runtime->hw_ptr_interrupt = hw_ptr_interrupt; 430
431 if (runtime->status->hw_ptr == new_hw_ptr)
432 return 0;
340 433
341 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 434 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
342 runtime->silence_size > 0) 435 runtime->silence_size > 0)
343 snd_pcm_playback_silence(substream, new_hw_ptr); 436 snd_pcm_playback_silence(substream, new_hw_ptr);
344 437
345 if (runtime->status->hw_ptr == new_hw_ptr)
346 return 0;
347
348 runtime->hw_ptr_base = hw_base; 438 runtime->hw_ptr_base = hw_base;
349 runtime->status->hw_ptr = new_hw_ptr; 439 runtime->status->hw_ptr = new_hw_ptr;
350 runtime->hw_ptr_jiffies = jiffies; 440 runtime->hw_ptr_jiffies = jiffies;
351 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) 441 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
352 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); 442 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
353 443
354 return snd_pcm_update_hw_ptr_post(substream, runtime); 444 return snd_pcm_update_state(substream, runtime);
355} 445}
356 446
357/* CAUTION: call it with irq disabled */ 447/* CAUTION: call it with irq disabled */
358int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream) 448int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
359{ 449{
360 struct snd_pcm_runtime *runtime = substream->runtime; 450 return snd_pcm_update_hw_ptr0(substream, 0);
361 snd_pcm_uframes_t pos;
362 snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base;
363 snd_pcm_sframes_t delta;
364 unsigned long jdelta;
365
366 old_hw_ptr = runtime->status->hw_ptr;
367 pos = snd_pcm_update_hw_ptr_pos(substream, runtime);
368 if (pos == SNDRV_PCM_POS_XRUN) {
369 xrun(substream);
370 return -EPIPE;
371 }
372 if (xrun_debug(substream, 16)) {
373 char name[16];
374 pcm_debug_name(substream, name, sizeof(name));
375 snd_printd("hw_update: %s: pos=0x%x/0x%x/0x%x, "
376 "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n",
377 name, (unsigned int)pos,
378 (unsigned int)runtime->period_size,
379 (unsigned int)runtime->buffer_size,
380 (unsigned long)old_hw_ptr,
381 (unsigned long)runtime->hw_ptr_base,
382 (unsigned long)runtime->hw_ptr_interrupt);
383 }
384
385 hw_base = runtime->hw_ptr_base;
386 new_hw_ptr = hw_base + pos;
387
388 delta = new_hw_ptr - old_hw_ptr;
389 jdelta = jiffies - runtime->hw_ptr_jiffies;
390 if (delta < 0) {
391 delta += runtime->buffer_size;
392 if (delta < 0) {
393 hw_ptr_error(substream,
394 "Unexpected hw_pointer value [2] "
395 "(stream=%i, pos=%ld, old_ptr=%ld, jdelta=%li)\n",
396 substream->stream, (long)pos,
397 (long)old_hw_ptr, jdelta);
398 return 0;
399 }
400 hw_base += runtime->buffer_size;
401 if (hw_base >= runtime->boundary)
402 hw_base = 0;
403 new_hw_ptr = hw_base + pos;
404 }
405 /* Do jiffies check only in xrun_debug mode */
406 if (!xrun_debug(substream, 4))
407 goto no_jiffies_check;
408 if (delta < runtime->delay)
409 goto no_jiffies_check;
410 delta -= runtime->delay;
411 if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
412 hw_ptr_error(substream,
413 "hw_ptr skipping! "
414 "(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n",
415 (long)pos, (long)delta,
416 (long)runtime->period_size, jdelta,
417 ((delta * HZ) / runtime->rate));
418 return 0;
419 }
420 no_jiffies_check:
421 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
422 runtime->silence_size > 0)
423 snd_pcm_playback_silence(substream, new_hw_ptr);
424
425 if (runtime->status->hw_ptr == new_hw_ptr)
426 return 0;
427
428 runtime->hw_ptr_base = hw_base;
429 runtime->status->hw_ptr = new_hw_ptr;
430 runtime->hw_ptr_jiffies = jiffies;
431 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
432 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
433
434 return snd_pcm_update_hw_ptr_post(substream, runtime);
435} 451}
436 452
437/** 453/**
@@ -1657,7 +1673,7 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
1657 1673
1658 snd_pcm_stream_lock_irqsave(substream, flags); 1674 snd_pcm_stream_lock_irqsave(substream, flags);
1659 if (!snd_pcm_running(substream) || 1675 if (!snd_pcm_running(substream) ||
1660 snd_pcm_update_hw_ptr_interrupt(substream) < 0) 1676 snd_pcm_update_hw_ptr0(substream, 1) < 0)
1661 goto _end; 1677 goto _end;
1662 1678
1663 if (substream->timer_running) 1679 if (substream->timer_running)
@@ -1790,6 +1806,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1790 goto _end_unlock; 1806 goto _end_unlock;
1791 } 1807 }
1792 1808
1809 runtime->nowake = 1;
1793 while (size > 0) { 1810 while (size > 0) {
1794 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 1811 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1795 snd_pcm_uframes_t avail; 1812 snd_pcm_uframes_t avail;
@@ -1811,15 +1828,17 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1811 if (frames > cont) 1828 if (frames > cont)
1812 frames = cont; 1829 frames = cont;
1813 if (snd_BUG_ON(!frames)) { 1830 if (snd_BUG_ON(!frames)) {
1831 runtime->nowake = 0;
1814 snd_pcm_stream_unlock_irq(substream); 1832 snd_pcm_stream_unlock_irq(substream);
1815 return -EINVAL; 1833 return -EINVAL;
1816 } 1834 }
1817 appl_ptr = runtime->control->appl_ptr; 1835 appl_ptr = runtime->control->appl_ptr;
1818 appl_ofs = appl_ptr % runtime->buffer_size; 1836 appl_ofs = appl_ptr % runtime->buffer_size;
1819 snd_pcm_stream_unlock_irq(substream); 1837 snd_pcm_stream_unlock_irq(substream);
1820 if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0) 1838 err = transfer(substream, appl_ofs, data, offset, frames);
1821 goto _end;
1822 snd_pcm_stream_lock_irq(substream); 1839 snd_pcm_stream_lock_irq(substream);
1840 if (err < 0)
1841 goto _end_unlock;
1823 switch (runtime->status->state) { 1842 switch (runtime->status->state) {
1824 case SNDRV_PCM_STATE_XRUN: 1843 case SNDRV_PCM_STATE_XRUN:
1825 err = -EPIPE; 1844 err = -EPIPE;
@@ -1848,8 +1867,10 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1848 } 1867 }
1849 } 1868 }
1850 _end_unlock: 1869 _end_unlock:
1870 runtime->nowake = 0;
1871 if (xfer > 0 && err >= 0)
1872 snd_pcm_update_state(substream, runtime);
1851 snd_pcm_stream_unlock_irq(substream); 1873 snd_pcm_stream_unlock_irq(substream);
1852 _end:
1853 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; 1874 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
1854} 1875}
1855 1876
@@ -2007,6 +2028,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2007 goto _end_unlock; 2028 goto _end_unlock;
2008 } 2029 }
2009 2030
2031 runtime->nowake = 1;
2010 while (size > 0) { 2032 while (size > 0) {
2011 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 2033 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
2012 snd_pcm_uframes_t avail; 2034 snd_pcm_uframes_t avail;
@@ -2035,15 +2057,17 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2035 if (frames > cont) 2057 if (frames > cont)
2036 frames = cont; 2058 frames = cont;
2037 if (snd_BUG_ON(!frames)) { 2059 if (snd_BUG_ON(!frames)) {
2060 runtime->nowake = 0;
2038 snd_pcm_stream_unlock_irq(substream); 2061 snd_pcm_stream_unlock_irq(substream);
2039 return -EINVAL; 2062 return -EINVAL;
2040 } 2063 }
2041 appl_ptr = runtime->control->appl_ptr; 2064 appl_ptr = runtime->control->appl_ptr;
2042 appl_ofs = appl_ptr % runtime->buffer_size; 2065 appl_ofs = appl_ptr % runtime->buffer_size;
2043 snd_pcm_stream_unlock_irq(substream); 2066 snd_pcm_stream_unlock_irq(substream);
2044 if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0) 2067 err = transfer(substream, appl_ofs, data, offset, frames);
2045 goto _end;
2046 snd_pcm_stream_lock_irq(substream); 2068 snd_pcm_stream_lock_irq(substream);
2069 if (err < 0)
2070 goto _end_unlock;
2047 switch (runtime->status->state) { 2071 switch (runtime->status->state) {
2048 case SNDRV_PCM_STATE_XRUN: 2072 case SNDRV_PCM_STATE_XRUN:
2049 err = -EPIPE; 2073 err = -EPIPE;
@@ -2066,8 +2090,10 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2066 xfer += frames; 2090 xfer += frames;
2067 } 2091 }
2068 _end_unlock: 2092 _end_unlock:
2093 runtime->nowake = 0;
2094 if (xfer > 0 && err >= 0)
2095 snd_pcm_update_state(substream, runtime);
2069 snd_pcm_stream_unlock_irq(substream); 2096 snd_pcm_stream_unlock_irq(substream);
2070 _end:
2071 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; 2097 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
2072} 2098}
2073 2099
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 25b0641e6b8c..a870fe696578 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -516,6 +516,7 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
516 struct snd_pcm_sw_params *params) 516 struct snd_pcm_sw_params *params)
517{ 517{
518 struct snd_pcm_runtime *runtime; 518 struct snd_pcm_runtime *runtime;
519 int err;
519 520
520 if (PCM_RUNTIME_CHECK(substream)) 521 if (PCM_RUNTIME_CHECK(substream))
521 return -ENXIO; 522 return -ENXIO;
@@ -540,6 +541,7 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
540 if (params->silence_threshold > runtime->buffer_size) 541 if (params->silence_threshold > runtime->buffer_size)
541 return -EINVAL; 542 return -EINVAL;
542 } 543 }
544 err = 0;
543 snd_pcm_stream_lock_irq(substream); 545 snd_pcm_stream_lock_irq(substream);
544 runtime->tstamp_mode = params->tstamp_mode; 546 runtime->tstamp_mode = params->tstamp_mode;
545 runtime->period_step = params->period_step; 547 runtime->period_step = params->period_step;
@@ -553,10 +555,10 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
553 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 555 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
554 runtime->silence_size > 0) 556 runtime->silence_size > 0)
555 snd_pcm_playback_silence(substream, ULONG_MAX); 557 snd_pcm_playback_silence(substream, ULONG_MAX);
556 wake_up(&runtime->sleep); 558 err = snd_pcm_update_state(substream, runtime);
557 } 559 }
558 snd_pcm_stream_unlock_irq(substream); 560 snd_pcm_stream_unlock_irq(substream);
559 return 0; 561 return err;
560} 562}
561 563
562static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream, 564static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream,
@@ -1247,8 +1249,6 @@ static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state)
1247 if (err < 0) 1249 if (err < 0)
1248 return err; 1250 return err;
1249 runtime->hw_ptr_base = 0; 1251 runtime->hw_ptr_base = 0;
1250 runtime->hw_ptr_interrupt = runtime->status->hw_ptr -
1251 runtime->status->hw_ptr % runtime->period_size;
1252 runtime->silence_start = runtime->status->hw_ptr; 1252 runtime->silence_start = runtime->status->hw_ptr;
1253 runtime->silence_filled = 0; 1253 runtime->silence_filled = 0;
1254 return 0; 1254 return 0;
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 139cf3b2b9d7..e288a5595f34 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -544,25 +544,10 @@ static int patch_wolfson04(struct snd_ac97 * ac97)
544 return 0; 544 return 0;
545} 545}
546 546
547static int patch_wolfson_wm9705_specific(struct snd_ac97 * ac97)
548{
549 int err, i;
550 for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) {
551 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0)
552 return err;
553 }
554 snd_ac97_write_cache(ac97, 0x72, 0x0808);
555 return 0;
556}
557
558static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = {
559 .build_specific = patch_wolfson_wm9705_specific,
560};
561
562static int patch_wolfson05(struct snd_ac97 * ac97) 547static int patch_wolfson05(struct snd_ac97 * ac97)
563{ 548{
564 /* WM9705, WM9710 */ 549 /* WM9705, WM9710 */
565 ac97->build_ops = &patch_wolfson_wm9705_ops; 550 ac97->build_ops = &patch_wolfson_wm9703_ops;
566#ifdef CONFIG_TOUCHSCREEN_WM9705 551#ifdef CONFIG_TOUCHSCREEN_WM9705
567 /* WM9705 touchscreen uses AUX and VIDEO for touch */ 552 /* WM9705 touchscreen uses AUX and VIDEO for touch */
568 ac97->flags |= AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX; 553 ac97->flags |= AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 950ee5cfcacf..d2f10b1c3a8a 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -931,6 +931,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
931#endif 931#endif
932 list_del(&codec->list); 932 list_del(&codec->list);
933 snd_array_free(&codec->mixers); 933 snd_array_free(&codec->mixers);
934 snd_array_free(&codec->nids);
934 codec->bus->caddr_tbl[codec->addr] = NULL; 935 codec->bus->caddr_tbl[codec->addr] = NULL;
935 if (codec->patch_ops.free) 936 if (codec->patch_ops.free)
936 codec->patch_ops.free(codec); 937 codec->patch_ops.free(codec);
@@ -985,7 +986,8 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
985 mutex_init(&codec->control_mutex); 986 mutex_init(&codec->control_mutex);
986 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); 987 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
987 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); 988 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
988 snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 60); 989 snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
990 snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
989 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); 991 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
990 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); 992 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
991 if (codec->bus->modelname) { 993 if (codec->bus->modelname) {
@@ -1706,7 +1708,7 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1706EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); 1708EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
1707 1709
1708/** 1710/**
1709 * snd_hda_ctl-add - Add a control element and assign to the codec 1711 * snd_hda_ctl_add - Add a control element and assign to the codec
1710 * @codec: HD-audio codec 1712 * @codec: HD-audio codec
1711 * @nid: corresponding NID (optional) 1713 * @nid: corresponding NID (optional)
1712 * @kctl: the control element to assign 1714 * @kctl: the control element to assign
@@ -1721,19 +1723,25 @@ EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
1721 * 1723 *
1722 * snd_hda_ctl_add() checks the control subdev id field whether 1724 * snd_hda_ctl_add() checks the control subdev id field whether
1723 * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower 1725 * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower
1724 * bits value is taken as the NID to assign. 1726 * bits value is taken as the NID to assign. The #HDA_NID_ITEM_AMP bit
1727 * specifies if kctl->private_value is a HDA amplifier value.
1725 */ 1728 */
1726int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, 1729int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
1727 struct snd_kcontrol *kctl) 1730 struct snd_kcontrol *kctl)
1728{ 1731{
1729 int err; 1732 int err;
1733 unsigned short flags = 0;
1730 struct hda_nid_item *item; 1734 struct hda_nid_item *item;
1731 1735
1732 if (kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) { 1736 if (kctl->id.subdevice & HDA_SUBDEV_AMP_FLAG) {
1737 flags |= HDA_NID_ITEM_AMP;
1733 if (nid == 0) 1738 if (nid == 0)
1734 nid = kctl->id.subdevice & 0xffff; 1739 nid = get_amp_nid_(kctl->private_value);
1735 kctl->id.subdevice = 0;
1736 } 1740 }
1741 if ((kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) != 0 && nid == 0)
1742 nid = kctl->id.subdevice & 0xffff;
1743 if (kctl->id.subdevice & (HDA_SUBDEV_NID_FLAG|HDA_SUBDEV_AMP_FLAG))
1744 kctl->id.subdevice = 0;
1737 err = snd_ctl_add(codec->bus->card, kctl); 1745 err = snd_ctl_add(codec->bus->card, kctl);
1738 if (err < 0) 1746 if (err < 0)
1739 return err; 1747 return err;
@@ -1742,11 +1750,41 @@ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
1742 return -ENOMEM; 1750 return -ENOMEM;
1743 item->kctl = kctl; 1751 item->kctl = kctl;
1744 item->nid = nid; 1752 item->nid = nid;
1753 item->flags = flags;
1745 return 0; 1754 return 0;
1746} 1755}
1747EXPORT_SYMBOL_HDA(snd_hda_ctl_add); 1756EXPORT_SYMBOL_HDA(snd_hda_ctl_add);
1748 1757
1749/** 1758/**
1759 * snd_hda_add_nid - Assign a NID to a control element
1760 * @codec: HD-audio codec
1761 * @nid: corresponding NID (optional)
1762 * @kctl: the control element to assign
1763 * @index: index to kctl
1764 *
1765 * Add the given control element to an array inside the codec instance.
1766 * This function is used when #snd_hda_ctl_add cannot be used for 1:1
1767 * NID:KCTL mapping - for example "Capture Source" selector.
1768 */
1769int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
1770 unsigned int index, hda_nid_t nid)
1771{
1772 struct hda_nid_item *item;
1773
1774 if (nid > 0) {
1775 item = snd_array_new(&codec->nids);
1776 if (!item)
1777 return -ENOMEM;
1778 item->kctl = kctl;
1779 item->index = index;
1780 item->nid = nid;
1781 return 0;
1782 }
1783 return -EINVAL;
1784}
1785EXPORT_SYMBOL_HDA(snd_hda_add_nid);
1786
1787/**
1750 * snd_hda_ctls_clear - Clear all controls assigned to the given codec 1788 * snd_hda_ctls_clear - Clear all controls assigned to the given codec
1751 * @codec: HD-audio codec 1789 * @codec: HD-audio codec
1752 */ 1790 */
@@ -1757,6 +1795,7 @@ void snd_hda_ctls_clear(struct hda_codec *codec)
1757 for (i = 0; i < codec->mixers.used; i++) 1795 for (i = 0; i < codec->mixers.used; i++)
1758 snd_ctl_remove(codec->bus->card, items[i].kctl); 1796 snd_ctl_remove(codec->bus->card, items[i].kctl);
1759 snd_array_free(&codec->mixers); 1797 snd_array_free(&codec->mixers);
1798 snd_array_free(&codec->nids);
1760} 1799}
1761 1800
1762/* pseudo device locking 1801/* pseudo device locking
@@ -3476,6 +3515,8 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
3476 3515
3477 for (; knew->name; knew++) { 3516 for (; knew->name; knew++) {
3478 struct snd_kcontrol *kctl; 3517 struct snd_kcontrol *kctl;
3518 if (knew->iface == -1) /* skip this codec private value */
3519 continue;
3479 kctl = snd_ctl_new1(knew, codec); 3520 kctl = snd_ctl_new1(knew, codec);
3480 if (!kctl) 3521 if (!kctl)
3481 return -ENOMEM; 3522 return -ENOMEM;
@@ -3496,6 +3537,32 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
3496} 3537}
3497EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls); 3538EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
3498 3539
3540/**
3541 * snd_hda_add_nids - assign nids to controls from the array
3542 * @codec: the HDA codec
3543 * @kctl: struct snd_kcontrol
3544 * @index: index to kctl
3545 * @nids: the array of hda_nid_t
3546 * @size: count of hda_nid_t items
3547 *
3548 * This helper function assigns NIDs in the given array to a control element.
3549 *
3550 * Returns 0 if successful, or a negative error code.
3551 */
3552int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl,
3553 unsigned int index, hda_nid_t *nids, unsigned int size)
3554{
3555 int err;
3556
3557 for ( ; size > 0; size--, nids++) {
3558 err = snd_hda_add_nid(codec, kctl, index, *nids);
3559 if (err < 0)
3560 return err;
3561 }
3562 return 0;
3563}
3564EXPORT_SYMBOL_HDA(snd_hda_add_nids);
3565
3499#ifdef CONFIG_SND_HDA_POWER_SAVE 3566#ifdef CONFIG_SND_HDA_POWER_SAVE
3500static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, 3567static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3501 unsigned int power_state); 3568 unsigned int power_state);
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 1d541b7f5547..0d08ad5bd898 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -789,6 +789,7 @@ struct hda_codec {
789 u32 *wcaps; 789 u32 *wcaps;
790 790
791 struct snd_array mixers; /* list of assigned mixer elements */ 791 struct snd_array mixers; /* list of assigned mixer elements */
792 struct snd_array nids; /* list of mapped mixer elements */
792 793
793 struct hda_cache_rec amp_cache; /* cache for amp access */ 794 struct hda_cache_rec amp_cache; /* cache for amp access */
794 struct hda_cache_rec cmd_cache; /* cache for other commands */ 795 struct hda_cache_rec cmd_cache; /* cache for other commands */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 092c6a7c2ff3..5ea21285ee1f 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -861,7 +861,8 @@ static int build_input_controls(struct hda_codec *codec)
861 } 861 }
862 862
863 /* create input MUX if multiple sources are available */ 863 /* create input MUX if multiple sources are available */
864 err = snd_hda_ctl_add(codec, 0, snd_ctl_new1(&cap_sel, codec)); 864 err = snd_hda_ctl_add(codec, spec->adc_node->nid,
865 snd_ctl_new1(&cap_sel, codec));
865 if (err < 0) 866 if (err < 0)
866 return err; 867 return err;
867 868
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 5778ae882b83..d505d052972e 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -31,6 +31,7 @@
31 * in snd_hda_ctl_add(), so that this value won't appear in the outside. 31 * in snd_hda_ctl_add(), so that this value won't appear in the outside.
32 */ 32 */
33#define HDA_SUBDEV_NID_FLAG (1U << 31) 33#define HDA_SUBDEV_NID_FLAG (1U << 31)
34#define HDA_SUBDEV_AMP_FLAG (1U << 30)
34 35
35/* 36/*
36 * for mixer controls 37 * for mixer controls
@@ -42,7 +43,7 @@
42/* mono volume with index (index=0,1,...) (channel=1,2) */ 43/* mono volume with index (index=0,1,...) (channel=1,2) */
43#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 44#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
44 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 45 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
45 .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ 46 .subdevice = HDA_SUBDEV_AMP_FLAG, \
46 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 47 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
47 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 48 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
48 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ 49 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
@@ -63,7 +64,7 @@
63/* mono mute switch with index (index=0,1,...) (channel=1,2) */ 64/* mono mute switch with index (index=0,1,...) (channel=1,2) */
64#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 65#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
65 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 66 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
66 .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ 67 .subdevice = HDA_SUBDEV_AMP_FLAG, \
67 .info = snd_hda_mixer_amp_switch_info, \ 68 .info = snd_hda_mixer_amp_switch_info, \
68 .get = snd_hda_mixer_amp_switch_get, \ 69 .get = snd_hda_mixer_amp_switch_get, \
69 .put = snd_hda_mixer_amp_switch_put, \ 70 .put = snd_hda_mixer_amp_switch_put, \
@@ -81,7 +82,7 @@
81/* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */ 82/* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */
82#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 83#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
83 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 84 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
84 .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ 85 .subdevice = HDA_SUBDEV_AMP_FLAG, \
85 .info = snd_hda_mixer_amp_switch_info, \ 86 .info = snd_hda_mixer_amp_switch_info, \
86 .get = snd_hda_mixer_amp_switch_get, \ 87 .get = snd_hda_mixer_amp_switch_get, \
87 .put = snd_hda_mixer_amp_switch_put_beep, \ 88 .put = snd_hda_mixer_amp_switch_put_beep, \
@@ -342,6 +343,8 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
342 const struct snd_pci_quirk *tbl); 343 const struct snd_pci_quirk *tbl);
343int snd_hda_add_new_ctls(struct hda_codec *codec, 344int snd_hda_add_new_ctls(struct hda_codec *codec,
344 struct snd_kcontrol_new *knew); 345 struct snd_kcontrol_new *knew);
346int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl,
347 unsigned int index, hda_nid_t *nids, unsigned int size);
345 348
346/* 349/*
347 * unsolicited event handler 350 * unsolicited event handler
@@ -464,13 +467,20 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid);
464u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); 467u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
465int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); 468int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
466 469
470/* flags for hda_nid_item */
471#define HDA_NID_ITEM_AMP (1<<0)
472
467struct hda_nid_item { 473struct hda_nid_item {
468 struct snd_kcontrol *kctl; 474 struct snd_kcontrol *kctl;
475 unsigned int index;
469 hda_nid_t nid; 476 hda_nid_t nid;
477 unsigned short flags;
470}; 478};
471 479
472int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, 480int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
473 struct snd_kcontrol *kctl); 481 struct snd_kcontrol *kctl);
482int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
483 unsigned int index, hda_nid_t nid);
474void snd_hda_ctls_clear(struct hda_codec *codec); 484void snd_hda_ctls_clear(struct hda_codec *codec);
475 485
476/* 486/*
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index c9afc04adac8..f97d35de66c4 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -61,18 +61,29 @@ static const char *get_wid_type_name(unsigned int wid_value)
61 return "UNKNOWN Widget"; 61 return "UNKNOWN Widget";
62} 62}
63 63
64static void print_nid_mixers(struct snd_info_buffer *buffer, 64static void print_nid_array(struct snd_info_buffer *buffer,
65 struct hda_codec *codec, hda_nid_t nid) 65 struct hda_codec *codec, hda_nid_t nid,
66 struct snd_array *array)
66{ 67{
67 int i; 68 int i;
68 struct hda_nid_item *items = codec->mixers.list; 69 struct hda_nid_item *items = array->list, *item;
69 struct snd_kcontrol *kctl; 70 struct snd_kcontrol *kctl;
70 for (i = 0; i < codec->mixers.used; i++) { 71 for (i = 0; i < array->used; i++) {
71 if (items[i].nid == nid) { 72 item = &items[i];
72 kctl = items[i].kctl; 73 if (item->nid == nid) {
74 kctl = item->kctl;
73 snd_iprintf(buffer, 75 snd_iprintf(buffer,
74 " Control: name=\"%s\", index=%i, device=%i\n", 76 " Control: name=\"%s\", index=%i, device=%i\n",
75 kctl->id.name, kctl->id.index, kctl->id.device); 77 kctl->id.name, kctl->id.index + item->index,
78 kctl->id.device);
79 if (item->flags & HDA_NID_ITEM_AMP)
80 snd_iprintf(buffer,
81 " ControlAmp: chs=%lu, dir=%s, "
82 "idx=%lu, ofs=%lu\n",
83 get_amp_channels(kctl),
84 get_amp_direction(kctl) ? "Out" : "In",
85 get_amp_index(kctl),
86 get_amp_offset(kctl));
76 } 87 }
77 } 88 }
78} 89}
@@ -528,7 +539,8 @@ static void print_gpio(struct snd_info_buffer *buffer,
528 (data & (1<<i)) ? 1 : 0, 539 (data & (1<<i)) ? 1 : 0,
529 (unsol & (1<<i)) ? 1 : 0); 540 (unsol & (1<<i)) ? 1 : 0);
530 /* FIXME: add GPO and GPI pin information */ 541 /* FIXME: add GPO and GPI pin information */
531 print_nid_mixers(buffer, codec, nid); 542 print_nid_array(buffer, codec, nid, &codec->mixers);
543 print_nid_array(buffer, codec, nid, &codec->nids);
532} 544}
533 545
534static void print_codec_info(struct snd_info_entry *entry, 546static void print_codec_info(struct snd_info_entry *entry,
@@ -608,7 +620,8 @@ static void print_codec_info(struct snd_info_entry *entry,
608 snd_iprintf(buffer, " CP"); 620 snd_iprintf(buffer, " CP");
609 snd_iprintf(buffer, "\n"); 621 snd_iprintf(buffer, "\n");
610 622
611 print_nid_mixers(buffer, codec, nid); 623 print_nid_array(buffer, codec, nid, &codec->mixers);
624 print_nid_array(buffer, codec, nid, &codec->nids);
612 print_nid_pcms(buffer, codec, nid); 625 print_nid_pcms(buffer, codec, nid);
613 626
614 /* volume knob is a special widget that always have connection 627 /* volume knob is a special widget that always have connection
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 1a36137e13ec..92b72d4f3984 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -174,6 +174,7 @@ static struct snd_kcontrol_new ad_beep_mixer[] = {
174static int ad198x_build_controls(struct hda_codec *codec) 174static int ad198x_build_controls(struct hda_codec *codec)
175{ 175{
176 struct ad198x_spec *spec = codec->spec; 176 struct ad198x_spec *spec = codec->spec;
177 struct snd_kcontrol *kctl;
177 unsigned int i; 178 unsigned int i;
178 int err; 179 int err;
179 180
@@ -208,9 +209,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
208 if (!kctl) 209 if (!kctl)
209 return -ENOMEM; 210 return -ENOMEM;
210 kctl->private_value = spec->beep_amp; 211 kctl->private_value = spec->beep_amp;
211 err = snd_hda_ctl_add(codec, 212 err = snd_hda_ctl_add(codec, 0, kctl);
212 get_amp_nid_(spec->beep_amp),
213 kctl);
214 if (err < 0) 213 if (err < 0)
215 return err; 214 return err;
216 } 215 }
@@ -239,6 +238,28 @@ static int ad198x_build_controls(struct hda_codec *codec)
239 } 238 }
240 239
241 ad198x_free_kctls(codec); /* no longer needed */ 240 ad198x_free_kctls(codec); /* no longer needed */
241
242 /* assign Capture Source enums to NID */
243 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
244 if (!kctl)
245 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
246 for (i = 0; kctl && i < kctl->count; i++) {
247 err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids,
248 spec->input_mux->num_items);
249 if (err < 0)
250 return err;
251 }
252
253 /* assign IEC958 enums to NID */
254 kctl = snd_hda_find_mixer_ctl(codec,
255 SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source");
256 if (kctl) {
257 err = snd_hda_add_nid(codec, kctl, 0,
258 spec->multiout.dig_out_nid);
259 if (err < 0)
260 return err;
261 }
262
242 return 0; 263 return 0;
243} 264}
244 265
@@ -701,6 +722,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
701 { 722 {
702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 723 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
703 .name = "External Amplifier", 724 .name = "External Amplifier",
725 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
704 .info = ad198x_eapd_info, 726 .info = ad198x_eapd_info,
705 .get = ad198x_eapd_get, 727 .get = ad198x_eapd_get,
706 .put = ad198x_eapd_put, 728 .put = ad198x_eapd_put,
@@ -808,6 +830,7 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
808 { 830 {
809 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
810 .name = "Master Playback Switch", 832 .name = "Master Playback Switch",
833 .subdevice = HDA_SUBDEV_AMP_FLAG,
811 .info = snd_hda_mixer_amp_switch_info, 834 .info = snd_hda_mixer_amp_switch_info,
812 .get = snd_hda_mixer_amp_switch_get, 835 .get = snd_hda_mixer_amp_switch_get,
813 .put = ad1986a_hp_master_sw_put, 836 .put = ad1986a_hp_master_sw_put,
@@ -1608,6 +1631,7 @@ static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1608 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), 1631 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1609 { 1632 {
1610 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1633 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1634 .subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
1611 .name = "Master Playback Switch", 1635 .name = "Master Playback Switch",
1612 .info = ad198x_eapd_info, 1636 .info = ad198x_eapd_info,
1613 .get = ad198x_eapd_get, 1637 .get = ad198x_eapd_get,
@@ -2129,6 +2153,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2129 { 2153 {
2130 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2131 .name = "External Amplifier", 2155 .name = "External Amplifier",
2156 .subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
2132 .info = ad198x_eapd_info, 2157 .info = ad198x_eapd_info,
2133 .get = ad198x_eapd_get, 2158 .get = ad198x_eapd_get,
2134 .put = ad198x_eapd_put, 2159 .put = ad198x_eapd_put,
@@ -2250,6 +2275,7 @@ static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2250 { 2275 {
2251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2276 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2252 .name = "IEC958 Playback Source", 2277 .name = "IEC958 Playback Source",
2278 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
2253 .info = ad1988_spdif_playback_source_info, 2279 .info = ad1988_spdif_playback_source_info,
2254 .get = ad1988_spdif_playback_source_get, 2280 .get = ad1988_spdif_playback_source_get,
2255 .put = ad1988_spdif_playback_source_put, 2281 .put = ad1988_spdif_playback_source_put,
@@ -2582,7 +2608,7 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name,
2582 if (! knew->name) 2608 if (! knew->name)
2583 return -ENOMEM; 2609 return -ENOMEM;
2584 if (get_amp_nid_(val)) 2610 if (get_amp_nid_(val))
2585 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 2611 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
2586 knew->private_value = val; 2612 knew->private_value = val;
2587 return 0; 2613 return 0;
2588} 2614}
@@ -3736,6 +3762,7 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3736 { 3762 {
3737 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3763 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3738 .name = "Master Playback Switch", 3764 .name = "Master Playback Switch",
3765 .subdevice = HDA_SUBDEV_AMP_FLAG,
3739 .info = snd_hda_mixer_amp_switch_info, 3766 .info = snd_hda_mixer_amp_switch_info,
3740 .get = snd_hda_mixer_amp_switch_get, 3767 .get = snd_hda_mixer_amp_switch_get,
3741 .put = ad1884a_mobile_master_sw_put, 3768 .put = ad1884a_mobile_master_sw_put,
@@ -3764,6 +3791,7 @@ static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3764 { 3791 {
3765 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3766 .name = "Master Playback Switch", 3793 .name = "Master Playback Switch",
3794 .subdevice = HDA_SUBDEV_AMP_FLAG,
3767 .info = snd_hda_mixer_amp_switch_info, 3795 .info = snd_hda_mixer_amp_switch_info,
3768 .get = snd_hda_mixer_amp_switch_get, 3796 .get = snd_hda_mixer_amp_switch_get,
3769 .put = ad1884a_mobile_master_sw_put, 3797 .put = ad1884a_mobile_master_sw_put,
@@ -4105,6 +4133,7 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4105/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 4133/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4106 { 4134 {
4107 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4135 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4136 .subdevice = HDA_SUBDEV_AMP_FLAG,
4108 .name = "Master Playback Switch", 4137 .name = "Master Playback Switch",
4109 .info = snd_hda_mixer_amp_switch_info, 4138 .info = snd_hda_mixer_amp_switch_info,
4110 .get = snd_hda_mixer_amp_switch_get, 4139 .get = snd_hda_mixer_amp_switch_get,
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index fe0423c39598..093cfbb55e9e 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -501,7 +501,8 @@ static int add_mute(struct hda_codec *codec, const char *name, int index,
501 knew.private_value = pval; 501 knew.private_value = pval;
502 snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]); 502 snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]);
503 *kctlp = snd_ctl_new1(&knew, codec); 503 *kctlp = snd_ctl_new1(&knew, codec);
504 return snd_hda_ctl_add(codec, get_amp_nid_(pval), *kctlp); 504 (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
505 return snd_hda_ctl_add(codec, 0, *kctlp);
505} 506}
506 507
507static int add_volume(struct hda_codec *codec, const char *name, 508static int add_volume(struct hda_codec *codec, const char *name,
@@ -514,7 +515,8 @@ static int add_volume(struct hda_codec *codec, const char *name,
514 knew.private_value = pval; 515 knew.private_value = pval;
515 snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]); 516 snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]);
516 *kctlp = snd_ctl_new1(&knew, codec); 517 *kctlp = snd_ctl_new1(&knew, codec);
517 return snd_hda_ctl_add(codec, get_amp_nid_(pval), *kctlp); 518 (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
519 return snd_hda_ctl_add(codec, 0, *kctlp);
518} 520}
519 521
520static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac) 522static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac)
@@ -760,6 +762,10 @@ static int build_input(struct hda_codec *codec)
760 err = snd_hda_ctl_add(codec, 0, kctl); 762 err = snd_hda_ctl_add(codec, 0, kctl);
761 if (err < 0) 763 if (err < 0)
762 return err; 764 return err;
765 err = snd_hda_add_nids(codec, kctl, 0, spec->adc_nid,
766 spec->num_inputs);
767 if (err < 0)
768 return err;
763 } 769 }
764 770
765 if (spec->num_inputs > 1 && !spec->mic_detect) { 771 if (spec->num_inputs > 1 && !spec->mic_detect) {
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index a45c1169762b..cc1c22370a60 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -315,7 +315,8 @@ static struct hda_verb cmi9880_allout_init[] = {
315static int cmi9880_build_controls(struct hda_codec *codec) 315static int cmi9880_build_controls(struct hda_codec *codec)
316{ 316{
317 struct cmi_spec *spec = codec->spec; 317 struct cmi_spec *spec = codec->spec;
318 int err; 318 struct snd_kcontrol *kctl;
319 int i, err;
319 320
320 err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer); 321 err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer);
321 if (err < 0) 322 if (err < 0)
@@ -340,6 +341,15 @@ static int cmi9880_build_controls(struct hda_codec *codec)
340 if (err < 0) 341 if (err < 0)
341 return err; 342 return err;
342 } 343 }
344
345 /* assign Capture Source enums to NID */
346 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
347 for (i = 0; kctl && i < kctl->count; i++) {
348 err = snd_hda_add_nids(codec, kctl, i, spec->adc_nids,
349 spec->input_mux->num_items);
350 if (err < 0)
351 return err;
352 }
343 return 0; 353 return 0;
344} 354}
345 355
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index c578c28f368e..947785f43b28 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -2187,6 +2187,7 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2187 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 2187 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2188 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 2188 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2189 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, 2189 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2190 .subdevice = HDA_SUBDEV_AMP_FLAG,
2190 .info = snd_hda_mixer_amp_volume_info, 2191 .info = snd_hda_mixer_amp_volume_info,
2191 .get = snd_hda_mixer_amp_volume_get, 2192 .get = snd_hda_mixer_amp_volume_get,
2192 .put = snd_hda_mixer_amp_volume_put, 2193 .put = snd_hda_mixer_amp_volume_put,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index c7465053d6bb..aeb23ef6afe5 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -633,6 +633,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
633 633
634#define ALC_PIN_MODE(xname, nid, dir) \ 634#define ALC_PIN_MODE(xname, nid, dir) \
635 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 635 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
636 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
636 .info = alc_pin_mode_info, \ 637 .info = alc_pin_mode_info, \
637 .get = alc_pin_mode_get, \ 638 .get = alc_pin_mode_get, \
638 .put = alc_pin_mode_put, \ 639 .put = alc_pin_mode_put, \
@@ -684,6 +685,7 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
684} 685}
685#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 686#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
686 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 687 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
688 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
687 .info = alc_gpio_data_info, \ 689 .info = alc_gpio_data_info, \
688 .get = alc_gpio_data_get, \ 690 .get = alc_gpio_data_get, \
689 .put = alc_gpio_data_put, \ 691 .put = alc_gpio_data_put, \
@@ -738,6 +740,7 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
738} 740}
739#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 741#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
740 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 742 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
743 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
741 .info = alc_spdif_ctrl_info, \ 744 .info = alc_spdif_ctrl_info, \
742 .get = alc_spdif_ctrl_get, \ 745 .get = alc_spdif_ctrl_get, \
743 .put = alc_spdif_ctrl_put, \ 746 .put = alc_spdif_ctrl_put, \
@@ -791,6 +794,7 @@ static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
791 794
792#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 795#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
793 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 796 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
797 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
794 .info = alc_eapd_ctrl_info, \ 798 .info = alc_eapd_ctrl_info, \
795 .get = alc_eapd_ctrl_get, \ 799 .get = alc_eapd_ctrl_get, \
796 .put = alc_eapd_ctrl_put, \ 800 .put = alc_eapd_ctrl_put, \
@@ -2443,6 +2447,15 @@ static const char *alc_slave_sws[] = {
2443 * build control elements 2447 * build control elements
2444 */ 2448 */
2445 2449
2450#define NID_MAPPING (-1)
2451
2452#define SUBDEV_SPEAKER_ (0 << 6)
2453#define SUBDEV_HP_ (1 << 6)
2454#define SUBDEV_LINE_ (2 << 6)
2455#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2456#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2457#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2458
2446static void alc_free_kctls(struct hda_codec *codec); 2459static void alc_free_kctls(struct hda_codec *codec);
2447 2460
2448#ifdef CONFIG_SND_HDA_INPUT_BEEP 2461#ifdef CONFIG_SND_HDA_INPUT_BEEP
@@ -2457,8 +2470,11 @@ static struct snd_kcontrol_new alc_beep_mixer[] = {
2457static int alc_build_controls(struct hda_codec *codec) 2470static int alc_build_controls(struct hda_codec *codec)
2458{ 2471{
2459 struct alc_spec *spec = codec->spec; 2472 struct alc_spec *spec = codec->spec;
2460 int err; 2473 struct snd_kcontrol *kctl;
2461 int i; 2474 struct snd_kcontrol_new *knew;
2475 int i, j, err;
2476 unsigned int u;
2477 hda_nid_t nid;
2462 2478
2463 for (i = 0; i < spec->num_mixers; i++) { 2479 for (i = 0; i < spec->num_mixers; i++) {
2464 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 2480 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
@@ -2499,8 +2515,7 @@ static int alc_build_controls(struct hda_codec *codec)
2499 if (!kctl) 2515 if (!kctl)
2500 return -ENOMEM; 2516 return -ENOMEM;
2501 kctl->private_value = spec->beep_amp; 2517 kctl->private_value = spec->beep_amp;
2502 err = snd_hda_ctl_add(codec, 2518 err = snd_hda_ctl_add(codec, 0, kctl);
2503 get_amp_nid_(spec->beep_amp), kctl);
2504 if (err < 0) 2519 if (err < 0)
2505 return err; 2520 return err;
2506 } 2521 }
@@ -2527,6 +2542,73 @@ static int alc_build_controls(struct hda_codec *codec)
2527 } 2542 }
2528 2543
2529 alc_free_kctls(codec); /* no longer needed */ 2544 alc_free_kctls(codec); /* no longer needed */
2545
2546 /* assign Capture Source enums to NID */
2547 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2548 if (!kctl)
2549 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2550 for (i = 0; kctl && i < kctl->count; i++) {
2551 err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids,
2552 spec->input_mux->num_items);
2553 if (err < 0)
2554 return err;
2555 }
2556 if (spec->cap_mixer) {
2557 const char *kname = kctl ? kctl->id.name : NULL;
2558 for (knew = spec->cap_mixer; knew->name; knew++) {
2559 if (kname && strcmp(knew->name, kname) == 0)
2560 continue;
2561 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2562 for (i = 0; kctl && i < kctl->count; i++) {
2563 err = snd_hda_add_nid(codec, kctl, i,
2564 spec->adc_nids[i]);
2565 if (err < 0)
2566 return err;
2567 }
2568 }
2569 }
2570
2571 /* other nid->control mapping */
2572 for (i = 0; i < spec->num_mixers; i++) {
2573 for (knew = spec->mixers[i]; knew->name; knew++) {
2574 if (knew->iface != NID_MAPPING)
2575 continue;
2576 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2577 if (kctl == NULL)
2578 continue;
2579 u = knew->subdevice;
2580 for (j = 0; j < 4; j++, u >>= 8) {
2581 nid = u & 0x3f;
2582 if (nid == 0)
2583 continue;
2584 switch (u & 0xc0) {
2585 case SUBDEV_SPEAKER_:
2586 nid = spec->autocfg.speaker_pins[nid];
2587 break;
2588 case SUBDEV_LINE_:
2589 nid = spec->autocfg.line_out_pins[nid];
2590 break;
2591 case SUBDEV_HP_:
2592 nid = spec->autocfg.hp_pins[nid];
2593 break;
2594 default:
2595 continue;
2596 }
2597 err = snd_hda_add_nid(codec, kctl, 0, nid);
2598 if (err < 0)
2599 return err;
2600 }
2601 u = knew->private_value;
2602 for (j = 0; j < 4; j++, u >>= 8) {
2603 nid = u & 0xff;
2604 if (nid == 0)
2605 continue;
2606 err = snd_hda_add_nid(codec, kctl, 0, nid);
2607 if (err < 0)
2608 return err;
2609 }
2610 }
2611 }
2530 return 0; 2612 return 0;
2531} 2613}
2532 2614
@@ -3832,6 +3914,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3832#define PIN_CTL_TEST(xname,nid) { \ 3914#define PIN_CTL_TEST(xname,nid) { \
3833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3915 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3834 .name = xname, \ 3916 .name = xname, \
3917 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3835 .info = alc_test_pin_ctl_info, \ 3918 .info = alc_test_pin_ctl_info, \
3836 .get = alc_test_pin_ctl_get, \ 3919 .get = alc_test_pin_ctl_get, \
3837 .put = alc_test_pin_ctl_put, \ 3920 .put = alc_test_pin_ctl_put, \
@@ -3841,6 +3924,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3841#define PIN_SRC_TEST(xname,nid) { \ 3924#define PIN_SRC_TEST(xname,nid) { \
3842 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3925 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3843 .name = xname, \ 3926 .name = xname, \
3927 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3844 .info = alc_test_pin_src_info, \ 3928 .info = alc_test_pin_src_info, \
3845 .get = alc_test_pin_src_get, \ 3929 .get = alc_test_pin_src_get, \
3846 .put = alc_test_pin_src_put, \ 3930 .put = alc_test_pin_src_put, \
@@ -4380,7 +4464,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
4380 if (!knew->name) 4464 if (!knew->name)
4381 return -ENOMEM; 4465 return -ENOMEM;
4382 if (get_amp_nid_(val)) 4466 if (get_amp_nid_(val))
4383 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 4467 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
4384 knew->private_value = val; 4468 knew->private_value = val;
4385 return 0; 4469 return 0;
4386} 4470}
@@ -5131,6 +5215,7 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5131 { 5215 {
5132 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5216 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5133 .name = "Master Playback Switch", 5217 .name = "Master Playback Switch",
5218 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5134 .info = snd_ctl_boolean_mono_info, 5219 .info = snd_ctl_boolean_mono_info,
5135 .get = alc260_hp_master_sw_get, 5220 .get = alc260_hp_master_sw_get,
5136 .put = alc260_hp_master_sw_put, 5221 .put = alc260_hp_master_sw_put,
@@ -5169,6 +5254,7 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5169 { 5254 {
5170 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5255 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5171 .name = "Master Playback Switch", 5256 .name = "Master Playback Switch",
5257 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5172 .info = snd_ctl_boolean_mono_info, 5258 .info = snd_ctl_boolean_mono_info,
5173 .get = alc260_hp_master_sw_get, 5259 .get = alc260_hp_master_sw_get,
5174 .put = alc260_hp_master_sw_put, 5260 .put = alc260_hp_master_sw_put,
@@ -10248,8 +10334,14 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10248 .info = snd_ctl_boolean_mono_info, \ 10334 .info = snd_ctl_boolean_mono_info, \
10249 .get = alc262_hp_master_sw_get, \ 10335 .get = alc262_hp_master_sw_get, \
10250 .put = alc262_hp_master_sw_put, \ 10336 .put = alc262_hp_master_sw_put, \
10337 }, \
10338 { \
10339 .iface = NID_MAPPING, \
10340 .name = "Master Playback Switch", \
10341 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
10251 } 10342 }
10252 10343
10344
10253static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 10345static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10254 ALC262_HP_MASTER_SWITCH, 10346 ALC262_HP_MASTER_SWITCH,
10255 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10347 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -10407,6 +10499,12 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10407 .info = snd_ctl_boolean_mono_info, \ 10499 .info = snd_ctl_boolean_mono_info, \
10408 .get = alc262_hippo_master_sw_get, \ 10500 .get = alc262_hippo_master_sw_get, \
10409 .put = alc262_hippo_master_sw_put, \ 10501 .put = alc262_hippo_master_sw_put, \
10502 }, \
10503 { \
10504 .iface = NID_MAPPING, \
10505 .name = "Master Playback Switch", \
10506 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
10507 (SUBDEV_SPEAKER(0) << 16), \
10410 } 10508 }
10411 10509
10412static struct snd_kcontrol_new alc262_hippo_mixer[] = { 10510static struct snd_kcontrol_new alc262_hippo_mixer[] = {
@@ -10887,11 +10985,17 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10887 { 10985 {
10888 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10986 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10889 .name = "Master Playback Switch", 10987 .name = "Master Playback Switch",
10988 .subdevice = HDA_SUBDEV_AMP_FLAG,
10890 .info = snd_hda_mixer_amp_switch_info, 10989 .info = snd_hda_mixer_amp_switch_info,
10891 .get = snd_hda_mixer_amp_switch_get, 10990 .get = snd_hda_mixer_amp_switch_get,
10892 .put = alc262_fujitsu_master_sw_put, 10991 .put = alc262_fujitsu_master_sw_put,
10893 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 10992 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10894 }, 10993 },
10994 {
10995 .iface = NID_MAPPING,
10996 .name = "Master Playback Switch",
10997 .private_value = 0x1b,
10998 },
10895 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10999 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10896 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11000 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10897 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11001 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
@@ -10922,6 +11026,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10922 { 11026 {
10923 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11027 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10924 .name = "Master Playback Switch", 11028 .name = "Master Playback Switch",
11029 .subdevice = HDA_SUBDEV_AMP_FLAG,
10925 .info = snd_hda_mixer_amp_switch_info, 11030 .info = snd_hda_mixer_amp_switch_info,
10926 .get = snd_hda_mixer_amp_switch_get, 11031 .get = snd_hda_mixer_amp_switch_get,
10927 .put = alc262_lenovo_3000_master_sw_put, 11032 .put = alc262_lenovo_3000_master_sw_put,
@@ -11076,6 +11181,11 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11076 .get = alc_mux_enum_get, 11181 .get = alc_mux_enum_get,
11077 .put = alc262_ultra_mux_enum_put, 11182 .put = alc262_ultra_mux_enum_put,
11078 }, 11183 },
11184 {
11185 .iface = NID_MAPPING,
11186 .name = "Capture Source",
11187 .private_value = 0x15,
11188 },
11079 { } /* end */ 11189 { } /* end */
11080}; 11190};
11081 11191
@@ -12094,6 +12204,7 @@ static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12094 { 12204 {
12095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12096 .name = "Master Playback Switch", 12206 .name = "Master Playback Switch",
12207 .subdevice = HDA_SUBDEV_AMP_FLAG,
12097 .info = snd_hda_mixer_amp_switch_info, 12208 .info = snd_hda_mixer_amp_switch_info,
12098 .get = snd_hda_mixer_amp_switch_get, 12209 .get = snd_hda_mixer_amp_switch_get,
12099 .put = alc268_acer_master_sw_put, 12210 .put = alc268_acer_master_sw_put,
@@ -12109,6 +12220,7 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
12109 { 12220 {
12110 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12221 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12111 .name = "Master Playback Switch", 12222 .name = "Master Playback Switch",
12223 .subdevice = HDA_SUBDEV_AMP_FLAG,
12112 .info = snd_hda_mixer_amp_switch_info, 12224 .info = snd_hda_mixer_amp_switch_info,
12113 .get = snd_hda_mixer_amp_switch_get, 12225 .get = snd_hda_mixer_amp_switch_get,
12114 .put = alc268_acer_master_sw_put, 12226 .put = alc268_acer_master_sw_put,
@@ -12126,6 +12238,7 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12126 { 12238 {
12127 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12128 .name = "Master Playback Switch", 12240 .name = "Master Playback Switch",
12241 .subdevice = HDA_SUBDEV_AMP_FLAG,
12129 .info = snd_hda_mixer_amp_switch_info, 12242 .info = snd_hda_mixer_amp_switch_info,
12130 .get = snd_hda_mixer_amp_switch_get, 12243 .get = snd_hda_mixer_amp_switch_get,
12131 .put = alc268_acer_master_sw_put, 12244 .put = alc268_acer_master_sw_put,
@@ -13078,6 +13191,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13078 { 13191 {
13079 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13080 .name = "Master Playback Switch", 13193 .name = "Master Playback Switch",
13194 .subdevice = HDA_SUBDEV_AMP_FLAG,
13081 .info = snd_hda_mixer_amp_switch_info, 13195 .info = snd_hda_mixer_amp_switch_info,
13082 .get = snd_hda_mixer_amp_switch_get, 13196 .get = snd_hda_mixer_amp_switch_get,
13083 .put = alc268_acer_master_sw_put, 13197 .put = alc268_acer_master_sw_put,
@@ -13098,6 +13212,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13098 { 13212 {
13099 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13213 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13100 .name = "Master Playback Switch", 13214 .name = "Master Playback Switch",
13215 .subdevice = HDA_SUBDEV_AMP_FLAG,
13101 .info = snd_hda_mixer_amp_switch_info, 13216 .info = snd_hda_mixer_amp_switch_info,
13102 .get = snd_hda_mixer_amp_switch_get, 13217 .get = snd_hda_mixer_amp_switch_get,
13103 .put = alc268_acer_master_sw_put, 13218 .put = alc268_acer_master_sw_put,
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 43b436c5d01b..f419ee8d75f0 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -122,6 +122,7 @@ static int si3054_switch_put(struct snd_kcontrol *kcontrol,
122#define SI3054_KCONTROL(kname,reg,mask) { \ 122#define SI3054_KCONTROL(kname,reg,mask) { \
123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
124 .name = kname, \ 124 .name = kname, \
125 .subdevice = HDA_SUBDEV_NID_FLAG | reg, \
125 .info = si3054_switch_info, \ 126 .info = si3054_switch_info, \
126 .get = si3054_switch_get, \ 127 .get = si3054_switch_get, \
127 .put = si3054_switch_put, \ 128 .put = si3054_switch_put, \
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index eeda7beeb57a..74d5d333ed6c 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -2688,7 +2688,7 @@ static struct snd_kcontrol_new *
2688stac_control_new(struct sigmatel_spec *spec, 2688stac_control_new(struct sigmatel_spec *spec,
2689 struct snd_kcontrol_new *ktemp, 2689 struct snd_kcontrol_new *ktemp,
2690 const char *name, 2690 const char *name,
2691 hda_nid_t nid) 2691 unsigned int subdev)
2692{ 2692{
2693 struct snd_kcontrol_new *knew; 2693 struct snd_kcontrol_new *knew;
2694 2694
@@ -2704,8 +2704,7 @@ stac_control_new(struct sigmatel_spec *spec,
2704 spec->kctls.alloced--; 2704 spec->kctls.alloced--;
2705 return NULL; 2705 return NULL;
2706 } 2706 }
2707 if (nid) 2707 knew->subdevice = subdev;
2708 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
2709 return knew; 2708 return knew;
2710} 2709}
2711 2710
@@ -2715,7 +2714,7 @@ static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
2715 unsigned long val) 2714 unsigned long val)
2716{ 2715{
2717 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name, 2716 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name,
2718 get_amp_nid_(val)); 2717 HDA_SUBDEV_AMP_FLAG);
2719 if (!knew) 2718 if (!knew)
2720 return -ENOMEM; 2719 return -ENOMEM;
2721 knew->index = idx; 2720 knew->index = idx;
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index b70e26ad263f..de4839e46762 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -54,6 +54,8 @@
54#include "hda_codec.h" 54#include "hda_codec.h"
55#include "hda_local.h" 55#include "hda_local.h"
56 56
57#define NID_MAPPING (-1)
58
57/* amp values */ 59/* amp values */
58#define AMP_VAL_IDX_SHIFT 19 60#define AMP_VAL_IDX_SHIFT 19
59#define AMP_VAL_IDX_MASK (0x0f<<19) 61#define AMP_VAL_IDX_MASK (0x0f<<19)
@@ -157,6 +159,19 @@ struct via_spec {
157#endif 159#endif
158}; 160};
159 161
162static struct via_spec * via_new_spec(struct hda_codec *codec)
163{
164 struct via_spec *spec;
165
166 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
167 if (spec == NULL)
168 return NULL;
169
170 codec->spec = spec;
171 spec->codec = codec;
172 return spec;
173}
174
160static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) 175static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
161{ 176{
162 u32 vendor_id = codec->vendor_id; 177 u32 vendor_id = codec->vendor_id;
@@ -443,11 +458,27 @@ static int via_add_control(struct via_spec *spec, int type, const char *name,
443 if (!knew->name) 458 if (!knew->name)
444 return -ENOMEM; 459 return -ENOMEM;
445 if (get_amp_nid_(val)) 460 if (get_amp_nid_(val))
446 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 461 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
447 knew->private_value = val; 462 knew->private_value = val;
448 return 0; 463 return 0;
449} 464}
450 465
466static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
467 struct snd_kcontrol_new *tmpl)
468{
469 struct snd_kcontrol_new *knew;
470
471 snd_array_init(&spec->kctls, sizeof(*knew), 32);
472 knew = snd_array_new(&spec->kctls);
473 if (!knew)
474 return NULL;
475 *knew = *tmpl;
476 knew->name = kstrdup(tmpl->name, GFP_KERNEL);
477 if (!knew->name)
478 return NULL;
479 return 0;
480}
481
451static void via_free_kctls(struct hda_codec *codec) 482static void via_free_kctls(struct hda_codec *codec)
452{ 483{
453 struct via_spec *spec = codec->spec; 484 struct via_spec *spec = codec->spec;
@@ -1088,24 +1119,9 @@ static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
1088 struct snd_ctl_elem_value *ucontrol) 1119 struct snd_ctl_elem_value *ucontrol)
1089{ 1120{
1090 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1121 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1091 struct via_spec *spec = codec->spec; 1122 hda_nid_t nid = kcontrol->private_value;
1092 hda_nid_t nid;
1093 unsigned int pinsel; 1123 unsigned int pinsel;
1094 1124
1095 switch (spec->codec_type) {
1096 case VT1718S:
1097 nid = 0x34;
1098 break;
1099 case VT2002P:
1100 nid = 0x35;
1101 break;
1102 case VT1812:
1103 nid = 0x3d;
1104 break;
1105 default:
1106 nid = spec->autocfg.hp_pins[0];
1107 break;
1108 }
1109 /* use !! to translate conn sel 2 for VT1718S */ 1125 /* use !! to translate conn sel 2 for VT1718S */
1110 pinsel = !!snd_hda_codec_read(codec, nid, 0, 1126 pinsel = !!snd_hda_codec_read(codec, nid, 0,
1111 AC_VERB_GET_CONNECT_SEL, 1127 AC_VERB_GET_CONNECT_SEL,
@@ -1127,29 +1143,24 @@ static void activate_ctl(struct hda_codec *codec, const char *name, int active)
1127 } 1143 }
1128} 1144}
1129 1145
1146static hda_nid_t side_mute_channel(struct via_spec *spec)
1147{
1148 switch (spec->codec_type) {
1149 case VT1708: return 0x1b;
1150 case VT1709_10CH: return 0x29;
1151 case VT1708B_8CH: /* fall thru */
1152 case VT1708S: return 0x27;
1153 default: return 0;
1154 }
1155}
1156
1130static int update_side_mute_status(struct hda_codec *codec) 1157static int update_side_mute_status(struct hda_codec *codec)
1131{ 1158{
1132 /* mute side channel */ 1159 /* mute side channel */
1133 struct via_spec *spec = codec->spec; 1160 struct via_spec *spec = codec->spec;
1134 unsigned int parm = spec->hp_independent_mode 1161 unsigned int parm = spec->hp_independent_mode
1135 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE; 1162 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
1136 hda_nid_t sw3; 1163 hda_nid_t sw3 = side_mute_channel(spec);
1137
1138 switch (spec->codec_type) {
1139 case VT1708:
1140 sw3 = 0x1b;
1141 break;
1142 case VT1709_10CH:
1143 sw3 = 0x29;
1144 break;
1145 case VT1708B_8CH:
1146 case VT1708S:
1147 sw3 = 0x27;
1148 break;
1149 default:
1150 sw3 = 0;
1151 break;
1152 }
1153 1164
1154 if (sw3) 1165 if (sw3)
1155 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE, 1166 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE,
@@ -1162,28 +1173,11 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1162{ 1173{
1163 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1174 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1164 struct via_spec *spec = codec->spec; 1175 struct via_spec *spec = codec->spec;
1165 hda_nid_t nid = spec->autocfg.hp_pins[0]; 1176 hda_nid_t nid = kcontrol->private_value;
1166 unsigned int pinsel = ucontrol->value.enumerated.item[0]; 1177 unsigned int pinsel = ucontrol->value.enumerated.item[0];
1167 /* Get Independent Mode index of headphone pin widget */ 1178 /* Get Independent Mode index of headphone pin widget */
1168 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel 1179 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
1169 ? 1 : 0; 1180 ? 1 : 0;
1170
1171 switch (spec->codec_type) {
1172 case VT1718S:
1173 nid = 0x34;
1174 pinsel = pinsel ? 2 : 0; /* indep HP use AOW4 (index 2) */
1175 spec->multiout.num_dacs = 4;
1176 break;
1177 case VT2002P:
1178 nid = 0x35;
1179 break;
1180 case VT1812:
1181 nid = 0x3d;
1182 break;
1183 default:
1184 nid = spec->autocfg.hp_pins[0];
1185 break;
1186 }
1187 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel); 1181 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel);
1188 1182
1189 if (spec->multiout.hp_nid && spec->multiout.hp_nid 1183 if (spec->multiout.hp_nid && spec->multiout.hp_nid
@@ -1207,18 +1201,55 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1207 return 0; 1201 return 0;
1208} 1202}
1209 1203
1210static struct snd_kcontrol_new via_hp_mixer[] = { 1204static struct snd_kcontrol_new via_hp_mixer[2] = {
1211 { 1205 {
1212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1213 .name = "Independent HP", 1207 .name = "Independent HP",
1214 .count = 1,
1215 .info = via_independent_hp_info, 1208 .info = via_independent_hp_info,
1216 .get = via_independent_hp_get, 1209 .get = via_independent_hp_get,
1217 .put = via_independent_hp_put, 1210 .put = via_independent_hp_put,
1218 }, 1211 },
1219 { } /* end */ 1212 {
1213 .iface = NID_MAPPING,
1214 .name = "Independent HP",
1215 },
1220}; 1216};
1221 1217
1218static int via_hp_build(struct via_spec *spec)
1219{
1220 struct snd_kcontrol_new *knew;
1221 hda_nid_t nid;
1222
1223 knew = via_clone_control(spec, &via_hp_mixer[0]);
1224 if (knew == NULL)
1225 return -ENOMEM;
1226
1227 switch (spec->codec_type) {
1228 case VT1718S:
1229 nid = 0x34;
1230 break;
1231 case VT2002P:
1232 nid = 0x35;
1233 break;
1234 case VT1812:
1235 nid = 0x3d;
1236 break;
1237 default:
1238 nid = spec->autocfg.hp_pins[0];
1239 break;
1240 }
1241
1242 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
1243 knew->private_value = nid;
1244
1245 knew = via_clone_control(spec, &via_hp_mixer[1]);
1246 if (knew == NULL)
1247 return -ENOMEM;
1248 knew->subdevice = side_mute_channel(spec);
1249
1250 return 0;
1251}
1252
1222static void notify_aa_path_ctls(struct hda_codec *codec) 1253static void notify_aa_path_ctls(struct hda_codec *codec)
1223{ 1254{
1224 int i; 1255 int i;
@@ -1376,7 +1407,7 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
1376 return 1; 1407 return 1;
1377} 1408}
1378 1409
1379static struct snd_kcontrol_new via_smart51_mixer[] = { 1410static struct snd_kcontrol_new via_smart51_mixer[2] = {
1380 { 1411 {
1381 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1412 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1382 .name = "Smart 5.1", 1413 .name = "Smart 5.1",
@@ -1385,9 +1416,36 @@ static struct snd_kcontrol_new via_smart51_mixer[] = {
1385 .get = via_smart51_get, 1416 .get = via_smart51_get,
1386 .put = via_smart51_put, 1417 .put = via_smart51_put,
1387 }, 1418 },
1388 {} /* end */ 1419 {
1420 .iface = NID_MAPPING,
1421 .name = "Smart 5.1",
1422 }
1389}; 1423};
1390 1424
1425static int via_smart51_build(struct via_spec *spec)
1426{
1427 struct snd_kcontrol_new *knew;
1428 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1429 hda_nid_t nid;
1430 int i;
1431
1432 knew = via_clone_control(spec, &via_smart51_mixer[0]);
1433 if (knew == NULL)
1434 return -ENOMEM;
1435
1436 for (i = 0; i < ARRAY_SIZE(index); i++) {
1437 nid = spec->autocfg.input_pins[index[i]];
1438 if (nid) {
1439 knew = via_clone_control(spec, &via_smart51_mixer[1]);
1440 if (knew == NULL)
1441 return -ENOMEM;
1442 knew->subdevice = nid;
1443 }
1444 }
1445
1446 return 0;
1447}
1448
1391/* capture mixer elements */ 1449/* capture mixer elements */
1392static struct snd_kcontrol_new vt1708_capture_mixer[] = { 1450static struct snd_kcontrol_new vt1708_capture_mixer[] = {
1393 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), 1451 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
@@ -1819,8 +1877,9 @@ static struct hda_pcm_stream vt1708_pcm_digital_capture = {
1819static int via_build_controls(struct hda_codec *codec) 1877static int via_build_controls(struct hda_codec *codec)
1820{ 1878{
1821 struct via_spec *spec = codec->spec; 1879 struct via_spec *spec = codec->spec;
1822 int err; 1880 struct snd_kcontrol *kctl;
1823 int i; 1881 struct snd_kcontrol_new *knew;
1882 int err, i;
1824 1883
1825 for (i = 0; i < spec->num_mixers; i++) { 1884 for (i = 0; i < spec->num_mixers; i++) {
1826 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1885 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
@@ -1845,6 +1904,28 @@ static int via_build_controls(struct hda_codec *codec)
1845 return err; 1904 return err;
1846 } 1905 }
1847 1906
1907 /* assign Capture Source enums to NID */
1908 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1909 for (i = 0; kctl && i < kctl->count; i++) {
1910 err = snd_hda_add_nids(codec, kctl, i, spec->mux_nids,
1911 spec->input_mux->num_items);
1912 if (err < 0)
1913 return err;
1914 }
1915
1916 /* other nid->control mapping */
1917 for (i = 0; i < spec->num_mixers; i++) {
1918 for (knew = spec->mixers[i]; knew->name; knew++) {
1919 if (knew->iface != NID_MAPPING)
1920 continue;
1921 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1922 if (kctl == NULL)
1923 continue;
1924 err = snd_hda_add_nid(codec, kctl, 0,
1925 knew->subdevice);
1926 }
1927 }
1928
1848 /* init power states */ 1929 /* init power states */
1849 set_jack_power_state(codec); 1930 set_jack_power_state(codec);
1850 analog_low_current_mode(codec, 1); 1931 analog_low_current_mode(codec, 1);
@@ -2481,9 +2562,9 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
2481 spec->input_mux = &spec->private_imux[0]; 2562 spec->input_mux = &spec->private_imux[0];
2482 2563
2483 if (spec->hp_mux) 2564 if (spec->hp_mux)
2484 spec->mixers[spec->num_mixers++] = via_hp_mixer; 2565 via_hp_build(spec);
2485 2566
2486 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 2567 via_smart51_build(spec);
2487 return 1; 2568 return 1;
2488} 2569}
2489 2570
@@ -2554,12 +2635,10 @@ static int patch_vt1708(struct hda_codec *codec)
2554 int err; 2635 int err;
2555 2636
2556 /* create a codec specific record */ 2637 /* create a codec specific record */
2557 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 2638 spec = via_new_spec(codec);
2558 if (spec == NULL) 2639 if (spec == NULL)
2559 return -ENOMEM; 2640 return -ENOMEM;
2560 2641
2561 codec->spec = spec;
2562
2563 /* automatic parse from the BIOS config */ 2642 /* automatic parse from the BIOS config */
2564 err = vt1708_parse_auto_config(codec); 2643 err = vt1708_parse_auto_config(codec);
2565 if (err < 0) { 2644 if (err < 0) {
@@ -2597,7 +2676,6 @@ static int patch_vt1708(struct hda_codec *codec)
2597#ifdef CONFIG_SND_HDA_POWER_SAVE 2676#ifdef CONFIG_SND_HDA_POWER_SAVE
2598 spec->loopback.amplist = vt1708_loopbacks; 2677 spec->loopback.amplist = vt1708_loopbacks;
2599#endif 2678#endif
2600 spec->codec = codec;
2601 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); 2679 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2602 return 0; 2680 return 0;
2603} 2681}
@@ -3010,9 +3088,9 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
3010 spec->input_mux = &spec->private_imux[0]; 3088 spec->input_mux = &spec->private_imux[0];
3011 3089
3012 if (spec->hp_mux) 3090 if (spec->hp_mux)
3013 spec->mixers[spec->num_mixers++] = via_hp_mixer; 3091 via_hp_build(spec);
3014 3092
3015 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 3093 via_smart51_build(spec);
3016 return 1; 3094 return 1;
3017} 3095}
3018 3096
@@ -3032,12 +3110,10 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
3032 int err; 3110 int err;
3033 3111
3034 /* create a codec specific record */ 3112 /* create a codec specific record */
3035 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3113 spec = via_new_spec(codec);
3036 if (spec == NULL) 3114 if (spec == NULL)
3037 return -ENOMEM; 3115 return -ENOMEM;
3038 3116
3039 codec->spec = spec;
3040
3041 err = vt1709_parse_auto_config(codec); 3117 err = vt1709_parse_auto_config(codec);
3042 if (err < 0) { 3118 if (err < 0) {
3043 via_free(codec); 3119 via_free(codec);
@@ -3126,12 +3202,10 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
3126 int err; 3202 int err;
3127 3203
3128 /* create a codec specific record */ 3204 /* create a codec specific record */
3129 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3205 spec = via_new_spec(codec);
3130 if (spec == NULL) 3206 if (spec == NULL)
3131 return -ENOMEM; 3207 return -ENOMEM;
3132 3208
3133 codec->spec = spec;
3134
3135 err = vt1709_parse_auto_config(codec); 3209 err = vt1709_parse_auto_config(codec);
3136 if (err < 0) { 3210 if (err < 0) {
3137 via_free(codec); 3211 via_free(codec);
@@ -3581,9 +3655,9 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
3581 spec->input_mux = &spec->private_imux[0]; 3655 spec->input_mux = &spec->private_imux[0];
3582 3656
3583 if (spec->hp_mux) 3657 if (spec->hp_mux)
3584 spec->mixers[spec->num_mixers++] = via_hp_mixer; 3658 via_hp_build(spec);
3585 3659
3586 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 3660 via_smart51_build(spec);
3587 return 1; 3661 return 1;
3588} 3662}
3589 3663
@@ -3605,12 +3679,10 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
3605 if (get_codec_type(codec) == VT1708BCE) 3679 if (get_codec_type(codec) == VT1708BCE)
3606 return patch_vt1708S(codec); 3680 return patch_vt1708S(codec);
3607 /* create a codec specific record */ 3681 /* create a codec specific record */
3608 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3682 spec = via_new_spec(codec);
3609 if (spec == NULL) 3683 if (spec == NULL)
3610 return -ENOMEM; 3684 return -ENOMEM;
3611 3685
3612 codec->spec = spec;
3613
3614 /* automatic parse from the BIOS config */ 3686 /* automatic parse from the BIOS config */
3615 err = vt1708B_parse_auto_config(codec); 3687 err = vt1708B_parse_auto_config(codec);
3616 if (err < 0) { 3688 if (err < 0) {
@@ -3657,12 +3729,10 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
3657 int err; 3729 int err;
3658 3730
3659 /* create a codec specific record */ 3731 /* create a codec specific record */
3660 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3732 spec = via_new_spec(codec);
3661 if (spec == NULL) 3733 if (spec == NULL)
3662 return -ENOMEM; 3734 return -ENOMEM;
3663 3735
3664 codec->spec = spec;
3665
3666 /* automatic parse from the BIOS config */ 3736 /* automatic parse from the BIOS config */
3667 err = vt1708B_parse_auto_config(codec); 3737 err = vt1708B_parse_auto_config(codec);
3668 if (err < 0) { 3738 if (err < 0) {
@@ -4071,9 +4141,9 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
4071 spec->input_mux = &spec->private_imux[0]; 4141 spec->input_mux = &spec->private_imux[0];
4072 4142
4073 if (spec->hp_mux) 4143 if (spec->hp_mux)
4074 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4144 via_hp_build(spec);
4075 4145
4076 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 4146 via_smart51_build(spec);
4077 return 1; 4147 return 1;
4078} 4148}
4079 4149
@@ -4103,12 +4173,10 @@ static int patch_vt1708S(struct hda_codec *codec)
4103 int err; 4173 int err;
4104 4174
4105 /* create a codec specific record */ 4175 /* create a codec specific record */
4106 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4176 spec = via_new_spec(codec);
4107 if (spec == NULL) 4177 if (spec == NULL)
4108 return -ENOMEM; 4178 return -ENOMEM;
4109 4179
4110 codec->spec = spec;
4111
4112 /* automatic parse from the BIOS config */ 4180 /* automatic parse from the BIOS config */
4113 err = vt1708S_parse_auto_config(codec); 4181 err = vt1708S_parse_auto_config(codec);
4114 if (err < 0) { 4182 if (err < 0) {
@@ -4443,7 +4511,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
4443 spec->input_mux = &spec->private_imux[0]; 4511 spec->input_mux = &spec->private_imux[0];
4444 4512
4445 if (spec->hp_mux) 4513 if (spec->hp_mux)
4446 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4514 via_hp_build(spec);
4447 4515
4448 return 1; 4516 return 1;
4449} 4517}
@@ -4464,12 +4532,10 @@ static int patch_vt1702(struct hda_codec *codec)
4464 int err; 4532 int err;
4465 4533
4466 /* create a codec specific record */ 4534 /* create a codec specific record */
4467 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4535 spec = via_new_spec(codec);
4468 if (spec == NULL) 4536 if (spec == NULL)
4469 return -ENOMEM; 4537 return -ENOMEM;
4470 4538
4471 codec->spec = spec;
4472
4473 /* automatic parse from the BIOS config */ 4539 /* automatic parse from the BIOS config */
4474 err = vt1702_parse_auto_config(codec); 4540 err = vt1702_parse_auto_config(codec);
4475 if (err < 0) { 4541 if (err < 0) {
@@ -4865,9 +4931,9 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
4865 spec->input_mux = &spec->private_imux[0]; 4931 spec->input_mux = &spec->private_imux[0];
4866 4932
4867 if (spec->hp_mux) 4933 if (spec->hp_mux)
4868 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4934 via_hp_build(spec);
4869 4935
4870 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 4936 via_smart51_build(spec);
4871 4937
4872 return 1; 4938 return 1;
4873} 4939}
@@ -4888,12 +4954,10 @@ static int patch_vt1718S(struct hda_codec *codec)
4888 int err; 4954 int err;
4889 4955
4890 /* create a codec specific record */ 4956 /* create a codec specific record */
4891 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4957 spec = via_new_spec(codec);
4892 if (spec == NULL) 4958 if (spec == NULL)
4893 return -ENOMEM; 4959 return -ENOMEM;
4894 4960
4895 codec->spec = spec;
4896
4897 /* automatic parse from the BIOS config */ 4961 /* automatic parse from the BIOS config */
4898 err = vt1718S_parse_auto_config(codec); 4962 err = vt1718S_parse_auto_config(codec);
4899 if (err < 0) { 4963 if (err < 0) {
@@ -5014,6 +5078,7 @@ static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
5014 { 5078 {
5015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5079 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5016 .name = "Digital Mic Capture Switch", 5080 .name = "Digital Mic Capture Switch",
5081 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
5017 .count = 1, 5082 .count = 1,
5018 .info = vt1716s_dmic_info, 5083 .info = vt1716s_dmic_info,
5019 .get = vt1716s_dmic_get, 5084 .get = vt1716s_dmic_get,
@@ -5361,9 +5426,9 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
5361 spec->input_mux = &spec->private_imux[0]; 5426 spec->input_mux = &spec->private_imux[0];
5362 5427
5363 if (spec->hp_mux) 5428 if (spec->hp_mux)
5364 spec->mixers[spec->num_mixers++] = via_hp_mixer; 5429 via_hp_build(spec);
5365 5430
5366 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 5431 via_smart51_build(spec);
5367 5432
5368 return 1; 5433 return 1;
5369} 5434}
@@ -5384,12 +5449,10 @@ static int patch_vt1716S(struct hda_codec *codec)
5384 int err; 5449 int err;
5385 5450
5386 /* create a codec specific record */ 5451 /* create a codec specific record */
5387 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5452 spec = via_new_spec(codec);
5388 if (spec == NULL) 5453 if (spec == NULL)
5389 return -ENOMEM; 5454 return -ENOMEM;
5390 5455
5391 codec->spec = spec;
5392
5393 /* automatic parse from the BIOS config */ 5456 /* automatic parse from the BIOS config */
5394 err = vt1716S_parse_auto_config(codec); 5457 err = vt1716S_parse_auto_config(codec);
5395 if (err < 0) { 5458 if (err < 0) {
@@ -5719,7 +5782,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
5719 spec->input_mux = &spec->private_imux[0]; 5782 spec->input_mux = &spec->private_imux[0];
5720 5783
5721 if (spec->hp_mux) 5784 if (spec->hp_mux)
5722 spec->mixers[spec->num_mixers++] = via_hp_mixer; 5785 via_hp_build(spec);
5723 5786
5724 return 1; 5787 return 1;
5725} 5788}
@@ -5741,12 +5804,10 @@ static int patch_vt2002P(struct hda_codec *codec)
5741 int err; 5804 int err;
5742 5805
5743 /* create a codec specific record */ 5806 /* create a codec specific record */
5744 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5807 spec = via_new_spec(codec);
5745 if (spec == NULL) 5808 if (spec == NULL)
5746 return -ENOMEM; 5809 return -ENOMEM;
5747 5810
5748 codec->spec = spec;
5749
5750 /* automatic parse from the BIOS config */ 5811 /* automatic parse from the BIOS config */
5751 err = vt2002P_parse_auto_config(codec); 5812 err = vt2002P_parse_auto_config(codec);
5752 if (err < 0) { 5813 if (err < 0) {
@@ -6070,7 +6131,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
6070 spec->input_mux = &spec->private_imux[0]; 6131 spec->input_mux = &spec->private_imux[0];
6071 6132
6072 if (spec->hp_mux) 6133 if (spec->hp_mux)
6073 spec->mixers[spec->num_mixers++] = via_hp_mixer; 6134 via_hp_build(spec);
6074 6135
6075 return 1; 6136 return 1;
6076} 6137}
@@ -6092,12 +6153,10 @@ static int patch_vt1812(struct hda_codec *codec)
6092 int err; 6153 int err;
6093 6154
6094 /* create a codec specific record */ 6155 /* create a codec specific record */
6095 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 6156 spec = via_new_spec(codec);
6096 if (spec == NULL) 6157 if (spec == NULL)
6097 return -ENOMEM; 6158 return -ENOMEM;
6098 6159
6099 codec->spec = spec;
6100
6101 /* automatic parse from the BIOS config */ 6160 /* automatic parse from the BIOS config */
6102 err = vt1812_parse_auto_config(codec); 6161 err = vt1812_parse_auto_config(codec);
6103 if (err < 0) { 6162 if (err < 0) {