diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/SOURCES | 1 | ||||
-rw-r--r-- | firmware/drivers/audio/eros_qn_codec.c | 50 | ||||
-rw-r--r-- | firmware/drivers/audio/es9018.c | 4 | ||||
-rw-r--r-- | firmware/drivers/audio/es9018k2m.c | 119 | ||||
-rw-r--r-- | firmware/export/audiohw.h | 1 | ||||
-rw-r--r-- | firmware/export/eros_qn_codec.h | 16 | ||||
-rw-r--r-- | firmware/export/es9018k2m.h | 64 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_x1000/debug-x1000.c | 13 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c | 77 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c | 4 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_x1000/erosqnative/gpio-target.h | 6 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_x1000/erosqnative/i2c-target.h | 3 |
12 files changed, 307 insertions, 51 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 71194748f9..0cfea38272 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -519,6 +519,7 @@ drivers/audio/es9018.c | |||
519 | drivers/audio/es9218.c | 519 | drivers/audio/es9218.c |
520 | #elif defined (HAVE_EROS_QN_CODEC) | 520 | #elif defined (HAVE_EROS_QN_CODEC) |
521 | drivers/audio/eros_qn_codec.c | 521 | drivers/audio/eros_qn_codec.c |
522 | drivers/audio/es9018k2m.c | ||
522 | #endif /* defined(HAVE_*) */ | 523 | #endif /* defined(HAVE_*) */ |
523 | #else /* PLATFORM_HOSTED */ | 524 | #else /* PLATFORM_HOSTED */ |
524 | #if defined(SAMSUNG_YPR0) && defined(HAVE_AS3514) | 525 | #if defined(SAMSUNG_YPR0) && defined(HAVE_AS3514) |
diff --git a/firmware/drivers/audio/eros_qn_codec.c b/firmware/drivers/audio/eros_qn_codec.c index 39a421ee92..095b3b5305 100644 --- a/firmware/drivers/audio/eros_qn_codec.c +++ b/firmware/drivers/audio/eros_qn_codec.c | |||
@@ -26,56 +26,30 @@ | |||
26 | #include "audiohw.h" | 26 | #include "audiohw.h" |
27 | #include "settings.h" | 27 | #include "settings.h" |
28 | #include "pcm_sw_volume.h" | 28 | #include "pcm_sw_volume.h" |
29 | #include "gpio-x1000.h" | ||
30 | 29 | ||
31 | static long int vol_l_hw = 0; | 30 | #include "gpio-x1000.h" |
32 | static long int vol_r_hw = 0; | ||
33 | 31 | ||
34 | /* internal: Switch the output sink. 0 - headphones, 1 - line out */ | 32 | static long int vol_l_hw = PCM5102A_VOLUME_MIN; |
35 | void audiohw_switch_output(int select); | 33 | static long int vol_r_hw = PCM5102A_VOLUME_MIN; |
34 | int es9018k2m_present_flag = 0; | ||
36 | 35 | ||
37 | void dac_set_outputs(void) | 36 | void eros_qn_set_outputs(void) |
38 | { | 37 | { |
39 | audiohw_set_volume(vol_l_hw, vol_r_hw); | 38 | audiohw_set_volume(vol_l_hw, vol_r_hw); |
40 | } | 39 | } |
41 | 40 | ||
42 | /* this makes less sense here than it does in the audiohw-*.c file, | 41 | void eros_qn_set_last_vol(long int vol_l, long int vol_r) |
43 | * but we need access to settings.h */ | ||
44 | void audiohw_set_volume(int vol_l, int vol_r) | ||
45 | { | 42 | { |
46 | int l, r; | ||
47 | |||
48 | vol_l_hw = vol_l; | 43 | vol_l_hw = vol_l; |
49 | vol_r_hw = vol_r; | 44 | vol_r_hw = vol_r; |
45 | } | ||
50 | 46 | ||
51 | l = vol_l; | 47 | int eros_qn_get_volume_limit(void) |
52 | r = vol_r; | 48 | { |
53 | 49 | return (global_settings.volume_limit * 10); | |
54 | #if (defined(HAVE_HEADPHONE_DETECTION) && defined(HAVE_LINEOUT_DETECTION)) | ||
55 | /* make sure headphones aren't present - don't want to | ||
56 | * blow out our eardrums cranking it to full */ | ||
57 | if (lineout_inserted() && !headphones_inserted()) | ||
58 | { | ||
59 | audiohw_switch_output(1); | ||
60 | |||
61 | l = r = global_settings.volume_limit * 10; | ||
62 | } | ||
63 | else | ||
64 | { | ||
65 | audiohw_switch_output(0); | ||
66 | |||
67 | l = vol_l; | ||
68 | r = vol_r; | ||
69 | } | ||
70 | #endif | ||
71 | |||
72 | l = l <= PCM5102A_VOLUME_MIN ? PCM_MUTE_LEVEL : (l / 20); | ||
73 | r = r <= PCM5102A_VOLUME_MIN ? PCM_MUTE_LEVEL : (r / 20); | ||
74 | |||
75 | pcm_set_master_volume(l, r); | ||
76 | } | 50 | } |
77 | 51 | ||
78 | void audiohw_switch_output(int select) | 52 | void eros_qn_switch_output(int select) |
79 | { | 53 | { |
80 | if (select == 0) | 54 | if (select == 0) |
81 | { | 55 | { |
@@ -85,4 +59,4 @@ void audiohw_switch_output(int select) | |||
85 | { | 59 | { |
86 | gpio_set_level(GPIO_STEREOSW_SEL, 1); | 60 | gpio_set_level(GPIO_STEREOSW_SEL, 1); |
87 | } | 61 | } |
88 | } | 62 | } \ No newline at end of file |
diff --git a/firmware/drivers/audio/es9018.c b/firmware/drivers/audio/es9018.c index 89e8c1d46f..6a73f7a2d3 100644 --- a/firmware/drivers/audio/es9018.c +++ b/firmware/drivers/audio/es9018.c | |||
@@ -25,8 +25,8 @@ | |||
25 | #include "audio.h" | 25 | #include "audio.h" |
26 | #include "audiohw.h" | 26 | #include "audiohw.h" |
27 | 27 | ||
28 | /* NOTE: The register names are not known, as the register numbering | 28 | /* NOTE: This implementation is specifically for the ES9018K2M, which has a different register |
29 | listed in the ES9018 datasheet does not match what is described below.. */ | 29 | * structure from the ES9018. */ |
30 | 30 | ||
31 | static uint8_t reg0 = 0x00; /* System settings. Default value of register 0 */ | 31 | static uint8_t reg0 = 0x00; /* System settings. Default value of register 0 */ |
32 | static uint8_t reg1 = 0x80; /* Input settings. Manual input, I2S, 32-bit (?) */ | 32 | static uint8_t reg1 = 0x80; /* Input settings. Manual input, I2S, 32-bit (?) */ |
diff --git a/firmware/drivers/audio/es9018k2m.c b/firmware/drivers/audio/es9018k2m.c new file mode 100644 index 0000000000..e19cf6e8a9 --- /dev/null +++ b/firmware/drivers/audio/es9018k2m.c | |||
@@ -0,0 +1,119 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * | ||
11 | * Copyright (c) 2023 Dana Conrad | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #include "system.h" | ||
24 | #include "es9018k2m.h" | ||
25 | #include "i2c-async.h" | ||
26 | #include "action.h" | ||
27 | |||
28 | //====================================================================================== | ||
29 | // ES9018K2M support stuff | ||
30 | |||
31 | #ifndef ES9018K2M_BUS | ||
32 | # error "No definition for ES9018K2M I2C bus!" | ||
33 | #endif | ||
34 | |||
35 | #ifndef ES9018K2M_ADDR | ||
36 | # error "No definition for ES9018K2M I2C address!" | ||
37 | #endif | ||
38 | |||
39 | static int vol_tenthdb2hw(const int tdb) | ||
40 | { | ||
41 | if (tdb < ES9018K2M_VOLUME_MIN) { | ||
42 | return 0xff; | ||
43 | } else if (tdb > ES9018K2M_VOLUME_MAX) { | ||
44 | return 0x00; | ||
45 | } else { | ||
46 | return (-tdb/5); | ||
47 | } | ||
48 | } | ||
49 | |||
50 | /* NOTE: This implementation is for the ES9018K2M specifically. */ | ||
51 | /* Register defaults from the datasheet. */ | ||
52 | /* These are basically just for reference. All defaults work out for us. | ||
53 | * static uint8_t reg0_system_settings = 0x00; // System settings. Default value of register 0 | ||
54 | * static uint8_t reg1_input_configuration = 0x8C; // Input settings. I2S input, 32-bit | ||
55 | * static uint8_t reg4_automute_time = 0x00; // Automute time. Default = disabled | ||
56 | * static uint8_t reg5_automute_level = 0x68; // Automute level. Default is some level | ||
57 | * static uint8_t reg6_deemphasis = 0x4A; // Deemphasis. Default = disabled | ||
58 | * static uint8_t reg7_general_settings = 0x80; // General settings. Default sharp fir, pcm iir and unmuted | ||
59 | * static uint8_t reg8_gpio_configuration = 0x10; // GPIO configuration | ||
60 | * static uint8_t reg10_master_mode_control = 0x05; // Master Mode Control. Default value: master mode off | ||
61 | * static uint8_t reg11_channel_mapping = 0x02; // Channel Mapping. Default stereo is Ch1=left, Ch2=right | ||
62 | * static uint8_t reg12_dpll_settings = 0x5A; // DPLL Settings. Default = 5 for I2S, A for DSD | ||
63 | * static uint8_t reg13_thd_comp = 0x40; // THD Compensation | ||
64 | * static uint8_t reg14_softstart_settings = 0x8A; // Soft Start Settings | ||
65 | * static uint8_t reg21_gpio_input_selection = 0x00; // Oversampling filter. Default: oversampling ON | ||
66 | */ | ||
67 | |||
68 | static uint8_t vol_reg_l = ES9018K2M_REG15_VOLUME_L; | ||
69 | static uint8_t reg15_vol_l = 0; | ||
70 | i2c_descriptor vol_desc_l = { | ||
71 | .slave_addr = ES9018K2M_ADDR, | ||
72 | .bus_cond = I2C_START | I2C_STOP, | ||
73 | .tran_mode = I2C_WRITE, | ||
74 | .buffer[0] = &vol_reg_l, | ||
75 | .count[0] = 1, | ||
76 | .buffer[1] = ®15_vol_l, | ||
77 | .count[1] = 1, | ||
78 | .callback = NULL, | ||
79 | .arg = 0, | ||
80 | .next = NULL, | ||
81 | }; | ||
82 | |||
83 | static uint8_t vol_reg_r = ES9018K2M_REG16_VOLUME_R; | ||
84 | static uint8_t reg16_vol_r = 0; | ||
85 | i2c_descriptor vol_desc_r = { | ||
86 | .slave_addr = ES9018K2M_ADDR, | ||
87 | .bus_cond = I2C_START | I2C_STOP, | ||
88 | .tran_mode = I2C_WRITE, | ||
89 | .buffer[0] = &vol_reg_r, | ||
90 | .count[0] = 1, | ||
91 | .buffer[1] = ®16_vol_r, | ||
92 | .count[1] = 1, | ||
93 | .callback = NULL, | ||
94 | .arg = 0, | ||
95 | .next = NULL, | ||
96 | }; | ||
97 | |||
98 | void es9018k2m_set_volume(int vol_l, int vol_r) | ||
99 | { | ||
100 | /* Queue writes to the DAC's volume. | ||
101 | * Note that this needs to be done asynchronously. From testing, calling | ||
102 | * synchronous writes from HP/LO detect causes hangs. */ | ||
103 | reg15_vol_l = vol_tenthdb2hw(vol_l); | ||
104 | reg16_vol_r = vol_tenthdb2hw(vol_r); | ||
105 | i2c_async_queue(ES9018K2M_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, &vol_desc_l); | ||
106 | i2c_async_queue(ES9018K2M_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, &vol_desc_r); | ||
107 | } | ||
108 | |||
109 | /* returns I2C_STATUS_OK upon success, I2C_STATUS_* errors upon error */ | ||
110 | int es9018k2m_write_reg(uint8_t reg, uint8_t val) | ||
111 | { | ||
112 | return i2c_reg_write1(ES9018K2M_BUS, ES9018K2M_ADDR, reg, val); | ||
113 | } | ||
114 | |||
115 | /* returns register value, or -1 upon error */ | ||
116 | int es9018k2m_read_reg(uint8_t reg) | ||
117 | { | ||
118 | return i2c_reg_read1(ES9018K2M_BUS, ES9018K2M_ADDR, reg); | ||
119 | } \ No newline at end of file | ||
diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h index 3f8b48d750..067118000e 100644 --- a/firmware/export/audiohw.h +++ b/firmware/export/audiohw.h | |||
@@ -214,6 +214,7 @@ struct sound_settings_info | |||
214 | #include "pcm1792.h" | 214 | #include "pcm1792.h" |
215 | #elif defined(HAVE_EROS_QN_CODEC) | 215 | #elif defined(HAVE_EROS_QN_CODEC) |
216 | #include "eros_qn_codec.h" | 216 | #include "eros_qn_codec.h" |
217 | #include "es9018k2m.h" | ||
217 | #elif defined(HAVE_NWZ_LINUX_CODEC) | 218 | #elif defined(HAVE_NWZ_LINUX_CODEC) |
218 | #include "nwzlinux_codec.h" | 219 | #include "nwzlinux_codec.h" |
219 | #elif defined(HAVE_CS4398) | 220 | #elif defined(HAVE_CS4398) |
diff --git a/firmware/export/eros_qn_codec.h b/firmware/export/eros_qn_codec.h index bf108aa1c7..223ef06779 100644 --- a/firmware/export/eros_qn_codec.h +++ b/firmware/export/eros_qn_codec.h | |||
@@ -32,13 +32,25 @@ | |||
32 | #define PCM5102A_VOLUME_MIN -740 | 32 | #define PCM5102A_VOLUME_MIN -740 |
33 | #define PCM5102A_VOLUME_MAX -20 | 33 | #define PCM5102A_VOLUME_MAX -20 |
34 | 34 | ||
35 | /* a small DC offset prevents play/pause clicking due to the DAC auto-muting */ | 35 | /* a small DC offset prevents play/pause clicking due to the PCM5102A DAC auto-muting */ |
36 | #define PCM_DC_OFFSET_VALUE -1 | 36 | #define PCM_DC_OFFSET_VALUE -1 |
37 | 37 | ||
38 | AUDIOHW_SETTING(VOLUME, "dB", 0, 2, PCM5102A_VOLUME_MIN/10, PCM5102A_VOLUME_MAX/10, 0) | 38 | AUDIOHW_SETTING(VOLUME, "dB", 0, 2, PCM5102A_VOLUME_MIN/10, PCM5102A_VOLUME_MAX/10, 0) |
39 | 39 | ||
40 | /* flag indicating whether this is a new revision unit with the ES9018K2M DAC */ | ||
41 | extern int es9018k2m_present_flag; | ||
42 | |||
43 | /* Switch the output sink. 0 - headphones, 1 - line out */ | ||
44 | void eros_qn_switch_output(int select); | ||
45 | |||
46 | /* Record last volume setting for switching between headphones/line out */ | ||
47 | void eros_qn_set_last_vol(long int vol_l, long int vol_r); | ||
48 | |||
40 | /* this just calls audiohw_set_volume() with the last (locally) known volume, | 49 | /* this just calls audiohw_set_volume() with the last (locally) known volume, |
41 | * used for switching to/from fixed line out volume. */ | 50 | * used for switching to/from fixed line out volume. */ |
42 | void dac_set_outputs(void); | 51 | void eros_qn_set_outputs(void); |
52 | |||
53 | /* returns (global_settings.volume_limit * 10) */ | ||
54 | int eros_qn_get_volume_limit(void); | ||
43 | 55 | ||
44 | #endif | 56 | #endif |
diff --git a/firmware/export/es9018k2m.h b/firmware/export/es9018k2m.h new file mode 100644 index 0000000000..035a607030 --- /dev/null +++ b/firmware/export/es9018k2m.h | |||
@@ -0,0 +1,64 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * | ||
11 | * Copyright (c) 2023 Dana Conrad | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #ifndef _ES9018K2M_H | ||
24 | #define _ES9018K2M_H | ||
25 | |||
26 | //====================================================================================== | ||
27 | // ES9018K2M support stuff | ||
28 | |||
29 | #ifndef ES9018K2M_VOLUME_MIN | ||
30 | # define ES9018K2M_VOLUME_MIN -1270 | ||
31 | #endif | ||
32 | |||
33 | #ifndef ES9018K2M_VOLUME_MAX | ||
34 | # define ES9018K2M_VOLUME_MAX 0 | ||
35 | #endif | ||
36 | |||
37 | #define ES9018K2M_REG0_SYSTEM_SETTINGS 0 | ||
38 | #define ES9018K2M_REG1_INPUT_CONFIG 1 | ||
39 | #define ES9018K2M_REG4_AUTOMUTE_TIME 4 | ||
40 | #define ES9018K2M_REG5_AUTOMUTE_LEVEL 5 | ||
41 | #define ES9018K2M_REG6_DEEMPHASIS 6 | ||
42 | #define ES9018K2M_REG7_GENERAL_SETTINGS 7 | ||
43 | #define ES9018K2M_REG8_GPIO_CONFIG 8 | ||
44 | #define ES9018K2M_REG10_MASTER_MODE_CTRL 10 | ||
45 | #define ES9018K2M_REG11_CHANNEL_MAPPING 11 | ||
46 | #define ES9018K2M_REG12_DPLL_SETTINGS 12 | ||
47 | #define ES9018K2M_REG13_THD_COMP 13 | ||
48 | #define ES9018K2M_REG14_SOFTSTART_SETTINGS 14 | ||
49 | #define ES9018K2M_REG15_VOLUME_L 15 | ||
50 | #define ES9018K2M_REG16_VOLUME_R 16 | ||
51 | #define ES9018K2M_REG21_GPIO_INPUT_SELECT 21 | ||
52 | |||
53 | /* writes volume levels to DAC over I2C */ | ||
54 | void es9018k2m_set_volume(int vol_l, int vol_r); | ||
55 | |||
56 | /* writes a single register */ | ||
57 | /* returns I2C_STATUS_OK upon success, I2C_STATUS_* errors upon error */ | ||
58 | int es9018k2m_write_reg(uint8_t reg, uint8_t val); | ||
59 | |||
60 | /* reads a single register */ | ||
61 | /* returns register value, or -1 upon error */ | ||
62 | int es9018k2m_read_reg(uint8_t reg); | ||
63 | |||
64 | #endif \ No newline at end of file | ||
diff --git a/firmware/target/mips/ingenic_x1000/debug-x1000.c b/firmware/target/mips/ingenic_x1000/debug-x1000.c index 236442a880..827bb37855 100644 --- a/firmware/target/mips/ingenic_x1000/debug-x1000.c +++ b/firmware/target/mips/ingenic_x1000/debug-x1000.c | |||
@@ -121,6 +121,9 @@ extern volatile unsigned aic_tx_underruns; | |||
121 | #ifdef HAVE_RECORDING | 121 | #ifdef HAVE_RECORDING |
122 | extern volatile unsigned aic_rx_overruns; | 122 | extern volatile unsigned aic_rx_overruns; |
123 | #endif | 123 | #endif |
124 | #ifdef HAVE_EROS_QN_CODEC | ||
125 | extern int es9018k2m_present_flag; | ||
126 | #endif | ||
124 | 127 | ||
125 | static bool dbg_audio(void) | 128 | static bool dbg_audio(void) |
126 | { | 129 | { |
@@ -130,6 +133,16 @@ static bool dbg_audio(void) | |||
130 | #ifdef HAVE_RECORDING | 133 | #ifdef HAVE_RECORDING |
131 | lcd_putsf(0, 1, "RX overruns: %u", aic_rx_overruns); | 134 | lcd_putsf(0, 1, "RX overruns: %u", aic_rx_overruns); |
132 | #endif | 135 | #endif |
136 | #ifdef HAVE_EROS_QN_CODEC | ||
137 | if (es9018k2m_present_flag) | ||
138 | { | ||
139 | lcd_putsf(0, 2, "(%d) ES9018K2M HWVOL", es9018k2m_present_flag); | ||
140 | } | ||
141 | else | ||
142 | { | ||
143 | lcd_putsf(0, 2, "(%d) SWVOL", es9018k2m_present_flag); | ||
144 | } | ||
145 | #endif | ||
133 | lcd_update(); | 146 | lcd_update(); |
134 | } while(get_action(CONTEXT_STD, HZ) != ACTION_STD_CANCEL); | 147 | } while(get_action(CONTEXT_STD, HZ) != ACTION_STD_CANCEL); |
135 | 148 | ||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c index c53da728ff..1e3e7f0b7f 100644 --- a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c +++ b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c | |||
@@ -19,13 +19,19 @@ | |||
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #include "audiohw.h" | ||
23 | #include "system.h" | 22 | #include "system.h" |
23 | #include "audiohw.h" | ||
24 | #include "pcm_sw_volume.h" | ||
24 | #include "pcm_sampr.h" | 25 | #include "pcm_sampr.h" |
26 | #include "i2c-target.h" | ||
27 | #include "button.h" | ||
28 | |||
29 | // #define LOGF_ENABLE | ||
30 | #include "logf.h" | ||
31 | |||
25 | #include "aic-x1000.h" | 32 | #include "aic-x1000.h" |
26 | #include "i2c-x1000.h" | 33 | #include "i2c-x1000.h" |
27 | #include "gpio-x1000.h" | 34 | #include "gpio-x1000.h" |
28 | #include "logf.h" | ||
29 | 35 | ||
30 | /* | 36 | /* |
31 | * Earlier devices audio path appears to be: | 37 | * Earlier devices audio path appears to be: |
@@ -42,7 +48,7 @@ void audiohw_init(void) | |||
42 | /* explicitly mute everything */ | 48 | /* explicitly mute everything */ |
43 | gpio_set_level(GPIO_HPAMP_SHDN, 0); | 49 | gpio_set_level(GPIO_HPAMP_SHDN, 0); |
44 | gpio_set_level(GPIO_STEREOSW_MUTE, 1); | 50 | gpio_set_level(GPIO_STEREOSW_MUTE, 1); |
45 | gpio_set_level(GPIO_DAC_XMIT, 0); | 51 | gpio_set_level(GPIO_DAC_PWR, 0); |
46 | 52 | ||
47 | aic_set_play_last_sample(true); | 53 | aic_set_play_last_sample(true); |
48 | aic_set_external_codec(true); | 54 | aic_set_external_codec(true); |
@@ -81,18 +87,34 @@ void audiohw_postinit(void) | |||
81 | gpio_set_level(GPIO_STEREOSW_SEL, 0); | 87 | gpio_set_level(GPIO_STEREOSW_SEL, 0); |
82 | gpio_set_level(GPIO_HPAMP_SHDN, 1); | 88 | gpio_set_level(GPIO_HPAMP_SHDN, 1); |
83 | mdelay(10); | 89 | mdelay(10); |
84 | gpio_set_level(GPIO_DAC_XMIT, 1); | 90 | gpio_set_level(GPIO_DAC_PWR, 1); |
85 | mdelay(10); | 91 | mdelay(10); |
86 | gpio_set_level(GPIO_STEREOSW_MUTE, 0); | 92 | gpio_set_level(GPIO_STEREOSW_MUTE, 0); |
93 | |||
94 | i2c_x1000_set_freq(ES9018K2M_BUS, I2C_FREQ_400K); | ||
95 | |||
96 | int ret = es9018k2m_read_reg(ES9018K2M_REG0_SYSTEM_SETTINGS); | ||
97 | if (ret >= 0) /* Detected ES9018K2M DAC */ | ||
98 | { | ||
99 | logf("ES9018K2M found: ret=%d", ret); | ||
100 | es9018k2m_present_flag = 1; | ||
101 | |||
102 | /* Default is 32-bit data, and it works ok. Enabling the following | ||
103 | * causes issue. Which is weird, I definitely thought AIC was configured | ||
104 | * for 24-bit data... */ | ||
105 | // es9018k2m_write_reg(ES9018K2M_REG1_INPUT_CONFIG, 0b01001100); // 24-bit data | ||
106 | |||
107 | } else { /* Default to SWVOL for PCM5102A DAC */ | ||
108 | logf("Default to SWVOL: ret=%d", ret); | ||
109 | } | ||
87 | } | 110 | } |
88 | 111 | ||
89 | /* TODO: get shutdown just right according to dac datasheet */ | ||
90 | void audiohw_close(void) | 112 | void audiohw_close(void) |
91 | { | 113 | { |
92 | /* mute - attempt to make power-off pop-free */ | 114 | /* mute - attempt to make power-off pop-free */ |
93 | gpio_set_level(GPIO_STEREOSW_MUTE, 1); | 115 | gpio_set_level(GPIO_STEREOSW_MUTE, 1); |
94 | mdelay(10); | 116 | mdelay(10); |
95 | gpio_set_level(GPIO_DAC_XMIT, 0); | 117 | gpio_set_level(GPIO_DAC_PWR, 0); |
96 | mdelay(10); | 118 | mdelay(10); |
97 | gpio_set_level(GPIO_HPAMP_SHDN, 0); | 119 | gpio_set_level(GPIO_HPAMP_SHDN, 0); |
98 | } | 120 | } |
@@ -107,3 +129,46 @@ void audiohw_set_frequency(int fsel) | |||
107 | aic_enable_i2s_bit_clock(true); | 129 | aic_enable_i2s_bit_clock(true); |
108 | } | 130 | } |
109 | 131 | ||
132 | void audiohw_set_volume(int vol_l, int vol_r) | ||
133 | { | ||
134 | int l, r; | ||
135 | |||
136 | eros_qn_set_last_vol(vol_l, vol_r); | ||
137 | |||
138 | l = vol_l; | ||
139 | r = vol_r; | ||
140 | |||
141 | #if (defined(HAVE_HEADPHONE_DETECTION) && defined(HAVE_LINEOUT_DETECTION)) | ||
142 | /* make sure headphones aren't present - don't want to | ||
143 | * blow out our eardrums cranking it to full */ | ||
144 | if (lineout_inserted() && !headphones_inserted()) | ||
145 | { | ||
146 | eros_qn_switch_output(1); | ||
147 | |||
148 | l = r = eros_qn_get_volume_limit(); | ||
149 | } | ||
150 | else | ||
151 | { | ||
152 | eros_qn_switch_output(0); | ||
153 | } | ||
154 | #endif | ||
155 | |||
156 | if (es9018k2m_present_flag) /* ES9018K2M */ | ||
157 | { | ||
158 | /* Same volume range and mute point for both DACs, so use PCM5102A_VOLUME_MIN */ | ||
159 | l = l <= PCM5102A_VOLUME_MIN ? PCM_MUTE_LEVEL : l; | ||
160 | r = r <= PCM5102A_VOLUME_MIN ? PCM_MUTE_LEVEL : r; | ||
161 | |||
162 | /* set software volume just below unity due to | ||
163 | * DAC offset. We don't want to overflow the PCM system. */ | ||
164 | pcm_set_master_volume(-1, -1); | ||
165 | es9018k2m_set_volume(l, r); | ||
166 | } | ||
167 | else /* PCM5102A */ | ||
168 | { | ||
169 | l = l <= PCM5102A_VOLUME_MIN ? PCM_MUTE_LEVEL : (l / 20); | ||
170 | r = r <= PCM5102A_VOLUME_MIN ? PCM_MUTE_LEVEL : (r / 20); | ||
171 | |||
172 | pcm_set_master_volume(l, r); | ||
173 | } | ||
174 | } \ No newline at end of file | ||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c index d82cb5b5dc..0d2207af2a 100644 --- a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c +++ b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c | |||
@@ -127,7 +127,7 @@ bool headphones_inserted(void) | |||
127 | { | 127 | { |
128 | hp_detect_reg_old = hp_detect_reg; | 128 | hp_detect_reg_old = hp_detect_reg; |
129 | #if !defined(BOOTLOADER) | 129 | #if !defined(BOOTLOADER) |
130 | dac_set_outputs(); | 130 | eros_qn_set_outputs(); |
131 | #endif | 131 | #endif |
132 | } | 132 | } |
133 | return hp_detect_reg & 0x10 ? false : true; | 133 | return hp_detect_reg & 0x10 ? false : true; |
@@ -140,7 +140,7 @@ bool lineout_inserted(void) | |||
140 | { | 140 | { |
141 | hp_detect_reg_old = hp_detect_reg; | 141 | hp_detect_reg_old = hp_detect_reg; |
142 | #if !defined(BOOTLOADER) | 142 | #if !defined(BOOTLOADER) |
143 | dac_set_outputs(); | 143 | eros_qn_set_outputs(); |
144 | #endif | 144 | #endif |
145 | } | 145 | } |
146 | return hp_detect_reg & 0x20 ? false : true; | 146 | return hp_detect_reg & 0x20 ? false : true; |
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/gpio-target.h b/firmware/target/mips/ingenic_x1000/erosqnative/gpio-target.h index 3318a39786..72052c261f 100644 --- a/firmware/target/mips/ingenic_x1000/erosqnative/gpio-target.h +++ b/firmware/target/mips/ingenic_x1000/erosqnative/gpio-target.h | |||
@@ -15,17 +15,21 @@ | |||
15 | 15 | ||
16 | /* ---------------------------------------------- */ | 16 | /* ---------------------------------------------- */ |
17 | 17 | ||
18 | |||
18 | /* Name Port Pins Function */ | 19 | /* Name Port Pins Function */ |
19 | DEFINE_PINGROUP(LCD_DATA, GPIO_A, 0xffff << 0, GPIOF_DEVICE(1)) | 20 | DEFINE_PINGROUP(LCD_DATA, GPIO_A, 0xffff << 0, GPIOF_DEVICE(1)) |
20 | DEFINE_PINGROUP(LCD_CONTROL, GPIO_B, 0x1a << 16, GPIOF_DEVICE(1)) | 21 | DEFINE_PINGROUP(LCD_CONTROL, GPIO_B, 0x1a << 16, GPIOF_DEVICE(1)) |
21 | DEFINE_PINGROUP(MSC0, GPIO_A, 0x3f << 20, GPIOF_DEVICE(1)) | 22 | DEFINE_PINGROUP(MSC0, GPIO_A, 0x3f << 20, GPIOF_DEVICE(1)) |
22 | DEFINE_PINGROUP(SFC, GPIO_A, 0x3f << 26, GPIOF_DEVICE(1)) | 23 | DEFINE_PINGROUP(SFC, GPIO_A, 0x3f << 26, GPIOF_DEVICE(1)) |
23 | DEFINE_PINGROUP(I2S, GPIO_B, 0x1f << 0, GPIOF_DEVICE(1)) | 24 | DEFINE_PINGROUP(I2S, GPIO_B, 0x1f << 0, GPIOF_DEVICE(1)) |
25 | DEFINE_PINGROUP(I2C1, GPIO_C, 3 << 26, GPIOF_DEVICE(0)) | ||
24 | DEFINE_PINGROUP(I2C2, GPIO_D, 3 << 0, GPIOF_DEVICE(1)) | 26 | DEFINE_PINGROUP(I2C2, GPIO_D, 3 << 0, GPIOF_DEVICE(1)) |
25 | 27 | ||
26 | /* Name Pin Function */ | 28 | /* Name Pin Function */ |
27 | /* mute DAC: 0 - mute, 1 - play */ | 29 | /* mute DAC: 0 - mute, 1 - play */ |
28 | DEFINE_GPIO(DAC_XMIT, GPIO_PB(12), GPIOF_OUTPUT(0)) | 30 | /* Note: This seems to actually be power to the DAC in general, |
31 | * at least on the ES9018K2M devices. Was "DAC_XMIT". */ | ||
32 | DEFINE_GPIO(DAC_PWR, GPIO_PB(12), GPIOF_OUTPUT(0)) | ||
29 | 33 | ||
30 | /* mute HP amp: 0 - mute, 1 - play */ | 34 | /* mute HP amp: 0 - mute, 1 - play */ |
31 | DEFINE_GPIO(HPAMP_SHDN, GPIO_PB(8), GPIOF_OUTPUT(0)) | 35 | DEFINE_GPIO(HPAMP_SHDN, GPIO_PB(8), GPIOF_OUTPUT(0)) |
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/i2c-target.h b/firmware/target/mips/ingenic_x1000/erosqnative/i2c-target.h index 8d0b8a6e20..89d995f33a 100644 --- a/firmware/target/mips/ingenic_x1000/erosqnative/i2c-target.h +++ b/firmware/target/mips/ingenic_x1000/erosqnative/i2c-target.h | |||
@@ -25,6 +25,9 @@ | |||
25 | #define I2C_ASYNC_BUS_COUNT 3 | 25 | #define I2C_ASYNC_BUS_COUNT 3 |
26 | #define I2C_ASYNC_QUEUE_SIZE 4 | 26 | #define I2C_ASYNC_QUEUE_SIZE 4 |
27 | 27 | ||
28 | #define ES9018K2M_BUS 1 | ||
29 | #define ES9018K2M_ADDR 0x48 | ||
30 | |||
28 | #define AXP_PMU_BUS 2 | 31 | #define AXP_PMU_BUS 2 |
29 | #define AXP_PMU_ADDR 0x34 | 32 | #define AXP_PMU_ADDR 0x34 |
30 | 33 | ||