1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2012 Samsung Electronics
4 * R. Chandrasekar <rcsekar@samsung.com>
7 #include <audio_codec.h>
16 #include <asm/arch/clk.h>
17 #include <asm/arch/cpu.h>
18 #include <asm/arch/sound.h>
20 #include "wm8994_registers.h"
22 /* defines for wm8994 system clock selection */
23 #define SEL_MCLK1 0x00
24 #define SEL_MCLK2 0x08
28 /* fll config to configure fll */
29 struct wm8994_fll_config
{
31 int in
; /* Input frequency in Hz */
32 int out
; /* output frequency in Hz */
35 /* codec private data */
37 enum wm8994_type type
; /* codec type of wolfson */
38 int revision
; /* Revision */
39 int sysclk
[WM8994_MAX_AIF
]; /* System clock frequency in Hz */
40 int mclk
[WM8994_MAX_AIF
]; /* master clock frequency in Hz */
41 int aifclk
[WM8994_MAX_AIF
]; /* audio interface clock in Hz */
42 struct wm8994_fll_config fll
[2]; /* fll config to configure fll */
47 /* wm 8994 supported sampling rate values */
48 static unsigned int src_rate
[] = {
49 8000, 11025, 12000, 16000, 22050, 24000,
50 32000, 44100, 48000, 88200, 96000
53 /* op clock divisions */
54 static int opclk_divs
[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 };
56 /* lr clock frame size ratio */
57 static int fs_ratios
[] = {
58 64, 128, 192, 256, 348, 512, 768, 1024, 1408, 1536
61 /* bit clock divisors */
62 static int bclk_divs
[] = {
63 10, 15, 20, 30, 40, 50, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480,
64 640, 880, 960, 1280, 1760, 1920
68 * Writes value to a device register through i2c
70 * @param priv Private data for driver
71 * @param reg reg number to be write
72 * @param data data to be writen to the above registor
74 * @return int value 1 for change, 0 for no change or negative error code.
76 static int wm8994_i2c_write(struct wm8994_priv
*priv
, unsigned int reg
,
81 val
[0] = (unsigned char)((data
>> 8) & 0xff);
82 val
[1] = (unsigned char)(data
& 0xff);
83 debug("Write Addr : 0x%04X, Data : 0x%04X\n", reg
, data
);
85 #ifdef CONFIG_DM_SOUND
86 debug("dev = %s\n", priv
->dev
->name
);
87 return dm_i2c_write(priv
->dev
, reg
, val
, 2);
89 return i2c_write(priv
->i2c_addr
, reg
, 2, val
, 2);
94 * Read a value from a device register through i2c
96 * @param priv Private data for driver
97 * @param reg reg number to be read
98 * @param data address of read data to be stored
100 * @return int value 0 for success, -1 in case of error.
102 static unsigned int wm8994_i2c_read(struct wm8994_priv
*priv
, unsigned int reg
,
103 unsigned short *data
)
105 unsigned char val
[2];
108 #ifdef CONFIG_DM_SOUND
109 ret
= dm_i2c_read(priv
->dev
, reg
, val
, 1);
111 ret
= i2c_read(priv
->i2c_addr
, reg
, 2, val
, 2);
114 debug("%s: Error while reading register %#04x\n",
127 * update device register bits through i2c
129 * @param priv Private data for driver
130 * @param reg codec register
131 * @param mask register mask
132 * @param value new value
134 * @return int value 1 if change in the register value,
135 * 0 for no change or negative error code.
137 static int wm8994_bic_or(struct wm8994_priv
*priv
, unsigned int reg
,
138 unsigned short mask
, unsigned short value
)
140 int change
, ret
= 0;
141 unsigned short old
, new;
143 if (wm8994_i2c_read(priv
, reg
, &old
) != 0)
145 new = (old
& ~mask
) | (value
& mask
);
146 change
= (old
!= new) ? 1 : 0;
148 ret
= wm8994_i2c_write(priv
, reg
, new);
156 * Sets i2s set format
158 * @param priv wm8994 information
159 * @param aif_id Interface ID
160 * @param fmt i2S format
162 * @return -1 for error and 0 Success.
164 static int wm8994_set_fmt(struct wm8994_priv
*priv
, int aif_id
, uint fmt
)
175 ms_reg
= WM8994_AIF1_MASTER_SLAVE
;
176 aif_reg
= WM8994_AIF1_CONTROL_1
;
177 aif_clk
= WM8994_AIF1_CLOCKING_1
;
180 ms_reg
= WM8994_AIF2_MASTER_SLAVE
;
181 aif_reg
= WM8994_AIF2_CONTROL_1
;
182 aif_clk
= WM8994_AIF2_CLOCKING_1
;
185 debug("%s: Invalid audio interface selection\n", __func__
);
189 switch (fmt
& SND_SOC_DAIFMT_MASTER_MASK
) {
190 case SND_SOC_DAIFMT_CBS_CFS
:
192 case SND_SOC_DAIFMT_CBM_CFM
:
193 ms
= WM8994_AIF1_MSTR
;
196 debug("%s: Invalid i2s master selection\n", __func__
);
200 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
201 case SND_SOC_DAIFMT_DSP_B
:
202 aif
|= WM8994_AIF1_LRCLK_INV
;
203 case SND_SOC_DAIFMT_DSP_A
:
206 case SND_SOC_DAIFMT_I2S
:
209 case SND_SOC_DAIFMT_RIGHT_J
:
211 case SND_SOC_DAIFMT_LEFT_J
:
215 debug("%s: Invalid i2s format selection\n", __func__
);
219 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
220 case SND_SOC_DAIFMT_DSP_A
:
221 case SND_SOC_DAIFMT_DSP_B
:
222 /* frame inversion not valid for DSP modes */
223 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
224 case SND_SOC_DAIFMT_NB_NF
:
226 case SND_SOC_DAIFMT_IB_NF
:
227 aif
|= WM8994_AIF1_BCLK_INV
;
230 debug("%s: Invalid i2s frame inverse selection\n",
236 case SND_SOC_DAIFMT_I2S
:
237 case SND_SOC_DAIFMT_RIGHT_J
:
238 case SND_SOC_DAIFMT_LEFT_J
:
239 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
240 case SND_SOC_DAIFMT_NB_NF
:
242 case SND_SOC_DAIFMT_IB_IF
:
243 aif
|= WM8994_AIF1_BCLK_INV
| WM8994_AIF1_LRCLK_INV
;
245 case SND_SOC_DAIFMT_IB_NF
:
246 aif
|= WM8994_AIF1_BCLK_INV
;
248 case SND_SOC_DAIFMT_NB_IF
:
249 aif
|= WM8994_AIF1_LRCLK_INV
;
252 debug("%s: Invalid i2s clock polarity selection\n",
258 debug("%s: Invalid i2s format selection\n", __func__
);
262 error
= wm8994_bic_or(priv
, aif_reg
, WM8994_AIF1_BCLK_INV
|
263 WM8994_AIF1_LRCLK_INV_MASK
|
264 WM8994_AIF1_FMT_MASK
, aif
);
266 error
|= wm8994_bic_or(priv
, ms_reg
, WM8994_AIF1_MSTR_MASK
, ms
);
267 error
|= wm8994_bic_or(priv
, aif_clk
, WM8994_AIF1CLK_ENA_MASK
,
270 debug("%s: codec register access error\n", __func__
);
278 * Sets hw params FOR WM8994
280 * @param priv wm8994 information pointer
281 * @param aif_id Audio interface ID
282 * @param sampling_rate Sampling rate
283 * @param bits_per_sample Bits per sample
284 * @param Channels Channels in the given audio input
286 * @return -1 for error and 0 Success.
288 static int wm8994_hw_params(struct wm8994_priv
*priv
, int aif_id
,
289 uint sampling_rate
, uint bits_per_sample
,
301 int i
, cur_val
, best_val
, bclk_rate
, best
;
302 unsigned short reg_data
;
307 aif1_reg
= WM8994_AIF1_CONTROL_1
;
308 aif2_reg
= WM8994_AIF1_CONTROL_2
;
309 bclk_reg
= WM8994_AIF1_BCLK
;
310 rate_reg
= WM8994_AIF1_RATE
;
313 aif1_reg
= WM8994_AIF2_CONTROL_1
;
314 aif2_reg
= WM8994_AIF2_CONTROL_2
;
315 bclk_reg
= WM8994_AIF2_BCLK
;
316 rate_reg
= WM8994_AIF2_RATE
;
322 bclk_rate
= sampling_rate
* 32;
323 switch (bits_per_sample
) {
343 /* Try to find an appropriate sample rate; look for an exact match. */
344 for (i
= 0; i
< ARRAY_SIZE(src_rate
); i
++)
345 if (src_rate
[i
] == sampling_rate
)
348 if (i
== ARRAY_SIZE(src_rate
)) {
349 debug("%s: Could not get the best matching samplingrate\n",
354 rate_val
|= i
<< WM8994_AIF1_SR_SHIFT
;
356 /* AIFCLK/fs ratio; look for a close match in either direction */
358 best_val
= abs((fs_ratios
[0] * sampling_rate
) - priv
->aifclk
[id
]);
360 for (i
= 1; i
< ARRAY_SIZE(fs_ratios
); i
++) {
361 cur_val
= abs(fs_ratios
[i
] * sampling_rate
- priv
->aifclk
[id
]);
362 if (cur_val
>= best_val
)
371 * We may not get quite the right frequency if using
372 * approximate clocks so look for the closest match that is
373 * higher than the target (we need to ensure that there enough
374 * BCLKs to clock out the samples).
377 for (i
= 0; i
< ARRAY_SIZE(bclk_divs
); i
++) {
378 cur_val
= (priv
->aifclk
[id
] * 10 / bclk_divs
[i
]) - bclk_rate
;
379 if (cur_val
< 0) /* BCLK table is sorted */
384 if (i
== ARRAY_SIZE(bclk_divs
)) {
385 debug("%s: Could not get the best matching bclk division\n",
390 bclk_rate
= priv
->aifclk
[id
] * 10 / bclk_divs
[best
];
391 bclk
|= best
<< WM8994_AIF1_BCLK_DIV_SHIFT
;
393 if (wm8994_i2c_read(priv
, aif1_reg
, ®_data
) != 0) {
394 debug("%s: AIF1 register read Failed\n", __func__
);
398 if ((channels
== 1) && ((reg_data
& 0x18) == 0x18))
399 aif2
|= WM8994_AIF1_MONO
;
401 if (priv
->aifclk
[id
] == 0) {
402 debug("%s:Audio interface clock not set\n", __func__
);
406 ret
= wm8994_bic_or(priv
, aif1_reg
, WM8994_AIF1_WL_MASK
, aif1
);
407 ret
|= wm8994_bic_or(priv
, aif2_reg
, WM8994_AIF1_MONO
, aif2
);
408 ret
|= wm8994_bic_or(priv
, bclk_reg
, WM8994_AIF1_BCLK_DIV_MASK
,
410 ret
|= wm8994_bic_or(priv
, rate_reg
, WM8994_AIF1_SR_MASK
|
411 WM8994_AIF1CLK_RATE_MASK
, rate_val
);
413 debug("rate vale = %x , bclk val= %x\n", rate_val
, bclk
);
416 debug("%s: codec register access error\n", __func__
);
424 * Configures Audio interface Clock
426 * @param priv wm8994 information pointer
427 * @param aif Audio Interface ID
429 * @return -1 for error and 0 Success.
431 static int configure_aif_clock(struct wm8994_priv
*priv
, int aif
)
438 /* AIF(1/0) register adress offset calculated */
444 switch (priv
->sysclk
[aif
- 1]) {
445 case WM8994_SYSCLK_MCLK1
:
447 rate
= priv
->mclk
[0];
450 case WM8994_SYSCLK_MCLK2
:
452 rate
= priv
->mclk
[1];
455 case WM8994_SYSCLK_FLL1
:
457 rate
= priv
->fll
[0].out
;
460 case WM8994_SYSCLK_FLL2
:
462 rate
= priv
->fll
[1].out
;
466 debug("%s: Invalid input clock selection [%d]\n",
467 __func__
, priv
->sysclk
[aif
- 1]);
471 /* if input clock frequenct is more than 135Mhz then divide */
472 if (rate
>= WM8994_MAX_INPUT_CLK_FREQ
) {
474 reg1
|= WM8994_AIF1CLK_DIV
;
477 priv
->aifclk
[aif
- 1] = rate
;
479 ret
= wm8994_bic_or(priv
, WM8994_AIF1_CLOCKING_1
+ offset
,
480 WM8994_AIF1CLK_SRC_MASK
| WM8994_AIF1CLK_DIV
,
483 if (aif
== WM8994_AIF1
)
484 ret
|= wm8994_bic_or(priv
, WM8994_CLOCKING_1
,
485 WM8994_AIF1DSPCLK_ENA_MASK
| WM8994_SYSDSPCLK_ENA_MASK
,
486 WM8994_AIF1DSPCLK_ENA
| WM8994_SYSDSPCLK_ENA
);
487 else if (aif
== WM8994_AIF2
)
488 ret
|= wm8994_bic_or(priv
, WM8994_CLOCKING_1
,
489 WM8994_SYSCLK_SRC
| WM8994_AIF2DSPCLK_ENA_MASK
|
490 WM8994_SYSDSPCLK_ENA_MASK
, WM8994_SYSCLK_SRC
|
491 WM8994_AIF2DSPCLK_ENA
| WM8994_SYSDSPCLK_ENA
);
494 debug("%s: codec register access error\n", __func__
);
502 * Configures Audio interface for the given frequency
504 * @param priv wm8994 information
505 * @param aif_id Audio Interface
506 * @param clk_id Input Clock ID
507 * @param freq Sampling frequency in Hz
509 * @return -1 for error and 0 success.
511 static int wm8994_set_sysclk(struct wm8994_priv
*priv
, int aif_id
, int clk_id
,
517 priv
->sysclk
[aif_id
- 1] = clk_id
;
520 case WM8994_SYSCLK_MCLK1
:
521 priv
->mclk
[0] = freq
;
523 ret
= wm8994_bic_or(priv
, WM8994_AIF1_CLOCKING_2
,
524 WM8994_AIF2DAC_DIV_MASK
, 0);
528 case WM8994_SYSCLK_MCLK2
:
529 /* TODO: Set GPIO AF */
530 priv
->mclk
[1] = freq
;
533 case WM8994_SYSCLK_FLL1
:
534 case WM8994_SYSCLK_FLL2
:
537 case WM8994_SYSCLK_OPCLK
:
539 * Special case - a division (times 10) is given and
540 * no effect on main clocking.
543 for (i
= 0; i
< ARRAY_SIZE(opclk_divs
); i
++)
544 if (opclk_divs
[i
] == freq
)
546 if (i
== ARRAY_SIZE(opclk_divs
)) {
547 debug("%s frequency divisor not found\n",
551 ret
= wm8994_bic_or(priv
, WM8994_CLOCKING_2
,
552 WM8994_OPCLK_DIV_MASK
, i
);
553 ret
|= wm8994_bic_or(priv
, WM8994_POWER_MANAGEMENT_2
,
557 ret
|= wm8994_bic_or(priv
, WM8994_POWER_MANAGEMENT_2
,
558 WM8994_OPCLK_ENA
, 0);
562 debug("%s Invalid input clock selection [%d]\n",
567 ret
|= configure_aif_clock(priv
, aif_id
);
570 debug("%s: codec register access error\n", __func__
);
578 * Initializes Volume for AIF2 to HP path
580 * @param priv wm8994 information
581 * @returns -1 for error and 0 Success.
584 static int wm8994_init_volume_aif2_dac1(struct wm8994_priv
*priv
)
589 ret
= wm8994_bic_or(priv
, WM8994_AIF2_DAC_FILTERS_1
,
590 WM8994_AIF2DAC_MUTE_MASK
, 0);
593 ret
|= wm8994_bic_or(priv
, WM8994_AIF2_DAC_LEFT_VOLUME
,
594 WM8994_AIF2DAC_VU_MASK
| WM8994_AIF2DACL_VOL_MASK
,
595 WM8994_AIF2DAC_VU
| 0xff);
597 ret
|= wm8994_bic_or(priv
, WM8994_AIF2_DAC_RIGHT_VOLUME
,
598 WM8994_AIF2DAC_VU_MASK
| WM8994_AIF2DACR_VOL_MASK
,
599 WM8994_AIF2DAC_VU
| 0xff);
602 ret
|= wm8994_bic_or(priv
, WM8994_DAC1_LEFT_VOLUME
,
603 WM8994_DAC1_VU_MASK
| WM8994_DAC1L_VOL_MASK
|
604 WM8994_DAC1L_MUTE_MASK
, WM8994_DAC1_VU
| 0xc0);
606 ret
|= wm8994_bic_or(priv
, WM8994_DAC1_RIGHT_VOLUME
,
607 WM8994_DAC1_VU_MASK
| WM8994_DAC1R_VOL_MASK
|
608 WM8994_DAC1R_MUTE_MASK
, WM8994_DAC1_VU
| 0xc0);
609 /* Head Phone Volume */
610 ret
|= wm8994_i2c_write(priv
, WM8994_LEFT_OUTPUT_VOLUME
, 0x12D);
611 ret
|= wm8994_i2c_write(priv
, WM8994_RIGHT_OUTPUT_VOLUME
, 0x12D);
614 debug("%s: codec register access error\n", __func__
);
622 * Initializes Volume for AIF1 to HP path
624 * @param priv wm8994 information
625 * @returns -1 for error and 0 Success.
628 static int wm8994_init_volume_aif1_dac1(struct wm8994_priv
*priv
)
633 ret
|= wm8994_i2c_write(priv
, WM8994_AIF1_DAC_FILTERS_1
, 0x0000);
635 ret
|= wm8994_bic_or(priv
, WM8994_DAC1_LEFT_VOLUME
,
636 WM8994_DAC1_VU_MASK
| WM8994_DAC1L_VOL_MASK
|
637 WM8994_DAC1L_MUTE_MASK
, WM8994_DAC1_VU
| 0xc0);
639 ret
|= wm8994_bic_or(priv
, WM8994_DAC1_RIGHT_VOLUME
,
640 WM8994_DAC1_VU_MASK
| WM8994_DAC1R_VOL_MASK
|
641 WM8994_DAC1R_MUTE_MASK
, WM8994_DAC1_VU
| 0xc0);
642 /* Head Phone Volume */
643 ret
|= wm8994_i2c_write(priv
, WM8994_LEFT_OUTPUT_VOLUME
, 0x12D);
644 ret
|= wm8994_i2c_write(priv
, WM8994_RIGHT_OUTPUT_VOLUME
, 0x12D);
647 debug("%s: codec register access error\n", __func__
);
655 * Intialise wm8994 codec device
657 * @param priv wm8994 information
659 * @returns -1 for error and 0 Success.
661 static int wm8994_device_init(struct wm8994_priv
*priv
)
664 unsigned short reg_data
;
667 wm8994_i2c_write(priv
, WM8994_SOFTWARE_RESET
, WM8994_SW_RESET
);
669 ret
= wm8994_i2c_read(priv
, WM8994_SOFTWARE_RESET
, ®_data
);
671 debug("Failed to read ID register\n");
675 if (reg_data
== WM8994_ID
) {
677 debug("Device registered as type %d\n", priv
->type
);
680 debug("Device is not a WM8994, ID is %x\n", ret
);
684 ret
= wm8994_i2c_read(priv
, WM8994_CHIP_REVISION
, ®_data
);
686 debug("Failed to read revision register: %d\n", ret
);
689 priv
->revision
= reg_data
;
690 debug("%s revision %c\n", devname
, 'A' + priv
->revision
);
695 static int wm8994_setup_interface(struct wm8994_priv
*priv
,
696 enum en_audio_interface aif_id
)
701 ret
= wm8994_bic_or(priv
, WM8994_POWER_MANAGEMENT_1
,
702 WM8994_VMID_SEL_MASK
| WM8994_BIAS_ENA_MASK
, 0x3);
704 /* Charge Pump Enable */
705 ret
|= wm8994_bic_or(priv
, WM8994_CHARGE_PUMP_1
, WM8994_CP_ENA_MASK
,
708 /* Head Phone Power Enable */
709 ret
|= wm8994_bic_or(priv
, WM8994_POWER_MANAGEMENT_1
,
710 WM8994_HPOUT1L_ENA_MASK
, WM8994_HPOUT1L_ENA
);
712 ret
|= wm8994_bic_or(priv
, WM8994_POWER_MANAGEMENT_1
,
713 WM8994_HPOUT1R_ENA_MASK
, WM8994_HPOUT1R_ENA
);
715 if (aif_id
== WM8994_AIF1
) {
716 ret
|= wm8994_i2c_write(priv
, WM8994_POWER_MANAGEMENT_2
,
717 WM8994_TSHUT_ENA
| WM8994_MIXINL_ENA
|
718 WM8994_MIXINR_ENA
| WM8994_IN2L_ENA
|
721 ret
|= wm8994_i2c_write(priv
, WM8994_POWER_MANAGEMENT_4
,
722 WM8994_ADCL_ENA
| WM8994_ADCR_ENA
|
723 WM8994_AIF1ADC1R_ENA
|
724 WM8994_AIF1ADC1L_ENA
);
726 /* Power enable for AIF1 and DAC1 */
727 ret
|= wm8994_i2c_write(priv
, WM8994_POWER_MANAGEMENT_5
,
728 WM8994_AIF1DACL_ENA
|
729 WM8994_AIF1DACR_ENA
|
730 WM8994_DAC1L_ENA
| WM8994_DAC1R_ENA
);
731 } else if (aif_id
== WM8994_AIF2
) {
732 /* Power enable for AIF2 and DAC1 */
733 ret
|= wm8994_bic_or(priv
, WM8994_POWER_MANAGEMENT_5
,
734 WM8994_AIF2DACL_ENA_MASK
| WM8994_AIF2DACR_ENA_MASK
|
735 WM8994_DAC1L_ENA_MASK
| WM8994_DAC1R_ENA_MASK
,
736 WM8994_AIF2DACL_ENA
| WM8994_AIF2DACR_ENA
|
737 WM8994_DAC1L_ENA
| WM8994_DAC1R_ENA
);
739 /* Head Phone Initialisation */
740 ret
|= wm8994_bic_or(priv
, WM8994_ANALOGUE_HP_1
,
741 WM8994_HPOUT1L_DLY_MASK
| WM8994_HPOUT1R_DLY_MASK
,
742 WM8994_HPOUT1L_DLY
| WM8994_HPOUT1R_DLY
);
744 ret
|= wm8994_bic_or(priv
, WM8994_DC_SERVO_1
,
745 WM8994_DCS_ENA_CHAN_0_MASK
|
746 WM8994_DCS_ENA_CHAN_1_MASK
, WM8994_DCS_ENA_CHAN_0
|
747 WM8994_DCS_ENA_CHAN_1
);
749 ret
|= wm8994_bic_or(priv
, WM8994_ANALOGUE_HP_1
,
750 WM8994_HPOUT1L_DLY_MASK
|
751 WM8994_HPOUT1R_DLY_MASK
| WM8994_HPOUT1L_OUTP_MASK
|
752 WM8994_HPOUT1R_OUTP_MASK
|
753 WM8994_HPOUT1L_RMV_SHORT_MASK
|
754 WM8994_HPOUT1R_RMV_SHORT_MASK
, WM8994_HPOUT1L_DLY
|
755 WM8994_HPOUT1R_DLY
| WM8994_HPOUT1L_OUTP
|
756 WM8994_HPOUT1R_OUTP
| WM8994_HPOUT1L_RMV_SHORT
|
757 WM8994_HPOUT1R_RMV_SHORT
);
759 /* MIXER Config DAC1 to HP */
760 ret
|= wm8994_bic_or(priv
, WM8994_OUTPUT_MIXER_1
,
761 WM8994_DAC1L_TO_HPOUT1L_MASK
,
762 WM8994_DAC1L_TO_HPOUT1L
);
764 ret
|= wm8994_bic_or(priv
, WM8994_OUTPUT_MIXER_2
,
765 WM8994_DAC1R_TO_HPOUT1R_MASK
,
766 WM8994_DAC1R_TO_HPOUT1R
);
768 if (aif_id
== WM8994_AIF1
) {
769 /* Routing AIF1 to DAC1 */
770 ret
|= wm8994_i2c_write(priv
, WM8994_DAC1_LEFT_MIXER_ROUTING
,
771 WM8994_AIF1DAC1L_TO_DAC1L
);
773 ret
|= wm8994_i2c_write(priv
, WM8994_DAC1_RIGHT_MIXER_ROUTING
,
774 WM8994_AIF1DAC1R_TO_DAC1R
);
776 /* GPIO Settings for AIF1 */
777 ret
|= wm8994_i2c_write(priv
, WM8994_GPIO_1
,
778 WM8994_GPIO_DIR_OUTPUT
|
779 WM8994_GPIO_FUNCTION_I2S_CLK
|
780 WM8994_GPIO_INPUT_DEBOUNCE
);
782 ret
|= wm8994_init_volume_aif1_dac1(priv
);
783 } else if (aif_id
== WM8994_AIF2
) {
784 /* Routing AIF2 to DAC1 */
785 ret
|= wm8994_bic_or(priv
, WM8994_DAC1_LEFT_MIXER_ROUTING
,
786 WM8994_AIF2DACL_TO_DAC1L_MASK
,
787 WM8994_AIF2DACL_TO_DAC1L
);
789 ret
|= wm8994_bic_or(priv
, WM8994_DAC1_RIGHT_MIXER_ROUTING
,
790 WM8994_AIF2DACR_TO_DAC1R_MASK
,
791 WM8994_AIF2DACR_TO_DAC1R
);
793 /* GPIO Settings for AIF2 */
795 ret
|= wm8994_bic_or(priv
, WM8994_GPIO_3
, WM8994_GPIO_DIR_MASK
|
796 WM8994_GPIO_FUNCTION_MASK
,
797 WM8994_GPIO_DIR_OUTPUT
);
800 ret
|= wm8994_bic_or(priv
, WM8994_GPIO_4
, WM8994_GPIO_DIR_MASK
|
801 WM8994_GPIO_FUNCTION_MASK
,
802 WM8994_GPIO_DIR_OUTPUT
);
805 ret
|= wm8994_bic_or(priv
, WM8994_GPIO_5
, WM8994_GPIO_DIR_MASK
|
806 WM8994_GPIO_FUNCTION_MASK
,
807 WM8994_GPIO_DIR_OUTPUT
);
809 ret
|= wm8994_init_volume_aif2_dac1(priv
);
815 debug("%s: Codec chip setup ok\n", __func__
);
818 debug("%s: Codec chip setup error\n", __func__
);
822 #ifndef CONFIG_DM_SOUND
824 * Gets fdt values for wm8994 config parameters
826 * @param pcodec_info codec information structure
827 * @param blob FDT blob
828 * @return int value, 0 for success
830 static int get_codec_values(struct sound_codec_info
*pcodec_info
,
834 enum fdt_compat_id compat
;
838 /* Get the node from FDT for codec */
839 node
= fdtdec_next_compatible(blob
, 0, COMPAT_WOLFSON_WM8994_CODEC
);
841 debug("EXYNOS_SOUND: No node for codec in device tree\n");
842 debug("node = %d\n", node
);
846 parent
= fdt_parent_offset(blob
, node
);
848 debug("%s: Cannot find node parent\n", __func__
);
852 compat
= fdtdec_lookup(blob
, parent
);
854 case COMPAT_SAMSUNG_S3C2440_I2C
:
855 pcodec_info
->i2c_bus
= i2c_get_bus_num_fdt(parent
);
856 error
|= pcodec_info
->i2c_bus
;
857 debug("i2c bus = %d\n", pcodec_info
->i2c_bus
);
858 pcodec_info
->i2c_dev_addr
= fdtdec_get_int(blob
, node
,
860 error
|= pcodec_info
->i2c_dev_addr
;
861 debug("i2c dev addr = %d\n", pcodec_info
->i2c_dev_addr
);
864 debug("%s: Unknown compat id %d\n", __func__
, compat
);
869 debug("fail to get wm8994 codec node properties\n");
877 static int _wm8994_init(struct wm8994_priv
*priv
,
878 enum en_audio_interface aif_id
, int sampling_rate
,
879 int mclk_freq
, int bits_per_sample
,
880 unsigned int channels
)
884 ret
= wm8994_setup_interface(priv
, aif_id
);
886 debug("%s: wm8994 codec chip init failed\n", __func__
);
890 ret
= wm8994_set_sysclk(priv
, aif_id
, WM8994_SYSCLK_MCLK1
, mclk_freq
);
892 debug("%s: wm8994 codec set sys clock failed\n", __func__
);
896 ret
= wm8994_hw_params(priv
, aif_id
, sampling_rate
, bits_per_sample
,
900 ret
= wm8994_set_fmt(priv
, aif_id
, SND_SOC_DAIFMT_I2S
|
901 SND_SOC_DAIFMT_NB_NF
|
902 SND_SOC_DAIFMT_CBS_CFS
);
908 #ifndef CONFIG_DM_SOUND
909 /* WM8994 Device Initialisation */
910 int wm8994_init(const void *blob
, enum en_audio_interface aif_id
,
911 int sampling_rate
, int mclk_freq
, int bits_per_sample
,
912 unsigned int channels
)
914 struct sound_codec_info pcodec_info
;
915 struct wm8994_priv wm8994_info
;
918 /* Get the codec Values */
919 if (get_codec_values(&pcodec_info
, blob
) < 0) {
920 debug("FDT Codec values failed\n");
924 /* shift the device address by 1 for 7 bit addressing */
925 wm8994_info
.i2c_addr
= pcodec_info
.i2c_dev_addr
;
926 i2c_set_bus_num(pcodec_info
.i2c_bus
);
927 ret
= wm8994_device_init(&wm8994_info
);
929 debug("%s: wm8994 codec chip init failed\n", __func__
);
933 return _wm8994_init(&wm8994_info
, aif_id
, sampling_rate
, mclk_freq
,
934 bits_per_sample
, channels
);
938 static int wm8994_set_params(struct udevice
*dev
, int interface
, int rate
,
939 int mclk_freq
, int bits_per_sample
, uint channels
)
941 struct wm8994_priv
*priv
= dev_get_priv(dev
);
943 return _wm8994_init(priv
, interface
, rate
, mclk_freq
, bits_per_sample
,
947 static int wm8994_probe(struct udevice
*dev
)
949 struct wm8994_priv
*priv
= dev_get_priv(dev
);
952 return wm8994_device_init(priv
);
955 static const struct audio_codec_ops wm8994_ops
= {
956 .set_params
= wm8994_set_params
,
959 static const struct udevice_id wm8994_ids
[] = {
960 { .compatible
= "wolfson,wm8994" },
964 U_BOOT_DRIVER(wm8994
) = {
966 .id
= UCLASS_AUDIO_CODEC
,
967 .of_match
= wm8994_ids
,
968 .probe
= wm8994_probe
,
970 .priv_auto_alloc_size
= sizeof(struct wm8994_priv
),