예제 #1
0
static int stm32_lptimer_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct stm32_lptimer *ddata;
	struct resource *res;
	void __iomem *mmio;
	int ret;

	ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
	if (!ddata)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	mmio = devm_ioremap_resource(dev, res);
	if (IS_ERR(mmio))
		return PTR_ERR(mmio);

	ddata->regmap = devm_regmap_init_mmio_clk(dev, "mux", mmio,
						  &stm32_lptimer_regmap_cfg);
	if (IS_ERR(ddata->regmap))
		return PTR_ERR(ddata->regmap);

	ddata->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(ddata->clk))
		return PTR_ERR(ddata->clk);

	ret = stm32_lptimer_detect_encoder(ddata);
	if (ret)
		return ret;

	platform_set_drvdata(pdev, ddata);

	return devm_of_platform_populate(&pdev->dev);
}
예제 #2
0
static int fsl_sai_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct fsl_sai *sai;
	struct resource *res;
	void __iomem *base;
	int ret;

	sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
	if (!sai)
		return -ENOMEM;

	sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs");
	if (sai->big_endian_regs)
		fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG;

	sai->big_endian_data = of_property_read_bool(np, "big-endian-data");

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
			"sai", base, &fsl_sai_regmap_config);
	if (IS_ERR(sai->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		return PTR_ERR(sai->regmap);
	}

	sai->dma_params_rx.addr = res->start + FSL_SAI_RDR;
	sai->dma_params_tx.addr = res->start + FSL_SAI_TDR;
	sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
	sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;

	platform_set_drvdata(pdev, sai);

	ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
			&fsl_sai_dai, 1);
	if (ret)
		return ret;

	return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
			SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
}
예제 #3
0
파일: stm32_i2s.c 프로젝트: lfd/PreemptRT
static int stm32_i2s_probe(struct platform_device *pdev)
{
	struct stm32_i2s_data *i2s;
	int ret;

	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
	if (!i2s)
		return -ENOMEM;

	ret = stm32_i2s_parse_dt(pdev, i2s);
	if (ret)
		return ret;

	i2s->pdev = pdev;
	i2s->ms_flg = I2S_MS_NOT_SET;
	spin_lock_init(&i2s->lock_fd);
	spin_lock_init(&i2s->irq_lock);
	platform_set_drvdata(pdev, i2s);

	ret = stm32_i2s_dais_init(pdev, i2s);
	if (ret)
		return ret;

	i2s->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "pclk",
						i2s->base, i2s->regmap_conf);
	if (IS_ERR(i2s->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		return PTR_ERR(i2s->regmap);
	}

	ret = devm_snd_soc_register_component(&pdev->dev, &stm32_i2s_component,
					      i2s->dai_drv, 1);
	if (ret)
		return ret;

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
					      &stm32_i2s_pcm_config, 0);
	if (ret)
		return ret;

	/* Set SPI/I2S in i2s mode */
	return regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG,
				  I2S_CGFR_I2SMOD, I2S_CGFR_I2SMOD);
}
예제 #4
0
static int hi6421_pmic_probe(struct platform_device *pdev)
{
	struct hi6421_pmic *pmic;
	struct resource *res;
	void __iomem *base;
	int ret;

	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
	if (!pmic)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	pmic->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base,
						 &hi6421_regmap_config);
	if (IS_ERR(pmic->regmap)) {
		dev_err(&pdev->dev,
			"regmap init failed: %ld\n", PTR_ERR(pmic->regmap));
		return PTR_ERR(pmic->regmap);
	}

	/* set over-current protection debounce 8ms */
	regmap_update_bits(pmic->regmap, HI6421_OCP_DEB_CTRL_REG,
				(HI6421_OCP_DEB_SEL_MASK
				 | HI6421_OCP_EN_DEBOUNCE_MASK
				 | HI6421_OCP_AUTO_STOP_MASK),
				(HI6421_OCP_DEB_SEL_8MS
				 | HI6421_OCP_EN_DEBOUNCE_ENABLE));

	platform_set_drvdata(pdev, pmic);

	ret = devm_mfd_add_devices(&pdev->dev, 0, hi6421_devs,
				   ARRAY_SIZE(hi6421_devs), NULL, 0, NULL);
	if (ret) {
		dev_err(&pdev->dev, "add mfd devices failed: %d\n", ret);
		return ret;
	}

	return 0;
}
예제 #5
0
static int fsl_esai_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct fsl_esai *esai_priv;
	struct resource *res;
	const uint32_t *iprop;
	void __iomem *regs;
	int irq, ret;

	esai_priv = devm_kzalloc(&pdev->dev, sizeof(*esai_priv), GFP_KERNEL);
	if (!esai_priv)
		return -ENOMEM;

	esai_priv->pdev = pdev;
	strcpy(esai_priv->name, np->name);

	/* Get the addresses and IRQ */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(regs))
		return PTR_ERR(regs);

	esai_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
			"core", regs, &fsl_esai_regmap_config);
	if (IS_ERR(esai_priv->regmap)) {
		dev_err(&pdev->dev, "failed to init regmap: %ld\n",
				PTR_ERR(esai_priv->regmap));
		return PTR_ERR(esai_priv->regmap);
	}

	esai_priv->coreclk = devm_clk_get(&pdev->dev, "core");
	if (IS_ERR(esai_priv->coreclk)) {
		dev_err(&pdev->dev, "failed to get core clock: %ld\n",
				PTR_ERR(esai_priv->coreclk));
		return PTR_ERR(esai_priv->coreclk);
	}

	esai_priv->extalclk = devm_clk_get(&pdev->dev, "extal");
	if (IS_ERR(esai_priv->extalclk))
		dev_warn(&pdev->dev, "failed to get extal clock: %ld\n",
				PTR_ERR(esai_priv->extalclk));

	esai_priv->fsysclk = devm_clk_get(&pdev->dev, "fsys");
	if (IS_ERR(esai_priv->fsysclk))
		dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n",
				PTR_ERR(esai_priv->fsysclk));

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
		return irq;
	}

	ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0,
			       esai_priv->name, esai_priv);
	if (ret) {
		dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
		return ret;
	}

	/* Set a default slot size */
	esai_priv->slot_width = 32;

	/* Set a default master/slave state */
	esai_priv->slave_mode = true;

	/* Determine the FIFO depth */
	iprop = of_get_property(np, "fsl,fifo-depth", NULL);
	if (iprop)
		esai_priv->fifo_depth = be32_to_cpup(iprop);
	else
		esai_priv->fifo_depth = 64;

	esai_priv->dma_params_tx.maxburst = 16;
	esai_priv->dma_params_rx.maxburst = 16;
	esai_priv->dma_params_tx.addr = res->start + REG_ESAI_ETDR;
	esai_priv->dma_params_rx.addr = res->start + REG_ESAI_ERDR;

	esai_priv->synchronous =
		of_property_read_bool(np, "fsl,esai-synchronous");

	/* Implement full symmetry for synchronous mode */
	if (esai_priv->synchronous) {
		fsl_esai_dai.symmetric_rates = 1;
		fsl_esai_dai.symmetric_channels = 1;
		fsl_esai_dai.symmetric_samplebits = 1;
	}

	dev_set_drvdata(&pdev->dev, esai_priv);

	/* Reset ESAI unit */
	ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ERST);
	if (ret) {
		dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret);
		return ret;
	}

	/*
	 * We need to enable ESAI so as to access some of its registers.
	 * Otherwise, we would fail to dump regmap from user space.
	 */
	ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ESAIEN);
	if (ret) {
		dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret);
		return ret;
	}

	ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component,
					      &fsl_esai_dai, 1);
	if (ret) {
		dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
		return ret;
	}

	ret = imx_pcm_dma_init(pdev);
	if (ret)
		dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);

	return ret;
}
예제 #6
0
static int dspi_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct spi_master *master;
	struct fsl_dspi *dspi;
	struct resource *res;
	void __iomem *base;
	int ret = 0, cs_num, bus_num;

	master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_dspi));
	if (!master)
		return -ENOMEM;

	dspi = spi_master_get_devdata(master);
	dspi->pdev = pdev;
	dspi->bitbang.master = master;
	dspi->bitbang.chipselect = dspi_chipselect;
	dspi->bitbang.setup_transfer = dspi_setup_transfer;
	dspi->bitbang.txrx_bufs = dspi_txrx_transfer;
	dspi->bitbang.master->setup = dspi_setup;
	dspi->bitbang.master->dev.of_node = pdev->dev.of_node;

	master->mode_bits = SPI_CPOL | SPI_CPHA;
	master->bits_per_word_mask = SPI_BPW_MASK(4) | SPI_BPW_MASK(8) |
					SPI_BPW_MASK(16);

	ret = of_property_read_u32(np, "spi-num-chipselects", &cs_num);
	if (ret < 0) {
		dev_err(&pdev->dev, "can't get spi-num-chipselects\n");
		goto out_master_put;
	}
	master->num_chipselect = cs_num;

	ret = of_property_read_u32(np, "bus-num", &bus_num);
	if (ret < 0) {
		dev_err(&pdev->dev, "can't get bus-num\n");
		goto out_master_put;
	}
	master->bus_num = bus_num;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base)) {
		ret = PTR_ERR(base);
		goto out_master_put;
	}

	dspi_regmap_config.lock_arg = dspi;
	dspi_regmap_config.val_format_endian =
		of_property_read_bool(np, "big-endian")
			? REGMAP_ENDIAN_BIG : REGMAP_ENDIAN_DEFAULT;
	dspi->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dspi", base,
						&dspi_regmap_config);
	if (IS_ERR(dspi->regmap)) {
		dev_err(&pdev->dev, "failed to init regmap: %ld\n",
				PTR_ERR(dspi->regmap));
		return PTR_ERR(dspi->regmap);
	}

	dspi->irq = platform_get_irq(pdev, 0);
	if (dspi->irq < 0) {
		dev_err(&pdev->dev, "can't get platform irq\n");
		ret = dspi->irq;
		goto out_master_put;
	}

	ret = devm_request_irq(&pdev->dev, dspi->irq, dspi_interrupt, 0,
			pdev->name, dspi);
	if (ret < 0) {
		dev_err(&pdev->dev, "Unable to attach DSPI interrupt\n");
		goto out_master_put;
	}

	dspi->clk = devm_clk_get(&pdev->dev, "dspi");
	if (IS_ERR(dspi->clk)) {
		ret = PTR_ERR(dspi->clk);
		dev_err(&pdev->dev, "unable to get clock\n");
		goto out_master_put;
	}
	clk_prepare_enable(dspi->clk);

	init_waitqueue_head(&dspi->waitq);
	platform_set_drvdata(pdev, master);

	ret = spi_bitbang_start(&dspi->bitbang);
	if (ret != 0) {
		dev_err(&pdev->dev, "Problem registering DSPI master\n");
		goto out_clk_put;
	}

	pr_info(KERN_INFO "Freescale DSPI master initialized\n");
	return ret;

