Gigabeat S: Fully enable access to hardware tone controls and 3-D effect feature...
authorjethead71 <jethead71@a1c6a512-1295-4272-9138-f99709370657>
Sat, 15 May 2010 13:09:45 +0000 (15 13:09 +0000)
committerjethead71 <jethead71@a1c6a512-1295-4272-9138-f99709370657>
Sat, 15 May 2010 13:09:45 +0000 (15 13:09 +0000)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26051 a1c6a512-1295-4272-9138-f99709370657

18 files changed:
apps/SOURCES
apps/lang/english.lang
apps/menus/audiohw_eq_menu.c [new file with mode: 0644]
apps/menus/exported_menus.h
apps/menus/sound_menu.c
apps/plugin.c
apps/plugin.h
apps/plugins/mpegplayer/mpeg_settings.c
apps/settings.c
apps/settings.h
apps/settings_list.c
firmware/drivers/audio/wm8978.c
firmware/export/audiohw.h
firmware/export/config/gigabeats.h
firmware/export/sound.h
firmware/export/wm8978.h
firmware/sound.c
uisimulator/sdl/sound.c

index 2642fa1..2bd4018 100644 (file)
@@ -16,6 +16,9 @@ menus/menu_common.c
 menus/display_menu.c
 menus/theme_menu.c
 #if CONFIG_CODEC == SWCODEC
+#ifdef HAVE_WM8978
+menus/audiohw_eq_menu.c
+#endif
 menus/eq_menu.c
 buffering.c
 voice_thread.c
index c079a4a..4a4fb2c 100644 (file)
     radio: ""
   </voice>
 </phrase>
+<phrase>
+  id: LANG_HW_EQ_TONE_CONTROLS
+  desc: in sound_menu, hardware equalizer tone controls
+  user: core
+  <source>
+    *: none
+    gigabeats: "Tone Controls"
+  </source>
+  <dest>
+    *: none
+    gigabeats: "Tone Controls"
+  </dest>
+  <voice>
+    *: none
+    gigabeats: "Tone Controls"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_HW_EQ_TONE_CONTROLS_ADVANCED
+  desc: in sound_menu, advanced settings for hardware equalizer tone controls
+  user: core
+  <source>
+    *: none
+    gigabeats: "Advanced Tone Control Settings"
+  </source>
+  <dest>
+    *: none
+    gigabeats: "Advanced Tone Control Settings"
+  </dest>
+  <voice>
+    *: none
+    gigabeats: "Advanced Tone Control Settings"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_HW_EQ_GAIN
+  desc: in sound_menu, hardware equalizer tone controls filter gain
+  user: core
+  <source>
+    *: none
+    gigabeats: "Band %d Gain"
+  </source>
+  <dest>
+    *: none
+    gigabeats: "Band %d Gain"
+  </dest>
+  <voice>
+    *: none
+    gigabeats: "Band Gain"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_HW_EQ_FREQUENCY
+  desc: in sound_menu, hardware equalizer tone controls shelf filter cutoff frequency
+  user: core
+  <source>
+    *: none
+    gigabeats: "Band %d Frequency"
+  </source>
+  <dest>
+    *: none
+    gigabeats: "Band %d Frequency"
+  </dest>
+  <voice>
+    *: none
+    gigabeats: "Band Frequency"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_HW_EQ_WIDTH
+  desc: in sound_menu, hardware equalizer tone controls peak bandwith setting
+  user: core
+  <source>
+    *: none
+    gigabeats: "Band %d Width"
+  </source>
+  <dest>
+    *: none
+    gigabeats: "Band %d Width"
+  </dest>
+  <voice>
+    *: none
+    gigabeats: "Band Width"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_HW_EQ_WIDTH_NARROW
+  desc: in sound_menu, hardware equalizer tone controls narrow bandwith setting
+  user: core
+  <source>
+    *: none
+    gigabeats: "Narrow"
+  </source>
+  <dest>
+    *: none
+    gigabeats: "Narrow"
+  </dest>
+  <voice>
+    *: none
+    gigabeats: "Narrow"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_HW_EQ_WIDTH_WIDE
+  desc: in sound_menu, hardware equalizer tone controls wide bandwidth setting
+  user: core
+  <source>
+    *: none
+    gigabeats: "Wide"
+  </source>
+  <dest>
+    *: none
+    gigabeats: "Wide"
+  </dest>
+  <voice>
+    *: none
+    gigabeats: "Wide"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_DEPTH_3D
+  desc: in sound_menu, amount of 3D enhancement effect
+  user: core
+  <source>
+    *: none
+    gigabeats: "3-D Enhancement"
+  </source>
+  <dest>
+    *: none
+    gigabeats: "3-D Enhancement"
+  </dest>
+  <voice>
+    *: none
+    gigabeats: "3-D Enhancement"
+  </voice>
+</phrase>
+
diff --git a/apps/menus/audiohw_eq_menu.c b/apps/menus/audiohw_eq_menu.c
new file mode 100644 (file)
index 0000000..1027d6a
--- /dev/null
@@ -0,0 +1,244 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Michael Sevakis
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include <stdio.h>
+#include "config.h"
+#include "sound.h"
+#include "settings.h"
+#include "lang.h"
+#include "menu.h"
+#include "talk.h"
+
+#define HW_EQ_IDX(band, setting)  ((void *)(((setting) << 8) | (band)))
+#define HW_EQ_IDX_BAND(data)      ((uint8_t)(uintptr_t)(data))
+#define HW_EQ_IDX_SETTING(data)   ((uint8_t)((uintptr_t)(data) >> 8))
+
+static unsigned short hw_eq_setting_lang_ids[AUDIOHW_EQ_SETTING_NUM] =
+{
+    LANG_HW_EQ_GAIN,
+#ifdef AUDIOHW_HAVE_EQ_FREQUENCY
+    LANG_HW_EQ_FREQUENCY,
+#endif
+#ifdef AUDIOHW_HAVE_EQ_WIDTH
+    LANG_HW_EQ_WIDTH,
+#endif
+};
+
+static char * hw_eq_get_name(int selected_item, void * data, char *buffer)
+{
+    snprintf(buffer, MAX_PATH,
+             str(hw_eq_setting_lang_ids[HW_EQ_IDX_SETTING(data)]),
+             HW_EQ_IDX_BAND(data) + 1);
+    return buffer;
+    (void)selected_item;
+}
+
+static int hw_eq_speak_item(int selected_item, void * data)
+{
+    talk_id(hw_eq_setting_lang_ids[HW_EQ_IDX_SETTING(data)], false);
+    talk_number(HW_EQ_IDX_BAND(data) + 1, true);
+    return 0;
+    (void)selected_item;
+}
+
+static int hw_eq_do_band_setting(void *param)
+{
+    int band = HW_EQ_IDX_BAND(param);
+    int setting = HW_EQ_IDX_SETTING(param);
+    char desc[MAX_PATH];
+    struct menu_callback_with_desc cbwdesc =
+    {
+        .menu_callback = NULL,
+        .desc = hw_eq_get_name(0, param, desc),
+        .icon_id = Icon_NOICON
+    };
+    struct menu_item_ex item =
+    {
+        .flags = MT_SETTING_W_TEXT | MENU_HAS_DESC,
+        { .variable = (void*)(&global_settings.hw_eq_bands[band].gain + setting) },
+        { .callback_and_desc = &cbwdesc }
+    };
+    do_setting_from_menu(&item, NULL);
+    return 0;
+}
+
+MENUITEM_FUNCTION_DYNTEXT(hw_eq_band1_gain, MENU_FUNC_USEPARAM,
+                          hw_eq_do_band_setting,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND1, AUDIOHW_EQ_GAIN),
+                          hw_eq_get_name, hw_eq_speak_item,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND1, AUDIOHW_EQ_GAIN),
+                          NULL, Icon_Menu_setting);
+#ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY
+MENUITEM_FUNCTION_DYNTEXT(hw_eq_band1_frequency, MENU_FUNC_USEPARAM,
+                          hw_eq_do_band_setting,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND1, AUDIOHW_EQ_FREQUENCY),
+                          hw_eq_get_name, hw_eq_speak_item,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND1, AUDIOHW_EQ_FREQUENCY),
+                          NULL, Icon_NOICON);
+#endif
+#ifdef AUDIOHW_HAVE_EQ_BAND2
+MENUITEM_FUNCTION_DYNTEXT(hw_eq_band2_gain, MENU_FUNC_USEPARAM,
+                          hw_eq_do_band_setting,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_GAIN),
+                          hw_eq_get_name, hw_eq_speak_item,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_GAIN),
+                          NULL, Icon_Menu_setting);
+#ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY
+MENUITEM_FUNCTION_DYNTEXT(hw_eq_band2_frequency, MENU_FUNC_USEPARAM,
+                          hw_eq_do_band_setting,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_FREQUENCY),
+                          hw_eq_get_name, hw_eq_speak_item,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_FREQUENCY),
+                          NULL, Icon_NOICON);
+#endif
+#ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH
+MENUITEM_FUNCTION_DYNTEXT(hw_eq_band2_width, MENU_FUNC_USEPARAM,
+                          hw_eq_do_band_setting,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_WIDTH),
+                          hw_eq_get_name, hw_eq_speak_item,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_WIDTH),
+                          NULL, Icon_NOICON);
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND2 */
+#ifdef AUDIOHW_HAVE_EQ_BAND3
+MENUITEM_FUNCTION_DYNTEXT(hw_eq_band3_gain, MENU_FUNC_USEPARAM,
+                          hw_eq_do_band_setting,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_GAIN),
+                          hw_eq_get_name, hw_eq_speak_item,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_GAIN),
+                          NULL, Icon_Menu_setting);
+#ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY
+MENUITEM_FUNCTION_DYNTEXT(hw_eq_band3_frequency, MENU_FUNC_USEPARAM,
+                          hw_eq_do_band_setting,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_FREQUENCY),
+                          hw_eq_get_name, hw_eq_speak_item,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_FREQUENCY),
+                          NULL, Icon_NOICON);
+#endif
+#ifdef AUDIOHW_HAVE_EQ_BAND3_WIDTH
+MENUITEM_FUNCTION_DYNTEXT(hw_eq_band3_width, MENU_FUNC_USEPARAM,
+                          hw_eq_do_band_setting,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_WIDTH),
+                          hw_eq_get_name, hw_eq_speak_item,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_WIDTH),
+                          NULL, Icon_NOICON);
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND3 */
+#ifdef AUDIOHW_HAVE_EQ_BAND4
+MENUITEM_FUNCTION_DYNTEXT(hw_eq_band4_gain, MENU_FUNC_USEPARAM,
+                          hw_eq_do_band_setting,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_GAIN),
+                          hw_eq_get_name, hw_eq_speak_item,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_GAIN),
+                          NULL, Icon_Menu_setting);
+#ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY
+MENUITEM_FUNCTION_DYNTEXT(hw_eq_band4_frequency, MENU_FUNC_USEPARAM,
+                          hw_eq_do_band_setting,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_FREQUENCY),
+                          hw_eq_get_name, hw_eq_speak_item,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_FREQUENCY),
+                          NULL, Icon_NOICON);
+#endif
+#ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH
+MENUITEM_FUNCTION_DYNTEXT(hw_eq_band4_width, MENU_FUNC_USEPARAM,
+                          hw_eq_do_band_setting,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_WIDTH),
+                          hw_eq_get_name, hw_eq_speak_item,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_WIDTH),
+                          NULL, Icon_NOICON);
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND4 */
+#ifdef AUDIOHW_HAVE_EQ_BAND5
+MENUITEM_FUNCTION_DYNTEXT(hw_eq_band5_gain, MENU_FUNC_USEPARAM,
+                          hw_eq_do_band_setting,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND5, AUDIOHW_EQ_GAIN),
+                          hw_eq_get_name, hw_eq_speak_item,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND5, AUDIOHW_EQ_GAIN),
+                          NULL, Icon_Menu_setting);
+#ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY
+MENUITEM_FUNCTION_DYNTEXT(hw_eq_band5_frequency, MENU_FUNC_USEPARAM,
+                          hw_eq_do_band_setting,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND5, AUDIOHW_EQ_FREQUENCY),
+                          hw_eq_get_name, hw_eq_speak_item,
+                          HW_EQ_IDX(AUDIOHW_EQ_BAND5, AUDIOHW_EQ_FREQUENCY),
+                          NULL, Icon_NOICON);
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND5 */
+
+/* Submenu for multiple "tone controls". Gain + all advanced settings. */
+MAKE_MENU(hardware_eq_tone_controls_advanced, ID2P(LANG_HW_EQ_TONE_CONTROLS_ADVANCED),
+          NULL, Icon_NOICON
+          ,&hw_eq_band1_gain
+#ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY
+          ,&hw_eq_band1_frequency
+#endif
+#ifdef AUDIOHW_HAVE_EQ_BAND2
+          ,&hw_eq_band2_gain
+#ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY
+          ,&hw_eq_band2_frequency
+#endif
+#ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH
+          ,&hw_eq_band2_width
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND2 */
+#ifdef AUDIOHW_HAVE_EQ_BAND3
+          ,&hw_eq_band3_gain
+#ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY
+          ,&hw_eq_band3_frequency
+#endif
+#ifdef AUDIOHW_HAVE_EQ_BAND3_WIDTH
+          ,&hw_eq_band3_width
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND3 */
+#ifdef AUDIOHW_HAVE_EQ_BAND4
+          ,&hw_eq_band4_gain
+#ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY
+          ,&hw_eq_band4_frequency
+#endif
+#ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH
+          ,&hw_eq_band4_width
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND4 */
+#ifdef AUDIOHW_HAVE_EQ_BAND5
+          ,&hw_eq_band5_gain
+#ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY
+          ,&hw_eq_band5_frequency
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND5 */
+    );
+/* Shows only the gains + advanced settings submenu */
+MAKE_MENU(audiohw_eq_tone_controls, ID2P(LANG_HW_EQ_TONE_CONTROLS),
+          NULL, Icon_NOICON
+          ,&hw_eq_band1_gain
+#ifdef AUDIOHW_HAVE_EQ_BAND2
+          ,&hw_eq_band2_gain
+#endif
+#ifdef AUDIOHW_HAVE_EQ_BAND3
+          ,&hw_eq_band3_gain
+#endif
+#ifdef AUDIOHW_HAVE_EQ_BAND4
+          ,&hw_eq_band4_gain
+#endif
+#ifdef AUDIOHW_HAVE_EQ_BAND5
+          ,&hw_eq_band5_gain
+#endif
+          ,&hardware_eq_tone_controls_advanced
+    );
+
index 9fb39cb..37b5ff3 100644 (file)
@@ -40,6 +40,9 @@ extern const struct menu_item_ex
         playlist_settings,          /* playlist_menu.c  */
         playlist_options,           /* playlist_menu.c  */
         equalizer_menu,             /* eq_menu.c        */
