diff mbox

[RESEND,RFC,1/3] ASoC: mediatek: Add binding support for AFE driver

Message ID 1428653649-38200-2-git-send-email-koro.chen@mediatek.com (mailing list archive)
State New, archived
Headers show

Commit Message

Koro Chen April 10, 2015, 8:14 a.m. UTC
Add documentation and header file to support binding of Mediatek's AFE driver

Signed-off-by: Koro Chen <koro.chen@mediatek.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 .../devicetree/bindings/sound/mtk-afe-pcm.txt      | 105 +++++++++++++++++++++
 include/dt-bindings/sound/mtk-afe.h                |  36 +++++++
 2 files changed, 141 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt
 create mode 100644 include/dt-bindings/sound/mtk-afe.h

Comments

Mark Brown April 18, 2015, 5:34 p.m. UTC | #1
On Fri, Apr 10, 2015 at 04:14:07PM +0800, Koro Chen wrote:

> +Each external interface (called "IO" in this driver) is presented as a
> +DAI to ASoC. An IO must be connected via the interconnect to a memif.
> +The connection paths are configured through the device tree.

Why are these connection paths configured via device tree?  I would
expect that either there would be runtime configurability of these
things (particularly if loopback configurations within the hardware are
possible) or we'd just allocate memory interfaces to DAIs automatically
as DAIs come into use.

> +- mem-interface-playback:
> +  mem-interface-capture: property of memif, format is: <memif irq use_sram>;
> +	                 memif: which memif to be used
> +			        (defined in include/dt-bindings/sound/mtk-afe.h)
> +		         irq: which irq to be used
> +			      (defined in include/dt-bindings/sound/mtk-afe.h)
> +		         use_sram: 1 is yes, 0 is no

Again, this looks like stuff we should be able to figure out at runtime
- the use of SRAM in particular looks like something we might want to
change depending on use case.  Assuming it adds buffering then for a
VoIP application we might not want to use SRAM to minimize latency but
during music playback we might want to enable SRAM to minimize power
consumption.
Sascha Hauer April 20, 2015, 4:37 a.m. UTC | #2
On Sat, Apr 18, 2015 at 06:34:07PM +0100, Mark Brown wrote:
> On Fri, Apr 10, 2015 at 04:14:07PM +0800, Koro Chen wrote:
> 
> > +Each external interface (called "IO" in this driver) is presented as a
> > +DAI to ASoC. An IO must be connected via the interconnect to a memif.
> > +The connection paths are configured through the device tree.
> 
> Why are these connection paths configured via device tree?  I would
> expect that either there would be runtime configurability of these
> things (particularly if loopback configurations within the hardware are
> possible) or we'd just allocate memory interfaces to DAIs automatically
> as DAIs come into use.

There is a crossbar switch between the memory interfaces and the DAIs.
Not every connection is possible, so not every memory interface can be
used for every DAI. An algorithm choosing a suitable memory interface
must be quite clever, complicated and also SoC dependent (the same but
different hardware is used on MT8135 aswell), so I thought offering a
static configuration via device tree is a good start. Should there be
runtime configuration possible later the device tree settings could
provide a good default.

> 
> > +- mem-interface-playback:
> > +  mem-interface-capture: property of memif, format is: <memif irq use_sram>;
> > +	                 memif: which memif to be used
> > +			        (defined in include/dt-bindings/sound/mtk-afe.h)
> > +		         irq: which irq to be used
> > +			      (defined in include/dt-bindings/sound/mtk-afe.h)
> > +		         use_sram: 1 is yes, 0 is no
> 
> Again, this looks like stuff we should be able to figure out at runtime
> - the use of SRAM in particular looks like something we might want to
> change depending on use case.  Assuming it adds buffering then for a
> VoIP application we might not want to use SRAM to minimize latency but
> during music playback we might want to enable SRAM to minimize power
> consumption.

That's exactly the usecase. How could such a runtime configurability
look like? sysfs? Or something based on the buffer sizes?

Sascha
Mark Brown April 20, 2015, 8:48 p.m. UTC | #3
On Mon, Apr 20, 2015 at 06:37:47AM +0200, Sascha Hauer wrote:
> On Sat, Apr 18, 2015 at 06:34:07PM +0100, Mark Brown wrote:
> > On Fri, Apr 10, 2015 at 04:14:07PM +0800, Koro Chen wrote:

> > > +Each external interface (called "IO" in this driver) is presented as a
> > > +DAI to ASoC. An IO must be connected via the interconnect to a memif.
> > > +The connection paths are configured through the device tree.

> > Why are these connection paths configured via device tree?  I would
> > expect that either there would be runtime configurability of these
> > things (particularly if loopback configurations within the hardware are
> > possible) or we'd just allocate memory interfaces to DAIs automatically
> > as DAIs come into use.

> There is a crossbar switch between the memory interfaces and the DAIs.
> Not every connection is possible, so not every memory interface can be
> used for every DAI. An algorithm choosing a suitable memory interface
> must be quite clever, complicated and also SoC dependent (the same but
> different hardware is used on MT8135 aswell), so I thought offering a
> static configuration via device tree is a good start. Should there be
> runtime configuration possible later the device tree settings could
> provide a good default.

What exactly do the restrictions look like and how often do they vary in
practice (can we get away with just doing a single static setup in the
driver)?  I'd have thought it should be fairly straightforward to have a
table of valid mappings and just pick the first free memory interface?
I'd rather not get stuck with the tables in the DT.  It's partly to
avoid setting bad precendents, we really don't want everyone coming
along hard coding this stuff, and partly because the hardware you
described didn't seem that hard to handle.

> > > +- mem-interface-playback:
> > > +  mem-interface-capture: property of memif, format is: <memif irq use_sram>;
> > > +	                 memif: which memif to be used
> > > +			        (defined in include/dt-bindings/sound/mtk-afe.h)
> > > +		         irq: which irq to be used
> > > +			      (defined in include/dt-bindings/sound/mtk-afe.h)
> > > +		         use_sram: 1 is yes, 0 is no

> > Again, this looks like stuff we should be able to figure out at runtime
> > - the use of SRAM in particular looks like something we might want to
> > change depending on use case.  Assuming it adds buffering then for a
> > VoIP application we might not want to use SRAM to minimize latency but
> > during music playback we might want to enable SRAM to minimize power
> > consumption.

> That's exactly the usecase. How could such a runtime configurability
> look like? sysfs? Or something based on the buffer sizes?

Yeah, one of those :) but probably an ALSA control is going to be the
easiest for applications.
Sascha Hauer April 21, 2015, 9:49 a.m. UTC | #4
On Mon, Apr 20, 2015 at 09:48:49PM +0100, Mark Brown wrote:
> On Mon, Apr 20, 2015 at 06:37:47AM +0200, Sascha Hauer wrote:
> > On Sat, Apr 18, 2015 at 06:34:07PM +0100, Mark Brown wrote:
> > > On Fri, Apr 10, 2015 at 04:14:07PM +0800, Koro Chen wrote:
> 
> > > > +Each external interface (called "IO" in this driver) is presented as a
> > > > +DAI to ASoC. An IO must be connected via the interconnect to a memif.
> > > > +The connection paths are configured through the device tree.
> 
> > > Why are these connection paths configured via device tree?  I would
> > > expect that either there would be runtime configurability of these
> > > things (particularly if loopback configurations within the hardware are
> > > possible) or we'd just allocate memory interfaces to DAIs automatically
> > > as DAIs come into use.
> 
> > There is a crossbar switch between the memory interfaces and the DAIs.
> > Not every connection is possible, so not every memory interface can be
> > used for every DAI. An algorithm choosing a suitable memory interface
> > must be quite clever, complicated and also SoC dependent (the same but
> > different hardware is used on MT8135 aswell), so I thought offering a
> > static configuration via device tree is a good start. Should there be
> > runtime configuration possible later the device tree settings could
> > provide a good default.
> 
> What exactly do the restrictions look like and how often do they vary in
> practice (can we get away with just doing a single static setup in the
> driver)? I'd have thought it should be fairly straightforward to have a
> table of valid mappings and just pick the first free memory interface?

