static int davinci_i2s_probe(struct platform_device *pdev)
{
	struct snd_platform_data *pdata = pdev->dev.platform_data;
	struct davinci_mcbsp_dev *dev;
	struct resource *mem, *ioarea, *res;
	enum dma_event_q asp_chan_q = EVENTQ_0;
	enum dma_event_q ram_chan_q = EVENTQ_1;
	int ret;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "no mem resource?\n");
		return -ENODEV;
	}

	ioarea = devm_request_mem_region(&pdev->dev, mem->start,
					 resource_size(mem),
					 pdev->name);
	if (!ioarea) {
		dev_err(&pdev->dev, "McBSP region already claimed\n");
		return -EBUSY;
	}

	dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_mcbsp_dev),
			   GFP_KERNEL);
	if (!dev)
		return -ENOMEM;
	if (pdata) {
		dev->enable_channel_combine = pdata->enable_channel_combine;
		dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].sram_size =
			pdata->sram_size_playback;
		dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].sram_size =
			pdata->sram_size_capture;
		dev->clk_input_pin = pdata->clk_input_pin;
		dev->i2s_accurate_sck = pdata->i2s_accurate_sck;
		asp_chan_q = pdata->asp_chan_q;
		ram_chan_q = pdata->ram_chan_q;
	}

	dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].asp_chan_q	= asp_chan_q;
	dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].ram_chan_q	= ram_chan_q;
	dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].asp_chan_q	= asp_chan_q;
	dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].ram_chan_q	= ram_chan_q;

	dev->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(dev->clk))
		return -ENODEV;
	clk_enable(dev->clk);

	dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
	if (!dev->base) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto err_release_clk;
	}

	dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
	    (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG);

	dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
	    (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG);

	
	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!res) {
		dev_err(&pdev->dev, "no DMA resource\n");
		ret = -ENXIO;
		goto err_release_clk;
	}
	dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start;

	res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
	if (!res) {
		dev_err(&pdev->dev, "no DMA resource\n");
		ret = -ENXIO;
		goto err_release_clk;
	}
	dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
	dev->dev = &pdev->dev;

	dev_set_drvdata(&pdev->dev, dev);

	ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai);
	if (ret != 0)
		goto err_release_clk;

	return 0;

err_release_clk:
	clk_disable(dev->clk);
	clk_put(dev->clk);
	return ret;
}
Exemplo n.º 2
0
static int __init bfin_ac97_init(void)
{
	return snd_soc_register_dai(&bfin_ac97_dai);
}
Exemplo n.º 3
0
static __devinit int asoc_mcbsp_probe(struct platform_device *pdev)
{
	return snd_soc_register_dai(&pdev->dev, &omap_mcbsp_dai);
}
Exemplo n.º 4
0
static int __devinit s6000_i2s_probe(struct platform_device *pdev)
{
	struct s6000_i2s_dev *dev;
	struct resource *scbmem, *sifmem, *region, *dma1, *dma2;
	u8 __iomem *mmio;
	int ret;

	scbmem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!scbmem) {
		dev_err(&pdev->dev, "no mem resource?\n");
		ret = -ENODEV;
		goto err_release_none;
	}

	region = request_mem_region(scbmem->start, resource_size(scbmem),
								pdev->name);
	if (!region) {
		dev_err(&pdev->dev, "I2S SCB region already claimed\n");
		ret = -EBUSY;
		goto err_release_none;
	}

	mmio = ioremap(scbmem->start, resource_size(scbmem));
	if (!mmio) {
		dev_err(&pdev->dev, "can't ioremap SCB region\n");
		ret = -ENOMEM;
		goto err_release_scb;
	}

	sifmem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!sifmem) {
		dev_err(&pdev->dev, "no second mem resource?\n");
		ret = -ENODEV;
		goto err_release_map;
	}

	region = request_mem_region(sifmem->start, resource_size(sifmem),
								pdev->name);
	if (!region) {
		dev_err(&pdev->dev, "I2S SIF region already claimed\n");
		ret = -EBUSY;
		goto err_release_map;
	}

	dma1 = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!dma1) {
		dev_err(&pdev->dev, "no dma resource?\n");
		ret = -ENODEV;
		goto err_release_sif;
	}

	region = request_mem_region(dma1->start, resource_size(dma1),
								pdev->name);
	if (!region) {
		dev_err(&pdev->dev, "I2S DMA region already claimed\n");
		ret = -EBUSY;
		goto err_release_sif;
	}

	dma2 = platform_get_resource(pdev, IORESOURCE_DMA, 1);
	if (dma2) {
		region = request_mem_region(dma2->start, resource_size(dma2),
								pdev->name);
		if (!region) {
			dev_err(&pdev->dev,
				"I2S DMA region already claimed\n");
			ret = -EBUSY;
			goto err_release_dma1;
		}
	}

	dev = kzalloc(sizeof(struct s6000_i2s_dev), GFP_KERNEL);
	if (!dev) {
		ret = -ENOMEM;
		goto err_release_dma2;
	}
	dev_set_drvdata(&pdev->dev, dev);

	dev->sifbase = sifmem->start;
	dev->scbbase = mmio;

	s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0);
	s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_CLEAR,
			 S6_I2S_INT_ALIGNMENT |
			 S6_I2S_INT_UNDERRUN |
			 S6_I2S_INT_OVERRUN);

	s6000_i2s_stop_channel(dev, 0);
	s6000_i2s_stop_channel(dev, 1);
	s6000_i2s_wait_disabled(dev);

	dev->dma_params.check_xrun = s6000_i2s_check_xrun;
	dev->dma_params.trigger = s6000_i2s_trigger;
	dev->dma_params.dma_in = dma1->start;
	dev->dma_params.dma_out = dma2 ? dma2->start : 0;
	dev->dma_params.irq = platform_get_irq(pdev, 0);
	if (dev->dma_params.irq < 0) {
		dev_err(&pdev->dev, "no irq resource?\n");
		ret = -ENODEV;
		goto err_release_dev;
	}

	s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE,
			 S6_I2S_INT_ALIGNMENT |
			 S6_I2S_INT_UNDERRUN |
			 S6_I2S_INT_OVERRUN);

	ret = snd_soc_register_dai(&pdev->dev, &s6000_i2s_dai);
	if (ret)
		goto err_release_dev;

	return 0;

err_release_dev:
	kfree(dev);
err_release_dma2:
	if (dma2)
		release_mem_region(dma2->start, resource_size(dma2));
err_release_dma1:
	release_mem_region(dma1->start, resource_size(dma1));
err_release_sif:
	release_mem_region(sifmem->start, resource_size(sifmem));
err_release_map:
	iounmap(mmio);
err_release_scb:
	release_mem_region(scbmem->start, resource_size(scbmem));
err_release_none:
	return ret;
}
Exemplo n.º 5
0
static int tegra_i2s_driver_probe(struct platform_device *pdev)
{
	int err = 0;
	struct resource *res, *mem;
	struct tegra_i2s_info *info;
	int i = 0;

	pr_info("%s\n", __func__);

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->pdev = pdev;
	info->pdata = pdev->dev.platform_data;
	info->pdata->driver_data = info;
	BUG_ON(!info->pdata);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "no mem resource!\n");
		err = -ENODEV;
		goto fail;
	}

	mem = request_mem_region(res->start, resource_size(res), pdev->name);
	if (!mem) {
		dev_err(&pdev->dev, "memory region already claimed!\n");
		err = -EBUSY;
		goto fail;
	}

	info->i2s_phys = res->start;
	info->i2s_base = ioremap(res->start, res->end - res->start + 1);
	if (!info->i2s_base) {
		dev_err(&pdev->dev, "cannot remap iomem!\n");
		err = -ENOMEM;
		goto fail_release_mem;
	}

	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!res) {
		dev_err(&pdev->dev, "no dma resource!\n");
		err = -ENODEV;
		goto fail_unmap_mem;
	}
	info->dma_req_sel = res->start;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(&pdev->dev, "no irq resource!\n");
		err = -ENODEV;
		goto fail_unmap_mem;
	}
	info->irq = res->start;

	info->i2s_clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(info->i2s_clk)) {
		err = PTR_ERR(info->i2s_clk);
		goto fail_unmap_mem;
	}
	clk_set_rate(info->i2s_clk, info->pdata->i2s_clk_rate);

	info->dap_mclk = i2s_get_clock_by_name(info->pdata->dap_clk);
	if (IS_ERR(info->dap_mclk)) {
		err = PTR_ERR(info->dap_mclk);
		goto fail_unmap_mem;
	}

	info->audio_sync_clk = i2s_get_clock_by_name(
					info->pdata->audio_sync_clk);
	if (IS_ERR(info->audio_sync_clk)) {
		err = PTR_ERR(info->audio_sync_clk);
		goto fail_unmap_mem;
	}

	info->bit_format = TEGRA_AUDIO_BIT_FORMAT_DEFAULT;
	if (info->pdata->mode == I2S_BIT_FORMAT_DSP)
		info->bit_format = TEGRA_AUDIO_BIT_FORMAT_DSP;

	i2s_configure(info);

	for (i = 0; i < ARRAY_SIZE(tegra_i2s_dai); i++) {
		if (tegra_i2s_dai[i].id == pdev->id) {
			tegra_i2s_dai[i].dev = &pdev->dev;
			tegra_i2s_dai[i].private_data = info;
			err = snd_soc_register_dai(&tegra_i2s_dai[i]);
			if (err)
				goto fail_unmap_mem;
		}
	}

	return 0;