+#ifdef AUDIOHW_HAVE_EQ
+        audiohw_eq_tone_controls,   /* audiohw_eq_menu.c */
+#endif
         info_menu,                  /* info_menu.c      */
         theme_menu;                 /* theme_menu.c     */
 
index 0ce860c..066b1da 100644 (file)
@@ -23,6 +23,7 @@
 #include <stddef.h>
 #include <limits.h>
 #include "config.h"
+#include "sound.h"
 #include "lang.h"
 #include "action.h"
 #include "settings.h"
@@ -38,6 +39,7 @@
 /***********************************/
 /*    SOUND MENU                   */
 MENUITEM_SETTING(volume, &global_settings.volume, NULL);
+#ifdef AUDIOHW_HAVE_BASS
 MENUITEM_SETTING(bass, &global_settings.bass,
 #ifdef HAVE_SW_TONE_CONTROLS
     lowlatency_callback
@@ -45,9 +47,14 @@ MENUITEM_SETTING(bass, &global_settings.bass,
     NULL
 #endif
 );
-#ifdef HAVE_WM8758
-MENUITEM_SETTING(bass_cutoff, &global_settings.bass_cutoff, NULL);
+
+#ifdef AUDIOHW_HAVE_BASS_CUTOFF
+MENUITEM_SETTING(treble_cutoff, &global_settings.treble_cutoff, NULL);
 #endif
+#endif /* AUDIOHW_HAVE_BASS */
+
+
+#ifdef AUDIOHW_HAVE_TREBLE
 MENUITEM_SETTING(treble, &global_settings.treble,
 #ifdef HAVE_SW_TONE_CONTROLS
     lowlatency_callback
@@ -55,9 +62,13 @@ MENUITEM_SETTING(treble, &global_settings.treble,
     NULL
 #endif
 );
-#ifdef HAVE_WM8758
+
+#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
 MENUITEM_SETTING(treble_cutoff, &global_settings.treble_cutoff, NULL);
 #endif
+#endif /* AUDIOHW_HAVE_TREBLE */
+
+
 MENUITEM_SETTING(balance, &global_settings.balance, NULL);
 MENUITEM_SETTING(channel_config, &global_settings.channel_config,
 #if CONFIG_CODEC == SWCODEC
@@ -74,6 +85,10 @@ MENUITEM_SETTING(stereo_width, &global_settings.stereo_width,
 #endif
 );
 
+#ifdef AUDIOHW_HAVE_DEPTH_3D
+MENUITEM_SETTING(depth_3d, &global_settings.depth_3d, NULL);
+#endif
+
 #if CONFIG_CODEC == SWCODEC
     /* Crossfeed Submenu */
     MENUITEM_SETTING(crossfeed, &global_settings.crossfeed, lowlatency_callback);
@@ -137,19 +152,30 @@ static int timestretch_callback(int action,const struct menu_item_ex *this_item)
     MENUITEM_SETTING(speaker_enabled, &global_settings.speaker_enabled, NULL);
 #endif
 
-
+#ifdef AUDIOHW_HAVE_EQ
+#endif /* AUDIOHW_HAVE_EQ */
 
 MAKE_MENU(sound_settings, ID2P(LANG_SOUND_SETTINGS), NULL, Icon_Audio,
-          &volume,
-          &bass,
-#ifdef HAVE_WM8758
-          &bass_cutoff,
+          &volume
+#ifdef AUDIOHW_HAVE_BASS
+          ,&bass
+#endif
+#ifdef AUDIOHW_HAVE_BASS_CUTOFF
+          ,&bass_cutoff
+#endif
+#ifdef AUDIOHW_HAVE_TREBLE
+          ,&treble
+#endif
+#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
+          ,&treble_cutoff
+#endif
+#ifdef AUDIOHW_HAVE_EQ
+          ,&audiohw_eq_tone_controls
 #endif
-          &treble,
-#ifdef HAVE_WM8758
-          &treble_cutoff,
+          ,&balance,&channel_config,&stereo_width
+#ifdef AUDIOHW_HAVE_DEPTH_3D
+          ,&depth_3d
 #endif
-          &balance,&channel_config,&stereo_width
 #if CONFIG_CODEC == SWCODEC
           ,&crossfeed_menu, &equalizer_menu, &dithering_enabled
           ,&timestretch_enabled
index b60e2d6..90380a0 100644 (file)
@@ -721,6 +721,9 @@ static const struct plugin_api rockbox_api = {
     round_value_to_list32,
 #endif
 
+#ifdef AUDIOHW_HAVE_EQ
+    sound_enum_hw_eq_band_setting,
+#endif
 };
 
 int plugin_load(const char* plugin, const void* parameter)
index 5aaa638..108a283 100644 (file)
@@ -142,7 +142,7 @@ void* plugin_get_buffer(size_t *buffer_size);
 #define PLUGIN_MAGIC 0x526F634B /* RocK */
 
 /* increase this every time the api struct changes */
-#define PLUGIN_API_VERSION 184
+#define PLUGIN_API_VERSION 185
 
 /* update this to latest version if a change to the api struct breaks
    backwards compatibility (and please take the opportunity to sort in any
@@ -884,6 +884,11 @@ int (*round_value_to_list32)(unsigned long value,
                              int count,
                              bool signd);
 #endif
+
+#ifdef AUDIOHW_HAVE_EQ
+    int (*sound_enum_hw_eq_band_setting)(unsigned int band,
+                                         unsigned int band_setting);
+#endif /* AUDIOHW_HAVE_EQ */
 };
 
 /* plugin header */
index 6c8a2b8..1ac2476 100644 (file)
@@ -403,18 +403,53 @@ static void sync_audio_setting(int setting, bool global)
     switch (setting)
     {
     case MPEG_AUDIO_TONE_CONTROLS:
+    #if defined(AUDIOHW_HAVE_BASS) || defined(AUDIOHW_HAVE_TREBLE)
         if (global || settings.tone_controls)
         {
+    #ifdef AUDIOHW_HAVE_BASS
             val0 = rb->global_settings->bass;
+    #endif
+    #ifdef AUDIOHW_HAVE_TREBLE 
             val1 = rb->global_settings->treble;
+    #endif
         }
         else
         {
+    #ifdef AUDIOHW_HAVE_BASS
             val0 = rb->sound_default(SOUND_BASS);
+    #endif
+    #ifdef AUDIOHW_HAVE_TREBLE
             val1 = rb->sound_default(SOUND_TREBLE);
+    #endif
         }
+    #ifdef AUDIOHW_HAVE_BASS
         rb->sound_set(SOUND_BASS, val0);
+    #endif
+    #ifdef AUDIOHW_HAVE_TREBLE
         rb->sound_set(SOUND_TREBLE, val1);
+    #endif
+    #endif /* AUDIOHW_HAVE_BASS || AUDIOHW_HAVE_TREBLE */
+
+    #ifdef AUDIOHW_HAVE_EQ
+        for (val1 = 0;; val1++)
+        {
+            int setting = rb->sound_enum_hw_eq_band_setting(val1, AUDIOHW_EQ_GAIN);
+
+            if (setting == -1)
+                break;
+
+            if (global || settings.tone_controls)
+            {
+                val0 = rb->global_settings->hw_eq_bands[val1].gain;
+            }
+            else
+            {
+                val0 = rb->sound_default(setting);
+            }
+
+            rb->sound_set(setting, val0);
+        }
+    #endif /* AUDIOHW_HAVE_EQ */
         break;
 
     case MPEG_AUDIO_CHANNEL_MODES:
index 4901957..6349372 100644 (file)
@@ -27,6 +27,7 @@
 #include "config.h"
 #include "action.h"
 #include "crc32.h"
+#include "sound.h"
 #include "settings.h"
 #include "debug.h"
 #include "usb.h"
@@ -55,7 +56,6 @@
 #include "powermgmt.h"
 #include "keyboard.h"
 #include "version.h"
-#include "sound.h"
 #include "rbunicode.h"
 #include "dircache.h"
 #include "splash.h"
@@ -718,8 +718,12 @@ void sound_settings_apply(void)
 #if CONFIG_CODEC == SWCODEC
     sound_set_dsp_callback(dsp_callback);
 #endif
+#ifdef AUDIOHW_HAVE_BASS
     sound_set(SOUND_BASS, global_settings.bass);
+#endif
+#ifdef AUDIOHW_HAVE_TREBLE
     sound_set(SOUND_TREBLE, global_settings.treble);
+#endif
     sound_set(SOUND_BALANCE, global_settings.balance);
     sound_set(SOUND_VOLUME, global_settings.volume);
     sound_set(SOUND_CHANNELS, global_settings.channel_config);
@@ -734,13 +738,36 @@ void sound_settings_apply(void)
     sound_set(SOUND_MDB_ENABLE, global_settings.mdb_enable);
     sound_set(SOUND_SUPERBASS, global_settings.superbass);
 #endif
-
-#ifdef HAVE_WM8758
+#ifdef AUDIOHW_HAVE_BASS_CUTOFF
     sound_set(SOUND_BASS_CUTOFF, global_settings.bass_cutoff);
+#endif
+#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
     sound_set(SOUND_TREBLE_CUTOFF, global_settings.treble_cutoff);
 #endif
-}
+#ifdef AUDIOHW_HAVE_DEPTH_3D
+    sound_set(SOUND_DEPTH_3D, global_settings.depth_3d);
+#endif
+#ifdef AUDIOHW_HAVE_EQ
+    int b;
 
+    for (b = 0; b < AUDIOHW_EQ_BAND_NUM; b++)
+    {
+        int setting = sound_enum_hw_eq_band_setting(b, AUDIOHW_EQ_GAIN);
+        sound_set(setting, global_settings.hw_eq_bands[b].gain);
+
+#ifdef AUDIOHW_HAVE_EQ_FREQUENCY
+        setting = sound_enum_hw_eq_band_setting(b, AUDIOHW_EQ_FREQUENCY);
+        if (setting != -1)
+            sound_set(setting, global_settings.hw_eq_bands[b].frequency);
+#endif /* AUDIOHW_HAVE_EQ_FREQUENCY */
+#ifdef AUDIOHW_HAVE_EQ_WIDTH
+        setting = sound_enum_hw_eq_band_setting(b, AUDIOHW_EQ_WIDTH);
+        if (setting != -1)
+            sound_set(setting, global_settings.hw_eq_bands[b].width);
+#endif /* AUDIOHW_HAVE_EQ_WIDTH */
+    }
+#endif
+}
 
 void settings_apply(bool read_disk)
 {
index 2fdff99..c8e8d64 100644 (file)
@@ -336,7 +336,7 @@ struct user_settings
     bool superbass;     /* true/false */
 #endif
 
-#ifdef HAVE_WM8758
+#if defined(HAVE_WM8758) || defined(HAVE_WM8978)
     int bass_cutoff;
     int treble_cutoff;
 #endif
@@ -831,6 +831,25 @@ struct user_settings
     /* When resuming playback (after a stop), rewind this number of seconds */
     int resume_rewind;
 #endif
+
+#ifdef AUDIOHW_HAVE_DEPTH_3D
+    int depth_3d;
+#endif
+
+#ifdef AUDIOHW_HAVE_EQ
+    /** Hardware EQ tone controls **/
+    struct hw_eq_band
+    {
+        /* Maintain the order of members or sound_menu has to be changed */
+        int gain;
+#ifdef AUDIOHW_HAVE_EQ_FREQUENCY
+        int frequency;
+#endif
+#ifdef AUDIOHW_HAVE_EQ_WIDTH
+        int width;
+#endif
+    } hw_eq_bands[AUDIOHW_EQ_BAND_NUM];
+#endif /* AUDIOHW_HAVE_EQ */
 };
 
 /** global variables **/
index 1bc7832..d6f5f94 100644 (file)
 #include "lcd.h"
 #include "button.h"
 #include "backlight.h"
+#include "sound.h"
 #include "settings.h"
 #include "settings_list.h"
 #include "usb.h"
-#include "sound.h"
 #include "dsp.h"
 #include "audio.h"
 #include "power.h"
@@ -552,9 +552,97 @@ const struct settings_list settings[] = {
     /* sound settings */
     SOUND_SETTING(F_NO_WRAP,volume, LANG_VOLUME, "volume", SOUND_VOLUME),
     SOUND_SETTING(0, balance, LANG_BALANCE, "balance", SOUND_BALANCE),
+/* Tone controls */
+#ifdef AUDIOHW_HAVE_BASS
     SOUND_SETTING(F_NO_WRAP,bass, LANG_BASS, "bass", SOUND_BASS),
+#endif
+#ifdef AUDIOHW_HAVE_TREBLE
     SOUND_SETTING(F_NO_WRAP,treble, LANG_TREBLE, "treble", SOUND_TREBLE),
-
+#endif
+/* Hardware EQ tone controls */
+#ifdef AUDIOHW_HAVE_EQ
+/* Band gain is generic */
+    SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND1].gain,
+                  LANG_HW_EQ_GAIN, "tone band1 gain", SOUND_EQ_BAND1_GAIN),
+#ifdef AUDIOHW_HAVE_EQ_BAND2
+    SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND2].gain,
+                  LANG_HW_EQ_GAIN, "tone band2 gain", SOUND_EQ_BAND2_GAIN),
+#endif /* AUDIOHW_HAVE_EQ_BAND2 */
+#ifdef AUDIOHW_HAVE_EQ_BAND3
+    SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND3].gain,
+                  LANG_HW_EQ_GAIN, "tone band3 gain", SOUND_EQ_BAND3_GAIN),
+#endif /* AUDIOHW_HAVE_EQ_BAND3 */
+#ifdef AUDIOHW_HAVE_EQ_BAND4
+    SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND4].gain,
+                  LANG_HW_EQ_GAIN, "tone band4 gain", SOUND_EQ_BAND4_GAIN),
+#endif /* AUDIOHW_HAVE_EQ_BAND4 */
+#ifdef AUDIOHW_HAVE_EQ_BAND5
+    SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND5].gain,
+                  LANG_HW_EQ_GAIN, "tone band5 gain", SOUND_EQ_BAND5_GAIN),
+#endif /* AUDIOHW_HAVE_EQ_BAND5 */
+#ifdef HAVE_WM8978
+    /* Frequencies vary with samplerate but at least the user has an idea
+     * about the bands and it will be correct with normal playback rates. */
+/* Band 1 */
+    STRINGCHOICE_SETTING(F_SOUNDSETTING,
+                         hw_eq_bands[AUDIOHW_EQ_BAND1].frequency,
+                         LANG_HW_EQ_FREQUENCY, 0,"tone band1 frequency",
+                         "80 Hz,105 Hz,135 Hz,175 Hz",
+                         sound_set_hw_eq_band1_frequency, 4,
+                         TALK_ID(80, UNIT_HERTZ), TALK_ID(105, UNIT_HERTZ),
+                         TALK_ID(135, UNIT_HERTZ), TALK_ID(175, UNIT_HERTZ)),
+/* Band 2 */
+    STRINGCHOICE_SETTING(F_SOUNDSETTING,
+                         hw_eq_bands[AUDIOHW_EQ_BAND2].frequency,
+                         LANG_HW_EQ_FREQUENCY, 0,"tone band2 frequency",
+                         "230 Hz,300 Hz,385 Hz,500 Hz",
+                         sound_set_hw_eq_band2_frequency, 4,
+                         TALK_ID(230, UNIT_HERTZ), TALK_ID(300, UNIT_HERTZ),
+                         TALK_ID(385, UNIT_HERTZ), TALK_ID(500, UNIT_HERTZ)),
+    CHOICE_SETTING(F_SOUNDSETTING, hw_eq_bands[AUDIOHW_EQ_BAND2].width,
+                   LANG_HW_EQ_WIDTH, 0, "tone band2 width", "narrow,wide",
+                   sound_set_hw_eq_band2_width, 2,
+                   ID2P(LANG_HW_EQ_WIDTH_NARROW), ID2P(LANG_HW_EQ_WIDTH_WIDE)),
+/* Band 3 */
+    STRINGCHOICE_SETTING(F_SOUNDSETTING,
+                         hw_eq_bands[AUDIOHW_EQ_BAND3].frequency,
+                         LANG_HW_EQ_FREQUENCY, 0, "tone band3 frequency",
+                         "650 Hz,850 Hz,1.1 kHz,1.4 kHz",
+                         sound_set_hw_eq_band3_frequency, 4,
+                         TALK_ID(650, UNIT_HERTZ), TALK_ID(850, UNIT_HERTZ),
+                         TALK_ID_DECIMAL(11, 1, UNIT_KHZ),
+                         TALK_ID_DECIMAL(14, 1, UNIT_KHZ)),
+    CHOICE_SETTING(F_SOUNDSETTING,hw_eq_bands[AUDIOHW_EQ_BAND3].width,
+                   LANG_HW_EQ_WIDTH, 0, "tone band3 width", "narrow,wide",
+                   sound_set_hw_eq_band3_width, 2,
+                   ID2P(LANG_HW_EQ_WIDTH_NARROW), ID2P(LANG_HW_EQ_WIDTH_WIDE)),
+/* Band 4 */
+    STRINGCHOICE_SETTING(F_SOUNDSETTING,
+                         hw_eq_bands[AUDIOHW_EQ_BAND4].frequency,
+                         LANG_HW_EQ_FREQUENCY, 0, "tone band4 frequency",
+                         "1.8 kHz,2.4 kHz,3.2 kHz,4.1 kHz",
+                         sound_set_hw_eq_band4_frequency, 4,
+                         TALK_ID_DECIMAL(18, 1, UNIT_KHZ),
+                         TALK_ID_DECIMAL(24, 1, UNIT_KHZ),
+                         TALK_ID_DECIMAL(32, 1, UNIT_KHZ),
+                         TALK_ID_DECIMAL(41, 1, UNIT_KHZ)),
+    CHOICE_SETTING(F_SOUNDSETTING, hw_eq_bands[AUDIOHW_EQ_BAND4].width,
+                   LANG_HW_EQ_WIDTH, 0, "tone band4 width", "narrow,wide",
+                   sound_set_hw_eq_band4_width, 2,
+                   ID2P(LANG_HW_EQ_WIDTH_NARROW), ID2P(LANG_HW_EQ_WIDTH_WIDE)),
+/* Band 5 */
+    STRINGCHOICE_SETTING(F_SOUNDSETTING,
+                         hw_eq_bands[AUDIOHW_EQ_BAND5].frequency,
+                         LANG_HW_EQ_FREQUENCY, 0, "tone band5 frequency",
+                         "5.3 kHz,6.9 kHz,9.0 kHz,11.7 kHz",
+                         sound_set_hw_eq_band5_frequency, 4,
+                         TALK_ID_DECIMAL(53, 1, UNIT_KHZ),
+                         TALK_ID_DECIMAL(69, 1, UNIT_KHZ),
+                         TALK_ID_DECIMAL(90, 1, UNIT_KHZ),
+                         TALK_ID_DECIMAL(117, 1, UNIT_KHZ)),
+#endif /* HAVE_WM8978 */
+#endif /* AUDIOHW_HAVE_EQ */
+/* 3-d enhancement effect */
 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
     SOUND_SETTING(0,loudness, LANG_LOUDNESS, "loudness", SOUND_LOUDNESS),
     STRINGCHOICE_SETTING(F_SOUNDSETTING,avc,LANG_AUTOVOL,0,"auto volume",
@@ -574,6 +662,10 @@ const struct settings_list settings[] = {
                    ID2P(LANG_CHANNEL_RIGHT), ID2P(LANG_CHANNEL_KARAOKE)),
     SOUND_SETTING(F_SOUNDSETTING, stereo_width, LANG_STEREO_WIDTH,
                   "stereo_width", SOUND_STEREO_WIDTH),
+#ifdef AUDIOHW_HAVE_DEPTH_3D
+    SOUND_SETTING(0,depth_3d, LANG_DEPTH_3D, "3-d enhancement",
+                  SOUND_DEPTH_3D),
+#endif
     /* playback */
     OFFON_SETTING(0, playlist_shuffle, LANG_SHUFFLE, false, "shuffle", NULL),
     SYSTEM_SETTING(NVRAM(4), resume_index, -1),
@@ -1332,9 +1424,11 @@ const struct settings_list settings[] = {
                        "compressor release time", UNIT_MS, 100, 1000,
                        100, NULL, NULL, compressor_set),
 #endif
-#ifdef HAVE_WM8758
+#ifdef AUDIOHW_HAVE_BASS_CUTOFF
     SOUND_SETTING(F_NO_WRAP, bass_cutoff, LANG_BASS_CUTOFF,
                   "bass cutoff", SOUND_BASS_CUTOFF),
+#endif
+#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
     SOUND_SETTING(F_NO_WRAP, treble_cutoff, LANG_TREBLE_CUTOFF,
                   "treble cutoff", SOUND_TREBLE_CUTOFF),
 #endif
index a2dbf5a..2d57ce3 100644 (file)
@@ -37,27 +37,35 @@ extern void audiohw_enable_headphone_jack(bool enable);
 
 const struct sound_settings_info audiohw_settings[] =
 {
-    [SOUND_VOLUME]        = {"dB", 0,  1, -90,   6, -25},
-    [SOUND_BASS]          = {"dB", 0,  1, -12,  12,   0},
-    [SOUND_TREBLE]        = {"dB", 0,  1, -12,  12,   0},
-    [SOUND_BALANCE]       = {"%",  0,  1,-100, 100,   0},
-    [SOUND_CHANNELS]      = {"",   0,  1,   0,   5,   0},
-    [SOUND_STEREO_WIDTH]  = {"%",  0,  5,   0, 250, 100},
+    [SOUND_VOLUME]             = {"dB", 0,   1, -90,   6, -25},
+    [SOUND_BALANCE]            = {"%",  0,   1,-100, 100,   0},
+    [SOUND_CHANNELS]           = {"",   0,   1,   0,   5,   0},
+    [SOUND_STEREO_WIDTH]       = {"%",  0,   5,   0, 250, 100},
+    [SOUND_EQ_BAND1_GAIN]      = {"dB", 0,   1, -12,  12,   0},
+    [SOUND_EQ_BAND2_GAIN]      = {"dB", 0,   1, -12,  12,   0},
+    [SOUND_EQ_BAND3_GAIN]      = {"dB", 0,   1, -12,  12,   0},
+    [SOUND_EQ_BAND4_GAIN]      = {"dB", 0,   1, -12,  12,   0},
+    [SOUND_EQ_BAND5_GAIN]      = {"dB", 0,   1, -12,  12,   0},
+    [SOUND_EQ_BAND1_FREQUENCY] = {"",   0,   1,   0,   3,   0},
+    [SOUND_EQ_BAND2_FREQUENCY] = {"",   0,   1,   0,   3,   0},
+    [SOUND_EQ_BAND3_FREQUENCY] = {"",   0,   1,   0,   3,   0},
+    [SOUND_EQ_BAND4_FREQUENCY] = {"",   0,   1,   0,   3,   0},
+    [SOUND_EQ_BAND5_FREQUENCY] = {"",   0,   1,   0,   3,   0},
+    [SOUND_EQ_BAND2_WIDTH]     = {"",   0,   1,   0,   1,   0},
+    [SOUND_EQ_BAND3_WIDTH]     = {"",   0,   1,   0,   1,   0},
+    [SOUND_EQ_BAND4_WIDTH]     = {"",   0,   1,   0,   1,   0},
+    [SOUND_DEPTH_3D]           = {"%",  0,   1,   0,  15,   0},
 #ifdef HAVE_RECORDING
     /* Digital: -119.0dB to +8.0dB in 0.5dB increments
      * Analog:  Relegated to volume control
      * Circumstances unfortunately do not allow a great deal of positive
      * gain. */
-    [SOUND_LEFT_GAIN]     = {"dB", 1,  1,-238,  16,   0},
-    [SOUND_RIGHT_GAIN]    = {"dB", 1,  1,-238,  16,   0},
+    [SOUND_LEFT_GAIN]          = {"dB", 1,   1,-238,  16,   0},
+    [SOUND_RIGHT_GAIN]         = {"dB", 1,   1,-238,  16,   0},
 #if 0
-    [SOUND_MIC_GAIN]      = {"dB", 1,  1,-238,  16,   0},
+    [SOUND_MIC_GAIN]           = {"dB", 1,   1,-238,  16,   0},
 #endif
 #endif
-#if 0
-    [SOUND_BASS_CUTOFF]   = {"",   0,  1,   1,   4,   1},
-    [SOUND_TREBLE_CUTOFF] = {"",   0,  1,   1,   4,   1},
-#endif
 };
 
 static uint16_t wmc_regs[WMC_NUM_REGISTERS] =
@@ -123,10 +131,20 @@ struct
 {
     int vol_l;
     int vol_r;
+    int dac_l;
+    int dac_r;
     bool ahw_mute;
+    int prescaler;
+    int enhance_3d_prescaler;
 } wmc_vol =
 {
-    0, 0, false
+    .vol_l = 0,
+    .vol_r = 0,
+    .dac_l = 0,
+    .dac_r = 0,
+    .ahw_mute = false,
+    .prescaler = 0,
+    .enhance_3d_prescaler = 0,
 };
 
 static void wmc_write(unsigned int reg, unsigned int val)
@@ -191,6 +209,10 @@ int sound_val2phys(int setting, int value)
         break;
 #endif
 
+    case SOUND_DEPTH_3D:
+        result = (100 * value + 8) / 15;
+        break;
+
     default:
         result = value;
     }
