summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/audio/eros_qn_codec.c50
-rw-r--r--firmware/drivers/audio/es9018.c4
-rw-r--r--firmware/drivers/audio/es9018k2m.c119
3 files changed, 133 insertions, 40 deletions
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
31static long int vol_l_hw = 0; 30#include "gpio-x1000.h"
32static long int vol_r_hw = 0;
33 31
34/* internal: Switch the output sink. 0 - headphones, 1 - line out */ 32static long int vol_l_hw = PCM5102A_VOLUME_MIN;
35void audiohw_switch_output(int select); 33static long int vol_r_hw = PCM5102A_VOLUME_MIN;
34int es9018k2m_present_flag = 0;
36 35
37void dac_set_outputs(void) 36void 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, 41void eros_qn_set_last_vol(long int vol_l, long int vol_r)
43 * but we need access to settings.h */
44void 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; 47int 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
78void audiohw_switch_output(int select) 52void 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
31static uint8_t reg0 = 0x00; /* System settings. Default value of register 0 */ 31static uint8_t reg0 = 0x00; /* System settings. Default value of register 0 */
32static uint8_t reg1 = 0x80; /* Input settings. Manual input, I2S, 32-bit (?) */ 32static 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
39static 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
68static uint8_t vol_reg_l = ES9018K2M_REG15_VOLUME_L;
69static uint8_t reg15_vol_l = 0;
70i2c_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] = &reg15_vol_l,
77 .count[1] = 1,
78 .callback = NULL,
79 .arg = 0,
80 .next = NULL,
81};
82
83static uint8_t vol_reg_r = ES9018K2M_REG16_VOLUME_R;
84static uint8_t reg16_vol_r = 0;
85i2c_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] = &reg16_vol_r,
92 .count[1] = 1,
93 .callback = NULL,
94 .arg = 0,
95 .next = NULL,
96};
97
98void 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 */
110int 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 */
116int es9018k2m_read_reg(uint8_t reg)
117{
118 return i2c_reg_read1(ES9018K2M_BUS, ES9018K2M_ADDR, reg);
119} \ No newline at end of file