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