xref: /openbmc/u-boot/drivers/sound/wm8994.c (revision 107ab83e618486603190cc07bed2eae1fb9ca06f)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2a2d8e0a7SRajeshwari Shinde /*
3a2d8e0a7SRajeshwari Shinde  * Copyright (C) 2012 Samsung Electronics
4a2d8e0a7SRajeshwari Shinde  * R. Chandrasekar <rcsekar@samsung.com>
5a2d8e0a7SRajeshwari Shinde  */
6150c5afeSSimon Glass #include <common.h>
7a2d8e0a7SRajeshwari Shinde #include <asm/arch/clk.h>
8a2d8e0a7SRajeshwari Shinde #include <asm/arch/cpu.h>
9a2d8e0a7SRajeshwari Shinde #include <asm/gpio.h>
10a2d8e0a7SRajeshwari Shinde #include <asm/io.h>
11a2d8e0a7SRajeshwari Shinde #include <div64.h>
126647c7acSRajeshwari Shinde #include <fdtdec.h>
13a2d8e0a7SRajeshwari Shinde #include <i2c.h>
14a2d8e0a7SRajeshwari Shinde #include <i2s.h>
15a2d8e0a7SRajeshwari Shinde #include <sound.h>
166647c7acSRajeshwari Shinde #include <asm/arch/sound.h>
17a2d8e0a7SRajeshwari Shinde #include "wm8994.h"
18a2d8e0a7SRajeshwari Shinde #include "wm8994_registers.h"
19a2d8e0a7SRajeshwari Shinde 
20a2d8e0a7SRajeshwari Shinde /* defines for wm8994 system clock selection */
21a2d8e0a7SRajeshwari Shinde #define SEL_MCLK1	0x00
22a2d8e0a7SRajeshwari Shinde #define SEL_MCLK2	0x08
23a2d8e0a7SRajeshwari Shinde #define SEL_FLL1	0x10
24a2d8e0a7SRajeshwari Shinde #define SEL_FLL2	0x18
25a2d8e0a7SRajeshwari Shinde 
26a2d8e0a7SRajeshwari Shinde /* fll config to configure fll */
27a2d8e0a7SRajeshwari Shinde struct wm8994_fll_config {
28a2d8e0a7SRajeshwari Shinde 	int src;	/* Source */
29a2d8e0a7SRajeshwari Shinde 	int in;		/* Input frequency in Hz */
30a2d8e0a7SRajeshwari Shinde 	int out;	/* output frequency in Hz */
31a2d8e0a7SRajeshwari Shinde };
32a2d8e0a7SRajeshwari Shinde 
33a2d8e0a7SRajeshwari Shinde /* codec private data */
34a2d8e0a7SRajeshwari Shinde struct wm8994_priv {
35a2d8e0a7SRajeshwari Shinde 	enum wm8994_type type;		/* codec type of wolfson */
36a2d8e0a7SRajeshwari Shinde 	int revision;			/* Revision */
37a2d8e0a7SRajeshwari Shinde 	int sysclk[WM8994_MAX_AIF];	/* System clock frequency in Hz  */
38a2d8e0a7SRajeshwari Shinde 	int mclk[WM8994_MAX_AIF];	/* master clock frequency in Hz */
39a2d8e0a7SRajeshwari Shinde 	int aifclk[WM8994_MAX_AIF];	/* audio interface clock in Hz   */
40a2d8e0a7SRajeshwari Shinde 	struct wm8994_fll_config fll[2]; /* fll config to configure fll */
41a2d8e0a7SRajeshwari Shinde };
42a2d8e0a7SRajeshwari Shinde 
43a2d8e0a7SRajeshwari Shinde /* wm 8994 supported sampling rate values */
44a2d8e0a7SRajeshwari Shinde static unsigned int src_rate[] = {
45a2d8e0a7SRajeshwari Shinde 			 8000, 11025, 12000, 16000, 22050, 24000,
46a2d8e0a7SRajeshwari Shinde 			 32000, 44100, 48000, 88200, 96000
47a2d8e0a7SRajeshwari Shinde };
48a2d8e0a7SRajeshwari Shinde 
49a2d8e0a7SRajeshwari Shinde /* op clock divisions */
50a2d8e0a7SRajeshwari Shinde static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 };
51a2d8e0a7SRajeshwari Shinde 
52a2d8e0a7SRajeshwari Shinde /* lr clock frame size ratio */
53a2d8e0a7SRajeshwari Shinde static int fs_ratios[] = {
54a2d8e0a7SRajeshwari Shinde 	64, 128, 192, 256, 348, 512, 768, 1024, 1408, 1536
55a2d8e0a7SRajeshwari Shinde };
56a2d8e0a7SRajeshwari Shinde 
57a2d8e0a7SRajeshwari Shinde /* bit clock divisors */
58a2d8e0a7SRajeshwari Shinde static int bclk_divs[] = {
59a2d8e0a7SRajeshwari Shinde 	10, 15, 20, 30, 40, 50, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480,
60a2d8e0a7SRajeshwari Shinde 	640, 880, 960, 1280, 1760, 1920
61a2d8e0a7SRajeshwari Shinde };
62a2d8e0a7SRajeshwari Shinde 
63a2d8e0a7SRajeshwari Shinde static struct wm8994_priv g_wm8994_info;
64a2d8e0a7SRajeshwari Shinde static unsigned char g_wm8994_i2c_dev_addr;
656647c7acSRajeshwari Shinde static struct sound_codec_info g_codec_info;
66a2d8e0a7SRajeshwari Shinde 
67a2d8e0a7SRajeshwari Shinde /*
68a2d8e0a7SRajeshwari Shinde  * Initialise I2C for wm 8994
69a2d8e0a7SRajeshwari Shinde  *
70a2d8e0a7SRajeshwari Shinde  * @param bus no	i2c bus number in which wm8994 is connected
71a2d8e0a7SRajeshwari Shinde  */
72a2d8e0a7SRajeshwari Shinde static void wm8994_i2c_init(int bus_no)
73a2d8e0a7SRajeshwari Shinde {
74a2d8e0a7SRajeshwari Shinde 	i2c_set_bus_num(bus_no);
75a2d8e0a7SRajeshwari Shinde }
76a2d8e0a7SRajeshwari Shinde 
77a2d8e0a7SRajeshwari Shinde /*
78a2d8e0a7SRajeshwari Shinde  * Writes value to a device register through i2c
79a2d8e0a7SRajeshwari Shinde  *
80*107ab83eSSimon Glass  * @param priv	Private data for driver
81a2d8e0a7SRajeshwari Shinde  * @param reg	reg number to be write
82a2d8e0a7SRajeshwari Shinde  * @param data	data to be writen to the above registor
83a2d8e0a7SRajeshwari Shinde  *
84a2d8e0a7SRajeshwari Shinde  * @return	int value 1 for change, 0 for no change or negative error code.
85a2d8e0a7SRajeshwari Shinde  */
86*107ab83eSSimon Glass static int wm8994_i2c_write(struct wm8994_priv *priv, unsigned int reg,
87*107ab83eSSimon Glass 			    unsigned short data)
88a2d8e0a7SRajeshwari Shinde {
89a2d8e0a7SRajeshwari Shinde 	unsigned char val[2];
90a2d8e0a7SRajeshwari Shinde 
91a2d8e0a7SRajeshwari Shinde 	val[0] = (unsigned char)((data >> 8) & 0xff);
92a2d8e0a7SRajeshwari Shinde 	val[1] = (unsigned char)(data & 0xff);
93a2d8e0a7SRajeshwari Shinde 	debug("Write Addr : 0x%04X, Data :  0x%04X\n", reg, data);
94a2d8e0a7SRajeshwari Shinde 
95a2d8e0a7SRajeshwari Shinde 	return i2c_write(g_wm8994_i2c_dev_addr, reg, 2, val, 2);
96a2d8e0a7SRajeshwari Shinde }
97a2d8e0a7SRajeshwari Shinde 
98a2d8e0a7SRajeshwari Shinde /*
99a2d8e0a7SRajeshwari Shinde  * Read a value from a device register through i2c
100a2d8e0a7SRajeshwari Shinde  *
101*107ab83eSSimon Glass  * @param priv	Private data for driver
102a2d8e0a7SRajeshwari Shinde  * @param reg	reg number to be read
103a2d8e0a7SRajeshwari Shinde  * @param data	address of read data to be stored
104a2d8e0a7SRajeshwari Shinde  *
105a2d8e0a7SRajeshwari Shinde  * @return	int value 0 for success, -1 in case of error.
106a2d8e0a7SRajeshwari Shinde  */
107*107ab83eSSimon Glass static unsigned int wm8994_i2c_read(struct wm8994_priv *priv, unsigned int reg,
108*107ab83eSSimon Glass 				    unsigned short *data)
109a2d8e0a7SRajeshwari Shinde {
110a2d8e0a7SRajeshwari Shinde 	unsigned char val[2];
111a2d8e0a7SRajeshwari Shinde 	int ret;
112a2d8e0a7SRajeshwari Shinde 
113a2d8e0a7SRajeshwari Shinde 	ret = i2c_read(g_wm8994_i2c_dev_addr, reg, 2, val, 2);
114a2d8e0a7SRajeshwari Shinde 	if (ret != 0) {
115a2d8e0a7SRajeshwari Shinde 		debug("%s: Error while reading register %#04x\n",
116a2d8e0a7SRajeshwari Shinde 		      __func__, reg);
117a2d8e0a7SRajeshwari Shinde 		return -1;
118a2d8e0a7SRajeshwari Shinde 	}
119a2d8e0a7SRajeshwari Shinde 
120a2d8e0a7SRajeshwari Shinde 	*data = val[0];
121a2d8e0a7SRajeshwari Shinde 	*data <<= 8;
122a2d8e0a7SRajeshwari Shinde 	*data |= val[1];
123a2d8e0a7SRajeshwari Shinde 
124a2d8e0a7SRajeshwari Shinde 	return 0;
125a2d8e0a7SRajeshwari Shinde }
126a2d8e0a7SRajeshwari Shinde 
127a2d8e0a7SRajeshwari Shinde /*
128a2d8e0a7SRajeshwari Shinde  * update device register bits through i2c
129a2d8e0a7SRajeshwari Shinde  *
130*107ab83eSSimon Glass  * @param priv	Private data for driver
131a2d8e0a7SRajeshwari Shinde  * @param reg	codec register
132a2d8e0a7SRajeshwari Shinde  * @param mask	register mask
133a2d8e0a7SRajeshwari Shinde  * @param value	new value
134a2d8e0a7SRajeshwari Shinde  *
135a2d8e0a7SRajeshwari Shinde  * @return int value 1 if change in the register value,
136a2d8e0a7SRajeshwari Shinde  * 0 for no change or negative error code.
137a2d8e0a7SRajeshwari Shinde  */
138*107ab83eSSimon Glass static int wm8994_bic_or(struct wm8994_priv *priv, unsigned int reg,
139*107ab83eSSimon Glass 			 unsigned short mask, unsigned short value)
140a2d8e0a7SRajeshwari Shinde {
141a2d8e0a7SRajeshwari Shinde 	int change , ret = 0;
142a2d8e0a7SRajeshwari Shinde 	unsigned short old, new;
143a2d8e0a7SRajeshwari Shinde 
144*107ab83eSSimon Glass 	if (wm8994_i2c_read(priv, reg, &old) != 0)
145a2d8e0a7SRajeshwari Shinde 		return -1;
146a2d8e0a7SRajeshwari Shinde 	new = (old & ~mask) | (value & mask);
147a2d8e0a7SRajeshwari Shinde 	change  = (old != new) ? 1 : 0;
148a2d8e0a7SRajeshwari Shinde 	if (change)
149*107ab83eSSimon Glass 		ret = wm8994_i2c_write(priv, reg, new);
150a2d8e0a7SRajeshwari Shinde 	if (ret < 0)
151a2d8e0a7SRajeshwari Shinde 		return ret;
152a2d8e0a7SRajeshwari Shinde 
153a2d8e0a7SRajeshwari Shinde 	return change;
154a2d8e0a7SRajeshwari Shinde }
155a2d8e0a7SRajeshwari Shinde 
156a2d8e0a7SRajeshwari Shinde /*
157a2d8e0a7SRajeshwari Shinde  * Sets i2s set format
158a2d8e0a7SRajeshwari Shinde  *
159*107ab83eSSimon Glass  * @param priv		wm8994 information
160a2d8e0a7SRajeshwari Shinde  * @param aif_id	Interface ID
161a2d8e0a7SRajeshwari Shinde  * @param fmt		i2S format
162a2d8e0a7SRajeshwari Shinde  *
163a2d8e0a7SRajeshwari Shinde  * @return -1 for error and 0  Success.
164a2d8e0a7SRajeshwari Shinde  */
165*107ab83eSSimon Glass static int wm8994_set_fmt(struct wm8994_priv *priv, int aif_id, uint fmt)
166a2d8e0a7SRajeshwari Shinde {
167a2d8e0a7SRajeshwari Shinde 	int ms_reg;
168a2d8e0a7SRajeshwari Shinde 	int aif_reg;
169a2d8e0a7SRajeshwari Shinde 	int ms = 0;
170a2d8e0a7SRajeshwari Shinde 	int aif = 0;
171a2d8e0a7SRajeshwari Shinde 	int aif_clk = 0;
172a2d8e0a7SRajeshwari Shinde 	int error = 0;
173a2d8e0a7SRajeshwari Shinde 
174a2d8e0a7SRajeshwari Shinde 	switch (aif_id) {
175a2d8e0a7SRajeshwari Shinde 	case 1:
176a2d8e0a7SRajeshwari Shinde 		ms_reg = WM8994_AIF1_MASTER_SLAVE;
177a2d8e0a7SRajeshwari Shinde 		aif_reg = WM8994_AIF1_CONTROL_1;
178a2d8e0a7SRajeshwari Shinde 		aif_clk = WM8994_AIF1_CLOCKING_1;
179a2d8e0a7SRajeshwari Shinde 		break;
180a2d8e0a7SRajeshwari Shinde 	case 2:
181a2d8e0a7SRajeshwari Shinde 		ms_reg = WM8994_AIF2_MASTER_SLAVE;
182a2d8e0a7SRajeshwari Shinde 		aif_reg = WM8994_AIF2_CONTROL_1;
183a2d8e0a7SRajeshwari Shinde 		aif_clk = WM8994_AIF2_CLOCKING_1;
184a2d8e0a7SRajeshwari Shinde 		break;
185a2d8e0a7SRajeshwari Shinde 	default:
186a2d8e0a7SRajeshwari Shinde 		debug("%s: Invalid audio interface selection\n", __func__);
187a2d8e0a7SRajeshwari Shinde 		return -1;
188a2d8e0a7SRajeshwari Shinde 	}
189a2d8e0a7SRajeshwari Shinde 
190a2d8e0a7SRajeshwari Shinde 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
191a2d8e0a7SRajeshwari Shinde 	case SND_SOC_DAIFMT_CBS_CFS:
192a2d8e0a7SRajeshwari Shinde 		break;
193a2d8e0a7SRajeshwari Shinde 	case SND_SOC_DAIFMT_CBM_CFM:
194a2d8e0a7SRajeshwari Shinde 		ms = WM8994_AIF1_MSTR;
195a2d8e0a7SRajeshwari Shinde 		break;
196a2d8e0a7SRajeshwari Shinde 	default:
197a2d8e0a7SRajeshwari Shinde 		debug("%s: Invalid i2s master selection\n", __func__);
198a2d8e0a7SRajeshwari Shinde 		return -1;
199a2d8e0a7SRajeshwari Shinde 	}
200a2d8e0a7SRajeshwari Shinde 
201a2d8e0a7SRajeshwari Shinde 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
202a2d8e0a7SRajeshwari Shinde 	case SND_SOC_DAIFMT_DSP_B:
203a2d8e0a7SRajeshwari Shinde 		aif |= WM8994_AIF1_LRCLK_INV;
204a2d8e0a7SRajeshwari Shinde 	case SND_SOC_DAIFMT_DSP_A:
205a2d8e0a7SRajeshwari Shinde 		aif |= 0x18;
206a2d8e0a7SRajeshwari Shinde 		break;
207a2d8e0a7SRajeshwari Shinde 	case SND_SOC_DAIFMT_I2S:
208a2d8e0a7SRajeshwari Shinde 		aif |= 0x10;
209a2d8e0a7SRajeshwari Shinde 		break;
210a2d8e0a7SRajeshwari Shinde 	case SND_SOC_DAIFMT_RIGHT_J:
211a2d8e0a7SRajeshwari Shinde 		break;
212a2d8e0a7SRajeshwari Shinde 	case SND_SOC_DAIFMT_LEFT_J:
213a2d8e0a7SRajeshwari Shinde 		aif |= 0x8;
214a2d8e0a7SRajeshwari Shinde 		break;
215a2d8e0a7SRajeshwari Shinde 	default:
216a2d8e0a7SRajeshwari Shinde 		debug("%s: Invalid i2s format selection\n", __func__);
217a2d8e0a7SRajeshwari Shinde 		return -1;
218a2d8e0a7SRajeshwari Shinde 	}
219a2d8e0a7SRajeshwari Shinde 
220a2d8e0a7SRajeshwari Shinde 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
221a2d8e0a7SRajeshwari Shinde 	case SND_SOC_DAIFMT_DSP_A:
222a2d8e0a7SRajeshwari Shinde 	case SND_SOC_DAIFMT_DSP_B:
223a2d8e0a7SRajeshwari Shinde 		/* frame inversion not valid for DSP modes */
224a2d8e0a7SRajeshwari Shinde 		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
225a2d8e0a7SRajeshwari Shinde 		case SND_SOC_DAIFMT_NB_NF:
226a2d8e0a7SRajeshwari Shinde 			break;
227a2d8e0a7SRajeshwari Shinde 		case SND_SOC_DAIFMT_IB_NF:
228a2d8e0a7SRajeshwari Shinde 			aif |= WM8994_AIF1_BCLK_INV;
229a2d8e0a7SRajeshwari Shinde 			break;
230a2d8e0a7SRajeshwari Shinde 		default:
231a2d8e0a7SRajeshwari Shinde 			debug("%s: Invalid i2s frame inverse selection\n",
232a2d8e0a7SRajeshwari Shinde 			      __func__);
233a2d8e0a7SRajeshwari Shinde 			return -1;
234a2d8e0a7SRajeshwari Shinde 		}
235a2d8e0a7SRajeshwari Shinde 		break;
236a2d8e0a7SRajeshwari Shinde 
237a2d8e0a7SRajeshwari Shinde 	case SND_SOC_DAIFMT_I2S:
238a2d8e0a7SRajeshwari Shinde 	case SND_SOC_DAIFMT_RIGHT_J:
239a2d8e0a7SRajeshwari Shinde 	case SND_SOC_DAIFMT_LEFT_J:
240a2d8e0a7SRajeshwari Shinde 		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
241a2d8e0a7SRajeshwari Shinde 		case SND_SOC_DAIFMT_NB_NF:
242a2d8e0a7SRajeshwari Shinde 			break;
243a2d8e0a7SRajeshwari Shinde 		case SND_SOC_DAIFMT_IB_IF:
244a2d8e0a7SRajeshwari Shinde 			aif |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV;
245a2d8e0a7SRajeshwari Shinde 			break;
246a2d8e0a7SRajeshwari Shinde 		case SND_SOC_DAIFMT_IB_NF:
247a2d8e0a7SRajeshwari Shinde 			aif |= WM8994_AIF1_BCLK_INV;
248a2d8e0a7SRajeshwari Shinde 			break;
249a2d8e0a7SRajeshwari Shinde 		case SND_SOC_DAIFMT_NB_IF:
250a2d8e0a7SRajeshwari Shinde 			aif |= WM8994_AIF1_LRCLK_INV;
251a2d8e0a7SRajeshwari Shinde 			break;
252a2d8e0a7SRajeshwari Shinde 		default:
253a2d8e0a7SRajeshwari Shinde 			debug("%s: Invalid i2s clock polarity selection\n",
254a2d8e0a7SRajeshwari Shinde 			      __func__);
255a2d8e0a7SRajeshwari Shinde 			return -1;
256a2d8e0a7SRajeshwari Shinde 		}
257a2d8e0a7SRajeshwari Shinde 		break;
258a2d8e0a7SRajeshwari Shinde 	default:
259a2d8e0a7SRajeshwari Shinde 		debug("%s: Invalid i2s format selection\n", __func__);
260a2d8e0a7SRajeshwari Shinde 		return -1;
261a2d8e0a7SRajeshwari Shinde 	}
262a2d8e0a7SRajeshwari Shinde 
263*107ab83eSSimon Glass 	error = wm8994_bic_or(priv, aif_reg, WM8994_AIF1_BCLK_INV |
264*107ab83eSSimon Glass 			      WM8994_AIF1_LRCLK_INV_MASK |
265*107ab83eSSimon Glass 			       WM8994_AIF1_FMT_MASK, aif);
266a2d8e0a7SRajeshwari Shinde 
267*107ab83eSSimon Glass 	error |= wm8994_bic_or(priv, ms_reg, WM8994_AIF1_MSTR_MASK, ms);
268*107ab83eSSimon Glass 	error |= wm8994_bic_or(priv, aif_clk, WM8994_AIF1CLK_ENA_MASK,
269a2d8e0a7SRajeshwari Shinde 			       WM8994_AIF1CLK_ENA);
270a2d8e0a7SRajeshwari Shinde 	if (error < 0) {
271a2d8e0a7SRajeshwari Shinde 		debug("%s: codec register access error\n", __func__);
272a2d8e0a7SRajeshwari Shinde 		return -1;
273a2d8e0a7SRajeshwari Shinde 	}
274a2d8e0a7SRajeshwari Shinde 
275a2d8e0a7SRajeshwari Shinde 	return 0;
276a2d8e0a7SRajeshwari Shinde }
277a2d8e0a7SRajeshwari Shinde 
278a2d8e0a7SRajeshwari Shinde /*
279a2d8e0a7SRajeshwari Shinde  * Sets hw params FOR WM8994
280a2d8e0a7SRajeshwari Shinde  *
281*107ab83eSSimon Glass  * @param priv			wm8994 information pointer
282a2d8e0a7SRajeshwari Shinde  * @param aif_id		Audio interface ID
283a2d8e0a7SRajeshwari Shinde  * @param sampling_rate		Sampling rate
284a2d8e0a7SRajeshwari Shinde  * @param bits_per_sample	Bits per sample
285a2d8e0a7SRajeshwari Shinde  * @param Channels		Channels in the given audio input
286a2d8e0a7SRajeshwari Shinde  *
287a2d8e0a7SRajeshwari Shinde  * @return -1 for error  and 0  Success.
288a2d8e0a7SRajeshwari Shinde  */
289*107ab83eSSimon Glass static int wm8994_hw_params(struct wm8994_priv *priv, int aif_id,
290*107ab83eSSimon Glass 			    uint sampling_rate, uint bits_per_sample,
291*107ab83eSSimon Glass 			    uint channels)
292a2d8e0a7SRajeshwari Shinde {
293a2d8e0a7SRajeshwari Shinde 	int aif1_reg;
294a2d8e0a7SRajeshwari Shinde 	int aif2_reg;
295a2d8e0a7SRajeshwari Shinde 	int bclk_reg;
296a2d8e0a7SRajeshwari Shinde 	int bclk = 0;
297a2d8e0a7SRajeshwari Shinde 	int rate_reg;
298a2d8e0a7SRajeshwari Shinde 	int aif1 = 0;
299a2d8e0a7SRajeshwari Shinde 	int aif2 = 0;
300a2d8e0a7SRajeshwari Shinde 	int rate_val = 0;
301a2d8e0a7SRajeshwari Shinde 	int id = aif_id - 1;
302a2d8e0a7SRajeshwari Shinde 	int i, cur_val, best_val, bclk_rate, best;
303a2d8e0a7SRajeshwari Shinde 	unsigned short reg_data;
304a2d8e0a7SRajeshwari Shinde 	int ret = 0;
305a2d8e0a7SRajeshwari Shinde 
306a2d8e0a7SRajeshwari Shinde 	switch (aif_id) {
307a2d8e0a7SRajeshwari Shinde 	case 1:
308a2d8e0a7SRajeshwari Shinde 		aif1_reg = WM8994_AIF1_CONTROL_1;
309a2d8e0a7SRajeshwari Shinde 		aif2_reg = WM8994_AIF1_CONTROL_2;
310a2d8e0a7SRajeshwari Shinde 		bclk_reg = WM8994_AIF1_BCLK;
311a2d8e0a7SRajeshwari Shinde 		rate_reg = WM8994_AIF1_RATE;
312a2d8e0a7SRajeshwari Shinde 		break;
313a2d8e0a7SRajeshwari Shinde 	case 2:
314a2d8e0a7SRajeshwari Shinde 		aif1_reg = WM8994_AIF2_CONTROL_1;
315a2d8e0a7SRajeshwari Shinde 		aif2_reg = WM8994_AIF2_CONTROL_2;
316a2d8e0a7SRajeshwari Shinde 		bclk_reg = WM8994_AIF2_BCLK;
317a2d8e0a7SRajeshwari Shinde 		rate_reg = WM8994_AIF2_RATE;
318a2d8e0a7SRajeshwari Shinde 		break;
319a2d8e0a7SRajeshwari Shinde 	default:
320a2d8e0a7SRajeshwari Shinde 		return -1;
321a2d8e0a7SRajeshwari Shinde 	}
322a2d8e0a7SRajeshwari Shinde 
323a2d8e0a7SRajeshwari Shinde 	bclk_rate = sampling_rate * 32;
324a2d8e0a7SRajeshwari Shinde 	switch (bits_per_sample) {
325a2d8e0a7SRajeshwari Shinde 	case 16:
326a2d8e0a7SRajeshwari Shinde 		bclk_rate *= 16;
327a2d8e0a7SRajeshwari Shinde 		break;
328a2d8e0a7SRajeshwari Shinde 	case 20:
329a2d8e0a7SRajeshwari Shinde 		bclk_rate *= 20;
330a2d8e0a7SRajeshwari Shinde 		aif1 |= 0x20;
331a2d8e0a7SRajeshwari Shinde 		break;
332a2d8e0a7SRajeshwari Shinde 	case 24:
333a2d8e0a7SRajeshwari Shinde 		bclk_rate *= 24;
334a2d8e0a7SRajeshwari Shinde 		aif1 |= 0x40;
335a2d8e0a7SRajeshwari Shinde 		break;
336a2d8e0a7SRajeshwari Shinde 	case 32:
337a2d8e0a7SRajeshwari Shinde 		bclk_rate *= 32;
338a2d8e0a7SRajeshwari Shinde 		aif1 |= 0x60;
339a2d8e0a7SRajeshwari Shinde 		break;
340a2d8e0a7SRajeshwari Shinde 	default:
341a2d8e0a7SRajeshwari Shinde 		return -1;
342a2d8e0a7SRajeshwari Shinde 	}
343a2d8e0a7SRajeshwari Shinde 
344a2d8e0a7SRajeshwari Shinde 	/* Try to find an appropriate sample rate; look for an exact match. */
345a2d8e0a7SRajeshwari Shinde 	for (i = 0; i < ARRAY_SIZE(src_rate); i++)
346a2d8e0a7SRajeshwari Shinde 		if (src_rate[i] == sampling_rate)
347a2d8e0a7SRajeshwari Shinde 			break;
348a2d8e0a7SRajeshwari Shinde 
349a2d8e0a7SRajeshwari Shinde 	if (i == ARRAY_SIZE(src_rate)) {
350a2d8e0a7SRajeshwari Shinde 		debug("%s: Could not get the best matching samplingrate\n",
351a2d8e0a7SRajeshwari Shinde 		      __func__);
352a2d8e0a7SRajeshwari Shinde 		return -1;
353a2d8e0a7SRajeshwari Shinde 	}
354a2d8e0a7SRajeshwari Shinde 
355a2d8e0a7SRajeshwari Shinde 	rate_val |= i << WM8994_AIF1_SR_SHIFT;
356a2d8e0a7SRajeshwari Shinde 
357a2d8e0a7SRajeshwari Shinde 	/* AIFCLK/fs ratio; look for a close match in either direction */
358a2d8e0a7SRajeshwari Shinde 	best = 0;
359*107ab83eSSimon Glass 	best_val = abs((fs_ratios[0] * sampling_rate) - priv->aifclk[id]);
360a2d8e0a7SRajeshwari Shinde 
361a2d8e0a7SRajeshwari Shinde 	for (i = 1; i < ARRAY_SIZE(fs_ratios); i++) {
362*107ab83eSSimon Glass 		cur_val = abs(fs_ratios[i] * sampling_rate - priv->aifclk[id]);
363a2d8e0a7SRajeshwari Shinde 		if (cur_val >= best_val)
364a2d8e0a7SRajeshwari Shinde 			continue;
365a2d8e0a7SRajeshwari Shinde 		best = i;
366a2d8e0a7SRajeshwari Shinde 		best_val = cur_val;
367a2d8e0a7SRajeshwari Shinde 	}
368a2d8e0a7SRajeshwari Shinde 
369a2d8e0a7SRajeshwari Shinde 	rate_val |= best;
370a2d8e0a7SRajeshwari Shinde 
371a2d8e0a7SRajeshwari Shinde 	/*
372a2d8e0a7SRajeshwari Shinde 	 * We may not get quite the right frequency if using
373a2d8e0a7SRajeshwari Shinde 	 * approximate clocks so look for the closest match that is
374a2d8e0a7SRajeshwari Shinde 	 * higher than the target (we need to ensure that there enough
375a2d8e0a7SRajeshwari Shinde 	 * BCLKs to clock out the samples).
376a2d8e0a7SRajeshwari Shinde 	 */
377a2d8e0a7SRajeshwari Shinde 	best = 0;
378a2d8e0a7SRajeshwari Shinde 	for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
379*107ab83eSSimon Glass 		cur_val = (priv->aifclk[id] * 10 / bclk_divs[i]) - bclk_rate;
380a2d8e0a7SRajeshwari Shinde 		if (cur_val < 0) /* BCLK table is sorted */
381a2d8e0a7SRajeshwari Shinde 			break;
382a2d8e0a7SRajeshwari Shinde 		best = i;
383a2d8e0a7SRajeshwari Shinde 	}
384a2d8e0a7SRajeshwari Shinde 
385a2d8e0a7SRajeshwari Shinde 	if (i ==  ARRAY_SIZE(bclk_divs)) {
386a2d8e0a7SRajeshwari Shinde 		debug("%s: Could not get the best matching bclk division\n",
387a2d8e0a7SRajeshwari Shinde 		      __func__);
388a2d8e0a7SRajeshwari Shinde 		return -1;
389a2d8e0a7SRajeshwari Shinde 	}
390a2d8e0a7SRajeshwari Shinde 
391*107ab83eSSimon Glass 	bclk_rate = priv->aifclk[id] * 10 / bclk_divs[best];
392a2d8e0a7SRajeshwari Shinde 	bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT;
393a2d8e0a7SRajeshwari Shinde 
394*107ab83eSSimon Glass 	if (wm8994_i2c_read(priv, aif1_reg, &reg_data) != 0) {
395a2d8e0a7SRajeshwari Shinde 		debug("%s: AIF1 register read Failed\n", __func__);
396a2d8e0a7SRajeshwari Shinde 		return -1;
397a2d8e0a7SRajeshwari Shinde 	}
398a2d8e0a7SRajeshwari Shinde 
399a2d8e0a7SRajeshwari Shinde 	if ((channels == 1) && ((reg_data & 0x18) == 0x18))
400a2d8e0a7SRajeshwari Shinde 		aif2 |= WM8994_AIF1_MONO;
401a2d8e0a7SRajeshwari Shinde 
402*107ab83eSSimon Glass 	if (priv->aifclk[id] == 0) {
403a2d8e0a7SRajeshwari Shinde 		debug("%s:Audio interface clock not set\n", __func__);
404a2d8e0a7SRajeshwari Shinde 		return -1;
405a2d8e0a7SRajeshwari Shinde 	}
406a2d8e0a7SRajeshwari Shinde 
407*107ab83eSSimon Glass 	ret = wm8994_bic_or(priv, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
408*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, aif2_reg, WM8994_AIF1_MONO, aif2);
409*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK,
410*107ab83eSSimon Glass 				  bclk);
411*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, rate_reg, WM8994_AIF1_SR_MASK |
412a2d8e0a7SRajeshwari Shinde 				  WM8994_AIF1CLK_RATE_MASK, rate_val);
413a2d8e0a7SRajeshwari Shinde 
414a2d8e0a7SRajeshwari Shinde 	debug("rate vale = %x , bclk val= %x\n", rate_val, bclk);
415a2d8e0a7SRajeshwari Shinde 
416a2d8e0a7SRajeshwari Shinde 	if (ret < 0) {
417a2d8e0a7SRajeshwari Shinde 		debug("%s: codec register access error\n", __func__);
418a2d8e0a7SRajeshwari Shinde 		return -1;
419a2d8e0a7SRajeshwari Shinde 	}
420a2d8e0a7SRajeshwari Shinde 
421a2d8e0a7SRajeshwari Shinde 	return 0;
422a2d8e0a7SRajeshwari Shinde }
423a2d8e0a7SRajeshwari Shinde 
424a2d8e0a7SRajeshwari Shinde /*
425a2d8e0a7SRajeshwari Shinde  * Configures Audio interface Clock
426a2d8e0a7SRajeshwari Shinde  *
427*107ab83eSSimon Glass  * @param priv		wm8994 information pointer
428a2d8e0a7SRajeshwari Shinde  * @param aif		Audio Interface ID
429a2d8e0a7SRajeshwari Shinde  *
430a2d8e0a7SRajeshwari Shinde  * @return -1 for error  and 0  Success.
431a2d8e0a7SRajeshwari Shinde  */
432*107ab83eSSimon Glass static int configure_aif_clock(struct wm8994_priv *priv, int aif)
433a2d8e0a7SRajeshwari Shinde {
434a2d8e0a7SRajeshwari Shinde 	int rate;
435a2d8e0a7SRajeshwari Shinde 	int reg1 = 0;
436a2d8e0a7SRajeshwari Shinde 	int offset;
437a2d8e0a7SRajeshwari Shinde 	int ret;
438a2d8e0a7SRajeshwari Shinde 
439a2d8e0a7SRajeshwari Shinde 	/* AIF(1/0) register adress offset calculated */
440d981d80dSDani Krishna Mohan 	if (aif-1)
441a2d8e0a7SRajeshwari Shinde 		offset = 4;
442a2d8e0a7SRajeshwari Shinde 	else
443a2d8e0a7SRajeshwari Shinde 		offset = 0;
444a2d8e0a7SRajeshwari Shinde 
445*107ab83eSSimon Glass 	switch (priv->sysclk[aif - 1]) {
446a2d8e0a7SRajeshwari Shinde 	case WM8994_SYSCLK_MCLK1:
447a2d8e0a7SRajeshwari Shinde 		reg1 |= SEL_MCLK1;
448*107ab83eSSimon Glass 		rate = priv->mclk[0];
449a2d8e0a7SRajeshwari Shinde 		break;
450a2d8e0a7SRajeshwari Shinde 
451a2d8e0a7SRajeshwari Shinde 	case WM8994_SYSCLK_MCLK2:
452a2d8e0a7SRajeshwari Shinde 		reg1 |= SEL_MCLK2;
453*107ab83eSSimon Glass 		rate = priv->mclk[1];
454a2d8e0a7SRajeshwari Shinde 		break;
455a2d8e0a7SRajeshwari Shinde 
456a2d8e0a7SRajeshwari Shinde 	case WM8994_SYSCLK_FLL1:
457a2d8e0a7SRajeshwari Shinde 		reg1 |= SEL_FLL1;
458*107ab83eSSimon Glass 		rate = priv->fll[0].out;
459a2d8e0a7SRajeshwari Shinde 		break;
460a2d8e0a7SRajeshwari Shinde 
461a2d8e0a7SRajeshwari Shinde 	case WM8994_SYSCLK_FLL2:
462a2d8e0a7SRajeshwari Shinde 		reg1 |= SEL_FLL2;
463*107ab83eSSimon Glass 		rate = priv->fll[1].out;
464a2d8e0a7SRajeshwari Shinde 		break;
465a2d8e0a7SRajeshwari Shinde 
466a2d8e0a7SRajeshwari Shinde 	default:
467a2d8e0a7SRajeshwari Shinde 		debug("%s: Invalid input clock selection [%d]\n",
468*107ab83eSSimon Glass 		      __func__, priv->sysclk[aif - 1]);
469a2d8e0a7SRajeshwari Shinde 		return -1;
470a2d8e0a7SRajeshwari Shinde 	}
471a2d8e0a7SRajeshwari Shinde 
472a2d8e0a7SRajeshwari Shinde 	/* if input clock frequenct is more than 135Mhz then divide */
473a2d8e0a7SRajeshwari Shinde 	if (rate >= WM8994_MAX_INPUT_CLK_FREQ) {
474a2d8e0a7SRajeshwari Shinde 		rate /= 2;
475a2d8e0a7SRajeshwari Shinde 		reg1 |= WM8994_AIF1CLK_DIV;
476a2d8e0a7SRajeshwari Shinde 	}
477a2d8e0a7SRajeshwari Shinde 
478*107ab83eSSimon Glass 	priv->aifclk[aif - 1] = rate;
479a2d8e0a7SRajeshwari Shinde 
480*107ab83eSSimon Glass 	ret = wm8994_bic_or(priv, WM8994_AIF1_CLOCKING_1 + offset,
481a2d8e0a7SRajeshwari Shinde 			    WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV,
482a2d8e0a7SRajeshwari Shinde 			    reg1);
483a2d8e0a7SRajeshwari Shinde 
484d981d80dSDani Krishna Mohan 	if (aif == WM8994_AIF1)
485*107ab83eSSimon Glass 		ret |= wm8994_bic_or(priv, WM8994_CLOCKING_1,
486d981d80dSDani Krishna Mohan 			WM8994_AIF1DSPCLK_ENA_MASK | WM8994_SYSDSPCLK_ENA_MASK,
487d981d80dSDani Krishna Mohan 			WM8994_AIF1DSPCLK_ENA | WM8994_SYSDSPCLK_ENA);
488d981d80dSDani Krishna Mohan 	else if (aif == WM8994_AIF2)
489*107ab83eSSimon Glass 		ret |= wm8994_bic_or(priv, WM8994_CLOCKING_1,
490a2d8e0a7SRajeshwari Shinde 			WM8994_SYSCLK_SRC | WM8994_AIF2DSPCLK_ENA_MASK |
491a2d8e0a7SRajeshwari Shinde 			WM8994_SYSDSPCLK_ENA_MASK, WM8994_SYSCLK_SRC |
492a2d8e0a7SRajeshwari Shinde 			WM8994_AIF2DSPCLK_ENA | WM8994_SYSDSPCLK_ENA);
493a2d8e0a7SRajeshwari Shinde 
494a2d8e0a7SRajeshwari Shinde 	if (ret < 0) {
495a2d8e0a7SRajeshwari Shinde 		debug("%s: codec register access error\n", __func__);
496a2d8e0a7SRajeshwari Shinde 		return -1;
497a2d8e0a7SRajeshwari Shinde 	}
498a2d8e0a7SRajeshwari Shinde 
499a2d8e0a7SRajeshwari Shinde 	return 0;
500a2d8e0a7SRajeshwari Shinde }
501a2d8e0a7SRajeshwari Shinde 
502a2d8e0a7SRajeshwari Shinde /*
503a2d8e0a7SRajeshwari Shinde  * Configures Audio interface  for the given frequency
504a2d8e0a7SRajeshwari Shinde  *
505*107ab83eSSimon Glass  * @param priv		wm8994 information
506a2d8e0a7SRajeshwari Shinde  * @param aif_id	Audio Interface
507a2d8e0a7SRajeshwari Shinde  * @param clk_id	Input Clock ID
508a2d8e0a7SRajeshwari Shinde  * @param freq		Sampling frequency in Hz
509a2d8e0a7SRajeshwari Shinde  *
510a2d8e0a7SRajeshwari Shinde  * @return -1 for error and 0 success.
511a2d8e0a7SRajeshwari Shinde  */
512*107ab83eSSimon Glass static int wm8994_set_sysclk(struct wm8994_priv *priv, int aif_id, int clk_id,
513*107ab83eSSimon Glass 			     unsigned int freq)
514a2d8e0a7SRajeshwari Shinde {
515a2d8e0a7SRajeshwari Shinde 	int i;
516a2d8e0a7SRajeshwari Shinde 	int ret = 0;
517a2d8e0a7SRajeshwari Shinde 
518*107ab83eSSimon Glass 	priv->sysclk[aif_id - 1] = clk_id;
519a2d8e0a7SRajeshwari Shinde 
520a2d8e0a7SRajeshwari Shinde 	switch (clk_id) {
521a2d8e0a7SRajeshwari Shinde 	case WM8994_SYSCLK_MCLK1:
522*107ab83eSSimon Glass 		priv->mclk[0] = freq;
523a2d8e0a7SRajeshwari Shinde 		if (aif_id == 2) {
524*107ab83eSSimon Glass 			ret = wm8994_bic_or(priv, WM8994_AIF1_CLOCKING_2,
525a2d8e0a7SRajeshwari Shinde 					    WM8994_AIF2DAC_DIV_MASK, 0);
526a2d8e0a7SRajeshwari Shinde 		}
527a2d8e0a7SRajeshwari Shinde 		break;
528a2d8e0a7SRajeshwari Shinde 
529a2d8e0a7SRajeshwari Shinde 	case WM8994_SYSCLK_MCLK2:
530a2d8e0a7SRajeshwari Shinde 		/* TODO: Set GPIO AF */
531*107ab83eSSimon Glass 		priv->mclk[1] = freq;
532a2d8e0a7SRajeshwari Shinde 		break;
533a2d8e0a7SRajeshwari Shinde 
534a2d8e0a7SRajeshwari Shinde 	case WM8994_SYSCLK_FLL1:
535a2d8e0a7SRajeshwari Shinde 	case WM8994_SYSCLK_FLL2:
536a2d8e0a7SRajeshwari Shinde 		break;
537a2d8e0a7SRajeshwari Shinde 
538a2d8e0a7SRajeshwari Shinde 	case WM8994_SYSCLK_OPCLK:
539a2d8e0a7SRajeshwari Shinde 		/*
540a2d8e0a7SRajeshwari Shinde 		 * Special case - a division (times 10) is given and
541a2d8e0a7SRajeshwari Shinde 		 * no effect on main clocking.
542a2d8e0a7SRajeshwari Shinde 		 */
543a2d8e0a7SRajeshwari Shinde 		if (freq) {
544a2d8e0a7SRajeshwari Shinde 			for (i = 0; i < ARRAY_SIZE(opclk_divs); i++)
545a2d8e0a7SRajeshwari Shinde 				if (opclk_divs[i] == freq)
546a2d8e0a7SRajeshwari Shinde 					break;
547a2d8e0a7SRajeshwari Shinde 			if (i == ARRAY_SIZE(opclk_divs)) {
548a2d8e0a7SRajeshwari Shinde 				debug("%s frequency divisor not found\n",
549a2d8e0a7SRajeshwari Shinde 				      __func__);
550a2d8e0a7SRajeshwari Shinde 				return -1;
551a2d8e0a7SRajeshwari Shinde 			}
552*107ab83eSSimon Glass 			ret = wm8994_bic_or(priv, WM8994_CLOCKING_2,
553a2d8e0a7SRajeshwari Shinde 					    WM8994_OPCLK_DIV_MASK, i);
554*107ab83eSSimon Glass 			ret |= wm8994_bic_or(priv, WM8994_POWER_MANAGEMENT_2,
555*107ab83eSSimon Glass 					     WM8994_OPCLK_ENA,
556*107ab83eSSimon Glass 					     WM8994_OPCLK_ENA);
557a2d8e0a7SRajeshwari Shinde 		} else {
558*107ab83eSSimon Glass 			ret |= wm8994_bic_or(priv, WM8994_POWER_MANAGEMENT_2,
559a2d8e0a7SRajeshwari Shinde 					     WM8994_OPCLK_ENA, 0);
560a2d8e0a7SRajeshwari Shinde 		}
561a2d8e0a7SRajeshwari Shinde 
562a2d8e0a7SRajeshwari Shinde 	default:
563a2d8e0a7SRajeshwari Shinde 		debug("%s Invalid input clock selection [%d]\n",
564a2d8e0a7SRajeshwari Shinde 		      __func__, clk_id);
565a2d8e0a7SRajeshwari Shinde 		return -1;
566a2d8e0a7SRajeshwari Shinde 	}
567a2d8e0a7SRajeshwari Shinde 
568*107ab83eSSimon Glass 	ret |= configure_aif_clock(priv, aif_id);
569a2d8e0a7SRajeshwari Shinde 
570a2d8e0a7SRajeshwari Shinde 	if (ret < 0) {
571a2d8e0a7SRajeshwari Shinde 		debug("%s: codec register access error\n", __func__);
572a2d8e0a7SRajeshwari Shinde 		return -1;
573a2d8e0a7SRajeshwari Shinde 	}
574a2d8e0a7SRajeshwari Shinde 
575a2d8e0a7SRajeshwari Shinde 	return 0;
576a2d8e0a7SRajeshwari Shinde }
577a2d8e0a7SRajeshwari Shinde 
578a2d8e0a7SRajeshwari Shinde /*
579a2d8e0a7SRajeshwari Shinde  * Initializes Volume for AIF2 to HP path
580a2d8e0a7SRajeshwari Shinde  *
581*107ab83eSSimon Glass  * @param priv		wm8994 information
582a2d8e0a7SRajeshwari Shinde  * @returns -1 for error  and 0 Success.
583a2d8e0a7SRajeshwari Shinde  *
584a2d8e0a7SRajeshwari Shinde  */
585*107ab83eSSimon Glass static int wm8994_init_volume_aif2_dac1(struct wm8994_priv *priv)
586a2d8e0a7SRajeshwari Shinde {
587a2d8e0a7SRajeshwari Shinde 	int ret;
588a2d8e0a7SRajeshwari Shinde 
589a2d8e0a7SRajeshwari Shinde 	/* Unmute AIF2DAC */
590*107ab83eSSimon Glass 	ret = wm8994_bic_or(priv, WM8994_AIF2_DAC_FILTERS_1,
591a2d8e0a7SRajeshwari Shinde 			    WM8994_AIF2DAC_MUTE_MASK, 0);
592a2d8e0a7SRajeshwari Shinde 
593a2d8e0a7SRajeshwari Shinde 
594*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_AIF2_DAC_LEFT_VOLUME,
595a2d8e0a7SRajeshwari Shinde 			     WM8994_AIF2DAC_VU_MASK | WM8994_AIF2DACL_VOL_MASK,
596a2d8e0a7SRajeshwari Shinde 			     WM8994_AIF2DAC_VU | 0xff);
597a2d8e0a7SRajeshwari Shinde 
598*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_AIF2_DAC_RIGHT_VOLUME,
599a2d8e0a7SRajeshwari Shinde 			     WM8994_AIF2DAC_VU_MASK | WM8994_AIF2DACR_VOL_MASK,
600a2d8e0a7SRajeshwari Shinde 			     WM8994_AIF2DAC_VU | 0xff);
601a2d8e0a7SRajeshwari Shinde 
602a2d8e0a7SRajeshwari Shinde 
603*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_DAC1_LEFT_VOLUME,
604a2d8e0a7SRajeshwari Shinde 			     WM8994_DAC1_VU_MASK | WM8994_DAC1L_VOL_MASK |
605a2d8e0a7SRajeshwari Shinde 			     WM8994_DAC1L_MUTE_MASK, WM8994_DAC1_VU | 0xc0);
606a2d8e0a7SRajeshwari Shinde 
607*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_DAC1_RIGHT_VOLUME,
608a2d8e0a7SRajeshwari Shinde 			     WM8994_DAC1_VU_MASK | WM8994_DAC1R_VOL_MASK |
609a2d8e0a7SRajeshwari Shinde 			     WM8994_DAC1R_MUTE_MASK, WM8994_DAC1_VU | 0xc0);
610a2d8e0a7SRajeshwari Shinde 	/* Head Phone Volume */
611*107ab83eSSimon Glass 	ret |= wm8994_i2c_write(priv, WM8994_LEFT_OUTPUT_VOLUME, 0x12D);
612*107ab83eSSimon Glass 	ret |= wm8994_i2c_write(priv, WM8994_RIGHT_OUTPUT_VOLUME, 0x12D);
613a2d8e0a7SRajeshwari Shinde 
614a2d8e0a7SRajeshwari Shinde 	if (ret < 0) {
615a2d8e0a7SRajeshwari Shinde 		debug("%s: codec register access error\n", __func__);
616a2d8e0a7SRajeshwari Shinde 		return -1;
617a2d8e0a7SRajeshwari Shinde 	}
618a2d8e0a7SRajeshwari Shinde 
619a2d8e0a7SRajeshwari Shinde 	return 0;
620a2d8e0a7SRajeshwari Shinde }
621a2d8e0a7SRajeshwari Shinde 
622a2d8e0a7SRajeshwari Shinde /*
623d981d80dSDani Krishna Mohan  * Initializes Volume for AIF1 to HP path
624d981d80dSDani Krishna Mohan  *
625*107ab83eSSimon Glass  * @param priv		wm8994 information
626d981d80dSDani Krishna Mohan  * @returns -1 for error  and 0 Success.
627d981d80dSDani Krishna Mohan  *
628d981d80dSDani Krishna Mohan  */
629*107ab83eSSimon Glass static int wm8994_init_volume_aif1_dac1(struct wm8994_priv *priv)
630d981d80dSDani Krishna Mohan {
631d981d80dSDani Krishna Mohan 	int ret = 0;
632d981d80dSDani Krishna Mohan 
633d981d80dSDani Krishna Mohan 	/* Unmute AIF1DAC */
634*107ab83eSSimon Glass 	ret |= wm8994_i2c_write(priv, WM8994_AIF1_DAC_FILTERS_1, 0x0000);
635d981d80dSDani Krishna Mohan 
636*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_DAC1_LEFT_VOLUME,
637d981d80dSDani Krishna Mohan 			     WM8994_DAC1_VU_MASK | WM8994_DAC1L_VOL_MASK |
638d981d80dSDani Krishna Mohan 			     WM8994_DAC1L_MUTE_MASK, WM8994_DAC1_VU | 0xc0);
639d981d80dSDani Krishna Mohan 
640*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_DAC1_RIGHT_VOLUME,
641d981d80dSDani Krishna Mohan 			     WM8994_DAC1_VU_MASK | WM8994_DAC1R_VOL_MASK |
642d981d80dSDani Krishna Mohan 			     WM8994_DAC1R_MUTE_MASK, WM8994_DAC1_VU | 0xc0);
643d981d80dSDani Krishna Mohan 	/* Head Phone Volume */
644*107ab83eSSimon Glass 	ret |= wm8994_i2c_write(priv, WM8994_LEFT_OUTPUT_VOLUME, 0x12D);
645*107ab83eSSimon Glass 	ret |= wm8994_i2c_write(priv, WM8994_RIGHT_OUTPUT_VOLUME, 0x12D);
646d981d80dSDani Krishna Mohan 
647d981d80dSDani Krishna Mohan 	if (ret < 0) {
648d981d80dSDani Krishna Mohan 		debug("%s: codec register access error\n", __func__);
649d981d80dSDani Krishna Mohan 		return -1;
650d981d80dSDani Krishna Mohan 	}
651d981d80dSDani Krishna Mohan 
652d981d80dSDani Krishna Mohan 	return 0;
653d981d80dSDani Krishna Mohan }
654d981d80dSDani Krishna Mohan 
655d981d80dSDani Krishna Mohan /*
656a2d8e0a7SRajeshwari Shinde  * Intialise wm8994 codec device
657a2d8e0a7SRajeshwari Shinde  *
658*107ab83eSSimon Glass  * @param priv		wm8994 information
659a2d8e0a7SRajeshwari Shinde  *
660a2d8e0a7SRajeshwari Shinde  * @returns -1 for error  and 0 Success.
661a2d8e0a7SRajeshwari Shinde  */
662*107ab83eSSimon Glass static int wm8994_device_init(struct wm8994_priv *priv,
663d981d80dSDani Krishna Mohan 			      enum en_audio_interface aif_id)
664a2d8e0a7SRajeshwari Shinde {
665a2d8e0a7SRajeshwari Shinde 	const char *devname;
666a2d8e0a7SRajeshwari Shinde 	unsigned short reg_data;
667a2d8e0a7SRajeshwari Shinde 	int ret;
668a2d8e0a7SRajeshwari Shinde 
669*107ab83eSSimon Glass 	wm8994_i2c_write(priv, WM8994_SOFTWARE_RESET, WM8994_SW_RESET);
670a2d8e0a7SRajeshwari Shinde 
671*107ab83eSSimon Glass 	ret = wm8994_i2c_read(priv, WM8994_SOFTWARE_RESET, &reg_data);
672a2d8e0a7SRajeshwari Shinde 	if (ret < 0) {
673a2d8e0a7SRajeshwari Shinde 		debug("Failed to read ID register\n");
674a2d8e0a7SRajeshwari Shinde 		goto err;
675a2d8e0a7SRajeshwari Shinde 	}
676a2d8e0a7SRajeshwari Shinde 
677a2d8e0a7SRajeshwari Shinde 	if (reg_data == WM8994_ID) {
678a2d8e0a7SRajeshwari Shinde 		devname = "WM8994";
679*107ab83eSSimon Glass 		debug("Device registered as type %d\n", priv->type);
680*107ab83eSSimon Glass 		priv->type = WM8994;
681a2d8e0a7SRajeshwari Shinde 	} else {
682a2d8e0a7SRajeshwari Shinde 		debug("Device is not a WM8994, ID is %x\n", ret);
683a2d8e0a7SRajeshwari Shinde 		ret = -1;
684a2d8e0a7SRajeshwari Shinde 		goto err;
685a2d8e0a7SRajeshwari Shinde 	}
686a2d8e0a7SRajeshwari Shinde 
687*107ab83eSSimon Glass 	ret = wm8994_i2c_read(priv, WM8994_CHIP_REVISION, &reg_data);
688a2d8e0a7SRajeshwari Shinde 	if (ret < 0) {
689a2d8e0a7SRajeshwari Shinde 		debug("Failed to read revision register: %d\n", ret);
690a2d8e0a7SRajeshwari Shinde 		goto err;
691a2d8e0a7SRajeshwari Shinde 	}
692*107ab83eSSimon Glass 	priv->revision = reg_data;
693*107ab83eSSimon Glass 	debug("%s revision %c\n", devname, 'A' + priv->revision);
694a2d8e0a7SRajeshwari Shinde 
695a2d8e0a7SRajeshwari Shinde 	/* VMID Selection */
696*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_POWER_MANAGEMENT_1,
697a2d8e0a7SRajeshwari Shinde 			     WM8994_VMID_SEL_MASK | WM8994_BIAS_ENA_MASK, 0x3);
698a2d8e0a7SRajeshwari Shinde 
699a2d8e0a7SRajeshwari Shinde 	/* Charge Pump Enable */
700*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_CHARGE_PUMP_1, WM8994_CP_ENA_MASK,
701a2d8e0a7SRajeshwari Shinde 			     WM8994_CP_ENA);
702a2d8e0a7SRajeshwari Shinde 
703a2d8e0a7SRajeshwari Shinde 	/* Head Phone Power Enable */
704*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_POWER_MANAGEMENT_1,
705a2d8e0a7SRajeshwari Shinde 			     WM8994_HPOUT1L_ENA_MASK, WM8994_HPOUT1L_ENA);
706a2d8e0a7SRajeshwari Shinde 
707*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_POWER_MANAGEMENT_1,
708a2d8e0a7SRajeshwari Shinde 			     WM8994_HPOUT1R_ENA_MASK, WM8994_HPOUT1R_ENA);
709a2d8e0a7SRajeshwari Shinde 
710d981d80dSDani Krishna Mohan 	if (aif_id == WM8994_AIF1) {
711*107ab83eSSimon Glass 		ret |= wm8994_i2c_write(priv, WM8994_POWER_MANAGEMENT_2,
712d981d80dSDani Krishna Mohan 					WM8994_TSHUT_ENA | WM8994_MIXINL_ENA |
713d981d80dSDani Krishna Mohan 					WM8994_MIXINR_ENA | WM8994_IN2L_ENA |
714d981d80dSDani Krishna Mohan 					WM8994_IN2R_ENA);
715d981d80dSDani Krishna Mohan 
716*107ab83eSSimon Glass 		ret |= wm8994_i2c_write(priv, WM8994_POWER_MANAGEMENT_4,
717d981d80dSDani Krishna Mohan 					WM8994_ADCL_ENA | WM8994_ADCR_ENA |
718d981d80dSDani Krishna Mohan 					WM8994_AIF1ADC1R_ENA |
719d981d80dSDani Krishna Mohan 					WM8994_AIF1ADC1L_ENA);
720d981d80dSDani Krishna Mohan 
721d981d80dSDani Krishna Mohan 		/* Power enable for AIF1 and DAC1 */
722*107ab83eSSimon Glass 		ret |= wm8994_i2c_write(priv, WM8994_POWER_MANAGEMENT_5,
723d981d80dSDani Krishna Mohan 					WM8994_AIF1DACL_ENA |
724d981d80dSDani Krishna Mohan 					WM8994_AIF1DACR_ENA |
725d981d80dSDani Krishna Mohan 					WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
726d981d80dSDani Krishna Mohan 	} else if (aif_id == WM8994_AIF2) {
727a2d8e0a7SRajeshwari Shinde 		/* Power enable for AIF2 and DAC1 */
728*107ab83eSSimon Glass 		ret |= wm8994_bic_or(priv, WM8994_POWER_MANAGEMENT_5,
729a2d8e0a7SRajeshwari Shinde 			WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK |
730a2d8e0a7SRajeshwari Shinde 			WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK,
731d981d80dSDani Krishna Mohan 			WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
732d981d80dSDani Krishna Mohan 			WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
733d981d80dSDani Krishna Mohan 	}
734a2d8e0a7SRajeshwari Shinde 	/* Head Phone Initialisation */
735*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_ANALOGUE_HP_1,
736a2d8e0a7SRajeshwari Shinde 		WM8994_HPOUT1L_DLY_MASK | WM8994_HPOUT1R_DLY_MASK,
737a2d8e0a7SRajeshwari Shinde 		WM8994_HPOUT1L_DLY | WM8994_HPOUT1R_DLY);
738a2d8e0a7SRajeshwari Shinde 
739*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_DC_SERVO_1,
740a2d8e0a7SRajeshwari Shinde 			WM8994_DCS_ENA_CHAN_0_MASK |
741a2d8e0a7SRajeshwari Shinde 			WM8994_DCS_ENA_CHAN_1_MASK , WM8994_DCS_ENA_CHAN_0 |
742a2d8e0a7SRajeshwari Shinde 			WM8994_DCS_ENA_CHAN_1);
743a2d8e0a7SRajeshwari Shinde 
744*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_ANALOGUE_HP_1,
745a2d8e0a7SRajeshwari Shinde 			WM8994_HPOUT1L_DLY_MASK |
746a2d8e0a7SRajeshwari Shinde 			WM8994_HPOUT1R_DLY_MASK | WM8994_HPOUT1L_OUTP_MASK |
747a2d8e0a7SRajeshwari Shinde 			WM8994_HPOUT1R_OUTP_MASK |
748a2d8e0a7SRajeshwari Shinde 			WM8994_HPOUT1L_RMV_SHORT_MASK |
749a2d8e0a7SRajeshwari Shinde 			WM8994_HPOUT1R_RMV_SHORT_MASK, WM8994_HPOUT1L_DLY |
750a2d8e0a7SRajeshwari Shinde 			WM8994_HPOUT1R_DLY | WM8994_HPOUT1L_OUTP |
751a2d8e0a7SRajeshwari Shinde 			WM8994_HPOUT1R_OUTP | WM8994_HPOUT1L_RMV_SHORT |
752a2d8e0a7SRajeshwari Shinde 			WM8994_HPOUT1R_RMV_SHORT);
753a2d8e0a7SRajeshwari Shinde 
754a2d8e0a7SRajeshwari Shinde 	/* MIXER Config DAC1 to HP */
755*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_OUTPUT_MIXER_1,
756*107ab83eSSimon Glass 			     WM8994_DAC1L_TO_HPOUT1L_MASK,
757*107ab83eSSimon Glass 			     WM8994_DAC1L_TO_HPOUT1L);
758a2d8e0a7SRajeshwari Shinde 
759*107ab83eSSimon Glass 	ret |= wm8994_bic_or(priv, WM8994_OUTPUT_MIXER_2,
760*107ab83eSSimon Glass 			     WM8994_DAC1R_TO_HPOUT1R_MASK,
761*107ab83eSSimon Glass 			     WM8994_DAC1R_TO_HPOUT1R);
762a2d8e0a7SRajeshwari Shinde 
763d981d80dSDani Krishna Mohan 	if (aif_id == WM8994_AIF1) {
764d981d80dSDani Krishna Mohan 		/* Routing AIF1 to DAC1 */
765*107ab83eSSimon Glass 		ret |= wm8994_i2c_write(priv, WM8994_DAC1_LEFT_MIXER_ROUTING,
766d981d80dSDani Krishna Mohan 					WM8994_AIF1DAC1L_TO_DAC1L);
767d981d80dSDani Krishna Mohan 
768*107ab83eSSimon Glass 		ret |= wm8994_i2c_write(priv, WM8994_DAC1_RIGHT_MIXER_ROUTING,
769d981d80dSDani Krishna Mohan 					WM8994_AIF1DAC1R_TO_DAC1R);
770d981d80dSDani Krishna Mohan 
771d981d80dSDani Krishna Mohan 		/* GPIO Settings for AIF1 */
772*107ab83eSSimon Glass 		ret |=  wm8994_i2c_write(priv, WM8994_GPIO_1,
773*107ab83eSSimon Glass 					 WM8994_GPIO_DIR_OUTPUT |
774*107ab83eSSimon Glass 					 WM8994_GPIO_FUNCTION_I2S_CLK |
775*107ab83eSSimon Glass 					 WM8994_GPIO_INPUT_DEBOUNCE);
776d981d80dSDani Krishna Mohan 
777*107ab83eSSimon Glass 		ret |= wm8994_init_volume_aif1_dac1(priv);
778d981d80dSDani Krishna Mohan 	} else if (aif_id == WM8994_AIF2) {
779a2d8e0a7SRajeshwari Shinde 		/* Routing AIF2 to DAC1 */
780*107ab83eSSimon Glass 		ret |= wm8994_bic_or(priv, WM8994_DAC1_LEFT_MIXER_ROUTING,
781a2d8e0a7SRajeshwari Shinde 				     WM8994_AIF2DACL_TO_DAC1L_MASK,
782a2d8e0a7SRajeshwari Shinde 				     WM8994_AIF2DACL_TO_DAC1L);
783a2d8e0a7SRajeshwari Shinde 
784*107ab83eSSimon Glass 		ret |= wm8994_bic_or(priv, WM8994_DAC1_RIGHT_MIXER_ROUTING,
785a2d8e0a7SRajeshwari Shinde 				     WM8994_AIF2DACR_TO_DAC1R_MASK,
786a2d8e0a7SRajeshwari Shinde 				     WM8994_AIF2DACR_TO_DAC1R);
787a2d8e0a7SRajeshwari Shinde 
788a2d8e0a7SRajeshwari Shinde 		/* GPIO Settings for AIF2 */
789a2d8e0a7SRajeshwari Shinde 		/* B CLK */
790*107ab83eSSimon Glass 		ret |= wm8994_bic_or(priv, WM8994_GPIO_3, WM8994_GPIO_DIR_MASK |
791a2d8e0a7SRajeshwari Shinde 				     WM8994_GPIO_FUNCTION_MASK,
792d981d80dSDani Krishna Mohan 				     WM8994_GPIO_DIR_OUTPUT);
793a2d8e0a7SRajeshwari Shinde 
794a2d8e0a7SRajeshwari Shinde 		/* LR CLK */
795*107ab83eSSimon Glass 		ret |= wm8994_bic_or(priv, WM8994_GPIO_4, WM8994_GPIO_DIR_MASK |
796a2d8e0a7SRajeshwari Shinde 				     WM8994_GPIO_FUNCTION_MASK,
797d981d80dSDani Krishna Mohan 				     WM8994_GPIO_DIR_OUTPUT);
798a2d8e0a7SRajeshwari Shinde 
799a2d8e0a7SRajeshwari Shinde 		/* DATA */
800*107ab83eSSimon Glass 		ret |= wm8994_bic_or(priv, WM8994_GPIO_5, WM8994_GPIO_DIR_MASK |
801a2d8e0a7SRajeshwari Shinde 				     WM8994_GPIO_FUNCTION_MASK,
802d981d80dSDani Krishna Mohan 				     WM8994_GPIO_DIR_OUTPUT);
803a2d8e0a7SRajeshwari Shinde 
804*107ab83eSSimon Glass 		ret |= wm8994_init_volume_aif2_dac1(priv);
805d981d80dSDani Krishna Mohan 	}
806d981d80dSDani Krishna Mohan 
807a2d8e0a7SRajeshwari Shinde 	if (ret < 0)
808a2d8e0a7SRajeshwari Shinde 		goto err;
809a2d8e0a7SRajeshwari Shinde 
810a2d8e0a7SRajeshwari Shinde 	debug("%s: Codec chip init ok\n", __func__);
811a2d8e0a7SRajeshwari Shinde 	return 0;
812a2d8e0a7SRajeshwari Shinde err:
813a2d8e0a7SRajeshwari Shinde 	debug("%s: Codec chip init error\n", __func__);
814a2d8e0a7SRajeshwari Shinde 	return -1;
815a2d8e0a7SRajeshwari Shinde }
816a2d8e0a7SRajeshwari Shinde 
8176647c7acSRajeshwari Shinde /*
8186647c7acSRajeshwari Shinde  * Gets fdt values for wm8994 config parameters
8196647c7acSRajeshwari Shinde  *
8206647c7acSRajeshwari Shinde  * @param pcodec_info	codec information structure
8216647c7acSRajeshwari Shinde  * @param blob		FDT blob
8226647c7acSRajeshwari Shinde  * @return		int value, 0 for success
8236647c7acSRajeshwari Shinde  */
8246647c7acSRajeshwari Shinde static int get_codec_values(struct sound_codec_info *pcodec_info,
8256647c7acSRajeshwari Shinde 			    const void *blob)
8266647c7acSRajeshwari Shinde {
8276647c7acSRajeshwari Shinde 	int error = 0;
8286647c7acSRajeshwari Shinde 	enum fdt_compat_id compat;
8296647c7acSRajeshwari Shinde 	int node;
8306647c7acSRajeshwari Shinde 	int parent;
8316647c7acSRajeshwari Shinde 
8326647c7acSRajeshwari Shinde 	/* Get the node from FDT for codec */
8336647c7acSRajeshwari Shinde 	node = fdtdec_next_compatible(blob, 0, COMPAT_WOLFSON_WM8994_CODEC);
8346647c7acSRajeshwari Shinde 	if (node <= 0) {
8356647c7acSRajeshwari Shinde 		debug("EXYNOS_SOUND: No node for codec in device tree\n");
8366647c7acSRajeshwari Shinde 		debug("node = %d\n", node);
8376647c7acSRajeshwari Shinde 		return -1;
8386647c7acSRajeshwari Shinde 	}
8396647c7acSRajeshwari Shinde 
8406647c7acSRajeshwari Shinde 	parent = fdt_parent_offset(blob, node);
8416647c7acSRajeshwari Shinde 	if (parent < 0) {
8426647c7acSRajeshwari Shinde 		debug("%s: Cannot find node parent\n", __func__);
8436647c7acSRajeshwari Shinde 		return -1;
8446647c7acSRajeshwari Shinde 	}
8456647c7acSRajeshwari Shinde 
8466647c7acSRajeshwari Shinde 	compat = fdtdec_lookup(blob, parent);
8476647c7acSRajeshwari Shinde 	switch (compat) {
8486647c7acSRajeshwari Shinde 	case COMPAT_SAMSUNG_S3C2440_I2C:
8496647c7acSRajeshwari Shinde 		pcodec_info->i2c_bus = i2c_get_bus_num_fdt(parent);
8506647c7acSRajeshwari Shinde 		error |= pcodec_info->i2c_bus;
8516647c7acSRajeshwari Shinde 		debug("i2c bus = %d\n", pcodec_info->i2c_bus);
8526647c7acSRajeshwari Shinde 		pcodec_info->i2c_dev_addr = fdtdec_get_int(blob, node,
8536647c7acSRajeshwari Shinde 							"reg", 0);
8546647c7acSRajeshwari Shinde 		error |= pcodec_info->i2c_dev_addr;
8556647c7acSRajeshwari Shinde 		debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr);
8566647c7acSRajeshwari Shinde 		break;
8576647c7acSRajeshwari Shinde 	default:
8586647c7acSRajeshwari Shinde 		debug("%s: Unknown compat id %d\n", __func__, compat);
8596647c7acSRajeshwari Shinde 		return -1;
8606647c7acSRajeshwari Shinde 	}
8616647c7acSRajeshwari Shinde 
8626647c7acSRajeshwari Shinde 	if (error == -1) {
8636647c7acSRajeshwari Shinde 		debug("fail to get wm8994 codec node properties\n");
8646647c7acSRajeshwari Shinde 		return -1;
8656647c7acSRajeshwari Shinde 	}
8666647c7acSRajeshwari Shinde 
8676647c7acSRajeshwari Shinde 	return 0;
8686647c7acSRajeshwari Shinde }
8696647c7acSRajeshwari Shinde 
870d981d80dSDani Krishna Mohan /* WM8994 Device Initialisation */
8716647c7acSRajeshwari Shinde int wm8994_init(const void *blob, enum en_audio_interface aif_id,
872*107ab83eSSimon Glass 		int sampling_rate, int mclk_freq, int bits_per_sample,
873*107ab83eSSimon Glass 		unsigned int channels)
874a2d8e0a7SRajeshwari Shinde {
875a2d8e0a7SRajeshwari Shinde 	int ret = 0;
8766647c7acSRajeshwari Shinde 	struct sound_codec_info *pcodec_info = &g_codec_info;
8776647c7acSRajeshwari Shinde 
8786647c7acSRajeshwari Shinde 	/* Get the codec Values */
8796647c7acSRajeshwari Shinde 	if (get_codec_values(pcodec_info, blob) < 0) {
8806647c7acSRajeshwari Shinde 		debug("FDT Codec values failed\n");
8816647c7acSRajeshwari Shinde 		return -1;
8826647c7acSRajeshwari Shinde 	}
883a2d8e0a7SRajeshwari Shinde 
884a2d8e0a7SRajeshwari Shinde 	/* shift the device address by 1 for 7 bit addressing */
885a2d8e0a7SRajeshwari Shinde 	g_wm8994_i2c_dev_addr = pcodec_info->i2c_dev_addr;
886a2d8e0a7SRajeshwari Shinde 	wm8994_i2c_init(pcodec_info->i2c_bus);
887a2d8e0a7SRajeshwari Shinde 
888d981d80dSDani Krishna Mohan 	ret = wm8994_device_init(&g_wm8994_info, aif_id);
889a2d8e0a7SRajeshwari Shinde 	if (ret < 0) {
890a2d8e0a7SRajeshwari Shinde 		debug("%s: wm8994 codec chip init failed\n", __func__);
891a2d8e0a7SRajeshwari Shinde 		return ret;
892a2d8e0a7SRajeshwari Shinde 	}
893a2d8e0a7SRajeshwari Shinde 
894a2d8e0a7SRajeshwari Shinde 	ret =  wm8994_set_sysclk(&g_wm8994_info, aif_id, WM8994_SYSCLK_MCLK1,
895a2d8e0a7SRajeshwari Shinde 							mclk_freq);
896a2d8e0a7SRajeshwari Shinde 	if (ret < 0) {
897a2d8e0a7SRajeshwari Shinde 		debug("%s: wm8994 codec set sys clock failed\n", __func__);
898a2d8e0a7SRajeshwari Shinde 		return ret;
899a2d8e0a7SRajeshwari Shinde 	}
900a2d8e0a7SRajeshwari Shinde 
901a2d8e0a7SRajeshwari Shinde 	ret = wm8994_hw_params(&g_wm8994_info, aif_id, sampling_rate,
902a2d8e0a7SRajeshwari Shinde 			       bits_per_sample, channels);
903a2d8e0a7SRajeshwari Shinde 
904a2d8e0a7SRajeshwari Shinde 	if (ret == 0) {
905*107ab83eSSimon Glass 		ret = wm8994_set_fmt(&g_wm8994_info, aif_id,
906*107ab83eSSimon Glass 				     SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
907a2d8e0a7SRajeshwari Shinde 				     SND_SOC_DAIFMT_CBS_CFS);
908a2d8e0a7SRajeshwari Shinde 	}
909a2d8e0a7SRajeshwari Shinde 	return ret;
910a2d8e0a7SRajeshwari Shinde }
911