cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cros_ec_codec.c (27955B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright 2019 Google, Inc.
      4 *
      5 * ChromeOS Embedded Controller codec driver.
      6 *
      7 * This driver uses the cros-ec interface to communicate with the ChromeOS
      8 * EC for audio function.
      9 */
     10
     11#include <crypto/sha2.h>
     12#include <linux/acpi.h>
     13#include <linux/delay.h>
     14#include <linux/device.h>
     15#include <linux/io.h>
     16#include <linux/jiffies.h>
     17#include <linux/kernel.h>
     18#include <linux/module.h>
     19#include <linux/of.h>
     20#include <linux/of_address.h>
     21#include <linux/platform_data/cros_ec_commands.h>
     22#include <linux/platform_data/cros_ec_proto.h>
     23#include <linux/platform_device.h>
     24#include <sound/pcm.h>
     25#include <sound/pcm_params.h>
     26#include <sound/soc.h>
     27#include <sound/tlv.h>
     28
     29struct cros_ec_codec_priv {
     30	struct device *dev;
     31	struct cros_ec_device *ec_device;
     32
     33	/* common */
     34	uint32_t ec_capabilities;
     35
     36	uint64_t ec_shm_addr;
     37	uint32_t ec_shm_len;
     38
     39	uint64_t ap_shm_phys_addr;
     40	uint32_t ap_shm_len;
     41	uint64_t ap_shm_addr;
     42	uint64_t ap_shm_last_alloc;
     43
     44	/* DMIC */
     45	atomic_t dmic_probed;
     46
     47	/* I2S_RX */
     48	uint32_t i2s_rx_bclk_ratio;
     49
     50	/* WoV */
     51	bool wov_enabled;
     52	uint8_t *wov_audio_shm_p;
     53	uint32_t wov_audio_shm_len;
     54	uint8_t wov_audio_shm_type;
     55	uint8_t *wov_lang_shm_p;
     56	uint32_t wov_lang_shm_len;
     57	uint8_t wov_lang_shm_type;
     58
     59	struct mutex wov_dma_lock;
     60	uint8_t wov_buf[64000];
     61	uint32_t wov_rp, wov_wp;
     62	size_t wov_dma_offset;
     63	bool wov_burst_read;
     64	struct snd_pcm_substream *wov_substream;
     65	struct delayed_work wov_copy_work;
     66	struct notifier_block wov_notifier;
     67};
     68
     69static int ec_codec_capable(struct cros_ec_codec_priv *priv, uint8_t cap)
     70{
     71	return priv->ec_capabilities & BIT(cap);
     72}
     73
     74static int send_ec_host_command(struct cros_ec_device *ec_dev, uint32_t cmd,
     75				uint8_t *out, size_t outsize,
     76				uint8_t *in, size_t insize)
     77{
     78	int ret;
     79	struct cros_ec_command *msg;
     80
     81	msg = kmalloc(sizeof(*msg) + max(outsize, insize), GFP_KERNEL);
     82	if (!msg)
     83		return -ENOMEM;
     84
     85	msg->version = 0;
     86	msg->command = cmd;
     87	msg->outsize = outsize;
     88	msg->insize = insize;
     89
     90	if (outsize)
     91		memcpy(msg->data, out, outsize);
     92
     93	ret = cros_ec_cmd_xfer_status(ec_dev, msg);
     94	if (ret < 0)
     95		goto error;
     96
     97	if (in && insize)
     98		memcpy(in, msg->data, insize);
     99
    100	ret = 0;
    101error:
    102	kfree(msg);
    103	return ret;
    104}
    105
    106static int dmic_get_gain(struct snd_kcontrol *kcontrol,
    107			 struct snd_ctl_elem_value *ucontrol)
    108{
    109	struct snd_soc_component *component =
    110		snd_soc_kcontrol_component(kcontrol);
    111	struct cros_ec_codec_priv *priv =
    112		snd_soc_component_get_drvdata(component);
    113	struct ec_param_ec_codec_dmic p;
    114	struct ec_response_ec_codec_dmic_get_gain_idx r;
    115	int ret;
    116
    117	p.cmd = EC_CODEC_DMIC_GET_GAIN_IDX;
    118	p.get_gain_idx_param.channel = EC_CODEC_DMIC_CHANNEL_0;
    119	ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_DMIC,
    120				   (uint8_t *)&p, sizeof(p),
    121				   (uint8_t *)&r, sizeof(r));
    122	if (ret < 0)
    123		return ret;
    124	ucontrol->value.integer.value[0] = r.gain;
    125
    126	p.cmd = EC_CODEC_DMIC_GET_GAIN_IDX;
    127	p.get_gain_idx_param.channel = EC_CODEC_DMIC_CHANNEL_1;
    128	ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_DMIC,
    129				   (uint8_t *)&p, sizeof(p),
    130				   (uint8_t *)&r, sizeof(r));
    131	if (ret < 0)
    132		return ret;
    133	ucontrol->value.integer.value[1] = r.gain;
    134
    135	return 0;
    136}
    137
    138static int dmic_put_gain(struct snd_kcontrol *kcontrol,
    139			 struct snd_ctl_elem_value *ucontrol)
    140{
    141	struct snd_soc_component *component =
    142		snd_soc_kcontrol_component(kcontrol);
    143	struct cros_ec_codec_priv *priv =
    144		snd_soc_component_get_drvdata(component);
    145	struct soc_mixer_control *control =
    146		(struct soc_mixer_control *)kcontrol->private_value;
    147	int max_dmic_gain = control->max;
    148	int left = ucontrol->value.integer.value[0];
    149	int right = ucontrol->value.integer.value[1];
    150	struct ec_param_ec_codec_dmic p;
    151	int ret;
    152
    153	if (left > max_dmic_gain || right > max_dmic_gain)
    154		return -EINVAL;
    155
    156	dev_dbg(component->dev, "set mic gain to %u, %u\n", left, right);
    157
    158	p.cmd = EC_CODEC_DMIC_SET_GAIN_IDX;
    159	p.set_gain_idx_param.channel = EC_CODEC_DMIC_CHANNEL_0;
    160	p.set_gain_idx_param.gain = left;
    161	ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_DMIC,
    162				   (uint8_t *)&p, sizeof(p), NULL, 0);
    163	if (ret < 0)
    164		return ret;
    165
    166	p.cmd = EC_CODEC_DMIC_SET_GAIN_IDX;
    167	p.set_gain_idx_param.channel = EC_CODEC_DMIC_CHANNEL_1;
    168	p.set_gain_idx_param.gain = right;
    169	return send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_DMIC,
    170				    (uint8_t *)&p, sizeof(p), NULL, 0);
    171}
    172
    173static const DECLARE_TLV_DB_SCALE(dmic_gain_tlv, 0, 100, 0);
    174
    175enum {
    176	DMIC_CTL_GAIN = 0,
    177};
    178
    179static struct snd_kcontrol_new dmic_controls[] = {
    180	[DMIC_CTL_GAIN] =
    181		SOC_DOUBLE_EXT_TLV("EC Mic Gain", SND_SOC_NOPM, SND_SOC_NOPM,
    182				   0, 0, 0, dmic_get_gain, dmic_put_gain,
    183				   dmic_gain_tlv),
    184};
    185
    186static int dmic_probe(struct snd_soc_component *component)
    187{
    188	struct cros_ec_codec_priv *priv =
    189		snd_soc_component_get_drvdata(component);
    190	struct device *dev = priv->dev;
    191	struct soc_mixer_control *control;
    192	struct ec_param_ec_codec_dmic p;
    193	struct ec_response_ec_codec_dmic_get_max_gain r;
    194	int ret;
    195
    196	if (!atomic_add_unless(&priv->dmic_probed, 1, 1))
    197		return 0;
    198
    199	p.cmd = EC_CODEC_DMIC_GET_MAX_GAIN;
    200
    201	ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_DMIC,
    202				   (uint8_t *)&p, sizeof(p),
    203				   (uint8_t *)&r, sizeof(r));
    204	if (ret < 0) {
    205		dev_warn(dev, "get_max_gain() unsupported\n");
    206		return 0;
    207	}
    208
    209	dev_dbg(dev, "max gain = %d\n", r.max_gain);
    210
    211	control = (struct soc_mixer_control *)
    212		dmic_controls[DMIC_CTL_GAIN].private_value;
    213	control->max = r.max_gain;
    214	control->platform_max = r.max_gain;
    215
    216	return snd_soc_add_component_controls(component,
    217			&dmic_controls[DMIC_CTL_GAIN], 1);
    218}
    219
    220static int i2s_rx_hw_params(struct snd_pcm_substream *substream,
    221			    struct snd_pcm_hw_params *params,
    222			    struct snd_soc_dai *dai)
    223{
    224	struct snd_soc_component *component = dai->component;
    225	struct cros_ec_codec_priv *priv =
    226		snd_soc_component_get_drvdata(component);
    227	struct ec_param_ec_codec_i2s_rx p;
    228	enum ec_codec_i2s_rx_sample_depth depth;
    229	uint32_t bclk;
    230	int ret;
    231
    232	if (params_rate(params) != 48000)
    233		return -EINVAL;
    234
    235	switch (params_width(params)) {
    236	case 16:
    237		depth = EC_CODEC_I2S_RX_SAMPLE_DEPTH_16;
    238		break;
    239	case 24:
    240		depth = EC_CODEC_I2S_RX_SAMPLE_DEPTH_24;
    241		break;
    242	default:
    243		return -EINVAL;
    244	}
    245
    246	dev_dbg(component->dev, "set depth to %u\n", depth);
    247
    248	p.cmd = EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH;
    249	p.set_sample_depth_param.depth = depth;
    250	ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX,
    251				   (uint8_t *)&p, sizeof(p), NULL, 0);
    252	if (ret < 0)
    253		return ret;
    254
    255	if (priv->i2s_rx_bclk_ratio)
    256		bclk = params_rate(params) * priv->i2s_rx_bclk_ratio;
    257	else
    258		bclk = snd_soc_params_to_bclk(params);
    259
    260	dev_dbg(component->dev, "set bclk to %u\n", bclk);
    261
    262	p.cmd = EC_CODEC_I2S_RX_SET_BCLK;
    263	p.set_bclk_param.bclk = bclk;
    264	return send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX,
    265				    (uint8_t *)&p, sizeof(p), NULL, 0);
    266}
    267
    268static int i2s_rx_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
    269{
    270	struct snd_soc_component *component = dai->component;
    271	struct cros_ec_codec_priv *priv =
    272		snd_soc_component_get_drvdata(component);
    273
    274	priv->i2s_rx_bclk_ratio = ratio;
    275	return 0;
    276}
    277
    278static int i2s_rx_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
    279{
    280	struct snd_soc_component *component = dai->component;
    281	struct cros_ec_codec_priv *priv =
    282		snd_soc_component_get_drvdata(component);
    283	struct ec_param_ec_codec_i2s_rx p;
    284	enum ec_codec_i2s_rx_daifmt daifmt;
    285
    286	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
    287	case SND_SOC_DAIFMT_CBC_CFC:
    288		break;
    289	default:
    290		return -EINVAL;
    291	}
    292
    293	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    294	case SND_SOC_DAIFMT_NB_NF:
    295		break;
    296	default:
    297		return -EINVAL;
    298	}
    299
    300	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    301	case SND_SOC_DAIFMT_I2S:
    302		daifmt = EC_CODEC_I2S_RX_DAIFMT_I2S;
    303		break;
    304	case SND_SOC_DAIFMT_RIGHT_J:
    305		daifmt = EC_CODEC_I2S_RX_DAIFMT_RIGHT_J;
    306		break;
    307	case SND_SOC_DAIFMT_LEFT_J:
    308		daifmt = EC_CODEC_I2S_RX_DAIFMT_LEFT_J;
    309		break;
    310	default:
    311		return -EINVAL;
    312	}
    313
    314	dev_dbg(component->dev, "set format to %u\n", daifmt);
    315
    316	p.cmd = EC_CODEC_I2S_RX_SET_DAIFMT;
    317	p.set_daifmt_param.daifmt = daifmt;
    318	return send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX,
    319				    (uint8_t *)&p, sizeof(p), NULL, 0);
    320}
    321
    322static const struct snd_soc_dai_ops i2s_rx_dai_ops = {
    323	.hw_params = i2s_rx_hw_params,
    324	.set_fmt = i2s_rx_set_fmt,
    325	.set_bclk_ratio = i2s_rx_set_bclk_ratio,
    326};
    327
    328static int i2s_rx_event(struct snd_soc_dapm_widget *w,
    329			struct snd_kcontrol *kcontrol, int event)
    330{
    331	struct snd_soc_component *component =
    332		snd_soc_dapm_to_component(w->dapm);
    333	struct cros_ec_codec_priv *priv =
    334		snd_soc_component_get_drvdata(component);
    335	struct ec_param_ec_codec_i2s_rx p = {};
    336
    337	switch (event) {
    338	case SND_SOC_DAPM_PRE_PMU:
    339		dev_dbg(component->dev, "enable I2S RX\n");
    340		p.cmd = EC_CODEC_I2S_RX_ENABLE;
    341		break;
    342	case SND_SOC_DAPM_PRE_PMD:
    343		dev_dbg(component->dev, "disable I2S RX\n");
    344		p.cmd = EC_CODEC_I2S_RX_DISABLE;
    345		break;
    346	default:
    347		return 0;
    348	}
    349
    350	return send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX,
    351				    (uint8_t *)&p, sizeof(p), NULL, 0);
    352}
    353
    354static struct snd_soc_dapm_widget i2s_rx_dapm_widgets[] = {
    355	SND_SOC_DAPM_INPUT("DMIC"),
    356	SND_SOC_DAPM_SUPPLY("I2S RX Enable", SND_SOC_NOPM, 0, 0, i2s_rx_event,
    357			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
    358	SND_SOC_DAPM_AIF_OUT("I2S RX", "I2S Capture", 0, SND_SOC_NOPM, 0, 0),
    359};
    360
    361static struct snd_soc_dapm_route i2s_rx_dapm_routes[] = {
    362	{"I2S RX", NULL, "DMIC"},
    363	{"I2S RX", NULL, "I2S RX Enable"},
    364};
    365
    366static struct snd_soc_dai_driver i2s_rx_dai_driver = {
    367	.name = "EC Codec I2S RX",
    368	.capture = {
    369		.stream_name = "I2S Capture",
    370		.channels_min = 2,
    371		.channels_max = 2,
    372		.rates = SNDRV_PCM_RATE_48000,
    373		.formats = SNDRV_PCM_FMTBIT_S16_LE |
    374			SNDRV_PCM_FMTBIT_S24_LE,
    375	},
    376	.ops = &i2s_rx_dai_ops,
    377};
    378
    379static int i2s_rx_probe(struct snd_soc_component *component)
    380{
    381	return dmic_probe(component);
    382}
    383
    384static const struct snd_soc_component_driver i2s_rx_component_driver = {
    385	.probe			= i2s_rx_probe,
    386	.dapm_widgets		= i2s_rx_dapm_widgets,
    387	.num_dapm_widgets	= ARRAY_SIZE(i2s_rx_dapm_widgets),
    388	.dapm_routes		= i2s_rx_dapm_routes,
    389	.num_dapm_routes	= ARRAY_SIZE(i2s_rx_dapm_routes),
    390	.endianness		= 1,
    391};
    392
    393static void *wov_map_shm(struct cros_ec_codec_priv *priv,
    394			 uint8_t shm_id, uint32_t *len, uint8_t *type)
    395{
    396	struct ec_param_ec_codec p;
    397	struct ec_response_ec_codec_get_shm_addr r;
    398	uint32_t req, offset;
    399
    400	p.cmd = EC_CODEC_GET_SHM_ADDR;
    401	p.get_shm_addr_param.shm_id = shm_id;
    402	if (send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC,
    403				 (uint8_t *)&p, sizeof(p),
    404				 (uint8_t *)&r, sizeof(r)) < 0) {
    405		dev_err(priv->dev, "failed to EC_CODEC_GET_SHM_ADDR\n");
    406		return NULL;
    407	}
    408
    409	dev_dbg(priv->dev, "phys_addr=%#llx, len=%#x\n", r.phys_addr, r.len);
    410
    411	*len = r.len;
    412	*type = r.type;
    413
    414	switch (r.type) {
    415	case EC_CODEC_SHM_TYPE_EC_RAM:
    416		return (void __force *)devm_ioremap_wc(priv->dev,
    417				r.phys_addr + priv->ec_shm_addr, r.len);
    418	case EC_CODEC_SHM_TYPE_SYSTEM_RAM:
    419		if (r.phys_addr) {
    420			dev_err(priv->dev, "unknown status\n");
    421			return NULL;
    422		}
    423
    424		req = round_up(r.len, PAGE_SIZE);
    425		dev_dbg(priv->dev, "round up from %u to %u\n", r.len, req);
    426
    427		if (priv->ap_shm_last_alloc + req >
    428		    priv->ap_shm_phys_addr + priv->ap_shm_len) {
    429			dev_err(priv->dev, "insufficient space for AP SHM\n");
    430			return NULL;
    431		}
    432
    433		dev_dbg(priv->dev, "alloc AP SHM addr=%#llx, len=%#x\n",
    434			priv->ap_shm_last_alloc, req);
    435
    436		p.cmd = EC_CODEC_SET_SHM_ADDR;
    437		p.set_shm_addr_param.phys_addr = priv->ap_shm_last_alloc;
    438		p.set_shm_addr_param.len = req;
    439		p.set_shm_addr_param.shm_id = shm_id;
    440		if (send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC,
    441					 (uint8_t *)&p, sizeof(p),
    442					 NULL, 0) < 0) {
    443			dev_err(priv->dev, "failed to EC_CODEC_SET_SHM_ADDR\n");
    444			return NULL;
    445		}
    446
    447		/*
    448		 * Note: EC codec only requests for `r.len' but we allocate
    449		 * round up PAGE_SIZE `req'.
    450		 */
    451		offset = priv->ap_shm_last_alloc - priv->ap_shm_phys_addr;
    452		priv->ap_shm_last_alloc += req;
    453
    454		return (void *)(uintptr_t)(priv->ap_shm_addr + offset);
    455	default:
    456		return NULL;
    457	}
    458}
    459
    460static bool wov_queue_full(struct cros_ec_codec_priv *priv)
    461{
    462	return ((priv->wov_wp + 1) % sizeof(priv->wov_buf)) == priv->wov_rp;
    463}
    464
    465static size_t wov_queue_size(struct cros_ec_codec_priv *priv)
    466{
    467	if (priv->wov_wp >= priv->wov_rp)
    468		return priv->wov_wp - priv->wov_rp;
    469	else
    470		return sizeof(priv->wov_buf) - priv->wov_rp + priv->wov_wp;
    471}
    472
    473static void wov_queue_dequeue(struct cros_ec_codec_priv *priv, size_t len)
    474{
    475	struct snd_pcm_runtime *runtime = priv->wov_substream->runtime;
    476	size_t req;
    477
    478	while (len) {
    479		req = min(len, runtime->dma_bytes - priv->wov_dma_offset);
    480		if (priv->wov_wp >= priv->wov_rp)
    481			req = min(req, (size_t)priv->wov_wp - priv->wov_rp);
    482		else
    483			req = min(req, sizeof(priv->wov_buf) - priv->wov_rp);
    484
    485		memcpy(runtime->dma_area + priv->wov_dma_offset,
    486		       priv->wov_buf + priv->wov_rp, req);
    487
    488		priv->wov_dma_offset += req;
    489		if (priv->wov_dma_offset == runtime->dma_bytes)
    490			priv->wov_dma_offset = 0;
    491
    492		priv->wov_rp += req;
    493		if (priv->wov_rp == sizeof(priv->wov_buf))
    494			priv->wov_rp = 0;
    495
    496		len -= req;
    497	}
    498
    499	snd_pcm_period_elapsed(priv->wov_substream);
    500}
    501
    502static void wov_queue_try_dequeue(struct cros_ec_codec_priv *priv)
    503{
    504	size_t period_bytes = snd_pcm_lib_period_bytes(priv->wov_substream);
    505
    506	while (period_bytes && wov_queue_size(priv) >= period_bytes) {
    507		wov_queue_dequeue(priv, period_bytes);
    508		period_bytes = snd_pcm_lib_period_bytes(priv->wov_substream);
    509	}
    510}
    511
    512static void wov_queue_enqueue(struct cros_ec_codec_priv *priv,
    513			      uint8_t *addr, size_t len, bool iomem)
    514{
    515	size_t req;
    516
    517	while (len) {
    518		if (wov_queue_full(priv)) {
    519			wov_queue_try_dequeue(priv);
    520
    521			if (wov_queue_full(priv)) {
    522				dev_err(priv->dev, "overrun detected\n");
    523				return;
    524			}
    525		}
    526
    527		if (priv->wov_wp >= priv->wov_rp)
    528			req = sizeof(priv->wov_buf) - priv->wov_wp;
    529		else
    530			/* Note: waste 1-byte to differentiate full and empty */
    531			req = priv->wov_rp - priv->wov_wp - 1;
    532		req = min(req, len);
    533
    534		if (iomem)
    535			memcpy_fromio(priv->wov_buf + priv->wov_wp,
    536				      (void __force __iomem *)addr, req);
    537		else
    538			memcpy(priv->wov_buf + priv->wov_wp, addr, req);
    539
    540		priv->wov_wp += req;
    541		if (priv->wov_wp == sizeof(priv->wov_buf))
    542			priv->wov_wp = 0;
    543
    544		addr += req;
    545		len -= req;
    546	}
    547
    548	wov_queue_try_dequeue(priv);
    549}
    550
    551static int wov_read_audio_shm(struct cros_ec_codec_priv *priv)
    552{
    553	struct ec_param_ec_codec_wov p;
    554	struct ec_response_ec_codec_wov_read_audio_shm r;
    555	int ret;
    556
    557	p.cmd = EC_CODEC_WOV_READ_AUDIO_SHM;
    558	ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_WOV,
    559				   (uint8_t *)&p, sizeof(p),
    560				   (uint8_t *)&r, sizeof(r));
    561	if (ret) {
    562		dev_err(priv->dev, "failed to EC_CODEC_WOV_READ_AUDIO_SHM\n");
    563		return ret;
    564	}
    565
    566	if (!r.len)
    567		dev_dbg(priv->dev, "no data, sleep\n");
    568	else
    569		wov_queue_enqueue(priv, priv->wov_audio_shm_p + r.offset, r.len,
    570			priv->wov_audio_shm_type == EC_CODEC_SHM_TYPE_EC_RAM);
    571	return -EAGAIN;
    572}
    573
    574static int wov_read_audio(struct cros_ec_codec_priv *priv)
    575{
    576	struct ec_param_ec_codec_wov p;
    577	struct ec_response_ec_codec_wov_read_audio r;
    578	int remain = priv->wov_burst_read ? 16000 : 320;
    579	int ret;
    580
    581	while (remain >= 0) {
    582		p.cmd = EC_CODEC_WOV_READ_AUDIO;
    583		ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_WOV,
    584					   (uint8_t *)&p, sizeof(p),
    585					   (uint8_t *)&r, sizeof(r));
    586		if (ret) {
    587			dev_err(priv->dev,
    588				"failed to EC_CODEC_WOV_READ_AUDIO\n");
    589			return ret;
    590		}
    591
    592		if (!r.len) {
    593			dev_dbg(priv->dev, "no data, sleep\n");
    594			priv->wov_burst_read = false;
    595			break;
    596		}
    597
    598		wov_queue_enqueue(priv, r.buf, r.len, false);
    599		remain -= r.len;
    600	}
    601
    602	return -EAGAIN;
    603}
    604
    605static void wov_copy_work(struct work_struct *w)
    606{
    607	struct cros_ec_codec_priv *priv =
    608		container_of(w, struct cros_ec_codec_priv, wov_copy_work.work);
    609	int ret;
    610
    611	mutex_lock(&priv->wov_dma_lock);
    612	if (!priv->wov_substream) {
    613		dev_warn(priv->dev, "no pcm substream\n");
    614		goto leave;
    615	}
    616
    617	if (ec_codec_capable(priv, EC_CODEC_CAP_WOV_AUDIO_SHM))
    618		ret = wov_read_audio_shm(priv);
    619	else
    620		ret = wov_read_audio(priv);
    621
    622	if (ret == -EAGAIN)
    623		schedule_delayed_work(&priv->wov_copy_work,
    624				      msecs_to_jiffies(10));
    625	else if (ret)
    626		dev_err(priv->dev, "failed to read audio data\n");
    627leave:
    628	mutex_unlock(&priv->wov_dma_lock);
    629}
    630
    631static int wov_enable_get(struct snd_kcontrol *kcontrol,
    632			  struct snd_ctl_elem_value *ucontrol)
    633{
    634	struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
    635	struct cros_ec_codec_priv *priv = snd_soc_component_get_drvdata(c);
    636
    637	ucontrol->value.integer.value[0] = priv->wov_enabled;
    638	return 0;
    639}
    640
    641static int wov_enable_put(struct snd_kcontrol *kcontrol,
    642			  struct snd_ctl_elem_value *ucontrol)
    643{
    644	struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
    645	struct cros_ec_codec_priv *priv = snd_soc_component_get_drvdata(c);
    646	int enabled = ucontrol->value.integer.value[0];
    647	struct ec_param_ec_codec_wov p;
    648	int ret;
    649
    650	if (priv->wov_enabled != enabled) {
    651		if (enabled)
    652			p.cmd = EC_CODEC_WOV_ENABLE;
    653		else
    654			p.cmd = EC_CODEC_WOV_DISABLE;
    655
    656		ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_WOV,
    657					   (uint8_t *)&p, sizeof(p), NULL, 0);
    658		if (ret) {
    659			dev_err(priv->dev, "failed to %s wov\n",
    660				enabled ? "enable" : "disable");
    661			return ret;
    662		}
    663
    664		priv->wov_enabled = enabled;
    665	}
    666
    667	return 0;
    668}
    669
    670static int wov_set_lang_shm(struct cros_ec_codec_priv *priv,
    671			    uint8_t *buf, size_t size, uint8_t *digest)
    672{
    673	struct ec_param_ec_codec_wov p;
    674	struct ec_param_ec_codec_wov_set_lang_shm *pp = &p.set_lang_shm_param;
    675	int ret;
    676
    677	if (size > priv->wov_lang_shm_len) {
    678		dev_err(priv->dev, "no enough SHM size: %d\n",
    679			priv->wov_lang_shm_len);
    680		return -EIO;
    681	}
    682
    683	switch (priv->wov_lang_shm_type) {
    684	case EC_CODEC_SHM_TYPE_EC_RAM:
    685		memcpy_toio((void __force __iomem *)priv->wov_lang_shm_p,
    686			    buf, size);
    687		memset_io((void __force __iomem *)priv->wov_lang_shm_p + size,
    688			  0, priv->wov_lang_shm_len - size);
    689		break;
    690	case EC_CODEC_SHM_TYPE_SYSTEM_RAM:
    691		memcpy(priv->wov_lang_shm_p, buf, size);
    692		memset(priv->wov_lang_shm_p + size, 0,
    693		       priv->wov_lang_shm_len - size);
    694
    695		/* make sure write to memory before calling host command */
    696		wmb();
    697		break;
    698	}
    699
    700	p.cmd = EC_CODEC_WOV_SET_LANG_SHM;
    701	memcpy(pp->hash, digest, SHA256_DIGEST_SIZE);
    702	pp->total_len = size;
    703	ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_WOV,
    704				   (uint8_t *)&p, sizeof(p), NULL, 0);
    705	if (ret) {
    706		dev_err(priv->dev, "failed to EC_CODEC_WOV_SET_LANG_SHM\n");
    707		return ret;
    708	}
    709
    710	return 0;
    711}
    712
    713static int wov_set_lang(struct cros_ec_codec_priv *priv,
    714			uint8_t *buf, size_t size, uint8_t *digest)
    715{
    716	struct ec_param_ec_codec_wov p;
    717	struct ec_param_ec_codec_wov_set_lang *pp = &p.set_lang_param;
    718	size_t i, req;
    719	int ret;
    720
    721	for (i = 0; i < size; i += req) {
    722		req = min(size - i, ARRAY_SIZE(pp->buf));
    723
    724		p.cmd = EC_CODEC_WOV_SET_LANG;
    725		memcpy(pp->hash, digest, SHA256_DIGEST_SIZE);
    726		pp->total_len = size;
    727		pp->offset = i;
    728		memcpy(pp->buf, buf + i, req);
    729		pp->len = req;
    730		ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_WOV,
    731					   (uint8_t *)&p, sizeof(p), NULL, 0);
    732		if (ret) {
    733			dev_err(priv->dev, "failed to EC_CODEC_WOV_SET_LANG\n");
    734			return ret;
    735		}
    736	}
    737
    738	return 0;
    739}
    740
    741static int wov_hotword_model_put(struct snd_kcontrol *kcontrol,
    742				 const unsigned int __user *bytes,
    743				 unsigned int size)
    744{
    745	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
    746	struct cros_ec_codec_priv *priv =
    747		snd_soc_component_get_drvdata(component);
    748	struct ec_param_ec_codec_wov p;
    749	struct ec_response_ec_codec_wov_get_lang r;
    750	uint8_t digest[SHA256_DIGEST_SIZE];
    751	uint8_t *buf;
    752	int ret;
    753
    754	/* Skips the TLV header. */
    755	bytes += 2;
    756	size -= 8;
    757
    758	dev_dbg(priv->dev, "%s: size=%d\n", __func__, size);
    759
    760	buf = memdup_user(bytes, size);
    761	if (IS_ERR(buf))
    762		return PTR_ERR(buf);
    763
    764	sha256(buf, size, digest);
    765	dev_dbg(priv->dev, "hash=%*phN\n", SHA256_DIGEST_SIZE, digest);
    766
    767	p.cmd = EC_CODEC_WOV_GET_LANG;
    768	ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_WOV,
    769				   (uint8_t *)&p, sizeof(p),
    770				   (uint8_t *)&r, sizeof(r));
    771	if (ret)
    772		goto leave;
    773
    774	if (memcmp(digest, r.hash, SHA256_DIGEST_SIZE) == 0) {
    775		dev_dbg(priv->dev, "not updated");
    776		goto leave;
    777	}
    778
    779	if (ec_codec_capable(priv, EC_CODEC_CAP_WOV_LANG_SHM))
    780		ret = wov_set_lang_shm(priv, buf, size, digest);
    781	else
    782		ret = wov_set_lang(priv, buf, size, digest);
    783
    784leave:
    785	kfree(buf);
    786	return ret;
    787}
    788
    789static struct snd_kcontrol_new wov_controls[] = {
    790	SOC_SINGLE_BOOL_EXT("Wake-on-Voice Switch", 0,
    791			    wov_enable_get, wov_enable_put),
    792	SND_SOC_BYTES_TLV("Hotword Model", 0x11000, NULL,
    793			  wov_hotword_model_put),
    794};
    795
    796static struct snd_soc_dai_driver wov_dai_driver = {
    797	.name = "Wake on Voice",
    798	.capture = {
    799		.stream_name = "WoV Capture",
    800		.channels_min = 1,
    801		.channels_max = 1,
    802		.rates = SNDRV_PCM_RATE_16000,
    803		.formats = SNDRV_PCM_FMTBIT_S16_LE,
    804	},
    805};
    806
    807static int wov_host_event(struct notifier_block *nb,
    808			  unsigned long queued_during_suspend, void *notify)
    809{
    810	struct cros_ec_codec_priv *priv =
    811		container_of(nb, struct cros_ec_codec_priv, wov_notifier);
    812	u32 host_event;
    813
    814	dev_dbg(priv->dev, "%s\n", __func__);
    815
    816	host_event = cros_ec_get_host_event(priv->ec_device);
    817	if (host_event & EC_HOST_EVENT_MASK(EC_HOST_EVENT_WOV)) {
    818		schedule_delayed_work(&priv->wov_copy_work, 0);
    819		return NOTIFY_OK;
    820	} else {
    821		return NOTIFY_DONE;
    822	}
    823}
    824
    825static int wov_probe(struct snd_soc_component *component)
    826{
    827	struct cros_ec_codec_priv *priv =
    828		snd_soc_component_get_drvdata(component);
    829	int ret;
    830
    831	mutex_init(&priv->wov_dma_lock);
    832	INIT_DELAYED_WORK(&priv->wov_copy_work, wov_copy_work);
    833
    834	priv->wov_notifier.notifier_call = wov_host_event;
    835	ret = blocking_notifier_chain_register(
    836			&priv->ec_device->event_notifier, &priv->wov_notifier);
    837	if (ret)
    838		return ret;
    839
    840	if (ec_codec_capable(priv, EC_CODEC_CAP_WOV_LANG_SHM)) {
    841		priv->wov_lang_shm_p = wov_map_shm(priv,
    842				EC_CODEC_SHM_ID_WOV_LANG,
    843				&priv->wov_lang_shm_len,
    844				&priv->wov_lang_shm_type);
    845		if (!priv->wov_lang_shm_p)
    846			return -EFAULT;
    847	}
    848
    849	if (ec_codec_capable(priv, EC_CODEC_CAP_WOV_AUDIO_SHM)) {
    850		priv->wov_audio_shm_p = wov_map_shm(priv,
    851				EC_CODEC_SHM_ID_WOV_AUDIO,
    852				&priv->wov_audio_shm_len,
    853				&priv->wov_audio_shm_type);
    854		if (!priv->wov_audio_shm_p)
    855			return -EFAULT;
    856	}
    857
    858	return dmic_probe(component);
    859}
    860
    861static void wov_remove(struct snd_soc_component *component)
    862{
    863	struct cros_ec_codec_priv *priv =
    864		snd_soc_component_get_drvdata(component);
    865
    866	blocking_notifier_chain_unregister(
    867			&priv->ec_device->event_notifier, &priv->wov_notifier);
    868}
    869
    870static int wov_pcm_open(struct snd_soc_component *component,
    871			struct snd_pcm_substream *substream)
    872{
    873	static const struct snd_pcm_hardware hw_param = {
    874		.info = SNDRV_PCM_INFO_MMAP |
    875			SNDRV_PCM_INFO_INTERLEAVED |
    876			SNDRV_PCM_INFO_MMAP_VALID,
    877		.formats = SNDRV_PCM_FMTBIT_S16_LE,
    878		.rates = SNDRV_PCM_RATE_16000,
    879		.channels_min = 1,
    880		.channels_max = 1,
    881		.period_bytes_min = PAGE_SIZE,
    882		.period_bytes_max = 0x20000 / 8,
    883		.periods_min = 8,
    884		.periods_max = 8,
    885		.buffer_bytes_max = 0x20000,
    886	};
    887
    888	return snd_soc_set_runtime_hwparams(substream, &hw_param);
    889}
    890
    891static int wov_pcm_hw_params(struct snd_soc_component *component,
    892			     struct snd_pcm_substream *substream,
    893			     struct snd_pcm_hw_params *hw_params)
    894{
    895	struct cros_ec_codec_priv *priv =
    896		snd_soc_component_get_drvdata(component);
    897
    898	mutex_lock(&priv->wov_dma_lock);
    899	priv->wov_substream = substream;
    900	priv->wov_rp = priv->wov_wp = 0;
    901	priv->wov_dma_offset = 0;
    902	priv->wov_burst_read = true;
    903	mutex_unlock(&priv->wov_dma_lock);
    904
    905	return 0;
    906}
    907
    908static int wov_pcm_hw_free(struct snd_soc_component *component,
    909			   struct snd_pcm_substream *substream)
    910{
    911	struct cros_ec_codec_priv *priv =
    912		snd_soc_component_get_drvdata(component);
    913
    914	mutex_lock(&priv->wov_dma_lock);
    915	wov_queue_dequeue(priv, wov_queue_size(priv));
    916	priv->wov_substream = NULL;
    917	mutex_unlock(&priv->wov_dma_lock);
    918
    919	cancel_delayed_work_sync(&priv->wov_copy_work);
    920
    921	return 0;
    922}
    923
    924static snd_pcm_uframes_t wov_pcm_pointer(struct snd_soc_component *component,
    925					 struct snd_pcm_substream *substream)
    926{
    927	struct snd_pcm_runtime *runtime = substream->runtime;
    928	struct cros_ec_codec_priv *priv =
    929		snd_soc_component_get_drvdata(component);
    930
    931	return bytes_to_frames(runtime, priv->wov_dma_offset);
    932}
    933
    934static int wov_pcm_new(struct snd_soc_component *component,
    935		       struct snd_soc_pcm_runtime *rtd)
    936{
    937	snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_VMALLOC,
    938				       NULL, 0, 0);
    939	return 0;
    940}
    941
    942static const struct snd_soc_component_driver wov_component_driver = {
    943	.probe		= wov_probe,
    944	.remove		= wov_remove,
    945	.controls	= wov_controls,
    946	.num_controls	= ARRAY_SIZE(wov_controls),
    947	.open		= wov_pcm_open,
    948	.hw_params	= wov_pcm_hw_params,
    949	.hw_free	= wov_pcm_hw_free,
    950	.pointer	= wov_pcm_pointer,
    951	.pcm_construct	= wov_pcm_new,
    952};
    953
    954static int cros_ec_codec_platform_probe(struct platform_device *pdev)
    955{
    956	struct device *dev = &pdev->dev;
    957	struct cros_ec_device *ec_device = dev_get_drvdata(pdev->dev.parent);
    958	struct cros_ec_codec_priv *priv;
    959	struct ec_param_ec_codec p;
    960	struct ec_response_ec_codec_get_capabilities r;
    961	int ret;
    962#ifdef CONFIG_OF
    963	struct device_node *node;
    964	struct resource res;
    965	u64 ec_shm_size;
    966	const __be32 *regaddr_p;
    967#endif
    968
    969	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
    970	if (!priv)
    971		return -ENOMEM;
    972
    973#ifdef CONFIG_OF
    974	regaddr_p = of_get_address(dev->of_node, 0, &ec_shm_size, NULL);
    975	if (regaddr_p) {
    976		priv->ec_shm_addr = of_read_number(regaddr_p, 2);
    977		priv->ec_shm_len = ec_shm_size;
    978
    979		dev_dbg(dev, "ec_shm_addr=%#llx len=%#x\n",
    980			priv->ec_shm_addr, priv->ec_shm_len);
    981	}
    982
    983	node = of_parse_phandle(dev->of_node, "memory-region", 0);
    984	if (node) {
    985		ret = of_address_to_resource(node, 0, &res);
    986		if (!ret) {
    987			priv->ap_shm_phys_addr = res.start;
    988			priv->ap_shm_len = resource_size(&res);
    989			priv->ap_shm_addr =
    990				(uint64_t)(uintptr_t)devm_ioremap_wc(
    991					dev, priv->ap_shm_phys_addr,
    992					priv->ap_shm_len);
    993			priv->ap_shm_last_alloc = priv->ap_shm_phys_addr;
    994
    995			dev_dbg(dev, "ap_shm_phys_addr=%#llx len=%#x\n",
    996				priv->ap_shm_phys_addr, priv->ap_shm_len);
    997		}
    998	}
    999#endif
   1000
   1001	priv->dev = dev;
   1002	priv->ec_device = ec_device;
   1003	atomic_set(&priv->dmic_probed, 0);
   1004
   1005	p.cmd = EC_CODEC_GET_CAPABILITIES;
   1006	ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC,
   1007				   (uint8_t *)&p, sizeof(p),
   1008				   (uint8_t *)&r, sizeof(r));
   1009	if (ret) {
   1010		dev_err(dev, "failed to EC_CODEC_GET_CAPABILITIES\n");
   1011		return ret;
   1012	}
   1013	priv->ec_capabilities = r.capabilities;
   1014
   1015	/* Reset EC codec i2s rx. */
   1016	p.cmd = EC_CODEC_I2S_RX_RESET;
   1017	ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX,
   1018				   (uint8_t *)&p, sizeof(p), NULL, 0);
   1019	if (ret == -ENOPROTOOPT) {
   1020		dev_info(dev,
   1021			 "Missing reset command. Please update EC firmware.\n");
   1022	} else if (ret) {
   1023		dev_err(dev, "failed to EC_CODEC_I2S_RESET: %d\n", ret);
   1024		return ret;
   1025	}
   1026
   1027	platform_set_drvdata(pdev, priv);
   1028
   1029	ret = devm_snd_soc_register_component(dev, &i2s_rx_component_driver,
   1030					      &i2s_rx_dai_driver, 1);
   1031	if (ret)
   1032		return ret;
   1033
   1034	return devm_snd_soc_register_component(dev, &wov_component_driver,
   1035					       &wov_dai_driver, 1);
   1036}
   1037
   1038#ifdef CONFIG_OF
   1039static const struct of_device_id cros_ec_codec_of_match[] = {
   1040	{ .compatible = "google,cros-ec-codec" },
   1041	{},
   1042};
   1043MODULE_DEVICE_TABLE(of, cros_ec_codec_of_match);
   1044#endif
   1045
   1046#ifdef CONFIG_ACPI
   1047static const struct acpi_device_id cros_ec_codec_acpi_id[] = {
   1048	{ "GOOG0013", 0 },
   1049	{ }
   1050};
   1051MODULE_DEVICE_TABLE(acpi, cros_ec_codec_acpi_id);
   1052#endif
   1053
   1054static struct platform_driver cros_ec_codec_platform_driver = {
   1055	.driver = {
   1056		.name = "cros-ec-codec",
   1057		.of_match_table = of_match_ptr(cros_ec_codec_of_match),
   1058		.acpi_match_table = ACPI_PTR(cros_ec_codec_acpi_id),
   1059	},
   1060	.probe = cros_ec_codec_platform_probe,
   1061};
   1062
   1063module_platform_driver(cros_ec_codec_platform_driver);
   1064
   1065MODULE_LICENSE("GPL v2");
   1066MODULE_DESCRIPTION("ChromeOS EC codec driver");
   1067MODULE_AUTHOR("Cheng-Yi Chiang <cychiang@chromium.org>");
   1068MODULE_ALIAS("platform:cros-ec-codec");