Unverified Commit fc918cbe authored by Charles Keepax's avatar Charles Keepax Committed by Mark Brown
Browse files

ASoC: cs42l43: Add support for the cs42l43



The CS42L43 is an audio CODEC with integrated MIPI SoundWire interface
(Version 1.2.1 compliant), I2C, SPI, and I2S/TDM interfaces designed
for portable applications. It provides a high dynamic range, stereo
DAC for headphone output, two integrated Class D amplifiers for
loudspeakers, and two ADCs for wired headset microphone input or
stereo line input. PDM inputs are provided for digital microphones.

The ASoC component provides the majority of the functionality of the
device, all the audio functions.

Signed-off-by: default avatarCharles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230804104602.395892-7-ckeepax@opensource.cirrus.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 038e0da7
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * CS42L43 CODEC driver external data
 *
 * Copyright (C) 2022-2023 Cirrus Logic, Inc. and
 *                         Cirrus Logic International Semiconductor Ltd.
 */

#ifndef CS42L43_ASOC_EXT_H
#define CS42L43_ASOC_EXT_H

#define CS42L43_SYSCLK		0

#define CS42L43_SYSCLK_MCLK	0
#define CS42L43_SYSCLK_SDW	1

#endif /* CS42L43_ASOC_EXT_H */
+16 −0
Original line number Diff line number Diff line
@@ -74,6 +74,8 @@ config SND_SOC_ALL_CODECS
	imply SND_SOC_CS35L56_SDW
	imply SND_SOC_CS42L42
	imply SND_SOC_CS42L42_SDW
	imply SND_SOC_CS42L43
	imply SND_SOC_CS42L43_SDW
	imply SND_SOC_CS42L51_I2C
	imply SND_SOC_CS42L52
	imply SND_SOC_CS42L56
@@ -789,6 +791,20 @@ config SND_SOC_CS42L42_SDW
	help
	  Enable support for Cirrus Logic CS42L42 codec with Soundwire control

config SND_SOC_CS42L43
	tristate "Cirrus Logic CS42L43 CODEC"
	depends on MFD_CS42L43
	help
	  Select this to support the audio functions of the Cirrus Logic
	  CS42L43 PC CODEC.

config SND_SOC_CS42L43_SDW
	tristate "Cirrus Logic CS42L43 CODEC (SoundWire)"
	depends on SND_SOC_CS42L43 && MFD_CS42L43_SDW
	help
	  Select this to support the audio functions of the Cirrus Logic
	  CS42L43 PC CODEC over SoundWire.

config SND_SOC_CS42L51
	tristate

+4 −0
Original line number Diff line number Diff line
@@ -75,6 +75,8 @@ snd-soc-cs35l56-sdw-objs := cs35l56-sdw.o
snd-soc-cs42l42-objs := cs42l42.o
snd-soc-cs42l42-i2c-objs := cs42l42-i2c.o
snd-soc-cs42l42-sdw-objs := cs42l42-sdw.o
snd-soc-cs42l43-objs := cs42l43.o cs42l43-jack.o
snd-soc-cs42l43-sdw-objs := cs42l43-sdw.o
snd-soc-cs42l51-objs := cs42l51.o
snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o
snd-soc-cs42l52-objs := cs42l52.o
@@ -457,6 +459,8 @@ obj-$(CONFIG_SND_SOC_CS35L56_SDW) += snd-soc-cs35l56-sdw.o
obj-$(CONFIG_SND_SOC_CS42L42_CORE)	+= snd-soc-cs42l42.o
obj-$(CONFIG_SND_SOC_CS42L42)	+= snd-soc-cs42l42-i2c.o
obj-$(CONFIG_SND_SOC_CS42L42_SDW)	+= snd-soc-cs42l42-sdw.o
obj-$(CONFIG_SND_SOC_CS42L43)	+= snd-soc-cs42l43.o
obj-$(CONFIG_SND_SOC_CS42L43_SDW)	+= snd-soc-cs42l43-sdw.o
obj-$(CONFIG_SND_SOC_CS42L51)	+= snd-soc-cs42l51.o
obj-$(CONFIG_SND_SOC_CS42L51_I2C)	+= snd-soc-cs42l51-i2c.o
obj-$(CONFIG_SND_SOC_CS42L52)	+= snd-soc-cs42l52.o
+946 −0

File added.

Preview size limit exceeded, changes collapsed.

+74 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
//
// CS42L43 CODEC driver SoundWire handling
//
// Copyright (C) 2022-2023 Cirrus Logic, Inc. and
//                         Cirrus Logic International Semiconductor Ltd.

#include <linux/errno.h>
#include <linux/mfd/cs42l43.h>
#include <linux/mfd/cs42l43-regs.h>
#include <linux/module.h>
#include <sound/pcm.h>
#include <sound/sdw.h>
#include <sound/soc-component.h>
#include <sound/soc-dai.h>
#include <sound/soc.h>

#include "cs42l43.h"

int cs42l43_sdw_add_peripheral(struct snd_pcm_substream *substream,
			       struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(dai->component);
	struct sdw_stream_runtime *sdw_stream = snd_soc_dai_get_dma_data(dai, substream);
	struct sdw_slave *sdw = dev_to_sdw_dev(priv->dev->parent);
	struct sdw_stream_config sconfig = {0};
	struct sdw_port_config pconfig = {0};
	int ret;

	if (!sdw_stream)
		return -EINVAL;

	snd_sdw_params_to_config(substream, params, &sconfig, &pconfig);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		pconfig.num = dai->id;
	else
		pconfig.num = dai->id;

	ret = sdw_stream_add_slave(sdw, &sconfig, &pconfig, 1, sdw_stream);
	if (ret) {
		dev_err(priv->dev, "Failed to add sdw stream: %d\n", ret);
		return ret;
	}

	return 0;
}
EXPORT_SYMBOL_NS_GPL(cs42l43_sdw_add_peripheral, SND_SOC_CS42L43);

int cs42l43_sdw_remove_peripheral(struct snd_pcm_substream *substream,
				  struct snd_soc_dai *dai)
{
	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(dai->component);
	struct sdw_stream_runtime *sdw_stream = snd_soc_dai_get_dma_data(dai, substream);
	struct sdw_slave *sdw = dev_to_sdw_dev(priv->dev->parent);

	if (!sdw_stream)
		return -EINVAL;

	return sdw_stream_remove_slave(sdw, sdw_stream);
}
EXPORT_SYMBOL_NS_GPL(cs42l43_sdw_remove_peripheral, SND_SOC_CS42L43);

int cs42l43_sdw_set_stream(struct snd_soc_dai *dai, void *sdw_stream, int direction)
{
	snd_soc_dai_dma_data_set(dai, direction, sdw_stream);

	return 0;
}
EXPORT_SYMBOL_NS_GPL(cs42l43_sdw_set_stream, SND_SOC_CS42L43);

MODULE_DESCRIPTION("CS42L43 CODEC SoundWire Driver");
MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.cirrus.com>");
MODULE_LICENSE("GPL");
Loading