@@ -216,8 +238,12 @@ void audiohw_preinit(void)
     wmc_set(WMC_OUT4_MONO_MIXER_CTRL, WMC_MUTE);
 
     /* 3. Set L/RMIXEN = 1 and DACENL/R = 1 in register R3. */
-    wmc_write(WMC_POWER_MANAGEMENT3,
-              WMC_RMIXEN | WMC_LMIXEN | WMC_DACENR | WMC_DACENL);
+    wmc_write(WMC_POWER_MANAGEMENT3, WMC_RMIXEN | WMC_LMIXEN);
+
+    /* EQ and 3D applied to DAC (Set before DAC enable!) */
+    wmc_set(WMC_EQ1_LOW_SHELF, WMC_EQ3DMODE);
+
+    wmc_set(WMC_POWER_MANAGEMENT3, WMC_DACENR | WMC_DACENL);
 
     /* 4. Set BUFIOEN = 1 and VMIDSEL[1:0] to required value in register
      *    R1. Wait for VMID supply to settle */
@@ -305,6 +331,12 @@ void audiohw_set_headphone_vol(int vol_l, int vol_r)
     get_headphone_levels(vol_l, &dac_l, &hp_l, &mix_l, &boost_l);
     get_headphone_levels(vol_r, &dac_r, &hp_r, &mix_r, &boost_r);
 
