예제 #1
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;
}
예제 #2
0
static int snd_stm_conv_dac_mem_probe(struct platform_device *pdev)
{
	int result = 0;
	struct snd_stm_conv_dac_mem_info *conv_dac_mem_info =
			pdev->dev.platform_data;
	struct snd_stm_conv_dac_mem *conv_dac_mem;
	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(!conv_dac_mem_info);

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

	/* Get resources */

	result = snd_stm_memory_request(pdev, &conv_dac_mem->mem_region,
			&conv_dac_mem->base);
	if (result < 0) {
		snd_stm_printe("Memory region request failed!\n");
		goto error_memory_request;
	}

	/* Get connections */

	BUG_ON(!conv_dac_mem_info->source_bus_id);
	snd_stm_printd(0, "This DAC is attached to PCM player '%s'.\n",
			conv_dac_mem_info->source_bus_id);
	conv_dac_mem->converter = snd_stm_conv_register_converter(
			"Analog Output",
			&snd_stm_conv_dac_mem_ops, conv_dac_mem,
			&platform_bus_type, conv_dac_mem_info->source_bus_id,
			conv_dac_mem_info->channel_from,
			conv_dac_mem_info->channel_to, NULL);
	if (!conv_dac_mem->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_mem,
			&snd_stm_conv_dac_mem_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_mem);

	return 0;

error_device:
error_attach:
	snd_stm_memory_release(conv_dac_mem->mem_region,
			conv_dac_mem->base);
error_memory_request:
	snd_stm_magic_clear(conv_dac_mem);
	kfree(conv_dac_mem);
error_alloc:
	return result;
}
예제 #3
0
static int snd_stm_conv_i2sspdif_probe(struct platform_device *pdev)
{
	int result = 0;
	struct snd_stm_conv_i2sspdif_info *conv_i2sspdif_info =
			pdev->dev.platform_data;
	struct snd_stm_conv_i2sspdif *conv_i2sspdif;

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

	BUG_ON(!conv_i2sspdif_info);

	conv_i2sspdif = kzalloc(sizeof(*conv_i2sspdif), GFP_KERNEL);
	if (!conv_i2sspdif) {
		snd_stm_printe("Can't allocate memory "
				"for a device description!\n");
		result = -ENOMEM;
		goto error_alloc;
	}
	snd_stm_magic_set(conv_i2sspdif);
	conv_i2sspdif->ver = conv_i2sspdif_info->ver;
	BUG_ON(conv_i2sspdif->ver <= 0);
	conv_i2sspdif->info = conv_i2sspdif_info;
	conv_i2sspdif->device = &pdev->dev;
	spin_lock_init(&conv_i2sspdif->iec958_default_lock);

	/* Get resources */

	result = snd_stm_memory_request(pdev, &conv_i2sspdif->mem_region,
			&conv_i2sspdif->base);
	if (result < 0) {
		snd_stm_printe("Memory region request failed!\n");
		goto error_memory_request;
	}

	/* Get connections */

	BUG_ON(!conv_i2sspdif_info->source_bus_id);
	snd_stm_printd(0, "This I2S-SPDIF converter is attached to PCM player"
			" '%s'.\n",
			conv_i2sspdif_info->source_bus_id);
	conv_i2sspdif->converter = snd_stm_conv_register_converter(
			"HDMI Output",
			&snd_stm_conv_i2sspdif_ops, conv_i2sspdif,
			&platform_bus_type, conv_i2sspdif_info->source_bus_id,
			conv_i2sspdif_info->channel_from,
			conv_i2sspdif_info->channel_to,
			&conv_i2sspdif->index);
	if (!conv_i2sspdif->converter) {
		snd_stm_printe("Can't attach to PCM player!\n");
		result = -EINVAL;
		goto error_attach;
	}

	/* Create ALSA lowlevel device*/

	result = snd_device_new(snd_stm_card_get(), SNDRV_DEV_LOWLEVEL,
			conv_i2sspdif, &snd_stm_conv_i2sspdif_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_i2sspdif);

	return result;

error_device:
error_attach:
	snd_stm_memory_release(conv_i2sspdif->mem_region,
			conv_i2sspdif->base);
error_memory_request:
	snd_stm_magic_clear(conv_i2sspdif);
	kfree(conv_i2sspdif);
error_alloc:
	return result;
}
예제 #4
0
static int __init snd_stm_fli75xx_glue_probe(struct platform_device *pdev)
{
	int result = 0;
	struct snd_stm_fli75xx_glue *fli75xx_glue;
	unsigned int value;

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

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

	result = snd_stm_memory_request(pdev, &fli75xx_glue->mem_region,
			&fli75xx_glue->base);
	if (result < 0) {
		snd_stm_printe("Memory region request failed!\n");
		goto error_memory_request;
	}

	/* Clocking configuration:
	 *
	 * clk_256fs_free_run --> SPDIF clock
	 *
	 * clk_256fs_dec_1 -----> MAIN (LS) clock
	 *
	 *                    ,-> ENCODER clock
	 * clk_256fs_dec_2 --<
	 *                    `-> DAC (HP, AUX) clock
	 */
	value = SPDIF_CLK__CLK_256FS_FREE_RUN;
	value |= MAIN_CLK__CLK_256FS_DEC_1;
	value |= ENC_CLK__CLK_256FS_DEC_2;
	value |= DAC_CLK__CLK_256FS_DEC_2;
	value |= SPDIF_CLK_DIV2_EN__DISABLED;
	value |= SPDIF_IN_PAD_HYST_EN__DISABLED;
	writel(value, AUD_CONFIG_REG1(fli75xx_glue->base));

	value = SPDIF__PLAYER;

	switch (cpu_data->type) {
	case CPU_FLI7510:
	case CPU_FLI7560:
		value |= FLI7510_MAIN_I2S__PCM_PLAYER_0;
		value |= FLI7510_SEC_I2S__PCM_PLAYER_1;
		break;
	case CPU_FLI7520:
	case CPU_FLI7530:
	case CPU_FLI7540:
		value |= FLI7520_MAIN_I2S__PCM_PLAYER_0;
		value |= FLI7520_SEC_I2S__PCM_PLAYER_1;
	default:
		BUG();
	}

	value |= SPDIF_PLAYER_EN__ENABLED;
	writel(value, AUD_CONFIG_REG2(fli75xx_glue->base));

	/* Additional procfs info */
	snd_stm_info_register(&fli75xx_glue->proc_entry, "fli75xx_glue",
			snd_stm_fli75xx_glue_dump_registers, fli75xx_glue);

	platform_set_drvdata(pdev, fli75xx_glue);

	return result;

error_memory_request:
	snd_stm_magic_clear(fli75xx_glue);
	kfree(fli75xx_glue);
error_alloc:
	return result;
}
예제 #5
0
static int snd_stm_pcm_player_probe(struct platform_device *pdev)
{
	int result = 0;
	struct snd_stm_pcm_player *pcm_player;
	struct snd_card *card = snd_stm_card_get();
	int i;

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

	BUG_ON(!card);

	pcm_player = kzalloc(sizeof(*pcm_player), GFP_KERNEL);
	if (!pcm_player) {
		snd_stm_printe("Can't allocate memory "
				"for a device description!\n");
		result = -ENOMEM;
		goto error_alloc;
	}
	snd_stm_magic_set(pcm_player);
	pcm_player->info = pdev->dev.platform_data;
	BUG_ON(!pcm_player->info);
	pcm_player->ver = pcm_player->info->ver;
	BUG_ON(pcm_player->ver <= 0);
	pcm_player->device = &pdev->dev;

	/* Get resources */

	result = snd_stm_memory_request(pdev, &pcm_player->mem_region,
			&pcm_player->base);
	if (result < 0) {
		snd_stm_printe("Memory region request failed!\n");
		goto error_memory_request;
	}
	pcm_player->fifo_phys_address = pcm_player->mem_region->start +
		offset__AUD_PCMOUT_DATA(pcm_player);
	snd_stm_printd(0, "FIFO physical address: 0x%lx.\n",
			pcm_player->fifo_phys_address);

	result = snd_stm_irq_request(pdev, &pcm_player->irq,
			snd_stm_pcm_player_irq_handler, pcm_player);
	if (result < 0) {
		snd_stm_printe("IRQ request failed!\n");
		goto error_irq_request;
	}

	result = snd_stm_fdma_request(pdev, &pcm_player->fdma_channel);
	if (result < 0) {
		snd_stm_printe("FDMA request failed!\n");
		goto error_fdma_request;
	}

	/* FDMA transfer size depends (among others ;-) on FIFO length,
	 * which is:
	 * - 30 cells (120 bytes) in STx7100/9 and STx7200 cut 1.0
	 * - 70 cells (280 bytes) in STx7111 and STx7200 cut 2.0. */

	if (pcm_player->ver < 5)
		pcm_player->fdma_max_transfer_size = 2;
	else if (pcm_player->ver == 5)
		pcm_player->fdma_max_transfer_size = 20;
	else
		pcm_player->fdma_max_transfer_size = 30;

	/* Get player capabilities */

	snd_stm_printd(0, "Player's name is '%s'\n", pcm_player->info->name);

	BUG_ON(pcm_player->info->channels <= 0);
	BUG_ON(pcm_player->info->channels > 10);
	BUG_ON(pcm_player->info->channels % 2 != 0);
	if (pcm_player->ver > 1) {
		static unsigned int channels_2_10[] = { 2, 4, 6, 8, 10 };

		pcm_player->channels_constraint.list = channels_2_10;
		pcm_player->channels_constraint.count =
			pcm_player->info->channels / 2;
	} else {
		/* In STx7100 cut < 3.0 PCM player ignored NUM_CH setting in
		 * AUD_PCMOUT_FMT register (and it was always in 10 channels
		 * mode...) */
		static unsigned int channels_10[] = { 10 };

		pcm_player->channels_constraint.list = channels_10;
		pcm_player->channels_constraint.count = 1;
	}
	pcm_player->channels_constraint.mask = 0;
	for (i = 0; i < pcm_player->channels_constraint.count; i++)
		snd_stm_printd(0, "Player capable of playing %u-channels PCM."
				"\n", pcm_player->channels_constraint.list[i]);

	/* STx7100 has a problem with 16/16 bits FIFO organization,
	 * so we disable the 16 bits samples capability... */
	if (pcm_player->ver <= 2)
		snd_stm_pcm_player_hw.formats &= ~SNDRV_PCM_FMTBIT_S16_LE;

	/* Create ALSA lowlevel device */

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

	/* Create ALSA PCM device */

	result = snd_pcm_new(card, NULL, pcm_player->info->card_device, 1, 0,
			&pcm_player->pcm);
	if (result < 0) {
		snd_stm_printe("ALSA PCM instance creation failed!\n");
		goto error_pcm;
	}
	pcm_player->pcm->private_data = pcm_player;
	strcpy(pcm_player->pcm->name, pcm_player->info->name);

	snd_pcm_set_ops(pcm_player->pcm, SNDRV_PCM_STREAM_PLAYBACK,
			&snd_stm_pcm_player_pcm_ops);

	/* Initialize buffer */

	pcm_player->buffer = snd_stm_buffer_create(pcm_player->pcm,
			pcm_player->device,
			snd_stm_pcm_player_hw.buffer_bytes_max);
	if (!pcm_player->buffer) {
		snd_stm_printe("Cannot initialize buffer!\n");
		result = -ENOMEM;
		goto error_buffer_init;
	}

	/* Register in converters router */

	pcm_player->conv_source = snd_stm_conv_register_source(
		&platform_bus_type, dev_name(&pdev->dev),
			pcm_player->info->channels,
			card, pcm_player->info->card_device);
	if (!pcm_player->conv_source) {
		snd_stm_printe("Cannot register in converters router!\n");
		result = -ENOMEM;
		goto error_conv_register_source;
	}

	/* Claim the pads */

	if (pcm_player->info->pad_config) {
		pcm_player->pads = stm_pad_claim(pcm_player->info->pad_config,
				dev_name(&pdev->dev));
		if (!pcm_player->pads) {
			snd_stm_printe("Failed to claimed pads for '%s'!\n",
					dev_name(&pdev->dev));
			result = -EBUSY;
			goto error_pad_claim;
		}
	}

	/* Done now */

	platform_set_drvdata(pdev, pcm_player);

	return 0;

error_pad_claim:
	snd_stm_conv_unregister_source(pcm_player->conv_source);
error_conv_register_source:
	snd_stm_buffer_dispose(pcm_player->buffer);
error_buffer_init:
	/* snd_pcm_free() is not available - PCM device will be released
	 * during card release */
error_pcm:
	snd_device_free(card, pcm_player);
error_device:
	snd_stm_fdma_release(pcm_player->fdma_channel);
error_fdma_request:
	snd_stm_irq_release(pcm_player->irq, pcm_player);
error_irq_request:
	snd_stm_memory_release(pcm_player->mem_region, pcm_player->base);
error_memory_request:
	snd_stm_magic_clear(pcm_player);
	kfree(pcm_player);
error_alloc:
	return result;
}