All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v10 0/7] ASoC: fsl-ssi: ac97-slave support
@ 2013-07-27 11:31 ` Markus Pargmann
  0 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Timur Tabi, Liam Girdwood, Grant Likely,
	Mark Brown, Sascha Hauer, Shawn Guo

Hi,

this series implements ac97-slave support for fsl-ssi and phycore ac97 DT
support.

Since v9 there were a lot of changes. I dropped the board specific ac97-link
reset functions and added generic functions to soc-core. It uses devicetree
parsed pinctrl and gpios. The audmux setup was removed from phycore-ac97-dt.
The initial setup can now be defined in DT.

Regards,

Markus


Markus Pargmann (7):
      ASoC: core: Generic ac97 link reset functions
      ASoC: codec: wm9712 simple DT bindings
      ASoC: imx-audmux: Read default configuration from devicetree
      ASoC: fsl-ssi: Add support for imx-pcm-fiq
      ASoC: fsl-ssi: Use generic DMA bindings if possible
      ASoC: fsl-ssi: ac97-slave support
      ASoC: Add phycore-ac97-dt driver

 .../devicetree/bindings/sound/fsl,ssi.txt          |  12 +
 .../devicetree/bindings/sound/imx-audmux.txt       |   9 +
 .../bindings/sound/phytec,phycore-ac97.txt         |  16 +
 .../devicetree/bindings/sound/soc-ac97link.txt     |  28 ++
 Documentation/devicetree/bindings/sound/wm9712.txt |  10 +
 include/sound/soc.h                                |   2 +
 sound/soc/codecs/wm9712.c                          |   9 +
 sound/soc/fsl/Kconfig                              |  15 +-
 sound/soc/fsl/Makefile                             |   2 +
 sound/soc/fsl/fsl_ssi.c                            | 431 +++++++++++++++++----
 sound/soc/fsl/imx-audmux.c                         |  62 +++
 sound/soc/fsl/phycore-ac97-dt.c                    | 124 ++++++
 sound/soc/fsl/phycore-ac97.c                       |  13 +-
 sound/soc/soc-core.c                               | 153 ++++++++
 14 files changed, 789 insertions(+), 97 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt
 create mode 100644 Documentation/devicetree/bindings/sound/soc-ac97link.txt
 create mode 100644 Documentation/devicetree/bindings/sound/wm9712.txt
 create mode 100644 sound/soc/fsl/phycore-ac97-dt.c

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v10 0/7] ASoC: fsl-ssi: ac97-slave support
@ 2013-07-27 11:31 ` Markus Pargmann
  0 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

this series implements ac97-slave support for fsl-ssi and phycore ac97 DT
support.

Since v9 there were a lot of changes. I dropped the board specific ac97-link
reset functions and added generic functions to soc-core. It uses devicetree
parsed pinctrl and gpios. The audmux setup was removed from phycore-ac97-dt.
The initial setup can now be defined in DT.

Regards,

Markus


Markus Pargmann (7):
      ASoC: core: Generic ac97 link reset functions
      ASoC: codec: wm9712 simple DT bindings
      ASoC: imx-audmux: Read default configuration from devicetree
      ASoC: fsl-ssi: Add support for imx-pcm-fiq
      ASoC: fsl-ssi: Use generic DMA bindings if possible
      ASoC: fsl-ssi: ac97-slave support
      ASoC: Add phycore-ac97-dt driver

 .../devicetree/bindings/sound/fsl,ssi.txt          |  12 +
 .../devicetree/bindings/sound/imx-audmux.txt       |   9 +
 .../bindings/sound/phytec,phycore-ac97.txt         |  16 +
 .../devicetree/bindings/sound/soc-ac97link.txt     |  28 ++
 Documentation/devicetree/bindings/sound/wm9712.txt |  10 +
 include/sound/soc.h                                |   2 +
 sound/soc/codecs/wm9712.c                          |   9 +
 sound/soc/fsl/Kconfig                              |  15 +-
 sound/soc/fsl/Makefile                             |   2 +
 sound/soc/fsl/fsl_ssi.c                            | 431 +++++++++++++++++----
 sound/soc/fsl/imx-audmux.c                         |  62 +++
 sound/soc/fsl/phycore-ac97-dt.c                    | 124 ++++++
 sound/soc/fsl/phycore-ac97.c                       |  13 +-
 sound/soc/soc-core.c                               | 153 ++++++++
 14 files changed, 789 insertions(+), 97 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt
 create mode 100644 Documentation/devicetree/bindings/sound/soc-ac97link.txt
 create mode 100644 Documentation/devicetree/bindings/sound/wm9712.txt
 create mode 100644 sound/soc/fsl/phycore-ac97-dt.c

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v10 1/7] ASoC: core: Generic ac97 link reset functions
  2013-07-27 11:31 ` Markus Pargmann
@ 2013-07-27 11:31   ` Markus Pargmann
  -1 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Timur Tabi, Liam Girdwood, Grant Likely,
	Mark Brown, Sascha Hauer, Markus Pargmann, Shawn Guo

This patch adds generic ac97 reset functions using pincontrol and gpio
parsed from devicetree.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 .../devicetree/bindings/sound/soc-ac97link.txt     |  28 ++++
 include/sound/soc.h                                |   2 +
 sound/soc/soc-core.c                               | 153 +++++++++++++++++++++
 3 files changed, 183 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/soc-ac97link.txt

diff --git a/Documentation/devicetree/bindings/sound/soc-ac97link.txt b/Documentation/devicetree/bindings/sound/soc-ac97link.txt
new file mode 100644
index 0000000..80152a8
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/soc-ac97link.txt
@@ -0,0 +1,28 @@
+AC97 link bindings
+
+These bindings can be included within any other device node.
+
+Required properties:
+ - pinctrl-names: Has to contain following states to setup the correct
+   pinmuxing for the used gpios:
+	"ac97-running": AC97-link is active
+	"ac97-reset": AC97-link reset state
+	"ac97-warm-reset": AC97-link warm reset state
+ - ac97-gpios: List of gpio phandles with args in the order ac97-sync,
+   ac97-sdata, ac97-reset
+
+
+Example:
+
+ssi {
+	...
+
+	pinctrl-names = "default", "ac97-running", "ac97-reset", "ac97-warm-reset";
+	pinctrl-0 = <&ac97link_running>;
+	pinctrl-1 = <&ac97link_running>;
+	pinctrl-2 = <&ac97link_reset>;
+	pinctrl-3 = <&ac97link_warm_reset>;
+	ac97-gpios = <&gpio3 20 0 &gpio3 22 0 &gpio3 28 0>;
+
+	...
+};
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 6eabee7..c0ac3bc 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -468,6 +468,8 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
 void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
 
 int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops);
+int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops,
+		struct platform_device *pdev);
 
 /*
  *Controls
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 0ec070c..6010932 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -30,9 +30,12 @@
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
 #include <linux/platform_device.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/ctype.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
 #include <sound/ac97_codec.h>
 #include <sound/core.h>
 #include <sound/jack.h>
@@ -69,6 +72,16 @@ static int pmdown_time = 5000;
 module_param(pmdown_time, int, 0);
 MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
 
+struct snd_ac97_reset_cfg {
+	struct pinctrl *pctl;
+	struct pinctrl_state *pstate_reset;
+	struct pinctrl_state *pstate_warm_reset;
+	struct pinctrl_state *pstate_run;
+	int gpio_sdata;
+	int gpio_sync;
+	int gpio_reset;
+};
+
 /* returns the minimum number of bytes needed to represent
  * a particular given value */
 static int min_bytes_needed(unsigned long val)
@@ -2080,6 +2093,117 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
 }
 EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
 
+static struct snd_ac97_reset_cfg snd_ac97_rst_cfg;
+
+static void snd_soc_ac97_warm_reset(struct snd_ac97 *ac97)
+{
+	struct pinctrl *pctl = snd_ac97_rst_cfg.pctl;
+
+	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_warm_reset);
+
+	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 1);
+
+	udelay(10);
+
+	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0);
+
+	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run);
+	msleep(2);
+}
+
+static void snd_soc_ac97_reset(struct snd_ac97 *ac97)
+{
+	struct pinctrl *pctl = snd_ac97_rst_cfg.pctl;
+
+	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_reset);
+
+	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0);
+	gpio_direction_output(snd_ac97_rst_cfg.gpio_sdata, 0);
+	gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 0);
+
+	udelay(10);
+
+	gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 1);
+
+	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run);
+	msleep(2);
+}
+
+static int snd_soc_ac97_parse_pinctl(struct device *dev,
+		struct snd_ac97_reset_cfg *cfg)
+{
+	struct pinctrl *p;
+	struct pinctrl_state *state;
+	int gpio;
+	int ret;
+
+	p = devm_pinctrl_get(dev);
+	if (IS_ERR(p)) {
+		dev_err(dev, "Failed to get pinctrl\n");
+		return PTR_RET(p);
+	}
+	cfg->pctl = p;
+
+	state = pinctrl_lookup_state(p, "ac97-reset");
+	if (IS_ERR(state)) {
+		dev_err(dev, "Can't find pinctrl state ac97-reset\n");
+		return PTR_RET(state);
+	}
+	cfg->pstate_reset = state;
+
+	state = pinctrl_lookup_state(p, "ac97-warm-reset");
+	if (IS_ERR(state)) {
+		dev_err(dev, "Can't find pinctrl state ac97-warm-reset\n");
+		return PTR_RET(state);
+	}
+	cfg->pstate_warm_reset = state;
+
+	state = pinctrl_lookup_state(p, "ac97-running");
+	if (IS_ERR(state)) {
+		dev_err(dev, "Can't find pinctrl state ac97-running\n");
+		return PTR_RET(state);
+	}
+	cfg->pstate_run = state;
+
+	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 0);
+	if (gpio < 0) {
+		dev_err(dev, "Can't find ac97-sync gpio\n");
+		return gpio;
+	}
+	ret = devm_gpio_request(dev, gpio, "AC97 link sync");
+	if (ret) {
+		dev_err(dev, "Failed requesting ac97-sync gpio\n");
+		return ret;
+	}
+	cfg->gpio_sync = gpio;
+
+	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 1);
+	if (gpio < 0) {
+		dev_err(dev, "Can't find ac97-sdata gpio %d\n", gpio);
+		return gpio;
+	}
+	ret = devm_gpio_request(dev, gpio, "AC97 link sdata");
+	if (ret) {
+		dev_err(dev, "Failed requesting ac97-sdata gpio\n");
+		return ret;
+	}
+	cfg->gpio_sdata = gpio;
+
+	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 2);
+	if (gpio < 0) {
+		dev_err(dev, "Can't find ac97-reset gpio\n");
+		return gpio;
+	}
+	ret = devm_gpio_request(dev, gpio, "AC97 link reset");
+	if (ret) {
+		dev_err(dev, "Failed requesting ac97-reset gpio\n");
+		return ret;
+	}
+	cfg->gpio_reset = gpio;
+
+	return 0;
+}
+
 struct snd_ac97_bus_ops *soc_ac97_ops;
 EXPORT_SYMBOL_GPL(soc_ac97_ops);
 
@@ -2098,6 +2222,35 @@ int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
 EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops);
 
 /**
+ * snd_soc_set_ac97_ops_of_reset - Set ac97 ops with generic ac97 reset functions
+ *
+ * This function sets the reset and warm_reset properties of ops and parses
+ * the device node of pdev to get pinctrl states and gpio numbers to use.
+ */
+int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops,
+		struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct snd_ac97_reset_cfg cfg;
+	int ret;
+
+	ret = snd_soc_ac97_parse_pinctl(dev, &cfg);
+	if (ret)
+		return ret;
+
+	ret = snd_soc_set_ac97_ops(ops);
+	if (ret)
+		return ret;
+
+	ops->warm_reset = snd_soc_ac97_warm_reset;
+	ops->reset = snd_soc_ac97_reset;
+
+	snd_ac97_rst_cfg = cfg;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops_of_reset);
+
+/**
  * snd_soc_free_ac97_codec - free AC97 codec device
  * @codec: audio codec
  *
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 1/7] ASoC: core: Generic ac97 link reset functions
@ 2013-07-27 11:31   ` Markus Pargmann
  0 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds generic ac97 reset functions using pincontrol and gpio
parsed from devicetree.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 .../devicetree/bindings/sound/soc-ac97link.txt     |  28 ++++
 include/sound/soc.h                                |   2 +
 sound/soc/soc-core.c                               | 153 +++++++++++++++++++++
 3 files changed, 183 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/soc-ac97link.txt

diff --git a/Documentation/devicetree/bindings/sound/soc-ac97link.txt b/Documentation/devicetree/bindings/sound/soc-ac97link.txt
new file mode 100644
index 0000000..80152a8
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/soc-ac97link.txt
@@ -0,0 +1,28 @@
+AC97 link bindings
+
+These bindings can be included within any other device node.
+
+Required properties:
+ - pinctrl-names: Has to contain following states to setup the correct
+   pinmuxing for the used gpios:
+	"ac97-running": AC97-link is active
+	"ac97-reset": AC97-link reset state
+	"ac97-warm-reset": AC97-link warm reset state
+ - ac97-gpios: List of gpio phandles with args in the order ac97-sync,
+   ac97-sdata, ac97-reset
+
+
+Example:
+
+ssi {
+	...
+
+	pinctrl-names = "default", "ac97-running", "ac97-reset", "ac97-warm-reset";
+	pinctrl-0 = <&ac97link_running>;
+	pinctrl-1 = <&ac97link_running>;
+	pinctrl-2 = <&ac97link_reset>;
+	pinctrl-3 = <&ac97link_warm_reset>;
+	ac97-gpios = <&gpio3 20 0 &gpio3 22 0 &gpio3 28 0>;
+
+	...
+};
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 6eabee7..c0ac3bc 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -468,6 +468,8 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
 void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
 
 int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops);
+int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops,
+		struct platform_device *pdev);
 
 /*
  *Controls
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 0ec070c..6010932 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -30,9 +30,12 @@
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
 #include <linux/platform_device.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/ctype.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
 #include <sound/ac97_codec.h>
 #include <sound/core.h>
 #include <sound/jack.h>
@@ -69,6 +72,16 @@ static int pmdown_time = 5000;
 module_param(pmdown_time, int, 0);
 MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
 
+struct snd_ac97_reset_cfg {
+	struct pinctrl *pctl;
+	struct pinctrl_state *pstate_reset;
+	struct pinctrl_state *pstate_warm_reset;
+	struct pinctrl_state *pstate_run;
+	int gpio_sdata;
+	int gpio_sync;
+	int gpio_reset;
+};
+
 /* returns the minimum number of bytes needed to represent
  * a particular given value */
 static int min_bytes_needed(unsigned long val)
