diff options
| -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 | } |
