summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/cs35l56-spi.c
diff options
context:
space:
mode:
authorRichard Fitzgerald <rf@opensource.cirrus.com>2023-03-20 14:22:45 +0300
committerMark Brown <broonie@kernel.org>2023-03-21 15:13:24 +0300
commite496112529006ce0c2cfe67d1136186e2786d2e8 (patch)
tree0cccac0a5156607476b1498a42d043acf707a4c6 /sound/soc/codecs/cs35l56-spi.c
parent991b1de830f61076b7dc29bec081a4d2e50724cf (diff)
downloadlinux-e496112529006ce0c2cfe67d1136186e2786d2e8.tar.xz
ASoC: cs35l56: Add driver for Cirrus Logic CS35L56
The CS35L56 combines a high-performance mono audio amplifier, Class-H tracking inductive boost converter, Halo Core(TM) DSP and a DC-DC boost converter supporting Class-H tracking. Supported control interfaces are I2C, SPI or SoundWire. Supported audio interfaces are I2S/TDM or SoundWire. Most chip functionality is controlled by on-board ROM firmware that is always running. The driver must apply patch/tune to the firmware before using the CS35L56. Signed-off-by: Simon Trimmer <simont@opensource.cirrus.com> Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com> Link: https://lore.kernel.org/r/20230320112245.115720-9-rf@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/codecs/cs35l56-spi.c')
-rw-r--r--sound/soc/codecs/cs35l56-spi.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/sound/soc/codecs/cs35l56-spi.c b/sound/soc/codecs/cs35l56-spi.c
new file mode 100644
index 000000000000..80dcf37daae2
--- /dev/null
+++ b/sound/soc/codecs/cs35l56-spi.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// CS35L56 ALSA SoC audio driver SPI binding
+//
+// Copyright (C) 2023 Cirrus Logic, Inc. and
+// Cirrus Logic International Semiconductor Ltd.
+
+#include <linux/acpi.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+#include <linux/types.h>
+
+#include "cs35l56.h"
+
+static int cs35l56_spi_probe(struct spi_device *spi)
+{
+ const struct regmap_config *regmap_config = &cs35l56_regmap_spi;
+ struct cs35l56_private *cs35l56;
+ int ret;
+
+ cs35l56 = devm_kzalloc(&spi->dev, sizeof(struct cs35l56_private), GFP_KERNEL);
+ if (!cs35l56)
+ return -ENOMEM;
+
+ spi_set_drvdata(spi, cs35l56);
+ cs35l56->regmap = devm_regmap_init_spi(spi, regmap_config);
+ if (IS_ERR(cs35l56->regmap)) {
+ ret = PTR_ERR(cs35l56->regmap);
+ return dev_err_probe(&spi->dev, ret, "Failed to allocate register map\n");
+ return ret;
+ }
+
+ cs35l56->dev = &spi->dev;
+ cs35l56->irq = spi->irq;
+
+ ret = cs35l56_common_probe(cs35l56);
+ if (ret != 0)
+ return ret;
+
+ ret = cs35l56_init(cs35l56);
+ if (ret == 0)
+ ret = cs35l56_irq_request(cs35l56);
+ if (ret < 0)
+ cs35l56_remove(cs35l56);
+
+ return ret;
+}
+
+static void cs35l56_spi_remove(struct spi_device *spi)
+{
+ struct cs35l56_private *cs35l56 = spi_get_drvdata(spi);
+
+ cs35l56_remove(cs35l56);
+}
+
+static const struct spi_device_id cs35l56_id_spi[] = {
+ { "cs35l56", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(spi, cs35l56_id_spi);
+
+static struct spi_driver cs35l56_spi_driver = {
+ .driver = {
+ .name = "cs35l56",
+ .pm = &cs35l56_pm_ops_i2c_spi,
+ },
+ .id_table = cs35l56_id_spi,
+ .probe = cs35l56_spi_probe,
+ .remove = cs35l56_spi_remove,
+};
+
+module_spi_driver(cs35l56_spi_driver);
+
+MODULE_DESCRIPTION("ASoC CS35L56 SPI driver");
+MODULE_IMPORT_NS(SND_SOC_CS35L56_CORE);
+MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
+MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
+MODULE_LICENSE("GPL");