Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10550bea authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai
Browse files

ALSA: dice/firewire-lib: Keep dualwire mode but obsolete CIP_HI_DUALWIRE



In previous commit, AMDTP functionality in firewire-lib supports mapping
for PCM data channels. With this mapping, firewire-lib can obsolete
a flag, CIP_HI_DUALWIRE, but Dice driver still keeps dual wire mode.

Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 77d2a8a4
Loading
Loading
Loading
Loading
+6 −145
Original line number Original line Diff line number Diff line
@@ -145,14 +145,7 @@ void amdtp_stream_set_parameters(struct amdtp_stream *s,
	return;
	return;


sfc_found:
sfc_found:
	s->dual_wire = (s->flags & CIP_HI_DUALWIRE) && sfc > CIP_SFC_96000;
	if (s->dual_wire) {
		sfc -= 2;
		rate /= 2;
		s->pcm_channels = pcm_channels * 2;
	} else {
	s->pcm_channels = pcm_channels;
	s->pcm_channels = pcm_channels;
	}
	s->sfc = sfc;
	s->sfc = sfc;
	s->data_block_quadlets = s->pcm_channels + midi_channels;
	s->data_block_quadlets = s->pcm_channels + midi_channels;
	s->midi_ports = midi_ports;
	s->midi_ports = midi_ports;
@@ -191,18 +184,9 @@ static void amdtp_write_s16(struct amdtp_stream *s,
static void amdtp_write_s32(struct amdtp_stream *s,
static void amdtp_write_s32(struct amdtp_stream *s,
			    struct snd_pcm_substream *pcm,
			    struct snd_pcm_substream *pcm,
			    __be32 *buffer, unsigned int frames);
			    __be32 *buffer, unsigned int frames);
static void amdtp_write_s16_dualwire(struct amdtp_stream *s,
				     struct snd_pcm_substream *pcm,
				     __be32 *buffer, unsigned int frames);
static void amdtp_write_s32_dualwire(struct amdtp_stream *s,
				     struct snd_pcm_substream *pcm,
				     __be32 *buffer, unsigned int frames);
static void amdtp_read_s32(struct amdtp_stream *s,
static void amdtp_read_s32(struct amdtp_stream *s,
			   struct snd_pcm_substream *pcm,
			   struct snd_pcm_substream *pcm,
			   __be32 *buffer, unsigned int frames);
			   __be32 *buffer, unsigned int frames);
static void amdtp_read_s32_dualwire(struct amdtp_stream *s,
				    struct snd_pcm_substream *pcm,
				    __be32 *buffer, unsigned int frames);


/**
/**
 * amdtp_stream_set_pcm_format - set the PCM format
 * amdtp_stream_set_pcm_format - set the PCM format
@@ -225,26 +209,16 @@ void amdtp_stream_set_pcm_format(struct amdtp_stream *s,
		/* fall through */
		/* fall through */
	case SNDRV_PCM_FORMAT_S16:
	case SNDRV_PCM_FORMAT_S16:
		if (s->direction == AMDTP_OUT_STREAM) {
		if (s->direction == AMDTP_OUT_STREAM) {
			if (s->dual_wire)
				s->transfer_samples = amdtp_write_s16_dualwire;
			else
			s->transfer_samples = amdtp_write_s16;
			s->transfer_samples = amdtp_write_s16;
			break;
			break;
		}
		}
		WARN_ON(1);
		WARN_ON(1);
		/* fall through */
		/* fall through */
	case SNDRV_PCM_FORMAT_S32:
	case SNDRV_PCM_FORMAT_S32:
		if (s->direction == AMDTP_OUT_STREAM) {
		if (s->direction == AMDTP_OUT_STREAM)
			if (s->dual_wire)
				s->transfer_samples = amdtp_write_s32_dualwire;
			else
			s->transfer_samples = amdtp_write_s32;
			s->transfer_samples = amdtp_write_s32;
		} else {
			if (s->dual_wire)
				s->transfer_samples = amdtp_read_s32_dualwire;
		else
		else
			s->transfer_samples = amdtp_read_s32;
			s->transfer_samples = amdtp_read_s32;
		}
		break;
		break;
	}
	}
}
}
@@ -393,68 +367,6 @@ static void amdtp_write_s16(struct amdtp_stream *s,
	}
	}
}
}