fail_unmap_mem:
	iounmap(info->i2s_base);
fail_release_mem:
	release_mem_region(mem->start, resource_size(mem));
fail:
	kfree(info);
	return err;
}
Exemplo n.º 6
0
/**
 * cs4270_i2c_probe - initialize the I2C interface of the CS4270
 * @i2c_client: the I2C client object
 * @id: the I2C device ID (ignored)
 *
 * This function is called whenever the I2C subsystem finds a device that
 * matches the device ID given via a prior call to i2c_add_driver().
 */
static int cs4270_i2c_probe(struct i2c_client *i2c_client,
	const struct i2c_device_id *id)
{
	struct snd_soc_codec *codec;
	struct cs4270_private *cs4270;
	unsigned int reg;
	int ret;

	/* For now, we only support one cs4270 device in the system.  See the
	 * comment for cs4270_codec.
	 */
	if (cs4270_codec) {
		dev_err(&i2c_client->dev, "ignoring CS4270 at addr %X\n",
		       i2c_client->addr);
		dev_err(&i2c_client->dev, "only one per board allowed\n");
		/* Should we return something other than ENODEV here? */
		return -ENODEV;
	}

	/* Verify that we have a CS4270 */

	ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
	if (ret < 0) {
		dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
		       i2c_client->addr);
		return ret;
	}
	/* The top four bits of the chip ID should be 1100. */
	if ((ret & 0xF0) != 0xC0) {
		dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
		       i2c_client->addr);
		return -ENODEV;
	}

	dev_info(&i2c_client->dev, "found device at i2c address %X\n",
		i2c_client->addr);
	dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);

	/* Allocate enough space for the snd_soc_codec structure
	   and our private data together. */
	cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
	if (!cs4270) {
		dev_err(&i2c_client->dev, "could not allocate codec\n");
		return -ENOMEM;
	}
	codec = &cs4270->codec;

	mutex_init(&codec->mutex);
	INIT_LIST_HEAD(&codec->dapm_widgets);
	INIT_LIST_HEAD(&codec->dapm_paths);

	codec->dev = &i2c_client->dev;
	codec->name = "CS4270";
	codec->owner = THIS_MODULE;
	codec->dai = &cs4270_dai;
	codec->num_dai = 1;
	codec->private_data = cs4270;
	codec->control_data = i2c_client;
	codec->read = cs4270_read_reg_cache;
	codec->write = cs4270_i2c_write;
	codec->reg_cache = cs4270->reg_cache;
	codec->reg_cache_size = CS4270_NUMREGS;

	/* The I2C interface is set up, so pre-fill our register cache */

	ret = cs4270_fill_cache(codec);
	if (ret < 0) {
		dev_err(&i2c_client->dev, "failed to fill register cache\n");
		goto error_free_codec;
	}

	/* Disable auto-mute.  This feature appears to be buggy.  In some
	 * situations, auto-mute will not deactivate when it should, so we want
	 * this feature disabled by default.  An application (e.g. alsactl) can
	 * re-enabled it by using the controls.
	 */

	reg = cs4270_read_reg_cache(codec, CS4270_MUTE);
	reg &= ~CS4270_MUTE_AUTO;
	ret = cs4270_i2c_write(codec, CS4270_MUTE, reg);
	if (ret < 0) {
		dev_err(&i2c_client->dev, "i2c write failed\n");
		return ret;
	}

	/* Disable automatic volume control.  The hardware enables, and it
	 * causes volume change commands to be delayed, sometimes until after
	 * playback has started.  An application (e.g. alsactl) can
	 * re-enabled it by using the controls.
	 */

	reg = cs4270_read_reg_cache(codec, CS4270_TRANS);
	reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
	ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
	if (ret < 0) {
		dev_err(&i2c_client->dev, "i2c write failed\n");
		return ret;
	}

	/* Initialize the DAI. Normally, we'd prefer to have a kmalloc'd DAI
	 * structure for each CS4270 device, but the machine driver needs to
	 * have a pointer to the DAI structure, so for now it must be a global
	 * variable.
	 */
	cs4270_dai.dev = &i2c_client->dev;

	/* Register the DAI.  If all the other ASoC driver have already
	 * registered, then this will call our probe function, so
	 * cs4270_codec needs to be ready.
	 */
	cs4270_codec = codec;
	ret = snd_soc_register_dai(&cs4270_dai);
	if (ret < 0) {
		dev_err(&i2c_client->dev, "failed to register DAIe\n");
		goto error_free_codec;
	}

	i2c_set_clientdata(i2c_client, cs4270);

	return 0;

error_free_codec:
	kfree(cs4270);
	cs4270_codec = NULL;
	cs4270_dai.dev = NULL;

	return ret;
}
Exemplo n.º 7
0
static int __init ak4535_modinit(void)
{
	return snd_soc_register_dai(&ak4535_dai);
}
Exemplo n.º 8
0
static int tegra30_i2s_platform_probe(struct platform_device *pdev)
{
	struct tegra30_i2s *i2s;
	u32 cif_ids[2];
	struct resource *mem, *memregion;
	void __iomem *regs;
	int ret;

	i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_i2s), GFP_KERNEL);
	if (!i2s) {
		dev_err(&pdev->dev, "Can't allocate tegra30_i2s\n");
		ret = -ENOMEM;
		goto err;
	}
	dev_set_drvdata(&pdev->dev, i2s);

	i2s->dai = tegra30_i2s_dai_template;
	i2s->dai.name = dev_name(&pdev->dev);

	ret = of_property_read_u32_array(pdev->dev.of_node,
					 "nvidia,ahub-cif-ids", cif_ids,
					 ARRAY_SIZE(cif_ids));
	if (ret < 0)
		goto err;

	i2s->playback_i2s_cif = cif_ids[0];
	i2s->capture_i2s_cif = cif_ids[1];

	i2s->clk_i2s = clk_get(&pdev->dev, NULL);
	if (IS_ERR(i2s->clk_i2s)) {
		dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
		ret = PTR_ERR(i2s->clk_i2s);
		goto err;
	}

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "No memory resource\n");
		ret = -ENODEV;
		goto err_clk_put;
	}

	memregion = devm_request_mem_region(&pdev->dev, mem->start,
					    resource_size(mem), DRV_NAME);
	if (!memregion) {
		dev_err(&pdev->dev, "Memory region already claimed\n");
		ret = -EBUSY;
		goto err_clk_put;
	}

	regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
	if (!regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto err_clk_put;
	}

	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
					    &tegra30_i2s_regmap_config);
	if (IS_ERR(i2s->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		ret = PTR_ERR(i2s->regmap);
		goto err_clk_put;
	}
	regcache_cache_only(i2s->regmap, true);

	pm_runtime_enable(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev)) {
		ret = tegra30_i2s_runtime_resume(&pdev->dev);
		if (ret)
			goto err_pm_disable;
	}

	ret = snd_soc_register_dai(&pdev->dev, &i2s->dai);
	if (ret) {
		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
		ret = -ENOMEM;
		goto err_suspend;
	}

	ret = tegra_pcm_platform_register(&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
		goto err_unregister_dai;
	}

	return 0;

err_unregister_dai:
	snd_soc_unregister_dai(&pdev->dev);
err_suspend:
	if (!pm_runtime_status_suspended(&pdev->dev))
		tegra30_i2s_runtime_suspend(&pdev->dev);