+    wmc_vol.dac_l = dac_l;
+    wmc_vol.dac_r = dac_r;
+
+    dac_l -= wmc_vol.prescaler + wmc_vol.enhance_3d_prescaler;
+    dac_r -= wmc_vol.prescaler + wmc_vol.enhance_3d_prescaler;
+
     wmc_write_masked(WMC_LEFT_MIXER_CTRL, mix_l << WMC_BYPLMIXVOL_POS,
                      WMC_BYPLMIXVOL);
     wmc_write_masked(WMC_LEFT_ADC_BOOST_CTRL,
@@ -367,6 +399,64 @@ static void audiohw_mute(bool mute)
     }
 }
 
+/* Equalizer - set the eq band level -12 to +12 dB. */
+void audiohw_set_eq_band_gain(unsigned int band, int val)
+{
+    if (band > 4)
+        return;
+
+    wmc_write_masked(band + WMC_EQ1_LOW_SHELF, 12 - val, WMC_EQG);
+}
+
+/* Equalizer - set the eq band frequency index. */
+void audiohw_set_eq_band_frequency(unsigned int band, int val)
+{
+    if (band > 4)
+        return;
+
+    wmc_write_masked(band + WMC_EQ1_LOW_SHELF,
+                     val << WMC_EQC_POS, WMC_EQC);
+}
+
+/* Equalizer - set bandwidth for peaking filters to wide (!= 0) or
+ * narrow (0); only valid for peaking filter bands 1-3. */
+void audiohw_set_eq_band_width(unsigned int band, int val)
+{
+    if (band < 1 || band > 3)
+        return;
+
+    wmc_write_masked(band + WMC_EQ1_LOW_SHELF,
+                     (val == 0) ? 0 : WMC_EQBW, WMC_EQBW);
+}
+
+/* Set prescaler to prevent clipping the output amp when applying positive
+ * gain to EQ bands. */
+void audiohw_set_prescaler(int val)
+{
+    val *= 2;
+    wmc_vol.prescaler = val;
+    val += wmc_vol.enhance_3d_prescaler; /* Combine with 3D attenuation */
+
+    wmc_write_masked(WMC_LEFT_DAC_DIGITAL_VOL, wmc_vol.dac_l - val,
+                     WMC_DVOL);
+    wmc_write_masked(WMC_RIGHT_DAC_DIGITAL_VOL, wmc_vol.dac_r - val,
+                     WMC_DVOL);
+}
+
+/* Set the depth of the 3D effect */
+void audiohw_set_depth_3d(int val)
+{
+    int att = 10*val / 15; /* -5 dB @ full setting */
+    wmc_vol.enhance_3d_prescaler = att;
+    att += wmc_vol.prescaler;  /* Combine with prescaler attenuation */
+
+    wmc_write_masked(WMC_LEFT_DAC_DIGITAL_VOL, wmc_vol.dac_l - att,
+                     WMC_DVOL);
+    wmc_write_masked(WMC_RIGHT_DAC_DIGITAL_VOL, wmc_vol.dac_r - att,
+                     WMC_DVOL);
+    wmc_write_masked(WMC_3D_CONTROL, val, WMC_DEPTH3D);
+}
+
 void audiohw_close(void)
 {
     /* 1. Mute all analogue outputs */
index 22f6e68..12c4738 100644 (file)
 #include <stdbool.h>
 
 /* define some audiohw caps */
-#define TREBLE_CAP          (1 << 0)
-#define BASS_CAP            (1 << 1)
-#define BALANCE_CAP         (1 << 2)
-#define CLIPPING_CAP        (1 << 3)
-#define PRESCALER_CAP       (1 << 4)
-#define BASS_CUTOFF_CAP     (1 << 5)
-#define TREBLE_CUTOFF_CAP   (1 << 6)
+#define TREBLE_CAP            (1 << 0)
+#define BASS_CAP              (1 << 1)
+#define BALANCE_CAP           (1 << 2)
+#define CLIPPING_CAP          (1 << 3)
+#define PRESCALER_CAP         (1 << 4)
+#define BASS_CUTOFF_CAP       (1 << 5)
+#define TREBLE_CUTOFF_CAP     (1 << 6)
+#define EQ_CAP                (1 << 7)
+#define DEPTH_3D_CAP          (1 << 8)
 
 #ifdef HAVE_UDA1380
 #include "uda1380.h"
 #define VOLUME_MAX  0
 #endif
 
+#ifndef AUDIOHW_NUM_TONE_CONTROLS
+#define AUDIOHW_NUM_TONE_CONTROLS 0
+#endif
+
 /* volume/balance/treble/bass interdependency main part */
 #define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN)
 
 
 /* convert caps into defines */
 #ifdef AUDIOHW_CAPS
+/* Tone controls */
 #if (AUDIOHW_CAPS & TREBLE_CAP)
 #define AUDIOHW_HAVE_TREBLE
 #endif
 #define AUDIOHW_HAVE_BASS
 #endif
 
+#if (AUDIOHW_CAPS & BASS_CUTOFF_CAP)
+#define AUDIOHW_HAVE_BASS_CUTOFF
+#endif
+
+#if (AUDIOHW_CAPS & TREBLE_CUTOFF_CAP)
+#define AUDIOHW_HAVE_TREBLE_CUTOFF
+#endif
+
 #if (AUDIOHW_CAPS & BALANCE_CAP)
 #define AUDIOHW_HAVE_BALANCE
 #endif
 #define AUDIOHW_HAVE_PRESCALER
 #endif
 
-#if (AUDIOHW_CAPS & BASS_CUTOFF_CAP)
-#define AUDIOHW_HAVE_BASS_CUTOFF
+/* Hardware EQ tone controls */
+#if (AUDIOHW_CAPS & EQ_CAP)
+/* A hardware equalizer is present (or perhaps some tone control variation
+ * that is not Bass and/or Treble) */
+#define AUDIOHW_HAVE_EQ
+
+/* Defined band indexes for supported bands */
+enum
+{
+    /* Band 1 is implied; bands must be contiguous, 1 to N */
+    AUDIOHW_EQ_BAND1 = 0,
+#define AUDIOHW_HAVE_EQ_BAND1
+#if (AUDIOHW_EQ_BAND_CAPS & (EQ_CAP << 1))
+    AUDIOHW_EQ_BAND2,
+#define AUDIOHW_HAVE_EQ_BAND2
+#if (AUDIOHW_EQ_BAND_CAPS & (EQ_CAP << 2))
+    AUDIOHW_EQ_BAND3,
+#define AUDIOHW_HAVE_EQ_BAND3
+#if (AUDIOHW_EQ_BAND_CAPS & (EQ_CAP << 3))
+    AUDIOHW_EQ_BAND4,
+#define AUDIOHW_HAVE_EQ_BAND4
+#if (AUDIOHW_EQ_BAND_CAPS & (EQ_CAP << 4))
+    AUDIOHW_EQ_BAND5,
+#define AUDIOHW_HAVE_EQ_BAND5
+#endif /* 5 */
+#endif /* 4 */
+#endif /* 3 */
+#endif /* 2 */
+    AUDIOHW_EQ_BAND_NUM, /* Keep last */
+};
+
+#ifdef AUDIOHW_EQ_FREQUENCY_CAPS
+/* One or more bands supports frequency cutoff or center adjustment */
+#define AUDIOHW_HAVE_EQ_FREQUENCY
+enum
+{
+    __AUDIOHW_EQ_BAND_FREQUENCY = -1,
+#if defined(AUDIOHW_HAVE_EQ_BAND1) && \
+        (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 0))
+    AUDIOHW_EQ_BAND1_FREQUENCY,
+#define AUDIOHW_HAVE_EQ_BAND1_FREQUENCY
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND2) && \
+        (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 1))
+    AUDIOHW_EQ_BAND2_FREQUENCY,
+#define AUDIOHW_HAVE_EQ_BAND2_FREQUENCY
 #endif