@@ -2080,6 +2093,117 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
 }
 EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
 
+static struct snd_ac97_reset_cfg snd_ac97_rst_cfg;
+
+static void snd_soc_ac97_warm_reset(struct snd_ac97 *ac97)
+{
+	struct pinctrl *pctl = snd_ac97_rst_cfg.pctl;
+
+	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_warm_reset);
+
+	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 1);
+
+	udelay(10);
+
+	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0);
+
+	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run);
+	msleep(2);
+}
+
+static void snd_soc_ac97_reset(struct snd_ac97 *ac97)
+{
+	struct pinctrl *pctl = snd_ac97_rst_cfg.pctl;
+
+	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_reset);
+
+	gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0);
+	gpio_direction_output(snd_ac97_rst_cfg.gpio_sdata, 0);
+	gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 0);
+
+	udelay(10);
+
+	gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 1);
+
+	pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run);
+	msleep(2);
+}
+
+static int snd_soc_ac97_parse_pinctl(struct device *dev,
+		struct snd_ac97_reset_cfg *cfg)
+{
+	struct pinctrl *p;
+	struct pinctrl_state *state;
+	int gpio;
+	int ret;
+
+	p = devm_pinctrl_get(dev);
+	if (IS_ERR(p)) {
+		dev_err(dev, "Failed to get pinctrl\n");
+		return PTR_RET(p);
+	}
+	cfg->pctl = p;
+
+	state = pinctrl_lookup_state(p, "ac97-reset");
+	if (IS_ERR(state)) {
+		dev_err(dev, "Can't find pinctrl state ac97-reset\n");
+		return PTR_RET(state);
+	}
+	cfg->pstate_reset = state;
+
+	state = pinctrl_lookup_state(p, "ac97-warm-reset");
+	if (IS_ERR(state)) {
+		dev_err(dev, "Can't find pinctrl state ac97-warm-reset\n");
+		return PTR_RET(state);
+	}
+	cfg->pstate_warm_reset = state;
+
+	state = pinctrl_lookup_state(p, "ac97-running");
+	if (IS_ERR(state)) {
+		dev_err(dev, "Can't find pinctrl state ac97-running\n");
+		return PTR_RET(state);
+	}
+	cfg->pstate_run = state;
+
+	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 0);
+	if (gpio < 0) {
+		dev_err(dev, "Can't find ac97-sync gpio\n");
+		return gpio;
+	}
+	ret = devm_gpio_request(dev, gpio, "AC97 link sync");
+	if (ret) {
+		dev_err(dev, "Failed requesting ac97-sync gpio\n");
+		return ret;
+	}
+	cfg->gpio_sync = gpio;
+
+	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 1);
+	if (gpio < 0) {
+		dev_err(dev, "Can't find ac97-sdata gpio %d\n", gpio);
+		return gpio;
+	}
+	ret = devm_gpio_request(dev, gpio, "AC97 link sdata");
+	if (ret) {
+		dev_err(dev, "Failed requesting ac97-sdata gpio\n");
+		return ret;
+	}
+	cfg->gpio_sdata = gpio;
+
+	gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 2);
+	if (gpio < 0) {
+		dev_err(dev, "Can't find ac97-reset gpio\n");
+		return gpio;
+	}
+	ret = devm_gpio_request(dev, gpio, "AC97 link reset");
+	if (ret) {
+		dev_err(dev, "Failed requesting ac97-reset gpio\n");
+		return ret;
+	}
+	cfg->gpio_reset = gpio;
+
+	return 0;
+}
+
 struct snd_ac97_bus_ops *soc_ac97_ops;
 EXPORT_SYMBOL_GPL(soc_ac97_ops);
 
@@ -2098,6 +2222,35 @@ int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
 EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops);
 
 /**
+ * snd_soc_set_ac97_ops_of_reset - Set ac97 ops with generic ac97 reset functions
+ *
+ * This function sets the reset and warm_reset properties of ops and parses
+ * the device node of pdev to get pinctrl states and gpio numbers to use.
+ */
+int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops,
+		struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct snd_ac97_reset_cfg cfg;
+	int ret;
+
+	ret = snd_soc_ac97_parse_pinctl(dev, &cfg);
+	if (ret)
+		return ret;
+
+	ret = snd_soc_set_ac97_ops(ops);
+	if (ret)
+		return ret;
+
+	ops->warm_reset = snd_soc_ac97_warm_reset;
+	ops->reset = snd_soc_ac97_reset;
+
+	snd_ac97_rst_cfg = cfg;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops_of_reset);
+
+/**
  * snd_soc_free_ac97_codec - free AC97 codec device
  * @codec: audio codec
  *
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 2/7] ASoC: codec: wm9712 simple DT bindings
  2013-07-27 11:31 ` Markus Pargmann
@ 2013-07-27 11:31   ` Markus Pargmann
  -1 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Timur Tabi, Liam Girdwood, Grant Likely,
	Mark Brown, Sascha Hauer, Markus Pargmann, Shawn Guo

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 Documentation/devicetree/bindings/sound/wm9712.txt | 10 ++++++++++
 sound/soc/codecs/wm9712.c                          |  9 +++++++++
 2 files changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/wm9712.txt

diff --git a/Documentation/devicetree/bindings/sound/wm9712.txt b/Documentation/devicetree/bindings/sound/wm9712.txt
new file mode 100644
index 0000000..d29f673
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm9712.txt
@@ -0,0 +1,10 @@
+WM9712 audio CODEC
+
+Required properties:
+  - compatible : "wlf,wm9712"
+
+Example:
+
+wm9712: codec {
+	compatible = "wlf,wm9712";
+};
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index c5eb746..d619cdc 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -697,10 +697,19 @@ static int wm9712_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id wm9712_codec_of_dev_id[] = {
+	{
+		.compatible = "wlf,wm9712",
+	}, {
+		/* sentinel */
+	}
+};
+
 static struct platform_driver wm9712_codec_driver = {
 	.driver = {
 		.name = "wm9712-codec",
 		.owner = THIS_MODULE,
+		.of_match_table = wm9712_codec_of_dev_id,
 	},
 
 	.probe = wm9712_probe,
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 2/7] ASoC: codec: wm9712 simple DT bindings
@ 2013-07-27 11:31   ` Markus Pargmann
  0 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 Documentation/devicetree/bindings/sound/wm9712.txt | 10 ++++++++++
 sound/soc/codecs/wm9712.c                          |  9 +++++++++
 2 files changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/wm9712.txt

diff --git a/Documentation/devicetree/bindings/sound/wm9712.txt b/Documentation/devicetree/bindings/sound/wm9712.txt
new file mode 100644
index 0000000..d29f673
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm9712.txt
@@ -0,0 +1,10 @@
+WM9712 audio CODEC
+
+Required properties:
+  - compatible : "wlf,wm9712"
+
+Example:
+
+wm9712: codec {
+	compatible = "wlf,wm9712";
+};
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index c5eb746..d619cdc 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -697,10 +697,19 @@ static int wm9712_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id wm9712_codec_of_dev_id[] = {
+	{
+		.compatible = "wlf,wm9712",
+	}, {
+		/* sentinel */
+	}
+};
+
 static struct platform_driver wm9712_codec_driver = {
 	.driver = {
 		.name = "wm9712-codec",
 		.owner = THIS_MODULE,
+		.of_match_table = wm9712_codec_of_dev_id,
 	},
 
 	.probe = wm9712_probe,
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 3/7] ASoC: imx-audmux: Read default configuration from devicetree
  2013-07-27 11:31 ` Markus Pargmann
@ 2013-07-27 11:31   ` Markus Pargmann
  -1 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Timur Tabi, Liam Girdwood, Grant Likely,
	Mark Brown, Sascha Hauer, Markus Pargmann, Shawn Guo

Adds a function to parse a default port configuration from devicetree.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 .../devicetree/bindings/sound/imx-audmux.txt       |  9 ++++
 sound/soc/fsl/imx-audmux.c                         | 62 ++++++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/imx-audmux.txt b/Documentation/devicetree/bindings/sound/imx-audmux.txt
index 215aa98..f88a00e 100644
--- a/Documentation/devicetree/bindings/sound/imx-audmux.txt
+++ b/Documentation/devicetree/bindings/sound/imx-audmux.txt
@@ -5,6 +5,15 @@ Required properties:
   or "fsl,imx31-audmux" for the version firstly used on i.MX31.
 - reg : Should contain AUDMUX registers location and length
 
+An initial configuration can be setup using child nodes.
+
+Required properties of optional child nodes:
+- fsl,audmux-port : Integer of the audmux port that is configured by this
+  child node.
+- fsl,port-config : List of configuration options for the specific port. For
+  imx31-audmux and above, it is a list of tuples <ptcr pdcr>. For
+  imx21-audmux it is a list of pcr values.
+
 Example:
 
 audmux@021d8000 {
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 1a5da1e..103d1b0 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -251,6 +251,66 @@ int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
 }
 EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
 
+static int imx_audmux_parse_dt_defaults(struct platform_device *pdev,
+		struct device_node *of_node)
+{
+	struct device_node *child;
+
+	for_each_available_child_of_node(of_node, child) {
+		unsigned int port;
+		unsigned int ptcr = 0;
+		unsigned int pdcr = 0;
+		unsigned int pcr = 0;
+		unsigned int val;
+		int ret;
+		int i = 0;
+
+		ret = of_property_read_u32(child, "fsl,audmux-port", &port);
+		if (ret) {
+			dev_warn(&pdev->dev, "Failed to get fsl,audmux-port of child node \"%s\"\n",
+					child->full_name);
+			continue;
+		}
+		if (!of_property_read_bool(child, "fsl,port-config")) {
+			dev_warn(&pdev->dev, "child node \"%s\" does not have property fsl,port-config\n",
+					child->full_name);
+			continue;
+		}
+
+		for (i = 0; (ret = of_property_read_u32_index(child,
+					"fsl,port-config\n", i, &val)) == 0;
+				++i) {
+			if (audmux_type == IMX31_AUDMUX) {
+				if (i % 2)
+					pdcr |= val;
+				else
+					ptcr |= val;
+			} else {
+				pcr |= val;
+			}
+		}
+
+		if (ret != -ENODATA) {
+			dev_err(&pdev->dev, "Failed to read u32 at index %d of child %s\n",
+					i, child->full_name);
+			continue;
+		}
+
+		if (audmux_type == IMX31_AUDMUX) {
+			if (i % 2) {
+				dev_err(&pdev->dev, "One pdcr value is missing in child node %s\n",
+						child->full_name);
+				continue;
+			}
+			imx_audmux_v2_configure_port(port, ptcr, pdcr);
+		} else {
+			imx_audmux_v1_configure_port(port, pcr);
+		}
+	}
+
+	return 0;
+}
+
 static int imx_audmux_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -275,6 +335,8 @@ static int imx_audmux_probe(struct platform_device *pdev)
 	if (audmux_type == IMX31_AUDMUX)
 		audmux_debugfs_init();
 
+	imx_audmux_parse_dt_defaults(pdev, pdev->dev.of_node);
+
 	return 0;
 }
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 3/7] ASoC: imx-audmux: Read default configuration from devicetree
@ 2013-07-27 11:31   ` Markus Pargmann
  0 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

Adds a function to parse a default port configuration from devicetree.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 .../devicetree/bindings/sound/imx-audmux.txt       |  9 ++++
 sound/soc/fsl/imx-audmux.c                         | 62 ++++++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/imx-audmux.txt b/Documentation/devicetree/bindings/sound/imx-audmux.txt
index 215aa98..f88a00e 100644
--- a/Documentation/devicetree/bindings/sound/imx-audmux.txt
+++ b/Documentation/devicetree/bindings/sound/imx-audmux.txt
@@ -5,6 +5,15 @@ Required properties:
   or "fsl,imx31-audmux" for the version firstly used on i.MX31.
 - reg : Should contain AUDMUX registers location and length
 
+An initial configuration can be setup using child nodes.
+
+Required properties of optional child nodes:
+- fsl,audmux-port : Integer of the audmux port that is configured by this
+  child node.
+- fsl,port-config : List of configuration options for the specific port. For
+  imx31-audmux and above, it is a list of tuples <ptcr pdcr>. For
+  imx21-audmux it is a list of pcr values.
+
 Example:
 
 audmux at 021d8000 {
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 1a5da1e..103d1b0 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -251,6 +251,66 @@ int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
 }
 EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
 
+static int imx_audmux_parse_dt_defaults(struct platform_device *pdev,
+		struct device_node *of_node)
+{
+	struct device_node *child;
+
+	for_each_available_child_of_node(of_node, child) {
+		unsigned int port;
+		unsigned int ptcr = 0;
+		unsigned int pdcr = 0;
+		unsigned int pcr = 0;
+		unsigned int val;
+		int ret;
+		int i = 0;
+
+		ret = of_property_read_u32(child, "fsl,audmux-port", &port);
+		if (ret) {
+			dev_warn(&pdev->dev, "Failed to get fsl,audmux-port of child node \"%s\"\n",
+					child->full_name);
+			continue;
+		}
+		if (!of_property_read_bool(child, "fsl,port-config")) {
+			dev_warn(&pdev->dev, "child node \"%s\" does not have property fsl,port-config\n",
+					child->full_name);
+			continue;
+		}
+
+		for (i = 0; (ret = of_property_read_u32_index(child,
+					"fsl,port-config\n", i, &val)) == 0;
+				++i) {
+			if (audmux_type == IMX31_AUDMUX) {
+				if (i % 2)
+					pdcr |= val;
+				else
+					ptcr |= val;
+			} else {
+				pcr |= val;
+			}
+		}
+
+		if (ret != -ENODATA) {
+			dev_err(&pdev->dev, "Failed to read u32 at index %d of child %s\n",
+					i, child->full_name);
+			continue;
+		}
+
+		if (audmux_type == IMX31_AUDMUX) {
+			if (i % 2) {
+				dev_err(&pdev->dev, "One pdcr value is missing in child node %s\n",
+						child->full_name);
+				continue;
+			}
+			imx_audmux_v2_configure_port(port, ptcr, pdcr);
+		} else {
+			imx_audmux_v1_configure_port(port, pcr);
+		}
+	}
+
+	return 0;
+}
+
 static int imx_audmux_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -275,6 +335,8 @@ static int imx_audmux_probe(struct platform_device *pdev)
 	if (audmux_type == IMX31_AUDMUX)
 		audmux_debugfs_init();
 
