Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e3b8c34 authored by Hebbar, Gururaja's avatar Hebbar, Gururaja Committed by Mark Brown
Browse files

ASoC: Davinci: McASP: add device tree support for McASP



Add device tree probe for McASP driver.

Note:
DMA parameters are not populated from DT and will be done later.

Signed-off-by: default avatarHebbar, Gururaja <gururaja.hebbar@ti.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 896f66b7
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
Texas Instruments McASP controller

Required properties:
- compatible :
	"ti,dm646x-mcasp-audio"	: for DM646x platforms
	"ti,da830-mcasp-audio"	: for both DA830 & DA850 platforms

- reg : Should contain McASP registers offset and length
- interrupts : Interrupt number for McASP
- op-mode : I2S/DIT ops mode.
- tdm-slots : Slots for TDM operation.
- num-serializer : Serializers used by McASP.
- serial-dir : A list of serializer pin mode. The list number should be equal
		to "num-serializer" parameter. Each entry is a number indication
		serializer pin direction. (0 - INACTIVE, 1 - TX, 2 - RX)


Optional properties:

- ti,hwmods : Must be "mcasp<n>", n is controller instance starting 0
- tx-num-evt : FIFO levels.
- rx-num-evt : FIFO levels.
- sram-size-playback : size of sram to be allocated during playback
- sram-size-capture  : size of sram to be allocated during capture

Example:

mcasp0: mcasp0@1d00000 {
	compatible = "ti,da830-mcasp-audio";
	#address-cells = <1>;
	#size-cells = <0>;
	reg = <0x100000 0x3000>;
	interrupts = <82 83>;
	op-mode = <0>;		/* MCASP_IIS_MODE */
	tdm-slots = <2>;
	num-serializer = <16>;
	serial-dir = <
			0 0 0 0	/* 0: INACTIVE, 1: TX, 2: RX */
			0 0 0 0
			0 0 0 1
			2 0 0 0 >;
	tx-num-evt = <1>;
	rx-num-evt = <1>;
};
+123 −1
Original line number Diff line number Diff line
@@ -22,6 +22,9 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/of_device.h>

#include <sound/core.h>
#include <sound/pcm.h>
@@ -856,6 +859,114 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {

};

static const struct of_device_id mcasp_dt_ids[] = {
	{
		.compatible = "ti,dm646x-mcasp-audio",
		.data = (void *)MCASP_VERSION_1,
	},
	{
		.compatible = "ti,da830-mcasp-audio",
		.data = (void *)MCASP_VERSION_2,
	},
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mcasp_dt_ids);

static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
						struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct snd_platform_data *pdata = NULL;
	const struct of_device_id *match =
			of_match_device(of_match_ptr(mcasp_dt_ids), &pdev->dev);

	const u32 *of_serial_dir32;
	u8 *of_serial_dir;
	u32 val;
	int i, ret = 0;

	if (pdev->dev.platform_data) {
		pdata = pdev->dev.platform_data;
		return pdata;
	} else if (match) {
		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
		if (!pdata) {
			ret = -ENOMEM;
			goto nodata;
		}
	} else {
		/* control shouldn't reach here. something is wrong */
		ret = -EINVAL;
		goto nodata;
	}

	if (match->data)
		pdata->version = (u8)((int)match->data);

	ret = of_property_read_u32(np, "op-mode", &val);
	if (ret >= 0)
		pdata->op_mode = val;

	ret = of_property_read_u32(np, "tdm-slots", &val);
	if (ret >= 0)
		pdata->tdm_slots = val;

	ret = of_property_read_u32(np, "num-serializer", &val);
	if (ret >= 0)
		pdata->num_serializer = val;

	of_serial_dir32 = of_get_property(np, "serial-dir", &val);
	val /= sizeof(u32);
	if (val != pdata->num_serializer) {
		dev_err(&pdev->dev,
				"num-serializer(%d) != serial-dir size(%d)\n",
				pdata->num_serializer, val);
		ret = -EINVAL;
		goto nodata;
	}

	if (of_serial_dir32) {
		of_serial_dir = devm_kzalloc(&pdev->dev,
						(sizeof(*of_serial_dir) * val),
						GFP_KERNEL);
		if (!of_serial_dir) {
			ret = -ENOMEM;
			goto nodata;
		}

		for (i = 0; i < pdata->num_serializer; i++)
			of_serial_dir[i] = be32_to_cpup(&of_serial_dir32[i]);

		pdata->serial_dir = of_serial_dir;
	}

	ret = of_property_read_u32(np, "tx-num-evt", &val);
	if (ret >= 0)
		pdata->txnumevt = val;

	ret = of_property_read_u32(np, "rx-num-evt", &val);
	if (ret >= 0)
		pdata->rxnumevt = val;

	ret = of_property_read_u32(np, "sram-size-playback", &val);
	if (ret >= 0)
		pdata->sram_size_playback = val;

	ret = of_property_read_u32(np, "sram-size-capture", &val);
	if (ret >= 0)
		pdata->sram_size_capture = val;

	return  pdata;

nodata:
	if (ret < 0) {
		dev_err(&pdev->dev, "Error populating platform data, err %d\n",
			ret);
		pdata = NULL;
	}
	return  pdata;
}

static int davinci_mcasp_probe(struct platform_device *pdev)
{
	struct davinci_pcm_dma_params *dma_data;
@@ -864,11 +975,22 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
	struct davinci_audio_dev *dev;
	int ret;

	if (!pdev->dev.platform_data && !pdev->dev.of_node) {
		dev_err(&pdev->dev, "No platform data supplied\n");
		return -EINVAL;
	}

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

	pdata = davinci_mcasp_set_pdata_from_of(pdev);
	if (!pdata) {
		dev_err(&pdev->dev, "no platform data\n");
		return -EINVAL;
	}

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem) {
		dev_err(&pdev->dev, "no mem resource?\n");
@@ -882,7 +1004,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
		return -EBUSY;
	}

	pdata = pdev->dev.platform_data;
	pm_runtime_enable(&pdev->dev);

	ret = pm_runtime_get_sync(&pdev->dev);
@@ -980,6 +1101,7 @@ static struct platform_driver davinci_mcasp_driver = {
	.driver		= {
		.name	= "davinci-mcasp",
		.owner	= THIS_MODULE,
		.of_match_table = of_match_ptr(mcasp_dt_ids),
	},
};