Exemple #1
0
static snd_pcm_uframes_t snd_stm_pcm_player_pointer(struct snd_pcm_substream
		*substream)
{
	struct snd_stm_pcm_player *pcm_player =
		snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	int residue, hwptr;
	snd_pcm_uframes_t pointer;

	snd_stm_printd(2, "snd_stm_pcm_player_pointer(substream=0x%p)\n",
			substream);

	BUG_ON(!pcm_player);
	BUG_ON(!snd_stm_magic_valid(pcm_player));
	BUG_ON(!runtime);

	residue = get_dma_residue(pcm_player->fdma_channel);
	hwptr = (runtime->dma_bytes - residue) % runtime->dma_bytes;
	pointer = bytes_to_frames(runtime, hwptr);

	snd_stm_printd(2, "FDMA residue value is %i and buffer size is %u"
			" bytes...\n", residue, runtime->dma_bytes);
	snd_stm_printd(2, "... so HW pointer in frames is %lu (0x%lx)!\n",
			pointer, pointer);

	return pointer;
}
Exemple #2
0
static int snd_stm_conv_i2sspdif_disable(struct snd_stm_conv_i2sspdif
		*conv_i2sspdif)
{
	snd_stm_printd(1, "snd_stm_conv_i2sspdif_disable(conv_i2sspdif=%p)\n",
			conv_i2sspdif);

	BUG_ON(!conv_i2sspdif);
	BUG_ON(!snd_stm_magic_valid(conv_i2sspdif));
	BUG_ON(!conv_i2sspdif->enabled);

	if (snd_stm_conv_i2sspdif_iec958_set(conv_i2sspdif,
			&snd_stm_conv_i2sspdif_iec958_zeroed) != 0)
		snd_stm_printe("WARNING! Failed to clear channel status "
				"registers!\n");

	set__AUD_SPDIFPC_CFG(conv_i2sspdif,
		mask__AUD_SPDIFPC_CFG__DEVICE_EN__DISABLED(conv_i2sspdif) |
		mask__AUD_SPDIFPC_CFG__SW_RESET__RESET(conv_i2sspdif) |
		mask__AUD_SPDIFPC_CFG__FIFO_EN__DISABLED(conv_i2sspdif) |
		mask__AUD_SPDIFPC_CFG__REQ_ACK_EN__DISABLED(conv_i2sspdif));
	set__AUD_SPDIFPC_CTRL(conv_i2sspdif,
		mask__AUD_SPDIFPC_CTRL__OPERATION__OFF(conv_i2sspdif));

	conv_i2sspdif->enabled = 0;

	return 0;
}
Exemple #3
0
static int snd_stm_conv_i2sspdif_disconnect(struct snd_device *snd_device)
{
	struct snd_stm_conv_i2sspdif *conv_i2sspdif = snd_device->device_data;

	snd_stm_printd(1, "%s(snd_device=0x%p)\n", __func__, snd_device);

	BUG_ON(!conv_i2sspdif);
	BUG_ON(!snd_stm_magic_valid(conv_i2sspdif));
	BUG_ON(conv_i2sspdif->enabled);

	/* Remove procfs entry */

	snd_stm_info_unregister(conv_i2sspdif->proc_entry);

	/* Power done mode, just to be sure :-) */

	set__AUD_SPDIFPC_CFG(conv_i2sspdif,
		mask__AUD_SPDIFPC_CFG__DEVICE_EN__DISABLED(conv_i2sspdif) |
		mask__AUD_SPDIFPC_CFG__SW_RESET__RESET(conv_i2sspdif) |
		mask__AUD_SPDIFPC_CFG__FIFO_EN__DISABLED(conv_i2sspdif) |
		mask__AUD_SPDIFPC_CFG__REQ_ACK_EN__DISABLED(conv_i2sspdif));

	set__AUD_SPDIFPC_CTRL(conv_i2sspdif,
		mask__AUD_SPDIFPC_CTRL__OPERATION__OFF(conv_i2sspdif));

	return 0;
}
Exemple #4
0
static int snd_stm_conv_dac_mem_get_oversampling(void *priv)
{
	snd_stm_printd(1, "snd_stm_conv_dac_mem_get_oversampling(priv=%p)\n",
			priv);

	return 256;
}
Exemple #5
0
static int snd_stm_pcm_player_hw_free(struct snd_pcm_substream *substream)
{
	struct snd_stm_pcm_player *pcm_player =
			snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;

	snd_stm_printd(1, "snd_stm_pcm_player_hw_free(substream=0x%p)\n",
			substream);

	BUG_ON(!pcm_player);
	BUG_ON(!snd_stm_magic_valid(pcm_player));
	BUG_ON(!runtime);

	/* This callback may be called more than once... */

	if (snd_stm_buffer_is_allocated(pcm_player->buffer)) {
		/* Let the FDMA stop */
		dma_wait_for_completion(pcm_player->fdma_channel);

		/* Free buffer */
		snd_stm_buffer_free(pcm_player->buffer);

		/* Free FDMA parameters & configuration */
		dma_params_free(&pcm_player->fdma_params);
		dma_req_free(pcm_player->fdma_channel,
				pcm_player->fdma_request);
	}

	return 0;
}
Exemple #6
0
static int snd_stm_conv_dac_sc_get_oversampling(void *priv)
{
	snd_stm_printd(1, "snd_stm_conv_dac_sc_get_oversampling(priv=%p)\n",
			priv);

	return OVERSAMPLING;
}
Exemple #7
0
static irqreturn_t snd_stm_pcm_player_irq_handler(int irq, void *dev_id)
{
	irqreturn_t result = IRQ_NONE;
	struct snd_stm_pcm_player *pcm_player = dev_id;
	unsigned int status;

	snd_stm_printd(2, "snd_stm_pcm_player_irq_handler(irq=%d, "
			"dev_id=0x%p)\n", irq, dev_id);

	BUG_ON(!pcm_player);
	BUG_ON(!snd_stm_magic_valid(pcm_player));

	/* Get interrupt status & clear them immediately */
	preempt_disable();
	status = get__AUD_PCMOUT_ITS(pcm_player);
	set__AUD_PCMOUT_ITS_CLR(pcm_player, status);
	preempt_enable();

	/* Underflow? */
	if (unlikely(status & mask__AUD_PCMOUT_ITS__UNF__PENDING(pcm_player))) {
		snd_stm_printe("Underflow detected in PCM player '%s'!\n",
			       dev_name(pcm_player->device));

		snd_pcm_stop(pcm_player->substream, SNDRV_PCM_STATE_XRUN);

		result = IRQ_HANDLED;
	} else if (likely(status &
			mask__AUD_PCMOUT_ITS__NSAMPLE__PENDING(pcm_player))) {
		/* Period successfully played */
		do {
			BUG_ON(!pcm_player->substream);

			snd_stm_printd(2, "Period elapsed ('%s')\n",
					dev_name(pcm_player->device));
			snd_pcm_period_elapsed(pcm_player->substream);

			result = IRQ_HANDLED;
		} while (0);
	}

	/* Some alien interrupt??? */
	BUG_ON(result != IRQ_HANDLED);

	return result;
}
Exemple #8
0
static int snd_stm_conv_i2sspdif_set_enabled(int enabled, void *priv)
{
	struct snd_stm_conv_i2sspdif *conv_i2sspdif = priv;

	snd_stm_printd(1, "snd_stm_conv_i2sspdif_set_enabled(enabled=%d, "
			"priv=%p)\n", enabled, priv);

	BUG_ON(!conv_i2sspdif);
	BUG_ON(!snd_stm_magic_valid(conv_i2sspdif));

	snd_stm_printd(1, "%sabling I2S to SPDIF converter '%s'.\n",
			enabled ? "En" : "Dis",
			dev_name(conv_i2sspdif->device));

	if (enabled)
		return snd_stm_conv_i2sspdif_enable(conv_i2sspdif);
	else
		return snd_stm_conv_i2sspdif_disable(conv_i2sspdif);
}
Exemple #9
0
static int snd_stm_conv_dac_sc_set_muted(int muted, void *priv)
{
	struct snd_stm_conv_dac_sc *conv_dac_sc = priv;

	snd_stm_printd(1, "snd_stm_conv_dac_sc_set_muted(muted=%d, priv=%p)\n",
		       muted, priv);

	BUG_ON(!conv_dac_sc);
	BUG_ON(!snd_stm_magic_valid(conv_dac_sc));

	snd_stm_printd(1, "%suting DAC %s.\n", muted ? "M" : "Unm",
			conv_dac_sc->bus_id);

	if (muted)
		sysconf_write(conv_dac_sc->softmute, 1); /* MUTE */
	else
		sysconf_write(conv_dac_sc->softmute, 0); /* NORMAL */

	return 0;
}
Exemple #10
0
static int snd_stm_conv_i2sspdif_oversampling(struct snd_stm_conv_i2sspdif
		*conv_i2sspdif)
{
	snd_stm_printd(1, "snd_stm_conv_i2sspdif_oversampling("
			"conv_i2sspdif=%p)\n", conv_i2sspdif);

	BUG_ON(!conv_i2sspdif);
	BUG_ON(!snd_stm_magic_valid(conv_i2sspdif));

	return DEFAULT_OVERSAMPLING;
}
Exemple #11
0
static int snd_stm_conv_i2sspdif_get_oversampling(void *priv)
{
	struct snd_stm_conv_i2sspdif *conv_i2sspdif = priv;

	snd_stm_printd(1, "snd_stm_conv_i2sspdif_get_oversampling(priv=%p)\n",
			priv);

	BUG_ON(!conv_i2sspdif);
	BUG_ON(!snd_stm_magic_valid(conv_i2sspdif));

	return snd_stm_conv_i2sspdif_oversampling(conv_i2sspdif);
}
Exemple #12
0
static int snd_stm_conv_i2sspdif_register(struct snd_device *snd_device)
{
	struct snd_stm_conv_i2sspdif *conv_i2sspdif = snd_device->device_data;
	int i;

	snd_stm_printd(1, "%s(snd_device=0x%p)\n", __func__, snd_device);

	BUG_ON(!conv_i2sspdif);
	BUG_ON(!snd_stm_magic_valid(conv_i2sspdif));
	BUG_ON(conv_i2sspdif->enabled);

	/* Initialize converter's input & SPDIF player as disabled */

	set__AUD_SPDIFPC_CFG(conv_i2sspdif,
		mask__AUD_SPDIFPC_CFG__DEVICE_EN__DISABLED(conv_i2sspdif) |
		mask__AUD_SPDIFPC_CFG__SW_RESET__RESET(conv_i2sspdif) |
		mask__AUD_SPDIFPC_CFG__FIFO_EN__DISABLED(conv_i2sspdif) |
		mask__AUD_SPDIFPC_CFG__REQ_ACK_EN__DISABLED(conv_i2sspdif));

	set__AUD_SPDIFPC_CTRL(conv_i2sspdif,
		mask__AUD_SPDIFPC_CTRL__OPERATION__OFF(conv_i2sspdif));

	/* Additional procfs info */

	snd_stm_info_register(&conv_i2sspdif->proc_entry,
			dev_name(conv_i2sspdif->device),
			snd_stm_conv_i2sspdif_dump_registers,
			conv_i2sspdif);

	/* Create ALSA controls */

	for (i = 0; i < ARRAY_SIZE(snd_stm_conv_i2sspdif_ctls); i++) {
		int result;

		snd_stm_conv_i2sspdif_ctls[i].device =
				snd_stm_conv_get_card_device(
				conv_i2sspdif->converter);
		snd_stm_conv_i2sspdif_ctls[i].index = conv_i2sspdif->index;
		result = snd_ctl_add(snd_stm_card_get(),
				snd_ctl_new1(&snd_stm_conv_i2sspdif_ctls[i],
				conv_i2sspdif));
		if (result < 0) {
			snd_stm_printe("Failed to add I2S-SPDIF converter "
					"ALSA control!\n");
			return result;
		}
	}

	return 0;
}
Exemple #13
0
static int snd_stm_conv_dac_sc_set_enabled(int enabled, void *priv)
{
	struct snd_stm_conv_dac_sc *conv_dac_sc = priv;

	snd_stm_printd(1, "snd_stm_conv_dac_sc_set_enabled(enabled=%d, "
			"priv=%p)\n", enabled, priv);

	BUG_ON(!conv_dac_sc);
	BUG_ON(!snd_stm_magic_valid(conv_dac_sc));

	snd_stm_printd(1, "%sabling DAC %s's digital part.\n",
			enabled ? "En" : "Dis", conv_dac_sc->bus_id);

	if (enabled) {
		sysconf_write(conv_dac_sc->nsb, 1); /* NORMAL */
		sysconf_write(conv_dac_sc->nrst, 1); /* NORMAL */
	} else {
		sysconf_write(conv_dac_sc->nrst, 0); /* RESET */
		sysconf_write(conv_dac_sc->nsb, 0); /* POWER_DOWN */
	}

	return 0;
}
Exemple #14
0
static int snd_stm_conv_dac_mem_set_muted(int muted, void *priv)
{
	struct snd_stm_conv_dac_mem *conv_dac_mem = priv;
	unsigned long value;

	snd_stm_printd(1, "snd_stm_conv_dac_mem_set_muted(muted=%d, priv=%p)\n",
		       muted, priv);

	BUG_ON(!conv_dac_mem);
	BUG_ON(!snd_stm_magic_valid(conv_dac_mem));

	snd_stm_printd(1, "%suting DAC %s.\n", muted ? "M" : "Unm",
			conv_dac_mem->dev_name);

	value = readl(ADAC_CTRL(conv_dac_mem->base));
	value &= ~SOFTMUTE__MASK;
	if (muted)
		value |= SOFTMUTE__MUTE;
	else
		value |= SOFTMUTE__NORMAL;
	writel(value, ADAC_CTRL(conv_dac_mem->base));

	return 0;
}
Exemple #15
0
static int __exit snd_stm_pcm_player_disconnect(struct snd_device *snd_device)
{
	struct snd_stm_pcm_player *pcm_player = snd_device->device_data;

	snd_stm_printd(1, "%s(snd_device=0x%p)\n", __func__, snd_device);

	BUG_ON(!pcm_player);
	BUG_ON(!snd_stm_magic_valid(pcm_player));

	snd_stm_clk_put(pcm_player->clock);

	snd_stm_info_unregister(pcm_player->proc_entry);

	return 0;
}
Exemple #16
0
static int snd_stm_conv_dac_mem_set_enabled(int enabled, void *priv)
{
	struct snd_stm_conv_dac_mem *conv_dac_mem = priv;
	unsigned long value;

	snd_stm_printd(1, "snd_stm_conv_dac_mem_set_enabled(enabled=%d, "
			"priv=%p)\n", enabled, priv);

	BUG_ON(!conv_dac_mem);
	BUG_ON(!snd_stm_magic_valid(conv_dac_mem));

	snd_stm_printd(1, "%sabling DAC %s's digital part.\n",
			enabled ? "En" : "Dis", conv_dac_mem->dev_name);

	value = readl(ADAC_CTRL(conv_dac_mem->base));
	value &= ~(NSB__MASK | NRST__MASK);
	if (enabled)
		value |= NSB__NORMAL | NRST__NORMAL;
	else
		value |= NSB__POWER_DOWN | NRST__RESET;
	writel(value, ADAC_CTRL(conv_dac_mem->base));

	return 0;
}
Exemple #17
0
static int snd_stm_conv_i2sspdif_enable(struct snd_stm_conv_i2sspdif
		*conv_i2sspdif)
{
	int oversampling;
	struct snd_aes_iec958 iec958;

	snd_stm_printd(1, "snd_stm_conv_i2sspdif_enable(conv_i2sspdif=%p)\n",
			conv_i2sspdif);

	BUG_ON(!conv_i2sspdif);
	BUG_ON(!snd_stm_magic_valid(conv_i2sspdif));
	BUG_ON(conv_i2sspdif->enabled);

	oversampling = snd_stm_conv_i2sspdif_oversampling(conv_i2sspdif);
	BUG_ON(oversampling <= 0);
	BUG_ON((oversampling % 128) != 0);

	set__AUD_SPDIFPC_CFG(conv_i2sspdif,
		mask__AUD_SPDIFPC_CFG__DEVICE_EN__ENABLED(conv_i2sspdif) |
		mask__AUD_SPDIFPC_CFG__SW_RESET__RUNNING(conv_i2sspdif) |
		mask__AUD_SPDIFPC_CFG__FIFO_EN__ENABLED(conv_i2sspdif) |
		mask__AUD_SPDIFPC_CFG__AUDIO_WORD_SIZE__24_BITS(conv_i2sspdif)
		| mask__AUD_SPDIFPC_CFG__REQ_ACK_EN__ENABLED(conv_i2sspdif));
	set__AUD_SPDIFPC_CTRL(conv_i2sspdif,
		mask__AUD_SPDIFPC_CTRL__OPERATION__PCM(conv_i2sspdif) |
		mask__AUD_SPDIFPC_CTRL__ROUNDING__NO_ROUNDING(conv_i2sspdif));
	set__AUD_SPDIFPC_CTRL__DIVIDER(conv_i2sspdif, oversampling / 128);

	/* Full channel status processing - an undocumented feature that
	 * exists in some hardware... Normally channel status registers
	 * provides bits for each subframe, so only for 96 frames (a half
	 * of SPDIF block) - pathetic! ;-) Setting bit 6 of config register
	 * enables a mode in which channel status bits in L/R subframes
	 * are identical, and whole block is served... */
	if (conv_i2sspdif->ver >= 4)
		set__AUD_SPDIFPC_CFG__CHA_STA_BITS__FRAME(conv_i2sspdif);

	spin_lock(&conv_i2sspdif->iec958_default_lock);
	iec958 = conv_i2sspdif->iec958_default;
	spin_unlock(&conv_i2sspdif->iec958_default_lock);
	if (snd_stm_conv_i2sspdif_iec958_set(conv_i2sspdif, &iec958) != 0)
		snd_stm_printe("WARNING! Can't set channel status "
				"registers!\n");

	conv_i2sspdif->enabled = 1;

	return 0;
}
Exemple #18
0
static int snd_stm_pcm_player_release(struct snd_pcm_substream *substream)
{
	struct snd_stm_pcm_player *pcm_player =
		snd_pcm_substream_chip(substream);

	snd_stm_printd(1, "snd_stm_pcm_player_release(substream=0x%p)\n",
			substream);

	BUG_ON(!pcm_player);
	BUG_ON(!snd_stm_magic_valid(pcm_player));

	/* "Unmute" player */

	set__AUD_PCMOUT_CTRL__MODE__PCM(pcm_player);

	return 0;
}
Exemple #19
0
static int snd_stm_conv_i2sspdif_ctl_default_get(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	struct snd_stm_conv_i2sspdif *conv_i2sspdif =
			snd_kcontrol_chip(kcontrol);

	snd_stm_printd(1, "snd_stm_conv_i2sspdif_ctl_default_get("
			"kcontrol=0x%p, ucontrol=0x%p)\n", kcontrol, ucontrol);

	BUG_ON(!conv_i2sspdif);
	BUG_ON(!snd_stm_magic_valid(conv_i2sspdif));

	spin_lock(&conv_i2sspdif->iec958_default_lock);
	ucontrol->value.iec958 = conv_i2sspdif->iec958_default;
	spin_unlock(&conv_i2sspdif->iec958_default_lock);

	return 0;
}
Exemple #20
0
static int snd_stm_pcm_player_pause(struct snd_pcm_substream *substream)
{
	struct snd_stm_pcm_player *pcm_player =
			snd_pcm_substream_chip(substream);

	snd_stm_printd(1, "snd_stm_pcm_player_pause(substream=0x%p)\n",
			substream);

	BUG_ON(!pcm_player);
	BUG_ON(!snd_stm_magic_valid(pcm_player));

	/* "Mute" player
	 * Documentation describes this mode in a wrong way - data is _not_
	 * consumed in the "mute" mode, so it is actually a "pause" mode */

	set__AUD_PCMOUT_CTRL__MODE__MUTE(pcm_player);

	return 0;
}
Exemple #21
0
static int snd_stm_pcm_player_trigger(struct snd_pcm_substream *substream,
		int command)
{
	snd_stm_printd(1, "snd_stm_pcm_player_trigger(substream=0x%p,"
			" command=%d)\n", substream, command);

	switch (command) {
	case SNDRV_PCM_TRIGGER_START:
		return snd_stm_pcm_player_start(substream);
	case SNDRV_PCM_TRIGGER_STOP:
		return snd_stm_pcm_player_stop(substream);
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		return snd_stm_pcm_player_pause(substream);
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		return snd_stm_pcm_player_release(substream);
	default:
		return -EINVAL;
	}
}
Exemple #22
0
static int snd_stm_pcm_player_close(struct snd_pcm_substream *substream)
{
	struct snd_stm_pcm_player *pcm_player =
			snd_pcm_substream_chip(substream);

	snd_stm_printd(1, "snd_stm_pcm_player_close(substream=0x%p)\n",
			substream);

	BUG_ON(!pcm_player);
	BUG_ON(!snd_stm_magic_valid(pcm_player));

	if (pcm_player->conv_group) {
		snd_stm_conv_release_group(pcm_player->conv_group);
		pcm_player->conv_group = NULL;
	}

	pcm_player->substream = NULL;

	return 0;
}
Exemple #23
0
static int __exit snd_stm_fli75xx_glue_remove(struct platform_device *pdev)
{
	struct snd_stm_fli75xx_glue *fli75xx_glue = platform_get_drvdata(pdev);

	snd_stm_printd(0, "%s('%s')\n", __func__, dev_name(&pdev->dev));

	BUG_ON(!fli75xx_glue);
	BUG_ON(!snd_stm_magic_valid(fli75xx_glue));

	/* Remove procfs entry */
	snd_stm_info_unregister(fli75xx_glue->proc_entry);

	/* Disable audio outputs */

	snd_stm_memory_release(fli75xx_glue->mem_region, fli75xx_glue->base);

	snd_stm_magic_clear(fli75xx_glue);
	kfree(fli75xx_glue);

	return 0;
}
Exemple #24
0
static int snd_stm_pcm_player_remove(struct platform_device *pdev)
{
	struct snd_stm_pcm_player *pcm_player = platform_get_drvdata(pdev);

	snd_stm_printd(1, "snd_stm_pcm_player_remove(pdev=%p)\n", pdev);

	BUG_ON(!pcm_player);
	BUG_ON(!snd_stm_magic_valid(pcm_player));

	if (pcm_player->pads)
		stm_pad_release(pcm_player->pads);
	snd_stm_conv_unregister_source(pcm_player->conv_source);
	snd_stm_buffer_dispose(pcm_player->buffer);
	snd_stm_fdma_release(pcm_player->fdma_channel);
	snd_stm_irq_release(pcm_player->irq, pcm_player);
	snd_stm_memory_release(pcm_player->mem_region, pcm_player->base);

	snd_stm_magic_clear(pcm_player);
	kfree(pcm_player);

	return 0;
}
Exemple #25
0
static int snd_stm_pcm_player_register(struct snd_device *snd_device)
{
	struct snd_stm_pcm_player *pcm_player = snd_device->device_data;

	snd_stm_printd(1, "%s(snd_device=0x%p)\n", __func__, snd_device);

	BUG_ON(!pcm_player);
	BUG_ON(!snd_stm_magic_valid(pcm_player));

	/* Set reset mode */

	set__AUD_PCMOUT_RST__SRSTP__RESET(pcm_player);

	/* TODO: well, hardcoded - shall anyone use it?
	 * And what does it actually mean? */

	if (pcm_player->ver > 5)
		set__AUD_PCMOUT_FMT__BACK_STALLING__DISABLED(pcm_player);
	set__AUD_PCMOUT_CTRL__RND__NO_ROUNDING(pcm_player);

	/* Get frequency synthesizer channel */

	pcm_player->clock = snd_stm_clk_get(pcm_player->device,
			"pcm_player_clk", snd_device->card,
			pcm_player->info->card_device);
	if (!pcm_player->clock || IS_ERR(pcm_player->clock)) {
		snd_stm_printe("Failed to get a clock for '%s'!\n",
				dev_name(pcm_player->device));
		return -EINVAL;
	}

	/* Registers view in ALSA's procfs */

	snd_stm_info_register(&pcm_player->proc_entry,
			dev_name(pcm_player->device),
			snd_stm_pcm_player_dump_registers, pcm_player);

	return 0;
}
Exemple #26
0
static int snd_stm_pcm_player_stop(struct snd_pcm_substream *substream)
{
	struct snd_stm_pcm_player *pcm_player =
			snd_pcm_substream_chip(substream);

	snd_stm_printd(1, "snd_stm_pcm_player_stop(substream=0x%p)\n",
			substream);

	BUG_ON(!pcm_player);
	BUG_ON(!snd_stm_magic_valid(pcm_player));

	/* Mute & shutdown DAC */

	if (pcm_player->conv_group) {
		snd_stm_conv_mute(pcm_player->conv_group);
		snd_stm_conv_disable(pcm_player->conv_group);
	}

	/* Disable interrupts */

	set__AUD_PCMOUT_IT_EN_CLR__NSAMPLE__CLEAR(pcm_player);
	set__AUD_PCMOUT_IT_EN_CLR__UNF__CLEAR(pcm_player);
	disable_irq_nosync(pcm_player->irq);

	/* Stop PCM player */

	set__AUD_PCMOUT_CTRL__MODE__OFF(pcm_player);

	/* Stop FDMA transfer */

	dma_stop_channel(pcm_player->fdma_channel);

	/* Stop the clock & reset PCM player */

	clk_disable(pcm_player->clock);
	set__AUD_PCMOUT_RST__SRSTP__RESET(pcm_player);

	return 0;
}
Exemple #27
0
static int __init snd_stm_fli75xx_init(void)
{
	int result;

	snd_stm_printd(0, "%s()\n", __func__);

	switch (cpu_data->type) {
	case CPU_FLI7510:
	case CPU_FLI7520:
	case CPU_FLI7530:
	case CPU_FLI7540:
	case CPU_FLI7560:
		break;
	default:
		snd_stm_printe("Unsupported (non-Freeman) SOC detected!\n");
		result = -EINVAL;
		goto error_soc_type;
	}

	result = platform_driver_register(&snd_stm_fli75xx_glue_driver);
	if (result != 0) {
		snd_stm_printe("Failed to register audio glue driver!\n");
		goto error_glue_driver_register;
	}

	result = snd_stm_card_register();
	if (result != 0) {
		snd_stm_printe("Failed to register ALSA cards!\n");
		goto error_card_register;
	}

	return 0;

error_card_register:
	platform_driver_unregister(&snd_stm_fli75xx_glue_driver);
error_glue_driver_register:
error_soc_type:
	return result;
}
Exemple #28
0
static int snd_stm_conv_i2sspdif_ctl_default_put(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	struct snd_stm_conv_i2sspdif *conv_i2sspdif =
			snd_kcontrol_chip(kcontrol);
	int changed = 0;

	snd_stm_printd(1, "snd_stm_conv_i2sspdif_ctl_default_put("
			"kcontrol=0x%p, ucontrol=0x%p)\n", kcontrol, ucontrol);

	BUG_ON(!conv_i2sspdif);
	BUG_ON(!snd_stm_magic_valid(conv_i2sspdif));

	spin_lock(&conv_i2sspdif->iec958_default_lock);
	if (snd_stm_iec958_cmp(&conv_i2sspdif->iec958_default,
				&ucontrol->value.iec958) != 0) {
		conv_i2sspdif->iec958_default = ucontrol->value.iec958;
		changed = 1;
	}
	spin_unlock(&conv_i2sspdif->iec958_default_lock);

	return changed;
}
Exemple #29
0
static unsigned int snd_stm_conv_dac_sc_get_format(void *priv)
{
	snd_stm_printd(1, "snd_stm_conv_dac_sc_get_format(priv=%p)\n", priv);

	return FORMAT;
}
Exemple #30
0
static int snd_stm_conv_dac_sc_probe(struct platform_device *pdev)
{
	int result = 0;
	struct snd_stm_conv_dac_sc_info *info =
			pdev->dev.platform_data;
	struct snd_stm_conv_dac_sc *conv_dac_sc;
	struct snd_card *card = snd_stm_card_get();

	snd_stm_printd(0, "%s('%s')\n", __func__, dev_name(&pdev->dev));

	BUG_ON(!card);
	BUG_ON(!info);

	conv_dac_sc = kzalloc(sizeof(*conv_dac_sc), GFP_KERNEL);
	if (!conv_dac_sc) {
		snd_stm_printe("Can't allocate memory "
				"for a device description!\n");
		result = -ENOMEM;
		goto error_alloc;
	}
	snd_stm_magic_set(conv_dac_sc);
	conv_dac_sc->bus_id = dev_name(&pdev->dev);

	/* Get resources */

	conv_dac_sc->nrst = sysconf_claim(info->nrst.group, info->nrst.num,
			info->nrst.lsb, info->nrst.msb, "NRST");
	BUG_ON(!conv_dac_sc->nrst);
	conv_dac_sc->mode = sysconf_claim(info->mode.group, info->mode.num,
			info->mode.lsb, info->mode.msb, "MODE");
	BUG_ON(!conv_dac_sc->mode);
	conv_dac_sc->nsb = sysconf_claim(info->nsb.group, info->nsb.num,
			info->nsb.lsb, info->nsb.msb, "NSB");
	BUG_ON(!conv_dac_sc->nsb);
	conv_dac_sc->softmute = sysconf_claim(info->softmute.group,
			info->softmute.num, info->softmute.lsb,
			info->softmute.msb, "SOFTMUTE");
	BUG_ON(!conv_dac_sc->softmute);
	conv_dac_sc->pdana = sysconf_claim(info->pdana.group, info->pdana.num,
			info->pdana.lsb, info->pdana.msb, "PDANA");
	BUG_ON(!conv_dac_sc->pdana);
	conv_dac_sc->pndbg = sysconf_claim(info->pndbg.group, info->pndbg.num,
			info->pndbg.lsb, info->pndbg.msb, "PNDBG");
	BUG_ON(!conv_dac_sc->pndbg);

	/* Get connections */

	BUG_ON(!info->source_bus_id);
	snd_stm_printd(0, "This DAC is attached to PCM player '%s'.\n",
			info->source_bus_id);
	conv_dac_sc->converter = snd_stm_conv_register_converter(
			"Analog Output", &snd_stm_conv_dac_sc_ops, conv_dac_sc,
			&platform_bus_type, info->source_bus_id,
			info->channel_from, info->channel_to, NULL);
	if (!conv_dac_sc->converter) {
		snd_stm_printe("Can't attach to PCM player!\n");
		goto error_attach;
	}

	/* Create ALSA lowlevel device*/

	result = snd_device_new(card, SNDRV_DEV_LOWLEVEL, conv_dac_sc,
			&snd_stm_conv_dac_sc_snd_device_ops);
	if (result < 0) {
		snd_stm_printe("ALSA low level device creation failed!\n");
		goto error_device;
	}

	/* Done now */

	platform_set_drvdata(pdev, conv_dac_sc);

	return 0;

error_device:
error_attach:
	snd_stm_magic_clear(conv_dac_sc);
	kfree(conv_dac_sc);
error_alloc:
	return result;
}