I think this could be done. I checked the possible connections in the
crossbar switch and it seems all memory interfaces can be connected with
all relevant external interfaces. So indeed the memory interfaces could
be dynamically allocated instead of statically associated to an
external interface. There are two problems I see: Some memory interfaces
are limited in the rates they support, they can only do 8k/16k/32k (for
speech). How can we know such memory interface should be used? Also
there are two programmable hardware gain blocks which can be inserted to
the digital audio path using the crossbar switch. There must be some
mechanism to configure them into different places.

Sascha
Mark Brown April 21, 2015, 10:14 a.m. UTC | #5
On Tue, Apr 21, 2015 at 11:49:26AM +0200, Sascha Hauer wrote:

> I think this could be done. I checked the possible connections in the
> crossbar switch and it seems all memory interfaces can be connected with
> all relevant external interfaces. So indeed the memory interfaces could
> be dynamically allocated instead of statically associated to an
> external interface. There are two problems I see: Some memory interfaces
> are limited in the rates they support, they can only do 8k/16k/32k (for
> speech). How can we know such memory interface should be used? Also
> there are two programmable hardware gain blocks which can be inserted to
> the digital audio path using the crossbar switch. There must be some
> mechanism to configure them into different places.

This (particularly the gain controls) sounds like you want to expose the
routing to userspace and use DPCM, the code also seemed to look like it
was a good fit for DPCM.
Koro Chen April 21, 2015, 10:15 a.m. UTC | #6
On Tue, 2015-04-21 at 11:49 +0200, Sascha Hauer wrote:
> On Mon, Apr 20, 2015 at 09:48:49PM +0100, Mark Brown wrote:
> > On Mon, Apr 20, 2015 at 06:37:47AM +0200, Sascha Hauer wrote:
> > > On Sat, Apr 18, 2015 at 06:34:07PM +0100, Mark Brown wrote:
> > > > On Fri, Apr 10, 2015 at 04:14:07PM +0800, Koro Chen wrote:
> > 
> > > > > +Each external interface (called "IO" in this driver) is presented as a
> > > > > +DAI to ASoC. An IO must be connected via the interconnect to a memif.
> > > > > +The connection paths are configured through the device tree.
> > 
> > > > Why are these connection paths configured via device tree?  I would
> > > > expect that either there would be runtime configurability of these
> > > > things (particularly if loopback configurations within the hardware are
> > > > possible) or we'd just allocate memory interfaces to DAIs automatically
> > > > as DAIs come into use.
> > 
> > > There is a crossbar switch between the memory interfaces and the DAIs.
> > > Not every connection is possible, so not every memory interface can be
> > > used for every DAI. An algorithm choosing a suitable memory interface
> > > must be quite clever, complicated and also SoC dependent (the same but
> > > different hardware is used on MT8135 aswell), so I thought offering a
> > > static configuration via device tree is a good start. Should there be
> > > runtime configuration possible later the device tree settings could
> > > provide a good default.
> > 
> > What exactly do the restrictions look like and how often do they vary in
> > practice (can we get away with just doing a single static setup in the
> > driver)? I'd have thought it should be fairly straightforward to have a
> > table of valid mappings and just pick the first free memory interface?
> 
> I think this could be done. I checked the possible connections in the
> crossbar switch and it seems all memory interfaces can be connected with
> all relevant external interfaces. So indeed the memory interfaces could
> be dynamically allocated instead of statically associated to an
> external interface. There are two problems I see: Some memory interfaces
> are limited in the rates they support, they can only do 8k/16k/32k (for
> speech). How can we know such memory interface should be used? Also
The 2 memif are "DAI" and "MOD_DAI", designed for speech cases, and they
should be only connected to corresponding external interface "DAI/BT"
and "modem", respectively. We don't need to put them into dynamic
allocation. 
> there are two programmable hardware gain blocks which can be inserted to
> the digital audio path using the crossbar switch. There must be some
> mechanism to configure them into different places.
Maybe in DPCM, they can be "widgets", and we can define "routes" and
corresponding controls for them. 
> 
> Sascha
>
Mark Brown April 21, 2015, 10:56 a.m. UTC | #7
On Tue, Apr 21, 2015 at 06:15:06PM +0800, Koro Chen wrote:
> On Tue, 2015-04-21 at 11:49 +0200, Sascha Hauer wrote:

> > there are two programmable hardware gain blocks which can be inserted to
> > the digital audio path using the crossbar switch. There must be some
> > mechanism to configure them into different places.

> Maybe in DPCM, they can be "widgets", and we can define "routes" and
> corresponding controls for them. 

Yes, exactly - it's basically just like a CODEC.
Koro Chen April 22, 2015, 3:17 a.m. UTC | #8
On Mon, 2015-04-20 at 21:48 +0100, Mark Brown wrote:
> On Mon, Apr 20, 2015 at 06:37:47AM +0200, Sascha Hauer wrote:
> > On Sat, Apr 18, 2015 at 06:34:07PM +0100, Mark Brown wrote:
> > > On Fri, Apr 10, 2015 at 04:14:07PM +0800, Koro Chen wrote:
> 
> > > > +Each external interface (called "IO" in this driver) is presented as a
> > > > +DAI to ASoC. An IO must be connected via the interconnect to a memif.
> > > > +The connection paths are configured through the device tree.
> 
> > > Why are these connection paths configured via device tree?  I would
> > > expect that either there would be runtime configurability of these
> > > things (particularly if loopback configurations within the hardware are
> > > possible) or we'd just allocate memory interfaces to DAIs automatically
> > > as DAIs come into use.
> 
> > There is a crossbar switch between the memory interfaces and the DAIs.
> > Not every connection is possible, so not every memory interface can be
> > used for every DAI. An algorithm choosing a suitable memory interface
> > must be quite clever, complicated and also SoC dependent (the same but
> > different hardware is used on MT8135 aswell), so I thought offering a
> > static configuration via device tree is a good start. Should there be
> > runtime configuration possible later the device tree settings could
> > provide a good default.
> 
> What exactly do the restrictions look like and how often do they vary in
> practice (can we get away with just doing a single static setup in the
> driver)?  I'd have thought it should be fairly straightforward to have a
> table of valid mappings and just pick the first free memory interface?
> I'd rather not get stuck with the tables in the DT.  It's partly to
> avoid setting bad precendents, we really don't want everyone coming
> along hard coding this stuff, and partly because the hardware you
> described didn't seem that hard to handle.
> 
If using DPCM, it seems the most suitable FE DAIs will be memif, and
external interface like I2S should be BE DAIs. Do you think it is
suitable for our memif to be FE DAIs? Then which memif to used can be
described in a machine driver's FE DAIs. But I think this has a problem
that our memif is one-direction, playback or capture. So the binded pcm
device cannot have playback and capture capability together. May it
cause trouble for user space apps that assumes there will be pcmC0D0p,
pcmC0D0c?

> > > > +- mem-interface-playback:
> > > > +  mem-interface-capture: property of memif, format is: <memif irq use_sram>;
> > > > +	                 memif: which memif to be used
> > > > +			        (defined in include/dt-bindings/sound/mtk-afe.h)
> > > > +		         irq: which irq to be used
> > > > +			      (defined in include/dt-bindings/sound/mtk-afe.h)
> > > > +		         use_sram: 1 is yes, 0 is no
> 
> > > Again, this looks like stuff we should be able to figure out at runtime
> > > - the use of SRAM in particular looks like something we might want to
> > > change depending on use case.  Assuming it adds buffering then for a
> > > VoIP application we might not want to use SRAM to minimize latency but
> > > during music playback we might want to enable SRAM to minimize power
> > > consumption.
> 
> > That's exactly the usecase. How could such a runtime configurability
> > look like? sysfs? Or something based on the buffer sizes?
> 
> Yeah, one of those :) but probably an ALSA control is going to be the
> easiest for applications.
Mark Brown April 30, 2015, 8:12 p.m. UTC | #9
On Wed, Apr 22, 2015 at 11:17:20AM +0800, Koro Chen wrote:

> If using DPCM, it seems the most suitable FE DAIs will be memif, and
> external interface like I2S should be BE DAIs. Do you think it is
> suitable for our memif to be FE DAIs? Then which memif to used can be
> described in a machine driver's FE DAIs. But I think this has a problem
> that our memif is one-direction, playback or capture. So the binded pcm
> device cannot have playback and capture capability together. May it
> cause trouble for user space apps that assumes there will be pcmC0D0p,
> pcmC0D0c?

