Initial Contribution
msm-2.6.38: tag AU_LINUX_ANDROID_GINGERBREAD.02.03.04.00.142
Signed-off-by: Bryan Huntsman <bryanh@codeaurora.org>
diff --git a/drivers/mfd/msm-adie-codec.c b/drivers/mfd/msm-adie-codec.c
new file mode 100644
index 0000000..d9414ed
--- /dev/null
+++ b/drivers/mfd/msm-adie-codec.c
@@ -0,0 +1,196 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/msm-adie-codec.h>
+#include <linux/mfd/marimba.h>
+
+static const struct adie_codec_operations *cur_adie_ops;
+
+int adie_codec_register_codec_operations(
+ const struct adie_codec_operations *adie_ops)
+{
+ if (adie_ops == NULL)
+ return -EINVAL;
+
+ if (adie_ops->codec_id != adie_get_detected_codec_type())
+ return -EINVAL;
+
+ cur_adie_ops = adie_ops;
+ pr_info("%s: codec type %d\n", __func__, adie_ops->codec_id);
+ return 0;
+}
+
+int adie_codec_open(struct adie_codec_dev_profile *profile,
+ struct adie_codec_path **path_pptr)
+{
+ int rc = -EPERM;
+
+ if (cur_adie_ops != NULL) {
+ if (cur_adie_ops->codec_open != NULL)
+ rc = cur_adie_ops->codec_open(profile, path_pptr);
+ } else
+ rc = -ENODEV;
+
+ return rc;
+}
+EXPORT_SYMBOL(adie_codec_open);
+
+int adie_codec_close(struct adie_codec_path *path_ptr)
+{
+ int rc = -EPERM;
+
+ if (cur_adie_ops != NULL) {
+ if (cur_adie_ops->codec_close != NULL)
+ rc = cur_adie_ops->codec_close(path_ptr);
+ } else
+ rc = -ENODEV;
+
+ return rc;
+}
+EXPORT_SYMBOL(adie_codec_close);
+
+int adie_codec_set_device_digital_volume(struct adie_codec_path *path_ptr,
+ u32 num_channels, u32 vol_percentage /* in percentage */)
+{
+ int rc = -EPERM;
+
+ if (cur_adie_ops != NULL) {
+ if (cur_adie_ops->codec_set_device_digital_volume != NULL) {
+ rc = cur_adie_ops->codec_set_device_digital_volume(
+ path_ptr,
+ num_channels,
+ vol_percentage);
+ }
+ } else
+ rc = -ENODEV;
+
+ return rc;
+}
+EXPORT_SYMBOL(adie_codec_set_device_digital_volume);
+
+int adie_codec_set_device_analog_volume(struct adie_codec_path *path_ptr,
+ u32 num_channels, u32 volume /* in percentage */)
+{
+ int rc = -EPERM;
+
+ if (cur_adie_ops != NULL) {
+ if (cur_adie_ops->codec_set_device_analog_volume != NULL) {
+ rc = cur_adie_ops->codec_set_device_analog_volume(
+ path_ptr,
+ num_channels,
+ volume);
+ }
+ } else
+ rc = -ENODEV;
+
+ return rc;
+}
+EXPORT_SYMBOL(adie_codec_set_device_analog_volume);
+
+int adie_codec_setpath(struct adie_codec_path *path_ptr, u32 freq_plan, u32 osr)
+{
+ int rc = -EPERM;
+
+ if (cur_adie_ops != NULL) {
+ if (cur_adie_ops->codec_setpath != NULL) {
+ rc = cur_adie_ops->codec_setpath(path_ptr,
+ freq_plan,
+ osr);
+ }
+ } else
+ rc = -ENODEV;
+
+ return rc;
+}
+EXPORT_SYMBOL(adie_codec_setpath);
+
+u32 adie_codec_freq_supported(struct adie_codec_dev_profile *profile,
+ u32 requested_freq)
+{
+ int rc = -EPERM;
+
+ if (cur_adie_ops != NULL) {
+ if (cur_adie_ops->codec_freq_supported != NULL)
+ rc = cur_adie_ops->codec_freq_supported(profile,
+ requested_freq);
+ } else
+ rc = -ENODEV;
+
+ return rc;
+}
+EXPORT_SYMBOL(adie_codec_freq_supported);
+
+int adie_codec_enable_sidetone(struct adie_codec_path *rx_path_ptr,
+ u32 enable)
+{
+ int rc = -EPERM;
+
+ if (cur_adie_ops != NULL) {
+ if (cur_adie_ops->codec_enable_sidetone != NULL)
+ rc = cur_adie_ops->codec_enable_sidetone(rx_path_ptr,
+ enable);
+ } else
+ rc = -ENODEV;
+
+ return rc;
+}
+EXPORT_SYMBOL(adie_codec_enable_sidetone);
+
+int adie_codec_enable_anc(struct adie_codec_path *rx_path_ptr,
+ u32 enable, struct adie_codec_anc_data *calibration_writes)
+{
+ int rc = -EPERM;
+
+ if (cur_adie_ops != NULL) {
+ if (cur_adie_ops->codec_enable_anc != NULL)
+ rc = cur_adie_ops->codec_enable_anc(rx_path_ptr,
+ enable, calibration_writes);
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL(adie_codec_enable_anc);
+
+int adie_codec_proceed_stage(struct adie_codec_path *path_ptr, u32 state)
+{
+ int rc = -EPERM;
+
+ if (cur_adie_ops != NULL) {
+ if (cur_adie_ops->codec_proceed_stage != NULL)
+ rc = cur_adie_ops->codec_proceed_stage(path_ptr,
+ state);
+ } else
+ rc = -ENODEV;
+
+ return rc;
+}
+EXPORT_SYMBOL(adie_codec_proceed_stage);
+
+int adie_codec_set_master_mode(struct adie_codec_path *path_ptr, u8 master)
+{
+ int rc = -EPERM;
+
+ if (cur_adie_ops != NULL) {
+ if (cur_adie_ops->codec_set_master_mode != NULL)
+ rc = cur_adie_ops->codec_set_master_mode(path_ptr,
+ master);
+ } else
+ rc = -ENODEV;
+
+ return rc;
+}
+EXPORT_SYMBOL(adie_codec_set_master_mode);
+
+