diff options
Diffstat (limited to 'sound')
62 files changed, 1197 insertions, 643 deletions
diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c index 67893372173..3ff8cc5f487 100644 --- a/sound/aoa/soundbus/i2sbus/core.c +++ b/sound/aoa/soundbus/i2sbus/core.c | |||
@@ -437,9 +437,11 @@ static int i2sbus_shutdown(struct macio_dev* dev) | |||
437 | } | 437 | } |
438 | 438 | ||
439 | static struct macio_driver i2sbus_drv = { | 439 | static struct macio_driver i2sbus_drv = { |
440 | .name = "soundbus-i2s", | 440 | .driver = { |
441 | .owner = THIS_MODULE, | 441 | .name = "soundbus-i2s", |
442 | .match_table = i2sbus_match, | 442 | .owner = THIS_MODULE, |
443 | .of_match_table = i2sbus_match, | ||
444 | }, | ||
443 | .probe = i2sbus_probe, | 445 | .probe = i2sbus_probe, |
444 | .remove = i2sbus_remove, | 446 | .remove = i2sbus_remove, |
445 | #ifdef CONFIG_PM | 447 | #ifdef CONFIG_PM |
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index 428121a7e70..10c3a871a12 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c | |||
@@ -657,7 +657,7 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev) | |||
657 | if (sr & AC97C_SR_CAEVT) { | 657 | if (sr & AC97C_SR_CAEVT) { |
658 | struct snd_pcm_runtime *runtime; | 658 | struct snd_pcm_runtime *runtime; |
659 | int offset, next_period, block_size; | 659 | int offset, next_period, block_size; |
660 | dev_info(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n", | 660 | dev_dbg(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n", |
661 | casr & AC97C_CSR_OVRUN ? " OVRUN" : "", | 661 | casr & AC97C_CSR_OVRUN ? " OVRUN" : "", |
662 | casr & AC97C_CSR_RXRDY ? " RXRDY" : "", | 662 | casr & AC97C_CSR_RXRDY ? " RXRDY" : "", |
663 | casr & AC97C_CSR_UNRUN ? " UNRUN" : "", | 663 | casr & AC97C_CSR_UNRUN ? " UNRUN" : "", |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index a2ff86189d2..e9d98be190c 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -345,7 +345,9 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
345 | new_hw_ptr = hw_base + pos; | 345 | new_hw_ptr = hw_base + pos; |
346 | } | 346 | } |
347 | __delta: | 347 | __delta: |
348 | delta = (new_hw_ptr - old_hw_ptr) % runtime->boundary; | 348 | delta = new_hw_ptr - old_hw_ptr; |
349 | if (delta < 0) | ||
350 | delta += runtime->boundary; | ||
349 | if (xrun_debug(substream, in_interrupt ? | 351 | if (xrun_debug(substream, in_interrupt ? |
350 | XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) { | 352 | XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) { |
351 | char name[16]; | 353 | char name[16]; |
@@ -439,8 +441,13 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
439 | snd_pcm_playback_silence(substream, new_hw_ptr); | 441 | snd_pcm_playback_silence(substream, new_hw_ptr); |
440 | 442 | ||
441 | if (in_interrupt) { | 443 | if (in_interrupt) { |
442 | runtime->hw_ptr_interrupt = new_hw_ptr - | 444 | delta = new_hw_ptr - runtime->hw_ptr_interrupt; |
443 | (new_hw_ptr % runtime->period_size); | 445 | if (delta < 0) |
446 | delta += runtime->boundary; | ||
447 | delta -= (snd_pcm_uframes_t)delta % runtime->period_size; | ||
448 | runtime->hw_ptr_interrupt += delta; | ||
449 | if (runtime->hw_ptr_interrupt >= runtime->boundary) | ||
450 | runtime->hw_ptr_interrupt -= runtime->boundary; | ||
444 | } | 451 | } |
445 | runtime->hw_ptr_base = hw_base; | 452 | runtime->hw_ptr_base = hw_base; |
446 | runtime->status->hw_ptr = new_hw_ptr; | 453 | runtime->status->hw_ptr = new_hw_ptr; |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 644c2bb17b8..a3b2a647924 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/pm_qos_params.h> | 27 | #include <linux/pm_qos_params.h> |
28 | #include <linux/uio.h> | 28 | #include <linux/uio.h> |
29 | #include <linux/dma-mapping.h> | 29 | #include <linux/dma-mapping.h> |
30 | #include <linux/math64.h> | ||
31 | #include <sound/core.h> | 30 | #include <sound/core.h> |
32 | #include <sound/control.h> | 31 | #include <sound/control.h> |
33 | #include <sound/info.h> | 32 | #include <sound/info.h> |
@@ -370,38 +369,6 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime) | |||
370 | return usecs; | 369 | return usecs; |
371 | } | 370 | } |
372 | 371 | ||
373 | static int calc_boundary(struct snd_pcm_runtime *runtime) | ||
374 | { | ||
375 | u_int64_t boundary; | ||
376 | |||
377 | boundary = (u_int64_t)runtime->buffer_size * | ||
378 | (u_int64_t)runtime->period_size; | ||
379 | #if BITS_PER_LONG < 64 | ||
380 | /* try to find lowest common multiple for buffer and period */ | ||
381 | if (boundary > LONG_MAX - runtime->buffer_size) { | ||
382 | u_int32_t remainder = -1; | ||
383 | u_int32_t divident = runtime->buffer_size; | ||
384 | u_int32_t divisor = runtime->period_size; | ||
385 | while (remainder) { | ||
386 | remainder = divident % divisor; | ||
387 | if (remainder) { | ||
388 | divident = divisor; | ||
389 | divisor = remainder; | ||
390 | } | ||
391 | } | ||
392 | boundary = div_u64(boundary, divisor); | ||
393 | if (boundary > LONG_MAX - runtime->buffer_size) | ||
394 | return -ERANGE; | ||
395 | } | ||
396 | #endif | ||
397 | if (boundary == 0) | ||
398 | return -ERANGE; | ||
399 | runtime->boundary = boundary; | ||
400 | while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size) | ||
401 | runtime->boundary *= 2; | ||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static int snd_pcm_hw_params(struct snd_pcm_substream *substream, | 372 | static int snd_pcm_hw_params(struct snd_pcm_substream *substream, |
406 | struct snd_pcm_hw_params *params) | 373 | struct snd_pcm_hw_params *params) |
407 | { | 374 | { |
@@ -477,20 +444,18 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, | |||
477 | runtime->stop_threshold = runtime->buffer_size; | 444 | runtime->stop_threshold = runtime->buffer_size; |
478 | runtime->silence_threshold = 0; | 445 | runtime->silence_threshold = 0; |
479 | runtime->silence_size = 0; | 446 | runtime->silence_size = 0; |
480 | err = calc_boundary(runtime); | 447 | runtime->boundary = runtime->buffer_size; |
481 | if (err < 0) | 448 | while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size) |
482 | goto _error; | 449 | runtime->boundary *= 2; |
483 | 450 | ||
484 | snd_pcm_timer_resolution_change(substream); | 451 | snd_pcm_timer_resolution_change(substream); |
485 | runtime->status->state = SNDRV_PCM_STATE_SETUP; | 452 | runtime->status->state = SNDRV_PCM_STATE_SETUP; |
486 | 453 | ||
487 | if (substream->latency_pm_qos_req) { | 454 | if (pm_qos_request_active(&substream->latency_pm_qos_req)) |
488 | pm_qos_remove_request(substream->latency_pm_qos_req); | 455 | pm_qos_remove_request(&substream->latency_pm_qos_req); |
489 | substream->latency_pm_qos_req = NULL; | ||
490 | } | ||
491 | if ((usecs = period_to_usecs(runtime)) >= 0) | 456 | if ((usecs = period_to_usecs(runtime)) >= 0) |
492 | substream->latency_pm_qos_req = pm_qos_add_request( | 457 | pm_qos_add_request(&substream->latency_pm_qos_req, |
493 | PM_QOS_CPU_DMA_LATENCY, usecs); | 458 | PM_QOS_CPU_DMA_LATENCY, usecs); |
494 | return 0; | 459 | return 0; |
495 | _error: | 460 | _error: |
496 | /* hardware might be unuseable from this time, | 461 | /* hardware might be unuseable from this time, |
@@ -545,8 +510,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) | |||
545 | if (substream->ops->hw_free) | 510 | if (substream->ops->hw_free) |
546 | result = substream->ops->hw_free(substream); | 511 | result = substream->ops->hw_free(substream); |
547 | runtime->status->state = SNDRV_PCM_STATE_OPEN; | 512 | runtime->status->state = SNDRV_PCM_STATE_OPEN; |
548 | pm_qos_remove_request(substream->latency_pm_qos_req); | 513 | pm_qos_remove_request(&substream->latency_pm_qos_req); |
549 | substream->latency_pm_qos_req = NULL; | ||
550 | return result; | 514 | return result; |
551 | } | 515 | } |
552 | 516 | ||
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c index 3e763d6a5d6..446cf974866 100644 --- a/sound/mips/au1x00.c +++ b/sound/mips/au1x00.c | |||
@@ -516,6 +516,7 @@ get the interrupt driven case to work efficiently */ | |||
516 | break; | 516 | break; |
517 | if (i == 0x5000) { | 517 | if (i == 0x5000) { |
518 | printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n"); | 518 | printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n"); |
519 | spin_unlock(&au1000->ac97_lock); | ||
519 | return 0; | 520 | return 0; |
520 | } | 521 | } |
521 | 522 | ||
diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c index 1f477412306..13c214466d3 100644 --- a/sound/oss/dmasound/dmasound_atari.c +++ b/sound/oss/dmasound/dmasound_atari.c | |||
@@ -1277,7 +1277,7 @@ static irqreturn_t AtaInterrupt(int irq, void *dummy) | |||
1277 | * (almost) like on the TT. | 1277 | * (almost) like on the TT. |
1278 | */ | 1278 | */ |
1279 | write_sq_ignore_int = 0; | 1279 | write_sq_ignore_int = 0; |
1280 | return IRQ_HANDLED; | 1280 | goto out; |
1281 | } | 1281 | } |
1282 | 1282 | ||
1283 | if (!write_sq.active) { | 1283 | if (!write_sq.active) { |
@@ -1285,7 +1285,7 @@ static irqreturn_t AtaInterrupt(int irq, void *dummy) | |||
1285 | * the sq variables, so better don't do anything here. | 1285 | * the sq variables, so better don't do anything here. |
1286 | */ | 1286 | */ |
1287 | WAKE_UP(write_sq.sync_queue); | 1287 | WAKE_UP(write_sq.sync_queue); |
1288 | return IRQ_HANDLED; | 1288 | goto out; |
1289 | } | 1289 | } |
1290 | 1290 | ||
1291 | /* Probably ;) one frame is finished. Well, in fact it may be that a | 1291 | /* Probably ;) one frame is finished. Well, in fact it may be that a |
@@ -1322,6 +1322,7 @@ static irqreturn_t AtaInterrupt(int irq, void *dummy) | |||
1322 | /* We are not playing after AtaPlay(), so there | 1322 | /* We are not playing after AtaPlay(), so there |
1323 | is nothing to play any more. Wake up a process | 1323 | is nothing to play any more. Wake up a process |
1324 | waiting for audio output to drain. */ | 1324 | waiting for audio output to drain. */ |
1325 | out: | ||
1325 | spin_unlock(&dmasound.lock); | 1326 | spin_unlock(&dmasound.lock); |
1326 | return IRQ_HANDLED; | 1327 | return IRQ_HANDLED; |
1327 | } | 1328 | } |
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index f74c7372b3d..1db586af4f9 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c | |||
@@ -2578,6 +2578,9 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) | |||
2578 | if (err) | 2578 | if (err) |
2579 | return -err; | 2579 | return -err; |
2580 | 2580 | ||
2581 | memset(&prev_ctl, 0, sizeof(prev_ctl)); | ||
2582 | prev_ctl.control_type = -1; | ||
2583 | |||
2581 | for (idx = 0; idx < 2000; idx++) { | 2584 | for (idx = 0; idx < 2000; idx++) { |
2582 | err = hpi_mixer_get_control_by_index( | 2585 | err = hpi_mixer_get_control_by_index( |
2583 | ss, asihpi->h_mixer, | 2586 | ss, asihpi->h_mixer, |
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h index 99400de6c07..0173bbe62b6 100644 --- a/sound/pci/asihpi/hpi.h +++ b/sound/pci/asihpi/hpi.h | |||
@@ -50,7 +50,7 @@ i.e 3.05.02 is a development version | |||
50 | #define HPI_VER_RELEASE(v) ((int)(v & 0xFF)) | 50 | #define HPI_VER_RELEASE(v) ((int)(v & 0xFF)) |
51 | 51 | ||
52 | /* Use single digits for versions less that 10 to avoid octal. */ | 52 | /* Use single digits for versions less that 10 to avoid octal. */ |
53 | #define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 3, 18) | 53 | #define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 3, 25) |
54 | 54 | ||
55 | /* Library version as documented in hpi-api-versions.txt */ | 55 | /* Library version as documented in hpi-api-versions.txt */ |
56 | #define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0) | 56 | #define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0) |
@@ -1632,6 +1632,12 @@ u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys, | |||
1632 | u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys, | 1632 | u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys, |
1633 | u32 h_control, u32 *pquality); | 1633 | u32 h_control, u32 *pquality); |
1634 | 1634 | ||
1635 | u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, | ||
1636 | u32 h_control, u32 *pblend); | ||
1637 | |||
1638 | u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, | ||
1639 | u32 h_control, const u32 blend); | ||
1640 | |||
1635 | /****************************/ | 1641 | /****************************/ |
1636 | /* PADs control */ | 1642 | /* PADs control */ |
1637 | /****************************/ | 1643 | /****************************/ |
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index 839ecb2e4b6..12dab5e4892 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c | |||
@@ -691,9 +691,6 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
691 | case 0x6200: | 691 | case 0x6200: |
692 | boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); | 692 | boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); |
693 | break; | 693 | break; |
694 | case 0x8800: | ||
695 | boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x8800); | ||
696 | break; | ||
697 | default: | 694 | default: |
698 | return HPI6000_ERROR_UNHANDLED_SUBSYS_ID; | 695 | return HPI6000_ERROR_UNHANDLED_SUBSYS_ID; |
699 | } | 696 | } |
@@ -1775,7 +1772,6 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, | |||
1775 | u16 error = 0; | 1772 | u16 error = 0; |
1776 | u16 dsp_index = 0; | 1773 | u16 dsp_index = 0; |
1777 | u16 num_dsp = ((struct hpi_hw_obj *)pao->priv)->num_dsp; | 1774 | u16 num_dsp = ((struct hpi_hw_obj *)pao->priv)->num_dsp; |
1778 | hpios_dsplock_lock(pao); | ||
1779 | 1775 | ||
1780 | if (num_dsp < 2) | 1776 | if (num_dsp < 2) |
1781 | dsp_index = 0; | 1777 | dsp_index = 0; |
@@ -1796,6 +1792,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, | |||
1796 | } | 1792 | } |
1797 | } | 1793 | } |
1798 | } | 1794 | } |
1795 | |||
1796 | hpios_dsplock_lock(pao); | ||
1799 | error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr); | 1797 | error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr); |
1800 | 1798 | ||
1801 | /* maybe an error response */ | 1799 | /* maybe an error response */ |
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 5e88c1fc2b9..3b441344822 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c | |||
@@ -941,11 +941,11 @@ static void outstream_host_buffer_free(struct hpi_adapter_obj *pao, | |||
941 | 941 | ||
942 | } | 942 | } |
943 | 943 | ||
944 | static long outstream_get_space_available(struct hpi_hostbuffer_status | 944 | static u32 outstream_get_space_available(struct hpi_hostbuffer_status |
945 | *status) | 945 | *status) |
946 | { | 946 | { |
947 | return status->size_in_bytes - ((long)(status->host_index) - | 947 | return status->size_in_bytes - (status->host_index - |
948 | (long)(status->dSP_index)); | 948 | status->dSP_index); |
949 | } | 949 | } |
950 | 950 | ||
951 | static void outstream_write(struct hpi_adapter_obj *pao, | 951 | static void outstream_write(struct hpi_adapter_obj *pao, |
@@ -954,7 +954,7 @@ static void outstream_write(struct hpi_adapter_obj *pao, | |||
954 | struct hpi_hw_obj *phw = pao->priv; | 954 | struct hpi_hw_obj *phw = pao->priv; |
955 | struct bus_master_interface *interface = phw->p_interface_buffer; | 955 | struct bus_master_interface *interface = phw->p_interface_buffer; |
956 | struct hpi_hostbuffer_status *status; | 956 | struct hpi_hostbuffer_status *status; |
957 | long space_available; | 957 | u32 space_available; |
958 | 958 | ||
959 | if (!phw->outstream_host_buffer_size[phm->obj_index]) { | 959 | if (!phw->outstream_host_buffer_size[phm->obj_index]) { |
960 | /* there is no BBM buffer, write via message */ | 960 | /* there is no BBM buffer, write via message */ |
@@ -966,23 +966,16 @@ static void outstream_write(struct hpi_adapter_obj *pao, | |||
966 | status = &interface->outstream_host_buffer_status[phm->obj_index]; | 966 | status = &interface->outstream_host_buffer_status[phm->obj_index]; |
967 | 967 | ||
968 | if (phw->flag_outstream_just_reset[phm->obj_index]) { | 968 | if (phw->flag_outstream_just_reset[phm->obj_index]) { |
969 | /* Format can only change after reset. Must tell DSP. */ | ||
970 | u16 function = phm->function; | ||
971 | phw->flag_outstream_just_reset[phm->obj_index] = 0; | ||
972 | phm->function = HPI_OSTREAM_SET_FORMAT; | ||
973 | hw_message(pao, phm, phr); /* send the format to the DSP */ | ||
974 | phm->function = function; | ||
975 | if (phr->error) | ||
976 | return; | ||
977 | } | ||
978 | #if 1 | ||
979 | if (phw->flag_outstream_just_reset[phm->obj_index]) { | ||
980 | /* First OutStremWrite() call following reset will write data to the | 969 | /* First OutStremWrite() call following reset will write data to the |
981 | adapter's buffers, reducing delay before stream can start | 970 | adapter's buffers, reducing delay before stream can start. The DSP |
971 | takes care of setting the stream data format using format information | ||
972 | embedded in phm. | ||
982 | */ | 973 | */ |
983 | int partial_write = 0; | 974 | int partial_write = 0; |
984 | unsigned int original_size = 0; | 975 | unsigned int original_size = 0; |
985 | 976 | ||
977 | phw->flag_outstream_just_reset[phm->obj_index] = 0; | ||
978 | |||
986 | /* Send the first buffer to the DSP the old way. */ | 979 | /* Send the first buffer to the DSP the old way. */ |
987 | /* Limit size of first transfer - */ | 980 | /* Limit size of first transfer - */ |
988 | /* expect that this will not usually be triggered. */ | 981 | /* expect that this will not usually be triggered. */ |
@@ -1012,10 +1005,9 @@ static void outstream_write(struct hpi_adapter_obj *pao, | |||
1012 | original_size - HPI6205_SIZEOF_DATA; | 1005 | original_size - HPI6205_SIZEOF_DATA; |
1013 | phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA; | 1006 | phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA; |
1014 | } | 1007 | } |
1015 | #endif | ||
1016 | 1008 | ||
1017 | space_available = outstream_get_space_available(status); | 1009 | space_available = outstream_get_space_available(status); |
1018 | if (space_available < (long)phm->u.d.u.data.data_size) { | 1010 | if (space_available < phm->u.d.u.data.data_size) { |
1019 | phr->error = HPI_ERROR_INVALID_DATASIZE; | 1011 | phr->error = HPI_ERROR_INVALID_DATASIZE; |
1020 | return; | 1012 | return; |
1021 | } | 1013 | } |
@@ -1026,7 +1018,7 @@ static void outstream_write(struct hpi_adapter_obj *pao, | |||
1026 | && hpios_locked_mem_valid(&phw->outstream_host_buffers[phm-> | 1018 | && hpios_locked_mem_valid(&phw->outstream_host_buffers[phm-> |
1027 | obj_index])) { | 1019 | obj_index])) { |
1028 | u8 *p_bbm_data; | 1020 | u8 *p_bbm_data; |
1029 | long l_first_write; | 1021 | u32 l_first_write; |
1030 | u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data; | 1022 | u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data; |
1031 | 1023 | ||
1032 | if (hpios_locked_mem_get_virt_addr(&phw-> | 1024 | if (hpios_locked_mem_get_virt_addr(&phw-> |
@@ -1256,9 +1248,9 @@ static void instream_start(struct hpi_adapter_obj *pao, | |||
1256 | hw_message(pao, phm, phr); | 1248 | hw_message(pao, phm, phr); |
1257 | } | 1249 | } |
1258 | 1250 | ||
1259 | static long instream_get_bytes_available(struct hpi_hostbuffer_status *status) | 1251 | static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status) |
1260 | { | 1252 | { |
1261 | return (long)(status->dSP_index) - (long)(status->host_index); | 1253 | return status->dSP_index - status->host_index; |
1262 | } | 1254 | } |
1263 | 1255 | ||
1264 | static void instream_read(struct hpi_adapter_obj *pao, | 1256 | static void instream_read(struct hpi_adapter_obj *pao, |
@@ -1267,9 +1259,9 @@ static void instream_read(struct hpi_adapter_obj *pao, | |||
1267 | struct hpi_hw_obj *phw = pao->priv; | 1259 | struct hpi_hw_obj *phw = pao->priv; |
1268 | struct bus_master_interface *interface = phw->p_interface_buffer; | 1260 | struct bus_master_interface *interface = phw->p_interface_buffer; |
1269 | struct hpi_hostbuffer_status *status; | 1261 | struct hpi_hostbuffer_status *status; |
1270 | long data_available; | 1262 | u32 data_available; |
1271 | u8 *p_bbm_data; | 1263 | u8 *p_bbm_data; |
1272 | long l_first_read; | 1264 | u32 l_first_read; |
1273 | u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data; | 1265 | u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data; |
1274 | 1266 | ||
1275 | if (!phw->instream_host_buffer_size[phm->obj_index]) { | 1267 | if (!phw->instream_host_buffer_size[phm->obj_index]) { |
@@ -1280,7 +1272,7 @@ static void instream_read(struct hpi_adapter_obj *pao, | |||
1280 | 1272 | ||
1281 | status = &interface->instream_host_buffer_status[phm->obj_index]; | 1273 | status = &interface->instream_host_buffer_status[phm->obj_index]; |
1282 | data_available = instream_get_bytes_available(status); | 1274 | data_available = instream_get_bytes_available(status); |
1283 | if (data_available < (long)phm->u.d.u.data.data_size) { | 1275 | if (data_available < phm->u.d.u.data.data_size) { |
1284 | phr->error = HPI_ERROR_INVALID_DATASIZE; | 1276 | phr->error = HPI_ERROR_INVALID_DATASIZE; |
1285 | return; | 1277 | return; |
1286 | } | 1278 | } |
@@ -1369,6 +1361,9 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1369 | case HPI_ADAPTER_FAMILY_ASI(0x6500): | 1361 | case HPI_ADAPTER_FAMILY_ASI(0x6500): |
1370 | firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600); | 1362 | firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600); |
1371 | break; | 1363 | break; |
1364 | case HPI_ADAPTER_FAMILY_ASI(0x8800): | ||
1365 | firmware_id = HPI_ADAPTER_FAMILY_ASI(0x8900); | ||
1366 | break; | ||
1372 | } | 1367 | } |
1373 | boot_code_id[1] = firmware_id; | 1368 | boot_code_id[1] = firmware_id; |
1374 | 1369 | ||
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h index f1cd6f1a0d4..fdd0ce02aa6 100644 --- a/sound/pci/asihpi/hpi_internal.h +++ b/sound/pci/asihpi/hpi_internal.h | |||
@@ -232,6 +232,8 @@ enum HPI_BUSES { | |||
232 | #define HPI_TUNER_HDRADIO_SDK_VERSION HPI_CTL_ATTR(TUNER, 13) | 232 | #define HPI_TUNER_HDRADIO_SDK_VERSION HPI_CTL_ATTR(TUNER, 13) |
233 | /** HD Radio DSP firmware version. */ | 233 | /** HD Radio DSP firmware version. */ |
234 | #define HPI_TUNER_HDRADIO_DSP_VERSION HPI_CTL_ATTR(TUNER, 14) | 234 | #define HPI_TUNER_HDRADIO_DSP_VERSION HPI_CTL_ATTR(TUNER, 14) |
235 | /** HD Radio signal blend (force analog, or automatic). */ | ||
236 | #define HPI_TUNER_HDRADIO_BLEND HPI_CTL_ATTR(TUNER, 15) | ||
235 | 237 | ||
236 | /** \} */ | 238 | /** \} */ |
237 | 239 | ||
@@ -478,8 +480,10 @@ Threshold is a -ve number in units of dB/100, | |||
478 | 480 | ||
479 | /** First 2 hex digits define the adapter family */ | 481 | /** First 2 hex digits define the adapter family */ |
480 | #define HPI_ADAPTER_FAMILY_MASK 0xff00 | 482 | #define HPI_ADAPTER_FAMILY_MASK 0xff00 |
483 | #define HPI_MODULE_FAMILY_MASK 0xfff0 | ||
481 | 484 | ||
482 | #define HPI_ADAPTER_FAMILY_ASI(f) (f & HPI_ADAPTER_FAMILY_MASK) | 485 | #define HPI_ADAPTER_FAMILY_ASI(f) (f & HPI_ADAPTER_FAMILY_MASK) |
486 | #define HPI_MODULE_FAMILY_ASI(f) (f & HPI_MODULE_FAMILY_MASK) | ||
483 | #define HPI_ADAPTER_ASI(f) (f) | 487 | #define HPI_ADAPTER_ASI(f) (f) |
484 | 488 | ||
485 | /******************************************* message types */ | 489 | /******************************************* message types */ |
@@ -970,6 +974,7 @@ struct hpi_control_union_msg { | |||
970 | u32 mode; | 974 | u32 mode; |
971 | u32 value; | 975 | u32 value; |
972 | } mode; | 976 | } mode; |
977 | u32 blend; | ||
973 | } tuner; | 978 | } tuner; |
974 | } u; | 979 | } u; |
975 | }; | 980 | }; |
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index 565102cae4f..fcd64539d9e 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c | |||
@@ -347,20 +347,15 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, | |||
347 | found = 0; | 347 | found = 0; |
348 | break; | 348 | break; |
349 | case HPI_CONTROL_TUNER: | 349 | case HPI_CONTROL_TUNER: |
350 | { | 350 | if (phm->u.c.attribute == HPI_TUNER_FREQ) |
351 | struct hpi_control_cache_single *pCT = | 351 | phr->u.c.param1 = pC->u.t.freq_ink_hz; |
352 | (struct hpi_control_cache_single *)pI; | 352 | else if (phm->u.c.attribute == HPI_TUNER_BAND) |
353 | if (phm->u.c.attribute == HPI_TUNER_FREQ) | 353 | phr->u.c.param1 = pC->u.t.band; |
354 | phr->u.c.param1 = pCT->u.t.freq_ink_hz; | 354 | else if ((phm->u.c.attribute == HPI_TUNER_LEVEL) |
355 | else if (phm->u.c.attribute == HPI_TUNER_BAND) | 355 | && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE)) |
356 | phr->u.c.param1 = pCT->u.t.band; | 356 | phr->u.c.param1 = pC->u.t.level; |
357 | else if ((phm->u.c.attribute == HPI_TUNER_LEVEL) | 357 | else |
358 | && (phm->u.c.param1 == | 358 | found = 0; |
359 | HPI_TUNER_LEVEL_AVERAGE)) | ||
360 | phr->u.c.param1 = pCT->u.t.level; | ||
361 | else | ||
362 | found = 0; | ||
363 | } | ||
364 | break; | 359 | break; |
365 | case HPI_CONTROL_AESEBU_RECEIVER: | 360 | case HPI_CONTROL_AESEBU_RECEIVER: |
366 | if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS) | 361 | if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS) |
@@ -503,6 +498,9 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache, | |||
503 | struct hpi_control_cache_single *pC; | 498 | struct hpi_control_cache_single *pC; |
504 | struct hpi_control_cache_info *pI; | 499 | struct hpi_control_cache_info *pI; |
505 | 500 | ||
501 | if (phr->error) | ||
502 | return; | ||
503 | |||
506 | if (!find_control(phm, p_cache, &pI, &control_index)) | 504 | if (!find_control(phm, p_cache, &pI, &control_index)) |
507 | return; | 505 | return; |
508 | 506 | ||
@@ -520,8 +518,6 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache, | |||
520 | break; | 518 | break; |
521 | case HPI_CONTROL_MULTIPLEXER: | 519 | case HPI_CONTROL_MULTIPLEXER: |
522 | /* mux does not return its setting on Set command. */ | 520 | /* mux does not return its setting on Set command. */ |
523 | if (phr->error) | ||
524 | return; | ||
525 | if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { | 521 | if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { |
526 | pC->u.x.source_node_type = (u16)phm->u.c.param1; | 522 | pC->u.x.source_node_type = (u16)phm->u.c.param1; |
527 | pC->u.x.source_node_index = (u16)phm->u.c.param2; | 523 | pC->u.x.source_node_index = (u16)phm->u.c.param2; |
@@ -529,8 +525,6 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache, | |||
529 | break; | 525 | break; |
530 | case HPI_CONTROL_CHANNEL_MODE: | 526 | case HPI_CONTROL_CHANNEL_MODE: |
531 | /* mode does not return its setting on Set command. */ | 527 | /* mode does not return its setting on Set command. */ |
532 | if (phr->error) | ||
533 | return; | ||
534 | if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) | 528 | if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) |
535 | pC->u.m.mode = (u16)phm->u.c.param1; | 529 | pC->u.m.mode = (u16)phm->u.c.param1; |
536 | break; | 530 | break; |
@@ -545,20 +539,14 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache, | |||
545 | pC->u.phantom_power.state = (u16)phm->u.c.param1; | 539 | pC->u.phantom_power.state = (u16)phm->u.c.param1; |
546 | break; | 540 | break; |
547 | case HPI_CONTROL_AESEBU_TRANSMITTER: | 541 | case HPI_CONTROL_AESEBU_TRANSMITTER: |
548 | if (phr->error) | ||
549 | return; | ||
550 | if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT) | 542 | if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT) |
551 | pC->u.aes3tx.format = phm->u.c.param1; | 543 | pC->u.aes3tx.format = phm->u.c.param1; |
552 | break; | 544 | break; |
553 | case HPI_CONTROL_AESEBU_RECEIVER: | 545 | case HPI_CONTROL_AESEBU_RECEIVER: |
554 | if (phr->error) | ||
555 | return; | ||
556 | if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) | 546 | if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) |
557 | pC->u.aes3rx.source = phm->u.c.param1; | 547 | pC->u.aes3rx.source = phm->u.c.param1; |
558 | break; | 548 | break; |
559 | case HPI_CONTROL_SAMPLECLOCK: | 549 | case HPI_CONTROL_SAMPLECLOCK: |
560 | if (phr->error) | ||
561 | return; | ||
562 | if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE) | 550 | if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE) |
563 | pC->u.clk.source = (u16)phm->u.c.param1; | 551 | pC->u.clk.source = (u16)phm->u.c.param1; |
564 | else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) | 552 | else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) |
@@ -590,7 +578,7 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 | |||
590 | 578 | ||
591 | void hpi_free_control_cache(struct hpi_control_cache *p_cache) | 579 | void hpi_free_control_cache(struct hpi_control_cache *p_cache) |
592 | { | 580 | { |
593 | if ((p_cache->init) && (p_cache->p_info)) { | 581 | if (p_cache->init) { |
594 | kfree(p_cache->p_info); | 582 | kfree(p_cache->p_info); |
595 | p_cache->p_info = NULL; | 583 | p_cache->p_info = NULL; |
596 | p_cache->init = 0; | 584 | p_cache->init = 0; |
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c index eda26b31232..298eef3e20e 100644 --- a/sound/pci/asihpi/hpifunc.c +++ b/sound/pci/asihpi/hpifunc.c | |||
@@ -2946,6 +2946,20 @@ u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys, | |||
2946 | HPI_TUNER_HDRADIO_SIGNAL_QUALITY, 0, 0, pquality, NULL); | 2946 | HPI_TUNER_HDRADIO_SIGNAL_QUALITY, 0, 0, pquality, NULL); |
2947 | } | 2947 | } |
2948 | 2948 | ||
2949 | u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, | ||
2950 | u32 h_control, u32 *pblend) | ||
2951 | { | ||
2952 | return hpi_control_param_get(ph_subsys, h_control, | ||
2953 | HPI_TUNER_HDRADIO_BLEND, 0, 0, pblend, NULL); | ||
2954 | } | ||
2955 | |||
2956 | u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, | ||
2957 | u32 h_control, const u32 blend) | ||
2958 | { | ||
2959 | return hpi_control_param_set(ph_subsys, h_control, | ||
2960 | HPI_TUNER_HDRADIO_BLEND, blend, 0); | ||
2961 | } | ||
2962 | |||
2949 | u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control, | 2963 | u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control, |
2950 | char *p_data) | 2964 | char *p_data) |
2951 | { | 2965 | { |
@@ -3266,8 +3280,7 @@ u16 hpi_entity_find_next(struct hpi_entity *container_entity, | |||
3266 | 3280 | ||
3267 | void hpi_entity_free(struct hpi_entity *entity) | 3281 | void hpi_entity_free(struct hpi_entity *entity) |
3268 | { | 3282 | { |
3269 | if (entity != NULL) | 3283 | kfree(entity); |
3270 | kfree(entity); | ||
3271 | } | 3284 | } |
3272 | 3285 | ||
3273 | static u16 hpi_entity_alloc_and_copy(struct hpi_entity *src, | 3286 | static u16 hpi_entity_alloc_and_copy(struct hpi_entity *src, |
diff --git a/sound/pci/asihpi/hpios.c b/sound/pci/asihpi/hpios.c index de615cfdb95..742ee12a9e1 100644 --- a/sound/pci/asihpi/hpios.c +++ b/sound/pci/asihpi/hpios.c | |||
@@ -89,26 +89,3 @@ u16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area) | |||
89 | void hpios_locked_mem_free_all(void) | 89 | void hpios_locked_mem_free_all(void) |
90 | { | 90 | { |
91 | } | 91 | } |
92 | |||
93 | void __iomem *hpios_map_io(struct pci_dev *pci_dev, int idx, | ||
94 | unsigned int length) | ||
95 | { | ||
96 | HPI_DEBUG_LOG(DEBUG, "mapping %d %s %08llx-%08llx %04llx len 0x%x\n", | ||
97 | idx, pci_dev->resource[idx].name, | ||
98 | (unsigned long long)pci_resource_start(pci_dev, idx), | ||
99 | (unsigned long long)pci_resource_end(pci_dev, idx), | ||
100 | (unsigned long long)pci_resource_flags(pci_dev, idx), length); | ||
101 | |||
102 | if (!(pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM)) { | ||
103 | HPI_DEBUG_LOG(ERROR, "not an io memory resource\n"); | ||
104 | return NULL; | ||
105 | } | ||
106 | |||
107 | if (length > pci_resource_len(pci_dev, idx)) { | ||
108 | HPI_DEBUG_LOG(ERROR, "resource too small for requested %d \n", | ||
109 | length); | ||
110 | return NULL; | ||
111 | } | ||
112 | |||
113 | return ioremap(pci_resource_start(pci_dev, idx), length); | ||
114 | } | ||
diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h index a62c3f1e5f0..370f39b43f8 100644 --- a/sound/pci/asihpi/hpios.h +++ b/sound/pci/asihpi/hpios.h | |||
@@ -166,13 +166,4 @@ struct hpi_adapter { | |||
166 | void __iomem *ap_remapped_mem_base[HPI_MAX_ADAPTER_MEM_SPACES]; | 166 | void __iomem *ap_remapped_mem_base[HPI_MAX_ADAPTER_MEM_SPACES]; |
167 | }; | 167 | }; |
168 | 168 | ||
169 | static inline void hpios_unmap_io(void __iomem *addr, | ||
170 | unsigned long size) | ||
171 | { | ||
172 | iounmap(addr); | ||
173 | } | ||
174 | |||
175 | void __iomem *hpios_map_io(struct pci_dev *pci_dev, int idx, | ||
176 | unsigned int length); | ||
177 | |||
178 | #endif | 169 | #endif |
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 67921f93a41..c15002242d9 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <asm/io.h> | 29 | #include <linux/io.h> |
30 | #include <sound/core.h> | 30 | #include <sound/core.h> |
31 | #include <sound/initval.h> | 31 | #include <sound/initval.h> |
32 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
@@ -44,9 +44,6 @@ MODULE_LICENSE("GPL"); | |||
44 | /********************************* | 44 | /********************************* |
45 | * DEFINES | 45 | * DEFINES |
46 | ********************************/ | 46 | ********************************/ |
47 | #define PCI_VENDOR_ID_SAA7146 0x1131 | ||
48 | #define PCI_DEVICE_ID_SAA7146 0x7146 | ||
49 | |||
50 | #define CTL_ROUTE_ANALOG 0 | 47 | #define CTL_ROUTE_ANALOG 0 |
51 | #define CTL_ROUTE_DIGITAL 1 | 48 | #define CTL_ROUTE_DIGITAL 1 |
52 | 49 | ||
@@ -165,7 +162,7 @@ module_param_array(enable, bool, NULL, 0444); | |||
165 | MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard."); | 162 | MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard."); |
166 | 163 | ||
167 | static DEFINE_PCI_DEVICE_TABLE(snd_aw2_ids) = { | 164 | static DEFINE_PCI_DEVICE_TABLE(snd_aw2_ids) = { |
168 | {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0, | 165 | {PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0, 0, |
169 | 0, 0, 0}, | 166 | 0, 0, 0}, |
170 | {0} | 167 | {0} |
171 | }; | 168 | }; |
@@ -419,7 +416,7 @@ static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream) | |||
419 | { | 416 | { |
420 | struct snd_pcm_runtime *runtime = substream->runtime; | 417 | struct snd_pcm_runtime *runtime = substream->runtime; |
421 | 418 | ||
422 | snd_printdd(KERN_DEBUG "aw2: Playback_open \n"); | 419 | snd_printdd(KERN_DEBUG "aw2: Playback_open\n"); |
423 | runtime->hw = snd_aw2_playback_hw; | 420 | runtime->hw = snd_aw2_playback_hw; |
424 | return 0; | 421 | return 0; |
425 | } | 422 | } |
@@ -435,7 +432,7 @@ static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream) | |||
435 | { | 432 | { |
436 | struct snd_pcm_runtime *runtime = substream->runtime; | 433 | struct snd_pcm_runtime *runtime = substream->runtime; |
437 | 434 | ||
438 | snd_printdd(KERN_DEBUG "aw2: Capture_open \n"); | 435 | snd_printdd(KERN_DEBUG "aw2: Capture_open\n"); |
439 | runtime->hw = snd_aw2_capture_hw; | 436 | runtime->hw = snd_aw2_capture_hw; |
440 | return 0; | 437 | return 0; |
441 | } | 438 | } |
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 4b302d86f5f..7a9401462c1 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/vmalloc.h> | 35 | #include <linux/vmalloc.h> |
36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
37 | #include <linux/mutex.h> | 37 | #include <linux/mutex.h> |
38 | #include <linux/moduleparam.h> | ||
38 | 39 | ||
39 | #include <sound/core.h> | 40 | #include <sound/core.h> |
40 | #include <sound/tlv.h> | 41 | #include <sound/tlv.h> |
@@ -50,6 +51,10 @@ | |||
50 | #define EMU10K1_CENTER_LFE_FROM_FRONT | 51 | #define EMU10K1_CENTER_LFE_FROM_FRONT |
51 | #endif | 52 | #endif |
52 | 53 | ||
54 | static bool high_res_gpr_volume; | ||
55 | module_param(high_res_gpr_volume, bool, 0444); | ||
56 | MODULE_PARM_DESC(high_res_gpr_volume, "GPR mixer controls use 31-bit range."); | ||
57 | |||
53 | /* | 58 | /* |
54 | * Tables | 59 | * Tables |
55 | */ | 60 | */ |
@@ -296,6 +301,7 @@ static const u32 db_table[101] = { | |||
296 | 301 | ||
297 | /* EMU10k1/EMU10k2 DSP control db gain */ | 302 | /* EMU10k1/EMU10k2 DSP control db gain */ |
298 | static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); | 303 | static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); |
304 | static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0); | ||
299 | 305 | ||
300 | static const u32 onoff_table[2] = { | 306 | static const u32 onoff_table[2] = { |
301 | 0x00000000, 0x00000001 | 307 | 0x00000000, 0x00000001 |
@@ -1072,10 +1078,17 @@ snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl, | |||
1072 | strcpy(ctl->id.name, name); | 1078 | strcpy(ctl->id.name, name); |
1073 | ctl->vcount = ctl->count = 1; | 1079 | ctl->vcount = ctl->count = 1; |
1074 | ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; | 1080 | ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; |
1075 | ctl->min = 0; | 1081 | if (high_res_gpr_volume) { |
1076 | ctl->max = 100; | 1082 | ctl->min = 0; |
1077 | ctl->tlv = snd_emu10k1_db_scale1; | 1083 | ctl->max = 0x7fffffff; |
1078 | ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; | 1084 | ctl->tlv = snd_emu10k1_db_linear; |
1085 | ctl->translation = EMU10K1_GPR_TRANSLATION_NONE; | ||
1086 | } else { | ||
1087 | ctl->min = 0; | ||
1088 | ctl->max = 100; | ||
1089 | ctl->tlv = snd_emu10k1_db_scale1; | ||
1090 | ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; | ||
1091 | } | ||
1079 | } | 1092 | } |
1080 | 1093 | ||
1081 | static void __devinit | 1094 | static void __devinit |
@@ -1087,10 +1100,17 @@ snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl, | |||
1087 | ctl->vcount = ctl->count = 2; | 1100 | ctl->vcount = ctl->count = 2; |
1088 | ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; | 1101 | ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; |
1089 | ctl->gpr[1] = gpr + 1; ctl->value[1] = defval; | 1102 | ctl->gpr[1] = gpr + 1; ctl->value[1] = defval; |
1090 | ctl->min = 0; | 1103 | if (high_res_gpr_volume) { |
1091 | ctl->max = 100; | 1104 | ctl->min = 0; |
1092 | ctl->tlv = snd_emu10k1_db_scale1; | 1105 | ctl->max = 0x7fffffff; |
1093 | ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; | 1106 | ctl->tlv = snd_emu10k1_db_linear; |
1107 | ctl->translation = EMU10K1_GPR_TRANSLATION_NONE; | ||
1108 | } else { | ||
1109 | ctl->min = 0; | ||
1110 | ctl->max = 100; | ||
1111 | ctl->tlv = snd_emu10k1_db_scale1; | ||
1112 | ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; | ||
1113 | } | ||
1094 | } | 1114 | } |
1095 | 1115 | ||
1096 | static void __devinit | 1116 | static void __devinit |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index a3d638c8c1f..ba2098d20cc 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -784,6 +784,9 @@ static int read_pin_defaults(struct hda_codec *codec) | |||
784 | pin->nid = nid; | 784 | pin->nid = nid; |
785 | pin->cfg = snd_hda_codec_read(codec, nid, 0, | 785 | pin->cfg = snd_hda_codec_read(codec, nid, 0, |
786 | AC_VERB_GET_CONFIG_DEFAULT, 0); | 786 | AC_VERB_GET_CONFIG_DEFAULT, 0); |
787 | pin->ctrl = snd_hda_codec_read(codec, nid, 0, | ||
788 | AC_VERB_GET_PIN_WIDGET_CONTROL, | ||
789 | 0); | ||
787 | } | 790 | } |
788 | return 0; | 791 | return 0; |
789 | } | 792 | } |
@@ -912,15 +915,38 @@ static void restore_pincfgs(struct hda_codec *codec) | |||
912 | void snd_hda_shutup_pins(struct hda_codec *codec) | 915 | void snd_hda_shutup_pins(struct hda_codec *codec) |
913 | { | 916 | { |
914 | int i; | 917 | int i; |
918 | /* don't shut up pins when unloading the driver; otherwise it breaks | ||
919 | * the default pin setup at the next load of the driver | ||
920 | */ | ||
921 | if (codec->bus->shutdown) | ||
922 | return; | ||
915 | for (i = 0; i < codec->init_pins.used; i++) { | 923 | for (i = 0; i < codec->init_pins.used; i++) { |
916 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); | 924 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); |
917 | /* use read here for syncing after issuing each verb */ | 925 | /* use read here for syncing after issuing each verb */ |
918 | snd_hda_codec_read(codec, pin->nid, 0, | 926 | snd_hda_codec_read(codec, pin->nid, 0, |
919 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | 927 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); |
920 | } | 928 | } |
929 | codec->pins_shutup = 1; | ||
921 | } | 930 | } |
922 | EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); | 931 | EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); |
923 | 932 | ||
933 | /* Restore the pin controls cleared previously via snd_hda_shutup_pins() */ | ||
934 | static void restore_shutup_pins(struct hda_codec *codec) | ||
935 | { | ||
936 | int i; | ||
937 | if (!codec->pins_shutup) | ||
938 | return; | ||
939 | if (codec->bus->shutdown) | ||
940 | return; | ||
941 | for (i = 0; i < codec->init_pins.used; i++) { | ||
942 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); | ||
943 | snd_hda_codec_write(codec, pin->nid, 0, | ||
944 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
945 | pin->ctrl); | ||
946 | } | ||
947 | codec->pins_shutup = 0; | ||
948 | } | ||
949 | |||
924 | static void init_hda_cache(struct hda_cache_rec *cache, | 950 | static void init_hda_cache(struct hda_cache_rec *cache, |
925 | unsigned int record_size); | 951 | unsigned int record_size); |
926 | static void free_hda_cache(struct hda_cache_rec *cache); | 952 | static void free_hda_cache(struct hda_cache_rec *cache); |
@@ -2907,6 +2933,7 @@ static void hda_call_codec_resume(struct hda_codec *codec) | |||
2907 | codec->afg ? codec->afg : codec->mfg, | 2933 | codec->afg ? codec->afg : codec->mfg, |
2908 | AC_PWRST_D0); | 2934 | AC_PWRST_D0); |
2909 | restore_pincfgs(codec); /* restore all current pin configs */ | 2935 | restore_pincfgs(codec); /* restore all current pin configs */ |
2936 | restore_shutup_pins(codec); | ||
2910 | hda_exec_init_verbs(codec); | 2937 | hda_exec_init_verbs(codec); |
2911 | if (codec->patch_ops.resume) | 2938 | if (codec->patch_ops.resume) |
2912 | codec->patch_ops.resume(codec); | 2939 | codec->patch_ops.resume(codec); |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 49e939e7e5c..5991d14e1ec 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -821,6 +821,7 @@ struct hda_codec { | |||
821 | unsigned int pin_amp_workaround:1; /* pin out-amp takes index | 821 | unsigned int pin_amp_workaround:1; /* pin out-amp takes index |
822 | * (e.g. Conexant codecs) | 822 | * (e.g. Conexant codecs) |
823 | */ | 823 | */ |
824 | unsigned int pins_shutup:1; /* pins are shut up */ | ||
824 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ | 825 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ |
825 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 826 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
826 | unsigned int power_on :1; /* current (global) power-state */ | 827 | unsigned int power_on :1; /* current (global) power-state */ |
@@ -897,7 +898,9 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec); | |||
897 | /* the struct for codec->pin_configs */ | 898 | /* the struct for codec->pin_configs */ |
898 | struct hda_pincfg { | 899 | struct hda_pincfg { |
899 | hda_nid_t nid; | 900 | hda_nid_t nid; |
900 | unsigned int cfg; | 901 | unsigned char ctrl; /* current pin control value */ |
902 | unsigned char pad; /* reserved */ | ||
903 | unsigned int cfg; /* default configuration */ | ||
901 | }; | 904 | }; |
902 | 905 | ||
903 | unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid); | 906 | unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid); |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 170610e1d7d..1df25cf5ce3 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -1097,6 +1097,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
1097 | struct azx *chip = dev_id; | 1097 | struct azx *chip = dev_id; |
1098 | struct azx_dev *azx_dev; | 1098 | struct azx_dev *azx_dev; |
1099 | u32 status; | 1099 | u32 status; |
1100 | u8 sd_status; | ||
1100 | int i, ok; | 1101 | int i, ok; |
1101 | 1102 | ||
1102 | spin_lock(&chip->reg_lock); | 1103 | spin_lock(&chip->reg_lock); |
@@ -1110,8 +1111,10 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
1110 | for (i = 0; i < chip->num_streams; i++) { | 1111 | for (i = 0; i < chip->num_streams; i++) { |
1111 | azx_dev = &chip->azx_dev[i]; | 1112 | azx_dev = &chip->azx_dev[i]; |
1112 | if (status & azx_dev->sd_int_sta_mask) { | 1113 | if (status & azx_dev->sd_int_sta_mask) { |
1114 | sd_status = azx_sd_readb(azx_dev, SD_STS); | ||
1113 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); | 1115 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); |
1114 | if (!azx_dev->substream || !azx_dev->running) | 1116 | if (!azx_dev->substream || !azx_dev->running || |
1117 | !(sd_status & SD_INT_COMPLETE)) | ||
1115 | continue; | 1118 | continue; |
1116 | /* check whether this IRQ is really acceptable */ | 1119 | /* check whether this IRQ is really acceptable */ |
1117 | ok = azx_position_ok(chip, azx_dev); | 1120 | ok = azx_position_ok(chip, azx_dev); |
@@ -1910,11 +1913,11 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) | |||
1910 | if (WARN_ONCE(!azx_dev->period_bytes, | 1913 | if (WARN_ONCE(!azx_dev->period_bytes, |
1911 | "hda-intel: zero azx_dev->period_bytes")) | 1914 | "hda-intel: zero azx_dev->period_bytes")) |
1912 | return -1; /* this shouldn't happen! */ | 1915 | return -1; /* this shouldn't happen! */ |
1913 | if (wallclk <= azx_dev->period_wallclk && | 1916 | if (wallclk < (azx_dev->period_wallclk * 5) / 4 && |
1914 | pos % azx_dev->period_bytes > azx_dev->period_bytes / 2) | 1917 | pos % azx_dev->period_bytes > azx_dev->period_bytes / 2) |
1915 | /* NG - it's below the first next period boundary */ | 1918 | /* NG - it's below the first next period boundary */ |
1916 | return bdl_pos_adj[chip->dev_index] ? 0 : -1; | 1919 | return bdl_pos_adj[chip->dev_index] ? 0 : -1; |
1917 | azx_dev->start_wallclk = wallclk; | 1920 | azx_dev->start_wallclk += wallclk; |
1918 | return 1; /* OK, it's fine */ | 1921 | return 1; /* OK, it's fine */ |
1919 | } | 1922 | } |
1920 | 1923 | ||
@@ -2279,16 +2282,23 @@ static int azx_dev_free(struct snd_device *device) | |||
2279 | * white/black-listing for position_fix | 2282 | * white/black-listing for position_fix |
2280 | */ | 2283 | */ |
2281 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { | 2284 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { |
2285 | SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB), | ||
2282 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), | 2286 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), |
2283 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), | 2287 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), |
2284 | SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), | 2288 | SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), |
2285 | SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), | 2289 | SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), |
2286 | SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), | ||
2287 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), | 2290 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), |
2291 | SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), | ||
2292 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), | ||
2293 | SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), | ||
2294 | SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), | ||
2295 | SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB), | ||
2296 | SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB), | ||
2288 | SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), | 2297 | SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), |
2289 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), | 2298 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), |
2290 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), | 2299 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), |
2291 | SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB), | 2300 | SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB), |
2301 | SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB), | ||
2292 | SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB), | 2302 | SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB), |
2293 | SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB), | 2303 | SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB), |
2294 | {} | 2304 | {} |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index e863649d31f..2bf2cb5da95 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -2975,6 +2975,8 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
2975 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), | 2975 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), |
2976 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), | 2976 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), |
2977 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), | 2977 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), |
2978 | SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), | ||
2979 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), | ||
2978 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), | 2980 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), |
2979 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), | 2981 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), |
2980 | {} | 2982 | {} |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 86067ee7863..2fc53961054 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -52,6 +52,10 @@ struct hdmi_spec { | |||
52 | */ | 52 | */ |
53 | struct hda_multi_out multiout; | 53 | struct hda_multi_out multiout; |
54 | unsigned int codec_type; | 54 | unsigned int codec_type; |
55 | |||
56 | /* misc flags */ | ||
57 | /* PD bit indicates only the update, not the current state */ | ||
58 | unsigned int old_pin_detect:1; | ||
55 | }; | 59 | }; |
56 | 60 | ||
57 | 61 | ||
@@ -616,6 +620,9 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, | |||
616 | * Unsolicited events | 620 | * Unsolicited events |
617 | */ | 621 | */ |
618 | 622 | ||
623 | static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, | ||
624 | struct hdmi_eld *eld); | ||
625 | |||
619 | static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | 626 | static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) |
620 | { | 627 | { |
621 | struct hdmi_spec *spec = codec->spec; | 628 | struct hdmi_spec *spec = codec->spec; |
@@ -632,6 +639,12 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | |||
632 | if (index < 0) | 639 | if (index < 0) |
633 | return; | 640 | return; |
634 | 641 | ||
642 | if (spec->old_pin_detect) { | ||
643 | if (pind) | ||
644 | hdmi_present_sense(codec, tag, &spec->sink_eld[index]); | ||
645 | pind = spec->sink_eld[index].monitor_present; | ||
646 | } | ||
647 | |||
635 | spec->sink_eld[index].monitor_present = pind; | 648 | spec->sink_eld[index].monitor_present = pind; |
636 | spec->sink_eld[index].eld_valid = eldv; | 649 | spec->sink_eld[index].eld_valid = eldv; |
637 | 650 | ||
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index 3c10c0b149f..b0652acee9b 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c | |||
@@ -478,6 +478,7 @@ static int patch_nvhdmi_8ch_89(struct hda_codec *codec) | |||
478 | 478 | ||
479 | codec->spec = spec; | 479 | codec->spec = spec; |
480 | spec->codec_type = HDA_CODEC_NVIDIA_MCP89; | 480 | spec->codec_type = HDA_CODEC_NVIDIA_MCP89; |
481 | spec->old_pin_detect = 1; | ||
481 | 482 | ||
482 | if (hdmi_parse_codec(codec) < 0) { | 483 | if (hdmi_parse_codec(codec) < 0) { |
483 | codec->spec = NULL; | 484 | codec->spec = NULL; |
@@ -508,6 +509,7 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) | |||
508 | spec->multiout.max_channels = 8; | 509 | spec->multiout.max_channels = 8; |
509 | spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; | 510 | spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; |
510 | spec->codec_type = HDA_CODEC_NVIDIA_MCP7X; | 511 | spec->codec_type = HDA_CODEC_NVIDIA_MCP7X; |
512 | spec->old_pin_detect = 1; | ||
511 | 513 | ||
512 | codec->patch_ops = nvhdmi_patch_ops_8ch_7x; | 514 | codec->patch_ops = nvhdmi_patch_ops_8ch_7x; |
513 | 515 | ||
@@ -528,6 +530,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) | |||
528 | spec->multiout.max_channels = 2; | 530 | spec->multiout.max_channels = 2; |
529 | spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; | 531 | spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; |
530 | spec->codec_type = HDA_CODEC_NVIDIA_MCP7X; | 532 | spec->codec_type = HDA_CODEC_NVIDIA_MCP7X; |
533 | spec->old_pin_detect = 1; | ||
531 | 534 | ||
532 | codec->patch_ops = nvhdmi_patch_ops_2ch; | 535 | codec->patch_ops = nvhdmi_patch_ops_2ch; |
533 | 536 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 53538b0f999..596ea2f12cf 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1267,6 +1267,8 @@ static int alc_auto_parse_customize_define(struct hda_codec *codec) | |||
1267 | unsigned nid = 0; | 1267 | unsigned nid = 0; |
1268 | struct alc_spec *spec = codec->spec; | 1268 | struct alc_spec *spec = codec->spec; |
1269 | 1269 | ||
1270 | spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ | ||
1271 | |||
1270 | ass = codec->subsystem_id & 0xffff; | 1272 | ass = codec->subsystem_id & 0xffff; |
1271 | if (ass != codec->bus->pci->subsystem_device && (ass & 1)) | 1273 | if (ass != codec->bus->pci->subsystem_device && (ass & 1)) |
1272 | goto do_sku; | 1274 | goto do_sku; |
@@ -2547,7 +2549,7 @@ static struct snd_kcontrol_new alc_beep_mixer[] = { | |||
2547 | static int alc_build_controls(struct hda_codec *codec) | 2549 | static int alc_build_controls(struct hda_codec *codec) |
2548 | { | 2550 | { |
2549 | struct alc_spec *spec = codec->spec; | 2551 | struct alc_spec *spec = codec->spec; |
2550 | struct snd_kcontrol *kctl; | 2552 | struct snd_kcontrol *kctl = NULL; |
2551 | struct snd_kcontrol_new *knew; | 2553 | struct snd_kcontrol_new *knew; |
2552 | int i, j, err; | 2554 | int i, j, err; |
2553 | unsigned int u; | 2555 | unsigned int u; |
@@ -2619,16 +2621,18 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2619 | } | 2621 | } |
2620 | 2622 | ||
2621 | /* assign Capture Source enums to NID */ | 2623 | /* assign Capture Source enums to NID */ |
2622 | kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); | 2624 | if (spec->capsrc_nids || spec->adc_nids) { |
2623 | if (!kctl) | 2625 | kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); |
2624 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); | 2626 | if (!kctl) |
2625 | for (i = 0; kctl && i < kctl->count; i++) { | 2627 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); |
2626 | hda_nid_t *nids = spec->capsrc_nids; | 2628 | for (i = 0; kctl && i < kctl->count; i++) { |
2627 | if (!nids) | 2629 | hda_nid_t *nids = spec->capsrc_nids; |
2628 | nids = spec->adc_nids; | 2630 | if (!nids) |
2629 | err = snd_hda_add_nid(codec, kctl, i, nids[i]); | 2631 | nids = spec->adc_nids; |
2630 | if (err < 0) | 2632 | err = snd_hda_add_nid(codec, kctl, i, nids[i]); |
2631 | return err; | 2633 | if (err < 0) |
2634 | return err; | ||
2635 | } | ||
2632 | } | 2636 | } |
2633 | if (spec->cap_mixer) { | 2637 | if (spec->cap_mixer) { |
2634 | const char *kname = kctl ? kctl->id.name : NULL; | 2638 | const char *kname = kctl ? kctl->id.name : NULL; |
@@ -5176,8 +5180,24 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | |||
5176 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 5180 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
5177 | #define set_beep_amp(spec, nid, idx, dir) \ | 5181 | #define set_beep_amp(spec, nid, idx, dir) \ |
5178 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) | 5182 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) |
5183 | |||
5184 | static struct snd_pci_quirk beep_white_list[] = { | ||
5185 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), | ||
5186 | {} | ||
5187 | }; | ||
5188 | |||
5189 | static inline int has_cdefine_beep(struct hda_codec *codec) | ||
5190 | { | ||
5191 | struct alc_spec *spec = codec->spec; | ||
5192 | const struct snd_pci_quirk *q; | ||
5193 | q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); | ||
5194 | if (q) | ||
5195 | return q->value; | ||
5196 | return spec->cdefine.enable_pcbeep; | ||
5197 | } | ||
5179 | #else | 5198 | #else |
5180 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | 5199 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ |
5200 | #define has_cdefine_beep(codec) 0 | ||
5181 | #endif | 5201 | #endif |
5182 | 5202 | ||
5183 | /* | 5203 | /* |
@@ -6948,7 +6968,7 @@ static struct hda_input_mux mb5_capture_source = { | |||
6948 | .num_items = 3, | 6968 | .num_items = 3, |
6949 | .items = { | 6969 | .items = { |
6950 | { "Mic", 0x1 }, | 6970 | { "Mic", 0x1 }, |
6951 | { "Line", 0x2 }, | 6971 | { "Line", 0x7 }, |
6952 | { "CD", 0x4 }, | 6972 | { "CD", 0x4 }, |
6953 | }, | 6973 | }, |
6954 | }; | 6974 | }; |
@@ -7025,6 +7045,14 @@ static struct hda_input_mux alc889A_mb31_capture_source = { | |||
7025 | }, | 7045 | }, |
7026 | }; | 7046 | }; |
7027 | 7047 | ||
7048 | static struct hda_input_mux alc889A_imac91_capture_source = { | ||
7049 | .num_items = 2, | ||
7050 | .items = { | ||
7051 | { "Mic", 0x01 }, | ||
7052 | { "Line", 0x2 }, /* Not sure! */ | ||
7053 | }, | ||
7054 | }; | ||
7055 | |||
7028 | /* | 7056 | /* |
7029 | * 2ch mode | 7057 | * 2ch mode |
7030 | */ | 7058 | */ |
@@ -7461,8 +7489,8 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = { | |||
7461 | HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), | 7489 | HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), |
7462 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), | 7490 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), |
7463 | HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), | 7491 | HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), |
7464 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 7492 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), |
7465 | HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | 7493 | HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), |
7466 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | 7494 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), |
7467 | HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | 7495 | HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), |
7468 | HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), | 7496 | HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), |
@@ -7486,15 +7514,8 @@ static struct snd_kcontrol_new alc885_macmini3_mixer[] = { | |||
7486 | }; | 7514 | }; |
7487 | 7515 | ||
7488 | static struct snd_kcontrol_new alc885_imac91_mixer[] = { | 7516 | static struct snd_kcontrol_new alc885_imac91_mixer[] = { |
7489 | HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | 7517 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), |
7490 | HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT), | 7518 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), |
7491 | HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT), | ||
7492 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x00, HDA_OUTPUT), | ||
7493 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
7494 | HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
7495 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), | ||
7496 | HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), | ||
7497 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), | ||
7498 | { } /* end */ | 7519 | { } /* end */ |
7499 | }; | 7520 | }; |
7500 | 7521 | ||
@@ -7852,10 +7873,9 @@ static struct hda_verb alc885_mb5_init_verbs[] = { | |||
7852 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 7873 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
7853 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 7874 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
7854 | 7875 | ||
7855 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 7876 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)}, |
7856 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | 7877 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)}, |
7857 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | 7878 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)}, |
7858 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
7859 | { } | 7879 | { } |
7860 | }; | 7880 | }; |
7861 | 7881 | ||
@@ -7995,61 +8015,56 @@ static struct hda_verb alc885_mbp3_init_verbs[] = { | |||
7995 | 8015 | ||
7996 | /* iMac 9,1 */ | 8016 | /* iMac 9,1 */ |
7997 | static struct hda_verb alc885_imac91_init_verbs[] = { | 8017 | static struct hda_verb alc885_imac91_init_verbs[] = { |
7998 | /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */ | 8018 | /* Internal Speaker Pin (0x0c) */ |
7999 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 8019 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, |
8000 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8020 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
8001 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 8021 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, |
8002 | /* Rear mixer */ | 8022 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, |
8003 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 8023 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
8004 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8024 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, |
8005 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 8025 | /* HP Pin: Rear */ |
8006 | /* HP Pin: output 0 (0x0c) */ | ||
8007 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 8026 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
8008 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 8027 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
8009 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | 8028 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, |
8010 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 8029 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, |
8011 | /* Internal Speakers: output 0 (0x0d) */ | 8030 | /* Line in Rear */ |
8012 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 8031 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, |
8013 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 8032 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
8014 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
8015 | /* Mic (rear) pin: input vref at 80% */ | ||
8016 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
8017 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8018 | /* Front Mic pin: input vref at 80% */ | 8033 | /* Front Mic pin: input vref at 80% */ |
8019 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 8034 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
8020 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 8035 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
8021 | /* Line In pin: use output 1 when in LineOut mode */ | 8036 | /* Rear mixer */ |
8022 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 8037 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
8023 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 8038 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
8024 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, | 8039 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
8025 | 8040 | /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */ | |
8026 | /* FIXME: use matrix-type input source selection */ | 8041 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
8027 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | 8042 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
8028 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | 8043 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
8044 | /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ | ||
8029 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 8045 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
8030 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | 8046 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, |
8031 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | 8047 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, |
8032 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | 8048 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, |
8033 | /* Input mixer2 */ | 8049 | /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ |
8034 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 8050 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
8035 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | 8051 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, |
8036 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | 8052 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, |
8037 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | 8053 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, |
8038 | /* Input mixer3 */ | 8054 | /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ |
8039 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 8055 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
8040 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | 8056 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, |
8041 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | 8057 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, |
8042 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | 8058 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, |
8043 | /* ADC1: mute amp left and right */ | 8059 | /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ |
8044 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8060 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
8045 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | 8061 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, |
8046 | /* ADC2: mute amp left and right */ | 8062 | /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ |
8047 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8063 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
8048 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | 8064 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, |
8049 | /* ADC3: mute amp left and right */ | 8065 | /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ |
8050 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8066 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
8051 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | 8067 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, |
8052 | |||
8053 | { } | 8068 | { } |
8054 | }; | 8069 | }; |
8055 | 8070 | ||
@@ -8118,7 +8133,7 @@ static void alc885_imac91_setup(struct hda_codec *codec) | |||
8118 | struct alc_spec *spec = codec->spec; | 8133 | struct alc_spec *spec = codec->spec; |
8119 | 8134 | ||
8120 | spec->autocfg.hp_pins[0] = 0x14; | 8135 | spec->autocfg.hp_pins[0] = 0x14; |
8121 | spec->autocfg.speaker_pins[0] = 0x15; | 8136 | spec->autocfg.speaker_pins[0] = 0x18; |
8122 | spec->autocfg.speaker_pins[1] = 0x1a; | 8137 | spec->autocfg.speaker_pins[1] = 0x1a; |
8123 | } | 8138 | } |
8124 | 8139 | ||
@@ -9480,11 +9495,16 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { | |||
9480 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24), | 9495 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24), |
9481 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24), | 9496 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24), |
9482 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3), | 9497 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3), |
9498 | SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31), | ||
9499 | SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M), | ||
9500 | SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3), | ||
9501 | SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21), | ||
9483 | SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), | 9502 | SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), |
9484 | SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), | 9503 | SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), |
9485 | SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), | 9504 | SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), |
9486 | SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91), | 9505 | SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91), |
9487 | SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), | 9506 | SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), |
9507 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5), | ||
9488 | /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, | 9508 | /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, |
9489 | * so apparently no perfect solution yet | 9509 | * so apparently no perfect solution yet |
9490 | */ | 9510 | */ |
@@ -9627,14 +9647,14 @@ static struct alc_config_preset alc882_presets[] = { | |||
9627 | .init_hook = alc885_imac24_init_hook, | 9647 | .init_hook = alc885_imac24_init_hook, |
9628 | }, | 9648 | }, |
9629 | [ALC885_IMAC91] = { | 9649 | [ALC885_IMAC91] = { |
9630 | .mixers = { alc885_imac91_mixer, alc882_chmode_mixer }, | 9650 | .mixers = {alc885_imac91_mixer}, |
9631 | .init_verbs = { alc885_imac91_init_verbs, | 9651 | .init_verbs = { alc885_imac91_init_verbs, |
9632 | alc880_gpio1_init_verbs }, | 9652 | alc880_gpio1_init_verbs }, |
9633 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | 9653 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), |
9634 | .dac_nids = alc882_dac_nids, | 9654 | .dac_nids = alc882_dac_nids, |
9635 | .channel_mode = alc885_mbp_4ch_modes, | 9655 | .channel_mode = alc885_mba21_ch_modes, |
9636 | .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes), | 9656 | .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), |
9637 | .input_mux = &alc882_capture_source, | 9657 | .input_mux = &alc889A_imac91_capture_source, |
9638 | .dig_out_nid = ALC882_DIGOUT_NID, | 9658 | .dig_out_nid = ALC882_DIGOUT_NID, |
9639 | .dig_in_nid = ALC882_DIGIN_NID, | 9659 | .dig_in_nid = ALC882_DIGIN_NID, |
9640 | .unsol_event = alc_automute_amp_unsol_event, | 9660 | .unsol_event = alc_automute_amp_unsol_event, |
@@ -10562,10 +10582,12 @@ static int patch_alc882(struct hda_codec *codec) | |||
10562 | } | 10582 | } |
10563 | } | 10583 | } |
10564 | 10584 | ||
10565 | err = snd_hda_attach_beep_device(codec, 0x1); | 10585 | if (has_cdefine_beep(codec)) { |
10566 | if (err < 0) { | 10586 | err = snd_hda_attach_beep_device(codec, 0x1); |
10567 | alc_free(codec); | 10587 | if (err < 0) { |
10568 | return err; | 10588 | alc_free(codec); |
10589 | return err; | ||
10590 | } | ||
10569 | } | 10591 | } |
10570 | 10592 | ||
10571 | if (board_config != ALC882_AUTO) | 10593 | if (board_config != ALC882_AUTO) |
@@ -10615,7 +10637,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
10615 | 10637 | ||
10616 | set_capture_mixer(codec); | 10638 | set_capture_mixer(codec); |
10617 | 10639 | ||
10618 | if (spec->cdefine.enable_pcbeep) | 10640 | if (has_cdefine_beep(codec)) |
10619 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 10641 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
10620 | 10642 | ||
10621 | if (board_config == ALC882_AUTO) | 10643 | if (board_config == ALC882_AUTO) |
@@ -12431,7 +12453,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
12431 | } | 12453 | } |
12432 | } | 12454 | } |
12433 | 12455 | ||
12434 | if (!spec->no_analog) { | 12456 | if (!spec->no_analog && has_cdefine_beep(codec)) { |
12435 | err = snd_hda_attach_beep_device(codec, 0x1); | 12457 | err = snd_hda_attach_beep_device(codec, 0x1); |
12436 | if (err < 0) { | 12458 | if (err < 0) { |
12437 | alc_free(codec); | 12459 | alc_free(codec); |
@@ -12482,7 +12504,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
12482 | } | 12504 | } |
12483 | if (!spec->cap_mixer && !spec->no_analog) | 12505 | if (!spec->cap_mixer && !spec->no_analog) |
12484 | set_capture_mixer(codec); | 12506 | set_capture_mixer(codec); |
12485 | if (!spec->no_analog && spec->cdefine.enable_pcbeep) | 12507 | if (!spec->no_analog && has_cdefine_beep(codec)) |
12486 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 12508 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
12487 | 12509 | ||
12488 | spec->vmaster_nid = 0x0c; | 12510 | spec->vmaster_nid = 0x0c; |
@@ -14454,10 +14476,12 @@ static int patch_alc269(struct hda_codec *codec) | |||
14454 | } | 14476 | } |
14455 | } | 14477 | } |
14456 | 14478 | ||
14457 | err = snd_hda_attach_beep_device(codec, 0x1); | 14479 | if (has_cdefine_beep(codec)) { |
14458 | if (err < 0) { | 14480 | err = snd_hda_attach_beep_device(codec, 0x1); |
14459 | alc_free(codec); | 14481 | if (err < 0) { |
14460 | return err; | 14482 | alc_free(codec); |
14483 | return err; | ||
14484 | } | ||
14461 | } | 14485 | } |
14462 | 14486 | ||
14463 | if (board_config != ALC269_AUTO) | 14487 | if (board_config != ALC269_AUTO) |
@@ -14490,7 +14514,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
14490 | 14514 | ||
14491 | if (!spec->cap_mixer) | 14515 | if (!spec->cap_mixer) |
14492 | set_capture_mixer(codec); | 14516 | set_capture_mixer(codec); |
14493 | if (spec->cdefine.enable_pcbeep) | 14517 | if (has_cdefine_beep(codec)) |
14494 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | 14518 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
14495 | 14519 | ||
14496 | if (board_config == ALC269_AUTO) | 14520 | if (board_config == ALC269_AUTO) |
@@ -18687,10 +18711,12 @@ static int patch_alc662(struct hda_codec *codec) | |||
18687 | } | 18711 | } |
18688 | } | 18712 | } |
18689 | 18713 | ||
18690 | err = snd_hda_attach_beep_device(codec, 0x1); | 18714 | if (has_cdefine_beep(codec)) { |
18691 | if (err < 0) { | 18715 | err = snd_hda_attach_beep_device(codec, 0x1); |
18692 | alc_free(codec); | 18716 | if (err < 0) { |
18693 | return err; | 18717 | alc_free(codec); |
18718 | return err; | ||
18719 | } | ||
18694 | } | 18720 | } |
18695 | 18721 | ||
18696 | if (board_config != ALC662_AUTO) | 18722 | if (board_config != ALC662_AUTO) |
@@ -18712,7 +18738,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
18712 | if (!spec->cap_mixer) | 18738 | if (!spec->cap_mixer) |
18713 | set_capture_mixer(codec); | 18739 | set_capture_mixer(codec); |
18714 | 18740 | ||
18715 | if (spec->cdefine.enable_pcbeep) { | 18741 | if (has_cdefine_beep(codec)) { |
18716 | switch (codec->vendor_id) { | 18742 | switch (codec->vendor_id) { |
18717 | case 0x10ec0662: | 18743 | case 0x10ec0662: |
18718 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 18744 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a0e06d82da1..f1e7babd692 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -2078,12 +2078,12 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { | |||
2078 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000, | 2078 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000, |
2079 | "Intel D965", STAC_D965_3ST), | 2079 | "Intel D965", STAC_D965_3ST), |
2080 | /* Dell 3 stack systems */ | 2080 | /* Dell 3 stack systems */ |
2081 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_3ST), | ||
2082 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST), | 2081 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST), |
2083 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST), | 2082 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST), |
2084 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST), | 2083 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST), |
2085 | /* Dell 3 stack systems with verb table in BIOS */ | 2084 | /* Dell 3 stack systems with verb table in BIOS */ |
2086 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), | 2085 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), |
2086 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS), | ||
2087 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), | 2087 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), |
2088 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS), | 2088 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS), |
2089 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS), | 2089 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS), |
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index 495be6e7193..24454c98d0e 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c | |||
@@ -300,7 +300,7 @@ struct snd_soc_dai au1xpsc_i2s_dai = { | |||
300 | }; | 300 | }; |
301 | EXPORT_SYMBOL(au1xpsc_i2s_dai); | 301 | EXPORT_SYMBOL(au1xpsc_i2s_dai); |
302 | 302 | ||
303 | static int __init au1xpsc_i2s_drvprobe(struct platform_device *pdev) | 303 | static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) |
304 | { | 304 | { |
305 | struct resource *r; | 305 | struct resource *r; |
306 | unsigned long sel; | 306 | unsigned long sel; |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 31ac5538fe7..5da30eb6ad0 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -83,8 +83,8 @@ config SND_SOC_ALL_CODECS | |||
83 | 83 | ||
84 | config SND_SOC_WM_HUBS | 84 | config SND_SOC_WM_HUBS |
85 | tristate | 85 | tristate |
86 | default y if SND_SOC_WM8993=y | 86 | default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y |
87 | default m if SND_SOC_WM8993=m | 87 | default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m |
88 | 88 | ||
89 | config SND_SOC_AC97_CODEC | 89 | config SND_SOC_AC97_CODEC |
90 | tristate | 90 | tristate |
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 8ae20208e7b..0221ca79b3a 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -426,8 +426,8 @@ static const struct soc_enum wm8350_enum[] = { | |||
426 | SOC_ENUM_SINGLE(WM8350_INPUT_MIXER_VOLUME, 15, 2, wm8350_lr), | 426 | SOC_ENUM_SINGLE(WM8350_INPUT_MIXER_VOLUME, 15, 2, wm8350_lr), |
427 | }; | 427 | }; |
428 | 428 | ||
429 | static DECLARE_TLV_DB_LINEAR(pre_amp_tlv, -1200, 3525); | 429 | static DECLARE_TLV_DB_SCALE(pre_amp_tlv, -1200, 3525, 0); |
430 | static DECLARE_TLV_DB_LINEAR(out_pga_tlv, -5700, 600); | 430 | static DECLARE_TLV_DB_SCALE(out_pga_tlv, -5700, 600, 0); |
431 | static DECLARE_TLV_DB_SCALE(dac_pcm_tlv, -7163, 36, 1); | 431 | static DECLARE_TLV_DB_SCALE(dac_pcm_tlv, -7163, 36, 1); |
432 | static DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -12700, 50, 1); | 432 | static DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -12700, 50, 1); |
433 | static DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 1); | 433 | static DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 1); |
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 7f5d080536a..8f294066b0e 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
@@ -107,21 +107,21 @@ static void wm8400_codec_reset(struct snd_soc_codec *codec) | |||
107 | wm8400_reset_codec_reg_cache(wm8400->wm8400); | 107 | wm8400_reset_codec_reg_cache(wm8400->wm8400); |
108 | } | 108 | } |
109 | 109 | ||
110 | static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600); | 110 | static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 600, 0); |
111 | 111 | ||
112 | static const DECLARE_TLV_DB_LINEAR(in_pga_tlv, -1650, 3000); | 112 | static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1650, 3000, 0); |
113 | 113 | ||
114 | static const DECLARE_TLV_DB_LINEAR(out_mix_tlv, -2100, 0); | 114 | static const DECLARE_TLV_DB_SCALE(out_mix_tlv, -2100, 0, 0); |
115 | 115 | ||
116 | static const DECLARE_TLV_DB_LINEAR(out_pga_tlv, -7300, 600); | 116 | static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -7300, 600, 0); |
117 | 117 | ||
118 | static const DECLARE_TLV_DB_LINEAR(out_omix_tlv, -600, 0); | 118 | static const DECLARE_TLV_DB_SCALE(out_omix_tlv, -600, 0, 0); |
119 | 119 | ||
120 | static const DECLARE_TLV_DB_LINEAR(out_dac_tlv, -7163, 0); | 120 | static const DECLARE_TLV_DB_SCALE(out_dac_tlv, -7163, 0, 0); |
121 | 121 | ||
122 | static const DECLARE_TLV_DB_LINEAR(in_adc_tlv, -7163, 1763); | 122 | static const DECLARE_TLV_DB_SCALE(in_adc_tlv, -7163, 1763, 0); |
123 | 123 | ||
124 | static const DECLARE_TLV_DB_LINEAR(out_sidetone_tlv, -3600, 0); | 124 | static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0); |
125 | 125 | ||
126 | static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, | 126 | static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, |
127 | struct snd_ctl_elem_value *ucontrol) | 127 | struct snd_ctl_elem_value *ucontrol) |
@@ -440,7 +440,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w, | |||
440 | /* INMIX dB values */ | 440 | /* INMIX dB values */ |
441 | static const unsigned int in_mix_tlv[] = { | 441 | static const unsigned int in_mix_tlv[] = { |
442 | TLV_DB_RANGE_HEAD(1), | 442 | TLV_DB_RANGE_HEAD(1), |
443 | 0,7, TLV_DB_LINEAR_ITEM(-1200, 600), | 443 | 0,7, TLV_DB_SCALE_ITEM(-1200, 600, 0), |
444 | }; | 444 | }; |
445 | 445 | ||
446 | /* Left In PGA Connections */ | 446 | /* Left In PGA Connections */ |
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c index 1072621e93f..9d1df262813 100644 --- a/sound/soc/codecs/wm8727.c +++ b/sound/soc/codecs/wm8727.c | |||
@@ -127,6 +127,8 @@ static __devinit int wm8727_platform_probe(struct platform_device *pdev) | |||
127 | goto err_codec; | 127 | goto err_codec; |
128 | } | 128 | } |
129 | 129 | ||
130 | return 0; | ||
131 | |||
130 | err_codec: | 132 | err_codec: |
131 | snd_soc_unregister_codec(codec); | 133 | snd_soc_unregister_codec(codec); |
132 | err: | 134 | err: |
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 7e4a627b4c7..4e212ed62ea 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c | |||
@@ -94,7 +94,6 @@ SOC_DAPM_SINGLE("Bypass Switch", WM8776_OUTMUX, 2, 1, 0), | |||
94 | 94 | ||
95 | static const struct snd_soc_dapm_widget wm8776_dapm_widgets[] = { | 95 | static const struct snd_soc_dapm_widget wm8776_dapm_widgets[] = { |
96 | SND_SOC_DAPM_INPUT("AUX"), | 96 | SND_SOC_DAPM_INPUT("AUX"), |
97 | SND_SOC_DAPM_INPUT("AUX"), | ||
98 | 97 | ||
99 | SND_SOC_DAPM_INPUT("AIN1"), | 98 | SND_SOC_DAPM_INPUT("AIN1"), |
100 | SND_SOC_DAPM_INPUT("AIN2"), | 99 | SND_SOC_DAPM_INPUT("AIN2"), |
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 0417dae32e6..19ad590ca0b 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c | |||
@@ -885,7 +885,6 @@ static int wm8988_register(struct wm8988_priv *wm8988, | |||
885 | ret = snd_soc_register_dai(&wm8988_dai); | 885 | ret = snd_soc_register_dai(&wm8988_dai); |
886 | if (ret != 0) { | 886 | if (ret != 0) { |
887 | dev_err(codec->dev, "Failed to register DAI: %d\n", ret); | 887 | dev_err(codec->dev, "Failed to register DAI: %d\n", ret); |
888 | snd_soc_unregister_codec(codec); | ||
889 | goto err_codec; | 888 | goto err_codec; |
890 | } | 889 | } |
891 | 890 | ||
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 7b536d923ea..c018772cc43 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c | |||
@@ -111,21 +111,21 @@ static const u16 wm8990_reg[] = { | |||
111 | 111 | ||
112 | #define wm8990_reset(c) snd_soc_write(c, WM8990_RESET, 0) | 112 | #define wm8990_reset(c) snd_soc_write(c, WM8990_RESET, 0) |
113 | 113 | ||
114 | static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600); | 114 | static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 600, 0); |
115 | 115 | ||
116 | static const DECLARE_TLV_DB_LINEAR(in_pga_tlv, -1650, 3000); | 116 | static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1650, 3000, 0); |
117 | 117 | ||
118 | static const DECLARE_TLV_DB_LINEAR(out_mix_tlv, 0, -2100); | 118 | static const DECLARE_TLV_DB_SCALE(out_mix_tlv, 0, -2100, 0); |
119 | 119 | ||
120 | static const DECLARE_TLV_DB_LINEAR(out_pga_tlv, -7300, 600); | 120 | static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -7300, 600, 0); |
121 | 121 | ||
122 | static const DECLARE_TLV_DB_LINEAR(out_omix_tlv, -600, 0); | 122 | static const DECLARE_TLV_DB_SCALE(out_omix_tlv, -600, 0, 0); |
123 | 123 | ||
124 | static const DECLARE_TLV_DB_LINEAR(out_dac_tlv, -7163, 0); | 124 | static const DECLARE_TLV_DB_SCALE(out_dac_tlv, -7163, 0, 0); |
125 | 125 | ||
126 | static const DECLARE_TLV_DB_LINEAR(in_adc_tlv, -7163, 1763); | 126 | static const DECLARE_TLV_DB_SCALE(in_adc_tlv, -7163, 1763, 0); |
127 | 127 | ||
128 | static const DECLARE_TLV_DB_LINEAR(out_sidetone_tlv, -3600, 0); | 128 | static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0); |
129 | 129 | ||
130 | static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, | 130 | static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, |
131 | struct snd_ctl_elem_value *ucontrol) | 131 | struct snd_ctl_elem_value *ucontrol) |
@@ -451,7 +451,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w, | |||
451 | /* INMIX dB values */ | 451 | /* INMIX dB values */ |
452 | static const unsigned int in_mix_tlv[] = { | 452 | static const unsigned int in_mix_tlv[] = { |
453 | TLV_DB_RANGE_HEAD(1), | 453 | TLV_DB_RANGE_HEAD(1), |
454 | 0, 7, TLV_DB_LINEAR_ITEM(-1200, 600), | 454 | 0, 7, TLV_DB_SCALE_ITEM(-1200, 600, 0), |
455 | }; | 455 | }; |
456 | 456 | ||
457 | /* Left In PGA Connections */ | 457 | /* Left In PGA Connections */ |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 79f0f4ad242..d3955096d87 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -612,7 +612,6 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) | |||
612 | NUMDMA_MASK); | 612 | NUMDMA_MASK); |
613 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, | 613 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, |
614 | ((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK); | 614 | ((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK); |
615 | mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); | ||
616 | } | 615 | } |
617 | 616 | ||
618 | if (dev->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) { | 617 | if (dev->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) { |
@@ -623,7 +622,6 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) | |||
623 | NUMDMA_MASK); | 622 | NUMDMA_MASK); |
624 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, | 623 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, |
625 | ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); | 624 | ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); |
626 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE); | ||
627 | } | 625 | } |
628 | } | 626 | } |
629 | 627 | ||
diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h index 22208b373fb..e1ec6d91ea3 100644 --- a/sound/soc/fsl/mpc5200_dma.h +++ b/sound/soc/fsl/mpc5200_dma.h | |||
@@ -73,7 +73,7 @@ struct psc_dma { | |||
73 | }; | 73 | }; |
74 | 74 | ||
75 | /* Utility for retrieving psc_dma_stream structure from a substream */ | 75 | /* Utility for retrieving psc_dma_stream structure from a substream */ |
76 | inline struct psc_dma_stream * | 76 | static inline struct psc_dma_stream * |
77 | to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma) | 77 | to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma) |
78 | { | 78 | { |
79 | if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) | 79 | if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) |
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig index eba9b9d257a..252defea93b 100644 --- a/sound/soc/imx/Kconfig +++ b/sound/soc/imx/Kconfig | |||
@@ -13,9 +13,18 @@ config SND_MXC_SOC_SSI | |||
13 | 13 | ||
14 | config SND_MXC_SOC_WM1133_EV1 | 14 | config SND_MXC_SOC_WM1133_EV1 |
15 | tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted" | 15 | tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted" |
16 | depends on SND_IMX_SOC && EXPERIMENTAL | 16 | depends on SND_IMX_SOC && MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL |
17 | select SND_SOC_WM8350 | 17 | select SND_SOC_WM8350 |
18 | select SND_MXC_SOC_SSI | 18 | select SND_MXC_SOC_SSI |
19 | help | 19 | help |
20 | Enable support for audio on the i.MX31ADS with the WM1133-EV1 | 20 | Enable support for audio on the i.MX31ADS with the WM1133-EV1 |
21 | PMIC board with WM8835x fitted. | 21 | PMIC board with WM8835x fitted. |
22 | |||
23 | config SND_SOC_PHYCORE_AC97 | ||
24 | tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards" | ||
25 | depends on MACH_PCM043 || MACH_PCA100 | ||
26 | select SND_MXC_SOC_SSI | ||
27 | select SND_SOC_WM9712 | ||
28 | help | ||
29 | Say Y if you want to add support for SoC audio on Phytec phyCORE | ||
30 | and phyCARD boards in AC97 mode | ||
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index 2b31ac673ea..05f19c9284f 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c | |||
@@ -73,7 +73,8 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err) | |||
73 | { | 73 | { |
74 | struct snd_pcm_substream *substream = data; | 74 | struct snd_pcm_substream *substream = data; |
75 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 75 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
76 | struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; | 76 | struct imx_pcm_dma_params *dma_params = |
77 | snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); | ||
77 | struct snd_pcm_runtime *runtime = substream->runtime; | 78 | struct snd_pcm_runtime *runtime = substream->runtime; |
78 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 79 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
79 | int ret; | 80 | int ret; |
@@ -102,7 +103,7 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) | |||
102 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 103 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
103 | int ret; | 104 | int ret; |
104 | 105 | ||
105 | dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); | 106 | dma_params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); |
106 | 107 | ||
107 | iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); | 108 | iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); |
108 | if (iprtd->dma < 0) { | 109 | if (iprtd->dma < 0) { |
@@ -212,7 +213,7 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream) | |||
212 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 213 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
213 | int err; | 214 | int err; |
214 | 215 | ||
215 | dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); | 216 | dma_params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); |
216 | 217 | ||
217 | iprtd->substream = substream; | 218 | iprtd->substream = substream; |
218 | iprtd->buf = (unsigned int *)substream->dma_buffer.area; | 219 | iprtd->buf = (unsigned int *)substream->dma_buffer.area; |
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 1941a357e8c..d256f5f313b 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c | |||
@@ -328,38 +328,6 @@ static struct snd_soc_device spitz_snd_devdata = { | |||
328 | .codec_dev = &soc_codec_dev_wm8750, | 328 | .codec_dev = &soc_codec_dev_wm8750, |
329 | }; | 329 | }; |
330 | 330 | ||
331 | /* | ||
332 | * FIXME: This is a temporary bodge to avoid cross-tree merge issues. | ||
333 | * New drivers should register the wm8750 I2C device in the machine | ||
334 | * setup code (under arch/arm for ARM systems). | ||
335 | */ | ||
336 | static int wm8750_i2c_register(void) | ||
337 | { | ||
338 | struct i2c_board_info info; | ||
339 | struct i2c_adapter *adapter; | ||
340 | struct i2c_client *client; | ||
341 | |||
342 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
343 | info.addr = 0x1b; | ||
344 | strlcpy(info.type, "wm8750", I2C_NAME_SIZE); | ||
345 | |||
346 | adapter = i2c_get_adapter(0); | ||
347 | if (!adapter) { | ||
348 | printk(KERN_ERR "can't get i2c adapter 0\n"); | ||
349 | return -ENODEV; | ||
350 | } | ||
351 | |||
352 | client = i2c_new_device(adapter, &info); | ||
353 | i2c_put_adapter(adapter); | ||
354 | if (!client) { | ||
355 | printk(KERN_ERR "can't add i2c device at 0x%x\n", | ||
356 | (unsigned int)info.addr); | ||
357 | return -ENODEV; | ||
358 | } | ||
359 | |||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static struct platform_device *spitz_snd_device; | 331 | static struct platform_device *spitz_snd_device; |
364 | 332 | ||
365 | static int __init spitz_init(void) | 333 | static int __init spitz_init(void) |
@@ -369,10 +337,6 @@ static int __init spitz_init(void) | |||
369 | if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) | 337 | if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) |
370 | return -ENODEV; | 338 | return -ENODEV; |
371 | 339 | ||
372 | ret = wm8750_i2c_setup(); | ||
373 | if (ret != 0) | ||
374 | return ret; | ||
375 | |||
376 | spitz_snd_device = platform_device_alloc("soc-audio", -1); | 340 | spitz_snd_device = platform_device_alloc("soc-audio", -1); |
377 | if (!spitz_snd_device) | 341 | if (!spitz_snd_device) |
378 | return -ENOMEM; | 342 | return -ENOMEM; |
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 3396a0db06b..ec4acac49eb 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -683,20 +683,15 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
683 | 683 | ||
684 | /* clock inversion (CKG2) */ | 684 | /* clock inversion (CKG2) */ |
685 | data = 0; | 685 | data = 0; |
686 | switch (SH_FSI_INVERSION_MASK & flags) { | 686 | if (SH_FSI_LRM_INV & flags) |
687 | case SH_FSI_LRM_INV: | 687 | data |= 1 << 12; |
688 | data = 1 << 12; | 688 | if (SH_FSI_BRM_INV & flags) |
689 | break; | 689 | data |= 1 << 8; |
690 | case SH_FSI_BRM_INV: | 690 | if (SH_FSI_LRS_INV & flags) |
691 | data = 1 << 8; | 691 | data |= 1 << 4; |
692 | break; | 692 | if (SH_FSI_BRS_INV & flags) |
693 | case SH_FSI_LRS_INV: | 693 | data |= 1 << 0; |
694 | data = 1 << 4; | 694 | |
695 | break; | ||
696 | case SH_FSI_BRS_INV: | ||
697 | data = 1 << 0; | ||
698 | break; | ||
699 | } | ||
700 | fsi_reg_write(fsi, CKG2, data); | 695 | fsi_reg_write(fsi, CKG2, data); |
701 | 696 | ||
702 | /* do fmt, di fmt */ | 697 | /* do fmt, di fmt */ |
@@ -726,15 +721,15 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
726 | break; | 721 | break; |
727 | case SH_FSI_FMT_TDM: | 722 | case SH_FSI_FMT_TDM: |
728 | msg = "TDM"; | 723 | msg = "TDM"; |
729 | data = CR_FMT(CR_TDM) | (fsi->chan - 1); | ||
730 | fsi->chan = is_play ? | 724 | fsi->chan = is_play ? |
731 | SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); | 725 | SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); |
726 | data = CR_FMT(CR_TDM) | (fsi->chan - 1); | ||
732 | break; | 727 | break; |
733 | case SH_FSI_FMT_TDM_DELAY: | 728 | case SH_FSI_FMT_TDM_DELAY: |
734 | msg = "TDM Delay"; | 729 | msg = "TDM Delay"; |
735 | data = CR_FMT(CR_TDM_D) | (fsi->chan - 1); | ||
736 | fsi->chan = is_play ? | 730 | fsi->chan = is_play ? |
737 | SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); | 731 | SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); |
732 | data = CR_FMT(CR_TDM_D) | (fsi->chan - 1); | ||
738 | break; | 733 | break; |
739 | default: | 734 | default: |
740 | dev_err(dai->dev, "unknown format.\n"); | 735 | dev_err(dai->dev, "unknown format.\n"); |
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c index d86ee1bfc03..eeed5edd722 100644 --- a/sound/soc/sh/siu_dai.c +++ b/sound/soc/sh/siu_dai.c | |||
@@ -588,6 +588,8 @@ static int siu_dai_prepare(struct snd_pcm_substream *substream, | |||
588 | ret = siu_dai_spbstart(port_info); | 588 | ret = siu_dai_spbstart(port_info); |
589 | if (ret < 0) | 589 | if (ret < 0) |
590 | goto fail; | 590 | goto fail; |
591 | } else { | ||
592 | ret = 0; | ||
591 | } | 593 | } |
592 | 594 | ||
593 | port_info->play_cap |= self; | 595 | port_info->play_cap |= self; |
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c index 4c7b051f9d1..1bc56b2b94e 100644 --- a/sound/spi/at73c213.c +++ b/sound/spi/at73c213.c | |||
@@ -69,7 +69,6 @@ struct snd_at73c213 { | |||
69 | int irq; | 69 | int irq; |
70 | int period; | 70 | int period; |
71 | unsigned long bitrate; | 71 | unsigned long bitrate; |
72 | struct clk *bitclk; | ||
73 | struct ssc_device *ssc; | 72 | struct ssc_device *ssc; |
74 | struct spi_device *spi; | 73 | struct spi_device *spi; |
75 | u8 spi_wbuffer[2]; | 74 | u8 spi_wbuffer[2]; |
diff --git a/sound/usb/Makefile b/sound/usb/Makefile index e7ac7f493a8..1e362bf8834 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile | |||
@@ -11,7 +11,8 @@ snd-usb-audio-objs := card.o \ | |||
11 | endpoint.o \ | 11 | endpoint.o \ |
12 | urb.o \ | 12 | urb.o \ |
13 | pcm.o \ | 13 | pcm.o \ |
14 | helper.o | 14 | helper.o \ |
15 | clock.o | ||
15 | 16 | ||
16 | snd-usbmidi-lib-objs := midi.o | 17 | snd-usbmidi-lib-objs := midi.o |
17 | 18 | ||
diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c index 36ed703a741..91c804cd278 100644 --- a/sound/usb/caiaq/control.c +++ b/sound/usb/caiaq/control.c | |||
@@ -42,21 +42,12 @@ static int control_info(struct snd_kcontrol *kcontrol, | |||
42 | 42 | ||
43 | switch (dev->chip.usb_id) { | 43 | switch (dev->chip.usb_id) { |
44 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): | 44 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): |
45 | if (pos == 0) { | ||
46 | /* current input mode of A8DJ */ | ||
47 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
48 | uinfo->value.integer.min = 0; | ||
49 | uinfo->value.integer.max = 2; | ||
50 | return 0; | ||
51 | } | ||
52 | break; | ||
53 | |||
54 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): | 45 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): |
55 | if (pos == 0) { | 46 | if (pos == 0) { |
56 | /* current input mode of A4DJ */ | 47 | /* current input mode of A8DJ and A4DJ */ |
57 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 48 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
58 | uinfo->value.integer.min = 0; | 49 | uinfo->value.integer.min = 0; |
59 | uinfo->value.integer.max = 1; | 50 | uinfo->value.integer.max = 2; |
60 | return 0; | 51 | return 0; |
61 | } | 52 | } |
62 | break; | 53 | break; |
@@ -86,14 +77,6 @@ static int control_get(struct snd_kcontrol *kcontrol, | |||
86 | struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); | 77 | struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); |
87 | int pos = kcontrol->private_value; | 78 | int pos = kcontrol->private_value; |
88 | 79 | ||
89 | if (dev->chip.usb_id == | ||
90 | USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ)) { | ||
91 | /* A4DJ has only one control */ | ||
92 | /* do not expose hardware input mode 0 */ | ||
93 | ucontrol->value.integer.value[0] = dev->control_state[0] - 1; | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | if (pos & CNT_INTVAL) | 80 | if (pos & CNT_INTVAL) |
98 | ucontrol->value.integer.value[0] | 81 | ucontrol->value.integer.value[0] |
99 | = dev->control_state[pos & ~CNT_INTVAL]; | 82 | = dev->control_state[pos & ~CNT_INTVAL]; |
@@ -112,20 +95,9 @@ static int control_put(struct snd_kcontrol *kcontrol, | |||
112 | int pos = kcontrol->private_value; | 95 | int pos = kcontrol->private_value; |
113 | unsigned char cmd = EP1_CMD_WRITE_IO; | 96 | unsigned char cmd = EP1_CMD_WRITE_IO; |
114 | 97 | ||
115 | switch (dev->chip.usb_id) { | 98 | if (dev->chip.usb_id == |
116 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): { | 99 | USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1)) |
117 | /* A4DJ has only one control */ | ||
118 | /* do not expose hardware input mode 0 */ | ||
119 | dev->control_state[0] = ucontrol->value.integer.value[0] + 1; | ||
120 | snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, | ||
121 | dev->control_state, sizeof(dev->control_state)); | ||
122 | return 1; | ||
123 | } | ||
124 | |||
125 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | ||
126 | cmd = EP1_CMD_DIMM_LEDS; | 100 | cmd = EP1_CMD_DIMM_LEDS; |
127 | break; | ||
128 | } | ||
129 | 101 | ||
130 | if (pos & CNT_INTVAL) { | 102 | if (pos & CNT_INTVAL) { |
131 | dev->control_state[pos & ~CNT_INTVAL] | 103 | dev->control_state[pos & ~CNT_INTVAL] |
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index 80527182767..cdfb856bddd 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include "input.h" | 36 | #include "input.h" |
37 | 37 | ||
38 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); | 38 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); |
39 | MODULE_DESCRIPTION("caiaq USB audio, version 1.3.20"); | 39 | MODULE_DESCRIPTION("caiaq USB audio, version 1.3.21"); |
40 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
41 | MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," | 41 | MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," |
42 | "{Native Instruments, RigKontrol3}," | 42 | "{Native Instruments, RigKontrol3}," |
@@ -320,12 +320,6 @@ static void __devinit setup_card(struct snd_usb_caiaqdev *dev) | |||
320 | } | 320 | } |
321 | 321 | ||
322 | break; | 322 | break; |
323 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): | ||
324 | /* Audio 4 DJ - default input mode to phono */ | ||
325 | dev->control_state[0] = 2; | ||
326 | snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, | ||
327 | dev->control_state, 1); | ||
328 | break; | ||
329 | } | 323 | } |
330 | 324 | ||
331 | if (dev->spec.num_analog_audio_out + | 325 | if (dev->spec.num_analog_audio_out + |
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c index 8bbfbfd4c65..dcb620796d9 100644 --- a/sound/usb/caiaq/input.c +++ b/sound/usb/caiaq/input.c | |||
@@ -171,7 +171,7 @@ static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, | |||
171 | input_report_abs(input_dev, ABS_HAT0Y, (buf[4] << 8) | buf[5]); | 171 | input_report_abs(input_dev, ABS_HAT0Y, (buf[4] << 8) | buf[5]); |
172 | input_report_abs(input_dev, ABS_HAT1X, (buf[12] << 8) | buf[13]); | 172 | input_report_abs(input_dev, ABS_HAT1X, (buf[12] << 8) | buf[13]); |
173 | input_report_abs(input_dev, ABS_HAT1Y, (buf[2] << 8) | buf[3]); | 173 | input_report_abs(input_dev, ABS_HAT1Y, (buf[2] << 8) | buf[3]); |
174 | input_report_abs(input_dev, ABS_HAT2X, (buf[15] << 8) | buf[15]); | 174 | input_report_abs(input_dev, ABS_HAT2X, (buf[14] << 8) | buf[15]); |
175 | input_report_abs(input_dev, ABS_HAT2Y, (buf[0] << 8) | buf[1]); | 175 | input_report_abs(input_dev, ABS_HAT2Y, (buf[0] << 8) | buf[1]); |
176 | input_report_abs(input_dev, ABS_HAT3X, (buf[10] << 8) | buf[11]); | 176 | input_report_abs(input_dev, ABS_HAT3X, (buf[10] << 8) | buf[11]); |
177 | input_report_abs(input_dev, ABS_HAT3Y, (buf[6] << 8) | buf[7]); | 177 | input_report_abs(input_dev, ABS_HAT3Y, (buf[6] << 8) | buf[7]); |
diff --git a/sound/usb/card.c b/sound/usb/card.c index da1346bd485..7a8ac1d81be 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -236,7 +236,6 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
236 | } | 236 | } |
237 | 237 | ||
238 | case UAC_VERSION_2: { | 238 | case UAC_VERSION_2: { |
239 | struct uac_clock_source_descriptor *cs; | ||
240 | struct usb_interface_assoc_descriptor *assoc = | 239 | struct usb_interface_assoc_descriptor *assoc = |
241 | usb_ifnum_to_if(dev, ctrlif)->intf_assoc; | 240 | usb_ifnum_to_if(dev, ctrlif)->intf_assoc; |
242 | 241 | ||
@@ -245,21 +244,6 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
245 | return -EINVAL; | 244 | return -EINVAL; |
246 | } | 245 | } |
247 | 246 | ||
248 | /* FIXME: for now, we expect there is at least one clock source | ||
249 | * descriptor and we always take the first one. | ||
250 | * We should properly support devices with multiple clock sources, | ||
251 | * clock selectors and sample rate conversion units. */ | ||
252 | |||
253 | cs = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen, | ||
254 | NULL, UAC2_CLOCK_SOURCE); | ||
255 | |||
256 | if (!cs) { | ||
257 | snd_printk(KERN_ERR "CLOCK_SOURCE descriptor not found\n"); | ||
258 | return -EINVAL; | ||
259 | } | ||
260 | |||
261 | chip->clock_id = cs->bClockID; | ||
262 | |||
263 | for (i = 0; i < assoc->bInterfaceCount; i++) { | 247 | for (i = 0; i < assoc->bInterfaceCount; i++) { |
264 | int intf = assoc->bFirstInterface + i; | 248 | int intf = assoc->bFirstInterface + i; |
265 | 249 | ||
@@ -481,6 +465,8 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
481 | goto __error; | 465 | goto __error; |
482 | } | 466 | } |
483 | 467 | ||
468 | chip->ctrl_intf = alts; | ||
469 | |||
484 | if (err > 0) { | 470 | if (err > 0) { |
485 | /* create normal USB audio interfaces */ | 471 | /* create normal USB audio interfaces */ |
486 | if (snd_usb_create_streams(chip, ifnum) < 0 || | 472 | if (snd_usb_create_streams(chip, ifnum) < 0 || |
diff --git a/sound/usb/card.h b/sound/usb/card.h index ed92420c109..1febf2f2375 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
@@ -25,6 +25,7 @@ struct audioformat { | |||
25 | unsigned int rate_min, rate_max; /* min/max rates */ | 25 | unsigned int rate_min, rate_max; /* min/max rates */ |
26 | unsigned int nr_rates; /* number of rate table entries */ | 26 | unsigned int nr_rates; /* number of rate table entries */ |
27 | unsigned int *rate_table; /* rate table */ | 27 | unsigned int *rate_table; /* rate table */ |
28 | unsigned char clock; /* associated clock */ | ||
28 | }; | 29 | }; |
29 | 30 | ||
30 | struct snd_usb_substream; | 31 | struct snd_usb_substream; |
diff --git a/sound/usb/clock.c b/sound/usb/clock.c new file mode 100644 index 00000000000..b5855114667 --- /dev/null +++ b/sound/usb/clock.c | |||
@@ -0,0 +1,315 @@ | |||
1 | /* | ||
2 | * Clock domain and sample rate management functions | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/bitops.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/list.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/string.h> | ||
25 | #include <linux/usb.h> | ||
26 | #include <linux/moduleparam.h> | ||
27 | #include <linux/mutex.h> | ||
28 | #include <linux/usb/audio.h> | ||
29 | #include <linux/usb/audio-v2.h> | ||
30 | |||
31 | #include <sound/core.h> | ||
32 | #include <sound/info.h> | ||
33 | #include <sound/pcm.h> | ||
34 | #include <sound/pcm_params.h> | ||
35 | #include <sound/initval.h> | ||
36 | |||
37 | #include "usbaudio.h" | ||
38 | #include "card.h" | ||
39 | #include "midi.h" | ||
40 | #include "mixer.h" | ||
41 | #include "proc.h" | ||
42 | #include "quirks.h" | ||
43 | #include "endpoint.h" | ||
44 | #include "helper.h" | ||
45 | #include "debug.h" | ||
46 | #include "pcm.h" | ||
47 | #include "urb.h" | ||
48 | #include "format.h" | ||
49 | |||
50 | static struct uac_clock_source_descriptor * | ||
51 | snd_usb_find_clock_source(struct usb_host_interface *ctrl_iface, | ||
52 | int clock_id) | ||
53 | { | ||
54 | struct uac_clock_source_descriptor *cs = NULL; | ||
55 | |||
56 | while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, | ||
57 | ctrl_iface->extralen, | ||
58 | cs, UAC2_CLOCK_SOURCE))) { | ||
59 | if (cs->bClockID == clock_id) | ||
60 | return cs; | ||
61 | } | ||
62 | |||
63 | return NULL; | ||
64 | } | ||
65 | |||
66 | static struct uac_clock_selector_descriptor * | ||
67 | snd_usb_find_clock_selector(struct usb_host_interface *ctrl_iface, | ||
68 | int clock_id) | ||
69 | { | ||
70 | struct uac_clock_selector_descriptor *cs = NULL; | ||
71 | |||
72 | while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, | ||
73 | ctrl_iface->extralen, | ||
74 | cs, UAC2_CLOCK_SELECTOR))) { | ||
75 | if (cs->bClockID == clock_id) | ||
76 | return cs; | ||
77 | } | ||
78 | |||
79 | return NULL; | ||
80 | } | ||
81 | |||
82 | static struct uac_clock_multiplier_descriptor * | ||
83 | snd_usb_find_clock_multiplier(struct usb_host_interface *ctrl_iface, | ||
84 | int clock_id) | ||
85 | { | ||
86 | struct uac_clock_multiplier_descriptor *cs = NULL; | ||
87 | |||
88 | while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, | ||
89 | ctrl_iface->extralen, | ||
90 | cs, UAC2_CLOCK_MULTIPLIER))) { | ||
91 | if (cs->bClockID == clock_id) | ||
92 | return cs; | ||
93 | } | ||
94 | |||
95 | return NULL; | ||
96 | } | ||
97 | |||
98 | static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_id) | ||
99 | { | ||
100 | unsigned char buf; | ||
101 | int ret; | ||
102 | |||
103 | ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), | ||
104 | UAC2_CS_CUR, | ||
105 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
106 | UAC2_CX_CLOCK_SELECTOR << 8, | ||
107 | snd_usb_ctrl_intf(chip) | (selector_id << 8), | ||
108 | &buf, sizeof(buf), 1000); | ||
109 | |||
110 | if (ret < 0) | ||
111 | return ret; | ||
112 | |||
113 | return buf; | ||
114 | } | ||
115 | |||
116 | static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id) | ||
117 | { | ||
118 | int err; | ||
119 | unsigned char data; | ||
120 | struct usb_device *dev = chip->dev; | ||
121 | |||
122 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, | ||
123 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
124 | UAC2_CS_CONTROL_CLOCK_VALID << 8, | ||
125 | snd_usb_ctrl_intf(chip) | (source_id << 8), | ||
126 | &data, sizeof(data), 1000); | ||
127 | |||
128 | if (err < 0) { | ||
129 | snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n", | ||
130 | __func__, source_id); | ||
131 | return err; | ||
132 | } | ||
133 | |||
134 | return !!data; | ||
135 | } | ||
136 | |||
137 | /* Try to find the clock source ID of a given clock entity */ | ||
138 | |||
139 | static int __uac_clock_find_source(struct snd_usb_audio *chip, | ||
140 | struct usb_host_interface *host_iface, | ||
141 | int entity_id, unsigned long *visited) | ||
142 | { | ||
143 | struct uac_clock_source_descriptor *source; | ||
144 | struct uac_clock_selector_descriptor *selector; | ||
145 | struct uac_clock_multiplier_descriptor *multiplier; | ||
146 | |||
147 | entity_id &= 0xff; | ||
148 | |||
149 | if (test_and_set_bit(entity_id, visited)) { | ||
150 | snd_printk(KERN_WARNING | ||
151 | "%s(): recursive clock topology detected, id %d.\n", | ||
152 | __func__, entity_id); | ||
153 | return -EINVAL; | ||
154 | } | ||
155 | |||
156 | /* first, see if the ID we're looking for is a clock source already */ | ||
157 | source = snd_usb_find_clock_source(host_iface, entity_id); | ||
158 | if (source) | ||
159 | return source->bClockID; | ||
160 | |||
161 | selector = snd_usb_find_clock_selector(host_iface, entity_id); | ||
162 | if (selector) { | ||
163 | int ret; | ||
164 | |||
165 | /* the entity ID we are looking for is a selector. | ||
166 | * find out what it currently selects */ | ||
167 | ret = uac_clock_selector_get_val(chip, selector->bClockID); | ||
168 | if (ret < 0) | ||
169 | return ret; | ||
170 | |||
171 | if (ret > selector->bNrInPins || ret < 1) { | ||
172 | printk(KERN_ERR | ||
173 | "%s(): selector reported illegal value, id %d, ret %d\n", | ||
174 | __func__, selector->bClockID, ret); | ||
175 | |||
176 | return -EINVAL; | ||
177 | } | ||
178 | |||
179 | return __uac_clock_find_source(chip, host_iface, | ||
180 | selector->baCSourceID[ret-1], | ||
181 | visited); | ||
182 | } | ||
183 | |||
184 | /* FIXME: multipliers only act as pass-thru element for now */ | ||
185 | multiplier = snd_usb_find_clock_multiplier(host_iface, entity_id); | ||
186 | if (multiplier) | ||
187 | return __uac_clock_find_source(chip, host_iface, | ||
188 | multiplier->bCSourceID, visited); | ||
189 | |||
190 | return -EINVAL; | ||
191 | } | ||
192 | |||
193 | int snd_usb_clock_find_source(struct snd_usb_audio *chip, | ||
194 | struct usb_host_interface *host_iface, | ||
195 | int entity_id) | ||
196 | { | ||
197 | DECLARE_BITMAP(visited, 256); | ||
198 | memset(visited, 0, sizeof(visited)); | ||
199 | return __uac_clock_find_source(chip, host_iface, entity_id, visited); | ||
200 | } | ||
201 | |||
202 | static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, | ||
203 | struct usb_host_interface *alts, | ||
204 | struct audioformat *fmt, int rate) | ||
205 | { | ||
206 | struct usb_device *dev = chip->dev; | ||
207 | unsigned int ep; | ||
208 | unsigned char data[3]; | ||
209 | int err, crate; | ||
210 | |||
211 | ep = get_endpoint(alts, 0)->bEndpointAddress; | ||
212 | |||
213 | /* if endpoint doesn't have sampling rate control, bail out */ | ||
214 | if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE)) { | ||
215 | snd_printk(KERN_WARNING "%d:%d:%d: endpoint lacks sample rate attribute bit, cannot set.\n", | ||
216 | dev->devnum, iface, fmt->altsetting); | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | data[0] = rate; | ||
221 | data[1] = rate >> 8; | ||
222 | data[2] = rate >> 16; | ||
223 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, | ||
224 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, | ||
225 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, | ||
226 | data, sizeof(data), 1000)) < 0) { | ||
227 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n", | ||
228 | dev->devnum, iface, fmt->altsetting, rate, ep); | ||
229 | return err; | ||
230 | } | ||
231 | |||
232 | if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR, | ||
233 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN, | ||
234 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, | ||
235 | data, sizeof(data), 1000)) < 0) { | ||
236 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n", | ||
237 | dev->devnum, iface, fmt->altsetting, ep); | ||
238 | return 0; /* some devices don't support reading */ | ||
239 | } | ||
240 | |||
241 | crate = data[0] | (data[1] << 8) | (data[2] << 16); | ||
242 | if (crate != rate) { | ||
243 | snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate); | ||
244 | // runtime->rate = crate; | ||
245 | } | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | ||
251 | struct usb_host_interface *alts, | ||
252 | struct audioformat *fmt, int rate) | ||
253 | { | ||
254 | struct usb_device *dev = chip->dev; | ||
255 | unsigned char data[4]; | ||
256 | int err, crate; | ||
257 | int clock = snd_usb_clock_find_source(chip, chip->ctrl_intf, fmt->clock); | ||
258 | |||
259 | if (clock < 0) | ||
260 | return clock; | ||
261 | |||
262 | if (!uac_clock_source_is_valid(chip, clock)) { | ||
263 | snd_printk(KERN_ERR "%d:%d:%d: clock source %d is not valid, cannot use\n", | ||
264 | dev->devnum, iface, fmt->altsetting, clock); | ||
265 | return -ENXIO; | ||
266 | } | ||
267 | |||
268 | data[0] = rate; | ||
269 | data[1] = rate >> 8; | ||
270 | data[2] = rate >> 16; | ||
271 | data[3] = rate >> 24; | ||
272 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, | ||
273 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | ||
274 | UAC2_CS_CONTROL_SAM_FREQ << 8, | ||
275 | snd_usb_ctrl_intf(chip) | (clock << 8), | ||
276 | data, sizeof(data), 1000)) < 0) { | ||
277 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n", | ||
278 | dev->devnum, iface, fmt->altsetting, rate); | ||
279 | return err; | ||
280 | } | ||
281 | |||
282 | if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, | ||
283 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
284 | UAC2_CS_CONTROL_SAM_FREQ << 8, | ||
285 | snd_usb_ctrl_intf(chip) | (clock << 8), | ||
286 | data, sizeof(data), 1000)) < 0) { | ||
287 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", | ||
288 | dev->devnum, iface, fmt->altsetting); | ||
289 | return err; | ||
290 | } | ||
291 | |||
292 | crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); | ||
293 | if (crate != rate) | ||
294 | snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate); | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface, | ||
300 | struct usb_host_interface *alts, | ||
301 | struct audioformat *fmt, int rate) | ||
302 | { | ||
303 | struct usb_interface_descriptor *altsd = get_iface_desc(alts); | ||
304 | |||
305 | switch (altsd->bInterfaceProtocol) { | ||
306 | case UAC_VERSION_1: | ||
307 | return set_sample_rate_v1(chip, iface, alts, fmt, rate); | ||
308 | |||
309 | case UAC_VERSION_2: | ||
310 | return set_sample_rate_v2(chip, iface, alts, fmt, rate); | ||
311 | } | ||
312 | |||
313 | return -EINVAL; | ||
314 | } | ||
315 | |||
diff --git a/sound/usb/clock.h b/sound/usb/clock.h new file mode 100644 index 00000000000..beb253684e2 --- /dev/null +++ b/sound/usb/clock.h | |||
@@ -0,0 +1,12 @@ | |||
1 | #ifndef __USBAUDIO_CLOCK_H | ||
2 | #define __USBAUDIO_CLOCK_H | ||
3 | |||
4 | int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface, | ||
5 | struct usb_host_interface *alts, | ||
6 | struct audioformat *fmt, int rate); | ||
7 | |||
8 | int snd_usb_clock_find_source(struct snd_usb_audio *chip, | ||
9 | struct usb_host_interface *host_iface, | ||
10 | int entity_id); | ||
11 | |||
12 | #endif /* __USBAUDIO_CLOCK_H */ | ||
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index ef07a6d0dd5..6f6596cf2b1 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -149,6 +149,79 @@ int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct au | |||
149 | return 0; | 149 | return 0; |
150 | } | 150 | } |
151 | 151 | ||
152 | static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip, | ||
153 | struct usb_host_interface *alts, | ||
154 | int protocol, int iface_no) | ||
155 | { | ||
156 | /* parsed with a v1 header here. that's ok as we only look at the | ||
157 | * header first which is the same for both versions */ | ||
158 | struct uac_iso_endpoint_descriptor *csep; | ||
159 | struct usb_interface_descriptor *altsd = get_iface_desc(alts); | ||
160 | int attributes = 0; | ||
161 | |||
162 | csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT); | ||
163 | |||
164 | /* Creamware Noah has this descriptor after the 2nd endpoint */ | ||
165 | if (!csep && altsd->bNumEndpoints >= 2) | ||
166 | csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); | ||
167 | |||
168 | if (!csep || csep->bLength < 7 || | ||
169 | csep->bDescriptorSubtype != UAC_EP_GENERAL) { | ||
170 | snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" | ||
171 | " class specific endpoint descriptor\n", | ||
172 | chip->dev->devnum, iface_no, | ||
173 | altsd->bAlternateSetting); | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | if (protocol == UAC_VERSION_1) { | ||
178 | attributes = csep->bmAttributes; | ||
179 | } else { | ||
180 | struct uac2_iso_endpoint_descriptor *csep2 = | ||
181 | (struct uac2_iso_endpoint_descriptor *) csep; | ||
182 | |||
183 | attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX; | ||
184 | |||
185 | /* emulate the endpoint attributes of a v1 device */ | ||
186 | if (csep2->bmControls & UAC2_CONTROL_PITCH) | ||
187 | attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL; | ||
188 | } | ||
189 | |||
190 | return attributes; | ||
191 | } | ||
192 | |||
193 | static struct uac2_input_terminal_descriptor * | ||
194 | snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface, | ||
195 | int terminal_id) | ||
196 | { | ||
197 | struct uac2_input_terminal_descriptor *term = NULL; | ||
198 | |||
199 | while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, | ||
200 | ctrl_iface->extralen, | ||
201 | term, UAC_INPUT_TERMINAL))) { | ||
202 | if (term->bTerminalID == terminal_id) | ||
203 | return term; | ||
204 | } | ||
205 | |||
206 | return NULL; | ||
207 | } | ||
208 | |||
209 | static struct uac2_output_terminal_descriptor * | ||
210 | snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface, | ||
211 | int terminal_id) | ||
212 | { | ||
213 | struct uac2_output_terminal_descriptor *term = NULL; | ||
214 | |||
215 | while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, | ||
216 | ctrl_iface->extralen, | ||
217 | term, UAC_OUTPUT_TERMINAL))) { | ||
218 | if (term->bTerminalID == terminal_id) | ||
219 | return term; | ||
220 | } | ||
221 | |||
222 | return NULL; | ||
223 | } | ||
224 | |||
152 | int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | 225 | int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) |
153 | { | 226 | { |
154 | struct usb_device *dev; | 227 | struct usb_device *dev; |
@@ -158,8 +231,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
158 | int i, altno, err, stream; | 231 | int i, altno, err, stream; |
159 | int format = 0, num_channels = 0; | 232 | int format = 0, num_channels = 0; |
160 | struct audioformat *fp = NULL; | 233 | struct audioformat *fp = NULL; |
161 | unsigned char *fmt, *csep; | 234 | int num, protocol, clock = 0; |
162 | int num, protocol; | 235 | struct uac_format_type_i_continuous_descriptor *fmt; |
163 | 236 | ||
164 | dev = chip->dev; | 237 | dev = chip->dev; |
165 | 238 | ||
@@ -222,6 +295,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
222 | } | 295 | } |
223 | 296 | ||
224 | case UAC_VERSION_2: { | 297 | case UAC_VERSION_2: { |
298 | struct uac2_input_terminal_descriptor *input_term; | ||
299 | struct uac2_output_terminal_descriptor *output_term; | ||
225 | struct uac_as_header_descriptor_v2 *as = | 300 | struct uac_as_header_descriptor_v2 *as = |
226 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); | 301 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); |
227 | 302 | ||
@@ -240,7 +315,25 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
240 | num_channels = as->bNrChannels; | 315 | num_channels = as->bNrChannels; |
241 | format = le32_to_cpu(as->bmFormats); | 316 | format = le32_to_cpu(as->bmFormats); |
242 | 317 | ||
243 | break; | 318 | /* lookup the terminal associated to this interface |
319 | * to extract the clock */ | ||
320 | input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, | ||
321 | as->bTerminalLink); | ||
322 | if (input_term) { | ||
323 | clock = input_term->bCSourceID; | ||
324 | break; | ||
325 | } | ||
326 | |||
327 | output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, | ||
328 | as->bTerminalLink); | ||
329 | if (output_term) { | ||
330 | clock = output_term->bCSourceID; | ||
331 | break; | ||
332 | } | ||
333 | |||
334 | snd_printk(KERN_ERR "%d:%u:%d : bogus bTerminalLink %d\n", | ||
335 | dev->devnum, iface_no, altno, as->bTerminalLink); | ||
336 | continue; | ||
244 | } | 337 | } |
245 | 338 | ||
246 | default: | 339 | default: |
@@ -256,8 +349,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
256 | dev->devnum, iface_no, altno); | 349 | dev->devnum, iface_no, altno); |
257 | continue; | 350 | continue; |
258 | } | 351 | } |
259 | if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) || | 352 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || |
260 | ((protocol == UAC_VERSION_2) && (fmt[0] != 6))) { | 353 | ((protocol == UAC_VERSION_2) && (fmt->bLength != 6))) { |
261 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", | 354 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", |
262 | dev->devnum, iface_no, altno); | 355 | dev->devnum, iface_no, altno); |
263 | continue; | 356 | continue; |
@@ -268,7 +361,9 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
268 | * with the previous one, except for a larger packet size, but | 361 | * with the previous one, except for a larger packet size, but |
269 | * is actually a mislabeled two-channel setting; ignore it. | 362 | * is actually a mislabeled two-channel setting; ignore it. |
270 | */ | 363 | */ |
271 | if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 && | 364 | if (fmt->bNrChannels == 1 && |
365 | fmt->bSubframeSize == 2 && | ||
366 | altno == 2 && num == 3 && | ||
272 | fp && fp->altsetting == 1 && fp->channels == 1 && | 367 | fp && fp->altsetting == 1 && fp->channels == 1 && |
273 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && | 368 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && |
274 | protocol == UAC_VERSION_1 && | 369 | protocol == UAC_VERSION_1 && |
@@ -276,17 +371,6 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
276 | fp->maxpacksize * 2) | 371 | fp->maxpacksize * 2) |
277 | continue; | 372 | continue; |
278 | 373 | ||
279 | csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT); | ||
280 | /* Creamware Noah has this descriptor after the 2nd endpoint */ | ||
281 | if (!csep && altsd->bNumEndpoints >= 2) | ||
282 | csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); | ||
283 | if (!csep || csep[0] < 7 || csep[2] != UAC_EP_GENERAL) { | ||
284 | snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" | ||
285 | " class specific endpoint descriptor\n", | ||
286 | dev->devnum, iface_no, altno); | ||
287 | csep = NULL; | ||
288 | } | ||
289 | |||
290 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); | 374 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); |
291 | if (! fp) { | 375 | if (! fp) { |
292 | snd_printk(KERN_ERR "cannot malloc\n"); | 376 | snd_printk(KERN_ERR "cannot malloc\n"); |
@@ -305,7 +389,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
305 | if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) | 389 | if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) |
306 | fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) | 390 | fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) |
307 | * (fp->maxpacksize & 0x7ff); | 391 | * (fp->maxpacksize & 0x7ff); |
308 | fp->attributes = csep ? csep[3] : 0; | 392 | fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no); |
393 | fp->clock = clock; | ||
309 | 394 | ||
310 | /* some quirks for attributes here */ | 395 | /* some quirks for attributes here */ |
311 | 396 | ||
@@ -342,6 +427,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
342 | if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) { | 427 | if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) { |
343 | kfree(fp->rate_table); | 428 | kfree(fp->rate_table); |
344 | kfree(fp); | 429 | kfree(fp); |
430 | fp = NULL; | ||
345 | continue; | 431 | continue; |
346 | } | 432 | } |
347 | 433 | ||
diff --git a/sound/usb/format.c b/sound/usb/format.c index b87cf87c4e7..30364aba79c 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "quirks.h" | 29 | #include "quirks.h" |
30 | #include "helper.h" | 30 | #include "helper.h" |
31 | #include "debug.h" | 31 | #include "debug.h" |
32 | #include "clock.h" | ||
32 | 33 | ||
33 | /* | 34 | /* |
34 | * parse the audio format type I descriptor | 35 | * parse the audio format type I descriptor |
@@ -205,6 +206,60 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof | |||
205 | } | 206 | } |
206 | 207 | ||
207 | /* | 208 | /* |
209 | * Helper function to walk the array of sample rate triplets reported by | ||
210 | * the device. The problem is that we need to parse whole array first to | ||
211 | * get to know how many sample rates we have to expect. | ||
212 | * Then fp->rate_table can be allocated and filled. | ||
213 | */ | ||
214 | static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets, | ||
215 | const unsigned char *data) | ||
216 | { | ||
217 | int i, nr_rates = 0; | ||
218 | |||
219 | fp->rates = fp->rate_min = fp->rate_max = 0; | ||
220 | |||
221 | for (i = 0; i < nr_triplets; i++) { | ||
222 | int min = combine_quad(&data[2 + 12 * i]); | ||
223 | int max = combine_quad(&data[6 + 12 * i]); | ||
224 | int res = combine_quad(&data[10 + 12 * i]); | ||
225 | int rate; | ||
226 | |||
227 | if ((max < 0) || (min < 0) || (res < 0) || (max < min)) | ||
228 | continue; | ||
229 | |||
230 | /* | ||
231 | * for ranges with res == 1, we announce a continuous sample | ||
232 | * rate range, and this function should return 0 for no further | ||
233 | * parsing. | ||
234 | */ | ||
235 | if (res == 1) { | ||
236 | fp->rate_min = min; | ||
237 | fp->rate_max = max; | ||
238 | fp->rates = SNDRV_PCM_RATE_CONTINUOUS; | ||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | for (rate = min; rate <= max; rate += res) { | ||
243 | if (fp->rate_table) | ||
244 | fp->rate_table[nr_rates] = rate; | ||
245 | if (!fp->rate_min || rate < fp->rate_min) | ||
246 | fp->rate_min = rate; | ||
247 | if (!fp->rate_max || rate > fp->rate_max) | ||
248 | fp->rate_max = rate; | ||
249 | fp->rates |= snd_pcm_rate_to_rate_bit(rate); | ||
250 | |||
251 | nr_rates++; | ||
252 | |||
253 | /* avoid endless loop */ | ||
254 | if (res == 0) | ||
255 | break; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | return nr_rates; | ||
260 | } | ||
261 | |||
262 | /* | ||
208 | * parse the format descriptor and stores the possible sample rates | 263 | * parse the format descriptor and stores the possible sample rates |
209 | * on the audioformat table (audio class v2). | 264 | * on the audioformat table (audio class v2). |
210 | */ | 265 | */ |
@@ -214,21 +269,30 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, | |||
214 | { | 269 | { |
215 | struct usb_device *dev = chip->dev; | 270 | struct usb_device *dev = chip->dev; |
216 | unsigned char tmp[2], *data; | 271 | unsigned char tmp[2], *data; |
217 | int i, nr_rates, data_size, ret = 0; | 272 | int nr_triplets, data_size, ret = 0; |
273 | int clock = snd_usb_clock_find_source(chip, chip->ctrl_intf, fp->clock); | ||
274 | |||
275 | if (clock < 0) { | ||
276 | snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n", | ||
277 | __func__, clock); | ||
278 | goto err; | ||
279 | } | ||
218 | 280 | ||
219 | /* get the number of sample rates first by only fetching 2 bytes */ | 281 | /* get the number of sample rates first by only fetching 2 bytes */ |
220 | ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, | 282 | ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, |
221 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 283 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
222 | UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8, | 284 | UAC2_CS_CONTROL_SAM_FREQ << 8, |
285 | snd_usb_ctrl_intf(chip) | (clock << 8), | ||
223 | tmp, sizeof(tmp), 1000); | 286 | tmp, sizeof(tmp), 1000); |
224 | 287 | ||
225 | if (ret < 0) { | 288 | if (ret < 0) { |
226 | snd_printk(KERN_ERR "unable to retrieve number of sample rates\n"); | 289 | snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n", |
290 | __func__, clock); | ||
227 | goto err; | 291 | goto err; |
228 | } | 292 | } |
229 | 293 | ||
230 | nr_rates = (tmp[1] << 8) | tmp[0]; | 294 | nr_triplets = (tmp[1] << 8) | tmp[0]; |
231 | data_size = 2 + 12 * nr_rates; | 295 | data_size = 2 + 12 * nr_triplets; |
232 | data = kzalloc(data_size, GFP_KERNEL); | 296 | data = kzalloc(data_size, GFP_KERNEL); |
233 | if (!data) { | 297 | if (!data) { |
234 | ret = -ENOMEM; | 298 | ret = -ENOMEM; |
@@ -237,36 +301,40 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, | |||
237 | 301 | ||
238 | /* now get the full information */ | 302 | /* now get the full information */ |
239 | ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, | 303 | ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, |
240 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 304 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
241 | UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8, | 305 | UAC2_CS_CONTROL_SAM_FREQ << 8, |
242 | data, data_size, 1000); | 306 | snd_usb_ctrl_intf(chip) | (clock << 8), |
307 | data, data_size, 1000); | ||
243 | 308 | ||
244 | if (ret < 0) { | 309 | if (ret < 0) { |
245 | snd_printk(KERN_ERR "unable to retrieve sample rate range\n"); | 310 | snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n", |
311 | __func__, clock); | ||
246 | ret = -EINVAL; | 312 | ret = -EINVAL; |
247 | goto err_free; | 313 | goto err_free; |
248 | } | 314 | } |
249 | 315 | ||
250 | fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); | 316 | /* Call the triplet parser, and make sure fp->rate_table is NULL. |
317 | * We just use the return value to know how many sample rates we | ||
318 | * will have to deal with. */ | ||
319 | kfree(fp->rate_table); | ||
320 | fp->rate_table = NULL; | ||
321 | fp->nr_rates = parse_uac2_sample_rate_range(fp, nr_triplets, data); | ||
322 | |||
323 | if (fp->nr_rates == 0) { | ||
324 | /* SNDRV_PCM_RATE_CONTINUOUS */ | ||
325 | ret = 0; | ||
326 | goto err_free; | ||
327 | } | ||
328 | |||
329 | fp->rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL); | ||
251 | if (!fp->rate_table) { | 330 | if (!fp->rate_table) { |
252 | ret = -ENOMEM; | 331 | ret = -ENOMEM; |
253 | goto err_free; | 332 | goto err_free; |
254 | } | 333 | } |
255 | 334 | ||
256 | fp->nr_rates = 0; | 335 | /* Call the triplet parser again, but this time, fp->rate_table is |
257 | fp->rate_min = fp->rate_max = 0; | 336 | * allocated, so the rates will be stored */ |
258 | 337 | parse_uac2_sample_rate_range(fp, nr_triplets, data); | |
259 | for (i = 0; i < nr_rates; i++) { | ||
260 | int rate = combine_quad(&data[2 + 12 * i]); | ||
261 | |||
262 | fp->rate_table[fp->nr_rates] = rate; | ||
263 | if (!fp->rate_min || rate < fp->rate_min) | ||
264 | fp->rate_min = rate; | ||
265 | if (!fp->rate_max || rate > fp->rate_max) | ||
266 | fp->rate_max = rate; | ||
267 | fp->rates |= snd_pcm_rate_to_rate_bit(rate); | ||
268 | fp->nr_rates++; | ||
269 | } | ||
270 | 338 | ||
271 | err_free: | 339 | err_free: |
272 | kfree(data); | 340 | kfree(data); |
@@ -278,12 +346,11 @@ err: | |||
278 | * parse the format type I and III descriptors | 346 | * parse the format type I and III descriptors |
279 | */ | 347 | */ |
280 | static int parse_audio_format_i(struct snd_usb_audio *chip, | 348 | static int parse_audio_format_i(struct snd_usb_audio *chip, |
281 | struct audioformat *fp, | 349 | struct audioformat *fp, int format, |
282 | int format, void *_fmt, | 350 | struct uac_format_type_i_continuous_descriptor *fmt, |
283 | struct usb_host_interface *iface) | 351 | struct usb_host_interface *iface) |
284 | { | 352 | { |
285 | struct usb_interface_descriptor *altsd = get_iface_desc(iface); | 353 | struct usb_interface_descriptor *altsd = get_iface_desc(iface); |
286 | struct uac_format_type_i_discrete_descriptor *fmt = _fmt; | ||
287 | int protocol = altsd->bInterfaceProtocol; | 354 | int protocol = altsd->bInterfaceProtocol; |
288 | int pcm_format, ret; | 355 | int pcm_format, ret; |
289 | 356 | ||
@@ -320,7 +387,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
320 | switch (protocol) { | 387 | switch (protocol) { |
321 | case UAC_VERSION_1: | 388 | case UAC_VERSION_1: |
322 | fp->channels = fmt->bNrChannels; | 389 | fp->channels = fmt->bNrChannels; |
323 | ret = parse_audio_format_rates_v1(chip, fp, _fmt, 7); | 390 | ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7); |
324 | break; | 391 | break; |
325 | case UAC_VERSION_2: | 392 | case UAC_VERSION_2: |
326 | /* fp->channels is already set in this case */ | 393 | /* fp->channels is already set in this case */ |
@@ -392,12 +459,12 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, | |||
392 | } | 459 | } |
393 | 460 | ||
394 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, | 461 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, |
395 | int format, unsigned char *fmt, int stream, | 462 | int format, struct uac_format_type_i_continuous_descriptor *fmt, |
396 | struct usb_host_interface *iface) | 463 | int stream, struct usb_host_interface *iface) |
397 | { | 464 | { |
398 | int err; | 465 | int err; |
399 | 466 | ||
400 | switch (fmt[3]) { | 467 | switch (fmt->bFormatType) { |
401 | case UAC_FORMAT_TYPE_I: | 468 | case UAC_FORMAT_TYPE_I: |
402 | case UAC_FORMAT_TYPE_III: | 469 | case UAC_FORMAT_TYPE_III: |
403 | err = parse_audio_format_i(chip, fp, format, fmt, iface); | 470 | err = parse_audio_format_i(chip, fp, format, fmt, iface); |
@@ -407,10 +474,11 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *f | |||
407 | break; | 474 | break; |
408 | default: | 475 | default: |
409 | snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", | 476 | snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", |
410 | chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]); | 477 | chip->dev->devnum, fp->iface, fp->altsetting, |
411 | return -1; | 478 | fmt->bFormatType); |
479 | return -ENOTSUPP; | ||
412 | } | 480 | } |
413 | fp->fmt_type = fmt[3]; | 481 | fp->fmt_type = fmt->bFormatType; |
414 | if (err < 0) | 482 | if (err < 0) |
415 | return err; | 483 | return err; |
416 | #if 1 | 484 | #if 1 |
@@ -421,10 +489,10 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *f | |||
421 | if (chip->usb_id == USB_ID(0x041e, 0x3000) || | 489 | if (chip->usb_id == USB_ID(0x041e, 0x3000) || |
422 | chip->usb_id == USB_ID(0x041e, 0x3020) || | 490 | chip->usb_id == USB_ID(0x041e, 0x3020) || |
423 | chip->usb_id == USB_ID(0x041e, 0x3061)) { | 491 | chip->usb_id == USB_ID(0x041e, 0x3061)) { |
424 | if (fmt[3] == UAC_FORMAT_TYPE_I && | 492 | if (fmt->bFormatType == UAC_FORMAT_TYPE_I && |
425 | fp->rates != SNDRV_PCM_RATE_48000 && | 493 | fp->rates != SNDRV_PCM_RATE_48000 && |
426 | fp->rates != SNDRV_PCM_RATE_96000) | 494 | fp->rates != SNDRV_PCM_RATE_96000) |
427 | return -1; | 495 | return -ENOTSUPP; |
428 | } | 496 | } |
429 | #endif | 497 | #endif |
430 | return 0; | 498 | return 0; |
diff --git a/sound/usb/format.h b/sound/usb/format.h index 8298c4e8ddf..387924f0af8 100644 --- a/sound/usb/format.h +++ b/sound/usb/format.h | |||
@@ -1,8 +1,9 @@ | |||
1 | #ifndef __USBAUDIO_FORMAT_H | 1 | #ifndef __USBAUDIO_FORMAT_H |
2 | #define __USBAUDIO_FORMAT_H | 2 | #define __USBAUDIO_FORMAT_H |
3 | 3 | ||
4 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, | 4 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, |
5 | int format, unsigned char *fmt, int stream, | 5 | struct audioformat *fp, int format, |
6 | struct usb_host_interface *iface); | 6 | struct uac_format_type_i_continuous_descriptor *fmt, |
7 | int stream, struct usb_host_interface *iface); | ||
7 | 8 | ||
8 | #endif /* __USBAUDIO_FORMAT_H */ | 9 | #endif /* __USBAUDIO_FORMAT_H */ |
diff --git a/sound/usb/helper.h b/sound/usb/helper.h index a6b0e51b3a9..09bd943c43b 100644 --- a/sound/usb/helper.h +++ b/sound/usb/helper.h | |||
@@ -28,5 +28,9 @@ unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip, | |||
28 | #define snd_usb_get_speed(dev) ((dev)->speed) | 28 | #define snd_usb_get_speed(dev) ((dev)->speed) |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | static inline int snd_usb_ctrl_intf(struct snd_usb_audio *chip) | ||
32 | { | ||
33 | return get_iface_desc(chip->ctrl_intf)->bInterfaceNumber; | ||
34 | } | ||
31 | 35 | ||
32 | #endif /* __USBAUDIO_HELPER_H */ | 36 | #endif /* __USBAUDIO_HELPER_H */ |
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index 8b1e4b124a9..46785643c66 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c | |||
@@ -645,6 +645,105 @@ static struct usb_protocol_ops snd_usbmidi_cme_ops = { | |||
645 | }; | 645 | }; |
646 | 646 | ||
647 | /* | 647 | /* |
648 | * AKAI MPD16 protocol: | ||
649 | * | ||
650 | * For control port (endpoint 1): | ||
651 | * ============================== | ||
652 | * One or more chunks consisting of first byte of (0x10 | msg_len) and then a | ||
653 | * SysEx message (msg_len=9 bytes long). | ||
654 | * | ||
655 | * For data port (endpoint 2): | ||
656 | * =========================== | ||
657 | * One or more chunks consisting of first byte of (0x20 | msg_len) and then a | ||
658 | * MIDI message (msg_len bytes long) | ||
659 | * | ||
660 | * Messages sent: Active Sense, Note On, Poly Pressure, Control Change. | ||
661 | */ | ||
662 | static void snd_usbmidi_akai_input(struct snd_usb_midi_in_endpoint *ep, | ||
663 | uint8_t *buffer, int buffer_length) | ||
664 | { | ||
665 | unsigned int pos = 0; | ||
666 | unsigned int len = (unsigned int)buffer_length; | ||
667 | while (pos < len) { | ||
668 | unsigned int port = (buffer[pos] >> 4) - 1; | ||
669 | unsigned int msg_len = buffer[pos] & 0x0f; | ||
670 | pos++; | ||
671 | if (pos + msg_len <= len && port < 2) | ||
672 | snd_usbmidi_input_data(ep, 0, &buffer[pos], msg_len); | ||
673 | pos += msg_len; | ||
674 | } | ||
675 | } | ||
676 | |||
677 | #define MAX_AKAI_SYSEX_LEN 9 | ||
678 | |||
679 | static void snd_usbmidi_akai_output(struct snd_usb_midi_out_endpoint *ep, | ||
680 | struct urb *urb) | ||
681 | { | ||
682 | uint8_t *msg; | ||
683 | int pos, end, count, buf_end; | ||
684 | uint8_t tmp[MAX_AKAI_SYSEX_LEN]; | ||
685 | struct snd_rawmidi_substream *substream = ep->ports[0].substream; | ||
686 | |||
687 | if (!ep->ports[0].active) | ||
688 | return; | ||
689 | |||
690 | msg = urb->transfer_buffer + urb->transfer_buffer_length; | ||
691 | buf_end = ep->max_transfer - MAX_AKAI_SYSEX_LEN - 1; | ||
692 | |||
693 | /* only try adding more data when there's space for at least 1 SysEx */ | ||
694 | while (urb->transfer_buffer_length < buf_end) { | ||
695 | count = snd_rawmidi_transmit_peek(substream, | ||
696 | tmp, MAX_AKAI_SYSEX_LEN); | ||
697 | if (!count) { | ||
698 | ep->ports[0].active = 0; | ||
699 | return; | ||
700 | } | ||
701 | /* try to skip non-SysEx data */ | ||
702 | for (pos = 0; pos < count && tmp[pos] != 0xF0; pos++) | ||
703 | ; | ||
704 | |||
705 | if (pos > 0) { | ||
706 | snd_rawmidi_transmit_ack(substream, pos); | ||
707 | continue; | ||
708 | } | ||
709 | |||
710 | /* look for the start or end marker */ | ||
711 | for (end = 1; end < count && tmp[end] < 0xF0; end++) | ||
712 | ; | ||
713 | |||
714 | /* next SysEx started before the end of current one */ | ||
715 | if (end < count && tmp[end] == 0xF0) { | ||
716 | /* it's incomplete - drop it */ | ||
717 | snd_rawmidi_transmit_ack(substream, end); | ||
718 | continue; | ||
719 | } | ||
720 | /* SysEx complete */ | ||
721 | if (end < count && tmp[end] == 0xF7) { | ||
722 | /* queue it, ack it, and get the next one */ | ||
723 | count = end + 1; | ||
724 | msg[0] = 0x10 | count; | ||
725 | memcpy(&msg[1], tmp, count); | ||
726 | snd_rawmidi_transmit_ack(substream, count); | ||
727 | urb->transfer_buffer_length += count + 1; | ||
728 | msg += count + 1; | ||
729 | continue; | ||
730 | } | ||
731 | /* less than 9 bytes and no end byte - wait for more */ | ||
732 | if (count < MAX_AKAI_SYSEX_LEN) { | ||
733 | ep->ports[0].active = 0; | ||
734 | return; | ||
735 | } | ||
736 | /* 9 bytes and no end marker in sight - malformed, skip it */ | ||
737 | snd_rawmidi_transmit_ack(substream, count); | ||
738 | } | ||
739 | } | ||
740 | |||
741 | static struct usb_protocol_ops snd_usbmidi_akai_ops = { | ||
742 | .input = snd_usbmidi_akai_input, | ||
743 | .output = snd_usbmidi_akai_output, | ||
744 | }; | ||
745 | |||
746 | /* | ||
648 | * Novation USB MIDI protocol: number of data bytes is in the first byte | 747 | * Novation USB MIDI protocol: number of data bytes is in the first byte |
649 | * (when receiving) (+1!) or in the second byte (when sending); data begins | 748 | * (when receiving) (+1!) or in the second byte (when sending); data begins |
650 | * at the third byte. | 749 | * at the third byte. |
@@ -1434,6 +1533,11 @@ static struct port_info { | |||
1434 | EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"), | 1533 | EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"), |
1435 | EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"), | 1534 | EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"), |
1436 | EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"), | 1535 | EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"), |
1536 | /* Akai MPD16 */ | ||
1537 | CONTROL_PORT(0x09e8, 0x0062, 0, "%s Control"), | ||
1538 | PORT_INFO(0x09e8, 0x0062, 1, "%s MIDI", 0, | ||
1539 | SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | | ||
1540 | SNDRV_SEQ_PORT_TYPE_HARDWARE), | ||
1437 | /* Access Music Virus TI */ | 1541 | /* Access Music Virus TI */ |
1438 | EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"), | 1542 | EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"), |
1439 | PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0, | 1543 | PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0, |
@@ -2035,6 +2139,12 @@ int snd_usbmidi_create(struct snd_card *card, | |||
2035 | umidi->usb_protocol_ops = &snd_usbmidi_cme_ops; | 2139 | umidi->usb_protocol_ops = &snd_usbmidi_cme_ops; |
2036 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | 2140 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); |
2037 | break; | 2141 | break; |
2142 | case QUIRK_MIDI_AKAI: | ||
2143 | umidi->usb_protocol_ops = &snd_usbmidi_akai_ops; | ||
2144 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | ||
2145 | /* endpoint 1 is input-only */ | ||
2146 | endpoints[1].out_cables = 0; | ||
2147 | break; | ||
2038 | default: | 2148 | default: |
2039 | snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); | 2149 | snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); |
2040 | err = -ENXIO; | 2150 | err = -ENXIO; |
diff --git a/sound/usb/midi.h b/sound/usb/midi.h index 2089ec987c6..2fca80b744c 100644 --- a/sound/usb/midi.h +++ b/sound/usb/midi.h | |||
@@ -37,6 +37,8 @@ struct snd_usb_midi_endpoint_info { | |||
37 | 37 | ||
38 | /* for QUIRK_MIDI_CME, data is NULL */ | 38 | /* for QUIRK_MIDI_CME, data is NULL */ |
39 | 39 | ||
40 | /* for QUIRK_MIDI_AKAI, data is NULL */ | ||
41 | |||
40 | int snd_usbmidi_create(struct snd_card *card, | 42 | int snd_usbmidi_create(struct snd_card *card, |
41 | struct usb_interface *iface, | 43 | struct usb_interface *iface, |
42 | struct list_head *midi_list, | 44 | struct list_head *midi_list, |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 97dd1765510..736d134cc03 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -78,39 +78,6 @@ enum { | |||
78 | USB_MIXER_U16, | 78 | USB_MIXER_U16, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | enum { | ||
82 | USB_PROC_UPDOWN = 1, | ||
83 | USB_PROC_UPDOWN_SWITCH = 1, | ||
84 | USB_PROC_UPDOWN_MODE_SEL = 2, | ||
85 | |||
86 | USB_PROC_PROLOGIC = 2, | ||
87 | USB_PROC_PROLOGIC_SWITCH = 1, | ||
88 | USB_PROC_PROLOGIC_MODE_SEL = 2, | ||
89 | |||
90 | USB_PROC_3DENH = 3, | ||
91 | USB_PROC_3DENH_SWITCH = 1, | ||
92 | USB_PROC_3DENH_SPACE = 2, | ||
93 | |||
94 | USB_PROC_REVERB = 4, | ||
95 | USB_PROC_REVERB_SWITCH = 1, | ||
96 | USB_PROC_REVERB_LEVEL = 2, | ||
97 | USB_PROC_REVERB_TIME = 3, | ||
98 | USB_PROC_REVERB_DELAY = 4, | ||
99 | |||
100 | USB_PROC_CHORUS = 5, | ||
101 | USB_PROC_CHORUS_SWITCH = 1, | ||
102 | USB_PROC_CHORUS_LEVEL = 2, | ||
103 | USB_PROC_CHORUS_RATE = 3, | ||
104 | USB_PROC_CHORUS_DEPTH = 4, | ||
105 | |||
106 | USB_PROC_DCR = 6, | ||
107 | USB_PROC_DCR_SWITCH = 1, | ||
108 | USB_PROC_DCR_RATIO = 2, | ||
109 | USB_PROC_DCR_MAX_AMP = 3, | ||
110 | USB_PROC_DCR_THRESHOLD = 4, | ||
111 | USB_PROC_DCR_ATTACK = 5, | ||
112 | USB_PROC_DCR_RELEASE = 6, | ||
113 | }; | ||
114 | 81 | ||
115 | /*E-mu 0202(0404) eXtension Unit(XU) control*/ | 82 | /*E-mu 0202(0404) eXtension Unit(XU) control*/ |
116 | enum { | 83 | enum { |
@@ -198,22 +165,24 @@ static int check_mapped_selector_name(struct mixer_build *state, int unitid, | |||
198 | 165 | ||
199 | /* | 166 | /* |
200 | * find an audio control unit with the given unit id | 167 | * find an audio control unit with the given unit id |
201 | * this doesn't return any clock related units, so they need to be handled elsewhere | ||
202 | */ | 168 | */ |
203 | static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit) | 169 | static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit) |
204 | { | 170 | { |
205 | unsigned char *p; | 171 | /* we just parse the header */ |
172 | struct uac_feature_unit_descriptor *hdr = NULL; | ||
206 | 173 | ||
207 | p = NULL; | 174 | while ((hdr = snd_usb_find_desc(state->buffer, state->buflen, hdr, |
208 | while ((p = snd_usb_find_desc(state->buffer, state->buflen, p, | 175 | USB_DT_CS_INTERFACE)) != NULL) { |
209 | USB_DT_CS_INTERFACE)) != NULL) { | 176 | if (hdr->bLength >= 4 && |
210 | if (p[0] >= 4 && p[2] >= UAC_INPUT_TERMINAL && p[2] <= UAC2_EXTENSION_UNIT_V2 && p[3] == unit) | 177 | hdr->bDescriptorSubtype >= UAC_INPUT_TERMINAL && |
211 | return p; | 178 | hdr->bDescriptorSubtype <= UAC2_SAMPLE_RATE_CONVERTER && |
179 | hdr->bUnitID == unit) | ||
180 | return hdr; | ||
212 | } | 181 | } |
182 | |||
213 | return NULL; | 183 | return NULL; |
214 | } | 184 | } |
215 | 185 | ||
216 | |||
217 | /* | 186 | /* |
218 | * copy a string with the given id | 187 | * copy a string with the given id |
219 | */ | 188 | */ |
@@ -328,27 +297,36 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v | |||
328 | 297 | ||
329 | static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) | 298 | static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) |
330 | { | 299 | { |
331 | unsigned char buf[14]; /* enough space for one range of 4 bytes */ | 300 | unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ |
332 | unsigned char *val; | 301 | unsigned char *val; |
333 | int ret; | 302 | int ret, size; |
334 | __u8 bRequest; | 303 | __u8 bRequest; |
335 | 304 | ||
336 | bRequest = (request == UAC_GET_CUR) ? | 305 | if (request == UAC_GET_CUR) { |
337 | UAC2_CS_CUR : UAC2_CS_RANGE; | 306 | bRequest = UAC2_CS_CUR; |
307 | size = sizeof(__u16); | ||
308 | } else { | ||
309 | bRequest = UAC2_CS_RANGE; | ||
310 | size = sizeof(buf); | ||
311 | } | ||
312 | |||
313 | memset(buf, 0, sizeof(buf)); | ||
338 | 314 | ||
339 | ret = snd_usb_ctl_msg(cval->mixer->chip->dev, | 315 | ret = snd_usb_ctl_msg(cval->mixer->chip->dev, |
340 | usb_rcvctrlpipe(cval->mixer->chip->dev, 0), | 316 | usb_rcvctrlpipe(cval->mixer->chip->dev, 0), |
341 | bRequest, | 317 | bRequest, |
342 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | 318 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, |
343 | validx, cval->mixer->ctrlif | (cval->id << 8), | 319 | validx, cval->mixer->ctrlif | (cval->id << 8), |
344 | buf, sizeof(buf), 1000); | 320 | buf, size, 1000); |
345 | 321 | ||
346 | if (ret < 0) { | 322 | if (ret < 0) { |
347 | snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", | 323 | snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", |
348 | request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type); | 324 | request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type); |
349 | return ret; | 325 | return ret; |
350 | } | 326 | } |
351 | 327 | ||
328 | /* FIXME: how should we handle multiple triplets here? */ | ||
329 | |||
352 | switch (request) { | 330 | switch (request) { |
353 | case UAC_GET_CUR: | 331 | case UAC_GET_CUR: |
354 | val = buf; | 332 | val = buf; |
@@ -462,6 +440,16 @@ static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, | |||
462 | int index, int value) | 440 | int index, int value) |
463 | { | 441 | { |
464 | int err; | 442 | int err; |
443 | unsigned int read_only = (channel == 0) ? | ||
444 | cval->master_readonly : | ||
445 | cval->ch_readonly & (1 << (channel - 1)); | ||
446 | |||
447 | if (read_only) { | ||
448 | snd_printdd(KERN_INFO "%s(): channel %d of control %d is read_only\n", | ||
449 | __func__, channel, cval->control); | ||
450 | return 0; | ||
451 | } | ||
452 | |||
465 | err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel, | 453 | err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel, |
466 | value); | 454 | value); |
467 | if (err < 0) | 455 | if (err < 0) |
@@ -631,6 +619,7 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm | |||
631 | */ | 619 | */ |
632 | static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term) | 620 | static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term) |
633 | { | 621 | { |
622 | int err; | ||
634 | void *p1; | 623 | void *p1; |
635 | 624 | ||
636 | memset(term, 0, sizeof(*term)); | 625 | memset(term, 0, sizeof(*term)); |
@@ -651,6 +640,11 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ | |||
651 | term->channels = d->bNrChannels; | 640 | term->channels = d->bNrChannels; |
652 | term->chconfig = le32_to_cpu(d->bmChannelConfig); | 641 | term->chconfig = le32_to_cpu(d->bmChannelConfig); |
653 | term->name = d->iTerminal; | 642 | term->name = d->iTerminal; |
643 | |||
644 | /* call recursively to get the clock selectors */ | ||
645 | err = check_input_term(state, d->bCSourceID, term); | ||
646 | if (err < 0) | ||
647 | return err; | ||
654 | } | 648 | } |
655 | return 0; | 649 | return 0; |
656 | case UAC_FEATURE_UNIT: { | 650 | case UAC_FEATURE_UNIT: { |
@@ -667,7 +661,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ | |||
667 | term->name = uac_mixer_unit_iMixer(d); | 661 | term->name = uac_mixer_unit_iMixer(d); |
668 | return 0; | 662 | return 0; |
669 | } | 663 | } |
670 | case UAC_SELECTOR_UNIT: { | 664 | case UAC_SELECTOR_UNIT: |
665 | case UAC2_CLOCK_SELECTOR: { | ||
671 | struct uac_selector_unit_descriptor *d = p1; | 666 | struct uac_selector_unit_descriptor *d = p1; |
672 | /* call recursively to retrieve the channel info */ | 667 | /* call recursively to retrieve the channel info */ |
673 | if (check_input_term(state, d->baSourceID[0], term) < 0) | 668 | if (check_input_term(state, d->baSourceID[0], term) < 0) |
@@ -690,6 +685,13 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ | |||
690 | term->name = uac_processing_unit_iProcessing(d, state->mixer->protocol); | 685 | term->name = uac_processing_unit_iProcessing(d, state->mixer->protocol); |
691 | return 0; | 686 | return 0; |
692 | } | 687 | } |
688 | case UAC2_CLOCK_SOURCE: { | ||
689 | struct uac_clock_source_descriptor *d = p1; | ||
690 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | ||
691 | term->id = id; | ||
692 | term->name = d->iClockSource; | ||
693 | return 0; | ||
694 | } | ||
693 | default: | 695 | default: |
694 | return -ENODEV; | 696 | return -ENODEV; |
695 | } | 697 | } |
@@ -709,16 +711,20 @@ struct usb_feature_control_info { | |||
709 | }; | 711 | }; |
710 | 712 | ||
711 | static struct usb_feature_control_info audio_feature_info[] = { | 713 | static struct usb_feature_control_info audio_feature_info[] = { |
712 | { "Mute", USB_MIXER_INV_BOOLEAN }, | 714 | { "Mute", USB_MIXER_INV_BOOLEAN }, |
713 | { "Volume", USB_MIXER_S16 }, | 715 | { "Volume", USB_MIXER_S16 }, |
714 | { "Tone Control - Bass", USB_MIXER_S8 }, | 716 | { "Tone Control - Bass", USB_MIXER_S8 }, |
715 | { "Tone Control - Mid", USB_MIXER_S8 }, | 717 | { "Tone Control - Mid", USB_MIXER_S8 }, |
716 | { "Tone Control - Treble", USB_MIXER_S8 }, | 718 | { "Tone Control - Treble", USB_MIXER_S8 }, |
717 | { "Graphic Equalizer", USB_MIXER_S8 }, /* FIXME: not implemeted yet */ | 719 | { "Graphic Equalizer", USB_MIXER_S8 }, /* FIXME: not implemeted yet */ |
718 | { "Auto Gain Control", USB_MIXER_BOOLEAN }, | 720 | { "Auto Gain Control", USB_MIXER_BOOLEAN }, |
719 | { "Delay Control", USB_MIXER_U16 }, | 721 | { "Delay Control", USB_MIXER_U16 }, |
720 | { "Bass Boost", USB_MIXER_BOOLEAN }, | 722 | { "Bass Boost", USB_MIXER_BOOLEAN }, |
721 | { "Loudness", USB_MIXER_BOOLEAN }, | 723 | { "Loudness", USB_MIXER_BOOLEAN }, |
724 | /* UAC2 specific */ | ||
725 | { "Input Gain Control", USB_MIXER_U16 }, | ||
726 | { "Input Gain Pad Control", USB_MIXER_BOOLEAN }, | ||
727 | { "Phase Inverter Control", USB_MIXER_BOOLEAN }, | ||
722 | }; | 728 | }; |
723 | 729 | ||
724 | 730 | ||
@@ -958,7 +964,7 @@ static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str) | |||
958 | static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | 964 | static void build_feature_ctl(struct mixer_build *state, void *raw_desc, |
959 | unsigned int ctl_mask, int control, | 965 | unsigned int ctl_mask, int control, |
960 | struct usb_audio_term *iterm, int unitid, | 966 | struct usb_audio_term *iterm, int unitid, |
961 | int read_only) | 967 | int readonly_mask) |
962 | { | 968 | { |
963 | struct uac_feature_unit_descriptor *desc = raw_desc; | 969 | struct uac_feature_unit_descriptor *desc = raw_desc; |
964 | unsigned int len = 0; | 970 | unsigned int len = 0; |
@@ -970,7 +976,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
970 | 976 | ||
971 | control++; /* change from zero-based to 1-based value */ | 977 | control++; /* change from zero-based to 1-based value */ |
972 | 978 | ||
973 | if (control == UAC_GRAPHIC_EQUALIZER_CONTROL) { | 979 | if (control == UAC_FU_GRAPHIC_EQUALIZER) { |
974 | /* FIXME: not supported yet */ | 980 | /* FIXME: not supported yet */ |
975 | return; | 981 | return; |
976 | } | 982 | } |
@@ -989,20 +995,25 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
989 | cval->control = control; | 995 | cval->control = control; |
990 | cval->cmask = ctl_mask; | 996 | cval->cmask = ctl_mask; |
991 | cval->val_type = audio_feature_info[control-1].type; | 997 | cval->val_type = audio_feature_info[control-1].type; |
992 | if (ctl_mask == 0) | 998 | if (ctl_mask == 0) { |
993 | cval->channels = 1; /* master channel */ | 999 | cval->channels = 1; /* master channel */ |
994 | else { | 1000 | cval->master_readonly = readonly_mask; |
1001 | } else { | ||
995 | int i, c = 0; | 1002 | int i, c = 0; |
996 | for (i = 0; i < 16; i++) | 1003 | for (i = 0; i < 16; i++) |
997 | if (ctl_mask & (1 << i)) | 1004 | if (ctl_mask & (1 << i)) |
998 | c++; | 1005 | c++; |
999 | cval->channels = c; | 1006 | cval->channels = c; |
1007 | cval->ch_readonly = readonly_mask; | ||
1000 | } | 1008 | } |
1001 | 1009 | ||
1002 | /* get min/max values */ | 1010 | /* get min/max values */ |
1003 | get_min_max(cval, 0); | 1011 | get_min_max(cval, 0); |
1004 | 1012 | ||
1005 | if (read_only) | 1013 | /* if all channels in the mask are marked read-only, make the control |
1014 | * read-only. set_cur_mix_value() will check the mask again and won't | ||
1015 | * issue write commands to read-only channels. */ | ||
1016 | if (cval->channels == readonly_mask) | ||
1006 | kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval); | 1017 | kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval); |
1007 | else | 1018 | else |
1008 | kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); | 1019 | kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); |
@@ -1021,8 +1032,8 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1021 | kctl->id.name, sizeof(kctl->id.name)); | 1032 | kctl->id.name, sizeof(kctl->id.name)); |
1022 | 1033 | ||
1023 | switch (control) { | 1034 | switch (control) { |
1024 | case UAC_MUTE_CONTROL: | 1035 | case UAC_FU_MUTE: |
1025 | case UAC_VOLUME_CONTROL: | 1036 | case UAC_FU_VOLUME: |
1026 | /* determine the control name. the rule is: | 1037 | /* determine the control name. the rule is: |
1027 | * - if a name id is given in descriptor, use it. | 1038 | * - if a name id is given in descriptor, use it. |
1028 | * - if the connected input can be determined, then use the name | 1039 | * - if the connected input can be determined, then use the name |
@@ -1049,9 +1060,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1049 | len = append_ctl_name(kctl, " Playback"); | 1060 | len = append_ctl_name(kctl, " Playback"); |
1050 | } | 1061 | } |
1051 | } | 1062 | } |
1052 | append_ctl_name(kctl, control == UAC_MUTE_CONTROL ? | 1063 | append_ctl_name(kctl, control == UAC_FU_MUTE ? |
1053 | " Switch" : " Volume"); | 1064 | " Switch" : " Volume"); |
1054 | if (control == UAC_VOLUME_CONTROL) { | 1065 | if (control == UAC_FU_VOLUME) { |
1055 | kctl->tlv.c = mixer_vol_tlv; | 1066 | kctl->tlv.c = mixer_vol_tlv; |
1056 | kctl->vd[0].access |= | 1067 | kctl->vd[0].access |= |
1057 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | | 1068 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | |
@@ -1096,6 +1107,19 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1096 | } | 1107 | } |
1097 | break; | 1108 | break; |
1098 | 1109 | ||
1110 | case USB_ID(0x046d, 0x0809): | ||
1111 | case USB_ID(0x046d, 0x0991): | ||
1112 | /* Most audio usb devices lie about volume resolution. | ||
1113 | * Most Logitech webcams have res = 384. | ||
1114 | * Proboly there is some logitech magic behind this number --fishor | ||
1115 | */ | ||
1116 | if (!strcmp(kctl->id.name, "Mic Capture Volume")) { | ||
1117 | snd_printk(KERN_INFO | ||
1118 | "set resolution quirk: cval->res = 384\n"); | ||
1119 | cval->res = 384; | ||
1120 | } | ||
1121 | break; | ||
1122 | |||
1099 | } | 1123 | } |
1100 | 1124 | ||
1101 | snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", | 1125 | snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", |
@@ -1126,7 +1150,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void | |||
1126 | } else { | 1150 | } else { |
1127 | struct uac2_feature_unit_descriptor *ftr = _ftr; | 1151 | struct uac2_feature_unit_descriptor *ftr = _ftr; |
1128 | csize = 4; | 1152 | csize = 4; |
1129 | channels = (hdr->bLength - 6) / 4; | 1153 | channels = (hdr->bLength - 6) / 4 - 1; |
1130 | bmaControls = ftr->bmaControls; | 1154 | bmaControls = ftr->bmaControls; |
1131 | } | 1155 | } |
1132 | 1156 | ||
@@ -1150,7 +1174,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void | |||
1150 | snd_printk(KERN_INFO | 1174 | snd_printk(KERN_INFO |
1151 | "usbmixer: master volume quirk for PCM2702 chip\n"); | 1175 | "usbmixer: master volume quirk for PCM2702 chip\n"); |
1152 | /* disable non-functional volume control */ | 1176 | /* disable non-functional volume control */ |
1153 | master_bits &= ~UAC_FU_VOLUME; | 1177 | master_bits &= ~UAC_CONTROL_BIT(UAC_FU_VOLUME); |
1154 | break; | 1178 | break; |
1155 | } | 1179 | } |
1156 | if (channels > 0) | 1180 | if (channels > 0) |
@@ -1188,19 +1212,22 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void | |||
1188 | 1212 | ||
1189 | for (j = 0; j < channels; j++) { | 1213 | for (j = 0; j < channels; j++) { |
1190 | unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize); | 1214 | unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize); |
1191 | if (mask & (1 << (i * 2))) { | 1215 | if (uac2_control_is_readable(mask, i)) { |
1192 | ch_bits |= (1 << j); | 1216 | ch_bits |= (1 << j); |
1193 | if (~mask & (1 << ((i * 2) + 1))) | 1217 | if (!uac2_control_is_writeable(mask, i)) |
1194 | ch_read_only |= (1 << j); | 1218 | ch_read_only |= (1 << j); |
1195 | } | 1219 | } |
1196 | } | 1220 | } |
1197 | 1221 | ||
1198 | /* FIXME: the whole unit is read-only if any of the channels is marked read-only */ | 1222 | /* NOTE: build_feature_ctl() will mark the control read-only if all channels |
1223 | * are marked read-only in the descriptors. Otherwise, the control will be | ||
1224 | * reported as writeable, but the driver will not actually issue a write | ||
1225 | * command for read-only channels */ | ||
1199 | if (ch_bits & 1) /* the first channel must be set (for ease of programming) */ | 1226 | if (ch_bits & 1) /* the first channel must be set (for ease of programming) */ |
1200 | build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, !!ch_read_only); | 1227 | build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, ch_read_only); |
1201 | if (master_bits & (1 << i * 2)) | 1228 | if (uac2_control_is_readable(master_bits, i)) |
1202 | build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, | 1229 | build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, |
1203 | ~master_bits & (1 << ((i * 2) + 1))); | 1230 | !uac2_control_is_writeable(master_bits, i)); |
1204 | } | 1231 | } |
1205 | } | 1232 | } |
1206 | 1233 | ||
@@ -1392,51 +1419,51 @@ struct procunit_info { | |||
1392 | }; | 1419 | }; |
1393 | 1420 | ||
1394 | static struct procunit_value_info updown_proc_info[] = { | 1421 | static struct procunit_value_info updown_proc_info[] = { |
1395 | { USB_PROC_UPDOWN_SWITCH, "Switch", USB_MIXER_BOOLEAN }, | 1422 | { UAC_UD_ENABLE, "Switch", USB_MIXER_BOOLEAN }, |
1396 | { USB_PROC_UPDOWN_MODE_SEL, "Mode Select", USB_MIXER_U8, 1 }, | 1423 | { UAC_UD_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 }, |
1397 | { 0 } | 1424 | { 0 } |
1398 | }; | 1425 | }; |
1399 | static struct procunit_value_info prologic_proc_info[] = { | 1426 | static struct procunit_value_info prologic_proc_info[] = { |
1400 | { USB_PROC_PROLOGIC_SWITCH, "Switch", USB_MIXER_BOOLEAN }, | 1427 | { UAC_DP_ENABLE, "Switch", USB_MIXER_BOOLEAN }, |
1401 | { USB_PROC_PROLOGIC_MODE_SEL, "Mode Select", USB_MIXER_U8, 1 }, | 1428 | { UAC_DP_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 }, |
1402 | { 0 } | 1429 | { 0 } |
1403 | }; | 1430 | }; |
1404 | static struct procunit_value_info threed_enh_proc_info[] = { | 1431 | static struct procunit_value_info threed_enh_proc_info[] = { |
1405 | { USB_PROC_3DENH_SWITCH, "Switch", USB_MIXER_BOOLEAN }, | 1432 | { UAC_3D_ENABLE, "Switch", USB_MIXER_BOOLEAN }, |
1406 | { USB_PROC_3DENH_SPACE, "Spaciousness", USB_MIXER_U8 }, | 1433 | { UAC_3D_SPACE, "Spaciousness", USB_MIXER_U8 }, |
1407 | { 0 } | 1434 | { 0 } |
1408 | }; | 1435 | }; |
1409 | static struct procunit_value_info reverb_proc_info[] = { | 1436 | static struct procunit_value_info reverb_proc_info[] = { |
1410 | { USB_PROC_REVERB_SWITCH, "Switch", USB_MIXER_BOOLEAN }, | 1437 | { UAC_REVERB_ENABLE, "Switch", USB_MIXER_BOOLEAN }, |
1411 | { USB_PROC_REVERB_LEVEL, "Level", USB_MIXER_U8 }, | 1438 | { UAC_REVERB_LEVEL, "Level", USB_MIXER_U8 }, |
1412 | { USB_PROC_REVERB_TIME, "Time", USB_MIXER_U16 }, | 1439 | { UAC_REVERB_TIME, "Time", USB_MIXER_U16 }, |
1413 | { USB_PROC_REVERB_DELAY, "Delay", USB_MIXER_U8 }, | 1440 | { UAC_REVERB_FEEDBACK, "Feedback", USB_MIXER_U8 }, |
1414 | { 0 } | 1441 | { 0 } |
1415 | }; | 1442 | }; |
1416 | static struct procunit_value_info chorus_proc_info[] = { | 1443 | static struct procunit_value_info chorus_proc_info[] = { |
1417 | { USB_PROC_CHORUS_SWITCH, "Switch", USB_MIXER_BOOLEAN }, | 1444 | { UAC_CHORUS_ENABLE, "Switch", USB_MIXER_BOOLEAN }, |
1418 | { USB_PROC_CHORUS_LEVEL, "Level", USB_MIXER_U8 }, | 1445 | { UAC_CHORUS_LEVEL, "Level", USB_MIXER_U8 }, |
1419 | { USB_PROC_CHORUS_RATE, "Rate", USB_MIXER_U16 }, | 1446 | { UAC_CHORUS_RATE, "Rate", USB_MIXER_U16 }, |
1420 | { USB_PROC_CHORUS_DEPTH, "Depth", USB_MIXER_U16 }, | 1447 | { UAC_CHORUS_DEPTH, "Depth", USB_MIXER_U16 }, |
1421 | { 0 } | 1448 | { 0 } |
1422 | }; | 1449 | }; |
1423 | static struct procunit_value_info dcr_proc_info[] = { | 1450 | static struct procunit_value_info dcr_proc_info[] = { |
1424 | { USB_PROC_DCR_SWITCH, "Switch", USB_MIXER_BOOLEAN }, | 1451 | { UAC_DCR_ENABLE, "Switch", USB_MIXER_BOOLEAN }, |
1425 | { USB_PROC_DCR_RATIO, "Ratio", USB_MIXER_U16 }, | 1452 | { UAC_DCR_RATE, "Ratio", USB_MIXER_U16 }, |
1426 | { USB_PROC_DCR_MAX_AMP, "Max Amp", USB_MIXER_S16 }, | 1453 | { UAC_DCR_MAXAMPL, "Max Amp", USB_MIXER_S16 }, |
1427 | { USB_PROC_DCR_THRESHOLD, "Threshold", USB_MIXER_S16 }, | 1454 | { UAC_DCR_THRESHOLD, "Threshold", USB_MIXER_S16 }, |
1428 | { USB_PROC_DCR_ATTACK, "Attack Time", USB_MIXER_U16 }, | 1455 | { UAC_DCR_ATTACK_TIME, "Attack Time", USB_MIXER_U16 }, |
1429 | { USB_PROC_DCR_RELEASE, "Release Time", USB_MIXER_U16 }, | 1456 | { UAC_DCR_RELEASE_TIME, "Release Time", USB_MIXER_U16 }, |
1430 | { 0 } | 1457 | { 0 } |
1431 | }; | 1458 | }; |
1432 | 1459 | ||
1433 | static struct procunit_info procunits[] = { | 1460 | static struct procunit_info procunits[] = { |
1434 | { USB_PROC_UPDOWN, "Up Down", updown_proc_info }, | 1461 | { UAC_PROCESS_UP_DOWNMIX, "Up Down", updown_proc_info }, |
1435 | { USB_PROC_PROLOGIC, "Dolby Prologic", prologic_proc_info }, | 1462 | { UAC_PROCESS_DOLBY_PROLOGIC, "Dolby Prologic", prologic_proc_info }, |
1436 | { USB_PROC_3DENH, "3D Stereo Extender", threed_enh_proc_info }, | 1463 | { UAC_PROCESS_STEREO_EXTENDER, "3D Stereo Extender", threed_enh_proc_info }, |
1437 | { USB_PROC_REVERB, "Reverb", reverb_proc_info }, | 1464 | { UAC_PROCESS_REVERB, "Reverb", reverb_proc_info }, |
1438 | { USB_PROC_CHORUS, "Chorus", chorus_proc_info }, | 1465 | { UAC_PROCESS_CHORUS, "Chorus", chorus_proc_info }, |
1439 | { USB_PROC_DCR, "DCR", dcr_proc_info }, | 1466 | { UAC_PROCESS_DYN_RANGE_COMP, "DCR", dcr_proc_info }, |
1440 | { 0 }, | 1467 | { 0 }, |
1441 | }; | 1468 | }; |
1442 | /* | 1469 | /* |
@@ -1524,7 +1551,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw | |||
1524 | cval->channels = 1; | 1551 | cval->channels = 1; |
1525 | 1552 | ||
1526 | /* get min/max values */ | 1553 | /* get min/max values */ |
1527 | if (type == USB_PROC_UPDOWN && cval->control == USB_PROC_UPDOWN_MODE_SEL) { | 1554 | if (type == UAC_PROCESS_UP_DOWNMIX && cval->control == UAC_UD_MODE_SELECT) { |
1528 | __u8 *control_spec = uac_processing_unit_specific(desc, state->mixer->protocol); | 1555 | __u8 *control_spec = uac_processing_unit_specific(desc, state->mixer->protocol); |
1529 | /* FIXME: hard-coded */ | 1556 | /* FIXME: hard-coded */ |
1530 | cval->min = 1; | 1557 | cval->min = 1; |
@@ -1619,7 +1646,7 @@ static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
1619 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | 1646 | struct usb_mixer_elem_info *cval = kcontrol->private_data; |
1620 | int val, err; | 1647 | int val, err; |
1621 | 1648 | ||
1622 | err = get_cur_ctl_value(cval, 0, &val); | 1649 | err = get_cur_ctl_value(cval, cval->control << 8, &val); |
1623 | if (err < 0) { | 1650 | if (err < 0) { |
1624 | if (cval->mixer->ignore_ctl_error) { | 1651 | if (cval->mixer->ignore_ctl_error) { |
1625 | ucontrol->value.enumerated.item[0] = 0; | 1652 | ucontrol->value.enumerated.item[0] = 0; |
@@ -1638,7 +1665,7 @@ static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
1638 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | 1665 | struct usb_mixer_elem_info *cval = kcontrol->private_data; |
1639 | int val, oval, err; | 1666 | int val, oval, err; |
1640 | 1667 | ||
1641 | err = get_cur_ctl_value(cval, 0, &oval); | 1668 | err = get_cur_ctl_value(cval, cval->control << 8, &oval); |
1642 | if (err < 0) { | 1669 | if (err < 0) { |
1643 | if (cval->mixer->ignore_ctl_error) | 1670 | if (cval->mixer->ignore_ctl_error) |
1644 | return 0; | 1671 | return 0; |
@@ -1647,7 +1674,7 @@ static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
1647 | val = ucontrol->value.enumerated.item[0]; | 1674 | val = ucontrol->value.enumerated.item[0]; |
1648 | val = get_abs_value(cval, val); | 1675 | val = get_abs_value(cval, val); |
1649 | if (val != oval) { | 1676 | if (val != oval) { |
1650 | set_cur_ctl_value(cval, 0, val); | 1677 | set_cur_ctl_value(cval, cval->control << 8, val); |
1651 | return 1; | 1678 | return 1; |
1652 | } | 1679 | } |
1653 | return 0; | 1680 | return 0; |
@@ -1729,6 +1756,11 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void | |||
1729 | cval->res = 1; | 1756 | cval->res = 1; |
1730 | cval->initialized = 1; | 1757 | cval->initialized = 1; |
1731 | 1758 | ||
1759 | if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR) | ||
1760 | cval->control = UAC2_CX_CLOCK_SELECTOR; | ||
1761 | else | ||
1762 | cval->control = 0; | ||
1763 | |||
1732 | namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL); | 1764 | namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL); |
1733 | if (! namelist) { | 1765 | if (! namelist) { |
1734 | snd_printk(KERN_ERR "cannot malloc\n"); | 1766 | snd_printk(KERN_ERR "cannot malloc\n"); |
@@ -1778,7 +1810,9 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void | |||
1778 | if (! len) | 1810 | if (! len) |
1779 | strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name)); | 1811 | strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name)); |
1780 | 1812 | ||
1781 | if ((state->oterm.type & 0xff00) == 0x0100) | 1813 | if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR) |
1814 | append_ctl_name(kctl, " Clock Source"); | ||
1815 | else if ((state->oterm.type & 0xff00) == 0x0100) | ||
1782 | append_ctl_name(kctl, " Capture Source"); | 1816 | append_ctl_name(kctl, " Capture Source"); |
1783 | else | 1817 | else |
1784 | append_ctl_name(kctl, " Playback Source"); | 1818 | append_ctl_name(kctl, " Playback Source"); |
@@ -1812,10 +1846,12 @@ static int parse_audio_unit(struct mixer_build *state, int unitid) | |||
1812 | 1846 | ||
1813 | switch (p1[2]) { | 1847 | switch (p1[2]) { |
1814 | case UAC_INPUT_TERMINAL: | 1848 | case UAC_INPUT_TERMINAL: |
1849 | case UAC2_CLOCK_SOURCE: | ||
1815 | return 0; /* NOP */ | 1850 | return 0; /* NOP */ |
1816 | case UAC_MIXER_UNIT: | 1851 | case UAC_MIXER_UNIT: |
1817 | return parse_audio_mixer_unit(state, unitid, p1); | 1852 | return parse_audio_mixer_unit(state, unitid, p1); |
1818 | case UAC_SELECTOR_UNIT: | 1853 | case UAC_SELECTOR_UNIT: |
1854 | case UAC2_CLOCK_SELECTOR: | ||
1819 | return parse_audio_selector_unit(state, unitid, p1); | 1855 | return parse_audio_selector_unit(state, unitid, p1); |
1820 | case UAC_FEATURE_UNIT: | 1856 | case UAC_FEATURE_UNIT: |
1821 | return parse_audio_feature_unit(state, unitid, p1); | 1857 | return parse_audio_feature_unit(state, unitid, p1); |
@@ -1912,6 +1948,11 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) | |||
1912 | err = parse_audio_unit(&state, desc->bSourceID); | 1948 | err = parse_audio_unit(&state, desc->bSourceID); |
1913 | if (err < 0) | 1949 | if (err < 0) |
1914 | return err; | 1950 | return err; |
1951 | |||
1952 | /* for UAC2, use the same approach to also add the clock selectors */ | ||
1953 | err = parse_audio_unit(&state, desc->bCSourceID); | ||
1954 | if (err < 0) | ||
1955 | return err; | ||
1915 | } | 1956 | } |
1916 | } | 1957 | } |
1917 | 1958 | ||
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index 130123854a6..a7cf1007fbb 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h | |||
@@ -34,6 +34,8 @@ struct usb_mixer_elem_info { | |||
34 | unsigned int id; | 34 | unsigned int id; |
35 | unsigned int control; /* CS or ICN (high byte) */ | 35 | unsigned int control; /* CS or ICN (high byte) */ |
36 | unsigned int cmask; /* channel mask bitmap: 0 = master */ | 36 | unsigned int cmask; /* channel mask bitmap: 0 = master */ |
37 | unsigned int ch_readonly; | ||
38 | unsigned int master_readonly; | ||
37 | int channels; | 39 | int channels; |
38 | int val_type; | 40 | int val_type; |
39 | int min, max, res; | 41 | int min, max, res; |
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index d93fc89beba..f1324c42383 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c | |||
@@ -85,8 +85,8 @@ static struct usbmix_name_map extigy_map[] = { | |||
85 | /* 16: MU (w/o controls) */ | 85 | /* 16: MU (w/o controls) */ |
86 | { 17, NULL, 1 }, /* DISABLED: PU-switch (any effect?) */ | 86 | { 17, NULL, 1 }, /* DISABLED: PU-switch (any effect?) */ |
87 | { 17, "Channel Routing", 2 }, /* PU: mode select */ | 87 | { 17, "Channel Routing", 2 }, /* PU: mode select */ |
88 | { 18, "Tone Control - Bass", UAC_BASS_CONTROL }, /* FU */ | 88 | { 18, "Tone Control - Bass", UAC_FU_BASS }, /* FU */ |
89 | { 18, "Tone Control - Treble", UAC_TREBLE_CONTROL }, /* FU */ | 89 | { 18, "Tone Control - Treble", UAC_FU_TREBLE }, /* FU */ |
90 | { 18, "Master Playback" }, /* FU; others */ | 90 | { 18, "Master Playback" }, /* FU; others */ |
91 | /* 19: OT speaker */ | 91 | /* 19: OT speaker */ |
92 | /* 20: OT headphone */ | 92 | /* 20: OT headphone */ |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 2bf0d77d176..456829882f4 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "urb.h" | 31 | #include "urb.h" |
32 | #include "helper.h" | 32 | #include "helper.h" |
33 | #include "pcm.h" | 33 | #include "pcm.h" |
34 | #include "clock.h" | ||
34 | 35 | ||
35 | /* | 36 | /* |
36 | * return the current pcm pointer. just based on the hwptr_done value. | 37 | * return the current pcm pointer. just based on the hwptr_done value. |
@@ -120,10 +121,6 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface, | |||
120 | 121 | ||
121 | ep = get_endpoint(alts, 0)->bEndpointAddress; | 122 | ep = get_endpoint(alts, 0)->bEndpointAddress; |
122 | 123 | ||
123 | /* if endpoint doesn't have pitch control, bail out */ | ||
124 | if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL)) | ||
125 | return 0; | ||
126 | |||
127 | data[0] = 1; | 124 | data[0] = 1; |
128 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, | 125 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, |
129 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, | 126 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, |
@@ -137,119 +134,49 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface, | |||
137 | return 0; | 134 | return 0; |
138 | } | 135 | } |
139 | 136 | ||
140 | /* | 137 | static int init_pitch_v2(struct snd_usb_audio *chip, int iface, |
141 | * initialize the picth control and sample rate | 138 | struct usb_host_interface *alts, |
142 | */ | 139 | struct audioformat *fmt) |
143 | int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, | ||
144 | struct usb_host_interface *alts, | ||
145 | struct audioformat *fmt) | ||
146 | { | ||
147 | struct usb_interface_descriptor *altsd = get_iface_desc(alts); | ||
148 | |||
149 | switch (altsd->bInterfaceProtocol) { | ||
150 | case UAC_VERSION_1: | ||
151 | return init_pitch_v1(chip, iface, alts, fmt); | ||
152 | |||
153 | case UAC_VERSION_2: | ||
154 | /* not implemented yet */ | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | return -EINVAL; | ||
159 | } | ||
160 | |||
161 | static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, | ||
162 | struct usb_host_interface *alts, | ||
163 | struct audioformat *fmt, int rate) | ||
164 | { | 140 | { |
165 | struct usb_device *dev = chip->dev; | 141 | struct usb_device *dev = chip->dev; |
142 | unsigned char data[1]; | ||
166 | unsigned int ep; | 143 | unsigned int ep; |
167 | unsigned char data[3]; | 144 | int err; |
168 | int err, crate; | ||
169 | 145 | ||
170 | ep = get_endpoint(alts, 0)->bEndpointAddress; | 146 | ep = get_endpoint(alts, 0)->bEndpointAddress; |
171 | /* if endpoint doesn't have sampling rate control, bail out */ | ||
172 | if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE)) { | ||
173 | snd_printk(KERN_WARNING "%d:%d:%d: endpoint lacks sample rate attribute bit, cannot set.\n", | ||
174 | dev->devnum, iface, fmt->altsetting); | ||
175 | return 0; | ||
176 | } | ||
177 | 147 | ||
178 | data[0] = rate; | 148 | data[0] = 1; |
179 | data[1] = rate >> 8; | ||
180 | data[2] = rate >> 16; | ||
181 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, | ||
182 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, | ||
183 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, | ||
184 | data, sizeof(data), 1000)) < 0) { | ||
185 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n", | ||
186 | dev->devnum, iface, fmt->altsetting, rate, ep); | ||
187 | return err; | ||
188 | } | ||
189 | if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR, | ||
190 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, | ||
191 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, | ||
192 | data, sizeof(data), 1000)) < 0) { | ||
193 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n", | ||
194 | dev->devnum, iface, fmt->altsetting, ep); | ||
195 | return 0; /* some devices don't support reading */ | ||
196 | } | ||
197 | crate = data[0] | (data[1] << 8) | (data[2] << 16); | ||
198 | if (crate != rate) { | ||
199 | snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate); | ||
200 | // runtime->rate = crate; | ||
201 | } | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | ||
207 | struct usb_host_interface *alts, | ||
208 | struct audioformat *fmt, int rate) | ||
209 | { | ||
210 | struct usb_device *dev = chip->dev; | ||
211 | unsigned char data[4]; | ||
212 | int err, crate; | ||
213 | |||
214 | data[0] = rate; | ||
215 | data[1] = rate >> 8; | ||
216 | data[2] = rate >> 16; | ||
217 | data[3] = rate >> 24; | ||
218 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, | 149 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, |
219 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | 150 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, |
220 | UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8, | 151 | UAC2_EP_CS_PITCH << 8, 0, |
221 | data, sizeof(data), 1000)) < 0) { | ||
222 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n", | ||
223 | dev->devnum, iface, fmt->altsetting, rate); | ||
224 | return err; | ||
225 | } | ||
226 | if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, | ||
227 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
228 | UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8, | ||
229 | data, sizeof(data), 1000)) < 0) { | 152 | data, sizeof(data), 1000)) < 0) { |
230 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", | 153 | snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n", |
231 | dev->devnum, iface, fmt->altsetting); | 154 | dev->devnum, iface, fmt->altsetting); |
232 | return err; | 155 | return err; |
233 | } | 156 | } |
234 | crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); | ||
235 | if (crate != rate) | ||
236 | snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate); | ||
237 | 157 | ||
238 | return 0; | 158 | return 0; |
239 | } | 159 | } |
240 | 160 | ||
241 | int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface, | 161 | /* |
242 | struct usb_host_interface *alts, | 162 | * initialize the pitch control and sample rate |
243 | struct audioformat *fmt, int rate) | 163 | */ |
164 | int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, | ||
165 | struct usb_host_interface *alts, | ||
166 | struct audioformat *fmt) | ||
244 | { | 167 | { |
245 | struct usb_interface_descriptor *altsd = get_iface_desc(alts); | 168 | struct usb_interface_descriptor *altsd = get_iface_desc(alts); |
246 | 169 | ||
170 | /* if endpoint doesn't have pitch control, bail out */ | ||
171 | if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL)) | ||
172 | return 0; | ||
173 | |||
247 | switch (altsd->bInterfaceProtocol) { | 174 | switch (altsd->bInterfaceProtocol) { |
248 | case UAC_VERSION_1: | 175 | case UAC_VERSION_1: |
249 | return set_sample_rate_v1(chip, iface, alts, fmt, rate); | 176 | return init_pitch_v1(chip, iface, alts, fmt); |
250 | 177 | ||
251 | case UAC_VERSION_2: | 178 | case UAC_VERSION_2: |
252 | return set_sample_rate_v2(chip, iface, alts, fmt, rate); | 179 | return init_pitch_v2(chip, iface, alts, fmt); |
253 | } | 180 | } |
254 | 181 | ||
255 | return -EINVAL; | 182 | return -EINVAL; |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 91ddef31bcb..f8797f61a24 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -1973,6 +1973,17 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1973 | } | 1973 | } |
1974 | }, | 1974 | }, |
1975 | 1975 | ||
1976 | /* AKAI devices */ | ||
1977 | { | ||
1978 | USB_DEVICE(0x09e8, 0x0062), | ||
1979 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1980 | .vendor_name = "AKAI", | ||
1981 | .product_name = "MPD16", | ||
1982 | .ifnum = 0, | ||
1983 | .type = QUIRK_MIDI_AKAI, | ||
1984 | } | ||
1985 | }, | ||
1986 | |||
1976 | /* TerraTec devices */ | 1987 | /* TerraTec devices */ |
1977 | { | 1988 | { |
1978 | USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0012), | 1989 | USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0012), |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 136e5b4cf6d..b45e54c09ba 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -289,6 +289,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, | |||
289 | [QUIRK_MIDI_FASTLANE] = create_any_midi_quirk, | 289 | [QUIRK_MIDI_FASTLANE] = create_any_midi_quirk, |
290 | [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, | 290 | [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, |
291 | [QUIRK_MIDI_CME] = create_any_midi_quirk, | 291 | [QUIRK_MIDI_CME] = create_any_midi_quirk, |
292 | [QUIRK_MIDI_AKAI] = create_any_midi_quirk, | ||
292 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, | 293 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, |
293 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, | 294 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, |
294 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, | 295 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, |
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index d679e72a3e5..24d3319cc34 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
@@ -40,9 +40,6 @@ struct snd_usb_audio { | |||
40 | int num_interfaces; | 40 | int num_interfaces; |
41 | int num_suspended_intf; | 41 | int num_suspended_intf; |
42 | 42 | ||
43 | /* for audio class v2 */ | ||
44 | int clock_id; | ||
45 | |||
46 | struct list_head pcm_list; /* list of pcm streams */ | 43 | struct list_head pcm_list; /* list of pcm streams */ |
47 | int pcm_devs; | 44 | int pcm_devs; |
48 | 45 | ||
@@ -53,6 +50,8 @@ struct snd_usb_audio { | |||
53 | int setup; /* from the 'device_setup' module param */ | 50 | int setup; /* from the 'device_setup' module param */ |
54 | int nrpacks; /* from the 'nrpacks' module param */ | 51 | int nrpacks; /* from the 'nrpacks' module param */ |
55 | int async_unlink; /* from the 'async_unlink' module param */ | 52 | int async_unlink; /* from the 'async_unlink' module param */ |
53 | |||
54 | struct usb_host_interface *ctrl_intf; /* the audio control interface */ | ||
56 | }; | 55 | }; |
57 | 56 | ||
58 | /* | 57 | /* |
@@ -74,6 +73,7 @@ enum quirk_type { | |||
74 | QUIRK_MIDI_FASTLANE, | 73 | QUIRK_MIDI_FASTLANE, |
75 | QUIRK_MIDI_EMAGIC, | 74 | QUIRK_MIDI_EMAGIC, |
76 | QUIRK_MIDI_CME, | 75 | QUIRK_MIDI_CME, |
76 | QUIRK_MIDI_AKAI, | ||
77 | QUIRK_MIDI_US122L, | 77 | QUIRK_MIDI_US122L, |
78 | QUIRK_AUDIO_STANDARD_INTERFACE, | 78 | QUIRK_AUDIO_STANDARD_INTERFACE, |
79 | QUIRK_AUDIO_FIXED_ENDPOINT, | 79 | QUIRK_AUDIO_FIXED_ENDPOINT, |