summaryrefslogtreecommitdiffstats
path: root/firmware/export/es9218.h
blob: 1492304c67b89e0545fde6387924690daad1e3a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Copyright (C) 2021 Aidan MacDonald
 *
 * 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.
 *
 ****************************************************************************/

#ifndef __ES9218_H__
#define __ES9218_H__

#include <stdbool.h>
#include <stdint.h>

#define AUDIOHW_CAPS (FILTER_ROLL_OFF_CAP|POWER_MODE_CAP)
#define AUDIOHW_HAVE_ES9218_ROLL_OFF

#define ES9218_DIG_VOLUME_MIN   (-1275)
#define ES9218_DIG_VOLUME_MAX   0
#define ES9218_DIG_VOLUME_STEP  5

#define ES9218_AMP_VOLUME_MIN   (-240)
#define ES9218_AMP_VOLUME_MAX   0
#define ES9218_AMP_VOLUME_STEP  10

AUDIOHW_SETTING(VOLUME, "dB", 1, ES9218_DIG_VOLUME_STEP,
                ES9218_DIG_VOLUME_MIN, ES9218_DIG_VOLUME_MAX, -200)
AUDIOHW_SETTING(FILTER_ROLL_OFF, "", 0, 1, 0, 7, 0)
AUDIOHW_SETTING(POWER_MODE, "", 0, 1, 0, 1, 0)

/* Register addresses */
#define ES9218_REG_SYSTEM               0x00
#define ES9218_REG_INPUT_SEL            0x01
#define ES9218_REG_MIX_AUTOMUTE         0x02
#define ES9218_REG_ANALOG_VOL           0x03
#define ES9218_REG_AUTOMUTE_TIME        0x04
#define ES9218_REG_AUTOMUTE_LEVEL       0x05
#define ES9218_REG_DOP_VOLUME_RAMP      0x06
#define ES9218_REG_FILTER_SYS_MUTE      0x07
#define ES9218_REG_GPIO1_2_CONFIG       0x08
#define ES9218_REG_RESERVED_1           0x09
#define ES9218_REG_MASTER_MODE_CONFIG   0x0a
#define ES9218_REG_OVERCURRENT_PROT     0x0b
#define ES9218_REG_ASRC_DPLL_BANDWIDTH  0x0c
#define ES9218_REG_THD_COMP_BYPASS      0x0d
#define ES9218_REG_SOFT_START_CONFIG    0x0e
#define ES9218_REG_VOLUME_LEFT          0x0f
#define ES9218_REG_VOLUME_RIGHT         0x10
#define ES9218_REG_MASTER_TRIM_BIT0_7   0x11
#define ES9218_REG_MASTER_TRIM_BIT8_15  0x12
#define ES9218_REG_MASTER_TRIM_BIT16_23 0x13
#define ES9218_REG_MASTER_TRIM_BIT24_31 0x14
#define ES9218_REG_GPIO_INPUT_SEL       0x15
#define ES9218_REG_THD_COMP_C2_LO       0x16
#define ES9218_REG_THD_COMP_C2_HI       0x17
#define ES9218_REG_THD_COMP_C3_LO       0x18
#define ES9218_REG_THD_COMP_C3_HI       0x19
#define ES9218_REG_CHARGE_PUMP_SS_DELAY 0x1a
#define ES9218_REG_GENERAL_CONFIG       0x1b
#define ES9218_REG_RESERVED_2           0x1c
#define ES9218_REG_GPIO_INV_CLOCK_GEAR  0x1d
#define ES9218_REG_CHARGE_PUMP_CLK_LO   0x1e
#define ES9218_REG_CHARGE_PUMP_CLK_HI   0x1f
#define ES9218_REG_AMP_CONFIG           0x20
#define ES9218_REG_INTERRUPT_MASK       0x21
#define ES9218_REG_PROG_NCO_BIT0_7      0x22
#define ES9218_REG_PROG_NCO_BIT8_15     0x23
#define ES9218_REG_PROG_NCO_BIT16_23    0x24
#define ES9218_REG_PROG_NCO_BIT24_31    0x25
#define ES9218_REG_RESERVED_3           0x27
#define ES9218_REG_FIR_RAM_ADDR         0x28
#define ES9218_REG_FIR_DATA_BIT0_7      0x29
#define ES9218_REG_FIR_DATA_BIT8_15     0x2a
#define ES9218_REG_FIR_DATA_BIT16_23    0x2b
#define ES9218_REG_PROG_FIR_CONFIG      0x2c
#define ES9218_REG_ANALOG_OVERRIDE_1    0x2d
#define ES9218_REG_ANALOG_OVERRIDE_2    0x2e
#define ES9218_REG_ANALOG_OVERRIDE_3    0x2f
#define ES9218_REG_ANALOG_CTRL          0x30
#define ES9218_REG_CLKGEAR_CFG_BIT0_7   0x31
#define ES9218_REG_CLKGEAR_CFG_BIT8_15  0x32
#define ES9218_REG_CLKGEAR_CFG_BIT16_23 0x33
#define ES9218_REG_RESERVED_4           0x34
#define ES9218_REG_THD_COMP_C2_CH2_LO   0x35
#define ES9218_REG_THD_COMP_C2_CH2_HI   0x36
#define ES9218_REG_THD_COMP_C3_CH2_LO   0x37
#define ES9218_REG_THD_COMP_C3_CH2_HI   0x38
#define ES9218_REG_RESERVED_5           0x39
#define ES9218_REG_RESERVED_6           0x3a
#define ES9218_REG_RESERVED_7           0x3b
#define ES9218_REG_RESERVED_8           0x3c
#define ES9218_REG_CHIP_ID_AND_STATUS   0x40
#define ES9218_REG_GPIO_AND_CLOCK_GEAR  0x41
#define ES9218_REG_DPLL_NUMBER_BIT0_7   0x42
#define ES9218_REG_DPLL_NUMBER_BIT8_15  0x43
#define ES9218_REG_DPLL_NUMBER_BIT16_23 0x44
#define ES9218_REG_DPLL_NUMBER_BIT24_31 0x45
#define ES9218_REG_INPUT_MUTE_STATUS    0x48
#define ES9218_REG_FIR_READ_BIT0_7      0x49
#define ES9218_REG_FIR_READ_BIT8_15     0x4a
#define ES9218_REG_FIR_READ_BIT16_23    0x4b

