summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTzung-Bi Shih <tzungbi@chromium.org>2019-04-13 20:49:26 +0800
committerCommit Bot <commit-bot@chromium.org>2019-09-17 14:57:00 +0000
commit4e9246ab4f7a2c512bd9b9e08860091d91cb3b6f (patch)
tree2596cc39876a6f383b8c8b1da5ab5a66e36c064c
parent6a159855aae92c3d98a4927babb4a8319d644c1e (diff)
downloadchrome-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.c119
-rw-r--r--common/build.mk1
-rw-r--r--include/audio_codec.h61
-rw-r--r--include/config.h2
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