+	imx_audmux_parse_dt_defaults(pdev, pdev->dev.of_node);
+
 	return 0;
 }
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 4/7] ASoC: fsl-ssi: Add support for imx-pcm-fiq
  2013-07-27 11:31 ` Markus Pargmann
@ 2013-07-27 11:31   ` Markus Pargmann
  -1 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Timur Tabi, Liam Girdwood, Grant Likely,
	Mark Brown, Sascha Hauer, Markus Pargmann, Shawn Guo

Add support for non-dma pcm for imx platforms with imx-pcm-fiq support.
Instead of imx-pcm-audio, in this case imx-pcm-fiq-audio device is added
and the SIER flags are set differently.

We need imx-pcm-fiq for some boards that use an incompatible codec.
imx-pcm-fiq handles those codecs differently and allows to operate with
them. DMA is not possible because some data sent by the codecs, e.g.
wm9712, is not in the datastream. Also some data is mixed up in the
fifos, so that we need to sort them out manually.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
---
 .../devicetree/bindings/sound/fsl,ssi.txt          |  4 ++
 sound/soc/fsl/fsl_ssi.c                            | 79 ++++++++++++++++++----
 2 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl,ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
index 5ff76c9..e45cbce 100644
--- a/Documentation/devicetree/bindings/sound/fsl,ssi.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
@@ -47,6 +47,10 @@ Optional properties:
 - codec-handle:     Phandle to a 'codec' node that defines an audio
                     codec connected to this SSI.  This node is typically
                     a child of an I2C or other control node.
+- fsl,fiq-stream-filter: Bool property. Disabled DMA and use FIQ instead to
+		    filter the codec stream. This is necessary for some boards
+		    where an incompatible codec is connected to this SSI, e.g.
+		    on pca100 and pcm043.
 
 Child 'codec' node required properties:
 - compatible:       Compatible list, contains the name of the codec
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 4d78df7..8b075ef 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -8,6 +8,26 @@
  * 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.
+ *
+ *
+ * Some notes why imx-pcm-fiq is used instead of DMA on some boards:
+ *
+ * The i.MX SSI core has some nasty limitations in AC97 mode. While most
+ * sane processor vendors have a FIFO per AC97 slot, the i.MX has only
+ * one FIFO which combines all valid receive slots. We cannot even select
+ * which slots we want to receive. The WM9712 with which this driver
+ * was developed with always sends GPIO status data in slot 12 which
+ * we receive in our (PCM-) data stream. The only chance we have is to
+ * manually skip this data in the FIQ handler. With sampling rates different
+ * from 48000Hz not every frame has valid receive data, so the ratio
+ * between pcm data and GPIO status data changes. Our FIQ handler is not
+ * able to handle this, hence this driver only works with 48000Hz sampling
+ * rate.
+ * Reading and writing AC97 registers is another challenge. The core
+ * provides us status bits when the read register is updated with *another*
+ * value. When we read the same register two times (and the register still
+ * contains the same value) these status bits are not set. We work
+ * around this by not polling these bits but only wait a fixed delay.
  */
 
 #include <linux/init.h>
@@ -121,11 +141,13 @@ struct fsl_ssi_private {
 
 	bool new_binding;
 	bool ssi_on_imx;
+	bool use_dma;
 	struct clk *clk;
 	struct snd_dmaengine_dai_dma_data dma_params_tx;
 	struct snd_dmaengine_dai_dma_data dma_params_rx;
 	struct imx_dma_data filter_data_tx;
 	struct imx_dma_data filter_data_rx;
+	struct imx_pcm_fiq_params fiq_params;
 
 	struct {
 		unsigned int rfrc;
@@ -355,7 +377,12 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
 		 */
 
 		/* Enable the interrupts and DMA requests */
-		write_ssi(SIER_FLAGS, &ssi->sier);
+		if (ssi_private->use_dma)
+			write_ssi(SIER_FLAGS, &ssi->sier);
+		else
+			write_ssi(CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN |
+					CCSR_SSI_SIER_RIE |
+					CCSR_SSI_SIER_RFF0_EN, &ssi->sier);
 
 		/*
 		 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
@@ -543,7 +570,7 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
 {
 	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai);
 
-	if (ssi_private->ssi_on_imx) {
+	if (ssi_private->ssi_on_imx && ssi_private->use_dma) {
 		dai->playback_dma_data = &ssi_private->dma_params_tx;
 		dai->capture_dma_data = &ssi_private->dma_params_rx;
 	}
@@ -683,6 +710,9 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 
 	strcpy(ssi_private->name, p);
 
+	ssi_private->use_dma = !of_property_read_bool(np,
+			"fsl,fiq-stream-filter");
+
 	/* Initialize this copy of the CPU DAI driver structure */
 	memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template,
 	       sizeof(fsl_ssi_dai_template));
@@ -707,12 +737,16 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 		return -ENXIO;
 	}
 
-	/* The 'name' should not have any slashes in it. */
-	ret = devm_request_irq(&pdev->dev, ssi_private->irq, fsl_ssi_isr, 0,
-			       ssi_private->name, ssi_private);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq);
-		goto error_irqmap;
+	if (ssi_private->use_dma) {
+		/* The 'name' should not have any slashes in it. */
+		ret = devm_request_irq(&pdev->dev, ssi_private->irq,
+					fsl_ssi_isr, 0, ssi_private->name,
+					ssi_private);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "could not claim irq %u\n",
+					ssi_private->irq);
+			goto error_irqmap;
+		}
 	}
 
 	/* Are the RX and the TX clocks locked? */
@@ -766,7 +800,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 		 */
 		ret = of_property_read_u32_array(pdev->dev.of_node,
 					"fsl,ssi-dma-events", dma_events, 2);
-		if (ret) {
+		if (ret && !ssi_private->use_dma) {
 			dev_err(&pdev->dev, "could not get dma events\n");
 			goto error_clk;
 		}
@@ -805,9 +839,30 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	}
 
 	if (ssi_private->ssi_on_imx) {
-		ret = imx_pcm_dma_init(pdev);
-		if (ret)
-			goto error_dev;
+		if (!ssi_private->use_dma) {
+
+			/*
+			 * Some boards use an incompatible codec. To get it
+			 * working, we are using imx-fiq-pcm-audio, that
+			 * can handle those codecs. DMA is not possible in this
+			 * situation.
+			 */
+
+			ssi_private->fiq_params.irq = ssi_private->irq;
+			ssi_private->fiq_params.base = ssi_private->ssi;
+			ssi_private->fiq_params.dma_params_rx =
+				&ssi_private->dma_params_rx;
+			ssi_private->fiq_params.dma_params_tx =
+				&ssi_private->dma_params_tx;
+
+			ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params);
+			if (ret)
+				goto error_dev;
+		} else {
+			ret = imx_pcm_dma_init(pdev);
+			if (ret)
+				goto error_dev;
+		}
 	}
 
 	/*
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 4/7] ASoC: fsl-ssi: Add support for imx-pcm-fiq
@ 2013-07-27 11:31   ` Markus Pargmann
  0 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for non-dma pcm for imx platforms with imx-pcm-fiq support.
Instead of imx-pcm-audio, in this case imx-pcm-fiq-audio device is added
and the SIER flags are set differently.

We need imx-pcm-fiq for some boards that use an incompatible codec.
imx-pcm-fiq handles those codecs differently and allows to operate with
them. DMA is not possible because some data sent by the codecs, e.g.
wm9712, is not in the datastream. Also some data is mixed up in the
fifos, so that we need to sort them out manually.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
---
 .../devicetree/bindings/sound/fsl,ssi.txt          |  4 ++
 sound/soc/fsl/fsl_ssi.c                            | 79 ++++++++++++++++++----
 2 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl,ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
index 5ff76c9..e45cbce 100644
--- a/Documentation/devicetree/bindings/sound/fsl,ssi.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
@@ -47,6 +47,10 @@ Optional properties:
 - codec-handle:     Phandle to a 'codec' node that defines an audio
                     codec connected to this SSI.  This node is typically
                     a child of an I2C or other control node.
+- fsl,fiq-stream-filter: Bool property. Disabled DMA and use FIQ instead to
+		    filter the codec stream. This is necessary for some boards
+		    where an incompatible codec is connected to this SSI, e.g.
+		    on pca100 and pcm043.
 
 Child 'codec' node required properties:
 - compatible:       Compatible list, contains the name of the codec
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 4d78df7..8b075ef 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -8,6 +8,26 @@
  * 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.
+ *
+ *
+ * Some notes why imx-pcm-fiq is used instead of DMA on some boards:
+ *
+ * The i.MX SSI core has some nasty limitations in AC97 mode. While most
+ * sane processor vendors have a FIFO per AC97 slot, the i.MX has only
+ * one FIFO which combines all valid receive slots. We cannot even select
+ * which slots we want to receive. The WM9712 with which this driver
+ * was developed with always sends GPIO status data in slot 12 which
+ * we receive in our (PCM-) data stream. The only chance we have is to
+ * manually skip this data in the FIQ handler. With sampling rates different
+ * from 48000Hz not every frame has valid receive data, so the ratio
+ * between pcm data and GPIO status data changes. Our FIQ handler is not
+ * able to handle this, hence this driver only works with 48000Hz sampling
+ * rate.
+ * Reading and writing AC97 registers is another challenge. The core
+ * provides us status bits when the read register is updated with *another*
+ * value. When we read the same register two times (and the register still
+ * contains the same value) these status bits are not set. We work
+ * around this by not polling these bits but only wait a fixed delay.
  */
 
 #include <linux/init.h>
@@ -121,11 +141,13 @@ struct fsl_ssi_private {
 
 	bool new_binding;
 	bool ssi_on_imx;
+	bool use_dma;
 	struct clk *clk;
 	struct snd_dmaengine_dai_dma_data dma_params_tx;
 	struct snd_dmaengine_dai_dma_data dma_params_rx;
 	struct imx_dma_data filter_data_tx;
 	struct imx_dma_data filter_data_rx;
+	struct imx_pcm_fiq_params fiq_params;
 
 	struct {
 		unsigned int rfrc;
@@ -355,7 +377,12 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
 		 */
 
 		/* Enable the interrupts and DMA requests */
-		write_ssi(SIER_FLAGS, &ssi->sier);
+		if (ssi_private->use_dma)
+			write_ssi(SIER_FLAGS, &ssi->sier);
+		else
+			write_ssi(CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN |
+					CCSR_SSI_SIER_RIE |
+					CCSR_SSI_SIER_RFF0_EN, &ssi->sier);
 
 		/*
 		 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
@@ -543,7 +570,7 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
 {
 	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai);
 
-	if (ssi_private->ssi_on_imx) {
+	if (ssi_private->ssi_on_imx && ssi_private->use_dma) {
 		dai->playback_dma_data = &ssi_private->dma_params_tx;
 		dai->capture_dma_data = &ssi_private->dma_params_rx;
 	}
@@ -683,6 +710,9 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 
 	strcpy(ssi_private->name, p);
 
+	ssi_private->use_dma = !of_property_read_bool(np,
+			"fsl,fiq-stream-filter");
+
 	/* Initialize this copy of the CPU DAI driver structure */
 	memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template,
 	       sizeof(fsl_ssi_dai_template));
@@ -707,12 +737,16 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 		return -ENXIO;
 	}
 
-	/* The 'name' should not have any slashes in it. */
-	ret = devm_request_irq(&pdev->dev, ssi_private->irq, fsl_ssi_isr, 0,
-			       ssi_private->name, ssi_private);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq);
-		goto error_irqmap;
+	if (ssi_private->use_dma) {
+		/* The 'name' should not have any slashes in it. */
+		ret = devm_request_irq(&pdev->dev, ssi_private->irq,
+					fsl_ssi_isr, 0, ssi_private->name,
+					ssi_private);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "could not claim irq %u\n",
+					ssi_private->irq);
+			goto error_irqmap;
+		}
 	}
 
 	/* Are the RX and the TX clocks locked? */
@@ -766,7 +800,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 		 */
 		ret = of_property_read_u32_array(pdev->dev.of_node,
 					"fsl,ssi-dma-events", dma_events, 2);
