summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/lang/english.lang29
-rw-r--r--apps/menus/eq_menu.c153
-rw-r--r--apps/menus/eq_menu.h11
-rw-r--r--apps/menus/sound_menu.c18
-rw-r--r--apps/playback.c7
-rw-r--r--apps/settings.c5
-rw-r--r--apps/settings.h27
-rw-r--r--apps/settings_list.c63
-rw-r--r--firmware/drivers/audio/wm8758.c53
-rw-r--r--firmware/export/audiohw.h4
-rw-r--r--firmware/export/sound.h4
-rw-r--r--firmware/export/wm8758.h8
-rw-r--r--firmware/sound.c50
13 files changed, 146 insertions, 286 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 1e7e5154bc..118a01ebb5 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -11478,3 +11478,32 @@
11478 *: "Say file type" 11478 *: "Say file type"
11479 </voice> 11479 </voice>
11480</phrase> 11480</phrase>
11481<phrase>
11482 id: LANG_BASS_CUTOFF
11483 desc: Bass setting cut-off frequency
11484 user:
11485 <source>
11486 *: "Bass Cutoff"
11487 </source>
11488 <dest>
11489 *: "Bass Cutoff"
11490 </dest>
11491 <voice>
11492 *: "Bass Cutoff"
11493 </voice>
11494</phrase>
11495<phrase>
11496 id: LANG_TREBLE_CUTOFF
11497 desc: Treble setting cut-off frequency
11498 user:
11499 <source>
11500 *: "Treble Cutoff"
11501 </source>
11502 <dest>
11503 *: "Treble Cutoff"
11504 </dest>
11505 <voice>
11506 *: "Treble Cutoff"
11507 </voice>
11508</phrase>
11509
diff --git a/apps/menus/eq_menu.c b/apps/menus/eq_menu.c
index 4dd8c06c65..2c2e596496 100644
--- a/apps/menus/eq_menu.c
+++ b/apps/menus/eq_menu.c
@@ -46,11 +46,6 @@
46#include "keyboard.h" 46#include "keyboard.h"
47#include "gui/scrollbar.h" 47#include "gui/scrollbar.h"
48#include "eq_menu.h" 48#include "eq_menu.h"
49#ifdef HAVE_WM8758
50#include "wm8758.h"
51#endif
52
53
54 49
55/* 50/*
56 * Utility functions 51 * Utility functions
@@ -667,151 +662,3 @@ MAKE_MENU(equalizer_menu, ID2P(LANG_EQUALIZER), soundmenu_callback, Icon_EQ,
667 &eq_enable, &eq_graphical, &eq_precut, &gain_menu, 662 &eq_enable, &eq_graphical, &eq_precut, &gain_menu,
668 &advanced_eq_menu_, &eq_save, &eq_browse); 663 &advanced_eq_menu_, &eq_save, &eq_browse);
669 664
670
671#ifdef HAVE_WM8758
672
673void eq_hw_gain_format(char* buffer, size_t buffer_size, int value,
674 const char* unit)
675{
676 snprintf(buffer, buffer_size, "%d %s", value, unit);
677}
678
679static int band0_callback(int action, const struct menu_item_ex *this_item)
680{
681 (void)this_item;
682 if (action == ACTION_EXIT_MENUITEM)
683 {
684#ifndef SIMULATOR
685 audiohw_set_equalizer_band(0, global_settings.eq_hw_band0_cutoff, 0,
686 global_settings.eq_hw_band0_gain);
687#endif
688 }
689 return action;
690}
691static int band1_callback(int action, const struct menu_item_ex *this_item)
692{
693 (void)this_item;
694 if (action == ACTION_EXIT_MENUITEM)
695 {
696#ifndef SIMULATOR
697 audiohw_set_equalizer_band(1, global_settings.eq_hw_band1_center,
698 global_settings.eq_hw_band1_bandwidth,
699 global_settings.eq_hw_band1_gain);
700#endif
701 }
702 return action;
703}
704static int band2_callback(int action, const struct menu_item_ex *this_item)
705{
706 (void)this_item;
707 if (action == ACTION_EXIT_MENUITEM)
708 {
709#ifndef SIMULATOR
710 audiohw_set_equalizer_band(2, global_settings.eq_hw_band2_center,
711 global_settings.eq_hw_band2_bandwidth,
712 global_settings.eq_hw_band2_gain);
713#endif
714 }
715 return action;
716}
717static int band3_callback(int action, const struct menu_item_ex *this_item)
718{
719 (void)this_item;
720 if (action == ACTION_EXIT_MENUITEM)
721 {
722#ifndef SIMULATOR
723 audiohw_set_equalizer_band(3, global_settings.eq_hw_band3_center,
724 global_settings.eq_hw_band3_bandwidth,
725 global_settings.eq_hw_band3_gain);
726#endif
727 }
728 return action;
729}
730static int band4_callback(int action, const struct menu_item_ex *this_item)
731{
732 (void)this_item;
733 if (action == ACTION_EXIT_MENUITEM)
734 {
735#ifndef SIMULATOR
736 audiohw_set_equalizer_band(4, global_settings.eq_hw_band4_cutoff, 0,
737 global_settings.eq_hw_band4_gain);
738#endif
739 }
740 return action;
741}
742void eq_hw_enable(bool enable)
743{
744#ifdef SIMULATOR
745 (void) enable;
746#else
747 if (enable) {
748 audiohw_set_equalizer_band(0, global_settings.eq_hw_band0_cutoff,
749 0, global_settings.eq_hw_band0_gain);
750 audiohw_set_equalizer_band(1, global_settings.eq_hw_band1_center,
751 global_settings.eq_hw_band1_bandwidth,
752 global_settings.eq_hw_band1_gain);
753 audiohw_set_equalizer_band(2, global_settings.eq_hw_band2_center,
754 global_settings.eq_hw_band2_bandwidth,
755 global_settings.eq_hw_band2_gain);
756 audiohw_set_equalizer_band(3, global_settings.eq_hw_band3_center,
757 global_settings.eq_hw_band3_bandwidth,
758 global_settings.eq_hw_band3_gain);
759 audiohw_set_equalizer_band(4, global_settings.eq_hw_band4_cutoff,
760 0, global_settings.eq_hw_band4_gain);
761 } else {
762 audiohw_set_equalizer_band(0, global_settings.eq_hw_band0_cutoff, 0, 0);
763 audiohw_set_equalizer_band(1, global_settings.eq_hw_band1_center,
764 global_settings.eq_hw_band1_bandwidth, 0);
765 audiohw_set_equalizer_band(2, global_settings.eq_hw_band2_center,
766 global_settings.eq_hw_band2_bandwidth, 0);
767 audiohw_set_equalizer_band(3, global_settings.eq_hw_band3_center,
768 global_settings.eq_hw_band3_bandwidth, 0);
769 audiohw_set_equalizer_band(4, global_settings.eq_hw_band4_cutoff, 0, 0);
770 }
771#endif
772}
773static int hweq_enable_callback(int action, const struct menu_item_ex *this_item)
774{
775 (void)this_item;
776 if (action == ACTION_EXIT_MENUITEM)
777 {
778 eq_hw_enable(global_settings.eq_hw_enabled);
779 }
780 return action;
781}
782MENUITEM_SETTING(hw_eq_enable, &global_settings.eq_hw_enabled, hweq_enable_callback);
783
784MENUITEM_SETTING(hw_eq_cutoff_0, &global_settings.eq_hw_band0_cutoff, band0_callback);
785MENUITEM_SETTING(hw_eq_gain_0, &global_settings.eq_hw_band0_gain, band0_callback);
786MAKE_MENU(hw_eq_band0, ID2P(LANG_EQUALIZER_BAND_LOW_SHELF), NULL, Icon_NOICON,
787 &hw_eq_cutoff_0, &hw_eq_gain_0);
788
789MENUITEM_SETTING(hw_eq_cutoff_1, &global_settings.eq_hw_band1_center, band1_callback);
790MENUITEM_SETTING(hw_eq_bandwidth_1, &global_settings.eq_hw_band1_bandwidth, band1_callback);
791MENUITEM_SETTING(hw_eq_gain_1, &global_settings.eq_hw_band1_gain, band1_callback);
792MAKE_MENU(hw_eq_band1, "Peak Filter 1", NULL, Icon_NOICON,
793 &hw_eq_cutoff_1, &hw_eq_bandwidth_1, &hw_eq_gain_1);
794
795MENUITEM_SETTING(hw_eq_cutoff_2, &global_settings.eq_hw_band2_center, band2_callback);
796MENUITEM_SETTING(hw_eq_bandwidth_2, &global_settings.eq_hw_band2_bandwidth, band2_callback);
797MENUITEM_SETTING(hw_eq_gain_2, &global_settings.eq_hw_band2_gain, band2_callback);
798MAKE_MENU(hw_eq_band2, "Peak Filter 2", NULL, Icon_NOICON,
799 &hw_eq_cutoff_2, &hw_eq_bandwidth_2, &hw_eq_gain_2);
800
801MENUITEM_SETTING(hw_eq_cutoff_3, &global_settings.eq_hw_band3_center, band3_callback);
802MENUITEM_SETTING(hw_eq_bandwidth_3, &global_settings.eq_hw_band3_bandwidth, band3_callback);
803MENUITEM_SETTING(hw_eq_gain_3, &global_settings.eq_hw_band3_gain, band3_callback);
804MAKE_MENU(hw_eq_band3, "Peak Filter 3", NULL, Icon_NOICON,
805 &hw_eq_cutoff_3, &hw_eq_bandwidth_3, &hw_eq_gain_3);
806
807MENUITEM_SETTING(hw_eq_cutoff_4, &global_settings.eq_hw_band4_cutoff, band4_callback);
808MENUITEM_SETTING(hw_eq_gain_4, &global_settings.eq_hw_band4_gain, band4_callback);
809MAKE_MENU(hw_eq_band4, ID2P(LANG_EQUALIZER_BAND_HIGH_SHELF), NULL, Icon_NOICON,
810 &hw_eq_cutoff_4, &hw_eq_gain_4);
811
812MAKE_MENU(hw_eq_menu, ID2P(LANG_EQUALIZER_HARDWARE), NULL, Icon_EQ,
813 &hw_eq_enable, &hw_eq_band0, &hw_eq_band1,
814 &hw_eq_band2, &hw_eq_band3, &hw_eq_band4);
815
816
817#endif
diff --git a/apps/menus/eq_menu.h b/apps/menus/eq_menu.h
index b101ff36ed..ebeedff787 100644
--- a/apps/menus/eq_menu.h
+++ b/apps/menus/eq_menu.h
@@ -44,16 +44,5 @@ bool eq_menu_graphical(void);
44void eq_gain_format(char* buffer, size_t buffer_size, int value, const char* unit); 44void eq_gain_format(char* buffer, size_t buffer_size, int value, const char* unit);
45void eq_q_format(char* buffer, size_t buffer_size, int value, const char* unit); 45void eq_q_format(char* buffer, size_t buffer_size, int value, const char* unit);
46void eq_precut_format(char* buffer, size_t buffer_size, int value, const char* unit); 46void eq_precut_format(char* buffer, size_t buffer_size, int value, const char* unit);
47#ifdef HAVE_WM8758
48void eq_hw_gain_format(char* buffer, size_t buffer_size, int value,
49 const char* unit);
50/* WM8758 equalizer supports -12 to +12 dB gain in 1 dB increments. */
51#define EQ_HW_GAIN_STEP 1
52#define EQ_HW_GAIN_MIN -12
53#define EQ_HW_GAIN_MAX 12
54
55bool eq_hw_menu(void);
56void eq_hw_enable(bool enable);
57#endif
58 47
59#endif 48#endif
diff --git a/apps/menus/sound_menu.c b/apps/menus/sound_menu.c
index 4d6a3e2095..127b01d342 100644
--- a/apps/menus/sound_menu.c
+++ b/apps/menus/sound_menu.c
@@ -58,7 +58,13 @@ int soundmenu_callback(int action, const struct menu_item_ex *this_item)
58 58
59MENUITEM_SETTING(volume, &global_settings.volume, soundmenu_callback); 59MENUITEM_SETTING(volume, &global_settings.volume, soundmenu_callback);
60MENUITEM_SETTING(bass, &global_settings.bass, soundmenu_callback); 60MENUITEM_SETTING(bass, &global_settings.bass, soundmenu_callback);
61#ifdef HAVE_WM8758
62MENUITEM_SETTING(bass_cutoff, &global_settings.bass_cutoff, soundmenu_callback);
63#endif
61MENUITEM_SETTING(treble, &global_settings.treble, soundmenu_callback); 64MENUITEM_SETTING(treble, &global_settings.treble, soundmenu_callback);
65#ifdef HAVE_WM8758
66MENUITEM_SETTING(treble_cutoff, &global_settings.treble_cutoff, soundmenu_callback);
67#endif
62MENUITEM_SETTING(balance, &global_settings.balance, soundmenu_callback); 68MENUITEM_SETTING(balance, &global_settings.balance, soundmenu_callback);
63MENUITEM_SETTING(channel_config, &global_settings.channel_config, soundmenu_callback); 69MENUITEM_SETTING(channel_config, &global_settings.channel_config, soundmenu_callback);
64MENUITEM_SETTING(stereo_width, &global_settings.stereo_width, soundmenu_callback); 70MENUITEM_SETTING(stereo_width, &global_settings.stereo_width, soundmenu_callback);
@@ -97,14 +103,18 @@ MENUITEM_SETTING(stereo_width, &global_settings.stereo_width, soundmenu_callback
97 103
98MAKE_MENU(sound_settings, ID2P(LANG_SOUND_SETTINGS), NULL, Icon_Audio, 104MAKE_MENU(sound_settings, ID2P(LANG_SOUND_SETTINGS), NULL, Icon_Audio,
99 &volume, 105 &volume,
100 &bass,&treble, 106 &bass,
107#ifdef HAVE_WM8758
108 &bass_cutoff,
109#endif
110 &treble,
111#ifdef HAVE_WM8758
112 &treble_cutoff,
113#endif
101 &balance,&channel_config,&stereo_width 114 &balance,&channel_config,&stereo_width
102#if CONFIG_CODEC == SWCODEC 115#if CONFIG_CODEC == SWCODEC
103 ,&crossfeed_menu, &equalizer_menu, &dithering_enabled 116 ,&crossfeed_menu, &equalizer_menu, &dithering_enabled
104#endif 117#endif
105#ifdef HAVE_WM8758
106 ,&hw_eq_menu
107#endif
108#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 118#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
109 ,&loudness,&avc,&superbass,&mdb_enable,&mdb_strength 119 ,&loudness,&avc,&superbass,&mdb_enable,&mdb_strength
110 ,&mdb_harmonics,&mdb_center,&mdb_shape 120 ,&mdb_harmonics,&mdb_center,&mdb_shape
diff --git a/apps/playback.c b/apps/playback.c
index a880e4ef13..5e42b7629d 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -83,10 +83,6 @@
83#include "talk.h" 83#include "talk.h"
84#endif 84#endif
85 85
86#ifdef HAVE_WM8758
87#include "menus/eq_menu.h"
88#endif
89
90#define PLAYBACK_VOICE 86#define PLAYBACK_VOICE
91 87
92/* default point to start buffer refill */ 88/* default point to start buffer refill */
@@ -2601,9 +2597,6 @@ void audio_init(void)
2601 audio_is_initialized = true; 2597 audio_is_initialized = true;
2602 2598
2603 sound_settings_apply(); 2599 sound_settings_apply();
2604#ifdef HAVE_WM8758
2605 eq_hw_enable(global_settings.eq_hw_enabled);
2606#endif
2607#ifndef HAVE_FLASH_STORAGE 2600#ifndef HAVE_FLASH_STORAGE
2608 audio_set_buffer_margin(global_settings.buffer_margin); 2601 audio_set_buffer_margin(global_settings.buffer_margin);
2609#endif 2602#endif
diff --git a/apps/settings.c b/apps/settings.c
index 0b82ad41ac..6467a0e4d6 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -648,6 +648,11 @@ void sound_settings_apply(void)
648 sound_set(SOUND_SUPERBASS, global_settings.superbass); 648 sound_set(SOUND_SUPERBASS, global_settings.superbass);
649#endif 649#endif
650 650
651#ifdef HAVE_WM8758
652 sound_set(SOUND_BASS_CUTOFF, global_settings.bass_cutoff);
653 sound_set(SOUND_TREBLE_CUTOFF, global_settings.treble_cutoff);
654#endif
655
651#ifdef HAVE_USB_POWER 656#ifdef HAVE_USB_POWER
652#if CONFIG_CHARGING 657#if CONFIG_CHARGING
653 usb_charging_enable(global_settings.usb_charging); 658 usb_charging_enable(global_settings.usb_charging);
diff --git a/apps/settings.h b/apps/settings.h
index e5a2b1790b..369c7fdb4b 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -306,6 +306,11 @@ struct user_settings
306 bool superbass; /* true/false */ 306 bool superbass; /* true/false */
307#endif 307#endif
308 308
309#ifdef HAVE_WM8758
310 int bass_cutoff;
311 int treble_cutoff;
312#endif
313
309#if CONFIG_CODEC == SWCODEC 314#if CONFIG_CODEC == SWCODEC
310 int crossfade; /* Enable crossfade (0=off,1=shuffle,2=trackskip,3=shuff&trackskip,4=always) */ 315 int crossfade; /* Enable crossfade (0=off,1=shuffle,2=trackskip,3=shuff&trackskip,4=always) */
311 int crossfade_fade_in_delay; /* Fade in delay (0-15s) */ 316 int crossfade_fade_in_delay; /* Fade in delay (0-15s) */
@@ -616,6 +621,7 @@ struct user_settings
616 bool dithering_enabled; 621 bool dithering_enabled;
617#endif 622#endif
618 623
624
619#if LCD_DEPTH > 1 625#if LCD_DEPTH > 1
620 unsigned char backdrop_file[MAX_FILENAME+1]; /* backdrop bitmap file */ 626 unsigned char backdrop_file[MAX_FILENAME+1]; /* backdrop bitmap file */
621#endif 627#endif
@@ -656,27 +662,6 @@ struct user_settings
656#endif 662#endif
657#endif 663#endif
658 664
659#ifdef HAVE_WM8758
660 bool eq_hw_enabled; /* Enable hardware equalizer */
661
662 int eq_hw_band0_cutoff;
663 int eq_hw_band0_gain;
664
665 int eq_hw_band1_center;
666 int eq_hw_band1_bandwidth;
667 int eq_hw_band1_gain;
668
669 int eq_hw_band2_center;
670 int eq_hw_band2_bandwidth;
671 int eq_hw_band2_gain;
672
673 int eq_hw_band3_center;
674 int eq_hw_band3_bandwidth;
675 int eq_hw_band3_gain;
676
677 int eq_hw_band4_cutoff;
678 int eq_hw_band4_gain;
679#endif
680 bool hold_lr_for_scroll_in_list; /* hold L/R scrolls the list left/right */ 665 bool hold_lr_for_scroll_in_list; /* hold L/R scrolls the list left/right */
681 int show_path_in_browser; /* 0=off, 1=current directory, 2=full path */ 666 int show_path_in_browser; /* 0=off, 1=current directory, 2=full path */
682 667
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 6aa816f6fe..ea1e2f9bcb 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -1001,6 +1001,12 @@ const struct settings_list settings[] = {
1001 OFFON_SETTING(0, dithering_enabled, LANG_DITHERING, 1001 OFFON_SETTING(0, dithering_enabled, LANG_DITHERING,
1002 false, "dithering enabled", dsp_dither_enable), 1002 false, "dithering enabled", dsp_dither_enable),
1003#endif 1003#endif
1004#ifdef HAVE_WM8758
1005 SOUND_SETTING(F_NO_WRAP, bass_cutoff, LANG_BASS_CUTOFF, "bass cutoff",
1006 SOUND_BASS_CUTOFF),
1007 SOUND_SETTING(F_NO_WRAP, treble_cutoff, LANG_TREBLE_CUTOFF, "treble cutoff",
1008 SOUND_TREBLE_CUTOFF),
1009#endif
1004#ifdef HAVE_DIRCACHE 1010#ifdef HAVE_DIRCACHE
1005 OFFON_SETTING(0,dircache,LANG_DIRCACHE_ENABLE,false,"dircache",NULL), 1011 OFFON_SETTING(0,dircache,LANG_DIRCACHE_ENABLE,false,"dircache",NULL),
1006 SYSTEM_SETTING(NVRAM(4),dircache_size,0), 1012 SYSTEM_SETTING(NVRAM(4),dircache_size,0),
@@ -1059,63 +1065,6 @@ const struct settings_list settings[] = {
1059#endif 1065#endif
1060#endif /* HAVE_BACKLIGHT */ 1066#endif /* HAVE_BACKLIGHT */
1061 1067
1062#ifdef HAVE_WM8758
1063 OFFON_SETTING(0,eq_hw_enabled,LANG_EQUALIZER_HARDWARE_ENABLED,false,
1064 "eq hardware enabled",NULL),
1065
1066 STRINGCHOICE_SETTING(0, eq_hw_band0_cutoff, LANG_EQUALIZER_BAND_CUTOFF, 1,
1067 "eq hardware band 0 cutoff", "80Hz,105Hz,135Hz,175Hz", NULL, 4,
1068 TALK_ID(80, UNIT_HERTZ), TALK_ID(105, UNIT_HERTZ),
1069 TALK_ID(135, UNIT_HERTZ), TALK_ID(175, UNIT_HERTZ)),
1070 INT_SETTING(0, eq_hw_band0_gain, LANG_GAIN, 0,
1071 "eq hardware band 0 gain", UNIT_DB, EQ_HW_GAIN_MIN,
1072 EQ_HW_GAIN_MAX, EQ_HW_GAIN_STEP, eq_hw_gain_format, NULL, NULL),
1073
1074 STRINGCHOICE_SETTING(0, eq_hw_band1_center, LANG_EQUALIZER_BAND_CENTER, 1,
1075 "eq hardware band 1 center", "230Hz,300Hz,385Hz,500Hz", NULL, 4,
1076 TALK_ID(230, UNIT_HERTZ), TALK_ID(300, UNIT_HERTZ),
1077 TALK_ID(385, UNIT_HERTZ), TALK_ID(500, UNIT_HERTZ)),
1078 CHOICE_SETTING(0, eq_hw_band1_bandwidth, LANG_EQUALIZER_BANDWIDTH, 0,
1079 "eq hardware band 1 bandwidth", "narrow,wide", NULL, 2,
1080 ID2P(LANG_EQUALIZER_HARDWARE_BANDWIDTH_NARROW),
1081 ID2P(LANG_EQUALIZER_HARDWARE_BANDWIDTH_WIDE)),
1082 INT_SETTING(0, eq_hw_band1_gain, LANG_GAIN, 0,
1083 "eq hardware band 1 gain", UNIT_DB, EQ_HW_GAIN_MIN,
1084 EQ_HW_GAIN_MAX, EQ_HW_GAIN_STEP, eq_hw_gain_format, NULL, NULL),
1085
1086 STRINGCHOICE_SETTING(0, eq_hw_band2_center, LANG_EQUALIZER_BAND_CENTER, 1,
1087 "eq hardware band 2 center", "650Hz,850Hz,1.1kHz,1.4kHz", NULL, 4,
1088 TALK_ID(650, UNIT_HERTZ), TALK_ID(850, UNIT_HERTZ),
1089 TALK_ID(1100, UNIT_HERTZ), TALK_ID(1400, UNIT_HERTZ)),
1090 CHOICE_SETTING(0, eq_hw_band2_bandwidth, LANG_EQUALIZER_BANDWIDTH, 0,
1091 "eq hardware band 2 bandwidth", "narrow,wide", NULL, 2,
1092 ID2P(LANG_EQUALIZER_HARDWARE_BANDWIDTH_NARROW),
1093 ID2P(LANG_EQUALIZER_HARDWARE_BANDWIDTH_WIDE)),
1094 INT_SETTING(0, eq_hw_band2_gain, LANG_GAIN, 0,
1095 "eq hardware band 2 gain", UNIT_DB, EQ_HW_GAIN_MIN,
1096 EQ_HW_GAIN_MAX, EQ_HW_GAIN_STEP, eq_hw_gain_format, NULL, NULL),
1097
1098 STRINGCHOICE_SETTING(0, eq_hw_band3_center, LANG_EQUALIZER_BAND_CENTER, 1,
1099 "eq hardware band 3 center", "1.8kHz,2.4kHz,3.2kHz,4.1kHz", NULL, 4,
1100 TALK_ID(1800, UNIT_HERTZ), TALK_ID(2400, UNIT_HERTZ),
1101 TALK_ID(3200, UNIT_HERTZ), TALK_ID(4100, UNIT_HERTZ)),
1102 CHOICE_SETTING(0, eq_hw_band3_bandwidth, LANG_EQUALIZER_BANDWIDTH, 0,
1103 "eq hardware band 3 bandwidth", "narrow,wide", NULL, 2,
1104 ID2P(LANG_EQUALIZER_HARDWARE_BANDWIDTH_NARROW),
1105 ID2P(LANG_EQUALIZER_HARDWARE_BANDWIDTH_WIDE)),
1106 INT_SETTING(0, eq_hw_band3_gain, LANG_GAIN, 0,
1107 "eq hardware band 3 gain", UNIT_DB, EQ_HW_GAIN_MIN,
1108 EQ_HW_GAIN_MAX, EQ_HW_GAIN_STEP, eq_hw_gain_format, NULL, NULL),
1109
1110 STRINGCHOICE_SETTING(0, eq_hw_band4_cutoff, LANG_EQUALIZER_BAND_CUTOFF, 1,
1111 "eq hardware band 4 cutoff", "5.3kHz,6.9kHz,9kHz,11.7kHz", NULL, 4,
1112 TALK_ID(5300, UNIT_HERTZ), TALK_ID(6900, UNIT_HERTZ),
1113 TALK_ID(9000, UNIT_HERTZ), TALK_ID(11700, UNIT_HERTZ)),
1114 INT_SETTING(0, eq_hw_band4_gain, LANG_GAIN, 0,
1115 "eq hardware band 4 gain", UNIT_DB, EQ_HW_GAIN_MIN,
1116 EQ_HW_GAIN_MAX, EQ_HW_GAIN_STEP, eq_hw_gain_format, NULL, NULL),
1117#endif
1118
1119 OFFON_SETTING(0,hold_lr_for_scroll_in_list,-1,true, 1068 OFFON_SETTING(0,hold_lr_for_scroll_in_list,-1,true,
1120 "hold_lr_for_scroll_in_list",NULL), 1069 "hold_lr_for_scroll_in_list",NULL),
1121 CHOICE_SETTING(0, show_path_in_browser, LANG_SHOW_PATH, SHOW_PATH_OFF, 1070 CHOICE_SETTING(0, show_path_in_browser, LANG_SHOW_PATH, SHOW_PATH_OFF,
diff --git a/firmware/drivers/audio/wm8758.c b/firmware/drivers/audio/wm8758.c
index 1cfac7c7cb..a9f10fbe67 100644
--- a/firmware/drivers/audio/wm8758.c
+++ b/firmware/drivers/audio/wm8758.c
@@ -33,16 +33,22 @@
33 33
34const struct sound_settings_info audiohw_settings[] = { 34const struct sound_settings_info audiohw_settings[] = {
35 [SOUND_VOLUME] = {"dB", 0, 1, -58, 6, -25}, 35 [SOUND_VOLUME] = {"dB", 0, 1, -58, 6, -25},
36 [SOUND_BASS] = {"dB", 0, 1, -6, 9, 0}, 36 [SOUND_BASS] = {"dB", 0, 1, -12, 12, 0},
37 [SOUND_TREBLE] = {"dB", 0, 1, -6, 9, 0}, 37 [SOUND_TREBLE] = {"dB", 0, 1, -12, 12, 0},
38 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, 38 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
39 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, 39 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
40 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, 40 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
41 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0}, 41 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
42 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0}, 42 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
43 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16}, 43 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
44 [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1},
45 [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1},
44}; 46};
45 47
48/* shadow registers */
49unsigned int eq1_reg;
50unsigned int eq5_reg;
51
46/* convert tenth of dB volume (-57..6) to master volume register value */ 52/* convert tenth of dB volume (-57..6) to master volume register value */
47int tenthdb2master(int db) 53int tenthdb2master(int db)
48{ 54{
@@ -138,15 +144,28 @@ int audiohw_set_mixer_vol(int channel1, int channel2)
138 return 0; 144 return 0;
139} 145}
140 146
141/* We are using Linear bass control */
142void audiohw_set_bass(int value) 147void audiohw_set_bass(int value)
143{ 148{
144 (void)value; 149 eq1_reg = (eq1_reg & ~EQ_GAIN_MASK) | EQ_GAIN_VALUE(value);
150 wmcodec_write(EQ1, 0x100 | eq1_reg);
151}
152
153void audiohw_set_bass_cutoff(int value)
154{
155 eq1_reg = (eq1_reg & ~EQ_CUTOFF_MASK) | EQ_CUTOFF_VALUE(value);
156 wmcodec_write(EQ1, 0x100 | eq1_reg);
145} 157}
146 158
147void audiohw_set_treble(int value) 159void audiohw_set_treble(int value)
148{ 160{
149 (void)value; 161 eq5_reg = (eq5_reg & ~EQ_GAIN_MASK) | EQ_GAIN_VALUE(value);
162 wmcodec_write(EQ5, eq5_reg);
163}
164
165void audiohw_set_treble_cutoff(int value)
166{
167 eq5_reg = (eq5_reg & ~EQ_CUTOFF_MASK) | EQ_CUTOFF_VALUE(value);
168 wmcodec_write(EQ5, eq5_reg);
150} 169}
151 170
152void audiohw_mute(bool mute) 171void audiohw_mute(bool mute)
@@ -271,27 +290,3 @@ void audiohw_set_monitor(bool enable) {
271 (void)enable; 290 (void)enable;
272} 291}
273 292
274void audiohw_set_equalizer_band(int band, int freq, int bw, int gain)
275{
276 unsigned int eq = 0;
277
278 /* Band 1..3 are peak filters */
279 if (band >= 1 && band <= 3) {
280 eq |= (bw << 8);
281 }
282
283 eq |= (freq << 5);
284 eq |= 12 - gain;
285
286 if (band == 0) {
287 wmcodec_write(EQ1, eq | 0x100); /* Always apply EQ to the DAC path */
288 } else if (band == 1) {
289 wmcodec_write(EQ2, eq);
290 } else if (band == 2) {
291 wmcodec_write(EQ3, eq);
292 } else if (band == 3) {
293 wmcodec_write(EQ4, eq);
294 } else if (band == 4) {
295 wmcodec_write(EQ5, eq);
296 }
297}
diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h
index c5093a151a..5dc7550478 100644
--- a/firmware/export/audiohw.h
+++ b/firmware/export/audiohw.h
@@ -67,6 +67,10 @@ enum {
67 SOUND_RIGHT_GAIN, 67 SOUND_RIGHT_GAIN,
68 SOUND_MIC_GAIN, 68 SOUND_MIC_GAIN,
69#endif 69#endif
70#ifdef HAVE_WM8758
71 SOUND_BASS_CUTOFF,
72 SOUND_TREBLE_CUTOFF,
73#endif
70}; 74};
71 75
72enum Channel { 76enum Channel {
diff --git a/firmware/export/sound.h b/firmware/export/sound.h
index 929b83b9e6..5933f4cc75 100644
--- a/firmware/export/sound.h
+++ b/firmware/export/sound.h
@@ -41,6 +41,10 @@ void sound_set_bass(int value);
41void sound_set_treble(int value); 41void sound_set_treble(int value);
42void sound_set_channels(int value); 42void sound_set_channels(int value);
43void sound_set_stereo_width(int value); 43void sound_set_stereo_width(int value);
44#ifdef HAVE_WM8758
45void sound_set_bass_cutoff(int value);
46void sound_set_treble_cutoff(int value);
47#endif
44#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 48#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
45void sound_set_loudness(int value); 49void sound_set_loudness(int value);
46void sound_set_avc(int value); 50void sound_set_avc(int value);
diff --git a/firmware/export/wm8758.h b/firmware/export/wm8758.h
index 6d3220a5fc..df60851550 100644
--- a/firmware/export/wm8758.h
+++ b/firmware/export/wm8758.h
@@ -32,12 +32,12 @@ extern int audiohw_set_master_vol(int vol_l, int vol_r);
32extern int audiohw_set_lineout_vol(int vol_l, int vol_r); 32extern int audiohw_set_lineout_vol(int vol_l, int vol_r);
33extern int audiohw_set_mixer_vol(int channel1, int channel2); 33extern int audiohw_set_mixer_vol(int channel1, int channel2);
34extern void audiohw_set_bass(int value); 34extern void audiohw_set_bass(int value);
35extern void audiohw_set_bass_cutoff(int value);
35extern void audiohw_set_treble(int value); 36extern void audiohw_set_treble(int value);
37extern void audiohw_set_treble_cutoff(int value);
36extern void audiohw_set_nsorder(int order); 38extern void audiohw_set_nsorder(int order);
37extern void audiohw_set_sample_rate(int sampling_control); 39extern void audiohw_set_sample_rate(int sampling_control);
38 40
39extern void audiohw_set_equalizer_band(int band, int freq, int bw, int gain);
40
41#define RESET 0x00 41#define RESET 0x00
42#define PWRMGMT1 0x01 42#define PWRMGMT1 0x01
43#define PWRMGMT2 0x02 43#define PWRMGMT2 0x02
@@ -70,6 +70,10 @@ extern void audiohw_set_equalizer_band(int band, int freq, int bw, int gain);
70#define EQ3 0x14 70#define EQ3 0x14
71#define EQ4 0x15 71#define EQ4 0x15
72#define EQ5 0x16 72#define EQ5 0x16
73#define EQ_GAIN_MASK 0x001f
74#define EQ_CUTOFF_MASK 0x0060
75#define EQ_GAIN_VALUE(x) (((-x) + 12) & 0x1f)
76#define EQ_CUTOFF_VALUE(x) ((((x) - 1) & 0x03) << 5)
73 77
74/* Register settings for the supported samplerates: */ 78/* Register settings for the supported samplerates: */
75#define WM8758_8000HZ 0x4d 79#define WM8758_8000HZ 0x4d
diff --git a/firmware/sound.c b/firmware/sound.c
index 9cb4c28f32..0e1e7c5576 100644
--- a/firmware/sound.c
+++ b/firmware/sound.c
@@ -70,6 +70,10 @@ const struct sound_settings_info audiohw_settings[] = {
70 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0}, 70 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
71 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16}, 71 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
72#endif 72#endif
73#if defined(HAVE_WM8758)
74 [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1},
75 [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1},
76#endif
73}; 77};
74#endif 78#endif
75 79
@@ -132,6 +136,16 @@ sound_set_type* sound_get_fn(int setting)
132 result = sound_set_stereo_width; 136 result = sound_set_stereo_width;
133 break; 137 break;
134 138
139#ifdef HAVE_WM8758
140 case SOUND_BASS_CUTOFF:
141 result = sound_set_bass_cutoff;
142 break;
143
144 case SOUND_TREBLE_CUTOFF:
145 result = sound_set_treble_cutoff;
146 break;
147#endif
148
135#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 149#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
136 case SOUND_LOUDNESS: 150 case SOUND_LOUDNESS:
137 result = sound_set_loudness; 151 result = sound_set_loudness;
@@ -219,7 +233,8 @@ static void set_prescaled_volume(void)
219/* The WM codecs listed don't have suitable prescaler functionality, so we let 233/* The WM codecs listed don't have suitable prescaler functionality, so we let
220 * the prescaler stay at 0 for these unless SW tone controls are in use */ 234 * the prescaler stay at 0 for these unless SW tone controls are in use */
221#if defined(HAVE_SW_TONE_CONTROLS) || !(defined(HAVE_WM8975) \ 235#if defined(HAVE_SW_TONE_CONTROLS) || !(defined(HAVE_WM8975) \
222 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751)) 236 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751) \
237 || defined(HAVE_WM8758))
223 238
224 prescale = MAX(current_bass, current_treble); 239 prescale = MAX(current_bass, current_treble);
225 if (prescale < 0) 240 if (prescale < 0)
@@ -237,7 +252,7 @@ static void set_prescaled_volume(void)
237 dsp_callback(DSP_CALLBACK_SET_PRESCALE, prescale); 252 dsp_callback(DSP_CALLBACK_SET_PRESCALE, prescale);
238#elif CONFIG_CODEC == MAS3507D 253#elif CONFIG_CODEC == MAS3507D
239 mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); 254 mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]);
240#elif defined(HAVE_UDA1380) || defined(HAVE_WM8758) 255#elif defined(HAVE_UDA1380)
241 audiohw_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale)); 256 audiohw_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale));
242#endif 257#endif
243 258
@@ -492,6 +507,24 @@ void sound_set_stereo_width(int value)
492#endif 507#endif
493} 508}
494 509
510#ifdef HAVE_WM8758
511void sound_set_bass_cutoff(int value)
512{
513 if(!audio_is_initialized)
514 return;
515
516 audiohw_set_bass_cutoff(value);
517}
518
519void sound_set_treble_cutoff(int value)
520{
521 if(!audio_is_initialized)
522 return;
523
524 audiohw_set_treble_cutoff(value);
525}
526#endif
527
495#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 528#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
496void sound_set_loudness(int value) 529void sound_set_loudness(int value)
497{ 530{
@@ -652,6 +685,19 @@ void sound_set_superbass(int value)
652 (void)value; 685 (void)value;
653} 686}
654#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ 687#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
688
689#ifdef HAVE_WM8758
690void sound_set_bass_cutoff(int value)
691{
692 (void) value;
693}
694
695void sound_set_treble_cutoff(int value)
696{
697 (void) value;
698}
699#endif /* HAVE_WM8758 */
700
655#endif /* SIMULATOR */ 701#endif /* SIMULATOR */
656 702
657void sound_set(int setting, int value) 703void sound_set(int setting, int value)