Unverified Commit 85d12eda authored by Mark Brown's avatar Mark Brown
Browse files

ALSA: hda: Adding support for CS35L56 on HDA

Merge series from Richard Fitzgerald <rf@opensource.cirrus.com>:

This set of patches adds support for using the CS35L56 boosted smart
amplifier on HDA systems. In these systems the CS35L56 audio is
routed through a HDA-to-I2S bridge codec.

This doesn't include the changes to the Realtek driver to actually hook
up the CS35L56 driver, because we don't yet have the QUIRK IDs to
associate it with. But we want to publish the driver now so that it is
available for bringing up hardware with the CS35L56.

The first 9 patches are moving code out of the ASoC driver and into the
shared library so that it can be shared with the HDA driver.

Patch #10 fixes missing #includes in the HDA headers so that the CS35L56
driver doesn't have to #include headers that it doesn't use.
parents f54e3474 73cfbfa9
Loading
Loading
Loading
Loading
+27 −2
Original line number Diff line number Diff line
@@ -252,15 +252,40 @@
#define CS35L56_NUM_BULK_SUPPLIES			3
#define CS35L56_NUM_DSP_REGIONS				5

struct cs35l56_base {
	struct device *dev;
	struct regmap *regmap;
	int irq;
	struct mutex irq_lock;
	u8 rev;
	bool init_done;
	bool fw_patched;
	bool secured;
	bool can_hibernate;
	struct gpio_desc *reset_gpio;
};

extern struct regmap_config cs35l56_regmap_i2c;
extern struct regmap_config cs35l56_regmap_spi;
extern struct regmap_config cs35l56_regmap_sdw;

extern const struct cs_dsp_region cs35l56_dsp1_regions[CS35L56_NUM_DSP_REGIONS];
extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC];
extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC];

int cs35l56_set_patch(struct regmap *regmap);
int cs35l56_set_patch(struct cs35l56_base *cs35l56_base);
int cs35l56_mbox_send(struct cs35l56_base *cs35l56_base, unsigned int command);
int cs35l56_firmware_shutdown(struct cs35l56_base *cs35l56_base);
int cs35l56_wait_for_firmware_boot(struct cs35l56_base *cs35l56_base);
void cs35l56_wait_control_port_ready(void);
void cs35l56_wait_min_reset_pulse(void);
void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire);
int cs35l56_irq_request(struct cs35l56_base *cs35l56_base, int irq);
irqreturn_t cs35l56_irq(int irq, void *data);
int cs35l56_is_fw_reload_needed(struct cs35l56_base *cs35l56_base);
int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base);
int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_soundwire);
void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp);
int cs35l56_hw_init(struct cs35l56_base *cs35l56_base);
int cs35l56_get_bclk_freq_id(unsigned int freq);
void cs35l56_fill_supply_names(struct regulator_bulk_data *data);

+31 −0
Original line number Diff line number Diff line
@@ -130,6 +130,37 @@ config SND_HDA_SCODEC_CS35L41_SPI
comment "Set to Y if you want auto-loading the side codec driver"
	depends on SND_HDA=y && SND_HDA_SCODEC_CS35L41_SPI=m

config SND_HDA_SCODEC_CS35L56
	tristate

config SND_HDA_SCODEC_CS35L56_I2C
	tristate "Build CS35L56 HD-audio side codec support for I2C Bus"
	depends on I2C
	depends on ACPI || COMPILE_TEST
	depends on SND_SOC
	select CS_DSP
	select SND_HDA_GENERIC
	select SND_SOC_CS35L56_SHARED
	select SND_HDA_SCODEC_CS35L56
	select SND_HDA_CS_DSP_CONTROLS
	help
	  Say Y or M here to include CS35L56 amplifier support with
	  I2C control.

config SND_HDA_SCODEC_CS35L56_SPI
	tristate "Build CS35L56 HD-audio side codec support for SPI Bus"
	depends on SPI_MASTER
	depends on ACPI || COMPILE_TEST
	depends on SND_SOC
	select CS_DSP
	select SND_HDA_GENERIC
	select SND_SOC_CS35L56_SHARED
	select SND_HDA_SCODEC_CS35L56
	select SND_HDA_CS_DSP_CONTROLS
	help
	  Say Y or M here to include CS35L56 amplifier support with
	  SPI control.

config SND_HDA_CODEC_REALTEK
	tristate "Build Realtek HD-audio codec support"
	select SND_HDA_GENERIC
+6 −0
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@ snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o
snd-hda-scodec-cs35l41-objs :=		cs35l41_hda.o
snd-hda-scodec-cs35l41-i2c-objs :=	cs35l41_hda_i2c.o
snd-hda-scodec-cs35l41-spi-objs :=	cs35l41_hda_spi.o
snd-hda-scodec-cs35l56-objs :=		cs35l56_hda.o
snd-hda-scodec-cs35l56-i2c-objs :=	cs35l56_hda_i2c.o
snd-hda-scodec-cs35l56-spi-objs :=	cs35l56_hda_spi.o
snd-hda-cs-dsp-ctls-objs :=		hda_cs_dsp_ctl.o

# common driver
@@ -55,6 +58,9 @@ obj-$(CONFIG_SND_HDA_CODEC_HDMI) += snd-hda-codec-hdmi.o
obj-$(CONFIG_SND_HDA_SCODEC_CS35L41) += snd-hda-scodec-cs35l41.o
obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_I2C) += snd-hda-scodec-cs35l41-i2c.o
obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_SPI) += snd-hda-scodec-cs35l41-spi.o
obj-$(CONFIG_SND_HDA_SCODEC_CS35L56) += snd-hda-scodec-cs35l56.o
obj-$(CONFIG_SND_HDA_SCODEC_CS35L56_I2C) += snd-hda-scodec-cs35l56-i2c.o
obj-$(CONFIG_SND_HDA_SCODEC_CS35L56_SPI) += snd-hda-scodec-cs35l56-spi.o
obj-$(CONFIG_SND_HDA_CS_DSP_CONTROLS) += snd-hda-cs-dsp-ctls.o

# this must be the last entry after codec drivers;
+995 −0

File added.

Preview size limit exceeded, changes collapsed.

+48 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only
 *
 * HDA audio driver for Cirrus Logic CS35L56 smart amp
 *
 * Copyright (C) 2023 Cirrus Logic, Inc. and
 *                    Cirrus Logic International Semiconductor Ltd.
 */

#ifndef __CS35L56_HDA_H__
#define __CS35L56_HDA_H__

#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/firmware/cirrus/cs_dsp.h>
#include <linux/firmware/cirrus/wmfw.h>
#include <linux/regulator/consumer.h>
#include <sound/cs35l56.h>

struct dentry;

struct cs35l56_hda {
	struct cs35l56_base base;
	struct hda_codec *codec;

	int index;
	const char *system_name;
	const char *amp_name;

	struct cs_dsp cs_dsp;
	bool playing;
	bool suspended;
	u8 asp_tx_mask;

	struct snd_kcontrol *posture_ctl;
	struct snd_kcontrol *volume_ctl;
	struct snd_kcontrol *mixer_ctl[4];

#if IS_ENABLED(CONFIG_SND_DEBUG)
	struct dentry *debugfs_root;
#endif
};

extern const struct dev_pm_ops cs35l56_hda_pm_ops;

int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int id);
void cs35l56_hda_remove(struct device *dev);

#endif /*__CS35L56_HDA_H__*/
Loading