aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/writing-an-alsa-driver.tmpl27
-rw-r--r--include/sound/info.h24
-rw-r--r--sound/atmel/Kconfig2
-rw-r--r--sound/atmel/ac97c.c355
-rw-r--r--sound/core/control.c5
-rw-r--r--sound/core/info.c74
-rw-r--r--sound/core/oss/mixer_oss.c5
-rw-r--r--sound/core/oss/pcm_oss.c5
-rw-r--r--sound/core/pcm_native.c19
-rw-r--r--sound/core/rawmidi.c5
-rw-r--r--sound/core/seq/seq_clientmgr.c6
-rw-r--r--sound/core/sound.c73
-rw-r--r--sound/core/timer.c6
-rw-r--r--sound/drivers/opl4/opl4_proc.c83
-rw-r--r--sound/isa/gus/gus_mem_proc.c48
-rw-r--r--sound/pci/cs4281.c40
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c19
-rw-r--r--sound/pci/emu10k1/emuproc.c51
-rw-r--r--sound/pci/ice1712/aureon.c89
-rw-r--r--sound/pci/mixart/mixart.c79
-rw-r--r--sound/ppc/tumbler.c12
-rw-r--r--sound/usb/Kconfig1
-rw-r--r--sound/usb/caiaq/control.c99
-rw-r--r--sound/usb/caiaq/device.c8
-rw-r--r--sound/usb/caiaq/device.h24
-rw-r--r--sound/usb/caiaq/input.c162
26 files changed, 829 insertions, 492 deletions
diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl
index 0d0f7b4d4b1a..0ba149de2608 100644
--- a/Documentation/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl
@@ -5518,34 +5518,41 @@ struct _snd_pcm_runtime {
5518]]> 5518]]>
5519 </programlisting> 5519 </programlisting>
5520 </informalexample> 5520 </informalexample>
5521
5522 For the raw data, <structfield>size</structfield> field must be
5523 set properly. This specifies the maximum size of the proc file access.
5521 </para> 5524 </para>
5522 5525
5523 <para> 5526 <para>
5524 The callback is much more complicated than the text-file 5527 The read/write callbacks of raw mode are more direct than the text mode.
5525 version. You need to use a low-level I/O functions such as 5528 You need to use a low-level I/O functions such as
5526 <function>copy_from/to_user()</function> to transfer the 5529 <function>copy_from/to_user()</function> to transfer the
5527 data. 5530 data.
5528 5531
5529 <informalexample> 5532 <informalexample>
5530 <programlisting> 5533 <programlisting>
5531<![CDATA[ 5534<![CDATA[
5532 static long my_file_io_read(struct snd_info_entry *entry, 5535 static ssize_t my_file_io_read(struct snd_info_entry *entry,
5533 void *file_private_data, 5536 void *file_private_data,
5534 struct file *file, 5537 struct file *file,
5535 char *buf, 5538 char *buf,
5536 unsigned long count, 5539 size_t count,
5537 unsigned long pos) 5540 loff_t pos)
5538 { 5541 {
5539 long size = count; 5542 if (copy_to_user(buf, local_data + pos, count))
5540 if (pos + size > local_max_size)
5541 size = local_max_size - pos;
5542 if (copy_to_user(buf, local_data + pos, size))
5543 return -EFAULT; 5543 return -EFAULT;
5544 return size; 5544 return count;
5545 } 5545 }
5546]]> 5546]]>
5547 </programlisting> 5547 </programlisting>
5548 </informalexample> 5548 </informalexample>
5549
5550 If the size of the info entry has been set up properly,
5551 <structfield>count</structfield> and <structfield>pos</structfield> are
5552 guaranteed to fit within 0 and the given size.
5553 You don't have to check the range in the callbacks unless any
5554 other condition is required.
5555
5549 </para> 5556 </para>
5550 5557
5551 </chapter> 5558 </chapter>
diff --git a/include/sound/info.h b/include/sound/info.h
index 112e8949e1a7..4e94cf1ff762 100644
--- a/include/sound/info.h
+++ b/include/sound/info.h
@@ -51,18 +51,18 @@ struct snd_info_entry_ops {
51 unsigned short mode, void **file_private_data); 51 unsigned short mode, void **file_private_data);
52 int (*release)(struct snd_info_entry *entry, 52 int (*release)(struct snd_info_entry *entry,
53 unsigned short mode, void *file_private_data); 53 unsigned short mode, void *file_private_data);
54 long (*read)(struct snd_info_entry *entry, void *file_private_data, 54 ssize_t (*read)(struct snd_info_entry *entry, void *file_private_data,
55 struct file *file, char __user *buf, 55 struct file *file, char __user *buf,
56 unsigned long count, unsigned long pos); 56 size_t count, loff_t pos);
57 long (*write)(struct snd_info_entry *entry, void *file_private_data, 57 ssize_t (*write)(struct snd_info_entry *entry, void *file_private_data,
58 struct file *file, const char __user *buf, 58 struct file *file, const char __user *buf,
59 unsigned long count, unsigned long pos); 59 size_t count, loff_t pos);
60 long long (*llseek)(struct snd_info_entry *entry, 60 loff_t (*llseek)(struct snd_info_entry *entry,
61 void *file_private_data, struct file *file, 61 void *file_private_data, struct file *file,
62 long long offset, int orig); 62 loff_t offset, int orig);
63 unsigned int(*poll)(struct snd_info_entry *entry, 63 unsigned int (*poll)(struct snd_info_entry *entry,
64 void *file_private_data, struct file *file, 64 void *file_private_data, struct file *file,
65 poll_table *wait); 65 poll_table *wait);
66 int (*ioctl)(struct snd_info_entry *entry, void *file_private_data, 66 int (*ioctl)(struct snd_info_entry *entry, void *file_private_data,
67 struct file *file, unsigned int cmd, unsigned long arg); 67 struct file *file, unsigned int cmd, unsigned long arg);
68 int (*mmap)(struct snd_info_entry *entry, void *file_private_data, 68 int (*mmap)(struct snd_info_entry *entry, void *file_private_data,
diff --git a/sound/atmel/Kconfig b/sound/atmel/Kconfig
index 6c228a91940d..94de43a096f1 100644
--- a/sound/atmel/Kconfig
+++ b/sound/atmel/Kconfig
@@ -12,7 +12,7 @@ config SND_ATMEL_AC97C
12 tristate "Atmel AC97 Controller (AC97C) driver" 12 tristate "Atmel AC97 Controller (AC97C) driver"
13 select SND_PCM 13 select SND_PCM
14 select SND_AC97_CODEC 14 select SND_AC97_CODEC
15 depends on DW_DMAC && AVR32 15 depends on (DW_DMAC && AVR32) || ARCH_AT91
16 help 16 help
17 ALSA sound driver for the Atmel AC97 controller. 17 ALSA sound driver for the Atmel AC97 controller.
18 18
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index 0c0f8771656a..428121a7e705 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -13,6 +13,7 @@
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/dmaengine.h> 14#include <linux/dmaengine.h>
15#include <linux/dma-mapping.h> 15#include <linux/dma-mapping.h>
16#include <linux/atmel_pdc.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/interrupt.h> 18#include <linux/interrupt.h>
18#include <linux/module.h> 19#include <linux/module.h>
@@ -31,6 +32,10 @@
31 32
32#include <linux/dw_dmac.h> 33#include <linux/dw_dmac.h>
33 34
35#include <mach/cpu.h>
36#include <mach/hardware.h>
37#include <mach/gpio.h>
38
34#include "ac97c.h" 39#include "ac97c.h"
35 40
36enum { 41enum {
@@ -63,6 +68,7 @@ struct atmel_ac97c {
63 u64 cur_format; 68 u64 cur_format;
64 unsigned int cur_rate; 69 unsigned int cur_rate;
65 unsigned long flags; 70 unsigned long flags;
71 int playback_period, capture_period;
66 /* Serialize access to opened variable */ 72 /* Serialize access to opened variable */
67 spinlock_t lock; 73 spinlock_t lock;
68 void __iomem *regs; 74 void __iomem *regs;
@@ -242,10 +248,12 @@ static int atmel_ac97c_playback_hw_params(struct snd_pcm_substream *substream,
242 if (retval < 0) 248 if (retval < 0)
243 return retval; 249 return retval;
244 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ 250 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
245 if (retval == 1) 251 if (cpu_is_at32ap7000()) {
246 if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) 252 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
247 dw_dma_cyclic_free(chip->dma.tx_chan); 253 if (retval == 1)
248 254 if (test_and_clear_bit(DMA_TX_READY, &chip->flags))
255 dw_dma_cyclic_free(chip->dma.tx_chan);
256 }
249 /* Set restrictions to params. */ 257 /* Set restrictions to params. */
250 mutex_lock(&opened_mutex); 258 mutex_lock(&opened_mutex);
251 chip->cur_rate = params_rate(hw_params); 259 chip->cur_rate = params_rate(hw_params);
@@ -266,9 +274,14 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
266 if (retval < 0) 274 if (retval < 0)
267 return retval; 275 return retval;
268 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ 276 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
269 if (retval == 1) 277 if (cpu_is_at32ap7000()) {
270 if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) 278 if (retval < 0)
271 dw_dma_cyclic_free(chip->dma.rx_chan); 279 return retval;
280 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
281 if (retval == 1)
282 if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
283 dw_dma_cyclic_free(chip->dma.rx_chan);
284 }
272 285
273 /* Set restrictions to params. */ 286 /* Set restrictions to params. */
274 mutex_lock(&opened_mutex); 287 mutex_lock(&opened_mutex);
@@ -282,16 +295,20 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
282static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream) 295static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream)
283{ 296{
284 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 297 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
285 if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) 298 if (cpu_is_at32ap7000()) {
286 dw_dma_cyclic_free(chip->dma.tx_chan); 299 if (test_and_clear_bit(DMA_TX_READY, &chip->flags))
300 dw_dma_cyclic_free(chip->dma.tx_chan);
301 }
287 return snd_pcm_lib_free_pages(substream); 302 return snd_pcm_lib_free_pages(substream);
288} 303}
289 304
290static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream) 305static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream)
291{ 306{
292 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 307 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
293 if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) 308 if (cpu_is_at32ap7000()) {
294 dw_dma_cyclic_free(chip->dma.rx_chan); 309 if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
310 dw_dma_cyclic_free(chip->dma.rx_chan);
311 }
295 return snd_pcm_lib_free_pages(substream); 312 return snd_pcm_lib_free_pages(substream);
296} 313}
297 314
@@ -299,9 +316,11 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
299{ 316{
300 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 317 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
301 struct snd_pcm_runtime *runtime = substream->runtime; 318 struct snd_pcm_runtime *runtime = substream->runtime;
319 int block_size = frames_to_bytes(runtime, runtime->period_size);
302 unsigned long word = ac97c_readl(chip, OCA); 320 unsigned long word = ac97c_readl(chip, OCA);
303 int retval; 321 int retval;
304 322
323 chip->playback_period = 0;
305 word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT)); 324 word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
306 325
307 /* assign channels to AC97C channel A */ 326 /* assign channels to AC97C channel A */
@@ -320,11 +339,16 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
320 ac97c_writel(chip, OCA, word); 339 ac97c_writel(chip, OCA, word);
321 340
322 /* configure sample format and size */ 341 /* configure sample format and size */
323 word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; 342 word = ac97c_readl(chip, CAMR);
343 if (chip->opened <= 1)
344 word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
345 else
346 word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
324 347
325 switch (runtime->format) { 348 switch (runtime->format) {
326 case SNDRV_PCM_FORMAT_S16_LE: 349 case SNDRV_PCM_FORMAT_S16_LE:
327 word |= AC97C_CMR_CEM_LITTLE; 350 if (cpu_is_at32ap7000())
351 word |= AC97C_CMR_CEM_LITTLE;
328 break; 352 break;
329 case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ 353 case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
330 word &= ~(AC97C_CMR_CEM_LITTLE); 354 word &= ~(AC97C_CMR_CEM_LITTLE);
@@ -363,9 +387,18 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
363 dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", 387 dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n",
364 runtime->rate); 388 runtime->rate);
365 389
366 if (!test_bit(DMA_TX_READY, &chip->flags)) 390 if (cpu_is_at32ap7000()) {
367 retval = atmel_ac97c_prepare_dma(chip, substream, 391 if (!test_bit(DMA_TX_READY, &chip->flags))
368 DMA_TO_DEVICE); 392 retval = atmel_ac97c_prepare_dma(chip, substream,
393 DMA_TO_DEVICE);
394 } else {
395 /* Initialize and start the PDC */
396 writel(runtime->dma_addr, chip->regs + ATMEL_PDC_TPR);
397 writel(block_size / 2, chip->regs + ATMEL_PDC_TCR);
398 writel(runtime->dma_addr + block_size,
399 chip->regs + ATMEL_PDC_TNPR);
400 writel(block_size / 2, chip->regs + ATMEL_PDC_TNCR);
401 }
369 402
370 return retval; 403 return retval;
371} 404}
@@ -374,9 +407,11 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
374{ 407{
375 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 408 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
376 struct snd_pcm_runtime *runtime = substream->runtime; 409 struct snd_pcm_runtime *runtime = substream->runtime;
410 int block_size = frames_to_bytes(runtime, runtime->period_size);
377 unsigned long word = ac97c_readl(chip, ICA); 411 unsigned long word = ac97c_readl(chip, ICA);
378 int retval; 412 int retval;
379 413
414 chip->capture_period = 0;
380 word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT)); 415 word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
381 416
382 /* assign channels to AC97C channel A */ 417 /* assign channels to AC97C channel A */
@@ -395,11 +430,16 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
395 ac97c_writel(chip, ICA, word); 430 ac97c_writel(chip, ICA, word);
396 431
397 /* configure sample format and size */ 432 /* configure sample format and size */
398 word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; 433 word = ac97c_readl(chip, CAMR);
434 if (chip->opened <= 1)
435 word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
436 else
437 word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
399 438
400 switch (runtime->format) { 439 switch (runtime->format) {
401 case SNDRV_PCM_FORMAT_S16_LE: 440 case SNDRV_PCM_FORMAT_S16_LE:
402 word |= AC97C_CMR_CEM_LITTLE; 441 if (cpu_is_at32ap7000())
442 word |= AC97C_CMR_CEM_LITTLE;
403 break; 443 break;
404 case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ 444 case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
405 word &= ~(AC97C_CMR_CEM_LITTLE); 445 word &= ~(AC97C_CMR_CEM_LITTLE);
@@ -438,9 +478,18 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
438 dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", 478 dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n",
439 runtime->rate); 479 runtime->rate);
440 480
441 if (!test_bit(DMA_RX_READY, &chip->flags)) 481 if (cpu_is_at32ap7000()) {
442 retval = atmel_ac97c_prepare_dma(chip, substream, 482 if (!test_bit(DMA_RX_READY, &chip->flags))
443 DMA_FROM_DEVICE); 483 retval = atmel_ac97c_prepare_dma(chip, substream,
484 DMA_FROM_DEVICE);
485 } else {
486 /* Initialize and start the PDC */
487 writel(runtime->dma_addr, chip->regs + ATMEL_PDC_RPR);
488 writel(block_size / 2, chip->regs + ATMEL_PDC_RCR);
489 writel(runtime->dma_addr + block_size,
490 chip->regs + ATMEL_PDC_RNPR);
491 writel(block_size / 2, chip->regs + ATMEL_PDC_RNCR);
492 }
444 493
445 return retval; 494 return retval;
446} 495}
@@ -449,7 +498,7 @@ static int
449atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) 498atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
450{ 499{
451 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 500 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
452 unsigned long camr; 501 unsigned long camr, ptcr = 0;
453 int retval = 0; 502 int retval = 0;
454 503
455 camr = ac97c_readl(chip, CAMR); 504 camr = ac97c_readl(chip, CAMR);
@@ -458,15 +507,22 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
458 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ 507 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
459 case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ 508 case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
460 case SNDRV_PCM_TRIGGER_START: 509 case SNDRV_PCM_TRIGGER_START:
461 retval = dw_dma_cyclic_start(chip->dma.tx_chan); 510 if (cpu_is_at32ap7000()) {
462 if (retval) 511 retval = dw_dma_cyclic_start(chip->dma.tx_chan);
463 goto out; 512 if (retval)
464 camr |= AC97C_CMR_CENA; 513 goto out;
514 } else {
515 ptcr = ATMEL_PDC_TXTEN;
516 }
517 camr |= AC97C_CMR_CENA | AC97C_CSR_ENDTX;
465 break; 518 break;
466 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ 519 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
467 case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ 520 case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
468 case SNDRV_PCM_TRIGGER_STOP: 521 case SNDRV_PCM_TRIGGER_STOP:
469 dw_dma_cyclic_stop(chip->dma.tx_chan); 522 if (cpu_is_at32ap7000())
523 dw_dma_cyclic_stop(chip->dma.tx_chan);
524 else
525 ptcr |= ATMEL_PDC_TXTDIS;
470 if (chip->opened <= 1) 526 if (chip->opened <= 1)
471 camr &= ~AC97C_CMR_CENA; 527 camr &= ~AC97C_CMR_CENA;
472 break; 528 break;
@@ -476,6 +532,8 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
476 } 532 }
477 533
478 ac97c_writel(chip, CAMR, camr); 534 ac97c_writel(chip, CAMR, camr);
535 if (!cpu_is_at32ap7000())
536 writel(ptcr, chip->regs + ATMEL_PDC_PTCR);
479out: 537out:
480 return retval; 538 return retval;
481} 539}
@@ -484,24 +542,32 @@ static int
484atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd) 542atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd)
485{ 543{
486 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 544 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
487 unsigned long camr; 545 unsigned long camr, ptcr = 0;
488 int retval = 0; 546 int retval = 0;
489 547
490 camr = ac97c_readl(chip, CAMR); 548 camr = ac97c_readl(chip, CAMR);
549 ptcr = readl(chip->regs + ATMEL_PDC_PTSR);
491 550
492 switch (cmd) { 551 switch (cmd) {
493 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ 552 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
494 case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ 553 case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
495 case SNDRV_PCM_TRIGGER_START: 554 case SNDRV_PCM_TRIGGER_START:
496 retval = dw_dma_cyclic_start(chip->dma.rx_chan); 555 if (cpu_is_at32ap7000()) {
497 if (retval) 556 retval = dw_dma_cyclic_start(chip->dma.rx_chan);
498 goto out; 557 if (retval)
499 camr |= AC97C_CMR_CENA; 558 goto out;
559 } else {
560 ptcr = ATMEL_PDC_RXTEN;
561 }
562 camr |= AC97C_CMR_CENA | AC97C_CSR_ENDRX;
500 break; 563 break;
501 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ 564 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
502 case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ 565 case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
503 case SNDRV_PCM_TRIGGER_STOP: 566 case SNDRV_PCM_TRIGGER_STOP:
504 dw_dma_cyclic_stop(chip->dma.rx_chan); 567 if (cpu_is_at32ap7000())
568 dw_dma_cyclic_stop(chip->dma.rx_chan);
569 else
570 ptcr |= (ATMEL_PDC_RXTDIS);
505 if (chip->opened <= 1) 571 if (chip->opened <= 1)
506 camr &= ~AC97C_CMR_CENA; 572 camr &= ~AC97C_CMR_CENA;
507 break; 573 break;
@@ -511,6 +577,8 @@ atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd)
511 } 577 }
512 578
513 ac97c_writel(chip, CAMR, camr); 579 ac97c_writel(chip, CAMR, camr);
580 if (!cpu_is_at32ap7000())
581 writel(ptcr, chip->regs + ATMEL_PDC_PTCR);
514out: 582out:
515 return retval; 583 return retval;
516} 584}
@@ -523,7 +591,10 @@ atmel_ac97c_playback_pointer(struct snd_pcm_substream *substream)
523 snd_pcm_uframes_t frames; 591 snd_pcm_uframes_t frames;
524 unsigned long bytes; 592 unsigned long bytes;
525 593
526 bytes = dw_dma_get_src_addr(chip->dma.tx_chan); 594 if (cpu_is_at32ap7000())
595 bytes = dw_dma_get_src_addr(chip->dma.tx_chan);
596 else
597 bytes = readl(chip->regs + ATMEL_PDC_TPR);
527 bytes -= runtime->dma_addr; 598 bytes -= runtime->dma_addr;
528 599
529 frames = bytes_to_frames(runtime, bytes); 600 frames = bytes_to_frames(runtime, bytes);
@@ -540,7 +611,10 @@ atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream)
540 snd_pcm_uframes_t frames; 611 snd_pcm_uframes_t frames;
541 unsigned long bytes; 612 unsigned long bytes;
542 613
543 bytes = dw_dma_get_dst_addr(chip->dma.rx_chan); 614 if (cpu_is_at32ap7000())
615 bytes = dw_dma_get_dst_addr(chip->dma.rx_chan);
616 else
617 bytes = readl(chip->regs + ATMEL_PDC_RPR);
544 bytes -= runtime->dma_addr; 618 bytes -= runtime->dma_addr;
545 619
546 frames = bytes_to_frames(runtime, bytes); 620 frames = bytes_to_frames(runtime, bytes);
@@ -578,8 +652,11 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
578 u32 sr = ac97c_readl(chip, SR); 652 u32 sr = ac97c_readl(chip, SR);
579 u32 casr = ac97c_readl(chip, CASR); 653 u32 casr = ac97c_readl(chip, CASR);
580 u32 cosr = ac97c_readl(chip, COSR); 654 u32 cosr = ac97c_readl(chip, COSR);
655 u32 camr = ac97c_readl(chip, CAMR);
581 656
582 if (sr & AC97C_SR_CAEVT) { 657 if (sr & AC97C_SR_CAEVT) {
658 struct snd_pcm_runtime *runtime;
659 int offset, next_period, block_size;
583 dev_info(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n", 660 dev_info(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n",
584 casr & AC97C_CSR_OVRUN ? " OVRUN" : "", 661 casr & AC97C_CSR_OVRUN ? " OVRUN" : "",
585 casr & AC97C_CSR_RXRDY ? " RXRDY" : "", 662 casr & AC97C_CSR_RXRDY ? " RXRDY" : "",
@@ -587,6 +664,50 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
587 casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "", 664 casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
588 casr & AC97C_CSR_TXRDY ? " TXRDY" : "", 665 casr & AC97C_CSR_TXRDY ? " TXRDY" : "",
589 !casr ? " NONE" : ""); 666 !casr ? " NONE" : "");
667 if (!cpu_is_at32ap7000()) {
668 if ((casr & camr) & AC97C_CSR_ENDTX) {
669 runtime = chip->playback_substream->runtime;
670 block_size = frames_to_bytes(runtime,
671 runtime->period_size);
672 chip->playback_period++;
673
674 if (chip->playback_period == runtime->periods)
675 chip->playback_period = 0;
676 next_period = chip->playback_period + 1;
677 if (next_period == runtime->periods)
678 next_period = 0;
679
680 offset = block_size * next_period;
681
682 writel(runtime->dma_addr + offset,
683 chip->regs + ATMEL_PDC_TNPR);
684 writel(block_size / 2,
685 chip->regs + ATMEL_PDC_TNCR);
686
687 snd_pcm_period_elapsed(
688 chip->playback_substream);
689 }
690 if ((casr & camr) & AC97C_CSR_ENDRX) {
691 runtime = chip->capture_substream->runtime;
692 block_size = frames_to_bytes(runtime,
693 runtime->period_size);
694 chip->capture_period++;
695
696 if (chip->capture_period == runtime->periods)
697 chip->capture_period = 0;
698 next_period = chip->capture_period + 1;
699 if (next_period == runtime->periods)
700 next_period = 0;
701
702 offset = block_size * next_period;
703
704 writel(runtime->dma_addr + offset,
705 chip->regs + ATMEL_PDC_RNPR);
706 writel(block_size / 2,
707 chip->regs + ATMEL_PDC_RNCR);
708 snd_pcm_period_elapsed(chip->capture_substream);
709 }
710 }
590 retval = IRQ_HANDLED; 711 retval = IRQ_HANDLED;
591 } 712 }
592 713
@@ -608,15 +729,50 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
608 return retval; 729 return retval;
609} 730}
610 731
732static struct ac97_pcm at91_ac97_pcm_defs[] __devinitdata = {
733 /* Playback */
734 {
735 .exclusive = 1,
736 .r = { {
737 .slots = ((1 << AC97_SLOT_PCM_LEFT)
738 | (1 << AC97_SLOT_PCM_RIGHT)),
739 } },
740 },
741 /* PCM in */
742 {
743 .stream = 1,
744 .exclusive = 1,
745 .r = { {
746 .slots = ((1 << AC97_SLOT_PCM_LEFT)
747 | (1 << AC97_SLOT_PCM_RIGHT)),
748 } }
749 },
750 /* Mic in */
751 {
752 .stream = 1,
753 .exclusive = 1,
754 .r = { {
755 .slots = (1<<AC97_SLOT_MIC),
756 } }
757 },
758};
759
611static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip) 760static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip)
612{ 761{
613 struct snd_pcm *pcm; 762 struct snd_pcm *pcm;
614 struct snd_pcm_hardware hw = atmel_ac97c_hw; 763 struct snd_pcm_hardware hw = atmel_ac97c_hw;
615 int capture, playback, retval; 764 int capture, playback, retval, err;
616 765
617 capture = test_bit(DMA_RX_CHAN_PRESENT, &chip->flags); 766 capture = test_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
618 playback = test_bit(DMA_TX_CHAN_PRESENT, &chip->flags); 767 playback = test_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
619 768
769 if (!cpu_is_at32ap7000()) {
770 err = snd_ac97_pcm_assign(chip->ac97_bus,
771 ARRAY_SIZE(at91_ac97_pcm_defs),
772 at91_ac97_pcm_defs);
773 if (err)
774 return err;
775 }
620 retval = snd_pcm_new(chip->card, chip->card->shortname, 776 retval = snd_pcm_new(chip->card, chip->card->shortname,
621 chip->pdev->id, playback, capture, &pcm); 777 chip->pdev->id, playback, capture, &pcm);
622 if (retval) 778 if (retval)
@@ -775,7 +931,12 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
775 return -ENXIO; 931 return -ENXIO;
776 } 932 }
777 933
778 pclk = clk_get(&pdev->dev, "pclk"); 934 if (cpu_is_at32ap7000()) {
935 pclk = clk_get(&pdev->dev, "pclk");
936 } else {
937 pclk = clk_get(&pdev->dev, "ac97_clk");
938 }
939
779 if (IS_ERR(pclk)) { 940 if (IS_ERR(pclk)) {
780 dev_dbg(&pdev->dev, "no peripheral clock\n"); 941 dev_dbg(&pdev->dev, "no peripheral clock\n");
781 return PTR_ERR(pclk); 942 return PTR_ERR(pclk);
@@ -844,43 +1005,52 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
844 goto err_ac97_bus; 1005 goto err_ac97_bus;
845 } 1006 }
846 1007
847 if (pdata->rx_dws.dma_dev) { 1008 if (cpu_is_at32ap7000()) {
848 struct dw_dma_slave *dws = &pdata->rx_dws; 1009 if (pdata->rx_dws.dma_dev) {
849 dma_cap_mask_t mask; 1010 struct dw_dma_slave *dws = &pdata->rx_dws;
1011 dma_cap_mask_t mask;
850 1012
851 dws->rx_reg = regs->start + AC97C_CARHR + 2; 1013 dws->rx_reg = regs->start + AC97C_CARHR + 2;
852 1014
853 dma_cap_zero(mask); 1015 dma_cap_zero(mask);
854 dma_cap_set(DMA_SLAVE, mask); 1016 dma_cap_set(DMA_SLAVE, mask);
855 1017
856 chip->dma.rx_chan = dma_request_channel(mask, filter, dws); 1018 chip->dma.rx_chan = dma_request_channel(mask, filter,
1019 dws);
857 1020
858 dev_info(&chip->pdev->dev, "using %s for DMA RX\n", 1021 dev_info(&chip->pdev->dev, "using %s for DMA RX\n",
859 dev_name(&chip->dma.rx_chan->dev->device)); 1022 dev_name(&chip->dma.rx_chan->dev->device));
860 set_bit(DMA_RX_CHAN_PRESENT, &chip->flags); 1023 set_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
861 } 1024 }
862 1025
863 if (pdata->tx_dws.dma_dev) { 1026 if (pdata->tx_dws.dma_dev) {
864 struct dw_dma_slave *dws = &pdata->tx_dws; 1027 struct dw_dma_slave *dws = &pdata->tx_dws;
865 dma_cap_mask_t mask; 1028 dma_cap_mask_t mask;
866 1029
867 dws->tx_reg = regs->start + AC97C_CATHR + 2; 1030 dws->tx_reg = regs->start + AC97C_CATHR + 2;
868 1031
869 dma_cap_zero(mask); 1032 dma_cap_zero(mask);
870 dma_cap_set(DMA_SLAVE, mask); 1033 dma_cap_set(DMA_SLAVE, mask);
871 1034
872 chip->dma.tx_chan = dma_request_channel(mask, filter, dws); 1035 chip->dma.tx_chan = dma_request_channel(mask, filter,
1036 dws);
873 1037
874 dev_info(&chip->pdev->dev, "using %s for DMA TX\n", 1038 dev_info(&chip->pdev->dev, "using %s for DMA TX\n",
875 dev_name(&chip->dma.tx_chan->dev->device)); 1039 dev_name(&chip->dma.tx_chan->dev->device));
876 set_bit(DMA_TX_CHAN_PRESENT, &chip->flags); 1040 set_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
877 } 1041 }
878 1042
879 if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) && 1043 if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) &&
880 !test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) { 1044 !test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) {
881 dev_dbg(&pdev->dev, "DMA not available\n"); 1045 dev_dbg(&pdev->dev, "DMA not available\n");
882 retval = -ENODEV; 1046 retval = -ENODEV;
883 goto err_dma; 1047 goto err_dma;
1048 }
1049 } else {
1050 /* Just pretend that we have DMA channel(for at91 i is actually
1051 * the PDC) */
1052 set_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
1053 set_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
884 } 1054 }
885 1055
886 retval = atmel_ac97c_pcm_new(chip); 1056 retval = atmel_ac97c_pcm_new(chip);
@@ -897,20 +1067,22 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
897 1067
898 platform_set_drvdata(pdev, card); 1068 platform_set_drvdata(pdev, card);
899 1069
900 dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p\n", 1070 dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p, irq = %d\n",
901 chip->regs); 1071 chip->regs, irq);
902 1072
903 return 0; 1073 return 0;
904 1074
905err_dma: 1075err_dma:
906 if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) 1076 if (cpu_is_at32ap7000()) {
907 dma_release_channel(chip->dma.rx_chan); 1077 if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
908 if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) 1078 dma_release_channel(chip->dma.rx_chan);
909 dma_release_channel(chip->dma.tx_chan); 1079 if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags))
910 clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); 1080 dma_release_channel(chip->dma.tx_chan);
911 clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); 1081 clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
912 chip->dma.rx_chan = NULL; 1082 clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
913 chip->dma.tx_chan = NULL; 1083 chip->dma.rx_chan = NULL;
1084 chip->dma.tx_chan = NULL;
1085 }
914err_ac97_bus: 1086err_ac97_bus:
915 snd_card_set_dev(card, NULL); 1087 snd_card_set_dev(card, NULL);
916 1088
@@ -934,10 +1106,12 @@ static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg)
934 struct snd_card *card = platform_get_drvdata(pdev); 1106 struct snd_card *card = platform_get_drvdata(pdev);
935 struct atmel_ac97c *chip = card->private_data; 1107 struct atmel_ac97c *chip = card->private_data;
936 1108
937 if (test_bit(DMA_RX_READY, &chip->flags)) 1109 if (cpu_is_at32ap7000()) {
938 dw_dma_cyclic_stop(chip->dma.rx_chan); 1110 if (test_bit(DMA_RX_READY, &chip->flags))
939 if (test_bit(DMA_TX_READY, &chip->flags)) 1111 dw_dma_cyclic_stop(chip->dma.rx_chan);
940 dw_dma_cyclic_stop(chip->dma.tx_chan); 1112 if (test_bit(DMA_TX_READY, &chip->flags))
1113 dw_dma_cyclic_stop(chip->dma.tx_chan);
1114 }
941 clk_disable(chip->pclk); 1115 clk_disable(chip->pclk);
942 1116
943 return 0; 1117 return 0;
@@ -949,11 +1123,12 @@ static int atmel_ac97c_resume(struct platform_device *pdev)
949 struct atmel_ac97c *chip = card->private_data; 1123 struct atmel_ac97c *chip = card->private_data;
950 1124
951 clk_enable(chip->pclk); 1125 clk_enable(chip->pclk);
952 if (test_bit(DMA_RX_READY, &chip->flags)) 1126 if (cpu_is_at32ap7000()) {
953 dw_dma_cyclic_start(chip->dma.rx_chan); 1127 if (test_bit(DMA_RX_READY, &chip->flags))
954 if (test_bit(DMA_TX_READY, &chip->flags)) 1128 dw_dma_cyclic_start(chip->dma.rx_chan);
955 dw_dma_cyclic_start(chip->dma.tx_chan); 1129 if (test_bit(DMA_TX_READY, &chip->flags))
956 1130 dw_dma_cyclic_start(chip->dma.tx_chan);
1131 }
957 return 0; 1132 return 0;
958} 1133}
959#else 1134#else
@@ -978,14 +1153,16 @@ static int __devexit atmel_ac97c_remove(struct platform_device *pdev)
978 iounmap(chip->regs); 1153 iounmap(chip->regs);
979 free_irq(chip->irq, chip); 1154 free_irq(chip->irq, chip);
980 1155
981 if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) 1156 if (cpu_is_at32ap7000()) {
982 dma_release_channel(chip->dma.rx_chan); 1157 if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
983 if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) 1158 dma_release_channel(chip->dma.rx_chan);
984 dma_release_channel(chip->dma.tx_chan); 1159 if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags))
985 clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); 1160 dma_release_channel(chip->dma.tx_chan);
986 clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); 1161 clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
987 chip->dma.rx_chan = NULL; 1162 clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
988 chip->dma.tx_chan = NULL; 1163 chip->dma.rx_chan = NULL;
1164 chip->dma.tx_chan = NULL;
1165 }
989 1166
990 snd_card_set_dev(card, NULL); 1167 snd_card_set_dev(card, NULL);
991 snd_card_free(card); 1168 snd_card_free(card);
diff --git a/sound/core/control.c b/sound/core/control.c
index 439ce64f9d82..070aab490191 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -50,6 +50,10 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
50 struct snd_ctl_file *ctl; 50 struct snd_ctl_file *ctl;
51 int err; 51 int err;
52 52
53 err = nonseekable_open(inode, file);
54 if (err < 0)
55 return err;
56
53 card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL); 57 card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL);
54 if (!card) { 58 if (!card) {
55 err = -ENODEV; 59 err = -ENODEV;
@@ -1388,6 +1392,7 @@ static const struct file_operations snd_ctl_f_ops =
1388 .read = snd_ctl_read, 1392 .read = snd_ctl_read,
1389 .open = snd_ctl_open, 1393 .open = snd_ctl_open,
1390 .release = snd_ctl_release, 1394 .release = snd_ctl_release,
1395 .llseek = no_llseek,
1391 .poll = snd_ctl_poll, 1396 .poll = snd_ctl_poll,
1392 .unlocked_ioctl = snd_ctl_ioctl, 1397 .unlocked_ioctl = snd_ctl_ioctl,
1393 .compat_ioctl = snd_ctl_ioctl_compat, 1398 .compat_ioctl = snd_ctl_ioctl_compat,
diff --git a/sound/core/info.c b/sound/core/info.c
index cc4a53d4b7f8..b70564ed8b37 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -164,40 +164,44 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
164{ 164{
165 struct snd_info_private_data *data; 165 struct snd_info_private_data *data;
166 struct snd_info_entry *entry; 166 struct snd_info_entry *entry;
167 loff_t ret; 167 loff_t ret = -EINVAL, size;
168 168
169 data = file->private_data; 169 data = file->private_data;
170 entry = data->entry; 170 entry = data->entry;
171 lock_kernel(); 171 mutex_lock(&entry->access);
172 switch (entry->content) { 172 if (entry->content == SNDRV_INFO_CONTENT_DATA &&
173 case SNDRV_INFO_CONTENT_TEXT: 173 entry->c.ops->llseek) {
174 switch (orig) { 174 offset = entry->c.ops->llseek(entry,
175 case SEEK_SET: 175 data->file_private_data,
176 file->f_pos = offset; 176 file, offset, orig);
177 ret = file->f_pos; 177 goto out;
178 goto out; 178 }
179 case SEEK_CUR: 179 if (entry->content == SNDRV_INFO_CONTENT_DATA)
180 file->f_pos += offset; 180 size = entry->size;
181 ret = file->f_pos; 181 else
182 goto out; 182 size = 0;
183 case SEEK_END: 183 switch (orig) {
184 default: 184 case SEEK_SET:
185 ret = -EINVAL;
186 goto out;
187 }
188 break; 185 break;
189 case SNDRV_INFO_CONTENT_DATA: 186 case SEEK_CUR:
190 if (entry->c.ops->llseek) { 187 offset += file->f_pos;
191 ret = entry->c.ops->llseek(entry, 188 break;
192 data->file_private_data, 189 case SEEK_END:
193 file, offset, orig); 190 if (!size)
194 goto out; 191 goto out;
195 } 192 offset += size;
196 break; 193 break;
197 } 194 default:
198 ret = -ENXIO; 195 goto out;
199out: 196 }
200 unlock_kernel(); 197 if (offset < 0)
198 goto out;
199 if (size && offset > size)
200 offset = size;
201 file->f_pos = offset;
202 ret = offset;
203 out:
204 mutex_unlock(&entry->access);
201 return ret; 205 return ret;
202} 206}
203 207
@@ -232,10 +236,15 @@ static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
232 return -EFAULT; 236 return -EFAULT;
233 break; 237 break;
234 case SNDRV_INFO_CONTENT_DATA: 238 case SNDRV_INFO_CONTENT_DATA:
235 if (entry->c.ops->read) 239 if (pos >= entry->size)
240 return 0;
241 if (entry->c.ops->read) {
242 size = entry->size - pos;
243 size = min(count, size);
236 size = entry->c.ops->read(entry, 244 size = entry->c.ops->read(entry,
237 data->file_private_data, 245 data->file_private_data,
238 file, buffer, count, pos); 246 file, buffer, size, pos);
247 }
239 break; 248 break;
240 } 249 }
241 if ((ssize_t) size > 0) 250 if ((ssize_t) size > 0)
@@ -282,10 +291,13 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
282 size = count; 291 size = count;
283 break; 292 break;
284 case SNDRV_INFO_CONTENT_DATA: 293 case SNDRV_INFO_CONTENT_DATA:
285 if (entry->c.ops->write) 294 if (entry->c.ops->write && count > 0) {
295 size_t maxsize = entry->size - pos;
296 count = min(count, maxsize);
286 size = entry->c.ops->write(entry, 297 size = entry->c.ops->write(entry,
287 data->file_private_data, 298 data->file_private_data,
288 file, buffer, count, pos); 299 file, buffer, count, pos);
300 }
289 break; 301 break;
290 } 302 }
291 if ((ssize_t) size > 0) 303 if ((ssize_t) size > 0)
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 54e2eb56e4c2..f50ebf20df96 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -43,6 +43,10 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
43 struct snd_mixer_oss_file *fmixer; 43 struct snd_mixer_oss_file *fmixer;
44 int err; 44 int err;
45 45
46 err = nonseekable_open(inode, file);
47 if (err < 0)
48 return err;
49
46 card = snd_lookup_oss_minor_data(iminor(inode), 50 card = snd_lookup_oss_minor_data(iminor(inode),
47 SNDRV_OSS_DEVICE_TYPE_MIXER); 51 SNDRV_OSS_DEVICE_TYPE_MIXER);
48 if (card == NULL) 52 if (card == NULL)
@@ -397,6 +401,7 @@ static const struct file_operations snd_mixer_oss_f_ops =
397 .owner = THIS_MODULE, 401 .owner = THIS_MODULE,
398 .open = snd_mixer_oss_open, 402 .open = snd_mixer_oss_open,
399 .release = snd_mixer_oss_release, 403 .release = snd_mixer_oss_release,
404 .llseek = no_llseek,
400 .unlocked_ioctl = snd_mixer_oss_ioctl, 405 .unlocked_ioctl = snd_mixer_oss_ioctl,
401 .compat_ioctl = snd_mixer_oss_ioctl_compat, 406 .compat_ioctl = snd_mixer_oss_ioctl_compat,
402}; 407};
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 82d4e3329b3d..5c8c7dff8ede 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -2379,6 +2379,10 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
2379 int nonblock; 2379 int nonblock;
2380 wait_queue_t wait; 2380 wait_queue_t wait;
2381 2381
2382 err = nonseekable_open(inode, file);
2383 if (err < 0)
2384 return err;
2385
2382 pcm = snd_lookup_oss_minor_data(iminor(inode), 2386 pcm = snd_lookup_oss_minor_data(iminor(inode),
2383 SNDRV_OSS_DEVICE_TYPE_PCM); 2387 SNDRV_OSS_DEVICE_TYPE_PCM);
2384 if (pcm == NULL) { 2388 if (pcm == NULL) {
@@ -2977,6 +2981,7 @@ static const struct file_operations snd_pcm_oss_f_reg =
2977 .write = snd_pcm_oss_write, 2981 .write = snd_pcm_oss_write,
2978 .open = snd_pcm_oss_open, 2982 .open = snd_pcm_oss_open,
2979 .release = snd_pcm_oss_release, 2983 .release = snd_pcm_oss_release,
2984 .llseek = no_llseek,
2980 .poll = snd_pcm_oss_poll, 2985 .poll = snd_pcm_oss_poll,
2981 .unlocked_ioctl = snd_pcm_oss_ioctl, 2986 .unlocked_ioctl = snd_pcm_oss_ioctl,
2982 .compat_ioctl = snd_pcm_oss_ioctl_compat, 2987 .compat_ioctl = snd_pcm_oss_ioctl_compat,
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 20b5982c996b..b9517f38073c 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2110,7 +2110,9 @@ static int snd_pcm_open_file(struct file *file,
2110static int snd_pcm_playback_open(struct inode *inode, struct file *file) 2110static int snd_pcm_playback_open(struct inode *inode, struct file *file)
2111{ 2111{
2112 struct snd_pcm *pcm; 2112 struct snd_pcm *pcm;
2113 2113 int err = nonseekable_open(inode, file);
2114 if (err < 0)
2115 return err;
2114 pcm = snd_lookup_minor_data(iminor(inode), 2116 pcm = snd_lookup_minor_data(iminor(inode),
2115 SNDRV_DEVICE_TYPE_PCM_PLAYBACK); 2117 SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
2116 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); 2118 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
@@ -2119,7 +2121,9 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file)
2119static int snd_pcm_capture_open(struct inode *inode, struct file *file) 2121static int snd_pcm_capture_open(struct inode *inode, struct file *file)
2120{ 2122{
2121 struct snd_pcm *pcm; 2123 struct snd_pcm *pcm;
2122 2124 int err = nonseekable_open(inode, file);
2125 if (err < 0)
2126 return err;
2123 pcm = snd_lookup_minor_data(iminor(inode), 2127 pcm = snd_lookup_minor_data(iminor(inode),
2124 SNDRV_DEVICE_TYPE_PCM_CAPTURE); 2128 SNDRV_DEVICE_TYPE_PCM_CAPTURE);
2125 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); 2129 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
@@ -3310,18 +3314,13 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
3310 struct snd_pcm_file * pcm_file; 3314 struct snd_pcm_file * pcm_file;
3311 struct snd_pcm_substream *substream; 3315 struct snd_pcm_substream *substream;
3312 struct snd_pcm_runtime *runtime; 3316 struct snd_pcm_runtime *runtime;
3313 int err = -ENXIO;
3314 3317
3315 lock_kernel();
3316 pcm_file = file->private_data; 3318 pcm_file = file->private_data;
3317 substream = pcm_file->substream; 3319 substream = pcm_file->substream;
3318 if (PCM_RUNTIME_CHECK(substream)) 3320 if (PCM_RUNTIME_CHECK(substream))
3319 goto out; 3321 return -ENXIO;
3320 runtime = substream->runtime; 3322 runtime = substream->runtime;
3321 err = fasync_helper(fd, file, on, &runtime->fasync); 3323 return fasync_helper(fd, file, on, &runtime->fasync);
3322out:
3323 unlock_kernel();
3324 return err;
3325} 3324}
3326 3325
3327/* 3326/*
@@ -3462,6 +3461,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
3462 .aio_write = snd_pcm_aio_write, 3461 .aio_write = snd_pcm_aio_write,
3463 .open = snd_pcm_playback_open, 3462 .open = snd_pcm_playback_open,
3464 .release = snd_pcm_release, 3463 .release = snd_pcm_release,
3464 .llseek = no_llseek,
3465 .poll = snd_pcm_playback_poll, 3465 .poll = snd_pcm_playback_poll,
3466 .unlocked_ioctl = snd_pcm_playback_ioctl, 3466 .unlocked_ioctl = snd_pcm_playback_ioctl,
3467 .compat_ioctl = snd_pcm_ioctl_compat, 3467 .compat_ioctl = snd_pcm_ioctl_compat,
@@ -3475,6 +3475,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
3475 .aio_read = snd_pcm_aio_read, 3475 .aio_read = snd_pcm_aio_read,
3476 .open = snd_pcm_capture_open, 3476 .open = snd_pcm_capture_open,
3477 .release = snd_pcm_release, 3477 .release = snd_pcm_release,
3478 .llseek = no_llseek,
3478 .poll = snd_pcm_capture_poll, 3479 .poll = snd_pcm_capture_poll,
3479 .unlocked_ioctl = snd_pcm_capture_ioctl, 3480 .unlocked_ioctl = snd_pcm_capture_ioctl,
3480 .compat_ioctl = snd_pcm_ioctl_compat, 3481 .compat_ioctl = snd_pcm_ioctl_compat,
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 0f5a194695d9..eb68326c37d4 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -376,6 +376,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
376 if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) 376 if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
377 return -EINVAL; /* invalid combination */ 377 return -EINVAL; /* invalid combination */
378 378
379 err = nonseekable_open(inode, file);
380 if (err < 0)
381 return err;
382
379 if (maj == snd_major) { 383 if (maj == snd_major) {
380 rmidi = snd_lookup_minor_data(iminor(inode), 384 rmidi = snd_lookup_minor_data(iminor(inode),
381 SNDRV_DEVICE_TYPE_RAWMIDI); 385 SNDRV_DEVICE_TYPE_RAWMIDI);
@@ -1391,6 +1395,7 @@ static const struct file_operations snd_rawmidi_f_ops =
1391 .write = snd_rawmidi_write, 1395 .write = snd_rawmidi_write,
1392 .open = snd_rawmidi_open, 1396 .open = snd_rawmidi_open,
1393 .release = snd_rawmidi_release, 1397 .release = snd_rawmidi_release,
1398 .llseek = no_llseek,
1394 .poll = snd_rawmidi_poll, 1399 .poll = snd_rawmidi_poll,
1395 .unlocked_ioctl = snd_rawmidi_ioctl, 1400 .unlocked_ioctl = snd_rawmidi_ioctl,
1396 .compat_ioctl = snd_rawmidi_ioctl_compat, 1401 .compat_ioctl = snd_rawmidi_ioctl_compat,
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 48eca9ff9ee7..99a485f13648 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -318,6 +318,11 @@ static int snd_seq_open(struct inode *inode, struct file *file)
318 int c, mode; /* client id */ 318 int c, mode; /* client id */
319 struct snd_seq_client *client; 319 struct snd_seq_client *client;
320 struct snd_seq_user_client *user; 320 struct snd_seq_user_client *user;
321 int err;
322
323 err = nonseekable_open(inode, file);
324 if (err < 0)
325 return err;
321 326
322 if (mutex_lock_interruptible(&register_mutex)) 327 if (mutex_lock_interruptible(&register_mutex))
323 return -ERESTARTSYS; 328 return -ERESTARTSYS;
@@ -2550,6 +2555,7 @@ static const struct file_operations snd_seq_f_ops =
2550 .write = snd_seq_write, 2555 .write = snd_seq_write,
2551 .open = snd_seq_open, 2556 .open = snd_seq_open,
2552 .release = snd_seq_release, 2557 .release = snd_seq_release,
2558 .llseek = no_llseek,
2553 .poll = snd_seq_poll, 2559 .poll = snd_seq_poll,
2554 .unlocked_ioctl = snd_seq_ioctl, 2560 .unlocked_ioctl = snd_seq_ioctl,
2555 .compat_ioctl = snd_seq_ioctl_compat, 2561 .compat_ioctl = snd_seq_ioctl_compat,
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 563d1967a0ad..ac42af42b787 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -120,7 +120,29 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
120 120
121EXPORT_SYMBOL(snd_lookup_minor_data); 121EXPORT_SYMBOL(snd_lookup_minor_data);
122 122
123static int __snd_open(struct inode *inode, struct file *file) 123#ifdef CONFIG_MODULES
124static struct snd_minor *autoload_device(unsigned int minor)
125{
126 int dev;
127 mutex_unlock(&sound_mutex); /* release lock temporarily */
128 dev = SNDRV_MINOR_DEVICE(minor);
129 if (dev == SNDRV_MINOR_CONTROL) {
130 /* /dev/aloadC? */
131 int card = SNDRV_MINOR_CARD(minor);
132 if (snd_cards[card] == NULL)
133 snd_request_card(card);
134 } else if (dev == SNDRV_MINOR_GLOBAL) {
135 /* /dev/aloadSEQ */
136 snd_request_other(minor);
137 }
138 mutex_lock(&sound_mutex); /* reacuire lock */
139 return snd_minors[minor];
140}
141#else /* !CONFIG_MODULES */
142#define autoload_device(minor) NULL
143#endif /* CONFIG_MODULES */
144
145static int snd_open(struct inode *inode, struct file *file)
124{ 146{
125 unsigned int minor = iminor(inode); 147 unsigned int minor = iminor(inode);
126 struct snd_minor *mptr = NULL; 148 struct snd_minor *mptr = NULL;
@@ -129,55 +151,36 @@ static int __snd_open(struct inode *inode, struct file *file)
129 151
130 if (minor >= ARRAY_SIZE(snd_minors)) 152 if (minor >= ARRAY_SIZE(snd_minors))
131 return -ENODEV; 153 return -ENODEV;
154 mutex_lock(&sound_mutex);
132 mptr = snd_minors[minor]; 155 mptr = snd_minors[minor];
133 if (mptr == NULL) { 156 if (mptr == NULL) {
134#ifdef CONFIG_MODULES 157 mptr = autoload_device(minor);
135 int dev = SNDRV_MINOR_DEVICE(minor); 158 if (!mptr) {
136 if (dev == SNDRV_MINOR_CONTROL) { 159 mutex_unlock(&sound_mutex);
137 /* /dev/aloadC? */
138 int card = SNDRV_MINOR_CARD(minor);
139 if (snd_cards[card] == NULL)
140 snd_request_card(card);
141 } else if (dev == SNDRV_MINOR_GLOBAL) {
142 /* /dev/aloadSEQ */
143 snd_request_other(minor);
144 }
145#ifndef CONFIG_SND_DYNAMIC_MINORS
146 /* /dev/snd/{controlC?,seq} */
147 mptr = snd_minors[minor];
148 if (mptr == NULL)
149#endif
150#endif
151 return -ENODEV; 160 return -ENODEV;
161 }
152 } 162 }
153 old_fops = file->f_op; 163 old_fops = file->f_op;
154 file->f_op = fops_get(mptr->f_ops); 164 file->f_op = fops_get(mptr->f_ops);
155 if (file->f_op == NULL) { 165 if (file->f_op == NULL) {
156 file->f_op = old_fops; 166 file->f_op = old_fops;
157 return -ENODEV; 167 err = -ENODEV;
158 } 168 }
159 if (file->f_op->open) 169 mutex_unlock(&sound_mutex);
170 if (err < 0)
171 return err;
172
173 if (file->f_op->open) {
160 err = file->f_op->open(inode, file); 174 err = file->f_op->open(inode, file);
161 if (err) { 175 if (err) {
162 fops_put(file->f_op); 176 fops_put(file->f_op);
163 file->f_op = fops_get(old_fops); 177 file->f_op = fops_get(old_fops);
178 }
164 } 179 }
165 fops_put(old_fops); 180 fops_put(old_fops);
166 return err; 181 return err;
167} 182}
168 183
169
170/* BKL pushdown: nasty #ifdef avoidance wrapper */
171static int snd_open(struct inode *inode, struct file *file)
172{
173 int ret;
174
175 lock_kernel();
176 ret = __snd_open(inode, file);
177 unlock_kernel();
178 return ret;
179}
180
181static const struct file_operations snd_fops = 184static const struct file_operations snd_fops =
182{ 185{
183 .owner = THIS_MODULE, 186 .owner = THIS_MODULE,
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 5040c7b862fe..13afb60999b9 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1238,6 +1238,11 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
1238static int snd_timer_user_open(struct inode *inode, struct file *file) 1238static int snd_timer_user_open(struct inode *inode, struct file *file)
1239{ 1239{
1240 struct snd_timer_user *tu; 1240 struct snd_timer_user *tu;
1241 int err;
1242
1243 err = nonseekable_open(inode, file);
1244 if (err < 0)
1245 return err;
1241 1246
1242 tu = kzalloc(sizeof(*tu), GFP_KERNEL); 1247 tu = kzalloc(sizeof(*tu), GFP_KERNEL);
1243 if (tu == NULL) 1248 if (tu == NULL)
@@ -1922,6 +1927,7 @@ static const struct file_operations snd_timer_f_ops =
1922 .read = snd_timer_user_read, 1927 .read = snd_timer_user_read,
1923 .open = snd_timer_user_open, 1928 .open = snd_timer_user_open,
1924 .release = snd_timer_user_release, 1929 .release = snd_timer_user_release,
1930 .llseek = no_llseek,
1925 .poll = snd_timer_user_poll, 1931 .poll = snd_timer_user_poll,
1926 .unlocked_ioctl = snd_timer_user_ioctl, 1932 .unlocked_ioctl = snd_timer_user_ioctl,
1927 .compat_ioctl = snd_timer_user_ioctl_compat, 1933 .compat_ioctl = snd_timer_user_ioctl_compat,
diff --git a/sound/drivers/opl4/opl4_proc.c b/sound/drivers/opl4/opl4_proc.c
index 1679300b7583..df850b8830a5 100644
--- a/sound/drivers/opl4/opl4_proc.c
+++ b/sound/drivers/opl4/opl4_proc.c
@@ -49,77 +49,45 @@ static int snd_opl4_mem_proc_release(struct snd_info_entry *entry,
49 return 0; 49 return 0;
50} 50}
51 51
52static long snd_opl4_mem_proc_read(struct snd_info_entry *entry, void *file_private_data, 52static ssize_t snd_opl4_mem_proc_read(struct snd_info_entry *entry,
53 struct file *file, char __user *_buf, 53 void *file_private_data,
54 unsigned long count, unsigned long pos) 54 struct file *file, char __user *_buf,
55 size_t count, loff_t pos)
55{ 56{
56 struct snd_opl4 *opl4 = entry->private_data; 57 struct snd_opl4 *opl4 = entry->private_data;
57 long size;
58 char* buf; 58 char* buf;
59 59
60 size = count; 60 buf = vmalloc(count);
61 if (pos + size > entry->size) 61 if (!buf)
62 size = entry->size - pos; 62 return -ENOMEM;
63 if (size > 0) { 63 snd_opl4_read_memory(opl4, buf, pos, count);
64 buf = vmalloc(size); 64 if (copy_to_user(_buf, buf, count)) {
65 if (!buf)
66 return -ENOMEM;
67 snd_opl4_read_memory(opl4, buf, pos, size);
68 if (copy_to_user(_buf, buf, size)) {
69 vfree(buf);
70 return -EFAULT;
71 }
72 vfree(buf); 65 vfree(buf);
73 return size; 66 return -EFAULT;
74 } 67 }
75 return 0; 68 vfree(buf);
69 return count;
76} 70}
77 71
78static long snd_opl4_mem_proc_write(struct snd_info_entry *entry, void *file_private_data, 72static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry,
79 struct file *file, const char __user *_buf, 73 void *file_private_data,
80 unsigned long count, unsigned long pos) 74 struct file *file,
75 const char __user *_buf,
76 size_t count, loff_t pos)
81{ 77{
82 struct snd_opl4 *opl4 = entry->private_data; 78 struct snd_opl4 *opl4 = entry->private_data;
83 long size;
84 char *buf; 79 char *buf;
85 80
86 size = count; 81 buf = vmalloc(count);
87 if (pos + size > entry->size) 82 if (!buf)
88 size = entry->size - pos; 83 return -ENOMEM;
89 if (size > 0) { 84 if (copy_from_user(buf, _buf, count)) {
90 buf = vmalloc(size);
91 if (!buf)
92 return -ENOMEM;
93 if (copy_from_user(buf, _buf, size)) {
94 vfree(buf);
95 return -EFAULT;
96 }
97 snd_opl4_write_memory(opl4, buf, pos, size);
98 vfree(buf); 85 vfree(buf);
99 return size; 86 return -EFAULT;
100 }
101 return 0;
102}
103
104static long long snd_opl4_mem_proc_llseek(struct snd_info_entry *entry, void *file_private_data,
105 struct file *file, long long offset, int orig)
106{
107 switch (orig) {
108 case SEEK_SET:
109 file->f_pos = offset;
110 break;
111 case SEEK_CUR:
112 file->f_pos += offset;
113 break;
114 case SEEK_END: /* offset is negative */
115 file->f_pos = entry->size + offset;
116 break;
117 default:
118 return -EINVAL;
119 } 87 }
120 if (file->f_pos > entry->size) 88 snd_opl4_write_memory(opl4, buf, pos, count);
121 file->f_pos = entry->size; 89 vfree(buf);
122 return file->f_pos; 90 return count;
123} 91}
124 92
125static struct snd_info_entry_ops snd_opl4_mem_proc_ops = { 93static struct snd_info_entry_ops snd_opl4_mem_proc_ops = {
@@ -127,7 +95,6 @@ static struct snd_info_entry_ops snd_opl4_mem_proc_ops = {
127 .release = snd_opl4_mem_proc_release, 95 .release = snd_opl4_mem_proc_release,
128 .read = snd_opl4_mem_proc_read, 96 .read = snd_opl4_mem_proc_read,
129 .write = snd_opl4_mem_proc_write, 97 .write = snd_opl4_mem_proc_write,
130 .llseek = snd_opl4_mem_proc_llseek,
131}; 98};
132 99
133int snd_opl4_create_proc(struct snd_opl4 *opl4) 100int snd_opl4_create_proc(struct snd_opl4 *opl4)
diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c
index 2803e227aec9..2ccb3fadd7be 100644
--- a/sound/isa/gus/gus_mem_proc.c
+++ b/sound/isa/gus/gus_mem_proc.c
@@ -31,52 +31,21 @@ struct gus_proc_private {
31 struct snd_gus_card * gus; 31 struct snd_gus_card * gus;
32}; 32};
33 33
34static long snd_gf1_mem_proc_dump(struct snd_info_entry *entry, void *file_private_data, 34static ssize_t snd_gf1_mem_proc_dump(struct snd_info_entry *entry,
35 struct file *file, char __user *buf, 35 void *file_private_data,
36 unsigned long count, unsigned long pos) 36 struct file *file, char __user *buf,
37 size_t count, loff_t pos)
37{ 38{
38 long size;
39 struct gus_proc_private *priv = entry->private_data; 39 struct gus_proc_private *priv = entry->private_data;
40 struct snd_gus_card *gus = priv->gus; 40 struct snd_gus_card *gus = priv->gus;
41 int err; 41 int err;
42 42
43 size = count; 43 err = snd_gus_dram_read(gus, buf, pos, count, priv->rom);
44 if (pos + size > priv->size) 44 if (err < 0)
45 size = (long)priv->size - pos; 45 return err;
46 if (size > 0) { 46 return count;
47 if ((err = snd_gus_dram_read(gus, buf, pos, size, priv->rom)) < 0)
48 return err;
49 return size;
50 }
51 return 0;
52} 47}
53 48
54static long long snd_gf1_mem_proc_llseek(struct snd_info_entry *entry,
55 void *private_file_data,
56 struct file *file,
57 long long offset,
58 int orig)
59{
60 struct gus_proc_private *priv = entry->private_data;
61
62 switch (orig) {
63 case SEEK_SET:
64 file->f_pos = offset;
65 break;
66 case SEEK_CUR:
67 file->f_pos += offset;
68 break;
69 case SEEK_END: /* offset is negative */
70 file->f_pos = priv->size + offset;
71 break;
72 default:
73 return -EINVAL;
74 }
75 if (file->f_pos > priv->size)
76 file->f_pos = priv->size;
77 return file->f_pos;
78}
79
80static void snd_gf1_mem_proc_free(struct snd_info_entry *entry) 49static void snd_gf1_mem_proc_free(struct snd_info_entry *entry)
81{ 50{
82 struct gus_proc_private *priv = entry->private_data; 51 struct gus_proc_private *priv = entry->private_data;
@@ -85,7 +54,6 @@ static void snd_gf1_mem_proc_free(struct snd_info_entry *entry)
85 54
86static struct snd_info_entry_ops snd_gf1_mem_proc_ops = { 55static struct snd_info_entry_ops snd_gf1_mem_proc_ops = {
87 .read = snd_gf1_mem_proc_dump, 56 .read = snd_gf1_mem_proc_dump,
88 .llseek = snd_gf1_mem_proc_llseek,
89}; 57};
90 58
91int snd_gf1_mem_proc_init(struct snd_gus_card * gus) 59int snd_gf1_mem_proc_init(struct snd_gus_card * gus)
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 9edc65059e3e..6772070ed492 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1139,40 +1139,28 @@ static void snd_cs4281_proc_read(struct snd_info_entry *entry,
1139 snd_iprintf(buffer, "Spurious end IRQs : %u\n", chip->spurious_dtc_irq); 1139 snd_iprintf(buffer, "Spurious end IRQs : %u\n", chip->spurious_dtc_irq);
1140} 1140}
1141 1141
1142static long snd_cs4281_BA0_read(struct snd_info_entry *entry, 1142static ssize_t snd_cs4281_BA0_read(struct snd_info_entry *entry,
1143 void *file_private_data, 1143 void *file_private_data,
1144 struct file *file, char __user *buf, 1144 struct file *file, char __user *buf,
1145 unsigned long count, unsigned long pos) 1145 size_t count, loff_t pos)
1146{ 1146{
1147 long size;
1148 struct cs4281 *chip = entry->private_data; 1147 struct cs4281 *chip = entry->private_data;
1149 1148
1150 size = count; 1149 if (copy_to_user_fromio(buf, chip->ba0 + pos, count))
1151 if (pos + size > CS4281_BA0_SIZE) 1150 return -EFAULT;
1152 size = (long)CS4281_BA0_SIZE - pos; 1151 return count;
1153 if (size > 0) {
1154 if (copy_to_user_fromio(buf, chip->ba0 + pos, size))
1155 return -EFAULT;
1156 }
1157 return size;
1158} 1152}
1159 1153
1160static long snd_cs4281_BA1_read(struct snd_info_entry *entry, 1154static ssize_t snd_cs4281_BA1_read(struct snd_info_entry *entry,
1161 void *file_private_data, 1155 void *file_private_data,
1162 struct file *file, char __user *buf, 1156 struct file *file, char __user *buf,
1163 unsigned long count, unsigned long pos) 1157 size_t count, loff_t pos)
1164{ 1158{
1165 long size;
1166 struct cs4281 *chip = entry->private_data; 1159 struct cs4281 *chip = entry->private_data;
1167 1160
1168 size = count; 1161 if (copy_to_user_fromio(buf, chip->ba1 + pos, count))
1169 if (pos + size > CS4281_BA1_SIZE) 1162 return -EFAULT;
1170 size = (long)CS4281_BA1_SIZE - pos; 1163 return count;
1171 if (size > 0) {
1172 if (copy_to_user_fromio(buf, chip->ba1 + pos, size))
1173 return -EFAULT;
1174 }
1175 return size;
1176} 1164}
1177 1165
1178static struct snd_info_entry_ops snd_cs4281_proc_ops_BA0 = { 1166static struct snd_info_entry_ops snd_cs4281_proc_ops_BA0 = {
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 3f99a5e8528c..aad37082cb6e 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -2657,21 +2657,16 @@ static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { }
2657 * proc interface 2657 * proc interface
2658 */ 2658 */
2659 2659
2660static long snd_cs46xx_io_read(struct snd_info_entry *entry, void *file_private_data, 2660static ssize_t snd_cs46xx_io_read(struct snd_info_entry *entry,
2661 struct file *file, char __user *buf, 2661 void *file_private_data,
2662 unsigned long count, unsigned long pos) 2662 struct file *file, char __user *buf,
2663 size_t count, loff_t pos)
2663{ 2664{
2664 long size;
2665 struct snd_cs46xx_region *region = entry->private_data; 2665 struct snd_cs46xx_region *region = entry->private_data;
2666 2666
2667 size = count; 2667 if (copy_to_user_fromio(buf, region->remap_addr + pos, count))
2668 if (pos + (size_t)size > region->size) 2668 return -EFAULT;
2669 size = region->size - pos; 2669 return count;
2670 if (size > 0) {
2671 if (copy_to_user_fromio(buf, region->remap_addr + pos, size))
2672 return -EFAULT;
2673 }
2674 return size;
2675} 2670}
2676 2671
2677static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = { 2672static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = {
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index baa7cd508cd8..bc38dd4d071f 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -341,15 +341,17 @@ static void snd_emu10k1_proc_acode_read(struct snd_info_entry *entry,
341#define TOTAL_SIZE_CODE (0x200*8) 341#define TOTAL_SIZE_CODE (0x200*8)
342#define A_TOTAL_SIZE_CODE (0x400*8) 342#define A_TOTAL_SIZE_CODE (0x400*8)
343 343
344static long snd_emu10k1_fx8010_read(struct snd_info_entry *entry, 344static ssize_t snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
345 void *file_private_data, 345 void *file_private_data,
346 struct file *file, char __user *buf, 346 struct file *file, char __user *buf,
347 unsigned long count, unsigned long pos) 347 size_t count, loff_t pos)
348{ 348{
349 long size;
350 struct snd_emu10k1 *emu = entry->private_data; 349 struct snd_emu10k1 *emu = entry->private_data;
351 unsigned int offset; 350 unsigned int offset;
352 int tram_addr = 0; 351 int tram_addr = 0;
352 unsigned int *tmp;
353 long res;
354 unsigned int idx;
353 355
354 if (!strcmp(entry->name, "fx8010_tram_addr")) { 356 if (!strcmp(entry->name, "fx8010_tram_addr")) {
355 offset = TANKMEMADDRREGBASE; 357 offset = TANKMEMADDRREGBASE;
@@ -361,30 +363,25 @@ static long snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
361 } else { 363 } else {
362 offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE; 364 offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE;
363 } 365 }
364 size = count; 366
365 if (pos + size > entry->size) 367 tmp = kmalloc(count + 8, GFP_KERNEL);
366 size = (long)entry->size - pos; 368 if (!tmp)
367 if (size > 0) { 369 return -ENOMEM;
368 unsigned int *tmp; 370 for (idx = 0; idx < ((pos & 3) + count + 3) >> 2; idx++) {
369 long res; 371 unsigned int val;
370 unsigned int idx; 372 val = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
371 if ((tmp = kmalloc(size + 8, GFP_KERNEL)) == NULL) 373 if (tram_addr && emu->audigy) {
372 return -ENOMEM; 374 val >>= 11;
373 for (idx = 0; idx < ((pos & 3) + size + 3) >> 2; idx++) 375 val |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
374 if (tram_addr && emu->audigy) {
375 tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0) >> 11;
376 tmp[idx] |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
377 } else
378 tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
379 if (copy_to_user(buf, ((char *)tmp) + (pos & 3), size))
380 res = -EFAULT;
381 else {
382 res = size;
383 } 376 }
384 kfree(tmp); 377 tmp[idx] = val;
385 return res;
386 } 378 }
387 return 0; 379 if (copy_to_user(buf, ((char *)tmp) + (pos & 3), count))
380 res = -EFAULT;
381 else
382 res = count;
383 kfree(tmp);
384 return res;
388} 385}
389 386
390static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry, 387static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry,
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 9e66f6d306f8..2f6252266a02 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -1956,11 +1956,10 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1956 return 0; 1956 return 0;
1957} 1957}
1958 1958
1959
1960/* 1959/*
1961 * initialize the chip 1960 * reset the chip
1962 */ 1961 */
1963static int __devinit aureon_init(struct snd_ice1712 *ice) 1962static int aureon_reset(struct snd_ice1712 *ice)
1964{ 1963{
1965 static const unsigned short wm_inits_aureon[] = { 1964 static const unsigned short wm_inits_aureon[] = {
1966 /* These come first to reduce init pop noise */ 1965 /* These come first to reduce init pop noise */
@@ -2047,30 +2046,10 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2047 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */ 2046 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
2048 (unsigned short)-1 2047 (unsigned short)-1
2049 }; 2048 };
2050 struct aureon_spec *spec;
2051 unsigned int tmp; 2049 unsigned int tmp;
2052 const unsigned short *p; 2050 const unsigned short *p;
2053 int err, i; 2051 int err;
2054 2052 struct aureon_spec *spec = ice->spec;
2055 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2056 if (!spec)
2057 return -ENOMEM;
2058 ice->spec = spec;
2059
2060 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2061 ice->num_total_dacs = 6;
2062 ice->num_total_adcs = 2;
2063 } else {
2064 /* aureon 7.1 and prodigy 7.1 */
2065 ice->num_total_dacs = 8;
2066 ice->num_total_adcs = 2;
2067 }
2068
2069 /* to remeber the register values of CS8415 */
2070 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2071 if (!ice->akm)
2072 return -ENOMEM;
2073 ice->akm_codecs = 1;
2074 2053
2075 err = aureon_ac97_init(ice); 2054 err = aureon_ac97_init(ice);
2076 if (err != 0) 2055 if (err != 0)
@@ -2118,6 +2097,61 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2118 /* initialize PCA9554 pin directions & set default input */ 2097 /* initialize PCA9554 pin directions & set default input */
2119 aureon_pca9554_write(ice, PCA9554_DIR, 0x00); 2098 aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2120 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */ 2099 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
2100 return 0;
2101}
2102
2103/*
2104 * suspend/resume
2105 */
2106#ifdef CONFIG_PM
2107static int aureon_resume(struct snd_ice1712 *ice)
2108{
2109 struct aureon_spec *spec = ice->spec;
2110 int err, i;
2111
2112 err = aureon_reset(ice);
2113 if (err != 0)
2114 return err;
2115
2116 /* workaround for poking volume with alsamixer after resume:
2117 * just set stored volume again */
2118 for (i = 0; i < ice->num_total_dacs; i++)
2119 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2120 return 0;
2121}
2122#endif
2123
2124/*
2125 * initialize the chip
2126 */
2127static int __devinit aureon_init(struct snd_ice1712 *ice)
2128{
2129 struct aureon_spec *spec;
2130 int i, err;
2131
2132 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2133 if (!spec)
2134 return -ENOMEM;
2135 ice->spec = spec;
2136
2137 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2138 ice->num_total_dacs = 6;
2139 ice->num_total_adcs = 2;
2140 } else {
2141 /* aureon 7.1 and prodigy 7.1 */
2142 ice->num_total_dacs = 8;
2143 ice->num_total_adcs = 2;
2144 }
2145
2146 /* to remeber the register values of CS8415 */
2147 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2148 if (!ice->akm)
2149 return -ENOMEM;
2150 ice->akm_codecs = 1;
2151
2152 err = aureon_reset(ice);
2153 if (err != 0)
2154 return err;
2121 2155
2122 spec->master[0] = WM_VOL_MUTE; 2156 spec->master[0] = WM_VOL_MUTE;
2123 spec->master[1] = WM_VOL_MUTE; 2157 spec->master[1] = WM_VOL_MUTE;
@@ -2126,6 +2160,11 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2126 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]); 2160 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2127 } 2161 }
2128 2162
2163#ifdef CONFIG_PM
2164 ice->pm_resume = aureon_resume;
2165 ice->pm_suspend_enabled = 1;
2166#endif
2167
2129 return 0; 2168 return 0;
2130} 2169}
2131 2170
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 3be8f97c8bc0..6c3fd4d1c49d 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1102,73 +1102,17 @@ static int snd_mixart_free(struct mixart_mgr *mgr)
1102/* 1102/*
1103 * proc interface 1103 * proc interface
1104 */ 1104 */
1105static long long snd_mixart_BA0_llseek(struct snd_info_entry *entry,
1106 void *private_file_data,
1107 struct file *file,
1108 long long offset,
1109 int orig)
1110{
1111 offset = offset & ~3; /* 4 bytes aligned */
1112
1113 switch(orig) {
1114 case SEEK_SET:
1115 file->f_pos = offset;
1116 break;
1117 case SEEK_CUR:
1118 file->f_pos += offset;
1119 break;
1120 case SEEK_END: /* offset is negative */
1121 file->f_pos = MIXART_BA0_SIZE + offset;
1122 break;
1123 default:
1124 return -EINVAL;
1125 }
1126 if(file->f_pos > MIXART_BA0_SIZE)
1127 file->f_pos = MIXART_BA0_SIZE;
1128 return file->f_pos;
1129}
1130
1131static long long snd_mixart_BA1_llseek(struct snd_info_entry *entry,
1132 void *private_file_data,
1133 struct file *file,
1134 long long offset,
1135 int orig)
1136{
1137 offset = offset & ~3; /* 4 bytes aligned */
1138
1139 switch(orig) {
1140 case SEEK_SET:
1141 file->f_pos = offset;
1142 break;
1143 case SEEK_CUR:
1144 file->f_pos += offset;
1145 break;
1146 case SEEK_END: /* offset is negative */
1147 file->f_pos = MIXART_BA1_SIZE + offset;
1148 break;
1149 default:
1150 return -EINVAL;
1151 }
1152 if(file->f_pos > MIXART_BA1_SIZE)
1153 file->f_pos = MIXART_BA1_SIZE;
1154 return file->f_pos;
1155}
1156 1105
1157/* 1106/*
1158 mixart_BA0 proc interface for BAR 0 - read callback 1107 mixart_BA0 proc interface for BAR 0 - read callback
1159 */ 1108 */
1160static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private_data, 1109static ssize_t snd_mixart_BA0_read(struct snd_info_entry *entry,
1161 struct file *file, char __user *buf, 1110 void *file_private_data,
1162 unsigned long count, unsigned long pos) 1111 struct file *file, char __user *buf,
1112 size_t count, loff_t pos)
1163{ 1113{
1164 struct mixart_mgr *mgr = entry->private_data; 1114 struct mixart_mgr *mgr = entry->private_data;
1165 unsigned long maxsize;
1166 1115
1167 if (pos >= MIXART_BA0_SIZE)
1168 return 0;
1169 maxsize = MIXART_BA0_SIZE - pos;
1170 if (count > maxsize)
1171 count = maxsize;
1172 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ 1116 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
1173 if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count)) 1117 if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count))
1174 return -EFAULT; 1118 return -EFAULT;
@@ -1178,18 +1122,13 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private
1178/* 1122/*
1179 mixart_BA1 proc interface for BAR 1 - read callback 1123 mixart_BA1 proc interface for BAR 1 - read callback
1180 */ 1124 */
1181static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private_data, 1125static ssize_t snd_mixart_BA1_read(struct snd_info_entry *entry,
1182 struct file *file, char __user *buf, 1126 void *file_private_data,
1183 unsigned long count, unsigned long pos) 1127 struct file *file, char __user *buf,
1128 size_t count, loff_t pos)
1184{ 1129{
1185 struct mixart_mgr *mgr = entry->private_data; 1130 struct mixart_mgr *mgr = entry->private_data;
1186 unsigned long maxsize;
1187 1131
1188 if (pos > MIXART_BA1_SIZE)
1189 return 0;
1190 maxsize = MIXART_BA1_SIZE - pos;
1191 if (count > maxsize)
1192 count = maxsize;
1193 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ 1132 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
1194 if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count)) 1133 if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count))
1195 return -EFAULT; 1134 return -EFAULT;
@@ -1198,12 +1137,10 @@ static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private
1198 1137
1199static struct snd_info_entry_ops snd_mixart_proc_ops_BA0 = { 1138static struct snd_info_entry_ops snd_mixart_proc_ops_BA0 = {
1200 .read = snd_mixart_BA0_read, 1139 .read = snd_mixart_BA0_read,
1201 .llseek = snd_mixart_BA0_llseek
1202}; 1140};
1203 1141
1204static struct snd_info_entry_ops snd_mixart_proc_ops_BA1 = { 1142static struct snd_info_entry_ops snd_mixart_proc_ops_BA1 = {
1205 .read = snd_mixart_BA1_read, 1143 .read = snd_mixart_BA1_read,
1206 .llseek = snd_mixart_BA1_llseek
1207}; 1144};
1208 1145
1209 1146
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 789f44f4ac78..20afdf9772ee 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -30,6 +30,7 @@
30#include <linux/kmod.h> 30#include <linux/kmod.h>
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/interrupt.h> 32#include <linux/interrupt.h>
33#include <linux/string.h>
33#include <sound/core.h> 34#include <sound/core.h>
34#include <asm/io.h> 35#include <asm/io.h>
35#include <asm/irq.h> 36#include <asm/irq.h>
@@ -46,6 +47,8 @@
46#define DBG(fmt...) 47#define DBG(fmt...)
47#endif 48#endif
48 49
50#define IS_G4DA (of_machine_is_compatible("PowerMac3,4"))
51
49/* i2c address for tumbler */ 52/* i2c address for tumbler */
50#define TAS_I2C_ADDR 0x34 53#define TAS_I2C_ADDR 0x34
51 54
@@ -243,6 +246,7 @@ static int tumbler_set_master_volume(struct pmac_tumbler *mix)
243 snd_printk(KERN_ERR "failed to set volume \n"); 246 snd_printk(KERN_ERR "failed to set volume \n");
244 return -EINVAL; 247 return -EINVAL;
245 } 248 }
249 DBG("(I) succeeded to set volume (%u, %u)\n", left_vol, right_vol);
246 return 0; 250 return 0;
247} 251}
248 252
@@ -353,6 +357,7 @@ static int tumbler_set_drc(struct pmac_tumbler *mix)
353 snd_printk(KERN_ERR "failed to set DRC\n"); 357 snd_printk(KERN_ERR "failed to set DRC\n");
354 return -EINVAL; 358 return -EINVAL;
355 } 359 }
360 DBG("(I) succeeded to set DRC (%u, %u)\n", val[0], val[1]);
356 return 0; 361 return 0;
357} 362}
358 363
@@ -389,6 +394,7 @@ static int snapper_set_drc(struct pmac_tumbler *mix)
389 snd_printk(KERN_ERR "failed to set DRC\n"); 394 snd_printk(KERN_ERR "failed to set DRC\n");
390 return -EINVAL; 395 return -EINVAL;
391 } 396 }
397 DBG("(I) succeeded to set DRC (%u, %u)\n", val[0], val[1]);
392 return 0; 398 return 0;
393} 399}
394 400
@@ -1134,7 +1140,8 @@ static long tumbler_find_device(const char *device, const char *platform,
1134 gp->inactive_val = (*base) ? 0x4 : 0x5; 1140 gp->inactive_val = (*base) ? 0x4 : 0x5;
1135 } else { 1141 } else {
1136 const u32 *prop = NULL; 1142 const u32 *prop = NULL;
1137 gp->active_state = 0; 1143 gp->active_state = IS_G4DA
1144 && !strncmp(device, "keywest-gpio1", 13);
1138 gp->active_val = 0x4; 1145 gp->active_val = 0x4;
1139 gp->inactive_val = 0x5; 1146 gp->inactive_val = 0x5;
1140 /* Here are some crude hacks to extract the GPIO polarity and 1147 /* Here are some crude hacks to extract the GPIO polarity and
@@ -1312,6 +1319,9 @@ static int __devinit tumbler_init(struct snd_pmac *chip)
1312 if (irq <= NO_IRQ) 1319 if (irq <= NO_IRQ)
1313 irq = tumbler_find_device("line-output-detect", 1320 irq = tumbler_find_device("line-output-detect",
1314 NULL, &mix->line_detect, 1); 1321 NULL, &mix->line_detect, 1);
1322 if (IS_G4DA && irq <= NO_IRQ)
1323 irq = tumbler_find_device("keywest-gpio16",
1324 NULL, &mix->line_detect, 1);
1315 mix->lineout_irq = irq; 1325 mix->lineout_irq = irq;
1316 1326
1317 tumbler_reset_audio(chip); 1327 tumbler_reset_audio(chip);
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index c570ae3e6d55..c4dcbadd83aa 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -65,6 +65,7 @@ config SND_USB_CAIAQ
65 * Native Instruments Audio 8 DJ 65 * Native Instruments Audio 8 DJ
66 * Native Instruments Guitar Rig Session I/O 66 * Native Instruments Guitar Rig Session I/O
67 * Native Instruments Guitar Rig mobile 67 * Native Instruments Guitar Rig mobile
68 * Native Instruments Traktor Kontrol X1
68 69
69 To compile this driver as a module, choose M here: the module 70 To compile this driver as a module, choose M here: the module
70 will be called snd-usb-caiaq. 71 will be called snd-usb-caiaq.
diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c
index 537102ba6b9d..36ed703a7416 100644
--- a/sound/usb/caiaq/control.c
+++ b/sound/usb/caiaq/control.c
@@ -35,33 +35,41 @@ static int control_info(struct snd_kcontrol *kcontrol,
35 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); 35 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
36 int pos = kcontrol->private_value; 36 int pos = kcontrol->private_value;
37 int is_intval = pos & CNT_INTVAL; 37 int is_intval = pos & CNT_INTVAL;
38 unsigned int id = dev->chip.usb_id; 38 int maxval = 63;
39 39
40 uinfo->count = 1; 40 uinfo->count = 1;
41 pos &= ~CNT_INTVAL; 41 pos &= ~CNT_INTVAL;
42 42
43 if (id == USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ) 43 switch (dev->chip.usb_id) {
44 && (pos == 0)) { 44 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
45 /* current input mode of A8DJ */ 45 if (pos == 0) {
46 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 46 /* current input mode of A8DJ */
47 uinfo->value.integer.min = 0; 47 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
48 uinfo->value.integer.max = 2; 48 uinfo->value.integer.min = 0;
49 return 0; 49 uinfo->value.integer.max = 2;
50 } 50 return 0;
51 }
52 break;
51 53
52 if (id == USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ) 54 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
53 && (pos == 0)) { 55 if (pos == 0) {
54 /* current input mode of A4DJ */ 56 /* current input mode of A4DJ */
55 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 57 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
56 uinfo->value.integer.min = 0; 58 uinfo->value.integer.min = 0;
57 uinfo->value.integer.max = 1; 59 uinfo->value.integer.max = 1;
58 return 0; 60 return 0;
61 }
62 break;
63
64 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
65 maxval = 127;
66 break;
59 } 67 }
60 68
61 if (is_intval) { 69 if (is_intval) {
62 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 70 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
63 uinfo->value.integer.min = 0; 71 uinfo->value.integer.min = 0;
64 uinfo->value.integer.max = 64; 72 uinfo->value.integer.max = maxval;
65 } else { 73 } else {
66 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 74 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
67 uinfo->value.integer.min = 0; 75 uinfo->value.integer.min = 0;
@@ -102,9 +110,10 @@ static int control_put(struct snd_kcontrol *kcontrol,
102 struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); 110 struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
103 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); 111 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
104 int pos = kcontrol->private_value; 112 int pos = kcontrol->private_value;
113 unsigned char cmd = EP1_CMD_WRITE_IO;
105 114
106 if (dev->chip.usb_id == 115 switch (dev->chip.usb_id) {
107 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ)) { 116 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): {
108 /* A4DJ has only one control */ 117 /* A4DJ has only one control */
109 /* do not expose hardware input mode 0 */ 118 /* do not expose hardware input mode 0 */
110 dev->control_state[0] = ucontrol->value.integer.value[0] + 1; 119 dev->control_state[0] = ucontrol->value.integer.value[0] + 1;
@@ -113,10 +122,15 @@ static int control_put(struct snd_kcontrol *kcontrol,
113 return 1; 122 return 1;
114 } 123 }
115 124
125 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
126 cmd = EP1_CMD_DIMM_LEDS;
127 break;
128 }
129
116 if (pos & CNT_INTVAL) { 130 if (pos & CNT_INTVAL) {
117 dev->control_state[pos & ~CNT_INTVAL] 131 dev->control_state[pos & ~CNT_INTVAL]
118 = ucontrol->value.integer.value[0]; 132 = ucontrol->value.integer.value[0];
119 snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, 133 snd_usb_caiaq_send_command(dev, cmd,
120 dev->control_state, sizeof(dev->control_state)); 134 dev->control_state, sizeof(dev->control_state));
121 } else { 135 } else {
122 if (ucontrol->value.integer.value[0]) 136 if (ucontrol->value.integer.value[0])
@@ -124,7 +138,7 @@ static int control_put(struct snd_kcontrol *kcontrol,
124 else 138 else
125 dev->control_state[pos / 8] &= ~(1 << (pos % 8)); 139 dev->control_state[pos / 8] &= ~(1 << (pos % 8));
126 140
127 snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, 141 snd_usb_caiaq_send_command(dev, cmd,
128 dev->control_state, sizeof(dev->control_state)); 142 dev->control_state, sizeof(dev->control_state));
129 } 143 }
130 144
@@ -273,6 +287,43 @@ static struct caiaq_controller a4dj_controller[] = {
273 { "Current input mode", 0 | CNT_INTVAL } 287 { "Current input mode", 0 | CNT_INTVAL }
274}; 288};
275 289
290static struct caiaq_controller kontrolx1_controller[] = {
291 { "LED FX A: ON", 7 | CNT_INTVAL },
292 { "LED FX A: 1", 6 | CNT_INTVAL },
293 { "LED FX A: 2", 5 | CNT_INTVAL },
294 { "LED FX A: 3", 4 | CNT_INTVAL },
295 { "LED FX B: ON", 3 | CNT_INTVAL },
296 { "LED FX B: 1", 2 | CNT_INTVAL },
297 { "LED FX B: 2", 1 | CNT_INTVAL },
298 { "LED FX B: 3", 0 | CNT_INTVAL },
299
300 { "LED Hotcue", 28 | CNT_INTVAL },
301 { "LED Shift (white)", 29 | CNT_INTVAL },
302 { "LED Shift (green)", 30 | CNT_INTVAL },
303
304 { "LED Deck A: FX1", 24 | CNT_INTVAL },
305 { "LED Deck A: FX2", 25 | CNT_INTVAL },
306 { "LED Deck A: IN", 17 | CNT_INTVAL },
307 { "LED Deck A: OUT", 16 | CNT_INTVAL },
308 { "LED Deck A: < BEAT", 19 | CNT_INTVAL },
309 { "LED Deck A: BEAT >", 18 | CNT_INTVAL },
310 { "LED Deck A: CUE/ABS", 21 | CNT_INTVAL },
311 { "LED Deck A: CUP/REL", 20 | CNT_INTVAL },
312 { "LED Deck A: PLAY", 23 | CNT_INTVAL },
313 { "LED Deck A: SYNC", 22 | CNT_INTVAL },
314
315 { "LED Deck B: FX1", 26 | CNT_INTVAL },
316 { "LED Deck B: FX2", 27 | CNT_INTVAL },
317 { "LED Deck B: IN", 15 | CNT_INTVAL },
318 { "LED Deck B: OUT", 14 | CNT_INTVAL },
319 { "LED Deck B: < BEAT", 13 | CNT_INTVAL },
320 { "LED Deck B: BEAT >", 12 | CNT_INTVAL },
321 { "LED Deck B: CUE/ABS", 11 | CNT_INTVAL },
322 { "LED Deck B: CUP/REL", 10 | CNT_INTVAL },
323 { "LED Deck B: PLAY", 9 | CNT_INTVAL },
324 { "LED Deck B: SYNC", 8 | CNT_INTVAL },
325};
326
276static int __devinit add_controls(struct caiaq_controller *c, int num, 327static int __devinit add_controls(struct caiaq_controller *c, int num,
277 struct snd_usb_caiaqdev *dev) 328 struct snd_usb_caiaqdev *dev)
278{ 329{
@@ -321,10 +372,16 @@ int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
321 ret = add_controls(a8dj_controller, 372 ret = add_controls(a8dj_controller,
322 ARRAY_SIZE(a8dj_controller), dev); 373 ARRAY_SIZE(a8dj_controller), dev);
323 break; 374 break;
375
324 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): 376 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
325 ret = add_controls(a4dj_controller, 377 ret = add_controls(a4dj_controller,
326 ARRAY_SIZE(a4dj_controller), dev); 378 ARRAY_SIZE(a4dj_controller), dev);
327 break; 379 break;
380
381 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
382 ret = add_controls(kontrolx1_controller,
383 ARRAY_SIZE(kontrolx1_controller), dev);
384 break;
328 } 385 }
329 386
330 return ret; 387 return ret;
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index afc5aeb68005..805271827675 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -47,7 +47,8 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
47 "{Native Instruments, Audio 4 DJ}," 47 "{Native Instruments, Audio 4 DJ},"
48 "{Native Instruments, Audio 8 DJ}," 48 "{Native Instruments, Audio 8 DJ},"
49 "{Native Instruments, Session I/O}," 49 "{Native Instruments, Session I/O},"
50 "{Native Instruments, GuitarRig mobile}"); 50 "{Native Instruments, GuitarRig mobile}"
51 "{Native Instruments, Traktor Kontrol X1}");
51 52
52static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ 53static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
53static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ 54static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
@@ -128,6 +129,11 @@ static struct usb_device_id snd_usb_id_table[] = {
128 .idVendor = USB_VID_NATIVEINSTRUMENTS, 129 .idVendor = USB_VID_NATIVEINSTRUMENTS,
129 .idProduct = USB_PID_AUDIO2DJ 130 .idProduct = USB_PID_AUDIO2DJ
130 }, 131 },
132 {
133 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
134 .idVendor = USB_VID_NATIVEINSTRUMENTS,
135 .idProduct = USB_PID_TRAKTORKONTROLX1
136 },
131 { /* terminator */ } 137 { /* terminator */ }
132}; 138};
133 139
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h
index 44e3edf88bef..f1117ecc84fd 100644
--- a/sound/usb/caiaq/device.h
+++ b/sound/usb/caiaq/device.h
@@ -5,18 +5,20 @@
5 5
6#define USB_VID_NATIVEINSTRUMENTS 0x17cc 6#define USB_VID_NATIVEINSTRUMENTS 0x17cc
7 7
8#define USB_PID_RIGKONTROL2 0x1969 8#define USB_PID_RIGKONTROL2 0x1969
9#define USB_PID_RIGKONTROL3 0x1940 9#define USB_PID_RIGKONTROL3 0x1940
10#define USB_PID_KORECONTROLLER 0x4711 10#define USB_PID_KORECONTROLLER 0x4711
11#define USB_PID_KORECONTROLLER2 0x4712 11#define USB_PID_KORECONTROLLER2 0x4712
12#define USB_PID_AK1 0x0815 12#define USB_PID_AK1 0x0815
13#define USB_PID_AUDIO2DJ 0x041c 13#define USB_PID_AUDIO2DJ 0x041c
14#define USB_PID_AUDIO4DJ 0x0839 14#define USB_PID_AUDIO4DJ 0x0839
15#define USB_PID_AUDIO8DJ 0x1978 15#define USB_PID_AUDIO8DJ 0x1978
16#define USB_PID_SESSIONIO 0x1915 16#define USB_PID_SESSIONIO 0x1915
17#define USB_PID_GUITARRIGMOBILE 0x0d8d 17#define USB_PID_GUITARRIGMOBILE 0x0d8d
18#define USB_PID_TRAKTORKONTROLX1 0x2305
18 19
19#define EP1_BUFSIZE 64 20#define EP1_BUFSIZE 64
21#define EP4_BUFSIZE 512
20#define CAIAQ_USB_STR_LEN 0xff 22#define CAIAQ_USB_STR_LEN 0xff
21#define MAX_STREAMS 32 23#define MAX_STREAMS 32
22 24
@@ -104,6 +106,8 @@ struct snd_usb_caiaqdev {
104 struct input_dev *input_dev; 106 struct input_dev *input_dev;
105 char phys[64]; /* physical device path */ 107 char phys[64]; /* physical device path */
106 unsigned short keycode[64]; 108 unsigned short keycode[64];
109 struct urb *ep4_in_urb;
110 unsigned char ep4_in_buf[EP4_BUFSIZE];
107#endif 111#endif
108 112
109 /* ALSA */ 113 /* ALSA */
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c
index a48d309bd94c..27ed0bc651ae 100644
--- a/sound/usb/caiaq/input.c
+++ b/sound/usb/caiaq/input.c
@@ -19,6 +19,7 @@
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/usb.h> 20#include <linux/usb.h>
21#include <linux/usb/input.h> 21#include <linux/usb/input.h>
22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23 24
24#include "device.h" 25#include "device.h"
@@ -65,6 +66,8 @@ static unsigned short keycode_kore[] = {
65 KEY_BRL_DOT5 66 KEY_BRL_DOT5
66}; 67};
67 68
69#define KONTROLX1_INPUTS 40
70
68#define DEG90 (range / 2) 71#define DEG90 (range / 2)
69#define DEG180 (range) 72#define DEG180 (range)
70#define DEG270 (DEG90 + DEG180) 73#define DEG270 (DEG90 + DEG180)
@@ -162,6 +165,17 @@ static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
162 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]); 165 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]);
163 input_sync(input_dev); 166 input_sync(input_dev);
164 break; 167 break;
168 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
169 input_report_abs(input_dev, ABS_HAT0X, (buf[8] << 8) | buf[9]);
170 input_report_abs(input_dev, ABS_HAT0Y, (buf[4] << 8) | buf[5]);
171 input_report_abs(input_dev, ABS_HAT1X, (buf[12] << 8) | buf[13]);
172 input_report_abs(input_dev, ABS_HAT1Y, (buf[2] << 8) | buf[3]);
173 input_report_abs(input_dev, ABS_HAT2X, (buf[15] << 8) | buf[15]);
174 input_report_abs(input_dev, ABS_HAT2Y, (buf[0] << 8) | buf[1]);
175 input_report_abs(input_dev, ABS_HAT3X, (buf[10] << 8) | buf[11]);
176 input_report_abs(input_dev, ABS_HAT3Y, (buf[6] << 8) | buf[7]);
177 input_sync(input_dev);
178 break;
165 } 179 }
166} 180}
167 181
@@ -201,7 +215,7 @@ static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
201} 215}
202 216
203static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, 217static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
204 char *buf, unsigned int len) 218 unsigned char *buf, unsigned int len)
205{ 219{
206 struct input_dev *input_dev = dev->input_dev; 220 struct input_dev *input_dev = dev->input_dev;
207 unsigned short *keycode = input_dev->keycode; 221 unsigned short *keycode = input_dev->keycode;
@@ -218,15 +232,84 @@ static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
218 input_report_key(input_dev, keycode[i], 232 input_report_key(input_dev, keycode[i],
219 buf[i / 8] & (1 << (i % 8))); 233 buf[i / 8] & (1 << (i % 8)));
220 234
221 if (dev->chip.usb_id == 235 switch (dev->chip.usb_id) {
222 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER) || 236 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
223 dev->chip.usb_id == 237 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
224 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2))
225 input_report_abs(dev->input_dev, ABS_MISC, 255 - buf[4]); 238 input_report_abs(dev->input_dev, ABS_MISC, 255 - buf[4]);
239 break;
240 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
241 /* rotary encoders */
242 input_report_abs(dev->input_dev, ABS_X, buf[5] & 0xf);
243 input_report_abs(dev->input_dev, ABS_Y, buf[5] >> 4);
244 input_report_abs(dev->input_dev, ABS_Z, buf[6] & 0xf);
245 input_report_abs(dev->input_dev, ABS_MISC, buf[6] >> 4);
246 break;
247 }
226 248
227 input_sync(input_dev); 249 input_sync(input_dev);
228} 250}
229 251
252static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
253{
254 struct snd_usb_caiaqdev *dev = urb->context;
255 unsigned char *buf = urb->transfer_buffer;
256 int ret;
257
258 if (urb->status || !dev || urb != dev->ep4_in_urb)
259 return;
260
261 if (urb->actual_length < 24)
262 goto requeue;
263
264 switch (dev->chip.usb_id) {
265 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
266 if (buf[0] & 0x3)
267 snd_caiaq_input_read_io(dev, buf + 1, 7);
268
269 if (buf[0] & 0x4)
270 snd_caiaq_input_read_analog(dev, buf + 8, 16);
271
272 break;
273 }
274
275requeue:
276 dev->ep4_in_urb->actual_length = 0;
277 ret = usb_submit_urb(dev->ep4_in_urb, GFP_ATOMIC);
278 if (ret < 0)
279 log("unable to submit urb. OOM!?\n");
280}
281
282static int snd_usb_caiaq_input_open(struct input_dev *idev)
283{
284 struct snd_usb_caiaqdev *dev = input_get_drvdata(idev);
285
286 if (!dev)
287 return -EINVAL;
288
289 switch (dev->chip.usb_id) {
290 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
291 if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0)
292 return -EIO;
293 break;
294 }
295
296 return 0;
297}
298
299static void snd_usb_caiaq_input_close(struct input_dev *idev)
300{
301 struct snd_usb_caiaqdev *dev = input_get_drvdata(idev);
302
303 if (!dev)
304 return;
305
306 switch (dev->chip.usb_id) {
307 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
308 usb_kill_urb(dev->ep4_in_urb);
309 break;
310 }
311}
312
230void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, 313void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev,
231 char *buf, 314 char *buf,
232 unsigned int len) 315 unsigned int len)
@@ -251,7 +334,7 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
251{ 334{
252 struct usb_device *usb_dev = dev->chip.dev; 335 struct usb_device *usb_dev = dev->chip.dev;
253 struct input_dev *input; 336 struct input_dev *input;
254 int i, ret; 337 int i, ret = 0;
255 338
256 input = input_allocate_device(); 339 input = input_allocate_device();
257 if (!input) 340 if (!input)
@@ -265,7 +348,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
265 usb_to_input_id(usb_dev, &input->id); 348 usb_to_input_id(usb_dev, &input->id);
266 input->dev.parent = &usb_dev->dev; 349 input->dev.parent = &usb_dev->dev;
267 350
268 switch (dev->chip.usb_id) { 351 input_set_drvdata(input, dev);
352
353 switch (dev->chip.usb_id) {
269 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): 354 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
270 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 355 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
271 input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | 356 input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
@@ -326,25 +411,72 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
326 input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1); 411 input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1);
327 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); 412 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
328 break; 413 break;
414 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
415 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
416 input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
417 BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
418 BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
419 BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
420 BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
421 BIT_MASK(ABS_Z);
422 input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
423 BUILD_BUG_ON(sizeof(dev->keycode) < KONTROLX1_INPUTS);
424 for (i = 0; i < KONTROLX1_INPUTS; i++)
425 dev->keycode[i] = BTN_MISC + i;
426 input->keycodemax = KONTROLX1_INPUTS;
427
428 /* analog potentiometers */
429 input_set_abs_params(input, ABS_HAT0X, 0, 4096, 0, 10);
430 input_set_abs_params(input, ABS_HAT0Y, 0, 4096, 0, 10);
431 input_set_abs_params(input, ABS_HAT1X, 0, 4096, 0, 10);
432 input_set_abs_params(input, ABS_HAT1Y, 0, 4096, 0, 10);
433 input_set_abs_params(input, ABS_HAT2X, 0, 4096, 0, 10);
434 input_set_abs_params(input, ABS_HAT2Y, 0, 4096, 0, 10);
435 input_set_abs_params(input, ABS_HAT3X, 0, 4096, 0, 10);
436 input_set_abs_params(input, ABS_HAT3Y, 0, 4096, 0, 10);
437
438 /* rotary encoders */
439 input_set_abs_params(input, ABS_X, 0, 0xf, 0, 1);
440 input_set_abs_params(input, ABS_Y, 0, 0xf, 0, 1);
441 input_set_abs_params(input, ABS_Z, 0, 0xf, 0, 1);
442 input_set_abs_params(input, ABS_MISC, 0, 0xf, 0, 1);
443
444 dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
445 if (!dev->ep4_in_urb) {
446 ret = -ENOMEM;
447 goto exit_free_idev;
448 }
449
450 usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev,
451 usb_rcvbulkpipe(usb_dev, 0x4),
452 dev->ep4_in_buf, EP4_BUFSIZE,
453 snd_usb_caiaq_ep4_reply_dispatch, dev);
454
455 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
456
457 break;
329 default: 458 default:
330 /* no input methods supported on this device */ 459 /* no input methods supported on this device */
331 input_free_device(input); 460 goto exit_free_idev;
332 return 0;
333 } 461 }
334 462
463 input->open = snd_usb_caiaq_input_open;
464 input->close = snd_usb_caiaq_input_close;
335 input->keycode = dev->keycode; 465 input->keycode = dev->keycode;
336 input->keycodesize = sizeof(unsigned short); 466 input->keycodesize = sizeof(unsigned short);
337 for (i = 0; i < input->keycodemax; i++) 467 for (i = 0; i < input->keycodemax; i++)
338 __set_bit(dev->keycode[i], input->keybit); 468 __set_bit(dev->keycode[i], input->keybit);
339 469
340 ret = input_register_device(input); 470 ret = input_register_device(input);
341 if (ret < 0) { 471 if (ret < 0)
342 input_free_device(input); 472 goto exit_free_idev;
343 return ret;
344 }
345 473
346 dev->input_dev = input; 474 dev->input_dev = input;
347 return 0; 475 return 0;
476
477exit_free_idev:
478 input_free_device(input);
479 return ret;
348} 480}
349 481
350void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) 482void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
@@ -352,6 +484,10 @@ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
352 if (!dev || !dev->input_dev) 484 if (!dev || !dev->input_dev)
353 return; 485 return;
354 486
487 usb_kill_urb(dev->ep4_in_urb);
488 usb_free_urb(dev->ep4_in_urb);
489 dev->ep4_in_urb = NULL;
490
355 input_unregister_device(dev->input_dev); 491 input_unregister_device(dev->input_dev);
356 dev->input_dev = NULL; 492 dev->input_dev = NULL;
357} 493}