-		if (ret) {
+		if (ret && !ssi_private->use_dma) {
 			dev_err(&pdev->dev, "could not get dma events\n");
 			goto error_clk;
 		}
@@ -805,9 +839,30 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	}
 
 	if (ssi_private->ssi_on_imx) {
-		ret = imx_pcm_dma_init(pdev);
-		if (ret)
-			goto error_dev;
+		if (!ssi_private->use_dma) {
+
+			/*
+			 * Some boards use an incompatible codec. To get it
+			 * working, we are using imx-fiq-pcm-audio, that
+			 * can handle those codecs. DMA is not possible in this
+			 * situation.
+			 */
+
+			ssi_private->fiq_params.irq = ssi_private->irq;
+			ssi_private->fiq_params.base = ssi_private->ssi;
+			ssi_private->fiq_params.dma_params_rx =
+				&ssi_private->dma_params_rx;
+			ssi_private->fiq_params.dma_params_tx =
+				&ssi_private->dma_params_tx;
+
+			ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params);
+			if (ret)
+				goto error_dev;
+		} else {
+			ret = imx_pcm_dma_init(pdev);
+			if (ret)
+				goto error_dev;
+		}
 	}
 
 	/*
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 5/7] ASoC: fsl-ssi: Use generic DMA bindings if possible
  2013-07-27 11:31 ` Markus Pargmann
@ 2013-07-27 11:31   ` Markus Pargmann
  -1 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Timur Tabi, Liam Girdwood, Grant Likely,
	Mark Brown, Sascha Hauer, Markus Pargmann, Shawn Guo

There may be some platforms using fsl-ssi that do not have a DMA driver
with generic DMA bindings. So this patch adds support for the generic
DMA bindings, while still accepting the old "fsl,dma-events" property if
"dmas" is not found.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
---
 Documentation/devicetree/bindings/sound/fsl,ssi.txt |  4 ++++
 sound/soc/fsl/fsl_ssi.c                             | 20 ++++++++++++--------
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl,ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
index e45cbce..088a2c0 100644
--- a/Documentation/devicetree/bindings/sound/fsl,ssi.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
@@ -51,6 +51,10 @@ Optional properties:
 		    filter the codec stream. This is necessary for some boards
 		    where an incompatible codec is connected to this SSI, e.g.
 		    on pca100 and pcm043.
+- dmas:		    Generic dma devicetree binding as described in
+		    Documentation/devicetree/bindings/dma/dma.txt.
+- dma-names:	    Two dmas have to be defined, "tx" and "rx", if fsl,imx-fiq
+		    is not defined.
 
 Child 'codec' node required properties:
 - compatible:       Compatible list, contains the name of the codec
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 8b075ef..0c072ff 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -794,15 +794,19 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 			&ssi_private->filter_data_tx;
 		ssi_private->dma_params_rx.filter_data =
 			&ssi_private->filter_data_rx;
-		/*
-		 * TODO: This is a temporary solution and should be changed
-		 * to use generic DMA binding later when the helplers get in.
-		 */
-		ret = of_property_read_u32_array(pdev->dev.of_node,
+		if (!of_property_read_bool(pdev->dev.of_node, "dmas") &&
+				ssi_private->use_dma) {
+			/*
+			 * FIXME: This is a temporary solution until all
+			 * necessary dma drivers support the generic dma
+			 * bindings.
+			 */
+			ret = of_property_read_u32_array(pdev->dev.of_node,
 					"fsl,ssi-dma-events", dma_events, 2);
-		if (ret && !ssi_private->use_dma) {
-			dev_err(&pdev->dev, "could not get dma events\n");
-			goto error_clk;
+			if (ret && ssi_private->use_dma) {
+				dev_err(&pdev->dev, "could not get dma events but fsl-ssi is configured to use DMA\n");
+				goto error_clk;
+			}
 		}
 
 		shared = of_device_is_compatible(of_get_parent(np),
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 5/7] ASoC: fsl-ssi: Use generic DMA bindings if possible
@ 2013-07-27 11:31   ` Markus Pargmann
  0 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

There may be some platforms using fsl-ssi that do not have a DMA driver
with generic DMA bindings. So this patch adds support for the generic
DMA bindings, while still accepting the old "fsl,dma-events" property if
"dmas" is not found.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
---
 Documentation/devicetree/bindings/sound/fsl,ssi.txt |  4 ++++
 sound/soc/fsl/fsl_ssi.c                             | 20 ++++++++++++--------
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl,ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
index e45cbce..088a2c0 100644
--- a/Documentation/devicetree/bindings/sound/fsl,ssi.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
@@ -51,6 +51,10 @@ Optional properties:
 		    filter the codec stream. This is necessary for some boards
 		    where an incompatible codec is connected to this SSI, e.g.
 		    on pca100 and pcm043.
+- dmas:		    Generic dma devicetree binding as described in
+		    Documentation/devicetree/bindings/dma/dma.txt.
+- dma-names:	    Two dmas have to be defined, "tx" and "rx", if fsl,imx-fiq
+		    is not defined.
 
 Child 'codec' node required properties:
 - compatible:       Compatible list, contains the name of the codec
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 8b075ef..0c072ff 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -794,15 +794,19 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 			&ssi_private->filter_data_tx;
 		ssi_private->dma_params_rx.filter_data =
 			&ssi_private->filter_data_rx;
-		/*
-		 * TODO: This is a temporary solution and should be changed
-		 * to use generic DMA binding later when the helplers get in.
-		 */
-		ret = of_property_read_u32_array(pdev->dev.of_node,
+		if (!of_property_read_bool(pdev->dev.of_node, "dmas") &&
+				ssi_private->use_dma) {
+			/*
+			 * FIXME: This is a temporary solution until all
+			 * necessary dma drivers support the generic dma
+			 * bindings.
+			 */
+			ret = of_property_read_u32_array(pdev->dev.of_node,
 					"fsl,ssi-dma-events", dma_events, 2);
-		if (ret && !ssi_private->use_dma) {
-			dev_err(&pdev->dev, "could not get dma events\n");
-			goto error_clk;
+			if (ret && ssi_private->use_dma) {
+				dev_err(&pdev->dev, "could not get dma events but fsl-ssi is configured to use DMA\n");
+				goto error_clk;
+			}
 		}
 
 		shared = of_device_is_compatible(of_get_parent(np),
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 6/7] ASoC: fsl-ssi: ac97-slave support
  2013-07-27 11:31 ` Markus Pargmann
@ 2013-07-27 11:31   ` Markus Pargmann
  -1 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Timur Tabi, Liam Girdwood, Grant Likely,
	Mark Brown, Sascha Hauer, Markus Pargmann, Shawn Guo

This patch adds ac97-slave support.

For ac97, the registers have to be setup earlier than for other ssi
modes because there is some communication with the external device
before streaming. So this patch introduces a fsl_ssi_setup function to
setup the registers for different ssi operation modes seperately.

This patch was tested with imx27-pca100.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
---
 .../devicetree/bindings/sound/fsl,ssi.txt          |   4 +
 sound/soc/fsl/fsl_ssi.c                            | 346 ++++++++++++++++-----
 2 files changed, 280 insertions(+), 70 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl,ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
index 088a2c0..4303b6a 100644
--- a/Documentation/devicetree/bindings/sound/fsl,ssi.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
@@ -43,6 +43,10 @@ Required properties:
                     together.  This would still allow different sample sizes,
                     but not different sample rates.
 
+Required are also ac97 link bindings if ac97 is used. See
+Documentation/devicetree/bindings/sound/soc-ac97link.txt for the necessary
+bindings.
+
 Optional properties:
 - codec-handle:     Phandle to a 'codec' node that defines an audio
                     codec connected to this SSI.  This node is typically
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 0c072ff..827af75 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -141,6 +141,7 @@ struct fsl_ssi_private {
 
 	bool new_binding;
 	bool ssi_on_imx;
+	bool imx_ac97;
 	bool use_dma;
 	struct clk *clk;
 	struct snd_dmaengine_dai_dma_data dma_params_tx;
@@ -320,6 +321,124 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 	return ret;
 }
 
+static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
+{
+	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+	u8 i2s_mode;
+	u8 wm;
+	int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
+
+	if (ssi_private->imx_ac97)
+		i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET;
+	else
+		i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE;
+
+	/*
+	 * Section 16.5 of the MPC8610 reference manual says that the SSI needs
+	 * to be disabled before updating the registers we set here.
+	 */
+	write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
+
+	/*
+	 * Program the SSI into I2S Slave Non-Network Synchronous mode. Also
+	 * enable the transmit and receive FIFO.
+	 *
+	 * FIXME: Little-endian samples require a different shift dir
+	 */
+	write_ssi_mask(&ssi->scr,
+		CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
+		CCSR_SSI_SCR_TFR_CLK_DIS |
+		i2s_mode |
+		(synchronous ? CCSR_SSI_SCR_SYN : 0));
+
+	write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
+		 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
+		 CCSR_SSI_STCR_TSCKP, &ssi->stcr);
+
+	write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
+		 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
+		 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
+	/*
+	 * The DC and PM bits are only used if the SSI is the clock master.
+	 */
+
+	/*
+	 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't
+	 * use FIFO 1. We program the transmit water to signal a DMA transfer
+	 * if there are only two (or fewer) elements left in the FIFO. Two
+	 * elements equals one frame (left channel, right channel). This value,
+	 * however, depends on the depth of the transmit buffer.
+	 *
+	 * We set the watermark on the same level as the DMA burstsize.  For
+	 * fiq it is probably better to use the biggest possible watermark
+	 * size.
+	 */
+	if (ssi_private->use_dma)
+		wm = ssi_private->fifo_depth - 2;
+	else
+		wm = ssi_private->fifo_depth;
+
+	write_ssi(CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) |
+		CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm),
+		&ssi->sfcsr);
+
+	/*
+	 * For non-ac97 setups, we keep the SSI disabled because if we enable
+	 * it, then the DMA controller will start. It's not supposed to start
+	 * until the SCR.TE (or SCR.RE) bit is set, but it does anyway. The DMA
+	 * controller will transfer one "BWC" of data (i.e. the amount of data
+	 * that the MR.BWC bits are set to). The reason this is bad is because
+	 * at this point, the PCM driver has not finished initializing the DMA
+	 * controller.
+	 */
+
+
+	/*
+	 * For ac97 interrupts are enabled with the startup of the substream
+	 * because it is also running without an active substream. Normally SSI
+	 * is only enabled when there is a substream.
+	 */
+	if (!ssi_private->imx_ac97) {
+		/* Enable the interrupts and DMA requests */
+		if (ssi_private->use_dma)
+			write_ssi(SIER_FLAGS, &ssi->sier);
+		else
+			write_ssi(CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN |
+					CCSR_SSI_SIER_RIE |
+					CCSR_SSI_SIER_RFF0_EN, &ssi->sier);
+	} else {
+		/*
+		 * Setup the clock control register
+		 */
+		write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
+				&ssi->stccr);
+		write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
+				&ssi->srccr);
+
+		/*
+		 * Enable AC97 mode and startup the SSI
+		 */
+		write_ssi(CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV,
+				&ssi->sacnt);
+		write_ssi(0xff, &ssi->saccdis);
+		write_ssi(0x300, &ssi->saccen);
+
+		/*
+		 * Enable SSI
+		 */
+		write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN);
+		write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor);
+
+		/*
+		 * Enable Transmit and Receive
+		 */
+		write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE);
+	}
+
+	return 0;
+}
+
+
 /**
  * fsl_ssi_startup: create a new substream
  *
@@ -341,75 +460,14 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
 	 * and initialize the SSI registers.
 	 */
 	if (!ssi_private->first_stream) {
-		struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
-
 		ssi_private->first_stream = substream;
 
 		/*
-		 * Section 16.5 of the MPC8610 reference manual says that the
-		 * SSI needs to be disabled before updating the registers we set
-		 * here.
-		 */
-		write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
-
-		/*
-		 * Program the SSI into I2S Slave Non-Network Synchronous mode.
-		 * Also enable the transmit and receive FIFO.
-		 *
-		 * FIXME: Little-endian samples require a different shift dir
-		 */
-		write_ssi_mask(&ssi->scr,
-			CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
-			CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
-			| (synchronous ? CCSR_SSI_SCR_SYN : 0));
-
-		write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
-			 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
-			 CCSR_SSI_STCR_TSCKP, &ssi->stcr);
-
-		write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
-			 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
-			 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
-
-		/*
-		 * The DC and PM bits are only used if the SSI is the clock
-		 * master.
-		 */
-
-		/* Enable the interrupts and DMA requests */
-		if (ssi_private->use_dma)
-			write_ssi(SIER_FLAGS, &ssi->sier);
-		else
-			write_ssi(CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN |
-					CCSR_SSI_SIER_RIE |
-					CCSR_SSI_SIER_RFF0_EN, &ssi->sier);
-
-		/*
-		 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
-		 * don't use FIFO 1.  We program the transmit water to signal a
-		 * DMA transfer if there are only two (or fewer) elements left
-		 * in the FIFO.  Two elements equals one frame (left channel,
-		 * right channel).  This value, however, depends on the depth of
-		 * the transmit buffer.
-		 *
-		 * We program the receive FIFO to notify us if at least two
-		 * elements (one frame) have been written to the FIFO.  We could
-		 * make this value larger (and maybe we should), but this way
-		 * data will be written to memory as soon as it's available.
-		 */
-		write_ssi(CCSR_SSI_SFCSR_TFWM0(ssi_private->fifo_depth - 2) |
-			CCSR_SSI_SFCSR_RFWM0(ssi_private->fifo_depth - 2),
-			&ssi->sfcsr);
-
-		/*
-		 * We keep the SSI disabled because if we enable it, then the
-		 * DMA controller will start.  It's not supposed to start until
-		 * the SCR.TE (or SCR.RE) bit is set, but it does anyway.  The
-		 * DMA controller will transfer one "BWC" of data (i.e. the
-		 * amount of data that the MR.BWC bits are set to).  The reason
-		 * this is bad is because at this point, the PCM driver has not
-		 * finished initializing the DMA controller.
+		 * fsl_ssi_setup was already called by ac97_init earlier if
+		 * the driver is in ac97 mode.
 		 */
+		if (!ssi_private->imx_ac97)
+			fsl_ssi_setup(ssi_private);
 	} else {
 		if (synchronous) {
 			struct snd_pcm_runtime *first_runtime =
@@ -538,7 +596,8 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
 		else
 			write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0);
 
-		if ((read_ssi(&ssi->scr) & (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0)
+		if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) &
+					(CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0)
 			write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
 		break;
 
@@ -608,6 +667,133 @@ static const struct snd_soc_component_driver fsl_ssi_component = {
 	.name		= "fsl-ssi",
 };
 
+/**
+ * fsl_ssi_ac97_trigger: start and stop the AC97 receive/transmit.
+ *
+ * This function is called by ALSA to start, stop, pause, and resume the
+ * transfer of data.
+ */
+static int fsl_ssi_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
+			   struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(
+			rtd->cpu_dai);
+	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_TIE |
+					CCSR_SSI_SIER_TFE0_EN);
+		else
+			write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_RIE |
+					CCSR_SSI_SIER_RFF0_EN);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_TIE |
+					CCSR_SSI_SIER_TFE0_EN, 0);
+		else
+			write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_RIE |
+					CCSR_SSI_SIER_RFF0_EN, 0);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor);
+	else
+		write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor);
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops fsl_ssi_ac97_dai_ops = {
+	.startup	= fsl_ssi_startup,
+	.shutdown	= fsl_ssi_shutdown,
+	.trigger	= fsl_ssi_ac97_trigger,
+};
+
+static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
+	.ac97_control = 1,
+	.playback = {
+		.stream_name = "AC97 Playback",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+	.capture = {
+		.stream_name = "AC97 Capture",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+	.ops = &fsl_ssi_ac97_dai_ops,
+};
+
+
+static struct fsl_ssi_private *fsl_ac97_data;
+
+static void fsl_ssi_ac97_init(void)
+{
+	fsl_ssi_setup(fsl_ac97_data);
+}
+
+void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
+		unsigned short val)
+{
+	struct ccsr_ssi *ssi = fsl_ac97_data->ssi;
+	unsigned int lreg;
+	unsigned int lval;
+
+	if (reg > 0x7f)
+		return;
+
+
+	lreg = reg <<  12;
+	write_ssi(lreg, &ssi->sacadd);
+
+	lval = val << 4;
+	write_ssi(lval , &ssi->sacdat);
+
+	write_ssi_mask(&ssi->sacnt, CCSR_SSI_SACNT_RDWR_MASK,
+			CCSR_SSI_SACNT_WR);
+	udelay(100);
+}
+
+unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
+		unsigned short reg)
+{
+	struct ccsr_ssi *ssi = fsl_ac97_data->ssi;
+
+	unsigned short val = -1;
+	unsigned int lreg;
+
+	lreg = (reg & 0x7f) <<  12;
+	write_ssi(lreg, &ssi->sacadd);
+	write_ssi_mask(&ssi->sacnt, CCSR_SSI_SACNT_RDWR_MASK,
+			CCSR_SSI_SACNT_RD);
+
+	udelay(100);
+
+	val = (read_ssi(&ssi->sacdat) >> 4) & 0xffff;
+
+	return val;
+}
+
+static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
+	.read		= fsl_ssi_ac97_read,
+	.write		= fsl_ssi_ac97_write,
+};
+
 /* Show the statistics of a flag only if its interrupt is enabled.  The
  * compiler will optimze this code to a no-op if the interrupt is not
  * enabled.
@@ -684,6 +870,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	struct resource res;
 	char name[64];
 	bool shared;
+	bool ac97 = false;
 
 	/* SSIs that are not connected on the board should have a
 	 *      status = "disabled"
@@ -694,7 +881,13 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 
 	/* We only support the SSI in "I2S Slave" mode */
 	sprop = of_get_property(np, "fsl,mode", NULL);
-	if (!sprop || strcmp(sprop, "i2s-slave")) {
+	if (!sprop) {
+		dev_err(&pdev->dev, "fsl,mode property is necessary\n");
+		return -EINVAL;
+	}
+	if (!strcmp(sprop, "ac97-slave")) {
+		ac97 = true;
+	} else if (strcmp(sprop, "i2s-slave")) {
 		dev_notice(&pdev->dev, "mode %s is unsupported\n", sprop);
 		return -ENODEV;
 	}
@@ -713,9 +906,19 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	ssi_private->use_dma = !of_property_read_bool(np,
 			"fsl,fiq-stream-filter");
 
-	/* Initialize this copy of the CPU DAI driver structure */
-	memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template,
-	       sizeof(fsl_ssi_dai_template));
+	if (ac97) {
+		memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai,
+				sizeof(fsl_ssi_ac97_dai));
+
+		fsl_ac97_data = ssi_private;
+		ssi_private->imx_ac97 = true;
+
+		snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev);
+	} else {
+		/* Initialize this copy of the CPU DAI driver structure */
+		memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template,
+		       sizeof(fsl_ssi_dai_template));
+	}
 	ssi_private->cpu_dai_drv.name = ssi_private->name;
 
 	/* Get the addresses and IRQ */
@@ -901,6 +1104,9 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	}
 
 done:
+	if (ssi_private->imx_ac97)
+		fsl_ssi_ac97_init();
+
 	return 0;
 
 error_dai:
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 6/7] ASoC: fsl-ssi: ac97-slave support
@ 2013-07-27 11:31   ` Markus Pargmann
  0 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds ac97-slave support.

For ac97, the registers have to be setup earlier than for other ssi
modes because there is some communication with the external device
before streaming. So this patch introduces a fsl_ssi_setup function to
setup the registers for different ssi operation modes seperately.

This patch was tested with imx27-pca100.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
---
 .../devicetree/bindings/sound/fsl,ssi.txt          |   4 +
 sound/soc/fsl/fsl_ssi.c                            | 346 ++++++++++++++++-----
 2 files changed, 280 insertions(+), 70 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl,ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
index 088a2c0..4303b6a 100644
--- a/Documentation/devicetree/bindings/sound/fsl,ssi.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
@@ -43,6 +43,10 @@ Required properties:
                     together.  This would still allow different sample sizes,
                     but not different sample rates.
 
+Required are also ac97 link bindings if ac97 is used. See
+Documentation/devicetree/bindings/sound/soc-ac97link.txt for the necessary
+bindings.
+
 Optional properties:
 - codec-handle:     Phandle to a 'codec' node that defines an audio
                     codec connected to this SSI.  This node is typically
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 0c072ff..827af75 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -141,6 +141,7 @@ struct fsl_ssi_private {
 
 	bool new_binding;
 	bool ssi_on_imx;
+	bool imx_ac97;
 	bool use_dma;
 	struct clk *clk;
 	struct snd_dmaengine_dai_dma_data dma_params_tx;
@@ -320,6 +321,124 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 	return ret;
 }
 
+static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
+{
+	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+	u8 i2s_mode;
+	u8 wm;
+	int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
+
+	if (ssi_private->imx_ac97)
+		i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET;
+	else
+		i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE;
+
+	/*
+	 * Section 16.5 of the MPC8610 reference manual says that the SSI needs
+	 * to be disabled before updating the registers we set here.
+	 */
+	write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
+
+	/*
+	 * Program the SSI into I2S Slave Non-Network Synchronous mode. Also
+	 * enable the transmit and receive FIFO.
+	 *
+	 * FIXME: Little-endian samples require a different shift dir
+	 */
+	write_ssi_mask(&ssi->scr,
+		CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
+		CCSR_SSI_SCR_TFR_CLK_DIS |
+		i2s_mode |
+		(synchronous ? CCSR_SSI_SCR_SYN : 0));
+
+	write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
+		 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
+		 CCSR_SSI_STCR_TSCKP, &ssi->stcr);
+
+	write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
+		 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
+		 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
+	/*
+	 * The DC and PM bits are only used if the SSI is the clock master.
+	 */
+
+	/*
+	 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't
+	 * use FIFO 1. We program the transmit water to signal a DMA transfer
+	 * if there are only two (or fewer) elements left in the FIFO. Two
+	 * elements equals one frame (left channel, right channel). This value,
+	 * however, depends on the depth of the transmit buffer.
+	 *
+	 * We set the watermark on the same level as the DMA burstsize.  For
+	 * fiq it is probably better to use the biggest possible watermark
+	 * size.
+	 */
+	if (ssi_private->use_dma)
+		wm = ssi_private->fifo_depth - 2;
+	else
+		wm = ssi_private->fifo_depth;
+
+	write_ssi(CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) |
+		CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm),
+		&ssi->sfcsr);
+
+	/*
+	 * For non-ac97 setups, we keep the SSI disabled because if we enable
+	 * it, then the DMA controller will start. It's not supposed to start
+	 * until the SCR.TE (or SCR.RE) bit is set, but it does anyway. The DMA
+	 * controller will transfer one "BWC" of data (i.e. the amount of data
+	 * that the MR.BWC bits are set to). The reason this is bad is because
+	 * at this point, the PCM driver has not finished initializing the DMA
+	 * controller.
+	 */
+
+
+	/*
+	 * For ac97 interrupts are enabled with the startup of the substream
+	 * because it is also running without an active substream. Normally SSI
+	 * is only enabled when there is a substream.
+	 */
+	if (!ssi_private->imx_ac97) {
+		/* Enable the interrupts and DMA requests */
+		if (ssi_private->use_dma)
+			write_ssi(SIER_FLAGS, &ssi->sier);
+		else
+			write_ssi(CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN |
+					CCSR_SSI_SIER_RIE |
+					CCSR_SSI_SIER_RFF0_EN, &ssi->sier);
+	} else {
+		/*
+		 * Setup the clock control register
+		 */
+		write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
+				&ssi->stccr);
+		write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
+				&ssi->srccr);
+
+		/*
+		 * Enable AC97 mode and startup the SSI
+		 */
+		write_ssi(CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV,
+				&ssi->sacnt);
+		write_ssi(0xff, &ssi->saccdis);
+		write_ssi(0x300, &ssi->saccen);
+
+		/*
+		 * Enable SSI
+		 */
+		write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN);
+		write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor);
+
+		/*
+		 * Enable Transmit and Receive
+		 */
+		write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE);
+	}
+
+	return 0;
+}
+
+
 /**
  * fsl_ssi_startup: create a new substream
  *
@@ -341,75 +460,14 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
 	 * and initialize the SSI registers.
 	 */
 	if (!ssi_private->first_stream) {
-		struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
-
 		ssi_private->first_stream = substream;
 
 		/*
-		 * Section 16.5 of the MPC8610 reference manual says that the
-		 * SSI needs to be disabled before updating the registers we set
-		 * here.
-		 */
-		write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
-
-		/*
-		 * Program the SSI into I2S Slave Non-Network Synchronous mode.
-		 * Also enable the transmit and receive FIFO.
-		 *
-		 * FIXME: Little-endian samples require a different shift dir
-		 */
-		write_ssi_mask(&ssi->scr,
-			CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
-			CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
-			| (synchronous ? CCSR_SSI_SCR_SYN : 0));
-
-		write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
-			 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
-			 CCSR_SSI_STCR_TSCKP, &ssi->stcr);
-
-		write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
-			 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
-			 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
-
-		/*
-		 * The DC and PM bits are only used if the SSI is the clock
-		 * master.
-		 */
-
-		/* Enable the interrupts and DMA requests */
-		if (ssi_private->use_dma)
-			write_ssi(SIER_FLAGS, &ssi->sier);
-		else
-			write_ssi(CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN |
-					CCSR_SSI_SIER_RIE |
-					CCSR_SSI_SIER_RFF0_EN, &ssi->sier);
-
-		/*
-		 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
-		 * don't use FIFO 1.  We program the transmit water to signal a
-		 * DMA transfer if there are only two (or fewer) elements left
-		 * in the FIFO.  Two elements equals one frame (left channel,
-		 * right channel).  This value, however, depends on the depth of
-		 * the transmit buffer.
-		 *
-		 * We program the receive FIFO to notify us if at least two
-		 * elements (one frame) have been written to the FIFO.  We could
-		 * make this value larger (and maybe we should), but this way
-		 * data will be written to memory as soon as it's available.
-		 */
-		write_ssi(CCSR_SSI_SFCSR_TFWM0(ssi_private->fifo_depth - 2) |
-			CCSR_SSI_SFCSR_RFWM0(ssi_private->fifo_depth - 2),
-			&ssi->sfcsr);
-
-		/*
-		 * We keep the SSI disabled because if we enable it, then the
-		 * DMA controller will start.  It's not supposed to start until
-		 * the SCR.TE (or SCR.RE) bit is set, but it does anyway.  The
-		 * DMA controller will transfer one "BWC" of data (i.e. the
-		 * amount of data that the MR.BWC bits are set to).  The reason
-		 * this is bad is because at this point, the PCM driver has not
-		 * finished initializing the DMA controller.
+		 * fsl_ssi_setup was already called by ac97_init earlier if
+		 * the driver is in ac97 mode.
 		 */