err_pm_disable:
	pm_runtime_disable(&pdev->dev);
err_clk_put:
	clk_put(i2s->clk_i2s);
err:
	return ret;
}
Exemplo n.º 9
0
static __devinit int asoc_pcm_cpu_probe(struct platform_device *pdev)
{
	return snd_soc_register_dai(&pdev->dev, msm_pcm_cpu_dais);
}
Exemplo n.º 10
0
static int __init mxs_spdif_dai_init(void)
{
	return snd_soc_register_dai(&mxs_spdif_dai);
}
Exemplo n.º 11
0
static int __devinit ux500_msp_drv_probe(struct platform_device *pdev)
{
    struct ux500_msp_i2s_drvdata *drvdata;
    int ret = 0;

    dev_dbg(&pdev->dev, "%s: Enter (pdev->name = %s).\n", __func__,
            pdev->name);

    drvdata = devm_kzalloc(&pdev->dev,
                           sizeof(struct ux500_msp_i2s_drvdata),
                           GFP_KERNEL);
    drvdata->fmt = 0;
    drvdata->slots = 1;
    drvdata->tx_mask = 0x01;
    drvdata->rx_mask = 0x01;
    drvdata->slot_width = 16;
    drvdata->master_clk = MSP_INPUT_FREQ_APB;

    drvdata->reg_vape = devm_regulator_get(&pdev->dev, "v-ape");
    if (IS_ERR(drvdata->reg_vape)) {
        ret = (int)PTR_ERR(drvdata->reg_vape);
        dev_err(&pdev->dev,
                "%s: ERROR: Failed to get Vape supply (%d)!\n",
                __func__, ret);
        return ret;
    }
    prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, (char *)pdev->name, 50);

    drvdata->clk = clk_get(&pdev->dev, NULL);
    if (IS_ERR(drvdata->clk)) {
        ret = (int)PTR_ERR(drvdata->clk);
        dev_err(&pdev->dev, "%s: ERROR: clk_get failed (%d)!\n",
                __func__, ret);
        goto err_clk;
    }

    ret = ux500_msp_i2s_init_msp(pdev, &drvdata->msp,
                                 pdev->dev.platform_data);
    if (!drvdata->msp) {
        dev_err(&pdev->dev,
                "%s: ERROR: Failed to init MSP-struct (%d)!",
                __func__, ret);
        goto err_init_msp;
    }
    dev_set_drvdata(&pdev->dev, drvdata);

    ret = snd_soc_register_dai(&pdev->dev,
                               &ux500_msp_dai_drv[drvdata->msp->id]);
    if (ret < 0) {
        dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n",
                __func__, drvdata->msp->id);
        goto err_init_msp;
    }

    return 0;

err_init_msp:
    clk_put(drvdata->clk);

err_clk:
    devm_regulator_put(drvdata->reg_vape);

    return ret;
}
static int davinci_mcasp_probe(struct platform_device *pdev)
{
	struct davinci_pcm_dma_params *dma_data;
	struct resource *mem, *ioarea, *res;
	struct snd_platform_data *pdata;
	struct davinci_audio_dev *dev;
	int ret = 0;

	dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL);
	if (!dev)
		return	-ENOMEM;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "no mem resource?\n");
		ret = -ENODEV;
		goto err_release_data;
	}

	ioarea = request_mem_region(mem->start,
			(mem->end - mem->start) + 1, pdev->name);
	if (!ioarea) {
		dev_err(&pdev->dev, "Audio region already claimed\n");
		ret = -EBUSY;
		goto err_release_data;
	}

	pdata = pdev->dev.platform_data;
	dev->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(dev->clk)) {
		ret = -ENODEV;
		goto err_release_region;
	}

	clk_enable(dev->clk);
	dev->clk_active = 1;

	dev->base = (void __iomem *)IO_ADDRESS(mem->start);
	dev->op_mode = pdata->op_mode;
	dev->tdm_slots = pdata->tdm_slots;
	dev->num_serializer = pdata->num_serializer;
	dev->serial_dir = pdata->serial_dir;
	dev->codec_fmt = pdata->codec_fmt;
	dev->version = pdata->version;
	dev->txnumevt = pdata->txnumevt;
	dev->rxnumevt = pdata->rxnumevt;

	dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
	dma_data->asp_chan_q = pdata->asp_chan_q;
	dma_data->ram_chan_q = pdata->ram_chan_q;
	dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
							io_v2p(dev->base));

	/* first TX, then RX */
	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!res) {
		dev_err(&pdev->dev, "no DMA resource\n");
		goto err_release_region;
	}

	dma_data->channel = res->start;

	dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE];
	dma_data->asp_chan_q = pdata->asp_chan_q;
	dma_data->ram_chan_q = pdata->ram_chan_q;
	dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
							io_v2p(dev->base));

	res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
	if (!res) {
		dev_err(&pdev->dev, "no DMA resource\n");
		goto err_release_region;
	}

	dma_data->channel = res->start;
	dev_set_drvdata(&pdev->dev, dev);
	ret = snd_soc_register_dai(&pdev->dev, &davinci_mcasp_dai[pdata->op_mode]);

	if (ret != 0)
		goto err_release_region;
	return 0;

err_release_region:
	release_mem_region(mem->start, (mem->end - mem->start) + 1);
err_release_data:
	kfree(dev);

	return ret;
}
Exemplo n.º 13
0
static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev)
{
    struct s3c_pcm_info *pcm;
    struct snd_soc_dai *dai;
    struct resource *mem_res, *dmatx_res, *dmarx_res;
    struct s3c_audio_pdata *pcm_pdata;
    int ret;

    /* Check for valid device index */
    if ((pdev->id < 0) || pdev->id >= ARRAY_SIZE(s3c_pcm)) {
        dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
        return -EINVAL;
    }

    pcm_pdata = pdev->dev.platform_data;

    /* Check for availability of necessary resource */
    dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
    if (!dmatx_res) {
        dev_err(&pdev->dev, "Unable to get PCM-TX dma resource\n");
        return -ENXIO;
    }

    dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
    if (!dmarx_res) {
        dev_err(&pdev->dev, "Unable to get PCM-RX dma resource\n");
        return -ENXIO;
    }

    mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!mem_res) {
        dev_err(&pdev->dev, "Unable to get register resource\n");
        return -ENXIO;
    }

    if (pcm_pdata && pcm_pdata->cfg_gpio && pcm_pdata->cfg_gpio(pdev)) {
        dev_err(&pdev->dev, "Unable to configure gpio\n");
        return -EINVAL;
    }

    pcm = &s3c_pcm[pdev->id];
    pcm->dev = &pdev->dev;

    spin_lock_init(&pcm->lock);

    dai = &s3c_pcm_dai[pdev->id];
    dai->dev = &pdev->dev;

    /* Default is 128fs */
    pcm->sclk_per_fs = 128;

    pcm->cclk = clk_get(&pdev->dev, "audio-bus");
    if (IS_ERR(pcm->cclk)) {
        dev_err(&pdev->dev, "failed to get audio-bus\n");
        ret = PTR_ERR(pcm->cclk);
        goto err1;
    }
    clk_enable(pcm->cclk);

    /* record our pcm structure for later use in the callbacks */
    dai->private_data = pcm;

    if (!request_mem_region(mem_res->start,
                            resource_size(mem_res), "samsung-pcm")) {
        dev_err(&pdev->dev, "Unable to request register region\n");
        ret = -EBUSY;
        goto err2;
    }

    pcm->regs = ioremap(mem_res->start, 0x100);
    if (pcm->regs == NULL) {
        dev_err(&pdev->dev, "cannot ioremap registers\n");
        ret = -ENXIO;
        goto err3;
    }

    pcm->pclk = clk_get(&pdev->dev, "pcm");
    if (IS_ERR(pcm->pclk)) {
        dev_err(&pdev->dev, "failed to get pcm_clock\n");
        ret = -ENOENT;
        goto err4;
    }
    clk_enable(pcm->pclk);

    ret = snd_soc_register_dai(dai);
    if (ret != 0) {
        dev_err(&pdev->dev, "failed to get pcm_clock\n");
        goto err5;
    }

    s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start
                                           + S3C_PCM_RXFIFO;
    s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start
                                            + S3C_PCM_TXFIFO;

    s3c_pcm_stereo_in[pdev->id].channel = dmarx_res->start;
    s3c_pcm_stereo_out[pdev->id].channel = dmatx_res->start;

    pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id];
    pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id];

    return 0;

