xref: /OK3568_Linux_fs/u-boot/drivers/sound/max98095.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * max98095.c -- MAX98095 ALSA SoC Audio driver
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright 2011 Maxim Integrated Products
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Modified for uboot by R. Chandrasekar (rcsekar@samsung.com)
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * This program is free software; you can redistribute it and/or modify
9*4882a593Smuzhiyun  * it under the terms of the GNU General Public License version 2 as
10*4882a593Smuzhiyun  * published by the Free Software Foundation.
11*4882a593Smuzhiyun  */
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include <common.h>
14*4882a593Smuzhiyun #include <asm/arch/clk.h>
15*4882a593Smuzhiyun #include <asm/arch/cpu.h>
16*4882a593Smuzhiyun #include <asm/arch/power.h>
17*4882a593Smuzhiyun #include <asm/gpio.h>
18*4882a593Smuzhiyun #include <asm/io.h>
19*4882a593Smuzhiyun #include <common.h>
20*4882a593Smuzhiyun #include <div64.h>
21*4882a593Smuzhiyun #include <fdtdec.h>
22*4882a593Smuzhiyun #include <i2c.h>
23*4882a593Smuzhiyun #include <sound.h>
24*4882a593Smuzhiyun #include "i2s.h"
25*4882a593Smuzhiyun #include "max98095.h"
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun enum max98095_type {
28*4882a593Smuzhiyun 	MAX98095,
29*4882a593Smuzhiyun };
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun struct max98095_priv {
32*4882a593Smuzhiyun 	enum max98095_type devtype;
33*4882a593Smuzhiyun 	unsigned int sysclk;
34*4882a593Smuzhiyun 	unsigned int rate;
35*4882a593Smuzhiyun 	unsigned int fmt;
36*4882a593Smuzhiyun };
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun static struct sound_codec_info g_codec_info;
39*4882a593Smuzhiyun struct max98095_priv g_max98095_info;
40*4882a593Smuzhiyun unsigned int g_max98095_i2c_dev_addr;
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /* Index 0 is reserved. */
43*4882a593Smuzhiyun int rate_table[] = {0, 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000,
44*4882a593Smuzhiyun 		88200, 96000};
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun /*
47*4882a593Smuzhiyun  * Writes value to a device register through i2c
48*4882a593Smuzhiyun  *
49*4882a593Smuzhiyun  * @param reg	reg number to be write
50*4882a593Smuzhiyun  * @param data	data to be writen to the above registor
51*4882a593Smuzhiyun  *
52*4882a593Smuzhiyun  * @return	int value 1 for change, 0 for no change or negative error code.
53*4882a593Smuzhiyun  */
max98095_i2c_write(unsigned int reg,unsigned char data)54*4882a593Smuzhiyun static int max98095_i2c_write(unsigned int reg, unsigned char data)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun 	debug("%s: Write Addr : 0x%02X, Data :  0x%02X\n",
57*4882a593Smuzhiyun 	      __func__, reg, data);
58*4882a593Smuzhiyun 	return i2c_write(g_max98095_i2c_dev_addr, reg, 1, &data, 1);
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun /*
62*4882a593Smuzhiyun  * Read a value from a device register through i2c
63*4882a593Smuzhiyun  *
64*4882a593Smuzhiyun  * @param reg	reg number to be read
65*4882a593Smuzhiyun  * @param data	address of read data to be stored
66*4882a593Smuzhiyun  *
67*4882a593Smuzhiyun  * @return	int value 0 for success, -1 in case of error.
68*4882a593Smuzhiyun  */
max98095_i2c_read(unsigned int reg,unsigned char * data)69*4882a593Smuzhiyun static unsigned int max98095_i2c_read(unsigned int reg, unsigned char *data)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun 	int ret;
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	ret = i2c_read(g_max98095_i2c_dev_addr, reg, 1, data, 1);
74*4882a593Smuzhiyun 	if (ret != 0) {
75*4882a593Smuzhiyun 		debug("%s: Error while reading register %#04x\n",
76*4882a593Smuzhiyun 		      __func__, reg);
77*4882a593Smuzhiyun 		return -1;
78*4882a593Smuzhiyun 	}
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun 	return 0;
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun /*
84*4882a593Smuzhiyun  * update device register bits through i2c
85*4882a593Smuzhiyun  *
86*4882a593Smuzhiyun  * @param reg	codec register
87*4882a593Smuzhiyun  * @param mask	register mask
88*4882a593Smuzhiyun  * @param value	new value
89*4882a593Smuzhiyun  *
90*4882a593Smuzhiyun  * @return int value 0 for success, non-zero error code.
91*4882a593Smuzhiyun  */
max98095_update_bits(unsigned int reg,unsigned char mask,unsigned char value)92*4882a593Smuzhiyun static int max98095_update_bits(unsigned int reg, unsigned char mask,
93*4882a593Smuzhiyun 				unsigned char value)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun 	int change, ret = 0;
96*4882a593Smuzhiyun 	unsigned char old, new;
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	if (max98095_i2c_read(reg, &old) != 0)
99*4882a593Smuzhiyun 		return -1;
100*4882a593Smuzhiyun 	new = (old & ~mask) | (value & mask);
101*4882a593Smuzhiyun 	change  = (old != new) ? 1 : 0;
102*4882a593Smuzhiyun 	if (change)
103*4882a593Smuzhiyun 		ret = max98095_i2c_write(reg, new);
104*4882a593Smuzhiyun 	if (ret < 0)
105*4882a593Smuzhiyun 		return ret;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	return change;
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun /*
111*4882a593Smuzhiyun  * codec mclk clock divider coefficients based on sampling rate
112*4882a593Smuzhiyun  *
113*4882a593Smuzhiyun  * @param rate sampling rate
114*4882a593Smuzhiyun  * @param value address of indexvalue to be stored
115*4882a593Smuzhiyun  *
116*4882a593Smuzhiyun  * @return	0 for success or negative error code.
117*4882a593Smuzhiyun  */
rate_value(int rate,u8 * value)118*4882a593Smuzhiyun static int rate_value(int rate, u8 *value)
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun 	int i;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	for (i = 1; i < ARRAY_SIZE(rate_table); i++) {
123*4882a593Smuzhiyun 		if (rate_table[i] >= rate) {
124*4882a593Smuzhiyun 			*value = i;
125*4882a593Smuzhiyun 			return 0;
126*4882a593Smuzhiyun 		}
127*4882a593Smuzhiyun 	}
128*4882a593Smuzhiyun 	*value = 1;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	return -1;
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun /*
134*4882a593Smuzhiyun  * Sets hw params for max98095
135*4882a593Smuzhiyun  *
136*4882a593Smuzhiyun  * @param max98095	max98095 information pointer
137*4882a593Smuzhiyun  * @param rate		Sampling rate
138*4882a593Smuzhiyun  * @param bits_per_sample	Bits per sample
139*4882a593Smuzhiyun  *
140*4882a593Smuzhiyun  * @return -1 for error  and 0  Success.
141*4882a593Smuzhiyun  */
max98095_hw_params(struct max98095_priv * max98095,enum en_max_audio_interface aif_id,unsigned int rate,unsigned int bits_per_sample)142*4882a593Smuzhiyun static int max98095_hw_params(struct max98095_priv *max98095,
143*4882a593Smuzhiyun 			      enum en_max_audio_interface aif_id,
144*4882a593Smuzhiyun 			      unsigned int rate, unsigned int bits_per_sample)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun 	u8 regval;
147*4882a593Smuzhiyun 	int error;
148*4882a593Smuzhiyun 	unsigned short M98095_DAI_CLKMODE;
149*4882a593Smuzhiyun 	unsigned short M98095_DAI_FORMAT;
150*4882a593Smuzhiyun 	unsigned short M98095_DAI_FILTERS;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	if (aif_id == AIF1) {
153*4882a593Smuzhiyun 		M98095_DAI_CLKMODE = M98095_027_DAI1_CLKMODE;
154*4882a593Smuzhiyun 		M98095_DAI_FORMAT = M98095_02A_DAI1_FORMAT;
155*4882a593Smuzhiyun 		M98095_DAI_FILTERS = M98095_02E_DAI1_FILTERS;
156*4882a593Smuzhiyun 	} else {
157*4882a593Smuzhiyun 		M98095_DAI_CLKMODE = M98095_031_DAI2_CLKMODE;
158*4882a593Smuzhiyun 		M98095_DAI_FORMAT = M98095_034_DAI2_FORMAT;
159*4882a593Smuzhiyun 		M98095_DAI_FILTERS = M98095_038_DAI2_FILTERS;
160*4882a593Smuzhiyun 	}
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	switch (bits_per_sample) {
163*4882a593Smuzhiyun 	case 16:
164*4882a593Smuzhiyun 		error = max98095_update_bits(M98095_DAI_FORMAT,
165*4882a593Smuzhiyun 					     M98095_DAI_WS, 0);
166*4882a593Smuzhiyun 		break;
167*4882a593Smuzhiyun 	case 24:
168*4882a593Smuzhiyun 		error = max98095_update_bits(M98095_DAI_FORMAT,
169*4882a593Smuzhiyun 					     M98095_DAI_WS, M98095_DAI_WS);
170*4882a593Smuzhiyun 		break;
171*4882a593Smuzhiyun 	default:
172*4882a593Smuzhiyun 		debug("%s: Illegal bits per sample %d.\n",
173*4882a593Smuzhiyun 		      __func__, bits_per_sample);
174*4882a593Smuzhiyun 		return -1;
175*4882a593Smuzhiyun 	}
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	if (rate_value(rate, &regval)) {
178*4882a593Smuzhiyun 		debug("%s: Failed to set sample rate to %d.\n",
179*4882a593Smuzhiyun 		      __func__, rate);
180*4882a593Smuzhiyun 		return -1;
181*4882a593Smuzhiyun 	}
182*4882a593Smuzhiyun 	max98095->rate = rate;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	error |= max98095_update_bits(M98095_DAI_CLKMODE,
185*4882a593Smuzhiyun 				      M98095_CLKMODE_MASK, regval);
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	/* Update sample rate mode */
188*4882a593Smuzhiyun 	if (rate < 50000)
189*4882a593Smuzhiyun 		error |= max98095_update_bits(M98095_DAI_FILTERS,
190*4882a593Smuzhiyun 					      M98095_DAI_DHF, 0);
191*4882a593Smuzhiyun 	else
192*4882a593Smuzhiyun 		error |= max98095_update_bits(M98095_DAI_FILTERS,
193*4882a593Smuzhiyun 					      M98095_DAI_DHF, M98095_DAI_DHF);
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	if (error < 0) {
196*4882a593Smuzhiyun 		debug("%s: Error setting hardware params.\n", __func__);
197*4882a593Smuzhiyun 		return -1;
198*4882a593Smuzhiyun 	}
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	return 0;
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun /*
204*4882a593Smuzhiyun  * Configures Audio interface system clock for the given frequency
205*4882a593Smuzhiyun  *
206*4882a593Smuzhiyun  * @param max98095	max98095 information
207*4882a593Smuzhiyun  * @param freq		Sampling frequency in Hz
208*4882a593Smuzhiyun  *
209*4882a593Smuzhiyun  * @return -1 for error and 0 success.
210*4882a593Smuzhiyun  */
max98095_set_sysclk(struct max98095_priv * max98095,unsigned int freq)211*4882a593Smuzhiyun static int max98095_set_sysclk(struct max98095_priv *max98095,
212*4882a593Smuzhiyun 			       unsigned int freq)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun 	int error = 0;
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	/* Requested clock frequency is already setup */
217*4882a593Smuzhiyun 	if (freq == max98095->sysclk)
218*4882a593Smuzhiyun 		return 0;
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	/* Setup clocks for slave mode, and using the PLL
221*4882a593Smuzhiyun 	 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
222*4882a593Smuzhiyun 	 *	0x02 (when master clk is 20MHz to 40MHz)..
223*4882a593Smuzhiyun 	 *	0x03 (when master clk is 40MHz to 60MHz)..
224*4882a593Smuzhiyun 	 */
225*4882a593Smuzhiyun 	if ((freq >= 10000000) && (freq < 20000000)) {
226*4882a593Smuzhiyun 		error = max98095_i2c_write(M98095_026_SYS_CLK, 0x10);
227*4882a593Smuzhiyun 	} else if ((freq >= 20000000) && (freq < 40000000)) {
228*4882a593Smuzhiyun 		error = max98095_i2c_write(M98095_026_SYS_CLK, 0x20);
229*4882a593Smuzhiyun 	} else if ((freq >= 40000000) && (freq < 60000000)) {
230*4882a593Smuzhiyun 		error = max98095_i2c_write(M98095_026_SYS_CLK, 0x30);
231*4882a593Smuzhiyun 	} else {
232*4882a593Smuzhiyun 		debug("%s: Invalid master clock frequency\n", __func__);
233*4882a593Smuzhiyun 		return -1;
234*4882a593Smuzhiyun 	}
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	debug("%s: Clock at %uHz\n", __func__, freq);
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	if (error < 0)
239*4882a593Smuzhiyun 		return -1;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	max98095->sysclk = freq;
242*4882a593Smuzhiyun 	return 0;
243*4882a593Smuzhiyun }
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun /*
246*4882a593Smuzhiyun  * Sets Max98095 I2S format
247*4882a593Smuzhiyun  *
248*4882a593Smuzhiyun  * @param max98095	max98095 information
249*4882a593Smuzhiyun  * @param fmt		i2S format - supports a subset of the options defined
250*4882a593Smuzhiyun  *			in i2s.h.
251*4882a593Smuzhiyun  *
252*4882a593Smuzhiyun  * @return -1 for error and 0  Success.
253*4882a593Smuzhiyun  */
max98095_set_fmt(struct max98095_priv * max98095,int fmt,enum en_max_audio_interface aif_id)254*4882a593Smuzhiyun static int max98095_set_fmt(struct max98095_priv *max98095, int fmt,
255*4882a593Smuzhiyun 			    enum en_max_audio_interface aif_id)
256*4882a593Smuzhiyun {
257*4882a593Smuzhiyun 	u8 regval = 0;
258*4882a593Smuzhiyun 	int error = 0;
259*4882a593Smuzhiyun 	unsigned short M98095_DAI_CLKCFG_HI;
260*4882a593Smuzhiyun 	unsigned short M98095_DAI_CLKCFG_LO;
261*4882a593Smuzhiyun 	unsigned short M98095_DAI_FORMAT;
262*4882a593Smuzhiyun 	unsigned short M98095_DAI_CLOCK;
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	if (fmt == max98095->fmt)
265*4882a593Smuzhiyun 		return 0;
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 	max98095->fmt = fmt;
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 	if (aif_id == AIF1) {
270*4882a593Smuzhiyun 		M98095_DAI_CLKCFG_HI = M98095_028_DAI1_CLKCFG_HI;
271*4882a593Smuzhiyun 		M98095_DAI_CLKCFG_LO = M98095_029_DAI1_CLKCFG_LO;
272*4882a593Smuzhiyun 		M98095_DAI_FORMAT = M98095_02A_DAI1_FORMAT;
273*4882a593Smuzhiyun 		M98095_DAI_CLOCK = M98095_02B_DAI1_CLOCK;
274*4882a593Smuzhiyun 	} else {
275*4882a593Smuzhiyun 		M98095_DAI_CLKCFG_HI = M98095_032_DAI2_CLKCFG_HI;
276*4882a593Smuzhiyun 		M98095_DAI_CLKCFG_LO = M98095_033_DAI2_CLKCFG_LO;
277*4882a593Smuzhiyun 		M98095_DAI_FORMAT = M98095_034_DAI2_FORMAT;
278*4882a593Smuzhiyun 		M98095_DAI_CLOCK = M98095_035_DAI2_CLOCK;
279*4882a593Smuzhiyun 	}
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
282*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_CBS_CFS:
283*4882a593Smuzhiyun 		/* Slave mode PLL */
284*4882a593Smuzhiyun 		error |= max98095_i2c_write(M98095_DAI_CLKCFG_HI,
285*4882a593Smuzhiyun 					0x80);
286*4882a593Smuzhiyun 		error |= max98095_i2c_write(M98095_DAI_CLKCFG_LO,
287*4882a593Smuzhiyun 					0x00);
288*4882a593Smuzhiyun 		break;
289*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_CBM_CFM:
290*4882a593Smuzhiyun 		/* Set to master mode */
291*4882a593Smuzhiyun 		regval |= M98095_DAI_MAS;
292*4882a593Smuzhiyun 		break;
293*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_CBS_CFM:
294*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_CBM_CFS:
295*4882a593Smuzhiyun 	default:
296*4882a593Smuzhiyun 		debug("%s: Clock mode unsupported\n", __func__);
297*4882a593Smuzhiyun 		return -1;
298*4882a593Smuzhiyun 	}
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
301*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_I2S:
302*4882a593Smuzhiyun 		regval |= M98095_DAI_DLY;
303*4882a593Smuzhiyun 		break;
304*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_LEFT_J:
305*4882a593Smuzhiyun 		break;
306*4882a593Smuzhiyun 	default:
307*4882a593Smuzhiyun 		debug("%s: Unrecognized format.\n", __func__);
308*4882a593Smuzhiyun 		return -1;
309*4882a593Smuzhiyun 	}
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
312*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_NB_NF:
313*4882a593Smuzhiyun 		break;
314*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_NB_IF:
315*4882a593Smuzhiyun 		regval |= M98095_DAI_WCI;
316*4882a593Smuzhiyun 		break;
317*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_IB_NF:
318*4882a593Smuzhiyun 		regval |= M98095_DAI_BCI;
319*4882a593Smuzhiyun 		break;
320*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_IB_IF:
321*4882a593Smuzhiyun 		regval |= M98095_DAI_BCI | M98095_DAI_WCI;
322*4882a593Smuzhiyun 		break;
323*4882a593Smuzhiyun 	default:
324*4882a593Smuzhiyun 		debug("%s: Unrecognized inversion settings.\n", __func__);
325*4882a593Smuzhiyun 		return -1;
326*4882a593Smuzhiyun 	}
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 	error |= max98095_update_bits(M98095_DAI_FORMAT,
329*4882a593Smuzhiyun 				      M98095_DAI_MAS | M98095_DAI_DLY |
330*4882a593Smuzhiyun 				      M98095_DAI_BCI | M98095_DAI_WCI,
331*4882a593Smuzhiyun 				      regval);
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	error |= max98095_i2c_write(M98095_DAI_CLOCK,
334*4882a593Smuzhiyun 				    M98095_DAI_BSEL64);
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	if (error < 0) {
337*4882a593Smuzhiyun 		debug("%s: Error setting i2s format.\n", __func__);
338*4882a593Smuzhiyun 		return -1;
339*4882a593Smuzhiyun 	}
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	return 0;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun /*
345*4882a593Smuzhiyun  * resets the audio codec
346*4882a593Smuzhiyun  *
347*4882a593Smuzhiyun  * @return -1 for error and 0 success.
348*4882a593Smuzhiyun  */
max98095_reset(void)349*4882a593Smuzhiyun static int max98095_reset(void)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun 	int i, ret;
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun 	/*
354*4882a593Smuzhiyun 	 * Gracefully reset the DSP core and the codec hardware in a proper
355*4882a593Smuzhiyun 	 * sequence.
356*4882a593Smuzhiyun 	 */
357*4882a593Smuzhiyun 	ret = max98095_i2c_write(M98095_00F_HOST_CFG, 0);
358*4882a593Smuzhiyun 	if (ret != 0) {
359*4882a593Smuzhiyun 		debug("%s: Failed to reset DSP: %d\n", __func__, ret);
360*4882a593Smuzhiyun 		return ret;
361*4882a593Smuzhiyun 	}
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	ret = max98095_i2c_write(M98095_097_PWR_SYS, 0);
364*4882a593Smuzhiyun 	if (ret != 0) {
365*4882a593Smuzhiyun 		debug("%s: Failed to reset codec: %d\n", __func__, ret);
366*4882a593Smuzhiyun 		return ret;
367*4882a593Smuzhiyun 	}
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	/*
370*4882a593Smuzhiyun 	 * Reset to hardware default for registers, as there is not a soft
371*4882a593Smuzhiyun 	 * reset hardware control register.
372*4882a593Smuzhiyun 	 */
373*4882a593Smuzhiyun 	for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) {
374*4882a593Smuzhiyun 		ret = max98095_i2c_write(i, 0);
375*4882a593Smuzhiyun 		if (ret < 0) {
376*4882a593Smuzhiyun 			debug("%s: Failed to reset: %d\n", __func__, ret);
377*4882a593Smuzhiyun 			return ret;
378*4882a593Smuzhiyun 		}
379*4882a593Smuzhiyun 	}
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 	return 0;
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun /*
385*4882a593Smuzhiyun  * Intialise max98095 codec device
386*4882a593Smuzhiyun  *
387*4882a593Smuzhiyun  * @param max98095	max98095 information
388*4882a593Smuzhiyun  *
389*4882a593Smuzhiyun  * @returns -1 for error  and 0 Success.
390*4882a593Smuzhiyun  */
max98095_device_init(struct max98095_priv * max98095,enum en_max_audio_interface aif_id)391*4882a593Smuzhiyun static int max98095_device_init(struct max98095_priv *max98095,
392*4882a593Smuzhiyun 				enum en_max_audio_interface aif_id)
393*4882a593Smuzhiyun {
394*4882a593Smuzhiyun 	unsigned char id;
395*4882a593Smuzhiyun 	int error = 0;
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 	/* reset the codec, the DSP core, and disable all interrupts */
398*4882a593Smuzhiyun 	error = max98095_reset();
399*4882a593Smuzhiyun 	if (error != 0) {
400*4882a593Smuzhiyun 		debug("Reset\n");
401*4882a593Smuzhiyun 		return error;
402*4882a593Smuzhiyun 	}
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	/* initialize private data */
405*4882a593Smuzhiyun 	max98095->sysclk = -1U;
406*4882a593Smuzhiyun 	max98095->rate = -1U;
407*4882a593Smuzhiyun 	max98095->fmt = -1U;
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	error = max98095_i2c_read(M98095_0FF_REV_ID, &id);
410*4882a593Smuzhiyun 	if (error < 0) {
411*4882a593Smuzhiyun 		debug("%s: Failure reading hardware revision: %d\n",
412*4882a593Smuzhiyun 		      __func__, id);
413*4882a593Smuzhiyun 		goto err_access;
414*4882a593Smuzhiyun 	}
415*4882a593Smuzhiyun 	debug("%s: Hardware revision: %c\n", __func__, (id - 0x40) + 'A');
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	error |= max98095_i2c_write(M98095_097_PWR_SYS, M98095_PWRSV);
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	/*
420*4882a593Smuzhiyun 	 * initialize registers to hardware default configuring audio
421*4882a593Smuzhiyun 	 * interface2 to DAC
422*4882a593Smuzhiyun 	 */
423*4882a593Smuzhiyun 	if (aif_id == AIF1)
424*4882a593Smuzhiyun 		error |= max98095_i2c_write(M98095_048_MIX_DAC_LR,
425*4882a593Smuzhiyun 					    M98095_DAI1L_TO_DACL |
426*4882a593Smuzhiyun 					    M98095_DAI1R_TO_DACR);
427*4882a593Smuzhiyun 	else
428*4882a593Smuzhiyun 		error |= max98095_i2c_write(M98095_048_MIX_DAC_LR,
429*4882a593Smuzhiyun 					    M98095_DAI2M_TO_DACL |
430*4882a593Smuzhiyun 					    M98095_DAI2M_TO_DACR);
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun 	error |= max98095_i2c_write(M98095_092_PWR_EN_OUT,
433*4882a593Smuzhiyun 				    M98095_SPK_SPREADSPECTRUM);
434*4882a593Smuzhiyun 	error |= max98095_i2c_write(M98095_04E_CFG_HP, M98095_HPNORMAL);
435*4882a593Smuzhiyun 	if (aif_id == AIF1)
436*4882a593Smuzhiyun 		error |= max98095_i2c_write(M98095_02C_DAI1_IOCFG,
437*4882a593Smuzhiyun 					    M98095_S1NORMAL | M98095_SDATA);
438*4882a593Smuzhiyun 	else
439*4882a593Smuzhiyun 		error |= max98095_i2c_write(M98095_036_DAI2_IOCFG,
440*4882a593Smuzhiyun 					    M98095_S2NORMAL | M98095_SDATA);
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 	/* take the codec out of the shut down */
443*4882a593Smuzhiyun 	error |= max98095_update_bits(M98095_097_PWR_SYS, M98095_SHDNRUN,
444*4882a593Smuzhiyun 				      M98095_SHDNRUN);
445*4882a593Smuzhiyun 	/* route DACL and DACR output to HO and Spekers */
446*4882a593Smuzhiyun 	error |= max98095_i2c_write(M98095_050_MIX_SPK_LEFT, 0x01); /* DACL */
447*4882a593Smuzhiyun 	error |= max98095_i2c_write(M98095_051_MIX_SPK_RIGHT, 0x01);/* DACR */
448*4882a593Smuzhiyun 	error |= max98095_i2c_write(M98095_04C_MIX_HP_LEFT, 0x01);  /* DACL */
449*4882a593Smuzhiyun 	error |= max98095_i2c_write(M98095_04D_MIX_HP_RIGHT, 0x01); /* DACR */
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	/* power Enable */
452*4882a593Smuzhiyun 	error |= max98095_i2c_write(M98095_091_PWR_EN_OUT, 0xF3);
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 	/* set Volume */
455*4882a593Smuzhiyun 	error |= max98095_i2c_write(M98095_064_LVL_HP_L, 15);
456*4882a593Smuzhiyun 	error |= max98095_i2c_write(M98095_065_LVL_HP_R, 15);
457*4882a593Smuzhiyun 	error |= max98095_i2c_write(M98095_067_LVL_SPK_L, 16);
458*4882a593Smuzhiyun 	error |= max98095_i2c_write(M98095_068_LVL_SPK_R, 16);
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 	/* Enable DAIs */
461*4882a593Smuzhiyun 	error |= max98095_i2c_write(M98095_093_BIAS_CTRL, 0x30);
462*4882a593Smuzhiyun 	if (aif_id == AIF1)
463*4882a593Smuzhiyun 		error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x01);
464*4882a593Smuzhiyun 	else
465*4882a593Smuzhiyun 		error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x07);
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun err_access:
468*4882a593Smuzhiyun 	if (error < 0)
469*4882a593Smuzhiyun 		return -1;
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun 	return 0;
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun 
max98095_do_init(struct sound_codec_info * pcodec_info,enum en_max_audio_interface aif_id,int sampling_rate,int mclk_freq,int bits_per_sample)474*4882a593Smuzhiyun static int max98095_do_init(struct sound_codec_info *pcodec_info,
475*4882a593Smuzhiyun 			    enum en_max_audio_interface aif_id,
476*4882a593Smuzhiyun 			    int sampling_rate, int mclk_freq,
477*4882a593Smuzhiyun 			    int bits_per_sample)
478*4882a593Smuzhiyun {
479*4882a593Smuzhiyun 	int ret = 0;
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 	/* Enable codec clock */
482*4882a593Smuzhiyun 	set_xclkout();
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun 	/* shift the device address by 1 for 7 bit addressing */
485*4882a593Smuzhiyun 	g_max98095_i2c_dev_addr = pcodec_info->i2c_dev_addr >> 1;
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	if (pcodec_info->codec_type == CODEC_MAX_98095) {
488*4882a593Smuzhiyun 		g_max98095_info.devtype = MAX98095;
489*4882a593Smuzhiyun 	} else {
490*4882a593Smuzhiyun 		debug("%s: Codec id [%d] not defined\n", __func__,
491*4882a593Smuzhiyun 		      pcodec_info->codec_type);
492*4882a593Smuzhiyun 		return -1;
493*4882a593Smuzhiyun 	}
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 	ret = max98095_device_init(&g_max98095_info, aif_id);
496*4882a593Smuzhiyun 	if (ret < 0) {
497*4882a593Smuzhiyun 		debug("%s: max98095 codec chip init failed\n", __func__);
498*4882a593Smuzhiyun 		return ret;
499*4882a593Smuzhiyun 	}
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 	ret = max98095_set_sysclk(&g_max98095_info, mclk_freq);
502*4882a593Smuzhiyun 	if (ret < 0) {
503*4882a593Smuzhiyun 		debug("%s: max98095 codec set sys clock failed\n", __func__);
504*4882a593Smuzhiyun 		return ret;
505*4882a593Smuzhiyun 	}
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun 	ret = max98095_hw_params(&g_max98095_info, aif_id, sampling_rate,
508*4882a593Smuzhiyun 				 bits_per_sample);
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	if (ret == 0) {
511*4882a593Smuzhiyun 		ret = max98095_set_fmt(&g_max98095_info,
512*4882a593Smuzhiyun 				       SND_SOC_DAIFMT_I2S |
513*4882a593Smuzhiyun 				       SND_SOC_DAIFMT_NB_NF |
514*4882a593Smuzhiyun 				       SND_SOC_DAIFMT_CBS_CFS,
515*4882a593Smuzhiyun 				       aif_id);
516*4882a593Smuzhiyun 	}
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun 	return ret;
519*4882a593Smuzhiyun }
520*4882a593Smuzhiyun 
get_max98095_codec_values(struct sound_codec_info * pcodec_info,const void * blob)521*4882a593Smuzhiyun static int get_max98095_codec_values(struct sound_codec_info *pcodec_info,
522*4882a593Smuzhiyun 				const void *blob)
523*4882a593Smuzhiyun {
524*4882a593Smuzhiyun 	int error = 0;
525*4882a593Smuzhiyun #if CONFIG_IS_ENABLED(OF_CONTROL)
526*4882a593Smuzhiyun 	enum fdt_compat_id compat;
527*4882a593Smuzhiyun 	int node;
528*4882a593Smuzhiyun 	int parent;
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 	/* Get the node from FDT for codec */
531*4882a593Smuzhiyun 	node = fdtdec_next_compatible(blob, 0, COMPAT_MAXIM_98095_CODEC);
532*4882a593Smuzhiyun 	if (node <= 0) {
533*4882a593Smuzhiyun 		debug("EXYNOS_SOUND: No node for codec in device tree\n");
534*4882a593Smuzhiyun 		debug("node = %d\n", node);
535*4882a593Smuzhiyun 		return -1;
536*4882a593Smuzhiyun 	}
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 	parent = fdt_parent_offset(blob, node);
539*4882a593Smuzhiyun 	if (parent < 0) {
540*4882a593Smuzhiyun 		debug("%s: Cannot find node parent\n", __func__);
541*4882a593Smuzhiyun 		return -1;
542*4882a593Smuzhiyun 	}
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	compat = fdtdec_lookup(blob, parent);
545*4882a593Smuzhiyun 	switch (compat) {
546*4882a593Smuzhiyun 	case COMPAT_SAMSUNG_S3C2440_I2C:
547*4882a593Smuzhiyun 		pcodec_info->i2c_bus = i2c_get_bus_num_fdt(parent);
548*4882a593Smuzhiyun 		error |= pcodec_info->i2c_bus;
549*4882a593Smuzhiyun 		debug("i2c bus = %d\n", pcodec_info->i2c_bus);
550*4882a593Smuzhiyun 		pcodec_info->i2c_dev_addr = fdtdec_get_int(blob, node,
551*4882a593Smuzhiyun 							"reg", 0);
552*4882a593Smuzhiyun 		error |= pcodec_info->i2c_dev_addr;
553*4882a593Smuzhiyun 		debug("i2c dev addr = %x\n", pcodec_info->i2c_dev_addr);
554*4882a593Smuzhiyun 		break;
555*4882a593Smuzhiyun 	default:
556*4882a593Smuzhiyun 		debug("%s: Unknown compat id %d\n", __func__, compat);
557*4882a593Smuzhiyun 		return -1;
558*4882a593Smuzhiyun 	}
559*4882a593Smuzhiyun #else
560*4882a593Smuzhiyun 	pcodec_info->i2c_bus = AUDIO_I2C_BUS;
561*4882a593Smuzhiyun 	pcodec_info->i2c_dev_addr = AUDIO_I2C_REG;
562*4882a593Smuzhiyun 	debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr);
563*4882a593Smuzhiyun #endif
564*4882a593Smuzhiyun 	pcodec_info->codec_type = CODEC_MAX_98095;
565*4882a593Smuzhiyun 	if (error == -1) {
566*4882a593Smuzhiyun 		debug("fail to get max98095 codec node properties\n");
567*4882a593Smuzhiyun 		return -1;
568*4882a593Smuzhiyun 	}
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 	return 0;
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun /* max98095 Device Initialisation */
max98095_init(const void * blob,enum en_max_audio_interface aif_id,int sampling_rate,int mclk_freq,int bits_per_sample)574*4882a593Smuzhiyun int max98095_init(const void *blob, enum en_max_audio_interface aif_id,
575*4882a593Smuzhiyun 		  int sampling_rate, int mclk_freq,
576*4882a593Smuzhiyun 		  int bits_per_sample)
577*4882a593Smuzhiyun {
578*4882a593Smuzhiyun 	int ret;
579*4882a593Smuzhiyun 	int old_bus = i2c_get_bus_num();
580*4882a593Smuzhiyun 	struct sound_codec_info *pcodec_info = &g_codec_info;
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun 	if (get_max98095_codec_values(pcodec_info, blob) < 0) {
583*4882a593Smuzhiyun 		debug("FDT Codec values failed\n");
584*4882a593Smuzhiyun 		return -1;
585*4882a593Smuzhiyun 	}
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun 	i2c_set_bus_num(pcodec_info->i2c_bus);
588*4882a593Smuzhiyun 	ret = max98095_do_init(pcodec_info, aif_id, sampling_rate, mclk_freq,
589*4882a593Smuzhiyun 			       bits_per_sample);
590*4882a593Smuzhiyun 	i2c_set_bus_num(old_bus);
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun 	return ret;
593*4882a593Smuzhiyun }
594