+		if (!ssi_private->imx_ac97)
+			fsl_ssi_setup(ssi_private);
 	} else {
 		if (synchronous) {
 			struct snd_pcm_runtime *first_runtime =
@@ -538,7 +596,8 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
 		else
 			write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0);
 
-		if ((read_ssi(&ssi->scr) & (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0)
+		if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) &
+					(CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0)
 			write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
 		break;
 
@@ -608,6 +667,133 @@ static const struct snd_soc_component_driver fsl_ssi_component = {
 	.name		= "fsl-ssi",
 };
 
+/**
+ * fsl_ssi_ac97_trigger: start and stop the AC97 receive/transmit.
+ *
+ * This function is called by ALSA to start, stop, pause, and resume the
+ * transfer of data.
+ */
+static int fsl_ssi_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
+			   struct snd_soc_dai *dai)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(
+			rtd->cpu_dai);
+	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_TIE |
+					CCSR_SSI_SIER_TFE0_EN);
+		else
+			write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_RIE |
+					CCSR_SSI_SIER_RFF0_EN);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_TIE |
+					CCSR_SSI_SIER_TFE0_EN, 0);
+		else
+			write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_RIE |
+					CCSR_SSI_SIER_RFF0_EN, 0);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor);
+	else
+		write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor);
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops fsl_ssi_ac97_dai_ops = {
+	.startup	= fsl_ssi_startup,
+	.shutdown	= fsl_ssi_shutdown,
+	.trigger	= fsl_ssi_ac97_trigger,
+};
+
+static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
+	.ac97_control = 1,
+	.playback = {
+		.stream_name = "AC97 Playback",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+	.capture = {
+		.stream_name = "AC97 Capture",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+	.ops = &fsl_ssi_ac97_dai_ops,
+};
+
+
+static struct fsl_ssi_private *fsl_ac97_data;
+
+static void fsl_ssi_ac97_init(void)
+{
+	fsl_ssi_setup(fsl_ac97_data);
+}
+
+void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
+		unsigned short val)
+{
+	struct ccsr_ssi *ssi = fsl_ac97_data->ssi;
+	unsigned int lreg;
+	unsigned int lval;
+
+	if (reg > 0x7f)
+		return;
+
+
+	lreg = reg <<  12;
+	write_ssi(lreg, &ssi->sacadd);
+
+	lval = val << 4;
+	write_ssi(lval , &ssi->sacdat);
+
+	write_ssi_mask(&ssi->sacnt, CCSR_SSI_SACNT_RDWR_MASK,
+			CCSR_SSI_SACNT_WR);
+	udelay(100);
+}
+
+unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
+		unsigned short reg)
+{
+	struct ccsr_ssi *ssi = fsl_ac97_data->ssi;
+
+	unsigned short val = -1;
+	unsigned int lreg;
+
+	lreg = (reg & 0x7f) <<  12;
+	write_ssi(lreg, &ssi->sacadd);
+	write_ssi_mask(&ssi->sacnt, CCSR_SSI_SACNT_RDWR_MASK,
+			CCSR_SSI_SACNT_RD);
+
+	udelay(100);
+
+	val = (read_ssi(&ssi->sacdat) >> 4) & 0xffff;
+
+	return val;
+}
+
+static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
+	.read		= fsl_ssi_ac97_read,
+	.write		= fsl_ssi_ac97_write,
+};
+
 /* Show the statistics of a flag only if its interrupt is enabled.  The
  * compiler will optimze this code to a no-op if the interrupt is not
  * enabled.
@@ -684,6 +870,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	struct resource res;
 	char name[64];
 	bool shared;
+	bool ac97 = false;
 
 	/* SSIs that are not connected on the board should have a
 	 *      status = "disabled"
@@ -694,7 +881,13 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 
 	/* We only support the SSI in "I2S Slave" mode */
 	sprop = of_get_property(np, "fsl,mode", NULL);