out_clk_put:
	clk_disable_unprepare(dspi->clk);
out_master_put:
	spi_master_put(master);

	return ret;
}
예제 #7
0
파일: stm32_spdifrx.c 프로젝트: mdamt/linux
static int stm32_spdifrx_probe(struct platform_device *pdev)
{
	struct stm32_spdifrx_data *spdifrx;
	struct reset_control *rst;
	const struct snd_dmaengine_pcm_config *pcm_config = NULL;
	int ret;

	spdifrx = devm_kzalloc(&pdev->dev, sizeof(*spdifrx), GFP_KERNEL);
	if (!spdifrx)
		return -ENOMEM;

	spdifrx->pdev = pdev;
	init_completion(&spdifrx->cs_completion);
	spin_lock_init(&spdifrx->lock);

	platform_set_drvdata(pdev, spdifrx);

	ret = stm_spdifrx_parse_of(pdev, spdifrx);
	if (ret)
		return ret;

	spdifrx->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "kclk",
						    spdifrx->base,
						    spdifrx->regmap_conf);
	if (IS_ERR(spdifrx->regmap)) {
		dev_err(&pdev->dev, "Regmap init failed\n");
		return PTR_ERR(spdifrx->regmap);
	}

	ret = devm_request_irq(&pdev->dev, spdifrx->irq, stm32_spdifrx_isr, 0,
			       dev_name(&pdev->dev), spdifrx);
	if (ret) {
		dev_err(&pdev->dev, "IRQ request returned %d\n", ret);
		return ret;
	}

	rst = devm_reset_control_get(&pdev->dev, NULL);
	if (!IS_ERR(rst)) {
		reset_control_assert(rst);
		udelay(2);
		reset_control_deassert(rst);
	}

	ret = devm_snd_soc_register_component(&pdev->dev,
					      &stm32_spdifrx_component,
					      stm32_spdifrx_dai,
					      ARRAY_SIZE(stm32_spdifrx_dai));
	if (ret)
		return ret;

	ret = stm32_spdifrx_dma_ctrl_register(&pdev->dev, spdifrx);
	if (ret)
		goto error;

	pcm_config = &stm32_spdifrx_pcm_config;
	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0);
	if (ret) {
		dev_err(&pdev->dev, "PCM DMA register returned %d\n", ret);
		goto error;
	}

	return 0;

