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