diff options
Diffstat (limited to 'sound/soc/codecs/cros_ec_codec.c')
| -rw-r--r-- | sound/soc/codecs/cros_ec_codec.c | 100 |
1 files changed, 44 insertions, 56 deletions
diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c index 8d45c628e988..f78a85b89d95 100644 --- a/sound/soc/codecs/cros_ec_codec.c +++ b/sound/soc/codecs/cros_ec_codec.c @@ -8,7 +8,7 @@ * EC for audio function. */ -#include <crypto/sha.h> +#include <crypto/sha2.h> #include <linux/acpi.h> #include <linux/delay.h> #include <linux/device.h> @@ -18,9 +18,11 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/of_reserved_mem.h> #include <linux/platform_data/cros_ec_commands.h> #include <linux/platform_data/cros_ec_proto.h> #include <linux/platform_device.h> +#include <linux/string_choices.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> @@ -94,7 +96,7 @@ static int send_ec_host_command(struct cros_ec_device *ec_dev, uint32_t cmd, if (ret < 0) goto error; - if (insize) + if (in && insize) memcpy(in, msg->data, insize); ret = 0; @@ -103,33 +105,10 @@ error: return ret; } -static int calculate_sha256(struct cros_ec_codec_priv *priv, - uint8_t *buf, uint32_t size, uint8_t *digest) -{ - struct sha256_state sctx; - - sha256_init(&sctx); - sha256_update(&sctx, buf, size); - sha256_final(&sctx, digest); - -#ifdef DEBUG - { - char digest_str[65]; - - bin2hex(digest_str, digest, 32); - digest_str[64] = 0; - dev_dbg(priv->dev, "hash=%s\n", digest_str); - } -#endif - - return 0; -} - static int dmic_get_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct cros_ec_codec_priv *priv = snd_soc_component_get_drvdata(component); struct ec_param_ec_codec_dmic p; @@ -160,8 +139,7 @@ static int dmic_get_gain(struct snd_kcontrol *kcontrol, static int dmic_put_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct cros_ec_codec_priv *priv = snd_soc_component_get_drvdata(component); struct soc_mixer_control *control = @@ -254,11 +232,11 @@ static int i2s_rx_hw_params(struct snd_pcm_substream *substream, if (params_rate(params) != 48000) return -EINVAL; - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: depth = EC_CODEC_I2S_RX_SAMPLE_DEPTH_16; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: depth = EC_CODEC_I2S_RX_SAMPLE_DEPTH_24; break; default: @@ -305,8 +283,8 @@ static int i2s_rx_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) struct ec_param_ec_codec_i2s_rx p; enum ec_codec_i2s_rx_daifmt daifmt; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; @@ -354,7 +332,7 @@ static int i2s_rx_event(struct snd_soc_dapm_widget *w, snd_soc_dapm_to_component(w->dapm); struct cros_ec_codec_priv *priv = snd_soc_component_get_drvdata(component); - struct ec_param_ec_codec_i2s_rx p; + struct ec_param_ec_codec_i2s_rx p = {}; switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -409,6 +387,7 @@ static const struct snd_soc_component_driver i2s_rx_component_driver = { .num_dapm_widgets = ARRAY_SIZE(i2s_rx_dapm_widgets), .dapm_routes = i2s_rx_dapm_routes, .num_dapm_routes = ARRAY_SIZE(i2s_rx_dapm_routes), + .endianness = 1, }; static void *wov_map_shm(struct cros_ec_codec_priv *priv, @@ -652,7 +631,7 @@ leave: static int wov_enable_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol); + struct snd_soc_component *c = snd_kcontrol_chip(kcontrol); struct cros_ec_codec_priv *priv = snd_soc_component_get_drvdata(c); ucontrol->value.integer.value[0] = priv->wov_enabled; @@ -662,7 +641,7 @@ static int wov_enable_get(struct snd_kcontrol *kcontrol, static int wov_enable_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol); + struct snd_soc_component *c = snd_kcontrol_chip(kcontrol); struct cros_ec_codec_priv *priv = snd_soc_component_get_drvdata(c); int enabled = ucontrol->value.integer.value[0]; struct ec_param_ec_codec_wov p; @@ -678,7 +657,7 @@ static int wov_enable_put(struct snd_kcontrol *kcontrol, (uint8_t *)&p, sizeof(p), NULL, 0); if (ret) { dev_err(priv->dev, "failed to %s wov\n", - enabled ? "enable" : "disable"); + str_enable_disable(enabled)); return ret; } @@ -782,9 +761,8 @@ static int wov_hotword_model_put(struct snd_kcontrol *kcontrol, if (IS_ERR(buf)) return PTR_ERR(buf); - ret = calculate_sha256(priv, buf, size, digest); - if (ret) - goto leave; + sha256(buf, size, digest); + dev_dbg(priv->dev, "hash=%*phN\n", SHA256_DIGEST_SIZE, digest); p.cmd = EC_CODEC_WOV_GET_LANG; ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_WOV, @@ -982,7 +960,6 @@ static int cros_ec_codec_platform_probe(struct platform_device *pdev) struct ec_response_ec_codec_get_capabilities r; int ret; #ifdef CONFIG_OF - struct device_node *node; struct resource res; u64 ec_shm_size; const __be32 *regaddr_p; @@ -1002,21 +979,18 @@ static int cros_ec_codec_platform_probe(struct platform_device *pdev) priv->ec_shm_addr, priv->ec_shm_len); } - node = of_parse_phandle(dev->of_node, "memory-region", 0); - if (node) { - ret = of_address_to_resource(node, 0, &res); - if (!ret) { - priv->ap_shm_phys_addr = res.start; - priv->ap_shm_len = resource_size(&res); - priv->ap_shm_addr = - (uint64_t)(uintptr_t)devm_ioremap_wc( - dev, priv->ap_shm_phys_addr, - priv->ap_shm_len); - priv->ap_shm_last_alloc = priv->ap_shm_phys_addr; - - dev_dbg(dev, "ap_shm_phys_addr=%#llx len=%#x\n", - priv->ap_shm_phys_addr, priv->ap_shm_len); - } + ret = of_reserved_mem_region_to_resource(dev->of_node, 0, &res); + if (!ret) { + priv->ap_shm_phys_addr = res.start; + priv->ap_shm_len = resource_size(&res); + priv->ap_shm_addr = + (uint64_t)(uintptr_t)devm_ioremap_wc( + dev, priv->ap_shm_phys_addr, + priv->ap_shm_len); + priv->ap_shm_last_alloc = priv->ap_shm_phys_addr; + + dev_dbg(dev, "ap_shm_phys_addr=%#llx len=%#x\n", + priv->ap_shm_phys_addr, priv->ap_shm_len); } #endif @@ -1034,6 +1008,18 @@ static int cros_ec_codec_platform_probe(struct platform_device *pdev) } priv->ec_capabilities = r.capabilities; + /* Reset EC codec i2s rx. */ + p.cmd = EC_CODEC_I2S_RX_RESET; + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX, + (uint8_t *)&p, sizeof(p), NULL, 0); + if (ret == -ENOPROTOOPT) { + dev_info(dev, + "Missing reset command. Please update EC firmware.\n"); + } else if (ret) { + dev_err(dev, "failed to EC_CODEC_I2S_RESET: %d\n", ret); + return ret; + } + platform_set_drvdata(pdev, priv); ret = devm_snd_soc_register_component(dev, &i2s_rx_component_driver, @@ -1053,11 +1039,13 @@ static const struct of_device_id cros_ec_codec_of_match[] = { MODULE_DEVICE_TABLE(of, cros_ec_codec_of_match); #endif +#ifdef CONFIG_ACPI static const struct acpi_device_id cros_ec_codec_acpi_id[] = { { "GOOG0013", 0 }, { } }; MODULE_DEVICE_TABLE(acpi, cros_ec_codec_acpi_id); +#endif static struct platform_driver cros_ec_codec_platform_driver = { .driver = { |