err5:
    clk_disable(pcm->pclk);
    clk_put(pcm->pclk);
err4:
    iounmap(pcm->regs);
err3:
    release_mem_region(mem_res->start, resource_size(mem_res));
err2:
    clk_disable(pcm->cclk);
    clk_put(pcm->cclk);
err1:
    return ret;
}
Exemplo n.º 14
0
static __devinit int spdif_probe(struct platform_device *pdev)
{
	int ret;
	struct samsung_spdif_info *spdif;
	struct snd_soc_dai *dai;
	struct resource *mem_res, *dma_res;
	struct s3c_audio_pdata *spdif_pdata;

	spdif_pdata = pdev->dev.platform_data;

	dev_dbg(&pdev->dev, "Entered %s\n", __func__);

	dma_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!dma_res) {
		dev_err(&pdev->dev, "Unable to get dma resource.\n");
		return -ENXIO;
	}

	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem_res) {
		dev_err(&pdev->dev, "Unable to get register resource.\n");
		return -ENXIO;
	}

	if (spdif_pdata && spdif_pdata->cfg_gpio
			&& spdif_pdata->cfg_gpio(pdev)) {
		dev_err(&pdev->dev, "Unable to configure GPIO pins\n");
		return -EINVAL;
	}

	/* Fill-up basic DAI features */
	samsung_spdif_dai.name = "samsung-spdif";
	samsung_spdif_dai.ops = &spdif_dai_ops;
	samsung_spdif_dai.suspend = spdif_suspend;
	samsung_spdif_dai.resume = spdif_resume;
	samsung_spdif_dai.playback.channels_min = 2;
	samsung_spdif_dai.playback.channels_max = 2;
	samsung_spdif_dai.playback.rates = S5P_SPDIF_RATES;
	samsung_spdif_dai.playback.formats = S5P_SPDIF_FORMATS;

	spdif = &spdif_info;
	spdif->dev = &pdev->dev;

	spin_lock_init(&spdif->lock);

	spdif->pclk = clk_get(&pdev->dev, "spdif");
	if (IS_ERR(spdif->pclk)) {
		dev_err(&pdev->dev, "failed to get SPDIF PCLK\n");
		ret = -ENOENT;
		goto err0;
	}
	clk_enable(spdif->pclk);

	spdif->use_int_clk = 1;
	spdif->clk_rate = 0;

	/* Get source clock that can be set rate. Actually 'sclk_spdif'
	 * has no divider to set it's rate, so we should have to use
	 * parent clock of 'sclk_spdif' that has divider.
	 */
	spdif->sclk = clk_get_parent(clk_get(&pdev->dev, "sclk_spdif"));
	if (IS_ERR(spdif->sclk)) {
		dev_err(&pdev->dev, "failed to get SPDIF source clock\n");
		ret = -ENOENT;
		goto err1;
	}
	clk_enable(spdif->sclk);

	/* Request SPDIF Register's memory region */
	if (!request_mem_region(mem_res->start,
				resource_size(mem_res), "samsung-spdif")) {
		dev_err(&pdev->dev, "Unable to request register region\n");
		ret = -EBUSY;
		goto err2;
	}

	spdif->regs = ioremap(mem_res->start, 0x100);
	if (spdif->regs == NULL) {
		dev_err(&pdev->dev, "Cannot ioremap registers\n");
		ret = -ENXIO;
		goto err4;
	}

	/* Register cpu dai */
	dai = &samsung_spdif_dai;
	dai->dev = &pdev->dev;
	dai->private_data = spdif;

	ret = snd_soc_register_dai(dai);
	if (ret != 0) {
		dev_err(&pdev->dev, "Failed to register cpu dai\n");
		goto err5;
	}

	spdif_stereo_out.dma_size = 2;
	spdif_stereo_out.client = &spdif_dma_client_out;
	spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF;
	spdif_stereo_out.channel = dma_res->start;

	spdif->dma_playback = &spdif_stereo_out;

	return 0;
err5:
	iounmap(spdif->regs);
err4:
	release_mem_region(mem_res->start, resource_size(mem_res));
err2:
	clk_disable(spdif->sclk);
	clk_put(spdif->sclk);
err1:
	clk_disable(spdif->pclk);
	clk_put(spdif->pclk);
err0:
	return ret;
}
Exemplo n.º 15
0
static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
{
    struct tegra_i2s * i2s;
    char clk_name[12]; /* tegra-i2s.0 */
    struct resource *mem, *memregion, *dmareq;
    int ret;

    if ((pdev->id < 0) ||
            (pdev->id >= ARRAY_SIZE(tegra_i2s_dai))) {
        dev_err(&pdev->dev, "ID %d out of range\n", pdev->id);
        return -EINVAL;
    }

    /*
     * FIXME: Until a codec driver exists for the tegra DAS, hard-code a
     * 1:1 mapping between audio controllers and audio ports.
     */
    ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1 + pdev->id,
                                       TEGRA_DAS_DAP_SEL_DAC1 + pdev->id);
    if (ret) {
        dev_err(&pdev->dev, "Can't set up DAP connection\n");
        return ret;
    }
    ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1 + pdev->id,
                                       TEGRA_DAS_DAC_SEL_DAP1 + pdev->id);
    if (ret) {
        dev_err(&pdev->dev, "Can't set up DAC connection\n");
        return ret;
    }

    i2s = kzalloc(sizeof(struct tegra_i2s), GFP_KERNEL);
    if (!i2s) {
        dev_err(&pdev->dev, "Can't allocate tegra_i2s\n");
        ret = -ENOMEM;
        goto exit;
    }
    dev_set_drvdata(&pdev->dev, i2s);

    snprintf(clk_name, sizeof(clk_name), DRV_NAME ".%d", pdev->id);
    i2s->clk_i2s = clk_get_sys(clk_name, NULL);
    if (IS_ERR(i2s->clk_i2s)) {
        dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
        ret = PTR_ERR(i2s->clk_i2s);
        goto err_free;
    }

    mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!mem) {
        dev_err(&pdev->dev, "No memory resource\n");
        ret = -ENODEV;
        goto err_clk_put;
    }

    dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
    if (!dmareq) {
        dev_err(&pdev->dev, "No DMA resource\n");
        ret = -ENODEV;
        goto err_clk_put;
    }

    memregion = request_mem_region(mem->start, resource_size(mem),
                                   DRV_NAME);
    if (!memregion) {
        dev_err(&pdev->dev, "Memory region already claimed\n");
        ret = -EBUSY;
        goto err_clk_put;
    }

    i2s->regs = ioremap(mem->start, resource_size(mem));
    if (!i2s->regs) {
        dev_err(&pdev->dev, "ioremap failed\n");
        ret = -ENOMEM;
        goto err_release;
    }

    i2s->capture_dma_data.addr = mem->start + TEGRA_I2S_FIFO2;
    i2s->capture_dma_data.wrap = 4;
    i2s->capture_dma_data.width = 32;
    i2s->capture_dma_data.req_sel = dmareq->start;

    i2s->playback_dma_data.addr = mem->start + TEGRA_I2S_FIFO1;
    i2s->playback_dma_data.wrap = 4;
    i2s->playback_dma_data.width = 32;
    i2s->playback_dma_data.req_sel = dmareq->start;

    i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED;

    ret = snd_soc_register_dai(&pdev->dev, &tegra_i2s_dai[pdev->id]);
    if (ret) {
        dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
        ret = -ENOMEM;
        goto err_unmap;
    }

    tegra_i2s_debug_add(i2s, pdev->id);

    return 0;

err_unmap:
    iounmap(i2s->regs);
err_release:
    release_mem_region(mem->start, resource_size(mem));
err_clk_put:
    clk_put(i2s->clk_i2s);
err_free:
    kfree(i2s);