I think the only userspace application you really have to worry about
here is PulseAudio which (at least with UCM) should be able to cope
since it needs to handle things like USB microphones.  I think
everything else I can think of can either cope or has to handle the same
use cases as PulseAudio does so should have support.
Koro Chen May 4, 2015, 1:57 a.m. UTC | #10
On Thu, 2015-04-30 at 21:12 +0100, Mark Brown wrote:
> On Wed, Apr 22, 2015 at 11:17:20AM +0800, Koro Chen wrote:
> 
> > If using DPCM, it seems the most suitable FE DAIs will be memif, and
> > external interface like I2S should be BE DAIs. Do you think it is
> > suitable for our memif to be FE DAIs? Then which memif to used can be
> > described in a machine driver's FE DAIs. But I think this has a problem
> > that our memif is one-direction, playback or capture. So the binded pcm
> > device cannot have playback and capture capability together. May it
> > cause trouble for user space apps that assumes there will be pcmC0D0p,
> > pcmC0D0c?
> 
> I think the only userspace application you really have to worry about
> here is PulseAudio which (at least with UCM) should be able to cope
> since it needs to handle things like USB microphones.  I think
> everything else I can think of can either cope or has to handle the same
> use cases as PulseAudio does so should have support.
Thank you very much for the feedback, I will try DPCM.
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt
new file mode 100644
index 0000000..11fc8ba
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mtk-afe-pcm.txt
@@ -0,0 +1,105 @@ 
+Mediatek AFE PCM controller
+
+The AFE unit can be illustrated by this figure:
+
+| MEMIF    |      AFE      |     IO     |
+           *****************
+DL1------> *I5           O3* <----I2S--->
+           *I6           O4*
+           *             I3*
+           *             I4*
+           *             O0* <--2ndI2S-->
+           *             O1*
+           *             I0*
+           *             I1*
+AWB<------ *O5             * <--MTKIF--->
+           *O6             *
+VUL<------ *O9             * <---HDMI--->
+           *O10            *
+           *      AFE      *
+HDMI-----> * inter-connect *
+           *****************
+AFE comprises several memory interfaces (DL1, DL2, VUL, DAI, AWB, MOD_DAI
+and HDMI) that communicate with CPU, a multi input multi output digital audio
+interconnect, and several external interfaces (I2S, proprietary MTKIF, HDMI).
+Each external interface (called "IO" in this driver) is presented as a
+DAI to ASoC. An IO must be connected via the interconnect to a memif.
+The connection paths are configured through the device tree.
+
+Required properties:
+- compatible = "mediatek,mt8173-afe-pcm";
+- reg: array of register and sram location and size:
+       <register base address, size>,
+       <sram base address, size>;
+- interrupts: Should contain AFE interrupt
+- clock-names: should have these clock names:
+		"infra_sys_audio_clk",
+		"top_pdn_audio",
+		"top_pdn_aud_intbus",
+		"bck0",
+		"bck1",
+		"i2s0_m",
+		"i2s1_m",
+		"i2s2_m",
+		"i2s3_m",
+		"i2s3_b";
+
+DAI subnodes:
+  A DAI subnode describes which io connects to which memif.
+
+Required subnode properties:
+- io: which I/O to be used
+      (defined in include/dt-bindings/sound/mtk-afe.h)
+- connections: AFE connection pairs definition of this dai
+	       For example, <5 3 6 4> means I5->O3, I6->O4
+	       check SoC datasheet for a complete description
+- mem-interface-playback:
+  mem-interface-capture: property of memif, format is: <memif irq use_sram>;
+	                 memif: which memif to be used
+			        (defined in include/dt-bindings/sound/mtk-afe.h)
+		         irq: which irq to be used
+			      (defined in include/dt-bindings/sound/mtk-afe.h)
+		         use_sram: 1 is yes, 0 is no
+
+  Each DAI should describes at least playback or capture
+
+Example:
+
+	afe: mt8173-afe-pcm@11220000  {
+		compatible = "mediatek,mt8173-afe-pcm";
+		reg = <0 0x11220000 0 0x1000>,
+		      <0 0x11221000 0 0x9000>;
+		interrupts = <GIC_SPI 134 IRQ_TYPE_EDGE_FALLING>;
+		clocks = <&infracfg INFRA_AUDIO>,
+			<&topckgen TOP_AUDIO_SEL>,
+			<&topckgen TOP_AUD_INTBUS_SEL>,
+			<&topckgen TOP_APLL1_DIV0>,
+			<&topckgen TOP_APLL2_DIV0>,
+			<&topckgen TOP_I2S0_M_CK_SEL>,
+			<&topckgen TOP_I2S1_M_CK_SEL>,
+			<&topckgen TOP_I2S2_M_CK_SEL>,
+			<&topckgen TOP_I2S3_M_CK_SEL>,
+			<&topckgen TOP_I2S3_B_CK_SEL>;
+		clock-names = "infra_sys_audio_clk",
+				"top_pdn_audio",
+				"top_pdn_aud_intbus",
+				"bck0",
+				"bck1",
+				"i2s0_m",
+				"i2s1_m",
+				"i2s2_m",
+				"i2s3_m",
+				"i2s3_b";
+		dai@0 {
+			io = <MTK_AFE_IO_I2S>;
+			connections = <5 3 6 4 3 9 4 10>;
+			mem-interface-playback = <MTK_AFE_MEMIF_DL1 MTK_AFE_IRQ_1 1>;
+			mem-interface-capture = <MTK_AFE_MEMIF_VUL MTK_AFE_IRQ_2 0>;
+		};
+
+		dai@1 {
+			io = <MTK_AFE_IO_HDMI>;
+			connections = <36 36 37 37 34 32 35 33 32 34 33 35 30 30 31 31>;
+			mem-interface-playback = <MTK_AFE_MEMIF_HDMI MTK_AFE_IRQ_5 0>;
+		};
+	};
diff --git a/include/dt-bindings/sound/mtk-afe.h b/include/dt-bindings/sound/mtk-afe.h
new file mode 100644
index 0000000..e6da18e
--- /dev/null
+++ b/include/dt-bindings/sound/mtk-afe.h
@@ -0,0 +1,36 @@ 
+#ifndef __DT_MTK_AFE_H
+#define __DT_MTK_AFE_H
+
+#define MTK_AFE_MEMIF_DL1		0
+#define MTK_AFE_MEMIF_DL2		1
+#define MTK_AFE_MEMIF_VUL		2
+#define MTK_AFE_MEMIF_DAI		3
+#define MTK_AFE_MEMIF_AWB		4
+#define MTK_AFE_MEMIF_MOD_DAI		5
+#define MTK_AFE_MEMIF_HDMI		6
+#define MTK_AFE_MEMIF_NUM		7
+
+#define MTK_AFE_IO_MOD_PCM1		0 /* connection to int main modem */
+#define MTK_AFE_IO_MOD_PCM2		1 /* connection to extrt/int modem */
+#define MTK_AFE_IO_PMIC		2 /* MTKIF for DAC and ADC */
+#define MTK_AFE_IO_I2S			3 /* I2S */
+#define MTK_AFE_IO_2ND_I2S		4 /* 2nd I2S */
+#define MTK_AFE_IO_HW_GAIN1		5 /* HW gain control */
+#define MTK_AFE_IO_HW_GAIN2		6
+#define MTK_AFE_IO_MRG_O		7 /* merge interface */
+#define MTK_AFE_IO_MRG_I		8
+#define MTK_AFE_IO_DAIBT		9
+#define MTK_AFE_IO_HDMI		10
+#define MTK_AFE_IO_NUM			11
+
+#define MTK_AFE_IRQ_1			0
+#define MTK_AFE_IRQ_2			1
+#define MTK_AFE_IRQ_3			2
+#define MTK_AFE_IRQ_4			3
+#define MTK_AFE_IRQ_5			4
+#define MTK_AFE_IRQ_6			5
+#define MTK_AFE_IRQ_7			6
+#define MTK_AFE_IRQ_8			7
+#define MTK_AFE_IRQ_NUM			8
+
+#endif /* __DT_MTK_AFE_H */