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; }
static int __init bfin_ac97_init(void) { return snd_soc_register_dai(&bfin_ac97_dai); }
static __devinit int asoc_mcbsp_probe(struct platform_device *pdev) { return snd_soc_register_dai(&pdev->dev, &omap_mcbsp_dai); }
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; }
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; }
/** * 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; }
static int __init ak4535_modinit(void) { return snd_soc_register_dai(&ak4535_dai); }
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; }
static __devinit int asoc_pcm_cpu_probe(struct platform_device *pdev) { return snd_soc_register_dai(&pdev->dev, msm_pcm_cpu_dais); }
static int __init mxs_spdif_dai_init(void) { return snd_soc_register_dai(&mxs_spdif_dai); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
static int __init dit_modinit(void) { return snd_soc_register_dai(&tegra_generic_codec_dai); }
/* * 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; }
static int __init wm8728_modinit(void) { return snd_soc_register_dai(&wm8728_dai); }
static int __init s3c_i2s_init(void) { return snd_soc_register_dai(&s3c_i2s_dai); }
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; }
static int __init ad73311_init(void) { return snd_soc_register_dai(&ad73311_dai); }
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; }