+#if defined(AUDIOHW_HAVE_EQ_BAND3) && \
+        (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 2))
+    AUDIOHW_EQ_BAND3_FREQUENCY,
+#define AUDIOHW_HAVE_EQ_BAND3_FREQUENCY
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND4) && \
+        (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 3))
+    AUDIOHW_EQ_BAND4_FREQUENCY,
+#define AUDIOHW_HAVE_EQ_BAND4_FREQUENCY
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND5) && \
+        (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 4))
+    AUDIOHW_EQ_BAND5_FREQUENCY,
+#define AUDIOHW_HAVE_EQ_BAND5_FREQUENCY
+#endif
+    AUDIOHW_EQ_FREQUENCY_NUM,
+};
+#endif /* AUDIOHW_EQ_FREQUENCY_CAPS */
+
+#ifdef AUDIOHW_EQ_WIDTH_CAPS
+/* One or more bands supports bandwidth adjustment */
+#define AUDIOHW_HAVE_EQ_WIDTH
+enum
+{
+    __AUDIOHW_EQ_BAND_WIDTH = -1,
+#if defined(AUDIOHW_HAVE_EQ_BAND1) && \
+        (AUDIOHW_EQ_WIDTH_CAPS & (EQ_CAP << 1))
+    AUDIOHW_EQ_BAND2_WIDTH,
+#define AUDIOHW_HAVE_EQ_BAND2_WIDTH
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND2) && \
+        (AUDIOHW_EQ_WIDTH_CAPS & (EQ_CAP << 2))
+    AUDIOHW_EQ_BAND3_WIDTH,
+#define AUDIOHW_HAVE_EQ_BAND3_WIDTH
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND3) && \
+        (AUDIOHW_EQ_WIDTH_CAPS & (EQ_CAP << 3))
+    AUDIOHW_EQ_BAND4_WIDTH,
+#define AUDIOHW_HAVE_EQ_BAND4_WIDTH
+#endif
+    AUDIOHW_EQ_WIDTH_NUM, /* Keep last */
+};
+#endif /* AUDIOHW_EQ_WIDTH_CAPS */
+
+/* Types and number of settings types (gain, frequency, width) */
+enum AUDIOHW_EQ_SETTINGS
+{
+    AUDIOHW_EQ_GAIN = 0,
+#ifdef AUDIOHW_HAVE_EQ_FREQUENCY
+    AUDIOHW_EQ_FREQUENCY,
+#endif
+#ifdef AUDIOHW_HAVE_EQ_WIDTH
+    AUDIOHW_EQ_WIDTH,
+#endif
+    AUDIOHW_EQ_SETTING_NUM
+};
 