-	if (!sprop || strcmp(sprop, "i2s-slave")) {
+	if (!sprop) {
+		dev_err(&pdev->dev, "fsl,mode property is necessary\n");
+		return -EINVAL;
+	}
+	if (!strcmp(sprop, "ac97-slave")) {
+		ac97 = true;
+	} else if (strcmp(sprop, "i2s-slave")) {
 		dev_notice(&pdev->dev, "mode %s is unsupported\n", sprop);
 		return -ENODEV;
 	}
@@ -713,9 +906,19 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	ssi_private->use_dma = !of_property_read_bool(np,
 			"fsl,fiq-stream-filter");
 
-	/* Initialize this copy of the CPU DAI driver structure */
-	memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template,
-	       sizeof(fsl_ssi_dai_template));
+	if (ac97) {
+		memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai,
+				sizeof(fsl_ssi_ac97_dai));
+
+		fsl_ac97_data = ssi_private;
+		ssi_private->imx_ac97 = true;
+
+		snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev);
+	} else {
+		/* Initialize this copy of the CPU DAI driver structure */
+		memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template,
+		       sizeof(fsl_ssi_dai_template));
+	}
 	ssi_private->cpu_dai_drv.name = ssi_private->name;
 
 	/* Get the addresses and IRQ */
@@ -901,6 +1104,9 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 	}
 
 done:
+	if (ssi_private->imx_ac97)
+		fsl_ssi_ac97_init();
+
 	return 0;
 
 error_dai:
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 7/7] ASoC: Add phycore-ac97-dt driver
  2013-07-27 11:31 ` Markus Pargmann
@ 2013-07-27 11:31   ` Markus Pargmann
  -1 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Timur Tabi, Liam Girdwood, Grant Likely,
	Mark Brown, Sascha Hauer, Markus Pargmann, Shawn Guo

Add devicetree support for phycore-ac97 driver in a seperated driver for
DT loading. The seperation reduces the confusion with the old style
initialization of this driver via late_initcall. Also this driver is
using fsl-ssi instead of imx-ssi.

platform_of_node and cpu_of_node are set according to the fsl,audmux
phandle.

This patch adds handling of ac97 reset functions according to fsl ac97
support. They are setup from here to avoid board specific code in the
generic fsl-ssi driver.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
---
 .../bindings/sound/phytec,phycore-ac97.txt         |  16 +++
 sound/soc/fsl/Kconfig                              |  15 ++-
 sound/soc/fsl/Makefile                             |   2 +
 sound/soc/fsl/phycore-ac97-dt.c                    | 124 +++++++++++++++++++++
 sound/soc/fsl/phycore-ac97.c                       |  13 +--
 5 files changed, 156 insertions(+), 14 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt
 create mode 100644 sound/soc/fsl/phycore-ac97-dt.c

diff --git a/Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt b/Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt
new file mode 100644
index 0000000..b3ce9cb
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt
@@ -0,0 +1,16 @@
+Phytec phycore AC97
+
+Required properties:
+- compatible: "phytec,phycore-ac97"
+- phytec,ssi: A phandle to the ssi device that is connected to ac97.
+- phytec,audmux: A phandle to the audmux device.
+- audio-codec: phandle to the codec device node.
+
+Example:
+
+sound {
+	compatible = "phytec,phycore-ac97";
+	phytec,ssi = <&ssi1>;
+	phytec,audmux = <&audmux>;
+	audio-codec = <&codec>;
+};
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 3a79d01..5f992b3 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -142,8 +142,8 @@ config SND_SOC_MX27VIS_AIC32X4
 	  board with TLV320AIC32X4 codec.
 
 config SND_SOC_PHYCORE_AC97
-	tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
-	depends on MACH_PCM043 || MACH_PCA100
+	tristate "SoC Audio support for Phytec phyCORE boards"
+	depends on MACH_PCM043
 	select SND_SOC_AC97_BUS
 	select SND_SOC_WM9712
 	select SND_SOC_IMX_PCM_FIQ
@@ -153,6 +153,17 @@ config SND_SOC_PHYCORE_AC97
 	  Say Y if you want to add support for SoC audio on Phytec phyCORE
 	  and phyCARD boards in AC97 mode
 
+config SND_SOC_PHYCORE_AC97_DT
+	tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards (devicetree only)"
+	select SND_SOC_AC97_BUS
+	select SND_SOC_WM9712
+	select SND_SOC_IMX_PCM_FIQ
+	select SND_SOC_IMX_AUDMUX
+	select SND_SOC_FSL_SSI
+	help
+	  Say Y if you want to add support for SoC audio on Phytec phyCORE
+	  and phyCARD boards in AC97 mode when using devicetree.
+
 config SND_SOC_EUKREA_TLV320
 	tristate "Eukrea TLV320"
 	depends on MACH_EUKREA_MBIMX27_BASEBOARD \
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index d4b4aa8..31bdd69 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o
 # i.MX Machine Support
 snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
 snd-soc-phycore-ac97-objs := phycore-ac97.o
+snd-soc-phycore-ac97-dt-objs := phycore-ac97-dt.o
 snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
 snd-soc-wm1133-ev1-objs := wm1133-ev1.o
 snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
@@ -47,6 +48,7 @@ snd-soc-imx-mc13783-objs := imx-mc13783.o
 
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
 obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
+obj-$(CONFIG_SND_SOC_PHYCORE_AC97_DT) += snd-soc-phycore-ac97-dt.o
 obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
 obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
 obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
diff --git a/sound/soc/fsl/phycore-ac97-dt.c b/sound/soc/fsl/phycore-ac97-dt.c
new file mode 100644
index 0000000..46b3423
--- /dev/null
+++ b/sound/soc/fsl/phycore-ac97-dt.c
@@ -0,0 +1,124 @@
+/*
+ * phycore-ac97-dt.c  --  SoC audio for imx_phycore in AC97 mode
+ *
+ * Copyright 2013 Markus Pargmann, Pengutronix <mpa@pengutronix.de>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/of.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+#include "imx-audmux.h"
+#include "fsl_ssi.h"
+
+#define DRV_NAME "phycore-ac97-dt-driver"
+
+struct phycore_ac97_data {
+	struct snd_soc_card card;
+	struct device_node *cpu_np;
+	struct device_node *codec_np;
+};
+
+static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
+	{
+		.name		= "HiFi",
+		.stream_name	= "HiFi",
+		.codec_dai_name	= "wm9712-hifi",
+	},
+};
+
+static struct snd_soc_card imx_phycore = {
+	.name		= "PhyCORE-ac97-audio",
+	.owner		= THIS_MODULE,
+	.dai_link	= imx_phycore_dai_ac97,
+	.num_links	= ARRAY_SIZE(imx_phycore_dai_ac97),
+};
+
+static const struct of_device_id imx_phycore_ac97_of_dev_id[] = {
+	{
+		.compatible = "phytec,phycore-ac97",
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, imx_phycore_ac97_of_dev_id);
+
+static int imx_phycore_ac97_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct phycore_ac97_data *priv;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+
+	if (!priv)
+		return -ENOMEM;
+
+	imx_phycore.dev = &pdev->dev;
+
+	priv->cpu_np = of_parse_phandle(pdev->dev.of_node, "phytec,ssi", 0);
+	if (!priv->cpu_np) {
+		dev_err(&pdev->dev, "No valid ssi phandle found\n");
+		return -EINVAL;
+	}
+
+	priv->codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
+	if (!priv->codec_np) {
+		dev_err(&pdev->dev, "No valid codec phandle found\n");
+		of_node_put(priv->cpu_np);
+		return -EINVAL;
+	}
+
+	imx_phycore_dai_ac97[0].cpu_of_node = priv->cpu_np;
+	imx_phycore_dai_ac97[0].platform_of_node = priv->cpu_np;
+	imx_phycore_dai_ac97[0].codec_of_node = priv->codec_np;
+
+	ret = snd_soc_register_card(&imx_phycore);
+	if (ret) {
+		dev_err(&pdev->dev, "ASoC: soc card registration failed\n");
+		of_node_put(priv->cpu_np);
+		of_node_put(priv->codec_np);
+		return ret;
+	}
+
+	dev_set_drvdata(&pdev->dev, priv);
+
+	return ret;
+}
+
+static int imx_phycore_ac97_remove(struct platform_device *pdev)
+{
+	struct phycore_ac97_data *priv = dev_get_drvdata(&pdev->dev);
+
+	snd_soc_unregister_card(&imx_phycore);
+
+	of_node_put(priv->cpu_np);
+	of_node_put(priv->codec_np);
+
+	return 0;
+}
+
+static struct platform_driver imx_phycore_ac97_driver = {
+	.probe		= imx_phycore_ac97_probe,
+	.remove		= imx_phycore_ac97_remove,
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = imx_phycore_ac97_of_dev_id,
+	},
+};
+
+module_platform_driver(imx_phycore_ac97_driver);
+
+MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
+MODULE_DESCRIPTION(DRV_NAME ": PhyCORE ALSA SoC DT driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/phycore-ac97.c b/sound/soc/fsl/phycore-ac97.c
index ae403c2..4126edc 100644
--- a/sound/soc/fsl/phycore-ac97.c
+++ b/sound/soc/fsl/phycore-ac97.c
@@ -52,18 +52,7 @@ static int __init imx_phycore_init(void)
 {
 	int ret;
 
-	if (machine_is_pca100()) {
-		imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
-			IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
-			IMX_AUDMUX_V1_PCR_TFCSEL(3) |
-			IMX_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
-			IMX_AUDMUX_V1_PCR_RXDSEL(3));
-		imx_audmux_v1_configure_port(3,
-			IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
-			IMX_AUDMUX_V1_PCR_TFCSEL(0) |
-			IMX_AUDMUX_V1_PCR_TFSDIR |
-			IMX_AUDMUX_V1_PCR_RXDSEL(0));
-	} else if (machine_is_pcm043()) {
+	if (machine_is_pcm043()) {
 		imx_audmux_v2_configure_port(3,
 			IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
 			IMX_AUDMUX_V2_PTCR_TFSEL(0) |
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v10 7/7] ASoC: Add phycore-ac97-dt driver
@ 2013-07-27 11:31   ` Markus Pargmann
  0 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

Add devicetree support for phycore-ac97 driver in a seperated driver for
DT loading. The seperation reduces the confusion with the old style
initialization of this driver via late_initcall. Also this driver is
using fsl-ssi instead of imx-ssi.

platform_of_node and cpu_of_node are set according to the fsl,audmux
phandle.

This patch adds handling of ac97 reset functions according to fsl ac97
support. They are setup from here to avoid board specific code in the
generic fsl-ssi driver.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
---
 .../bindings/sound/phytec,phycore-ac97.txt         |  16 +++
 sound/soc/fsl/Kconfig                              |  15 ++-
 sound/soc/fsl/Makefile                             |   2 +
 sound/soc/fsl/phycore-ac97-dt.c                    | 124 +++++++++++++++++++++
 sound/soc/fsl/phycore-ac97.c                       |  13 +--
 5 files changed, 156 insertions(+), 14 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt
 create mode 100644 sound/soc/fsl/phycore-ac97-dt.c

diff --git a/Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt b/Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt
new file mode 100644
index 0000000..b3ce9cb
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/phytec,phycore-ac97.txt
@@ -0,0 +1,16 @@
+Phytec phycore AC97
+
+Required properties:
+- compatible: "phytec,phycore-ac97"
+- phytec,ssi: A phandle to the ssi device that is connected to ac97.
+- phytec,audmux: A phandle to the audmux device.
+- audio-codec: phandle to the codec device node.
+
+Example:
+
+sound {
+	compatible = "phytec,phycore-ac97";
+	phytec,ssi = <&ssi1>;
+	phytec,audmux = <&audmux>;
+	audio-codec = <&codec>;
+};
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 3a79d01..5f992b3 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -142,8 +142,8 @@ config SND_SOC_MX27VIS_AIC32X4
 	  board with TLV320AIC32X4 codec.
 
 config SND_SOC_PHYCORE_AC97
-	tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
-	depends on MACH_PCM043 || MACH_PCA100
+	tristate "SoC Audio support for Phytec phyCORE boards"
+	depends on MACH_PCM043
 	select SND_SOC_AC97_BUS
 	select SND_SOC_WM9712
 	select SND_SOC_IMX_PCM_FIQ
@@ -153,6 +153,17 @@ config SND_SOC_PHYCORE_AC97
 	  Say Y if you want to add support for SoC audio on Phytec phyCORE
 	  and phyCARD boards in AC97 mode
 
+config SND_SOC_PHYCORE_AC97_DT
+	tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards (devicetree only)"
+	select SND_SOC_AC97_BUS
+	select SND_SOC_WM9712
+	select SND_SOC_IMX_PCM_FIQ
+	select SND_SOC_IMX_AUDMUX
+	select SND_SOC_FSL_SSI
+	help
+	  Say Y if you want to add support for SoC audio on Phytec phyCORE
+	  and phyCARD boards in AC97 mode when using devicetree.
+
 config SND_SOC_EUKREA_TLV320
 	tristate "Eukrea TLV320"
 	depends on MACH_EUKREA_MBIMX27_BASEBOARD \
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index d4b4aa8..31bdd69 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o
 # i.MX Machine Support
 snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
 snd-soc-phycore-ac97-objs := phycore-ac97.o
+snd-soc-phycore-ac97-dt-objs := phycore-ac97-dt.o
 snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
 snd-soc-wm1133-ev1-objs := wm1133-ev1.o
 snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
@@ -47,6 +48,7 @@ snd-soc-imx-mc13783-objs := imx-mc13783.o
 
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
 obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
+obj-$(CONFIG_SND_SOC_PHYCORE_AC97_DT) += snd-soc-phycore-ac97-dt.o
 obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
 obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
 obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
diff --git a/sound/soc/fsl/phycore-ac97-dt.c b/sound/soc/fsl/phycore-ac97-dt.c
new file mode 100644
index 0000000..46b3423
--- /dev/null
+++ b/sound/soc/fsl/phycore-ac97-dt.c
@@ -0,0 +1,124 @@
+/*
+ * phycore-ac97-dt.c  --  SoC audio for imx_phycore in AC97 mode
+ *
+ * Copyright 2013 Markus Pargmann, Pengutronix <mpa@pengutronix.de>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/of.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+#include "imx-audmux.h"
+#include "fsl_ssi.h"
+
+#define DRV_NAME "phycore-ac97-dt-driver"
+
+struct phycore_ac97_data {
+	struct snd_soc_card card;
+	struct device_node *cpu_np;
+	struct device_node *codec_np;
+};
+
+static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
+	{
+		.name		= "HiFi",
+		.stream_name	= "HiFi",
+		.codec_dai_name	= "wm9712-hifi",
+	},
+};
+
+static struct snd_soc_card imx_phycore = {
+	.name		= "PhyCORE-ac97-audio",
+	.owner		= THIS_MODULE,
+	.dai_link	= imx_phycore_dai_ac97,
+	.num_links	= ARRAY_SIZE(imx_phycore_dai_ac97),
+};
+
+static const struct of_device_id imx_phycore_ac97_of_dev_id[] = {
+	{
+		.compatible = "phytec,phycore-ac97",
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, imx_phycore_ac97_of_dev_id);
+
+static int imx_phycore_ac97_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct phycore_ac97_data *priv;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+
+	if (!priv)
+		return -ENOMEM;
+
+	imx_phycore.dev = &pdev->dev;
+
+	priv->cpu_np = of_parse_phandle(pdev->dev.of_node, "phytec,ssi", 0);
+	if (!priv->cpu_np) {
+		dev_err(&pdev->dev, "No valid ssi phandle found\n");
+		return -EINVAL;
+	}
+
+	priv->codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
+	if (!priv->codec_np) {
+		dev_err(&pdev->dev, "No valid codec phandle found\n");
+		of_node_put(priv->cpu_np);
+		return -EINVAL;
+	}
+
+	imx_phycore_dai_ac97[0].cpu_of_node = priv->cpu_np;
+	imx_phycore_dai_ac97[0].platform_of_node = priv->cpu_np;
+	imx_phycore_dai_ac97[0].codec_of_node = priv->codec_np;
+
+	ret = snd_soc_register_card(&imx_phycore);
+	if (ret) {
+		dev_err(&pdev->dev, "ASoC: soc card registration failed\n");
+		of_node_put(priv->cpu_np);
+		of_node_put(priv->codec_np);
+		return ret;
+	}
+
+	dev_set_drvdata(&pdev->dev, priv);
+
+	return ret;
+}
+
+static int imx_phycore_ac97_remove(struct platform_device *pdev)
+{
+	struct phycore_ac97_data *priv = dev_get_drvdata(&pdev->dev);
+
+	snd_soc_unregister_card(&imx_phycore);
+
+	of_node_put(priv->cpu_np);
+	of_node_put(priv->codec_np);
+
+	return 0;
+}
+
+static struct platform_driver imx_phycore_ac97_driver = {
+	.probe		= imx_phycore_ac97_probe,
+	.remove		= imx_phycore_ac97_remove,
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = imx_phycore_ac97_of_dev_id,
+	},
+};
+
+module_platform_driver(imx_phycore_ac97_driver);
+
+MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
+MODULE_DESCRIPTION(DRV_NAME ": PhyCORE ALSA SoC DT driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/phycore-ac97.c b/sound/soc/fsl/phycore-ac97.c
index ae403c2..4126edc 100644
--- a/sound/soc/fsl/phycore-ac97.c
+++ b/sound/soc/fsl/phycore-ac97.c
@@ -52,18 +52,7 @@ static int __init imx_phycore_init(void)
 {
 	int ret;
 
-	if (machine_is_pca100()) {
-		imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
-			IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
-			IMX_AUDMUX_V1_PCR_TFCSEL(3) |
-			IMX_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
-			IMX_AUDMUX_V1_PCR_RXDSEL(3));
-		imx_audmux_v1_configure_port(3,
-			IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
-			IMX_AUDMUX_V1_PCR_TFCSEL(0) |
-			IMX_AUDMUX_V1_PCR_TFSDIR |
-			IMX_AUDMUX_V1_PCR_RXDSEL(0));
-	} else if (machine_is_pcm043()) {
+	if (machine_is_pcm043()) {
 		imx_audmux_v2_configure_port(3,
 			IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
 			IMX_AUDMUX_V2_PTCR_TFSEL(0) |
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 2/7] ASoC: codec: wm9712 simple DT bindings
  2013-07-27 11:31   ` Markus Pargmann
@ 2013-07-27 11:59     ` Mark Brown
  -1 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-07-27 11:59 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Liam Girdwood, Timur Tabi, Grant Likely,
	Sascha Hauer, Shawn Guo, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 504 bytes --]

On Sat, Jul 27, 2013 at 01:31:51PM +0200, Markus Pargmann wrote:

> +static const struct of_device_id wm9712_codec_of_dev_id[] = {
> +	{
> +		.compatible = "wlf,wm9712",
> +	}, {
> +		/* sentinel */
> +	}
> +};
> +
>  static struct platform_driver wm9712_codec_driver = {
>  	.driver = {
>  		.name = "wm9712-codec",
>  		.owner = THIS_MODULE,
> +		.of_match_table = wm9712_codec_of_dev_id,
>  	},
>  
>  	.probe = wm9712_probe,

AC'97 is an enumerable bus, we shouldn't need this...

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v10 2/7] ASoC: codec: wm9712 simple DT bindings
@ 2013-07-27 11:59     ` Mark Brown
  0 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-07-27 11:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 27, 2013 at 01:31:51PM +0200, Markus Pargmann wrote:

> +static const struct of_device_id wm9712_codec_of_dev_id[] = {
> +	{
> +		.compatible = "wlf,wm9712",
> +	}, {
> +		/* sentinel */
> +	}
> +};
> +
>  static struct platform_driver wm9712_codec_driver = {
>  	.driver = {
>  		.name = "wm9712-codec",
>  		.owner = THIS_MODULE,
> +		.of_match_table = wm9712_codec_of_dev_id,
>  	},
>  
>  	.probe = wm9712_probe,

AC'97 is an enumerable bus, we shouldn't need this...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130727/5c73c832/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 1/7] ASoC: core: Generic ac97 link reset functions
  2013-07-27 11:31   ` Markus Pargmann
@ 2013-07-27 12:05     ` Mark Brown
  -1 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-07-27 12:05 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, devicetree, alsa-devel, Lars-Peter Clausen,
	Liam Girdwood, Timur Tabi, Grant Likely, Sascha Hauer, Shawn Guo,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 778 bytes --]

On Sat, Jul 27, 2013 at 01:31:50PM +0200, Markus Pargmann wrote:

This is a really nice approach to the problem, just one thing I'd like
to see changed in the bindings:

> +ssi {
> +	...
> +
> +	pinctrl-names = "default", "ac97-running", "ac97-reset", "ac97-warm-reset";

I'd like to see some documentation of this "default" state - I'd expect
this corresponds to the bus being idle and waiting for a wakeup from the
CODEC which is definitely a useful state to have for power optimisation
so it'd be good to bake it into the bindings.

Alternatively it could be the bus being totally idle with no possibility
of wakeup in which case it'd be good to say that too then someone can
add the waiting for wakeup state later.

Please also note the new list devicetree@vger.kernel.org.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v10 1/7] ASoC: core: Generic ac97 link reset functions
@ 2013-07-27 12:05     ` Mark Brown
  0 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-07-27 12:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 27, 2013 at 01:31:50PM +0200, Markus Pargmann wrote:

This is a really nice approach to the problem, just one thing I'd like
to see changed in the bindings:

> +ssi {
> +	...
> +
> +	pinctrl-names = "default", "ac97-running", "ac97-reset", "ac97-warm-reset";

I'd like to see some documentation of this "default" state - I'd expect
this corresponds to the bus being idle and waiting for a wakeup from the
CODEC which is definitely a useful state to have for power optimisation
so it'd be good to bake it into the bindings.

Alternatively it could be the bus being totally idle with no possibility
of wakeup in which case it'd be good to say that too then someone can
add the waiting for wakeup state later.

Please also note the new list devicetree at vger.kernel.org.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130727/39a1016c/attachment.sig>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 2/7] ASoC: codec: wm9712 simple DT bindings
  2013-07-27 11:59     ` Mark Brown
@ 2013-07-27 13:44       ` Markus Pargmann
  -1 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 13:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen, Liam Girdwood,
	Timur Tabi, Grant Likely, Sascha Hauer, Shawn Guo,
	linux-arm-kernel

On Sat, Jul 27, 2013 at 12:59:50PM +0100, Mark Brown wrote:
> On Sat, Jul 27, 2013 at 01:31:51PM +0200, Markus Pargmann wrote:
> 
> > +static const struct of_device_id wm9712_codec_of_dev_id[] = {
> > +	{
> > +		.compatible = "wlf,wm9712",
> > +	}, {
> > +		/* sentinel */
> > +	}
> > +};
> > +
> >  static struct platform_driver wm9712_codec_driver = {
> >  	.driver = {
> >  		.name = "wm9712-codec",
> >  		.owner = THIS_MODULE,
> > +		.of_match_table = wm9712_codec_of_dev_id,
> >  	},
> >  
> >  	.probe = wm9712_probe,
> 
> AC'97 is an enumerable bus, we shouldn't need this...

What do you mean exactly? Is there a way to automaticaly discover
connected codecs and register them?

Regards,

Markus


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v10 2/7] ASoC: codec: wm9712 simple DT bindings
@ 2013-07-27 13:44       ` Markus Pargmann
  0 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 13:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 27, 2013 at 12:59:50PM +0100, Mark Brown wrote:
> On Sat, Jul 27, 2013 at 01:31:51PM +0200, Markus Pargmann wrote:
> 
> > +static const struct of_device_id wm9712_codec_of_dev_id[] = {
> > +	{
> > +		.compatible = "wlf,wm9712",
> > +	}, {
> > +		/* sentinel */
> > +	}
> > +};
> > +
> >  static struct platform_driver wm9712_codec_driver = {
> >  	.driver = {
> >  		.name = "wm9712-codec",
> >  		.owner = THIS_MODULE,
> > +		.of_match_table = wm9712_codec_of_dev_id,
> >  	},
> >  
> >  	.probe = wm9712_probe,
> 
> AC'97 is an enumerable bus, we shouldn't need this...

What do you mean exactly? Is there a way to automaticaly discover
connected codecs and register them?

Regards,

Markus


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 1/7] ASoC: core: Generic ac97 link reset functions
  2013-07-27 12:05     ` Mark Brown
@ 2013-07-27 13:55       ` Markus Pargmann
  -1 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 13:55 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen, Liam Girdwood,
	Timur Tabi, Grant Likely, Sascha Hauer, Shawn Guo,
	linux-arm-kernel

On Sat, Jul 27, 2013 at 01:05:22PM +0100, Mark Brown wrote:
> On Sat, Jul 27, 2013 at 01:31:50PM +0200, Markus Pargmann wrote:
> 
> This is a really nice approach to the problem, just one thing I'd like
> to see changed in the bindings:
> 
> > +ssi {
> > +	...
> > +
> > +	pinctrl-names = "default", "ac97-running", "ac97-reset", "ac97-warm-reset";
> 
> I'd like to see some documentation of this "default" state - I'd expect
> this corresponds to the bus being idle and waiting for a wakeup from the
> CODEC which is definitely a useful state to have for power optimisation
> so it'd be good to bake it into the bindings.
> 
> Alternatively it could be the bus being totally idle with no possibility
> of wakeup in which case it'd be good to say that too then someone can
> add the waiting for wakeup state later.

The "default" state is actually just the default pin state that is set
before the driver is probed. I will remove it from the example. I didn't
add a low power state although it might be usefull and is defined by the
standard.

> 
> Please also note the new list devicetree@vger.kernel.org.

Yes thanks.

Regards,

Markus



-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v10 1/7] ASoC: core: Generic ac97 link reset functions
@ 2013-07-27 13:55       ` Markus Pargmann
  0 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-07-27 13:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 27, 2013 at 01:05:22PM +0100, Mark Brown wrote:
> On Sat, Jul 27, 2013 at 01:31:50PM +0200, Markus Pargmann wrote:
> 
> This is a really nice approach to the problem, just one thing I'd like
> to see changed in the bindings:
> 
> > +ssi {
> > +	...
> > +
> > +	pinctrl-names = "default", "ac97-running", "ac97-reset", "ac97-warm-reset";
> 
> I'd like to see some documentation of this "default" state - I'd expect
> this corresponds to the bus being idle and waiting for a wakeup from the
> CODEC which is definitely a useful state to have for power optimisation
> so it'd be good to bake it into the bindings.
> 
> Alternatively it could be the bus being totally idle with no possibility
> of wakeup in which case it'd be good to say that too then someone can
> add the waiting for wakeup state later.

The "default" state is actually just the default pin state that is set
before the driver is probed. I will remove it from the example. I didn't
add a low power state although it might be usefull and is defined by the
standard.

> 
> Please also note the new list devicetree at vger.kernel.org.

Yes thanks.

Regards,

Markus



-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 2/7] ASoC: codec: wm9712 simple DT bindings
  2013-07-27 13:44       ` Markus Pargmann
@ 2013-07-27 14:21         ` Mark Brown
  -1 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-07-27 14:21 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen, Liam Girdwood,
	Timur Tabi, Grant Likely, Sascha Hauer, Shawn Guo,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 382 bytes --]

On Sat, Jul 27, 2013 at 03:44:52PM +0200, Markus Pargmann wrote:
> On Sat, Jul 27, 2013 at 12:59:50PM +0100, Mark Brown wrote:

> > AC'97 is an enumerable bus, we shouldn't need this...

> What do you mean exactly? Is there a way to automaticaly discover
> connected codecs and register them?

Yes, of coure - just read the ID registers.  Look at how the non-ASoC
AC'97 code works.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v10 2/7] ASoC: codec: wm9712 simple DT bindings
@ 2013-07-27 14:21         ` Mark Brown
  0 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-07-27 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 27, 2013 at 03:44:52PM +0200, Markus Pargmann wrote:
> On Sat, Jul 27, 2013 at 12:59:50PM +0100, Mark Brown wrote:

> > AC'97 is an enumerable bus, we shouldn't need this...

> What do you mean exactly? Is there a way to automaticaly discover
> connected codecs and register them?

Yes, of coure - just read the ID registers.  Look at how the non-ASoC
AC'97 code works.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130727/e7bfe6d5/attachment.sig>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 3/7] ASoC: imx-audmux: Read default configuration from devicetree
  2013-07-27 11:31   ` Markus Pargmann
@ 2013-08-06 16:57     ` Mark Brown
  -1 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-08-06 16:57 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Liam Girdwood, Timur Tabi, Grant Likely,
	Sascha Hauer, Shawn Guo, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 192 bytes --]

On Sat, Jul 27, 2013 at 01:31:52PM +0200, Markus Pargmann wrote:
> Adds a function to parse a default port configuration from devicetree.

Applied, thanks - this is a really nice improvement.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v10 3/7] ASoC: imx-audmux: Read default configuration from devicetree
@ 2013-08-06 16:57     ` Mark Brown
  0 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-08-06 16:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 27, 2013 at 01:31:52PM +0200, Markus Pargmann wrote:
> Adds a function to parse a default port configuration from devicetree.

Applied, thanks - this is a really nice improvement.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130806/29b73435/attachment.sig>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 4/7] ASoC: fsl-ssi: Add support for imx-pcm-fiq
  2013-07-27 11:31   ` Markus Pargmann
@ 2013-08-06 16:59     ` Mark Brown
  -1 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-08-06 16:59 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Liam Girdwood, Timur Tabi, Grant Likely,
	Sascha Hauer, Shawn Guo, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 387 bytes --]

On Sat, Jul 27, 2013 at 01:31:53PM +0200, Markus Pargmann wrote:
> Add support for non-dma pcm for imx platforms with imx-pcm-fiq support.
> Instead of imx-pcm-audio, in this case imx-pcm-fiq-audio device is added
> and the SIER flags are set differently.

Applied, thanks.  Ideally we'd have a quirk infrastructure to figure out
if this is required but it really doesn't seem worth it.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v10 4/7] ASoC: fsl-ssi: Add support for imx-pcm-fiq
@ 2013-08-06 16:59     ` Mark Brown
  0 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-08-06 16:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 27, 2013 at 01:31:53PM +0200, Markus Pargmann wrote:
> Add support for non-dma pcm for imx platforms with imx-pcm-fiq support.
> Instead of imx-pcm-audio, in this case imx-pcm-fiq-audio device is added
> and the SIER flags are set differently.

Applied, thanks.  Ideally we'd have a quirk infrastructure to figure out
if this is required but it really doesn't seem worth it.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130806/9e120bde/attachment.sig>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 5/7] ASoC: fsl-ssi: Use generic DMA bindings if possible
  2013-07-27 11:31   ` Markus Pargmann
@ 2013-08-06 16:59     ` Mark Brown
  -1 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-08-06 16:59 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Liam Girdwood, Timur Tabi, Grant Likely,
	Sascha Hauer, Shawn Guo, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 327 bytes --]

On Sat, Jul 27, 2013 at 01:31:54PM +0200, Markus Pargmann wrote:
> There may be some platforms using fsl-ssi that do not have a DMA driver
> with generic DMA bindings. So this patch adds support for the generic
> DMA bindings, while still accepting the old "fsl,dma-events" property if
> "dmas" is not found.

Applied, thanks.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v10 5/7] ASoC: fsl-ssi: Use generic DMA bindings if possible
@ 2013-08-06 16:59     ` Mark Brown
  0 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-08-06 16:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 27, 2013 at 01:31:54PM +0200, Markus Pargmann wrote:
> There may be some platforms using fsl-ssi that do not have a DMA driver
> with generic DMA bindings. So this patch adds support for the generic
> DMA bindings, while still accepting the old "fsl,dma-events" property if
> "dmas" is not found.

Applied, thanks.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130806/80ee4959/attachment.sig>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 6/7] ASoC: fsl-ssi: ac97-slave support
  2013-07-27 11:31   ` Markus Pargmann
@ 2013-08-06 17:00     ` Mark Brown
  -1 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-08-06 17:00 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Liam Girdwood, Timur Tabi, Grant Likely,
	Sascha Hauer, Shawn Guo, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 121 bytes --]

On Sat, Jul 27, 2013 at 01:31:55PM +0200, Markus Pargmann wrote:
> This patch adds ac97-slave support.

Applied, thanks.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v10 6/7] ASoC: fsl-ssi: ac97-slave support
@ 2013-08-06 17:00     ` Mark Brown
  0 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-08-06 17:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 27, 2013 at 01:31:55PM +0200, Markus Pargmann wrote:
> This patch adds ac97-slave support.

Applied, thanks.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130806/9286fd54/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v10 3/7] ASoC: imx-audmux: Read default configuration from devicetree
  2013-08-06 16:57     ` Mark Brown
@ 2013-08-09 12:37       ` Markus Pargmann
  -1 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-08-09 12:37 UTC (permalink / raw)
  To: Mark Brown
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Liam Girdwood, Timur Tabi, Grant Likely,
	Sascha Hauer, Shawn Guo, linux-arm-kernel

On Tue, Aug 06, 2013 at 05:57:46PM +0100, Mark Brown wrote:
> On Sat, Jul 27, 2013 at 01:31:52PM +0200, Markus Pargmann wrote:
> > Adds a function to parse a default port configuration from devicetree.
> 
> Applied, thanks - this is a really nice improvement.

Sorry, but I noticed two bugs in this patch, I will send a fixup.

Regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v10 3/7] ASoC: imx-audmux: Read default configuration from devicetree
@ 2013-08-09 12:37       ` Markus Pargmann
  0 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-08-09 12:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Aug 06, 2013 at 05:57:46PM +0100, Mark Brown wrote:
> On Sat, Jul 27, 2013 at 01:31:52PM +0200, Markus Pargmann wrote:
> > Adds a function to parse a default port configuration from devicetree.
> 
> Applied, thanks - this is a really nice improvement.

Sorry, but I noticed two bugs in this patch, I will send a fixup.

Regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH] ASoC: imx-audmux: default configuration parser fixups
  2013-08-09 12:37       ` Markus Pargmann
@ 2013-08-10 12:55         ` Markus Pargmann
  -1 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-08-10 12:55 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Timur Tabi, Liam Girdwood, Grant Likely,
	Mark Brown, Sascha Hauer, Markus Pargmann, Shawn Guo

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/imx-audmux.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index f37cd9c..b21b85f 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -270,7 +270,7 @@ static int imx_audmux_parse_dt_defaults(struct platform_device *pdev,
 		}
 
 		for (i = 0; (ret = of_property_read_u32_index(child,
-					"fsl,port-config\n", i, &val)) == 0;
+					"fsl,port-config", i, &val)) == 0;
 				++i) {
 			if (audmux_type == IMX31_AUDMUX) {
 				if (i % 2)
@@ -282,7 +282,7 @@ static int imx_audmux_parse_dt_defaults(struct platform_device *pdev,
 			}
 		}
 
-		if (ret != -ENODATA) {
+		if (ret != -EOVERFLOW) {
 			dev_err(&pdev->dev, "Failed to read u32 at index %d of child %s\n",
 					i, child->full_name);
 			continue;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH] ASoC: imx-audmux: default configuration parser fixups
@ 2013-08-10 12:55         ` Markus Pargmann
  0 siblings, 0 replies; 40+ messages in thread
From: Markus Pargmann @ 2013-08-10 12:55 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/imx-audmux.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index f37cd9c..b21b85f 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -270,7 +270,7 @@ static int imx_audmux_parse_dt_defaults(struct platform_device *pdev,
 		}
 
 		for (i = 0; (ret = of_property_read_u32_index(child,
-					"fsl,port-config\n", i, &val)) == 0;
+					"fsl,port-config", i, &val)) == 0;
 				++i) {
 			if (audmux_type == IMX31_AUDMUX) {
 				if (i % 2)
@@ -282,7 +282,7 @@ static int imx_audmux_parse_dt_defaults(struct platform_device *pdev,
 			}
 		}
 
-		if (ret != -ENODATA) {
+		if (ret != -EOVERFLOW) {
 			dev_err(&pdev->dev, "Failed to read u32 at index %d of child %s\n",
 					i, child->full_name);
 			continue;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH] ASoC: imx-audmux: default configuration parser fixups
  2013-08-10 12:55         ` Markus Pargmann
@ 2013-08-11 10:59           ` Mark Brown
  -1 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-08-11 10:59 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Fabio Estevam, alsa-devel, Lars-Peter Clausen,
	devicetree-discuss, Liam Girdwood, Timur Tabi, Grant Likely,
	Sascha Hauer, Shawn Guo, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 198 bytes --]

On Sat, Aug 10, 2013 at 02:55:57PM +0200, Markus Pargmann wrote:
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>

Applied, thanks.  This is two changes so would've been better as two
patches.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH] ASoC: imx-audmux: default configuration parser fixups
@ 2013-08-11 10:59           ` Mark Brown
  0 siblings, 0 replies; 40+ messages in thread
From: Mark Brown @ 2013-08-11 10:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Aug 10, 2013 at 02:55:57PM +0200, Markus Pargmann wrote:
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>

Applied, thanks.  This is two changes so would've been better as two
patches.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130811/e06942f6/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2013-08-11 10:59 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-27 11:31 [PATCH v10 0/7] ASoC: fsl-ssi: ac97-slave support Markus Pargmann
2013-07-27 11:31 ` Markus Pargmann
2013-07-27 11:31 ` [PATCH v10 1/7] ASoC: core: Generic ac97 link reset functions Markus Pargmann
2013-07-27 11:31   ` Markus Pargmann
2013-07-27 12:05   ` Mark Brown
2013-07-27 12:05     ` Mark Brown
2013-07-27 13:55     ` Markus Pargmann
2013-07-27 13:55       ` Markus Pargmann
2013-07-27 11:31 ` [PATCH v10 2/7] ASoC: codec: wm9712 simple DT bindings Markus Pargmann
2013-07-27 11:31   ` Markus Pargmann
2013-07-27 11:59   ` Mark Brown
2013-07-27 11:59     ` Mark Brown
2013-07-27 13:44     ` Markus Pargmann
2013-07-27 13:44       ` Markus Pargmann
2013-07-27 14:21       ` Mark Brown
2013-07-27 14:21         ` Mark Brown
2013-07-27 11:31 ` [PATCH v10 3/7] ASoC: imx-audmux: Read default configuration from devicetree Markus Pargmann
2013-07-27 11:31   ` Markus Pargmann
2013-08-06 16:57   ` Mark Brown
2013-08-06 16:57     ` Mark Brown
2013-08-09 12:37     ` Markus Pargmann
2013-08-09 12:37       ` Markus Pargmann
2013-08-10 12:55       ` [PATCH] ASoC: imx-audmux: default configuration parser fixups Markus Pargmann
2013-08-10 12:55         ` Markus Pargmann
2013-08-11 10:59         ` Mark Brown
2013-08-11 10:59           ` Mark Brown
2013-07-27 11:31 ` [PATCH v10 4/7] ASoC: fsl-ssi: Add support for imx-pcm-fiq Markus Pargmann
2013-07-27 11:31   ` Markus Pargmann
2013-08-06 16:59   ` Mark Brown
2013-08-06 16:59     ` Mark Brown
2013-07-27 11:31 ` [PATCH v10 5/7] ASoC: fsl-ssi: Use generic DMA bindings if possible Markus Pargmann
2013-07-27 11:31   ` Markus Pargmann
2013-08-06 16:59   ` Mark Brown
2013-08-06 16:59     ` Mark Brown
2013-07-27 11:31 ` [PATCH v10 6/7] ASoC: fsl-ssi: ac97-slave support Markus Pargmann
2013-07-27 11:31   ` Markus Pargmann
2013-08-06 17:00   ` Mark Brown
2013-08-06 17:00     ` Mark Brown
2013-07-27 11:31 ` [PATCH v10 7/7] ASoC: Add phycore-ac97-dt driver Markus Pargmann
2013-07-27 11:31   ` Markus Pargmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.