enum es9218_clock_gear {
    ES9218_CLK_GEAR_1 = 0, /* CLK = XI/1 */
    ES9218_CLK_GEAR_2 = 1, /* CLK = XI/2 */
    ES9218_CLK_GEAR_4 = 2, /* CLK = XI/4 */
    ES9218_CLK_GEAR_8 = 3, /* CLK = XI/8 */
};

enum es9218_amp_mode {
    ES9218_AMP_MODE_CORE_ON = 0,
    ES9218_AMP_MODE_LOWFI = 1,
    ES9218_AMP_MODE_1VRMS = 2,
    ES9218_AMP_MODE_2VRMS = 3,
};

enum es9218_iface_role {
    ES9218_IFACE_ROLE_SLAVE = 0,
    ES9218_IFACE_ROLE_MASTER = 1,
};

enum es9218_iface_format {
    ES9218_IFACE_FORMAT_I2S = 0,
    ES9218_IFACE_FORMAT_LJUST = 1,
    ES9218_IFACE_FORMAT_RJUST = 2,
};

enum es9218_iface_bits {
    ES9218_IFACE_BITS_16 = 0,
    ES9218_IFACE_BITS_24 = 1,
    ES9218_IFACE_BITS_32 = 2,
};

enum es9218_filter_type {
    ES9218_FILTER_LINEAR_FAST = 0,
    ES9218_FILTER_LINEAR_SLOW = 1,
    ES9218_FILTER_MINIMUM_FAST = 2,
    ES9218_FILTER_MINIMUM_SLOW = 3,
    ES9218_FILTER_APODIZING_1 = 4,
    ES9218_FILTER_APODIZING_2 = 5,
    ES9218_FILTER_HYBRID_FAST = 6,
    ES9218_FILTER_BRICK_WALL = 7,
};

/* Power DAC on or off */
extern void es9218_open(void);
extern void es9218_close(void);

/* Clock controls
 *
 * - Clock gear divides the input master clock to produce the DAC's clock.
 *   Frequency can be lowered to save power when using lower sample rates.
 *
 * - NCO (numerically controller oscillator), according to the datasheet,
 *   defines the ratio between the DAC's clock and the FSR (for PCM modes,
 *   this is I2S frame clock = sample rate). In master mode it effectively
 *   controls the sampling frequency by setting the I2S frame clock output.
 *   It can also be used in slave mode, but other parts of the datasheet
 *   say contradictory things about synchronous operation in slave mode.
 *
 * - If using NCO mode and a varying MCLK input (eg. input from the SoC) then
 *   you will need to call es9218_recompute_nco() when changing MCLK in order
 *   to refresh the NCO setting.
 */
extern void es9218_set_clock_gear(enum es9218_clock_gear gear);
extern void es9218_set_nco_frequency(uint32_t fsr);
extern void es9218_recompute_nco(void);

/* Amplifier controls */
extern void es9218_set_amp_mode(enum es9218_amp_mode mode);
extern void es9218_set_amp_powered(bool en);

/* Interface selection */
extern void es9218_set_iface_role(enum es9218_iface_role role);
extern void es9218_set_iface_format(enum es9218_iface_format fmt,
                                    enum es9218_iface_bits bits);

/* Volume controls, all volumes given in units of dB/10 */
extern void es9218_set_dig_volume(int vol_l, int vol_r);
extern void es9218_set_amp_volume(int vol);

/* System mute */
extern void es9218_mute(bool muted);

/* Oversampling filter */
extern void es9218_set_filter(enum es9218_filter_type filt);

/* Automute settings */
extern void es9218_set_automute_time(int time);
extern void es9218_set_automute_level(int dB);
extern void es9218_set_automute_fast_mode(bool en);

/* DPLL bandwidth setting (knob = 0-15) */
extern void es9218_set_dpll_bandwidth(int knob);

/* THD compensation */
extern void es9218_set_thd_compensation(bool en);
extern void es9218_set_thd_coeffs(uint16_t c2, uint16_t c3);

/* Direct register read/write/update operations */
extern int es9218_read(int reg);
extern void es9218_write(int reg, uint8_t val);
extern void es9218_update(int reg, uint8_t msk, uint8_t val);

/* GPIO pin setting callbacks */
extern void es9218_set_power_pin(int level);
extern void es9218_set_reset_pin(int level);

/* XI(MCLK) getter -- supplied by the target.
 *
 * Note: when changing the supplied MCLK frequency, the NCO will need to be
 * reprogrammed for the new master clock. Call es9218_recompute_nco() to
 * force this. Not necessary if you're not using NCO mode.
 */
extern uint32_t es9218_get_mclk(void);

#endif /* __ES9218_H__ */