1 /*
2  * Copyright 2024 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_CODEC_WM8904_H_
8 #define ZEPHYR_INCLUDE_CODEC_WM8904_H_
9 
10 /*******************************************************************************
11  * Definitions
12  ******************************************************************************/
13 
14 #define WM8904_REG_RESET                    (0x00)
15 #define WM8904_REG_ANALOG_ADC_0             (0x0A)
16 #define WM8904_REG_POWER_MGMT_0             (0x0C)
17 #define WM8904_REG_POWER_MGMT_2             (0x0E)
18 #define WM8904_REG_POWER_MGMT_3             (0x0F)
19 #define WM8904_REG_POWER_MGMT_6             (0x12)
20 #define WM8904_REG_CLK_RATES_0              (0x14)
21 #define WM8904_REG_CLK_RATES_1              (0x15)
22 #define WM8904_REG_CLK_RATES_2              (0x16)
23 #define WM8904_REG_AUDIO_IF_0               (0x18)
24 #define WM8904_REG_AUDIO_IF_1               (0x19)
25 #define WM8904_REG_AUDIO_IF_2               (0x1A)
26 #define WM8904_REG_AUDIO_IF_3               (0x1B)
27 #define WM8904_REG_DAC_DIG_1                (0x21)
28 #define WM8904_REG_DAC_DIG_0                (0x27)
29 #define WM8904_REG_ANALOG_LEFT_IN_0         (0x2C)
30 #define WM8904_REG_ANALOG_RIGHT_IN_0        (0x2D)
31 #define WM8904_REG_ANALOG_LEFT_IN_1         (0x2E)
32 #define WM8904_REG_ANALOG_RIGHT_IN_1        (0x2F)
33 #define WM8904_REG_ANALOG_OUT1_LEFT         (0x39)
34 #define WM8904_REG_ANALOG_OUT1_RIGHT        (0x3A)
35 #define WM8904_REG_ANALOG_OUT12_ZC          (0x3D)
36 #define WM8904_REG_DC_SERVO_0               (0x43)
37 #define WM8904_REG_ANALOG_HP_0              (0x5A)
38 #define WM8904_REG_CHRG_PUMP_0              (0x62)
39 #define WM8904_REG_CLS_W_0                  (0x68)
40 #define WM8904_REG_WRT_SEQUENCER_0          (0x6C)
41 #define WM8904_REG_WRT_SEQUENCER_3          (0x6F)
42 #define WM8904_REG_WRT_SEQUENCER_4          (0x70)
43 #define WM8904_REG_DAC_DIGITAL_VOLUME_LEFT  (0x1E)
44 #define WM8904_REG_DAC_DIGITAL_VOLUME_RIGHT (0x1F)
45 #define WM8904_REG_ADC_DIGITAL_VOLUME_LEFT  (0x24)
46 #define WM8904_REG_ADC_DIGITAL_VOLUME_RIGHT (0x25)
47 #define WM8904_REG_ANALOG_OUT2_LEFT         (0x3B)
48 #define WM8904_REG_ANALOG_OUT2_RIGHT        (0x3C)
49 #define WM8904_REG_GPIO_CONTROL_4           (0x7C)
50 /* FLL control register */
51 #define WM8904_REG_FLL_CONTROL_1 (0x74)
52 #define WM8904_REG_FLL_CONTROL_2 (0x75)
53 #define WM8904_REG_FLL_CONTROL_3 (0x76)
54 #define WM8904_REG_FLL_CONTROL_4 (0x77)
55 #define WM8904_REG_FLL_CONTROL_5 (0x78)
56 /* GPIO control register */
57 #define WM8904_REG_GPIO_CONTROL_1 (0x79)
58 #define WM8904_REG_GPIO_CONTROL_2 (0x7A)
59 #define WM8904_REG_GPIO_CONTROL_3 (0x7B)
60 #define WM8904_REG_GPIO_CONTROL_4 (0x7C)
61 /* fll nco */
62 #define WM8904_REG_FLL_NCO_TEST_0 (0xF7U)
63 #define WM8904_REG_FLL_NCO_TEST_1 (0xF8U)
64 
65 #define WM8904_OUTPUT_VOLUME_MIN (0b000000)
66 #define WM8904_OUTPUT_VOLUME_MAX (0b111111)
67 #define WM8904_OUTPUT_VOLUME_DEFAULT (0b101101)
68 #define WM8904_INPUT_VOLUME_MIN (0b00000)
69 #define WM8904_INPUT_VOLUME_MAX (0b11111)
70 #define WM8904_INPUT_VOLUME_DEFAULT (0b00101)
71 
72 /**
73  * WM8904_ANALOG_OUT1_LEFT, WM8904_ANALOG_OUT1_RIGHT (headphone outs),
74  * WM8904_ANALOG_OUT2_LEFT, WM8904_ANALOG_OUT2_RIGHT (line outs):
75  * [8]   - MUTE: Output mute
76  * [7]   - VU: Volume update, works for entire channel pair
77  * [6]   - ZC: Zero-crossing enable
78  * [5:0] - VOL: 6-bit volume value
79  */
80 #define WM8904_REGVAL_OUT_VOL(mute, vu, zc, vol) \
81 	(((mute & 0b1) << 8) | (vu & 0b1) << 7 | (zc & 0b1) << 6 | (vol & 0b000111111))
82 #define WM8904_REGMASK_OUT_MUTE	0b100000000
83 #define WM8904_REGMASK_OUT_VU	0b010000000
84 #define WM8904_REGMASK_OUT_ZC	0b001000000
85 #define WM8904_REGMASK_OUT_VOL	0b000111111
86 
87 /**
88  * WM8904_ANALOG_LEFT_IN_0, WM8904_ANALOG_RIGHT_IN_0:
89  * [7]   - MUTE: Input mute
90  * [4:0] - VOL: 5 bit volume value
91  */
92 #define WM8904_REGVAL_IN_VOL(mute, vol) \
93 	((mute & 0b1) << 7 | (vol & 0b00011111))
94 #define WM8904_REGMASK_IN_MUTE		0b10000000
95 #define WM8904_REGMASK_IN_VOLUME	0b00011111
96 
97 /**
98  * WM8904_ANALOG_LEFT_IN_1, WM8904_ANALOG_RIGHT_IN_1:
99  * [6]   - INx_CM_ENA: Common-mode rejection enable (N/A for single-mode)
100  * [5:4] - x_IP_SEL_N: Inverting input selection
101  * [3:2] - x_IP_SEL_P: Non-inverting input selection
102  * [1:0] - x_MODE: Input mode
103  */
104 #define WM8904_REGVAL_INSEL(cm, nin, pin, mode) \
105 	(((cm) & 0b1) << 6) | (((nin) & 0b11) << 4)
106 #define WM8904_REGMASK_INSEL_CMENA		0b01000000
107 #define WM8904_REGMASK_INSEL_IP_SEL_N	0b00110000
108 #define WM8904_REGMASK_INSEL_IP_SEL_P	0b00001100
109 #define WM8904_REGMASK_INSEL_MODE		0b00000011
110 
111 
112 /*!@brief WM8904 maximum volume */
113 #define WM8904_MAP_HEADPHONE_LINEOUT_MAX_VOLUME 0x3FU
114 #define WM8904_DAC_MAX_VOLUME                   0xC0U
115 
116 
117 /*! @brief The audio data transfer protocol. */
118 typedef enum _wm8904_protocol {
119 	kWM8904_ProtocolI2S            = 0x2,            /*!< I2S type */
120 	kWM8904_ProtocolLeftJustified  = 0x1,            /*!< Left justified mode */
121 	kWM8904_ProtocolRightJustified = 0x0,            /*!< Right justified mode */
122 	kWM8904_ProtocolPCMA           = 0x3,            /*!< PCM A mode */
123 	kWM8904_ProtocolPCMB           = 0x3 | (1 << 4), /*!< PCM B mode */
124 } wm8904_protocol_t;
125 
126 /*! @brief The SYSCLK / fs ratio. */
127 typedef enum _wm8904_fs_ratio {
128 	kWM8904_FsRatio64X   = 0x0, /*!< SYSCLK is   64 * sample rate * frame width */
129 	kWM8904_FsRatio128X  = 0x1, /*!< SYSCLK is  128 * sample rate * frame width */
130 	kWM8904_FsRatio192X  = 0x2, /*!< SYSCLK is  192 * sample rate * frame width */
131 	kWM8904_FsRatio256X  = 0x3, /*!< SYSCLK is  256 * sample rate * frame width */
132 	kWM8904_FsRatio384X  = 0x4, /*!< SYSCLK is  384 * sample rate * frame width */
133 	kWM8904_FsRatio512X  = 0x5, /*!< SYSCLK is  512 * sample rate * frame width */
134 	kWM8904_FsRatio768X  = 0x6, /*!< SYSCLK is  768 * sample rate * frame width */
135 	kWM8904_FsRatio1024X = 0x7, /*!< SYSCLK is 1024 * sample rate * frame width */
136 	kWM8904_FsRatio1408X = 0x8, /*!< SYSCLK is 1408 * sample rate * frame width */
137 	kWM8904_FsRatio1536X = 0x9  /*!< SYSCLK is 1536 * sample rate * frame width */
138 } wm8904_fs_ratio_t;
139 
140 
141 /*! @brief Sample rate. */
142 typedef enum _wm8904_sample_rate {
143 	kWM8904_SampleRate8kHz    = 0x0, /*!< 8 kHz */
144 	kWM8904_SampleRate12kHz   = 0x1, /*!< 12kHz */
145 	kWM8904_SampleRate16kHz   = 0x2, /*!< 16kHz */
146 	kWM8904_SampleRate24kHz   = 0x3, /*!< 24kHz */
147 	kWM8904_SampleRate32kHz   = 0x4, /*!< 32kHz */
148 	kWM8904_SampleRate48kHz   = 0x5, /*!< 48kHz */
149 	kWM8904_SampleRate11025Hz = 0x6, /*!< 11.025kHz */
150 	kWM8904_SampleRate22050Hz = 0x7, /*!< 22.05kHz */
151 	kWM8904_SampleRate44100Hz = 0x8  /*!< 44.1kHz */
152 } wm8904_sample_rate_t;
153 
154 #endif /* ZEPHYR_INCLUDE_CODEC_WM8904_H_ */
155