* [PATCH 1/6] spi: imx: specify spi base for device tree probe
[not found] ` <1352469625-32024-1-git-send-email-s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
@ 2012-11-09 14:00 ` Steffen Trumtrar
2012-11-09 16:38 ` Mark Brown
2012-11-09 14:00 ` [PATCH 2/6] spi/devicetree: find spi_device via device_node Steffen Trumtrar
` (4 subsequent siblings)
5 siblings, 1 reply; 16+ messages in thread
From: Steffen Trumtrar @ 2012-11-09 14:00 UTC (permalink / raw)
To: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, Mark Brown, Sascha Hauer,
patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E, Rob Herring,
Rob Landley, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
Steffen Trumtrar, Liam Girdwood,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
The DT probe uses a dynamically allocated base for the spi core. This is a
completely different numbering scheme than in the non-DT probe.
* This breaks compatibility with user space applications between non-DT and DT.
* On platforms that are in between DT and non-DT, it breaks registration of
devices via spi_board_info.
Use the same method as 7e6086d9e54a159a6257c02bb7fc5805c614aad2 does for gpios:
Use alias to identify the spi port, and then specify the base via the port id.
If alias is not defined in DT, allocate the base dynamically.
Signed-off-by: Steffen Trumtrar <s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
drivers/spi/spi-imx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index c9a0d84..d1e92b4 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -783,7 +783,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, master);
- master->bus_num = pdev->id;
+ master->bus_num = (pdev->id < 0) ? of_alias_get_id(np, "spi") : pdev->id;
master->num_chipselect = num_cs;
spi_imx = spi_master_get_devdata(master);
--
1.7.10.4
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_nov
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 1/6] spi: imx: specify spi base for device tree probe
2012-11-09 14:00 ` [PATCH 1/6] spi: imx: specify spi base for device tree probe Steffen Trumtrar
@ 2012-11-09 16:38 ` Mark Brown
[not found] ` <20121109163830.GP23807-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
0 siblings, 1 reply; 16+ messages in thread
From: Mark Brown @ 2012-11-09 16:38 UTC (permalink / raw)
To: Steffen Trumtrar
Cc: alsa-devel, Sascha Hauer, devicetree-discuss, patches,
Grant Likely, Rob Herring, Rob Landley, spi-devel-general,
Liam Girdwood, linux-arm-kernel
[-- Attachment #1.1: Type: text/plain, Size: 568 bytes --]
On Fri, Nov 09, 2012 at 03:00:20PM +0100, Steffen Trumtrar wrote:
> * This breaks compatibility with user space applications between non-DT and DT.
> * On platforms that are in between DT and non-DT, it breaks registration of
> devices via spi_board_info.
> Use the same method as 7e6086d9e54a159a6257c02bb7fc5805c614aad2 does for gpios:
> Use alias to identify the spi port, and then specify the base via the port id.
> If alias is not defined in DT, allocate the base dynamically.
This sounds like a fix userspace and/or complete your DT conversion
problem...
[-- 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] 16+ messages in thread
* [PATCH 2/6] spi/devicetree: find spi_device via device_node
[not found] ` <1352469625-32024-1-git-send-email-s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2012-11-09 14:00 ` [PATCH 1/6] spi: imx: specify spi base for device tree probe Steffen Trumtrar
@ 2012-11-09 14:00 ` Steffen Trumtrar
2012-11-09 14:00 ` [PATCH 3/6] ASoC: wm8974: include MCLKDIV in pll_factors Steffen Trumtrar
` (3 subsequent siblings)
5 siblings, 0 replies; 16+ messages in thread
From: Steffen Trumtrar @ 2012-11-09 14:00 UTC (permalink / raw)
To: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, Mark Brown, Sascha Hauer,
patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E, Rob Herring,
Rob Landley, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
Steffen Trumtrar, Liam Girdwood,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Add a function to find a spi_device via DT device_node.
The patch is based on the way i2c does it.
This is intended for devices that depend on multiple subsystems and are therefore
not a child of the spi-master node (e.g. sound devices that are controlled via spi
and get their data via another bus). The driver instead can find the desired device
via scanning the spi bus.
Signed-off-by: Steffen Trumtrar <s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
drivers/spi/spi.c | 20 ++++++++++++++++++++
include/linux/spi/spi.h | 3 +++
2 files changed, 23 insertions(+)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 84c2861..e25487f 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -801,6 +801,26 @@ err_init_queue:
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_OF) && !defined(CONFIG_SPARC)
+
+static int of_dev_node_match(struct device *dev, void *data)
+{
+ return dev->of_node == data;
+}
+
+/* must call spi_dev_put() when done with returned spi_device device */
+struct spi_device *of_find_spi_device_by_node(struct device_node *node)
+{
+ struct device *dev;
+
+ dev = bus_find_device(&spi_bus_type, NULL, node, of_dev_node_match);
+
+ if (!dev)
+ return NULL;
+
+ return to_spi_device(dev);
+}
+EXPORT_SYMBOL_GPL(of_find_spi_device_by_node);
+
/**
* of_register_spi_devices() - Register child devices onto the SPI bus
* @master: Pointer to spi_master device
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index fa702ae..db3a630 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -23,6 +23,7 @@
#include <linux/mod_devicetable.h>
#include <linux/slab.h>
#include <linux/kthread.h>
+#include <linux/of.h>
/*
* INTERFACES between SPI master-side drivers and SPI infrastructure.
@@ -387,6 +388,8 @@ static inline void spi_master_put(struct spi_master *master)
put_device(&master->dev);
}
+extern struct spi_device *of_find_spi_device_by_node(struct device_node *node);
+
/* PM calls that need to be issued by the driver */
extern int spi_master_suspend(struct spi_master *master);
extern int spi_master_resume(struct spi_master *master);
--
1.7.10.4
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_nov
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/6] ASoC: wm8974: include MCLKDIV in pll_factors
[not found] ` <1352469625-32024-1-git-send-email-s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2012-11-09 14:00 ` [PATCH 1/6] spi: imx: specify spi base for device tree probe Steffen Trumtrar
2012-11-09 14:00 ` [PATCH 2/6] spi/devicetree: find spi_device via device_node Steffen Trumtrar
@ 2012-11-09 14:00 ` Steffen Trumtrar
[not found] ` <1352469625-32024-4-git-send-email-s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2012-11-09 14:00 ` [PATCH 4/6] ASoC: wm8974: add SPI as a possible bus master Steffen Trumtrar
` (2 subsequent siblings)
5 siblings, 1 reply; 16+ messages in thread
From: Steffen Trumtrar @ 2012-11-09 14:00 UTC (permalink / raw)
To: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, Mark Brown, Sascha Hauer,
patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E, Rob Herring,
Rob Landley, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
Steffen Trumtrar, Liam Girdwood,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
To calculate the integer part of the frequency ratio, the whole output
path has to be considered (post and pre are optional):
Ndiv = (pre * target * 4 * post) / source
In the current implementation only the fixed- and pre-divider is
considered, but the post-divider is omitted.
To calculate Ndiv, this post divider has to be applied before any
calculation happens. Otherwise Ndiv is considered to be to low in the
later stages. This leads to a wrong value in the PLLN register, which
in turn produces a wrong playback speed of the audio signal.
This patch adds the post divider to the pll calculation.
Signed-off-by: Steffen Trumtrar <s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
sound/soc/codecs/wm8974.c | 39 +++++++++++++++++++++++++++++++++++++--
1 file changed, 37 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 9a39511..b012e4d 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -275,16 +275,51 @@ struct pll_ {
* to allow rounding later */
#define FIXED_PLL_SIZE ((1 << 24) * 10)
-static void pll_factors(struct pll_ *pll_div,
+static void pll_factors(struct pll_ *pll_div, struct snd_soc_codec *codec,
unsigned int target, unsigned int source)
{
unsigned long long Kpart;
unsigned int K, Ndiv, Nmod;
+ u16 reg;
/* There is a fixed divide by 4 in the output path */
+
target *= 4;
+ /* target also depends on MCLKDIV */
+ reg = (snd_soc_read(codec, WM8974_CLOCK) & 0xe0) >> 5;
+
+ switch (reg) {
+ case WM8974_MCLKDIV_1:
+ reg = 1;
+ break;
+ case WM8974_MCLKDIV_1_5:
+ case WM8974_MCLKDIV_2:
+ reg = 2;
+ break;
+ case WM8974_MCLKDIV_3:
+ reg = 3;
+ break;
+ case WM8974_MCLKDIV_4:
+ reg = 4;
+ break;
+ case WM8974_MCLKDIV_6:
+ reg = 6;
+ break;
+ case WM8974_MCLKDIV_8:
+ reg = 8;
+ break;
+ case WM8974_MCLKDIV_12:
+ reg = 12;
+ break;
+ default:
+ reg = 2;
+ }
+
+ target *= reg;
+
Ndiv = target / source;
+
if (Ndiv < 6) {
source /= 2;
pll_div->pre_div = 1;
@@ -333,7 +368,7 @@ static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
return 0;
}
- pll_factors(&pll_div, freq_out, freq_in);
+ pll_factors(&pll_div, codec, freq_out, freq_in);
snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n);
snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18);
--
1.7.10.4
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_nov
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 4/6] ASoC: wm8974: add SPI as a possible bus master
[not found] ` <1352469625-32024-1-git-send-email-s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
` (2 preceding siblings ...)
2012-11-09 14:00 ` [PATCH 3/6] ASoC: wm8974: include MCLKDIV in pll_factors Steffen Trumtrar
@ 2012-11-09 14:00 ` Steffen Trumtrar
[not found] ` <1352469625-32024-5-git-send-email-s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2012-11-09 14:00 ` [PATCH 5/6] ARM i.MX: rename ssi1 clock for imx27 Steffen Trumtrar
2012-11-09 14:00 ` [PATCH 6/6] ASoC: fsl: add imx-wm8974 machine driver Steffen Trumtrar
5 siblings, 1 reply; 16+ messages in thread
From: Steffen Trumtrar @ 2012-11-09 14:00 UTC (permalink / raw)
To: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, Mark Brown, Sascha Hauer,
patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E, Rob Herring,
Rob Landley, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
Steffen Trumtrar, Liam Girdwood,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
The wm8974 can be controlled via i2c or spi. The current driver only supports
i2c. Add SPI as possible bus.
As the driver has to distinguish the bus type, pass this info via the wm8974_priv.
This reverts c2562a8e3b5f871ad0b73caf98bb7541e8724efc, because the driver now
needs it back.
This is based on earlier work by Uwe Kleine-König.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
sound/soc/codecs/Kconfig | 2 +-
sound/soc/codecs/wm8974.c | 62 +++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index b92759a..cc6069d 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -104,7 +104,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM8961 if I2C
select SND_SOC_WM8962 if I2C
select SND_SOC_WM8971 if I2C
- select SND_SOC_WM8974 if I2C
+ select SND_SOC_WM8974 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8978 if I2C
select SND_SOC_WM8983 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8985 if SND_SOC_I2C_AND_SPI
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index b012e4d..8af553c 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -17,6 +17,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
+#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -48,6 +49,10 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
#define WM8974_POWER1_BIASEN 0x08
#define WM8974_POWER1_BUFIOEN 0x04
+struct wm8974_priv {
+ enum snd_soc_control_type control_type;
+};
+
#define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0)
static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" };
@@ -617,8 +622,9 @@ static int wm8974_resume(struct snd_soc_codec *codec)
static int wm8974_probe(struct snd_soc_codec *codec)
{
int ret = 0;
+ struct wm8974_priv *wm8974 = snd_soc_codec_get_drvdata(codec);
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8974->control_type);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
@@ -660,13 +666,64 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
.num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes),
};
+#if defined(CONFIG_SPI_MASTER)
+static int __devinit wm8974_spi_probe(struct spi_device *spi)
+{
+ struct wm8974_priv *wm8974;
+ int ret;
+
+ wm8974 = kzalloc(sizeof(*wm8974), GFP_KERNEL);
+ if (!wm8974)
+ return -ENOMEM;
+
+ wm8974->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, wm8974);
+
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8974, &wm8974_dai, 1);
+ if (ret)
+ kfree(wm8974);
+
+ return ret;
+}
+
+static int __devexit wm8974_spi_remove(struct spi_device *spi)
+{
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
+ return 0;
+}
+
+static struct spi_driver wm8974_spi_driver = {
+ .driver = {
+ .name = "wm8974",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8974_spi_probe,
+ .remove = __devexit_p(wm8974_spi_remove),
+};
+
+module_spi_driver(wm8974_spi_driver);
+#endif
+
+#if IS_ENABLED(CONFIG_I2C)
static __devinit int wm8974_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
+ struct wm8974_priv *wm8974;
int ret;
+ wm8974 = kzalloc(sizeof(*wm8974), GFP_KERNEL);
+ if (!wm8974)
+ return -ENOMEM;
+
+ wm8974->control_type = SND_SOC_I2C;
+ i2c_set_clientdata(i2c, wm8974);
+
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8974, &wm8974_dai, 1);
+ if (ret)
+ kfree(wm8974);
return ret;
}
@@ -674,7 +731,7 @@ static __devinit int wm8974_i2c_probe(struct i2c_client *i2c,
static __devexit int wm8974_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -695,6 +752,7 @@ static struct i2c_driver wm8974_i2c_driver = {
};
module_i2c_driver(wm8974_i2c_driver);
+#endif
MODULE_DESCRIPTION("ASoC WM8974 driver");
MODULE_AUTHOR("Liam Girdwood");
--
1.7.10.4
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_nov
_______________________________________________
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 5/6] ARM i.MX: rename ssi1 clock for imx27
[not found] ` <1352469625-32024-1-git-send-email-s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
` (3 preceding siblings ...)
2012-11-09 14:00 ` [PATCH 4/6] ASoC: wm8974: add SPI as a possible bus master Steffen Trumtrar
@ 2012-11-09 14:00 ` Steffen Trumtrar
[not found] ` <1352469625-32024-6-git-send-email-s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2012-11-09 14:00 ` [PATCH 6/6] ASoC: fsl: add imx-wm8974 machine driver Steffen Trumtrar
5 siblings, 1 reply; 16+ messages in thread
From: Steffen Trumtrar @ 2012-11-09 14:00 UTC (permalink / raw)
To: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, Mark Brown, Sascha Hauer,
patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E, Rob Herring,
Rob Landley, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
Steffen Trumtrar, Liam Girdwood,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Signed-off-by: Steffen Trumtrar <s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
arch/arm/mach-imx/clk-imx27.c | 2 +-
arch/arm/mach-imx/imx27-dt.c | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
index 366e5d5..d269532 100644
--- a/arch/arm/mach-imx/clk-imx27.c
+++ b/arch/arm/mach-imx/clk-imx27.c
@@ -236,7 +236,7 @@ int __init mx27_clocks_init(unsigned long fref)
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.2");
clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.2");
- clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0");
+ clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "10010000.ssi");
clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
clk_register_clkdev(clk[nfc_baud_gate], NULL, "mxc_nand.0");
clk_register_clkdev(clk[vpu_baud_gate], "per", "coda-imx27.0");
diff --git a/arch/arm/mach-imx/imx27-dt.c b/arch/arm/mach-imx/imx27-dt.c
index e80d523..60eed17 100644
--- a/arch/arm/mach-imx/imx27-dt.c
+++ b/arch/arm/mach-imx/imx27-dt.c
@@ -29,6 +29,7 @@ static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = {
OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI3_BASE_ADDR, "imx27-cspi.2", NULL),
OF_DEV_AUXDATA("fsl,imx27-wdt", MX27_WDOG_BASE_ADDR, "imx2-wdt.0", NULL),
OF_DEV_AUXDATA("fsl,imx27-nand", MX27_NFC_BASE_ADDR, "mxc_nand.0", NULL),
+ OF_DEV_AUXDATA("fsl,imx21-ssi", MX27_SSI1_BASE_ADDR, "10010000.ssi", NULL),
{ /* sentinel */ }
};
--
1.7.10.4
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_nov
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 6/6] ASoC: fsl: add imx-wm8974 machine driver
[not found] ` <1352469625-32024-1-git-send-email-s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
` (4 preceding siblings ...)
2012-11-09 14:00 ` [PATCH 5/6] ARM i.MX: rename ssi1 clock for imx27 Steffen Trumtrar
@ 2012-11-09 14:00 ` Steffen Trumtrar
[not found] ` <1352469625-32024-7-git-send-email-s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
5 siblings, 1 reply; 16+ messages in thread
From: Steffen Trumtrar @ 2012-11-09 14:00 UTC (permalink / raw)
To: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, Mark Brown, Sascha Hauer,
patches-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E, Rob Herring,
Rob Landley, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
Steffen Trumtrar, Liam Girdwood,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
This is the initial support for a wm8974 sound codec connected to an imx ssi.
It follows along the lines of the imx-sgtl5000 driver.
* only the playback dai link is implemented.
* DT only driver, working with the fsl_ssi driver and imx21 compatible
audmux
Signed-off-by: Steffen Trumtrar <s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
.../devicetree/bindings/sound/imx-audio-wm8974.txt | 48 ++++
sound/soc/fsl/Kconfig | 12 +
sound/soc/fsl/Makefile | 2 +
sound/soc/fsl/imx-wm8974.c | 233 ++++++++++++++++++++
4 files changed, 295 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/imx-audio-wm8974.txt
create mode 100644 sound/soc/fsl/imx-wm8974.c
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-wm8974.txt b/Documentation/devicetree/bindings/sound/imx-audio-wm8974.txt
new file mode 100644
index 0000000..7e661e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-wm8974.txt
@@ -0,0 +1,48 @@
+Freescale i.MX audio complex with WM8974 codec
+
+Required properties:
+- compatible : "fsl,imx-audio-wm8974"
+- model : The user-visible name of this sound complex
+- ssi-controller : The phandle of the i.MX SSI controller (imx21 compatible)
+- audio-codec : The phandle of the WM8974 audio codec
+- audio-routing : A list of the connections between audio components.
+ Each entry is a pair of strings, the first being the connection's sink,
+ the second being the connection's source. Valid names could be power
+ supplies, WM8974 pins, and the jacks on the board:
+
+ Power supplies:
+ * Mic Bias
+
+ WM8974 pins:
+ * MICN
+ * MICP
+ * AUX
+ * MONOOUT
+ * SPKOUTP
+ * SPKOUTN
+
+ Board connectors:
+ * Mic Jack
+ * Line In Jack
+ * Headphone Jack
+ * Line Out Jack
+ * Ext Spk
+
+- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX)
+- mux-ext-port : The external port of the i.MX audio muxer
+
+Note: The AUDMUX port numbering should start at 1, which is consistent with
+hardware manual.
+
+Example:
+
+sound {
+ compatible = "fsl,imx-audio-wm8974";
+ model = "wm8974";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&wm8974>;
+ audio-routing =
+ "Mic Jack", "Mic Bias",
+ mux-int-port = <1>;
+ mux-ext-port = <4>;
+};
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 4563b28..19d9b31 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -179,4 +179,16 @@ config SND_SOC_IMX_MC13783
select SND_SOC_MC13783
select SND_SOC_IMX_PCM_DMA
+config SND_SOC_IMX_WM8974
+ tristate "SoC Audio support for i.MX boards with WM8974"
+ depends on OF && SPI
+ select SND_SOC_IMX_AUDMUX
+ select SND_SOC_IMX_PCM_DMA
+ select SND_SOC_FSL_SSI
+ select SND_SOC_FSL_UTILS
+ select SND_SOC_WM8974
+ help
+ Say Y here if you want to add support for SoC audio on an i.MX board with
+ a wm8974 codec.
+
endif # SND_IMX_SOC
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 5f3cf3f..1a8ac3d 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -42,6 +42,7 @@ snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
snd-soc-wm1133-ev1-objs := wm1133-ev1.o
snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
snd-soc-imx-mc13783-objs := imx-mc13783.o
+snd-soc-imx-wm8974-objs := imx-wm8974.o
obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
@@ -49,3 +50,4 @@ 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
obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
+obj-$(CONFIG_SND_SOC_IMX_WM8974) += snd-soc-imx-wm8974.o
diff --git a/sound/soc/fsl/imx-wm8974.c b/sound/soc/fsl/imx-wm8974.c
new file mode 100644
index 0000000..02b239d
--- /dev/null
+++ b/sound/soc/fsl/imx-wm8974.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2012 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
+ * Steffen Trumtrar <s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <sound/soc.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/spi/spi.h>
+#include <linux/clk.h>
+
+#include "imx-audmux.h"
+#include "../codecs/wm8974.h"
+
+#define DRIVER_NAME "imx-wm8974"
+
+#define DAI_NAME_SIZE 32
+
+struct imx_wm8974_data {
+ struct snd_soc_dai_link dai;
+ struct snd_soc_card card;
+ char codec_dai_name[DAI_NAME_SIZE];
+ char platform_name[DAI_NAME_SIZE];
+ struct clk *codec_clk;
+ unsigned int clk_frequency;
+};
+
+static int imx_wm8974_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct imx_wm8974_data *data = container_of(rtd->card,
+ struct imx_wm8974_data, card);
+ struct device *dev = rtd->card->dev;
+ int ret;
+
+ /* the pll stability peaks at N=8 and around 90MHz.
+ * This values are best reached with a 12.288MHz or
+ * 11.289MHz clock. As the first is closer to N=8 in
+ * more situations, chose 12.288MHz as the target clock
+ * (ref: datasheet section "Master Clock and Phase Locked Loop")*/
+ ret = snd_soc_dai_set_pll(rtd->codec_dai, 0, 0, data->clk_frequency,
+ 12288000);
+ if (ret) {
+ dev_err(dev, "couldn't set pll: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_dapm_widget imx_wm8974_dapm_widgets[] = {
+ SND_SOC_DAPM_MIC("Mic Jack", NULL),
+ SND_SOC_DAPM_SPK("Ext Spk", NULL),
+};
+
+static int __devinit imx_wm8974_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *ssi_np, *codec_np;
+ struct device_node *audmux_np;
+ struct platform_device *ssi_pdev;
+ struct spi_device *codec_pdev;
+ struct imx_wm8974_data *data;
+ int int_port, ext_port;
+ int ret;
+
+ ret = of_property_read_u32(np, "mux-int-port", &int_port);
+ if (ret) {
+ dev_err(&pdev->dev, "mux-int-port missing or invalid\n");
+ return ret;
+ }
+ ret = of_property_read_u32(np, "mux-ext-port", &ext_port);
+ if (ret) {
+ dev_err(&pdev->dev, "mux-ext-port missing or invalid\n");
+ return ret;
+ }
+
+ /*
+ * The port numbering in the hardware manual starts at 1, while
+ * the audmux API expects it starts at 0.
+ */
+ int_port--;
+ ext_port--;
+
+ audmux_np = of_find_node_by_name(NULL, "audmux");
+ if (!audmux_np) {
+ dev_err(&pdev->dev, "audmux missing or invalid\n");
+ return ret;
+ }
+
+ if (of_device_is_compatible(audmux_np, "fsl,imx21-audmux")) {
+ ret = imx_audmux_v1_configure_port(int_port,
+ IMX_AUDMUX_V1_PCR_TFSDIR |
+ IMX_AUDMUX_V1_PCR_TCLKDIR |
+ IMX_AUDMUX_V1_PCR_TFCSEL(ext_port) |
+ IMX_AUDMUX_V1_PCR_RXDSEL(ext_port) |
+ IMX_AUDMUX_V1_PCR_SYN);
+ if (ret) {
+ dev_err(&pdev->dev, "audmux internal port setup failed\n");
+ return ret;
+ }
+ ret = imx_audmux_v1_configure_port(ext_port,
+ IMX_AUDMUX_V1_PCR_RXDSEL(int_port) |
+ IMX_AUDMUX_V1_PCR_SYN);
+ if (ret) {
+ dev_err(&pdev->dev, "audmux external port setup failed\n");
+ return ret;
+ }
+ } else {
+ dev_err(&pdev->dev, "audmux not compatible\n");
+ }
+ of_node_put(audmux_np);
+
+ ssi_np = of_parse_phandle(np, "ssi-controller", 0);
+ codec_np = of_parse_phandle(np, "audio-codec", 0);
+ if (!ssi_np || !codec_np) {
+ dev_err(&pdev->dev, "phandle missing or invalid\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ ssi_pdev = of_find_device_by_node(ssi_np);
+ if (!ssi_pdev) {
+ dev_err(&pdev->dev, "failed to find SSI platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ codec_pdev = of_find_spi_device_by_node(codec_np);
+ if (!codec_pdev) {
+ dev_err(&pdev->dev, "failed to find codec platform device\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ data->codec_clk = clk_get(&codec_pdev->dev, NULL);
+ if (IS_ERR(data->codec_clk)) {
+ data->codec_clk = NULL;
+ ret = of_property_read_u32(codec_np, "clock-frequency",
+ &data->clk_frequency);
+ if (ret) {
+ dev_err(&codec_pdev->dev,
+ "clock-frequency missing or invalid\n");
+ goto fail;
+ }
+ } else {
+ data->clk_frequency = clk_get_rate(data->codec_clk);
+ clk_prepare_enable(data->codec_clk);
+ }
+
+ data->dai.name = "HiFi";
+ data->dai.stream_name = "HiFi";
+ data->dai.codec_dai_name = "wm8974-hifi";
+ data->dai.codec_of_node = codec_np;
+ data->dai.cpu_dai_name = dev_name(&ssi_pdev->dev);
+ data->dai.platform_name = "imx-pcm-audio";
+ data->dai.init = &imx_wm8974_dai_init;
+ data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
+
+ data->card.dev = &pdev->dev;
+ ret = snd_soc_of_parse_card_name(&data->card, "model");
+ if (ret)
+ goto clk_fail;
+ ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
+ if (ret)
+ goto clk_fail;
+
+ data->card.name = "wm8974-hifi";
+ data->card.num_links = 1;
+ data->card.dai_link = &data->dai;
+ data->card.dapm_widgets = imx_wm8974_dapm_widgets;
+ data->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8974_dapm_widgets);
+
+ ret = snd_soc_register_card(&data->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+ goto clk_fail;
+ }
+
+ platform_set_drvdata(pdev, data);
+
+clk_fail:
+ clk_put(data->codec_clk);
+fail:
+ if (ssi_np)
+ of_node_put(ssi_np);
+ if (codec_np)
+ of_node_put(codec_np);
+ if (codec_pdev)
+ spi_dev_put(codec_pdev);
+ return ret;
+}
+
+static int __devexit imx_wm8974_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ snd_soc_unregister_card(card);
+
+ return 0;
+}
+
+static const struct of_device_id imx_wm8974_of_match[] __devinitconst = {
+ { .compatible = "fsl,imx-audio-wm8974", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_wm8974_of_match);
+
+static struct platform_driver imx_wm8974_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = imx_wm8974_of_match,
+ },
+ .probe = imx_wm8974_probe,
+ .remove = __devexit_p(imx_wm8974_remove),
+};
+module_platform_driver(imx_wm8974_driver);
+
+MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>");
+MODULE_AUTHOR("Steffen Trumtrar <s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
--
1.7.10.4
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_nov
^ permalink raw reply related [flat|nested] 16+ messages in thread