ALSA: dice: cache stream formats at current mode of sampling transmission frequency

In former commits, proxy structure get members for cache of stream
formats. This commit fills the cache with stream formats at current mode
of sampling transmission frequency.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Sakamoto 2018-05-02 19:16:42 +09:00 committed by Takashi Iwai
parent b7fd3d64e7
commit b60152f750
3 changed files with 93 additions and 0 deletions

View File

@ -30,6 +30,34 @@ const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = {
[6] = 192000,
};
int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
enum snd_dice_rate_mode *mode)
{
/* Corresponding to each entry in snd_dice_rates. */
static const enum snd_dice_rate_mode modes[] = {
[0] = SND_DICE_RATE_MODE_LOW,
[1] = SND_DICE_RATE_MODE_LOW,
[2] = SND_DICE_RATE_MODE_LOW,
[3] = SND_DICE_RATE_MODE_MIDDLE,
[4] = SND_DICE_RATE_MODE_MIDDLE,
[5] = SND_DICE_RATE_MODE_HIGH,
[6] = SND_DICE_RATE_MODE_HIGH,
};
int i;
for (i = 0; i < ARRAY_SIZE(snd_dice_rates); i++) {
if (!(dice->clock_caps & BIT(i)))
continue;
if (snd_dice_rates[i] != rate)
continue;
*mode = modes[i];
return 0;
}
return -EINVAL;
}
/*
* This operation has an effect to synchronize GLOBAL_STATUS/GLOBAL_SAMPLE_RATE
* to GLOBAL_STATUS. Especially, just after powering on, these are different.
@ -484,6 +512,64 @@ void snd_dice_stream_update_duplex(struct snd_dice *dice)
}
}
int snd_dice_stream_detect_current_formats(struct snd_dice *dice)
{
unsigned int rate;
enum snd_dice_rate_mode mode;
__be32 reg[2];
struct reg_params tx_params, rx_params;
int i;
int err;
/*
* Available stream format is restricted at current mode of sampling
* clock.
*/
err = snd_dice_transaction_get_rate(dice, &rate);
if (err < 0)
return err;
err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
if (err < 0)
return err;
/*
* Just after owning the unit (GLOBAL_OWNER), the unit can return
* invalid stream formats. Selecting clock parameters have an effect
* for the unit to refine it.
*/
err = ensure_phase_lock(dice);
if (err < 0)
return err;
err = get_register_params(dice, &tx_params, &rx_params);
if (err < 0)
return err;
for (i = 0; i < tx_params.count; ++i) {
err = snd_dice_transaction_read_tx(dice,
tx_params.size * i + TX_NUMBER_AUDIO,
reg, sizeof(reg));
if (err < 0)
return err;
dice->tx_pcm_chs[i][mode] = be32_to_cpu(reg[0]);
dice->tx_midi_ports[i] = max_t(unsigned int,
be32_to_cpu(reg[1]), dice->tx_midi_ports[i]);
}
for (i = 0; i < rx_params.count; ++i) {
err = snd_dice_transaction_read_rx(dice,
rx_params.size * i + RX_NUMBER_AUDIO,
reg, sizeof(reg));
if (err < 0)
return err;
dice->rx_pcm_chs[i][mode] = be32_to_cpu(reg[0]);
dice->rx_midi_ports[i] = max_t(unsigned int,
be32_to_cpu(reg[1]), dice->rx_midi_ports[i]);
}
return 0;
}
static void dice_lock_changed(struct snd_dice *dice)
{
dice->dev_lock_changed = true;

View File

@ -199,6 +199,10 @@ static void do_registration(struct work_struct *work)
dice_card_strings(dice);
err = snd_dice_stream_detect_current_formats(dice);
if (err < 0)
goto error;
err = snd_dice_stream_init_duplex(dice);
if (err < 0)
goto error;

View File

@ -201,11 +201,14 @@ void snd_dice_transaction_destroy(struct snd_dice *dice);
#define SND_DICE_RATES_COUNT 7
extern const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT];
int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
enum snd_dice_rate_mode *mode);
int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate);
void snd_dice_stream_stop_duplex(struct snd_dice *dice);
int snd_dice_stream_init_duplex(struct snd_dice *dice);
void snd_dice_stream_destroy_duplex(struct snd_dice *dice);
void snd_dice_stream_update_duplex(struct snd_dice *dice);
int snd_dice_stream_detect_current_formats(struct snd_dice *dice);
int snd_dice_stream_lock_try(struct snd_dice *dice);
void snd_dice_stream_lock_release(struct snd_dice *dice);