diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-04-13 05:24:34 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-04-13 05:24:34 -0400 |
commit | 067e4a5d23422c9e9a0787b7e18fa2457226d999 (patch) | |
tree | 550ab9dc96efe513b2ffeafbff6662f8caaa68ef | |
parent | 0d0fb0f9c5fddef4a10242fe3337f00f528a3099 (diff) | |
parent | 4cf19b848f92641eeb2585949a09eedec57fb53a (diff) |
Merge branch 'topic/bkl' into topic/core-cleanup
-rw-r--r-- | sound/atmel/Kconfig | 2 | ||||
-rw-r--r-- | sound/atmel/ac97c.c | 355 | ||||
-rw-r--r-- | sound/core/info.c | 4 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 9 | ||||
-rw-r--r-- | sound/core/sound.c | 73 | ||||
-rw-r--r-- | sound/pci/ice1712/aureon.c | 89 | ||||
-rw-r--r-- | sound/ppc/tumbler.c | 12 | ||||
-rw-r--r-- | sound/usb/Kconfig | 1 | ||||
-rw-r--r-- | sound/usb/caiaq/control.c | 99 | ||||
-rw-r--r-- | sound/usb/caiaq/device.c | 8 | ||||
-rw-r--r-- | sound/usb/caiaq/device.h | 24 | ||||
-rw-r--r-- | sound/usb/caiaq/input.c | 162 |
12 files changed, 633 insertions, 205 deletions
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 | ||
36 | enum { | 41 | enum { |
@@ -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, | |||
282 | static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream) | 295 | static 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 | ||
290 | static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream) | 305 | static 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 | |||
449 | atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) | 498 | atmel_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); | ||
479 | out: | 537 | out: |
480 | return retval; | 538 | return retval; |
481 | } | 539 | } |
@@ -484,24 +542,32 @@ static int | |||
484 | atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd) | 542 | atmel_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); | ||
514 | out: | 582 | out: |
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 | ||
732 | static 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 | |||
611 | static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip) | 760 | static 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 | ||
905 | err_dma: | 1075 | err_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 | } | ||
914 | err_ac97_bus: | 1086 | err_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/info.c b/sound/core/info.c index cc4a53d4b7f8..ff968be81678 100644 --- a/sound/core/info.c +++ b/sound/core/info.c | |||
@@ -168,7 +168,7 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig) | |||
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 | switch (entry->content) { |
173 | case SNDRV_INFO_CONTENT_TEXT: | 173 | case SNDRV_INFO_CONTENT_TEXT: |
174 | switch (orig) { | 174 | switch (orig) { |
@@ -197,7 +197,7 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig) | |||
197 | } | 197 | } |
198 | ret = -ENXIO; | 198 | ret = -ENXIO; |
199 | out: | 199 | out: |
200 | unlock_kernel(); | 200 | mutex_unlock(&entry->access); |
201 | return ret; | 201 | return ret; |
202 | } | 202 | } |
203 | 203 | ||
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 872887624030..cadba3087768 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -3303,18 +3303,13 @@ static int snd_pcm_fasync(int fd, struct file * file, int on) | |||
3303 | struct snd_pcm_file * pcm_file; | 3303 | struct snd_pcm_file * pcm_file; |
3304 | struct snd_pcm_substream *substream; | 3304 | struct snd_pcm_substream *substream; |
3305 | struct snd_pcm_runtime *runtime; | 3305 | struct snd_pcm_runtime *runtime; |
3306 | int err = -ENXIO; | ||
3307 | 3306 | ||
3308 | lock_kernel(); | ||
3309 | pcm_file = file->private_data; | 3307 | pcm_file = file->private_data; |
3310 | substream = pcm_file->substream; | 3308 | substream = pcm_file->substream; |
3311 | if (PCM_RUNTIME_CHECK(substream)) | 3309 | if (PCM_RUNTIME_CHECK(substream)) |
3312 | goto out; | 3310 | return -ENXIO; |
3313 | runtime = substream->runtime; | 3311 | runtime = substream->runtime; |
3314 | err = fasync_helper(fd, file, on, &runtime->fasync); | 3312 | return fasync_helper(fd, file, on, &runtime->fasync); |
3315 | out: | ||
3316 | unlock_kernel(); | ||
3317 | return err; | ||
3318 | } | 3313 | } |
3319 | 3314 | ||
3320 | /* | 3315 | /* |
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 | ||
121 | EXPORT_SYMBOL(snd_lookup_minor_data); | 121 | EXPORT_SYMBOL(snd_lookup_minor_data); |
122 | 122 | ||
123 | static int __snd_open(struct inode *inode, struct file *file) | 123 | #ifdef CONFIG_MODULES |
124 | static 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 | |||
145 | static 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 */ | ||
171 | static 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 | |||
181 | static const struct file_operations snd_fops = | 184 | static const struct file_operations snd_fops = |
182 | { | 185 | { |
183 | .owner = THIS_MODULE, | 186 | .owner = THIS_MODULE, |
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 | */ |
1963 | static int __devinit aureon_init(struct snd_ice1712 *ice) | 1962 | static 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 | ||
2107 | static 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 | */ | ||
2127 | static 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/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 | ||
290 | static 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 | |||
276 | static int __devinit add_controls(struct caiaq_controller *c, int num, | 327 | static 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 | ||
52 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ | 53 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ |
53 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ | 54 | static 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 | ||
203 | static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, | 217 | static 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 | ||
252 | static 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 | |||
275 | requeue: | ||
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 | |||
282 | static 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 | |||
299 | static 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 | |||
230 | void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, | 313 | void 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 | |||
477 | exit_free_idev: | ||
478 | input_free_device(input); | ||
479 | return ret; | ||
348 | } | 480 | } |
349 | 481 | ||
350 | void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) | 482 | void 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 | } |