static void amdtp_write_s32_dualwire(struct amdtp_stream *s,
				     struct snd_pcm_substream *pcm,
				     __be32 *buffer, unsigned int frames)
{
	struct snd_pcm_runtime *runtime = pcm->runtime;
	unsigned int channels, remaining_frames, i, c;
	const u32 *src;

	src = (void *)runtime->dma_area +
			frames_to_bytes(runtime, s->pcm_buffer_pointer);
	remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
	channels = s->pcm_channels / 2;

	for (i = 0; i < frames; ++i) {
		for (c = 0; c < channels; ++c) {
			buffer[s->pcm_positions[c] * 2] =
					cpu_to_be32((*src >> 8) | 0x40000000);
			src++;
		}
		buffer += 1;
		for (c = 0; c < channels; ++c) {
			buffer[s->pcm_positions[c] * 2] =
					cpu_to_be32((*src >> 8) | 0x40000000);
			src++;
		}
		buffer += s->data_block_quadlets - 1;
		if (--remaining_frames == 0)
			src = (void *)runtime->dma_area;
	}
}

static void amdtp_write_s16_dualwire(struct amdtp_stream *s,
				     struct snd_pcm_substream *pcm,
				     __be32 *buffer, unsigned int frames)
{
	struct snd_pcm_runtime *runtime = pcm->runtime;
	unsigned int channels, remaining_frames, i, c;
	const u16 *src;

	src = (void *)runtime->dma_area +
			frames_to_bytes(runtime, s->pcm_buffer_pointer);
	remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
	channels = s->pcm_channels / 2;

	for (i = 0; i < frames; ++i) {
		for (c = 0; c < channels; ++c) {
			buffer[s->pcm_positions[c] * 2] =
					cpu_to_be32((*src << 8) | 0x40000000);
			src++;
		}
		buffer += 1;
		for (c = 0; c < channels; ++c) {
			buffer[s->pcm_positions[c] * 2] =
					cpu_to_be32((*src << 8) | 0x40000000);
			src++;
		}
		buffer += s->data_block_quadlets - 1;
		if (--remaining_frames == 0)
			src = (void *)runtime->dma_area;
	}
}

static void amdtp_read_s32(struct amdtp_stream *s,
static void amdtp_read_s32(struct amdtp_stream *s,
			   struct snd_pcm_substream *pcm,
			   struct snd_pcm_substream *pcm,
			   __be32 *buffer, unsigned int frames)
			   __be32 *buffer, unsigned int frames)
@@ -479,37 +391,6 @@ static void amdtp_read_s32(struct amdtp_stream *s,
	}
	}
}
}


static void amdtp_read_s32_dualwire(struct amdtp_stream *s,
				    struct snd_pcm_substream *pcm,
				    __be32 *buffer, unsigned int frames)
{
	struct snd_pcm_runtime *runtime = pcm->runtime;
	unsigned int channels, remaining_frames, i, c;
	u32 *dst;

	dst = (void *)runtime->dma_area +
			frames_to_bytes(runtime, s->pcm_buffer_pointer);
	remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
	channels = s->pcm_channels / 2;

	for (i = 0; i < frames; ++i) {
		for (c = 0; c < channels; ++c) {
			*dst =
			     be32_to_cpu(buffer[s->pcm_positions[c] * 2]) << 8;
			dst++;
		}
		buffer += 1;
		for (c = 0; c < channels; ++c) {
			*dst =
			     be32_to_cpu(buffer[s->pcm_positions[c] * 2]) << 8;
			dst++;
		}
		buffer += s->data_block_quadlets - 1;
		if (--remaining_frames == 0)
			dst = (void *)runtime->dma_area;
	}
}

