sound/firewire/oxfw/oxfw-pcm.c

Source file repositories/reference/linux-study-clean/sound/firewire/oxfw/oxfw-pcm.c

File Facts

System
Linux kernel
Corpus path
sound/firewire/oxfw/oxfw-pcm.c
Extension
.c
Size
11127 bytes
Lines
436
Domain
Driver Families
Bucket
sound/firewire
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (j == ARRAY_SIZE(list)) {
			list[count] = formation.pcm;
			if (++count == ARRAY_SIZE(list))
				break;
		}
	}

	return snd_interval_list(c, count, list, 0);
}

static void limit_channels_and_rates(struct snd_pcm_hardware *hw, u8 **formats)
{
	struct snd_oxfw_stream_formation formation;
	int i, err;

	hw->channels_min = UINT_MAX;
	hw->channels_max = 0;

	hw->rate_min = UINT_MAX;
	hw->rate_max = 0;
	hw->rates = 0;

	for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
		if (formats[i] == NULL)
			break;

		err = snd_oxfw_stream_parse_format(formats[i], &formation);
		if (err < 0)
			continue;

		hw->channels_min = min(hw->channels_min, formation.pcm);
		hw->channels_max = max(hw->channels_max, formation.pcm);

		hw->rate_min = min(hw->rate_min, formation.rate);
		hw->rate_max = max(hw->rate_max, formation.rate);
		hw->rates |= snd_pcm_rate_to_rate_bit(formation.rate);
	}
}

static int init_hw_params(struct snd_oxfw *oxfw,
			  struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	u8 **formats;
	struct amdtp_stream *stream;
	int err;

	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
		runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS;
		stream = &oxfw->tx_stream;
		formats = oxfw->tx_stream_formats;
	} else {
		runtime->hw.formats = AM824_OUT_PCM_FORMAT_BITS;
		stream = &oxfw->rx_stream;
		formats = oxfw->rx_stream_formats;
	}

	limit_channels_and_rates(&runtime->hw, formats);

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
				  hw_rule_channels, formats,
				  SNDRV_PCM_HW_PARAM_RATE, -1);
	if (err < 0)
		goto end;

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_rate, formats,
				  SNDRV_PCM_HW_PARAM_CHANNELS, -1);
	if (err < 0)
		goto end;

	err = amdtp_am824_add_pcm_hw_constraints(stream, runtime);
end:
	return err;
}

static int limit_to_current_params(struct snd_pcm_substream *substream)
{
	struct snd_oxfw *oxfw = substream->private_data;
	struct snd_oxfw_stream_formation formation;
	enum avc_general_plug_dir dir;
	int err;

	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
		dir = AVC_GENERAL_PLUG_DIR_OUT;
	else
		dir = AVC_GENERAL_PLUG_DIR_IN;

	err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
	if (err < 0)

Annotation

Implementation Notes