exit:
    return ret;
}
Exemplo n.º 16
0
static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)
{
	struct resource *mem;
	struct kirkwood_asoc_platform_data *data =
		pdev->dev.platform_data;
	struct kirkwood_dma_data *priv;
	int err;

	priv = kzalloc(sizeof(struct kirkwood_dma_data), GFP_KERNEL);
	if (!priv) {
		dev_err(&pdev->dev, "allocation failed\n");
		err = -ENOMEM;
		goto error;
	}
	dev_set_drvdata(&pdev->dev, priv);

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "platform_get_resource failed\n");
		err = -ENXIO;
		goto err_alloc;
	}

	priv->mem = request_mem_region(mem->start, SZ_16K, DRV_NAME);
	if (!priv->mem) {
		dev_err(&pdev->dev, "request_mem_region failed\n");
		err = -EBUSY;
		goto err_alloc;
	}

	priv->io = ioremap(priv->mem->start, SZ_16K);
	if (!priv->io) {
		dev_err(&pdev->dev, "ioremap failed\n");
		err = -ENOMEM;
		goto err_iomem;
	}

	priv->irq = platform_get_irq(pdev, 0);
	if (priv->irq <= 0) {
		dev_err(&pdev->dev, "platform_get_irq failed\n");
		err = -ENXIO;
		goto err_ioremap;
	}

	if (!data) {
		dev_err(&pdev->dev, "no platform data ?!\n");
		err = -EINVAL;
		goto err_ioremap;
	}

	priv->burst = data->burst;
	priv->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(priv->clk)) {
		dev_err(&pdev->dev, "no clock\n");
		err = PTR_ERR(priv->clk);
		goto err_ioremap;
	}
	clk_prepare_enable(priv->clk);
	writel(KIRKWOOD_MCLK_SOURCE_DCO, 
	       priv->io+KIRKWOOD_CLOCKS_CTRL);

	priv->extclk = clk_get(&pdev->dev, "extclk");
	if (!IS_ERR(priv->extclk)) {
		if (priv->extclk == priv->clk) {
			clk_put(priv->extclk);
			priv->extclk = NULL;
		} else {
			dev_info(&pdev->dev, "found external clock\n");
			clk_prepare_enable(priv->extclk);
			kirkwood_i2s_dai.playback.channels_min = 1;
			kirkwood_i2s_dai.playback.channels_max = 8;
			kirkwood_i2s_dai.playback.rates = 
				SNDRV_PCM_RATE_8000_192000 |
				SNDRV_PCM_RATE_CONTINUOUS |
				SNDRV_PCM_RATE_KNOT;
			kirkwood_i2s_dai.capture.rates = 
				SNDRV_PCM_RATE_8000_192000 |
				SNDRV_PCM_RATE_CONTINUOUS |
				SNDRV_PCM_RATE_KNOT;
		}
	}

	priv->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(priv->clk)) {
		dev_err(&pdev->dev, "no clock\n");
		err = PTR_ERR(priv->clk);
		goto err_ioremap;
	}
	clk_prepare_enable(priv->clk);

	err = snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai);
	if (!err)
		return 0;
	dev_err(&pdev->dev, "snd_soc_register_dai failed\n");

	clk_disable_unprepare(priv->clk);
	clk_put(priv->clk);

err_ioremap:
	iounmap(priv->io);
err_iomem:
	release_mem_region(priv->mem->start, SZ_16K);
err_alloc:
	kfree(priv);
error:
	return err;
}
Exemplo n.º 17
0
static int tegra20_spdif_platform_probe(struct platform_device *pdev)
{
	struct tegra20_spdif *spdif;
	struct resource *mem, *memregion, *dmareq;
	void __iomem *regs;
	int ret;
	u32 reg_val;

	spdif = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_spdif),
			     GFP_KERNEL);
	if (!spdif) {
		dev_err(&pdev->dev, "Can't allocate tegra20_spdif\n");
		ret = -ENOMEM;
		goto err;
	}
	dev_set_drvdata(&pdev->dev, spdif);

	spdif->clk_spdif_out = clk_get(&pdev->dev, "spdif_out");
	if (IS_ERR(spdif->clk_spdif_out)) {
		pr_err("Can't retrieve spdif clock\n");
		ret = PTR_ERR(spdif->clk_spdif_out);
		goto err;
	}

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "No memory resource\n");
		ret = -ENODEV;
		goto err_clk_put;
	}

	dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!dmareq) {
		dev_err(&pdev->dev, "No DMA resource\n");
		ret = -ENODEV;
		goto err_clk_put;
	}

	memregion = devm_request_mem_region(&pdev->dev, mem->start,
					    resource_size(mem), DRV_NAME);
	if (!memregion) {
		dev_err(&pdev->dev, "Memory region already claimed\n");
		ret = -EBUSY;
		goto err_clk_put;
	}

	regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
	if (!regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto err_clk_put;
	}

	spdif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
					    &tegra20_spdif_regmap_config);
	if (IS_ERR(spdif->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		ret = PTR_ERR(spdif->regmap);
		goto err_clk_put;
	}

	spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT;
	spdif->playback_dma_data.wrap = 4;
	spdif->playback_dma_data.width = 32;
	spdif->playback_dma_data.req_sel = dmareq->start;

	pm_runtime_enable(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev)) {
		ret = tegra20_spdif_runtime_resume(&pdev->dev);
		if (ret)
			goto err_pm_disable;
	}

	clk_enable(spdif->clk_spdif_out);

	reg_val = tegra20_spdif_read(spdif, TEGRA20_SPDIF_DATA_FIFO_CSR);
	reg_val &= ~TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_MASK;
	reg_val |= TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU4_WORD_FULL;
	tegra20_spdif_write(spdif, TEGRA20_SPDIF_DATA_FIFO_CSR, reg_val);

	clk_disable(spdif->clk_spdif_out);

	ret = snd_soc_register_dai(&pdev->dev, &tegra20_spdif_dai);
	if (ret) {
		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
		ret = -ENOMEM;
		goto err_suspend;
	}

	ret = tegra_pcm_platform_register(&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
		goto err_unregister_dai;
	}

	return 0;

err_unregister_dai:
	snd_soc_unregister_dai(&pdev->dev);
err_suspend:
	if (!pm_runtime_status_suspended(&pdev->dev))
		tegra20_spdif_runtime_suspend(&pdev->dev);
err_pm_disable:
	pm_runtime_disable(&pdev->dev);
err_clk_put:
	clk_put(spdif->clk_spdif_out);
err:
	return ret;
}
Exemplo n.º 18
0
static int wm8523_register(struct wm8523_priv *wm8523,
			   enum snd_soc_control_type control)
{
	int ret;
	struct snd_soc_codec *codec = &wm8523->codec;
	int i;

	if (wm8523_codec) {
		dev_err(codec->dev, "Another WM8523 is registered\n");
		return -EINVAL;
	}

	mutex_init(&codec->mutex);
	INIT_LIST_HEAD(&codec->dapm_widgets);
	INIT_LIST_HEAD(&codec->dapm_paths);

	snd_soc_codec_set_drvdata(codec, wm8523);
	codec->name = "WM8523";
	codec->owner = THIS_MODULE;
	codec->bias_level = SND_SOC_BIAS_OFF;
	codec->set_bias_level = wm8523_set_bias_level;
	codec->dai = &wm8523_dai;
	codec->num_dai = 1;
	codec->reg_cache_size = WM8523_REGISTER_COUNT;
	codec->reg_cache = &wm8523->reg_cache;
	codec->volatile_register = wm8523_volatile_register;

	wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
	wm8523->rate_constraint.count =
		ARRAY_SIZE(wm8523->rate_constraint_list);

	memcpy(codec->reg_cache, wm8523_reg, sizeof(wm8523_reg));

	ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
		goto err;
	}

	for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
		wm8523->supplies[i].supply = wm8523_supply_names[i];

	ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8523->supplies),
				 wm8523->supplies);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
		goto err;
	}

	ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
				    wm8523->supplies);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
		goto err_get;
	}

	ret = snd_soc_read(codec, WM8523_DEVICE_ID);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to read ID register\n");
		goto err_enable;
	}
	if (ret != wm8523_reg[WM8523_DEVICE_ID]) {
		dev_err(codec->dev, "Device is not a WM8523, ID is %x\n", ret);
		ret = -EINVAL;
		goto err_enable;
	}

	ret = snd_soc_read(codec, WM8523_REVISION);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to read revision register\n");
		goto err_enable;
	}
	dev_info(codec->dev, "revision %c\n",
		 (ret & WM8523_CHIP_REV_MASK) + 'A');

	ret = wm8523_reset(codec);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to issue reset\n");
		goto err_enable;
	}

	wm8523_dai.dev = codec->dev;

	/* Change some default settings - latch VU and enable ZC */
	wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
	wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;

	wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

	/* Bias level configuration will have done an extra enable */
	regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);

	wm8523_codec = codec;

	ret = snd_soc_register_codec(codec);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
		return ret;
	}

	ret = snd_soc_register_dai(&wm8523_dai);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
		snd_soc_unregister_codec(codec);
		return ret;
	}

	return 0;

