summaryrefslogtreecommitdiff
path: root/firmware/drivers/wm8523.h
blob: 0e9f5dea87459d045b38d5227fbc4383bbc93a81 (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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
 *            wm8523.h
 *
 *  Tue Jun  4 20:47:15 CEST 2013
 *  Copyright 2013 Bent Bisballe Nyeng
 *  deva@aasimon.org
 ****************************************************************************/

/*
 *  This file is part of Pedal2Metal.
 *
 *  Pedal2Metal 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.
 *
 *  Pedal2Metal is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Pedal2Metal; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
 */
#ifndef __PEDAL2METAL_WM8523_H__
#define __PEDAL2METAL_WM8523_H__

#include <stdint.h>


typedef enum {
  WM8523_FS_8K,
  WM8523_FS_32K,
  WM8523_FS_44K1,
  WM8523_FS_48K,
  WM8523_FS_88K2,
  WM8523_FS_96K,
  WM8523_FS_176K4,
  WM8523_FS_192K,
} wm8523_samplerate_t;
/**
 * Prepare I2S, SSP and GPIO.
 */
void wm8523_init(uint8_t portnum, wm8523_samplerate_t fs);

/**
 * Read chip ID.
 * Is always 0x8523
 * Register: R0 [0:15] (read)
 * Default: 1000 0101 0010 0011 
 */
#define WM8523_CHIP_ID 0b1000010100100011
unsigned short wm8523_get_chip_id(uint8_t portnum);

/**
 * Reset all register values to their defaults.
 * Register: R0 [0:15] (write)
 */
void wm8523_reset_registers(uint8_t portnum);

/**
 * Read hardware revision counter.
 * Register: R1 [0:2] (read)
 */
uint8_t wm8523_get_hardware_revision(uint8_t portnum);

typedef enum __attribute__ ((packed)) {
  WM8523_PWR_OFF                = 0b00,
  WM8523_PWR_POWER_DOWN         = 0b01,
  WM8523_PWR_POWER_UP_TO_MUTE   = 0b10,
  WM8523_PWR_POWER_UP_TO_UNMUTE = 0b11,
} wm8523_power_mode_t;

/**
 * Get current power mode.
 * Register: R2 [0:1] (read)
 */
wm8523_power_mode_t wm8523_get_power_mode(uint8_t portnum);

/**
 * Set power mode.
 * Register: R2 [0:1] (write)
 */
void wm8523_set_power_mode(uint8_t portnum, wm8523_power_mode_t mode);

/*
R3 [0:1]
Audio Data Interface Format
00 = Right justified
01 = Left justified
10 = I2S format
11 = DSP mode
*/
typedef enum __attribute__ ((packed)) {
  WM8523_FMT_RIGHT = 0b00, // Right justified
  WM8523_FMT_LEFT  = 0b01, // Left justified
  WM8523_FMT_I2S   = 0b10, // I2S format
  WM8523_FMT_DSP   = 0b11, // DSP mode
} wm8523_audio_data_interface_format_t;

/*
R3 [3:4]
Audio Data Word Length
00 = 16 bits
01 = 20 bits
10 = 24 bits
11 = 32 bits
*/
typedef enum __attribute__ ((packed)) {
  WM8523_WLEN_16 = 0b00, // 16 bit word length
  WM8523_WLEN_20 = 0b01, // 20 bit word length
  WM8523_WLEN_24 = 0b10, // 24 bit word length
  WM8523_WLEN_32 = 0b11, // 32 bit word length
} wm8523_audio_data_word_length_t;

/*
R3 [5]
BCLK Inversion Control
Slave mode:
0 = Use rising edge
1 = Use falling edge
Master mode:
0 = BCLK normal
1 = BCLK inverted
*/
typedef enum __attribute__ ((packed)) {
  // Slave mode:
  WM8523_INVCTL_SLAVE_RISING    = 0b0, // Use rising edge
  WM8523_INVCTL_SLAVE_FALLING   = 0b1, // Use falling edge

  // Master mode:
  WM8523_INVCTL_MASTER_NORMAL   = 0b0, // BCLK normal
  WM8523_INVCTL_MASTER_INVERTED = 0b1, // BCLK inverted
} wm8523_bclk_inversion_control_t;

/*
R3 [6]
LRCLK Inversion Control
0 = Normal polarity
1 = Inverted polarity
When AIF_FMT[2:0]=011 (DSP Mode):
0 = Mode A (2nd clock)
1 = Mode B (1st clock)
*/
typedef enum __attribute__ ((packed)) {
  // Slave mode:
  WM8523_LRCLKINVCTL_SLAVE_NORMAL   = 0b0, // Normal polarity
  WM8523_LRCLKINVCTL_SLAVE_INVERTED = 0b1, // Inverted polarity

  // Master mode:
  WM8523_LRCLKINVCTL_MASTER_MODE_A  = 0b0, // Mode A (2nd clock)
  WM8523_LRCLKINVCTL_MASTER_MODE_B  = 0b1, // Mode B (1st clock)
} wm8523_lrclk_inversion_control_t;

/*
R3 [7]
Master/Slave Select
0 = Slave mode
1 = Master mode
*/
typedef enum __attribute__ ((packed)) {
  WM8523_MODESEL_SLAVE  = 0b0, // Slave mode
  WM8523_MODESEL_MASTER = 0b1, // Master mode
} wm8523_slave_master_mode_sel_t;

/*
R3 [8]
DAC De-emphasis Control
0 = No de-emphasis
1 = De-emphasis enabled
*/
typedef enum __attribute__ ((packed)) {
  WM8523_DEEMPH_DISABLED = 0b0, // No de-emphasis
  WM8523_DEEMPH_ENABLED  = 0b1, // De-emphasis enabled
} wm8523_dac_deemphasis_control_t;

typedef struct __attribute__ ((packed)) {
  wm8523_audio_data_interface_format_t fmt:2;
  int reserved:1;
  wm8523_audio_data_word_length_t wlen:2;
  wm8523_bclk_inversion_control_t invctl:1;
  wm8523_lrclk_inversion_control_t lrclkinvctl:1;
  wm8523_slave_master_mode_sel_t modesel:1;
  wm8523_dac_deemphasis_control_t deemp:1;
  uint16_t blank:7;
} wm8523_aif_ctrl1_t;

void wm8523_set_aif_ctrl1(uint8_t portnum, wm8523_aif_ctrl1_t aif_ctrl1);
wm8523_aif_ctrl1_t wm8523_get_aif_ctrl1(uint8_t portnum);

/*
R4 [0:2]
MCLK:LRCLK Ratio
000 = Auto detect
001 = 128fs
010 = 192fs
011 = 256fs
100 = 384fs
101 = 512fs
110 = 768fs
111 = 1152fs
*/
typedef enum __attribute__ ((packed)) {
  WM8523_CLKRATIO_AUTO    = 0b000, // Auto detect
  WM8523_CLKRATIO_128_FS  = 0b001, // 128fs
  WM8523_CLKRATIO_192_FS  = 0b010, // 192fs
  WM8523_CLKRATIO_256_FS  = 0b011, // 256fs
  WM8523_CLKRATIO_384_FS  = 0b100, // 384fs
  WM8523_CLKRATIO_512_FS  = 0b101, // 512fs
  WM8523_CLKRATIO_768_FS  = 0b110, // 768fs
  WM8523_CLKRATIO_1152_FS = 0b111, // 1152fs
} wm8523_mclk_lrclk_ratio_t;

/*
R4 [3:5]
BCLK Divider Control (Master Mode)
000 = MCLK/4
001 = MCLK/8
010 = 32fs
011 = 64fs
100 = 128fs
101 - 111 reserved
*/
typedef enum __attribute__ ((packed)) {
  WM8523_CLKDIV_MCLK_4 = 0b000, // MCLK/4
  WM8523_CLKDIV_MCLK_8 = 0b001, // MCLK/8
  WM8523_CLKDIV_32_FS  = 0b010, // 32fs
  WM8523_CLKDIV_64_FS  = 0b011, // 64fs
  WM8523_CLKDIV_128_FS = 0b100, // 128fs
} wm8523_bclk_divider_control_t;

/*
R4 [6:7]
Digital Monomix Control
00 = Stereo (normal operation)
01 = Mono (Left data to DACR)
10 = Mono (Right data to DACL)
11 = Digital monomix, (L+R)/2
*/
typedef enum __attribute__ ((packed)) {
  WM8523_MIX_STEREO     = 0b00, // Stereo (normal operation)
  WM8523_MIX_MONO_LEFT  = 0b01, // Mono (Left data to DACR)
  WM8523_MIX_MONO_RIGHT = 0b10, // Mono (Right data to DACL)
  WM8523_MIX_MONO_MIXED = 0b11, // Digital monomix, (L+R)/2
} wm8523_digital_monomix_control_t;

typedef struct __attribute__ ((packed)) {
  wm8523_mclk_lrclk_ratio_t clkratio:3;
  wm8523_bclk_divider_control_t clkdiv:3;
  wm8523_digital_monomix_control_t mix:2;
} wm8523_aif_ctrl2_t;

void wm8523_set_aif_ctrl2(uint8_t portnum, wm8523_aif_ctrl2_t aif_ctrl2);
wm8523_aif_ctrl2_t wm8523_get_aif_ctrl2(uint8_t portnum);

/*
R5 [0]
DAC Digital Volume Decrease Control
0 = Apply volume decreases instantly (step)
1 = Ramp volume decreases
*/
typedef enum __attribute__ ((packed)) {
  WM8523_VOL_DOWN_RAMP    = 0b00, // Apply volume decreases instantly (step)
  WM8523_VOL_DOWN_INSTANT = 0b01, // Ramp volume decreases
} wm8523_dac_vol_down_ramp_t;

/*
R5 [1]
DAC Digital Volume Increase Control
0 = Apply volume increases instantly (step)
1 = Ramp volume increases
*/
typedef enum __attribute__ ((packed)) {
  WM8523_VOL_UP_RAMP    = 0b00, // Apply volume increases instantly (step)
  WM8523_VOL_UP_INSTANT = 0b01, // Ramp volume increases
} wm8523_dac_vol_up_ramp_t;

/*
R5 [2]
Left DAC Mute
0 = Normal operation
1 = Mute
*/
typedef enum __attribute__ ((packed)) {
  WM8523_DACL_UNMUTE = 0b00, // Normal operation
  WM8523_DACL_MUTE   = 0b01, // Mute
} wm8523_dacl_mute_t;

/*
R5 [3]
Right DAC Mute
0 = Normal operation
1 = Mute
*/
typedef enum __attribute__ ((packed)) {
  WM8523_DACR_UNMUTE = 0b00, // Normal operation
  WM8523_DACR_MUTE   = 0b01, // Mute
} wm8523_dacr_mute_t;

/*
R5 [4]
Zero Cross Enable
0 = Do not use zero cross
1 = Use zero cross
*/
typedef enum __attribute__ ((packed)) {
  WM8523_ZERO_CROSSING_DISABLED = 0b00, // Do not use zero cross
  WM8523_ZERO_CROSSING_ENABLED  = 0b01, // Use zero cross
} wm8523_dac_zc_t;

typedef struct __attribute__ ((packed)) {
  wm8523_dac_vol_down_ramp_t downramp:1;
  wm8523_dac_vol_up_ramp_t upramp:1;
  wm8523_dacl_mute_t lmute:1;
  wm8523_dacr_mute_t rmute:1;
  wm8523_dac_zc_t dac_zc:1;
} wm8523_dac_ctrl3_t;

void wm8523_set_dac_ctrl3(uint8_t portnum, wm8523_dac_ctrl3_t dac_ctrl3);
wm8523_dac_ctrl3_t wm8523_get_dac_ctrl3(uint8_t portnum);

/*
R6 [0:8]
Left DAC Digital Volume Control
0 0000 0000 = -100dB
0 0000 0001 = -99.75dB
0 0000 0010 = -99.5dB
...0.25dB steps
1 1001 0000 = 0dB
...0.25dB steps
1 1011 1110 = +11.75dB
1 11XX XXXX = +12dB
*/

/*
R6 [9]
Left DAC Digital Volume Update
0 = Latch Left DAC volume setting into register map but do not update volume
1 = Latch Left DAC volume setting into register map and update left and right channels simultaneously
*/

/*
R7 [0:8]
Right DAC Digital Volume Control
0 0000 0000 = -100dB
0 0000 0001 = -99.75dB
0 0000 0010 = -99.5dB
...0.25dB steps
1 1001 0000 = 0dB
...0.25dB steps
1 1011 1110 = +11.75dB
1 11XX XXXX = +12dB
*/

/*
R7 [9]
Right DAC Digital Volume Update
0 = Latch Right DAC volume setting into register map but do not update volume
1 = Latch Right DAC volume setting into register map and update left and right channels simultaneously
*/

/*
R8 [0]
Zero Detect Count Control
0 = 1024
1 = 2048
*/


void wm8523_tone();

//void wm8523_configure();
//uint16_t wm8523_read(uint8_t reg);
//void wm8523_write(uint8_t reg, uint16_t data);

#endif/*__PEDAL2METAL_WM8523_H__*/