diff options
author | Tzung-Bi Shih <tzungbi@chromium.org> | 2019-05-17 11:22:53 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-09-17 14:56:58 +0000 |
commit | 0ba3ba3049226e92d6cf64ed06031ec9a3bb7949 (patch) | |
tree | b4f3aff83258c93042ad2b3a02bda7f2f50e3af3 | |
parent | bb5d21d349efbc12fa5596a811a241508621e64d (diff) | |
download | chrome-ec-0ba3ba3049226e92d6cf64ed06031ec9a3bb7949.tar.gz |
audio_codec: add DMIC abstract layer
Common DMIC host commands:
- get_max_gain
- get_gain_idx
- set_gain_idx
BRANCH=none
BUG=b:122027734, b:123268236
TEST=1. define CONFIG_AUDIO_CODEC in board.h
2. define CONFIG_AUDIO_CODEC_DMIC in board.h
3. make BOARD=kukui_scp -j
Change-Id: I7b4cc11645675f9d790947b17c3ea385dae13483
Signed-off-by: Tzung-Bi Shih <tzungbi@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1564502
Commit-Queue: Sean Abraham <seanabraham@chromium.org>
Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
-rw-r--r-- | common/audio_codec_dmic.c | 77 | ||||
-rw-r--r-- | common/build.mk | 1 | ||||
-rw-r--r-- | include/audio_codec.h | 57 | ||||
-rw-r--r-- | include/config.h | 2 | ||||
-rw-r--r-- | include/ec_commands.h | 43 |
5 files changed, 170 insertions, 10 deletions
diff --git a/common/audio_codec_dmic.c b/common/audio_codec_dmic.c new file mode 100644 index 0000000000..461b8508e9 --- /dev/null +++ b/common/audio_codec_dmic.c @@ -0,0 +1,77 @@ +/* + * Copyright 2019 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "audio_codec.h" +#include "console.h" +#include "host_command.h" + +#define CPRINTS(format, args...) cprints(CC_AUDIO_CODEC, format, ## args) + +static int dmic_get_max_gain(struct host_cmd_handler_args *args) +{ + struct ec_response_ec_codec_dmic_get_max_gain *r = args->response; + + if (audio_codec_dmic_get_max_gain(&r->max_gain) != EC_SUCCESS) + return EC_RES_ERROR; + + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; +} + +static int dmic_set_gain_idx(struct host_cmd_handler_args *args) +{ + const struct ec_param_ec_codec_dmic *p = args->params; + + if (audio_codec_dmic_set_gain_idx( + p->set_gain_idx_param.channel, + p->set_gain_idx_param.gain) != EC_SUCCESS) + return EC_RES_ERROR; + + return EC_RES_SUCCESS; +} + +static int dmic_get_gain_idx(struct host_cmd_handler_args *args) +{ + const struct ec_param_ec_codec_dmic *p = args->params; + struct ec_response_ec_codec_dmic_get_gain_idx *r = args->response; + + if (audio_codec_dmic_get_gain_idx( + p->get_gain_idx_param.channel, &r->gain) != EC_SUCCESS) + return EC_RES_ERROR; + + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; +} + +static int (*sub_cmds[])(struct host_cmd_handler_args *) = { + [EC_CODEC_DMIC_GET_MAX_GAIN] = dmic_get_max_gain, + [EC_CODEC_DMIC_SET_GAIN_IDX] = dmic_set_gain_idx, + [EC_CODEC_DMIC_GET_GAIN_IDX] = dmic_get_gain_idx, +}; + +#ifdef DEBUG_AUDIO_CODEC +static char *strcmd[] = { + [EC_CODEC_DMIC_GET_MAX_GAIN] = "EC_CODEC_DMIC_GET_MAX_GAIN", + [EC_CODEC_DMIC_SET_GAIN_IDX] = "EC_CODEC_DMIC_SET_GAIN_IDX", + [EC_CODEC_DMIC_GET_GAIN_IDX] = "EC_CODEC_DMIC_GET_GAIN_IDX", +}; +BUILD_ASSERT(ARRAY_SIZE(sub_cmds) == ARRAY_SIZE(strcmd)); +#endif + +static int dmic_host_command(struct host_cmd_handler_args *args) +{ + const struct ec_param_ec_codec_dmic *p = args->params; + +#ifdef DEBUG_AUDIO_CODEC + CPRINTS("DMIC subcommand: %s", strcmd[p->cmd]); +#endif + + if (p->cmd < EC_CODEC_DMIC_SUBCMD_COUNT) + return sub_cmds[p->cmd](args); + + return EC_RES_INVALID_PARAM; +} +DECLARE_HOST_COMMAND(EC_CMD_EC_CODEC_DMIC, dmic_host_command, EC_VER_MASK(0)); diff --git a/common/build.mk b/common/build.mk index 213db0a0fc..8398434b47 100644 --- a/common/build.mk +++ b/common/build.mk @@ -30,6 +30,7 @@ common-$(CONFIG_CMD_ADC)+=adc.o common-$(HAS_TASK_ALS)+=als.o common-$(CONFIG_AP_HANG_DETECT)+=ap_hang_detect.o common-$(CONFIG_AUDIO_CODEC)+=audio_codec.o +common-$(CONFIG_AUDIO_CODEC_DMIC)+=audio_codec_dmic.o common-$(CONFIG_BACKLIGHT_LID)+=backlight_lid.o common-$(CONFIG_BASE32)+=base32.o common-$(CONFIG_DETACHABLE_BASE)+=base_state.o diff --git a/include/audio_codec.h b/include/audio_codec.h index ab1c65ae61..29a61ed817 100644 --- a/include/audio_codec.h +++ b/include/audio_codec.h @@ -58,4 +58,61 @@ int audio_codec_register_shm(uint8_t shm_id, uint8_t cap, */ int audio_codec_memmap_ap_to_ec(uintptr_t ap_addr, uintptr_t *ec_addr); + +/* + * DMIC abstract layer + */ + +/* + * Gets the maximum possible gain value. All channels share the same maximum + * gain value [0, max]. + * + * The gain has no unit and should fit in a scale to represent relative dB. + * + * For example, suppose maximum possible gain value is 4, one could define a + * mapping: + * - 0 => -10 dB + * - 1 => -5 dB + * - 2 => 0 dB + * - 3 => 5 dB + * - 4 => 10 dB + * + * @max_gain is the destination address to put the gain value. + * + * Returns: + * EC_SUCCESS if success. + * EC_ERROR_UNKNOWN if internal error. + */ +int audio_codec_dmic_get_max_gain(uint8_t *max_gain); + +/* + * Sets the microphone gain for the specified channel. + * + * @channel is an integer from enum ec_codec_dmic_channel. The valid range + * is [0, 7]. + * @gain is the target gain for the specified channel. The valid range + * is [0, max_gain]. See also audio_codec_dmic_get_max_gain. + * + * Returns: + * EC_SUCCESS if success. + * EC_ERROR_UNKNOWN if internal error. + * EC_ERROR_INVAL if channel does not look good. + * EC_ERROR_INVAL if gain does not look good. + */ +int audio_codec_dmic_set_gain_idx(uint8_t channel, uint8_t gain); + +/* + * Gets the microphone gain of the specified channel. + * + * @channel is an integer from enum ec_codec_dmic_channel. The valid range + * is [0, 7]. + * @gain is the destination address to put the gain value of the channel. + * + * Returns: + * EC_SUCCESS if success. + * EC_ERROR_UNKNOWN if internal error. + * EC_ERROR_INVAL if channel does not look good. + */ +int audio_codec_dmic_get_gain_idx(uint8_t channel, uint8_t *gain); + #endif diff --git a/include/config.h b/include/config.h index b09f26555b..b39196140a 100644 --- a/include/config.h +++ b/include/config.h @@ -352,6 +352,8 @@ /* Support audio codec. */ #undef CONFIG_AUDIO_CODEC +/* Support audio codec on DMIC. */ +#undef CONFIG_AUDIO_CODEC_DMIC /* Allow proprietary communication protocols' extensions. */ #undef CONFIG_EXTENSION_COMMAND diff --git a/include/ec_commands.h b/include/ec_commands.h index 057c3411f4..e553ecdfa9 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -4723,30 +4723,53 @@ struct __ec_align4 ec_response_ec_codec_get_shm_addr { #define EC_CMD_EC_CODEC_DMIC 0x00BD enum ec_codec_dmic_subcmd { - EC_CODEC_DMIC_SET_GAIN = 0x0, - EC_CODEC_DMIC_GET_GAIN = 0x1, + EC_CODEC_DMIC_GET_MAX_GAIN = 0x0, + EC_CODEC_DMIC_SET_GAIN_IDX = 0x1, + EC_CODEC_DMIC_GET_GAIN_IDX = 0x2, EC_CODEC_DMIC_SUBCMD_COUNT, }; -struct __ec_align1 ec_param_ec_codec_dmic_set_gain { - uint8_t left; - uint8_t right; +enum ec_codec_dmic_channel { + EC_CODEC_DMIC_CHANNEL_0 = 0x0, + EC_CODEC_DMIC_CHANNEL_1 = 0x1, + EC_CODEC_DMIC_CHANNEL_2 = 0x2, + EC_CODEC_DMIC_CHANNEL_3 = 0x3, + EC_CODEC_DMIC_CHANNEL_4 = 0x4, + EC_CODEC_DMIC_CHANNEL_5 = 0x5, + EC_CODEC_DMIC_CHANNEL_6 = 0x6, + EC_CODEC_DMIC_CHANNEL_7 = 0x7, + EC_CODEC_DMIC_CHANNEL_COUNT, +}; + +struct __ec_align1 ec_param_ec_codec_dmic_set_gain_idx { + uint8_t channel; /* enum ec_codec_dmic_channel */ + uint8_t gain; uint8_t reserved[2]; }; +struct __ec_align1 ec_param_ec_codec_dmic_get_gain_idx { + uint8_t channel; /* enum ec_codec_dmic_channel */ + uint8_t reserved[3]; +}; + struct __ec_align4 ec_param_ec_codec_dmic { uint8_t cmd; /* enum ec_codec_dmic_subcmd */ uint8_t reserved[3]; union { - struct ec_param_ec_codec_dmic_set_gain - set_gain_param; + struct ec_param_ec_codec_dmic_set_gain_idx + set_gain_idx_param; + struct ec_param_ec_codec_dmic_get_gain_idx + get_gain_idx_param; }; }; -struct __ec_align1 ec_response_ec_codec_dmic_get_gain { - uint8_t left; - uint8_t right; +struct __ec_align1 ec_response_ec_codec_dmic_get_max_gain { + uint8_t max_gain; +}; + +struct __ec_align1 ec_response_ec_codec_dmic_get_gain_idx { + uint8_t gain; }; /*****************************************************************************/ |