Esempio n. 1
0
static int mv88fx_initalize_machine_data(struct platform_device *pdev)
{
	struct resource *r = NULL;
	int err = 0;

	mv88fx_snd_debug("");

	mv88fx_machine_data.port = pdev->id;
	mv88fx_machine_data.pdata =
	    (struct orion_i2s_platform_data *)pdev->dev.platform_data;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		mv88fx_snd_error("");
		err = -ENXIO;
		goto error;
	}
	r = request_mem_region(r->start, SZ_16K, DRIVER_NAME);
	if (!r) {
		mv88fx_snd_error("");
		err = -EBUSY;
		goto error;
	}
	mv88fx_machine_data.res = r;
	mv88fx_machine_data.base = ioremap(r->start, SZ_16K);

	if (!mv88fx_machine_data.base) {
		mv88fx_snd_error("ioremap failed");
		err = -ENOMEM;
		goto error;
	}
	mv88fx_machine_data.base -= AUDIO_REG_BASE(mv88fx_machine_data.port);

	mv88fx_machine_data.irq = platform_get_irq(pdev, 0);
	if (mv88fx_machine_data.irq == NO_IRQ) {
		mv88fx_snd_error("");
		err = -ENXIO;
		goto error;
	}
#if defined(CONFIG_HAVE_CLK)
	mv88fx_machine_data.clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(mv88fx_machine_data.clk))
		dev_notice(&pdev->dev, "cannot get clkdev\n");
	else
		clk_enable(mv88fx_machine_data.clk);
#endif

	return 0;