static void amdtp_fill_pcm_silence(struct amdtp_stream *s,
static void amdtp_fill_pcm_silence(struct amdtp_stream *s,
				   __be32 *buffer, unsigned int frames)
				   __be32 *buffer, unsigned int frames)
{
{
@@ -522,21 +403,6 @@ static void amdtp_fill_pcm_silence(struct amdtp_stream *s,
	}
	}
}
}


static void amdtp_fill_pcm_silence_dualwire(struct amdtp_stream *s,
					   __be32 *buffer, unsigned int frames)
{
	unsigned int i, c, channels;

	channels = s->pcm_channels / 2;
	for (i = 0; i < frames; ++i) {
		for (c = 0; c < channels; ++c) {
			buffer[s->pcm_positions[c] * 2] =
			buffer[s->pcm_positions[c] * 2 + 1] =
						cpu_to_be32(0x40000000);
		}
		buffer += s->data_block_quadlets;
	}
}
static void amdtp_fill_midi(struct amdtp_stream *s,
static void amdtp_fill_midi(struct amdtp_stream *s,
			    __be32 *buffer, unsigned int frames)
			    __be32 *buffer, unsigned int frames)
{
{
@@ -582,9 +448,6 @@ static void update_pcm_pointers(struct amdtp_stream *s,
				unsigned int frames)
				unsigned int frames)
{	unsigned int ptr;
{	unsigned int ptr;


	if (s->dual_wire)
		frames *= 2;

	ptr = s->pcm_buffer_pointer + frames;
	ptr = s->pcm_buffer_pointer + frames;
	if (ptr >= pcm->runtime->buffer_size)
	if (ptr >= pcm->runtime->buffer_size)
		ptr -= pcm->runtime->buffer_size;
		ptr -= pcm->runtime->buffer_size;
@@ -674,8 +537,6 @@ static void handle_out_packet(struct amdtp_stream *s, unsigned int syt)
	pcm = ACCESS_ONCE(s->pcm);
	pcm = ACCESS_ONCE(s->pcm);
	if (pcm)
	if (pcm)
		s->transfer_samples(s, pcm, buffer, data_blocks);
		s->transfer_samples(s, pcm, buffer, data_blocks);
	else if (s->dual_wire)
		amdtp_fill_pcm_silence_dualwire(s, buffer, data_blocks);
	else
	else
		amdtp_fill_pcm_silence(s, buffer, data_blocks);
		amdtp_fill_pcm_silence(s, buffer, data_blocks);
	if (s->midi_ports)
	if (s->midi_ports)
+1 −7
Original line number Original line Diff line number Diff line
@@ -16,18 +16,13 @@
 * @CIP_BLOCKING: In blocking mode, each packet contains either zero or
 * @CIP_BLOCKING: In blocking mode, each packet contains either zero or
 *	SYT_INTERVAL samples, with these two types alternating so that
 *	SYT_INTERVAL samples, with these two types alternating so that
 *	the overall sample rate comes out right.
 *	the overall sample rate comes out right.
 * @CIP_HI_DUALWIRE: At rates above 96 kHz, pretend that the stream runs
 *	at half the actual sample rate with twice the number of channels;
 *	two samples of a channel are stored consecutively in the packet.
 *	Requires blocking mode and SYT_INTERVAL-aligned PCM buffer size.
 * @CIP_SYNC_TO_DEVICE: In sync to device mode, time stamp in out packets is
 * @CIP_SYNC_TO_DEVICE: In sync to device mode, time stamp in out packets is
 *	generated by in packets. Defaultly this driver generates timestamp.
 *	generated by in packets. Defaultly this driver generates timestamp.
 */
 */
enum cip_flags {
enum cip_flags {
	CIP_NONBLOCKING		= 0x00,
	CIP_NONBLOCKING		= 0x00,
	CIP_BLOCKING		= 0x01,
	CIP_BLOCKING		= 0x01,
	CIP_HI_DUALWIRE		= 0x02,
	CIP_SYNC_TO_DEVICE	= 0x02,
	CIP_SYNC_TO_DEVICE	= 0x04,
};
};


/**
/**
@@ -84,7 +79,6 @@ struct amdtp_stream {
	struct mutex mutex;
	struct mutex mutex;


	enum cip_sfc sfc;
	enum cip_sfc sfc;
	bool dual_wire;
	unsigned int data_block_quadlets;
	unsigned int data_block_quadlets;
	unsigned int pcm_channels;
	unsigned int pcm_channels;
	unsigned int midi_ports;
	unsigned int midi_ports;
+27 −6
Original line number Original line Diff line number Diff line
@@ -563,7 +563,7 @@ static int dice_hw_params(struct snd_pcm_substream *substream,
			  struct snd_pcm_hw_params *hw_params)
			  struct snd_pcm_hw_params *hw_params)
{
{
	struct dice *dice = substream->private_data;
	struct dice *dice = substream->private_data;
	unsigned int rate_index, mode;
	unsigned int rate_index, mode, rate, channels, i;
	int err;
	int err;


	mutex_lock(&dice->mutex);
	mutex_lock(&dice->mutex);
@@ -575,15 +575,36 @@ static int dice_hw_params(struct snd_pcm_substream *substream,
	if (err < 0)
	if (err < 0)
		return err;
		return err;


	rate_index = rate_to_index(params_rate(hw_params));
	rate = params_rate(hw_params);
	rate_index = rate_to_index(rate);
	err = dice_change_rate(dice, rate_index << CLOCK_RATE_SHIFT);
	err = dice_change_rate(dice, rate_index << CLOCK_RATE_SHIFT);
	if (err < 0)
	if (err < 0)
		return err;
		return err;


	/*
	 * At rates above 96 kHz, pretend that the stream runs at half the
	 * actual sample rate with twice the number of channels; two samples
	 * of a channel are stored consecutively in the packet. Requires
	 * blocking mode and PCM buffer size should be aligned to SYT_INTERVAL.
	 */
	channels = params_channels(hw_params);
	if (rate_index > 4) {
		if (channels > AMDTP_MAX_CHANNELS_FOR_PCM / 2) {
			err = -ENOSYS;
			return err;
		}

		for (i = 0; i < channels; i++) {
			dice->stream.pcm_positions[i * 2] = i;
			dice->stream.pcm_positions[i * 2 + 1] = i + channels;
		}

		rate /= 2;
		channels *= 2;
	}

	mode = rate_index_to_mode(rate_index);
	mode = rate_index_to_mode(rate_index);
	amdtp_stream_set_parameters(&dice->stream,
	amdtp_stream_set_parameters(&dice->stream, rate, channels,
				    params_rate(hw_params),
				    params_channels(hw_params),
				    dice->rx_midi_ports[mode]);
				    dice->rx_midi_ports[mode]);
	amdtp_stream_set_pcm_format(&dice->stream,
	amdtp_stream_set_pcm_format(&dice->stream,
				    params_format(hw_params));
				    params_format(hw_params));
@@ -1361,7 +1382,7 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
	dice->resources.channels_mask = 0x00000000ffffffffuLL;
	dice->resources.channels_mask = 0x00000000ffffffffuLL;


	err = amdtp_stream_init(&dice->stream, unit, AMDTP_OUT_STREAM,
	err = amdtp_stream_init(&dice->stream, unit, AMDTP_OUT_STREAM,
				CIP_BLOCKING | CIP_HI_DUALWIRE);
				CIP_BLOCKING);
	if (err < 0)
	if (err < 0)
		goto err_resources;
		goto err_resources;