err_enable:
	regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
err_get:
	regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
err:
	kfree(wm8523);
	return ret;
}
Exemplo n.º 19
0
static int imx_ssi_dev_probe(struct platform_device *pdev)
{
	int fifo0_channel = pdev->id * 2;
	struct snd_soc_dai *dai;
	struct imx_ssi *priv;
	int fifo, channel;
	struct resource *res;
	int ret;

	BUG_ON(fifo0_channel >= MAX_SSI_CHANNELS);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;

	priv = kzalloc(sizeof(struct imx_ssi), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	/* Each SSI block has 2 fifos which share the same
	   private data (struct imx_ssi) */
	priv->baseaddr = res->start;
	priv->ioaddr = ioremap(res->start, 0x5C);
	priv->irq = platform_get_irq(pdev, 0);
	priv->ssi_clk = clk_get(&pdev->dev, "ssi_clk");
	priv->pdev = pdev;

	for (fifo = 0; fifo < 2; fifo++) {
		channel = (pdev->id * 2) + fifo;

		dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
		if (IS_ERR(dai)) {
			ret = -ENOMEM;
			goto DAI_ERR;
		}

		dai->name = kasprintf(GFP_KERNEL, "imx-ssi-%d-%d",
				      pdev->id + 1, fifo);
		if (IS_ERR(dai->name)) {
			kfree(dai);
			ret = -ENOMEM;
			goto DAI_ERR;
		}

		dai->probe = imx_ssi_probe;
		dai->suspend = imx_ssi_suspend;
		dai->remove = imx_ssi_remove;
		dai->resume = imx_ssi_resume;

		dai->playback.channels_min = 1;
		dai->playback.channels_max = 2;
		dai->playback.rates = IMX_SSI_RATES;
		dai->playback.formats = IMX_SSI_FORMATS;

		dai->capture.channels_min = 1;
		dai->capture.channels_max = 2;
		dai->capture.rates = IMX_SSI_RATES;
		dai->capture.formats = IMX_SSI_FORMATS;

		dai->ops = &imx_ssi_dai_ops;

		dai->private_data = priv;

		dai->id = channel;
		imx_ssi_dai[channel] = dai;

		ret = snd_soc_register_dai(dai);
		if (ret < 0) {
			kfree(dai->name);
			kfree(dai);
			goto DAI_ERR;
		}
	}
	return 0;

DAI_ERR:
	if (fifo == 1) {
		dai = imx_ssi_dai[fifo0_channel];
		snd_soc_unregister_dai(dai);
		kfree(dai->name);
		kfree(dai);
	}

	clk_put(priv->ssi_clk);
	iounmap(priv->ioaddr);
	kfree(priv);
	return ret;
}
Exemplo n.º 20
0
static int wm8993_i2c_probe(struct i2c_client *i2c,
			    const struct i2c_device_id *id)
{
	struct wm8993_priv *wm8993;
	struct snd_soc_codec *codec;
	unsigned int val;
	int ret;
	int i;

	if (wm8993_codec) {
		dev_err(&i2c->dev, "A WM8993 is already registered\n");
		return -EINVAL;
	}

	wm8993 = kzalloc(sizeof(struct wm8993_priv), GFP_KERNEL);
	if (wm8993 == NULL)
		return -ENOMEM;

	codec = &wm8993->codec;
	if (i2c->dev.platform_data)
		memcpy(&wm8993->pdata, i2c->dev.platform_data,
		       sizeof(wm8993->pdata));

	mutex_init(&codec->mutex);
	INIT_LIST_HEAD(&codec->dapm_widgets);
	INIT_LIST_HEAD(&codec->dapm_paths);

	codec->name = "WM8993";
	codec->volatile_register = wm8993_volatile;
	codec->reg_cache = wm8993->reg_cache;
	codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache);
	codec->bias_level = SND_SOC_BIAS_OFF;
	codec->set_bias_level = wm8993_set_bias_level;
	codec->dai = &wm8993_dai;
	codec->num_dai = 1;
	codec->private_data = wm8993;

	wm8993->hubs_data.hp_startup_mode = 1;
	wm8993->hubs_data.dcs_codes = -2;

	memcpy(wm8993->reg_cache, wm8993_reg_defaults,
	       sizeof(wm8993->reg_cache));

	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
		goto err;
	}

	i2c_set_clientdata(i2c, wm8993);
	codec->control_data = i2c;
	wm8993_codec = codec;

	codec->dev = &i2c->dev;

	for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
		wm8993->supplies[i].supply = wm8993_supply_names[i];

	ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies),
				 wm8993->supplies);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
		goto err;
	}

	ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
				    wm8993->supplies);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
		goto err_get;
	}

	val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
	if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
		dev_err(codec->dev, "Invalid ID register value %x\n", val);
		ret = -EINVAL;
		goto err_enable;
	}

	ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
	if (ret != 0)
		goto err_enable;

	codec->cache_only = 1;

	/* By default we're using the output mixers */
	wm8993->class_w_users = 2;

	/* Latch volume update bits and default ZC on */
	snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
			    WM8993_DAC_VU, WM8993_DAC_VU);
	snd_soc_update_bits(codec, WM8993_RIGHT_ADC_DIGITAL_VOLUME,
			    WM8993_ADC_VU, WM8993_ADC_VU);

	/* Manualy manage the HPOUT sequencing for independent stereo
	 * control. */
	snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
			    WM8993_HPOUT1_AUTO_PU, 0);

	/* Use automatic clock configuration */
	snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);

	wm_hubs_handle_analogue_pdata(codec, wm8993->pdata.lineout1_diff,
				      wm8993->pdata.lineout2_diff,
				      wm8993->pdata.lineout1fb,
				      wm8993->pdata.lineout2fb,
				      wm8993->pdata.jd_scthr,
				      wm8993->pdata.jd_thr,
				      wm8993->pdata.micbias1_lvl,
				      wm8993->pdata.micbias2_lvl);
			     
	ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
	if (ret != 0)
		goto err_enable;

	wm8993_dai.dev = codec->dev;

	ret = snd_soc_register_dai(&wm8993_dai);
	if (ret != 0)
		goto err_bias;

	ret = snd_soc_register_codec(codec);

	return 0;

err_bias:
	wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
err_enable:
	regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
err_get:
	regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
