summaryrefslogtreecommitdiff
path: root/tfa9890
diff options
context:
space:
mode:
Diffstat (limited to 'tfa9890')
-rw-r--r--tfa9890/Android.mk19
-rw-r--r--tfa9890/tfa9890.c157
-rw-r--r--tfa9890/tfa9890.h91
-rw-r--r--tfa9890/tfa9890_amp.c21
4 files changed, 288 insertions, 0 deletions
diff --git a/tfa9890/Android.mk b/tfa9890/Android.mk
new file mode 100644
index 0000000..a4523e8
--- /dev/null
+++ b/tfa9890/Android.mk
@@ -0,0 +1,19 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog libutils libcutils
+
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+
+LOCAL_SRC_FILES := \
+ tfa9890.c \
+ tfa9890_amp.c
+
+LOCAL_MODULE := tfa9890_amp
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_EXECUTABLE)
diff --git a/tfa9890/tfa9890.c b/tfa9890/tfa9890.c
new file mode 100644
index 0000000..0220829
--- /dev/null
+++ b/tfa9890/tfa9890.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2013-2014, The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "tfa9890"
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <cutils/log.h>
+#include <cutils/misc.h>
+#include <sys/ioctl.h>
+#include <system/audio.h>
+
+#include "tfa9890.h"
+#include "tfa9890_eq.h"
+
+struct tfa98xx_param_data tfa9890_param_data = {
+ .size = 0,
+ .type = 0,
+ .data = NULL
+};
+
+/* Module functions */
+
+int tfa9890_prepare_for_ioctl(const char *file_name, unsigned int type) {
+ int ret = 0;
+ unsigned int size;
+ unsigned char *buf;
+
+ ALOGV("Preparing %s", file_name);
+
+ /* Reset values */
+ tfa9890_param_data.size = 0;
+ tfa9890_param_data.type = 0;
+ free(tfa9890_param_data.data);
+
+ buf = (unsigned char*) load_file(file_name, &size);
+
+ if (buf == NULL) {
+ ret = -1;
+ return ret;
+ } else {
+ ret = size;
+ }
+
+ /* Set the data for the ioctl arg */
+ if (size)
+ tfa9890_param_data.size = size;
+ if (type)
+ tfa9890_param_data.type = type;
+ /* Already checked above */
+ tfa9890_param_data.data = buf;
+
+ return ret;
+}
+
+int tfa9890_prepare_for_ioctl_eq(const char *file_name, unsigned int type) {
+ unsigned int size;
+ unsigned char buf[PARAM_SIZE_MAX];
+
+ ALOGV("Preparing %s", file_name);
+
+ /* Reset values */
+ tfa9890_param_data.size = 0;
+ tfa9890_param_data.type = 0;
+ tfa9890_param_data.data = NULL;
+
+ size = sizeof(eq_data[type]);
+ memcpy(buf, eq_data[type], size);
+
+ /* Set the data for the ioctl arg */
+ if (size)
+ tfa9890_param_data.size = size;
+ if (type)
+ tfa9890_param_data.type = type;
+ if (buf != NULL)
+ tfa9890_param_data.data = buf;
+
+ return 0;
+}
+
+/* Public functions */
+
+int tfa9890_init(void) {
+ int fd;
+ int ret = 0;
+
+ ALOGV("enter %s", __func__);
+
+ /* Open the amplifier device */
+ if ((fd = open(TFA9890_DEVICE, O_RDWR)) < 0) {
+ ALOGE("Error opening amplifier device %s", TFA9890_DEVICE);
+ return -1;
+ }
+
+ /* The ".patch" files */
+ TFA9890_IOCTL(TFA98XX_PATCH_PARAM, PATCH_DSP_FILE, PATCH_DSP)
+ TFA9890_IOCTL(TFA98XX_PATCH_PARAM, PATCH_COLDBOOT_FILE, PATCH_COLDBOOT)
+
+ /* The ".config" files */
+ TFA9890_IOCTL(TFA98XX_CONFIG_PARAM, CONFIG_TOP, AMP_TOP)
+ TFA9890_IOCTL(TFA98XX_CONFIG_PARAM, CONFIG_BOTTOM, AMP_BOTTOM)
+ TFA9890_IOCTL(TFA98XX_CONFIG_PARAM, CONFIG_RECEIVER, AMP_RECEIVER)
+
+ /* The ".speaker" files */
+ TFA9890_IOCTL(TFA98XX_SPEAKER_PARAM, SPEAKER_TOP, AMP_TOP)
+ TFA9890_IOCTL(TFA98XX_SPEAKER_PARAM, SPEAKER_BOTTOM, AMP_BOTTOM)
+
+ /* The ".preset" files */
+ TFA9890_IOCTL(TFA98XX_PRESET_PARAM, PRESET_HIFISPEAKER_TOP, TYPE_HIFISPEAKER_TOP)
+ TFA9890_IOCTL(TFA98XX_PRESET_PARAM, PRESET_HIFISPEAKER_BOTTOM, TYPE_HIFISPEAKER_BOTTOM)
+ TFA9890_IOCTL(TFA98XX_PRESET_PARAM, PRESET_HIFISPEAKER_RING_TOP, TYPE_HIFISPEAKER_RING_TOP)
+ TFA9890_IOCTL(TFA98XX_PRESET_PARAM, PRESET_HIFISPEAKER_RING_BOTTOM, TYPE_HIFISPEAKER_RING_BOTTOM)
+ TFA9890_IOCTL(TFA98XX_PRESET_PARAM, PRESET_HIFISPEAKER_SFORCE_TOP, TYPE_HIFISPEAKER_SFORCE_TOP)
+ TFA9890_IOCTL(TFA98XX_PRESET_PARAM, PRESET_HIFISPEAKER_SFORCE_BOTTOM, TYPE_HIFISPEAKER_SFORCE_BOTTOM)
+ TFA9890_IOCTL(TFA98XX_PRESET_PARAM, PRESET_VOICECALLSPEAKER_TOP, TYPE_VOICECALLSPEAKER_TOP)
+ TFA9890_IOCTL(TFA98XX_PRESET_PARAM, PRESET_VOICECALLSPEAKER_BOTTOM, TYPE_VOICECALLSPEAKER_BOTTOM)
+ TFA9890_IOCTL(TFA98XX_PRESET_PARAM, PRESET_FMSPEAKER_TOP, TYPE_FMSPEAKER_TOP)
+ TFA9890_IOCTL(TFA98XX_PRESET_PARAM, PRESET_FMSPEAKER_BOTTOM, TYPE_FMSPEAKER_BOTTOM)
+ TFA9890_IOCTL(TFA98XX_PRESET_PARAM, PRESET_VOICECALLEARPICE_TOP, TYPE_VOICECALLEARPICE_TOP)
+
+ /* The ".eq" files */
+ TFA9890_IOCTL_EQ(EQ_HIFISPEAKER_TOP, TYPE_HIFISPEAKER_TOP)
+ TFA9890_IOCTL_EQ(EQ_HIFISPEAKER_BOTTOM, TYPE_HIFISPEAKER_BOTTOM)
+ TFA9890_IOCTL_EQ(EQ_HIFISPEAKER_RING_TOP, TYPE_HIFISPEAKER_RING_TOP)
+ TFA9890_IOCTL_EQ(EQ_HIFISPEAKER_RING_BOTTOM, TYPE_HIFISPEAKER_RING_BOTTOM)
+ TFA9890_IOCTL_EQ(EQ_HIFISPEAKER_SFORCE_TOP, TYPE_HIFISPEAKER_SFORCE_TOP)
+ TFA9890_IOCTL_EQ(EQ_HIFISPEAKER_SFORCE_BOTTOM, TYPE_HIFISPEAKER_SFORCE_BOTTOM)
+ TFA9890_IOCTL_EQ(EQ_VOICECALLSPEAKER_TOP, TYPE_VOICECALLSPEAKER_TOP)
+ TFA9890_IOCTL_EQ(EQ_VOICECALLSPEAKER_BOTTOM, TYPE_VOICECALLSPEAKER_BOTTOM)
+ TFA9890_IOCTL_EQ(EQ_FMSPEAKER_TOP, TYPE_FMSPEAKER_TOP)
+ TFA9890_IOCTL_EQ(EQ_FMSPEAKER_BOTTOM, TYPE_FMSPEAKER_BOTTOM)
+ TFA9890_IOCTL_EQ(EQ_VOICECALLEARPICE_TOP, TYPE_VOICECALLEARPICE_TOP)
+
+error:
+ ALOGV("exit %s with %d", __func__, ret);
+ close(fd);
+ return ret;
+}
diff --git a/tfa9890/tfa9890.h b/tfa9890/tfa9890.h
new file mode 100644
index 0000000..f9f042e
--- /dev/null
+++ b/tfa9890/tfa9890.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2014, The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Kernel header */
+#include <sound/tfa98xx.h>
+
+#define TFA9890_DEVICE "/dev/tfa98xx"
+
+/* All the files in /system/etc/tfa98xx */
+#define PATCH_DSP_FILE "/system/etc/tfa98xx/TFA9890.patch"
+#define PATCH_COLDBOOT_FILE "/system/etc/tfa98xx/coldboot.patch"
+
+#define CONFIG_TOP "/system/etc/tfa98xx/TFA9890_top.config"
+#define CONFIG_BOTTOM "/system/etc/tfa98xx/TFA9890_btm.config"
+#define CONFIG_RECEIVER "/system/etc/tfa98xx/TFA9890_Receiver.config"
+
+#define SPEAKER_TOP "/system/etc/tfa98xx/top.speaker"
+#define SPEAKER_BOTTOM "/system/etc/tfa98xx/btm.speaker"
+
+#define PRESET_HIFISPEAKER_TOP "/system/etc/tfa98xx/HiFiSpeaker_top.preset"
+#define PRESET_HIFISPEAKER_BOTTOM "/system/etc/tfa98xx/HiFiSpeaker_btm.preset"
+#define PRESET_HIFISPEAKER_RING_TOP "/system/etc/tfa98xx/HiFiSpeakerRing_top.preset"
+#define PRESET_HIFISPEAKER_RING_BOTTOM "/system/etc/tfa98xx/HiFiSpeakerRing_btm.preset"
+#define PRESET_HIFISPEAKER_SFORCE_TOP "/system/etc/tfa98xx/HiFiSpeakerSforce_top.preset"
+#define PRESET_HIFISPEAKER_SFORCE_BOTTOM "/system/etc/tfa98xx/HiFiSpeakerSforce_btm.preset"
+#define PRESET_VOICECALLSPEAKER_TOP "/system/etc/tfa98xx/VoiceCallSpeaker_top.preset"
+#define PRESET_VOICECALLSPEAKER_BOTTOM "/system/etc/tfa98xx/VoiceCallSpeaker_btm.preset"
+#define PRESET_FMSPEAKER_TOP "/system/etc/tfa98xx/FMSpeaker_top.preset"
+#define PRESET_FMSPEAKER_BOTTOM "/system/etc/tfa98xx/FMSpeaker_btm.preset"
+#define PRESET_VOICECALLEARPICE_TOP "/system/etc/tfa98xx/VoiceCallEarpice_top.preset"
+
+#define EQ_HIFISPEAKER_TOP "/system/etc/tfa98xx/HiFiSpeaker_top.eq"
+#define EQ_HIFISPEAKER_BOTTOM "/system/etc/tfa98xx/HiFiSpeaker_btm.eq"
+#define EQ_HIFISPEAKER_RING_TOP "/system/etc/tfa98xx/HiFiSpeakerRing_top.eq"
+#define EQ_HIFISPEAKER_RING_BOTTOM "/system/etc/tfa98xx/HiFiSpeakerRing_btm.eq"
+#define EQ_HIFISPEAKER_SFORCE_TOP "/system/etc/tfa98xx/HiFiSpeakerSforce_top.eq"
+#define EQ_HIFISPEAKER_SFORCE_BOTTOM "/system/etc/tfa98xx/HiFiSpeakerSforce_btm.eq"
+#define EQ_VOICECALLSPEAKER_TOP "/system/etc/tfa98xx/VoiceCallSpeaker_top.eq"
+#define EQ_VOICECALLSPEAKER_BOTTOM "/system/etc/tfa98xx/VoiceCallSpeaker_btm.eq"
+#define EQ_FMSPEAKER_TOP "/system/etc/tfa98xx/FMSpeaker_top.eq"
+#define EQ_FMSPEAKER_BOTTOM "/system/etc/tfa98xx/FMSpeaker_btm.eq"
+#define EQ_VOICECALLEARPICE_TOP "/system/etc/tfa98xx/VoiceCallEarpice_top.eq"
+
+/* Macros for ioctl with above files
+ * This macro calls tfa9890_prepare_for_ioctl()
+ * to setup the ioctl arg,
+ * and then calls ioctl() */
+#define TFA9890_IOCTL(ioctltype, filename, filetype) \
+ ret = tfa9890_prepare_for_ioctl(filename, filetype); \
+ if (ret > 0) { \
+ ALOGV("ioctl %s", filename); \
+ ret = ioctl(fd, ioctltype, &tfa9890_param_data); \
+ if (ret == -1) { \
+ ALOGE("ioctl failed for %s with %d", filename, errno); \
+ goto error; \
+ } \
+ } else \
+ goto error; \
+
+/* Macro for only ".eq"/EQ_ files
+ * Same as above but calls a different function
+ * to setup the ioctl arg */
+#define TFA9890_IOCTL_EQ(filename, filetype) \
+ ret = tfa9890_prepare_for_ioctl_eq(filename, filetype); \
+ if (!ret) { \
+ ALOGV("ioctl %s", filename); \
+ ret = ioctl(fd, TFA98XX_EQ_PARAM, &tfa9890_param_data); \
+ if (ret == -1) { \
+ ret = errno; \
+ ALOGE("ioctl failed for %s with %d", filename, ret); \
+ goto error; \
+ } \
+ } else \
+ goto error; \
+
+int tfa9890_prepare_for_ioctl(const char*, unsigned int);
+int tfa9890_prepare_for_ioctl_eq(const char*, unsigned int);
+int tfa9890_init(void);
diff --git a/tfa9890/tfa9890_amp.c b/tfa9890/tfa9890_amp.c
new file mode 100644
index 0000000..81f4792
--- /dev/null
+++ b/tfa9890/tfa9890_amp.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2014, The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tfa9890.h"
+
+int main(void) {
+ return tfa9890_init();
+}