1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2020-07-02 thread-liu first version
9 */
10
11 #include "board.h"
12
13 #if defined(BSP_USING_AUDIO)
14 #include <drv_wm8994.h>
15
16 #define DRV_DEBUG
17 #define LOG_TAG "drv.wm8994"
18 #include <drv_log.h>
19
20 #define CHIP_ADDRESS 0x1B /* wm8994 address */
21 #define I2C_NAME "i2c2"
22
23 struct wm8994_dev
24 {
25 struct rt_device dev;
26 struct rt_i2c_bus_device *i2c_bus;
27 rt_uint16_t id;
28 rt_uint16_t type;
29 };
30 static struct wm8994_dev rt_wm8994 = {0};
31
32 /* i2c read reg */
read_reg(struct rt_i2c_bus_device * bus,rt_uint16_t reg,rt_uint8_t len,rt_uint8_t * buf)33 static rt_err_t read_reg(struct rt_i2c_bus_device *bus, rt_uint16_t reg, rt_uint8_t len, rt_uint8_t *buf)
34 {
35 struct rt_i2c_msg msg[2] = {0, 0};
36 static rt_uint8_t i2c_reg[2] = {0, 0};
37
38 RT_ASSERT(bus != RT_NULL);
39
40 i2c_reg[0] = ((uint16_t)(reg >> 8) & 0xFF);
41 i2c_reg[1] = ((uint16_t)(reg) & 0xFF);
42
43 msg[0].addr = CHIP_ADDRESS;
44 msg[0].flags = RT_I2C_WR;
45 msg[0].buf = i2c_reg;
46 msg[0].len = 2;
47
48 msg[1].addr = CHIP_ADDRESS;
49 msg[1].flags = RT_I2C_RD;
50 msg[1].len = len;
51 msg[1].buf = buf;
52
53 if (rt_i2c_transfer(bus, msg, 2) == 2)
54 {
55 return RT_EOK;
56 }
57
58 return -RT_ERROR;
59 }
60
61 /* i2c write reg */
write_reg(struct rt_i2c_bus_device * bus,rt_uint16_t reg,rt_uint16_t data)62 static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint16_t reg, rt_uint16_t data)
63 {
64 rt_uint8_t buf[4];
65 struct rt_i2c_msg msgs;
66
67 RT_ASSERT(bus != RT_NULL);
68
69 buf[0] = ((uint16_t)(reg >> 8) & 0xFF);
70 buf[1] = ((uint16_t)(reg) & 0xFF);
71
72 buf[2] = ((uint16_t)(data >> 8) & 0xFF);
73 buf[3] = ((uint16_t)(data) & 0xFF);
74
75 msgs.addr = CHIP_ADDRESS;
76 msgs.flags = RT_I2C_WR;
77 msgs.buf = buf;
78 msgs.len = 4;
79
80 if (rt_i2c_transfer(bus, &msgs, 1) == 1)
81 {
82 return RT_EOK;
83 }
84
85 return -RT_ERROR;
86 }
87
wm8994_set_output_mode(struct rt_i2c_bus_device * bus,rt_uint16_t mode)88 static rt_err_t wm8994_set_output_mode(struct rt_i2c_bus_device *bus, rt_uint16_t mode)
89 {
90 switch (mode & 0x000F)
91 {
92 case OUTPUT_DEVICE_SPEAKER:
93 /* Enable DAC1 (Left), Enable DAC1 (Right),
94 * Disable DAC2 (Left), Disable DAC2 (Right) */
95 write_reg(bus, 0x0005, 0x0C0C);
96
97 /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
98 write_reg(bus, 0x0601, 0x0000);
99
100 /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
101 write_reg(bus, 0x0602, 0x0000);
102
103 /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
104 write_reg(bus, 0x0604, 0x0002);
105
106 /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
107 write_reg(bus, 0x0605, 0x0002);
108 break;
109
110 case OUTPUT_DEVICE_HEADPHONE:
111 /* Disable DAC1 (Left), Disable DAC1 (Right),
112 Enable DAC2 (Left), Enable DAC2 (Right)*/
113 write_reg(bus, 0x05, 0x0303);
114
115 /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
116 write_reg(bus, 0x0601, 0x01);
117
118 /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
119 write_reg(bus, 0x0602, 0x01);
120
121 /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
122 write_reg(bus, 0x0604, 0x00);
123
124 /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
125 write_reg(bus, 0x0605, 0x00);
126 break;
127
128 case OUTPUT_DEVICE_BOTH:
129 default:
130 break;
131 }
132
133 return RT_EOK;
134 }
135
wm8994_set_input_mode(struct rt_i2c_bus_device * bus,rt_uint16_t mode)136 static rt_err_t wm8994_set_input_mode(struct rt_i2c_bus_device *bus, rt_uint16_t mode)
137 {
138 switch (mode & 0x01F0)
139 {
140 case INPUT_DEVICE_DIGITAL_MICROPHONE_2:
141 /* Enable AIF1ADC2 (Left), Enable AIF1ADC2 (Right)
142 * Enable DMICDAT2 (Left), Enable DMICDAT2 (Right)
143 * Enable Left ADC, Enable Right ADC */
144 write_reg(bus, 0x04, 0x0C30);
145
146 /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
147 write_reg(bus, 0x0450, 0x00DB);
148
149 /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
150 write_reg(bus, 0x02, 0x6000);
151
152 /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
153 write_reg(bus, 0x0608, 0x0002);
154
155 /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
156 write_reg(bus, 0x0609, 0x0002);
157
158 /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC2 signal detect */
159 write_reg(bus, 0x0700, 0x000E);
160 break;
161
162 case INPUT_DEVICE_INPUT_LINE_1:
163 /* IN1LN_TO_IN1L, IN1LP_TO_VMID, IN1RN_TO_IN1R, IN1RP_TO_VMID */
164 write_reg(bus, 0x28, 0x0011);
165
166 /* Disable mute on IN1L_TO_MIXINL and +30dB on IN1L PGA output */
167 write_reg(bus, 0x29, 0x0035);
168
169 /* Disable mute on IN1R_TO_MIXINL, Gain = +30dB */
170 write_reg(bus, 0x2A, 0x0035);
171
172 /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
173 * Enable Left ADC, Enable Right ADC */
174 write_reg(bus, 0x04, 0x0303);
175
176 /* Enable AIF1 DRC1 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
177 write_reg(bus, 0x0440, 0x00DB);
178
179 /* Enable IN1L and IN1R, Disable IN2L and IN2R, Enable Thermal sensor & shutdown */
180 write_reg(bus, 0x02, 0x6350);
181
182 /* Enable the ADCL(Left) to AIF1 Timeslot 0 (Left) mixer path */
183 write_reg(bus, 0x0606, 0x0002);
184
185 /* Enable the ADCR(Right) to AIF1 Timeslot 0 (Right) mixer path */
186 write_reg(bus, 0x0607, 0x0002);
187
188 /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
189 write_reg(bus, 0x0700, 0x000D);
190 break;
191
192 case INPUT_DEVICE_DIGITAL_MICROPHONE_1:
193 /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
194 * Enable DMICDAT1 (Left), Enable DMICDAT1 (Right)
195 * Enable Left ADC, Enable Right ADC */
196 write_reg(bus, 0x04, 0x030C);
197
198 /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
199 write_reg(bus, 0x0440, 0x00DB);
200
201 /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
202 write_reg(bus, 0x02, 0x6350);
203
204 /* Enable the DMIC2(Left) to AIF1 Timeslot 0 (Left) mixer path */
205 write_reg(bus, 0x0606, 0x0002);
206
207 /* Enable the DMIC2(Right) to AIF1 Timeslot 0 (Right) mixer path */
208 write_reg(bus, 0x0607, 0x0002);
209
210 /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
211 write_reg(bus, 0x0700, 0x000D);
212 break;
213
214 case INPUT_DEVICE_DIGITAL_MIC1_MIC2:
215 /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
216 * Enable DMICDAT1 (Left), Enable DMICDAT1 (Right)
217 * Enable Left ADC, Enable Right ADC */
218 write_reg(bus, 0x04, 0x0F3C);
219
220 /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
221 write_reg(bus, 0x0450, 0x00DB);
222
223 /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
224 write_reg(bus, 0x0440, 0x00DB);
225
226 /* Disable IN1L, IN1R, Enable IN2L, IN2R, Thermal sensor & shutdown */
227 write_reg(bus, 0x02, 0x63A0);
228
229 /* Enable the DMIC2(Left) to AIF1 Timeslot 0 (Left) mixer path */
230 write_reg(bus, 0x0606, 0x0002);
231
232 /* Enable the DMIC2(Right) to AIF1 Timeslot 0 (Right) mixer path */
233 write_reg(bus, 0x0607, 0x0002);
234
235 /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
236 write_reg(bus, 0x0608, 0x0002);
237
238 /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
239 write_reg(bus, 0x0609, 0x0002);
240
241 /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
242 write_reg(bus, 0x0700, 0x000D);
243 break;
244
245 case INPUT_DEVICE_INPUT_LINE_2:
246 default:
247 /* Actually, no other input devices supported */
248 break;
249 }
250
251 return RT_EOK;
252 }
253
_wm8994_init(struct wm8994_dev * dev)254 static rt_err_t _wm8994_init(struct wm8994_dev *dev)
255 {
256 RT_ASSERT(dev != RT_NULL);
257
258 /* wm8994 Errata Work-Arounds */
259 write_reg(dev->i2c_bus, 0x0102, 0x0003);
260 write_reg(dev->i2c_bus, 0x0817, 0x0000);
261 write_reg(dev->i2c_bus, 0x0102, 0x0000);
262
263 /* Enable VMID soft start (fast), Start-up Bias Current Enabled */
264 write_reg(dev->i2c_bus, 0x0039, 0x006C);
265
266 /* Enable bias generator, Enable VMID */
267 if ((dev->type & 0x01F0) != 0)
268 {
269 /* audio input */
270 write_reg(dev->i2c_bus, 0x0001, 0x0013);
271 }
272 else
273 {
274 /* audio output */
275 write_reg(dev->i2c_bus, 0x0001, 0x0003);
276 }
277 rt_thread_mdelay(50);
278
279 if ((dev->type & 0x000F) != 0 )
280 {
281 /* Path Configurations for output */
282 wm8994_set_output_mode(dev->i2c_bus, dev->type);
283 }
284 if ((dev->type & 0x01F0) != 0 )
285 {
286 /* Path Configurations for input */
287 wm8994_set_input_mode(dev->i2c_bus, dev->type);
288 }
289
290 if (dev->type & INPUT_DEVICE_DIGITAL_MIC1_MIC2)
291 {
292 /* AIF1 Word Length = 16-bits, AIF1 Format = DSP mode */
293 write_reg(dev->i2c_bus, 0x0300, 0x4018);
294 }
295 else
296 {
297 /* AIF1 Word Length = 16-bits, AIF1 Format = I2S (Default Register Value) */
298 write_reg(dev->i2c_bus, 0x0300, 0x4010);
299 }
300
301 /* slave mode */
302 write_reg(dev->i2c_bus, 0x0302, 0x0000);
303
304 /* Enable the DSP processing clock for AIF1, Enable the core clock */
305 write_reg(dev->i2c_bus, 0x0208, 0x000A);
306
307 /* Enable AIF1 Clock, AIF1 Clock Source = MCLK1 pin */
308 write_reg(dev->i2c_bus, 0x0200, 0x0001);
309
310 /* Audio output selected */
311 if ((dev->type & 0x000F) != 0 )
312 {
313 if (dev->type & OUTPUT_DEVICE_HEADPHONE)
314 {
315 /* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
316 write_reg(dev->i2c_bus, 0x2D, 0x0100);
317
318 /* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
319 write_reg(dev->i2c_bus, 0x2E, 0x0100);
320
321 /* Startup sequence for Headphone */
322 write_reg(dev->i2c_bus, 0x0110, 0x8100);
323
324 rt_thread_mdelay(300);
325
326 /* Soft un-Mute the AIF1 Timeslot 0 DAC1 path L&R */
327 write_reg(dev->i2c_bus, 0x0420, 0x0000);
328 }
329
330 /* Enable SPKRVOL PGA, Enable SPKMIXR, Enable SPKLVOL PGA, Enable SPKMIXL */
331 write_reg(dev->i2c_bus, 0x03, 0x0300);
332
333 /* Left Speaker Mixer Volume = 0dB */
334 write_reg(dev->i2c_bus, 0x22, 0x0000);
335
336 /* Speaker output mode = Class D, Right Speaker Mixer Volume = 0dB ((0x23, 0x0100) = class AB)*/
337 write_reg(dev->i2c_bus, 0x23, 0x0000);
338
339 /* Unmute DAC2 (Left) to Left Speaker Mixer (SPKMIXL) path,
340 Unmute DAC2 (Right) to Right Speaker Mixer (SPKMIXR) path */
341 write_reg(dev->i2c_bus, 0x36, 0x0300);
342
343 /* Enable bias generator, Enable VMID, Enable SPKOUTL, Enable SPKOUTR */
344 write_reg(dev->i2c_bus, 0x01, 0x3003);
345
346 /* Headphone/Speaker Enable */
347
348 if (dev->type & INPUT_DEVICE_DIGITAL_MIC1_MIC2)
349 {
350 /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslots 0 and 1 */
351 write_reg(dev->i2c_bus, 0x51, 0x0205);
352 }
353 else
354 {
355 /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslot 0 */
356 write_reg(dev->i2c_bus, 0x51, 0x0005);
357 }
358
359 /* Enable bias generator, Enable VMID, Enable HPOUT1 (Left) and Enable HPOUT1 (Right) input stages */
360 /* idem for Speaker */
361 write_reg(dev->i2c_bus, 0x01, 0x3303);
362
363 /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate stages */
364 write_reg(dev->i2c_bus, 0x60, 0x0022);
365
366 /* Enable Charge Pump */
367 write_reg(dev->i2c_bus, 0x4C, 0x9F25);
368
369 /* Add Delay */
370 rt_thread_mdelay(15);
371
372 /* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
373 write_reg(dev->i2c_bus, 0x2D, 0x0001);
374
375 /* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
376 write_reg(dev->i2c_bus, 0x2E, 0x0001);
377
378 /* Enable Left Output Mixer (MIXOUTL), Enable Right Output Mixer (MIXOUTR) */
379 /* idem for SPKOUTL and SPKOUTR */
380 write_reg(dev->i2c_bus, 0x03, 0x0330);
381
382 /* Enable DC Servo and trigger start-up mode on left and right channels */
383 write_reg(dev->i2c_bus, 0x54, 0x0033);
384
385 /* Add Delay */
386 rt_thread_mdelay(200);
387
388 /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate and output stages. Remove clamps */
389 write_reg(dev->i2c_bus, 0x60, 0x00EE);
390
391 /* Unmute DAC 1 (Left) */
392 write_reg(dev->i2c_bus, 0x0610, 0x00C0);
393
394 /* Unmute DAC 1 (Right) */
395 write_reg(dev->i2c_bus, 0x0611, 0x00C0);
396
397 /* Unmute the AIF1 Timeslot 0 DAC path */
398 write_reg(dev->i2c_bus, 0x0420, 0x0000);
399
400 /* Unmute DAC 2 (Left) */
401 write_reg(dev->i2c_bus, 0x0612, 0x00C0);
402
403 /* Unmute DAC 2 (Right) */
404 write_reg(dev->i2c_bus, 0x0613, 0x00C0);
405
406 /* Unmute the AIF1 Timeslot 1 DAC2 path */
407 write_reg(dev->i2c_bus, 0x0422, 0x0000);
408
409 }
410
411 /* Audio input selected */
412 if ((dev->type & 0x01F0) != 0 )
413 {
414 if ((dev->type & INPUT_DEVICE_DIGITAL_MICROPHONE_1) || (dev->type & INPUT_DEVICE_DIGITAL_MICROPHONE_2))
415 {
416 /* Enable Microphone bias 1 generator, Enable VMID */
417 write_reg(dev->i2c_bus, 0x01, 0x0013);
418
419 /* ADC oversample enable */
420 write_reg(dev->i2c_bus, 0x0620, 0x0002);
421
422 /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
423 write_reg(dev->i2c_bus, 0x0411, 0x3800);
424 }
425 else if (dev->type & INPUT_DEVICE_DIGITAL_MIC1_MIC2)
426 {
427 /* Enable Microphone bias 1 generator, Enable VMID */
428 write_reg(dev->i2c_bus, 0x01, 0x0013);
429
430 /* ADC oversample enable */
431 write_reg(dev->i2c_bus, 0x0620, 0x0002);
432
433 /* AIF ADC1 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
434 write_reg(dev->i2c_bus, 0x0410, 0x1800);
435
436 /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
437 write_reg(dev->i2c_bus, 0x0411, 0x1800);
438 }
439 else if ((dev->type & INPUT_DEVICE_INPUT_LINE_1) || (dev->type & INPUT_DEVICE_INPUT_LINE_2))
440 {
441
442 /* Disable mute on IN1L, IN1L Volume = +0dB */
443 write_reg(dev->i2c_bus, 0x18, 0x000B);
444
445 /* Disable mute on IN1R, IN1R Volume = +0dB */
446 write_reg(dev->i2c_bus, 0x1A, 0x000B);
447
448 /* AIF ADC1 HPF enable, HPF cut = hifi mode fc=4Hz at fs=48kHz */
449 write_reg(dev->i2c_bus, 0x0410, 0x1800);
450 }
451 }
452
453 /* Return communication control value */
454 return RT_EOK;
455
456 }
457
_read_id(struct rt_i2c_bus_device * bus,rt_uint16_t * id)458 static rt_err_t _read_id(struct rt_i2c_bus_device *bus, rt_uint16_t *id)
459 {
460 rt_uint8_t read_value[2];
461
462 read_reg(bus, 0x0000, 2, read_value);
463 *id = ((uint16_t)(read_value[0] << 8) & 0xFF00);
464 *id |= ((uint16_t)(read_value[1])& 0x00FF);
465
466 if (*id != WM8994_ID)
467 {
468 LOG_E("error id: 0x%04x", *id);
469 return -RT_ERROR;
470 }
471
472 LOG_I("wm8994 init success, id: %04x", *id);
473
474 return RT_EOK;
475 }
476
_set_mute(struct rt_i2c_bus_device * bus,uint32_t cmd)477 static rt_err_t _set_mute(struct rt_i2c_bus_device *bus, uint32_t cmd)
478 {
479 /* Set the Mute mode */
480 if (cmd == AUDIO_MUTE_ON)
481 {
482 /* Soft Mute the AIF1 Timeslot 0 DAC1 path L&R */
483 write_reg(bus, 0x420, 0x0200);
484
485 /* Soft Mute the AIF1 Timeslot 1 DAC2 path L&R */
486 write_reg(bus, 0x422, 0x0200);
487 }
488 else /* AUDIO_MUTE_OFF Disable the Mute */
489 {
490 /* Unmute the AIF1 Timeslot 0 DAC1 path L&R */
491 write_reg(bus, 0x420, 0x0010);
492
493 /* Unmute the AIF1 Timeslot 1 DAC2 path L&R */
494 write_reg(bus, 0x422, 0x0010);
495 }
496
497 return RT_EOK;
498 }
499
_play(struct rt_i2c_bus_device * bus)500 static rt_err_t _play(struct rt_i2c_bus_device *bus)
501 {
502 _set_mute(bus, AUDIO_MUTE_OFF);
503
504 return RT_EOK;
505 }
506
_set_volume(struct rt_i2c_bus_device * bus,rt_uint16_t type,rt_uint8_t volume)507 static rt_err_t _set_volume(struct rt_i2c_bus_device *bus, rt_uint16_t type, rt_uint8_t volume)
508 {
509 rt_uint8_t convertedvol = VOLUME_CONVERT(volume);
510
511 if (type & 0x000F)
512 {
513 /* Output volume */
514 if(convertedvol > 0x3E)
515 {
516 /* Unmute audio codec */
517 _set_mute(bus, AUDIO_MUTE_OFF);
518
519 /* Left Headphone Volume */
520 write_reg(bus, 0x1C, 0x3F | 0x140);
521
522 /* Right Headphone Volume */
523 write_reg(bus, 0x1D, 0x3F | 0x140);
524
525 /* Left Speaker Volume */
526 write_reg(bus, 0x26, 0x3F | 0x140);
527
528 /* Right Speaker Volume */
529 write_reg(bus, 0x27, 0x3F | 0x140);
530 }
531 else if (volume == 0)
532 {
533 /* Mute audio codec */
534 _set_mute(bus, AUDIO_MUTE_ON);
535 }
536 else
537 {
538 /* Unmute audio codec */
539 _set_mute(bus, AUDIO_MUTE_OFF);
540
541 /* Left Headphone Volume */
542 write_reg(bus, 0x1C, convertedvol | 0x140);
543
544 /* Right Headphone Volume */
545 write_reg(bus, 0x1D, convertedvol | 0x140);
546
547 /* Left Speaker Volume */
548 write_reg(bus, 0x26, convertedvol | 0x140);
549
550 /* Right Speaker Volume */
551 write_reg(bus, 0x27, convertedvol | 0x140);
552 }
553 }
554 /* Input volume */
555 else
556 {
557 convertedvol = VOLUME_IN_CONVERT(volume);
558
559 /* Left AIF1 ADC1 volume */
560 write_reg(bus, 0x400, convertedvol | 0x100);
561
562 /* Right AIF1 ADC1 volume */
563 write_reg(bus, 0x401, convertedvol | 0x100);
564
565 /* Left AIF1 ADC2 volume */
566 write_reg(bus, 0x404, convertedvol | 0x100);
567
568 /* Right AIF1 ADC2 volume */
569 write_reg(bus, 0x405, convertedvol | 0x100);
570 }
571
572 return RT_EOK;
573 }
574
_get_volume(struct rt_i2c_bus_device * bus,rt_uint32_t * value)575 static rt_err_t _get_volume(struct rt_i2c_bus_device *bus, rt_uint32_t *value)
576 {
577 rt_uint8_t read_value[2];
578
579 read_reg(bus, 0x001C, 2, read_value);
580
581 *value = ((uint16_t)(read_value[0] << 8) & 0xFF00);
582 *value |= ((uint16_t)(read_value[1])& 0x00FF);
583
584 return RT_EOK;
585 }
586
_set_frequency(struct rt_i2c_bus_device * bus,rt_uint32_t freq)587 static rt_err_t _set_frequency(struct rt_i2c_bus_device *bus, rt_uint32_t freq)
588 {
589 switch (freq)
590 {
591 case AUDIO_FREQUENCY_8K:
592 write_reg(bus, 0x210, 0x0003);
593 break;
594
595 case AUDIO_FREQUENCY_16K:
596 write_reg(bus, 0x210, 0x0033);
597 break;
598
599 case AUDIO_FREQUENCY_32K:
600 write_reg(bus, 0x210, 0x0063);
601 break;
602
603 case AUDIO_FREQUENCY_48K:
604 write_reg(bus, 0x210, 0x0083);
605 break;
606
607 case AUDIO_FREQUENCY_96K:
608 write_reg(bus, 0x210, 0x00A3);
609 break;
610
611 case AUDIO_FREQUENCY_11K:
612 write_reg(bus, 0x210, 0x0013);
613 break;
614
615 case AUDIO_FREQUENCY_22K:
616 write_reg(bus, 0x210, 0x0043);
617 break;
618
619 case AUDIO_FREQUENCY_44K:
620 write_reg(bus, 0x210, 0x0073);
621 break;
622
623 default:
624 write_reg(bus, 0x210, 0x0083);
625 break;
626 }
627
628 return RT_EOK;
629 }
630
_reset(struct rt_i2c_bus_device * bus)631 static rt_err_t _reset(struct rt_i2c_bus_device *bus)
632 {
633 /* Reset Codec by writing in 0x0000 address register */
634 write_reg(bus, 0x0000, 0x0000);
635
636 return RT_EOK;
637 }
638
rt_wm8994_init(rt_device_t dev)639 static rt_err_t rt_wm8994_init(rt_device_t dev)
640 {
641 RT_ASSERT(dev != RT_NULL);
642 rt_err_t result = RT_EOK;
643 static rt_uint16_t old_type = DEVICE_NONE;
644
645 struct wm8994_dev *device = (struct wm8994_dev *)dev;
646
647 if (old_type == device->type)
648 {
649 return RT_EOK;
650 }
651
652 old_type = device->type;
653
654 device->i2c_bus = rt_i2c_bus_device_find(I2C_NAME);
655 if (device->i2c_bus == RT_NULL)
656 {
657 LOG_E("can't find %c deivce", I2C_NAME);
658 return -RT_ERROR;
659 }
660
661 result = _wm8994_init(device);
662 /* set volume */
663 _set_volume(device->i2c_bus, device->type, VOLUME_CONVERT(100));
664 /* set frequency */
665 _set_frequency(device->i2c_bus, AUDIO_FREQUENCY_44K);
666
667 return result;
668 }
669
rt_wm8994_open(rt_device_t dev,rt_uint16_t oflag)670 static rt_err_t rt_wm8994_open(rt_device_t dev, rt_uint16_t oflag)
671 {
672 RT_ASSERT(dev != RT_NULL);
673
674 return RT_EOK;
675 }
676
rt_wm8994_close(rt_device_t dev)677 static rt_err_t rt_wm8994_close(rt_device_t dev)
678 {
679 RT_ASSERT(dev != RT_NULL);
680 struct wm8994_dev *device = (struct wm8994_dev *)dev;
681
682 _set_mute(device->i2c_bus, AUDIO_MUTE_ON);
683
684 /* Mute the AIF1 Timeslot 0 DAC1 path */
685 write_reg(device->i2c_bus, 0x420, 0x0200);
686 /* Mute the AIF1 Timeslot 1 DAC2 path */
687 write_reg(device->i2c_bus, 0x422, 0x0200);
688 /* Disable DAC1L_TO_HPOUT1L */
689 write_reg(device->i2c_bus, 0x2D, 0x0000);
690 /* Disable DAC1R_TO_HPOUT1R */
691 write_reg(device->i2c_bus, 0x2E, 0x0000);
692 /* Disable DAC1 and DAC2 */
693 write_reg(device->i2c_bus, 0x05, 0x0000);
694 /* Reset Codec by writing in 0x0000 address register */
695 write_reg(device->i2c_bus, 0x0000, 0x0000);
696
697 return RT_EOK;
698 }
699
rt_wm8994_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)700 static rt_ssize_t rt_wm8994_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
701 {
702 RT_ASSERT(dev != RT_NULL);
703
704 return RT_EOK;
705 }
706
rt_wm8994_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)707 static rt_ssize_t rt_wm8994_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
708 {
709 RT_ASSERT(dev != RT_NULL);
710
711 return RT_EOK;
712 }
713
rt_wm8994_control(rt_device_t dev,int cmd,void * args)714 static rt_err_t rt_wm8994_control(rt_device_t dev, int cmd, void *args)
715 {
716 RT_ASSERT(dev != RT_NULL);
717 struct wm8994_dev *device = (struct wm8994_dev *)dev;
718 rt_err_t result = RT_EOK;
719 switch (cmd)
720 {
721 case GET_ID:
722 result = _read_id(device->i2c_bus, (rt_uint16_t*)args);
723 break;
724
725 case SET_FREQUENCE:
726 result = _set_frequency(device->i2c_bus, (*(rt_uint32_t *)args));
727 break;
728
729 case SET_VOLUME:
730 result = _set_volume(device->i2c_bus, device->type, (*(rt_uint8_t*)args));
731 break;
732
733 case GET_VOLUME:
734 result = _get_volume(device->i2c_bus, (rt_uint32_t *)args);
735 break;
736
737 case SET_MUTE:
738 result = _set_mute(device->i2c_bus, (*(rt_uint32_t*)args));
739 break;
740
741 case SET_RESET:
742 result = _reset(device->i2c_bus);
743 break;
744
745 case START_PLAY:
746 result = _play(device->i2c_bus);
747 break;
748
749 case SET_PLAY_TYPE:
750 device->type = 0;
751 device->type = *(rt_uint32_t *)args;
752 rt_wm8994_init(dev);
753 break;
754
755 default:
756 LOG_D("not support cmd");
757 break;
758 }
759
760 return result;
761 }
762
wm8994_init(void)763 int wm8994_init(void)
764 {
765 rt_wm8994.dev.type = RT_Device_Class_Sound;
766 rt_wm8994.dev.init = rt_wm8994_init;
767 rt_wm8994.dev.open = rt_wm8994_open;
768 rt_wm8994.dev.close = rt_wm8994_close;
769 rt_wm8994.dev.read = rt_wm8994_read;
770 rt_wm8994.dev.write = rt_wm8994_write;
771 rt_wm8994.dev.control = rt_wm8994_control;
772 rt_wm8994.dev.user_data = RT_NULL;
773
774 rt_device_register(&rt_wm8994.dev, "decoder", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
775
776 LOG_I("lowlevel decoder device init success!");
777
778 return RT_EOK;
779 }
780 INIT_DEVICE_EXPORT(wm8994_init);
781
782 #endif
783