aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-05-22 04:01:29 -0400
committerTakashi Iwai <tiwai@suse.de>2011-05-22 04:01:29 -0400
commit02e5fbf622aabf68bdc02282a17a3aeed054237a (patch)
tree60f2d4e09464dbf338c832bb39f861f29779b86b /sound
parentb759b3ac9aee3afb01c21b603970ebb200c8048e (diff)
parentbfe9fc8aebc997ce8bcf8ac0586c84a247812064 (diff)
Merge branch 'topic/misc' into for-linus
Diffstat (limited to 'sound')
-rw-r--r--sound/core/control.c64
-rw-r--r--sound/core/init.c2
-rw-r--r--sound/core/pcm_lib.c14
-rw-r--r--sound/firewire/Kconfig11
-rw-r--r--sound/firewire/Makefile2
-rw-r--r--sound/firewire/isight.c755
-rw-r--r--sound/firewire/iso-resources.c5
-rw-r--r--sound/firewire/packets-buffer.c2
-rw-r--r--sound/i2c/other/Makefile2
-rw-r--r--sound/i2c/other/tea575x-tuner.c153
-rw-r--r--sound/pci/Kconfig18
-rw-r--r--sound/pci/asihpi/asihpi.c328
-rw-r--r--sound/pci/asihpi/hpi6000.c39
-rw-r--r--sound/pci/asihpi/hpi6205.c95
-rw-r--r--sound/pci/asihpi/hpi_internal.h19
-rw-r--r--sound/pci/asihpi/hpicmn.c10
-rw-r--r--sound/pci/asihpi/hpicmn.h2
-rw-r--r--sound/pci/asihpi/hpifunc.c27
-rw-r--r--sound/pci/asihpi/hpimsgx.c31
-rw-r--r--sound/pci/asihpi/hpioctl.c63
-rw-r--r--sound/pci/au88x0/au8810.h2
-rw-r--r--sound/pci/au88x0/au8820.h2
-rw-r--r--sound/pci/au88x0/au8830.h2
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c13
-rw-r--r--sound/pci/emu10k1/emufx.c5
-rw-r--r--sound/pci/emu10k1/emumixer.c10
-rw-r--r--sound/pci/es1968.c78
-rw-r--r--sound/pci/fm801.c371
-rw-r--r--sound/pci/intel8x0m.c4
-rw-r--r--sound/ppc/tumbler.c2
-rw-r--r--sound/usb/6fire/control.c105
-rw-r--r--sound/usb/6fire/control.h17
-rw-r--r--sound/usb/6fire/firmware.c73
-rw-r--r--sound/usb/6fire/pcm.c97
-rw-r--r--sound/usb/Kconfig10
-rw-r--r--sound/usb/clock.c11
-rw-r--r--sound/usb/debug.h2
-rw-r--r--sound/usb/format.c1
-rw-r--r--sound/usb/mixer.c10
-rw-r--r--sound/usb/mixer_quirks.c12
-rw-r--r--sound/usb/quirks-table.h47
-rw-r--r--sound/usb/quirks.c1
42 files changed, 1697 insertions, 820 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index a08ad57c49b6..5d98194bcad5 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -366,6 +366,70 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
366EXPORT_SYMBOL(snd_ctl_add); 366EXPORT_SYMBOL(snd_ctl_add);
367 367
368/** 368/**
369 * snd_ctl_replace - replace the control instance of the card
370 * @card: the card instance
371 * @kcontrol: the control instance to replace
372 * @add_on_replace: add the control if not already added
373 *
374 * Replaces the given control. If the given control does not exist
375 * and the add_on_replace flag is set, the control is added. If the
376 * control exists, it is destroyed first.
377 *
378 * Returns zero if successful, or a negative error code on failure.
379 *
380 * It frees automatically the control which cannot be added or replaced.
381 */
382int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol,
383 bool add_on_replace)
384{
385 struct snd_ctl_elem_id id;
386 unsigned int idx;
387 struct snd_kcontrol *old;
388 int ret;
389
390 if (!kcontrol)
391 return -EINVAL;
392 if (snd_BUG_ON(!card || !kcontrol->info)) {
393 ret = -EINVAL;
394 goto error;
395 }
396 id = kcontrol->id;
397 down_write(&card->controls_rwsem);
398 old = snd_ctl_find_id(card, &id);
399 if (!old) {
400 if (add_on_replace)
401 goto add;
402 up_write(&card->controls_rwsem);
403 ret = -EINVAL;
404 goto error;
405 }
406 ret = snd_ctl_remove(card, old);
407 if (ret < 0) {
408 up_write(&card->controls_rwsem);
409 goto error;
410 }
411add:
412 if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
413 up_write(&card->controls_rwsem);
414 ret = -ENOMEM;
415 goto error;
416 }
417 list_add_tail(&kcontrol->list, &card->controls);
418 card->controls_count += kcontrol->count;
419 kcontrol->id.numid = card->last_numid + 1;
420 card->last_numid += kcontrol->count;
421 up_write(&card->controls_rwsem);
422 for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
423 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
424 return 0;
425
426error:
427 snd_ctl_free_one(kcontrol);
428 return ret;
429}
430EXPORT_SYMBOL(snd_ctl_replace);
431
432/**
369 * snd_ctl_remove - remove the control from the card and release it 433 * snd_ctl_remove - remove the control from the card and release it
370 * @card: the card instance 434 * @card: the card instance
371 * @kcontrol: the control instance to remove 435 * @kcontrol: the control instance to remove
diff --git a/sound/core/init.c b/sound/core/init.c
index a0080aa45ae9..30ecad41403c 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -514,7 +514,7 @@ static void snd_card_set_id_no_lock(struct snd_card *card, const char *nid)
514 id = card->id; 514 id = card->id;
515 515
516 if (*id == '\0') 516 if (*id == '\0')
517 strcpy(id, "default"); 517 strcpy(id, "Default");
518 518
519 while (1) { 519 while (1) {
520 if (loops-- == 0) { 520 if (loops-- == 0) {
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 64449cb8f873..abfeff1611ce 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -189,6 +189,7 @@ static void xrun(struct snd_pcm_substream *substream)
189#define XRUN_LOG_CNT 10 189#define XRUN_LOG_CNT 10
190 190
191struct hwptr_log_entry { 191struct hwptr_log_entry {
192 unsigned int in_interrupt;
192 unsigned long jiffies; 193 unsigned long jiffies;
193 snd_pcm_uframes_t pos; 194 snd_pcm_uframes_t pos;
194 snd_pcm_uframes_t period_size; 195 snd_pcm_uframes_t period_size;
@@ -204,7 +205,7 @@ struct snd_pcm_hwptr_log {
204}; 205};
205 206
206static void xrun_log(struct snd_pcm_substream *substream, 207static void xrun_log(struct snd_pcm_substream *substream,
207 snd_pcm_uframes_t pos) 208 snd_pcm_uframes_t pos, int in_interrupt)
208{ 209{
209 struct snd_pcm_runtime *runtime = substream->runtime; 210 struct snd_pcm_runtime *runtime = substream->runtime;
210 struct snd_pcm_hwptr_log *log = runtime->hwptr_log; 211 struct snd_pcm_hwptr_log *log = runtime->hwptr_log;
@@ -220,6 +221,7 @@ static void xrun_log(struct snd_pcm_substream *substream,
220 return; 221 return;
221 } 222 }
222 entry = &log->entries[log->idx]; 223 entry = &log->entries[log->idx];
224 entry->in_interrupt = in_interrupt;
223 entry->jiffies = jiffies; 225 entry->jiffies = jiffies;
224 entry->pos = pos; 226 entry->pos = pos;
225 entry->period_size = runtime->period_size; 227 entry->period_size = runtime->period_size;
@@ -246,9 +248,11 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
246 entry = &log->entries[idx]; 248 entry = &log->entries[idx];
247 if (entry->period_size == 0) 249 if (entry->period_size == 0)
248 break; 250 break;
249 snd_printd("hwptr log: %s: j=%lu, pos=%ld/%ld/%ld, " 251 snd_printd("hwptr log: %s: %sj=%lu, pos=%ld/%ld/%ld, "
250 "hwptr=%ld/%ld\n", 252 "hwptr=%ld/%ld\n",
251 name, entry->jiffies, (unsigned long)entry->pos, 253 name, entry->in_interrupt ? "[Q] " : "",
254 entry->jiffies,
255 (unsigned long)entry->pos,
252 (unsigned long)entry->period_size, 256 (unsigned long)entry->period_size,
253 (unsigned long)entry->buffer_size, 257 (unsigned long)entry->buffer_size,
254 (unsigned long)entry->old_hw_ptr, 258 (unsigned long)entry->old_hw_ptr,
@@ -262,7 +266,7 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
262#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */ 266#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */
263 267
264#define hw_ptr_error(substream, fmt, args...) do { } while (0) 268#define hw_ptr_error(substream, fmt, args...) do { } while (0)
265#define xrun_log(substream, pos) do { } while (0) 269#define xrun_log(substream, pos, in_interrupt) do { } while (0)
266#define xrun_log_show(substream) do { } while (0) 270#define xrun_log_show(substream) do { } while (0)
267 271
268#endif 272#endif
@@ -326,7 +330,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
326 } 330 }
327 pos -= pos % runtime->min_align; 331 pos -= pos % runtime->min_align;
328 if (xrun_debug(substream, XRUN_DEBUG_LOG)) 332 if (xrun_debug(substream, XRUN_DEBUG_LOG))
329 xrun_log(substream, pos); 333 xrun_log(substream, pos, in_interrupt);
330 hw_base = runtime->hw_ptr_base; 334 hw_base = runtime->hw_ptr_base;
331 new_hw_ptr = hw_base + pos; 335 new_hw_ptr = hw_base + pos;
332 if (in_interrupt) { 336 if (in_interrupt) {
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
index e486f48660fb..26071489970b 100644
--- a/sound/firewire/Kconfig
+++ b/sound/firewire/Kconfig
@@ -22,4 +22,15 @@ config SND_FIREWIRE_SPEAKERS
22 To compile this driver as a module, choose M here: the module 22 To compile this driver as a module, choose M here: the module
23 will be called snd-firewire-speakers. 23 will be called snd-firewire-speakers.
24 24
25config SND_ISIGHT
26 tristate "Apple iSight microphone"
27 select SND_PCM
28 select SND_FIREWIRE_LIB
29 help
30 Say Y here to include support for the front and rear microphones
31 of the Apple iSight web camera.
32
33 To compile this driver as a module, choose M here: the module
34 will be called snd-isight.
35
25endif # SND_FIREWIRE 36endif # SND_FIREWIRE
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile
index e5b1634d9ad4..d71ed8935f76 100644
--- a/sound/firewire/Makefile
+++ b/sound/firewire/Makefile
@@ -1,6 +1,8 @@
1snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \ 1snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \
2 fcp.o cmp.o amdtp.o 2 fcp.o cmp.o amdtp.o
3snd-firewire-speakers-objs := speakers.o 3snd-firewire-speakers-objs := speakers.o
4snd-isight-objs := isight.o
4 5
5obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o 6obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o
6obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o 7obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o
8obj-$(CONFIG_SND_ISIGHT) += snd-isight.o
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c
new file mode 100644
index 000000000000..86ee16ca365e
--- /dev/null
+++ b/sound/firewire/isight.c
@@ -0,0 +1,755 @@
1/*
2 * Apple iSight audio driver
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
8#include <asm/byteorder.h>
9#include <linux/delay.h>
10#include <linux/device.h>
11#include <linux/firewire.h>
12#include <linux/firewire-constants.h>
13#include <linux/module.h>
14#include <linux/mod_devicetable.h>
15#include <linux/mutex.h>
16#include <linux/string.h>
17#include <sound/control.h>
18#include <sound/core.h>
19#include <sound/initval.h>
20#include <sound/pcm.h>
21#include <sound/tlv.h>
22#include "lib.h"
23#include "iso-resources.h"
24#include "packets-buffer.h"
25
26#define OUI_APPLE 0x000a27
27#define MODEL_APPLE_ISIGHT 0x000008
28#define SW_ISIGHT_AUDIO 0x000010
29
30#define REG_AUDIO_ENABLE 0x000
31#define AUDIO_ENABLE 0x80000000
32#define REG_DEF_AUDIO_GAIN 0x204
33#define REG_GAIN_RAW_START 0x210
34#define REG_GAIN_RAW_END 0x214
35#define REG_GAIN_DB_START 0x218
36#define REG_GAIN_DB_END 0x21c
37#define REG_SAMPLE_RATE_INQUIRY 0x280
38#define REG_ISO_TX_CONFIG 0x300
39#define SPEED_SHIFT 16
40#define REG_SAMPLE_RATE 0x400
41#define RATE_48000 0x80000000
42#define REG_GAIN 0x500
43#define REG_MUTE 0x504
44
45#define MAX_FRAMES_PER_PACKET 475
46
47#define QUEUE_LENGTH 20
48
49struct isight {
50 struct snd_card *card;
51 struct fw_unit *unit;
52 struct fw_device *device;
53 u64 audio_base;
54 struct fw_address_handler iris_handler;
55 struct snd_pcm_substream *pcm;
56 struct mutex mutex;
57 struct iso_packets_buffer buffer;
58 struct fw_iso_resources resources;
59 struct fw_iso_context *context;
60 bool pcm_active;
61 bool pcm_running;
62 bool first_packet;
63 int packet_index;
64 u32 total_samples;
65 unsigned int buffer_pointer;
66 unsigned int period_counter;
67 s32 gain_min, gain_max;
68 unsigned int gain_tlv[4];
69};
70
71struct audio_payload {
72 __be32 sample_count;
73 __be32 signature;
74 __be32 sample_total;
75 __be32 reserved;
76 __be16 samples[2 * MAX_FRAMES_PER_PACKET];
77};
78
79MODULE_DESCRIPTION("iSight audio driver");
80MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
81MODULE_LICENSE("GPL v2");
82
83static struct fw_iso_packet audio_packet = {
84 .payload_length = sizeof(struct audio_payload),
85 .interrupt = 1,
86 .header_length = 4,
87};
88
89static void isight_update_pointers(struct isight *isight, unsigned int count)
90{
91 struct snd_pcm_runtime *runtime = isight->pcm->runtime;
92 unsigned int ptr;
93
94 smp_wmb(); /* update buffer data before buffer pointer */
95
96 ptr = isight->buffer_pointer;
97 ptr += count;
98 if (ptr >= runtime->buffer_size)
99 ptr -= runtime->buffer_size;
100 ACCESS_ONCE(isight->buffer_pointer) = ptr;
101
102 isight->period_counter += count;
103 if (isight->period_counter >= runtime->period_size) {
104 isight->period_counter -= runtime->period_size;
105 snd_pcm_period_elapsed(isight->pcm);
106 }
107}
108
109static void isight_samples(struct isight *isight,
110 const __be16 *samples, unsigned int count)
111{
112 struct snd_pcm_runtime *runtime;
113 unsigned int count1;
114
115 if (!ACCESS_ONCE(isight->pcm_running))
116 return;
117
118 runtime = isight->pcm->runtime;
119 if (isight->buffer_pointer + count <= runtime->buffer_size) {
120 memcpy(runtime->dma_area + isight->buffer_pointer * 4,
121 samples, count * 4);
122 } else {
123 count1 = runtime->buffer_size - isight->buffer_pointer;
124 memcpy(runtime->dma_area + isight->buffer_pointer * 4,
125 samples, count1 * 4);
126 samples += count1 * 2;
127 memcpy(runtime->dma_area, samples, (count - count1) * 4);
128 }
129
130 isight_update_pointers(isight, count);
131}
132
133static void isight_pcm_abort(struct isight *isight)
134{
135 unsigned long flags;
136
137 if (ACCESS_ONCE(isight->pcm_active)) {
138 snd_pcm_stream_lock_irqsave(isight->pcm, flags);
139 if (snd_pcm_running(isight->pcm))
140 snd_pcm_stop(isight->pcm, SNDRV_PCM_STATE_XRUN);
141 snd_pcm_stream_unlock_irqrestore(isight->pcm, flags);
142 }
143}
144
145static void isight_dropped_samples(struct isight *isight, unsigned int total)
146{
147 struct snd_pcm_runtime *runtime;
148 u32 dropped;
149 unsigned int count1;
150
151 if (!ACCESS_ONCE(isight->pcm_running))
152 return;
153
154 runtime = isight->pcm->runtime;
155 dropped = total - isight->total_samples;
156 if (dropped < runtime->buffer_size) {
157 if (isight->buffer_pointer + dropped <= runtime->buffer_size) {
158 memset(runtime->dma_area + isight->buffer_pointer * 4,
159 0, dropped * 4);
160 } else {
161 count1 = runtime->buffer_size - isight->buffer_pointer;
162 memset(runtime->dma_area + isight->buffer_pointer * 4,
163 0, count1 * 4);
164 memset(runtime->dma_area, 0, (dropped - count1) * 4);
165 }
166 isight_update_pointers(isight, dropped);
167 } else {
168 isight_pcm_abort(isight);
169 }
170}
171
172static void isight_packet(struct fw_iso_context *context, u32 cycle,
173 size_t header_length, void *header, void *data)
174{
175 struct isight *isight = data;
176 const struct audio_payload *payload;
177 unsigned int index, length, count, total;
178 int err;
179
180 if (isight->packet_index < 0)
181 return;
182 index = isight->packet_index;
183 payload = isight->buffer.packets[index].buffer;
184 length = be32_to_cpup(header) >> 16;
185
186 if (likely(length >= 16 &&
187 payload->signature == cpu_to_be32(0x73676874/*"sght"*/))) {
188 count = be32_to_cpu(payload->sample_count);
189 if (likely(count <= (length - 16) / 4)) {
190 total = be32_to_cpu(payload->sample_total);
191 if (unlikely(total != isight->total_samples)) {
192 if (!isight->first_packet)
193 isight_dropped_samples(isight, total);
194 isight->first_packet = false;
195 isight->total_samples = total;
196 }
197
198 isight_samples(isight, payload->samples, count);
199 isight->total_samples += count;
200 }
201 }
202
203 err = fw_iso_context_queue(isight->context, &audio_packet,
204 &isight->buffer.iso_buffer,
205 isight->buffer.packets[index].offset);
206 if (err < 0) {
207 dev_err(&isight->unit->device, "queueing error: %d\n", err);
208 isight_pcm_abort(isight);
209 isight->packet_index = -1;
210 return;
211 }
212
213 if (++index >= QUEUE_LENGTH)
214 index = 0;
215 isight->packet_index = index;
216}
217
218static int isight_connect(struct isight *isight)
219{
220 int ch, err, rcode, errors = 0;
221 __be32 value;
222
223retry_after_bus_reset:
224 ch = fw_iso_resources_allocate(&isight->resources,
225 sizeof(struct audio_payload),
226 isight->device->max_speed);
227 if (ch < 0) {
228 err = ch;
229 goto error;
230 }
231
232 value = cpu_to_be32(ch | (isight->device->max_speed << SPEED_SHIFT));
233 for (;;) {
234 rcode = fw_run_transaction(
235 isight->device->card,
236 TCODE_WRITE_QUADLET_REQUEST,
237 isight->device->node_id,
238 isight->resources.generation,
239 isight->device->max_speed,
240 isight->audio_base + REG_ISO_TX_CONFIG,
241 &value, 4);
242 if (rcode == RCODE_COMPLETE) {
243 return 0;
244 } else if (rcode == RCODE_GENERATION) {
245 fw_iso_resources_free(&isight->resources);
246 goto retry_after_bus_reset;
247 } else if (rcode_is_permanent_error(rcode) || ++errors >= 3) {
248 err = -EIO;
249 goto err_resources;
250 }
251 msleep(5);
252 }
253
254err_resources:
255 fw_iso_resources_free(&isight->resources);
256error:
257 return err;
258}
259
260static int isight_open(struct snd_pcm_substream *substream)
261{
262 static const struct snd_pcm_hardware hardware = {
263 .info = SNDRV_PCM_INFO_MMAP |
264 SNDRV_PCM_INFO_MMAP_VALID |
265 SNDRV_PCM_INFO_BATCH |
266 SNDRV_PCM_INFO_INTERLEAVED |
267 SNDRV_PCM_INFO_BLOCK_TRANSFER,
268 .formats = SNDRV_PCM_FMTBIT_S16_BE,
269 .rates = SNDRV_PCM_RATE_48000,
270 .rate_min = 48000,
271 .rate_max = 48000,
272 .channels_min = 2,
273 .channels_max = 2,
274 .buffer_bytes_max = 4 * 1024 * 1024,
275 .period_bytes_min = MAX_FRAMES_PER_PACKET * 4,
276 .period_bytes_max = 1024 * 1024,
277 .periods_min = 2,
278 .periods_max = UINT_MAX,
279 };
280 struct isight *isight = substream->private_data;
281
282 substream->runtime->hw = hardware;
283
284 return iso_packets_buffer_init(&isight->buffer, isight->unit,
285 QUEUE_LENGTH,
286 sizeof(struct audio_payload),
287 DMA_FROM_DEVICE);
288}
289
290static int isight_close(struct snd_pcm_substream *substream)
291{
292 struct isight *isight = substream->private_data;
293
294 iso_packets_buffer_destroy(&isight->buffer, isight->unit);
295
296 return 0;
297}
298
299static int isight_hw_params(struct snd_pcm_substream *substream,
300 struct snd_pcm_hw_params *hw_params)
301{
302 struct isight *isight = substream->private_data;
303 int err;
304
305 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
306 params_buffer_bytes(hw_params));
307 if (err < 0)
308 return err;
309
310 ACCESS_ONCE(isight->pcm_active) = true;
311
312 return 0;
313}
314
315static int reg_read(struct isight *isight, int offset, __be32 *value)
316{
317 return snd_fw_transaction(isight->unit, TCODE_READ_QUADLET_REQUEST,
318 isight->audio_base + offset, value, 4);
319}
320
321static int reg_write(struct isight *isight, int offset, __be32 value)
322{
323 return snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST,
324 isight->audio_base + offset, &value, 4);
325}
326
327static void isight_stop_streaming(struct isight *isight)
328{
329 if (!isight->context)
330 return;
331
332 fw_iso_context_stop(isight->context);
333 fw_iso_context_destroy(isight->context);
334 isight->context = NULL;
335 fw_iso_resources_free(&isight->resources);
336 reg_write(isight, REG_AUDIO_ENABLE, 0);
337}
338
339static int isight_hw_free(struct snd_pcm_substream *substream)
340{
341 struct isight *isight = substream->private_data;
342
343 ACCESS_ONCE(isight->pcm_active) = false;
344
345 mutex_lock(&isight->mutex);
346 isight_stop_streaming(isight);
347 mutex_unlock(&isight->mutex);
348
349 return snd_pcm_lib_free_vmalloc_buffer(substream);
350}
351
352static int isight_start_streaming(struct isight *isight)
353{
354 unsigned int i;
355 int err;
356
357 if (isight->context) {
358 if (isight->packet_index < 0)
359 isight_stop_streaming(isight);
360 else
361 return 0;
362 }
363
364 err = reg_write(isight, REG_SAMPLE_RATE, cpu_to_be32(RATE_48000));
365 if (err < 0)
366 goto error;
367
368 err = isight_connect(isight);
369 if (err < 0)
370 goto error;
371
372 err = reg_write(isight, REG_AUDIO_ENABLE, cpu_to_be32(AUDIO_ENABLE));
373 if (err < 0)
374 goto err_resources;
375
376 isight->context = fw_iso_context_create(isight->device->card,
377 FW_ISO_CONTEXT_RECEIVE,
378 isight->resources.channel,
379 isight->device->max_speed,
380 4, isight_packet, isight);
381 if (IS_ERR(isight->context)) {
382 err = PTR_ERR(isight->context);
383 isight->context = NULL;
384 goto err_resources;
385 }
386
387 for (i = 0; i < QUEUE_LENGTH; ++i) {
388 err = fw_iso_context_queue(isight->context, &audio_packet,
389 &isight->buffer.iso_buffer,
390 isight->buffer.packets[i].offset);
391 if (err < 0)
392 goto err_context;
393 }
394
395 isight->first_packet = true;
396 isight->packet_index = 0;
397
398 err = fw_iso_context_start(isight->context, -1, 0,
399 FW_ISO_CONTEXT_MATCH_ALL_TAGS/*?*/);
400 if (err < 0)
401 goto err_context;
402
403 return 0;
404
405err_context:
406 fw_iso_context_destroy(isight->context);
407 isight->context = NULL;
408err_resources:
409 fw_iso_resources_free(&isight->resources);
410 reg_write(isight, REG_AUDIO_ENABLE, 0);
411error:
412 return err;
413}
414
415static int isight_prepare(struct snd_pcm_substream *substream)
416{
417 struct isight *isight = substream->private_data;
418 int err;
419
420 isight->buffer_pointer = 0;
421 isight->period_counter = 0;
422
423 mutex_lock(&isight->mutex);
424 err = isight_start_streaming(isight);
425 mutex_unlock(&isight->mutex);
426
427 return err;
428}
429
430static int isight_trigger(struct snd_pcm_substream *substream, int cmd)
431{
432 struct isight *isight = substream->private_data;
433
434 switch (cmd) {
435 case SNDRV_PCM_TRIGGER_START:
436 ACCESS_ONCE(isight->pcm_running) = true;
437 break;
438 case SNDRV_PCM_TRIGGER_STOP:
439 ACCESS_ONCE(isight->pcm_running) = false;
440 break;
441 default:
442 return -EINVAL;
443 }
444 return 0;
445}
446
447static snd_pcm_uframes_t isight_pointer(struct snd_pcm_substream *substream)
448{
449 struct isight *isight = substream->private_data;
450
451 return ACCESS_ONCE(isight->buffer_pointer);
452}
453
454static int isight_create_pcm(struct isight *isight)
455{
456 static struct snd_pcm_ops ops = {
457 .open = isight_open,
458 .close = isight_close,
459 .ioctl = snd_pcm_lib_ioctl,
460 .hw_params = isight_hw_params,
461 .hw_free = isight_hw_free,
462 .prepare = isight_prepare,
463 .trigger = isight_trigger,
464 .pointer = isight_pointer,
465 .page = snd_pcm_lib_get_vmalloc_page,
466 .mmap = snd_pcm_lib_mmap_vmalloc,
467 };
468 struct snd_pcm *pcm;
469 int err;
470
471 err = snd_pcm_new(isight->card, "iSight", 0, 0, 1, &pcm);
472 if (err < 0)
473 return err;
474 pcm->private_data = isight;
475 strcpy(pcm->name, "iSight");
476 isight->pcm = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
477 isight->pcm->ops = &ops;
478
479 return 0;
480}
481
482static int isight_gain_info(struct snd_kcontrol *ctl,
483 struct snd_ctl_elem_info *info)
484{
485 struct isight *isight = ctl->private_data;
486
487 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
488 info->count = 1;
489 info->value.integer.min = isight->gain_min;
490 info->value.integer.max = isight->gain_max;
491
492 return 0;
493}
494
495static int isight_gain_get(struct snd_kcontrol *ctl,
496 struct snd_ctl_elem_value *value)
497{
498 struct isight *isight = ctl->private_data;
499 __be32 gain;
500 int err;
501
502 err = reg_read(isight, REG_GAIN, &gain);
503 if (err < 0)
504 return err;
505
506 value->value.integer.value[0] = (s32)be32_to_cpu(gain);
507
508 return 0;
509}
510
511static int isight_gain_put(struct snd_kcontrol *ctl,
512 struct snd_ctl_elem_value *value)
513{
514 struct isight *isight = ctl->private_data;
515
516 if (value->value.integer.value[0] < isight->gain_min ||
517 value->value.integer.value[0] > isight->gain_max)
518 return -EINVAL;
519
520 return reg_write(isight, REG_GAIN,
521 cpu_to_be32(value->value.integer.value[0]));
522}
523
524static int isight_mute_get(struct snd_kcontrol *ctl,
525 struct snd_ctl_elem_value *value)
526{
527 struct isight *isight = ctl->private_data;
528 __be32 mute;
529 int err;
530
531 err = reg_read(isight, REG_MUTE, &mute);
532 if (err < 0)
533 return err;
534
535 value->value.integer.value[0] = !mute;
536
537 return 0;
538}
539
540static int isight_mute_put(struct snd_kcontrol *ctl,
541 struct snd_ctl_elem_value *value)
542{
543 struct isight *isight = ctl->private_data;
544
545 return reg_write(isight, REG_MUTE,
546 (__force __be32)!value->value.integer.value[0]);
547}
548
549static int isight_create_mixer(struct isight *isight)
550{
551 static const struct snd_kcontrol_new gain_control = {
552 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
553 .name = "Mic Capture Volume",
554 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
555 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
556 .info = isight_gain_info,
557 .get = isight_gain_get,
558 .put = isight_gain_put,
559 };
560 static const struct snd_kcontrol_new mute_control = {
561 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
562 .name = "Mic Capture Switch",
563 .info = snd_ctl_boolean_mono_info,
564 .get = isight_mute_get,
565 .put = isight_mute_put,
566 };
567 __be32 value;
568 struct snd_kcontrol *ctl;
569 int err;
570
571 err = reg_read(isight, REG_GAIN_RAW_START, &value);
572 if (err < 0)
573 return err;
574 isight->gain_min = be32_to_cpu(value);
575
576 err = reg_read(isight, REG_GAIN_RAW_END, &value);
577 if (err < 0)
578 return err;
579 isight->gain_max = be32_to_cpu(value);
580
581 isight->gain_tlv[0] = SNDRV_CTL_TLVT_DB_MINMAX;
582 isight->gain_tlv[1] = 2 * sizeof(unsigned int);
583
584 err = reg_read(isight, REG_GAIN_DB_START, &value);
585 if (err < 0)
586 return err;
587 isight->gain_tlv[2] = (s32)be32_to_cpu(value) * 100;
588
589 err = reg_read(isight, REG_GAIN_DB_END, &value);
590 if (err < 0)
591 return err;
592 isight->gain_tlv[3] = (s32)be32_to_cpu(value) * 100;
593
594 ctl = snd_ctl_new1(&gain_control, isight);
595 if (ctl)
596 ctl->tlv.p = isight->gain_tlv;
597 err = snd_ctl_add(isight->card, ctl);
598 if (err < 0)
599 return err;
600
601 err = snd_ctl_add(isight->card, snd_ctl_new1(&mute_control, isight));
602 if (err < 0)
603 return err;
604
605 return 0;
606}
607
608static void isight_card_free(struct snd_card *card)
609{
610 struct isight *isight = card->private_data;
611
612 fw_iso_resources_destroy(&isight->resources);
613 fw_unit_put(isight->unit);
614 fw_device_put(isight->device);
615 mutex_destroy(&isight->mutex);
616}
617
618static u64 get_unit_base(struct fw_unit *unit)
619{
620 struct fw_csr_iterator i;
621 int key, value;
622
623 fw_csr_iterator_init(&i, unit->directory);
624 while (fw_csr_iterator_next(&i, &key, &value))
625 if (key == CSR_OFFSET)
626 return CSR_REGISTER_BASE + value * 4;
627 return 0;
628}
629
630static int isight_probe(struct device *unit_dev)
631{
632 struct fw_unit *unit = fw_unit(unit_dev);
633 struct fw_device *fw_dev = fw_parent_device(unit);
634 struct snd_card *card;
635 struct isight *isight;
636 int err;
637
638 err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*isight), &card);
639 if (err < 0)
640 return err;
641 snd_card_set_dev(card, unit_dev);
642
643 isight = card->private_data;
644 isight->card = card;
645 mutex_init(&isight->mutex);
646 isight->unit = fw_unit_get(unit);
647 isight->device = fw_device_get(fw_dev);
648 isight->audio_base = get_unit_base(unit);
649 if (!isight->audio_base) {
650 dev_err(&unit->device, "audio unit base not found\n");
651 err = -ENXIO;
652 goto err_unit;
653 }
654 fw_iso_resources_init(&isight->resources, unit);
655
656 card->private_free = isight_card_free;
657
658 strcpy(card->driver, "iSight");
659 strcpy(card->shortname, "Apple iSight");
660 snprintf(card->longname, sizeof(card->longname),
661 "Apple iSight (GUID %08x%08x) at %s, S%d",
662 fw_dev->config_rom[3], fw_dev->config_rom[4],
663 dev_name(&unit->device), 100 << fw_dev->max_speed);
664 strcpy(card->mixername, "iSight");
665
666 err = isight_create_pcm(isight);
667 if (err < 0)
668 goto error;
669
670 err = isight_create_mixer(isight);
671 if (err < 0)
672 goto error;
673
674 err = snd_card_register(card);
675 if (err < 0)
676 goto error;
677
678 dev_set_drvdata(unit_dev, isight);
679
680 return 0;
681
682err_unit:
683 fw_unit_put(isight->unit);
684 fw_device_put(isight->device);
685 mutex_destroy(&isight->mutex);
686error:
687 snd_card_free(card);
688 return err;
689}
690
691static int isight_remove(struct device *dev)
692{
693 struct isight *isight = dev_get_drvdata(dev);
694
695 isight_pcm_abort(isight);
696
697 snd_card_disconnect(isight->card);
698
699 mutex_lock(&isight->mutex);
700 isight_stop_streaming(isight);
701 mutex_unlock(&isight->mutex);
702
703 snd_card_free_when_closed(isight->card);
704
705 return 0;
706}
707
708static void isight_bus_reset(struct fw_unit *unit)
709{
710 struct isight *isight = dev_get_drvdata(&unit->device);
711
712 if (fw_iso_resources_update(&isight->resources) < 0) {
713 isight_pcm_abort(isight);
714
715 mutex_lock(&isight->mutex);
716 isight_stop_streaming(isight);
717 mutex_unlock(&isight->mutex);
718 }
719}
720
721static const struct ieee1394_device_id isight_id_table[] = {
722 {
723 .match_flags = IEEE1394_MATCH_SPECIFIER_ID |
724 IEEE1394_MATCH_VERSION,
725 .specifier_id = OUI_APPLE,
726 .version = SW_ISIGHT_AUDIO,
727 },
728 { }
729};
730MODULE_DEVICE_TABLE(ieee1394, isight_id_table);
731
732static struct fw_driver isight_driver = {
733 .driver = {
734 .owner = THIS_MODULE,
735 .name = KBUILD_MODNAME,
736 .bus = &fw_bus_type,
737 .probe = isight_probe,
738 .remove = isight_remove,
739 },
740 .update = isight_bus_reset,
741 .id_table = isight_id_table,
742};
743
744static int __init alsa_isight_init(void)
745{
746 return driver_register(&isight_driver.driver);
747}
748
749static void __exit alsa_isight_exit(void)
750{
751 driver_unregister(&isight_driver.driver);
752}
753
754module_init(alsa_isight_init);
755module_exit(alsa_isight_exit);
diff --git a/sound/firewire/iso-resources.c b/sound/firewire/iso-resources.c
index 775dbd5f3445..9d4a6714f9ec 100644
--- a/sound/firewire/iso-resources.c
+++ b/sound/firewire/iso-resources.c
@@ -36,6 +36,7 @@ int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit)
36 36
37 return 0; 37 return 0;
38} 38}
39EXPORT_SYMBOL(fw_iso_resources_init);
39 40
40/** 41/**
41 * fw_iso_resources_destroy - destroy a resource manager 42 * fw_iso_resources_destroy - destroy a resource manager
@@ -48,6 +49,7 @@ void fw_iso_resources_destroy(struct fw_iso_resources *r)
48 mutex_destroy(&r->mutex); 49 mutex_destroy(&r->mutex);
49 fw_unit_put(r->unit); 50 fw_unit_put(r->unit);
50} 51}
52EXPORT_SYMBOL(fw_iso_resources_destroy);
51 53
52static unsigned int packet_bandwidth(unsigned int max_payload_bytes, int speed) 54static unsigned int packet_bandwidth(unsigned int max_payload_bytes, int speed)
53{ 55{
@@ -152,6 +154,7 @@ retry_after_bus_reset:
152 154
153 return channel; 155 return channel;
154} 156}
157EXPORT_SYMBOL(fw_iso_resources_allocate);
155 158
156/** 159/**
157 * fw_iso_resources_update - update resource allocations after a bus reset 160 * fw_iso_resources_update - update resource allocations after a bus reset
@@ -203,6 +206,7 @@ int fw_iso_resources_update(struct fw_iso_resources *r)
203 206
204 return channel; 207 return channel;
205} 208}
209EXPORT_SYMBOL(fw_iso_resources_update);
206 210
207/** 211/**
208 * fw_iso_resources_free - frees allocated resources 212 * fw_iso_resources_free - frees allocated resources
@@ -230,3 +234,4 @@ void fw_iso_resources_free(struct fw_iso_resources *r)
230 234
231 mutex_unlock(&r->mutex); 235 mutex_unlock(&r->mutex);
232} 236}
237EXPORT_SYMBOL(fw_iso_resources_free);
diff --git a/sound/firewire/packets-buffer.c b/sound/firewire/packets-buffer.c
index 1e20e60ba6a6..3c61ca2e6152 100644
--- a/sound/firewire/packets-buffer.c
+++ b/sound/firewire/packets-buffer.c
@@ -60,6 +60,7 @@ err_packets:
60error: 60error:
61 return err; 61 return err;
62} 62}
63EXPORT_SYMBOL(iso_packets_buffer_init);
63 64
64/** 65/**
65 * iso_packets_buffer_destroy - frees packet buffer resources 66 * iso_packets_buffer_destroy - frees packet buffer resources
@@ -72,3 +73,4 @@ void iso_packets_buffer_destroy(struct iso_packets_buffer *b,
72 fw_iso_buffer_destroy(&b->iso_buffer, fw_parent_device(unit)->card); 73 fw_iso_buffer_destroy(&b->iso_buffer, fw_parent_device(unit)->card);
73 kfree(b->packets); 74 kfree(b->packets);
74} 75}
76EXPORT_SYMBOL(iso_packets_buffer_destroy);
diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile
index 2dad40f3f622..c95d8f1aae87 100644
--- a/sound/i2c/other/Makefile
+++ b/sound/i2c/other/Makefile
@@ -14,4 +14,4 @@ snd-tea575x-tuner-objs := tea575x-tuner.o
14obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o 14obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o
15obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o 15obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o
16obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o 16obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o
17obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o 17obj-$(CONFIG_SND_TEA575X) += snd-tea575x-tuner.o
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index ee538f1ae846..4831800239d3 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -37,8 +37,8 @@ static int radio_nr = -1;
37module_param(radio_nr, int, 0); 37module_param(radio_nr, int, 0);
38 38
39#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) 39#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
40#define FREQ_LO (87 * 16000) 40#define FREQ_LO (50UL * 16000)
41#define FREQ_HI (108 * 16000) 41#define FREQ_HI (150UL * 16000)
42 42
43/* 43/*
44 * definitions 44 * definitions
@@ -77,27 +77,95 @@ static struct v4l2_queryctrl radio_qctrl[] = {
77 * lowlevel part 77 * lowlevel part
78 */ 78 */
79 79
80static void snd_tea575x_write(struct snd_tea575x *tea, unsigned int val)
81{
82 u16 l;
83 u8 data;
84
85 tea->ops->set_direction(tea, 1);
86 udelay(16);
87
88 for (l = 25; l > 0; l--) {
89 data = (val >> 24) & TEA575X_DATA;
90 val <<= 1; /* shift data */
91 tea->ops->set_pins(tea, data | TEA575X_WREN);
92 udelay(2);
93 tea->ops->set_pins(tea, data | TEA575X_WREN | TEA575X_CLK);
94 udelay(2);
95 tea->ops->set_pins(tea, data | TEA575X_WREN);
96 udelay(2);
97 }
98
99 if (!tea->mute)
100 tea->ops->set_pins(tea, 0);
101}
102
103static unsigned int snd_tea575x_read(struct snd_tea575x *tea)
104{
105 u16 l, rdata;
106 u32 data = 0;
107
108 tea->ops->set_direction(tea, 0);
109 tea->ops->set_pins(tea, 0);
110 udelay(16);
111
112 for (l = 24; l--;) {
113 tea->ops->set_pins(tea, TEA575X_CLK);
114 udelay(2);
115 if (!l)
116 tea->tuned = tea->ops->get_pins(tea) & TEA575X_MOST ? 0 : 1;
117 tea->ops->set_pins(tea, 0);
118 udelay(2);
119 data <<= 1; /* shift data */
120 rdata = tea->ops->get_pins(tea);
121 if (!l)
122 tea->stereo = (rdata & TEA575X_MOST) ? 0 : 1;
123 if (rdata & TEA575X_DATA)
124 data++;
125 udelay(2);
126 }
127
128 if (tea->mute)
129 tea->ops->set_pins(tea, TEA575X_WREN);
130
131 return data;
132}
133
134static void snd_tea575x_get_freq(struct snd_tea575x *tea)
135{
136 unsigned long freq;
137
138 freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK;
139 /* freq *= 12.5 */
140 freq *= 125;
141 freq /= 10;
142 /* crystal fixup */
143 if (tea->tea5759)
144 freq += TEA575X_FMIF;
145 else
146 freq -= TEA575X_FMIF;
147
148 tea->freq = freq * 16; /* from kHz */
149}
150
80static void snd_tea575x_set_freq(struct snd_tea575x *tea) 151static void snd_tea575x_set_freq(struct snd_tea575x *tea)
81{ 152{
82 unsigned long freq; 153 unsigned long freq;
83 154
84 freq = tea->freq / 16; /* to kHz */ 155 freq = clamp(tea->freq, FREQ_LO, FREQ_HI);
85 if (freq > 108000) 156 freq /= 16; /* to kHz */
86 freq = 108000;
87 if (freq < 87000)
88 freq = 87000;
89 /* crystal fixup */ 157 /* crystal fixup */
90 if (tea->tea5759) 158 if (tea->tea5759)
91 freq -= tea->freq_fixup; 159 freq -= TEA575X_FMIF;
92 else 160 else
93 freq += tea->freq_fixup; 161 freq += TEA575X_FMIF;
94 /* freq /= 12.5 */ 162 /* freq /= 12.5 */
95 freq *= 10; 163 freq *= 10;
96 freq /= 125; 164 freq /= 125;
97 165
98 tea->val &= ~TEA575X_BIT_FREQ_MASK; 166 tea->val &= ~TEA575X_BIT_FREQ_MASK;
99 tea->val |= freq & TEA575X_BIT_FREQ_MASK; 167 tea->val |= freq & TEA575X_BIT_FREQ_MASK;
100 tea->ops->write(tea, tea->val); 168 snd_tea575x_write(tea, tea->val);
101} 169}
102 170
103/* 171/*
@@ -109,29 +177,34 @@ static int vidioc_querycap(struct file *file, void *priv,
109{ 177{
110 struct snd_tea575x *tea = video_drvdata(file); 178 struct snd_tea575x *tea = video_drvdata(file);
111 179
112 strcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757");
113 strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver)); 180 strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver));
114 strlcpy(v->card, "Maestro Radio", sizeof(v->card)); 181 strlcpy(v->card, tea->card, sizeof(v->card));
115 sprintf(v->bus_info, "PCI"); 182 strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card));
183 strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info));
116 v->version = RADIO_VERSION; 184 v->version = RADIO_VERSION;
117 v->capabilities = V4L2_CAP_TUNER; 185 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
118 return 0; 186 return 0;
119} 187}
120 188
121static int vidioc_g_tuner(struct file *file, void *priv, 189static int vidioc_g_tuner(struct file *file, void *priv,
122 struct v4l2_tuner *v) 190 struct v4l2_tuner *v)
123{ 191{
192 struct snd_tea575x *tea = video_drvdata(file);
193
124 if (v->index > 0) 194 if (v->index > 0)
125 return -EINVAL; 195 return -EINVAL;
126 196
197 snd_tea575x_read(tea);
198
127 strcpy(v->name, "FM"); 199 strcpy(v->name, "FM");
128 v->type = V4L2_TUNER_RADIO; 200 v->type = V4L2_TUNER_RADIO;
201 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
129 v->rangelow = FREQ_LO; 202 v->rangelow = FREQ_LO;
130 v->rangehigh = FREQ_HI; 203 v->rangehigh = FREQ_HI;
131 v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; 204 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
132 v->capability = V4L2_TUNER_CAP_LOW; 205 v->audmode = tea->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO;
133 v->audmode = V4L2_TUNER_MODE_MONO; 206 v->signal = tea->tuned ? 0xffff : 0;
134 v->signal = 0xffff; 207
135 return 0; 208 return 0;
136} 209}
137 210
@@ -148,7 +221,10 @@ static int vidioc_g_frequency(struct file *file, void *priv,
148{ 221{
149 struct snd_tea575x *tea = video_drvdata(file); 222 struct snd_tea575x *tea = video_drvdata(file);
150 223
224 if (f->tuner != 0)
225 return -EINVAL;
151 f->type = V4L2_TUNER_RADIO; 226 f->type = V4L2_TUNER_RADIO;
227 snd_tea575x_get_freq(tea);
152 f->frequency = tea->freq; 228 f->frequency = tea->freq;
153 return 0; 229 return 0;
154} 230}
@@ -158,6 +234,9 @@ static int vidioc_s_frequency(struct file *file, void *priv,
158{ 234{
159 struct snd_tea575x *tea = video_drvdata(file); 235 struct snd_tea575x *tea = video_drvdata(file);
160 236
237 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
238 return -EINVAL;
239
161 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) 240 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
162 return -EINVAL; 241 return -EINVAL;
163 242
@@ -209,10 +288,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
209 288
210 switch (ctrl->id) { 289 switch (ctrl->id) {
211 case V4L2_CID_AUDIO_MUTE: 290 case V4L2_CID_AUDIO_MUTE:
212 if (tea->ops->mute) { 291 ctrl->value = tea->mute;
213 ctrl->value = tea->mute; 292 return 0;
214 return 0;
215 }
216 } 293 }
217 return -EINVAL; 294 return -EINVAL;
218} 295}
@@ -224,11 +301,11 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
224 301
225 switch (ctrl->id) { 302 switch (ctrl->id) {
226 case V4L2_CID_AUDIO_MUTE: 303 case V4L2_CID_AUDIO_MUTE:
227 if (tea->ops->mute) { 304 if (tea->mute != ctrl->value) {
228 tea->ops->mute(tea, ctrl->value);
229 tea->mute = ctrl->value; 305 tea->mute = ctrl->value;
230 return 0; 306 snd_tea575x_set_freq(tea);
231 } 307 }
308 return 0;
232 } 309 }
233 return -EINVAL; 310 return -EINVAL;
234} 311}
@@ -293,18 +370,16 @@ static struct video_device tea575x_radio = {
293/* 370/*
294 * initialize all the tea575x chips 371 * initialize all the tea575x chips
295 */ 372 */
296void snd_tea575x_init(struct snd_tea575x *tea) 373int snd_tea575x_init(struct snd_tea575x *tea)
297{ 374{
298 int retval; 375 int retval;
299 unsigned int val;
300 struct video_device *tea575x_radio_inst; 376 struct video_device *tea575x_radio_inst;
301 377
302 val = tea->ops->read(tea); 378 tea->mute = 1;
303 if (val == 0x1ffffff || val == 0) { 379
304 snd_printk(KERN_ERR 380 snd_tea575x_write(tea, 0x55AA);
305 "tea575x-tuner: Cannot find TEA575x chip\n"); 381 if (snd_tea575x_read(tea) != 0x55AA)
306 return; 382 return -ENODEV;
307 }
308 383
309 tea->in_use = 0; 384 tea->in_use = 0;
310 tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; 385 tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40;
@@ -313,7 +388,7 @@ void snd_tea575x_init(struct snd_tea575x *tea)
313 tea575x_radio_inst = video_device_alloc(); 388 tea575x_radio_inst = video_device_alloc();
314 if (tea575x_radio_inst == NULL) { 389 if (tea575x_radio_inst == NULL) {
315 printk(KERN_ERR "tea575x-tuner: not enough memory\n"); 390 printk(KERN_ERR "tea575x-tuner: not enough memory\n");
316 return; 391 return -ENOMEM;
317 } 392 }
318 393
319 memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio)); 394 memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio));
@@ -328,17 +403,13 @@ void snd_tea575x_init(struct snd_tea575x *tea)
328 if (retval) { 403 if (retval) {
329 printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); 404 printk(KERN_ERR "tea575x-tuner: can't register video device!\n");
330 kfree(tea575x_radio_inst); 405 kfree(tea575x_radio_inst);
331 return; 406 return retval;
332 } 407 }
333 408
334 snd_tea575x_set_freq(tea); 409 snd_tea575x_set_freq(tea);
335
336 /* mute on init */
337 if (tea->ops->mute) {
338 tea->ops->mute(tea, 1);
339 tea->mute = 1;
340 }
341 tea->vd = tea575x_radio_inst; 410 tea->vd = tea575x_radio_inst;
411
412 return 0;
342} 413}
343 414
344void snd_tea575x_exit(struct snd_tea575x *tea) 415void snd_tea575x_exit(struct snd_tea575x *tea)
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 8d2856fb4d97..e90d103e177e 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -534,6 +534,14 @@ config SND_ES1968_INPUT
534 If you say N the buttons will directly control the master volume. 534 If you say N the buttons will directly control the master volume.
535 It is recommended to say Y. 535 It is recommended to say Y.
536 536
537config SND_ES1968_RADIO
538 bool "Enable TEA5757 radio tuner support for es1968"
539 depends on SND_ES1968
540 depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_ES1968
541 help
542 Say Y here to include support for TEA5757 radio tuner integrated on
543 some MediaForte cards (e.g. SF64-PCE2).
544
537config SND_FM801 545config SND_FM801
538 tristate "ForteMedia FM801" 546 tristate "ForteMedia FM801"
539 select SND_OPL3_LIB 547 select SND_OPL3_LIB
@@ -552,13 +560,13 @@ config SND_FM801_TEA575X_BOOL
552 depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801 560 depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801
553 help 561 help
554 Say Y here to include support for soundcards based on the ForteMedia 562 Say Y here to include support for soundcards based on the ForteMedia
555 FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media 563 FM801 chip with a TEA5757 tuner (MediaForte SF256-PCS, SF256-PCP and
556 Forte SF256-PCS-02) into the snd-fm801 driver. 564 SF64-PCR) into the snd-fm801 driver.
557 565
558config SND_FM801_TEA575X 566config SND_TEA575X
559 tristate 567 tristate
560 depends on SND_FM801_TEA575X_BOOL 568 depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO
561 default SND_FM801 569 default SND_FM801 || SND_ES1968
562 570
563source "sound/pci/hda/Kconfig" 571source "sound/pci/hda/Kconfig"
564 572
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index f8ccc9677c6f..2ca6f4f85b41 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -42,10 +42,29 @@
42#include <sound/tlv.h> 42#include <sound/tlv.h>
43#include <sound/hwdep.h> 43#include <sound/hwdep.h>
44 44
45
45MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
46MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); 47MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
47MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); 48MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
48 49
50#if defined CONFIG_SND_DEBUG
51/* copied from pcm_lib.c, hope later patch will make that version public
52and this copy can be removed */
53static void pcm_debug_name(struct snd_pcm_substream *substream,
54 char *name, size_t len)
55{
56 snprintf(name, len, "pcmC%dD%d%c:%d",
57 substream->pcm->card->number,
58 substream->pcm->device,
59 substream->stream ? 'c' : 'p',
60 substream->number);
61}
62#define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name))
63#else
64#define pcm_debug_name(s, n, l) do { } while (0)
65#define DEBUG_NAME(name, substream) do { } while (0)
66#endif
67
49#if defined CONFIG_SND_DEBUG_VERBOSE 68#if defined CONFIG_SND_DEBUG_VERBOSE
50/** 69/**
51 * snd_printddd - very verbose debug printk 70 * snd_printddd - very verbose debug printk
@@ -58,7 +77,7 @@ MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
58#define snd_printddd(format, args...) \ 77#define snd_printddd(format, args...) \
59 __snd_printk(3, __FILE__, __LINE__, format, ##args) 78 __snd_printk(3, __FILE__, __LINE__, format, ##args)
60#else 79#else
61#define snd_printddd(format, args...) do { } while (0) 80#define snd_printddd(format, args...) do { } while (0)
62#endif 81#endif
63 82
64static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ 83static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
@@ -101,13 +120,6 @@ static int adapter_fs = DEFAULT_SAMPLERATE;
101#define PERIOD_BYTES_MIN 2048 120#define PERIOD_BYTES_MIN 2048
102#define BUFFER_BYTES_MAX (512 * 1024) 121#define BUFFER_BYTES_MAX (512 * 1024)
103 122
104/* convert stream to character */
105#define SCHR(s) ((s == SNDRV_PCM_STREAM_PLAYBACK) ? 'P' : 'C')
106
107/*#define TIMER_MILLISECONDS 20
108#define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000)
109*/
110
111#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7) 123#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
112 124
113struct clk_source { 125struct clk_source {
@@ -136,7 +148,7 @@ struct snd_card_asihpi {
136 u32 h_mixer; 148 u32 h_mixer;
137 struct clk_cache cc; 149 struct clk_cache cc;
138 150
139 u16 support_mmap; 151 u16 can_dma;
140 u16 support_grouping; 152 u16 support_grouping;
141 u16 support_mrx; 153 u16 support_mrx;
142 u16 update_interval_frames; 154 u16 update_interval_frames;
@@ -155,6 +167,7 @@ struct snd_card_asihpi_pcm {
155 unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */ 167 unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */
156 unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */ 168 unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */
157 unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */ 169 unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */
170 unsigned int drained_count;
158 struct snd_pcm_substream *substream; 171 struct snd_pcm_substream *substream;
159 u32 h_stream; 172 u32 h_stream;
160 struct hpi_format format; 173 struct hpi_format format;
@@ -288,19 +301,26 @@ static u16 handle_error(u16 err, int line, char *filename)
288#define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__) 301#define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
289 302
290/***************************** GENERAL PCM ****************/ 303/***************************** GENERAL PCM ****************/
291static void print_hwparams(struct snd_pcm_hw_params *p) 304
305static void print_hwparams(struct snd_pcm_substream *substream,
306 struct snd_pcm_hw_params *p)
292{ 307{
293 snd_printd("HWPARAMS \n"); 308 DEBUG_NAME(substream, name);
294 snd_printd("samplerate %d \n", params_rate(p)); 309 snd_printd("%s HWPARAMS\n", name);
295 snd_printd("Channels %d \n", params_channels(p)); 310 snd_printd(" samplerate %d Hz\n", params_rate(p));
296 snd_printd("Format %d \n", params_format(p)); 311 snd_printd(" channels %d\n", params_channels(p));
297 snd_printd("subformat %d \n", params_subformat(p)); 312 snd_printd(" format %d\n", params_format(p));
298 snd_printd("Buffer bytes %d \n", params_buffer_bytes(p)); 313 snd_printd(" subformat %d\n", params_subformat(p));
299 snd_printd("Period bytes %d \n", params_period_bytes(p)); 314 snd_printd(" buffer %d B\n", params_buffer_bytes(p));
300 snd_printd("access %d \n", params_access(p)); 315 snd_printd(" period %d B\n", params_period_bytes(p));
301 snd_printd("period_size %d \n", params_period_size(p)); 316 snd_printd(" access %d\n", params_access(p));
302 snd_printd("periods %d \n", params_periods(p)); 317 snd_printd(" period_size %d\n", params_period_size(p));
303 snd_printd("buffer_size %d \n", params_buffer_size(p)); 318 snd_printd(" periods %d\n", params_periods(p));
319 snd_printd(" buffer_size %d\n", params_buffer_size(p));
320 snd_printd(" %d B/s\n", params_rate(p) *
321 params_channels(p) *
322 snd_pcm_format_width(params_format(p)) / 8);
323
304} 324}
305 325
306static snd_pcm_format_t hpi_to_alsa_formats[] = { 326static snd_pcm_format_t hpi_to_alsa_formats[] = {
@@ -451,7 +471,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
451 int width; 471 int width;
452 unsigned int bytes_per_sec; 472 unsigned int bytes_per_sec;
453 473
454 print_hwparams(params); 474 print_hwparams(substream, params);
455 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); 475 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
456 if (err < 0) 476 if (err < 0)
457 return err; 477 return err;
@@ -459,10 +479,6 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
459 if (err) 479 if (err)
460 return err; 480 return err;
461 481
462 snd_printdd("format %d, %d chans, %d_hz\n",
463 format, params_channels(params),
464 params_rate(params));
465
466 hpi_handle_error(hpi_format_create(&dpcm->format, 482 hpi_handle_error(hpi_format_create(&dpcm->format,
467 params_channels(params), 483 params_channels(params),
468 format, params_rate(params), 0, 0)); 484 format, params_rate(params), 0, 0));
@@ -477,8 +493,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
477 } 493 }
478 494
479 dpcm->hpi_buffer_attached = 0; 495 dpcm->hpi_buffer_attached = 0;
480 if (card->support_mmap) { 496 if (card->can_dma) {
481
482 err = hpi_stream_host_buffer_attach(dpcm->h_stream, 497 err = hpi_stream_host_buffer_attach(dpcm->h_stream,
483 params_buffer_bytes(params), runtime->dma_addr); 498 params_buffer_bytes(params), runtime->dma_addr);
484 if (err == 0) { 499 if (err == 0) {
@@ -509,8 +524,6 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
509 dpcm->bytes_per_sec = bytes_per_sec; 524 dpcm->bytes_per_sec = bytes_per_sec;
510 dpcm->buffer_bytes = params_buffer_bytes(params); 525 dpcm->buffer_bytes = params_buffer_bytes(params);
511 dpcm->period_bytes = params_period_bytes(params); 526 dpcm->period_bytes = params_period_bytes(params);
512 snd_printdd("buffer_bytes=%d, period_bytes=%d, bps=%d\n",
513 dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec);
514 527
515 return 0; 528 return 0;
516} 529}
@@ -564,9 +577,10 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
564 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); 577 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
565 struct snd_pcm_substream *s; 578 struct snd_pcm_substream *s;
566 u16 e; 579 u16 e;
580 DEBUG_NAME(substream, name);
581
582 snd_printdd("%s trigger\n", name);
567 583
568 snd_printdd("%c%d trigger\n",
569 SCHR(substream->stream), substream->number);
570 switch (cmd) { 584 switch (cmd) {
571 case SNDRV_PCM_TRIGGER_START: 585 case SNDRV_PCM_TRIGGER_START:
572 snd_pcm_group_for_each_entry(s, substream) { 586 snd_pcm_group_for_each_entry(s, substream) {
@@ -580,8 +594,8 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
580 if (substream->stream != s->stream) 594 if (substream->stream != s->stream)
581 continue; 595 continue;
582 596
583 if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && 597 ds->drained_count = 0;
584 (card->support_mmap)) { 598 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
585 /* How do I know how much valid data is present 599 /* How do I know how much valid data is present
586 * in buffer? Must be at least one period! 600 * in buffer? Must be at least one period!
587 * Guessing 2 periods, but if 601 * Guessing 2 periods, but if
@@ -599,9 +613,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
599 } 613 }
600 614
601 if (card->support_grouping) { 615 if (card->support_grouping) {
602 snd_printdd("\t%c%d group\n", 616 snd_printdd("%d group\n", s->number);
603 SCHR(s->stream),
604 s->number);
605 e = hpi_stream_group_add( 617 e = hpi_stream_group_add(
606 dpcm->h_stream, 618 dpcm->h_stream,
607 ds->h_stream); 619 ds->h_stream);
@@ -618,7 +630,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
618 /* start the master stream */ 630 /* start the master stream */
619 snd_card_asihpi_pcm_timer_start(substream); 631 snd_card_asihpi_pcm_timer_start(substream);
620 if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || 632 if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ||
621 !card->support_mmap) 633 !card->can_dma)
622 hpi_handle_error(hpi_stream_start(dpcm->h_stream)); 634 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
623 break; 635 break;
624 636
@@ -636,9 +648,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
636 s->runtime->status->state = SNDRV_PCM_STATE_SETUP; 648 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
637 649
638 if (card->support_grouping) { 650 if (card->support_grouping) {
639 snd_printdd("\t%c%d group\n", 651 snd_printdd("%d group\n", s->number);
640 SCHR(s->stream),
641 s->number);
642 snd_pcm_trigger_done(s, substream); 652 snd_pcm_trigger_done(s, substream);
643 } else 653 } else
644 break; 654 break;
@@ -732,9 +742,9 @@ static void snd_card_asihpi_timer_function(unsigned long data)
732 int loops = 0; 742 int loops = 0;
733 u16 state; 743 u16 state;
734 u32 buffer_size, bytes_avail, samples_played, on_card_bytes; 744 u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
745 DEBUG_NAME(substream, name);
735 746
736 snd_printdd("%c%d snd_card_asihpi_timer_function\n", 747 snd_printdd("%s snd_card_asihpi_timer_function\n", name);
737 SCHR(substream->stream), substream->number);
738 748
739 /* find minimum newdata and buffer pos in group */ 749 /* find minimum newdata and buffer pos in group */
740 snd_pcm_group_for_each_entry(s, substream) { 750 snd_pcm_group_for_each_entry(s, substream) {
@@ -756,6 +766,9 @@ static void snd_card_asihpi_timer_function(unsigned long data)
756 /* number of bytes in on-card buffer */ 766 /* number of bytes in on-card buffer */
757 runtime->delay = on_card_bytes; 767 runtime->delay = on_card_bytes;
758 768
769 if (!card->can_dma)
770 on_card_bytes = bytes_avail;
771
759 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { 772 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
760 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail; 773 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
761 if (state == HPI_STATE_STOPPED) { 774 if (state == HPI_STATE_STOPPED) {
@@ -763,12 +776,18 @@ static void snd_card_asihpi_timer_function(unsigned long data)
763 (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { 776 (on_card_bytes < ds->pcm_buf_host_rw_ofs)) {
764 hpi_handle_error(hpi_stream_start(ds->h_stream)); 777 hpi_handle_error(hpi_stream_start(ds->h_stream));
765 snd_printdd("P%d start\n", s->number); 778 snd_printdd("P%d start\n", s->number);
779 ds->drained_count = 0;
766 } 780 }
767 } else if (state == HPI_STATE_DRAINED) { 781 } else if (state == HPI_STATE_DRAINED) {
768 snd_printd(KERN_WARNING "P%d drained\n", 782 snd_printd(KERN_WARNING "P%d drained\n",
769 s->number); 783 s->number);
770 /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); 784 ds->drained_count++;
771 continue; */ 785 if (ds->drained_count > 2) {
786 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
787 continue;
788 }
789 } else {
790 ds->drained_count = 0;
772 } 791 }
773 } else 792 } else
774 pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs; 793 pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
@@ -786,16 +805,18 @@ static void snd_card_asihpi_timer_function(unsigned long data)
786 newdata); 805 newdata);
787 } 806 }
788 807
789 snd_printdd("hw_ptr x%04lX, appl_ptr x%04lX\n", 808 snd_printdd("hw_ptr 0x%04lX, appl_ptr 0x%04lX\n",
790 (unsigned long)frames_to_bytes(runtime, 809 (unsigned long)frames_to_bytes(runtime,
791 runtime->status->hw_ptr), 810 runtime->status->hw_ptr),
792 (unsigned long)frames_to_bytes(runtime, 811 (unsigned long)frames_to_bytes(runtime,
793 runtime->control->appl_ptr)); 812 runtime->control->appl_ptr));
794 813
795 snd_printdd("%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," 814 snd_printdd("%d S=%d, "
796 " aux=x%04X space=x%04X\n", 815 "rw=0x%04X, dma=0x%04X, left=0x%04X, "
797 loops, SCHR(s->stream), s->number, 816 "aux=0x%04X space=0x%04X\n",
798 state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail, 817 s->number, state,
818 ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs,
819 (int)bytes_avail,
799 (int)on_card_bytes, buffer_size-bytes_avail); 820 (int)on_card_bytes, buffer_size-bytes_avail);
800 loops++; 821 loops++;
801 } 822 }
@@ -814,7 +835,7 @@ static void snd_card_asihpi_timer_function(unsigned long data)
814 835
815 next_jiffies = max(next_jiffies, 1U); 836 next_jiffies = max(next_jiffies, 1U);
816 dpcm->timer.expires = jiffies + next_jiffies; 837 dpcm->timer.expires = jiffies + next_jiffies;
817 snd_printdd("jif %d buf pos x%04X newdata x%04X xfer x%04X\n", 838 snd_printdd("jif %d buf pos 0x%04X newdata 0x%04X xfer 0x%04X\n",
818 next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); 839 next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
819 840
820 snd_pcm_group_for_each_entry(s, substream) { 841 snd_pcm_group_for_each_entry(s, substream) {
@@ -826,30 +847,63 @@ static void snd_card_asihpi_timer_function(unsigned long data)
826 847
827 ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs; 848 ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
828 849
829 if (xfercount && (on_card_bytes <= ds->period_bytes)) { 850 if (xfercount &&
830 if (card->support_mmap) { 851 /* Limit use of on card fifo for playback */
831 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { 852 ((on_card_bytes <= ds->period_bytes) ||
832 snd_printddd("P%d write x%04x\n", 853 (s->stream == SNDRV_PCM_STREAM_CAPTURE)))
854
855 {
856
857 unsigned int buf_ofs = ds->pcm_buf_host_rw_ofs % ds->buffer_bytes;
858 unsigned int xfer1, xfer2;
859 char *pd = &s->runtime->dma_area[buf_ofs];
860
861 if (card->can_dma) { /* buffer wrap is handled at lower level */
862 xfer1 = xfercount;
863 xfer2 = 0;
864 } else {
865 xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs);
866 xfer2 = xfercount - xfer1;
867 }
868
869 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
870 snd_printddd("P%d write1 0x%04X 0x%04X\n",
871 s->number, xfer1, buf_ofs);
872 hpi_handle_error(
873 hpi_outstream_write_buf(
874 ds->h_stream, pd, xfer1,
875 &ds->format));
876
877 if (xfer2) {
878 pd = s->runtime->dma_area;
879
880 snd_printddd("P%d write2 0x%04X 0x%04X\n",
833 s->number, 881 s->number,
834 ds->period_bytes); 882 xfercount - xfer1, buf_ofs);
835 hpi_handle_error( 883 hpi_handle_error(
836 hpi_outstream_write_buf( 884 hpi_outstream_write_buf(
837 ds->h_stream, 885 ds->h_stream, pd,
838 &s->runtime-> 886 xfercount - xfer1,
839 dma_area[0],
840 xfercount,
841 &ds->format)); 887 &ds->format));
842 } else { 888 }
843 snd_printddd("C%d read x%04x\n", 889 } else {
844 s->number, 890 snd_printddd("C%d read1 0x%04x\n",
845 xfercount); 891 s->number, xfer1);
892 hpi_handle_error(
893 hpi_instream_read_buf(
894 ds->h_stream,
895 pd, xfer1));
896 if (xfer2) {
897 pd = s->runtime->dma_area;
898 snd_printddd("C%d read2 0x%04x\n",
899 s->number, xfer2);
846 hpi_handle_error( 900 hpi_handle_error(
847 hpi_instream_read_buf( 901 hpi_instream_read_buf(
848 ds->h_stream, 902 ds->h_stream,
849 NULL, xfercount)); 903 pd, xfer2));
850 } 904 }
851 ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount; 905 }
852 } /* else R/W will be handled by read/write callbacks */ 906 ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount;
853 ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs; 907 ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs;
854 snd_pcm_period_elapsed(s); 908 snd_pcm_period_elapsed(s);
855 } 909 }
@@ -863,7 +917,7 @@ static void snd_card_asihpi_timer_function(unsigned long data)
863static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, 917static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
864 unsigned int cmd, void *arg) 918 unsigned int cmd, void *arg)
865{ 919{
866 snd_printdd(KERN_INFO "Playback ioctl %d\n", cmd); 920 snd_printddd(KERN_INFO "P%d ioctl %d\n", substream->number, cmd);
867 return snd_pcm_lib_ioctl(substream, cmd, arg); 921 return snd_pcm_lib_ioctl(substream, cmd, arg);
868} 922}
869 923
@@ -873,7 +927,7 @@ static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
873 struct snd_pcm_runtime *runtime = substream->runtime; 927 struct snd_pcm_runtime *runtime = substream->runtime;
874 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 928 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
875 929
876 snd_printdd("playback prepare %d\n", substream->number); 930 snd_printdd("P%d prepare\n", substream->number);
877 931
878 hpi_handle_error(hpi_outstream_reset(dpcm->h_stream)); 932 hpi_handle_error(hpi_outstream_reset(dpcm->h_stream));
879 dpcm->pcm_buf_host_rw_ofs = 0; 933 dpcm->pcm_buf_host_rw_ofs = 0;
@@ -890,7 +944,7 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
890 snd_pcm_uframes_t ptr; 944 snd_pcm_uframes_t ptr;
891 945
892 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); 946 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
893 snd_printddd("playback_pointer=x%04lx\n", (unsigned long)ptr); 947 snd_printddd("P%d pointer = 0x%04lx\n", substream->number, (unsigned long)ptr);
894 return ptr; 948 return ptr;
895} 949}
896 950
@@ -986,11 +1040,9 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
986 SNDRV_PCM_INFO_DOUBLE | 1040 SNDRV_PCM_INFO_DOUBLE |
987 SNDRV_PCM_INFO_BATCH | 1041 SNDRV_PCM_INFO_BATCH |
988 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1042 SNDRV_PCM_INFO_BLOCK_TRANSFER |
989 SNDRV_PCM_INFO_PAUSE; 1043 SNDRV_PCM_INFO_PAUSE |
990 1044 SNDRV_PCM_INFO_MMAP |
991 if (card->support_mmap) 1045 SNDRV_PCM_INFO_MMAP_VALID;
992 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP |
993 SNDRV_PCM_INFO_MMAP_VALID;
994 1046
995 if (card->support_grouping) 1047 if (card->support_grouping)
996 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START; 1048 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
@@ -998,7 +1050,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
998 /* struct is copied, so can create initializer dynamically */ 1050 /* struct is copied, so can create initializer dynamically */
999 runtime->hw = snd_card_asihpi_playback; 1051 runtime->hw = snd_card_asihpi_playback;
1000 1052
1001 if (card->support_mmap) 1053 if (card->can_dma)
1002 err = snd_pcm_hw_constraint_pow2(runtime, 0, 1054 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1003 SNDRV_PCM_HW_PARAM_BUFFER_BYTES); 1055 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1004 if (err < 0) 1056 if (err < 0)
@@ -1028,58 +1080,6 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1028 return 0; 1080 return 0;
1029} 1081}
1030 1082
1031static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,
1032 int channel,
1033 snd_pcm_uframes_t pos,
1034 void __user *src,
1035 snd_pcm_uframes_t count)
1036{
1037 struct snd_pcm_runtime *runtime = substream->runtime;
1038 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1039 unsigned int len;
1040
1041 len = frames_to_bytes(runtime, count);
1042
1043 if (copy_from_user(runtime->dma_area, src, len))
1044 return -EFAULT;
1045
1046 snd_printddd("playback copy%d %u bytes\n",
1047 substream->number, len);
1048
1049 hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream,
1050 runtime->dma_area, len, &dpcm->format));
1051
1052 dpcm->pcm_buf_host_rw_ofs += len;
1053
1054 return 0;
1055}
1056
1057static int snd_card_asihpi_playback_silence(struct snd_pcm_substream *
1058 substream, int channel,
1059 snd_pcm_uframes_t pos,
1060 snd_pcm_uframes_t count)
1061{
1062 /* Usually writes silence to DMA buffer, which should be overwritten
1063 by real audio later. Our fifos cannot be overwritten, and are not
1064 free-running DMAs. Silence is output on fifo underflow.
1065 This callback is still required to allow the copy callback to be used.
1066 */
1067 return 0;
1068}
1069
1070static struct snd_pcm_ops snd_card_asihpi_playback_ops = {
1071 .open = snd_card_asihpi_playback_open,
1072 .close = snd_card_asihpi_playback_close,
1073 .ioctl = snd_card_asihpi_playback_ioctl,
1074 .hw_params = snd_card_asihpi_pcm_hw_params,
1075 .hw_free = snd_card_asihpi_hw_free,
1076 .prepare = snd_card_asihpi_playback_prepare,
1077 .trigger = snd_card_asihpi_trigger,
1078 .pointer = snd_card_asihpi_playback_pointer,
1079 .copy = snd_card_asihpi_playback_copy,
1080 .silence = snd_card_asihpi_playback_silence,
1081};
1082
1083static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = { 1083static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
1084 .open = snd_card_asihpi_playback_open, 1084 .open = snd_card_asihpi_playback_open,
1085 .close = snd_card_asihpi_playback_close, 1085 .close = snd_card_asihpi_playback_close,
@@ -1211,18 +1211,16 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1211 snd_card_asihpi_capture_format(card, dpcm->h_stream, 1211 snd_card_asihpi_capture_format(card, dpcm->h_stream,
1212 &snd_card_asihpi_capture); 1212 &snd_card_asihpi_capture);
1213 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture); 1213 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
1214 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED; 1214 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED |
1215 1215 SNDRV_PCM_INFO_MMAP |
1216 if (card->support_mmap) 1216 SNDRV_PCM_INFO_MMAP_VALID;
1217 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP |
1218 SNDRV_PCM_INFO_MMAP_VALID;
1219 1217
1220 if (card->support_grouping) 1218 if (card->support_grouping)
1221 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START; 1219 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
1222 1220
1223 runtime->hw = snd_card_asihpi_capture; 1221 runtime->hw = snd_card_asihpi_capture;
1224 1222
1225 if (card->support_mmap) 1223 if (card->can_dma)
1226 err = snd_pcm_hw_constraint_pow2(runtime, 0, 1224 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1227 SNDRV_PCM_HW_PARAM_BUFFER_BYTES); 1225 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1228 if (err < 0) 1226 if (err < 0)
@@ -1246,28 +1244,6 @@ static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1246 return 0; 1244 return 0;
1247} 1245}
1248 1246
1249static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream,
1250 int channel, snd_pcm_uframes_t pos,
1251 void __user *dst, snd_pcm_uframes_t count)
1252{
1253 struct snd_pcm_runtime *runtime = substream->runtime;
1254 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1255 u32 len;
1256
1257 len = frames_to_bytes(runtime, count);
1258
1259 snd_printddd("capture copy%d %d bytes\n", substream->number, len);
1260 hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream,
1261 runtime->dma_area, len));
1262
1263 dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len;
1264
1265 if (copy_to_user(dst, runtime->dma_area, len))
1266 return -EFAULT;
1267
1268 return 0;
1269}
1270
1271static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { 1247static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1272 .open = snd_card_asihpi_capture_open, 1248 .open = snd_card_asihpi_capture_open,
1273 .close = snd_card_asihpi_capture_close, 1249 .close = snd_card_asihpi_capture_close,
@@ -1279,18 +1255,6 @@ static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1279 .pointer = snd_card_asihpi_capture_pointer, 1255 .pointer = snd_card_asihpi_capture_pointer,
1280}; 1256};
1281 1257
1282static struct snd_pcm_ops snd_card_asihpi_capture_ops = {
1283 .open = snd_card_asihpi_capture_open,
1284 .close = snd_card_asihpi_capture_close,
1285 .ioctl = snd_card_asihpi_capture_ioctl,
1286 .hw_params = snd_card_asihpi_pcm_hw_params,
1287 .hw_free = snd_card_asihpi_hw_free,
1288 .prepare = snd_card_asihpi_capture_prepare,
1289 .trigger = snd_card_asihpi_trigger,
1290 .pointer = snd_card_asihpi_capture_pointer,
1291 .copy = snd_card_asihpi_capture_copy
1292};
1293
1294static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, 1258static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1295 int device, int substreams) 1259 int device, int substreams)
1296{ 1260{
@@ -1303,17 +1267,10 @@ static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1303 if (err < 0) 1267 if (err < 0)
1304 return err; 1268 return err;
1305 /* pointer to ops struct is stored, dont change ops afterwards! */ 1269 /* pointer to ops struct is stored, dont change ops afterwards! */
1306 if (asihpi->support_mmap) {
1307 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, 1270 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1308 &snd_card_asihpi_playback_mmap_ops); 1271 &snd_card_asihpi_playback_mmap_ops);
1309 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 1272 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1310 &snd_card_asihpi_capture_mmap_ops); 1273 &snd_card_asihpi_capture_mmap_ops);
1311 } else {
1312 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1313 &snd_card_asihpi_playback_ops);
1314 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1315 &snd_card_asihpi_capture_ops);
1316 }
1317 1274
1318 pcm->private_data = asihpi; 1275 pcm->private_data = asihpi;
1319 pcm->info_flags = 0; 1276 pcm->info_flags = 0;
@@ -1413,14 +1370,16 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1413 struct hpi_control *hpi_ctl, 1370 struct hpi_control *hpi_ctl,
1414 char *name) 1371 char *name)
1415{ 1372{
1416 char *dir = ""; 1373 char *dir;
1417 memset(snd_control, 0, sizeof(*snd_control)); 1374 memset(snd_control, 0, sizeof(*snd_control));
1418 snd_control->name = hpi_ctl->name; 1375 snd_control->name = hpi_ctl->name;
1419 snd_control->private_value = hpi_ctl->h_control; 1376 snd_control->private_value = hpi_ctl->h_control;
1420 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1377 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1421 snd_control->index = 0; 1378 snd_control->index = 0;
1422 1379
1423 if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM) 1380 if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE)
1381 dir = ""; /* clock is neither capture nor playback */
1382 else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
1424 dir = "Capture "; /* On or towards a PCM capture destination*/ 1383 dir = "Capture "; /* On or towards a PCM capture destination*/
1425 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) && 1384 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1426 (!hpi_ctl->dst_node_type)) 1385 (!hpi_ctl->dst_node_type))
@@ -1433,7 +1392,7 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1433 dir = "Playback "; /* PCM Playback source, or output node */ 1392 dir = "Playback "; /* PCM Playback source, or output node */
1434 1393
1435 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type) 1394 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1436 sprintf(hpi_ctl->name, "%s%d %s%d %s%s", 1395 sprintf(hpi_ctl->name, "%s %d %s %d %s%s",
1437 asihpi_src_names[hpi_ctl->src_node_type], 1396 asihpi_src_names[hpi_ctl->src_node_type],
1438 hpi_ctl->src_node_index, 1397 hpi_ctl->src_node_index,
1439 asihpi_dst_names[hpi_ctl->dst_node_type], 1398 asihpi_dst_names[hpi_ctl->dst_node_type],
@@ -2875,14 +2834,14 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2875 if (err) 2834 if (err)
2876 asihpi->update_interval_frames = 512; 2835 asihpi->update_interval_frames = 512;
2877 2836
2878 if (!asihpi->support_mmap) 2837 if (!asihpi->can_dma)
2879 asihpi->update_interval_frames *= 2; 2838 asihpi->update_interval_frames *= 2;
2880 2839
2881 hpi_handle_error(hpi_instream_open(asihpi->adapter_index, 2840 hpi_handle_error(hpi_instream_open(asihpi->adapter_index,
2882 0, &h_stream)); 2841 0, &h_stream));
2883 2842
2884 err = hpi_instream_host_buffer_free(h_stream); 2843 err = hpi_instream_host_buffer_free(h_stream);
2885 asihpi->support_mmap = (!err); 2844 asihpi->can_dma = (!err);
2886 2845
2887 hpi_handle_error(hpi_instream_close(h_stream)); 2846 hpi_handle_error(hpi_instream_close(h_stream));
2888 2847
@@ -2894,8 +2853,8 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2894 asihpi->out_max_chans = 2; 2853 asihpi->out_max_chans = 2;
2895 } 2854 }
2896 2855
2897 snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n", 2856 snd_printk(KERN_INFO "has dma:%d, grouping:%d, mrx:%d\n",
2898 asihpi->support_mmap, 2857 asihpi->can_dma,
2899 asihpi->support_grouping, 2858 asihpi->support_grouping,
2900 asihpi->support_mrx 2859 asihpi->support_mrx
2901 ); 2860 );
@@ -2925,10 +2884,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2925 by enable_hwdep module param*/ 2884 by enable_hwdep module param*/
2926 snd_asihpi_hpi_new(asihpi, 0, NULL); 2885 snd_asihpi_hpi_new(asihpi, 0, NULL);
2927 2886
2928 if (asihpi->support_mmap) 2887 strcpy(card->driver, "ASIHPI");
2929 strcpy(card->driver, "ASIHPI-MMAP");
2930 else
2931 strcpy(card->driver, "ASIHPI");
2932 2888
2933 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type); 2889 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
2934 sprintf(card->longname, "%s %i", 2890 sprintf(card->longname, "%s %i",
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
index 8c8aac4c567e..df4aed5295dd 100644
--- a/sound/pci/asihpi/hpi6000.c
+++ b/sound/pci/asihpi/hpi6000.c
@@ -200,8 +200,8 @@ static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
200static void subsys_create_adapter(struct hpi_message *phm, 200static void subsys_create_adapter(struct hpi_message *phm,
201 struct hpi_response *phr); 201 struct hpi_response *phr);
202 202
203static void subsys_delete_adapter(struct hpi_message *phm, 203static void adapter_delete(struct hpi_adapter_obj *pao,
204 struct hpi_response *phr); 204 struct hpi_message *phm, struct hpi_response *phr);
205 205
206static void adapter_get_asserts(struct hpi_adapter_obj *pao, 206static void adapter_get_asserts(struct hpi_adapter_obj *pao,
207 struct hpi_message *phm, struct hpi_response *phr); 207 struct hpi_message *phm, struct hpi_response *phr);
@@ -222,9 +222,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
222 case HPI_SUBSYS_CREATE_ADAPTER: 222 case HPI_SUBSYS_CREATE_ADAPTER:
223 subsys_create_adapter(phm, phr); 223 subsys_create_adapter(phm, phr);
224 break; 224 break;
225 case HPI_SUBSYS_DELETE_ADAPTER:
226 subsys_delete_adapter(phm, phr);
227 break;
228 default: 225 default:
229 phr->error = HPI_ERROR_INVALID_FUNC; 226 phr->error = HPI_ERROR_INVALID_FUNC;
230 break; 227 break;
@@ -279,6 +276,10 @@ static void adapter_message(struct hpi_adapter_obj *pao,
279 adapter_get_asserts(pao, phm, phr); 276 adapter_get_asserts(pao, phm, phr);
280 break; 277 break;
281 278
279 case HPI_ADAPTER_DELETE:
280 adapter_delete(pao, phm, phr);
281 break;
282
282 default: 283 default:
283 hw_message(pao, phm, phr); 284 hw_message(pao, phm, phr);
284 break; 285 break;
@@ -333,26 +334,22 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
333{ 334{
334 struct hpi_adapter_obj *pao = NULL; 335 struct hpi_adapter_obj *pao = NULL;
335 336
336 /* subsytem messages get executed by every HPI. */
337 /* All other messages are ignored unless the adapter index matches */
338 /* an adapter in the HPI */
339 /*HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->wObject, phm->wFunction); */
340
341 /* if Dsp has crashed then do not communicate with it any more */
342 if (phm->object != HPI_OBJ_SUBSYSTEM) { 337 if (phm->object != HPI_OBJ_SUBSYSTEM) {
343 pao = hpi_find_adapter(phm->adapter_index); 338 pao = hpi_find_adapter(phm->adapter_index);
344 if (!pao) { 339 if (!pao) {
345 HPI_DEBUG_LOG(DEBUG, 340 hpi_init_response(phr, phm->object, phm->function,
346 " %d,%d refused, for another HPI?\n", 341 HPI_ERROR_BAD_ADAPTER_NUMBER);
347 phm->object, phm->function); 342 HPI_DEBUG_LOG(DEBUG, "invalid adapter index: %d \n",
343 phm->adapter_index);
348 return; 344 return;
349 } 345 }
350 346
347 /* Don't even try to communicate with crashed DSP */
351 if (pao->dsp_crashed >= 10) { 348 if (pao->dsp_crashed >= 10) {
352 hpi_init_response(phr, phm->object, phm->function, 349 hpi_init_response(phr, phm->object, phm->function,
353 HPI_ERROR_DSP_HARDWARE); 350 HPI_ERROR_DSP_HARDWARE);
354 HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n", 351 HPI_DEBUG_LOG(DEBUG, "adapter %d dsp crashed\n",
355 phm->object, phm->function); 352 phm->adapter_index);
356 return; 353 return;
357 } 354 }
358 } 355 }
@@ -463,15 +460,9 @@ static void subsys_create_adapter(struct hpi_message *phm,
463 phr->error = 0; 460 phr->error = 0;
464} 461}
465 462
466static void subsys_delete_adapter(struct hpi_message *phm, 463static void adapter_delete(struct hpi_adapter_obj *pao,
467 struct hpi_response *phr) 464 struct hpi_message *phm, struct hpi_response *phr)
468{ 465{
469 struct hpi_adapter_obj *pao = NULL;
470
471 pao = hpi_find_adapter(phm->obj_index);
472 if (!pao)
473 return;
474
475 delete_adapter_obj(pao); 466 delete_adapter_obj(pao);
476 hpi_delete_adapter(pao); 467 hpi_delete_adapter(pao);
477 phr->error = 0; 468 phr->error = 0;
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
index 22e9f08dea6d..9d5df54a6b46 100644
--- a/sound/pci/asihpi/hpi6205.c
+++ b/sound/pci/asihpi/hpi6205.c
@@ -152,8 +152,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
152 152
153static void subsys_create_adapter(struct hpi_message *phm, 153static void subsys_create_adapter(struct hpi_message *phm,
154 struct hpi_response *phr); 154 struct hpi_response *phr);
155static void subsys_delete_adapter(struct hpi_message *phm, 155static void adapter_delete(struct hpi_adapter_obj *pao,
156 struct hpi_response *phr); 156 struct hpi_message *phm, struct hpi_response *phr);
157 157
158static u16 create_adapter_obj(struct hpi_adapter_obj *pao, 158static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
159 u32 *pos_error_code); 159 u32 *pos_error_code);
@@ -223,15 +223,13 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
223 223
224/*****************************************************************************/ 224/*****************************************************************************/
225 225
226static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) 226static void subsys_message(struct hpi_adapter_obj *pao,
227 struct hpi_message *phm, struct hpi_response *phr)
227{ 228{
228 switch (phm->function) { 229 switch (phm->function) {
229 case HPI_SUBSYS_CREATE_ADAPTER: 230 case HPI_SUBSYS_CREATE_ADAPTER:
230 subsys_create_adapter(phm, phr); 231 subsys_create_adapter(phm, phr);
231 break; 232 break;
232 case HPI_SUBSYS_DELETE_ADAPTER:
233 subsys_delete_adapter(phm, phr);
234 break;
235 default: 233 default:
236 phr->error = HPI_ERROR_INVALID_FUNC; 234 phr->error = HPI_ERROR_INVALID_FUNC;
237 break; 235 break;
@@ -279,6 +277,10 @@ static void adapter_message(struct hpi_adapter_obj *pao,
279 struct hpi_message *phm, struct hpi_response *phr) 277 struct hpi_message *phm, struct hpi_response *phr)
280{ 278{
281 switch (phm->function) { 279 switch (phm->function) {
280 case HPI_ADAPTER_DELETE:
281 adapter_delete(pao, phm, phr);
282 break;
283
282 default: 284 default:
283 hw_message(pao, phm, phr); 285 hw_message(pao, phm, phr);
284 break; 286 break;
@@ -371,36 +373,17 @@ static void instream_message(struct hpi_adapter_obj *pao,
371/** Entry point to this HPI backend 373/** Entry point to this HPI backend
372 * All calls to the HPI start here 374 * All calls to the HPI start here
373 */ 375 */
374void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) 376void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
377 struct hpi_response *phr)
375{ 378{
376 struct hpi_adapter_obj *pao = NULL; 379 if (pao && (pao->dsp_crashed >= 10)
377 380 && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
378 /* subsytem messages are processed by every HPI. 381 /* allow last resort debug read even after crash */
379 * All other messages are ignored unless the adapter index matches 382 hpi_init_response(phr, phm->object, phm->function,
380 * an adapter in the HPI 383 HPI_ERROR_DSP_HARDWARE);
381 */ 384 HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", phm->object,
382 /* HPI_DEBUG_LOG(DEBUG, "HPI Obj=%d, Func=%d\n", phm->wObject, 385 phm->function);
383 phm->wFunction); */ 386 return;
384
385 /* if Dsp has crashed then do not communicate with it any more */
386 if (phm->object != HPI_OBJ_SUBSYSTEM) {
387 pao = hpi_find_adapter(phm->adapter_index);
388 if (!pao) {
389 HPI_DEBUG_LOG(DEBUG,
390 " %d,%d refused, for another HPI?\n",
391 phm->object, phm->function);
392 return;
393 }
394
395 if ((pao->dsp_crashed >= 10)
396 && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
397 /* allow last resort debug read even after crash */
398 hpi_init_response(phr, phm->object, phm->function,
399 HPI_ERROR_DSP_HARDWARE);
400 HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n",
401 phm->object, phm->function);
402 return;
403 }
404 } 387 }
405 388
406 /* Init default response */ 389 /* Init default response */
@@ -412,7 +395,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
412 case HPI_TYPE_MESSAGE: 395 case HPI_TYPE_MESSAGE:
413 switch (phm->object) { 396 switch (phm->object) {
414 case HPI_OBJ_SUBSYSTEM: 397 case HPI_OBJ_SUBSYSTEM:
415 subsys_message(phm, phr); 398 subsys_message(pao, phm, phr);
416 break; 399 break;
417 400
418 case HPI_OBJ_ADAPTER: 401 case HPI_OBJ_ADAPTER:
@@ -444,6 +427,26 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
444 } 427 }
445} 428}
446 429
430void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
431{
432 struct hpi_adapter_obj *pao = NULL;
433
434 if (phm->object != HPI_OBJ_SUBSYSTEM) {
435 /* normal messages must have valid adapter index */
436 pao = hpi_find_adapter(phm->adapter_index);
437 } else {
438 /* subsys messages don't address an adapter */
439 _HPI_6205(NULL, phm, phr);
440 return;
441 }
442
443 if (pao)
444 _HPI_6205(pao, phm, phr);
445 else
446 hpi_init_response(phr, phm->object, phm->function,
447 HPI_ERROR_BAD_ADAPTER_NUMBER);
448}
449
447/*****************************************************************************/ 450/*****************************************************************************/
448/* SUBSYSTEM */ 451/* SUBSYSTEM */
449 452
@@ -491,13 +494,11 @@ static void subsys_create_adapter(struct hpi_message *phm,
491} 494}
492 495
493/** delete an adapter - required by WDM driver */ 496/** delete an adapter - required by WDM driver */
494static void subsys_delete_adapter(struct hpi_message *phm, 497static void adapter_delete(struct hpi_adapter_obj *pao,
495 struct hpi_response *phr) 498 struct hpi_message *phm, struct hpi_response *phr)
496{ 499{
497 struct hpi_adapter_obj *pao;
498 struct hpi_hw_obj *phw; 500 struct hpi_hw_obj *phw;
499 501
500 pao = hpi_find_adapter(phm->obj_index);
501 if (!pao) { 502 if (!pao) {
502 phr->error = HPI_ERROR_INVALID_OBJ_INDEX; 503 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
503 return; 504 return;
@@ -563,11 +564,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
563 } 564 }
564 565
565 err = adapter_boot_load_dsp(pao, pos_error_code); 566 err = adapter_boot_load_dsp(pao, pos_error_code);
566 if (err) 567 if (err) {
568 HPI_DEBUG_LOG(ERROR, "DSP code load failed\n");
567 /* no need to clean up as SubSysCreateAdapter */ 569 /* no need to clean up as SubSysCreateAdapter */
568 /* calls DeleteAdapter on error. */ 570 /* calls DeleteAdapter on error. */
569 return err; 571 return err;
570 572 }
571 HPI_DEBUG_LOG(INFO, "load DSP code OK\n"); 573 HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
572 574
573 /* allow boot load even if mem alloc wont work */ 575 /* allow boot load even if mem alloc wont work */
@@ -604,6 +606,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
604 control_cache.number_of_controls, 606 control_cache.number_of_controls,
605 interface->control_cache.size_in_bytes, 607 interface->control_cache.size_in_bytes,
606 p_control_cache_virtual); 608 p_control_cache_virtual);
609
607 if (!phw->p_cache) 610 if (!phw->p_cache)
608 err = HPI_ERROR_MEMORY_ALLOC; 611 err = HPI_ERROR_MEMORY_ALLOC;
609 } 612 }
@@ -675,16 +678,14 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
675} 678}
676 679
677/** Free memory areas allocated by adapter 680/** Free memory areas allocated by adapter
678 * this routine is called from SubSysDeleteAdapter, 681 * this routine is called from AdapterDelete,
679 * and SubSysCreateAdapter if duplicate index 682 * and SubSysCreateAdapter if duplicate index
680*/ 683*/
681static void delete_adapter_obj(struct hpi_adapter_obj *pao) 684static void delete_adapter_obj(struct hpi_adapter_obj *pao)
682{ 685{
683 struct hpi_hw_obj *phw; 686 struct hpi_hw_obj *phw = pao->priv;
684 int i; 687 int i;
685 688
686 phw = pao->priv;
687
688 if (hpios_locked_mem_valid(&phw->h_control_cache)) { 689 if (hpios_locked_mem_valid(&phw->h_control_cache)) {
689 hpios_locked_mem_free(&phw->h_control_cache); 690 hpios_locked_mem_free(&phw->h_control_cache);
690 hpi_free_control_cache(phw->p_cache); 691 hpi_free_control_cache(phw->p_cache);
@@ -1275,6 +1276,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1275 case HPI_ADAPTER_FAMILY_ASI(0x6300): 1276 case HPI_ADAPTER_FAMILY_ASI(0x6300):
1276 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400); 1277 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400);
1277 break; 1278 break;
1279 case HPI_ADAPTER_FAMILY_ASI(0x5500):
1278 case HPI_ADAPTER_FAMILY_ASI(0x5600): 1280 case HPI_ADAPTER_FAMILY_ASI(0x5600):
1279 case HPI_ADAPTER_FAMILY_ASI(0x6500): 1281 case HPI_ADAPTER_FAMILY_ASI(0x6500):
1280 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600); 1282 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600);
@@ -2059,7 +2061,6 @@ static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
2059static void send_dsp_command(struct hpi_hw_obj *phw, int cmd) 2061static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
2060{ 2062{
2061 struct bus_master_interface *interface = phw->p_interface_buffer; 2063 struct bus_master_interface *interface = phw->p_interface_buffer;
2062
2063 u32 r; 2064 u32 r;
2064 2065
2065 interface->host_cmd = cmd; 2066 interface->host_cmd = cmd;
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
index 3b9fd115da36..bf5eced76bac 100644
--- a/sound/pci/asihpi/hpi_internal.h
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -294,7 +294,7 @@ enum HPI_CONTROL_ATTRIBUTES {
294 294
295/* These defines are used to fill in protocol information for an Ethernet packet 295/* These defines are used to fill in protocol information for an Ethernet packet
296 sent using HMI on CS18102 */ 296 sent using HMI on CS18102 */
297/** ID supplied by Cirrius for ASI packets. */ 297/** ID supplied by Cirrus for ASI packets. */
298#define HPI_ETHERNET_PACKET_ID 0x85 298#define HPI_ETHERNET_PACKET_ID 0x85
299/** Simple packet - no special routing required */ 299/** Simple packet - no special routing required */
300#define HPI_ETHERNET_PACKET_V1 0x01 300#define HPI_ETHERNET_PACKET_V1 0x01
@@ -307,7 +307,7 @@ enum HPI_CONTROL_ATTRIBUTES {
307/** This packet must make its way to the host across the HPI interface */ 307/** This packet must make its way to the host across the HPI interface */
308#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41 308#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41
309 309
310#define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */ 310#define HPI_ETHERNET_UDP_PORT 44600 /**< HPI UDP service */
311 311
312/** Default network timeout in milli-seconds. */ 312/** Default network timeout in milli-seconds. */
313#define HPI_ETHERNET_TIMEOUT_MS 500 313#define HPI_ETHERNET_TIMEOUT_MS 500
@@ -397,14 +397,14 @@ enum HPI_FUNCTION_IDS {
397 HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1), 397 HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1),
398 HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2), 398 HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2),
399 HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3), 399 HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3),
400 HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), 400 /* HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), */
401 HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5), 401 HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5),
402 HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6), 402 HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6),
403 HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), 403 /* HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), */
404 HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8), 404 HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8),
405 HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9), 405 HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9),
406 HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), 406 /* HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), */
407 HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), 407 /* HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), */
408 HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12), 408 HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12),
409 HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13), 409 HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13),
410 HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14), 410 HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14),
@@ -433,7 +433,8 @@ enum HPI_FUNCTION_IDS {
433 HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18), 433 HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18),
434 HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19), 434 HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19),
435 HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20), 435 HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20),
436#define HPI_ADAPTER_FUNCTION_COUNT 20 436 HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21),
437#define HPI_ADAPTER_FUNCTION_COUNT 21
437 438
438 HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1), 439 HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1),
439 HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2), 440 HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2),
@@ -1561,8 +1562,6 @@ void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr);
1561u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource, 1562u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource,
1562 u16 *pw_adapter_index); 1563 u16 *pw_adapter_index);
1563 1564
1564u16 hpi_subsys_delete_adapter(u16 adapter_index);
1565
1566u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer, 1565u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer,
1567 struct hpi_hostbuffer_status **pp_status); 1566 struct hpi_hostbuffer_status **pp_status);
1568 1567
@@ -1584,9 +1583,7 @@ void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR);
1584 1583
1585/*////////////////////////////////////////////////////////////////////////// */ 1584/*////////////////////////////////////////////////////////////////////////// */
1586/* declarations for individual HPI entry points */ 1585/* declarations for individual HPI entry points */
1587hpi_handler_func HPI_1000;
1588hpi_handler_func HPI_6000; 1586hpi_handler_func HPI_6000;
1589hpi_handler_func HPI_6205; 1587hpi_handler_func HPI_6205;
1590hpi_handler_func HPI_COMMON;
1591 1588
1592#endif /* _HPI_INTERNAL_H_ */ 1589#endif /* _HPI_INTERNAL_H_ */
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
index 3e9c5c289764..b15a02e91f82 100644
--- a/sound/pci/asihpi/hpicmn.c
+++ b/sound/pci/asihpi/hpicmn.c
@@ -227,8 +227,9 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
227 if (info->control_type) { 227 if (info->control_type) {
228 pC->p_info[info->control_index] = info; 228 pC->p_info[info->control_index] = info;
229 cached++; 229 cached++;
230 } else /* dummy cache entry */ 230 } else { /* dummy cache entry */
231 pC->p_info[info->control_index] = NULL; 231 pC->p_info[info->control_index] = NULL;
232 }
232 233
233 byte_count += info->size_in32bit_words * 4; 234 byte_count += info->size_in32bit_words * 4;
234 235
@@ -298,7 +299,7 @@ struct pad_ofs_size {
298 unsigned int field_size; 299 unsigned int field_size;
299}; 300};
300 301
301static struct pad_ofs_size pad_desc[] = { 302static const struct pad_ofs_size pad_desc[] = {
302 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */ 303 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
303 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */ 304 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */
304 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */ 305 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */
@@ -617,6 +618,10 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
617 } 618 }
618} 619}
619 620
621/** Allocate control cache.
622
623\return Cache pointer, or NULL if allocation fails.
624*/
620struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count, 625struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
621 const u32 size_in_bytes, u8 *p_dsp_control_buffer) 626 const u32 size_in_bytes, u8 *p_dsp_control_buffer)
622{ 627{
@@ -667,7 +672,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
667 phr->u.s.num_adapters = adapters.gw_num_adapters; 672 phr->u.s.num_adapters = adapters.gw_num_adapters;
668 break; 673 break;
669 case HPI_SUBSYS_CREATE_ADAPTER: 674 case HPI_SUBSYS_CREATE_ADAPTER:
670 case HPI_SUBSYS_DELETE_ADAPTER:
671 break; 675 break;
672 default: 676 default:
673 phr->error = HPI_ERROR_INVALID_FUNC; 677 phr->error = HPI_ERROR_INVALID_FUNC;
diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h
index 590f0b69e655..d53cdf6e535f 100644
--- a/sound/pci/asihpi/hpicmn.h
+++ b/sound/pci/asihpi/hpicmn.h
@@ -60,3 +60,5 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *pC,
60 struct hpi_message *phm, struct hpi_response *phr); 60 struct hpi_message *phm, struct hpi_response *phr);
61 61
62u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr); 62u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr);
63
64hpi_handler_func HPI_COMMON;
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
index c38fc9487560..7397b169b89f 100644
--- a/sound/pci/asihpi/hpifunc.c
+++ b/sound/pci/asihpi/hpifunc.c
@@ -105,33 +105,6 @@ u16 hpi_subsys_get_version_ex(u32 *pversion_ex)
105 return hr.error; 105 return hr.error;
106} 106}
107 107
108u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource,
109 u16 *pw_adapter_index)
110{
111 struct hpi_message hm;
112 struct hpi_response hr;
113
114 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
115 HPI_SUBSYS_CREATE_ADAPTER);
116 hm.u.s.resource = *p_resource;
117
118 hpi_send_recv(&hm, &hr);
119
120 *pw_adapter_index = hr.u.s.adapter_index;
121 return hr.error;
122}
123
124u16 hpi_subsys_delete_adapter(u16 adapter_index)
125{
126 struct hpi_message hm;
127 struct hpi_response hr;
128 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
129 HPI_SUBSYS_DELETE_ADAPTER);
130 hm.obj_index = adapter_index;
131 hpi_send_recv(&hm, &hr);
132 return hr.error;
133}
134
135u16 hpi_subsys_get_num_adapters(int *pn_num_adapters) 108u16 hpi_subsys_get_num_adapters(int *pn_num_adapters)
136{ 109{
137 struct hpi_message hm; 110 struct hpi_message hm;
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c
index 360028b9abf5..7352a5f7b4f7 100644
--- a/sound/pci/asihpi/hpimsgx.c
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -211,24 +211,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
211 HPIMSGX__init(phm, phr); 211 HPIMSGX__init(phm, phr);
212 break; 212 break;
213 213
214 case HPI_SUBSYS_DELETE_ADAPTER:
215 HPIMSGX__cleanup(phm->obj_index, h_owner);
216 {
217 struct hpi_message hm;
218 struct hpi_response hr;
219 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
220 HPI_ADAPTER_CLOSE);
221 hm.adapter_index = phm->obj_index;
222 hw_entry_point(&hm, &hr);
223 }
224 if ((phm->obj_index < HPI_MAX_ADAPTERS)
225 && hpi_entry_points[phm->obj_index]) {
226 hpi_entry_points[phm->obj_index] (phm, phr);
227 hpi_entry_points[phm->obj_index] = NULL;
228 } else
229 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
230
231 break;
232 default: 214 default:
233 /* Must explicitly handle every subsys message in this switch */ 215 /* Must explicitly handle every subsys message in this switch */
234 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 216 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function,
@@ -247,6 +229,19 @@ static void adapter_message(struct hpi_message *phm, struct hpi_response *phr,
247 case HPI_ADAPTER_CLOSE: 229 case HPI_ADAPTER_CLOSE:
248 adapter_close(phm, phr); 230 adapter_close(phm, phr);
249 break; 231 break;
232 case HPI_ADAPTER_DELETE:
233 HPIMSGX__cleanup(phm->adapter_index, h_owner);
234 {
235 struct hpi_message hm;
236 struct hpi_response hr;
237 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
238 HPI_ADAPTER_CLOSE);
239 hm.adapter_index = phm->adapter_index;
240 hw_entry_point(&hm, &hr);
241 }
242 hw_entry_point(phm, phr);
243 break;
244
250 default: 245 default:
251 hw_entry_point(phm, phr); 246 hw_entry_point(phm, phr);
252 break; 247 break;
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index cd624f13ff8e..d8e7047512f8 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -25,6 +25,7 @@ Common Linux HPI ioctl and module probe/remove functions
25#include "hpidebug.h" 25#include "hpidebug.h"
26#include "hpimsgx.h" 26#include "hpimsgx.h"
27#include "hpioctl.h" 27#include "hpioctl.h"
28#include "hpicmn.h"
28 29
29#include <linux/fs.h> 30#include <linux/fs.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
@@ -161,26 +162,24 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
161 goto out; 162 goto out;
162 } 163 }
163 164
164 pa = &adapters[hm->h.adapter_index]; 165 switch (hm->h.function) {
166 case HPI_SUBSYS_CREATE_ADAPTER:
167 case HPI_ADAPTER_DELETE:
168 /* Application must not use these functions! */
169 hr->h.size = sizeof(hr->h);
170 hr->h.error = HPI_ERROR_INVALID_OPERATION;
171 hr->h.function = hm->h.function;
172 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
173 if (uncopied_bytes)
174 err = -EFAULT;
175 else
176 err = 0;
177 goto out;
178 }
179
165 hr->h.size = res_max_size; 180 hr->h.size = res_max_size;
166 if (hm->h.object == HPI_OBJ_SUBSYSTEM) { 181 if (hm->h.object == HPI_OBJ_SUBSYSTEM) {
167 switch (hm->h.function) { 182 hpi_send_recv_f(&hm->m0, &hr->r0, file);
168 case HPI_SUBSYS_CREATE_ADAPTER:
169 case HPI_SUBSYS_DELETE_ADAPTER:
170 /* Application must not use these functions! */
171 hr->h.size = sizeof(hr->h);
172 hr->h.error = HPI_ERROR_INVALID_OPERATION;
173 hr->h.function = hm->h.function;
174 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
175 if (uncopied_bytes)
176 err = -EFAULT;
177 else
178 err = 0;
179 goto out;
180
181 default:
182 hpi_send_recv_f(&hm->m0, &hr->r0, file);
183 }
184 } else { 183 } else {
185 u16 __user *ptr = NULL; 184 u16 __user *ptr = NULL;
186 u32 size = 0; 185 u32 size = 0;
@@ -188,8 +187,9 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
188 /* -1=no data 0=read from user mem, 1=write to user mem */ 187 /* -1=no data 0=read from user mem, 1=write to user mem */
189 int wrflag = -1; 188 int wrflag = -1;
190 u32 adapter = hm->h.adapter_index; 189 u32 adapter = hm->h.adapter_index;
190 pa = &adapters[adapter];
191 191
192 if ((hm->h.adapter_index > HPI_MAX_ADAPTERS) || (!pa->type)) { 192 if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) {
193 hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER, 193 hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER,
194 HPI_ADAPTER_OPEN, 194 HPI_ADAPTER_OPEN,
195 HPI_ERROR_BAD_ADAPTER_NUMBER); 195 HPI_ERROR_BAD_ADAPTER_NUMBER);
@@ -317,7 +317,7 @@ out:
317int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, 317int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
318 const struct pci_device_id *pci_id) 318 const struct pci_device_id *pci_id)
319{ 319{
320 int err, idx, nm; 320 int idx, nm;
321 unsigned int memlen; 321 unsigned int memlen;
322 struct hpi_message hm; 322 struct hpi_message hm;
323 struct hpi_response hr; 323 struct hpi_response hr;
@@ -351,11 +351,8 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
351 nm = HPI_MAX_ADAPTER_MEM_SPACES; 351 nm = HPI_MAX_ADAPTER_MEM_SPACES;
352 352
353 for (idx = 0; idx < nm; idx++) { 353 for (idx = 0; idx < nm; idx++) {
354 HPI_DEBUG_LOG(INFO, "resource %d %s %08llx-%08llx %04llx\n", 354 HPI_DEBUG_LOG(INFO, "resource %d %pR\n", idx,
355 idx, pci_dev->resource[idx].name, 355 &pci_dev->resource[idx]);
356 (unsigned long long)pci_resource_start(pci_dev, idx),
357 (unsigned long long)pci_resource_end(pci_dev, idx),
358 (unsigned long long)pci_resource_flags(pci_dev, idx));
359 356
360 if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) { 357 if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) {
361 memlen = pci_resource_len(pci_dev, idx); 358 memlen = pci_resource_len(pci_dev, idx);
@@ -395,17 +392,20 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
395 392
396 adapter.index = hr.u.s.adapter_index; 393 adapter.index = hr.u.s.adapter_index;
397 adapter.type = hr.u.s.adapter_type; 394 adapter.type = hr.u.s.adapter_type;
395
396 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
397 HPI_ADAPTER_OPEN);
398 hm.adapter_index = adapter.index; 398 hm.adapter_index = adapter.index;
399 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
399 400
400 err = hpi_adapter_open(adapter.index); 401 if (hr.error)
401 if (err)
402 goto err; 402 goto err;
403 403
404 adapter.snd_card_asihpi = NULL; 404 adapter.snd_card_asihpi = NULL;
405 /* WARNING can't init mutex in 'adapter' 405 /* WARNING can't init mutex in 'adapter'
406 * and then copy it to adapters[] ?!?! 406 * and then copy it to adapters[] ?!?!
407 */ 407 */
408 adapters[hr.u.s.adapter_index] = adapter; 408 adapters[adapter.index] = adapter;
409 mutex_init(&adapters[adapter.index].mutex); 409 mutex_init(&adapters[adapter.index].mutex);
410 pci_set_drvdata(pci_dev, &adapters[adapter.index]); 410 pci_set_drvdata(pci_dev, &adapters[adapter.index]);
411 411
@@ -440,10 +440,9 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
440 struct hpi_adapter *pa; 440 struct hpi_adapter *pa;
441 pa = pci_get_drvdata(pci_dev); 441 pa = pci_get_drvdata(pci_dev);
442 442
443 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, 443 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
444 HPI_SUBSYS_DELETE_ADAPTER); 444 HPI_ADAPTER_DELETE);
445 hm.obj_index = pa->index; 445 hm.adapter_index = pa->index;
446 hm.adapter_index = HPI_ADAPTER_INDEX_INVALID;
447 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); 446 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
448 447
449 /* unmap PCI memory space, mapped during device init. */ 448 /* unmap PCI memory space, mapped during device init. */
diff --git a/sound/pci/au88x0/au8810.h b/sound/pci/au88x0/au8810.h
index 5d69c31fe3f4..79fbee3845eb 100644
--- a/sound/pci/au88x0/au8810.h
+++ b/sound/pci/au88x0/au8810.h
@@ -4,7 +4,7 @@
4 4
5#define CHIP_AU8810 5#define CHIP_AU8810
6 6
7#define CARD_NAME "Aureal Advantage 3D Sound Processor" 7#define CARD_NAME "Aureal Advantage"
8#define CARD_NAME_SHORT "au8810" 8#define CARD_NAME_SHORT "au8810"
9 9
10#define NR_ADB 0x10 10#define NR_ADB 0x10
diff --git a/sound/pci/au88x0/au8820.h b/sound/pci/au88x0/au8820.h
index abbe85e4f7a9..cafdb9668a34 100644
--- a/sound/pci/au88x0/au8820.h
+++ b/sound/pci/au88x0/au8820.h
@@ -11,7 +11,7 @@
11 11
12#define CHIP_AU8820 12#define CHIP_AU8820
13 13
14#define CARD_NAME "Aureal Vortex 3D Sound Processor" 14#define CARD_NAME "Aureal Vortex"
15#define CARD_NAME_SHORT "au8820" 15#define CARD_NAME_SHORT "au8820"
16 16
17/* Number of ADB and WT channels */ 17/* Number of ADB and WT channels */
diff --git a/sound/pci/au88x0/au8830.h b/sound/pci/au88x0/au8830.h
index 04ece1b1c218..999b29ab34ad 100644
--- a/sound/pci/au88x0/au8830.h
+++ b/sound/pci/au88x0/au8830.h
@@ -11,7 +11,7 @@
11 11
12#define CHIP_AU8830 12#define CHIP_AU8830
13 13
14#define CARD_NAME "Aureal Vortex 2 3D Sound Processor" 14#define CARD_NAME "Aureal Vortex 2"
15#define CARD_NAME_SHORT "au8830" 15#define CARD_NAME_SHORT "au8830"
16 16
17#define NR_ADB 0x20 17#define NR_ADB 0x20
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index 62e959120c44..c5f7ae46afef 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -426,11 +426,11 @@ static struct snd_pcm_ops snd_vortex_playback_ops = {
426*/ 426*/
427 427
428static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = { 428static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = {
429 "AU88x0 ADB", 429 CARD_NAME " ADB",
430 "AU88x0 SPDIF", 430 CARD_NAME " SPDIF",
431 "AU88x0 A3D", 431 CARD_NAME " A3D",
432 "AU88x0 WT", 432 CARD_NAME " WT",
433 "AU88x0 I2S", 433 CARD_NAME " I2S",
434}; 434};
435static char *vortex_pcm_name[VORTEX_PCM_LAST] = { 435static char *vortex_pcm_name[VORTEX_PCM_LAST] = {
436 "adb", 436 "adb",
@@ -527,7 +527,8 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
527 nr_capt, &pcm); 527 nr_capt, &pcm);
528 if (err < 0) 528 if (err < 0)
529 return err; 529 return err;
530 strcpy(pcm->name, vortex_pcm_name[idx]); 530 snprintf(pcm->name, sizeof(pcm->name),
531 "%s %s", CARD_NAME_SHORT, vortex_pcm_name[idx]);
531 chip->pcm[idx] = pcm; 532 chip->pcm[idx] = pcm;
532 // This is an evil hack, but it saves a lot of duplicated code. 533 // This is an evil hack, but it saves a lot of duplicated code.
533 VORTEX_PCM_TYPE(pcm) = idx; 534 VORTEX_PCM_TYPE(pcm) = idx;
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 7a9401462c1c..dae4050ede5c 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -303,6 +303,9 @@ static const u32 db_table[101] = {
303static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); 303static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1);
304static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0); 304static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0);
305 305
306/* EMU10K1 bass/treble db gain */
307static const DECLARE_TLV_DB_SCALE(snd_emu10k1_bass_treble_db_scale, -1200, 60, 0);
308
306static const u32 onoff_table[2] = { 309static const u32 onoff_table[2] = {
307 0x00000000, 0x00000001 310 0x00000000, 0x00000001
308}; 311};
@@ -2163,6 +2166,7 @@ static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2163 ctl->min = 0; 2166 ctl->min = 0;
2164 ctl->max = 40; 2167 ctl->max = 40;
2165 ctl->value[0] = ctl->value[1] = 20; 2168 ctl->value[0] = ctl->value[1] = 20;
2169 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
2166 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS; 2170 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
2167 ctl = &controls[i + 1]; 2171 ctl = &controls[i + 1];
2168 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2172 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
@@ -2172,6 +2176,7 @@ static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2172 ctl->min = 0; 2176 ctl->min = 0;
2173 ctl->max = 40; 2177 ctl->max = 40;
2174 ctl->value[0] = ctl->value[1] = 20; 2178 ctl->value[0] = ctl->value[1] = 20;
2179 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
2175 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE; 2180 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
2176 2181
2177#define BASS_GPR 0x8c 2182#define BASS_GPR 0x8c
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 05afe06e353a..9d890a5aec5a 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -1729,8 +1729,6 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1729 "Master Mono Playback Volume", 1729 "Master Mono Playback Volume",
1730 "PCM Out Path & Mute", 1730 "PCM Out Path & Mute",
1731 "Mono Output Select", 1731 "Mono Output Select",
1732 "Front Playback Switch",
1733 "Front Playback Volume",
1734 "Surround Playback Switch", 1732 "Surround Playback Switch",
1735 "Surround Playback Volume", 1733 "Surround Playback Volume",
1736 "Center Playback Switch", 1734 "Center Playback Switch",
@@ -1879,6 +1877,8 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1879 emu->rear_ac97 = 1; 1877 emu->rear_ac97 = 1;
1880 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT); 1878 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
1881 snd_ac97_write_cache(emu->ac97, AC97_HEADPHONE, 0x0202); 1879 snd_ac97_write_cache(emu->ac97, AC97_HEADPHONE, 0x0202);
1880 remove_ctl(card,"Front Playback Volume");
1881 remove_ctl(card,"Front Playback Switch");
1882 } 1882 }
1883 /* remove unused AC97 controls */ 1883 /* remove unused AC97 controls */
1884 snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202); 1884 snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
@@ -1913,6 +1913,12 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1913 for (; *c; c += 2) 1913 for (; *c; c += 2)
1914 rename_ctl(card, c[0], c[1]); 1914 rename_ctl(card, c[0], c[1]);
1915 1915
1916 if (emu->card_capabilities->subsystem == 0x80401102) { /* SB Live! Platinum CT4760P */
1917 remove_ctl(card, "Center Playback Volume");
1918 remove_ctl(card, "LFE Playback Volume");
1919 remove_ctl(card, "Wave Center Playback Volume");
1920 remove_ctl(card, "Wave LFE Playback Volume");
1921 }
1916 if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */ 1922 if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */
1917 rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume"); 1923 rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume");
1918 rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume"); 1924 rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume");
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 7c17f45d876d..ab0a6156a704 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -112,6 +112,10 @@
112#include <sound/ac97_codec.h> 112#include <sound/ac97_codec.h>
113#include <sound/initval.h> 113#include <sound/initval.h>
114 114
115#ifdef CONFIG_SND_ES1968_RADIO
116#include <sound/tea575x-tuner.h>
117#endif
118
115#define CARD_NAME "ESS Maestro1/2" 119#define CARD_NAME "ESS Maestro1/2"
116#define DRIVER_NAME "ES1968" 120#define DRIVER_NAME "ES1968"
117 121
@@ -553,6 +557,10 @@ struct es1968 {
553 spinlock_t ac97_lock; 557 spinlock_t ac97_lock;
554 struct tasklet_struct hwvol_tq; 558 struct tasklet_struct hwvol_tq;
555#endif 559#endif
560
561#ifdef CONFIG_SND_ES1968_RADIO
562 struct snd_tea575x tea;
563#endif
556}; 564};
557 565
558static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); 566static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
@@ -2571,6 +2579,63 @@ static int __devinit snd_es1968_input_register(struct es1968 *chip)
2571} 2579}
2572#endif /* CONFIG_SND_ES1968_INPUT */ 2580#endif /* CONFIG_SND_ES1968_INPUT */
2573 2581
2582#ifdef CONFIG_SND_ES1968_RADIO
2583#define GPIO_DATA 0x60
2584#define IO_MASK 4 /* mask register offset from GPIO_DATA
2585 bits 1=unmask write to given bit */
2586#define IO_DIR 8 /* direction register offset from GPIO_DATA
2587 bits 0/1=read/write direction */
2588/* mask bits for GPIO lines */
2589#define STR_DATA 0x0040 /* GPIO6 */
2590#define STR_CLK 0x0080 /* GPIO7 */
2591#define STR_WREN 0x0100 /* GPIO8 */
2592#define STR_MOST 0x0200 /* GPIO9 */
2593
2594static void snd_es1968_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
2595{
2596 struct es1968 *chip = tea->private_data;
2597 unsigned long io = chip->io_port + GPIO_DATA;
2598 u16 val = 0;
2599
2600 val |= (pins & TEA575X_DATA) ? STR_DATA : 0;
2601 val |= (pins & TEA575X_CLK) ? STR_CLK : 0;
2602 val |= (pins & TEA575X_WREN) ? STR_WREN : 0;
2603
2604 outw(val, io);
2605}
2606
2607static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea)
2608{
2609 struct es1968 *chip = tea->private_data;
2610 unsigned long io = chip->io_port + GPIO_DATA;
2611 u16 val = inw(io);
2612
2613 return (val & STR_DATA) ? TEA575X_DATA : 0 |
2614 (val & STR_MOST) ? TEA575X_MOST : 0;
2615}
2616
2617static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output)
2618{
2619 struct es1968 *chip = tea->private_data;
2620 unsigned long io = chip->io_port + GPIO_DATA;
2621 u16 odir = inw(io + IO_DIR);
2622
2623 if (output) {
2624 outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
2625 outw(odir | STR_DATA | STR_CLK | STR_WREN, io + IO_DIR);
2626 } else {
2627 outw(~(STR_CLK | STR_WREN | STR_DATA | STR_MOST), io + IO_MASK);
2628 outw((odir & ~(STR_DATA | STR_MOST)) | STR_CLK | STR_WREN, io + IO_DIR);
2629 }
2630}
2631
2632static struct snd_tea575x_ops snd_es1968_tea_ops = {
2633 .set_pins = snd_es1968_tea575x_set_pins,
2634 .get_pins = snd_es1968_tea575x_get_pins,
2635 .set_direction = snd_es1968_tea575x_set_direction,
2636};
2637#endif
2638
2574static int snd_es1968_free(struct es1968 *chip) 2639static int snd_es1968_free(struct es1968 *chip)
2575{ 2640{
2576#ifdef CONFIG_SND_ES1968_INPUT 2641#ifdef CONFIG_SND_ES1968_INPUT
@@ -2585,6 +2650,10 @@ static int snd_es1968_free(struct es1968 *chip)
2585 outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */ 2650 outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */
2586 } 2651 }
2587 2652
2653#ifdef CONFIG_SND_ES1968_RADIO
2654 snd_tea575x_exit(&chip->tea);
2655#endif
2656
2588 if (chip->irq >= 0) 2657 if (chip->irq >= 0)
2589 free_irq(chip->irq, chip); 2658 free_irq(chip->irq, chip);
2590 snd_es1968_free_gameport(chip); 2659 snd_es1968_free_gameport(chip);
@@ -2723,6 +2792,15 @@ static int __devinit snd_es1968_create(struct snd_card *card,
2723 2792
2724 snd_card_set_dev(card, &pci->dev); 2793 snd_card_set_dev(card, &pci->dev);
2725 2794
2795#ifdef CONFIG_SND_ES1968_RADIO
2796 chip->tea.private_data = chip;
2797 chip->tea.ops = &snd_es1968_tea_ops;
2798 strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card));
2799 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
2800 if (!snd_tea575x_init(&chip->tea))
2801 printk(KERN_INFO "es1968: detected TEA575x radio\n");
2802#endif
2803
2726 *chip_ret = chip; 2804 *chip_ret = chip;
2727 2805
2728 return 0; 2806 return 0;
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index e1baad74ea4b..eacd4901a308 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -38,7 +38,6 @@
38 38
39#ifdef CONFIG_SND_FM801_TEA575X_BOOL 39#ifdef CONFIG_SND_FM801_TEA575X_BOOL
40#include <sound/tea575x-tuner.h> 40#include <sound/tea575x-tuner.h>
41#define TEA575X_RADIO 1
42#endif 41#endif
43 42
44MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 43MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
@@ -53,7 +52,7 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card *
53/* 52/*
54 * Enable TEA575x tuner 53 * Enable TEA575x tuner
55 * 1 = MediaForte 256-PCS 54 * 1 = MediaForte 256-PCS
56 * 2 = MediaForte 256-PCPR 55 * 2 = MediaForte 256-PCP
57 * 3 = MediaForte 64-PCR 56 * 3 = MediaForte 64-PCR
58 * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card 57 * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card
59 * High 16-bits are video (radio) device number + 1 58 * High 16-bits are video (radio) device number + 1
@@ -67,7 +66,7 @@ MODULE_PARM_DESC(id, "ID string for the FM801 soundcard.");
67module_param_array(enable, bool, NULL, 0444); 66module_param_array(enable, bool, NULL, 0444);
68MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); 67MODULE_PARM_DESC(enable, "Enable FM801 soundcard.");
69module_param_array(tea575x_tuner, int, NULL, 0444); 68module_param_array(tea575x_tuner, int, NULL, 0444);
70MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (1 = SF256-PCS, 2=SF256-PCPR, 3=SF64-PCR, +16=tuner-only)."); 69MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only).");
71 70
72#define TUNER_ONLY (1<<4) 71#define TUNER_ONLY (1<<4)
73#define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF) 72#define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF)
@@ -196,7 +195,7 @@ struct fm801 {
196 spinlock_t reg_lock; 195 spinlock_t reg_lock;
197 struct snd_info_entry *proc_entry; 196 struct snd_info_entry *proc_entry;
198 197
199#ifdef TEA575X_RADIO 198#ifdef CONFIG_SND_FM801_TEA575X_BOOL
200 struct snd_tea575x tea; 199 struct snd_tea575x tea;
201#endif 200#endif
202 201
@@ -715,310 +714,89 @@ static int __devinit snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pc
715 * TEA5757 radio 714 * TEA5757 radio
716 */ 715 */
717 716
718#ifdef TEA575X_RADIO 717#ifdef CONFIG_SND_FM801_TEA575X_BOOL
719
720/* 256PCS GPIO numbers */
721#define TEA_256PCS_DATA 1
722#define TEA_256PCS_WRITE_ENABLE 2 /* inverted */
723#define TEA_256PCS_BUS_CLOCK 3
724
725static void snd_fm801_tea575x_256pcs_write(struct snd_tea575x *tea, unsigned int val)
726{
727 struct fm801 *chip = tea->private_data;
728 unsigned short reg;
729 int i = 25;
730 718
731 spin_lock_irq(&chip->reg_lock); 719/* GPIO to TEA575x maps */
732 reg = inw(FM801_REG(chip, GPIO_CTRL)); 720struct snd_fm801_tea575x_gpio {
733 /* use GPIO lines and set write enable bit */ 721 u8 data, clk, wren, most;
734 reg |= FM801_GPIO_GS(TEA_256PCS_DATA) | 722 char *name;
735 FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) | 723};
736 FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK);
737 /* all of lines are in the write direction */
738 /* clear data and clock lines */
739 reg &= ~(FM801_GPIO_GD(TEA_256PCS_DATA) |
740 FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) |
741 FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) |
742 FM801_GPIO_GP(TEA_256PCS_DATA) |
743 FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK) |
744 FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE));
745 outw(reg, FM801_REG(chip, GPIO_CTRL));
746 udelay(1);
747
748 while (i--) {
749 if (val & (1 << i))
750 reg |= FM801_GPIO_GP(TEA_256PCS_DATA);
751 else
752 reg &= ~FM801_GPIO_GP(TEA_256PCS_DATA);
753 outw(reg, FM801_REG(chip, GPIO_CTRL));
754 udelay(1);
755 reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
756 outw(reg, FM801_REG(chip, GPIO_CTRL));
757 reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
758 outw(reg, FM801_REG(chip, GPIO_CTRL));
759 udelay(1);
760 }
761 724
762 /* and reset the write enable bit */ 725static struct snd_fm801_tea575x_gpio snd_fm801_tea575x_gpios[] = {
763 reg |= FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE) | 726 { .data = 1, .clk = 3, .wren = 2, .most = 0, .name = "SF256-PCS" },
764 FM801_GPIO_GP(TEA_256PCS_DATA); 727 { .data = 1, .clk = 0, .wren = 2, .most = 3, .name = "SF256-PCP" },
765 outw(reg, FM801_REG(chip, GPIO_CTRL)); 728 { .data = 2, .clk = 0, .wren = 1, .most = 3, .name = "SF64-PCR" },
766 spin_unlock_irq(&chip->reg_lock); 729};
767}
768 730
769static unsigned int snd_fm801_tea575x_256pcs_read(struct snd_tea575x *tea) 731static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
770{ 732{
771 struct fm801 *chip = tea->private_data; 733 struct fm801 *chip = tea->private_data;
772 unsigned short reg; 734 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
773 unsigned int val = 0; 735 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1];
774 int i;
775
776 spin_lock_irq(&chip->reg_lock);
777 reg = inw(FM801_REG(chip, GPIO_CTRL));
778 /* use GPIO lines, set data direction to input */
779 reg |= FM801_GPIO_GS(TEA_256PCS_DATA) |
780 FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) |
781 FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK) |
782 FM801_GPIO_GD(TEA_256PCS_DATA) |
783 FM801_GPIO_GP(TEA_256PCS_DATA) |
784 FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE);
785 /* all of lines are in the write direction, except data */
786 /* clear data, write enable and clock lines */
787 reg &= ~(FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) |
788 FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) |
789 FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK));
790
791 for (i = 0; i < 24; i++) {
792 reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
793 outw(reg, FM801_REG(chip, GPIO_CTRL));
794 udelay(1);
795 reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
796 outw(reg, FM801_REG(chip, GPIO_CTRL));
797 udelay(1);
798 val <<= 1;
799 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCS_DATA))
800 val |= 1;
801 }
802 736
803 spin_unlock_irq(&chip->reg_lock); 737 reg &= ~(FM801_GPIO_GP(gpio.data) |
738 FM801_GPIO_GP(gpio.clk) |
739 FM801_GPIO_GP(gpio.wren));
804 740
805 return val; 741 reg |= (pins & TEA575X_DATA) ? FM801_GPIO_GP(gpio.data) : 0;
806} 742 reg |= (pins & TEA575X_CLK) ? FM801_GPIO_GP(gpio.clk) : 0;
743 /* WRITE_ENABLE is inverted */
744 reg |= (pins & TEA575X_WREN) ? 0 : FM801_GPIO_GP(gpio.wren);
807 745
808/* 256PCPR GPIO numbers */
809#define TEA_256PCPR_BUS_CLOCK 0
810#define TEA_256PCPR_DATA 1
811#define TEA_256PCPR_WRITE_ENABLE 2 /* inverted */
812
813static void snd_fm801_tea575x_256pcpr_write(struct snd_tea575x *tea, unsigned int val)
814{
815 struct fm801 *chip = tea->private_data;
816 unsigned short reg;
817 int i = 25;
818
819 spin_lock_irq(&chip->reg_lock);
820 reg = inw(FM801_REG(chip, GPIO_CTRL));
821 /* use GPIO lines and set write enable bit */
822 reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) |
823 FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) |
824 FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK);
825 /* all of lines are in the write direction */
826 /* clear data and clock lines */
827 reg &= ~(FM801_GPIO_GD(TEA_256PCPR_DATA) |
828 FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) |
829 FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) |
830 FM801_GPIO_GP(TEA_256PCPR_DATA) |
831 FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK) |
832 FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE));
833 outw(reg, FM801_REG(chip, GPIO_CTRL)); 746 outw(reg, FM801_REG(chip, GPIO_CTRL));
834 udelay(1);
835
836 while (i--) {
837 if (val & (1 << i))
838 reg |= FM801_GPIO_GP(TEA_256PCPR_DATA);
839 else
840 reg &= ~FM801_GPIO_GP(TEA_256PCPR_DATA);
841 outw(reg, FM801_REG(chip, GPIO_CTRL));
842 udelay(1);
843 reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
844 outw(reg, FM801_REG(chip, GPIO_CTRL));
845 reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
846 outw(reg, FM801_REG(chip, GPIO_CTRL));
847 udelay(1);
848 }
849
850 /* and reset the write enable bit */
851 reg |= FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE) |
852 FM801_GPIO_GP(TEA_256PCPR_DATA);
853 outw(reg, FM801_REG(chip, GPIO_CTRL));
854 spin_unlock_irq(&chip->reg_lock);
855} 747}
856 748
857static unsigned int snd_fm801_tea575x_256pcpr_read(struct snd_tea575x *tea) 749static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea)
858{ 750{
859 struct fm801 *chip = tea->private_data; 751 struct fm801 *chip = tea->private_data;
860 unsigned short reg; 752 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
861 unsigned int val = 0; 753 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1];
862 int i;
863
864 spin_lock_irq(&chip->reg_lock);
865 reg = inw(FM801_REG(chip, GPIO_CTRL));
866 /* use GPIO lines, set data direction to input */
867 reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) |
868 FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) |
869 FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK) |
870 FM801_GPIO_GD(TEA_256PCPR_DATA) |
871 FM801_GPIO_GP(TEA_256PCPR_DATA) |
872 FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE);
873 /* all of lines are in the write direction, except data */
874 /* clear data, write enable and clock lines */
875 reg &= ~(FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) |
876 FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) |
877 FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK));
878
879 for (i = 0; i < 24; i++) {
880 reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
881 outw(reg, FM801_REG(chip, GPIO_CTRL));
882 udelay(1);
883 reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
884 outw(reg, FM801_REG(chip, GPIO_CTRL));
885 udelay(1);
886 val <<= 1;
887 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCPR_DATA))
888 val |= 1;
889 }
890 754
891 spin_unlock_irq(&chip->reg_lock); 755 return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 |
892 756 (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0;
893 return val;
894} 757}
895 758
896/* 64PCR GPIO numbers */ 759static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output)
897#define TEA_64PCR_BUS_CLOCK 0
898#define TEA_64PCR_WRITE_ENABLE 1 /* inverted */
899#define TEA_64PCR_DATA 2
900
901static void snd_fm801_tea575x_64pcr_write(struct snd_tea575x *tea, unsigned int val)
902{ 760{
903 struct fm801 *chip = tea->private_data; 761 struct fm801 *chip = tea->private_data;
904 unsigned short reg; 762 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
905 int i = 25; 763 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1];
906 764
907 spin_lock_irq(&chip->reg_lock);
908 reg = inw(FM801_REG(chip, GPIO_CTRL));
909 /* use GPIO lines and set write enable bit */ 765 /* use GPIO lines and set write enable bit */
910 reg |= FM801_GPIO_GS(TEA_64PCR_DATA) | 766 reg |= FM801_GPIO_GS(gpio.data) |
911 FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) | 767 FM801_GPIO_GS(gpio.wren) |
912 FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK); 768 FM801_GPIO_GS(gpio.clk) |
913 /* all of lines are in the write direction */ 769 FM801_GPIO_GS(gpio.most);
914 /* clear data and clock lines */ 770 if (output) {
915 reg &= ~(FM801_GPIO_GD(TEA_64PCR_DATA) | 771 /* all of lines are in the write direction */
916 FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) | 772 /* clear data and clock lines */
917 FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) | 773 reg &= ~(FM801_GPIO_GD(gpio.data) |
918 FM801_GPIO_GP(TEA_64PCR_DATA) | 774 FM801_GPIO_GD(gpio.wren) |
919 FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK) | 775 FM801_GPIO_GD(gpio.clk) |
920 FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE)); 776 FM801_GPIO_GP(gpio.data) |
921 outw(reg, FM801_REG(chip, GPIO_CTRL)); 777 FM801_GPIO_GP(gpio.clk) |
922 udelay(1); 778 FM801_GPIO_GP(gpio.wren));
923 779 } else {
924 while (i--) { 780 /* use GPIO lines, set data direction to input */
925 if (val & (1 << i)) 781 reg |= FM801_GPIO_GD(gpio.data) |
926 reg |= FM801_GPIO_GP(TEA_64PCR_DATA); 782 FM801_GPIO_GD(gpio.most) |
927 else 783 FM801_GPIO_GP(gpio.data) |
928 reg &= ~FM801_GPIO_GP(TEA_64PCR_DATA); 784 FM801_GPIO_GP(gpio.most) |
929 outw(reg, FM801_REG(chip, GPIO_CTRL)); 785 FM801_GPIO_GP(gpio.wren);
930 udelay(1); 786 /* all of lines are in the write direction, except data */
931 reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); 787 /* clear data, write enable and clock lines */
932 outw(reg, FM801_REG(chip, GPIO_CTRL)); 788 reg &= ~(FM801_GPIO_GD(gpio.wren) |
933 reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); 789 FM801_GPIO_GD(gpio.clk) |
934 outw(reg, FM801_REG(chip, GPIO_CTRL)); 790 FM801_GPIO_GP(gpio.clk));
935 udelay(1);
936 } 791 }
937 792
938 /* and reset the write enable bit */
939 reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE) |
940 FM801_GPIO_GP(TEA_64PCR_DATA);
941 outw(reg, FM801_REG(chip, GPIO_CTRL)); 793 outw(reg, FM801_REG(chip, GPIO_CTRL));
942 spin_unlock_irq(&chip->reg_lock);
943}
944
945static unsigned int snd_fm801_tea575x_64pcr_read(struct snd_tea575x *tea)
946{
947 struct fm801 *chip = tea->private_data;
948 unsigned short reg;
949 unsigned int val = 0;
950 int i;
951
952 spin_lock_irq(&chip->reg_lock);
953 reg = inw(FM801_REG(chip, GPIO_CTRL));
954 /* use GPIO lines, set data direction to input */
955 reg |= FM801_GPIO_GS(TEA_64PCR_DATA) |
956 FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) |
957 FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK) |
958 FM801_GPIO_GD(TEA_64PCR_DATA) |
959 FM801_GPIO_GP(TEA_64PCR_DATA) |
960 FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
961 /* all of lines are in the write direction, except data */
962 /* clear data, write enable and clock lines */
963 reg &= ~(FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) |
964 FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) |
965 FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK));
966
967 for (i = 0; i < 24; i++) {
968 reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
969 outw(reg, FM801_REG(chip, GPIO_CTRL));
970 udelay(1);
971 reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
972 outw(reg, FM801_REG(chip, GPIO_CTRL));
973 udelay(1);
974 val <<= 1;
975 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_64PCR_DATA))
976 val |= 1;
977 }
978
979 spin_unlock_irq(&chip->reg_lock);
980
981 return val;
982} 794}
983 795
984static void snd_fm801_tea575x_64pcr_mute(struct snd_tea575x *tea, 796static struct snd_tea575x_ops snd_fm801_tea_ops = {
985 unsigned int mute) 797 .set_pins = snd_fm801_tea575x_set_pins,
986{ 798 .get_pins = snd_fm801_tea575x_get_pins,
987 struct fm801 *chip = tea->private_data; 799 .set_direction = snd_fm801_tea575x_set_direction,
988 unsigned short reg;
989
990 spin_lock_irq(&chip->reg_lock);
991
992 reg = inw(FM801_REG(chip, GPIO_CTRL));
993 if (mute)
994 /* 0xf800 (mute) */
995 reg &= ~FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
996 else
997 /* 0xf802 (unmute) */
998 reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
999 outw(reg, FM801_REG(chip, GPIO_CTRL));
1000 udelay(1);
1001
1002 spin_unlock_irq(&chip->reg_lock);
1003}
1004
1005static struct snd_tea575x_ops snd_fm801_tea_ops[3] = {
1006 {
1007 /* 1 = MediaForte 256-PCS */
1008 .write = snd_fm801_tea575x_256pcs_write,
1009 .read = snd_fm801_tea575x_256pcs_read,
1010 },
1011 {
1012 /* 2 = MediaForte 256-PCPR */
1013 .write = snd_fm801_tea575x_256pcpr_write,
1014 .read = snd_fm801_tea575x_256pcpr_read,
1015 },
1016 {
1017 /* 3 = MediaForte 64-PCR */
1018 .write = snd_fm801_tea575x_64pcr_write,
1019 .read = snd_fm801_tea575x_64pcr_read,
1020 .mute = snd_fm801_tea575x_64pcr_mute,
1021 }
1022}; 800};
1023#endif 801#endif
1024 802
@@ -1371,7 +1149,7 @@ static int snd_fm801_free(struct fm801 *chip)
1371 outw(cmdw, FM801_REG(chip, IRQ_MASK)); 1149 outw(cmdw, FM801_REG(chip, IRQ_MASK));
1372 1150
1373 __end_hw: 1151 __end_hw:
1374#ifdef TEA575X_RADIO 1152#ifdef CONFIG_SND_FM801_TEA575X_BOOL
1375 snd_tea575x_exit(&chip->tea); 1153 snd_tea575x_exit(&chip->tea);
1376#endif 1154#endif
1377 if (chip->irq >= 0) 1155 if (chip->irq >= 0)
@@ -1450,16 +1228,25 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1450 1228
1451 snd_card_set_dev(card, &pci->dev); 1229 snd_card_set_dev(card, &pci->dev);
1452 1230
1453#ifdef TEA575X_RADIO 1231#ifdef CONFIG_SND_FM801_TEA575X_BOOL
1232 chip->tea.private_data = chip;
1233 chip->tea.ops = &snd_fm801_tea_ops;
1234 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
1454 if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && 1235 if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 &&
1455 (tea575x_tuner & TUNER_TYPE_MASK) < 4) { 1236 (tea575x_tuner & TUNER_TYPE_MASK) < 4) {
1456 chip->tea.dev_nr = tea575x_tuner >> 16; 1237 if (snd_tea575x_init(&chip->tea))
1457 chip->tea.card = card; 1238 snd_printk(KERN_ERR "TEA575x radio not found\n");
1458 chip->tea.freq_fixup = 10700; 1239 } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0)
1459 chip->tea.private_data = chip; 1240 /* autodetect tuner connection */
1460 chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & TUNER_TYPE_MASK) - 1]; 1241 for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) {
1461 snd_tea575x_init(&chip->tea); 1242 chip->tea575x_tuner = tea575x_tuner;
1462 } 1243 if (!snd_tea575x_init(&chip->tea)) {
1244 snd_printk(KERN_INFO "detected TEA575x radio type %s\n",
1245 snd_fm801_tea575x_gpios[tea575x_tuner - 1].name);
1246 break;
1247 }
1248 }
1249 strlcpy(chip->tea.card, snd_fm801_tea575x_gpios[(tea575x_tuner & TUNER_TYPE_MASK) - 1].name, sizeof(chip->tea.card));
1463#endif 1250#endif
1464 1251
1465 *rchip = chip; 1252 *rchip = chip;
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 27709f0cd2a6..f3353b49c785 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -235,8 +235,8 @@ static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0m_ids) = {
235 { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */ 235 { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */
236 { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */ 236 { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */
237 { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */ 237 { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */
238 { PCI_VDEVICE(AMD, 0x746e), DEVICE_INTEL }, /* AMD8111 */
238#if 0 239#if 0
239 { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */
240 { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */ 240 { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */
241#endif 241#endif
242 { 0, } 242 { 0, }
@@ -1261,9 +1261,9 @@ static struct shortname_table {
1261 { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" }, 1261 { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" },
1262 { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" }, 1262 { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" },
1263 { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" }, 1263 { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" },
1264 { 0x746e, "AMD AMD8111" },
1264#if 0 1265#if 0
1265 { 0x5455, "ALi M5455" }, 1266 { 0x5455, "ALi M5455" },
1266 { 0x746d, "AMD AMD8111" },
1267#endif 1267#endif
1268 { 0 }, 1268 { 0 },
1269}; 1269};
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 961d98297695..9cea84c3e0c6 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -1000,7 +1000,7 @@ static void device_change_handler(struct work_struct *work)
1000 chip->lineout_sw_ctl); 1000 chip->lineout_sw_ctl);
1001 if (mix->anded_reset) 1001 if (mix->anded_reset)
1002 msleep(10); 1002 msleep(10);
1003 check_mute(chip, &mix->amp_mute, 1, mix->auto_mute_notify, 1003 check_mute(chip, &mix->amp_mute, !IS_G4DA, mix->auto_mute_notify,
1004 chip->speaker_sw_ctl); 1004 chip->speaker_sw_ctl);
1005 } else { 1005 } else {
1006 /* unmute speaker, mute others */ 1006 /* unmute speaker, mute others */
diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c
index 248463511186..ac828eff1a63 100644
--- a/sound/usb/6fire/control.c
+++ b/sound/usb/6fire/control.c
@@ -65,6 +65,15 @@ init_data[] = {
65 { 0 } /* TERMINATING ENTRY */ 65 { 0 } /* TERMINATING ENTRY */
66}; 66};
67 67
68static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 };
69/* values to write to soundcard register for all samplerates */
70static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
71static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00};
72
73enum {
74 DIGITAL_THRU_ONLY_SAMPLERATE = 3
75};
76
68static void usb6fire_control_master_vol_update(struct control_runtime *rt) 77static void usb6fire_control_master_vol_update(struct control_runtime *rt)
69{ 78{
70 struct comm_runtime *comm_rt = rt->chip->comm; 79 struct comm_runtime *comm_rt = rt->chip->comm;
@@ -95,6 +104,67 @@ static void usb6fire_control_opt_coax_update(struct control_runtime *rt)
95 } 104 }
96} 105}
97 106
107static int usb6fire_control_set_rate(struct control_runtime *rt, int rate)
108{
109 int ret;
110 struct usb_device *device = rt->chip->dev;
111 struct comm_runtime *comm_rt = rt->chip->comm;
112
113 if (rate < 0 || rate >= CONTROL_N_RATES)
114 return -EINVAL;
115
116 ret = usb_set_interface(device, 1, rates_altsetting[rate]);
117 if (ret < 0)
118 return ret;
119
120 /* set soundcard clock */
121 ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rate],
122 rates_6fire_vh[rate]);
123 if (ret < 0)
124 return ret;
125
126 return 0;
127}
128
129static int usb6fire_control_set_channels(
130 struct control_runtime *rt, int n_analog_out,
131 int n_analog_in, bool spdif_out, bool spdif_in)
132{
133 int ret;
134 struct comm_runtime *comm_rt = rt->chip->comm;
135
136 /* enable analog inputs and outputs
137 * (one bit per stereo-channel) */
138 ret = comm_rt->write16(comm_rt, 0x02, 0x02,
139 (1 << (n_analog_out / 2)) - 1,
140 (1 << (n_analog_in / 2)) - 1);
141 if (ret < 0)
142 return ret;
143
144 /* disable digital inputs and outputs */
145 /* TODO: use spdif_x to enable/disable digital channels */
146 ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00);
147 if (ret < 0)
148 return ret;
149
150 return 0;
151}
152
153static int usb6fire_control_streaming_update(struct control_runtime *rt)
154{
155 struct comm_runtime *comm_rt = rt->chip->comm;
156
157 if (comm_rt) {
158 if (!rt->usb_streaming && rt->digital_thru_switch)
159 usb6fire_control_set_rate(rt,
160 DIGITAL_THRU_ONLY_SAMPLERATE);
161 return comm_rt->write16(comm_rt, 0x02, 0x00, 0x00,
162 (rt->usb_streaming ? 0x01 : 0x00) |
163 (rt->digital_thru_switch ? 0x08 : 0x00));
164 }
165 return -EINVAL;
166}
167
98static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol, 168static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol,
99 struct snd_ctl_elem_info *uinfo) 169 struct snd_ctl_elem_info *uinfo)
100{ 170{
@@ -195,6 +265,28 @@ static int usb6fire_control_opt_coax_get(struct snd_kcontrol *kcontrol,
195 return 0; 265 return 0;
196} 266}
197 267
268static int usb6fire_control_digital_thru_put(struct snd_kcontrol *kcontrol,
269 struct snd_ctl_elem_value *ucontrol)
270{
271 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
272 int changed = 0;
273
274 if (rt->digital_thru_switch != ucontrol->value.integer.value[0]) {
275 rt->digital_thru_switch = ucontrol->value.integer.value[0];
276 usb6fire_control_streaming_update(rt);
277 changed = 1;
278 }
279 return changed;
280}
281
282static int usb6fire_control_digital_thru_get(struct snd_kcontrol *kcontrol,
283 struct snd_ctl_elem_value *ucontrol)
284{
285 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
286 ucontrol->value.integer.value[0] = rt->digital_thru_switch;
287 return 0;
288}
289
198static struct __devinitdata snd_kcontrol_new elements[] = { 290static struct __devinitdata snd_kcontrol_new elements[] = {
199 { 291 {
200 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 292 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -223,6 +315,15 @@ static struct __devinitdata snd_kcontrol_new elements[] = {
223 .get = usb6fire_control_opt_coax_get, 315 .get = usb6fire_control_opt_coax_get,
224 .put = usb6fire_control_opt_coax_put 316 .put = usb6fire_control_opt_coax_put
225 }, 317 },
318 {
319 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
320 .name = "Digital Thru Playback Route",
321 .index = 0,
322 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
323 .info = snd_ctl_boolean_mono_info,
324 .get = usb6fire_control_digital_thru_get,
325 .put = usb6fire_control_digital_thru_put
326 },
226 {} 327 {}
227}; 328};
228 329
@@ -238,6 +339,9 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip)
238 return -ENOMEM; 339 return -ENOMEM;
239 340
240 rt->chip = chip; 341 rt->chip = chip;
342 rt->update_streaming = usb6fire_control_streaming_update;
343 rt->set_rate = usb6fire_control_set_rate;
344 rt->set_channels = usb6fire_control_set_channels;
241 345
242 i = 0; 346 i = 0;
243 while (init_data[i].type) { 347 while (init_data[i].type) {
@@ -249,6 +353,7 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip)
249 usb6fire_control_opt_coax_update(rt); 353 usb6fire_control_opt_coax_update(rt);
250 usb6fire_control_line_phono_update(rt); 354 usb6fire_control_line_phono_update(rt);
251 usb6fire_control_master_vol_update(rt); 355 usb6fire_control_master_vol_update(rt);
356 usb6fire_control_streaming_update(rt);
252 357
253 i = 0; 358 i = 0;
254 while (elements[i].name) { 359 while (elements[i].name) {
diff --git a/sound/usb/6fire/control.h b/sound/usb/6fire/control.h
index b534c777ab02..8f5aeead2e3d 100644
--- a/sound/usb/6fire/control.h
+++ b/sound/usb/6fire/control.h
@@ -21,12 +21,29 @@ enum {
21 CONTROL_MAX_ELEMENTS = 32 21 CONTROL_MAX_ELEMENTS = 32
22}; 22};
23 23
24enum {
25 CONTROL_RATE_44KHZ,
26 CONTROL_RATE_48KHZ,
27 CONTROL_RATE_88KHZ,
28 CONTROL_RATE_96KHZ,
29 CONTROL_RATE_176KHZ,
30 CONTROL_RATE_192KHZ,
31 CONTROL_N_RATES
32};
33
24struct control_runtime { 34struct control_runtime {
35 int (*update_streaming)(struct control_runtime *rt);
36 int (*set_rate)(struct control_runtime *rt, int rate);
37 int (*set_channels)(struct control_runtime *rt, int n_analog_out,
38 int n_analog_in, bool spdif_out, bool spdif_in);
39
25 struct sfire_chip *chip; 40 struct sfire_chip *chip;
26 41
27 struct snd_kcontrol *element[CONTROL_MAX_ELEMENTS]; 42 struct snd_kcontrol *element[CONTROL_MAX_ELEMENTS];
28 bool opt_coax_switch; 43 bool opt_coax_switch;
29 bool line_phono_switch; 44 bool line_phono_switch;
45 bool digital_thru_switch;
46 bool usb_streaming;
30 u8 master_vol; 47 u8 master_vol;
31}; 48};
32 49
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c
index 86c1a3103760..d47beffedb0f 100644
--- a/sound/usb/6fire/firmware.c
+++ b/sound/usb/6fire/firmware.c
@@ -3,12 +3,6 @@
3 * 3 *
4 * Firmware loader 4 * Firmware loader
5 * 5 *
6 * Currently not working for all devices. To be able to use the device
7 * in linux, it is also possible to let the windows driver upload the firmware.
8 * For that, start the computer in windows and reboot.
9 * As long as the device is connected to the power supply, no firmware reload
10 * needs to be performed.
11 *
12 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
13 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
14 * Version: 0.3.0 8 * Version: 0.3.0
@@ -21,6 +15,7 @@
21 */ 15 */
22 16
23#include <linux/firmware.h> 17#include <linux/firmware.h>
18#include <linux/bitrev.h>
24 19
25#include "firmware.h" 20#include "firmware.h"
26#include "chip.h" 21#include "chip.h"
@@ -33,32 +28,6 @@ enum {
33 FPGA_BUFSIZE = 512, FPGA_EP = 2 28 FPGA_BUFSIZE = 512, FPGA_EP = 2
34}; 29};
35 30
36static const u8 BIT_REVERSE_TABLE[256] = {
37 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50,
38 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8,
39 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04,
40 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4,
41 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c,
42 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82,
43 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32,
44 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
45 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46,
46 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6,
47 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e,
48 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,
49 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71,
50 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99,
51 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25,
52 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
53 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d,
54 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3,
55 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b,
56 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb,
57 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67,
58 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f,
59 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f,
60 0xbf, 0x7f, 0xff };
61
62/* 31/*
63 * wMaxPacketSize of pcm endpoints. 32 * wMaxPacketSize of pcm endpoints.
64 * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c 33 * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c
@@ -72,6 +41,10 @@ static const u8 ep_w_max_packet_size[] = {
72 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */ 41 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */
73}; 42};
74 43
44static const u8 known_fw_versions[][4] = {
45 { 0x03, 0x01, 0x0b, 0x00 }
46};
47
75struct ihex_record { 48struct ihex_record {
76 u16 address; 49 u16 address;
77 u8 len; 50 u8 len;
@@ -340,7 +313,7 @@ static int usb6fire_fw_fpga_upload(
340 313
341 while (c != end) { 314 while (c != end) {
342 for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++) 315 for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++)
343 buffer[i] = BIT_REVERSE_TABLE[(u8) *c]; 316 buffer[i] = byte_rev_table[(u8) *c];
344 317
345 ret = usb6fire_fw_fpga_write(device, buffer, i); 318 ret = usb6fire_fw_fpga_write(device, buffer, i);
346 if (ret < 0) { 319 if (ret < 0) {
@@ -363,6 +336,25 @@ static int usb6fire_fw_fpga_upload(
363 return 0; 336 return 0;
364} 337}
365 338
339/* check, if the firmware version the devices has currently loaded
340 * is known by this driver. 'version' needs to have 4 bytes version
341 * info data. */
342static int usb6fire_fw_check(u8 *version)
343{
344 int i;
345
346 for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++)
347 if (!memcmp(version, known_fw_versions + i, 4))
348 return 0;
349
350 snd_printk(KERN_ERR PREFIX "invalid fimware version in device: "
351 "%02x %02x %02x %02x. "
352 "please reconnect to power. if this failure "
353 "still happens, check your firmware installation.",
354 version[0], version[1], version[2], version[3]);
355 return -EINVAL;
356}
357
366int usb6fire_fw_init(struct usb_interface *intf) 358int usb6fire_fw_init(struct usb_interface *intf)
367{ 359{
368 int i; 360 int i;
@@ -378,9 +370,7 @@ int usb6fire_fw_init(struct usb_interface *intf)
378 "firmware state.\n"); 370 "firmware state.\n");
379 return ret; 371 return ret;
380 } 372 }
381 if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55 373 if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55) {
382 || buffer[4] != 0x03 || buffer[5] != 0x01 || buffer[7]
383 != 0x00) {
384 snd_printk(KERN_ERR PREFIX "unknown device firmware state " 374 snd_printk(KERN_ERR PREFIX "unknown device firmware state "
385 "received from device: "); 375 "received from device: ");
386 for (i = 0; i < 8; i++) 376 for (i = 0; i < 8; i++)
@@ -389,7 +379,7 @@ int usb6fire_fw_init(struct usb_interface *intf)
389 return -EIO; 379 return -EIO;
390 } 380 }
391 /* do we need fpga loader ezusb firmware? */ 381 /* do we need fpga loader ezusb firmware? */
392 if (buffer[3] == 0x01 && buffer[6] == 0x19) { 382 if (buffer[3] == 0x01) {
393 ret = usb6fire_fw_ezusb_upload(intf, 383 ret = usb6fire_fw_ezusb_upload(intf,
394 "6fire/dmx6firel2.ihx", 0, NULL, 0); 384 "6fire/dmx6firel2.ihx", 0, NULL, 0);
395 if (ret < 0) 385 if (ret < 0)
@@ -397,7 +387,10 @@ int usb6fire_fw_init(struct usb_interface *intf)
397 return FW_NOT_READY; 387 return FW_NOT_READY;
398 } 388 }
399 /* do we need fpga firmware and application ezusb firmware? */ 389 /* do we need fpga firmware and application ezusb firmware? */
400 else if (buffer[3] == 0x02 && buffer[6] == 0x0b) { 390 else if (buffer[3] == 0x02) {
391 ret = usb6fire_fw_check(buffer + 4);
392 if (ret < 0)
393 return ret;
401 ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin"); 394 ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin");
402 if (ret < 0) 395 if (ret < 0)
403 return ret; 396 return ret;
@@ -410,8 +403,8 @@ int usb6fire_fw_init(struct usb_interface *intf)
410 return FW_NOT_READY; 403 return FW_NOT_READY;
411 } 404 }
412 /* all fw loaded? */ 405 /* all fw loaded? */
413 else if (buffer[3] == 0x03 && buffer[6] == 0x0b) 406 else if (buffer[3] == 0x03)
414 return 0; 407 return usb6fire_fw_check(buffer + 4);
415 /* unknown data? */ 408 /* unknown data? */
416 else { 409 else {
417 snd_printk(KERN_ERR PREFIX "unknown device firmware state " 410 snd_printk(KERN_ERR PREFIX "unknown device firmware state "
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index ba62c7468ba8..b137b25865cc 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -17,26 +17,23 @@
17#include "pcm.h" 17#include "pcm.h"
18#include "chip.h" 18#include "chip.h"
19#include "comm.h" 19#include "comm.h"
20#include "control.h"
20 21
21enum { 22enum {
22 OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4 23 OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4
23}; 24};
24 25
25/* keep next two synced with 26/* keep next two synced with
26 * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE */ 27 * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE
28 * and CONTROL_RATE_XXX in control.h */
27static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 }; 29static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 };
28static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 }; 30static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 };
29static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 }; 31static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 };
30static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 };
31static const int rates_alsaid[] = { 32static const int rates_alsaid[] = {
32 SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000, 33 SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000,
33 SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000, 34 SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000,
34 SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 }; 35 SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 };
35 36
36/* values to write to soundcard register for all samplerates */
37static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
38static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00};
39
40enum { /* settings for pcm */ 37enum { /* settings for pcm */
41 OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024 38 OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024
42}; 39};
@@ -48,15 +45,6 @@ enum { /* pcm streaming states */
48 STREAM_STOPPING 45 STREAM_STOPPING
49}; 46};
50 47
51enum { /* pcm sample rates (also index into RATES_XXX[]) */
52 RATE_44KHZ,
53 RATE_48KHZ,
54 RATE_88KHZ,
55 RATE_96KHZ,
56 RATE_176KHZ,
57 RATE_192KHZ
58};
59
60static const struct snd_pcm_hardware pcm_hw = { 48static const struct snd_pcm_hardware pcm_hw = {
61 .info = SNDRV_PCM_INFO_MMAP | 49 .info = SNDRV_PCM_INFO_MMAP |
62 SNDRV_PCM_INFO_INTERLEAVED | 50 SNDRV_PCM_INFO_INTERLEAVED |
@@ -64,7 +52,7 @@ static const struct snd_pcm_hardware pcm_hw = {
64 SNDRV_PCM_INFO_MMAP_VALID | 52 SNDRV_PCM_INFO_MMAP_VALID |
65 SNDRV_PCM_INFO_BATCH, 53 SNDRV_PCM_INFO_BATCH,
66 54
67 .formats = SNDRV_PCM_FMTBIT_S24_LE, 55 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
68 56
69 .rates = SNDRV_PCM_RATE_44100 | 57 .rates = SNDRV_PCM_RATE_44100 |
70 SNDRV_PCM_RATE_48000 | 58 SNDRV_PCM_RATE_48000 |
@@ -87,57 +75,34 @@ static const struct snd_pcm_hardware pcm_hw = {
87static int usb6fire_pcm_set_rate(struct pcm_runtime *rt) 75static int usb6fire_pcm_set_rate(struct pcm_runtime *rt)
88{ 76{
89 int ret; 77 int ret;
90 struct usb_device *device = rt->chip->dev; 78 struct control_runtime *ctrl_rt = rt->chip->control;
91 struct comm_runtime *comm_rt = rt->chip->comm;
92 79
93 if (rt->rate >= ARRAY_SIZE(rates)) 80 ctrl_rt->usb_streaming = false;
94 return -EINVAL; 81 ret = ctrl_rt->update_streaming(ctrl_rt);
95 /* disable streaming */
96 ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x00);
97 if (ret < 0) { 82 if (ret < 0) {
98 snd_printk(KERN_ERR PREFIX "error stopping streaming while " 83 snd_printk(KERN_ERR PREFIX "error stopping streaming while "
99 "setting samplerate %d.\n", rates[rt->rate]); 84 "setting samplerate %d.\n", rates[rt->rate]);
100 return ret; 85 return ret;
101 } 86 }
102 87
103 ret = usb_set_interface(device, 1, rates_altsetting[rt->rate]); 88 ret = ctrl_rt->set_rate(ctrl_rt, rt->rate);
104 if (ret < 0) {
105 snd_printk(KERN_ERR PREFIX "error setting interface "
106 "altsetting %d for samplerate %d.\n",
107 rates_altsetting[rt->rate], rates[rt->rate]);
108 return ret;
109 }
110
111 /* set soundcard clock */
112 ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rt->rate],
113 rates_6fire_vh[rt->rate]);
114 if (ret < 0) { 89 if (ret < 0) {
115 snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n", 90 snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n",
116 rates[rt->rate]); 91 rates[rt->rate]);
117 return ret; 92 return ret;
118 } 93 }
119 94
120 /* enable analog inputs and outputs 95 ret = ctrl_rt->set_channels(ctrl_rt, OUT_N_CHANNELS, IN_N_CHANNELS,
121 * (one bit per stereo-channel) */ 96 false, false);
122 ret = comm_rt->write16(comm_rt, 0x02, 0x02,
123 (1 << (OUT_N_CHANNELS / 2)) - 1,
124 (1 << (IN_N_CHANNELS / 2)) - 1);
125 if (ret < 0) { 97 if (ret < 0) {
126 snd_printk(KERN_ERR PREFIX "error initializing analog channels " 98 snd_printk(KERN_ERR PREFIX "error initializing channels "
127 "while setting samplerate %d.\n", 99 "while setting samplerate %d.\n",
128 rates[rt->rate]); 100 rates[rt->rate]);
129 return ret; 101 return ret;
130 } 102 }
131 /* disable digital inputs and outputs */
132 ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00);
133 if (ret < 0) {
134 snd_printk(KERN_ERR PREFIX "error initializing digital "
135 "channels while setting samplerate %d.\n",
136 rates[rt->rate]);
137 return ret;
138 }
139 103
140 ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x01); 104 ctrl_rt->usb_streaming = true;
105 ret = ctrl_rt->update_streaming(ctrl_rt);
141 if (ret < 0) { 106 if (ret < 0) {
142 snd_printk(KERN_ERR PREFIX "error starting streaming while " 107 snd_printk(KERN_ERR PREFIX "error starting streaming while "
143 "setting samplerate %d.\n", rates[rt->rate]); 108 "setting samplerate %d.\n", rates[rt->rate]);
@@ -168,12 +133,15 @@ static struct pcm_substream *usb6fire_pcm_get_substream(
168static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt) 133static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt)
169{ 134{
170 int i; 135 int i;
136 struct control_runtime *ctrl_rt = rt->chip->control;
171 137
172 if (rt->stream_state != STREAM_DISABLED) { 138 if (rt->stream_state != STREAM_DISABLED) {
173 for (i = 0; i < PCM_N_URBS; i++) { 139 for (i = 0; i < PCM_N_URBS; i++) {
174 usb_kill_urb(&rt->in_urbs[i].instance); 140 usb_kill_urb(&rt->in_urbs[i].instance);
175 usb_kill_urb(&rt->out_urbs[i].instance); 141 usb_kill_urb(&rt->out_urbs[i].instance);
176 } 142 }
143 ctrl_rt->usb_streaming = false;
144 ctrl_rt->update_streaming(ctrl_rt);
177 rt->stream_state = STREAM_DISABLED; 145 rt->stream_state = STREAM_DISABLED;
178 } 146 }
179} 147}
@@ -228,7 +196,7 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
228 unsigned int total_length = 0; 196 unsigned int total_length = 0;
229 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance); 197 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
230 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime; 198 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
231 u32 *src = (u32 *) urb->buffer; 199 u32 *src = NULL;
232 u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off 200 u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off
233 * (alsa_rt->frame_bits >> 3)); 201 * (alsa_rt->frame_bits >> 3));
234 u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size 202 u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
@@ -244,7 +212,12 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
244 else 212 else
245 frame_count = 0; 213 frame_count = 0;
246 214
247 src = (u32 *) (urb->buffer + total_length); 215 if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)
216 src = (u32 *) (urb->buffer + total_length);
217 else if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE)
218 src = (u32 *) (urb->buffer - 1 + total_length);
219 else
220 return;
248 src++; /* skip leading 4 bytes of every packet */ 221 src++; /* skip leading 4 bytes of every packet */
249 total_length += urb->packets[i].length; 222 total_length += urb->packets[i].length;
250 for (frame = 0; frame < frame_count; frame++) { 223 for (frame = 0; frame < frame_count; frame++) {
@@ -274,9 +247,18 @@ static void usb6fire_pcm_playback(struct pcm_substream *sub,
274 * (alsa_rt->frame_bits >> 3)); 247 * (alsa_rt->frame_bits >> 3));
275 u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size 248 u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
276 * (alsa_rt->frame_bits >> 3)); 249 * (alsa_rt->frame_bits >> 3));
277 u32 *dest = (u32 *) urb->buffer; 250 u32 *dest;
278 int bytes_per_frame = alsa_rt->channels << 2; 251 int bytes_per_frame = alsa_rt->channels << 2;
279 252
253 if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE)
254 dest = (u32 *) (urb->buffer - 1);
255 else if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)
256 dest = (u32 *) (urb->buffer);
257 else {
258 snd_printk(KERN_ERR PREFIX "Unknown sample format.");
259 return;
260 }
261
280 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) { 262 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
281 /* at least 4 header bytes for valid packet. 263 /* at least 4 header bytes for valid packet.
282 * after that: 32 bits per sample for analog channels */ 264 * after that: 32 bits per sample for analog channels */
@@ -456,7 +438,7 @@ static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
456 /* all substreams closed? if so, stop streaming */ 438 /* all substreams closed? if so, stop streaming */
457 if (!rt->playback.instance && !rt->capture.instance) { 439 if (!rt->playback.instance && !rt->capture.instance) {
458 usb6fire_pcm_stream_stop(rt); 440 usb6fire_pcm_stream_stop(rt);
459 rt->rate = -1; 441 rt->rate = ARRAY_SIZE(rates);
460 } 442 }
461 } 443 }
462 mutex_unlock(&rt->stream_mutex); 444 mutex_unlock(&rt->stream_mutex);
@@ -480,7 +462,6 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
480 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub); 462 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
481 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); 463 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
482 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime; 464 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
483 int i;
484 int ret; 465 int ret;
485 466
486 if (rt->panic) 467 if (rt->panic)
@@ -493,12 +474,10 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
493 sub->period_off = 0; 474 sub->period_off = 0;
494 475
495 if (rt->stream_state == STREAM_DISABLED) { 476 if (rt->stream_state == STREAM_DISABLED) {
496 for (i = 0; i < ARRAY_SIZE(rates); i++) 477 for (rt->rate = 0; rt->rate < ARRAY_SIZE(rates); rt->rate++)
497 if (alsa_rt->rate == rates[i]) { 478 if (alsa_rt->rate == rates[rt->rate])
498 rt->rate = i;
499 break; 479 break;
500 } 480 if (rt->rate == ARRAY_SIZE(rates)) {
501 if (i == ARRAY_SIZE(rates)) {
502 mutex_unlock(&rt->stream_mutex); 481 mutex_unlock(&rt->stream_mutex);
503 snd_printk("invalid rate %d in prepare.\n", 482 snd_printk("invalid rate %d in prepare.\n",
504 alsa_rt->rate); 483 alsa_rt->rate);
@@ -613,7 +592,7 @@ int __devinit usb6fire_pcm_init(struct sfire_chip *chip)
613 592
614 rt->chip = chip; 593 rt->chip = chip;
615 rt->stream_state = STREAM_DISABLED; 594 rt->stream_state = STREAM_DISABLED;
616 rt->rate = -1; 595 rt->rate = ARRAY_SIZE(rates);
617 init_waitqueue_head(&rt->stream_wait_queue); 596 init_waitqueue_head(&rt->stream_wait_queue);
618 mutex_init(&rt->stream_mutex); 597 mutex_init(&rt->stream_mutex);
619 598
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 97724d8fa9f6..8beb77563da2 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -100,19 +100,17 @@ config SND_USB_US122L
100 100
101config SND_USB_6FIRE 101config SND_USB_6FIRE
102 tristate "TerraTec DMX 6Fire USB" 102 tristate "TerraTec DMX 6Fire USB"
103 depends on EXPERIMENTAL
104 select FW_LOADER 103 select FW_LOADER
104 select BITREVERSE
105 select SND_RAWMIDI 105 select SND_RAWMIDI
106 select SND_PCM 106 select SND_PCM
107 help 107 help
108 Say Y here to include support for TerraTec 6fire DMX USB interface. 108 Say Y here to include support for TerraTec 6fire DMX USB interface.
109 109
110 You will need firmware files in order to be able to use the device 110 You will need firmware files in order to be able to use the device
111 after it has been coldstarted. This driver currently does not support 111 after it has been coldstarted. An install script for the firmware
112 firmware loading for all devices. If you own such a device, 112 and further help can be found at
113 you could start windows and let the windows driver upload 113 http://sixfireusb.sourceforge.net
114 the firmware. As long as you do not unplug your device from power,
115 it should be usable.
116 114
117endif # SND_USB 115endif # SND_USB
118 116
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 7754a1034545..075195e8661a 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -104,6 +104,15 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
104 int err; 104 int err;
105 unsigned char data; 105 unsigned char data;
106 struct usb_device *dev = chip->dev; 106 struct usb_device *dev = chip->dev;
107 struct uac_clock_source_descriptor *cs_desc =
108 snd_usb_find_clock_source(chip->ctrl_intf, source_id);
109
110 if (!cs_desc)
111 return 0;
112
113 /* If a clock source can't tell us whether it's valid, we assume it is */
114 if (!uac2_control_is_readable(cs_desc->bmControls, UAC2_CS_CONTROL_CLOCK_VALID))
115 return 1;
107 116
108 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, 117 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
109 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 118 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
@@ -114,7 +123,7 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
114 if (err < 0) { 123 if (err < 0) {
115 snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n", 124 snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n",
116 __func__, source_id); 125 __func__, source_id);
117 return err; 126 return 0;
118 } 127 }
119 128
120 return !!data; 129 return !!data;
diff --git a/sound/usb/debug.h b/sound/usb/debug.h
index 343ec2d9ee66..58030176f008 100644
--- a/sound/usb/debug.h
+++ b/sound/usb/debug.h
@@ -8,7 +8,7 @@
8#ifdef HW_CONST_DEBUG 8#ifdef HW_CONST_DEBUG
9#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args) 9#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args)
10#else 10#else
11#define hwc_debug(fmt, args...) /**/ 11#define hwc_debug(fmt, args...) do { } while(0)
12#endif 12#endif
13 13
14#endif /* __USBAUDIO_DEBUG_H */ 14#endif /* __USBAUDIO_DEBUG_H */
diff --git a/sound/usb/format.c b/sound/usb/format.c
index f079b5e2ab28..8d042dce0d16 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -30,6 +30,7 @@
30#include "helper.h" 30#include "helper.h"
31#include "debug.h" 31#include "debug.h"
32#include "clock.h" 32#include "clock.h"
33#include "format.h"
33 34
34/* 35/*
35 * parse the audio format type I descriptor 36 * parse the audio format type I descriptor
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 6ec33b62e6cf..eab06edcc9b7 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1097,11 +1097,13 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1097 append_ctl_name(kctl, control == UAC_FU_MUTE ? 1097 append_ctl_name(kctl, control == UAC_FU_MUTE ?
1098 " Switch" : " Volume"); 1098 " Switch" : " Volume");
1099 if (control == UAC_FU_VOLUME) { 1099 if (control == UAC_FU_VOLUME) {
1100 kctl->tlv.c = mixer_vol_tlv;
1101 kctl->vd[0].access |=
1102 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
1103 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1104 check_mapped_dB(map, cval); 1100 check_mapped_dB(map, cval);
1101 if (cval->dBmin < cval->dBmax) {
1102 kctl->tlv.c = mixer_vol_tlv;
1103 kctl->vd[0].access |=
1104 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
1105 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1106 }
1105 } 1107 }
1106 break; 1108 break;
1107 1109
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 73dcc8256bc0..9146cffa6ede 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -61,6 +61,7 @@ static const struct rc_config {
61 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */ 61 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
62 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */ 62 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
63 { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */ 63 { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */
64 { USB_ID(0x041e, 0x30df), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */
64 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ 65 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
65}; 66};
66 67
@@ -188,6 +189,12 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
188 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, 189 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
189 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 190 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
190 !value, 0, NULL, 0, 100); 191 !value, 0, NULL, 0, 100);
192 /* USB X-Fi S51 Pro */
193 if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df))
194 err = snd_usb_ctl_msg(mixer->chip->dev,
195 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
196 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
197 !value, 0, NULL, 0, 100);
191 else 198 else
192 err = snd_usb_ctl_msg(mixer->chip->dev, 199 err = snd_usb_ctl_msg(mixer->chip->dev,
193 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, 200 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
@@ -234,9 +241,13 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
234 /* USB X-Fi S51 doesn't have a CMSS LED */ 241 /* USB X-Fi S51 doesn't have a CMSS LED */
235 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0) 242 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0)
236 continue; 243 continue;
244 /* USB X-Fi S51 Pro doesn't have one either */
245 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) && i == 0)
246 continue;
237 if (i > 1 && /* Live24ext has 2 LEDs only */ 247 if (i > 1 && /* Live24ext has 2 LEDs only */
238 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || 248 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
239 mixer->chip->usb_id == USB_ID(0x041e, 0x3042) || 249 mixer->chip->usb_id == USB_ID(0x041e, 0x3042) ||
250 mixer->chip->usb_id == USB_ID(0x041e, 0x30df) ||
240 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))) 251 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
241 break; 252 break;
242 err = snd_ctl_add(mixer->chip->card, 253 err = snd_ctl_add(mixer->chip->card,
@@ -512,6 +523,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
512 case USB_ID(0x041e, 0x3020): 523 case USB_ID(0x041e, 0x3020):
513 case USB_ID(0x041e, 0x3040): 524 case USB_ID(0x041e, 0x3040):
514 case USB_ID(0x041e, 0x3042): 525 case USB_ID(0x041e, 0x3042):
526 case USB_ID(0x041e, 0x30df):
515 case USB_ID(0x041e, 0x3048): 527 case USB_ID(0x041e, 0x3048):
516 err = snd_audigy2nx_controls_create(mixer); 528 err = snd_audigy2nx_controls_create(mixer);
517 if (err < 0) 529 if (err < 0)
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index c66d3f64dcf8..78792a8900c3 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -1651,6 +1651,32 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1651 } 1651 }
1652 } 1652 }
1653}, 1653},
1654{
1655 USB_DEVICE(0x0582, 0x0127),
1656 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1657 /* .vendor_name = "Roland", */
1658 /* .product_name = "GR-55", */
1659 .ifnum = QUIRK_ANY_INTERFACE,
1660 .type = QUIRK_COMPOSITE,
1661 .data = (const struct snd_usb_audio_quirk[]) {
1662 {
1663 .ifnum = 0,
1664 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1665 },
1666 {
1667 .ifnum = 1,
1668 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1669 },
1670 {
1671 .ifnum = 2,
1672 .type = QUIRK_MIDI_STANDARD_INTERFACE
1673 },
1674 {
1675 .ifnum = -1
1676 }
1677 }
1678 }
1679},
1654 1680
1655/* Guillemot devices */ 1681/* Guillemot devices */
1656{ 1682{
@@ -1953,7 +1979,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1953 } 1979 }
1954}, 1980},
1955{ 1981{
1956 USB_DEVICE(0x0763, 0x2080), 1982 USB_DEVICE_VENDOR_SPEC(0x0763, 0x2080),
1957 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1983 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1958 /* .vendor_name = "M-Audio", */ 1984 /* .vendor_name = "M-Audio", */
1959 /* .product_name = "Fast Track Ultra", */ 1985 /* .product_name = "Fast Track Ultra", */
@@ -2020,7 +2046,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2020 } 2046 }
2021}, 2047},
2022{ 2048{
2023 USB_DEVICE(0x0763, 0x2081), 2049 USB_DEVICE_VENDOR_SPEC(0x0763, 0x2081),
2024 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 2050 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
2025 /* .vendor_name = "M-Audio", */ 2051 /* .vendor_name = "M-Audio", */
2026 /* .product_name = "Fast Track Ultra 8R", */ 2052 /* .product_name = "Fast Track Ultra 8R", */
@@ -2179,6 +2205,17 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2179 } 2205 }
2180}, 2206},
2181 2207
2208/* KORG devices */
2209{
2210 USB_DEVICE_VENDOR_SPEC(0x0944, 0x0200),
2211 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
2212 .vendor_name = "KORG, Inc.",
2213 /* .product_name = "PANDORA PX5D", */
2214 .ifnum = 3,
2215 .type = QUIRK_MIDI_STANDARD_INTERFACE,
2216 }
2217},
2218
2182/* AKAI devices */ 2219/* AKAI devices */
2183{ 2220{
2184 USB_DEVICE(0x09e8, 0x0062), 2221 USB_DEVICE(0x09e8, 0x0062),
@@ -2332,6 +2369,12 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2332 2369
2333/* Native Instruments MK2 series */ 2370/* Native Instruments MK2 series */
2334{ 2371{
2372 /* Komplete Audio 6 */
2373 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
2374 .idVendor = 0x17cc,
2375 .idProduct = 0x1000,
2376},
2377{
2335 /* Traktor Audio 6 */ 2378 /* Traktor Audio 6 */
2336 .match_flags = USB_DEVICE_ID_MATCH_DEVICE, 2379 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
2337 .idVendor = 0x17cc, 2380 .idVendor = 0x17cc,
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 1b94ec3a3368..bd13d7257240 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -540,6 +540,7 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
540 /* Access Music VirusTI Desktop */ 540 /* Access Music VirusTI Desktop */
541 return snd_usb_accessmusic_boot_quirk(dev); 541 return snd_usb_accessmusic_boot_quirk(dev);
542 542
543 case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */
543 case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */ 544 case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
544 case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */ 545 case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
545 return snd_usb_nativeinstruments_boot_quirk(dev); 546 return snd_usb_nativeinstruments_boot_quirk(dev);