err:
	wm8993_codec = NULL;
	kfree(wm8993);
	return ret;
}
Exemplo n.º 21
0
static int __init sunxi_spdif_dev_probe(struct platform_device *pdev)
{
	int reg_val = 0;
	int ret = 0;
	#ifdef CONFIG_ARCH_SUN9IW1
	if(script_get_item("spdif0", "spdif_voltage", &spdif_voltage) != SCIRPT_ITEM_VALUE_TYPE_STR){
		printk("[aif3_voltage]script_get_item return type err\n");
		return -EFAULT;
	}
	/*spdif:dcdc1*/
	spdif_vol = regulator_get(NULL, spdif_voltage.str);
	if (!spdif_vol) {
		printk("get audio spdif_vol failed\n");
		return -EFAULT;
	}
	//regulator_set_voltage(spdif_vol, 3000000, 3000000);
	regulator_enable(spdif_vol);
	#endif

	sunxi_spdif.regs = ioremap(SUNXI_SPDIFBASE, 0x100);
	if (sunxi_spdif.regs == NULL) {
		return -ENXIO;
	}
	printk("%s, line:%d, dev_name(&pdev->dev):%s\n", __func__, __LINE__, dev_name(&pdev->dev));
	spdif_pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
	if (IS_ERR_OR_NULL(spdif_pinctrl)) {
		dev_warn(&pdev->dev,
			"pins are not configured from the driver\n");
	}

    #ifdef CONFIG_ARCH_SUN8IW6
	spdif_pllx8 = clk_get(NULL, "pll_audiox8");
    if ((!spdif_pllx8)||(IS_ERR(spdif_pllx8))) {
		printk("try to get spdif_pllx8 failed\n");
	}
	if (clk_prepare_enable(spdif_pllx8)) {
		printk("enable spdif_pll2clk failed; \n");
	}
    #else
    #ifdef CONFIG_ARCH_SUN9IW1
	/*spdif pll3clk*/
	spdif_pll3clk = clk_get(NULL, "pll3");
	if ((!spdif_pll3clk)||(IS_ERR(spdif_pll3clk))) {
		printk("try to get spdif_pll3clk failed\n");
	}
	if (clk_prepare_enable(spdif_pll3clk)) {
		printk("enable spdif_pll3clk failed; \n");
	}
    #else
	spdif_pllx8 = clk_get(NULL, "pll2x8");
	if ((!spdif_pllx8)||(IS_ERR(spdif_pllx8))) {
		printk("try to get spdif_pllx8 failed\n");
	}
	if (clk_prepare_enable(spdif_pllx8)) {
		printk("enable spdif_pll2clk failed; \n");
	}
	#endif
	#endif
#ifndef CONFIG_ARCH_SUN9IW1
/********spdif pll2clk can be remove****************/
	/*spdif pll2clk*/
	spdif_pll2clk = clk_get(NULL, "pll2");
	if ((!spdif_pll2clk)||(IS_ERR(spdif_pll2clk))) {
		printk("try to get spdif_pll2clk failed\n");
	}
	if (clk_prepare_enable(spdif_pll2clk)) {
		printk("enable spdif_pll2clk failed; \n");
	}
#endif
	/*spdif module clk*/
	spdif_moduleclk = clk_get(NULL, "spdif");
	if ((!spdif_moduleclk)||(IS_ERR(spdif_moduleclk))) {
		printk("try to get spdif_moduleclk failed\n");
	}
#ifndef CONFIG_ARCH_SUN9IW1
/*******clk_set_parent can be remove*******/
	if (clk_set_parent(spdif_moduleclk, spdif_pll2clk)) {
		printk("try to set parent of spdif_moduleclk to spdif_pll2ck failed! line = %d\n",__LINE__);
	}
	if (clk_set_rate(spdif_moduleclk, 24576000/8)) {
		printk("set spdif_moduleclk clock freq to 24576000 failed! line = %d\n", __LINE__);
	}
#else
	if (clk_set_parent(spdif_moduleclk, spdif_pll3clk)) {
		printk("try to set parent of spdif_moduleclk to spdif_pll2ck failed! line = %d\n",__LINE__);
	}
	if (clk_set_rate(spdif_moduleclk, 24576000)) {
		printk("set spdif_moduleclk clock freq to 24576000 failed! line = %d\n", __LINE__);
	}
#endif
	if (clk_prepare_enable(spdif_moduleclk)) {
		printk("open spdif_moduleclk failed! line = %d\n", __LINE__);
	}
//	if (clk_reset(spdif_moduleclk, AW_CCU_CLK_NRESET)) {
//		printk("try to NRESET spdif module clk failed!\n");
//	}

	/*global enbale*/
	reg_val = readl(sunxi_spdif.regs + SUNXI_SPDIF_CTL);
	reg_val |= SUNXI_SPDIF_CTL_GEN;
	writel(reg_val, sunxi_spdif.regs + SUNXI_SPDIF_CTL);

	ret = snd_soc_register_dai(&pdev->dev, &sunxi_spdif_dai);
	return 0;
}
Exemplo n.º 22
0
static int davinci_i2s_probe(struct platform_device *pdev)
{
	struct snd_platform_data *pdata = pdev->dev.platform_data;
	struct davinci_mcbsp_dev *dev;
	struct resource *mem, *ioarea, *res;
	int ret;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "no mem resource?\n");
		return -ENODEV;
	}

	ioarea = request_mem_region(mem->start, (mem->end - mem->start) + 1,
				    pdev->name);
	if (!ioarea) {
		dev_err(&pdev->dev, "McBSP region already claimed\n");
		return -EBUSY;
	}

	dev = kzalloc(sizeof(struct davinci_mcbsp_dev), GFP_KERNEL);
	if (!dev) {
		ret = -ENOMEM;
		goto err_release_region;
	}
	if (pdata) {
		dev->enable_channel_combine = pdata->enable_channel_combine;
		dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].sram_size =
			pdata->sram_size_playback;
		dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].sram_size =
			pdata->sram_size_capture;
	}
	dev->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(dev->clk)) {
		ret = -ENODEV;
		goto err_free_mem;
	}
	clk_enable(dev->clk);

	dev->base = (void __iomem *)IO_ADDRESS(mem->start);

	dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
	    (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG);

	dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
	    (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG);

	/* first TX, then RX */
	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!res) {
		dev_err(&pdev->dev, "no DMA resource\n");
		ret = -ENXIO;
		goto err_free_mem;
	}
	dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start;

	res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
	if (!res) {
		dev_err(&pdev->dev, "no DMA resource\n");
		ret = -ENXIO;
		goto err_free_mem;
	}
	dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;

	davinci_i2s_dai.private_data = dev;
	davinci_i2s_dai.capture.dma_data = dev->dma_params;
	davinci_i2s_dai.playback.dma_data = dev->dma_params;
	ret = snd_soc_register_dai(&davinci_i2s_dai);
	if (ret != 0)
		goto err_free_mem;

	return 0;

err_free_mem:
	kfree(dev);
err_release_region:
	release_mem_region(mem->start, (mem->end - mem->start) + 1);

	return ret;
}
/* To do: change to register DAIs as batch */
static __devinit int msm_dai_q6_dev_probe(struct platform_device *pdev)
{
	int rc = 0;

	dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));

	switch (pdev->id) {
	case PRIMARY_I2S_RX:
	case SECONDARY_I2S_RX:
		rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_i2s_rx_dai);
		break;
	case PRIMARY_I2S_TX:
		rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_i2s_tx_dai);
		break;
	case PCM_RX:
		rc = snd_soc_register_dai(&pdev->dev,
				&msm_dai_q6_aux_pcm_rx_dai);
		break;
	case PCM_TX:
		rc = snd_soc_register_dai(&pdev->dev,
				&msm_dai_q6_aux_pcm_tx_dai);
		break;
	case MI2S_RX:
		rc = snd_soc_register_dai(&pdev->dev,
					&msm_dai_q6_mi2s_rx_dai);
		break;
	case SLIMBUS_0_RX:
		rc = snd_soc_register_dai(&pdev->dev,
				&msm_dai_q6_slimbus_rx_dai);
		break;
	case SLIMBUS_0_TX:
		rc = snd_soc_register_dai(&pdev->dev,
				&msm_dai_q6_slimbus_tx_dai);
	case INT_BT_SCO_RX:
		rc = snd_soc_register_dai(&pdev->dev,
					&msm_dai_q6_bt_sco_rx_dai);
		break;
	case INT_BT_SCO_TX:
		rc = snd_soc_register_dai(&pdev->dev,
					&msm_dai_q6_bt_sco_tx_dai);
		break;
	case INT_FM_RX:
		rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_fm_rx_dai);
		break;
	case INT_FM_TX:
		rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_fm_tx_dai);
		break;
	case RT_PROXY_DAI_001_RX:
	case RT_PROXY_DAI_002_RX:
		rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_afe_rx_dai);
		break;
	case RT_PROXY_DAI_001_TX:
	case RT_PROXY_DAI_002_TX:
		rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_afe_tx_dai);
		break;
	case VOICE_PLAYBACK_TX:
		rc = snd_soc_register_dai(&pdev->dev,
					&msm_dai_q6_voice_playback_tx_dai);
		break;
	case VOICE_RECORD_RX:
	case VOICE_RECORD_TX:
		rc = snd_soc_register_dai(&pdev->dev,
						&msm_dai_q6_incall_record_dai);
		break;
	default:
		rc = -ENODEV;
		break;
	}
	return rc;
}
Exemplo n.º 24
0
static int __init dit_modinit(void)
{
	return snd_soc_register_dai(&tegra_generic_codec_dai);
}
Exemplo n.º 25
0
/*
 * initialise the AK4642 driver
 * register the mixer and dsp interfaces with the kernel
 */