-#if (AUDIOHW_CAPS & TREBLE_CUTOFF_CAP)
-#define AUDIOHW_HAVE_TREBLE_CUTOFF
+#endif /* (AUDIOHW_CAPS & EQ_CAP) */
+
+#if (AUDIOHW_CAPS & DEPTH_3D_CAP)
+#define AUDIOHW_HAVE_DEPTH_3D
 #endif
+
 #endif /* AUDIOHW_CAPS */
 
 enum {
     SOUND_VOLUME = 0,
+/* Tone control */
+#if defined(AUDIOHW_HAVE_BASS)
     SOUND_BASS,
+#endif
+#if defined(AUDIOHW_HAVE_TREBLE)
     SOUND_TREBLE,
+#endif
     SOUND_BALANCE,
     SOUND_CHANNELS,
     SOUND_STEREO_WIDTH,
@@ -132,12 +255,61 @@ enum {
     SOUND_RIGHT_GAIN,
     SOUND_MIC_GAIN,
 #endif
+/* Bass and treble tone controls */
 #if defined(AUDIOHW_HAVE_BASS_CUTOFF)
     SOUND_BASS_CUTOFF,
 #endif
 #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
     SOUND_TREBLE_CUTOFF,
 #endif
+/* 3D effect */
+#if defined(AUDIOHW_HAVE_DEPTH_3D)
+    SOUND_DEPTH_3D,
+#endif
+/* Hardware EQ tone controls */
+/* Band gains */
+#if defined(AUDIOHW_HAVE_EQ)
+    /* Band 1 implied */
+    SOUND_EQ_BAND1_GAIN,
+#if defined(AUDIOHW_HAVE_EQ_BAND2)
+    SOUND_EQ_BAND2_GAIN,
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND3)
+    SOUND_EQ_BAND3_GAIN,
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND4)
+    SOUND_EQ_BAND4_GAIN,
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND5)
+    SOUND_EQ_BAND5_GAIN,
+#endif
+/* Band frequencies */
+#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
+    SOUND_EQ_BAND1_FREQUENCY,
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
+    SOUND_EQ_BAND2_FREQUENCY,
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
+    SOUND_EQ_BAND3_FREQUENCY,
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
+    SOUND_EQ_BAND4_FREQUENCY,
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
+    SOUND_EQ_BAND5_FREQUENCY,
+#endif
+/* Band widths */
+#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
+    SOUND_EQ_BAND2_WIDTH,
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
+    SOUND_EQ_BAND3_WIDTH,
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
+    SOUND_EQ_BAND4_WIDTH,
+#endif
+#endif /* AUDIOHW_HAVE_EQ */
     SOUND_LAST_SETTING, /* Keep this last */
 };
 
@@ -262,6 +434,64 @@ void audiohw_set_bass_cutoff(int val);
 void audiohw_set_treble_cutoff(int val);
 #endif
 
+#ifdef AUDIOHW_HAVE_EQ
+/**
+ * Set new band gain value.
+ * @param band index to which val is set
+ * @param val to set.
+ * NOTE: AUDIOHW_CAPS need to contain
+ *          EQ_CAP
+ *
+ *       AUDIOHW_EQ_BAND_CAPS must be defined as a bitmask
+ *       of EQ_CAP each shifted by the zero-based band number
+ *       for each band. Bands 1 to N are indexed 0 to N-1.
+ */
+void audiohw_set_eq_band_gain(unsigned int band, int val);
+#endif
+
+#ifdef AUDIOHW_HAVE_EQ_FREQUENCY
+/**
+ * Set new band cutoff or center frequency value.
+ * @param band index to which val is set
+ * @param val to set.
+ * NOTE: AUDIOHW_CAPS need to contain
+ *          EQ_CAP
+ *
+ *       AUDIOHW_EQ_FREQUENCY_CAPS must be defined as a bitmask
+ *       of EQ_CAP each shifted by the zero-based band number
+ *       for each band that supports frequency adjustment.
+ *       Bands 1 to N are indexed 0 to N-1.
+ */
+void audiohw_set_eq_band_frequency(unsigned int band, int val);
+#endif
+
+#ifdef AUDIOHW_HAVE_EQ_WIDTH
+/**
+ * Set new band cutoff or center frequency value.
+ * @param band index to which val is set
+ * @param val to set.
+ * NOTE: AUDIOHW_CAPS need to contain
+ *          EQ_CAP
+ *
+ *       AUDIOHW_EQ_WIDTH_CAPS must be defined as a bitmask
+ *       of EQ_CAP each shifted by the zero-based band number
+ *       for each band that supports width adjustment.
+ *       Bands 1 to N are indexed 0 to N-1.
+ */
+void audiohw_set_eq_band_width(unsigned int band, int val);
+#endif
+
+#ifdef AUDIOHW_HAVE_DEPTH_3D
+/**
+ * Set new 3-d enhancement (stereo expansion) effect value.
+ * @param val to set.
+ * NOTE: AUDIOHW_CAPS need to contain
+ *          DEPTH_3D_CAP
+ */
+void audiohw_set_depth_3d(int val);
+#endif
+
+
 void audiohw_set_frequency(int fsel);
 
 #ifdef HAVE_RECORDING
index 2bc56ec..73eb79c 100644 (file)
@@ -90,9 +90,6 @@
 /* Define this if you have the WM8978 audio codec */
 #define HAVE_WM8978
 
-/* Tone controls for WM8978 have not been implemented yet */
-#define HAVE_SW_TONE_CONTROLS
-
 /* Define bitmask of input sources - recordable bitmask can be defined
    explicitly if different */
 #define INPUT_SRC_CAPS SRC_CAP_FMRADIO
index e68ae23..7243f48 100644 (file)
@@ -55,10 +55,70 @@ void sound_set_bass(int value);
 void sound_set_treble(int value);
 void sound_set_channels(int value);
 void sound_set_stereo_width(int value);
-#if defined(HAVE_WM8758) || defined(HAVE_WM8985)
+#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
 void sound_set_bass_cutoff(int value);
+#endif
+#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
 void sound_set_treble_cutoff(int value);
 #endif
