Skip to content

Commit

Permalink
ALSA: dice: cache stream formats at current mode of sampling transmis…
Browse files Browse the repository at this point in the history
…sion 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>
  • Loading branch information
takaswie authored and tiwai committed May 2, 2018
1 parent b7fd3d6 commit b60152f
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 0 deletions.
86 changes: 86 additions & 0 deletions sound/firewire/dice/dice-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions sound/firewire/dice/dice.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions sound/firewire/dice/dice.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit b60152f

Please sign in to comment.