static int ak4642_init(struct ak4642_priv *ak4642)
{
	struct snd_soc_codec *codec = &ak4642->codec;
	int ret = 0;

	if (ak4642_codec) {
		dev_err(codec->dev, "Another ak4642 is registered\n");
		return -EINVAL;
	}

	mutex_init(&codec->mutex);
	INIT_LIST_HEAD(&codec->dapm_widgets);
	INIT_LIST_HEAD(&codec->dapm_paths);

	codec->private_data	= ak4642;
	codec->name		= "AK4642";
	codec->owner		= THIS_MODULE;
	codec->read		= ak4642_read_reg_cache;
	codec->write		= ak4642_write;
	codec->dai		= &ak4642_dai;
	codec->num_dai		= 1;
	codec->hw_write		= (hw_write_t)i2c_master_send;
	codec->reg_cache_size	= ARRAY_SIZE(ak4642_reg);
	codec->reg_cache	= kmemdup(ak4642_reg,
					  sizeof(ak4642_reg), GFP_KERNEL);

	if (!codec->reg_cache)
		return -ENOMEM;

	ak4642_dai.dev = codec->dev;
	ak4642_codec = codec;

	ret = snd_soc_register_codec(codec);
	if (ret) {
		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
		goto reg_cache_err;
	}

	ret = snd_soc_register_dai(&ak4642_dai);
	if (ret) {
		dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
		snd_soc_unregister_codec(codec);
		goto reg_cache_err;
	}

	/*
	 * clock setting
	 *
	 * Audio I/F Format: MSB justified (ADC & DAC)
	 * BICK frequency at Master Mode: 64fs
	 * Input Master Clock Select at PLL Mode: 11.2896MHz
	 * MCKO: Enable
	 * Sampling Frequency: 44.1kHz
	 *
	 * This operation came from example code of
	 * "ASAHI KASEI AK4642" (japanese) manual p89.
	 *
	 * please fix-me
	 */
	ak4642_write(codec, 0x01, 0x08);
	ak4642_write(codec, 0x04, 0x4a);
	ak4642_write(codec, 0x05, 0x27);
	ak4642_write(codec, 0x00, 0x40);
	ak4642_write(codec, 0x01, 0x0b);

	return ret;

reg_cache_err:
	kfree(codec->reg_cache);
	codec->reg_cache = NULL;

	return ret;
}
Exemplo n.º 26
0
static int __init wm8728_modinit(void)
{
	return snd_soc_register_dai(&wm8728_dai);
}
Exemplo n.º 27
0
static int __init s3c_i2s_init(void)
{
	return snd_soc_register_dai(&s3c_i2s_dai);
}
Exemplo n.º 28
0
static int wm8961_register(struct wm8961_priv *wm8961)
{
	struct snd_soc_codec *codec = &wm8961->codec;
	int ret;
	u16 reg;

	if (wm8961_codec) {
		dev_err(codec->dev, "Another WM8961 is registered\n");
		ret = -EINVAL;
		goto err;
	}

	mutex_init(&codec->mutex);
	INIT_LIST_HEAD(&codec->dapm_widgets);
	INIT_LIST_HEAD(&codec->dapm_paths);

	snd_soc_codec_set_drvdata(codec, wm8961);
	codec->name = "WM8961";
	codec->owner = THIS_MODULE;
	codec->dai = &wm8961_dai;
	codec->num_dai = 1;
	codec->reg_cache_size = ARRAY_SIZE(wm8961->reg_cache);
	codec->reg_cache = &wm8961->reg_cache;
	codec->bias_level = SND_SOC_BIAS_OFF;
	codec->set_bias_level = wm8961_set_bias_level;
	codec->volatile_register = wm8961_volatile_register;

	memcpy(codec->reg_cache, wm8961_reg_defaults,
	       sizeof(wm8961_reg_defaults));

	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
		goto err;
	}

	reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET);
	if (reg != 0x1801) {
		dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg);
		ret = -EINVAL;
		goto err;
	}

	/* This isn't volatile - readback doesn't correspond to write */
	reg = codec->hw_read(codec, WM8961_RIGHT_INPUT_VOLUME);
	dev_info(codec->dev, "WM8961 family %d revision %c\n",
		 (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
		 ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
		 + 'A');

	ret = wm8961_reset(codec);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to issue reset\n");
		return ret;
	}

	/* Enable class W */
	reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B);
	reg |= WM8961_CP_DYN_PWR_MASK;
	snd_soc_write(codec, WM8961_CHARGE_PUMP_B, reg);

	/* Latch volume update bits (right channel only, we always
	 * write both out) and default ZC on. */
	reg = snd_soc_read(codec, WM8961_ROUT1_VOLUME);
	snd_soc_write(codec, WM8961_ROUT1_VOLUME,
		     reg | WM8961_LO1ZC | WM8961_OUT1VU);
	snd_soc_write(codec, WM8961_LOUT1_VOLUME, reg | WM8961_LO1ZC);
	reg = snd_soc_read(codec, WM8961_ROUT2_VOLUME);
	snd_soc_write(codec, WM8961_ROUT2_VOLUME,
		     reg | WM8961_SPKRZC | WM8961_SPKVU);
	snd_soc_write(codec, WM8961_LOUT2_VOLUME, reg | WM8961_SPKLZC);

	reg = snd_soc_read(codec, WM8961_RIGHT_ADC_VOLUME);
	snd_soc_write(codec, WM8961_RIGHT_ADC_VOLUME, reg | WM8961_ADCVU);
	reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME);
	snd_soc_write(codec, WM8961_RIGHT_INPUT_VOLUME, reg | WM8961_IPVU);

	/* Use soft mute by default */
	reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_2);
	reg |= WM8961_DACSMM;
	snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);

	/* Use automatic clocking mode by default; for now this is all
	 * we support.
	 */
	reg = snd_soc_read(codec, WM8961_CLOCKING_3);
	reg &= ~WM8961_MANUAL_MODE;
	snd_soc_write(codec, WM8961_CLOCKING_3, reg);

	wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

	wm8961_dai.dev = codec->dev;

	wm8961_codec = codec;

	ret = snd_soc_register_codec(codec);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
		return ret;
	}

	ret = snd_soc_register_dai(&wm8961_dai);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
		snd_soc_unregister_codec(codec);
		return ret;
	}

	return 0;

err:
	kfree(wm8961);
	return ret;
}
Exemplo n.º 29
0
static int __init ad73311_init(void)
{
    return snd_soc_register_dai(&ad73311_dai);
}
Exemplo n.º 30
0
static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
{
	struct tegra_i2s * i2s;
	struct resource *mem, *memregion, *dmareq;
	u32 of_dma[2];
	u32 dma_ch;
	int ret;

	i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra_i2s), GFP_KERNEL);
	if (!i2s) {
		dev_err(&pdev->dev, "Can't allocate tegra_i2s\n");
		ret = -ENOMEM;
		goto err;
	}
	dev_set_drvdata(&pdev->dev, i2s);

	i2s->dai = tegra_i2s_dai_template;
	i2s->dai.name = dev_name(&pdev->dev);

	i2s->clk_i2s = clk_get(&pdev->dev, NULL);
	if (IS_ERR(i2s->clk_i2s)) {
		dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
		ret = PTR_ERR(i2s->clk_i2s);
		goto err;
	}

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "No memory resource\n");
		ret = -ENODEV;
		goto err_clk_put;
	}

	dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!dmareq) {
		if (of_property_read_u32_array(pdev->dev.of_node,
					"nvidia,dma-request-selector",
					of_dma, 2) < 0) {
			dev_err(&pdev->dev, "No DMA resource\n");
			ret = -ENODEV;
			goto err_clk_put;
		}
		dma_ch = of_dma[1];
	} else {
		dma_ch = dmareq->start;
	}

	memregion = devm_request_mem_region(&pdev->dev, mem->start,
					    resource_size(mem), DRV_NAME);
	if (!memregion) {
		dev_err(&pdev->dev, "Memory region already claimed\n");
		ret = -EBUSY;
		goto err_clk_put;
	}

	i2s->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
	if (!i2s->regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto err_clk_put;
	}

	i2s->capture_dma_data.addr = mem->start + TEGRA_I2S_FIFO2;
	i2s->capture_dma_data.wrap = 4;
	i2s->capture_dma_data.width = 32;
	i2s->capture_dma_data.req_sel = dma_ch;

	i2s->playback_dma_data.addr = mem->start + TEGRA_I2S_FIFO1;
	i2s->playback_dma_data.wrap = 4;
	i2s->playback_dma_data.width = 32;
	i2s->playback_dma_data.req_sel = dma_ch;

	i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED;

	ret = snd_soc_register_dai(&pdev->dev, &i2s->dai);
	if (ret) {
		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
		ret = -ENOMEM;
		goto err_clk_put;
	}

	tegra_i2s_debug_add(i2s);

	return 0;

err_clk_put:
	clk_put(i2s->clk_i2s);
err:
	return ret;
}