error:
	if (spdifrx->ctrl_chan)
		dma_release_channel(spdifrx->ctrl_chan);
	if (spdifrx->dmab)
		snd_dma_free_pages(spdifrx->dmab);

	return ret;
}
예제 #8
0
static int mxc_asrc_probe(struct platform_device *pdev)
{
	const struct of_device_id *of_id = of_match_device(fsl_asrc_ids, &pdev->dev);
	struct device_node *np = pdev->dev.of_node;
	enum mxc_asrc_type devtype;
	struct resource *res;
	void __iomem *regs;
	int ret;

	/* Check if the device is existed */
	if (!np)
		return -ENODEV;

	asrc = devm_kzalloc(&pdev->dev, sizeof(struct asrc_data), GFP_KERNEL);
	if (!asrc)
		return -ENOMEM;

	if (of_id) {
		const struct platform_device_id *id_entry = of_id->data;
		devtype = id_entry->driver_data;
	} else {
		devtype = pdev->id_entry->driver_data;
	}

	asrc->dev = &pdev->dev;
	asrc->dev->coherent_dma_mask = DMA_BIT_MASK(32);

	asrc->asrc_pair[ASRC_PAIR_A].chn_max = 2;
	asrc->asrc_pair[ASRC_PAIR_B].chn_max = 6;
	asrc->asrc_pair[ASRC_PAIR_C].chn_max = 2;
	asrc->asrc_pair[ASRC_PAIR_A].overload_error = 0;
	asrc->asrc_pair[ASRC_PAIR_B].overload_error = 0;
	asrc->asrc_pair[ASRC_PAIR_C].overload_error = 0;

	/* Map the address */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (IS_ERR(res)) {
		dev_err(&pdev->dev, "could not determine device resources\n");
		return PTR_ERR(res);
	}

	regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(regs)) {
		dev_err(&pdev->dev, "could not map device resources\n");
		return PTR_ERR(regs);
	}
	asrc->paddr = res->start;

	/* Register regmap and let it prepare core clock */
	asrc->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
			"core", regs, &asrc_regmap_config);
	if (IS_ERR(asrc->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		return PTR_ERR(asrc->regmap);
	}

	asrc->irq = platform_get_irq(pdev, 0);
	if (asrc->irq == NO_IRQ) {
		dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
		return asrc->irq;
	}

	ret = devm_request_irq(&pdev->dev, asrc->irq, asrc_isr, 0, np->name, NULL);
	if (ret) {
		dev_err(&pdev->dev, "could not claim irq %u: %d\n", asrc->irq, ret);
		return ret;
	}

	asrc->asrc_clk = devm_clk_get(&pdev->dev, "core");
	if (IS_ERR(asrc->asrc_clk)) {
		dev_err(&pdev->dev, "failed to get core clock\n");
		return PTR_ERR(asrc->asrc_clk);
	}

	asrc->dma_clk = devm_clk_get(&pdev->dev, "dma");
	if (IS_ERR(asrc->dma_clk)) {
		dev_err(&pdev->dev, "failed to get dma script clock\n");
		return PTR_ERR(asrc->dma_clk);
	}

	switch (devtype) {
	case IMX35_ASRC:
		asrc->channel_bits = 3;
		input_clk_map = input_clk_map_v1;
		output_clk_map = output_clk_map_v1;
		break;
	case IMX53_ASRC:
		asrc->channel_bits = 4;
		input_clk_map = input_clk_map_v2;
		output_clk_map = output_clk_map_v2;
		break;
	default:
		dev_err(&pdev->dev, "unsupported device type\n");
		return -EINVAL;
	}

	ret = misc_register(&asrc_miscdev);
	if (ret) {
		dev_err(&pdev->dev, "failed to register char device %d\n", ret);
		return ret;
	}

	asrc_proc_create();

	ret = mxc_init_asrc();
	if (ret) {
		dev_err(&pdev->dev, "failed to init asrc %d\n", ret);
		goto err_misc;
	}

	dev_info(&pdev->dev, "mxc_asrc registered\n");

	return ret;

err_misc:
	misc_deregister(&asrc_miscdev);

	return ret;
}
예제 #9
0
static int fsl_asrc_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct fsl_asrc *asrc_priv;
	struct resource *res;
	void __iomem *regs;
	int irq, ret, i;
	char tmp[16];

	asrc_priv = devm_kzalloc(&pdev->dev, sizeof(*asrc_priv), GFP_KERNEL);
	if (!asrc_priv)
		return -ENOMEM;

	asrc_priv->pdev = pdev;
	strncpy(asrc_priv->name, np->name, sizeof(asrc_priv->name) - 1);

	/* Get the addresses and IRQ */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(regs))
		return PTR_ERR(regs);

	asrc_priv->paddr = res->start;

	asrc_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "mem", regs,
						      &fsl_asrc_regmap_config);
	if (IS_ERR(asrc_priv->regmap)) {
		dev_err(&pdev->dev, "failed to init regmap\n");
		return PTR_ERR(asrc_priv->regmap);
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
		return irq;
	}

	ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0,
			       asrc_priv->name, asrc_priv);
	if (ret) {
		dev_err(&pdev->dev, "failed to claim irq %u: %d\n", irq, ret);
		return ret;
	}

	asrc_priv->mem_clk = devm_clk_get(&pdev->dev, "mem");
	if (IS_ERR(asrc_priv->mem_clk)) {
		dev_err(&pdev->dev, "failed to get mem clock\n");
		return PTR_ERR(asrc_priv->mem_clk);
	}

	asrc_priv->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
	if (IS_ERR(asrc_priv->ipg_clk)) {
		dev_err(&pdev->dev, "failed to get ipg clock\n");
		return PTR_ERR(asrc_priv->ipg_clk);
	}

	for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
		sprintf(tmp, "asrck_%x", i);
		asrc_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp);
		if (IS_ERR(asrc_priv->asrck_clk[i])) {
			dev_err(&pdev->dev, "failed to get %s clock\n", tmp);
			return PTR_ERR(asrc_priv->asrck_clk[i]);
		}
	}

	if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx35-asrc")) {
		asrc_priv->channel_bits = 3;
		clk_map[IN] = input_clk_map_imx35;
		clk_map[OUT] = output_clk_map_imx35;
	} else {
		asrc_priv->channel_bits = 4;
		clk_map[IN] = input_clk_map_imx53;
		clk_map[OUT] = output_clk_map_imx53;
	}

	ret = fsl_asrc_init(asrc_priv);
	if (ret) {
		dev_err(&pdev->dev, "failed to init asrc %d\n", ret);
		return -EINVAL;
	}

	asrc_priv->channel_avail = 10;

	ret = of_property_read_u32(np, "fsl,asrc-rate",
				   &asrc_priv->asrc_rate);
	if (ret) {
		dev_err(&pdev->dev, "failed to get output rate\n");
		return -EINVAL;
	}

	ret = of_property_read_u32(np, "fsl,asrc-width",
				   &asrc_priv->asrc_width);
	if (ret) {
		dev_err(&pdev->dev, "failed to get output width\n");
		return -EINVAL;
	}

	if (asrc_priv->asrc_width != 16 && asrc_priv->asrc_width != 24) {
		dev_warn(&pdev->dev, "unsupported width, switching to 24bit\n");
		asrc_priv->asrc_width = 24;
	}

	platform_set_drvdata(pdev, asrc_priv);
	pm_runtime_enable(&pdev->dev);
	spin_lock_init(&asrc_priv->lock);

	ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component,
					      &fsl_asrc_dai, 1);
	if (ret) {
		dev_err(&pdev->dev, "failed to register ASoC DAI\n");
		return ret;
	}

	ret = devm_snd_soc_register_platform(&pdev->dev, &fsl_asrc_platform);
	if (ret) {
		dev_err(&pdev->dev, "failed to register ASoC platform\n");
		return ret;
	}

	dev_info(&pdev->dev, "driver registered\n");

	return 0;
}
예제 #10
0
static int hi655x_pmic_probe(struct platform_device *pdev)
{
	int ret;
	struct hi655x_pmic *pmic;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	void __iomem *base;

	pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
	if (!pmic)
		return -ENOMEM;
	pmic->dev = dev;

	pmic->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(dev, pmic->res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	pmic->regmap = devm_regmap_init_mmio_clk(dev, NULL, base,
						 &hi655x_regmap_config);

	regmap_read(pmic->regmap, HI655X_BUS_ADDR(HI655X_VER_REG), &pmic->ver);
	if ((pmic->ver < PMU_VER_START) || (pmic->ver > PMU_VER_END)) {
		dev_warn(dev, "PMU version %d unsupported\n", pmic->ver);
		return -EINVAL;
	}

	hi655x_local_irq_clear(pmic->regmap);

	pmic->gpio = of_get_named_gpio(np, "pmic-gpios", 0);
	if (!gpio_is_valid(pmic->gpio)) {
		dev_err(dev, "Failed to get the pmic-gpios\n");
		return -ENODEV;
	}

	ret = devm_gpio_request_one(dev, pmic->gpio, GPIOF_IN,
				    "hi655x_pmic_irq");
	if (ret < 0) {
		dev_err(dev, "Failed to request gpio %d  ret = %d\n",
			pmic->gpio, ret);
		return ret;
	}

	ret = regmap_add_irq_chip(pmic->regmap, gpio_to_irq(pmic->gpio),
				  IRQF_TRIGGER_LOW | IRQF_NO_SUSPEND, 0,
				  &hi655x_irq_chip, &pmic->irq_data);
	if (ret) {
		dev_err(dev, "Failed to obtain 'hi655x_pmic_irq' %d\n", ret);
		return ret;
	}

	platform_set_drvdata(pdev, pmic);

	ret = mfd_add_devices(dev, PLATFORM_DEVID_AUTO, hi655x_pmic_devs,
			      ARRAY_SIZE(hi655x_pmic_devs), NULL, 0,
			      regmap_irq_get_domain(pmic->irq_data));
	if (ret) {
		dev_err(dev, "Failed to register device %d\n", ret);
		regmap_del_irq_chip(gpio_to_irq(pmic->gpio), pmic->irq_data);
		return ret;
	}

	return 0;
}