linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] ASoC: add es7241 support
@ 2018-07-03 13:28 Jerome Brunet
  2018-07-03 13:28 ` [PATCH v3 1/2] ASoC: es7241: add dt-bindings documentation for the es7241 adc Jerome Brunet
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Jerome Brunet @ 2018-07-03 13:28 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown; +Cc: Jerome Brunet, alsa-devel, linux-kernel

Add support for the es7241 which is a simple 2 channels analog to
digital converter.

Changes since v1: [0]
 * Add missing break as reported by smatch [1]
   My device is hardwired in slave mode, which probably why this slipped
   through unnoticed.

Changes since v2: [2]
 * Supply are now required dt properties
 * Add a dt property to state the serial interface configuration

[0]: https://lkml.kernel.org/r/20180629152444.21525-1-jbrunet@baylibre.com
[1]: https://lkml.kernel.org/r/20180630082829.qwnhkk4f76n32omm@mwanda
[2]: https://lkml.kernel.org/r/20180630172241.10806-1-jbrunet@baylibre.com

Jerome Brunet (2):
  ASoC: es7241: add dt-bindings documentation for the es7241 adc
  ASoC: es7241: add es7241 codec support

 .../devicetree/bindings/sound/everest,es7241.txt   |  28 ++
 sound/soc/codecs/Kconfig                           |   4 +
 sound/soc/codecs/Makefile                          |   2 +
 sound/soc/codecs/es7241.c                          | 322 +++++++++++++++++++++
 4 files changed, 356 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/everest,es7241.txt
 create mode 100644 sound/soc/codecs/es7241.c

-- 
2.14.4


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

* [PATCH v3 1/2] ASoC: es7241: add dt-bindings documentation for the es7241 adc
  2018-07-03 13:28 [PATCH v3 0/2] ASoC: add es7241 support Jerome Brunet
@ 2018-07-03 13:28 ` Jerome Brunet
  2018-07-03 15:34   ` Applied "ASoC: es7241: add dt-bindings documentation for the es7241 adc" to the asoc tree Mark Brown
  2018-07-03 13:28 ` [PATCH v3 2/2] ASoC: es7241: add es7241 codec support Jerome Brunet
  2018-07-03 15:32 ` [PATCH v3 0/2] ASoC: add es7241 support Mark Brown
  2 siblings, 1 reply; 9+ messages in thread
From: Jerome Brunet @ 2018-07-03 13:28 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown; +Cc: Jerome Brunet, alsa-devel, linux-kernel

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
 .../devicetree/bindings/sound/everest,es7241.txt   | 28 ++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/everest,es7241.txt

diff --git a/Documentation/devicetree/bindings/sound/everest,es7241.txt b/Documentation/devicetree/bindings/sound/everest,es7241.txt
new file mode 100644
index 000000000000..28f82cf4959f
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/everest,es7241.txt
@@ -0,0 +1,28 @@
+ES7241 i2s AD converter
+
+Required properties:
+- compatible : "everest,es7241"
+- VDDP-supply: regulator phandle for the VDDA supply
+- VDDA-supply: regulator phandle for the VDDP supply
+- VDDD-supply: regulator phandle for the VDDD supply
+
+Optional properties:
+- reset-gpios: gpio connected to the reset pin
+- m0-gpios   : gpio connected to the m0 pin
+- m1-gpios   : gpio connected to the m1 pin
+- everest,sdout-pull-down:
+   Format used by the serial interface is controlled by pulling
+   the sdout. If the sdout is pulled down, leftj format is used.
+   If this property is not provided, sdout is assumed to pulled
+   up and i2s format is used
+
+Example:
+
+linein: audio-codec@2 {
+	#sound-dai-cells = <0>;
+	compatible = "everest,es7241";
+	VDDA-supply = <&vcc_3v3>;
+	VDDP-supply = <&vcc_3v3>;
+	VDDD-supply = <&vcc_3v3>;
+	reset-gpios = <&gpio GPIOH_42>;
+};
-- 
2.14.4


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

* [PATCH v3 2/2] ASoC: es7241: add es7241 codec support
  2018-07-03 13:28 [PATCH v3 0/2] ASoC: add es7241 support Jerome Brunet
  2018-07-03 13:28 ` [PATCH v3 1/2] ASoC: es7241: add dt-bindings documentation for the es7241 adc Jerome Brunet
@ 2018-07-03 13:28 ` Jerome Brunet
  2018-07-03 15:34   ` Applied "ASoC: es7241: add es7241 codec support" to the asoc tree Mark Brown
  2018-07-03 15:32 ` [PATCH v3 0/2] ASoC: add es7241 support Mark Brown
  2 siblings, 1 reply; 9+ messages in thread
From: Jerome Brunet @ 2018-07-03 13:28 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown; +Cc: Jerome Brunet, alsa-devel, linux-kernel

Add support for the everest es7241 which is a simple 2 channels
analog to digital converter.

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
 sound/soc/codecs/Kconfig  |   4 +
 sound/soc/codecs/Makefile |   2 +
 sound/soc/codecs/es7241.c | 322 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 328 insertions(+)
 create mode 100644 sound/soc/codecs/es7241.c

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index f5839eeeed5e..047ac28ba40f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -79,6 +79,7 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_ES8328_SPI if SPI_MASTER
 	select SND_SOC_ES8328_I2C if I2C
 	select SND_SOC_ES7134
+	select SND_SOC_ES7241
 	select SND_SOC_GTM601
 	select SND_SOC_HDAC_HDMI
 	select SND_SOC_ICS43432
@@ -584,6 +585,9 @@ config SND_SOC_HDMI_CODEC
 config SND_SOC_ES7134
        tristate "Everest Semi ES7134 CODEC"
 
+config SND_SOC_ES7241
+       tristate "Everest Semi ES7241 CODEC"
+
 config SND_SOC_ES8316
 	tristate "Everest Semi ES8316 CODEC"
 	depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 6cc15d1c5767..719653a4c882 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -71,6 +71,7 @@ snd-soc-da732x-objs := da732x.o
 snd-soc-da9055-objs := da9055.o
 snd-soc-dmic-objs := dmic.o
 snd-soc-es7134-objs := es7134.o
+snd-soc-es7241-objs := es7241.o
 snd-soc-es8316-objs := es8316.o
 snd-soc-es8328-objs := es8328.o
 snd-soc-es8328-i2c-objs := es8328-i2c.o
@@ -329,6 +330,7 @@ obj-$(CONFIG_SND_SOC_DA732X)	+= snd-soc-da732x.o
 obj-$(CONFIG_SND_SOC_DA9055)	+= snd-soc-da9055.o
 obj-$(CONFIG_SND_SOC_DMIC)	+= snd-soc-dmic.o
 obj-$(CONFIG_SND_SOC_ES7134)	+= snd-soc-es7134.o
+obj-$(CONFIG_SND_SOC_ES7241)	+= snd-soc-es7241.o
 obj-$(CONFIG_SND_SOC_ES8316)    += snd-soc-es8316.o
 obj-$(CONFIG_SND_SOC_ES8328)	+= snd-soc-es8328.o
 obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o
diff --git a/sound/soc/codecs/es7241.c b/sound/soc/codecs/es7241.c
new file mode 100644
index 000000000000..87991bd4acef
--- /dev/null
+++ b/sound/soc/codecs/es7241.c
@@ -0,0 +1,322 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2018 BayLibre, SAS.
+// Author: Jerome Brunet <jbrunet@baylibre.com>
+
+#include <linux/gpio/consumer.h>
+#include <linux/of_platform.h>
+#include <linux/module.h>
+#include <sound/soc.h>
+
+struct es7241_clock_mode {
+	unsigned int rate_min;
+	unsigned int rate_max;
+	unsigned int *slv_mfs;
+	unsigned int slv_mfs_num;
+	unsigned int mst_mfs;
+	unsigned int mst_m0:1;
+	unsigned int mst_m1:1;
+};
+
+struct es7241_chip {
+	const struct es7241_clock_mode *modes;
+	unsigned int mode_num;
+};
+
+struct es7241_data {
+	struct gpio_desc *reset;
+	struct gpio_desc *m0;
+	struct gpio_desc *m1;
+	unsigned int fmt;
+	unsigned int mclk;
+	bool is_slave;
+	const struct es7241_chip *chip;
+};
+
+static void es7241_set_mode(struct es7241_data *priv,  int m0, int m1)
+{
+	/* put the device in reset */
+	gpiod_set_value_cansleep(priv->reset, 0);
+
+	/* set the mode */
+	gpiod_set_value_cansleep(priv->m0, m0);
+	gpiod_set_value_cansleep(priv->m1, m1);
+
+	/* take the device out of reset - datasheet does not specify a delay */
+	gpiod_set_value_cansleep(priv->reset, 1);
+}
+
+static int es7241_set_slave_mode(struct es7241_data *priv,
+				 const struct es7241_clock_mode *mode,
+				 unsigned int mfs)
+{
+	int j;
+
+	if (!mfs)
+		goto out_ok;
+
+	for (j = 0; j < mode->slv_mfs_num; j++) {
+		if (mode->slv_mfs[j] == mfs)
+			goto out_ok;
+	}
+
+	return -EINVAL;
+
+out_ok:
+	es7241_set_mode(priv, 1, 1);
+	return 0;
+}
+
+static int es7241_set_master_mode(struct es7241_data *priv,
+				  const struct es7241_clock_mode *mode,
+				  unsigned int mfs)
+{
+	/*
+	 * We can't really set clock ratio, if the mclk/lrclk is different
+	 * from what we provide, then error out
+	 */
+	if (mfs && mfs != mode->mst_mfs)
+		return -EINVAL;
+
+	es7241_set_mode(priv, mode->mst_m0, mode->mst_m1);
+
+	return 0;
+}
+
+static int es7241_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	struct es7241_data *priv = snd_soc_dai_get_drvdata(dai);
+	unsigned int rate = params_rate(params);
+	unsigned int mfs = priv->mclk / rate;
+	int i;
+
+	for (i = 0; i < priv->chip->mode_num; i++) {
+		const struct es7241_clock_mode *mode = &priv->chip->modes[i];
+
+		if (rate < mode->rate_min || rate >= mode->rate_max)
+			continue;
+
+		if (priv->is_slave)
+			return es7241_set_slave_mode(priv, mode, mfs);
+		else
+			return es7241_set_master_mode(priv, mode, mfs);
+	}
+
+	/* should not happen */
+	dev_err(dai->dev, "unsupported rate: %u\n", rate);
+	return -EINVAL;
+}
+
+static int es7241_set_sysclk(struct snd_soc_dai *dai, int clk_id,
+			     unsigned int freq, int dir)
+{
+	struct es7241_data *priv = snd_soc_dai_get_drvdata(dai);
+
+	if (dir == SND_SOC_CLOCK_IN && clk_id == 0) {
+		priv->mclk = freq;
+		return 0;
+	}
+
+	return -ENOTSUPP;
+}
+
+static int es7241_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct es7241_data *priv = snd_soc_dai_get_drvdata(dai);
+
+	if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) {
+		dev_err(dai->dev, "Unsupported dai clock inversion\n");
+		return -EINVAL;
+	}
+
+	if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != priv->fmt) {
+		dev_err(dai->dev, "Invalid dai format\n");
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBS_CFS:
+		priv->is_slave = true;
+		break;
+	case SND_SOC_DAIFMT_CBM_CFM:
+		priv->is_slave = false;
+		break;
+
+	default:
+		dev_err(dai->dev, "Unsupported clock configuration\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops es7241_dai_ops = {
+	.set_fmt	= es7241_set_fmt,
+	.hw_params	= es7241_hw_params,
+	.set_sysclk	= es7241_set_sysclk,
+};
+
+static struct snd_soc_dai_driver es7241_dai = {
+	.name = "es7241-hifi",
+	.capture = {
+		.stream_name = "Capture",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_192000,
+		.formats = (SNDRV_PCM_FMTBIT_S16_LE  |
+			    SNDRV_PCM_FMTBIT_S24_3LE |
+			    SNDRV_PCM_FMTBIT_S24_LE),
+	},
+	.ops = &es7241_dai_ops,
+};
+
+static const struct es7241_clock_mode es7241_modes[] = {
+	{
+		/* Single speed mode */
+		.rate_min = 8000,
+		.rate_max = 50000,
+		.slv_mfs = (unsigned int[]) { 256, 384, 512, 768, 1024 },
+		.slv_mfs_num = 5,
+		.mst_mfs = 256,
+		.mst_m0 = 0,
+		.mst_m1 = 0,
+	}, {
+		/* Double speed mode */
+		.rate_min = 50000,
+		.rate_max = 100000,
+		.slv_mfs = (unsigned int[]) { 128, 192 },
+		.slv_mfs_num = 2,
+		.mst_mfs = 128,
+		.mst_m0 = 1,
+		.mst_m1 = 0,
+	}, {
+		/* Quad speed mode */
+		.rate_min = 100000,
+		.rate_max = 200000,
+		.slv_mfs = (unsigned int[]) { 64 },
+		.slv_mfs_num = 1,
+		.mst_mfs = 64,
+		.mst_m0 = 0,
+		.mst_m1 = 1,
+	},
+};
+
+static const struct es7241_chip es7241_chip = {
+	.modes = es7241_modes,
+	.mode_num = ARRAY_SIZE(es7241_modes),
+};
+
+static const struct snd_soc_dapm_widget es7241_dapm_widgets[] = {
+	SND_SOC_DAPM_INPUT("AINL"),
+	SND_SOC_DAPM_INPUT("AINR"),
+	SND_SOC_DAPM_DAC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_REGULATOR_SUPPLY("VDDP", 0, 0),
+	SND_SOC_DAPM_REGULATOR_SUPPLY("VDDD", 0, 0),
+	SND_SOC_DAPM_REGULATOR_SUPPLY("VDDA", 0, 0),
+};
+
+static const struct snd_soc_dapm_route es7241_dapm_routes[] = {
+	{ "ADC", NULL, "AINL", },
+	{ "ADC", NULL, "AINR", },
+	{ "ADC", NULL, "VDDA", },
+	{ "Capture", NULL, "VDDP", },
+	{ "Capture", NULL, "VDDD", },
+};
+
+static const struct snd_soc_component_driver es7241_component_driver = {
+	.dapm_widgets		= es7241_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(es7241_dapm_widgets),
+	.dapm_routes		= es7241_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(es7241_dapm_routes),
+	.idle_bias_on		= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
+};
+
+static void es7241_parse_fmt(struct device *dev, struct es7241_data *priv)
+{
+	bool is_leftj;
+
+	/*
+	 * The format is given by a pull resistor on the SDOUT pin:
+	 * pull-up for i2s, pull-down for left justified.
+	 */
+	is_leftj = of_property_read_bool(dev->of_node,
+					 "everest,sdout-pull-down");
+	if (is_leftj)
+		priv->fmt = SND_SOC_DAIFMT_LEFT_J;
+	else
+		priv->fmt = SND_SOC_DAIFMT_I2S;
+}
+
+static int es7241_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct es7241_data *priv;
+	int err;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, priv);
+
+	priv->chip = of_device_get_match_data(dev);
+	if (!priv->chip) {
+		dev_err(dev, "failed to match device\n");
+		return -ENODEV;
+	}
+
+	es7241_parse_fmt(dev, priv);
+
+	priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(priv->reset)) {
+		err = PTR_ERR(priv->reset);
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get 'reset' gpio: %d", err);
+		return err;
+	}
+
+	priv->m0 = devm_gpiod_get_optional(dev, "m0", GPIOD_OUT_LOW);
+	if (IS_ERR(priv->m0)) {
+		err = PTR_ERR(priv->m0);
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get 'm0' gpio: %d", err);
+		return err;
+	}
+
+	priv->m1 = devm_gpiod_get_optional(dev, "m1", GPIOD_OUT_LOW);
+	if (IS_ERR(priv->m1)) {
+		err = PTR_ERR(priv->m1);
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get 'm1' gpio: %d", err);
+		return err;
+	}
+
+	return devm_snd_soc_register_component(&pdev->dev,
+				      &es7241_component_driver,
+				      &es7241_dai, 1);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id es7241_ids[] = {
+	{ .compatible = "everest,es7241", .data = &es7241_chip },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, es7241_ids);
+#endif
+
+static struct platform_driver es7241_driver = {
+	.driver = {
+		.name = "es7241",
+		.of_match_table = of_match_ptr(es7241_ids),
+	},
+	.probe = es7241_probe,
+};
+
+module_platform_driver(es7241_driver);
+
+MODULE_DESCRIPTION("ASoC ES7241 audio codec driver");
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
+MODULE_LICENSE("GPL");
-- 
2.14.4


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

* Re: [PATCH v3 0/2] ASoC: add es7241 support
  2018-07-03 13:28 [PATCH v3 0/2] ASoC: add es7241 support Jerome Brunet
  2018-07-03 13:28 ` [PATCH v3 1/2] ASoC: es7241: add dt-bindings documentation for the es7241 adc Jerome Brunet
  2018-07-03 13:28 ` [PATCH v3 2/2] ASoC: es7241: add es7241 codec support Jerome Brunet
@ 2018-07-03 15:32 ` Mark Brown
  2018-07-03 15:36   ` Jerome Brunet
  2 siblings, 1 reply; 9+ messages in thread
From: Mark Brown @ 2018-07-03 15:32 UTC (permalink / raw)
  To: Jerome Brunet; +Cc: Liam Girdwood, alsa-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 557 bytes --]

On Tue, Jul 03, 2018 at 03:28:43PM +0200, Jerome Brunet wrote:
> Add support for the es7241 which is a simple 2 channels analog to
> digital converter.

Please don't resubmit patches that have already been applied, you should
submit patches against current code in the tree you're expecting things
to be applied to.  If any updates are needed to a patch that's already
been applied you should submit incremental patches which make those
updates.  This avoids having to change published git commits which could
cause problems for people working against git.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Applied "ASoC: es7241: add es7241 codec support" to the asoc tree
  2018-07-03 13:28 ` [PATCH v3 2/2] ASoC: es7241: add es7241 codec support Jerome Brunet
@ 2018-07-03 15:34   ` Mark Brown
  0 siblings, 0 replies; 9+ messages in thread
From: Mark Brown @ 2018-07-03 15:34 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: Mark Brown, Liam Girdwood, Mark Brown, alsa-devel, linux-kernel,
	alsa-devel

The patch

   ASoC: es7241: add es7241 codec support

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From 5f7bdc466c772b3af3145a71724965ecdc03e6bf Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Tue, 3 Jul 2018 15:28:45 +0200
Subject: [PATCH] ASoC: es7241: add es7241 codec support

Add support for the everest es7241 which is a simple 2 channels
analog to digital converter.

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/Kconfig  |   4 +
 sound/soc/codecs/Makefile |   2 +
 sound/soc/codecs/es7241.c | 322 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 328 insertions(+)
 create mode 100644 sound/soc/codecs/es7241.c

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 6d1674699385..efb095dbcd71 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -79,6 +79,7 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_ES8328_SPI if SPI_MASTER
 	select SND_SOC_ES8328_I2C if I2C
 	select SND_SOC_ES7134
+	select SND_SOC_ES7241
 	select SND_SOC_GTM601
 	select SND_SOC_HDAC_HDMI
 	select SND_SOC_ICS43432
@@ -585,6 +586,9 @@ config SND_SOC_HDMI_CODEC
 config SND_SOC_ES7134
        tristate "Everest Semi ES7134 CODEC"
 
+config SND_SOC_ES7241
+       tristate "Everest Semi ES7241 CODEC"
+
 config SND_SOC_ES8316
 	tristate "Everest Semi ES8316 CODEC"
 	depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f26ded89a1e5..7ae7c85e8219 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -71,6 +71,7 @@ snd-soc-da732x-objs := da732x.o
 snd-soc-da9055-objs := da9055.o
 snd-soc-dmic-objs := dmic.o
 snd-soc-es7134-objs := es7134.o
+snd-soc-es7241-objs := es7241.o
 snd-soc-es8316-objs := es8316.o
 snd-soc-es8328-objs := es8328.o
 snd-soc-es8328-i2c-objs := es8328-i2c.o
@@ -330,6 +331,7 @@ obj-$(CONFIG_SND_SOC_DA732X)	+= snd-soc-da732x.o
 obj-$(CONFIG_SND_SOC_DA9055)	+= snd-soc-da9055.o
 obj-$(CONFIG_SND_SOC_DMIC)	+= snd-soc-dmic.o
 obj-$(CONFIG_SND_SOC_ES7134)	+= snd-soc-es7134.o
+obj-$(CONFIG_SND_SOC_ES7241)	+= snd-soc-es7241.o
 obj-$(CONFIG_SND_SOC_ES8316)    += snd-soc-es8316.o
 obj-$(CONFIG_SND_SOC_ES8328)	+= snd-soc-es8328.o
 obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o
diff --git a/sound/soc/codecs/es7241.c b/sound/soc/codecs/es7241.c
new file mode 100644
index 000000000000..87991bd4acef
--- /dev/null
+++ b/sound/soc/codecs/es7241.c
@@ -0,0 +1,322 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2018 BayLibre, SAS.
+// Author: Jerome Brunet <jbrunet@baylibre.com>
+
+#include <linux/gpio/consumer.h>
+#include <linux/of_platform.h>
+#include <linux/module.h>
+#include <sound/soc.h>
+
+struct es7241_clock_mode {
+	unsigned int rate_min;
+	unsigned int rate_max;
+	unsigned int *slv_mfs;
+	unsigned int slv_mfs_num;
+	unsigned int mst_mfs;
+	unsigned int mst_m0:1;
+	unsigned int mst_m1:1;
+};
+
+struct es7241_chip {
+	const struct es7241_clock_mode *modes;
+	unsigned int mode_num;
+};
+
+struct es7241_data {
+	struct gpio_desc *reset;
+	struct gpio_desc *m0;
+	struct gpio_desc *m1;
+	unsigned int fmt;
+	unsigned int mclk;
+	bool is_slave;
+	const struct es7241_chip *chip;
+};
+
+static void es7241_set_mode(struct es7241_data *priv,  int m0, int m1)
+{
+	/* put the device in reset */
+	gpiod_set_value_cansleep(priv->reset, 0);
+
+	/* set the mode */
+	gpiod_set_value_cansleep(priv->m0, m0);
+	gpiod_set_value_cansleep(priv->m1, m1);
+
+	/* take the device out of reset - datasheet does not specify a delay */
+	gpiod_set_value_cansleep(priv->reset, 1);
+}
+
+static int es7241_set_slave_mode(struct es7241_data *priv,
+				 const struct es7241_clock_mode *mode,
+				 unsigned int mfs)
+{
+	int j;
+
+	if (!mfs)
+		goto out_ok;
+
+	for (j = 0; j < mode->slv_mfs_num; j++) {
+		if (mode->slv_mfs[j] == mfs)
+			goto out_ok;
+	}
+
+	return -EINVAL;
+
+out_ok:
+	es7241_set_mode(priv, 1, 1);
+	return 0;
+}
+
+static int es7241_set_master_mode(struct es7241_data *priv,
+				  const struct es7241_clock_mode *mode,
+				  unsigned int mfs)
+{
+	/*
+	 * We can't really set clock ratio, if the mclk/lrclk is different
+	 * from what we provide, then error out
+	 */
+	if (mfs && mfs != mode->mst_mfs)
+		return -EINVAL;
+
+	es7241_set_mode(priv, mode->mst_m0, mode->mst_m1);
+
+	return 0;
+}
+
+static int es7241_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	struct es7241_data *priv = snd_soc_dai_get_drvdata(dai);
+	unsigned int rate = params_rate(params);
+	unsigned int mfs = priv->mclk / rate;
+	int i;
+
+	for (i = 0; i < priv->chip->mode_num; i++) {
+		const struct es7241_clock_mode *mode = &priv->chip->modes[i];
+
+		if (rate < mode->rate_min || rate >= mode->rate_max)
+			continue;
+
+		if (priv->is_slave)
+			return es7241_set_slave_mode(priv, mode, mfs);
+		else
+			return es7241_set_master_mode(priv, mode, mfs);
+	}
+
+	/* should not happen */
+	dev_err(dai->dev, "unsupported rate: %u\n", rate);
+	return -EINVAL;
+}
+
+static int es7241_set_sysclk(struct snd_soc_dai *dai, int clk_id,
+			     unsigned int freq, int dir)
+{
+	struct es7241_data *priv = snd_soc_dai_get_drvdata(dai);
+
+	if (dir == SND_SOC_CLOCK_IN && clk_id == 0) {
+		priv->mclk = freq;
+		return 0;
+	}
+
+	return -ENOTSUPP;
+}
+
+static int es7241_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct es7241_data *priv = snd_soc_dai_get_drvdata(dai);
+
+	if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) {
+		dev_err(dai->dev, "Unsupported dai clock inversion\n");
+		return -EINVAL;
+	}
+
+	if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != priv->fmt) {
+		dev_err(dai->dev, "Invalid dai format\n");
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBS_CFS:
+		priv->is_slave = true;
+		break;
+	case SND_SOC_DAIFMT_CBM_CFM:
+		priv->is_slave = false;
+		break;
+
+	default:
+		dev_err(dai->dev, "Unsupported clock configuration\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops es7241_dai_ops = {
+	.set_fmt	= es7241_set_fmt,
+	.hw_params	= es7241_hw_params,
+	.set_sysclk	= es7241_set_sysclk,
+};
+
+static struct snd_soc_dai_driver es7241_dai = {
+	.name = "es7241-hifi",
+	.capture = {
+		.stream_name = "Capture",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_192000,
+		.formats = (SNDRV_PCM_FMTBIT_S16_LE  |
+			    SNDRV_PCM_FMTBIT_S24_3LE |
+			    SNDRV_PCM_FMTBIT_S24_LE),
+	},
+	.ops = &es7241_dai_ops,
+};
+
+static const struct es7241_clock_mode es7241_modes[] = {
+	{
+		/* Single speed mode */
+		.rate_min = 8000,
+		.rate_max = 50000,
+		.slv_mfs = (unsigned int[]) { 256, 384, 512, 768, 1024 },
+		.slv_mfs_num = 5,
+		.mst_mfs = 256,
+		.mst_m0 = 0,
+		.mst_m1 = 0,
+	}, {
+		/* Double speed mode */
+		.rate_min = 50000,
+		.rate_max = 100000,
+		.slv_mfs = (unsigned int[]) { 128, 192 },
+		.slv_mfs_num = 2,
+		.mst_mfs = 128,
+		.mst_m0 = 1,
+		.mst_m1 = 0,
+	}, {
+		/* Quad speed mode */
+		.rate_min = 100000,
+		.rate_max = 200000,
+		.slv_mfs = (unsigned int[]) { 64 },
+		.slv_mfs_num = 1,
+		.mst_mfs = 64,
+		.mst_m0 = 0,
+		.mst_m1 = 1,
+	},
+};
+
+static const struct es7241_chip es7241_chip = {
+	.modes = es7241_modes,
+	.mode_num = ARRAY_SIZE(es7241_modes),
+};
+
+static const struct snd_soc_dapm_widget es7241_dapm_widgets[] = {
+	SND_SOC_DAPM_INPUT("AINL"),
+	SND_SOC_DAPM_INPUT("AINR"),
+	SND_SOC_DAPM_DAC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_REGULATOR_SUPPLY("VDDP", 0, 0),
+	SND_SOC_DAPM_REGULATOR_SUPPLY("VDDD", 0, 0),
+	SND_SOC_DAPM_REGULATOR_SUPPLY("VDDA", 0, 0),
+};
+
+static const struct snd_soc_dapm_route es7241_dapm_routes[] = {
+	{ "ADC", NULL, "AINL", },
+	{ "ADC", NULL, "AINR", },
+	{ "ADC", NULL, "VDDA", },
+	{ "Capture", NULL, "VDDP", },
+	{ "Capture", NULL, "VDDD", },
+};
+
+static const struct snd_soc_component_driver es7241_component_driver = {
+	.dapm_widgets		= es7241_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(es7241_dapm_widgets),
+	.dapm_routes		= es7241_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(es7241_dapm_routes),
+	.idle_bias_on		= 1,
+	.endianness		= 1,
+	.non_legacy_dai_naming	= 1,
+};
+
+static void es7241_parse_fmt(struct device *dev, struct es7241_data *priv)
+{
+	bool is_leftj;
+
+	/*
+	 * The format is given by a pull resistor on the SDOUT pin:
+	 * pull-up for i2s, pull-down for left justified.
+	 */
+	is_leftj = of_property_read_bool(dev->of_node,
+					 "everest,sdout-pull-down");
+	if (is_leftj)
+		priv->fmt = SND_SOC_DAIFMT_LEFT_J;
+	else
+		priv->fmt = SND_SOC_DAIFMT_I2S;
+}
+
+static int es7241_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct es7241_data *priv;
+	int err;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, priv);
+
+	priv->chip = of_device_get_match_data(dev);
+	if (!priv->chip) {
+		dev_err(dev, "failed to match device\n");
+		return -ENODEV;
+	}
+
+	es7241_parse_fmt(dev, priv);
+
+	priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(priv->reset)) {
+		err = PTR_ERR(priv->reset);
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get 'reset' gpio: %d", err);
+		return err;
+	}
+
+	priv->m0 = devm_gpiod_get_optional(dev, "m0", GPIOD_OUT_LOW);
+	if (IS_ERR(priv->m0)) {
+		err = PTR_ERR(priv->m0);
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get 'm0' gpio: %d", err);
+		return err;
+	}
+
+	priv->m1 = devm_gpiod_get_optional(dev, "m1", GPIOD_OUT_LOW);
+	if (IS_ERR(priv->m1)) {
+		err = PTR_ERR(priv->m1);
+		if (err != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get 'm1' gpio: %d", err);
+		return err;
+	}
+
+	return devm_snd_soc_register_component(&pdev->dev,
+				      &es7241_component_driver,
+				      &es7241_dai, 1);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id es7241_ids[] = {
+	{ .compatible = "everest,es7241", .data = &es7241_chip },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, es7241_ids);
+#endif
+
+static struct platform_driver es7241_driver = {
+	.driver = {
+		.name = "es7241",
+		.of_match_table = of_match_ptr(es7241_ids),
+	},
+	.probe = es7241_probe,
+};
+
+module_platform_driver(es7241_driver);
+
+MODULE_DESCRIPTION("ASoC ES7241 audio codec driver");
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
+MODULE_LICENSE("GPL");
-- 
2.18.0.rc2


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

* Applied "ASoC: es7241: add dt-bindings documentation for the es7241 adc" to the asoc tree
  2018-07-03 13:28 ` [PATCH v3 1/2] ASoC: es7241: add dt-bindings documentation for the es7241 adc Jerome Brunet
@ 2018-07-03 15:34   ` Mark Brown
  0 siblings, 0 replies; 9+ messages in thread
From: Mark Brown @ 2018-07-03 15:34 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: Mark Brown, Liam Girdwood, Mark Brown, alsa-devel, linux-kernel,
	alsa-devel

The patch

   ASoC: es7241: add dt-bindings documentation for the es7241 adc

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From 1b8fc56ed514f815c4779273348c3308fb263c87 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Tue, 3 Jul 2018 15:28:44 +0200
Subject: [PATCH] ASoC: es7241: add dt-bindings documentation for the es7241
 adc

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 .../bindings/sound/everest,es7241.txt         | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/everest,es7241.txt

diff --git a/Documentation/devicetree/bindings/sound/everest,es7241.txt b/Documentation/devicetree/bindings/sound/everest,es7241.txt
new file mode 100644
index 000000000000..28f82cf4959f
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/everest,es7241.txt
@@ -0,0 +1,28 @@
+ES7241 i2s AD converter
+
+Required properties:
+- compatible : "everest,es7241"
+- VDDP-supply: regulator phandle for the VDDA supply
+- VDDA-supply: regulator phandle for the VDDP supply
+- VDDD-supply: regulator phandle for the VDDD supply
+
+Optional properties:
+- reset-gpios: gpio connected to the reset pin
+- m0-gpios   : gpio connected to the m0 pin
+- m1-gpios   : gpio connected to the m1 pin
+- everest,sdout-pull-down:
+   Format used by the serial interface is controlled by pulling
+   the sdout. If the sdout is pulled down, leftj format is used.
+   If this property is not provided, sdout is assumed to pulled
+   up and i2s format is used
+
+Example:
+
+linein: audio-codec@2 {
+	#sound-dai-cells = <0>;
+	compatible = "everest,es7241";
+	VDDA-supply = <&vcc_3v3>;
+	VDDP-supply = <&vcc_3v3>;
+	VDDD-supply = <&vcc_3v3>;
+	reset-gpios = <&gpio GPIOH_42>;
+};
-- 
2.18.0.rc2


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

* Re: [PATCH v3 0/2] ASoC: add es7241 support
  2018-07-03 15:32 ` [PATCH v3 0/2] ASoC: add es7241 support Mark Brown
@ 2018-07-03 15:36   ` Jerome Brunet
  2018-07-03 15:41     ` Mark Brown
  0 siblings, 1 reply; 9+ messages in thread
From: Jerome Brunet @ 2018-07-03 15:36 UTC (permalink / raw)
  To: Mark Brown; +Cc: Liam Girdwood, alsa-devel, linux-kernel

On Tue, 2018-07-03 at 16:32 +0100, Mark Brown wrote:
> On Tue, Jul 03, 2018 at 03:28:43PM +0200, Jerome Brunet wrote:
> > Add support for the es7241 which is a simple 2 channels analog to
> > digital converter.
> 
> Please don't resubmit patches that have already been applied, you should
> submit patches against current code in the tree you're expecting things
> to be applied to.  If any updates are needed to a patch that's already
> been applied you should submit incremental patches which make those
> updates.  This avoids having to change published git commits which could
> cause problems for people working against git.

Unless I missed something, which entirely possible, I don't think any patches of
this series have been applied yet. You asked me resubmit after the v1 because of
 power supply bindings and the mode selection.

I don't see anything related to the es7241 in your tree ATM.





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

* Re: [PATCH v3 0/2] ASoC: add es7241 support
  2018-07-03 15:36   ` Jerome Brunet
@ 2018-07-03 15:41     ` Mark Brown
  2018-07-03 15:59       ` Jerome Brunet
  0 siblings, 1 reply; 9+ messages in thread
From: Mark Brown @ 2018-07-03 15:41 UTC (permalink / raw)
  To: Jerome Brunet; +Cc: Liam Girdwood, alsa-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 461 bytes --]

On Tue, Jul 03, 2018 at 05:36:19PM +0200, Jerome Brunet wrote:

> Unless I missed something, which entirely possible, I don't think any patches of
> this series have been applied yet. You asked me resubmit after the v1 because of
>  power supply bindings and the mode selection.

> I don't see anything related to the es7241 in your tree ATM.

Oh, my mistake sorry - I must have copied it into my to apply queue
twice so got a reject on the second application.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH v3 0/2] ASoC: add es7241 support
  2018-07-03 15:41     ` Mark Brown
@ 2018-07-03 15:59       ` Jerome Brunet
  0 siblings, 0 replies; 9+ messages in thread
From: Jerome Brunet @ 2018-07-03 15:59 UTC (permalink / raw)
  To: Mark Brown; +Cc: Liam Girdwood, alsa-devel, linux-kernel

On Tue, 2018-07-03 at 16:41 +0100, Mark Brown wrote:
> On Tue, Jul 03, 2018 at 05:36:19PM +0200, Jerome Brunet wrote:
> 
> > Unless I missed something, which entirely possible, I don't think any patches of
> > this series have been applied yet. You asked me resubmit after the v1 because of
> >  power supply bindings and the mode selection.
> > I don't see anything related to the es7241 in your tree ATM.
> 
> Oh, my mistake sorry - I must have copied it into my to apply queue
> twice so got a reject on the second application.

No worries. Just wanted to make sure.
Thanks !

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

end of thread, other threads:[~2018-07-03 15:59 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-03 13:28 [PATCH v3 0/2] ASoC: add es7241 support Jerome Brunet
2018-07-03 13:28 ` [PATCH v3 1/2] ASoC: es7241: add dt-bindings documentation for the es7241 adc Jerome Brunet
2018-07-03 15:34   ` Applied "ASoC: es7241: add dt-bindings documentation for the es7241 adc" to the asoc tree Mark Brown
2018-07-03 13:28 ` [PATCH v3 2/2] ASoC: es7241: add es7241 codec support Jerome Brunet
2018-07-03 15:34   ` Applied "ASoC: es7241: add es7241 codec support" to the asoc tree Mark Brown
2018-07-03 15:32 ` [PATCH v3 0/2] ASoC: add es7241 support Mark Brown
2018-07-03 15:36   ` Jerome Brunet
2018-07-03 15:41     ` Mark Brown
2018-07-03 15:59       ` Jerome Brunet

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).