Loading sound/core/pcm.c +1 −0 Original line number Diff line number Diff line Loading @@ -253,6 +253,7 @@ static const char * const snd_pcm_state_names[] = { STATE(DRAINING), STATE(PAUSED), STATE(SUSPENDED), STATE(DISCONNECTED), }; static const char * const snd_pcm_access_names[] = { Loading sound/drivers/pcmtest.c +12 −1 Original line number Diff line number Diff line Loading @@ -397,7 +397,6 @@ static int snd_pcmtst_pcm_close(struct snd_pcm_substream *substream) struct pcmtst_buf_iter *v_iter = substream->runtime->private_data; timer_shutdown_sync(&v_iter->timer_instance); v_iter->substream = NULL; playback_capture_test = !v_iter->is_buf_corrupted; kfree(v_iter); return 0; Loading Loading @@ -435,6 +434,7 @@ static int snd_pcmtst_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_PUSH: // We can't call timer_shutdown_sync here, as it is forbidden to sleep here v_iter->suspend = true; timer_delete(&v_iter->timer_instance); break; } Loading Loading @@ -512,12 +512,22 @@ static int snd_pcmtst_ioctl(struct snd_pcm_substream *substream, unsigned int cm return snd_pcm_lib_ioctl(substream, cmd, arg); } static int snd_pcmtst_sync_stop(struct snd_pcm_substream *substream) { struct pcmtst_buf_iter *v_iter = substream->runtime->private_data; timer_delete_sync(&v_iter->timer_instance); return 0; } static const struct snd_pcm_ops snd_pcmtst_playback_ops = { .open = snd_pcmtst_pcm_open, .close = snd_pcmtst_pcm_close, .trigger = snd_pcmtst_pcm_trigger, .hw_params = snd_pcmtst_pcm_hw_params, .ioctl = snd_pcmtst_ioctl, .sync_stop = snd_pcmtst_sync_stop, .hw_free = snd_pcmtst_pcm_hw_free, .prepare = snd_pcmtst_pcm_prepare, .pointer = snd_pcmtst_pcm_pointer, Loading @@ -530,6 +540,7 @@ static const struct snd_pcm_ops snd_pcmtst_capture_ops = { .hw_params = snd_pcmtst_pcm_hw_params, .hw_free = snd_pcmtst_pcm_hw_free, .ioctl = snd_pcmtst_ioctl, .sync_stop = snd_pcmtst_sync_stop, .prepare = snd_pcmtst_pcm_prepare, .pointer = snd_pcmtst_pcm_pointer, }; Loading sound/hda/intel-nhlt.c +29 −4 Original line number Diff line number Diff line Loading @@ -238,7 +238,7 @@ EXPORT_SYMBOL(intel_nhlt_ssp_mclk_mask); static struct nhlt_specific_cfg * nhlt_get_specific_cfg(struct device *dev, struct nhlt_fmt *fmt, u8 num_ch, u32 rate, u8 vbps, u8 bps) u32 rate, u8 vbps, u8 bps, bool ignore_vbps) { struct nhlt_fmt_cfg *cfg = fmt->fmt_config; struct wav_fmt *wfmt; Loading @@ -255,8 +255,12 @@ nhlt_get_specific_cfg(struct device *dev, struct nhlt_fmt *fmt, u8 num_ch, dev_dbg(dev, "Endpoint format: ch=%d fmt=%d/%d rate=%d\n", wfmt->channels, _vbps, _bps, wfmt->samples_per_sec); /* * When looking for exact match of configuration ignore the vbps * from NHLT table when ignore_vbps is true */ if (wfmt->channels == num_ch && wfmt->samples_per_sec == rate && vbps == _vbps && bps == _bps) (ignore_vbps || vbps == _vbps) && bps == _bps) return &cfg->config; cfg = (struct nhlt_fmt_cfg *)(cfg->config.caps + cfg->config.size); Loading Loading @@ -289,6 +293,7 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt, { struct nhlt_specific_cfg *cfg; struct nhlt_endpoint *epnt; bool ignore_vbps = false; struct nhlt_fmt *fmt; int i; Loading @@ -298,7 +303,26 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt, dev_dbg(dev, "Looking for configuration:\n"); dev_dbg(dev, " vbus_id=%d link_type=%d dir=%d, dev_type=%d\n", bus_id, link_type, dir, dev_type); if (link_type == NHLT_LINK_DMIC && bps == 32 && (vbps == 24 || vbps == 32)) { /* * The DMIC hardware supports only one type of 32 bits sample * size, which is 24 bit sampling on the MSB side and bits[1:0] * are used for indicating the channel number. * It has been observed that some NHLT tables have the vbps * specified as 32 while some uses 24. * The format these variations describe are identical, the * hardware is configured and behaves the same way. * Note: when the samples assumed to be vbps=32 then the 'noise' * introduced by the lower two bits (channel number) have no * real life implication on audio quality. */ dev_dbg(dev, " ch=%d fmt=%d rate=%d (vbps is ignored for DMIC 32bit format)\n", num_ch, bps, rate); ignore_vbps = true; } else { dev_dbg(dev, " ch=%d fmt=%d/%d rate=%d\n", num_ch, vbps, bps, rate); } dev_dbg(dev, "Endpoint count=%d\n", nhlt->endpoint_count); epnt = (struct nhlt_endpoint *)nhlt->desc; Loading @@ -307,7 +331,8 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt, if (nhlt_check_ep_match(dev, epnt, bus_id, link_type, dir, dev_type)) { fmt = (struct nhlt_fmt *)(epnt->config.caps + epnt->config.size); cfg = nhlt_get_specific_cfg(dev, fmt, num_ch, rate, vbps, bps); cfg = nhlt_get_specific_cfg(dev, fmt, num_ch, rate, vbps, bps, ignore_vbps); if (cfg) return cfg; } Loading sound/pci/hda/cs35l41_hda.c +24 −3 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <sound/hda_codec.h> #include <sound/soc.h> #include <linux/pm_runtime.h> #include <linux/spi/spi.h> #include "hda_local.h" #include "hda_auto_parser.h" #include "hda_jack.h" Loading Loading @@ -996,6 +997,11 @@ static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) __be32 halo_sts; int ret; if (cs35l41->bypass_fw) { dev_warn(cs35l41->dev, "Bypassing Firmware.\n"); return 0; } ret = cs35l41_init_dsp(cs35l41); if (ret) { dev_warn(cs35l41->dev, "Cannot Initialize Firmware. Error: %d\n", ret); Loading Loading @@ -1588,6 +1594,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i u32 values[HDA_MAX_COMPONENTS]; struct acpi_device *adev; struct device *physdev; struct spi_device *spi; const char *sub; char *property; size_t nval; Loading @@ -1610,7 +1617,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i ret = cs35l41_add_dsd_properties(cs35l41, physdev, id, hid); if (!ret) { dev_info(cs35l41->dev, "Using extra _DSD properties, bypassing _DSD in ACPI\n"); goto put_physdev; goto out; } property = "cirrus,dev-index"; Loading Loading @@ -1701,8 +1708,20 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i hw_cfg->bst_type = CS35L41_EXT_BOOST; hw_cfg->valid = true; out: put_device(physdev); cs35l41->bypass_fw = false; if (cs35l41->control_bus == SPI) { spi = to_spi_device(cs35l41->dev); if (spi->max_speed_hz < CS35L41_MAX_ACCEPTABLE_SPI_SPEED_HZ) { dev_warn(cs35l41->dev, "SPI speed is too slow to support firmware download: %d Hz.\n", spi->max_speed_hz); cs35l41->bypass_fw = true; } } return 0; err: Loading @@ -1711,14 +1730,13 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i hw_cfg->gpio1.valid = false; hw_cfg->gpio2.valid = false; acpi_dev_put(cs35l41->dacpi); put_physdev: put_device(physdev); return ret; } int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, struct regmap *regmap) struct regmap *regmap, enum control_bus control_bus) { unsigned int regid, reg_revid; struct cs35l41_hda *cs35l41; Loading @@ -1737,6 +1755,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i cs35l41->dev = dev; cs35l41->irq = irq; cs35l41->regmap = regmap; cs35l41->control_bus = control_bus; dev_set_drvdata(dev, cs35l41); ret = cs35l41_hda_read_acpi(cs35l41, device_name, id); Loading Loading @@ -1826,6 +1845,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); gpiod_put(cs35l41->reset_gpio); gpiod_put(cs35l41->cs_gpio); acpi_dev_put(cs35l41->dacpi); kfree(cs35l41->acpi_subsystem_id); Loading Loading @@ -1853,6 +1873,7 @@ void cs35l41_hda_remove(struct device *dev) if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); gpiod_put(cs35l41->reset_gpio); gpiod_put(cs35l41->cs_gpio); kfree(cs35l41->acpi_subsystem_id); } EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); Loading sound/pci/hda/cs35l41_hda.h +14 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ #include <linux/firmware/cirrus/cs_dsp.h> #include <linux/firmware/cirrus/wmfw.h> #define CS35L41_MAX_ACCEPTABLE_SPI_SPEED_HZ 1000000 struct cs35l41_amp_cal_data { u32 calTarget[2]; u32 calTime[2]; Loading @@ -35,8 +37,8 @@ struct cs35l41_amp_efi_data { } __packed; enum cs35l41_hda_spk_pos { CS35l41_LEFT, CS35l41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT, }; enum cs35l41_hda_gpio_function { Loading @@ -46,10 +48,16 @@ enum cs35l41_hda_gpio_function { CS35l41_SYNC, }; enum control_bus { I2C, SPI }; struct cs35l41_hda { struct device *dev; struct regmap *regmap; struct gpio_desc *reset_gpio; struct gpio_desc *cs_gpio; struct cs35l41_hw_cfg hw_cfg; struct hda_codec *codec; Loading @@ -73,6 +81,9 @@ struct cs35l41_hda { struct cs_dsp cs_dsp; struct acpi_device *dacpi; bool mute_override; enum control_bus control_bus; bool bypass_fw; }; enum halo_state { Loading @@ -84,7 +95,7 @@ enum halo_state { extern const struct dev_pm_ops cs35l41_hda_pm_ops; int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, struct regmap *regmap); struct regmap *regmap, enum control_bus control_bus); void cs35l41_hda_remove(struct device *dev); int cs35l41_get_speaker_id(struct device *dev, int amp_index, int num_amps, int fixed_gpio_id); Loading Loading
sound/core/pcm.c +1 −0 Original line number Diff line number Diff line Loading @@ -253,6 +253,7 @@ static const char * const snd_pcm_state_names[] = { STATE(DRAINING), STATE(PAUSED), STATE(SUSPENDED), STATE(DISCONNECTED), }; static const char * const snd_pcm_access_names[] = { Loading
sound/drivers/pcmtest.c +12 −1 Original line number Diff line number Diff line Loading @@ -397,7 +397,6 @@ static int snd_pcmtst_pcm_close(struct snd_pcm_substream *substream) struct pcmtst_buf_iter *v_iter = substream->runtime->private_data; timer_shutdown_sync(&v_iter->timer_instance); v_iter->substream = NULL; playback_capture_test = !v_iter->is_buf_corrupted; kfree(v_iter); return 0; Loading Loading @@ -435,6 +434,7 @@ static int snd_pcmtst_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_PUSH: // We can't call timer_shutdown_sync here, as it is forbidden to sleep here v_iter->suspend = true; timer_delete(&v_iter->timer_instance); break; } Loading Loading @@ -512,12 +512,22 @@ static int snd_pcmtst_ioctl(struct snd_pcm_substream *substream, unsigned int cm return snd_pcm_lib_ioctl(substream, cmd, arg); } static int snd_pcmtst_sync_stop(struct snd_pcm_substream *substream) { struct pcmtst_buf_iter *v_iter = substream->runtime->private_data; timer_delete_sync(&v_iter->timer_instance); return 0; } static const struct snd_pcm_ops snd_pcmtst_playback_ops = { .open = snd_pcmtst_pcm_open, .close = snd_pcmtst_pcm_close, .trigger = snd_pcmtst_pcm_trigger, .hw_params = snd_pcmtst_pcm_hw_params, .ioctl = snd_pcmtst_ioctl, .sync_stop = snd_pcmtst_sync_stop, .hw_free = snd_pcmtst_pcm_hw_free, .prepare = snd_pcmtst_pcm_prepare, .pointer = snd_pcmtst_pcm_pointer, Loading @@ -530,6 +540,7 @@ static const struct snd_pcm_ops snd_pcmtst_capture_ops = { .hw_params = snd_pcmtst_pcm_hw_params, .hw_free = snd_pcmtst_pcm_hw_free, .ioctl = snd_pcmtst_ioctl, .sync_stop = snd_pcmtst_sync_stop, .prepare = snd_pcmtst_pcm_prepare, .pointer = snd_pcmtst_pcm_pointer, }; Loading
sound/hda/intel-nhlt.c +29 −4 Original line number Diff line number Diff line Loading @@ -238,7 +238,7 @@ EXPORT_SYMBOL(intel_nhlt_ssp_mclk_mask); static struct nhlt_specific_cfg * nhlt_get_specific_cfg(struct device *dev, struct nhlt_fmt *fmt, u8 num_ch, u32 rate, u8 vbps, u8 bps) u32 rate, u8 vbps, u8 bps, bool ignore_vbps) { struct nhlt_fmt_cfg *cfg = fmt->fmt_config; struct wav_fmt *wfmt; Loading @@ -255,8 +255,12 @@ nhlt_get_specific_cfg(struct device *dev, struct nhlt_fmt *fmt, u8 num_ch, dev_dbg(dev, "Endpoint format: ch=%d fmt=%d/%d rate=%d\n", wfmt->channels, _vbps, _bps, wfmt->samples_per_sec); /* * When looking for exact match of configuration ignore the vbps * from NHLT table when ignore_vbps is true */ if (wfmt->channels == num_ch && wfmt->samples_per_sec == rate && vbps == _vbps && bps == _bps) (ignore_vbps || vbps == _vbps) && bps == _bps) return &cfg->config; cfg = (struct nhlt_fmt_cfg *)(cfg->config.caps + cfg->config.size); Loading Loading @@ -289,6 +293,7 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt, { struct nhlt_specific_cfg *cfg; struct nhlt_endpoint *epnt; bool ignore_vbps = false; struct nhlt_fmt *fmt; int i; Loading @@ -298,7 +303,26 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt, dev_dbg(dev, "Looking for configuration:\n"); dev_dbg(dev, " vbus_id=%d link_type=%d dir=%d, dev_type=%d\n", bus_id, link_type, dir, dev_type); if (link_type == NHLT_LINK_DMIC && bps == 32 && (vbps == 24 || vbps == 32)) { /* * The DMIC hardware supports only one type of 32 bits sample * size, which is 24 bit sampling on the MSB side and bits[1:0] * are used for indicating the channel number. * It has been observed that some NHLT tables have the vbps * specified as 32 while some uses 24. * The format these variations describe are identical, the * hardware is configured and behaves the same way. * Note: when the samples assumed to be vbps=32 then the 'noise' * introduced by the lower two bits (channel number) have no * real life implication on audio quality. */ dev_dbg(dev, " ch=%d fmt=%d rate=%d (vbps is ignored for DMIC 32bit format)\n", num_ch, bps, rate); ignore_vbps = true; } else { dev_dbg(dev, " ch=%d fmt=%d/%d rate=%d\n", num_ch, vbps, bps, rate); } dev_dbg(dev, "Endpoint count=%d\n", nhlt->endpoint_count); epnt = (struct nhlt_endpoint *)nhlt->desc; Loading @@ -307,7 +331,8 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt, if (nhlt_check_ep_match(dev, epnt, bus_id, link_type, dir, dev_type)) { fmt = (struct nhlt_fmt *)(epnt->config.caps + epnt->config.size); cfg = nhlt_get_specific_cfg(dev, fmt, num_ch, rate, vbps, bps); cfg = nhlt_get_specific_cfg(dev, fmt, num_ch, rate, vbps, bps, ignore_vbps); if (cfg) return cfg; } Loading
sound/pci/hda/cs35l41_hda.c +24 −3 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <sound/hda_codec.h> #include <sound/soc.h> #include <linux/pm_runtime.h> #include <linux/spi/spi.h> #include "hda_local.h" #include "hda_auto_parser.h" #include "hda_jack.h" Loading Loading @@ -996,6 +997,11 @@ static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) __be32 halo_sts; int ret; if (cs35l41->bypass_fw) { dev_warn(cs35l41->dev, "Bypassing Firmware.\n"); return 0; } ret = cs35l41_init_dsp(cs35l41); if (ret) { dev_warn(cs35l41->dev, "Cannot Initialize Firmware. Error: %d\n", ret); Loading Loading @@ -1588,6 +1594,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i u32 values[HDA_MAX_COMPONENTS]; struct acpi_device *adev; struct device *physdev; struct spi_device *spi; const char *sub; char *property; size_t nval; Loading @@ -1610,7 +1617,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i ret = cs35l41_add_dsd_properties(cs35l41, physdev, id, hid); if (!ret) { dev_info(cs35l41->dev, "Using extra _DSD properties, bypassing _DSD in ACPI\n"); goto put_physdev; goto out; } property = "cirrus,dev-index"; Loading Loading @@ -1701,8 +1708,20 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i hw_cfg->bst_type = CS35L41_EXT_BOOST; hw_cfg->valid = true; out: put_device(physdev); cs35l41->bypass_fw = false; if (cs35l41->control_bus == SPI) { spi = to_spi_device(cs35l41->dev); if (spi->max_speed_hz < CS35L41_MAX_ACCEPTABLE_SPI_SPEED_HZ) { dev_warn(cs35l41->dev, "SPI speed is too slow to support firmware download: %d Hz.\n", spi->max_speed_hz); cs35l41->bypass_fw = true; } } return 0; err: Loading @@ -1711,14 +1730,13 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i hw_cfg->gpio1.valid = false; hw_cfg->gpio2.valid = false; acpi_dev_put(cs35l41->dacpi); put_physdev: put_device(physdev); return ret; } int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, struct regmap *regmap) struct regmap *regmap, enum control_bus control_bus) { unsigned int regid, reg_revid; struct cs35l41_hda *cs35l41; Loading @@ -1737,6 +1755,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i cs35l41->dev = dev; cs35l41->irq = irq; cs35l41->regmap = regmap; cs35l41->control_bus = control_bus; dev_set_drvdata(dev, cs35l41); ret = cs35l41_hda_read_acpi(cs35l41, device_name, id); Loading Loading @@ -1826,6 +1845,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); gpiod_put(cs35l41->reset_gpio); gpiod_put(cs35l41->cs_gpio); acpi_dev_put(cs35l41->dacpi); kfree(cs35l41->acpi_subsystem_id); Loading Loading @@ -1853,6 +1873,7 @@ void cs35l41_hda_remove(struct device *dev) if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); gpiod_put(cs35l41->reset_gpio); gpiod_put(cs35l41->cs_gpio); kfree(cs35l41->acpi_subsystem_id); } EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); Loading
sound/pci/hda/cs35l41_hda.h +14 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ #include <linux/firmware/cirrus/cs_dsp.h> #include <linux/firmware/cirrus/wmfw.h> #define CS35L41_MAX_ACCEPTABLE_SPI_SPEED_HZ 1000000 struct cs35l41_amp_cal_data { u32 calTarget[2]; u32 calTime[2]; Loading @@ -35,8 +37,8 @@ struct cs35l41_amp_efi_data { } __packed; enum cs35l41_hda_spk_pos { CS35l41_LEFT, CS35l41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT, }; enum cs35l41_hda_gpio_function { Loading @@ -46,10 +48,16 @@ enum cs35l41_hda_gpio_function { CS35l41_SYNC, }; enum control_bus { I2C, SPI }; struct cs35l41_hda { struct device *dev; struct regmap *regmap; struct gpio_desc *reset_gpio; struct gpio_desc *cs_gpio; struct cs35l41_hw_cfg hw_cfg; struct hda_codec *codec; Loading @@ -73,6 +81,9 @@ struct cs35l41_hda { struct cs_dsp cs_dsp; struct acpi_device *dacpi; bool mute_override; enum control_bus control_bus; bool bypass_fw; }; enum halo_state { Loading @@ -84,7 +95,7 @@ enum halo_state { extern const struct dev_pm_ops cs35l41_hda_pm_ops; int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, struct regmap *regmap); struct regmap *regmap, enum control_bus control_bus); void cs35l41_hda_remove(struct device *dev); int cs35l41_get_speaker_id(struct device *dev, int amp_index, int num_amps, int fixed_gpio_id); Loading