error:
	if (mv88fx_machine_data.base) {
		iounmap(mv88fx_machine_data.base);
		mv88fx_machine_data.base = NULL;
	}
	release_mem_region(mv88fx_machine_data.res->start, SZ_16K);
	return err;
}
Esempio n. 2
0
static int mv88fx_i2_hw_init(int port)
{
	mv88fx_snd_debug("");

	mv88fx_snd_writel(mv88fx_i2s_info[port].base,
		MV_AUDIO_INT_CAUSE_REG(port), 0xffffffff);
	mv88fx_snd_writel(mv88fx_i2s_info[port].base,
		MV_AUDIO_INT_MASK_REG(port), 0);
	mv88fx_snd_writel(mv88fx_i2s_info[port].base,
		MV_AUDIO_SPDIF_REC_INT_CAUSE_MASK_REG(port), 0);

//	if (MV_OK != mvAudioInit(mv88fx_i2s_info.port))
//		return -EIO;
	mvSysAudioInit(port);

	/* Disable all playback/recording */
	mv88fx_snd_bitreset(mv88fx_i2s_info[port].base,
		MV_AUDIO_PLAYBACK_CTRL_REG(port),
		(APCR_PLAY_I2S_ENABLE_MASK | APCR_PLAY_SPDIF_ENABLE_MASK));

	mv88fx_snd_bitreset(mv88fx_i2s_info[port].base,
		MV_AUDIO_RECORD_CTRL_REG(port),
		(ARCR_RECORD_SPDIF_EN_MASK | ARCR_RECORD_I2S_EN_MASK));

	if (MV_OK != mvSPDIFRecordTclockSet(port)) {
		mv88fx_snd_error("mvSPDIFRecordTclockSet failed");
		return -ENOMEM;
	}
	return 0;
}
Esempio n. 3
0
static int mv88fx_snd_probe(struct platform_device *pdev)
{
	int ret = 0;

	mv88fx_snd_debug("mv88fx_snd_probe");

	if (mv88fx_initalize_machine_data(pdev) != 0)
		goto error;

	mv88fx_machine_data.snd_dev = platform_device_alloc("soc-audio", 0);
	if (!mv88fx_machine_data.snd_dev) {
		ret = -ENOMEM;
		goto error;
	}
	if(machine_is_dove_avng_v3())
	{
		platform_set_drvdata(mv88fx_machine_data.snd_dev, &mv88fx_snd_devdata_avd1_v3);
		mv88fx_snd_devdata_avd1_v3.dev = &mv88fx_machine_data.snd_dev->dev;
	}
	else
	{
		platform_set_drvdata(mv88fx_machine_data.snd_dev, &mv88fx_snd_devdata);
		mv88fx_snd_devdata.dev = &mv88fx_machine_data.snd_dev->dev;	
	}
	mv88fx_machine_data.snd_dev->dev.platform_data = &mv88fx_machine_data;

	ret = platform_device_add(mv88fx_machine_data.snd_dev);

	if(ret)
	{
                platform_device_put(mv88fx_machine_data.snd_dev);
	}

	ret = platform_device_register(&rt5630_codec_dev);
	if(ret)
                platform_device_unregister(&rt5630_codec_dev);
	return ret;
error:
	mv88fx_snd_error("");
#if defined(CONFIG_HAVE_CLK)
	if (!IS_ERR(mv88fx_machine_data.clk)) {
		clk_disable(mv88fx_machine_data.clk);
		clk_put(mv88fx_machine_data.clk);
	}
#endif
	if (mv88fx_machine_data.snd_dev)
		platform_device_unregister(mv88fx_machine_data.snd_dev);
	return ret;

}
Esempio n. 4
0
static int mv88fx_snd_probe(struct platform_device *pdev)
{
	int ret = 0;

	mv88fx_snd_debug("");

	if (mv88fx_initalize_machine_data(pdev) != 0)
		goto error;
	mv88fx_machine_data.snd_dev = platform_device_alloc("soc-audio", 1);
	if (!mv88fx_machine_data.snd_dev) {
		ret = -ENOMEM;
		goto error;
	}

	platform_set_drvdata(mv88fx_machine_data.snd_dev, &mv88fx_snd_devdata);
	mv88fx_snd_devdata.dev = &mv88fx_machine_data.snd_dev->dev;

	mv88fx_machine_data.snd_dev->dev.platform_data = &mv88fx_machine_data;

	ret = platform_device_add(mv88fx_machine_data.snd_dev);

	mv88fx_snd_debug("");

	return 0;
error:
	mv88fx_snd_error("");

#if defined(CONFIG_HAVE_CLK)
	if (!IS_ERR(mv88fx_machine_data.clk)) {
		clk_disable(mv88fx_machine_data.clk);
		clk_put(mv88fx_machine_data.clk);
	}
#endif

	if (mv88fx_machine_data.snd_dev)
		platform_device_unregister(mv88fx_machine_data.snd_dev);
	return ret;

}
Esempio n. 5
0
static int mv88fx_i2s_snd_hw_playback_set(struct mv88fx_snd_chip *chip,
					  struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct mv88fx_snd_stream *audio_stream = runtime->private_data;
	MV_AUDIO_PLAYBACK_CTRL pcm_play_ctrl;
	MV_I2S_PLAYBACK_CTRL i2s_play_ctrl;
	MV_SPDIF_PLAYBACK_CTRL spdif_play_ctrl;
	MV_AUDIO_FREQ_DATA dco_ctrl;

	mv88fx_snd_debug("chip=%p chip->base=%p", chip, chip->base);

	memset(&pcm_play_ctrl, 0, sizeof(pcm_play_ctrl));
	memset(&dco_ctrl, 0, sizeof(dco_ctrl));
	memset(&i2s_play_ctrl, 0, sizeof(i2s_play_ctrl));
	memset(&spdif_play_ctrl, 0, sizeof(spdif_play_ctrl));

	dco_ctrl.offset = chip->dco_ctrl_offst;

	mv88fx_snd_debug("rate: %u	", runtime->rate);
	switch (runtime->rate) {
	case 44100:
		dco_ctrl.baseFreq = AUDIO_FREQ_44_1KH;
		break;
	case 48000:
		dco_ctrl.baseFreq = AUDIO_FREQ_48KH;
		break;
	case 96000:
		dco_ctrl.baseFreq = AUDIO_FREQ_96KH;
		break;
	default:
		mv88fx_snd_error("Requested rate %d is not supported",
				 runtime->rate);
		return -1;
	}

	pcm_play_ctrl.burst = (chip->burst == 128) ? AUDIO_128BYTE_BURST :
	    AUDIO_32BYTE_BURST;

	pcm_play_ctrl.loopBack = chip->loopback;

	if (mv88fx_pcm_is_stereo(runtime)) {
		pcm_play_ctrl.monoMode = AUDIO_PLAY_MONO_OFF;
	} else {

		switch (audio_stream->mono_mode) {
		case MONO_LEFT:
			pcm_play_ctrl.monoMode = AUDIO_PLAY_LEFT_MONO;
			break;
		case MONO_RIGHT:
			pcm_play_ctrl.monoMode = AUDIO_PLAY_RIGHT_MONO;
			break;
		case MONO_BOTH:
		default:
			pcm_play_ctrl.monoMode = AUDIO_PLAY_BOTH_MONO;
			break;
		}
	}

	if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
		pcm_play_ctrl.sampleSize = SAMPLE_16BIT;
		i2s_play_ctrl.sampleSize = SAMPLE_16BIT;
	} else if (runtime->format == SNDRV_PCM_FORMAT_S24_LE) {
		pcm_play_ctrl.sampleSize = SAMPLE_24BIT;
		i2s_play_ctrl.sampleSize = SAMPLE_24BIT;

	} else if (runtime->format == SNDRV_PCM_FORMAT_S32_LE) {
		pcm_play_ctrl.sampleSize = SAMPLE_32BIT;
		i2s_play_ctrl.sampleSize = SAMPLE_32BIT;
	} else {
		mv88fx_snd_error("Requested format %d is not supported",
				 runtime->format);
		return -1;
	}

	/* buffer and period sizes in frame */
	pcm_play_ctrl.bufferPhyBase = runtime->dma_addr;
	pcm_play_ctrl.bufferSize =
	    frames_to_bytes(runtime, runtime->buffer_size);
	pcm_play_ctrl.intByteCount =
	    frames_to_bytes(runtime, runtime->period_size);

	/* I2S playback streem stuff */
	/*i2s_play_ctrl.sampleSize = pcm_play_ctrl.sampleSize; */
	i2s_play_ctrl.justification = I2S_JUSTIFIED;
	i2s_play_ctrl.sendLastFrame = 0;

	spdif_play_ctrl.nonPcm = MV_FALSE;

	spdif_play_ctrl.validity = chip->ch_stat_valid;

	if (audio_stream->stat_mem) {
		spdif_play_ctrl.userBitsFromMemory = MV_TRUE;
		spdif_play_ctrl.validityFromMemory = MV_TRUE;
		spdif_play_ctrl.blockStartInternally = MV_FALSE;
	} else {
		spdif_play_ctrl.userBitsFromMemory = MV_FALSE;
		spdif_play_ctrl.validityFromMemory = MV_FALSE;
		spdif_play_ctrl.blockStartInternally = MV_TRUE;
	}

	mv88fx_snd_debug("");
	/* If this is non-PCM sound, mute I2S channel */
	spin_lock_irq(&chip->reg_lock);

	mv88fx_snd_debug("chip=%p chip->base=%p port=%d", chip, chip->base,
			 chip->port);

	if (!(mv88fx_snd_readl(chip->base,
		MV_AUDIO_PLAYBACK_CTRL_REG(chip->port)) &
		(APCR_PLAY_I2S_ENABLE_MASK | APCR_PLAY_SPDIF_ENABLE_MASK))) {

		mv88fx_snd_debug("");

		if (MV_OK != mvAudioDCOCtrlSet(chip->port, &dco_ctrl)) {
			mv88fx_snd_error
			    ("Failed to initialize DCO clock control.");
			return -1;
			mv88fx_snd_debug("");

		}
	}

	mv88fx_snd_debug("");

	if (audio_stream->clock_src == DCO_CLOCK)
		while ((mv88fx_snd_readl(chip->base,
			 MV_AUDIO_SPCR_DCO_STATUS_REG(chip->port)) &
			ASDSR_DCO_LOCK_MASK) == 0)
			;
	else if (audio_stream->clock_src == SPCR_CLOCK)
		while ((mv88fx_snd_readl(chip->base,
			 MV_AUDIO_SPCR_DCO_STATUS_REG(chip->port)) &
			ASDSR_SPCR_LOCK_MASK) == 0)
			;

	mv88fx_snd_debug("");

	if (MV_OK != mvAudioPlaybackControlSet(chip->port, &pcm_play_ctrl)) {
		mv88fx_snd_error("Failed to initialize PCM playback control.");
		return -1;
	}
	mv88fx_snd_debug("");

	if (MV_OK != mvI2SPlaybackCtrlSet(chip->port, &i2s_play_ctrl)) {
		mv88fx_snd_error("Failed to initialize I2S playback control.");
		return -1;
	}
	mv88fx_snd_debug("");

	mvSPDIFPlaybackCtrlSet(chip->port, &spdif_play_ctrl);

	mv88fx_snd_debug("");

	spin_unlock_irq(&chip->reg_lock);

	return 0;
}
Esempio n. 6
0
static int mv88fx_i2s_snd_hw_capture_set(struct mv88fx_snd_chip *chip,
					 struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct mv88fx_snd_stream *audio_stream = runtime->private_data;
	MV_AUDIO_RECORD_CTRL pcm_rec_ctrl;
	MV_I2S_RECORD_CTRL i2s_rec_ctrl;
	MV_AUDIO_FREQ_DATA dco_ctrl;
//#ifdef CONFIG_MACH_DOVE_RD_AVNG
//	int phoneInDetected;
//#endif

	mv88fx_snd_debug("chip=%p chip->base=%p", chip, chip->base);

	dco_ctrl.offset = chip->dco_ctrl_offst;

	switch (runtime->rate) {
	case 44100:
		dco_ctrl.baseFreq = AUDIO_FREQ_44_1KH;
		break;
	case 48000:
		dco_ctrl.baseFreq = AUDIO_FREQ_48KH;
		break;
	case 96000:
		dco_ctrl.baseFreq = AUDIO_FREQ_96KH;
		break;
	default:
		mv88fx_snd_debug("ERROR");
		mv88fx_snd_error("Requested rate %d is not supported",
				 runtime->rate);
		return -1;
	}

	pcm_rec_ctrl.burst = (chip->burst == 128) ? AUDIO_128BYTE_BURST :
	    AUDIO_32BYTE_BURST;

	if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
		pcm_rec_ctrl.sampleSize = SAMPLE_16BIT;
	} else if (runtime->format == SNDRV_PCM_FORMAT_S24_LE) {
		pcm_rec_ctrl.sampleSize = SAMPLE_24BIT;
	} else if (runtime->format == SNDRV_PCM_FORMAT_S32_LE) {
		pcm_rec_ctrl.sampleSize = SAMPLE_32BIT;
	} else {
		mv88fx_snd_error("Requested format %d is not supported",
				 runtime->format);
		return -1;
	}

	pcm_rec_ctrl.mono =
	    (mv88fx_pcm_is_stereo(runtime)) ? MV_FALSE : MV_TRUE;

	if (pcm_rec_ctrl.mono) {
		switch (audio_stream->mono_mode) {
		case MONO_LEFT:
			pcm_rec_ctrl.monoChannel = AUDIO_REC_LEFT_MONO;
			break;
		default:
		case MONO_RIGHT:
			pcm_rec_ctrl.monoChannel = AUDIO_REC_RIGHT_MONO;
			break;
		}

	} else
		pcm_rec_ctrl.monoChannel = AUDIO_REC_LEFT_MONO;

	pcm_rec_ctrl.bufferPhyBase = runtime->dma_addr;
	pcm_rec_ctrl.bufferSize =
	    frames_to_bytes(runtime, runtime->buffer_size);
	pcm_rec_ctrl.intByteCount =
	    frames_to_bytes(runtime, runtime->period_size);

	/* I2S record streem stuff */
	i2s_rec_ctrl.sample = pcm_rec_ctrl.sampleSize;
	i2s_rec_ctrl.justf = I2S_JUSTIFIED;

	spin_lock_irq(&chip->reg_lock);

	/* set clock only if record is not enabled */
	if (!(mv88fx_snd_readl(chip->base,
		MV_AUDIO_RECORD_CTRL_REG(chip->port)) &
		(ARCR_RECORD_SPDIF_EN_MASK | ARCR_RECORD_I2S_EN_MASK))) {

		if (MV_OK != mvAudioDCOCtrlSet(chip->port, &dco_ctrl)) {
			mv88fx_snd_debug("ERROR");
			mv88fx_snd_error
			    ("Failed to initialize DCO clock control.");
			return -1;
		}
	}
	mv88fx_snd_debug("");
	if (MV_OK != mvAudioRecordControlSet(chip->port, &pcm_rec_ctrl)) {
		mv88fx_snd_error("Failed to initialize PCM record control.");
		return -1;
	}

	if (MV_OK != mvI2SRecordCntrlSet(chip->port, &i2s_rec_ctrl)) {
		mv88fx_snd_error("Failed to initialize I2S record control.");
		return -1;
	}
	mv88fx_snd_debug("");

//#ifdef CONFIG_MACH_DOVE_RD_AVNG
//	if (machine_is_dove_rd_avng()) {
//		phoneInDetected = gpio_get_value(53);
//		if (phoneInDetected < 0)
//			mv88fx_snd_error("Failed to detect phone-in.");
//		else {
//			int input_type;
//			mv88fx_snd_error("detect phone-in.");
//			if (!phoneInDetected)
//				input_type = 2;	/* external MIC */
//			else
//				input_type = 1;	/* internal MIC */
//		}
//	}
//#endif
	mv88fx_snd_debug("");

	spin_unlock_irq(&chip->reg_lock);

	mv88fx_snd_debug("");

	return 0;

}