5 #include <linux/slab.h>
6 #include <linux/wait.h>
7 #include <linux/jiffies.h>
8 #include <sound/asound.h>
10 #include <sound/control.h>
11 #include "msm-pcm-routing-v2.h"
12 #include <sound/q6audio-v2.h>
13 #include <sound/apr_audio-v2.h>
14 #include "msm-elliptic.h"
16 #include <drivers/elliptic/elliptic_data_io.h>
17 #include <drivers/elliptic/elliptic_device.h>
18 #include <drivers/elliptic/elliptic_mixer_controls.h>
20 struct elliptic_system_configuration {
22 uint8_t reserved[ELLIPTIC_SYSTEM_CONFIGURATION_SIZE];
26 struct elliptic_system_configuration elliptic_system_configuration;
28 enum elliptic_system_configuration_parameter_type {
30 ESCPT_SPEAKER_SCALING = 1,
31 ESCPT_CHANNEL_SENSITIVITY,
33 ESCPT_MICROPHONE_INDEX,
35 ESCPT_OPERATION_MODE_FLAGS,
36 ESCPT_COMPONENT_GAIN_CHANGE,
37 ESCPT_CALIBRATION_STATE,
39 ESCPT_CALIBRATION_PROFILE,
40 ESCPT_ULTRASOUND_GAIN,
44 struct elliptic_system_configuration_parameter {
45 enum elliptic_system_configuration_parameter_type type;
47 int32_t speaker_scaling[2];
50 int32_t microphone_index;
51 int32_t operation_mode;
52 int32_t operation_mode_flags;
53 int32_t component_gain_change;
54 int32_t calibration_state;
55 int32_t engine_version;
56 int32_t calibration_profile;
57 int32_t ultrasound_gain;
62 struct elliptic_system_configuration_parameters_cache {
63 int32_t speaker_scaling[2];
66 int32_t microphone_index;
67 int32_t operation_mode;
68 int32_t operation_mode_flags;
69 int32_t component_gain_change;
70 int32_t calibration_state;
71 int32_t engine_version;
72 int32_t calibration_profile;
73 int32_t ultrasound_gain;
77 struct elliptic_system_configuration_parameters_cache
78 elliptic_system_configuration_cache = { {0}, 0 };
80 static struct elliptic_engine_version_info
81 elliptic_engine_version_cache = { 0xde, 0xad, 0xbe, 0xef };
83 struct elliptic_engine_calibration_data {
85 uint8_t reserved[ELLIPTIC_CALIBRATION_DATA_SIZE];
89 static struct elliptic_engine_calibration_data
90 elliptic_engine_calibration_data_cache = { .reserved = {
92 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe,
93 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad,
94 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde,
95 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
96 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe,
97 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } };
99 struct elliptic_engine_branch_info {
100 char build_branch[ELLIPTIC_BRANCH_INFO_SIZE];
103 static struct elliptic_engine_branch_info
104 elliptic_engine_branch_cache = { { 0 } };
106 static struct elliptic_shared_data_block shared_data_blocks[] = {
107 { ELLIPTIC_OBJ_ID_CALIBRATION_DATA, ELLIPTIC_CALIBRATION_DATA_SIZE,
108 &elliptic_engine_calibration_data_cache },
110 { ELLIPTIC_OBJ_ID_VERSION_INFO, ELLIPTIC_VERSION_INFO_SIZE,
111 &elliptic_engine_version_cache },
112 { ELLIPTIC_OBJ_ID_BRANCH_INFO, ELLIPTIC_BRANCH_INFO_SIZE,
113 &elliptic_engine_branch_cache },
117 static const size_t NUM_SHARED_RW_OBJS =
118 sizeof(shared_data_blocks) / sizeof(struct elliptic_shared_data_block);
120 struct elliptic_shared_data_block *elliptic_get_shared_obj(uint32_t
125 for (i = 0; i < NUM_SHARED_RW_OBJS; ++i) {
126 if (shared_data_blocks[i].object_id == object_id)
127 return &shared_data_blocks[i];
134 static const char * const ultrasound_enable_texts[] = {"Off", "On"};
136 static const struct soc_enum elliptic_enum[] = {
137 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ultrasound_enable_texts),
138 ultrasound_enable_texts),
141 int get_elliptic_calibration_data(uint8_t *caldata, uint32_t max_size)
143 uint32_t copied = ELLIPTIC_CALIBRATION_DATA_SIZE;
145 if (max_size < ELLIPTIC_CALIBRATION_DATA_SIZE) {
147 EL_PRINT_D("size mismatch : %d vs %d",
148 ELLIPTIC_CALIBRATION_DATA_SIZE, max_size);
151 memcpy(caldata, (uint8_t *)&elliptic_engine_calibration_data_cache,
157 static uint32_t ultrasound_enable_cache;
159 int msm_routing_get_ultrasound_enable(struct snd_kcontrol *kcontrol,
160 struct snd_ctl_elem_value *ucontrol)
162 ucontrol->value.integer.value[0] = ultrasound_enable_cache;
166 int msm_routing_set_ultrasound_enable(struct snd_kcontrol *kcontrol,
167 struct snd_ctl_elem_value *ucontrol)
171 ultrasound_enable_cache = ucontrol->value.integer.value[0];
173 msm_pcm_routing_acquire_lock();
174 ret = ultrasound_apr_set(ELLIPTIC_PORT_ID, &ultrasound_enable_cache,
176 msm_pcm_routing_release_lock();
180 int msm_routing_get_ultrasound_rampdown(struct snd_kcontrol *kcontrol,
181 struct snd_ctl_elem_value *ucontrol)
183 /* Rampdown is a strobe, so always return Off */
184 ucontrol->value.integer.value[0] = 0;
188 int msm_routing_set_ultrasound_rampdown(struct snd_kcontrol *kcontrol,
189 struct snd_ctl_elem_value *ucontrol)
192 uint32_t filter_set = ELLIPTIC_ULTRASOUND_RAMP_DOWN;
194 if (ucontrol->value.integer.value[0] == 0)
197 msm_pcm_routing_acquire_lock();
198 pr_debug("ELUS in %s", __func__);
199 ret = ultrasound_apr_set(ELLIPTIC_PORT_ID, &filter_set, NULL, 0);
200 msm_pcm_routing_release_lock();
204 int elliptic_system_configuration_get(struct snd_kcontrol *kcontrol,
205 struct snd_ctl_elem_value *ucontrol)
207 memcpy(ucontrol->value.bytes.data, &elliptic_system_configuration,
208 ELLIPTIC_SYSTEM_CONFIGURATION_SIZE);
212 int elliptic_system_configuration_put(struct snd_kcontrol *kcontrol,
213 struct snd_ctl_elem_value *ucontrol)
215 int32_t param_id = ELLIPTIC_ULTRASOUND_SET_PARAMS;
217 memcpy(&elliptic_system_configuration, ucontrol->value.bytes.data,
218 ELLIPTIC_SYSTEM_CONFIGURATION_SIZE);
219 return ultrasound_apr_set(ELLIPTIC_PORT_ID,
221 (u8 *)&elliptic_system_configuration,
222 ELLIPTIC_SYSTEM_CONFIGURATION_SIZE);
225 int elliptic_calibration_data_get(struct snd_kcontrol *kcontrol,
226 struct snd_ctl_elem_value *ucontrol)
228 memcpy(ucontrol->value.bytes.data,
229 &elliptic_engine_calibration_data_cache,
230 ELLIPTIC_CALIBRATION_DATA_SIZE);
234 int elliptic_calibration_data_put(struct snd_kcontrol *kcontrol,
235 struct snd_ctl_elem_value *ucontrol)
237 int32_t param_id = ELLIPTIC_ULTRASOUND_SET_PARAMS;
239 memcpy(&elliptic_engine_calibration_data_cache,
240 ucontrol->value.bytes.data, ELLIPTIC_CALIBRATION_DATA_SIZE);
242 return ultrasound_apr_set(ELLIPTIC_PORT_ID,
244 (u8 *)&elliptic_engine_calibration_data_cache,
245 ELLIPTIC_CALIBRATION_DATA_SIZE);
248 int elliptic_version_data_get(struct snd_kcontrol *kcontrol,
249 struct snd_ctl_elem_value *ucontrol)
251 memcpy(ucontrol->value.bytes.data, &elliptic_engine_version_cache,
252 ELLIPTIC_VERSION_INFO_SIZE);
256 int elliptic_version_data_put(struct snd_kcontrol *kcontrol,
257 struct snd_ctl_elem_value *ucontrol)
262 int elliptic_branch_data_get(struct snd_kcontrol *kcontrol,
263 struct snd_ctl_elem_value *ucontrol)
265 memcpy(ucontrol->value.bytes.data, &elliptic_engine_branch_cache,
266 ELLIPTIC_BRANCH_INFO_SIZE);
270 int elliptic_branch_data_put(struct snd_kcontrol *kcontrol,
271 struct snd_ctl_elem_value *ucontrol)
276 int elliptic_calibration_param_get(
277 struct snd_kcontrol *kcontrol,
278 struct snd_ctl_elem_value *ucontrol)
280 struct soc_mixer_control *mc =
281 (struct soc_mixer_control *)kcontrol->private_value;
283 pr_err("%s: reg: %d shift: %d\n", __func__, mc->reg, mc->shift);
285 if (mc->reg != ELLIPTIC_CALIBRATION)
289 case ELLIPTIC_CALIBRATION_STATE:
290 ucontrol->value.integer.value[0] =
291 elliptic_system_configuration_cache.calibration_state;
294 case ELLIPTIC_CALIBRATION_PROFILE:
295 ucontrol->value.integer.value[0] =
296 elliptic_system_configuration_cache.calibration_profile;
299 case ELLIPTIC_ULTRASOUND_GAIN:
300 ucontrol->value.integer.value[0] =
301 elliptic_system_configuration_cache.ultrasound_gain;
311 int elliptic_calibration_param_put(
312 struct snd_kcontrol *kcontrol,
313 struct snd_ctl_elem_value *ucontrol)
315 struct soc_mixer_control *mc =
316 (struct soc_mixer_control *)kcontrol->private_value;
317 struct elliptic_system_configuration_parameter param;
318 uint32_t param_id = ELLIPTIC_ULTRASOUND_SET_PARAMS;
320 if (mc->reg != ELLIPTIC_CALIBRATION)
324 case ELLIPTIC_CALIBRATION_STATE:
325 elliptic_system_configuration_cache.calibration_state =
326 ucontrol->value.integer.value[0];
328 param.type = ESCPT_CALIBRATION_STATE;
329 param.calibration_state =
330 elliptic_system_configuration_cache.calibration_state;
333 case ELLIPTIC_CALIBRATION_PROFILE:
334 elliptic_system_configuration_cache.calibration_profile =
335 ucontrol->value.integer.value[0];
337 param.type = ESCPT_CALIBRATION_PROFILE;
338 param.calibration_profile =
339 elliptic_system_configuration_cache.calibration_profile;
342 case ELLIPTIC_ULTRASOUND_GAIN:
343 elliptic_system_configuration_cache.ultrasound_gain =
344 ucontrol->value.integer.value[0];
345 param.type = ESCPT_ULTRASOUND_GAIN;
346 param.ultrasound_gain =
347 elliptic_system_configuration_cache.ultrasound_gain;
354 return ultrasound_apr_set(ELLIPTIC_PORT_ID, ¶m_id,
355 (u8 *)¶m, sizeof(param));
358 int elliptic_system_configuration_param_get(
359 struct snd_kcontrol *kcontrol,
360 struct snd_ctl_elem_value *ucontrol)
362 struct soc_mixer_control *mc =
363 (struct soc_mixer_control *)kcontrol->private_value;
365 pr_err("%s: reg: %d shift: %d\n", __func__, mc->reg, mc->shift);
367 if (mc->reg != ELLIPTIC_SYSTEM_CONFIGURATION)
371 case ELLIPTIC_SYSTEM_CONFIGURATION_LATENCY:
372 ucontrol->value.integer.value[0] =
373 elliptic_system_configuration_cache.latency;
376 case ELLIPTIC_SYSTEM_CONFIGURATION_SENSITIVITY:
377 ucontrol->value.integer.value[0] =
378 elliptic_system_configuration_cache.sensitivity;
381 case ELLIPTIC_SYSTEM_CONFIGURATION_SPEAKER_SCALING:
382 ucontrol->value.integer.value[0] =
383 elliptic_system_configuration_cache.speaker_scaling[0];
384 ucontrol->value.integer.value[1] =
385 elliptic_system_configuration_cache.speaker_scaling[1];
388 case ELLIPTIC_SYSTEM_CONFIGURATION_MICROPHONE_INDEX:
389 ucontrol->value.integer.value[0] =
390 elliptic_system_configuration_cache.microphone_index;
393 case ELLIPTIC_SYSTEM_CONFIGURATION_OPERATION_MODE:
394 ucontrol->value.integer.value[0] =
395 elliptic_system_configuration_cache.operation_mode;
398 case ELLIPTIC_SYSTEM_CONFIGURATION_OPERATION_MODE_FLAGS:
399 ucontrol->value.integer.value[0] =
400 elliptic_system_configuration_cache.operation_mode_flags;
403 case ELLIPTIC_SYSTEM_CONFIGURATION_LOG_LEVEL:
404 ucontrol->value.integer.value[0] =
405 elliptic_system_configuration_cache.log_level;
417 int elliptic_system_configuration_param_put(
418 struct snd_kcontrol *kcontrol,
419 struct snd_ctl_elem_value *ucontrol)
421 struct soc_mixer_control *mc =
422 (struct soc_mixer_control *)kcontrol->private_value;
423 struct elliptic_system_configuration_parameter param;
424 uint32_t param_id = ELLIPTIC_ULTRASOUND_SET_PARAMS;
426 if (mc->reg != ELLIPTIC_SYSTEM_CONFIGURATION)
430 case ELLIPTIC_SYSTEM_CONFIGURATION_LATENCY:
431 elliptic_system_configuration_cache.latency =
432 ucontrol->value.integer.value[0];
433 param.type = ESCPT_LATENCY;
434 param.latency = elliptic_system_configuration_cache.latency;
437 case ELLIPTIC_SYSTEM_CONFIGURATION_SENSITIVITY:
438 elliptic_system_configuration_cache.sensitivity =
439 ucontrol->value.integer.value[0];
440 param.type = ESCPT_CHANNEL_SENSITIVITY;
442 elliptic_system_configuration_cache.sensitivity;
445 case ELLIPTIC_SYSTEM_CONFIGURATION_SPEAKER_SCALING:
446 elliptic_system_configuration_cache.speaker_scaling[0] =
447 ucontrol->value.integer.value[0];
448 elliptic_system_configuration_cache.speaker_scaling[1] =
449 ucontrol->value.integer.value[1];
450 param.type = ESCPT_SPEAKER_SCALING;
451 param.speaker_scaling[0] =
452 elliptic_system_configuration_cache.speaker_scaling[0];
453 param.speaker_scaling[1] =
454 elliptic_system_configuration_cache.speaker_scaling[1];
457 case ELLIPTIC_SYSTEM_CONFIGURATION_MICROPHONE_INDEX:
458 elliptic_system_configuration_cache.microphone_index =
459 ucontrol->value.integer.value[0];
460 param.type = ESCPT_MICROPHONE_INDEX;
461 param.microphone_index =
462 elliptic_system_configuration_cache.microphone_index;
465 case ELLIPTIC_SYSTEM_CONFIGURATION_OPERATION_MODE:
466 elliptic_system_configuration_cache.operation_mode =
467 ucontrol->value.integer.value[0];
468 param.type = ESCPT_OPERATION_MODE;
469 param.operation_mode =
470 elliptic_system_configuration_cache.operation_mode;
473 case ELLIPTIC_SYSTEM_CONFIGURATION_OPERATION_MODE_FLAGS:
474 elliptic_system_configuration_cache.operation_mode_flags =
475 ucontrol->value.integer.value[0];
476 param.type = ESCPT_OPERATION_MODE_FLAGS;
477 param.operation_mode_flags =
478 elliptic_system_configuration_cache.operation_mode_flags;
481 case ELLIPTIC_SYSTEM_CONFIGURATION_LOG_LEVEL:
482 elliptic_system_configuration_cache.log_level =
483 ucontrol->value.integer.value[0];
484 param.type = ESCPT_LOG_LEVEL;
486 elliptic_system_configuration_cache.log_level;
493 return ultrasound_apr_set(ELLIPTIC_PORT_ID, ¶m_id,
494 (u8 *)¶m, sizeof(param));
498 static const struct snd_kcontrol_new ultrasound_filter_mixer_controls[] = {
499 SOC_ENUM_EXT("Ultrasound Enable",
501 msm_routing_get_ultrasound_enable,
502 msm_routing_set_ultrasound_enable),
503 SOC_ENUM_EXT("Ultrasound RampDown",
505 msm_routing_get_ultrasound_rampdown,
506 msm_routing_set_ultrasound_rampdown),
507 SOC_SINGLE_EXT("Ultrasound Latency",
508 ELLIPTIC_SYSTEM_CONFIGURATION,
509 ELLIPTIC_SYSTEM_CONFIGURATION_LATENCY,
512 elliptic_system_configuration_param_get,
513 elliptic_system_configuration_param_put),
514 SOC_SINGLE_EXT("Ultrasound Sensitivity",
515 ELLIPTIC_SYSTEM_CONFIGURATION,
516 ELLIPTIC_SYSTEM_CONFIGURATION_SENSITIVITY,
519 elliptic_system_configuration_param_get,
520 elliptic_system_configuration_param_put),
521 SOC_DOUBLE_EXT("Ultrasound Speaker Scaling",
522 ELLIPTIC_SYSTEM_CONFIGURATION,
523 ELLIPTIC_SYSTEM_CONFIGURATION_SPEAKER_SCALING,
527 elliptic_system_configuration_param_get,
528 elliptic_system_configuration_param_put),
529 SOC_SINGLE_EXT("Ultrasound Microphone Index",
530 ELLIPTIC_SYSTEM_CONFIGURATION,
531 ELLIPTIC_SYSTEM_CONFIGURATION_MICROPHONE_INDEX,
534 elliptic_system_configuration_param_get,
535 elliptic_system_configuration_param_put),
536 SOC_SINGLE_EXT("Ultrasound Mode",
537 ELLIPTIC_SYSTEM_CONFIGURATION,
538 ELLIPTIC_SYSTEM_CONFIGURATION_OPERATION_MODE,
541 elliptic_system_configuration_param_get,
542 elliptic_system_configuration_param_put),
543 SOC_SINGLE_EXT("Ultrasound Mode Flags",
544 ELLIPTIC_SYSTEM_CONFIGURATION,
545 ELLIPTIC_SYSTEM_CONFIGURATION_OPERATION_MODE_FLAGS,
548 elliptic_system_configuration_param_get,
549 elliptic_system_configuration_param_put),
550 SOC_SINGLE_EXT("Ultrasound Calibration Profile",
551 ELLIPTIC_CALIBRATION,
552 ELLIPTIC_CALIBRATION_PROFILE,
555 elliptic_calibration_param_get,
556 elliptic_calibration_param_put),
557 SOC_SINGLE_EXT("Ultrasound Gain",
558 ELLIPTIC_CALIBRATION,
559 ELLIPTIC_ULTRASOUND_GAIN,
562 elliptic_calibration_param_get,
563 elliptic_calibration_param_put),
564 SOC_SINGLE_EXT("Ultrasound Calibration State",
565 ELLIPTIC_CALIBRATION,
566 ELLIPTIC_CALIBRATION_STATE,
569 elliptic_calibration_param_get,
570 elliptic_calibration_param_put),
571 SND_SOC_BYTES_EXT("Ultrasound System Configuration",
572 ELLIPTIC_SYSTEM_CONFIGURATION_SIZE,
573 elliptic_system_configuration_get,
574 elliptic_system_configuration_put),
575 SND_SOC_BYTES_EXT("Ultrasound Calibration Data",
576 ELLIPTIC_CALIBRATION_DATA_SIZE,
577 elliptic_calibration_data_get,
578 elliptic_calibration_data_put),
579 SND_SOC_BYTES_EXT("Ultrasound Version",
580 ELLIPTIC_VERSION_INFO_SIZE,
581 elliptic_version_data_get,
582 elliptic_version_data_put),
583 SND_SOC_BYTES_EXT("Ultrasound Branch",
584 ELLIPTIC_BRANCH_INFO_SIZE,
585 elliptic_branch_data_get,
586 elliptic_branch_data_put),
587 SOC_SINGLE_EXT("Ultrasound Log Level",
588 ELLIPTIC_SYSTEM_CONFIGURATION,
589 ELLIPTIC_SYSTEM_CONFIGURATION_LOG_LEVEL,
592 elliptic_system_configuration_param_get,
593 elliptic_system_configuration_param_put),
598 unsigned int elliptic_add_platform_controls(void *platform)
600 const unsigned int num_controls =
601 ARRAY_SIZE(ultrasound_filter_mixer_controls);
603 if (platform != NULL) {
604 snd_soc_add_platform_controls(
605 (struct snd_soc_platform *)platform,
606 ultrasound_filter_mixer_controls,
609 pr_debug("[ELUS]: pointer is NULL %s\n", __func__);