diff options
Diffstat (limited to 'sound/hda/codecs/side-codecs')
-rw-r--r-- | sound/hda/codecs/side-codecs/cirrus_scodec_test.c | 2 | ||||
-rw-r--r-- | sound/hda/codecs/side-codecs/cs35l41_hda.c | 110 | ||||
-rw-r--r-- | sound/hda/codecs/side-codecs/cs35l41_hda_property.c | 4 | ||||
-rw-r--r-- | sound/hda/codecs/side-codecs/cs35l56_hda.c | 1 | ||||
-rw-r--r-- | sound/hda/codecs/side-codecs/cs35l56_hda_i2c.c | 2 | ||||
-rw-r--r-- | sound/hda/codecs/side-codecs/cs35l56_hda_spi.c | 2 | ||||
-rw-r--r-- | sound/hda/codecs/side-codecs/hda_component.c | 15 | ||||
-rw-r--r-- | sound/hda/codecs/side-codecs/hda_component.h | 3 | ||||
-rw-r--r-- | sound/hda/codecs/side-codecs/tas2781_hda.c | 30 | ||||
-rw-r--r-- | sound/hda/codecs/side-codecs/tas2781_hda_i2c.c | 97 |
10 files changed, 140 insertions, 126 deletions
diff --git a/sound/hda/codecs/side-codecs/cirrus_scodec_test.c b/sound/hda/codecs/side-codecs/cirrus_scodec_test.c index 9ba14c09c07f..3cca750857b6 100644 --- a/sound/hda/codecs/side-codecs/cirrus_scodec_test.c +++ b/sound/hda/codecs/side-codecs/cirrus_scodec_test.c @@ -69,7 +69,7 @@ static int cirrus_scodec_test_gpio_set_config(struct gpio_chip *gc, unsigned long config) { switch (pinconf_to_config_param(config)) { - case PIN_CONFIG_OUTPUT: + case PIN_CONFIG_LEVEL: case PIN_CONFIG_OUTPUT_ENABLE: return -EOPNOTSUPP; default: diff --git a/sound/hda/codecs/side-codecs/cs35l41_hda.c b/sound/hda/codecs/side-codecs/cs35l41_hda.c index 37f2cdc8ce82..c04208e685a0 100644 --- a/sound/hda/codecs/side-codecs/cs35l41_hda.c +++ b/sound/hda/codecs/side-codecs/cs35l41_hda.c @@ -624,11 +624,10 @@ static void cs35l41_remove_dsp(struct cs35l41_hda *cs35l41) cancel_work_sync(&cs35l41->fw_load_work); - mutex_lock(&cs35l41->fw_mutex); + guard(mutex)(&cs35l41->fw_mutex); cs35l41_shutdown_dsp(cs35l41); cs_dsp_remove(dsp); cs35l41->halo_initialized = false; - mutex_unlock(&cs35l41->fw_mutex); } /* Protection release cycle to get the speaker out of Safe-Mode */ @@ -790,9 +789,9 @@ static void cs35l41_hda_pre_playback_hook(struct device *dev, int action) switch (action) { case HDA_GEN_PCM_ACT_CLEANUP: - mutex_lock(&cs35l41->fw_mutex); - cs35l41_hda_pause_start(dev); - mutex_unlock(&cs35l41->fw_mutex); + scoped_guard(mutex, &cs35l41->fw_mutex) { + cs35l41_hda_pause_start(dev); + } break; default: break; @@ -813,24 +812,24 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) pm_runtime_get_sync(dev); break; case HDA_GEN_PCM_ACT_PREPARE: - mutex_lock(&cs35l41->fw_mutex); - cs35l41_hda_play_start(dev); - mutex_unlock(&cs35l41->fw_mutex); + scoped_guard(mutex, &cs35l41->fw_mutex) { + cs35l41_hda_play_start(dev); + } break; case HDA_GEN_PCM_ACT_CLEANUP: - mutex_lock(&cs35l41->fw_mutex); - cs35l41_hda_pause_done(dev); - mutex_unlock(&cs35l41->fw_mutex); + scoped_guard(mutex, &cs35l41->fw_mutex) { + cs35l41_hda_pause_done(dev); + } break; case HDA_GEN_PCM_ACT_CLOSE: - mutex_lock(&cs35l41->fw_mutex); - if (!cs35l41->cs_dsp.running && cs35l41->request_fw_load && - !cs35l41->fw_request_ongoing) { - dev_info(dev, "Requesting Firmware Load after HDA_GEN_PCM_ACT_CLOSE\n"); - cs35l41->fw_request_ongoing = true; - schedule_work(&cs35l41->fw_load_work); + scoped_guard(mutex, &cs35l41->fw_mutex) { + if (!cs35l41->cs_dsp.running && cs35l41->request_fw_load && + !cs35l41->fw_request_ongoing) { + dev_info(dev, "Requesting Firmware Load after HDA_GEN_PCM_ACT_CLOSE\n"); + cs35l41->fw_request_ongoing = true; + schedule_work(&cs35l41->fw_load_work); + } } - mutex_unlock(&cs35l41->fw_mutex); /* * Playback must be finished for all amps before we start runtime suspend. @@ -849,9 +848,9 @@ static void cs35l41_hda_post_playback_hook(struct device *dev, int action) switch (action) { case HDA_GEN_PCM_ACT_PREPARE: - mutex_lock(&cs35l41->fw_mutex); - cs35l41_hda_play_done(dev); - mutex_unlock(&cs35l41->fw_mutex); + scoped_guard(mutex, &cs35l41->fw_mutex) { + cs35l41_hda_play_done(dev); + } break; default: break; @@ -917,13 +916,12 @@ static int cs35l41_verify_id(struct cs35l41_hda *cs35l41, unsigned int *regid, u static int cs35l41_ready_for_reset(struct cs35l41_hda *cs35l41) { - mutex_lock(&cs35l41->fw_mutex); + guard(mutex)(&cs35l41->fw_mutex); if (cs35l41->cs_dsp.running) { cs35l41->cs_dsp.running = false; cs35l41->cs_dsp.booted = false; } regcache_mark_dirty(cs35l41->regmap); - mutex_unlock(&cs35l41->fw_mutex); return 0; } @@ -939,10 +937,9 @@ static int cs35l41_system_suspend_prep(struct device *dev) return 0; /* don't block the whole system suspend */ } - mutex_lock(&cs35l41->fw_mutex); + guard(mutex)(&cs35l41->fw_mutex); if (cs35l41->playback_started) cs35l41_hda_pause_start(dev); - mutex_unlock(&cs35l41->fw_mutex); return 0; } @@ -959,10 +956,10 @@ static int cs35l41_system_suspend(struct device *dev) return 0; /* don't block the whole system suspend */ } - mutex_lock(&cs35l41->fw_mutex); - if (cs35l41->playback_started) - cs35l41_hda_pause_done(dev); - mutex_unlock(&cs35l41->fw_mutex); + scoped_guard(mutex, &cs35l41->fw_mutex) { + if (cs35l41->playback_started) + cs35l41_hda_pause_done(dev); + } ret = pm_runtime_force_suspend(dev); if (ret) { @@ -1047,13 +1044,12 @@ static int cs35l41_system_resume(struct device *dev) return ret; } - mutex_lock(&cs35l41->fw_mutex); + guard(mutex)(&cs35l41->fw_mutex); if (cs35l41->request_fw_load && !cs35l41->fw_request_ongoing) { cs35l41->fw_request_ongoing = true; schedule_work(&cs35l41->fw_load_work); } - mutex_unlock(&cs35l41->fw_mutex); return ret; } @@ -1070,7 +1066,7 @@ static int cs35l41_runtime_idle(struct device *dev) static int cs35l41_runtime_suspend(struct device *dev) { struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); - int ret = 0; + int ret; dev_dbg(cs35l41->dev, "Runtime Suspend\n"); @@ -1079,13 +1075,13 @@ static int cs35l41_runtime_suspend(struct device *dev) return 0; } - mutex_lock(&cs35l41->fw_mutex); + guard(mutex)(&cs35l41->fw_mutex); if (cs35l41->cs_dsp.running) { ret = cs35l41_enter_hibernate(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type); if (ret) - goto err; + return ret; } else { cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type); } @@ -1093,17 +1089,14 @@ static int cs35l41_runtime_suspend(struct device *dev) regcache_cache_only(cs35l41->regmap, true); regcache_mark_dirty(cs35l41->regmap); -err: - mutex_unlock(&cs35l41->fw_mutex); - - return ret; + return 0; } static int cs35l41_runtime_resume(struct device *dev) { struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); unsigned int regid, reg_revid; - int ret = 0; + int ret; dev_dbg(cs35l41->dev, "Runtime Resume\n"); @@ -1112,7 +1105,7 @@ static int cs35l41_runtime_resume(struct device *dev) return 0; } - mutex_lock(&cs35l41->fw_mutex); + guard(mutex)(&cs35l41->fw_mutex); regcache_cache_only(cs35l41->regmap, false); @@ -1120,13 +1113,13 @@ static int cs35l41_runtime_resume(struct device *dev) ret = cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap); if (ret) { dev_warn(cs35l41->dev, "Unable to exit Hibernate."); - goto err; + return ret; } } ret = cs35l41_verify_id(cs35l41, ®id, ®_revid); if (ret) - goto err; + return ret; /* Test key needs to be unlocked to allow the OTP settings to re-apply */ cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); @@ -1134,7 +1127,7 @@ static int cs35l41_runtime_resume(struct device *dev) cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); if (ret) { dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret); - goto err; + return ret; } if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) @@ -1142,22 +1135,14 @@ static int cs35l41_runtime_resume(struct device *dev) dev_dbg(cs35l41->dev, "CS35L41 Resumed (%x), Revision: %02X\n", regid, reg_revid); -err: - mutex_unlock(&cs35l41->fw_mutex); - - return ret; + return 0; } static int cs35l41_hda_read_ctl(struct cs_dsp *dsp, const char *name, int type, unsigned int alg, void *buf, size_t len) { - int ret; - - mutex_lock(&dsp->pwr_lock); - ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(dsp, name, type, alg), 0, buf, len); - mutex_unlock(&dsp->pwr_lock); - - return ret; + guard(mutex)(&dsp->pwr_lock); + return cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(dsp, name, type, alg), 0, buf, len); } static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) @@ -1272,16 +1257,15 @@ static void cs35l41_fw_load_work(struct work_struct *work) pm_runtime_get_sync(cs35l41->dev); - mutex_lock(&cs35l41->fw_mutex); - - /* Recheck if playback is ongoing, mutex will block playback during firmware loading */ - if (cs35l41->playback_started) - dev_err(cs35l41->dev, "Cannot Load/Unload firmware during Playback. Retrying...\n"); - else - cs35l41_load_firmware(cs35l41, cs35l41->request_fw_load); + scoped_guard(mutex, &cs35l41->fw_mutex) { + /* Recheck if playback is ongoing, mutex will block playback during firmware loading */ + if (cs35l41->playback_started) + dev_err(cs35l41->dev, "Cannot Load/Unload firmware during Playback. Retrying...\n"); + else + cs35l41_load_firmware(cs35l41, cs35l41->request_fw_load); - cs35l41->fw_request_ongoing = false; - mutex_unlock(&cs35l41->fw_mutex); + cs35l41->fw_request_ongoing = false; + } pm_runtime_put_autosuspend(cs35l41->dev); } diff --git a/sound/hda/codecs/side-codecs/cs35l41_hda_property.c b/sound/hda/codecs/side-codecs/cs35l41_hda_property.c index d8249d997c2a..16d5ea77192f 100644 --- a/sound/hda/codecs/side-codecs/cs35l41_hda_property.c +++ b/sound/hda/codecs/side-codecs/cs35l41_hda_property.c @@ -135,6 +135,8 @@ static const struct cs35l41_config cs35l41_config_table[] = { { "17AA38C8", 4, INTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT }, 0, 2, -1, 1000, 4500, 24 }, { "17AA38F9", 2, EXTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, 0, 2, -1, 0, 0, 0 }, { "17AA38FA", 2, EXTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, 0, 2, -1, 0, 0, 0 }, + { "17AA3929", 4, INTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT }, 0, 2, -1, 1000, 4500, 24 }, + { "17AA392B", 4, INTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT }, 0, 2, -1, 1000, 4500, 24 }, {} }; @@ -558,6 +560,8 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = { { "CSC3551", "17AA38C8", generic_dsd_config }, { "CSC3551", "17AA38F9", generic_dsd_config }, { "CSC3551", "17AA38FA", generic_dsd_config }, + { "CSC3551", "17AA3929", generic_dsd_config }, + { "CSC3551", "17AA392B", generic_dsd_config }, {} }; diff --git a/sound/hda/codecs/side-codecs/cs35l56_hda.c b/sound/hda/codecs/side-codecs/cs35l56_hda.c index 36fa62a41984..5bb1c4ebeaf3 100644 --- a/sound/hda/codecs/side-codecs/cs35l56_hda.c +++ b/sound/hda/codecs/side-codecs/cs35l56_hda.c @@ -1049,6 +1049,7 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id) goto err; } + cs35l56->base.type = hid & 0xff; cs35l56->base.cal_index = -1; cs35l56_init_cs_dsp(&cs35l56->base, &cs35l56->cs_dsp); diff --git a/sound/hda/codecs/side-codecs/cs35l56_hda_i2c.c b/sound/hda/codecs/side-codecs/cs35l56_hda_i2c.c index d10209e4eddd..1072f17385ac 100644 --- a/sound/hda/codecs/side-codecs/cs35l56_hda_i2c.c +++ b/sound/hda/codecs/side-codecs/cs35l56_hda_i2c.c @@ -27,8 +27,6 @@ static int cs35l56_hda_i2c_probe(struct i2c_client *clt) cs35l56->base.can_hibernate = true; #endif - cs35l56->base.fw_reg = &cs35l56_fw_reg; - cs35l56->base.regmap = devm_regmap_init_i2c(clt, &cs35l56_regmap_i2c); if (IS_ERR(cs35l56->base.regmap)) { ret = PTR_ERR(cs35l56->base.regmap); diff --git a/sound/hda/codecs/side-codecs/cs35l56_hda_spi.c b/sound/hda/codecs/side-codecs/cs35l56_hda_spi.c index f57533d3d728..f802c83c57b4 100644 --- a/sound/hda/codecs/side-codecs/cs35l56_hda_spi.c +++ b/sound/hda/codecs/side-codecs/cs35l56_hda_spi.c @@ -30,8 +30,6 @@ static int cs35l56_hda_spi_probe(struct spi_device *spi) cs35l56->base.can_hibernate = true; #endif - cs35l56->base.fw_reg = &cs35l56_fw_reg; - cs35l56->base.regmap = devm_regmap_init_spi(spi, &cs35l56_regmap_spi); if (IS_ERR(cs35l56->base.regmap)) { ret = PTR_ERR(cs35l56->base.regmap); diff --git a/sound/hda/codecs/side-codecs/hda_component.c b/sound/hda/codecs/side-codecs/hda_component.c index 71860e2d6377..bcf47a301697 100644 --- a/sound/hda/codecs/side-codecs/hda_component.c +++ b/sound/hda/codecs/side-codecs/hda_component.c @@ -21,13 +21,12 @@ void hda_component_acpi_device_notify(struct hda_component_parent *parent, struct hda_component *comp; int i; - mutex_lock(&parent->mutex); + guard(mutex)(&parent->mutex); for (i = 0; i < ARRAY_SIZE(parent->comps); i++) { comp = hda_component_from_index(parent, i); if (comp->dev && comp->acpi_notify) comp->acpi_notify(acpi_device_handle(comp->adev), event, comp->dev); } - mutex_unlock(&parent->mutex); } EXPORT_SYMBOL_NS_GPL(hda_component_acpi_device_notify, "SND_HDA_SCODEC_COMPONENT"); @@ -89,7 +88,7 @@ void hda_component_manager_playback_hook(struct hda_component_parent *parent, in struct hda_component *comp; int i; - mutex_lock(&parent->mutex); + guard(mutex)(&parent->mutex); for (i = 0; i < ARRAY_SIZE(parent->comps); i++) { comp = hda_component_from_index(parent, i); if (comp->dev && comp->pre_playback_hook) @@ -105,7 +104,6 @@ void hda_component_manager_playback_hook(struct hda_component_parent *parent, in if (comp->dev && comp->post_playback_hook) comp->post_playback_hook(comp->dev, action); } - mutex_unlock(&parent->mutex); } EXPORT_SYMBOL_NS_GPL(hda_component_manager_playback_hook, "SND_HDA_SCODEC_COMPONENT"); @@ -138,16 +136,11 @@ static int hda_comp_match_dev_name(struct device *dev, void *data) int hda_component_manager_bind(struct hda_codec *cdc, struct hda_component_parent *parent) { - int ret; - /* Init shared and component specific data */ memset(parent->comps, 0, sizeof(parent->comps)); - mutex_lock(&parent->mutex); - ret = component_bind_all(hda_codec_dev(cdc), parent); - mutex_unlock(&parent->mutex); - - return ret; + guard(mutex)(&parent->mutex); + return component_bind_all(hda_codec_dev(cdc), parent); } EXPORT_SYMBOL_NS_GPL(hda_component_manager_bind, "SND_HDA_SCODEC_COMPONENT"); diff --git a/sound/hda/codecs/side-codecs/hda_component.h b/sound/hda/codecs/side-codecs/hda_component.h index 7ee37154749f..075137a73bae 100644 --- a/sound/hda/codecs/side-codecs/hda_component.h +++ b/sound/hda/codecs/side-codecs/hda_component.h @@ -95,9 +95,8 @@ static inline struct hda_component *hda_component_from_index(struct hda_componen static inline void hda_component_manager_unbind(struct hda_codec *cdc, struct hda_component_parent *parent) { - mutex_lock(&parent->mutex); + guard(mutex)(&parent->mutex); component_unbind_all(hda_codec_dev(cdc), parent); - mutex_unlock(&parent->mutex); } #endif /* ifndef __HDA_COMPONENT_H__ */ diff --git a/sound/hda/codecs/side-codecs/tas2781_hda.c b/sound/hda/codecs/side-codecs/tas2781_hda.c index f46d2e06c64f..96e6d82dc69e 100644 --- a/sound/hda/codecs/side-codecs/tas2781_hda.c +++ b/sound/hda/codecs/side-codecs/tas2781_hda.c @@ -33,6 +33,23 @@ const efi_guid_t tasdev_fct_efi_guid[] = { }; EXPORT_SYMBOL_NS_GPL(tasdev_fct_efi_guid, "SND_HDA_SCODEC_TAS2781"); +/* + * The order of calibrated-data writing function is a bit different from the + * order in UEFI. Here is the conversion to match the order of calibrated-data + * writing function. + */ +static void cali_cnv(unsigned char *data, unsigned int base, int offset) +{ + struct cali_reg reg_data; + + memcpy(®_data, &data[base], sizeof(reg_data)); + /* the data order has to be swapped between r0_low_reg and inv0_reg */ + swap(reg_data.r0_low_reg, reg_data.invr0_reg); + + cpu_to_be32_array((__force __be32 *)(data + offset + 1), + (u32 *)®_data, TASDEV_CALIB_N); +} + static void tas2781_apply_calib(struct tasdevice_priv *p) { struct calidata *cali_data = &p->cali_data; @@ -103,8 +120,7 @@ static void tas2781_apply_calib(struct tasdevice_priv *p) data[l] = k; oft++; - for (i = 0; i < TASDEV_CALIB_N * 4; i++) - data[l + i + 1] = data[4 * oft + i]; + cali_cnv(data, 4 * oft, l); k++; } } @@ -130,9 +146,8 @@ static void tas2781_apply_calib(struct tasdevice_priv *p) for (j = p->ndev - 1; j >= 0; j--) { l = j * (cali_data->cali_dat_sz_per_dev + 1); - for (i = TASDEV_CALIB_N * 4; i > 0 ; i--) - data[l + i] = data[p->index * 5 + i]; - data[l+i] = j; + cali_cnv(data, cali_data->cali_dat_sz_per_dev * j, l); + data[l] = j; } } @@ -178,6 +193,11 @@ int tas2781_save_calibration(struct tas2781_hda *hda) efi_status_t status; int i; + if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) { + dev_err(p->dev, "%s: NO EFI FOUND!\n", __func__); + return -EINVAL; + } + if (hda->catlog_id < LENOVO) efi_guid = tasdev_fct_efi_guid[hda->catlog_id]; diff --git a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c index e34b17f0c9b9..4dea442d8c30 100644 --- a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c +++ b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c @@ -26,6 +26,7 @@ #include <sound/tlv.h> #include <sound/tas2770-tlv.h> #include <sound/tas2781-tlv.h> +#include <sound/tas5825-tlv.h> #include "hda_local.h" #include "hda_auto_parser.h" @@ -50,6 +51,7 @@ enum device_chip_id { HDA_TAS2563, HDA_TAS2770, HDA_TAS2781, + HDA_TAS5825, HDA_OTHERS }; @@ -156,16 +158,16 @@ static void tas2781_hda_playback_hook(struct device *dev, int action) switch (action) { case HDA_GEN_PCM_ACT_OPEN: pm_runtime_get_sync(dev); - mutex_lock(&tas_hda->priv->codec_lock); - tasdevice_tuning_switch(tas_hda->priv, 0); - tas_hda->priv->playback_started = true; - mutex_unlock(&tas_hda->priv->codec_lock); + scoped_guard(mutex, &tas_hda->priv->codec_lock) { + tasdevice_tuning_switch(tas_hda->priv, 0); + tas_hda->priv->playback_started = true; + } break; case HDA_GEN_PCM_ACT_CLOSE: - mutex_lock(&tas_hda->priv->codec_lock); - tasdevice_tuning_switch(tas_hda->priv, 1); - tas_hda->priv->playback_started = false; - mutex_unlock(&tas_hda->priv->codec_lock); + scoped_guard(mutex, &tas_hda->priv->codec_lock) { + tasdevice_tuning_switch(tas_hda->priv, 1); + tas_hda->priv->playback_started = false; + } pm_runtime_put_autosuspend(dev); break; @@ -182,15 +184,13 @@ static int tas2781_amp_getvol(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; int ret; - mutex_lock(&tas_priv->codec_lock); + guard(mutex)(&tas_priv->codec_lock); ret = tasdevice_amp_getvol(tas_priv, ucontrol, mc); dev_dbg(tas_priv->dev, "%s: kcontrol %s: %ld\n", __func__, kcontrol->id.name, ucontrol->value.integer.value[0]); - mutex_unlock(&tas_priv->codec_lock); - return ret; } @@ -200,19 +200,14 @@ static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol, struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - int ret; - mutex_lock(&tas_priv->codec_lock); + guard(mutex)(&tas_priv->codec_lock); dev_dbg(tas_priv->dev, "%s: kcontrol %s: -> %ld\n", __func__, kcontrol->id.name, ucontrol->value.integer.value[0]); /* The check of the given value is in tasdevice_amp_putvol. */ - ret = tasdevice_amp_putvol(tas_priv, ucontrol, mc); - - mutex_unlock(&tas_priv->codec_lock); - - return ret; + return tasdevice_amp_putvol(tas_priv, ucontrol, mc); } static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol, @@ -220,14 +215,12 @@ static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol, { struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); - mutex_lock(&tas_priv->codec_lock); + guard(mutex)(&tas_priv->codec_lock); ucontrol->value.integer.value[0] = (int)tas_priv->force_fwload_status; dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n", __func__, kcontrol->id.name, tas_priv->force_fwload_status); - mutex_unlock(&tas_priv->codec_lock); - return 0; } @@ -237,7 +230,7 @@ static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol, struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); bool change, val = (bool)ucontrol->value.integer.value[0]; - mutex_lock(&tas_priv->codec_lock); + guard(mutex)(&tas_priv->codec_lock); dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n", __func__, kcontrol->id.name, @@ -250,8 +243,6 @@ static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol, tas_priv->force_fwload_status = val; } - mutex_unlock(&tas_priv->codec_lock); - return change; } @@ -272,6 +263,17 @@ static const struct snd_kcontrol_new tas2781_snd_controls[] = { tas2781_force_fwload_get, tas2781_force_fwload_put), }; +static const struct snd_kcontrol_new tas5825_snd_controls[] = { + ACARD_SINGLE_RANGE_EXT_TLV("Speaker Analog Volume", TAS5825_AMP_LEVEL, + 0, 0, 31, 1, tas2781_amp_getvol, + tas2781_amp_putvol, tas5825_amp_tlv), + ACARD_SINGLE_RANGE_EXT_TLV("Speaker Digital Volume", TAS5825_DVC_LEVEL, + 0, 0, 254, 1, tas2781_amp_getvol, + tas2781_amp_putvol, tas5825_dvc_tlv), + ACARD_SINGLE_BOOL_EXT("Speaker Force Firmware Load", 0, + tas2781_force_fwload_get, tas2781_force_fwload_put), +}; + static const struct snd_kcontrol_new tasdevice_prof_ctrl = { .name = "Speaker Profile Id", .iface = SNDRV_CTL_ELEM_IFACE_CARD, @@ -300,7 +302,7 @@ static int tas2563_save_calibration(struct tas2781_hda *h) { efi_guid_t efi_guid = tasdev_fct_efi_guid[LENOVO]; char *vars[TASDEV_CALIB_N] = { - "R0_%d", "InvR0_%d", "R0_Low_%d", "Power_%d", "TLim_%d" + "R0_%d", "R0_Low_%d", "InvR0_%d", "Power_%d", "TLim_%d" }; efi_char16_t efi_name[TAS2563_CAL_VAR_NAME_MAX]; unsigned long max_size = TAS2563_CAL_DATA_SIZE; @@ -310,10 +312,16 @@ static int tas2563_save_calibration(struct tas2781_hda *h) struct cali_reg *r = &cd->cali_reg_array; unsigned int offset = 0; unsigned char *data; + __be32 bedata; efi_status_t status; unsigned int attr; int ret, i, j, k; + if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) { + dev_err(p->dev, "%s: NO EFI FOUND!\n", __func__); + return -EINVAL; + } + cd->cali_dat_sz_per_dev = TAS2563_CAL_DATA_SIZE * TASDEV_CALIB_N; /* extra byte for each device is the device number */ @@ -327,8 +335,8 @@ static int tas2563_save_calibration(struct tas2781_hda *h) data[offset] = i; offset++; for (j = 0; j < TASDEV_CALIB_N; ++j) { - ret = snprintf(var8, sizeof(var8), vars[j], i); - + /* EFI name for calibration started with 1, not 0 */ + ret = snprintf(var8, sizeof(var8), vars[j], i + 1); if (ret < 0 || ret >= sizeof(var8) - 1) { dev_err(p->dev, "%s: Read %s failed\n", __func__, var8); @@ -351,12 +359,14 @@ static int tas2563_save_calibration(struct tas2781_hda *h) i, j, status); return -EINVAL; } + bedata = cpu_to_be32(*(uint32_t *)&data[offset]); + memcpy(&data[offset], &bedata, sizeof(bedata)); offset += TAS2563_CAL_DATA_SIZE; } } if (cd->total_sz != offset) { - dev_err(p->dev, "%s: tot_size(%lu) and offset(%u) dismatch\n", + dev_err(p->dev, "%s: tot_size(%lu) and offset(%u) mismatch\n", __func__, cd->total_sz, offset); return -EINVAL; } @@ -501,6 +511,12 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context) ARRAY_SIZE(tas2781_snd_controls)); tasdevice_dspfw_init(context); break; + case HDA_TAS5825: + tasdev_add_kcontrols(tas_priv, hda_priv->snd_ctls, codec, + &tas5825_snd_controls[0], + ARRAY_SIZE(tas5825_snd_controls)); + tasdevice_dspfw_init(context); + break; case HDA_TAS2563: tasdevice_dspfw_init(context); break; @@ -628,6 +644,7 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt) } else if (strstarts(dev_name(&clt->dev), "i2c-TXNW2781:00-tas2781-hda.0")) { device_name = "TXNW2781"; + hda_priv->hda_chip_id = HDA_TAS2781; hda_priv->save_calibration = tas2781_save_calibration; tas_hda->priv->global_addr = TAS2781_GLOBAL_ADDR; } else if (strstr(dev_name(&clt->dev), "INT8866")) { @@ -639,6 +656,13 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt) hda_priv->hda_chip_id = HDA_TAS2563; hda_priv->save_calibration = tas2563_save_calibration; tas_hda->priv->global_addr = TAS2563_GLOBAL_ADDR; + } else if (strstarts(dev_name(&clt->dev), "i2c-TXNW5825")) { + /* + * TAS5825, integrated on-chip DSP without + * global I2C address and calibration supported. + */ + device_name = "TXNW5825"; + hda_priv->hda_chip_id = HDA_TAS5825; } else { return -ENODEV; } @@ -684,7 +708,7 @@ static int tas2781_runtime_suspend(struct device *dev) dev_dbg(tas_hda->dev, "Runtime Suspend\n"); - mutex_lock(&tas_hda->priv->codec_lock); + guard(mutex)(&tas_hda->priv->codec_lock); /* The driver powers up the amplifiers at module load time. * Stop the playback if it's unused. @@ -694,8 +718,6 @@ static int tas2781_runtime_suspend(struct device *dev) tas_hda->priv->playback_started = false; } - mutex_unlock(&tas_hda->priv->codec_lock); - return 0; } @@ -705,12 +727,10 @@ static int tas2781_runtime_resume(struct device *dev) dev_dbg(tas_hda->dev, "Runtime Resume\n"); - mutex_lock(&tas_hda->priv->codec_lock); + guard(mutex)(&tas_hda->priv->codec_lock); tasdevice_prmg_load(tas_hda->priv, tas_hda->priv->cur_prog); - mutex_unlock(&tas_hda->priv->codec_lock); - return 0; } @@ -720,14 +740,12 @@ static int tas2781_system_suspend(struct device *dev) dev_dbg(tas_hda->priv->dev, "System Suspend\n"); - mutex_lock(&tas_hda->priv->codec_lock); + guard(mutex)(&tas_hda->priv->codec_lock); /* Shutdown chip before system suspend */ if (tas_hda->priv->playback_started) tasdevice_tuning_switch(tas_hda->priv, 1); - mutex_unlock(&tas_hda->priv->codec_lock); - /* * Reset GPIO may be shared, so cannot reset here. * However beyond this point, amps may be powered down. @@ -742,7 +760,7 @@ static int tas2781_system_resume(struct device *dev) dev_dbg(tas_hda->priv->dev, "System Resume\n"); - mutex_lock(&tas_hda->priv->codec_lock); + guard(mutex)(&tas_hda->priv->codec_lock); for (i = 0; i < tas_hda->priv->ndev; i++) { tas_hda->priv->tasdevice[i].cur_book = -1; @@ -755,8 +773,6 @@ static int tas2781_system_resume(struct device *dev) if (tas_hda->priv->playback_started) tasdevice_tuning_switch(tas_hda->priv, 0); - mutex_unlock(&tas_hda->priv->codec_lock); - return 0; } @@ -775,6 +791,7 @@ static const struct acpi_device_id tas2781_acpi_hda_match[] = { {"TIAS2781", 0 }, {"TXNW2770", 0 }, {"TXNW2781", 0 }, + {"TXNW5825", 0 }, {} }; MODULE_DEVICE_TABLE(acpi, tas2781_acpi_hda_match); |