+
+#if defined(AUDIOHW_HAVE_DEPTH_3D)
+void sound_set_depth_3d(int value);
+#endif
+
+#ifdef AUDIOHW_HAVE_EQ
+/*
+ * band = SOUND_EQ_BANDb
+ * band_setting = AUDIOHW_EQ_s
+ *
+ * Returns SOUND_EQ_BANDb_s or -1 if it doesn't exist.
+ *
+ * b: band number
+ * s: one of GAIN, FREQUENCY, WIDTH
+ */
+int sound_enum_hw_eq_band_setting(unsigned int band,
+                                  unsigned int band_setting);
+/* Band1 implied */
+void sound_set_hw_eq_band1_gain(int value);
+#ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY
+void sound_set_hw_eq_band1_frequency(int value);
+#endif
+#ifdef AUDIOHW_HAVE_EQ_BAND2
+void sound_set_hw_eq_band2_gain(int value);
+#ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY
+void sound_set_hw_eq_band2_frequency(int value);
+#endif
+#ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH
+void sound_set_hw_eq_band2_width(int value);
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND2 */
+#ifdef AUDIOHW_HAVE_EQ_BAND3
+/* Band 3 */
+void sound_set_hw_eq_band3_gain(int value);
+#ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY
+void sound_set_hw_eq_band3_frequency(int value);
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
+void sound_set_hw_eq_band3_width(int value);
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND3 */
+#ifdef AUDIOHW_HAVE_EQ_BAND4
+void sound_set_hw_eq_band4_gain(int value);
+#ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY
+void sound_set_hw_eq_band4_frequency(int value);
+#endif
+#ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH
+void sound_set_hw_eq_band4_width(int value);
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND4 */
+#ifdef AUDIOHW_HAVE_EQ_BAND5
+void sound_set_hw_eq_band5_gain(int value);
+#ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY
+void sound_set_hw_eq_band5_frequency(int value);
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND5 */
+#endif /* AUDIOHW_HAVE_EQ */
+
 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
 void sound_set_loudness(int value);
 void sound_set_avc(int value);
index 270c666..4081d05 100644 (file)
 #define VOLUME_MIN -900
 #define VOLUME_MAX 60
 
+#define AUDIOHW_CAPS (EQ_CAP | PRESCALER_CAP | DEPTH_3D_CAP)
+/* Filter bitmask */
+#define AUDIOHW_EQ_BAND_CAPS      ((EQ_CAP << 0) | (EQ_CAP << 1) | \
+                                   (EQ_CAP << 2) | (EQ_CAP << 3) | \
+                                   (EQ_CAP << 4))
+/* Filters that can adjust cutoff and center frequency */
+#define AUDIOHW_EQ_FREQUENCY_CAPS ((EQ_CAP << 0) | (EQ_CAP << 1) | \
+                                   (EQ_CAP << 2) | (EQ_CAP << 3) | \
+                                   (EQ_CAP << 4))
+/* Filters that can adjust band width */
+#define AUDIOHW_EQ_WIDTH_CAPS     ((EQ_CAP << 1) | (EQ_CAP << 2) | \
+                                   (EQ_CAP << 3))
+
 int tenthdb2master(int db);
 void audiohw_set_headphone_vol(int vol_l, int vol_r);
 void audiohw_set_recsrc(int source, bool recording);
index b56e610..fb2f353 100644 (file)
@@ -48,8 +48,13 @@ extern void audiohw_set_volume(int value);
 /* dummy for sim */
 const struct sound_settings_info audiohw_settings[] = {
     [SOUND_VOLUME]        = {"dB", 0,  1, VOLUME_MIN / 10, VOLUME_MAX / 10, -25},
+/* Bass and treble tone controls */
+#ifdef AUDIOHW_HAVE_BASS
     [SOUND_BASS]          = {"dB", 0,  1, -24,  24,   0},
+#endif
+#ifdef AUDIOHW_HAVE_TREBLE
     [SOUND_TREBLE]        = {"dB", 0,  1, -24,  24,   0},
+#endif
     [SOUND_BALANCE]       = {"%",  0,  1,-100, 100,   0},
     [SOUND_CHANNELS]      = {"",   0,  1,   0,   5,   0},
     [SOUND_STEREO_WIDTH]  = {"%",  0,  5,   0, 250, 100},
@@ -64,6 +69,50 @@ const struct sound_settings_info audiohw_settings[] = {
 #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
     [SOUND_TREBLE_CUTOFF] = {"",   0,  1,   1,   4,   1},
 #endif
+#if defined(AUDIOHW_HAVE_DEPTH_3D)
+    [SOUND_DEPTH_3D]      = {"%",  0,   1,   0,  15,   0},
+#endif
+/* Hardware EQ tone controls */
+#if defined(AUDIOHW_HAVE_EQ_BAND1)
+    [SOUND_EQ_BAND1_GAIN] = {"dB", 0,  1, -12,  12,   0},
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND2)
+    [SOUND_EQ_BAND2_GAIN] = {"dB", 0,  1, -12,  12,   0},
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND3)
+    [SOUND_EQ_BAND3_GAIN] = {"dB", 0,  1, -12,  12,   0},
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND4)
+    [SOUND_EQ_BAND4_GAIN] = {"dB", 0,  1, -12,  12,   0},
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND5)
+    [SOUND_EQ_BAND5_GAIN] = {"dB", 0,  1, -12,  12,   0},
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
+    [SOUND_EQ_BAND1_FREQUENCY] = {"",   0,  1,   1,   4,   1},
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
+    [SOUND_EQ_BAND2_FREQUENCY] = {"",   0,  1,   1,   4,   1},
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
+    [SOUND_EQ_BAND3_FREQUENCY] = {"",   0,  1,   1,   4,   1},
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
+    [SOUND_EQ_BAND4_FREQUENCY] = {"",   0,  1,   1,   4,   1},
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
+    [SOUND_EQ_BAND5_FREQUENCY] = {"",   0,  1,   1,   4,   1},
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
+    [SOUND_EQ_BAND2_WIDTH]     = {"",   0,  1,   0,   1,   0},
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
+    [SOUND_EQ_BAND3_WIDTH]     = {"",   0,  1,   0,   1,   0},
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
+    [SOUND_EQ_BAND4_WIDTH]     = {"",   0,  1,   0,   1,   0},
+#endif
+
 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
     [SOUND_LOUDNESS]      = {"dB", 0,  1,   0,  17,   0},
     [SOUND_AVC]           = {"",   0,  1,  -1,   4,   0},
@@ -111,8 +160,12 @@ static sound_set_type * const sound_set_fns[] =
 {
     [0 ... SOUND_LAST_SETTING-1] = NULL,
     [SOUND_VOLUME]        = sound_set_volume,
+#if defined(AUDIOHW_HAVE_BASS)
     [SOUND_BASS]          = sound_set_bass,
+#endif
+#if defined(AUDIOHW_HAVE_TREBLE)
     [SOUND_TREBLE]        = sound_set_treble,
+#endif
     [SOUND_BALANCE]       = sound_set_balance,
     [SOUND_CHANNELS]      = sound_set_channels,
     [SOUND_STEREO_WIDTH]  = sound_set_stereo_width,
@@ -132,6 +185,49 @@ static sound_set_type * const sound_set_fns[] =
 #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
     [SOUND_TREBLE_CUTOFF] = sound_set_treble_cutoff,
 #endif
+#if defined(AUDIOHW_HAVE_DEPTH_3D)
+    [SOUND_DEPTH_3D]      = sound_set_depth_3d,
+#endif
+/* Hardware EQ tone controls */
+#if defined(AUDIOHW_HAVE_EQ)
+    [SOUND_EQ_BAND1_GAIN] = sound_set_hw_eq_band1_gain,
+#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
+    [SOUND_EQ_BAND1_FREQUENCY] = sound_set_hw_eq_band1_frequency,
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND2)
+    [SOUND_EQ_BAND2_GAIN] = sound_set_hw_eq_band2_gain,
+#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
+    [SOUND_EQ_BAND2_FREQUENCY] = sound_set_hw_eq_band2_frequency,
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
+    [SOUND_EQ_BAND2_WIDTH] = sound_set_hw_eq_band2_width,
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND2 */
+#if defined(AUDIOHW_HAVE_EQ_BAND3)
+    [SOUND_EQ_BAND3_GAIN] = sound_set_hw_eq_band3_gain,
+#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
+    [SOUND_EQ_BAND3_FREQUENCY] = sound_set_hw_eq_band3_frequency,
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
+    [SOUND_EQ_BAND3_WIDTH] = sound_set_hw_eq_band3_width,
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND3 */
+#if defined(AUDIOHW_HAVE_EQ_BAND4)
+    [SOUND_EQ_BAND4_GAIN] = sound_set_hw_eq_band4_gain,
+#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
+    [SOUND_EQ_BAND4_FREQUENCY] = sound_set_hw_eq_band4_frequency,
+#endif
+#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
+    [SOUND_EQ_BAND4_WIDTH] = sound_set_hw_eq_band4_width,
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND4 */
+#if defined(AUDIOHW_HAVE_EQ_BAND5)
+    [SOUND_EQ_BAND5_GAIN] = sound_set_hw_eq_band5_gain,
+#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
+    [SOUND_EQ_BAND5_FREQUENCY] = sound_set_hw_eq_band5_frequency,
+#endif
+#endif /* AUDIOHW_HAVE_EQ_BAND5 */
+#endif /* AUDIOHW_HAVE_EQ */
 };
 
 sound_set_type* sound_get_fn(int setting)
@@ -174,8 +270,15 @@ static int tenthdb2reg(int db)
 /* all values in tenth of dB    MAS3507D    UDA1380  */
 int current_volume = 0;    /* -780..+180  -840..   0 */
 int current_balance = 0;   /* -960..+960  -840..+840 */
+#ifdef AUDIOHW_HAVE_TREBLE
 int current_treble = 0;    /* -150..+150     0.. +60 */
+#endif
+#ifdef AUDIOHW_HAVE_BASS
 int current_bass = 0;      /* -150..+150     0..+240 */
+#endif
+#ifdef AUDIOHW_HAVE_EQ
+int current_eq_band_gain[AUDIOHW_EQ_BAND_NUM];
+#endif
 
 static void set_prescaled_volume(void)
 {
@@ -191,10 +294,18 @@ static void set_prescaled_volume(void)
     || defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \
     || defined(HAVE_WM8758) || defined(HAVE_WM8985) || defined(HAVE_UDA1341))
 
