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