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