+#if defined(AUDIOHW_HAVE_BASS) && defined(AUDIOHW_HAVE_TREBLE)
     prescale = MAX(current_bass, current_treble);
+#endif
+#if defined(AUDIOHW_HAVE_EQ)
+    int i;
+    for (i = 0; i < AUDIOHW_EQ_BAND_NUM; i++)
+        prescale = MAX(current_eq_band_gain[i], prescale);
+#endif
+
     if (prescale < 0)
         prescale = 0;  /* no need to prescale if we don't boost
-                          bass or treble */
+                          bass, treble or eq band */
 
     /* Gain up the analog volume to compensate the prescale gain reduction,
      * but if this would push the volume over the top, reduce prescaling
@@ -289,6 +400,7 @@ void sound_set_balance(int value)
 #endif
 }
 
+#ifdef AUDIOHW_HAVE_BASS
 void sound_set_bass(int value)
 {
     if(!audio_is_initialized)
@@ -302,17 +414,19 @@ void sound_set_bass(int value)
 #endif
 #endif
 
-#if defined(AUDIOHW_HAVE_BASS)
-    audiohw_set_bass(value);
-#else
+#if defined(HAVE_SW_TONE_CONTROLS)
     dsp_callback(DSP_CALLBACK_SET_BASS, current_bass);
+#else
+    audiohw_set_bass(value);
 #endif
 
 #if !defined(AUDIOHW_HAVE_CLIPPING)
     set_prescaled_volume();
 #endif
 }
+#endif /* AUDIOHW_HAVE_BASS */
 
+#ifdef AUDIOHW_HAVE_TREBLE
 void sound_set_treble(int value)
 {
     if(!audio_is_initialized)
@@ -326,16 +440,37 @@ void sound_set_treble(int value)
 #endif
 #endif
 
-#if defined(AUDIOHW_HAVE_TREBLE)
-    audiohw_set_treble(value);
-#else
+#if defined(HAVE_SW_TONE_CONTROLS)
     dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble);
+#else
+    audiohw_set_treble(value);
 #endif
 
 #if !defined(AUDIOHW_HAVE_CLIPPING)
     set_prescaled_volume();
 #endif
 }
+#endif /* AUDIOHW_HAVE_TREBLE */
+
+#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
+void sound_set_bass_cutoff(int value)
+{
+    if(!audio_is_initialized)
+        return;
+
+    audiohw_set_bass_cutoff(value);
+}
+#endif
+
+#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
+void sound_set_treble_cutoff(int value)
+{
+    if(!audio_is_initialized)
+        return;
+
+    audiohw_set_treble_cutoff(value);
+}
+#endif
 
 void sound_set_channels(int value)
 {
@@ -361,26 +496,208 @@ void sound_set_stereo_width(int value)
 #endif
 }
 
-#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
-void sound_set_bass_cutoff(int value)
+#if defined(AUDIOHW_HAVE_DEPTH_3D)
+void sound_set_depth_3d(int value)
 {
     if(!audio_is_initialized)
         return;
 
-    audiohw_set_bass_cutoff(value);
+    audiohw_set_depth_3d(value);
 }
 #endif
 
-#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
-void sound_set_treble_cutoff(int value)
+#if defined(AUDIOHW_HAVE_EQ)
+int sound_enum_hw_eq_band_setting(unsigned int band,
+                                  unsigned int band_setting)
+{
+    static const int8_t
+    sound_hw_eq_band_setting[AUDIOHW_EQ_SETTING_NUM][AUDIOHW_EQ_BAND_NUM] =
+    {
+        [AUDIOHW_EQ_GAIN] =
+        {
+            [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1,
+            [AUDIOHW_EQ_BAND1] = SOUND_EQ_BAND1_GAIN,
+        #ifdef AUDIOHW_HAVE_EQ_BAND2
+            [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_GAIN,
+        #endif
+        #ifdef AUDIOHW_HAVE_EQ_BAND3
+            [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_GAIN,
+        #endif
+        #ifdef AUDIOHW_HAVE_EQ_BAND4
+            [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_GAIN,
+        #endif
+        #ifdef AUDIOHW_HAVE_EQ_BAND5
+            [AUDIOHW_EQ_BAND5] = SOUND_EQ_BAND5_GAIN,
+        #endif
+        },
+#ifdef AUDIOHW_HAVE_EQ_FREQUENCY
+        [AUDIOHW_EQ_FREQUENCY] =
+        {
+            [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1,
+        #ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY
+            [AUDIOHW_EQ_BAND1] = SOUND_EQ_BAND1_FREQUENCY,
+        #endif
+        #ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY
+            [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_FREQUENCY,
+        #endif
+        #ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY
+            [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_FREQUENCY,
+        #endif
+        #ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY
+            [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_FREQUENCY,
+        #endif
+        #ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY
+            [AUDIOHW_EQ_BAND5] = SOUND_EQ_BAND5_FREQUENCY,
+        #endif
+        },
+#endif /* AUDIOHW_HAVE_EQ_FREQUENCY */
+#ifdef AUDIOHW_HAVE_EQ_WIDTH
+        [AUDIOHW_EQ_WIDTH] =
+        {
+            [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1,
+        #ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH
+            [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_WIDTH,
+        #endif
+        #ifdef AUDIOHW_HAVE_EQ_BAND3_WIDTH
+            [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_WIDTH,
+        #endif
+        #ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH
+            [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_WIDTH,
+        #endif
+        },
+#endif /* AUDIOHW_HAVE_EQ_WIDTH */
+    };
+
+    if (band < AUDIOHW_EQ_BAND_NUM && band_setting < AUDIOHW_EQ_SETTING_NUM)
+        return sound_hw_eq_band_setting[band_setting][band];
+
+    return -1;
+}
+
+static void sound_set_hw_eq_band_gain(unsigned int band, int value)
 {
     if(!audio_is_initialized)
         return;
 
-    audiohw_set_treble_cutoff(value);
+    current_eq_band_gain[band] = value;
+    audiohw_set_eq_band_gain(band, value);
+    set_prescaled_volume();
+}
+
+void sound_set_hw_eq_band1_gain(int value)
+{
+    sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND1, value);
+}
+
+#if defined(AUDIOHW_HAVE_EQ_BAND2)
+void sound_set_hw_eq_band2_gain(int value)
+{
+    sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND2, value);
+}
+#endif
+
+#if defined(AUDIOHW_HAVE_EQ_BAND3)
+void sound_set_hw_eq_band3_gain(int value)
+{
+    sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND3, value);
 }
 #endif
 
+#if defined(AUDIOHW_HAVE_EQ_BAND4)
+void sound_set_hw_eq_band4_gain(int value)
+{
+    sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND4, value);
+}
+#endif
+
+#if defined(AUDIOHW_HAVE_EQ_BAND5)
+void sound_set_hw_eq_band5_gain(int value)
+{
+    sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND5, value);
+}
+#endif
+
+#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
+void sound_set_hw_eq_band1_frequency(int value)
+{
+    if(!audio_is_initialized)
+        return;
+
+    audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND1, value);
+}
+#endif
+
+#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
+void sound_set_hw_eq_band2_frequency(int value)
+{
+    if(!audio_is_initialized)
+        return;
+
+    audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND2, value);
+}
+#endif
+
+#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
+void sound_set_hw_eq_band3_frequency(int value)
+{
+    if(!audio_is_initialized)
+        return;
+
+    audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND3, value);
+}
+#endif
+
+#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
+void sound_set_hw_eq_band4_frequency(int value)
+{
+    if(!audio_is_initialized)
+        return;
+
+    audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND4, value);
+}
+#endif
+
+#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
+void sound_set_hw_eq_band5_frequency(int value)
+{
+    if(!audio_is_initialized)
+        return;
+
+    audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND5, value);
+}
+#endif
+
+#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
+void sound_set_hw_eq_band2_width(int value)
+{
+    if(!audio_is_initialized)
+        return;
+
+    audiohw_set_eq_band_width(AUDIOHW_EQ_BAND2, value);
+}
+#endif
+
+#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
+void sound_set_hw_eq_band3_width(int value)
+{
+    if(!audio_is_initialized)
+        return;
+
+    audiohw_set_eq_band_width(AUDIOHW_EQ_BAND3, value);
+}
+#endif
+
+#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
+void sound_set_hw_eq_band4_width(int value)
+{
+    if(!audio_is_initialized)
+        return;
+
+    audiohw_set_eq_band_width(AUDIOHW_EQ_BAND4, value);
+}
+#endif
+#endif /* AUDIOHW_HAVE_EQ */
+
 #if ((CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F))
 void sound_set_loudness(int value)
 {
@@ -572,6 +889,10 @@ int sound_val2phys(int setting, int value)
         break;
 #endif
 
+    case SOUND_DEPTH_3D:
+        result = (100 * value + 8) / 15;
+        break;
+
     default:
         result = value;
     }
index dd5e434..0f8d5d4 100644 (file)
@@ -385,6 +385,23 @@ void audiohw_set_bass_cutoff(int value) { (void)value; }
 #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
 void audiohw_set_treble_cutoff(int value){ (void)value; }
 #endif
+/* EQ-based tone controls */
+#if defined(AUDIOHW_HAVE_EQ)
+void audiohw_set_eq_band_gain(unsigned int band, int value)
+    { (void)band; (void)value; }
+#endif
+#if defined(AUDIOHW_HAVE_EQ_FREQUENCY)
+void audiohw_set_eq_band_frequency(unsigned int band, int value)
+    { (void)band; (void)value; }
+#endif
+#if defined(AUDIOHW_HAVE_EQ_WIDTH)
+void audiohw_set_eq_band_width(unsigned int band, int value)
+    { (void)band; (void)value; }
+#endif
+#if defined(AUDIOHW_HAVE_DEPTH_3D)
+void audiohw_set_depth_3d(int value)
+    { (void)value; }
+#endif
 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
 int mas_codec_readreg(int reg)
 {