diff options
author | Tzung-Bi Shih <tzungbi@chromium.org> | 2019-04-13 20:49:26 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-09-17 14:57:00 +0000 |
commit | 4e9246ab4f7a2c512bd9b9e08860091d91cb3b6f (patch) | |
tree | 2596cc39876a6f383b8c8b1da5ab5a66e36c064c | |
parent | 6a159855aae92c3d98a4927babb4a8319d644c1e (diff) | |
download | chrome-ec-4e9246ab4f7a2c512bd9b9e08860091d91cb3b6f.tar.gz |
audio_codec: add I2S RX abstract layer
Common I2S RX host commands:
- set_sample_depth
- set_daifmt
- set_bclk
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. define CONFIG_AUDIO_CODEC_DMIC_SOFTWARE_GAIN in board.h
4. define CONFIG_AUDIO_CODEC_DMIC_MAX_SOFTWARE_GAIN in board.h
5. define CONFIG_AUDIO_CODEC_I2S_RX in board.h
6. make BOARD=kukui_scp -j
Change-Id: I9031bad5429f51ab9f911098f38ed7eb0fa59d18
Signed-off-by: Tzung-Bi Shih <tzungbi@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1564503
Commit-Queue: Sean Abraham <seanabraham@chromium.org>
Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
-rw-r--r-- | common/audio_codec_i2s_rx.c | 119 | ||||
-rw-r--r-- | common/build.mk | 1 | ||||
-rw-r--r-- | include/audio_codec.h | 61 | ||||
-rw-r--r-- | include/config.h | 2 |
4 files changed, 183 insertions, 0 deletions
diff --git a/common/audio_codec_i2s_rx.c b/common/audio_codec_i2s_rx.c new file mode 100644 index 0000000000..301612b086 --- /dev/null +++ b/common/audio_codec_i2s_rx.c @@ -0,0 +1,119 @@ +/* + * 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 uint8_t i2s_rx_enabled; + +static int i2s_rx_enable(struct host_cmd_handler_args *args) +{ + if (i2s_rx_enabled) + return EC_RES_BUSY; + + if (audio_codec_i2s_rx_enable() != EC_SUCCESS) + return EC_RES_ERROR; + + i2s_rx_enabled = 1; + + return EC_RES_SUCCESS; +} + +static int i2s_rx_disable(struct host_cmd_handler_args *args) +{ + if (!i2s_rx_enabled) + return EC_RES_BUSY; + + if (audio_codec_i2s_rx_disable() != EC_SUCCESS) + return EC_RES_ERROR; + + i2s_rx_enabled = 0; + + return EC_RES_SUCCESS; +} + +static int i2s_rx_set_sample_depth(struct host_cmd_handler_args *args) +{ + const struct ec_param_ec_codec_i2s_rx *p = args->params; + const uint8_t depth = p->set_sample_depth_param.depth; + + if (i2s_rx_enabled) + return EC_RES_BUSY; + if (depth >= EC_CODEC_I2S_RX_SAMPLE_DEPTH_COUNT) + return EC_RES_INVALID_PARAM; + + if (audio_codec_i2s_rx_set_sample_depth(depth) != EC_SUCCESS) + return EC_RES_ERROR; + + return EC_RES_SUCCESS; +} + +static int i2s_rx_set_daifmt(struct host_cmd_handler_args *args) +{ + const struct ec_param_ec_codec_i2s_rx *p = args->params; + const uint8_t daifmt = p->set_daifmt_param.daifmt; + + if (i2s_rx_enabled) + return EC_RES_BUSY; + if (daifmt >= EC_CODEC_I2S_RX_DAIFMT_COUNT) + return EC_RES_INVALID_PARAM; + + if (audio_codec_i2s_rx_set_daifmt(daifmt) != EC_SUCCESS) + return EC_RES_ERROR; + + return EC_RES_SUCCESS; +} + +static int i2s_rx_set_bclk(struct host_cmd_handler_args *args) +{ + const struct ec_param_ec_codec_i2s_rx *p = args->params; + + if (i2s_rx_enabled) + return EC_RES_BUSY; + + if (audio_codec_i2s_rx_set_bclk(p->set_bclk_param.bclk) != EC_SUCCESS) + return EC_RES_ERROR; + + return EC_RES_SUCCESS; +} + +static int (*sub_cmds[])(struct host_cmd_handler_args *) = { + [EC_CODEC_I2S_RX_ENABLE] = i2s_rx_enable, + [EC_CODEC_I2S_RX_DISABLE] = i2s_rx_disable, + [EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH] = i2s_rx_set_sample_depth, + [EC_CODEC_I2S_RX_SET_DAIFMT] = i2s_rx_set_daifmt, + [EC_CODEC_I2S_RX_SET_BCLK] = i2s_rx_set_bclk, +}; + +#ifdef DEBUG_AUDIO_CODEC +static char *strcmd[] = { + [EC_CODEC_I2S_RX_ENABLE] = "EC_CODEC_I2S_RX_ENABLE", + [EC_CODEC_I2S_RX_DISABLE] = "EC_CODEC_I2S_RX_DISABLE", + [EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH] = "EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH", + [EC_CODEC_I2S_RX_SET_DAIFMT] = "EC_CODEC_I2S_RX_SET_DAIFMT", + [EC_CODEC_I2S_RX_SET_BCLK] = "EC_CODEC_I2S_RX_SET_BCLK", +}; +BUILD_ASSERT(ARRAY_SIZE(sub_cmds) == ARRAY_SIZE(strcmd)); +#endif + +static int i2s_rx_host_command(struct host_cmd_handler_args *args) +{ + const struct ec_param_ec_codec_i2s_rx *p = args->params; + +#ifdef DEBUG_AUDIO_CODEC + CPRINTS("I2S RX subcommand: %s", strcmd[p->cmd]); +#endif + + if (p->cmd < EC_CODEC_I2S_RX_SUBCMD_COUNT) + return sub_cmds[p->cmd](args); + + return EC_RES_INVALID_PARAM; +} +DECLARE_HOST_COMMAND(EC_CMD_EC_CODEC_I2S_RX, + i2s_rx_host_command, EC_VER_MASK(0)); diff --git a/common/build.mk b/common/build.mk index 8398434b47..693d3f236c 100644 --- a/common/build.mk +++ b/common/build.mk @@ -31,6 +31,7 @@ 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_AUDIO_CODEC_I2S_RX)+=audio_codec_i2s_rx.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 29a61ed817..af64deb16d 100644 --- a/include/audio_codec.h +++ b/include/audio_codec.h @@ -115,4 +115,65 @@ int audio_codec_dmic_set_gain_idx(uint8_t channel, uint8_t gain); */ int audio_codec_dmic_get_gain_idx(uint8_t channel, uint8_t *gain); + +/* + * I2S RX abstract layer + */ + +/* + * Enables I2S RX. + * + * Returns: + * EC_SUCCESS if success. + * EC_ERROR_UNKNOWN if internal error. + * EC_ERROR_BUSY if has enabled. + */ +int audio_codec_i2s_rx_enable(void); + +/* + * Disables I2S RX. + * + * Returns: + * EC_SUCCESS if success. + * EC_ERROR_UNKNOWN if internal error. + * EC_ERROR_BUSY if has not enabled. + */ +int audio_codec_i2s_rx_disable(void); + +/* + * Sets I2S RX sample depth. + * + * @depth is an integer from enum ec_codec_i2s_rx_sample_depth. + * + * Returns: + * EC_SUCCESS if success. + * EC_ERROR_UNKNOWN if internal error. + * EC_ERROR_INVAL if depth does not look good. + */ +int audio_codec_i2s_rx_set_sample_depth(uint8_t depth); + +/* + * Sets I2S RX DAI format. + * + * @daifmt is an integer from enum ec_codec_i2s_rx_daifmt. + * + * Returns: + * EC_SUCCESS if success. + * EC_ERROR_UNKNOWN if internal error. + * EC_ERROR_INVAL if daifmt does not look good. + */ +int audio_codec_i2s_rx_set_daifmt(uint8_t daifmt); + +/* + * Sets I2S RX BCLK. + * + * @bclk is an integer to represent the bit clock rate. + * + * Returns: + * EC_SUCCESS if success. + * EC_ERROR_UNKNOWN if internal error. + * EC_ERROR_INVAL if bclk does not look good. + */ +int audio_codec_i2s_rx_set_bclk(uint32_t bclk); + #endif diff --git a/include/config.h b/include/config.h index 207410cc92..bc19b6eb17 100644 --- a/include/config.h +++ b/include/config.h @@ -357,6 +357,8 @@ /* Support audio codec software gain on DMIC. */ #undef CONFIG_AUDIO_CODEC_DMIC_SOFTWARE_GAIN #undef CONFIG_AUDIO_CODEC_DMIC_MAX_SOFTWARE_GAIN +/* Support audio codec on I2S RX. */ +#undef CONFIG_AUDIO_CODEC_I2S_RX /* Allow proprietary communication protocols' extensions. */ #undef CONFIG_EXTENSION_COMMAND |