mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
Merge tag 'sound-6.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "A collection of lots of small changes, almost all device-specific: - A series of fixes for ASoC Qualcomm stuff - Various fixes for Cirrus ASoC and HD-audio codecs - A few AMD ASoC quirks and usual HD-audio quirks - Other misc fixes, including a long-time regression in USB-audio" * tag 'sound-6.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (39 commits) ASoC: cs35l56: Patch CS35L56_IRQ1_MASK_18 to the default value ASoC: meson: axg-fifo: fix irq scheduling issue with PREEMPT_RT MAINTAINERS: Update Cirrus Logic parts to linux-sound mailing list ASoC: dt-bindings: qcom,wcd939x: Correct reset GPIO polarity in example ASoC: dt-bindings: qcom,wcd938x: Correct reset GPIO polarity in example ASoC: dt-bindings: qcom,wcd934x: Correct reset GPIO polarity in example ASoC: dt-bindings: qcom,wcd937x: Correct reset GPIO polarity in example ASoC: amd: yc: Add quirk entry for OMEN by HP Gaming Laptop 16-n0xxx ASoC: codecs: ES8326: button detect issue ASoC: amd: yc: Support mic on Lenovo Thinkpad E14 Gen 6 ALSA: usb-audio: Re-add ScratchAmp quirk entries ALSA: hda/realtek: Add Framework Laptop 13 (Intel Core Ultra) to quirks ALSA: hda/hdmi: Yet more pin fix for HP EliteDesk 800 G4 ALSA: hda: Add HP MP9 G4 Retail System AMS to force connect list ASoC: cs35l56: Handle OTP read latency over SoundWire ASoC: codecs: lpass-macro: fix missing codec version ALSA: line6: Fix racy access to midibuf ASoC: cs-amp-lib: Fix NULL pointer crash if efi.get_variable is NULL ASoC: cs35l56: Stop creating ALSA controls for firmware coefficients ASoC: wm_adsp: Add control_add callback and export wm_adsp_control_add() ...
This commit is contained in:
@@ -199,10 +199,11 @@ additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
codec@1,0{
|
||||
compatible = "slim217,250";
|
||||
reg = <1 0>;
|
||||
reset-gpios = <&tlmm 64 0>;
|
||||
reset-gpios = <&tlmm 64 GPIO_ACTIVE_LOW>;
|
||||
slim-ifc-dev = <&wcd9340_ifd>;
|
||||
#sound-dai-cells = <1>;
|
||||
interrupt-parent = <&tlmm>;
|
||||
|
||||
@@ -42,7 +42,7 @@ examples:
|
||||
pinctrl-names = "default", "sleep";
|
||||
pinctrl-0 = <&wcd_reset_n>;
|
||||
pinctrl-1 = <&wcd_reset_n_sleep>;
|
||||
reset-gpios = <&tlmm 83 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpios = <&tlmm 83 GPIO_ACTIVE_LOW>;
|
||||
vdd-buck-supply = <&vreg_l17b_1p8>;
|
||||
vdd-rxtx-supply = <&vreg_l18b_1p8>;
|
||||
vdd-px-supply = <&vreg_l18b_1p8>;
|
||||
|
||||
@@ -34,9 +34,10 @@ unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
codec {
|
||||
compatible = "qcom,wcd9380-codec";
|
||||
reset-gpios = <&tlmm 32 0>;
|
||||
reset-gpios = <&tlmm 32 GPIO_ACTIVE_LOW>;
|
||||
#sound-dai-cells = <1>;
|
||||
qcom,tx-device = <&wcd938x_tx>;
|
||||
qcom,rx-device = <&wcd938x_rx>;
|
||||
|
||||
@@ -52,10 +52,10 @@ unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
codec {
|
||||
compatible = "qcom,wcd9390-codec";
|
||||
reset-gpios = <&tlmm 32 IRQ_TYPE_NONE>;
|
||||
reset-gpios = <&tlmm 32 GPIO_ACTIVE_LOW>;
|
||||
#sound-dai-cells = <1>;
|
||||
qcom,tx-device = <&wcd939x_tx>;
|
||||
qcom,rx-device = <&wcd939x_rx>;
|
||||
|
||||
@@ -5306,7 +5306,7 @@ F: drivers/media/cec/i2c/ch7322.c
|
||||
CIRRUS LOGIC AUDIO CODEC DRIVERS
|
||||
M: David Rhodes <david.rhodes@cirrus.com>
|
||||
M: Richard Fitzgerald <rf@opensource.cirrus.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
L: linux-sound@vger.kernel.org
|
||||
L: patches@opensource.cirrus.com
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/cirrus,cs*
|
||||
@@ -5375,7 +5375,7 @@ F: sound/soc/codecs/lochnagar-sc.c
|
||||
CIRRUS LOGIC MADERA CODEC DRIVERS
|
||||
M: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
M: Richard Fitzgerald <rf@opensource.cirrus.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
L: linux-sound@vger.kernel.org
|
||||
L: patches@opensource.cirrus.com
|
||||
S: Supported
|
||||
W: https://github.com/CirrusLogic/linux-drivers/wiki
|
||||
|
||||
@@ -277,6 +277,11 @@ static inline int cs35l56_force_sync_asp1_registers_from_cache(struct cs35l56_ba
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool cs35l56_is_otp_register(unsigned int reg)
|
||||
{
|
||||
return (reg >> 16) == 3;
|
||||
}
|
||||
|
||||
extern struct regmap_config cs35l56_regmap_i2c;
|
||||
extern struct regmap_config cs35l56_regmap_spi;
|
||||
extern struct regmap_config cs35l56_regmap_sdw;
|
||||
|
||||
@@ -462,6 +462,11 @@ int snd_soc_component_force_enable_pin_unlocked(
|
||||
const char *pin);
|
||||
|
||||
/* component controls */
|
||||
struct snd_kcontrol *snd_soc_component_get_kcontrol(struct snd_soc_component *component,
|
||||
const char * const ctl);
|
||||
struct snd_kcontrol *
|
||||
snd_soc_component_get_kcontrol_locked(struct snd_soc_component *component,
|
||||
const char * const ctl);
|
||||
int snd_soc_component_notify_control(struct snd_soc_component *component,
|
||||
const char * const ctl);
|
||||
|
||||
|
||||
@@ -133,17 +133,6 @@ static const struct reg_sequence cs35l41_hda_mute[] = {
|
||||
{ CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_HPF_PCM_EN = 1, AMP_VOL_PCM Mute
|
||||
};
|
||||
|
||||
static void cs35l41_add_controls(struct cs35l41_hda *cs35l41)
|
||||
{
|
||||
struct hda_cs_dsp_ctl_info info;
|
||||
|
||||
info.device_name = cs35l41->amp_name;
|
||||
info.fw_type = cs35l41->firmware_type;
|
||||
info.card = cs35l41->codec->card;
|
||||
|
||||
hda_cs_dsp_add_controls(&cs35l41->cs_dsp, &info);
|
||||
}
|
||||
|
||||
static const struct cs_dsp_client_ops client_ops = {
|
||||
.control_remove = hda_cs_dsp_control_remove,
|
||||
};
|
||||
@@ -603,8 +592,6 @@ static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41)
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
cs35l41_add_controls(cs35l41);
|
||||
|
||||
cs35l41_hda_apply_calibration(cs35l41);
|
||||
|
||||
err:
|
||||
|
||||
@@ -559,18 +559,6 @@ static void cs35l56_hda_release_firmware_files(const struct firmware *wmfw_firmw
|
||||
kfree(coeff_filename);
|
||||
}
|
||||
|
||||
static void cs35l56_hda_create_dsp_controls_work(struct work_struct *work)
|
||||
{
|
||||
struct cs35l56_hda *cs35l56 = container_of(work, struct cs35l56_hda, control_work);
|
||||
struct hda_cs_dsp_ctl_info info;
|
||||
|
||||
info.device_name = cs35l56->amp_name;
|
||||
info.fw_type = HDA_CS_DSP_FW_MISC;
|
||||
info.card = cs35l56->codec->card;
|
||||
|
||||
hda_cs_dsp_add_controls(&cs35l56->cs_dsp, &info);
|
||||
}
|
||||
|
||||
static void cs35l56_hda_apply_calibration(struct cs35l56_hda *cs35l56)
|
||||
{
|
||||
int ret;
|
||||
@@ -595,26 +583,15 @@ static void cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
|
||||
char *wmfw_filename = NULL;
|
||||
unsigned int preloaded_fw_ver;
|
||||
bool firmware_missing;
|
||||
bool add_dsp_controls_required = false;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* control_work must be flushed before proceeding, but we can't do that
|
||||
* here as it would create a deadlock on controls_rwsem so it must be
|
||||
* performed before queuing dsp_work.
|
||||
*/
|
||||
WARN_ON_ONCE(work_busy(&cs35l56->control_work));
|
||||
|
||||
/*
|
||||
* Prepare for a new DSP power-up. If the DSP has had firmware
|
||||
* downloaded previously then it needs to be powered down so that it
|
||||
* can be updated and if hadn't been patched before then the controls
|
||||
* will need to be added once firmware download succeeds.
|
||||
* can be updated.
|
||||
*/
|
||||
if (cs35l56->base.fw_patched)
|
||||
cs_dsp_power_down(&cs35l56->cs_dsp);
|
||||
else
|
||||
add_dsp_controls_required = true;
|
||||
|
||||
cs35l56->base.fw_patched = false;
|
||||
|
||||
@@ -698,15 +675,6 @@ static void cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
|
||||
CS35L56_FIRMWARE_MISSING);
|
||||
cs35l56->base.fw_patched = true;
|
||||
|
||||
/*
|
||||
* Adding controls is deferred to prevent a lock inversion - ALSA takes
|
||||
* the controls_rwsem when adding a control, the get() / put()
|
||||
* functions of a control are called holding controls_rwsem and those
|
||||
* that depend on running firmware wait for dsp_work() to complete.
|
||||
*/
|
||||
if (add_dsp_controls_required)
|
||||
queue_work(system_long_wq, &cs35l56->control_work);
|
||||
|
||||
ret = cs_dsp_run(&cs35l56->cs_dsp);
|
||||
if (ret)
|
||||
dev_dbg(cs35l56->base.dev, "%s: cs_dsp_run ret %d\n", __func__, ret);
|
||||
@@ -753,7 +721,6 @@ static int cs35l56_hda_bind(struct device *dev, struct device *master, void *mas
|
||||
strscpy(comp->name, dev_name(dev), sizeof(comp->name));
|
||||
comp->playback_hook = cs35l56_hda_playback_hook;
|
||||
|
||||
flush_work(&cs35l56->control_work);
|
||||
queue_work(system_long_wq, &cs35l56->dsp_work);
|
||||
|
||||
cs35l56_hda_create_controls(cs35l56);
|
||||
@@ -775,7 +742,6 @@ static void cs35l56_hda_unbind(struct device *dev, struct device *master, void *
|
||||
struct hda_component *comp;
|
||||
|
||||
cancel_work_sync(&cs35l56->dsp_work);
|
||||
cancel_work_sync(&cs35l56->control_work);
|
||||
|
||||
cs35l56_hda_remove_controls(cs35l56);
|
||||
|
||||
@@ -806,7 +772,6 @@ static int cs35l56_hda_system_suspend(struct device *dev)
|
||||
struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
|
||||
|
||||
cs35l56_hda_wait_dsp_ready(cs35l56);
|
||||
flush_work(&cs35l56->control_work);
|
||||
|
||||
if (cs35l56->playing)
|
||||
cs35l56_hda_pause(cs35l56);
|
||||
@@ -1026,7 +991,6 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id)
|
||||
dev_set_drvdata(cs35l56->base.dev, cs35l56);
|
||||
|
||||
INIT_WORK(&cs35l56->dsp_work, cs35l56_hda_dsp_work);
|
||||
INIT_WORK(&cs35l56->control_work, cs35l56_hda_create_dsp_controls_work);
|
||||
|
||||
ret = cs35l56_hda_read_acpi(cs35l56, hid, id);
|
||||
if (ret)
|
||||
|
||||
@@ -23,7 +23,6 @@ struct cs35l56_hda {
|
||||
struct cs35l56_base base;
|
||||
struct hda_codec *codec;
|
||||
struct work_struct dsp_work;
|
||||
struct work_struct control_work;
|
||||
|
||||
int index;
|
||||
const char *system_name;
|
||||
|
||||
@@ -1989,6 +1989,8 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
|
||||
}
|
||||
|
||||
static const struct snd_pci_quirk force_connect_list[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x83e2, "HP EliteDesk 800 G4", 1),
|
||||
SND_PCI_QUIRK(0x103c, 0x83ef, "HP MP9 G4 Retail System AMS", 1),
|
||||
SND_PCI_QUIRK(0x103c, 0x870f, "HP", 1),
|
||||
SND_PCI_QUIRK(0x103c, 0x871a, "HP", 1),
|
||||
SND_PCI_QUIRK(0x103c, 0x8711, "HP", 1),
|
||||
|
||||
@@ -10678,6 +10678,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x8086, 0x3038, "Intel NUC 13", ALC295_FIXUP_CHROME_BOOK),
|
||||
SND_PCI_QUIRK(0xf111, 0x0001, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0xf111, 0x0006, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0xf111, 0x0009, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE),
|
||||
|
||||
#if 0
|
||||
/* Below is a quirk table taken from the old code.
|
||||
|
||||
@@ -220,6 +220,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21J6"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21M3"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
@@ -409,6 +416,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "8A43"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "8A44"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
@@ -423,6 +437,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "8A3E"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "8B27"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
|
||||
@@ -108,7 +108,7 @@ static efi_status_t cs_amp_get_efi_variable(efi_char16_t *name,
|
||||
|
||||
KUNIT_STATIC_STUB_REDIRECT(cs_amp_get_efi_variable, name, guid, size, buf);
|
||||
|
||||
if (IS_ENABLED(CONFIG_EFI))
|
||||
if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
|
||||
return efi.get_variable(name, guid, &attr, size, buf);
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
|
||||
@@ -176,17 +176,10 @@ static int cs35l45_activate_ctl(struct snd_soc_component *component,
|
||||
struct snd_kcontrol *kcontrol;
|
||||
struct snd_kcontrol_volatile *vd;
|
||||
unsigned int index_offset;
|
||||
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
|
||||
if (component->name_prefix)
|
||||
snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s",
|
||||
component->name_prefix, ctl_name);
|
||||
else
|
||||
snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s", ctl_name);
|
||||
|
||||
kcontrol = snd_soc_card_get_kcontrol_locked(component->card, name);
|
||||
kcontrol = snd_soc_component_get_kcontrol_locked(component, ctl_name);
|
||||
if (!kcontrol) {
|
||||
dev_err(component->dev, "Can't find kcontrol %s\n", name);
|
||||
dev_err(component->dev, "Can't find kcontrol %s\n", ctl_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,79 @@
|
||||
/* Register addresses are offset when sent over SoundWire */
|
||||
#define CS35L56_SDW_ADDR_OFFSET 0x8000
|
||||
|
||||
/* Cirrus bus bridge registers */
|
||||
#define CS35L56_SDW_MEM_ACCESS_STATUS 0xd0
|
||||
#define CS35L56_SDW_MEM_READ_DATA 0xd8
|
||||
|
||||
#define CS35L56_SDW_LAST_LATE BIT(3)
|
||||
#define CS35L56_SDW_CMD_IN_PROGRESS BIT(2)
|
||||
#define CS35L56_SDW_RDATA_RDY BIT(0)
|
||||
|
||||
#define CS35L56_LATE_READ_POLL_US 10
|
||||
#define CS35L56_LATE_READ_TIMEOUT_US 1000
|
||||
|
||||
static int cs35l56_sdw_poll_mem_status(struct sdw_slave *peripheral,
|
||||
unsigned int mask,
|
||||
unsigned int match)
|
||||
{
|
||||
int ret, val;
|
||||
|
||||
ret = read_poll_timeout(sdw_read_no_pm, val,
|
||||
(val < 0) || ((val & mask) == match),
|
||||
CS35L56_LATE_READ_POLL_US, CS35L56_LATE_READ_TIMEOUT_US,
|
||||
false, peripheral, CS35L56_SDW_MEM_ACCESS_STATUS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs35l56_sdw_slow_read(struct sdw_slave *peripheral, unsigned int reg,
|
||||
u8 *buf, size_t val_size)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
reg += CS35L56_SDW_ADDR_OFFSET;
|
||||
|
||||
for (i = 0; i < val_size; i += sizeof(u32)) {
|
||||
/* Poll for bus bridge idle */
|
||||
ret = cs35l56_sdw_poll_mem_status(peripheral,
|
||||
CS35L56_SDW_CMD_IN_PROGRESS,
|
||||
0);
|
||||
if (ret < 0) {
|
||||
dev_err(&peripheral->dev, "!CMD_IN_PROGRESS fail: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Reading LSByte triggers read of register to holding buffer */
|
||||
sdw_read_no_pm(peripheral, reg + i);
|
||||
|
||||
/* Wait for data available */
|
||||
ret = cs35l56_sdw_poll_mem_status(peripheral,
|
||||
CS35L56_SDW_RDATA_RDY,
|
||||
CS35L56_SDW_RDATA_RDY);
|
||||
if (ret < 0) {
|
||||
dev_err(&peripheral->dev, "RDATA_RDY fail: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Read data from buffer */
|
||||
ret = sdw_nread_no_pm(peripheral, CS35L56_SDW_MEM_READ_DATA,
|
||||
sizeof(u32), &buf[i]);
|
||||
if (ret) {
|
||||
dev_err(&peripheral->dev, "Late read @%#x failed: %d\n", reg + i, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
swab32s((u32 *)&buf[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs35l56_sdw_read_one(struct sdw_slave *peripheral, unsigned int reg, void *buf)
|
||||
{
|
||||
int ret;
|
||||
@@ -48,6 +121,10 @@ static int cs35l56_sdw_read(void *context, const void *reg_buf,
|
||||
int ret;
|
||||
|
||||
reg = le32_to_cpu(*(const __le32 *)reg_buf);
|
||||
|
||||
if (cs35l56_is_otp_register(reg))
|
||||
return cs35l56_sdw_slow_read(peripheral, reg, buf8, val_size);
|
||||
|
||||
reg += CS35L56_SDW_ADDR_OFFSET;
|
||||
|
||||
if (val_size == 4)
|
||||
|
||||
@@ -36,6 +36,7 @@ static const struct reg_sequence cs35l56_patch[] = {
|
||||
{ CS35L56_SWIRE_DP3_CH2_INPUT, 0x00000019 },
|
||||
{ CS35L56_SWIRE_DP3_CH3_INPUT, 0x00000029 },
|
||||
{ CS35L56_SWIRE_DP3_CH4_INPUT, 0x00000028 },
|
||||
{ CS35L56_IRQ1_MASK_18, 0x1f7df0ff },
|
||||
|
||||
/* These are not reset by a soft-reset, so patch to defaults. */
|
||||
{ CS35L56_MAIN_RENDER_USER_MUTE, 0x00000000 },
|
||||
|
||||
@@ -1095,6 +1095,11 @@ int cs35l56_system_resume(struct device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cs35l56_system_resume);
|
||||
|
||||
static int cs35l56_control_add_nop(struct wm_adsp *dsp, struct cs_dsp_coeff_ctl *cs_ctl)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs35l56_dsp_init(struct cs35l56_private *cs35l56)
|
||||
{
|
||||
struct wm_adsp *dsp;
|
||||
@@ -1117,6 +1122,12 @@ static int cs35l56_dsp_init(struct cs35l56_private *cs35l56)
|
||||
dsp->fw = 12;
|
||||
dsp->wmfw_optional = true;
|
||||
|
||||
/*
|
||||
* None of the firmware controls need to be exported so add a no-op
|
||||
* callback that suppresses creating an ALSA control.
|
||||
*/
|
||||
dsp->control_add = &cs35l56_control_add_nop;
|
||||
|
||||
dev_dbg(cs35l56->base.dev, "DSP system name: '%s'\n", dsp->system_name);
|
||||
|
||||
ret = wm_halo_init(dsp);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
@@ -252,24 +253,20 @@ CS42L43_IRQ_COMPLETE(load_detect)
|
||||
static irqreturn_t cs42l43_mic_shutter(int irq, void *data)
|
||||
{
|
||||
struct cs42l43_codec *priv = data;
|
||||
static const char * const controls[] = {
|
||||
"Decimator 1 Switch",
|
||||
"Decimator 2 Switch",
|
||||
"Decimator 3 Switch",
|
||||
"Decimator 4 Switch",
|
||||
};
|
||||
int i, ret;
|
||||
struct snd_soc_component *component = priv->component;
|
||||
int i;
|
||||
|
||||
dev_dbg(priv->dev, "Microphone shutter changed\n");
|
||||
|
||||
if (!priv->component)
|
||||
if (!component)
|
||||
return IRQ_NONE;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(controls); i++) {
|
||||
ret = snd_soc_component_notify_control(priv->component,
|
||||
controls[i]);
|
||||
if (ret)
|
||||
for (i = 1; i < ARRAY_SIZE(priv->kctl); i++) {
|
||||
if (!priv->kctl[i])
|
||||
return IRQ_NONE;
|
||||
|
||||
snd_ctl_notify(component->card->snd_card,
|
||||
SNDRV_CTL_EVENT_MASK_VALUE, &priv->kctl[i]->id);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@@ -278,18 +275,19 @@ static irqreturn_t cs42l43_mic_shutter(int irq, void *data)
|
||||
static irqreturn_t cs42l43_spk_shutter(int irq, void *data)
|
||||
{
|
||||
struct cs42l43_codec *priv = data;
|
||||
int ret;
|
||||
struct snd_soc_component *component = priv->component;
|
||||
|
||||
dev_dbg(priv->dev, "Speaker shutter changed\n");
|
||||
|
||||
if (!priv->component)
|
||||
if (!component)
|
||||
return IRQ_NONE;
|
||||
|
||||
ret = snd_soc_component_notify_control(priv->component,
|
||||
"Speaker Digital Switch");
|
||||
if (ret)
|
||||
if (!priv->kctl[0])
|
||||
return IRQ_NONE;
|
||||
|
||||
snd_ctl_notify(component->card->snd_card,
|
||||
SNDRV_CTL_EVENT_MASK_VALUE, &priv->kctl[0]->id);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -590,7 +588,46 @@ static int cs42l43_asp_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mas
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs42l43_dai_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
|
||||
static const char * const controls[] = {
|
||||
"Speaker Digital Switch",
|
||||
"Decimator 1 Switch",
|
||||
"Decimator 2 Switch",
|
||||
"Decimator 3 Switch",
|
||||
"Decimator 4 Switch",
|
||||
};
|
||||
int i;
|
||||
|
||||
static_assert(ARRAY_SIZE(controls) == ARRAY_SIZE(priv->kctl));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(controls); i++) {
|
||||
if (priv->kctl[i])
|
||||
continue;
|
||||
|
||||
priv->kctl[i] = snd_soc_component_get_kcontrol(component, controls[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs42l43_dai_remove(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(priv->kctl); i++)
|
||||
priv->kctl[i] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops cs42l43_asp_ops = {
|
||||
.probe = cs42l43_dai_probe,
|
||||
.remove = cs42l43_dai_remove,
|
||||
.startup = cs42l43_startup,
|
||||
.hw_params = cs42l43_asp_hw_params,
|
||||
.set_fmt = cs42l43_asp_set_fmt,
|
||||
@@ -608,9 +645,11 @@ static int cs42l43_sdw_hw_params(struct snd_pcm_substream *substream,
|
||||
return ret;
|
||||
|
||||
return cs42l43_set_sample_rate(substream, params, dai);
|
||||
};
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops cs42l43_sdw_ops = {
|
||||
.probe = cs42l43_dai_probe,
|
||||
.remove = cs42l43_dai_remove,
|
||||
.startup = cs42l43_startup,
|
||||
.set_stream = cs42l43_sdw_set_stream,
|
||||
.hw_params = cs42l43_sdw_hw_params,
|
||||
|
||||
@@ -100,6 +100,8 @@ struct cs42l43_codec {
|
||||
struct delayed_work hp_ilimit_clear_work;
|
||||
bool hp_ilimited;
|
||||
int hp_ilimit_count;
|
||||
|
||||
struct snd_kcontrol *kctl[5];
|
||||
};
|
||||
|
||||
#if IS_REACHABLE(CONFIG_SND_SOC_CS42L43_SDW)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user