[alsa-devel] [PATCH RFC 0/8] Fix AM335x-evm analog audio support
From: Jyri Sarha jsarha@ti.com
This set of patches fixes the basic audio support for am335x-evm. It should also be relatively simple to add the necessary nodes to relevant dts files to get BeagleBone + AudioCape and am335x-evmsk working too.
The patch set depends on following patches:
[PATCH v2] ARM: dts: add AM33XX EDMA support https://lkml.org/lkml/2013/8/26/57
[PATCH v11 5/8] ARM: dts: add AM33XX SPI DMA support https://lkml.org/lkml/2013/6/18/55
[PATCH v2] ARM: EDMA: Fix clearing of unused list for DT DMA resources https://lkml.org/lkml/2013/7/22/441
I have tried my best not to break the existing support for older davinci boards, but since I do not have those boards I can not be sure.
Some commit comments refer to a dmaengine based davinci audio implementation which is planned for but nothing has been done yet.
Best regards, Jyri
Darren Etheridge (1): ARM/dts: am335x-evm: Add audio support for am335x-evm.dts
Hebbar, Gururaja (2): ASoC: davinci-evm: Add device tree binding ASoC: davinci: Add support for AM33xx SoC Audio
Joel A Fernandes (1): ASoC: davinci-mcasp: Add pinctrl support
Jyri Sarha (3): ASoC: davinci-mcasp: Get DMA related properties from DT ASoC: davinci-mcasp: Extract DMA channels directly from DT ARM/dts: am33xx: mcasp: Add new dma related properties
Pantelis Antoniou (1): ARM/dts: am33xx: Add mcasp0 and mcasp1 device tree entries
.../bindings/sound/davinci-evm-audio.txt | 53 ++++++ .../bindings/sound/davinci-mcasp-audio.txt | 13 +- arch/arm/boot/dts/am335x-evm.dts | 56 ++++++ arch/arm/boot/dts/am33xx.dtsi | 35 ++++ include/linux/platform_data/davinci_asp.h | 2 + sound/soc/davinci/Kconfig | 8 + sound/soc/davinci/Makefile | 3 + sound/soc/davinci/davinci-evm.c | 181 +++++++++++++++++--- sound/soc/davinci/davinci-mcasp.c | 82 +++++++-- 9 files changed, 391 insertions(+), 42 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
From: Joel A Fernandes agnel.joel@gmail.com
Signed-off-by: Hebbar, Gururaja gururaja.hebbar@ti.com Signed-off-by: Joel A Fernandes agnel.joel@gmail.com Signed-off-by: Darren Etheridge detheridge@ti.com Signed-off-by: Jyri Sarha jsarha@ti.com --- sound/soc/davinci/davinci-mcasp.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 32ddb7f..b849c9d 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -25,6 +25,7 @@ #include <linux/of.h> #include <linux/of_platform.h> #include <linux/of_device.h> +#include <linux/pinctrl/consumer.h>
#include <sound/core.h> #include <sound/pcm.h> @@ -1127,6 +1128,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) struct resource *mem, *ioarea, *res; struct snd_platform_data *pdata; struct davinci_audio_dev *dev; + struct pinctrl *pinctrl; int ret;
if (!pdev->dev.platform_data && !pdev->dev.of_node) { @@ -1158,6 +1160,11 @@ static int davinci_mcasp_probe(struct platform_device *pdev) return -EBUSY; }
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev); + if (IS_ERR(pinctrl)) + dev_warn(&pdev->dev, + "pins are not configured from the driver\n"); + pm_runtime_enable(&pdev->dev);
ret = pm_runtime_get_sync(&pdev->dev);
On Mon, Sep 09, 2013 at 06:12:12PM +0300, oku@iki.fi wrote:
- pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
- if (IS_ERR(pinctrl))
dev_warn(&pdev->dev,
"pins are not configured from the driver\n");
This should be being done by the driver core now - is that not working?
From: "Hebbar, Gururaja" gururaja.hebbar@ti.com
Device tree support for Davinci Machine driver
When the board boots with device tree, the driver will receive card, codec, dai interface details (like the card name, DAPM routing map, phandle for the audio components described in the dts file, codec mclk speed). The card will be set up based on this information. Since the routing is provided via DT we can mark the card fully routed so core can take care of disconnecting the unused pins.
Signed-off-by: Hebbar, Gururaja gururaja.hebbar@ti.com Signed-off-by: Darren Etheridge detheridge@ti.com Signed-off-by: Jyri Sarha jsarha@ti.com --- .../bindings/sound/davinci-evm-audio.txt | 53 ++++++ sound/soc/davinci/davinci-evm.c | 181 +++++++++++++++++--- 2 files changed, 214 insertions(+), 20 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
diff --git a/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt new file mode 100644 index 0000000..25f7180 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt @@ -0,0 +1,53 @@ +* Texas Instruments SoC audio setups with TLV320AIC3X Codec + +Required properties: +- compatible : + "ti,dm365-voice-codec-audio" : for DM365 platforms with Voice Codec + "ti,da830-evm-audio" : for DM365/DA8xx/OMAPL1x/AM33xx + +- ti,model : The user-visible name of this sound complex. +- ti,audio-codec : The phandle of the TLV320AIC3x audio codec +- ti,mcasp-controller : The phandle of the McASP controller +- ti,codec-clock-rate : The Codec Clock rate (in Hz) applied to the Codec +- ti,audio-routing : A list of the connections between audio components. + Each entry is a pair of strings, the first being the connection's sink, + the second being the connection's source. Valid names for sources and + sinks are the codec's pins, and the jacks on the board: + + Codec pins: + + * MIC3L + * MIC3R + * LINE1L + * LINE2L + * LINE1R + * LINE2R + + Board connectors: + + * Headphone Jack + * Line Out + * Mic Jack + + +Example: + +sound { + compatible = "ti,da830-evm-audio"; + ti,model = "DA830 EVM"; + ti,audio-codec = <&tlv320aic3x>; + ti,mcasp-controller = <&mcasp1>; + ti,codec-clock-rate = <12000000>; + ti,audio-routing = + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "Line Out", "LLOUT", + "Line Out", "RLOUT", + "MIC3L", "Mic Bias 2V", + "MIC3R", "Mic Bias 2V", + "Mic Bias 2V", "Mic Jack", + "LINE1L", "Line In", + "LINE2L", "Line In", + "LINE1R", "Line In", + "LINE2R", "Line In"; +}; diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index fd7c45b..ca548b3 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -16,6 +16,7 @@ #include <linux/platform_device.h> #include <linux/platform_data/edma.h> #include <linux/i2c.h> +#include <linux/of_platform.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> @@ -23,6 +24,8 @@ #include <asm/dma.h> #include <asm/mach-types.h>
+#include <linux/edma.h> + #include "davinci-pcm.h" #include "davinci-i2s.h" #include "davinci-mcasp.h" @@ -35,27 +38,38 @@ static int evm_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_card *soc_card = codec->card; + struct device_node *np = soc_card->dev->of_node; int ret = 0; unsigned sysclk;
- /* ASP1 on DM355 EVM is clocked by an external oscillator */ - if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm() || - machine_is_davinci_dm365_evm()) - sysclk = 27000000; - - /* ASP0 in DM6446 EVM is clocked by U55, as configured by - * board-dm644x-evm.c using GPIOs from U18. There are six - * options; here we "know" we use a 48 KHz sample rate. - */ - else if (machine_is_davinci_evm()) - sysclk = 12288000; - - else if (machine_is_davinci_da830_evm() || - machine_is_davinci_da850_evm()) - sysclk = 24576000; - - else - return -EINVAL; + if (np) { + ret = of_property_read_u32(np, "ti,codec-clock-rate", &sysclk); + if (ret < 0) + return ret; + } else { + /* ASP1 on DM355 EVM is clocked by an external oscillator */ + if (machine_is_davinci_dm355_evm() || + machine_is_davinci_dm6467_evm() || + machine_is_davinci_dm365_evm()) + sysclk = 27000000; + + /* + * ASP0 in DM6446 EVM is clocked by U55, as configured by + * board-dm644x-evm.c using GPIOs from U18. There are six + * options; here we "know" we use a 48 KHz sample rate. + */ + else if (machine_is_davinci_evm()) + sysclk = 12288000; + + else if (machine_is_davinci_da830_evm() || + machine_is_davinci_da850_evm()) + sysclk = 24576000; + + else + return -EINVAL; + }
/* set codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT); @@ -133,13 +147,22 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; + struct device_node *np = codec->card->dev->of_node; + int ret;
/* Add davinci-evm specific widgets */ snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, ARRAY_SIZE(aic3x_dapm_widgets));
- /* Set up davinci-evm specific audio path audio_map */ - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); + if (np) { + ret = snd_soc_of_parse_audio_routing(codec->card, + "ti,audio-routing"); + if (ret) + return ret; + } else { + /* Set up davinci-evm specific audio path audio_map */ + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); + }
/* not connected */ snd_soc_dapm_disable_pin(dapm, "MONO_LOUT"); @@ -288,6 +311,108 @@ static struct snd_soc_card da850_snd_soc_card = { .num_links = 1, };
+#if defined(CONFIG_OF) + +enum { + MACHINE_VERSION_1 = 0, /* DM365 with Voice Codec */ + MACHINE_VERSION_2, /* DM365/DA8xx/OMAPL1x/AM33xx */ +}; + +static const struct of_device_id davinci_evm_dt_ids[] = { + { + .compatible = "ti,dm365-voice-codec-audio", + .data = (void *)MACHINE_VERSION_1, + }, + { + .compatible = "ti,da830-evm-audio", + .data = (void *)MACHINE_VERSION_2, + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, davinci_evm_dt_ids); + +/* + * This struct is just used as place holder. It will be filled with + * data from dt node + */ +static struct snd_soc_dai_link evm_dai = { + .name = "TLV320AIC3X", + .stream_name = "AIC3X", + .codec_dai_name = "tlv320aic3x-hifi", +}; + +/* davinci evm audio machine driver */ +static struct snd_soc_card evm_soc_card = { + .owner = THIS_MODULE, + .dai_link = &evm_dai, + .num_links = 1, +}; + +static int davinci_evm_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + const struct of_device_id *match = + of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev); + u32 machine_ver; + int ret = 0; + + machine_ver = (u32)match->data; + switch (machine_ver) { + case MACHINE_VERSION_1: + evm_dai.name = "Voice Codec - CQ93VC"; + evm_dai.stream_name = "CQ93"; + evm_dai.codec_dai_name = "cq93vc-hifi"; + break; + + case MACHINE_VERSION_2: + evm_dai.ops = &evm_ops; + evm_dai.init = evm_aic3x_init; + break; + } + + evm_dai.codec_of_node = of_parse_phandle(np, "ti,audio-codec", 0); + if (!evm_dai.codec_of_node) + return -EINVAL; + + evm_dai.cpu_of_node = of_parse_phandle(np, + "ti,mcasp-controller", 0); + if (!evm_dai.cpu_of_node) + return -EINVAL; + + evm_dai.platform_of_node = evm_dai.cpu_of_node; + + evm_soc_card.dev = &pdev->dev; + ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model"); + if (ret) + return ret; + + ret = snd_soc_register_card(&evm_soc_card); + if (ret) + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); + + return ret; +} + +static int davinci_evm_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + + return 0; +} + +static struct platform_driver davinci_evm_driver = { + .probe = davinci_evm_probe, + .remove = davinci_evm_remove, + .driver = { + .name = "davinci_evm", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(davinci_evm_dt_ids), + }, +}; +#endif + static struct platform_device *evm_snd_device;
static int __init evm_init(void) @@ -296,6 +421,15 @@ static int __init evm_init(void) int index; int ret;
+#if defined(CONFIG_OF) + /* + * If dtb is there, the devices will be created dynamically. + * Only register platfrom driver structure. + */ + if (of_have_populated_dt()) + return platform_driver_register(&davinci_evm_driver); +#endif + if (machine_is_davinci_evm()) { evm_snd_dev_data = &dm6446_snd_soc_card_evm; index = 0; @@ -331,6 +465,13 @@ static int __init evm_init(void)
static void __exit evm_exit(void) { +#if defined(CONFIG_OF) + if (of_have_populated_dt()) { + platform_driver_unregister(&davinci_evm_driver); + return; + } +#endif + platform_device_unregister(evm_snd_device); }
On Mon, Sep 09, 2013 at 06:12:13PM +0300, oku@iki.fi wrote:
From: "Hebbar, Gururaja" gururaja.hebbar@ti.com
Device tree support for Davinci Machine driver
You need to send this to the device tree maintainers and the device tree mailing list (not the old one you CCed).
- Codec pins:
- MIC3L
- MIC3R
- LINE1L
- LINE2L
- LINE1R
- LINE2R
These should be documented in the binding for the CODEC and referenced here - if there isn't a binding for the CODEC you should add it.
- machine_ver = (u32)match->data;
- switch (machine_ver) {
- case MACHINE_VERSION_1:
evm_dai.name = "Voice Codec - CQ93VC";
evm_dai.stream_name = "CQ93";
evm_dai.codec_dai_name = "cq93vc-hifi";
break;
- case MACHINE_VERSION_2:
evm_dai.ops = &evm_ops;
evm_dai.init = evm_aic3x_init;
break;
- }
This appears to have binndings for two completely different CODECs...
On 2013-09-09 18:21, Mark Brown wrote:
On Mon, Sep 09, 2013 at 06:12:13PM +0300, oku@iki.fi wrote: From: "Hebbar, Gururaja" gururaja.hebbar@ti.com
Device tree support for Davinci Machine driver
...
- Codec pins:
- MIC3L
- MIC3R
- LINE1L
- LINE2L
- LINE1R
- LINE2R
These should be documented in the binding for the CODEC and referenced here - if there isn't a binding for the CODEC you should add it.
After checking the code, are you sure about this? Non of the other codecs have pins in their devicetree binding document?
Best regards, Jyri
On Wed, Sep 11, 2013 at 01:38:47PM +0300, Jyri Sarha wrote:
After checking the code, are you sure about this? Non of the other codecs have pins in their devicetree binding document?
Yes, I am sure and yes there are other CODECs with pins listed, check again.
On 2013-09-11 14:35, Mark Brown wrote:
On Wed, Sep 11, 2013 at 01:38:47PM +0300, Jyri Sarha wrote:
After checking the code, are you sure about this? Non of the other codecs have pins in their devicetree binding document?
Yes, I am sure and yes there are other CODECs with pins listed, check again.
I wonder if I somehow misunderstood your first comment. I just noticed that davinci-evm-audio.txt is missing all the output pins and some connectors that are found in the code and also in the example node. I will add those.
I can of course also add the list of pins to Documentation/devicetree/ bindings/sound/tlv320aic3x.txt, if that was what you meant. It would make sense to have the pins there. However, I really can not find the list of pins from any of the Wolfson codec binding documents (Documentation/devicetree/bindings/sound/wm*.txt) for exmaple. Are you perhaps refering to some other document or is the convention changing for v3.12?
When comparing the codec bindings I found that the regulators are missing from tlv320aic3x.txt. I'll add those too.
Best regards, Jyri
On Wed, Sep 11, 2013 at 09:02:06PM +0300, Jyri Sarha wrote:
I can of course also add the list of pins to Documentation/devicetree/ bindings/sound/tlv320aic3x.txt, if that was what you meant. It would make sense to have the pins there. However, I really can not find the
Yes, that is what I meant.
list of pins from any of the Wolfson codec binding documents (Documentation/devicetree/bindings/sound/wm*.txt) for exmaple. Are you perhaps refering to some other document or is the convention changing for v3.12?
This is more to do with the fact that very few people have actually done DT bindings for machines so nobody has been documenting the bindings properly. If you look you'll see some of the Wolfson devices do have pin lists.
From: Jyri Sarha jsarha@ti.com
This patch adds new DMA related properties to mcasp DT bindings. The new properties may not be needed after davinci audio is updated to use dmaengine.
Signed-off-by: Hebbar, Gururaja gururaja.hebbar@ti.com Signed-off-by: Darren Etheridge detheridge@ti.com Signed-off-by: Jyri Sarha jsarha@ti.com --- .../bindings/sound/davinci-mcasp-audio.txt | 13 ++++++--- sound/soc/davinci/davinci-mcasp.c | 28 +++++++++++++++++--- 2 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt index 374e145..417d90e 100644 --- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt @@ -6,7 +6,10 @@ Required properties: "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms "ti,omap2-mcasp-audio" : for OMAP2 platforms (TI81xx, AM33xx)
-- reg : Should contain McASP registers offset and length +- reg : Should contain McASP registers offset/address and length + and the following nodes contain offset/addresses and lenghts + for TX and RX DMA areas +- reg-names : First node name should be "mpu" followed by "dma-tx" and "dma-rx" - interrupts : Interrupt number for McASP - op-mode : I2S/DIT ops mode. - tdm-slots : Slots for TDM operation. @@ -14,7 +17,7 @@ Required properties: - 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) - +- asp-chan-q : Selects EDMA event queue (transfer controller) to use
Optional properties:
@@ -23,6 +26,8 @@ Optional properties: - 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 +- ram-chan-q : Selects EDMA event queue (transfer controller) to use for + ping-pong mode.
Example:
@@ -30,7 +35,9 @@ mcasp0: mcasp0@1d00000 { compatible = "ti,da830-mcasp-audio"; #address-cells = <1>; #size-cells = <0>; - reg = <0x100000 0x3000>; + reg = <0x100000 0x3000>, + <0x102000 0x1000>; + reg-names "mpu", "dma"; interrupts = <82 83>; op-mode = <0>; /* MCASP_IIS_MODE */ tdm-slots = <2>; diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index b849c9d..cc02255 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -1095,6 +1095,14 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( pdata->serial_dir = of_serial_dir; }
+ ret = of_property_read_u32(np, "asp-chan-q", &pdata->asp_chan_q); + if (ret < 0) + goto nodata; + + ret = of_property_read_u32(np, "ram-chan-q", &val); + if (ret >= 0) + pdata->ram_chan_q = val; + ret = of_property_read_u32(np, "tx-num-evt", &val); if (ret >= 0) pdata->txnumevt = val; @@ -1189,13 +1197,26 @@ static int davinci_mcasp_probe(struct platform_device *pdev) dev->rxnumevt = pdata->rxnumevt; dev->dev = &pdev->dev;
+ dma = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma-tx"); + if (dma) + pdata->tx_dma_offset = dma->start; + + dma = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma-rx"); + if (dma) + pdata->rx_dma_offset = dma->start; + + if (dev->version == MCASP_VERSION_1 || + dev->version == MCASP_VERSION_2) { + pdata->tx_dma_offset += mem->start; + pdata->rx_dma_offset += mem->start; + } + 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->sram_pool = pdata->sram_pool; dma_data->sram_size = pdata->sram_size_playback; - dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + - mem->start); + dma_data->dma_addr = pdata->tx_dma_offset;
/* first TX, then RX */ res = platform_get_resource(pdev, IORESOURCE_DMA, 0); @@ -1212,8 +1233,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) dma_data->ram_chan_q = pdata->ram_chan_q; dma_data->sram_pool = pdata->sram_pool; dma_data->sram_size = pdata->sram_size_capture; - dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + - mem->start); + dma_data->dma_addr = pdata->rx_dma_offset;
res = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!res) {
On Mon, Sep 09, 2013 at 06:12:14PM +0300, oku@iki.fi wrote:
From: Jyri Sarha jsarha@ti.com
This patch adds new DMA related properties to mcasp DT bindings. The new properties may not be needed after davinci audio is updated to use dmaengine.
How hard is it going to be to convert to dmaengine or to open code something that works with the standard bindings even if the implementation is open coded? I'm not enthusiastic about adding temporary bindings, I'm not sure the DT maintainers would be either.
On 2013-09-09 18:25, Mark Brown wrote:
On Mon, Sep 09, 2013 at 06:12:14PM +0300, oku@iki.fi wrote: From: Jyri Sarha jsarha@ti.com
This patch adds new DMA related properties to mcasp DT bindings. The new properties may not be needed after davinci audio is updated to use dmaengine.
How hard is it going to be to convert to dmaengine or to open code something that works with the standard bindings even if the implementation is open coded? I'm not enthusiastic about adding temporary bindings, I'm not sure the DT maintainers would be either.
I have not studied the code enough to give a good work estimate about the conversion, but at least the current EDMA driver would need cyclic mode to be implemented before the conversion would be possible. It may also be difficult to make sure all the old davinci HW using the same code would still work after the change. In any case I do not think the conversion is going to be made anytime soon (read: in time for v3.13).
However, after taking a another look at the added DT bindings, I think we could survive with mcasp dma register addresses only for now. To my understanding those are anyway need in mcasp node. In DT boot the mcasp EDMA event queue could be hardcoded to the highest priority for now.
How does this sound?
Best regards, Jyri
On Wed, Sep 11, 2013 at 02:48:19PM +0300, Jyri Sarha wrote:
I have not studied the code enough to give a good work estimate about the conversion, but at least the current EDMA driver would need cyclic mode to be implemented before the conversion would be possible. It may
The other option is to support non-cyclic mode in the generic code.
However, after taking a another look at the added DT bindings, I think we could survive with mcasp dma register addresses only for now. To my understanding those are anyway need in mcasp node. In DT boot the mcasp EDMA event queue could be hardcoded to the highest priority for now.
How does this sound?
I'm not clear what that means in concrete terms, sorry. Do you mean you can just use the existing register ranges for the McASP? Please bear in mind that I don't really know anything about this hardware.
On 2013-09-12 14:08, Mark Brown wrote:
On Wed, Sep 11, 2013 at 02:48:19PM +0300, Jyri Sarha wrote:
...
However, after taking a another look at the added DT bindings, I think we could survive with mcasp dma register addresses only for now. To my understanding those are anyway need in mcasp node. In DT boot the mcasp EDMA event queue could be hardcoded to the highest priority for now.
How does this sound?
I'm not clear what that means in concrete terms, sorry. Do you mean you can just use the existing register ranges for the McASP? Please bear in mind that I don't really know anything about this hardware.
The bottom line of my suggestion is only to add the dma register location to reg-property, since that info is needed in the mcasp node also in the future dmaengine_pcm-implementation.
The driver implementation would still remain pretty much the same. The McASP code would - instead of adding new properties to DT - use sensible hard-coded default event queue selection (= dma priority selection) for now.
Best regards, Jyri
On Thu, Sep 12, 2013 at 02:34:13PM +0300, Jyri Sarha wrote:
The bottom line of my suggestion is only to add the dma register location to reg-property, since that info is needed in the mcasp node also in the future dmaengine_pcm-implementation.
What exactly is the dma register location here - what hardware is being controlled?
On 2013-09-12 14:56, Mark Brown wrote:
On Thu, Sep 12, 2013 at 02:34:13PM +0300, Jyri Sarha wrote:
The bottom line of my suggestion is only to add the dma register location to reg-property, since that info is needed in the mcasp node also in the future dmaengine_pcm-implementation.
What exactly is the dma register location here - what hardware is being controlled?
They is the McASP-bus receive/transmit buffer data port addresses. So those are McASP entity specific properties that need to be passed to DMA-engine.
On Thu, Sep 12, 2013 at 03:10:12PM +0300, Jyri Sarha wrote:
On 2013-09-12 14:56, Mark Brown wrote:
What exactly is the dma register location here - what hardware is being controlled?
They is the McASP-bus receive/transmit buffer data port addresses. So those are McASP entity specific properties that need to be passed to DMA-engine.
OK, and presumably this is just part of the main McASP register block and doesn't need to go into DT?
On 09/13/2013 01:34 PM, Mark Brown wrote:
On Thu, Sep 12, 2013 at 03:10:12PM +0300, Jyri Sarha wrote:
On 2013-09-12 14:56, Mark Brown wrote:
What exactly is the dma register location here - what hardware is being controlled?
They is the McASP-bus receive/transmit buffer data port addresses. So those are McASP entity specific properties that need to be passed to DMA-engine.
OK, and presumably this is just part of the main McASP register block and doesn't need to go into DT?
Not really. For instance on am33xx SoCs the MPU usually accesses McASP registers trough L4 interconnect, which is not accessible by DMA controller. For DMA controller the data port is also mapped trough L3 bus to entirely different address and a simple register offset is not enough. Naturally this mapping may change SoC to SoC.
I have been working with OMAP family chips so long that I start think everybody would know their internal workings. Sorry about that.
Best regards, Jyri
On Fri, Sep 13, 2013 at 01:50:31PM +0300, Jyri Sarha wrote:
On 09/13/2013 01:34 PM, Mark Brown wrote:
OK, and presumably this is just part of the main McASP register block and doesn't need to go into DT?
Not really. For instance on am33xx SoCs the MPU usually accesses McASP registers trough L4 interconnect, which is not accessible by DMA controller. For DMA controller the data port is also mapped trough L3 bus to entirely different address and a simple register offset is not enough. Naturally this mapping may change SoC to SoC.
I see. I don't think this is a problem so long as the bindings are specified in a way that can be reused with dmaengine, which I'd guess ought to be the case if it's just specifying a physical address.
From: Jyri Sarha jsarha@ti.com
Extract DMA channels directly from DT as they can not be found from platform resources anymore. This is a work-around until davinci audio driver is updated to use dmaengine.
Signed-off-by: Jyri Sarha jsarha@ti.com --- include/linux/platform_data/davinci_asp.h | 2 ++ sound/soc/davinci/davinci-mcasp.c | 47 ++++++++++++++++++++--------- 2 files changed, 34 insertions(+), 15 deletions(-)
diff --git a/include/linux/platform_data/davinci_asp.h b/include/linux/platform_data/davinci_asp.h index 8db5ae0..689a856 100644 --- a/include/linux/platform_data/davinci_asp.h +++ b/include/linux/platform_data/davinci_asp.h @@ -84,6 +84,8 @@ struct snd_platform_data { u8 version; u8 txnumevt; u8 rxnumevt; + int tx_dma_channel; + int rx_dma_channel; };
enum { diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index cc02255..1ca8891 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -1026,6 +1026,7 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( struct snd_platform_data *pdata = NULL; const struct of_device_id *match = of_match_device(mcasp_dt_ids, &pdev->dev); + struct of_phandle_args dma_spec;
const u32 *of_serial_dir32; u8 *of_serial_dir; @@ -1103,6 +1104,28 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( if (ret >= 0) pdata->ram_chan_q = val;
+ ret = of_property_match_string(np, "dma-names", "tx"); + if (ret < 0) + goto nodata; + + ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", ret, + &dma_spec); + if (ret < 0) + goto nodata; + + pdata->tx_dma_channel = dma_spec.args[0]; + + ret = of_property_match_string(np, "dma-names", "rx"); + if (ret < 0) + goto nodata; + + ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", ret, + &dma_spec); + if (ret < 0) + goto nodata; + + pdata->rx_dma_channel = dma_spec.args[0]; + ret = of_property_read_u32(np, "tx-num-evt", &val); if (ret >= 0) pdata->txnumevt = val; @@ -1133,7 +1156,7 @@ nodata: static int davinci_mcasp_probe(struct platform_device *pdev) { struct davinci_pcm_dma_params *dma_data; - struct resource *mem, *ioarea, *res; + struct resource *mem, *ioarea, *res, *dma; struct snd_platform_data *pdata; struct davinci_audio_dev *dev; struct pinctrl *pinctrl; @@ -1218,15 +1241,11 @@ static int davinci_mcasp_probe(struct platform_device *pdev) dma_data->sram_size = pdata->sram_size_playback; dma_data->dma_addr = pdata->tx_dma_offset;
- /* first TX, then RX */ res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!res) { - dev_err(&pdev->dev, "no DMA resource\n"); - ret = -ENODEV; - goto err_release_clk; - } - - dma_data->channel = res->start; + if (res) + dma_data->channel = res->start; + else + dma_data->channel = pdata->tx_dma_channel;
dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; dma_data->asp_chan_q = pdata->asp_chan_q; @@ -1236,13 +1255,11 @@ static int davinci_mcasp_probe(struct platform_device *pdev) dma_data->dma_addr = pdata->rx_dma_offset;
res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (!res) { - dev_err(&pdev->dev, "no DMA resource\n"); - ret = -ENODEV; - goto err_release_clk; - } + if (res) + dma_data->channel = res->start; + else + dma_data->channel = pdata->rx_dma_channel;
- dma_data->channel = res->start; dev_set_drvdata(&pdev->dev, dev); ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component, &davinci_mcasp_dai[pdata->op_mode], 1);
From: "Hebbar, Gururaja" gururaja.hebbar@ti.com
AM33xx uses same McASP IP as the Davinci Platform. This patch updates Kconfig and makefile to enable build or McASP, PCM & Codec drivers
Signed-off-by: Hebbar, Gururaja gururaja.hebbar@ti.com Signed-off-by: Darren Etheridge detheridge@ti.com Signed-off-by: Jyri Sarha jsarha@ti.com --- sound/soc/davinci/Kconfig | 8 ++++++++ sound/soc/davinci/Makefile | 3 +++ 2 files changed, 11 insertions(+)
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index c82f89c..48ed52d 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -6,6 +6,14 @@ config SND_DAVINCI_SOC the DAVINCI AC97 or I2S interface. You will also need to select the audio interfaces to support below.
+config SND_AM33XX_SOC + tristate "SoC Audio for the AM33XX chip" + depends on SOC_AM33XX + select SND_SOC_TLV320AIC3X + help + Say Y or M if you want to add support for SoC audio on AM33xx + boards using McASP and TLV320AIC3X codec. + config SND_DAVINCI_SOC_I2S tristate
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile index a396ab6..120b6e2 100644 --- a/sound/soc/davinci/Makefile +++ b/sound/soc/davinci/Makefile @@ -5,14 +5,17 @@ snd-soc-davinci-mcasp-objs:= davinci-mcasp.o snd-soc-davinci-vcif-objs:= davinci-vcif.o
obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o +obj-$(CONFIG_SND_AM33XX_SOC) += snd-soc-davinci.o obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o +obj-$(CONFIG_SND_AM33XX_SOC) += snd-soc-davinci-mcasp.o obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o
# DAVINCI Machine Support snd-soc-evm-objs := davinci-evm.o
obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o +obj-$(CONFIG_SND_AM33XX_SOC) += snd-soc-evm.o obj-$(CONFIG_SND_DM6467_SOC_EVM) += snd-soc-evm.o obj-$(CONFIG_SND_DA830_SOC_EVM) += snd-soc-evm.o obj-$(CONFIG_SND_DA850_SOC_EVM) += snd-soc-evm.o
On Mon, Sep 09, 2013 at 06:12:16PM +0300, oku@iki.fi wrote:
obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o +obj-$(CONFIG_SND_AM33XX_SOC) += snd-soc-davinci.o obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o +obj-$(CONFIG_SND_AM33XX_SOC) += snd-soc-davinci-mcasp.o obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o
# DAVINCI Machine Support snd-soc-evm-objs := davinci-evm.o
obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o +obj-$(CONFIG_SND_AM33XX_SOC) += snd-soc-evm.o
This appears to be trying to include a duplicate copy of some of the existing code - that doesn't seem sensible? I'd expect to see additional machines added with || and possibly also some help text updates.
Even better would be to get the code to the point where it has no machine dependencies at all.
From: Pantelis Antoniou panto@antoniou-consulting.com
Add missing mcasp entries in the am33xx.dtsi include file.
Signed-off-by: Pantelis Antoniou panto@antoniou-consulting.com Signed-off-by: Darren Etheridge detheridge@ti.com Signed-off-by: Jyri Sarha jsarha@ti.com --- arch/arm/boot/dts/am33xx.dtsi | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 0fdb949..2c0679a 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -552,5 +552,26 @@ #size-cells = <1>; status = "disabled"; }; + + mcasp0: mcasp@48038000 { + compatible = "ti,omap2-mcasp-audio"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "mcasp0"; + reg = <0x48038000 0x2000>; + interrupts = <80 81>; + status = "disabled"; + }; + + mcasp1: mcasp@4803C000 { + compatible = "ti,omap2-mcasp-audio"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "mcasp1"; + reg = <0x4803C000 0x2000>; + interrupts = <82 83>; + status = "disabled"; + }; + }; };
On Mon, Sep 09, 2013 at 06:12:17PM +0300, oku@iki.fi wrote:
From: Pantelis Antoniou panto@antoniou-consulting.com
Add missing mcasp entries in the am33xx.dtsi include file.
Signed-off-by: Pantelis Antoniou panto@antoniou-consulting.com Signed-off-by: Darren Etheridge detheridge@ti.com Signed-off-by: Jyri Sarha jsarha@ti.com
Acked-by: Mark Brown broonie@linaro.org
I'd expect this to go via the arm-soc tree, the bindings are already merged and there's no build time dependency on any ASoC code anyway.
From: Jyri Sarha jsarha@ti.com
This patch adds couple of dma related mcasp properies to DT which may not be needed after dmaengine implementaion of davinci audio is ready.
Signed-off-by: Hebbar, Gururaja gururaja.hebbar@ti.com Signed-off-by: Darren Etheridge detheridge@ti.com Signed-off-by: Jyri Sarha jsarha@ti.com --- arch/arm/boot/dts/am33xx.dtsi | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 2c0679a..57f2b4a 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -558,9 +558,16 @@ #address-cells = <1>; #size-cells = <0>; ti,hwmods = "mcasp0"; - reg = <0x48038000 0x2000>; + reg = <0x48038000 0x2000>, + <0x46400000 0x400000>, + <0x46400000 0x400000>; + reg-names = "mpu", "dma-tx", "dma-rx"; interrupts = <80 81>; status = "disabled"; + asp-chan-q = <2>; /* EVENTQ_2 */ + dmas = <&edma 8 + &edma 9>; + dma-names = "tx", "rx"; };
mcasp1: mcasp@4803C000 { @@ -568,9 +575,16 @@ #address-cells = <1>; #size-cells = <0>; ti,hwmods = "mcasp1"; - reg = <0x4803C000 0x2000>; + reg = <0x4803C000 0x2000>, + <0x46400000 0x400000>, + <0x46400000 0x400000>; + reg-names = "mpu", "dma-tx", "dma-rx"; interrupts = <82 83>; status = "disabled"; + asp-chan-q = <2>; /* EVENTQ_2 */ + dmas = <&edma 10 + &edma 11>; + dma-names = "tx", "rx"; };
};
From: Darren Etheridge detheridge@ti.com
Adds sound, tlv320aic3x, mcasp1, and am335x_evm_audio_pin nodes.
Signed-off-by: Darren Etheridge detheridge@ti.com Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Signed-off-by: Jyri Sarha jsarha@ti.com --- arch/arm/boot/dts/am335x-evm.dts | 56 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts index 3aee1a4..4a49229 100644 --- a/arch/arm/boot/dts/am335x-evm.dts +++ b/arch/arm/boot/dts/am335x-evm.dts @@ -149,6 +149,16 @@ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) >; }; + + am335x_evm_audio_pins: am335x_evm_audio_pins { + pinctrl-single,pins = < + 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rx_dv.mcasp1_aclkx */ + 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_txd3.mcasp1_fsx */ + 0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */ + 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */ + >; + }; + };
ocp { @@ -215,6 +225,19 @@ compatible = "ti,tmp275"; reg = <0x48>; }; + + tlv320aic3x: tlv320aic3x@1b { + compatible = "ti,tlv320aic3x"; + reg = <0x1b>; + status = "okay"; + + /* Regulators */ + AVDD-supply = <&vaux2_reg>; + IOVDD-supply = <&vaux2_reg>; + DRVDD-supply = <&vaux2_reg>; + DVDD-supply = <&vbat>; + }; + };
elm: elm@48080000 { @@ -311,6 +334,20 @@ }; }; }; + + sound { + compatible = "ti,da830-evm-audio"; + ti,model = "DA830 EVM"; + ti,audio-codec = <&tlv320aic3x>; + ti,mcasp-controller = <&mcasp1>; + ti,codec-clock-rate = <12000000>; + ti,audio-routing = + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "LINE1L", "Line In", + "LINE1R", "Line In"; + }; + };
vbat: fixedregulator@0 { @@ -378,6 +415,25 @@
#include "tps65910.dtsi"
+&mcasp1 { + pinctrl-names = "default"; + pinctrl-0 = <&am335x_evm_audio_pins>; + + status = "okay"; + + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; + num-serializer = <16>; + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 0 0 1 2 + 0 0 0 0 + 0 0 0 0 + 0 0 0 0 + >; + tx-num-evt = <1>; + rx-num-evt = <1>; +}; + &tps { vcc1-supply = <&vbat>; vcc2-supply = <&vbat>;
participants (4)
-
Jyri Sarha
-
Jyri Sarha
-
Mark Brown
-
oku@iki.fi