|
1 | 1 | /*
|
2 | 2 | * Copyright (c) 2021 Nordic Semiconductor ASA
|
| 3 | + * Copyright (c) 2021 Croxel Inc |
3 | 4 | *
|
4 | 5 | * SPDX-License-Identifier: Apache-2.0
|
5 | 6 | */
|
@@ -123,3 +124,184 @@ bool init_wm8731_i2c(void)
|
123 | 124 | }
|
124 | 125 |
|
125 | 126 | #endif /* DT_ON_BUS(WM8731_NODE, i2c) */
|
| 127 | + |
| 128 | +#if DT_ON_BUS(MAX9867_NODE, i2c) |
| 129 | + |
| 130 | +#define MAX9867_I2C_NODE DT_BUS(MAX9867_NODE) |
| 131 | +#define MAX9867_I2C_ADDR DT_REG_ADDR(MAX9867_NODE) |
| 132 | +/* Register addresses */ |
| 133 | +#define MAX9867_00_STATUS 0x00 |
| 134 | +#define MAX9867_01_JACKSENSE 0x01 |
| 135 | +#define MAX9867_02_AUX_HIGH 0x02 |
| 136 | +#define MAX9867_03_AUX_LOW 0x03 |
| 137 | +#define MAX9867_04_INT_EN 0x04 |
| 138 | +#define MAX9867_05_SYS_CLK 0x05 |
| 139 | +#define MAX9867_06_CLK_HIGH 0x06 |
| 140 | +#define MAX9867_07_CLK_LOW 0x07 |
| 141 | +#define MAX9867_08_DAI_FORMAT 0x08 |
| 142 | +#define MAX9867_09_DAI_CLOCK 0x09 |
| 143 | +#define MAX9867_0A_DIG_FILTER 0x0A |
| 144 | +#define MAX9867_0B_SIDETONE 0x0B |
| 145 | +#define MAX9867_0C_LVL_DAC 0x0C |
| 146 | +#define MAX9867_0D_LVL_ADC 0x0D |
| 147 | +#define MAX9867_0E_LVL_LINE_IN_LEFT 0x0E |
| 148 | +#define MAX9867_0F_LVL_LINE_IN_RIGHT 0x0F |
| 149 | +#define MAX9867_10_VOL_LEFT 0x10 |
| 150 | +#define MAX9867_11_VOL_RIGHT 0x11 |
| 151 | +#define MAX9867_12_MIC_GAIN_LEFT 0x12 |
| 152 | +#define MAX9867_13_MIC_GAIN_RIGHT 0x13 |
| 153 | +#define MAX9867_14_ADC_INPUT 0x14 |
| 154 | +#define MAX9867_15_MIC 0x15 |
| 155 | +#define MAX9867_16_MODE 0x16 |
| 156 | +#define MAX9867_17_PWR_SYS 0x17 |
| 157 | +#define MAX9867_FF_REV_ID 0xFF |
| 158 | + |
| 159 | +/* MAX9867_04_INT_EN */ |
| 160 | +#define MAX9867_ICLD (1 << 7) |
| 161 | +#define MAX9867_SDODLY (1 << 2) |
| 162 | + |
| 163 | +/* MAX9867_05_SYS_CLK */ |
| 164 | +#define MAX9867_PSCLK_POS 4 |
| 165 | + |
| 166 | +/* MAX9867_06_CLK_HIGH */ |
| 167 | +#define MAX9867_PLL (1 << 7) |
| 168 | +#define MAX9867_NI_UPPER_8KHZ 0x10 |
| 169 | +#define MAX9867_NI_UPPER_16KHZ 0x20 |
| 170 | +#define MAX9867_NI_UPPER_24KHZ 0x30 |
| 171 | +#define MAX9867_NI_UPPER_32KHZ 0x40 |
| 172 | +#define MAX9867_NI_UPPER_44p1KHZ 0x58 |
| 173 | +#define MAX9867_NI_UPPER_48KHZ 0x60 |
| 174 | + |
| 175 | +/* MAX9867_07_CLK_LOW */ |
| 176 | +#define MAX9867_NI_LOWER_OTHER 0x00 |
| 177 | +#define MAX9867_NI_LOWER_44p1KHZ 0x33 |
| 178 | + |
| 179 | +/* MAX9867_08_DAI_FORMAT */ |
| 180 | +#define MAX9867_MAS (1 << 7) |
| 181 | +#define MAX9867_WCI (1 << 6) |
| 182 | +#define MAX9867_BCI (1 << 5) |
| 183 | +#define MAX9867_DLY (1 << 4) |
| 184 | +#define MAX9867_HIZOFF (1 << 3) |
| 185 | +#define MAX9867_TDM (1 << 2) |
| 186 | + |
| 187 | +/* MAX9867_09_DAI_CLOCK */ |
| 188 | +#define MAX9867_BSEL_PCLK_DIV8 0x06 |
| 189 | + |
| 190 | +/* MAX9867_0D_LVL_ADC */ |
| 191 | +#define MAX9867_AVL_POS 4 |
| 192 | +#define MAX9867_AVR_POS 0 |
| 193 | + |
| 194 | +/* MAX9867_0E_LVL_LINE_IN_LEFT |
| 195 | + * MAX9867_0F_LVL_LINE_IN_RIGHT */ |
| 196 | +#define MAX9867_LI_MUTE (1 << 6) |
| 197 | +#define MAX9867_LI_GAIN_POS 0 |
| 198 | + |
| 199 | +/* MAX9867_10_VOL_LEFT |
| 200 | + * MAX9867_11_VOL_RIGHT */ |
| 201 | +#define MAX9867_VOL_POS 0 |
| 202 | + |
| 203 | +/* MAX9867_14_ADC_INPUT */ |
| 204 | +#define MAX9867_MXINL_POS 6 |
| 205 | +#define MAX9867_MXINR_POS 4 |
| 206 | +#define MAX9867_MXIN_DIS 0 |
| 207 | +#define MAX9867_MXIN_ANALOG_MIC 1 |
| 208 | +#define MAX9867_MXIN_LINE 2 |
| 209 | + |
| 210 | +/* MAX9867_15_MIC */ |
| 211 | +#define MAX9867_MICCLK_POS 6 |
| 212 | +#define MAX9867_DIGMICL_POS 5 |
| 213 | +#define MAX9867_DIGMICR_POS 4 |
| 214 | + |
| 215 | +/* MAX9867_16_MODE */ |
| 216 | +#define MAX9867_HPMODE_POS 0 |
| 217 | +#define MAX9867_STEREO_SE_CLICKLESS 4 |
| 218 | +#define MAX9867_MONO_SE_CLICKLESS 5 |
| 219 | + |
| 220 | +/* MAX9867_17_PWR_SYS */ |
| 221 | +#define MAX9867_SHDN (1 << 7) |
| 222 | +#define MAX9867_LNLEN (1 << 6) |
| 223 | +#define MAX9867_LNREN (1 << 5) |
| 224 | +#define MAX9867_DALEN (1 << 3) |
| 225 | +#define MAX9867_DAREN (1 << 2) |
| 226 | +#define MAX9867_ADLEN (1 << 1) |
| 227 | +#define MAX9867_ADREN (1 << 0) |
| 228 | + |
| 229 | +bool init_max9867_i2c(void) |
| 230 | +{ |
| 231 | + const struct device *const i2c_dev = DEVICE_DT_GET(MAX9867_I2C_NODE); |
| 232 | + |
| 233 | + /* Initialization data for MAX9867 registers. */ |
| 234 | + static const uint8_t init[][2] = { |
| 235 | + /* Shutdown MAX9867 during configuration */ |
| 236 | + {MAX9867_17_PWR_SYS, 0x00}, |
| 237 | + /* Clear all regs to POR state. The MAX9867 does not not have an external |
| 238 | + * reset signal. So manually writing 0, from (0x04 - 0x17) |
| 239 | + */ |
| 240 | + {MAX9867_04_INT_EN, 0x00}, |
| 241 | + {MAX9867_05_SYS_CLK, 0x00}, |
| 242 | + {MAX9867_06_CLK_HIGH, 0x00}, |
| 243 | + {MAX9867_07_CLK_LOW, 0x00}, |
| 244 | + {MAX9867_08_DAI_FORMAT, 0x00}, |
| 245 | + {MAX9867_09_DAI_CLOCK, 0x00}, |
| 246 | + {MAX9867_0A_DIG_FILTER, 0x00}, |
| 247 | + {MAX9867_0B_SIDETONE, 0x00}, |
| 248 | + {MAX9867_0C_LVL_DAC, 0x00}, |
| 249 | + {MAX9867_0D_LVL_ADC, 0x00}, |
| 250 | + {MAX9867_0E_LVL_LINE_IN_LEFT, 0x00}, |
| 251 | + {MAX9867_0F_LVL_LINE_IN_RIGHT, 0x00}, |
| 252 | + {MAX9867_10_VOL_LEFT, 0x00}, |
| 253 | + {MAX9867_11_VOL_RIGHT, 0x00}, |
| 254 | + {MAX9867_12_MIC_GAIN_LEFT, 0x00}, |
| 255 | + {MAX9867_13_MIC_GAIN_RIGHT, 0x00}, |
| 256 | + {MAX9867_14_ADC_INPUT, 0x00}, |
| 257 | + {MAX9867_15_MIC, 0x00}, |
| 258 | + {MAX9867_16_MODE, 0x00}, |
| 259 | + {MAX9867_17_PWR_SYS, 0x00}, |
| 260 | + /* Select MCLK prescaler. PSCLK divides MCLK to generate a PCLK between 10MHz and |
| 261 | + * 20MHz. Set prescaler, FREQ field is 0 for Normal or PLL mode, < 20MHz. |
| 262 | + */ |
| 263 | + {MAX9867_05_SYS_CLK, 0x01 << MAX9867_PSCLK_POS}, |
| 264 | + /* Configure codec to generate 48kHz sampling frequency in master mode */ |
| 265 | + {MAX9867_06_CLK_HIGH, MAX9867_NI_UPPER_44p1KHZ}, |
| 266 | + {MAX9867_07_CLK_LOW, MAX9867_NI_LOWER_44p1KHZ}, |
| 267 | + {MAX9867_09_DAI_CLOCK, MAX9867_BSEL_PCLK_DIV8}, |
| 268 | + /* I2S format */ |
| 269 | + {MAX9867_08_DAI_FORMAT, MAX9867_MAS | MAX9867_DLY | MAX9867_HIZOFF}, |
| 270 | + /* */ |
| 271 | + {MAX9867_0A_DIG_FILTER, 0xA2}, |
| 272 | + /* Select Digital microphone input */ |
| 273 | + {MAX9867_15_MIC, ((0x1 << MAX9867_DIGMICR_POS))}, |
| 274 | + /* ADC level */ |
| 275 | + {MAX9867_0D_LVL_ADC, (3 << MAX9867_AVL_POS) | (3 << MAX9867_AVR_POS)}, |
| 276 | + /*Set line-in level, disconnect line input from playback amplifiers */ |
| 277 | + {MAX9867_0E_LVL_LINE_IN_LEFT, (0x0C << MAX9867_LI_GAIN_POS) | MAX9867_LI_MUTE}, |
| 278 | + {MAX9867_0F_LVL_LINE_IN_RIGHT, (0x0C << MAX9867_LI_GAIN_POS) | MAX9867_LI_MUTE}, |
| 279 | + /* Headphone mode */ |
| 280 | + {MAX9867_16_MODE, MAX9867_STEREO_SE_CLICKLESS << MAX9867_HPMODE_POS}, |
| 281 | + /* Set playback volume */ |
| 282 | + {MAX9867_10_VOL_LEFT, 0x04 << MAX9867_VOL_POS}, |
| 283 | + {MAX9867_11_VOL_RIGHT, 0x04 << MAX9867_VOL_POS}, |
| 284 | + /* Enable */ |
| 285 | + {MAX9867_17_PWR_SYS, MAX9867_SHDN | MAX9867_DALEN | MAX9867_DAREN | MAX9867_ADLEN}, |
| 286 | + }; |
| 287 | + |
| 288 | + if (!device_is_ready(i2c_dev)) { |
| 289 | + printk("%s is not ready\n", i2c_dev->name); |
| 290 | + return false; |
| 291 | + } |
| 292 | + |
| 293 | + for (int i = 0; i < ARRAY_SIZE(init); ++i) { |
| 294 | + const uint8_t *entry = init[i]; |
| 295 | + int ret; |
| 296 | + |
| 297 | + ret = i2c_reg_write_byte(i2c_dev, MAX9867_I2C_ADDR, entry[0], entry[1]); |
| 298 | + if (ret < 0) { |
| 299 | + printk("Initialization step %d failed with %d\n", i, ret); |
| 300 | + return false; |
| 301 | + } |
| 302 | + } |
| 303 | + |
| 304 | + return true; |
| 305 | +} |
| 306 | + |
| 307 | +#endif /* DT_ON_BUS(MAX9867_NODE, i2c) */ |
0 commit comments