Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1373558 > unrolled thread
| Started by | Jose Abreu <Jose.Abreu@synopsys.com> |
|---|---|
| First post | 2016-04-07 19:00 +0200 |
| Last post | 2016-04-07 20:00 +0200 |
| Articles | 12 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH 0/5 v4] Add I2S/ADV7511 audio support for ARC AXS10x boards Jose Abreu <Jose.Abreu@synopsys.com> - 2016-04-07 19:00 +0200
[PATCH 1/5 v4] drm/i2c/adv7511: Rename and move to separate folder Jose Abreu <Jose.Abreu@synopsys.com> - 2016-04-07 19:00 +0200
[PATCH 5/5 v4] ASoC: dwc: Update DOCUMENTATION for I2S Driver Jose Abreu <Jose.Abreu@synopsys.com> - 2016-04-07 19:00 +0200
Re: [PATCH 5/5 v4] ASoC: dwc: Update DOCUMENTATION for I2S Driver Mark Brown <broonie@kernel.org> - 2016-04-07 20:00 +0200
Re: [PATCH 5/5 v4] ASoC: dwc: Update DOCUMENTATION for I2S Driver Jose Abreu <Jose.Abreu@synopsys.com> - 2016-04-08 12:10 +0200
Re: [alsa-devel] [PATCH 5/5 v4] ASoC: dwc: Update DOCUMENTATION for I2S Driver Lars-Peter Clausen <lars@metafoo.de> - 2016-04-08 18:00 +0200
Re: [alsa-devel] [PATCH 5/5 v4] ASoC: dwc: Update DOCUMENTATION for I2S Driver Jose Abreu <Jose.Abreu@synopsys.com> - 2016-04-08 18:10 +0200
Re: [alsa-devel] [PATCH 5/5 v4] ASoC: dwc: Update DOCUMENTATION for I2S Driver Lars-Peter Clausen <lars@metafoo.de> - 2016-04-09 17:00 +0200
Re: [alsa-devel] [PATCH 5/5 v4] ASoC: dwc: Update DOCUMENTATION for I2S Driver Jose Abreu <Jose.Abreu@synopsys.com> - 2016-04-11 11:30 +0200
[PATCH 4/5 v4] ASoC: dwc: Add custom PCM driver Jose Abreu <Jose.Abreu@synopsys.com> - 2016-04-07 19:00 +0200
[PATCH 3/5 v4] ASoC: dwc: Use fifo depth to program FCR Jose Abreu <Jose.Abreu@synopsys.com> - 2016-04-07 19:00 +0200
Applied "ASoC: dwc: Use fifo depth to program FCR" to the asoc tree Mark Brown <broonie@kernel.org> - 2016-04-07 20:00 +0200
| From | Jose Abreu <Jose.Abreu@synopsys.com> |
|---|---|
| Date | 2016-04-07 19:00 +0200 |
| Subject | [PATCH 0/5 v4] Add I2S/ADV7511 audio support for ARC AXS10x boards |
| Message-ID | <rllrI-6RI-3@gated-at.bofh.it> |
ARC AXS10x platforms consist of a mainboard with several peripherals.
One of those peripherals is an HDMI output port controlled by the ADV7511
transmitter.
This patch set adds audio for the ADV7511 transmitter and I2S audio for
the AXS10x platform.
Changes v3 -> v4:
* Reintroduced custom PCM driver (see note below)
* Use DT boolean to switch between ALSA DMA engine PCM or custom PCM
* Use fifo depth to program I2S FCR
* Update I2S documentation
Changes v2 -> v3:
* Removed pll_config functions (as suggested by Alexey Brodkin)
* Removed HDMI start at adv7511_core (as suggested by Archit Taneja)
* Use NOP functions for adv7511_audio (as suggested by Archit Taneja)
* Added adv7511_audio_exit() function (as suggested by Archit Taneja)
* Moved adv7511 to its own folder (as suggested by Archit Taneja)
* Separated file rename of adv7511_core (as suggested by Emil Velikov)
* Compile adv7511 as module if ALSA SoC is compiled as module
* Load adv7511 audio only if declared in device tree (as suggested by Laurent Pinchart)
* Dropped custom platform driver, using now ALSA DMA engine
* Dropped IRQ handler for I2S
Changes v1 -> v2:
* DT bindings moved to separate patch (as suggested by Alexey Brodkin)
* Removed defconfigs entries (as suggested by Alexey Brodkin)
NOTE:
Although the mainline I2S driver uses ALSA DMA engine,
this controller can be built without DMA support so it
was necessary to add this custom platform driver so that
HDMI audio works in AXS boards.
Jose Abreu (5):
drm/i2c/adv7511: Rename and move to separate folder
drm/i2c/adv7511: Add audio support
ASoC: dwc: Use fifo depth to program FCR
ASoC: dwc: Add custom PCM driver
ASoC: dwc: Update DOCUMENTATION for I2S Driver
.../bindings/display/bridge/adi,adv7511.txt | 3 +
.../devicetree/bindings/sound/designware-i2s.txt | 5 +
drivers/gpu/drm/i2c/Kconfig | 6 +-
drivers/gpu/drm/i2c/Makefile | 2 +-
drivers/gpu/drm/i2c/adv7511/Kconfig | 18 ++
drivers/gpu/drm/i2c/adv7511/Makefile | 3 +
drivers/gpu/drm/i2c/{ => adv7511}/adv7511.h | 53 ++++
drivers/gpu/drm/i2c/adv7511/adv7511_audio.c | 310 +++++++++++++++++++++
.../drm/i2c/{adv7511.c => adv7511/adv7511_core.c} | 43 +--
include/sound/soc-dai.h | 1 +
sound/soc/dwc/Kconfig | 9 +
sound/soc/dwc/Makefile | 1 +
sound/soc/dwc/designware.h | 70 +++++
sound/soc/dwc/designware_i2s.c | 106 +++++--
sound/soc/dwc/designware_pcm.c | 230 +++++++++++++++
15 files changed, 796 insertions(+), 64 deletions(-)
create mode 100644 drivers/gpu/drm/i2c/adv7511/Kconfig
create mode 100644 drivers/gpu/drm/i2c/adv7511/Makefile
rename drivers/gpu/drm/i2c/{ => adv7511}/adv7511.h (90%)
create mode 100644 drivers/gpu/drm/i2c/adv7511/adv7511_audio.c
rename drivers/gpu/drm/i2c/{adv7511.c => adv7511/adv7511_core.c} (97%)
create mode 100644 sound/soc/dwc/designware.h
create mode 100644 sound/soc/dwc/designware_pcm.c
--
1.9.1
[toc] | [next] | [standalone]
| From | Jose Abreu <Jose.Abreu@synopsys.com> |
|---|---|
| Date | 2016-04-07 19:00 +0200 |
| Subject | [PATCH 1/5 v4] drm/i2c/adv7511: Rename and move to separate folder |
| Message-ID | <rllrI-6RI-7@gated-at.bofh.it> |
| In reply to | #1373558 |
Main file of adv7511 driver was renamed from adv7511.c
to adv7511_core.c and moved to separate folder in order
to prepare the adding of audio support.
Struct adv7511 was moved to adv7511.h and functions
adv7511_packet_enable() and adv7511_packet_disable()
were made public also to prepare the adding of audio
support.
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
---
No changes v3 -> v4.
This patch was only introduced in v3.
drivers/gpu/drm/i2c/Kconfig | 6 +---
drivers/gpu/drm/i2c/Makefile | 2 +-
drivers/gpu/drm/i2c/adv7511/Kconfig | 6 ++++
drivers/gpu/drm/i2c/adv7511/Makefile | 2 ++
drivers/gpu/drm/i2c/{ => adv7511}/adv7511.h | 31 +++++++++++++++++++++
.../drm/i2c/{adv7511.c => adv7511/adv7511_core.c} | 32 ++--------------------
6 files changed, 43 insertions(+), 36 deletions(-)
create mode 100644 drivers/gpu/drm/i2c/adv7511/Kconfig
create mode 100644 drivers/gpu/drm/i2c/adv7511/Makefile
rename drivers/gpu/drm/i2c/{ => adv7511}/adv7511.h (93%)
rename drivers/gpu/drm/i2c/{adv7511.c => adv7511/adv7511_core.c} (97%)
diff --git a/drivers/gpu/drm/i2c/Kconfig b/drivers/gpu/drm/i2c/Kconfig
index 22c7ed6..9258daf 100644
--- a/drivers/gpu/drm/i2c/Kconfig
+++ b/drivers/gpu/drm/i2c/Kconfig
@@ -1,11 +1,7 @@
menu "I2C encoder or helper chips"
depends on DRM && DRM_KMS_HELPER && I2C
-config DRM_I2C_ADV7511
- tristate "AV7511 encoder"
- select REGMAP_I2C
- help
- Support for the Analog Device ADV7511(W) and ADV7513 HDMI encoders.
+source "drivers/gpu/drm/i2c/adv7511/Kconfig"
config DRM_I2C_CH7006
tristate "Chrontel ch7006 TV encoder"
diff --git a/drivers/gpu/drm/i2c/Makefile b/drivers/gpu/drm/i2c/Makefile
index 2c72eb5..f144830 100644
--- a/drivers/gpu/drm/i2c/Makefile
+++ b/drivers/gpu/drm/i2c/Makefile
@@ -1,6 +1,6 @@
ccflags-y := -Iinclude/drm
-obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511.o
+obj-y += adv7511/
ch7006-y := ch7006_drv.o ch7006_mode.o
obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o
diff --git a/drivers/gpu/drm/i2c/adv7511/Kconfig b/drivers/gpu/drm/i2c/adv7511/Kconfig
new file mode 100644
index 0000000..302c8e34
--- /dev/null
+++ b/drivers/gpu/drm/i2c/adv7511/Kconfig
@@ -0,0 +1,6 @@
+config DRM_I2C_ADV7511
+ tristate "AV7511 encoder"
+ select REGMAP_I2C
+ help
+ Support for the Analog Device ADV7511(W) and ADV7513 HDMI encoders.
+
diff --git a/drivers/gpu/drm/i2c/adv7511/Makefile b/drivers/gpu/drm/i2c/adv7511/Makefile
new file mode 100644
index 0000000..c13f5a1
--- /dev/null
+++ b/drivers/gpu/drm/i2c/adv7511/Makefile
@@ -0,0 +1,2 @@
+adv7511-y := adv7511_core.o
+obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511.o
diff --git a/drivers/gpu/drm/i2c/adv7511.h b/drivers/gpu/drm/i2c/adv7511/adv7511.h
similarity index 93%
rename from drivers/gpu/drm/i2c/adv7511.h
rename to drivers/gpu/drm/i2c/adv7511/adv7511.h
index 38515b3..fcae1ee 100644
--- a/drivers/gpu/drm/i2c/adv7511.h
+++ b/drivers/gpu/drm/i2c/adv7511/adv7511.h
@@ -286,4 +286,35 @@ struct adv7511_video_config {
struct hdmi_avi_infoframe avi_infoframe;
};
+struct adv7511 {
+ struct i2c_client *i2c_main;
+ struct i2c_client *i2c_edid;
+
+ struct regmap *regmap;
+ struct regmap *packet_memory_regmap;
+ enum drm_connector_status status;
+ bool powered;
+
+ unsigned int f_tmds;
+
+ unsigned int current_edid_segment;
+ uint8_t edid_buf[256];
+ bool edid_read;
+
+ wait_queue_head_t wq;
+ struct drm_encoder *encoder;
+
+ bool embedded_sync;
+ enum adv7511_sync_polarity vsync_polarity;
+ enum adv7511_sync_polarity hsync_polarity;
+ bool rgb;
+
+ struct edid *edid;
+
+ struct gpio_desc *gpio_pd;
+};
+
+int adv7511_packet_enable(struct adv7511 *adv7511, unsigned int packet);
+int adv7511_packet_disable(struct adv7511 *adv7511, unsigned int packet);
+
#endif /* __DRM_I2C_ADV7511_H__ */
diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511/adv7511_core.c
similarity index 97%
rename from drivers/gpu/drm/i2c/adv7511.c
rename to drivers/gpu/drm/i2c/adv7511/adv7511_core.c
index a02112b..2b00581 100644
--- a/drivers/gpu/drm/i2c/adv7511.c
+++ b/drivers/gpu/drm/i2c/adv7511/adv7511_core.c
@@ -20,34 +20,6 @@
#include "adv7511.h"
-struct adv7511 {
- struct i2c_client *i2c_main;
- struct i2c_client *i2c_edid;
-
- struct regmap *regmap;
- struct regmap *packet_memory_regmap;
- enum drm_connector_status status;
- bool powered;
-
- unsigned int f_tmds;
-
- unsigned int current_edid_segment;
- uint8_t edid_buf[256];
- bool edid_read;
-
- wait_queue_head_t wq;
- struct drm_encoder *encoder;
-
- bool embedded_sync;
- enum adv7511_sync_polarity vsync_polarity;
- enum adv7511_sync_polarity hsync_polarity;
- bool rgb;
-
- struct edid *edid;
-
- struct gpio_desc *gpio_pd;
-};
-
static struct adv7511 *encoder_to_adv7511(struct drm_encoder *encoder)
{
return to_encoder_slave(encoder)->slave_priv;
@@ -194,7 +166,7 @@ static void adv7511_set_colormap(struct adv7511 *adv7511, bool enable,
ADV7511_CSC_UPDATE_MODE, 0);
}
-static int adv7511_packet_enable(struct adv7511 *adv7511, unsigned int packet)
+int adv7511_packet_enable(struct adv7511 *adv7511, unsigned int packet)
{
if (packet & 0xff)
regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE0,
@@ -209,7 +181,7 @@ static int adv7511_packet_enable(struct adv7511 *adv7511, unsigned int packet)
return 0;
}
-static int adv7511_packet_disable(struct adv7511 *adv7511, unsigned int packet)
+int adv7511_packet_disable(struct adv7511 *adv7511, unsigned int packet)
{
if (packet & 0xff)
regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE0,
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Jose Abreu <Jose.Abreu@synopsys.com> |
|---|---|
| Date | 2016-04-07 19:00 +0200 |
| Subject | [PATCH 5/5 v4] ASoC: dwc: Update DOCUMENTATION for I2S Driver |
| Message-ID | <rllrI-6RI-17@gated-at.bofh.it> |
| In reply to | #1373558 |
This patch updates documentation for the Designware I2S
driver.
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
---
This patch was only introduced in v4.
Documentation/devicetree/bindings/sound/designware-i2s.txt | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/designware-i2s.txt b/Documentation/devicetree/bindings/sound/designware-i2s.txt
index 7bb5424..f3b5c17 100644
--- a/Documentation/devicetree/bindings/sound/designware-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/designware-i2s.txt
@@ -7,6 +7,10 @@ Required properties:
clocks. The controller expects one clock: the clock used as the sampling
rate reference clock sample.
- clock-names : "i2sclk" for the sample rate reference clock.
+
+ Optional properties:
+ - snps,use-dmaengine: If set the driver will use ALSA DMA engine. If set
+ it is required to use the properties 'dmas' and 'dma-names'.
- dmas: Pairs of phandle and specifier for the DMA channels that are used by
the core. The core expects one or two dma channels: one for transmit and
one for receive.
@@ -26,6 +30,7 @@ Example:
clocks = <&scpi_i2sclk 0>;
clock-names = "i2sclk";
#sound-dai-cells = <0>;
+ snps,use-dmaengine;
dmas = <&dma0 5>;
dma-names = "tx";
};
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Mark Brown <broonie@kernel.org> |
|---|---|
| Date | 2016-04-07 20:00 +0200 |
| Subject | Re: [PATCH 5/5 v4] ASoC: dwc: Update DOCUMENTATION for I2S Driver |
| Message-ID | <rlmnP-7Av-43@gated-at.bofh.it> |
| In reply to | #1373562 |
[Multipart message — attachments visible in raw view] — view raw
On Thu, Apr 07, 2016 at 05:53:59PM +0100, Jose Abreu wrote: > + Optional properties: > + - snps,use-dmaengine: If set the driver will use ALSA DMA engine. If set > + it is required to use the properties 'dmas' and 'dma-names'. This is not a good interface, it's describing Linux internal APIs. If the device needs to operate in PIO mode it should just do that.
[toc] | [prev] | [next] | [standalone]
| From | Jose Abreu <Jose.Abreu@synopsys.com> |
|---|---|
| Date | 2016-04-08 12:10 +0200 |
| Subject | Re: [PATCH 5/5 v4] ASoC: dwc: Update DOCUMENTATION for I2S Driver |
| Message-ID | <rlBwu-2b5-9@gated-at.bofh.it> |
| In reply to | #1373618 |
Hi Mark, On 07-04-2016 18:53, Mark Brown wrote: > On Thu, Apr 07, 2016 at 05:53:59PM +0100, Jose Abreu wrote: > >> + Optional properties: >> + - snps,use-dmaengine: If set the driver will use ALSA DMA engine. If set >> + it is required to use the properties 'dmas' and 'dma-names'. > This is not a good interface, it's describing Linux internal APIs. If > the device needs to operate in PIO mode it should just do that. I added this interface because there is no direct way to check if DMA is available on the I2S controller so it is not possible to automatically change between DMA and PIO mode. As the I2S controller can be built with or without DMA support it is necessary to somehow check if DMA is enabled or not and according to that use either ALSA DMA engine or the custom platform driver sent in these patches. I did not want to remove drivers functionality so I added this property to the DT. This way a user can select between DMA and PIO mode. Is there a better option to do this without removing the possibility of using ALSA DMA engine in the driver? Best regards, Jose Miguel Abreu
[toc] | [prev] | [next] | [standalone]
| From | Lars-Peter Clausen <lars@metafoo.de> |
|---|---|
| Date | 2016-04-08 18:00 +0200 |
| Subject | Re: [alsa-devel] [PATCH 5/5 v4] ASoC: dwc: Update DOCUMENTATION for I2S Driver |
| Message-ID | <rlGZc-67T-11@gated-at.bofh.it> |
| In reply to | #1374123 |
On 04/08/2016 12:06 PM, Jose Abreu wrote: > Hi Mark, > > > On 07-04-2016 18:53, Mark Brown wrote: >> On Thu, Apr 07, 2016 at 05:53:59PM +0100, Jose Abreu wrote: >> >>> + Optional properties: >>> + - snps,use-dmaengine: If set the driver will use ALSA DMA engine. If set >>> + it is required to use the properties 'dmas' and 'dma-names'. >> This is not a good interface, it's describing Linux internal APIs. If >> the device needs to operate in PIO mode it should just do that. > > I added this interface because there is no direct way to check if DMA is > available on the I2S controller so it is not possible to automatically change > between DMA and PIO mode. As the I2S controller can be built with or without DMA > support it is necessary to somehow check if DMA is enabled or not and according > to that use either ALSA DMA engine or the custom platform driver sent in these > patches. I did not want to remove drivers functionality so I added this property > to the DT. This way a user can select between DMA and PIO mode. That's OK, but you need to describe the hardware, not the indented behavior of the software driver.
[toc] | [prev] | [next] | [standalone]
| From | Jose Abreu <Jose.Abreu@synopsys.com> |
|---|---|
| Date | 2016-04-08 18:10 +0200 |
| Subject | Re: [alsa-devel] [PATCH 5/5 v4] ASoC: dwc: Update DOCUMENTATION for I2S Driver |
| Message-ID | <rlH8R-6t5-1@gated-at.bofh.it> |
| In reply to | #1374325 |
Hi Lars, On 08-04-2016 16:52, Lars-Peter Clausen wrote: > On 04/08/2016 12:06 PM, Jose Abreu wrote: >> Hi Mark, >> >> >> On 07-04-2016 18:53, Mark Brown wrote: >>> On Thu, Apr 07, 2016 at 05:53:59PM +0100, Jose Abreu wrote: >>> >>>> + Optional properties: >>>> + - snps,use-dmaengine: If set the driver will use ALSA DMA engine. If set >>>> + it is required to use the properties 'dmas' and 'dma-names'. >>> This is not a good interface, it's describing Linux internal APIs. If >>> the device needs to operate in PIO mode it should just do that. >> I added this interface because there is no direct way to check if DMA is >> available on the I2S controller so it is not possible to automatically change >> between DMA and PIO mode. As the I2S controller can be built with or without DMA >> support it is necessary to somehow check if DMA is enabled or not and according >> to that use either ALSA DMA engine or the custom platform driver sent in these >> patches. I did not want to remove drivers functionality so I added this property >> to the DT. This way a user can select between DMA and PIO mode. > That's OK, but you need to describe the hardware, not the indented behavior > of the software driver. > Is this okay: "snps,use-dmaengine: Set this boolean paramater if I2S controller has DMA support. If set the properties 'dmas' and 'dma-names' must be also set" ? Best regards, Jose Miguel Abreu
[toc] | [prev] | [next] | [standalone]
| From | Lars-Peter Clausen <lars@metafoo.de> |
|---|---|
| Date | 2016-04-09 17:00 +0200 |
| Subject | Re: [alsa-devel] [PATCH 5/5 v4] ASoC: dwc: Update DOCUMENTATION for I2S Driver |
| Message-ID | <rm2wG-6Ee-5@gated-at.bofh.it> |
| In reply to | #1374334 |
On 04/08/2016 06:08 PM, Jose Abreu wrote: > Hi Lars, > > > On 08-04-2016 16:52, Lars-Peter Clausen wrote: >> On 04/08/2016 12:06 PM, Jose Abreu wrote: >>> Hi Mark, >>> >>> >>> On 07-04-2016 18:53, Mark Brown wrote: >>>> On Thu, Apr 07, 2016 at 05:53:59PM +0100, Jose Abreu wrote: >>>> >>>>> + Optional properties: >>>>> + - snps,use-dmaengine: If set the driver will use ALSA DMA engine. If set >>>>> + it is required to use the properties 'dmas' and 'dma-names'. >>>> This is not a good interface, it's describing Linux internal APIs. If >>>> the device needs to operate in PIO mode it should just do that. >>> I added this interface because there is no direct way to check if DMA is >>> available on the I2S controller so it is not possible to automatically change >>> between DMA and PIO mode. As the I2S controller can be built with or without DMA >>> support it is necessary to somehow check if DMA is enabled or not and according >>> to that use either ALSA DMA engine or the custom platform driver sent in these >>> patches. I did not want to remove drivers functionality so I added this property >>> to the DT. This way a user can select between DMA and PIO mode. >> That's OK, but you need to describe the hardware, not the indented behavior >> of the software driver. >> > > Is this okay: "snps,use-dmaengine: Set this boolean paramater if I2S controller > has DMA support. If set the properties 'dmas' and 'dma-names' must be also set" ? The description is better. But the name of the property is still imperative rather then descriptive. It tells the software what should be done rather then describing what the hardware looks like. Since there is already the dmas property which is present if a DMA is connected and is absent when no DMA is present it should be enough to just check that property rather than requiring an additional one.
[toc] | [prev] | [next] | [standalone]
| From | Jose Abreu <Jose.Abreu@synopsys.com> |
|---|---|
| Date | 2016-04-11 11:30 +0200 |
| Subject | Re: [alsa-devel] [PATCH 5/5 v4] ASoC: dwc: Update DOCUMENTATION for I2S Driver |
| Message-ID | <rmGkq-3sC-1@gated-at.bofh.it> |
| In reply to | #1374638 |
Hi Lars, On 09-04-2016 15:55, Lars-Peter Clausen wrote: > On 04/08/2016 06:08 PM, Jose Abreu wrote: >> Hi Lars, >> >> >> On 08-04-2016 16:52, Lars-Peter Clausen wrote: >>> On 04/08/2016 12:06 PM, Jose Abreu wrote: >>>> Hi Mark, >>>> >>>> >>>> On 07-04-2016 18:53, Mark Brown wrote: >>>>> On Thu, Apr 07, 2016 at 05:53:59PM +0100, Jose Abreu wrote: >>>>> >>>>>> + Optional properties: >>>>>> + - snps,use-dmaengine: If set the driver will use ALSA DMA engine. If set >>>>>> + it is required to use the properties 'dmas' and 'dma-names'. >>>>> This is not a good interface, it's describing Linux internal APIs. If >>>>> the device needs to operate in PIO mode it should just do that. >>>> I added this interface because there is no direct way to check if DMA is >>>> available on the I2S controller so it is not possible to automatically change >>>> between DMA and PIO mode. As the I2S controller can be built with or without DMA >>>> support it is necessary to somehow check if DMA is enabled or not and according >>>> to that use either ALSA DMA engine or the custom platform driver sent in these >>>> patches. I did not want to remove drivers functionality so I added this property >>>> to the DT. This way a user can select between DMA and PIO mode. >>> That's OK, but you need to describe the hardware, not the indented behavior >>> of the software driver. >>> >> Is this okay: "snps,use-dmaengine: Set this boolean paramater if I2S controller >> has DMA support. If set the properties 'dmas' and 'dma-names' must be also set" ? > The description is better. But the name of the property is still imperative > rather then descriptive. It tells the software what should be done rather > then describing what the hardware looks like. > > Since there is already the dmas property which is present if a DMA is > connected and is absent when no DMA is present it should be enough to just > check that property rather than requiring an additional one. Ok, will then use the DMA property to decide which mode to use: PIO or DMA. > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel Best regards, Jose Miguel Abreu
[toc] | [prev] | [next] | [standalone]
| From | Jose Abreu <Jose.Abreu@synopsys.com> |
|---|---|
| Date | 2016-04-07 19:00 +0200 |
| Subject | [PATCH 4/5 v4] ASoC: dwc: Add custom PCM driver |
| Message-ID | <rllrJ-6RI-25@gated-at.bofh.it> |
| In reply to | #1373558 |
HDMI audio support was added to the AXS board using an
I2S cpu driver and a custom platform driver.
The platform driver supports two channels @ 16 bits with
rates 32k, 44.1k and 48k.
Although the mainline I2S driver uses ALSA DMA engine,
this controller can be built without DMA support so it
was necessary to add this custom platform driver so that
HDMI audio works in AXS boards.
The selection between the use of DMA engine or custom
PCM can be made using a device tree boolean parameter
which was introduced in this patch ('snps,use-dmaengine').
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
---
Changes v3 -> v4:
* Reintroduced custom PCM driver
* Use DT boolean to switch between ALSA DMA engine PCM or custom PCM
Changes v2 -> v3:
* Removed pll_config functions (as suggested by Alexey Brodkin)
* Dropped custom platform driver, using now ALSA DMA engine
* Dropped IRQ handler for I2S
No changes v1 -> v2.
sound/soc/dwc/Kconfig | 9 ++
sound/soc/dwc/Makefile | 1 +
sound/soc/dwc/designware.h | 70 +++++++++++++
sound/soc/dwc/designware_i2s.c | 99 +++++++++++++-----
sound/soc/dwc/designware_pcm.c | 230 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 382 insertions(+), 27 deletions(-)
create mode 100644 sound/soc/dwc/designware.h
create mode 100644 sound/soc/dwc/designware_pcm.c
diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig
index d50e085..2a21120 100644
--- a/sound/soc/dwc/Kconfig
+++ b/sound/soc/dwc/Kconfig
@@ -7,4 +7,13 @@ config SND_DESIGNWARE_I2S
Synopsys desigwnware I2S device. The device supports upto
maximum of 8 channels each for play and record.
+config SND_DESIGNWARE_PCM
+ tristate "Synopsys I2S PCM Driver"
+ help
+ Say Y or M if you want to add support for ALSA ASoC platform driver
+ using I2S.
+
+ Select this option if you want to be able to create a sound interface
+ using the I2S device driver as CPU driver. Instead of using ALSA
+ DMA engine by selecting this driver a custom PCM driver will be used.
diff --git a/sound/soc/dwc/Makefile b/sound/soc/dwc/Makefile
index 319371f..1b48bccc 100644
--- a/sound/soc/dwc/Makefile
+++ b/sound/soc/dwc/Makefile
@@ -1,3 +1,4 @@
# SYNOPSYS Platform Support
obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_i2s.o
+obj-$(CONFIG_SND_DESIGNWARE_PCM) += designware_pcm.o
diff --git a/sound/soc/dwc/designware.h b/sound/soc/dwc/designware.h
new file mode 100644
index 0000000..196296c
--- /dev/null
+++ b/sound/soc/dwc/designware.h
@@ -0,0 +1,70 @@
+/*
+ * ALSA SoC Synopsys Audio Layer
+ *
+ * sound/soc/dwc/designware.h
+ *
+ * Copyright (C) 2016 Synopsys
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __DESIGNWARE_H
+#define __DESIGNWARE_H
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <sound/designware_i2s.h>
+#include <sound/dmaengine_pcm.h>
+
+struct dw_pcm_binfo {
+ struct snd_pcm_substream *stream;
+ unsigned char *dma_base;
+ unsigned char *dma_pointer;
+ unsigned int period_size_frames;
+ unsigned int size;
+ snd_pcm_uframes_t period_pointer;
+ unsigned int total_periods;
+ unsigned int current_period;
+};
+
+union dw_i2s_snd_dma_data {
+ struct i2s_dma_data pd;
+ struct snd_dmaengine_dai_dma_data dt;
+};
+
+struct dw_i2s_dev {
+ void __iomem *i2s_base;
+ struct clk *clk;
+ int active;
+ unsigned int capability;
+ unsigned int quirks;
+ unsigned int i2s_reg_comp1;
+ unsigned int i2s_reg_comp2;
+ struct device *dev;
+ u32 ccr;
+ u32 xfer_resolution;
+ u32 fifo_th;
+
+ /* data related to DMA transfers b/w i2s and DMAC */
+ bool use_dmaengine;
+ union dw_i2s_snd_dma_data play_dma_data;
+ union dw_i2s_snd_dma_data capture_dma_data;
+ struct i2s_clk_config_data config;
+ int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
+ struct dw_pcm_binfo binfo;
+};
+
+#ifdef CONFIG_SND_DESIGNWARE_PCM
+int dw_pcm_transfer(u32 *lsample, u32 *rsample, int bytes, int buf_size,
+ struct dw_pcm_binfo *bi);
+#else
+int dw_pcm_transfer(u32 *lsample, u32 *rsample, int bytes, int buf_size,
+ struct dw_pcm_binfo *bi)
+{
+ return 0;
+}
+#endif
+
+#endif
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index 0db69b7..16056c1 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -24,6 +24,7 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>
+#include "designware.h"
/* common register for all channel */
#define IER 0x000
@@ -84,31 +85,6 @@
#define MAX_CHANNEL_NUM 8
#define MIN_CHANNEL_NUM 2
-union dw_i2s_snd_dma_data {
- struct i2s_dma_data pd;
- struct snd_dmaengine_dai_dma_data dt;
-};
-
-struct dw_i2s_dev {
- void __iomem *i2s_base;
- struct clk *clk;
- int active;
- unsigned int capability;
- unsigned int quirks;
- unsigned int i2s_reg_comp1;
- unsigned int i2s_reg_comp2;
- struct device *dev;
- u32 ccr;
- u32 xfer_resolution;
- u32 fifo_th;
-
- /* data related to DMA transfers b/w i2s and DMAC */
- union dw_i2s_snd_dma_data play_dma_data;
- union dw_i2s_snd_dma_data capture_dma_data;
- struct i2s_clk_config_data config;
- int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
-};
-
static inline void i2s_write_reg(void __iomem *io_base, int reg, u32 val)
{
writel(val, io_base + reg);
@@ -145,6 +121,54 @@ static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream)
}
}
+static irqreturn_t dw_i2s_irq_handler(int irq, void *dev_id)
+{
+ struct dw_i2s_dev *dev = dev_id;
+ u32 isr[4], sleft[dev->fifo_th], sright[dev->fifo_th];
+ int i, j, xfer_bytes = dev->config.data_width / 8;
+ int dir = dev->binfo.stream->stream;
+
+ for (i = 0; i < 4; i++)
+ isr[i] = i2s_read_reg(dev->i2s_base, ISR(i));
+
+ i2s_clear_irqs(dev, SNDRV_PCM_STREAM_PLAYBACK);
+ i2s_clear_irqs(dev, SNDRV_PCM_STREAM_CAPTURE);
+
+ if (dev->use_dmaengine)
+ return IRQ_HANDLED;
+
+ for (i = 0; i < 4; i++) {
+ /* Copy only to/from first two channels
+ * TODO: Remaining channels
+ */
+ if ((isr[i] & 0x10) && (i == 0) &&
+ (dir == SNDRV_PCM_STREAM_PLAYBACK)) {
+ /* TXFEM - TX FIFO is empty */
+ dw_pcm_transfer(sleft, sright, xfer_bytes, dev->fifo_th,
+ &dev->binfo);
+ for (j = 0; j < dev->fifo_th; j++) {
+ i2s_write_reg(dev->i2s_base, LRBR_LTHR(i),
+ sleft[j]);
+ i2s_write_reg(dev->i2s_base, RRBR_RTHR(i),
+ sright[j]);
+ }
+ } else if ((isr[i] & 0x01) && (i == 0) &&
+ (dir == SNDRV_PCM_STREAM_CAPTURE)) {
+ /* RXDAM - RX FIFO is full */
+ for (j = 0; j < dev->fifo_th; j++) {
+ sleft[j] = i2s_read_reg(dev->i2s_base,
+ LRBR_LTHR(i));
+ sright[j] = i2s_read_reg(dev->i2s_base,
+ RRBR_RTHR(i));
+ }
+ dw_pcm_transfer(sleft, sright, xfer_bytes, dev->fifo_th,
+ &dev->binfo);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
static void i2s_start(struct dw_i2s_dev *dev,
struct snd_pcm_substream *substream)
{
@@ -626,7 +650,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
const struct i2s_platform_data *pdata = pdev->dev.platform_data;
struct dw_i2s_dev *dev;
struct resource *res;
- int ret;
+ int ret, irq_number;
struct snd_soc_dai_driver *dw_i2s_dai;
const char *clk_id;
@@ -649,6 +673,24 @@ static int dw_i2s_probe(struct platform_device *pdev)
if (IS_ERR(dev->i2s_base))
return PTR_ERR(dev->i2s_base);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dev->i2s_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(dev->i2s_base))
+ return PTR_ERR(dev->i2s_base);
+
+ irq_number = platform_get_irq(pdev, 0);
+ if (irq_number <= 0) {
+ dev_err(&pdev->dev, "get_irq fail\n");
+ return -EINVAL;
+ }
+
+ ret = devm_request_irq(&pdev->dev, irq_number, dw_i2s_irq_handler,
+ IRQF_SHARED, "dw_i2s_irq_handler", dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "request_irq fail\n");
+ return ret;
+ }
+
dev->dev = &pdev->dev;
dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
@@ -657,6 +699,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
dev->capability = pdata->cap;
clk_id = NULL;
dev->quirks = pdata->quirks;
+ dev->use_dmaengine = false;
if (dev->quirks & DW_I2S_QUIRK_COMP_REG_OFFSET) {
dev->i2s_reg_comp1 = pdata->i2s_reg_comp1;
dev->i2s_reg_comp2 = pdata->i2s_reg_comp2;
@@ -664,6 +707,8 @@ static int dw_i2s_probe(struct platform_device *pdev)
ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata);
} else {
clk_id = "i2sclk";
+ dev->use_dmaengine = of_property_read_bool(pdev->dev.of_node,
+ "snps,use-dmaengine");
ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res);
}
if (ret < 0)
@@ -695,7 +740,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
goto err_clk_disable;
}
- if (!pdata) {
+ if (dev->use_dmaengine) {
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
if (ret) {
dev_err(&pdev->dev,
diff --git a/sound/soc/dwc/designware_pcm.c b/sound/soc/dwc/designware_pcm.c
new file mode 100644
index 0000000..84ff6b9
--- /dev/null
+++ b/sound/soc/dwc/designware_pcm.c
@@ -0,0 +1,230 @@
+/*
+ * Synopsys I2S PCM Driver
+ *
+ * Copyright (C) 2016 Synopsys
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+#include "designware.h"
+
+#define BUFFER_BYTES_MAX 384000
+#define PERIOD_BYTES_MIN 2048
+#define PERIODS_MIN 8
+
+static const struct snd_pcm_hardware dw_pcm_hardware = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER,
+ .rates = SNDRV_PCM_RATE_32000 |
+ SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000,
+ .rate_min = 32000,
+ .rate_max = 48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = BUFFER_BYTES_MAX,
+ .period_bytes_min = PERIOD_BYTES_MIN,
+ .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
+ .periods_min = PERIODS_MIN,
+ .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
+};
+
+int dw_pcm_transfer(u32 *lsample, u32 *rsample, int bytes, int buf_size,
+ struct dw_pcm_binfo *bi)
+{
+ struct snd_pcm_runtime *rt = bi->stream->runtime;
+ int dir = bi->stream->stream;
+ int i;
+
+ for (i = 0; i < buf_size; i++) {
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
+ memcpy(&lsample[i], bi->dma_pointer, bytes);
+ bi->dma_pointer += bytes;
+ memcpy(&rsample[i], bi->dma_pointer, bytes);
+ bi->dma_pointer += bytes;
+ } else {
+ memcpy(bi->dma_pointer, &lsample[i], bytes);
+ bi->dma_pointer += bytes;
+ memcpy(bi->dma_pointer, &rsample[i], bytes);
+ bi->dma_pointer += bytes;
+ }
+ }
+
+ bi->period_pointer += bytes_to_frames(rt, bytes * 2 * buf_size);
+
+ if (bi->period_pointer >= (bi->period_size_frames * bi->current_period)) {
+ bi->current_period++;
+ if (bi->current_period > bi->total_periods) {
+ bi->dma_pointer = bi->dma_base;
+ bi->period_pointer = 0;
+ bi->current_period = 1;
+ }
+ snd_pcm_period_elapsed(bi->stream);
+ }
+
+ return 0;
+}
+
+static int dw_pcm_open(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_pcm_runtime *rt = substream->runtime;
+ struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(rtd->cpu_dai);
+
+ snd_soc_set_runtime_hwparams(substream, &dw_pcm_hardware);
+ snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
+
+ dev->binfo.stream = substream;
+ rt->private_data = &dev->binfo;
+ return 0;
+}
+
+static int dw_pcm_close(struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
+static int dw_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ struct snd_pcm_runtime *rt = substream->runtime;
+ struct dw_pcm_binfo *bi = rt->private_data;
+ int ret;
+
+ ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
+ params_buffer_bytes(hw_params));
+ if (ret < 0)
+ return ret;
+
+ memset(rt->dma_area, 0, params_buffer_bytes(hw_params));
+ bi->dma_base = rt->dma_area;
+ bi->dma_pointer = bi->dma_base;
+
+ return 0;
+}
+
+static int dw_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+ int ret;
+
+ ret = snd_pcm_lib_free_vmalloc_buffer(substream);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int dw_pcm_prepare(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *rt = substream->runtime;
+ struct dw_pcm_binfo *bi = rt->private_data;
+ u32 buffer_size_frames = 0;
+
+ bi->period_size_frames = bytes_to_frames(rt,
+ snd_pcm_lib_period_bytes(substream));
+ bi->size = snd_pcm_lib_buffer_bytes(substream);
+ buffer_size_frames = bytes_to_frames(rt, bi->size);
+ bi->total_periods = buffer_size_frames / bi->period_size_frames;
+ bi->current_period = 1;
+
+ if ((buffer_size_frames % bi->period_size_frames) != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int dw_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static snd_pcm_uframes_t dw_pcm_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *rt = substream->runtime;
+ struct dw_pcm_binfo *bi = rt->private_data;
+
+ return bi->period_pointer;
+}
+
+static struct snd_pcm_ops dw_pcm_ops = {
+ .open = dw_pcm_open,
+ .close = dw_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = dw_pcm_hw_params,
+ .hw_free = dw_pcm_hw_free,
+ .prepare = dw_pcm_prepare,
+ .trigger = dw_pcm_trigger,
+ .pointer = dw_pcm_pointer,
+ .page = snd_pcm_lib_get_vmalloc_page,
+ .mmap = snd_pcm_lib_mmap_vmalloc,
+};
+
+static int dw_pcm_new(struct snd_soc_pcm_runtime *runtime)
+{
+ struct snd_pcm *pcm = runtime->pcm;
+
+ return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+ snd_dma_continuous_data(GFP_KERNEL), BUFFER_BYTES_MAX,
+ BUFFER_BYTES_MAX);
+}
+
+static void dw_pcm_free(struct snd_pcm *pcm)
+{
+ snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+static struct snd_soc_platform_driver dw_pcm_platform = {
+ .pcm_new = dw_pcm_new,
+ .pcm_free = dw_pcm_free,
+ .ops = &dw_pcm_ops,
+};
+
+static int dw_pcm_probe(struct platform_device *pdev)
+{
+ return devm_snd_soc_register_platform(&pdev->dev, &dw_pcm_platform);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id dw_pcm_of[] = {
+ { .compatible = "snps,designware-pcm" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, dw_pcm_of);
+#endif
+
+static struct platform_driver dw_pcm_driver = {
+ .driver = {
+ .name = "designware-pcm",
+ .of_match_table = of_match_ptr(dw_pcm_of),
+ },
+ .probe = dw_pcm_probe,
+};
+
+module_platform_driver(dw_pcm_driver);
+
+MODULE_AUTHOR("Jose Abreu <joabreu@synopsys.com>, Tiago Duarte");
+MODULE_DESCRIPTION("Synopsys Designware PCM Driver");
+MODULE_LICENSE("GPL v2");
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Jose Abreu <Jose.Abreu@synopsys.com> |
|---|---|
| Date | 2016-04-07 19:00 +0200 |
| Subject | [PATCH 3/5 v4] ASoC: dwc: Use fifo depth to program FCR |
| Message-ID | <rllrJ-6RI-41@gated-at.bofh.it> |
| In reply to | #1373558 |
This patch makes Designware I2S driver use the fifo
depth value to program the fifo configuration register
instead of using hardcoded values.
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
---
This patch was only introduced in v4.
sound/soc/dwc/designware_i2s.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index 3effcd1..0db69b7 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -100,6 +100,7 @@ struct dw_i2s_dev {
struct device *dev;
u32 ccr;
u32 xfer_resolution;
+ u32 fifo_th;
/* data related to DMA transfers b/w i2s and DMAC */
union dw_i2s_snd_dma_data play_dma_data;
@@ -232,14 +233,16 @@ static void dw_i2s_config(struct dw_i2s_dev *dev, int stream)
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
i2s_write_reg(dev->i2s_base, TCR(ch_reg),
dev->xfer_resolution);
- i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02);
+ i2s_write_reg(dev->i2s_base, TFCR(ch_reg),
+ dev->fifo_th - 1);
irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30);
i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
} else {
i2s_write_reg(dev->i2s_base, RCR(ch_reg),
dev->xfer_resolution);
- i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07);
+ i2s_write_reg(dev->i2s_base, RFCR(ch_reg),
+ dev->fifo_th - 1);
irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03);
i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
@@ -499,6 +502,7 @@ static int dw_configure_dai(struct dw_i2s_dev *dev,
*/
u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
u32 comp2 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp2);
+ u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1));
u32 idx;
if (dev->capability & DWC_I2S_RECORD &&
@@ -537,6 +541,7 @@ static int dw_configure_dai(struct dw_i2s_dev *dev,
dev->capability |= DW_I2S_SLAVE;
}
+ dev->fifo_th = fifo_depth / 2;
return 0;
}
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Mark Brown <broonie@kernel.org> |
|---|---|
| Date | 2016-04-07 20:00 +0200 |
| Subject | Applied "ASoC: dwc: Use fifo depth to program FCR" to the asoc tree |
| Message-ID | <rlmnO-7Av-25@gated-at.bofh.it> |
| In reply to | #1373571 |
The patch
ASoC: dwc: Use fifo depth to program FCR
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
From 3fafd14d9422c46f5c2a142298384dc15dbf88b2 Mon Sep 17 00:00:00 2001
From: Jose Abreu <Jose.Abreu@synopsys.com>
Date: Thu, 7 Apr 2016 17:53:57 +0100
Subject: [PATCH] ASoC: dwc: Use fifo depth to program FCR
This patch makes Designware I2S driver use the fifo
depth value to program the fifo configuration register
instead of using hardcoded values.
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/dwc/designware_i2s.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index 3effcd1a7df8..0db69b7e9617 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -100,6 +100,7 @@ struct dw_i2s_dev {
struct device *dev;
u32 ccr;
u32 xfer_resolution;
+ u32 fifo_th;
/* data related to DMA transfers b/w i2s and DMAC */
union dw_i2s_snd_dma_data play_dma_data;
@@ -232,14 +233,16 @@ static void dw_i2s_config(struct dw_i2s_dev *dev, int stream)
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
i2s_write_reg(dev->i2s_base, TCR(ch_reg),
dev->xfer_resolution);
- i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02);
+ i2s_write_reg(dev->i2s_base, TFCR(ch_reg),
+ dev->fifo_th - 1);
irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30);
i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
} else {
i2s_write_reg(dev->i2s_base, RCR(ch_reg),
dev->xfer_resolution);
- i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07);
+ i2s_write_reg(dev->i2s_base, RFCR(ch_reg),
+ dev->fifo_th - 1);
irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03);
i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
@@ -499,6 +502,7 @@ static int dw_configure_dai(struct dw_i2s_dev *dev,
*/
u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
u32 comp2 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp2);
+ u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1));
u32 idx;
if (dev->capability & DWC_I2S_RECORD &&
@@ -537,6 +541,7 @@ static int dw_configure_dai(struct dw_i2s_dev *dev,
dev->capability |= DW_I2S_SLAVE;
}
+ dev->fifo_th = fifo_depth / 2;
return 0;
}
--
2.8.0.rc3
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web