aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire/dice.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2011-09-04 16:12:06 -0400
committerClemens Ladisch <clemens@ladisch.de>2013-10-20 16:07:57 -0400
commit341682cd4f5603fccbf559d201402539880c04a5 (patch)
tree83ae2894e966fda412df2929012231f9ae6d1ce3 /sound/firewire/dice.c
parent6abce9e63d44e94b16f08794fb6f5ad6d1025c79 (diff)
ALSA: dice: allow all sample rates
Instead of forcing a constant 44.1 kHz, read the current sample rate from the device when opening the PCM device. Actually changing the sample rate requires some separate controller application. Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Diffstat (limited to 'sound/firewire/dice.c')
-rw-r--r--sound/firewire/dice.c55
1 files changed, 42 insertions, 13 deletions
diff --git a/sound/firewire/dice.c b/sound/firewire/dice.c
index b081021064ed..d3f3eb7a546a 100644
--- a/sound/firewire/dice.c
+++ b/sound/firewire/dice.c
@@ -75,6 +75,7 @@
75#define CLOCK_RATE_ANY_MID 0x00000800 75#define CLOCK_RATE_ANY_MID 0x00000800
76#define CLOCK_RATE_ANY_HIGH 0x00000900 76#define CLOCK_RATE_ANY_HIGH 0x00000900
77#define CLOCK_RATE_NONE 0x00000a00 77#define CLOCK_RATE_NONE 0x00000a00
78#define CLOCK_RATE_SHIFT 8
78#define GLOBAL_ENABLE 0x050 79#define GLOBAL_ENABLE 0x050
79#define ENABLE 0x00000001 80#define ENABLE 0x00000001
80#define GLOBAL_STATUS 0x054 81#define GLOBAL_STATUS 0x054
@@ -248,6 +249,16 @@ MODULE_DESCRIPTION("DICE driver");
248MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 249MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
249MODULE_LICENSE("GPL v2"); 250MODULE_LICENSE("GPL v2");
250 251
252static const unsigned int dice_rates[] = {
253 [0] = 32000,
254 [1] = 44100,
255 [2] = 48000,
256 [3] = 88200,
257 [4] = 96000,
258 [5] = 176400,
259 [6] = 192000,
260};
261
251static inline u64 global_address(struct dice *dice, unsigned int offset) 262static inline u64 global_address(struct dice *dice, unsigned int offset)
252{ 263{
253 return DICE_PRIVATE_SPACE + dice->global_offset + offset; 264 return DICE_PRIVATE_SPACE + dice->global_offset + offset;
@@ -508,9 +519,6 @@ static int dice_open(struct snd_pcm_substream *substream)
508 SNDRV_PCM_INFO_INTERLEAVED | 519 SNDRV_PCM_INFO_INTERLEAVED |
509 SNDRV_PCM_INFO_BLOCK_TRANSFER, 520 SNDRV_PCM_INFO_BLOCK_TRANSFER,
510 .formats = AMDTP_OUT_PCM_FORMAT_BITS, 521 .formats = AMDTP_OUT_PCM_FORMAT_BITS,
511 .rates = SNDRV_PCM_RATE_44100,
512 .rate_min = 44100,
513 .rate_max = 44100,
514 .buffer_bytes_max = 16 * 1024 * 1024, 522 .buffer_bytes_max = 16 * 1024 * 1024,
515 .period_bytes_min = 1, 523 .period_bytes_min = 1,
516 .period_bytes_max = UINT_MAX, 524 .period_bytes_max = UINT_MAX,
@@ -519,10 +527,21 @@ static int dice_open(struct snd_pcm_substream *substream)
519 }; 527 };
520 struct dice *dice = substream->private_data; 528 struct dice *dice = substream->private_data;
521 struct snd_pcm_runtime *runtime = substream->runtime; 529 struct snd_pcm_runtime *runtime = substream->runtime;
522 __be32 number_audio, number_midi; 530 __be32 clock_sel, number_audio, number_midi;
531 unsigned int rate;
523 int err; 532 int err;
524 533
525 err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST, 534 err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST,
535 global_address(dice, GLOBAL_CLOCK_SELECT),
536 &clock_sel, 4);
537 if (err < 0)
538 return err;
539 rate = (be32_to_cpu(clock_sel) & CLOCK_RATE_MASK) >> CLOCK_RATE_SHIFT;
540 if (rate >= ARRAY_SIZE(dice_rates))
541 return -ENXIO;
542 rate = dice_rates[rate];
543
544 err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST,
526 rx_address(dice, RX_NUMBER_AUDIO), 545 rx_address(dice, RX_NUMBER_AUDIO),
527 &number_audio, 4); 546 &number_audio, 4);
528 if (err < 0) 547 if (err < 0)
@@ -534,10 +553,14 @@ static int dice_open(struct snd_pcm_substream *substream)
534 return err; 553 return err;
535 554
536 runtime->hw = hardware; 555 runtime->hw = hardware;
556
557 runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
558 snd_pcm_limit_hw_rates(runtime);
559
537 runtime->hw.channels_min = be32_to_cpu(number_audio); 560 runtime->hw.channels_min = be32_to_cpu(number_audio);
538 runtime->hw.channels_max = be32_to_cpu(number_audio); 561 runtime->hw.channels_max = be32_to_cpu(number_audio);
539 562
540 amdtp_out_stream_set_rate(&dice->stream, 44100); 563 amdtp_out_stream_set_rate(&dice->stream, rate);
541 amdtp_out_stream_set_pcm(&dice->stream, be32_to_cpu(number_audio)); 564 amdtp_out_stream_set_pcm(&dice->stream, be32_to_cpu(number_audio));
542 amdtp_out_stream_set_midi(&dice->stream, be32_to_cpu(number_midi)); 565 amdtp_out_stream_set_midi(&dice->stream, be32_to_cpu(number_midi));
543 566
@@ -746,17 +769,9 @@ static int dice_create_pcm(struct dice *dice)
746 .page = snd_pcm_lib_get_vmalloc_page, 769 .page = snd_pcm_lib_get_vmalloc_page,
747 .mmap = snd_pcm_lib_mmap_vmalloc, 770 .mmap = snd_pcm_lib_mmap_vmalloc,
748 }; 771 };
749 __be32 clock;
750 struct snd_pcm *pcm; 772 struct snd_pcm *pcm;
751 int err; 773 int err;
752 774
753 clock = cpu_to_be32(CLOCK_SOURCE_ARX1 | CLOCK_RATE_44100);
754 err = snd_fw_transaction(dice->unit, TCODE_WRITE_QUADLET_REQUEST,
755 global_address(dice, GLOBAL_CLOCK_SELECT),
756 &clock, 4);
757 if (err < 0)
758 return err;
759
760 err = snd_pcm_new(dice->card, "DICE", 0, 1, 0, &pcm); 775 err = snd_pcm_new(dice->card, "DICE", 0, 1, 0, &pcm);
761 if (err < 0) 776 if (err < 0)
762 return err; 777 return err;
@@ -897,6 +912,7 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
897{ 912{
898 struct snd_card *card; 913 struct snd_card *card;
899 struct dice *dice; 914 struct dice *dice;
915 __be32 clock_sel;
900 int err; 916 int err;
901 917
902 err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*dice), &card); 918 err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*dice), &card);
@@ -938,6 +954,19 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
938 954
939 dice_card_strings(dice); 955 dice_card_strings(dice);
940 956
957 err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST,
958 global_address(dice, GLOBAL_CLOCK_SELECT),
959 &clock_sel, 4);
960 if (err < 0)
961 goto error;
962 clock_sel &= cpu_to_be32(~CLOCK_SOURCE_MASK);
963 clock_sel |= cpu_to_be32(CLOCK_SOURCE_ARX1);
964 err = snd_fw_transaction(unit, TCODE_WRITE_QUADLET_REQUEST,
965 global_address(dice, GLOBAL_CLOCK_SELECT),
966 &clock_sel, 4);
967 if (err < 0)
968 goto error;
969
941 err = dice_create_pcm(dice); 970 err = dice_create_pcm(dice);
942 if (err < 0) 971 if (err < 0)
943 goto error; 972 goto error;