Commit 341682cd authored by Clemens Ladisch's avatar Clemens Ladisch

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: default avatarClemens Ladisch <clemens@ladisch.de>
parent 6abce9e6
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
#define CLOCK_RATE_ANY_MID 0x00000800 #define CLOCK_RATE_ANY_MID 0x00000800
#define CLOCK_RATE_ANY_HIGH 0x00000900 #define CLOCK_RATE_ANY_HIGH 0x00000900
#define CLOCK_RATE_NONE 0x00000a00 #define CLOCK_RATE_NONE 0x00000a00
#define CLOCK_RATE_SHIFT 8
#define GLOBAL_ENABLE 0x050 #define GLOBAL_ENABLE 0x050
#define ENABLE 0x00000001 #define ENABLE 0x00000001
#define GLOBAL_STATUS 0x054 #define GLOBAL_STATUS 0x054
...@@ -248,6 +249,16 @@ MODULE_DESCRIPTION("DICE driver"); ...@@ -248,6 +249,16 @@ MODULE_DESCRIPTION("DICE driver");
MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
static const unsigned int dice_rates[] = {
[0] = 32000,
[1] = 44100,
[2] = 48000,
[3] = 88200,
[4] = 96000,
[5] = 176400,
[6] = 192000,
};
static inline u64 global_address(struct dice *dice, unsigned int offset) static inline u64 global_address(struct dice *dice, unsigned int offset)
{ {
return DICE_PRIVATE_SPACE + dice->global_offset + offset; return DICE_PRIVATE_SPACE + dice->global_offset + offset;
...@@ -508,9 +519,6 @@ static int dice_open(struct snd_pcm_substream *substream) ...@@ -508,9 +519,6 @@ static int dice_open(struct snd_pcm_substream *substream)
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER, SNDRV_PCM_INFO_BLOCK_TRANSFER,
.formats = AMDTP_OUT_PCM_FORMAT_BITS, .formats = AMDTP_OUT_PCM_FORMAT_BITS,
.rates = SNDRV_PCM_RATE_44100,
.rate_min = 44100,
.rate_max = 44100,
.buffer_bytes_max = 16 * 1024 * 1024, .buffer_bytes_max = 16 * 1024 * 1024,
.period_bytes_min = 1, .period_bytes_min = 1,
.period_bytes_max = UINT_MAX, .period_bytes_max = UINT_MAX,
...@@ -519,9 +527,20 @@ static int dice_open(struct snd_pcm_substream *substream) ...@@ -519,9 +527,20 @@ static int dice_open(struct snd_pcm_substream *substream)
}; };
struct dice *dice = substream->private_data; struct dice *dice = substream->private_data;
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
__be32 number_audio, number_midi; __be32 clock_sel, number_audio, number_midi;
unsigned int rate;
int err; int err;
err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST,
global_address(dice, GLOBAL_CLOCK_SELECT),
&clock_sel, 4);
if (err < 0)
return err;
rate = (be32_to_cpu(clock_sel) & CLOCK_RATE_MASK) >> CLOCK_RATE_SHIFT;
if (rate >= ARRAY_SIZE(dice_rates))
return -ENXIO;
rate = dice_rates[rate];
err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST, err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST,
rx_address(dice, RX_NUMBER_AUDIO), rx_address(dice, RX_NUMBER_AUDIO),
&number_audio, 4); &number_audio, 4);
...@@ -534,10 +553,14 @@ static int dice_open(struct snd_pcm_substream *substream) ...@@ -534,10 +553,14 @@ static int dice_open(struct snd_pcm_substream *substream)
return err; return err;
runtime->hw = hardware; runtime->hw = hardware;
runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
snd_pcm_limit_hw_rates(runtime);
runtime->hw.channels_min = be32_to_cpu(number_audio); runtime->hw.channels_min = be32_to_cpu(number_audio);
runtime->hw.channels_max = be32_to_cpu(number_audio); runtime->hw.channels_max = be32_to_cpu(number_audio);
amdtp_out_stream_set_rate(&dice->stream, 44100); amdtp_out_stream_set_rate(&dice->stream, rate);
amdtp_out_stream_set_pcm(&dice->stream, be32_to_cpu(number_audio)); amdtp_out_stream_set_pcm(&dice->stream, be32_to_cpu(number_audio));
amdtp_out_stream_set_midi(&dice->stream, be32_to_cpu(number_midi)); amdtp_out_stream_set_midi(&dice->stream, be32_to_cpu(number_midi));
...@@ -746,17 +769,9 @@ static int dice_create_pcm(struct dice *dice) ...@@ -746,17 +769,9 @@ static int dice_create_pcm(struct dice *dice)
.page = snd_pcm_lib_get_vmalloc_page, .page = snd_pcm_lib_get_vmalloc_page,
.mmap = snd_pcm_lib_mmap_vmalloc, .mmap = snd_pcm_lib_mmap_vmalloc,
}; };
__be32 clock;
struct snd_pcm *pcm; struct snd_pcm *pcm;
int err; int err;
clock = cpu_to_be32(CLOCK_SOURCE_ARX1 | CLOCK_RATE_44100);
err = snd_fw_transaction(dice->unit, TCODE_WRITE_QUADLET_REQUEST,
global_address(dice, GLOBAL_CLOCK_SELECT),
&clock, 4);
if (err < 0)
return err;
err = snd_pcm_new(dice->card, "DICE", 0, 1, 0, &pcm); err = snd_pcm_new(dice->card, "DICE", 0, 1, 0, &pcm);
if (err < 0) if (err < 0)
return err; return err;
...@@ -897,6 +912,7 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) ...@@ -897,6 +912,7 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
{ {
struct snd_card *card; struct snd_card *card;
struct dice *dice; struct dice *dice;
__be32 clock_sel;
int err; int err;
err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*dice), &card); 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,6 +954,19 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
dice_card_strings(dice); dice_card_strings(dice);
err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST,
global_address(dice, GLOBAL_CLOCK_SELECT),
&clock_sel, 4);
if (err < 0)
goto error;
clock_sel &= cpu_to_be32(~CLOCK_SOURCE_MASK);
clock_sel |= cpu_to_be32(CLOCK_SOURCE_ARX1);
err = snd_fw_transaction(unit, TCODE_WRITE_QUADLET_REQUEST,
global_address(dice, GLOBAL_CLOCK_SELECT),
&clock_sel, 4);
if (err < 0)
goto error;
err = dice_create_pcm(dice); err = dice_create_pcm(dice);
if (err < 0) if (err < 0)
goto error; goto error;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment