[alsa-devel] [RFC PATCH 0/3] ASoC: pcm1792a: Add support for pcm1795 and pcm1796
Those patches add support for pcm1795 and pcm1796. Both are compatible with the pcm1792a with a minor change for the pcm1795
Michael Trimarchi (3): ASoC: pcm1792a: Rename internal data and function to pcm179x ASoC: pcm1792a: Rename pcm1792a to pcm179x ASoC: pcm179x: Add support for pcm1795 and pcm1796
.../devicetree/bindings/sound/pcm1792a.txt | 18 -- .../devicetree/bindings/sound/pcm179x.txt | 18 ++ sound/soc/codecs/Kconfig | 6 +- sound/soc/codecs/Makefile | 4 +- sound/soc/codecs/pcm1792a.c | 271 ------------------ sound/soc/codecs/pcm1792a.h | 27 -- sound/soc/codecs/pcm179x.c | 314 +++++++++++++++++++++ sound/soc/codecs/pcm179x.h | 31 ++ 8 files changed, 368 insertions(+), 321 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/pcm1792a.txt create mode 100644 Documentation/devicetree/bindings/sound/pcm179x.txt delete mode 100644 sound/soc/codecs/pcm1792a.c delete mode 100644 sound/soc/codecs/pcm1792a.h create mode 100644 sound/soc/codecs/pcm179x.c create mode 100644 sound/soc/codecs/pcm179x.h
Signed-off-by: Michael Trimarchi michael@amarulasolutions.com --- sound/soc/codecs/pcm1792a.c | 158 ++++++++++++++++++++++---------------------- sound/soc/codecs/pcm1792a.h | 6 +- 2 files changed, 82 insertions(+), 82 deletions(-)
diff --git a/sound/soc/codecs/pcm1792a.c b/sound/soc/codecs/pcm1792a.c index 08bb486..a56c7b7 100644 --- a/sound/soc/codecs/pcm1792a.c +++ b/sound/soc/codecs/pcm1792a.c @@ -1,5 +1,5 @@ /* - * PCM1792A ASoC codec driver + * PCM179X ASoC codec driver * * Copyright (c) Amarula Solutions B.V. 2013 * @@ -31,21 +31,21 @@ #include <linux/of.h> #include <linux/of_device.h>
-#include "pcm1792a.h" +#include "pcm179x.h"
-#define PCM1792A_DAC_VOL_LEFT 0x10 -#define PCM1792A_DAC_VOL_RIGHT 0x11 -#define PCM1792A_FMT_CONTROL 0x12 -#define PCM1792A_MODE_CONTROL 0x13 -#define PCM1792A_SOFT_MUTE PCM1792A_FMT_CONTROL +#define PCM179X_DAC_VOL_LEFT 0x10 +#define PCM179X_DAC_VOL_RIGHT 0x11 +#define PCM179X_FMT_CONTROL 0x12 +#define PCM179X_MODE_CONTROL 0x13 +#define PCM179X_SOFT_MUTE PCM179X_FMT_CONTROL
-#define PCM1792A_FMT_MASK 0x70 -#define PCM1792A_FMT_SHIFT 4 -#define PCM1792A_MUTE_MASK 0x01 -#define PCM1792A_MUTE_SHIFT 0 -#define PCM1792A_ATLD_ENABLE (1 << 7) +#define PCM179X_FMT_MASK 0x70 +#define PCM179X_FMT_SHIFT 4 +#define PCM179X_MUTE_MASK 0x01 +#define PCM179X_MUTE_SHIFT 0 +#define PCM179X_ATLD_ENABLE (1 << 7)
-static const struct reg_default pcm1792a_reg_defaults[] = { +static const struct reg_default pcm179x_reg_defaults[] = { { 0x10, 0xff }, { 0x11, 0xff }, { 0x12, 0x50 }, @@ -56,57 +56,57 @@ static const struct reg_default pcm1792a_reg_defaults[] = { { 0x17, 0x00 }, };
-static bool pcm1792a_accessible_reg(struct device *dev, unsigned int reg) +static bool pcm179x_accessible_reg(struct device *dev, unsigned int reg) { return reg >= 0x10 && reg <= 0x17; }
-static bool pcm1792a_writeable_reg(struct device *dev, unsigned register reg) +static bool pcm179x_writeable_reg(struct device *dev, unsigned register reg) { bool accessible;
- accessible = pcm1792a_accessible_reg(dev, reg); + accessible = pcm179x_accessible_reg(dev, reg);
return accessible && reg != 0x16 && reg != 0x17; }
-struct pcm1792a_private { +struct pcm179x_private { struct regmap *regmap; unsigned int format; unsigned int rate; };
-static int pcm1792a_set_dai_fmt(struct snd_soc_dai *codec_dai, +static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int format) { struct snd_soc_codec *codec = codec_dai->codec; - struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec); + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
priv->format = format;
return 0; }
-static int pcm1792a_digital_mute(struct snd_soc_dai *dai, int mute) +static int pcm179x_digital_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; - struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec); + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); int ret;
- ret = regmap_update_bits(priv->regmap, PCM1792A_SOFT_MUTE, - PCM1792A_MUTE_MASK, !!mute); + ret = regmap_update_bits(priv->regmap, PCM179X_SOFT_MUTE, + PCM179X_MUTE_MASK, !!mute); if (ret < 0) return ret;
return 0; }
-static int pcm1792a_hw_params(struct snd_pcm_substream *substream, +static int pcm179x_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; - struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec); + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); int val = 0, ret;
priv->rate = params_rate(params); @@ -143,129 +143,129 @@ static int pcm1792a_hw_params(struct snd_pcm_substream *substream, return -EINVAL; }
- val = val << PCM1792A_FMT_SHIFT | PCM1792A_ATLD_ENABLE; + val = val << PCM179X_FMT_SHIFT | PCM179X_ATLD_ENABLE;
- ret = regmap_update_bits(priv->regmap, PCM1792A_FMT_CONTROL, - PCM1792A_FMT_MASK | PCM1792A_ATLD_ENABLE, val); + ret = regmap_update_bits(priv->regmap, PCM179X_FMT_CONTROL, + PCM179X_FMT_MASK | PCM179X_ATLD_ENABLE, val); if (ret < 0) return ret;
return 0; }
-static const struct snd_soc_dai_ops pcm1792a_dai_ops = { - .set_fmt = pcm1792a_set_dai_fmt, - .hw_params = pcm1792a_hw_params, - .digital_mute = pcm1792a_digital_mute, +static const struct snd_soc_dai_ops pcm179x_dai_ops = { + .set_fmt = pcm179x_set_dai_fmt, + .hw_params = pcm179x_hw_params, + .digital_mute = pcm179x_digital_mute, };
-static const DECLARE_TLV_DB_SCALE(pcm1792a_dac_tlv, -12000, 50, 1); +static const DECLARE_TLV_DB_SCALE(pcm179x_dac_tlv, -12000, 50, 1);
-static const struct snd_kcontrol_new pcm1792a_controls[] = { - SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM1792A_DAC_VOL_LEFT, - PCM1792A_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0, - pcm1792a_dac_tlv), - SOC_SINGLE("DAC Invert Output Switch", PCM1792A_MODE_CONTROL, 7, 1, 0), - SOC_SINGLE("DAC Rolloff Filter Switch", PCM1792A_MODE_CONTROL, 1, 1, 0), +static const struct snd_kcontrol_new pcm179x_controls[] = { + SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM179X_DAC_VOL_LEFT, + PCM179X_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0, + pcm179x_dac_tlv), + SOC_SINGLE("DAC Invert Output Switch", PCM179X_MODE_CONTROL, 7, 1, 0), + SOC_SINGLE("DAC Rolloff Filter Switch", PCM179X_MODE_CONTROL, 1, 1, 0), };
-static const struct snd_soc_dapm_widget pcm1792a_dapm_widgets[] = { +static const struct snd_soc_dapm_widget pcm179x_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("IOUTL+"), SND_SOC_DAPM_OUTPUT("IOUTL-"), SND_SOC_DAPM_OUTPUT("IOUTR+"), SND_SOC_DAPM_OUTPUT("IOUTR-"), };
-static const struct snd_soc_dapm_route pcm1792a_dapm_routes[] = { +static const struct snd_soc_dapm_route pcm179x_dapm_routes[] = { { "IOUTL+", NULL, "Playback" }, { "IOUTL-", NULL, "Playback" }, { "IOUTR+", NULL, "Playback" }, { "IOUTR-", NULL, "Playback" }, };
-static struct snd_soc_dai_driver pcm1792a_dai = { - .name = "pcm1792a-hifi", +static struct snd_soc_dai_driver pcm179x_dai = { + .name = "pcm179x-hifi", .playback = { .stream_name = "Playback", .channels_min = 2, .channels_max = 2, .rates = PCM1792A_RATES, .formats = PCM1792A_FORMATS, }, - .ops = &pcm1792a_dai_ops, + .ops = &pcm179x_dai_ops, };
-static const struct of_device_id pcm1792a_of_match[] = { +static const struct of_device_id pcm179x_of_match[] = { { .compatible = "ti,pcm1792a", }, { } }; -MODULE_DEVICE_TABLE(of, pcm1792a_of_match); +MODULE_DEVICE_TABLE(of, pcm179x_of_match);
-static const struct regmap_config pcm1792a_regmap = { +static const struct regmap_config pcm179x_regmap = { .reg_bits = 8, .val_bits = 8, .max_register = 23, - .reg_defaults = pcm1792a_reg_defaults, - .num_reg_defaults = ARRAY_SIZE(pcm1792a_reg_defaults), - .writeable_reg = pcm1792a_writeable_reg, - .readable_reg = pcm1792a_accessible_reg, + .reg_defaults = pcm179x_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(pcm179x_reg_defaults), + .writeable_reg = pcm179x_writeable_reg, + .readable_reg = pcm179x_accessible_reg, };
-static struct snd_soc_codec_driver soc_codec_dev_pcm1792a = { - .controls = pcm1792a_controls, - .num_controls = ARRAY_SIZE(pcm1792a_controls), - .dapm_widgets = pcm1792a_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(pcm1792a_dapm_widgets), - .dapm_routes = pcm1792a_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(pcm1792a_dapm_routes), +static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { + .controls = pcm179x_controls, + .num_controls = ARRAY_SIZE(pcm179x_controls), + .dapm_widgets = pcm179x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(pcm179x_dapm_widgets), + .dapm_routes = pcm179x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), };
-static int pcm1792a_spi_probe(struct spi_device *spi) +static int pcm179x_spi_probe(struct spi_device *spi) { - struct pcm1792a_private *pcm1792a; + struct pcm179x_private *pcm179x; int ret;
- pcm1792a = devm_kzalloc(&spi->dev, sizeof(struct pcm1792a_private), + pcm179x = devm_kzalloc(&spi->dev, sizeof(struct pcm179x_private), GFP_KERNEL); - if (!pcm1792a) + if (!pcm179x) return -ENOMEM;
- spi_set_drvdata(spi, pcm1792a); + spi_set_drvdata(spi, pcm179x);
- pcm1792a->regmap = devm_regmap_init_spi(spi, &pcm1792a_regmap); - if (IS_ERR(pcm1792a->regmap)) { - ret = PTR_ERR(pcm1792a->regmap); + pcm179x->regmap = devm_regmap_init_spi(spi, &pcm179x_regmap); + if (IS_ERR(pcm179x->regmap)) { + ret = PTR_ERR(pcm179x->regmap); dev_err(&spi->dev, "Failed to register regmap: %d\n", ret); return ret; }
return snd_soc_register_codec(&spi->dev, - &soc_codec_dev_pcm1792a, &pcm1792a_dai, 1); + &soc_codec_dev_pcm179x, &pcm179x_dai, 1); }
-static int pcm1792a_spi_remove(struct spi_device *spi) +static int pcm179x_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); return 0; }
-static const struct spi_device_id pcm1792a_spi_ids[] = { - { "pcm1792a", 0 }, +static const struct spi_device_id pcm179x_spi_ids[] = { + { "pcm179x", 0 }, { }, }; -MODULE_DEVICE_TABLE(spi, pcm1792a_spi_ids); +MODULE_DEVICE_TABLE(spi, pcm179x_spi_ids);
-static struct spi_driver pcm1792a_codec_driver = { +static struct spi_driver pcm179x_codec_driver = { .driver = { - .name = "pcm1792a", - .of_match_table = of_match_ptr(pcm1792a_of_match), + .name = "pcm179x", + .of_match_table = of_match_ptr(pcm179x_of_match), }, - .id_table = pcm1792a_spi_ids, - .probe = pcm1792a_spi_probe, - .remove = pcm1792a_spi_remove, + .id_table = pcm179x_spi_ids, + .probe = pcm179x_spi_probe, + .remove = pcm179x_spi_remove, };
-module_spi_driver(pcm1792a_codec_driver); +module_spi_driver(pcm179x_codec_driver);
-MODULE_DESCRIPTION("ASoC PCM1792A driver"); +MODULE_DESCRIPTION("ASoC PCM179X driver"); MODULE_AUTHOR("Michael Trimarchi michael@amarulasolutions.com"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/pcm1792a.h b/sound/soc/codecs/pcm1792a.h index 51d5470..c6fdc06 100644 --- a/sound/soc/codecs/pcm1792a.h +++ b/sound/soc/codecs/pcm1792a.h @@ -1,5 +1,5 @@ /* - * definitions for PCM1792A + * definitions for PCM179X * * Copyright 2013 Amarula Solutions * @@ -14,8 +14,8 @@ * GNU General Public License for more details. */
-#ifndef __PCM1792A_H__ -#define __PCM1792A_H__ +#ifndef __PCM179X_H__ +#define __PCM179X_H__
#define PCM1792A_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_8000_48000 | \ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
The patch
ASoC: pcm1792a: Rename internal data and function to pcm179x
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 823733b91619aef5a2be21d0918ef6dd996de72a Mon Sep 17 00:00:00 2001
From: Michael Trimarchi michael@amarulasolutions.com Date: Sun, 10 Jan 2016 00:38:03 +0100 Subject: [PATCH] ASoC: pcm1792a: Rename internal data and function to pcm179x
Signed-off-by: Michael Trimarchi michael@amarulasolutions.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/pcm1792a.c | 158 ++++++++++++++++++++++---------------------- sound/soc/codecs/pcm1792a.h | 6 +- 2 files changed, 82 insertions(+), 82 deletions(-)
diff --git a/sound/soc/codecs/pcm1792a.c b/sound/soc/codecs/pcm1792a.c index 08bb4863e96f..a56c7b767d90 100644 --- a/sound/soc/codecs/pcm1792a.c +++ b/sound/soc/codecs/pcm1792a.c @@ -1,5 +1,5 @@ /* - * PCM1792A ASoC codec driver + * PCM179X ASoC codec driver * * Copyright (c) Amarula Solutions B.V. 2013 * @@ -31,21 +31,21 @@ #include <linux/of.h> #include <linux/of_device.h>
-#include "pcm1792a.h" +#include "pcm179x.h"
-#define PCM1792A_DAC_VOL_LEFT 0x10 -#define PCM1792A_DAC_VOL_RIGHT 0x11 -#define PCM1792A_FMT_CONTROL 0x12 -#define PCM1792A_MODE_CONTROL 0x13 -#define PCM1792A_SOFT_MUTE PCM1792A_FMT_CONTROL +#define PCM179X_DAC_VOL_LEFT 0x10 +#define PCM179X_DAC_VOL_RIGHT 0x11 +#define PCM179X_FMT_CONTROL 0x12 +#define PCM179X_MODE_CONTROL 0x13 +#define PCM179X_SOFT_MUTE PCM179X_FMT_CONTROL
-#define PCM1792A_FMT_MASK 0x70 -#define PCM1792A_FMT_SHIFT 4 -#define PCM1792A_MUTE_MASK 0x01 -#define PCM1792A_MUTE_SHIFT 0 -#define PCM1792A_ATLD_ENABLE (1 << 7) +#define PCM179X_FMT_MASK 0x70 +#define PCM179X_FMT_SHIFT 4 +#define PCM179X_MUTE_MASK 0x01 +#define PCM179X_MUTE_SHIFT 0 +#define PCM179X_ATLD_ENABLE (1 << 7)
-static const struct reg_default pcm1792a_reg_defaults[] = { +static const struct reg_default pcm179x_reg_defaults[] = { { 0x10, 0xff }, { 0x11, 0xff }, { 0x12, 0x50 }, @@ -56,57 +56,57 @@ static const struct reg_default pcm1792a_reg_defaults[] = { { 0x17, 0x00 }, };
-static bool pcm1792a_accessible_reg(struct device *dev, unsigned int reg) +static bool pcm179x_accessible_reg(struct device *dev, unsigned int reg) { return reg >= 0x10 && reg <= 0x17; }
-static bool pcm1792a_writeable_reg(struct device *dev, unsigned register reg) +static bool pcm179x_writeable_reg(struct device *dev, unsigned register reg) { bool accessible;
- accessible = pcm1792a_accessible_reg(dev, reg); + accessible = pcm179x_accessible_reg(dev, reg);
return accessible && reg != 0x16 && reg != 0x17; }
-struct pcm1792a_private { +struct pcm179x_private { struct regmap *regmap; unsigned int format; unsigned int rate; };
-static int pcm1792a_set_dai_fmt(struct snd_soc_dai *codec_dai, +static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int format) { struct snd_soc_codec *codec = codec_dai->codec; - struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec); + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
priv->format = format;
return 0; }
-static int pcm1792a_digital_mute(struct snd_soc_dai *dai, int mute) +static int pcm179x_digital_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; - struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec); + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); int ret;
- ret = regmap_update_bits(priv->regmap, PCM1792A_SOFT_MUTE, - PCM1792A_MUTE_MASK, !!mute); + ret = regmap_update_bits(priv->regmap, PCM179X_SOFT_MUTE, + PCM179X_MUTE_MASK, !!mute); if (ret < 0) return ret;
return 0; }
-static int pcm1792a_hw_params(struct snd_pcm_substream *substream, +static int pcm179x_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; - struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec); + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); int val = 0, ret;
priv->rate = params_rate(params); @@ -143,129 +143,129 @@ static int pcm1792a_hw_params(struct snd_pcm_substream *substream, return -EINVAL; }
- val = val << PCM1792A_FMT_SHIFT | PCM1792A_ATLD_ENABLE; + val = val << PCM179X_FMT_SHIFT | PCM179X_ATLD_ENABLE;
- ret = regmap_update_bits(priv->regmap, PCM1792A_FMT_CONTROL, - PCM1792A_FMT_MASK | PCM1792A_ATLD_ENABLE, val); + ret = regmap_update_bits(priv->regmap, PCM179X_FMT_CONTROL, + PCM179X_FMT_MASK | PCM179X_ATLD_ENABLE, val); if (ret < 0) return ret;
return 0; }
-static const struct snd_soc_dai_ops pcm1792a_dai_ops = { - .set_fmt = pcm1792a_set_dai_fmt, - .hw_params = pcm1792a_hw_params, - .digital_mute = pcm1792a_digital_mute, +static const struct snd_soc_dai_ops pcm179x_dai_ops = { + .set_fmt = pcm179x_set_dai_fmt, + .hw_params = pcm179x_hw_params, + .digital_mute = pcm179x_digital_mute, };
-static const DECLARE_TLV_DB_SCALE(pcm1792a_dac_tlv, -12000, 50, 1); +static const DECLARE_TLV_DB_SCALE(pcm179x_dac_tlv, -12000, 50, 1);
-static const struct snd_kcontrol_new pcm1792a_controls[] = { - SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM1792A_DAC_VOL_LEFT, - PCM1792A_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0, - pcm1792a_dac_tlv), - SOC_SINGLE("DAC Invert Output Switch", PCM1792A_MODE_CONTROL, 7, 1, 0), - SOC_SINGLE("DAC Rolloff Filter Switch", PCM1792A_MODE_CONTROL, 1, 1, 0), +static const struct snd_kcontrol_new pcm179x_controls[] = { + SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM179X_DAC_VOL_LEFT, + PCM179X_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0, + pcm179x_dac_tlv), + SOC_SINGLE("DAC Invert Output Switch", PCM179X_MODE_CONTROL, 7, 1, 0), + SOC_SINGLE("DAC Rolloff Filter Switch", PCM179X_MODE_CONTROL, 1, 1, 0), };
-static const struct snd_soc_dapm_widget pcm1792a_dapm_widgets[] = { +static const struct snd_soc_dapm_widget pcm179x_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("IOUTL+"), SND_SOC_DAPM_OUTPUT("IOUTL-"), SND_SOC_DAPM_OUTPUT("IOUTR+"), SND_SOC_DAPM_OUTPUT("IOUTR-"), };
-static const struct snd_soc_dapm_route pcm1792a_dapm_routes[] = { +static const struct snd_soc_dapm_route pcm179x_dapm_routes[] = { { "IOUTL+", NULL, "Playback" }, { "IOUTL-", NULL, "Playback" }, { "IOUTR+", NULL, "Playback" }, { "IOUTR-", NULL, "Playback" }, };
-static struct snd_soc_dai_driver pcm1792a_dai = { - .name = "pcm1792a-hifi", +static struct snd_soc_dai_driver pcm179x_dai = { + .name = "pcm179x-hifi", .playback = { .stream_name = "Playback", .channels_min = 2, .channels_max = 2, .rates = PCM1792A_RATES, .formats = PCM1792A_FORMATS, }, - .ops = &pcm1792a_dai_ops, + .ops = &pcm179x_dai_ops, };
-static const struct of_device_id pcm1792a_of_match[] = { +static const struct of_device_id pcm179x_of_match[] = { { .compatible = "ti,pcm1792a", }, { } }; -MODULE_DEVICE_TABLE(of, pcm1792a_of_match); +MODULE_DEVICE_TABLE(of, pcm179x_of_match);
-static const struct regmap_config pcm1792a_regmap = { +static const struct regmap_config pcm179x_regmap = { .reg_bits = 8, .val_bits = 8, .max_register = 23, - .reg_defaults = pcm1792a_reg_defaults, - .num_reg_defaults = ARRAY_SIZE(pcm1792a_reg_defaults), - .writeable_reg = pcm1792a_writeable_reg, - .readable_reg = pcm1792a_accessible_reg, + .reg_defaults = pcm179x_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(pcm179x_reg_defaults), + .writeable_reg = pcm179x_writeable_reg, + .readable_reg = pcm179x_accessible_reg, };
-static struct snd_soc_codec_driver soc_codec_dev_pcm1792a = { - .controls = pcm1792a_controls, - .num_controls = ARRAY_SIZE(pcm1792a_controls), - .dapm_widgets = pcm1792a_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(pcm1792a_dapm_widgets), - .dapm_routes = pcm1792a_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(pcm1792a_dapm_routes), +static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { + .controls = pcm179x_controls, + .num_controls = ARRAY_SIZE(pcm179x_controls), + .dapm_widgets = pcm179x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(pcm179x_dapm_widgets), + .dapm_routes = pcm179x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), };
-static int pcm1792a_spi_probe(struct spi_device *spi) +static int pcm179x_spi_probe(struct spi_device *spi) { - struct pcm1792a_private *pcm1792a; + struct pcm179x_private *pcm179x; int ret;
- pcm1792a = devm_kzalloc(&spi->dev, sizeof(struct pcm1792a_private), + pcm179x = devm_kzalloc(&spi->dev, sizeof(struct pcm179x_private), GFP_KERNEL); - if (!pcm1792a) + if (!pcm179x) return -ENOMEM;
- spi_set_drvdata(spi, pcm1792a); + spi_set_drvdata(spi, pcm179x);
- pcm1792a->regmap = devm_regmap_init_spi(spi, &pcm1792a_regmap); - if (IS_ERR(pcm1792a->regmap)) { - ret = PTR_ERR(pcm1792a->regmap); + pcm179x->regmap = devm_regmap_init_spi(spi, &pcm179x_regmap); + if (IS_ERR(pcm179x->regmap)) { + ret = PTR_ERR(pcm179x->regmap); dev_err(&spi->dev, "Failed to register regmap: %d\n", ret); return ret; }
return snd_soc_register_codec(&spi->dev, - &soc_codec_dev_pcm1792a, &pcm1792a_dai, 1); + &soc_codec_dev_pcm179x, &pcm179x_dai, 1); }
-static int pcm1792a_spi_remove(struct spi_device *spi) +static int pcm179x_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); return 0; }
-static const struct spi_device_id pcm1792a_spi_ids[] = { - { "pcm1792a", 0 }, +static const struct spi_device_id pcm179x_spi_ids[] = { + { "pcm179x", 0 }, { }, }; -MODULE_DEVICE_TABLE(spi, pcm1792a_spi_ids); +MODULE_DEVICE_TABLE(spi, pcm179x_spi_ids);
-static struct spi_driver pcm1792a_codec_driver = { +static struct spi_driver pcm179x_codec_driver = { .driver = { - .name = "pcm1792a", - .of_match_table = of_match_ptr(pcm1792a_of_match), + .name = "pcm179x", + .of_match_table = of_match_ptr(pcm179x_of_match), }, - .id_table = pcm1792a_spi_ids, - .probe = pcm1792a_spi_probe, - .remove = pcm1792a_spi_remove, + .id_table = pcm179x_spi_ids, + .probe = pcm179x_spi_probe, + .remove = pcm179x_spi_remove, };
-module_spi_driver(pcm1792a_codec_driver); +module_spi_driver(pcm179x_codec_driver);
-MODULE_DESCRIPTION("ASoC PCM1792A driver"); +MODULE_DESCRIPTION("ASoC PCM179X driver"); MODULE_AUTHOR("Michael Trimarchi michael@amarulasolutions.com"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/pcm1792a.h b/sound/soc/codecs/pcm1792a.h index 51d5470fee16..c6fdc062a497 100644 --- a/sound/soc/codecs/pcm1792a.h +++ b/sound/soc/codecs/pcm1792a.h @@ -1,5 +1,5 @@ /* - * definitions for PCM1792A + * definitions for PCM179X * * Copyright 2013 Amarula Solutions * @@ -14,8 +14,8 @@ * GNU General Public License for more details. */
-#ifndef __PCM1792A_H__ -#define __PCM1792A_H__ +#ifndef __PCM179X_H__ +#define __PCM179X_H__
#define PCM1792A_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_8000_48000 | \ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
pcm1792a is compatible with pcm1795 and pcm1796 so it's better to have them under the common name pcm179x
Signed-off-by: Michael Trimarchi michael@amarulasolutions.com --- .../devicetree/bindings/sound/pcm1792a.txt | 18 -- .../devicetree/bindings/sound/pcm179x.txt | 18 ++ sound/soc/codecs/Kconfig | 6 +- sound/soc/codecs/Makefile | 4 +- sound/soc/codecs/pcm1792a.c | 271 --------------------- sound/soc/codecs/pcm1792a.h | 27 -- sound/soc/codecs/pcm179x.c | 271 +++++++++++++++++++++ sound/soc/codecs/pcm179x.h | 27 ++ 8 files changed, 321 insertions(+), 321 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/pcm1792a.txt create mode 100644 Documentation/devicetree/bindings/sound/pcm179x.txt delete mode 100644 sound/soc/codecs/pcm1792a.c delete mode 100644 sound/soc/codecs/pcm1792a.h create mode 100644 sound/soc/codecs/pcm179x.c create mode 100644 sound/soc/codecs/pcm179x.h
diff --git a/Documentation/devicetree/bindings/sound/pcm1792a.txt b/Documentation/devicetree/bindings/sound/pcm1792a.txt deleted file mode 100644 index 970ba1e..0000000 --- a/Documentation/devicetree/bindings/sound/pcm1792a.txt +++ /dev/null @@ -1,18 +0,0 @@ -Texas Instruments pcm1792a DT bindings - -This driver supports the SPI bus. - -Required properties: - - - compatible: "ti,pcm1792a" - -For required properties on SPI, please consult -Documentation/devicetree/bindings/spi/spi-bus.txt - -Examples: - - codec_spi: 1792a@0 { - compatible = "ti,pcm1792a"; - spi-max-frequency = <600000>; - }; - diff --git a/Documentation/devicetree/bindings/sound/pcm179x.txt b/Documentation/devicetree/bindings/sound/pcm179x.txt new file mode 100644 index 0000000..4ae70d3 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/pcm179x.txt @@ -0,0 +1,18 @@ +Texas Instruments pcm179x DT bindings + +This driver supports the SPI bus. + +Required properties: + + - compatible: "ti,pcm1792a" + +For required properties on SPI, please consult +Documentation/devicetree/bindings/spi/spi-bus.txt + +Examples: + + codec_spi: 1792a@0 { + compatible = "ti,pcm1792a"; + spi-max-frequency = <600000>; + }; + diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 0c9733e..eaa3af7 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -81,7 +81,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_ML26124 if I2C select SND_SOC_HDMI_CODEC select SND_SOC_PCM1681 if I2C - select SND_SOC_PCM1792A if SPI_MASTER + select SND_SOC_PCM179X if SPI_MASTER select SND_SOC_PCM3008 select SND_SOC_PCM512x_I2C if I2C select SND_SOC_PCM512x_SPI if SPI_MASTER @@ -490,8 +490,8 @@ config SND_SOC_PCM1681 tristate "Texas Instruments PCM1681 CODEC" depends on I2C
-config SND_SOC_PCM1792A - tristate "Texas Instruments PCM1792A CODEC" +config SND_SOC_PCM179X + tristate "Texas Instruments PCM179X CODEC" depends on SPI_MASTER
config SND_SOC_PCM3008 diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 4a32077..35d6c1a 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -74,7 +74,7 @@ snd-soc-mc13783-objs := mc13783.o snd-soc-ml26124-objs := ml26124.o snd-soc-hdmi-codec-objs := hdmi.o snd-soc-pcm1681-objs := pcm1681.o -snd-soc-pcm1792a-codec-objs := pcm1792a.o +snd-soc-pcm179x-codec-objs := pcm179x.o snd-soc-pcm3008-objs := pcm3008.o snd-soc-pcm512x-objs := pcm512x.o snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o @@ -266,7 +266,7 @@ obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o -obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o +obj-$(CONFIG_SND_SOC_PCM179X) += snd-soc-pcm179x-codec.o obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o diff --git a/sound/soc/codecs/pcm1792a.c b/sound/soc/codecs/pcm1792a.c deleted file mode 100644 index a56c7b7..0000000 --- a/sound/soc/codecs/pcm1792a.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * PCM179X ASoC codec driver - * - * Copyright (c) Amarula Solutions B.V. 2013 - * - * Michael Trimarchi michael@amarulasolutions.com - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/kernel.h> -#include <linux/device.h> -#include <linux/spi/spi.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/initval.h> -#include <sound/soc.h> -#include <sound/tlv.h> -#include <linux/of.h> -#include <linux/of_device.h> - -#include "pcm179x.h" - -#define PCM179X_DAC_VOL_LEFT 0x10 -#define PCM179X_DAC_VOL_RIGHT 0x11 -#define PCM179X_FMT_CONTROL 0x12 -#define PCM179X_MODE_CONTROL 0x13 -#define PCM179X_SOFT_MUTE PCM179X_FMT_CONTROL - -#define PCM179X_FMT_MASK 0x70 -#define PCM179X_FMT_SHIFT 4 -#define PCM179X_MUTE_MASK 0x01 -#define PCM179X_MUTE_SHIFT 0 -#define PCM179X_ATLD_ENABLE (1 << 7) - -static const struct reg_default pcm179x_reg_defaults[] = { - { 0x10, 0xff }, - { 0x11, 0xff }, - { 0x12, 0x50 }, - { 0x13, 0x00 }, - { 0x14, 0x00 }, - { 0x15, 0x01 }, - { 0x16, 0x00 }, - { 0x17, 0x00 }, -}; - -static bool pcm179x_accessible_reg(struct device *dev, unsigned int reg) -{ - return reg >= 0x10 && reg <= 0x17; -} - -static bool pcm179x_writeable_reg(struct device *dev, unsigned register reg) -{ - bool accessible; - - accessible = pcm179x_accessible_reg(dev, reg); - - return accessible && reg != 0x16 && reg != 0x17; -} - -struct pcm179x_private { - struct regmap *regmap; - unsigned int format; - unsigned int rate; -}; - -static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int format) -{ - struct snd_soc_codec *codec = codec_dai->codec; - struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); - - priv->format = format; - - return 0; -} - -static int pcm179x_digital_mute(struct snd_soc_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); - int ret; - - ret = regmap_update_bits(priv->regmap, PCM179X_SOFT_MUTE, - PCM179X_MUTE_MASK, !!mute); - if (ret < 0) - return ret; - - return 0; -} - -static int pcm179x_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_codec *codec = dai->codec; - struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); - int val = 0, ret; - - priv->rate = params_rate(params); - - switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_RIGHT_J: - switch (params_width(params)) { - case 24: - case 32: - val = 2; - break; - case 16: - val = 0; - break; - default: - return -EINVAL; - } - break; - case SND_SOC_DAIFMT_I2S: - switch (params_width(params)) { - case 24: - case 32: - val = 5; - break; - case 16: - val = 4; - break; - default: - return -EINVAL; - } - break; - default: - dev_err(codec->dev, "Invalid DAI format\n"); - return -EINVAL; - } - - val = val << PCM179X_FMT_SHIFT | PCM179X_ATLD_ENABLE; - - ret = regmap_update_bits(priv->regmap, PCM179X_FMT_CONTROL, - PCM179X_FMT_MASK | PCM179X_ATLD_ENABLE, val); - if (ret < 0) - return ret; - - return 0; -} - -static const struct snd_soc_dai_ops pcm179x_dai_ops = { - .set_fmt = pcm179x_set_dai_fmt, - .hw_params = pcm179x_hw_params, - .digital_mute = pcm179x_digital_mute, -}; - -static const DECLARE_TLV_DB_SCALE(pcm179x_dac_tlv, -12000, 50, 1); - -static const struct snd_kcontrol_new pcm179x_controls[] = { - SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM179X_DAC_VOL_LEFT, - PCM179X_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0, - pcm179x_dac_tlv), - SOC_SINGLE("DAC Invert Output Switch", PCM179X_MODE_CONTROL, 7, 1, 0), - SOC_SINGLE("DAC Rolloff Filter Switch", PCM179X_MODE_CONTROL, 1, 1, 0), -}; - -static const struct snd_soc_dapm_widget pcm179x_dapm_widgets[] = { -SND_SOC_DAPM_OUTPUT("IOUTL+"), -SND_SOC_DAPM_OUTPUT("IOUTL-"), -SND_SOC_DAPM_OUTPUT("IOUTR+"), -SND_SOC_DAPM_OUTPUT("IOUTR-"), -}; - -static const struct snd_soc_dapm_route pcm179x_dapm_routes[] = { - { "IOUTL+", NULL, "Playback" }, - { "IOUTL-", NULL, "Playback" }, - { "IOUTR+", NULL, "Playback" }, - { "IOUTR-", NULL, "Playback" }, -}; - -static struct snd_soc_dai_driver pcm179x_dai = { - .name = "pcm179x-hifi", - .playback = { - .stream_name = "Playback", - .channels_min = 2, - .channels_max = 2, - .rates = PCM1792A_RATES, - .formats = PCM1792A_FORMATS, }, - .ops = &pcm179x_dai_ops, -}; - -static const struct of_device_id pcm179x_of_match[] = { - { .compatible = "ti,pcm1792a", }, - { } -}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match); - -static const struct regmap_config pcm179x_regmap = { - .reg_bits = 8, - .val_bits = 8, - .max_register = 23, - .reg_defaults = pcm179x_reg_defaults, - .num_reg_defaults = ARRAY_SIZE(pcm179x_reg_defaults), - .writeable_reg = pcm179x_writeable_reg, - .readable_reg = pcm179x_accessible_reg, -}; - -static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { - .controls = pcm179x_controls, - .num_controls = ARRAY_SIZE(pcm179x_controls), - .dapm_widgets = pcm179x_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(pcm179x_dapm_widgets), - .dapm_routes = pcm179x_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), -}; - -static int pcm179x_spi_probe(struct spi_device *spi) -{ - struct pcm179x_private *pcm179x; - int ret; - - pcm179x = devm_kzalloc(&spi->dev, sizeof(struct pcm179x_private), - GFP_KERNEL); - if (!pcm179x) - return -ENOMEM; - - spi_set_drvdata(spi, pcm179x); - - pcm179x->regmap = devm_regmap_init_spi(spi, &pcm179x_regmap); - if (IS_ERR(pcm179x->regmap)) { - ret = PTR_ERR(pcm179x->regmap); - dev_err(&spi->dev, "Failed to register regmap: %d\n", ret); - return ret; - } - - return snd_soc_register_codec(&spi->dev, - &soc_codec_dev_pcm179x, &pcm179x_dai, 1); -} - -static int pcm179x_spi_remove(struct spi_device *spi) -{ - snd_soc_unregister_codec(&spi->dev); - return 0; -} - -static const struct spi_device_id pcm179x_spi_ids[] = { - { "pcm179x", 0 }, - { }, -}; -MODULE_DEVICE_TABLE(spi, pcm179x_spi_ids); - -static struct spi_driver pcm179x_codec_driver = { - .driver = { - .name = "pcm179x", - .of_match_table = of_match_ptr(pcm179x_of_match), - }, - .id_table = pcm179x_spi_ids, - .probe = pcm179x_spi_probe, - .remove = pcm179x_spi_remove, -}; - -module_spi_driver(pcm179x_codec_driver); - -MODULE_DESCRIPTION("ASoC PCM179X driver"); -MODULE_AUTHOR("Michael Trimarchi michael@amarulasolutions.com"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/pcm1792a.h b/sound/soc/codecs/pcm1792a.h deleted file mode 100644 index c6fdc06..0000000 --- a/sound/soc/codecs/pcm1792a.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * definitions for PCM179X - * - * Copyright 2013 Amarula Solutions - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __PCM179X_H__ -#define __PCM179X_H__ - -#define PCM1792A_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_8000_48000 | \ - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \ - SNDRV_PCM_RATE_192000) - -#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S16_LE) - -#endif diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c new file mode 100644 index 0000000..a56c7b7 --- /dev/null +++ b/sound/soc/codecs/pcm179x.c @@ -0,0 +1,271 @@ +/* + * PCM179X ASoC codec driver + * + * Copyright (c) Amarula Solutions B.V. 2013 + * + * Michael Trimarchi michael@amarulasolutions.com + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/spi/spi.h> + +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/initval.h> +#include <sound/soc.h> +#include <sound/tlv.h> +#include <linux/of.h> +#include <linux/of_device.h> + +#include "pcm179x.h" + +#define PCM179X_DAC_VOL_LEFT 0x10 +#define PCM179X_DAC_VOL_RIGHT 0x11 +#define PCM179X_FMT_CONTROL 0x12 +#define PCM179X_MODE_CONTROL 0x13 +#define PCM179X_SOFT_MUTE PCM179X_FMT_CONTROL + +#define PCM179X_FMT_MASK 0x70 +#define PCM179X_FMT_SHIFT 4 +#define PCM179X_MUTE_MASK 0x01 +#define PCM179X_MUTE_SHIFT 0 +#define PCM179X_ATLD_ENABLE (1 << 7) + +static const struct reg_default pcm179x_reg_defaults[] = { + { 0x10, 0xff }, + { 0x11, 0xff }, + { 0x12, 0x50 }, + { 0x13, 0x00 }, + { 0x14, 0x00 }, + { 0x15, 0x01 }, + { 0x16, 0x00 }, + { 0x17, 0x00 }, +}; + +static bool pcm179x_accessible_reg(struct device *dev, unsigned int reg) +{ + return reg >= 0x10 && reg <= 0x17; +} + +static bool pcm179x_writeable_reg(struct device *dev, unsigned register reg) +{ + bool accessible; + + accessible = pcm179x_accessible_reg(dev, reg); + + return accessible && reg != 0x16 && reg != 0x17; +} + +struct pcm179x_private { + struct regmap *regmap; + unsigned int format; + unsigned int rate; +}; + +static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int format) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); + + priv->format = format; + + return 0; +} + +static int pcm179x_digital_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); + int ret; + + ret = regmap_update_bits(priv->regmap, PCM179X_SOFT_MUTE, + PCM179X_MUTE_MASK, !!mute); + if (ret < 0) + return ret; + + return 0; +} + +static int pcm179x_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); + int val = 0, ret; + + priv->rate = params_rate(params); + + switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_RIGHT_J: + switch (params_width(params)) { + case 24: + case 32: + val = 2; + break; + case 16: + val = 0; + break; + default: + return -EINVAL; + } + break; + case SND_SOC_DAIFMT_I2S: + switch (params_width(params)) { + case 24: + case 32: + val = 5; + break; + case 16: + val = 4; + break; + default: + return -EINVAL; + } + break; + default: + dev_err(codec->dev, "Invalid DAI format\n"); + return -EINVAL; + } + + val = val << PCM179X_FMT_SHIFT | PCM179X_ATLD_ENABLE; + + ret = regmap_update_bits(priv->regmap, PCM179X_FMT_CONTROL, + PCM179X_FMT_MASK | PCM179X_ATLD_ENABLE, val); + if (ret < 0) + return ret; + + return 0; +} + +static const struct snd_soc_dai_ops pcm179x_dai_ops = { + .set_fmt = pcm179x_set_dai_fmt, + .hw_params = pcm179x_hw_params, + .digital_mute = pcm179x_digital_mute, +}; + +static const DECLARE_TLV_DB_SCALE(pcm179x_dac_tlv, -12000, 50, 1); + +static const struct snd_kcontrol_new pcm179x_controls[] = { + SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM179X_DAC_VOL_LEFT, + PCM179X_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0, + pcm179x_dac_tlv), + SOC_SINGLE("DAC Invert Output Switch", PCM179X_MODE_CONTROL, 7, 1, 0), + SOC_SINGLE("DAC Rolloff Filter Switch", PCM179X_MODE_CONTROL, 1, 1, 0), +}; + +static const struct snd_soc_dapm_widget pcm179x_dapm_widgets[] = { +SND_SOC_DAPM_OUTPUT("IOUTL+"), +SND_SOC_DAPM_OUTPUT("IOUTL-"), +SND_SOC_DAPM_OUTPUT("IOUTR+"), +SND_SOC_DAPM_OUTPUT("IOUTR-"), +}; + +static const struct snd_soc_dapm_route pcm179x_dapm_routes[] = { + { "IOUTL+", NULL, "Playback" }, + { "IOUTL-", NULL, "Playback" }, + { "IOUTR+", NULL, "Playback" }, + { "IOUTR-", NULL, "Playback" }, +}; + +static struct snd_soc_dai_driver pcm179x_dai = { + .name = "pcm179x-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = PCM1792A_RATES, + .formats = PCM1792A_FORMATS, }, + .ops = &pcm179x_dai_ops, +}; + +static const struct of_device_id pcm179x_of_match[] = { + { .compatible = "ti,pcm1792a", }, + { } +}; +MODULE_DEVICE_TABLE(of, pcm179x_of_match); + +static const struct regmap_config pcm179x_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 23, + .reg_defaults = pcm179x_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(pcm179x_reg_defaults), + .writeable_reg = pcm179x_writeable_reg, + .readable_reg = pcm179x_accessible_reg, +}; + +static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { + .controls = pcm179x_controls, + .num_controls = ARRAY_SIZE(pcm179x_controls), + .dapm_widgets = pcm179x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(pcm179x_dapm_widgets), + .dapm_routes = pcm179x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), +}; + +static int pcm179x_spi_probe(struct spi_device *spi) +{ + struct pcm179x_private *pcm179x; + int ret; + + pcm179x = devm_kzalloc(&spi->dev, sizeof(struct pcm179x_private), + GFP_KERNEL); + if (!pcm179x) + return -ENOMEM; + + spi_set_drvdata(spi, pcm179x); + + pcm179x->regmap = devm_regmap_init_spi(spi, &pcm179x_regmap); + if (IS_ERR(pcm179x->regmap)) { + ret = PTR_ERR(pcm179x->regmap); + dev_err(&spi->dev, "Failed to register regmap: %d\n", ret); + return ret; + } + + return snd_soc_register_codec(&spi->dev, + &soc_codec_dev_pcm179x, &pcm179x_dai, 1); +} + +static int pcm179x_spi_remove(struct spi_device *spi) +{ + snd_soc_unregister_codec(&spi->dev); + return 0; +} + +static const struct spi_device_id pcm179x_spi_ids[] = { + { "pcm179x", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(spi, pcm179x_spi_ids); + +static struct spi_driver pcm179x_codec_driver = { + .driver = { + .name = "pcm179x", + .of_match_table = of_match_ptr(pcm179x_of_match), + }, + .id_table = pcm179x_spi_ids, + .probe = pcm179x_spi_probe, + .remove = pcm179x_spi_remove, +}; + +module_spi_driver(pcm179x_codec_driver); + +MODULE_DESCRIPTION("ASoC PCM179X driver"); +MODULE_AUTHOR("Michael Trimarchi michael@amarulasolutions.com"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/pcm179x.h b/sound/soc/codecs/pcm179x.h new file mode 100644 index 0000000..c6fdc06 --- /dev/null +++ b/sound/soc/codecs/pcm179x.h @@ -0,0 +1,27 @@ +/* + * definitions for PCM179X + * + * Copyright 2013 Amarula Solutions + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __PCM179X_H__ +#define __PCM179X_H__ + +#define PCM1792A_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_8000_48000 | \ + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \ + SNDRV_PCM_RATE_192000) + +#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S16_LE) + +#endif
On Sun, Jan 10, 2016 at 12:38:04AM +0100, Michael Trimarchi wrote:
pcm1792a is compatible with pcm1795 and pcm1796 so it's better to have them under the common name pcm179x
Signed-off-by: Michael Trimarchi michael@amarulasolutions.com
.../devicetree/bindings/sound/pcm1792a.txt | 18 -- .../devicetree/bindings/sound/pcm179x.txt | 18 ++
Acked-by: Rob Herring robh@kernel.org
Please use -M option for git-format-patch for renames/moves. The binding is short enough, but the driver isn't really.
sound/soc/codecs/Kconfig | 6 +- sound/soc/codecs/Makefile | 4 +- sound/soc/codecs/pcm1792a.c | 271 --------------------- sound/soc/codecs/pcm1792a.h | 27 -- sound/soc/codecs/pcm179x.c | 271 +++++++++++++++++++++ sound/soc/codecs/pcm179x.h | 27 ++ 8 files changed, 321 insertions(+), 321 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/pcm1792a.txt create mode 100644 Documentation/devicetree/bindings/sound/pcm179x.txt delete mode 100644 sound/soc/codecs/pcm1792a.c delete mode 100644 sound/soc/codecs/pcm1792a.h create mode 100644 sound/soc/codecs/pcm179x.c create mode 100644 sound/soc/codecs/pcm179x.h
Signed-off-by: Michael Trimarchi michael@amarulasolutions.com --- sound/soc/codecs/pcm179x.c | 51 ++++++++++++++++++++++++++++++++++++++++++---- sound/soc/codecs/pcm179x.h | 14 ++++++++----- 2 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index a56c7b7..c4f61d0 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c @@ -74,8 +74,26 @@ struct pcm179x_private { struct regmap *regmap; unsigned int format; unsigned int rate; +#define PCM1795 1 + unsigned int codec_model; };
+static int pcm179x_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); + u64 formats = PCM1792A_FORMATS; + + if (priv->codec_model == PCM1795) + formats = PCM1795_FORMATS; + + snd_pcm_hw_constraint_mask64(substream->runtime, + SNDRV_PCM_HW_PARAM_FORMAT, formats); + + return 0; +} + static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int format) { @@ -114,8 +132,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_RIGHT_J: switch (params_width(params)) { - case 24: case 32: + val = 1; + break; + case 24: val = 2; break; case 16: @@ -127,8 +147,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, break; case SND_SOC_DAIFMT_I2S: switch (params_width(params)) { - case 24: case 32: + val = 4; + break; + case 24: val = 5; break; case 16: @@ -154,6 +176,7 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, }
static const struct snd_soc_dai_ops pcm179x_dai_ops = { + .startup = pcm179x_startup, .set_fmt = pcm179x_set_dai_fmt, .hw_params = pcm179x_hw_params, .digital_mute = pcm179x_digital_mute, @@ -189,13 +212,19 @@ static struct snd_soc_dai_driver pcm179x_dai = { .stream_name = "Playback", .channels_min = 2, .channels_max = 2, - .rates = PCM1792A_RATES, - .formats = PCM1792A_FORMATS, }, + .rates = PCM179X_RATES, + .formats = PCM179X_FORMATS, }, .ops = &pcm179x_dai_ops, };
+static const unsigned int codec_model = PCM1795; + static const struct of_device_id pcm179x_of_match[] = { { .compatible = "ti,pcm1792a", }, + { .compatible = "ti,pcm1796", }, + { .compatible = "ti,pcm1795", + .data = &codec_model, + }, { } }; MODULE_DEVICE_TABLE(of, pcm179x_of_match); @@ -222,8 +251,19 @@ static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { static int pcm179x_spi_probe(struct spi_device *spi) { struct pcm179x_private *pcm179x; + struct device *dev = &spi->dev; + struct device_node *np = spi->dev.of_node; + const unsigned int *codec_model = NULL; int ret;
+ if (np) { + const struct of_device_id *of_id; + + of_id = of_match_device(pcm179x_of_match, dev); + if (of_id) + codec_model = of_id->data; + } + pcm179x = devm_kzalloc(&spi->dev, sizeof(struct pcm179x_private), GFP_KERNEL); if (!pcm179x) @@ -238,6 +278,9 @@ static int pcm179x_spi_probe(struct spi_device *spi) return ret; }
+ if (codec_model) + pcm179x->codec_model = *codec_model; + return snd_soc_register_codec(&spi->dev, &soc_codec_dev_pcm179x, &pcm179x_dai, 1); } diff --git a/sound/soc/codecs/pcm179x.h b/sound/soc/codecs/pcm179x.h index c6fdc06..d4b384d 100644 --- a/sound/soc/codecs/pcm179x.h +++ b/sound/soc/codecs/pcm179x.h @@ -17,11 +17,15 @@ #ifndef __PCM179X_H__ #define __PCM179X_H__
-#define PCM1792A_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_8000_48000 | \ - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \ - SNDRV_PCM_RATE_192000) +#define PCM179X_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_8000_48000 | \ + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \ + SNDRV_PCM_RATE_192000)
-#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S16_LE) +#define PCM179X_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S16_LE) + +#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) + +#define PCM1795_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE)
#endif
On Sun, Jan 10, 2016 at 12:38:05AM +0100, Michael Trimarchi wrote:
- if (priv->codec_model == PCM1795)
formats = PCM1795_FORMATS;
This should be a switch statement to handle any future variations.
static const struct of_device_id pcm179x_of_match[] = { { .compatible = "ti,pcm1792a", },
- { .compatible = "ti,pcm1796", },
- { .compatible = "ti,pcm1795",
.data = &codec_model,
- },
Please keep tables sorted, it avoid conflicts and merge issues when adding new entries.
Signed-off-by: Michael Trimarchi michael@amarulasolutions.com --- Changes v1 -> v2: - Use switch for support new variants - sort the compatible list
sound/soc/codecs/pcm179x.c | 56 ++++++++++++++++++++++++++++++++++++++++++---- sound/soc/codecs/pcm179x.h | 14 +++++++----- 2 files changed, 61 insertions(+), 9 deletions(-)
diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index a56c7b7..8784d52 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c @@ -74,8 +74,31 @@ struct pcm179x_private { struct regmap *regmap; unsigned int format; unsigned int rate; +#define PCM1795 1 + unsigned int codec_model; };
+static int pcm179x_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); + u64 formats; + + switch (priv->codec_model) { + case PCM1795: + formats = PCM1795_FORMATS; + break; + default: + formats = PCM1792A_FORMATS; + } + + snd_pcm_hw_constraint_mask64(substream->runtime, + SNDRV_PCM_HW_PARAM_FORMAT, formats); + + return 0; +} + static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int format) { @@ -114,8 +137,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_RIGHT_J: switch (params_width(params)) { - case 24: case 32: + val = 1; + break; + case 24: val = 2; break; case 16: @@ -127,8 +152,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, break; case SND_SOC_DAIFMT_I2S: switch (params_width(params)) { - case 24: case 32: + val = 4; + break; + case 24: val = 5; break; case 16: @@ -154,6 +181,7 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, }
static const struct snd_soc_dai_ops pcm179x_dai_ops = { + .startup = pcm179x_startup, .set_fmt = pcm179x_set_dai_fmt, .hw_params = pcm179x_hw_params, .digital_mute = pcm179x_digital_mute, @@ -189,13 +217,19 @@ static struct snd_soc_dai_driver pcm179x_dai = { .stream_name = "Playback", .channels_min = 2, .channels_max = 2, - .rates = PCM1792A_RATES, - .formats = PCM1792A_FORMATS, }, + .rates = PCM179X_RATES, + .formats = PCM179X_FORMATS, }, .ops = &pcm179x_dai_ops, };
+static const unsigned int codec_model = PCM1795; + static const struct of_device_id pcm179x_of_match[] = { { .compatible = "ti,pcm1792a", }, + { .compatible = "ti,pcm1795", + .data = &codec_model, + }, + { .compatible = "ti,pcm1796", }, { } }; MODULE_DEVICE_TABLE(of, pcm179x_of_match); @@ -222,8 +256,19 @@ static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { static int pcm179x_spi_probe(struct spi_device *spi) { struct pcm179x_private *pcm179x; + struct device *dev = &spi->dev; + struct device_node *np = spi->dev.of_node; + const unsigned int *codec_model = NULL; int ret;
+ if (np) { + const struct of_device_id *of_id; + + of_id = of_match_device(pcm179x_of_match, dev); + if (of_id) + codec_model = of_id->data; + } + pcm179x = devm_kzalloc(&spi->dev, sizeof(struct pcm179x_private), GFP_KERNEL); if (!pcm179x) @@ -238,6 +283,9 @@ static int pcm179x_spi_probe(struct spi_device *spi) return ret; }
+ if (codec_model) + pcm179x->codec_model = *codec_model; + return snd_soc_register_codec(&spi->dev, &soc_codec_dev_pcm179x, &pcm179x_dai, 1); } diff --git a/sound/soc/codecs/pcm179x.h b/sound/soc/codecs/pcm179x.h index c6fdc06..d4b384d 100644 --- a/sound/soc/codecs/pcm179x.h +++ b/sound/soc/codecs/pcm179x.h @@ -17,11 +17,15 @@ #ifndef __PCM179X_H__ #define __PCM179X_H__
-#define PCM1792A_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_8000_48000 | \ - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \ - SNDRV_PCM_RATE_192000) +#define PCM179X_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_8000_48000 | \ + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \ + SNDRV_PCM_RATE_192000)
-#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S16_LE) +#define PCM179X_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S16_LE) + +#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) + +#define PCM1795_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE)
#endif
Signed-off-by: Michael Trimarchi michael@amarulasolutions.com --- Not get time to retest
Changes v3 -> v2: - rebase after i2c support
Changes v1 -> v2: - Use switch for support new variants - sort the compatible list
sound/soc/codecs/pcm179x-i2c.c | 6 ---- sound/soc/codecs/pcm179x-spi.c | 6 ---- sound/soc/codecs/pcm179x.c | 62 ++++++++++++++++++++++++++++++++++++++++-- sound/soc/codecs/pcm179x.h | 9 ++++-- 4 files changed, 66 insertions(+), 17 deletions(-)
diff --git a/sound/soc/codecs/pcm179x-i2c.c b/sound/soc/codecs/pcm179x-i2c.c index 4118106..609f07f 100644 --- a/sound/soc/codecs/pcm179x-i2c.c +++ b/sound/soc/codecs/pcm179x-i2c.c @@ -44,12 +44,6 @@ static int pcm179x_i2c_remove(struct i2c_client *client) return pcm179x_common_exit(&client->dev); }
-static const struct of_device_id pcm179x_of_match[] = { - { .compatible = "ti,pcm1792a", }, - { } -}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match); - static const struct i2c_device_id pcm179x_i2c_ids[] = { { "pcm179x", 0 }, { } diff --git a/sound/soc/codecs/pcm179x-spi.c b/sound/soc/codecs/pcm179x-spi.c index da924d4..6ae0e4d 100644 --- a/sound/soc/codecs/pcm179x-spi.c +++ b/sound/soc/codecs/pcm179x-spi.c @@ -43,12 +43,6 @@ static int pcm179x_spi_remove(struct spi_device *spi) return pcm179x_common_exit(&spi->dev); }
-static const struct of_device_id pcm179x_of_match[] = { - { .compatible = "ti,pcm1792a", }, - { } -}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match); - static const struct spi_device_id pcm179x_spi_ids[] = { { "pcm179x", 0 }, { }, diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index 06a6657..73c80d3 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c @@ -20,6 +20,8 @@ #include <linux/slab.h> #include <linux/kernel.h> #include <linux/device.h> +#include <linux/of.h> +#include <linux/of_device.h>
#include <sound/core.h> #include <sound/pcm.h> @@ -72,8 +74,31 @@ struct pcm179x_private { struct regmap *regmap; unsigned int format; unsigned int rate; +#define PCM1795 1 + unsigned int codec_model; };
+static int pcm179x_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); + u64 formats = PCM1792A_FORMATS; + + switch (priv->codec_model) { + case PCM1795: + formats = PCM1795_FORMATS; + break; + default: + break; + } + + snd_pcm_hw_constraint_mask64(substream->runtime, + SNDRV_PCM_HW_PARAM_FORMAT, formats); + + return 0; +} + static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int format) { @@ -112,8 +137,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_RIGHT_J: switch (params_width(params)) { - case 24: case 32: + val = 1; + break; + case 24: val = 2; break; case 16: @@ -125,8 +152,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, break; case SND_SOC_DAIFMT_I2S: switch (params_width(params)) { - case 24: case 32: + val = 4; + break; + case 24: val = 5; break; case 16: @@ -152,6 +181,7 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, }
static const struct snd_soc_dai_ops pcm179x_dai_ops = { + .startup = pcm179x_startup, .set_fmt = pcm179x_set_dai_fmt, .hw_params = pcm179x_hw_params, .digital_mute = pcm179x_digital_mute, @@ -190,7 +220,7 @@ static struct snd_soc_dai_driver pcm179x_dai = { .rates = SNDRV_PCM_RATE_CONTINUOUS, .rate_min = 10000, .rate_max = 200000, - .formats = PCM1792A_FORMATS, }, + .formats = PCM179X_FORMATS, }, .ops = &pcm179x_dai_ops, };
@@ -214,15 +244,41 @@ static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), };
+static const unsigned int codec_model = PCM1795; + +const struct of_device_id pcm179x_of_match[] = { + { .compatible = "ti,pcm1792a", }, + { .compatible = "ti,pcm1795", + .data = &codec_model, + }, + { .compatible = "ti,pcm1796", }, + { } +}; +MODULE_DEVICE_TABLE(of, pcm179x_of_match); +EXPORT_SYMBOL_GPL(pcm179x_of_match); + int pcm179x_common_init(struct device *dev, struct regmap *regmap) { struct pcm179x_private *pcm179x; + struct device_node *np = dev->of_node; + const unsigned int *codec_model = NULL;
pcm179x = devm_kzalloc(dev, sizeof(struct pcm179x_private), GFP_KERNEL); if (!pcm179x) return -ENOMEM;
+ if (np) { + const struct of_device_id *of_id; + + of_id = of_match_device(pcm179x_of_match, dev); + if (of_id) + codec_model = of_id->data; + } + + if (codec_model) + pcm179x->codec_model = *codec_model; + pcm179x->regmap = regmap; dev_set_drvdata(dev, pcm179x);
diff --git a/sound/soc/codecs/pcm179x.h b/sound/soc/codecs/pcm179x.h index 11e3312..4c00047 100644 --- a/sound/soc/codecs/pcm179x.h +++ b/sound/soc/codecs/pcm179x.h @@ -17,10 +17,15 @@ #ifndef __PCM179X_H__ #define __PCM179X_H__
-#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S16_LE) +#define PCM179X_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S16_LE) + +#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) + +#define PCM1795_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE)
extern const struct regmap_config pcm179x_regmap_config; +extern const struct of_device_id pcm179x_of_match[];
int pcm179x_common_init(struct device *dev, struct regmap *regmap); int pcm179x_common_exit(struct device *dev);
Hi Jacob
On Fri, Feb 5, 2016 at 6:24 PM, Michael Trimarchi michael@amarulasolutions.com wrote:
Signed-off-by: Michael Trimarchi michael@amarulasolutions.com
Not get time to retest
Can you confirm that it works for you?
Michael
Changes v3 -> v2: - rebase after i2c support
Changes v1 -> v2: - Use switch for support new variants - sort the compatible list
sound/soc/codecs/pcm179x-i2c.c | 6 ---- sound/soc/codecs/pcm179x-spi.c | 6 ---- sound/soc/codecs/pcm179x.c | 62 ++++++++++++++++++++++++++++++++++++++++-- sound/soc/codecs/pcm179x.h | 9 ++++-- 4 files changed, 66 insertions(+), 17 deletions(-)
diff --git a/sound/soc/codecs/pcm179x-i2c.c b/sound/soc/codecs/pcm179x-i2c.c index 4118106..609f07f 100644 --- a/sound/soc/codecs/pcm179x-i2c.c +++ b/sound/soc/codecs/pcm179x-i2c.c @@ -44,12 +44,6 @@ static int pcm179x_i2c_remove(struct i2c_client *client) return pcm179x_common_exit(&client->dev); }
-static const struct of_device_id pcm179x_of_match[] = {
{ .compatible = "ti,pcm1792a", },
{ }
-}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match);
static const struct i2c_device_id pcm179x_i2c_ids[] = { { "pcm179x", 0 }, { } diff --git a/sound/soc/codecs/pcm179x-spi.c b/sound/soc/codecs/pcm179x-spi.c index da924d4..6ae0e4d 100644 --- a/sound/soc/codecs/pcm179x-spi.c +++ b/sound/soc/codecs/pcm179x-spi.c @@ -43,12 +43,6 @@ static int pcm179x_spi_remove(struct spi_device *spi) return pcm179x_common_exit(&spi->dev); }
-static const struct of_device_id pcm179x_of_match[] = {
{ .compatible = "ti,pcm1792a", },
{ }
-}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match);
static const struct spi_device_id pcm179x_spi_ids[] = { { "pcm179x", 0 }, { }, diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index 06a6657..73c80d3 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c @@ -20,6 +20,8 @@ #include <linux/slab.h> #include <linux/kernel.h> #include <linux/device.h> +#include <linux/of.h> +#include <linux/of_device.h>
#include <sound/core.h> #include <sound/pcm.h> @@ -72,8 +74,31 @@ struct pcm179x_private { struct regmap *regmap; unsigned int format; unsigned int rate; +#define PCM1795 1
unsigned int codec_model;
};
+static int pcm179x_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
+{
struct snd_soc_codec *codec = dai->codec;
struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
u64 formats = PCM1792A_FORMATS;
switch (priv->codec_model) {
case PCM1795:
formats = PCM1795_FORMATS;
break;
default:
break;
}
snd_pcm_hw_constraint_mask64(substream->runtime,
SNDRV_PCM_HW_PARAM_FORMAT, formats);
return 0;
+}
static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int format) { @@ -112,8 +137,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_RIGHT_J: switch (params_width(params)) {
case 24: case 32:
val = 1;
break;
case 24: val = 2; break; case 16:
@@ -125,8 +152,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, break; case SND_SOC_DAIFMT_I2S: switch (params_width(params)) {
case 24: case 32:
val = 4;
break;
case 24: val = 5; break; case 16:
@@ -152,6 +181,7 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, }
static const struct snd_soc_dai_ops pcm179x_dai_ops = {
.startup = pcm179x_startup, .set_fmt = pcm179x_set_dai_fmt, .hw_params = pcm179x_hw_params, .digital_mute = pcm179x_digital_mute,
@@ -190,7 +220,7 @@ static struct snd_soc_dai_driver pcm179x_dai = { .rates = SNDRV_PCM_RATE_CONTINUOUS, .rate_min = 10000, .rate_max = 200000,
.formats = PCM1792A_FORMATS, },
.formats = PCM179X_FORMATS, }, .ops = &pcm179x_dai_ops,
};
@@ -214,15 +244,41 @@ static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), };
+static const unsigned int codec_model = PCM1795;
+const struct of_device_id pcm179x_of_match[] = {
{ .compatible = "ti,pcm1792a", },
{ .compatible = "ti,pcm1795",
.data = &codec_model,
},
{ .compatible = "ti,pcm1796", },
{ }
+}; +MODULE_DEVICE_TABLE(of, pcm179x_of_match); +EXPORT_SYMBOL_GPL(pcm179x_of_match);
int pcm179x_common_init(struct device *dev, struct regmap *regmap) { struct pcm179x_private *pcm179x;
struct device_node *np = dev->of_node;
const unsigned int *codec_model = NULL; pcm179x = devm_kzalloc(dev, sizeof(struct pcm179x_private), GFP_KERNEL); if (!pcm179x) return -ENOMEM;
if (np) {
const struct of_device_id *of_id;
of_id = of_match_device(pcm179x_of_match, dev);
if (of_id)
codec_model = of_id->data;
}
if (codec_model)
pcm179x->codec_model = *codec_model;
pcm179x->regmap = regmap; dev_set_drvdata(dev, pcm179x);
diff --git a/sound/soc/codecs/pcm179x.h b/sound/soc/codecs/pcm179x.h index 11e3312..4c00047 100644 --- a/sound/soc/codecs/pcm179x.h +++ b/sound/soc/codecs/pcm179x.h @@ -17,10 +17,15 @@ #ifndef __PCM179X_H__ #define __PCM179X_H__
-#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S16_LE)
+#define PCM179X_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S16_LE)
+#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
+#define PCM1795_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE)
extern const struct regmap_config pcm179x_regmap_config; +extern const struct of_device_id pcm179x_of_match[];
int pcm179x_common_init(struct device *dev, struct regmap *regmap); int pcm179x_common_exit(struct device *dev); -- 2.7.0
-- | Michael Nazzareno Trimarchi Amarula Solutions BV | | COO - Founder Cruquiuskade 47 | | +31(0)851119172 Amsterdam 1018 AM NL | | [`as] http://www.amarulasolutions.com |
On Sat, Feb 20, 2016 at 10:27 AM, Michael Trimarchi michael@amarulasolutions.com wrote:
Hi Jacob
On Fri, Feb 5, 2016 at 6:24 PM, Michael Trimarchi michael@amarulasolutions.com wrote:
Signed-off-by: Michael Trimarchi michael@amarulasolutions.com
Not get time to retest
Can you confirm that it works for you?
Hi Michael!
Sorry for not getting back to your earlier. I tried some time ago, and it made me realize that our application has been using an incorrect format setting (S32_LE) all along. Changing to the (more) correct S24_LE doesn't work (due to some reason I yet have not confirmed - but it doesn't look to be caused by this driver).
However, from the datasheet, the removal of S32_LE from PCM1792A_FORMATS seems correct. For the logical changes, the driver works for me if I manually re-add S32_LE again.
I was hoping to figure out the cause of my S24_LE issue and then be able to test your patch without modifications, but I realize that it's taking too much time.
A few comments below.
Michael
Changes v3 -> v2: - rebase after i2c support
Changes v1 -> v2: - Use switch for support new variants - sort the compatible list
sound/soc/codecs/pcm179x-i2c.c | 6 ---- sound/soc/codecs/pcm179x-spi.c | 6 ---- sound/soc/codecs/pcm179x.c | 62 ++++++++++++++++++++++++++++++++++++++++-- sound/soc/codecs/pcm179x.h | 9 ++++-- 4 files changed, 66 insertions(+), 17 deletions(-)
diff --git a/sound/soc/codecs/pcm179x-i2c.c b/sound/soc/codecs/pcm179x-i2c.c index 4118106..609f07f 100644 --- a/sound/soc/codecs/pcm179x-i2c.c +++ b/sound/soc/codecs/pcm179x-i2c.c @@ -44,12 +44,6 @@ static int pcm179x_i2c_remove(struct i2c_client *client) return pcm179x_common_exit(&client->dev); }
-static const struct of_device_id pcm179x_of_match[] = {
{ .compatible = "ti,pcm1792a", },
{ }
-}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match);
static const struct i2c_device_id pcm179x_i2c_ids[] = { { "pcm179x", 0 }, { } diff --git a/sound/soc/codecs/pcm179x-spi.c b/sound/soc/codecs/pcm179x-spi.c index da924d4..6ae0e4d 100644 --- a/sound/soc/codecs/pcm179x-spi.c +++ b/sound/soc/codecs/pcm179x-spi.c @@ -43,12 +43,6 @@ static int pcm179x_spi_remove(struct spi_device *spi) return pcm179x_common_exit(&spi->dev); }
-static const struct of_device_id pcm179x_of_match[] = {
{ .compatible = "ti,pcm1792a", },
{ }
-}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match);
static const struct spi_device_id pcm179x_spi_ids[] = { { "pcm179x", 0 }, { }, diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index 06a6657..73c80d3 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c @@ -20,6 +20,8 @@ #include <linux/slab.h> #include <linux/kernel.h> #include <linux/device.h> +#include <linux/of.h> +#include <linux/of_device.h>
#include <sound/core.h> #include <sound/pcm.h> @@ -72,8 +74,31 @@ struct pcm179x_private { struct regmap *regmap; unsigned int format; unsigned int rate; +#define PCM1795 1
unsigned int codec_model;
};
+static int pcm179x_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
+{
struct snd_soc_codec *codec = dai->codec;
struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
u64 formats = PCM1792A_FORMATS;
How does this work? Are formats always overwritten here (and hence PCM179X_FORMATS never really used)?
switch (priv->codec_model) {
case PCM1795:
formats = PCM1795_FORMATS;
break;
default:
break;
}
snd_pcm_hw_constraint_mask64(substream->runtime,
SNDRV_PCM_HW_PARAM_FORMAT, formats);
return 0;
+}
static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int format) { @@ -112,8 +137,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_RIGHT_J: switch (params_width(params)) {
case 24: case 32:
val = 1;
break;
case 24: val = 2; break; case 16:
@@ -125,8 +152,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, break; case SND_SOC_DAIFMT_I2S: switch (params_width(params)) {
case 24: case 32:
val = 4;
break;
case 24: val = 5; break; case 16:
@@ -152,6 +181,7 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, }
static const struct snd_soc_dai_ops pcm179x_dai_ops = {
.startup = pcm179x_startup, .set_fmt = pcm179x_set_dai_fmt, .hw_params = pcm179x_hw_params, .digital_mute = pcm179x_digital_mute,
@@ -190,7 +220,7 @@ static struct snd_soc_dai_driver pcm179x_dai = { .rates = SNDRV_PCM_RATE_CONTINUOUS, .rate_min = 10000, .rate_max = 200000,
.formats = PCM1792A_FORMATS, },
.formats = PCM179X_FORMATS, }, .ops = &pcm179x_dai_ops,
};
@@ -214,15 +244,41 @@ static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), };
+static const unsigned int codec_model = PCM1795;
+const struct of_device_id pcm179x_of_match[] = {
{ .compatible = "ti,pcm1792a", },
{ .compatible = "ti,pcm1795",
.data = &codec_model,
},
{ .compatible = "ti,pcm1796", },
{ }
+}; +MODULE_DEVICE_TABLE(of, pcm179x_of_match); +EXPORT_SYMBOL_GPL(pcm179x_of_match);
int pcm179x_common_init(struct device *dev, struct regmap *regmap) { struct pcm179x_private *pcm179x;
struct device_node *np = dev->of_node;
const unsigned int *codec_model = NULL; pcm179x = devm_kzalloc(dev, sizeof(struct pcm179x_private), GFP_KERNEL); if (!pcm179x) return -ENOMEM;
if (np) {
const struct of_device_id *of_id;
of_id = of_match_device(pcm179x_of_match, dev);
if (of_id)
codec_model = of_id->data;
}
if (codec_model)
pcm179x->codec_model = *codec_model;
Double space.
pcm179x->regmap = regmap; dev_set_drvdata(dev, pcm179x);
diff --git a/sound/soc/codecs/pcm179x.h b/sound/soc/codecs/pcm179x.h index 11e3312..4c00047 100644 --- a/sound/soc/codecs/pcm179x.h +++ b/sound/soc/codecs/pcm179x.h @@ -17,10 +17,15 @@ #ifndef __PCM179X_H__ #define __PCM179X_H__
-#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S16_LE)
+#define PCM179X_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S16_LE)
+#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
+#define PCM1795_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE)
extern const struct regmap_config pcm179x_regmap_config; +extern const struct of_device_id pcm179x_of_match[];
int pcm179x_common_init(struct device *dev, struct regmap *regmap); int pcm179x_common_exit(struct device *dev); -- 2.7.0
On Fri, Feb 05, 2016 at 06:24:57PM +0100, Michael Trimarchi wrote:
+#define PCM1795 1
- unsigned int codec_model;
It looks like you're trying to define an enum here.
+static const unsigned int codec_model = PCM1795;
That's a weird name to use here. Call it pcm1795 or something, though normally we just cast the integer to and from a pointer.
- { .compatible = "ti,pcm1795",
.data = &codec_model,
- },
This is strange indentation, just keep it on one line and it's easier to follow.
Hi Mark
On Mon, Feb 22, 2016 at 4:19 AM, Mark Brown broonie@kernel.org wrote:
On Fri, Feb 05, 2016 at 06:24:57PM +0100, Michael Trimarchi wrote:
+#define PCM1795 1
unsigned int codec_model;
It looks like you're trying to define an enum here.
+static const unsigned int codec_model = PCM1795;
Ok
That's a weird name to use here. Call it pcm1795 or something, though normally we just cast the integer to and from a pointer.
{ .compatible = "ti,pcm1795",
.data = &codec_model,
},
This is strange indentation, just keep it on one line and it's easier to follow.
Ok
Michael
ASoC: pcm179x: Add support for pcm1795 and pcm1796
Signed-off-by: Michael Trimarchi michael@amarulasolutions.com Tested-by: Angelo Adamo adamo.a60@gmail.com ---
Changes v4 -> v3: - clean up compatible list - use enum type instead of pointer of int
Changes v3 -> v2: - rebase after i2c support
Changes v1 -> v2: - Use switch for support new variants - sort the compatible list
sound/soc/codecs/pcm179x-i2c.c | 6 ---- sound/soc/codecs/pcm179x-spi.c | 6 ---- sound/soc/codecs/pcm179x.c | 65 ++++++++++++++++++++++++++++++++++++++++-- sound/soc/codecs/pcm179x.h | 9 ++++-- 4 files changed, 69 insertions(+), 17 deletions(-)
diff --git a/sound/soc/codecs/pcm179x-i2c.c b/sound/soc/codecs/pcm179x-i2c.c index 4118106..609f07f 100644 --- a/sound/soc/codecs/pcm179x-i2c.c +++ b/sound/soc/codecs/pcm179x-i2c.c @@ -44,12 +44,6 @@ static int pcm179x_i2c_remove(struct i2c_client *client) return pcm179x_common_exit(&client->dev); }
-static const struct of_device_id pcm179x_of_match[] = { - { .compatible = "ti,pcm1792a", }, - { } -}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match); - static const struct i2c_device_id pcm179x_i2c_ids[] = { { "pcm179x", 0 }, { } diff --git a/sound/soc/codecs/pcm179x-spi.c b/sound/soc/codecs/pcm179x-spi.c index da924d4..6ae0e4d 100644 --- a/sound/soc/codecs/pcm179x-spi.c +++ b/sound/soc/codecs/pcm179x-spi.c @@ -43,12 +43,6 @@ static int pcm179x_spi_remove(struct spi_device *spi) return pcm179x_common_exit(&spi->dev); }
-static const struct of_device_id pcm179x_of_match[] = { - { .compatible = "ti,pcm1792a", }, - { } -}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match); - static const struct spi_device_id pcm179x_spi_ids[] = { { "pcm179x", 0 }, { }, diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index 06a6657..5be782e 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c @@ -20,6 +20,8 @@ #include <linux/slab.h> #include <linux/kernel.h> #include <linux/device.h> +#include <linux/of.h> +#include <linux/of_device.h>
#include <sound/core.h> #include <sound/pcm.h> @@ -68,12 +70,40 @@ static bool pcm179x_writeable_reg(struct device *dev, unsigned register reg) return accessible && reg != 0x16 && reg != 0x17; }
+enum pcm179x_type { + PCM1792A, + PCM1795, + PCM1796, +}; + struct pcm179x_private { struct regmap *regmap; unsigned int format; unsigned int rate; + enum pcm179x_type codec_model; };
+static int pcm179x_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); + u64 formats = PCM1792A_FORMATS; + + switch (priv->codec_model) { + case PCM1795: + formats = PCM1795_FORMATS; + break; + default: + break; + } + + snd_pcm_hw_constraint_mask64(substream->runtime, + SNDRV_PCM_HW_PARAM_FORMAT, formats); + + return 0; +} + static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int format) { @@ -112,8 +142,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_RIGHT_J: switch (params_width(params)) { - case 24: case 32: + val = 1; + break; + case 24: val = 2; break; case 16: @@ -125,8 +157,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, break; case SND_SOC_DAIFMT_I2S: switch (params_width(params)) { - case 24: case 32: + val = 4; + break; + case 24: val = 5; break; case 16: @@ -152,6 +186,7 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, }
static const struct snd_soc_dai_ops pcm179x_dai_ops = { + .startup = pcm179x_startup, .set_fmt = pcm179x_set_dai_fmt, .hw_params = pcm179x_hw_params, .digital_mute = pcm179x_digital_mute, @@ -190,7 +225,7 @@ static struct snd_soc_dai_driver pcm179x_dai = { .rates = SNDRV_PCM_RATE_CONTINUOUS, .rate_min = 10000, .rate_max = 200000, - .formats = PCM1792A_FORMATS, }, + .formats = PCM179X_FORMATS, }, .ops = &pcm179x_dai_ops, };
@@ -214,15 +249,39 @@ static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), };
+static const unsigned int codec_model = PCM1795; + +const struct of_device_id pcm179x_of_match[] = { + { .compatible = "ti,pcm1792a", }, + { .compatible = "ti,pcm1795", .data = (void *)PCM1795, }, + { .compatible = "ti,pcm1796", }, + { } +}; +MODULE_DEVICE_TABLE(of, pcm179x_of_match); +EXPORT_SYMBOL_GPL(pcm179x_of_match); + int pcm179x_common_init(struct device *dev, struct regmap *regmap) { struct pcm179x_private *pcm179x; + struct device_node *np = dev->of_node; + enum pcm179x_type codec_model = PCM1792A;
pcm179x = devm_kzalloc(dev, sizeof(struct pcm179x_private), GFP_KERNEL); if (!pcm179x) return -ENOMEM;
+ if (np) { + const struct of_device_id *of_id; + + of_id = of_match_device(pcm179x_of_match, dev); + if (of_id) + codec_model = (enum pcm179x_type) of_id->data; + } + + if (codec_model) + pcm179x->codec_model = codec_model; + pcm179x->regmap = regmap; dev_set_drvdata(dev, pcm179x);
diff --git a/sound/soc/codecs/pcm179x.h b/sound/soc/codecs/pcm179x.h index 11e3312..4c00047 100644 --- a/sound/soc/codecs/pcm179x.h +++ b/sound/soc/codecs/pcm179x.h @@ -17,10 +17,15 @@ #ifndef __PCM179X_H__ #define __PCM179X_H__
-#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S16_LE) +#define PCM179X_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S16_LE) + +#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) + +#define PCM1795_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE)
extern const struct regmap_config pcm179x_regmap_config; +extern const struct of_device_id pcm179x_of_match[];
int pcm179x_common_init(struct device *dev, struct regmap *regmap); int pcm179x_common_exit(struct device *dev);
ASoC: pcm179x: Add support for pcm1795 and pcm1796
Signed-off-by: Michael Trimarchi michael@amarulasolutions.com Tested-by: Angelo Adamo adamo.a60@gmail.com --- Changes v4 -> v5 - remove dead code
Changes v3 -> v4: - clean up compatible list - use enum type instead of pointer of int
Changes v2 -> v3: - rebase after i2c support
Changes v1 -> v2: - Use switch for support new variants - sort the compatible list
sound/soc/codecs/pcm179x-i2c.c | 6 ---- sound/soc/codecs/pcm179x-spi.c | 6 ---- sound/soc/codecs/pcm179x.c | 63 ++++++++++++++++++++++++++++++++++++++++-- sound/soc/codecs/pcm179x.h | 9 ++++-- 4 files changed, 67 insertions(+), 17 deletions(-)
diff --git a/sound/soc/codecs/pcm179x-i2c.c b/sound/soc/codecs/pcm179x-i2c.c index 4118106..609f07f 100644 --- a/sound/soc/codecs/pcm179x-i2c.c +++ b/sound/soc/codecs/pcm179x-i2c.c @@ -44,12 +44,6 @@ static int pcm179x_i2c_remove(struct i2c_client *client) return pcm179x_common_exit(&client->dev); }
-static const struct of_device_id pcm179x_of_match[] = { - { .compatible = "ti,pcm1792a", }, - { } -}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match); - static const struct i2c_device_id pcm179x_i2c_ids[] = { { "pcm179x", 0 }, { } diff --git a/sound/soc/codecs/pcm179x-spi.c b/sound/soc/codecs/pcm179x-spi.c index da924d4..6ae0e4d 100644 --- a/sound/soc/codecs/pcm179x-spi.c +++ b/sound/soc/codecs/pcm179x-spi.c @@ -43,12 +43,6 @@ static int pcm179x_spi_remove(struct spi_device *spi) return pcm179x_common_exit(&spi->dev); }
-static const struct of_device_id pcm179x_of_match[] = { - { .compatible = "ti,pcm1792a", }, - { } -}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match); - static const struct spi_device_id pcm179x_spi_ids[] = { { "pcm179x", 0 }, { }, diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index 06a6657..52b2d4b 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c @@ -20,6 +20,8 @@ #include <linux/slab.h> #include <linux/kernel.h> #include <linux/device.h> +#include <linux/of.h> +#include <linux/of_device.h>
#include <sound/core.h> #include <sound/pcm.h> @@ -68,12 +70,40 @@ static bool pcm179x_writeable_reg(struct device *dev, unsigned register reg) return accessible && reg != 0x16 && reg != 0x17; }
+enum pcm179x_type { + PCM1792A, + PCM1795, + PCM1796, +}; + struct pcm179x_private { struct regmap *regmap; unsigned int format; unsigned int rate; + enum pcm179x_type codec_model; };
+static int pcm179x_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); + u64 formats = PCM1792A_FORMATS; + + switch (priv->codec_model) { + case PCM1795: + formats = PCM1795_FORMATS; + break; + default: + break; + } + + snd_pcm_hw_constraint_mask64(substream->runtime, + SNDRV_PCM_HW_PARAM_FORMAT, formats); + + return 0; +} + static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int format) { @@ -112,8 +142,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_RIGHT_J: switch (params_width(params)) { - case 24: case 32: + val = 1; + break; + case 24: val = 2; break; case 16: @@ -125,8 +157,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, break; case SND_SOC_DAIFMT_I2S: switch (params_width(params)) { - case 24: case 32: + val = 4; + break; + case 24: val = 5; break; case 16: @@ -152,6 +186,7 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, }
static const struct snd_soc_dai_ops pcm179x_dai_ops = { + .startup = pcm179x_startup, .set_fmt = pcm179x_set_dai_fmt, .hw_params = pcm179x_hw_params, .digital_mute = pcm179x_digital_mute, @@ -190,7 +225,7 @@ static struct snd_soc_dai_driver pcm179x_dai = { .rates = SNDRV_PCM_RATE_CONTINUOUS, .rate_min = 10000, .rate_max = 200000, - .formats = PCM1792A_FORMATS, }, + .formats = PCM179X_FORMATS, }, .ops = &pcm179x_dai_ops, };
@@ -214,15 +249,37 @@ static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), };
+const struct of_device_id pcm179x_of_match[] = { + { .compatible = "ti,pcm1792a", }, + { .compatible = "ti,pcm1795", .data = (void *)PCM1795, }, + { .compatible = "ti,pcm1796", }, + { } +}; +MODULE_DEVICE_TABLE(of, pcm179x_of_match); +EXPORT_SYMBOL_GPL(pcm179x_of_match); + int pcm179x_common_init(struct device *dev, struct regmap *regmap) { struct pcm179x_private *pcm179x; + struct device_node *np = dev->of_node; + enum pcm179x_type codec_model = PCM1792A;
pcm179x = devm_kzalloc(dev, sizeof(struct pcm179x_private), GFP_KERNEL); if (!pcm179x) return -ENOMEM;
+ if (np) { + const struct of_device_id *of_id; + + of_id = of_match_device(pcm179x_of_match, dev); + if (of_id) + codec_model = (enum pcm179x_type) of_id->data; + } + + if (codec_model) + pcm179x->codec_model = codec_model; + pcm179x->regmap = regmap; dev_set_drvdata(dev, pcm179x);
diff --git a/sound/soc/codecs/pcm179x.h b/sound/soc/codecs/pcm179x.h index 11e3312..4c00047 100644 --- a/sound/soc/codecs/pcm179x.h +++ b/sound/soc/codecs/pcm179x.h @@ -17,10 +17,15 @@ #ifndef __PCM179X_H__ #define __PCM179X_H__
-#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S16_LE) +#define PCM179X_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S16_LE) + +#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) + +#define PCM1795_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE)
extern const struct regmap_config pcm179x_regmap_config; +extern const struct of_device_id pcm179x_of_match[];
int pcm179x_common_init(struct device *dev, struct regmap *regmap); int pcm179x_common_exit(struct device *dev);
ASoC: pcm179x: Add support for pcm1795 and pcm1796
Signed-off-by: Michael Trimarchi michael@amarulasolutions.com Tested-by: Angelo Adamo adamo.a60@gmail.com --- Changes v5 -> v6 - Add device tree documentation
Changes v4 -> v5 - remove dead code
Changes v3 -> v4: - clean up compatible list - use enum type instead of pointer of int
Changes v2 -> v3: - rebase after i2c support
Changes v1 -> v2: - Use switch for support new variants - sort the compatible list
.../devicetree/bindings/sound/pcm179x.txt | 2 + sound/soc/codecs/pcm179x-i2c.c | 6 -- sound/soc/codecs/pcm179x-spi.c | 6 -- sound/soc/codecs/pcm179x.c | 65 ++++++++++++++++++++-- sound/soc/codecs/pcm179x.h | 9 ++- 5 files changed, 70 insertions(+), 18 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/pcm179x.txt b/Documentation/devicetree/bindings/sound/pcm179x.txt index 436c2b2..f642eaf 100644 --- a/Documentation/devicetree/bindings/sound/pcm179x.txt +++ b/Documentation/devicetree/bindings/sound/pcm179x.txt @@ -5,6 +5,8 @@ This driver supports both the I2C and SPI bus. Required properties:
- compatible: "ti,pcm1792a" + - compatible: "ti,pcm1795" + - compatible: "ti,pcm1796"
For required properties on SPI, please consult Documentation/devicetree/bindings/spi/spi-bus.txt diff --git a/sound/soc/codecs/pcm179x-i2c.c b/sound/soc/codecs/pcm179x-i2c.c index 4118106..609f07f 100644 --- a/sound/soc/codecs/pcm179x-i2c.c +++ b/sound/soc/codecs/pcm179x-i2c.c @@ -44,12 +44,6 @@ static int pcm179x_i2c_remove(struct i2c_client *client) return pcm179x_common_exit(&client->dev); }
-static const struct of_device_id pcm179x_of_match[] = { - { .compatible = "ti,pcm1792a", }, - { } -}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match); - static const struct i2c_device_id pcm179x_i2c_ids[] = { { "pcm179x", 0 }, { } diff --git a/sound/soc/codecs/pcm179x-spi.c b/sound/soc/codecs/pcm179x-spi.c index da924d4..6ae0e4d 100644 --- a/sound/soc/codecs/pcm179x-spi.c +++ b/sound/soc/codecs/pcm179x-spi.c @@ -43,12 +43,6 @@ static int pcm179x_spi_remove(struct spi_device *spi) return pcm179x_common_exit(&spi->dev); }
-static const struct of_device_id pcm179x_of_match[] = { - { .compatible = "ti,pcm1792a", }, - { } -}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match); - static const struct spi_device_id pcm179x_spi_ids[] = { { "pcm179x", 0 }, { }, diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index 06a6657..fb01822 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c @@ -20,6 +20,8 @@ #include <linux/slab.h> #include <linux/kernel.h> #include <linux/device.h> +#include <linux/of.h> +#include <linux/of_device.h>
#include <sound/core.h> #include <sound/pcm.h> @@ -68,14 +70,42 @@ static bool pcm179x_writeable_reg(struct device *dev, unsigned register reg) return accessible && reg != 0x16 && reg != 0x17; }
+enum pcm179x_type { + PCM1792A, + PCM1795, + PCM1796, +}; + struct pcm179x_private { struct regmap *regmap; unsigned int format; unsigned int rate; + enum pcm179x_type codec_model; };
+static int pcm179x_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); + u64 formats = PCM1792A_FORMATS; + + switch (priv->codec_model) { + case PCM1795: + formats = PCM1795_FORMATS; + break; + default: + break; + } + + snd_pcm_hw_constraint_mask64(substream->runtime, + SNDRV_PCM_HW_PARAM_FORMAT, formats); + + return 0; +} + static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int format) + unsigned int format) { struct snd_soc_codec *codec = codec_dai->codec; struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); @@ -112,8 +142,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_RIGHT_J: switch (params_width(params)) { - case 24: case 32: + val = 1; + break; + case 24: val = 2; break; case 16: @@ -125,8 +157,10 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, break; case SND_SOC_DAIFMT_I2S: switch (params_width(params)) { - case 24: case 32: + val = 4; + break; + case 24: val = 5; break; case 16: @@ -152,6 +186,7 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream, }
static const struct snd_soc_dai_ops pcm179x_dai_ops = { + .startup = pcm179x_startup, .set_fmt = pcm179x_set_dai_fmt, .hw_params = pcm179x_hw_params, .digital_mute = pcm179x_digital_mute, @@ -190,7 +225,7 @@ static struct snd_soc_dai_driver pcm179x_dai = { .rates = SNDRV_PCM_RATE_CONTINUOUS, .rate_min = 10000, .rate_max = 200000, - .formats = PCM1792A_FORMATS, }, + .formats = PCM179X_FORMATS, }, .ops = &pcm179x_dai_ops, };
@@ -214,15 +249,37 @@ static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), };
+const struct of_device_id pcm179x_of_match[] = { + { .compatible = "ti,pcm1792a", }, + { .compatible = "ti,pcm1795", .data = (void *)PCM1795, }, + { .compatible = "ti,pcm1796", }, + { } +}; +MODULE_DEVICE_TABLE(of, pcm179x_of_match); +EXPORT_SYMBOL_GPL(pcm179x_of_match); + int pcm179x_common_init(struct device *dev, struct regmap *regmap) { struct pcm179x_private *pcm179x; + struct device_node *np = dev->of_node; + enum pcm179x_type codec_model = PCM1792A;
pcm179x = devm_kzalloc(dev, sizeof(struct pcm179x_private), GFP_KERNEL); if (!pcm179x) return -ENOMEM;
+ if (np) { + const struct of_device_id *of_id; + + of_id = of_match_device(pcm179x_of_match, dev); + if (of_id) + codec_model = (enum pcm179x_type) of_id->data; + } + + if (codec_model) + pcm179x->codec_model = codec_model; + pcm179x->regmap = regmap; dev_set_drvdata(dev, pcm179x);
diff --git a/sound/soc/codecs/pcm179x.h b/sound/soc/codecs/pcm179x.h index 11e3312..4c00047 100644 --- a/sound/soc/codecs/pcm179x.h +++ b/sound/soc/codecs/pcm179x.h @@ -17,10 +17,15 @@ #ifndef __PCM179X_H__ #define __PCM179X_H__
-#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S16_LE) +#define PCM179X_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S16_LE) + +#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) + +#define PCM1795_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE)
extern const struct regmap_config pcm179x_regmap_config; +extern const struct of_device_id pcm179x_of_match[];
int pcm179x_common_init(struct device *dev, struct regmap *regmap); int pcm179x_common_exit(struct device *dev);
On Sat, Mar 12, 2016 at 12:29:00AM +0100, Michael Trimarchi wrote:
diff --git a/sound/soc/codecs/pcm179x-i2c.c b/sound/soc/codecs/pcm179x-i2c.c index 4118106..609f07f 100644 --- a/sound/soc/codecs/pcm179x-i2c.c +++ b/sound/soc/codecs/pcm179x-i2c.c @@ -44,12 +44,6 @@ static int pcm179x_i2c_remove(struct i2c_client *client) return pcm179x_common_exit(&client->dev); }
-static const struct of_device_id pcm179x_of_match[] = {
- { .compatible = "ti,pcm1792a", },
- { }
-}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match);
One effect of moving this out of the I2C driver is to break module autoloading: currently modutils does not pay attention to the reference from the driver structure to the ID table but instead just looks at the MODULE_DEVICE_TABLE. This is a problem with some existing devices but we shouldn't introduce new instances.
I don't actually know if MODULE_DEVICE_TABLE can reference an object in a different file off the top of my head, though a brief test suggests it has issues.
+static int pcm179x_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
+{
- struct snd_soc_codec *codec = dai->codec;
- struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
- u64 formats = PCM1792A_FORMATS;
- switch (priv->codec_model) {
- case PCM1795:
formats = PCM1795_FORMATS;
break;
It would be more data driven to just register a different DAI structure for the 1795. Both approaches work, it's just a little nicer to avoid code where possible.
On Sat, Mar 12, 2016 at 12:53:17PM +0700, Mark Brown wrote:
On Sat, Mar 12, 2016 at 12:29:00AM +0100, Michael Trimarchi wrote:
diff --git a/sound/soc/codecs/pcm179x-i2c.c b/sound/soc/codecs/pcm179x-i2c.c index 4118106..609f07f 100644 --- a/sound/soc/codecs/pcm179x-i2c.c +++ b/sound/soc/codecs/pcm179x-i2c.c @@ -44,12 +44,6 @@ static int pcm179x_i2c_remove(struct i2c_client *client) return pcm179x_common_exit(&client->dev); }
-static const struct of_device_id pcm179x_of_match[] = {
- { .compatible = "ti,pcm1792a", },
- { }
-}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match);
One effect of moving this out of the I2C driver is to break module autoloading: currently modutils does not pay attention to the reference from the driver structure to the ID table but instead just looks at the MODULE_DEVICE_TABLE. This is a problem with some existing devices but we shouldn't introduce new instances.
I don't actually know if MODULE_DEVICE_TABLE can reference an object in a different file off the top of my head, though a brief test suggests it has issues.
Does this approch can work?
diff --git a/sound/soc/codecs/pcm179x-i2c.c b/sound/soc/codecs/pcm179x-i2c.c index 609f07f..6bed54f 100644 --- a/sound/soc/codecs/pcm179x-i2c.c +++ b/sound/soc/codecs/pcm179x-i2c.c @@ -49,6 +49,7 @@ static const struct i2c_device_id pcm179x_i2c_ids[] = { { } }; MODULE_DEVICE_TABLE(i2c, pcm179x_i2c_ids); +MODULE_DEVICE_TABLE(of, pcm179x_of_match);
static struct i2c_driver pcm179x_i2c_driver = { .driver = { diff --git a/sound/soc/codecs/pcm179x-spi.c b/sound/soc/codecs/pcm179x-spi.c index 6ae0e4d..556c875 100644 --- a/sound/soc/codecs/pcm179x-spi.c +++ b/sound/soc/codecs/pcm179x-spi.c @@ -48,6 +48,7 @@ static const struct spi_device_id pcm179x_spi_ids[] = { { }, }; MODULE_DEVICE_TABLE(spi, pcm179x_spi_ids); +MODULE_DEVICE_TABLE(of, pcm179x_of_match);
static struct spi_driver pcm179x_spi_driver = { .driver = { diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index fb01822..a34af5b 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c @@ -255,7 +255,6 @@ const struct of_device_id pcm179x_of_match[] = { { .compatible = "ti,pcm1796", }, { } }; -MODULE_DEVICE_TABLE(of, pcm179x_of_match); EXPORT_SYMBOL_GPL(pcm179x_of_match);
int pcm179x_common_init(struct device *dev, struct regmap *regmap)
+static int pcm179x_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
+{
- struct snd_soc_codec *codec = dai->codec;
- struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
- u64 formats = PCM1792A_FORMATS;
- switch (priv->codec_model) {
- case PCM1795:
formats = PCM1795_FORMATS;
break;
It would be more data driven to just register a different DAI structure for the 1795. Both approaches work, it's just a little nicer to avoid code where possible.
Yes I know but my idea was exactly to not create special DAI because technically they are the same code with diffferent constraints. This even give an other example of the usage of the API.
Michael
On Sun, Mar 13, 2016 at 09:53:46AM +0100, Michael Trimarchi wrote:
On Sat, Mar 12, 2016 at 12:53:17PM +0700, Mark Brown wrote:
On Sat, Mar 12, 2016 at 12:29:00AM +0100, Michael Trimarchi wrote:
diff --git a/sound/soc/codecs/pcm179x-i2c.c b/sound/soc/codecs/pcm179x-i2c.c index 4118106..609f07f 100644 --- a/sound/soc/codecs/pcm179x-i2c.c +++ b/sound/soc/codecs/pcm179x-i2c.c @@ -44,12 +44,6 @@ static int pcm179x_i2c_remove(struct i2c_client *client) return pcm179x_common_exit(&client->dev); }
-static const struct of_device_id pcm179x_of_match[] = {
- { .compatible = "ti,pcm1792a", },
- { }
-}; -MODULE_DEVICE_TABLE(of, pcm179x_of_match);
One effect of moving this out of the I2C driver is to break module autoloading: currently modutils does not pay attention to the reference from the driver structure to the ID table but instead just looks at the MODULE_DEVICE_TABLE. This is a problem with some existing devices but we shouldn't introduce new instances.
I don't actually know if MODULE_DEVICE_TABLE can reference an object in a different file off the top of my head, though a brief test suggests it has issues.
Does this approch can work?
I need to test, as you said I don't have feeling. I found only this commit
commit 5e4cb7b60833b0124a9f71dbc5118144ca79c3c4 Author: Axel Lin axel.lin@ingics.com Date: Thu Jun 25 21:44:13 2015 +0800
ASoC: cs42xx8: Setup of_match_table
Setup of_match_table and since cs42xx8_of_match is exported and used in cs42xx8-i2c.c, it cannot be static.
Signed-off-by: Axel Lin axel.lin@ingics.com Acked-by: Brian Austin brian.austin@cirrus.com Signed-off-by: Mark Brown broonie@kernel.org
Seems a similar approch
Michael
diff --git a/sound/soc/codecs/pcm179x-i2c.c b/sound/soc/codecs/pcm179x-i2c.c index 609f07f..6bed54f 100644 --- a/sound/soc/codecs/pcm179x-i2c.c +++ b/sound/soc/codecs/pcm179x-i2c.c @@ -49,6 +49,7 @@ static const struct i2c_device_id pcm179x_i2c_ids[] = { { } }; MODULE_DEVICE_TABLE(i2c, pcm179x_i2c_ids); +MODULE_DEVICE_TABLE(of, pcm179x_of_match);
static struct i2c_driver pcm179x_i2c_driver = { .driver = { diff --git a/sound/soc/codecs/pcm179x-spi.c b/sound/soc/codecs/pcm179x-spi.c index 6ae0e4d..556c875 100644 --- a/sound/soc/codecs/pcm179x-spi.c +++ b/sound/soc/codecs/pcm179x-spi.c @@ -48,6 +48,7 @@ static const struct spi_device_id pcm179x_spi_ids[] = { { }, }; MODULE_DEVICE_TABLE(spi, pcm179x_spi_ids); +MODULE_DEVICE_TABLE(of, pcm179x_of_match);
static struct spi_driver pcm179x_spi_driver = { .driver = { diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index fb01822..a34af5b 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c @@ -255,7 +255,6 @@ const struct of_device_id pcm179x_of_match[] = { { .compatible = "ti,pcm1796", }, { } }; -MODULE_DEVICE_TABLE(of, pcm179x_of_match); EXPORT_SYMBOL_GPL(pcm179x_of_match);
int pcm179x_common_init(struct device *dev, struct regmap *regmap)
+static int pcm179x_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
+{
- struct snd_soc_codec *codec = dai->codec;
- struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
- u64 formats = PCM1792A_FORMATS;
- switch (priv->codec_model) {
- case PCM1795:
formats = PCM1795_FORMATS;
break;
It would be more data driven to just register a different DAI structure for the 1795. Both approaches work, it's just a little nicer to avoid code where possible.
Yes I know but my idea was exactly to not create special DAI because technically they are the same code with diffferent constraints. This even give an other example of the usage of the API.
Michael
-- | Michael Nazzareno Trimarchi Amarula Solutions BV | | COO - Founder Cruquiuskade 47 | | +31(0)851119172 Amsterdam 1018 AM NL | | [`as] http://www.amarulasolutions.com |
On Sun, Mar 13, 2016 at 09:53:50AM +0100, Michael Trimarchi wrote:
On Sat, Mar 12, 2016 at 12:53:17PM +0700, Mark Brown wrote:
On Sat, Mar 12, 2016 at 12:29:00AM +0100, Michael Trimarchi wrote:
I don't actually know if MODULE_DEVICE_TABLE can reference an object in a different file off the top of my head, though a brief test suggests it has issues.
Does this approch can work?
I'd suggest testing...
It would be more data driven to just register a different DAI structure for the 1795. Both approaches work, it's just a little nicer to avoid code where possible.
Yes I know but my idea was exactly to not create special DAI because technically they are the same code with diffferent constraints. This even give an other example of the usage of the API.
They would still share all the same code, it's just moving the decision to probe time given that this is a trivial constraint change and the constraints are listed in the data structure.
On Sat, Mar 12, 2016 at 12:29:00AM +0100, Michael Trimarchi wrote:
ASoC: pcm179x: Add support for pcm1795 and pcm1796
Signed-off-by: Michael Trimarchi michael@amarulasolutions.com Tested-by: Angelo Adamo adamo.a60@gmail.com
Changes v5 -> v6
- Add device tree documentation
Changes v4 -> v5
- remove dead code
Changes v3 -> v4:
- clean up compatible list
- use enum type instead of pointer of int
Changes v2 -> v3:
- rebase after i2c support
Changes v1 -> v2:
- Use switch for support new variants
- sort the compatible list
.../devicetree/bindings/sound/pcm179x.txt | 2 +
Acked-by: Rob Herring robh@kernel.org
sound/soc/codecs/pcm179x-i2c.c | 6 -- sound/soc/codecs/pcm179x-spi.c | 6 -- sound/soc/codecs/pcm179x.c | 65 ++++++++++++++++++++-- sound/soc/codecs/pcm179x.h | 9 ++- 5 files changed, 70 insertions(+), 18 deletions(-)
On Fri, Mar 11, 2016 at 11:59:42PM +0100, Michael Trimarchi wrote:
ASoC: pcm179x: Add support for pcm1795 and pcm1796
Signed-off-by: Michael Trimarchi michael@amarulasolutions.com Tested-by: Angelo Adamo adamo.a60@gmail.com
Please don't send new patches in reply to old patches, it makes it hard to tell what versions of things are current.
participants (4)
-
Jacob Siverskog
-
Mark Brown
-
Michael Trimarchi
-
Rob Herring