xref: /rk3399_rockchip-uboot/drivers/sound/max98095.c (revision 150c5afe5bafa90e4fe398e59af32ad3cdbfe5b7)
15febe8dbSRajeshwari Shinde /*
25febe8dbSRajeshwari Shinde  * max98095.c -- MAX98095 ALSA SoC Audio driver
35febe8dbSRajeshwari Shinde  *
45febe8dbSRajeshwari Shinde  * Copyright 2011 Maxim Integrated Products
55febe8dbSRajeshwari Shinde  *
65febe8dbSRajeshwari Shinde  * Modified for uboot by R. Chandrasekar (rcsekar@samsung.com)
75febe8dbSRajeshwari Shinde  *
85febe8dbSRajeshwari Shinde  * This program is free software; you can redistribute it and/or modify
95febe8dbSRajeshwari Shinde  * it under the terms of the GNU General Public License version 2 as
105febe8dbSRajeshwari Shinde  * published by the Free Software Foundation.
115febe8dbSRajeshwari Shinde  */
12*150c5afeSSimon Glass 
13*150c5afeSSimon Glass #include <common.h>
145febe8dbSRajeshwari Shinde #include <asm/arch/clk.h>
155febe8dbSRajeshwari Shinde #include <asm/arch/cpu.h>
165febe8dbSRajeshwari Shinde #include <asm/arch/power.h>
175febe8dbSRajeshwari Shinde #include <asm/gpio.h>
185febe8dbSRajeshwari Shinde #include <asm/io.h>
195febe8dbSRajeshwari Shinde #include <common.h>
205febe8dbSRajeshwari Shinde #include <div64.h>
215febe8dbSRajeshwari Shinde #include <fdtdec.h>
225febe8dbSRajeshwari Shinde #include <i2c.h>
235febe8dbSRajeshwari Shinde #include <sound.h>
245febe8dbSRajeshwari Shinde #include "i2s.h"
255febe8dbSRajeshwari Shinde #include "max98095.h"
265febe8dbSRajeshwari Shinde 
275febe8dbSRajeshwari Shinde enum max98095_type {
285febe8dbSRajeshwari Shinde 	MAX98095,
295febe8dbSRajeshwari Shinde };
305febe8dbSRajeshwari Shinde 
315febe8dbSRajeshwari Shinde struct max98095_priv {
325febe8dbSRajeshwari Shinde 	enum max98095_type devtype;
335febe8dbSRajeshwari Shinde 	unsigned int sysclk;
345febe8dbSRajeshwari Shinde 	unsigned int rate;
355febe8dbSRajeshwari Shinde 	unsigned int fmt;
365febe8dbSRajeshwari Shinde };
375febe8dbSRajeshwari Shinde 
385febe8dbSRajeshwari Shinde static struct sound_codec_info g_codec_info;
395febe8dbSRajeshwari Shinde struct max98095_priv g_max98095_info;
405febe8dbSRajeshwari Shinde unsigned int g_max98095_i2c_dev_addr;
415febe8dbSRajeshwari Shinde 
425febe8dbSRajeshwari Shinde /* Index 0 is reserved. */
435febe8dbSRajeshwari Shinde int rate_table[] = {0, 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000,
445febe8dbSRajeshwari Shinde 		88200, 96000};
455febe8dbSRajeshwari Shinde 
465febe8dbSRajeshwari Shinde /*
475febe8dbSRajeshwari Shinde  * Writes value to a device register through i2c
485febe8dbSRajeshwari Shinde  *
495febe8dbSRajeshwari Shinde  * @param reg	reg number to be write
505febe8dbSRajeshwari Shinde  * @param data	data to be writen to the above registor
515febe8dbSRajeshwari Shinde  *
525febe8dbSRajeshwari Shinde  * @return	int value 1 for change, 0 for no change or negative error code.
535febe8dbSRajeshwari Shinde  */
max98095_i2c_write(unsigned int reg,unsigned char data)545febe8dbSRajeshwari Shinde static int max98095_i2c_write(unsigned int reg, unsigned char data)
555febe8dbSRajeshwari Shinde {
565febe8dbSRajeshwari Shinde 	debug("%s: Write Addr : 0x%02X, Data :  0x%02X\n",
575febe8dbSRajeshwari Shinde 	      __func__, reg, data);
585febe8dbSRajeshwari Shinde 	return i2c_write(g_max98095_i2c_dev_addr, reg, 1, &data, 1);
595febe8dbSRajeshwari Shinde }
605febe8dbSRajeshwari Shinde 
615febe8dbSRajeshwari Shinde /*
625febe8dbSRajeshwari Shinde  * Read a value from a device register through i2c
635febe8dbSRajeshwari Shinde  *
645febe8dbSRajeshwari Shinde  * @param reg	reg number to be read
655febe8dbSRajeshwari Shinde  * @param data	address of read data to be stored
665febe8dbSRajeshwari Shinde  *
675febe8dbSRajeshwari Shinde  * @return	int value 0 for success, -1 in case of error.
685febe8dbSRajeshwari Shinde  */
max98095_i2c_read(unsigned int reg,unsigned char * data)695febe8dbSRajeshwari Shinde static unsigned int max98095_i2c_read(unsigned int reg, unsigned char *data)
705febe8dbSRajeshwari Shinde {
715febe8dbSRajeshwari Shinde 	int ret;
725febe8dbSRajeshwari Shinde 
735febe8dbSRajeshwari Shinde 	ret = i2c_read(g_max98095_i2c_dev_addr, reg, 1, data, 1);
745febe8dbSRajeshwari Shinde 	if (ret != 0) {
755febe8dbSRajeshwari Shinde 		debug("%s: Error while reading register %#04x\n",
765febe8dbSRajeshwari Shinde 		      __func__, reg);
775febe8dbSRajeshwari Shinde 		return -1;
785febe8dbSRajeshwari Shinde 	}
795febe8dbSRajeshwari Shinde 
805febe8dbSRajeshwari Shinde 	return 0;
815febe8dbSRajeshwari Shinde }
825febe8dbSRajeshwari Shinde 
835febe8dbSRajeshwari Shinde /*
845febe8dbSRajeshwari Shinde  * update device register bits through i2c
855febe8dbSRajeshwari Shinde  *
865febe8dbSRajeshwari Shinde  * @param reg	codec register
875febe8dbSRajeshwari Shinde  * @param mask	register mask
885febe8dbSRajeshwari Shinde  * @param value	new value
895febe8dbSRajeshwari Shinde  *
905febe8dbSRajeshwari Shinde  * @return int value 0 for success, non-zero error code.
915febe8dbSRajeshwari Shinde  */
max98095_update_bits(unsigned int reg,unsigned char mask,unsigned char value)925febe8dbSRajeshwari Shinde static int max98095_update_bits(unsigned int reg, unsigned char mask,
935febe8dbSRajeshwari Shinde 				unsigned char value)
945febe8dbSRajeshwari Shinde {
955febe8dbSRajeshwari Shinde 	int change, ret = 0;
965febe8dbSRajeshwari Shinde 	unsigned char old, new;
975febe8dbSRajeshwari Shinde 
985febe8dbSRajeshwari Shinde 	if (max98095_i2c_read(reg, &old) != 0)
995febe8dbSRajeshwari Shinde 		return -1;
1005febe8dbSRajeshwari Shinde 	new = (old & ~mask) | (value & mask);
1015febe8dbSRajeshwari Shinde 	change  = (old != new) ? 1 : 0;
1025febe8dbSRajeshwari Shinde 	if (change)
1035febe8dbSRajeshwari Shinde 		ret = max98095_i2c_write(reg, new);
1045febe8dbSRajeshwari Shinde 	if (ret < 0)
1055febe8dbSRajeshwari Shinde 		return ret;
1065febe8dbSRajeshwari Shinde 
1075febe8dbSRajeshwari Shinde 	return change;
1085febe8dbSRajeshwari Shinde }
1095febe8dbSRajeshwari Shinde 
1105febe8dbSRajeshwari Shinde /*
1115febe8dbSRajeshwari Shinde  * codec mclk clock divider coefficients based on sampling rate
1125febe8dbSRajeshwari Shinde  *
1135febe8dbSRajeshwari Shinde  * @param rate sampling rate
1145febe8dbSRajeshwari Shinde  * @param value address of indexvalue to be stored
1155febe8dbSRajeshwari Shinde  *
1165febe8dbSRajeshwari Shinde  * @return	0 for success or negative error code.
1175febe8dbSRajeshwari Shinde  */
rate_value(int rate,u8 * value)1185febe8dbSRajeshwari Shinde static int rate_value(int rate, u8 *value)
1195febe8dbSRajeshwari Shinde {
1205febe8dbSRajeshwari Shinde 	int i;
1215febe8dbSRajeshwari Shinde 
1225febe8dbSRajeshwari Shinde 	for (i = 1; i < ARRAY_SIZE(rate_table); i++) {
1235febe8dbSRajeshwari Shinde 		if (rate_table[i] >= rate) {
1245febe8dbSRajeshwari Shinde 			*value = i;
1255febe8dbSRajeshwari Shinde 			return 0;
1265febe8dbSRajeshwari Shinde 		}
1275febe8dbSRajeshwari Shinde 	}
1285febe8dbSRajeshwari Shinde 	*value = 1;
1295febe8dbSRajeshwari Shinde 
1305febe8dbSRajeshwari Shinde 	return -1;
1315febe8dbSRajeshwari Shinde }
1325febe8dbSRajeshwari Shinde 
1335febe8dbSRajeshwari Shinde /*
1345febe8dbSRajeshwari Shinde  * Sets hw params for max98095
1355febe8dbSRajeshwari Shinde  *
1365febe8dbSRajeshwari Shinde  * @param max98095	max98095 information pointer
1375febe8dbSRajeshwari Shinde  * @param rate		Sampling rate
1385febe8dbSRajeshwari Shinde  * @param bits_per_sample	Bits per sample
1395febe8dbSRajeshwari Shinde  *
1405febe8dbSRajeshwari Shinde  * @return -1 for error  and 0  Success.
1415febe8dbSRajeshwari Shinde  */
max98095_hw_params(struct max98095_priv * max98095,enum en_max_audio_interface aif_id,unsigned int rate,unsigned int bits_per_sample)1425febe8dbSRajeshwari Shinde static int max98095_hw_params(struct max98095_priv *max98095,
1436b40852dSDani Krishna Mohan 			      enum en_max_audio_interface aif_id,
1445febe8dbSRajeshwari Shinde 			      unsigned int rate, unsigned int bits_per_sample)
1455febe8dbSRajeshwari Shinde {
1465febe8dbSRajeshwari Shinde 	u8 regval;
1475febe8dbSRajeshwari Shinde 	int error;
1486b40852dSDani Krishna Mohan 	unsigned short M98095_DAI_CLKMODE;
1496b40852dSDani Krishna Mohan 	unsigned short M98095_DAI_FORMAT;
1506b40852dSDani Krishna Mohan 	unsigned short M98095_DAI_FILTERS;
1516b40852dSDani Krishna Mohan 
1526b40852dSDani Krishna Mohan 	if (aif_id == AIF1) {
1536b40852dSDani Krishna Mohan 		M98095_DAI_CLKMODE = M98095_027_DAI1_CLKMODE;
1546b40852dSDani Krishna Mohan 		M98095_DAI_FORMAT = M98095_02A_DAI1_FORMAT;
1556b40852dSDani Krishna Mohan 		M98095_DAI_FILTERS = M98095_02E_DAI1_FILTERS;
1566b40852dSDani Krishna Mohan 	} else {
1576b40852dSDani Krishna Mohan 		M98095_DAI_CLKMODE = M98095_031_DAI2_CLKMODE;
1586b40852dSDani Krishna Mohan 		M98095_DAI_FORMAT = M98095_034_DAI2_FORMAT;
1596b40852dSDani Krishna Mohan 		M98095_DAI_FILTERS = M98095_038_DAI2_FILTERS;
1606b40852dSDani Krishna Mohan 	}
1615febe8dbSRajeshwari Shinde 
1625febe8dbSRajeshwari Shinde 	switch (bits_per_sample) {
1635febe8dbSRajeshwari Shinde 	case 16:
1646b40852dSDani Krishna Mohan 		error = max98095_update_bits(M98095_DAI_FORMAT,
1655febe8dbSRajeshwari Shinde 					     M98095_DAI_WS, 0);
1665febe8dbSRajeshwari Shinde 		break;
1675febe8dbSRajeshwari Shinde 	case 24:
1686b40852dSDani Krishna Mohan 		error = max98095_update_bits(M98095_DAI_FORMAT,
1695febe8dbSRajeshwari Shinde 					     M98095_DAI_WS, M98095_DAI_WS);
1705febe8dbSRajeshwari Shinde 		break;
1715febe8dbSRajeshwari Shinde 	default:
1725febe8dbSRajeshwari Shinde 		debug("%s: Illegal bits per sample %d.\n",
1735febe8dbSRajeshwari Shinde 		      __func__, bits_per_sample);
1745febe8dbSRajeshwari Shinde 		return -1;
1755febe8dbSRajeshwari Shinde 	}
1765febe8dbSRajeshwari Shinde 
1775febe8dbSRajeshwari Shinde 	if (rate_value(rate, &regval)) {
1785febe8dbSRajeshwari Shinde 		debug("%s: Failed to set sample rate to %d.\n",
1795febe8dbSRajeshwari Shinde 		      __func__, rate);
1805febe8dbSRajeshwari Shinde 		return -1;
1815febe8dbSRajeshwari Shinde 	}
1825febe8dbSRajeshwari Shinde 	max98095->rate = rate;
1835febe8dbSRajeshwari Shinde 
1846b40852dSDani Krishna Mohan 	error |= max98095_update_bits(M98095_DAI_CLKMODE,
1855febe8dbSRajeshwari Shinde 				      M98095_CLKMODE_MASK, regval);
1865febe8dbSRajeshwari Shinde 
1875febe8dbSRajeshwari Shinde 	/* Update sample rate mode */
1885febe8dbSRajeshwari Shinde 	if (rate < 50000)
1896b40852dSDani Krishna Mohan 		error |= max98095_update_bits(M98095_DAI_FILTERS,
1905febe8dbSRajeshwari Shinde 					      M98095_DAI_DHF, 0);
1915febe8dbSRajeshwari Shinde 	else
1926b40852dSDani Krishna Mohan 		error |= max98095_update_bits(M98095_DAI_FILTERS,
1935febe8dbSRajeshwari Shinde 					      M98095_DAI_DHF, M98095_DAI_DHF);
1945febe8dbSRajeshwari Shinde 
1955febe8dbSRajeshwari Shinde 	if (error < 0) {
1965febe8dbSRajeshwari Shinde 		debug("%s: Error setting hardware params.\n", __func__);
1975febe8dbSRajeshwari Shinde 		return -1;
1985febe8dbSRajeshwari Shinde 	}
1995febe8dbSRajeshwari Shinde 
2005febe8dbSRajeshwari Shinde 	return 0;
2015febe8dbSRajeshwari Shinde }
2025febe8dbSRajeshwari Shinde 
2035febe8dbSRajeshwari Shinde /*
2045febe8dbSRajeshwari Shinde  * Configures Audio interface system clock for the given frequency
2055febe8dbSRajeshwari Shinde  *
2065febe8dbSRajeshwari Shinde  * @param max98095	max98095 information
2075febe8dbSRajeshwari Shinde  * @param freq		Sampling frequency in Hz
2085febe8dbSRajeshwari Shinde  *
2095febe8dbSRajeshwari Shinde  * @return -1 for error and 0 success.
2105febe8dbSRajeshwari Shinde  */
max98095_set_sysclk(struct max98095_priv * max98095,unsigned int freq)2115febe8dbSRajeshwari Shinde static int max98095_set_sysclk(struct max98095_priv *max98095,
2125febe8dbSRajeshwari Shinde 			       unsigned int freq)
2135febe8dbSRajeshwari Shinde {
2145febe8dbSRajeshwari Shinde 	int error = 0;
2155febe8dbSRajeshwari Shinde 
2165febe8dbSRajeshwari Shinde 	/* Requested clock frequency is already setup */
2175febe8dbSRajeshwari Shinde 	if (freq == max98095->sysclk)
2185febe8dbSRajeshwari Shinde 		return 0;
2195febe8dbSRajeshwari Shinde 
2205febe8dbSRajeshwari Shinde 	/* Setup clocks for slave mode, and using the PLL
2215febe8dbSRajeshwari Shinde 	 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
2225febe8dbSRajeshwari Shinde 	 *	0x02 (when master clk is 20MHz to 40MHz)..
2235febe8dbSRajeshwari Shinde 	 *	0x03 (when master clk is 40MHz to 60MHz)..
2245febe8dbSRajeshwari Shinde 	 */
2255febe8dbSRajeshwari Shinde 	if ((freq >= 10000000) && (freq < 20000000)) {
2265febe8dbSRajeshwari Shinde 		error = max98095_i2c_write(M98095_026_SYS_CLK, 0x10);
2275febe8dbSRajeshwari Shinde 	} else if ((freq >= 20000000) && (freq < 40000000)) {
2285febe8dbSRajeshwari Shinde 		error = max98095_i2c_write(M98095_026_SYS_CLK, 0x20);
2295febe8dbSRajeshwari Shinde 	} else if ((freq >= 40000000) && (freq < 60000000)) {
2305febe8dbSRajeshwari Shinde 		error = max98095_i2c_write(M98095_026_SYS_CLK, 0x30);
2315febe8dbSRajeshwari Shinde 	} else {
2325febe8dbSRajeshwari Shinde 		debug("%s: Invalid master clock frequency\n", __func__);
2335febe8dbSRajeshwari Shinde 		return -1;
2345febe8dbSRajeshwari Shinde 	}
2355febe8dbSRajeshwari Shinde 
2365febe8dbSRajeshwari Shinde 	debug("%s: Clock at %uHz\n", __func__, freq);
2375febe8dbSRajeshwari Shinde 
2385febe8dbSRajeshwari Shinde 	if (error < 0)
2395febe8dbSRajeshwari Shinde 		return -1;
2405febe8dbSRajeshwari Shinde 
2415febe8dbSRajeshwari Shinde 	max98095->sysclk = freq;
2425febe8dbSRajeshwari Shinde 	return 0;
2435febe8dbSRajeshwari Shinde }
2445febe8dbSRajeshwari Shinde 
2455febe8dbSRajeshwari Shinde /*
2465febe8dbSRajeshwari Shinde  * Sets Max98095 I2S format
2475febe8dbSRajeshwari Shinde  *
2485febe8dbSRajeshwari Shinde  * @param max98095	max98095 information
2495febe8dbSRajeshwari Shinde  * @param fmt		i2S format - supports a subset of the options defined
2505febe8dbSRajeshwari Shinde  *			in i2s.h.
2515febe8dbSRajeshwari Shinde  *
2525febe8dbSRajeshwari Shinde  * @return -1 for error and 0  Success.
2535febe8dbSRajeshwari Shinde  */
max98095_set_fmt(struct max98095_priv * max98095,int fmt,enum en_max_audio_interface aif_id)2546b40852dSDani Krishna Mohan static int max98095_set_fmt(struct max98095_priv *max98095, int fmt,
2556b40852dSDani Krishna Mohan 			    enum en_max_audio_interface aif_id)
2565febe8dbSRajeshwari Shinde {
2575febe8dbSRajeshwari Shinde 	u8 regval = 0;
2585febe8dbSRajeshwari Shinde 	int error = 0;
2596b40852dSDani Krishna Mohan 	unsigned short M98095_DAI_CLKCFG_HI;
2606b40852dSDani Krishna Mohan 	unsigned short M98095_DAI_CLKCFG_LO;
2616b40852dSDani Krishna Mohan 	unsigned short M98095_DAI_FORMAT;
2626b40852dSDani Krishna Mohan 	unsigned short M98095_DAI_CLOCK;
2635febe8dbSRajeshwari Shinde 
2645febe8dbSRajeshwari Shinde 	if (fmt == max98095->fmt)
2655febe8dbSRajeshwari Shinde 		return 0;
2665febe8dbSRajeshwari Shinde 
2675febe8dbSRajeshwari Shinde 	max98095->fmt = fmt;
2685febe8dbSRajeshwari Shinde 
2696b40852dSDani Krishna Mohan 	if (aif_id == AIF1) {
2706b40852dSDani Krishna Mohan 		M98095_DAI_CLKCFG_HI = M98095_028_DAI1_CLKCFG_HI;
2716b40852dSDani Krishna Mohan 		M98095_DAI_CLKCFG_LO = M98095_029_DAI1_CLKCFG_LO;
2726b40852dSDani Krishna Mohan 		M98095_DAI_FORMAT = M98095_02A_DAI1_FORMAT;
2736b40852dSDani Krishna Mohan 		M98095_DAI_CLOCK = M98095_02B_DAI1_CLOCK;
2746b40852dSDani Krishna Mohan 	} else {
2756b40852dSDani Krishna Mohan 		M98095_DAI_CLKCFG_HI = M98095_032_DAI2_CLKCFG_HI;
2766b40852dSDani Krishna Mohan 		M98095_DAI_CLKCFG_LO = M98095_033_DAI2_CLKCFG_LO;
2776b40852dSDani Krishna Mohan 		M98095_DAI_FORMAT = M98095_034_DAI2_FORMAT;
2786b40852dSDani Krishna Mohan 		M98095_DAI_CLOCK = M98095_035_DAI2_CLOCK;
2796b40852dSDani Krishna Mohan 	}
2806b40852dSDani Krishna Mohan 
2815febe8dbSRajeshwari Shinde 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2825febe8dbSRajeshwari Shinde 	case SND_SOC_DAIFMT_CBS_CFS:
2835febe8dbSRajeshwari Shinde 		/* Slave mode PLL */
2846b40852dSDani Krishna Mohan 		error |= max98095_i2c_write(M98095_DAI_CLKCFG_HI,
2855febe8dbSRajeshwari Shinde 					0x80);
2866b40852dSDani Krishna Mohan 		error |= max98095_i2c_write(M98095_DAI_CLKCFG_LO,
2875febe8dbSRajeshwari Shinde 					0x00);
2885febe8dbSRajeshwari Shinde 		break;
2895febe8dbSRajeshwari Shinde 	case SND_SOC_DAIFMT_CBM_CFM:
2905febe8dbSRajeshwari Shinde 		/* Set to master mode */
2915febe8dbSRajeshwari Shinde 		regval |= M98095_DAI_MAS;
2925febe8dbSRajeshwari Shinde 		break;
2935febe8dbSRajeshwari Shinde 	case SND_SOC_DAIFMT_CBS_CFM:
2945febe8dbSRajeshwari Shinde 	case SND_SOC_DAIFMT_CBM_CFS:
2955febe8dbSRajeshwari Shinde 	default:
2965febe8dbSRajeshwari Shinde 		debug("%s: Clock mode unsupported\n", __func__);
2975febe8dbSRajeshwari Shinde 		return -1;
2985febe8dbSRajeshwari Shinde 	}
2995febe8dbSRajeshwari Shinde 
3005febe8dbSRajeshwari Shinde 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3015febe8dbSRajeshwari Shinde 	case SND_SOC_DAIFMT_I2S:
3025febe8dbSRajeshwari Shinde 		regval |= M98095_DAI_DLY;
3035febe8dbSRajeshwari Shinde 		break;
3045febe8dbSRajeshwari Shinde 	case SND_SOC_DAIFMT_LEFT_J:
3055febe8dbSRajeshwari Shinde 		break;
3065febe8dbSRajeshwari Shinde 	default:
3075febe8dbSRajeshwari Shinde 		debug("%s: Unrecognized format.\n", __func__);
3085febe8dbSRajeshwari Shinde 		return -1;
3095febe8dbSRajeshwari Shinde 	}
3105febe8dbSRajeshwari Shinde 
3115febe8dbSRajeshwari Shinde 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3125febe8dbSRajeshwari Shinde 	case SND_SOC_DAIFMT_NB_NF:
3135febe8dbSRajeshwari Shinde 		break;
3145febe8dbSRajeshwari Shinde 	case SND_SOC_DAIFMT_NB_IF:
3155febe8dbSRajeshwari Shinde 		regval |= M98095_DAI_WCI;
3165febe8dbSRajeshwari Shinde 		break;
3175febe8dbSRajeshwari Shinde 	case SND_SOC_DAIFMT_IB_NF:
3185febe8dbSRajeshwari Shinde 		regval |= M98095_DAI_BCI;
3195febe8dbSRajeshwari Shinde 		break;
3205febe8dbSRajeshwari Shinde 	case SND_SOC_DAIFMT_IB_IF:
3215febe8dbSRajeshwari Shinde 		regval |= M98095_DAI_BCI | M98095_DAI_WCI;
3225febe8dbSRajeshwari Shinde 		break;
3235febe8dbSRajeshwari Shinde 	default:
3245febe8dbSRajeshwari Shinde 		debug("%s: Unrecognized inversion settings.\n", __func__);
3255febe8dbSRajeshwari Shinde 		return -1;
3265febe8dbSRajeshwari Shinde 	}
3275febe8dbSRajeshwari Shinde 
3286b40852dSDani Krishna Mohan 	error |= max98095_update_bits(M98095_DAI_FORMAT,
3296b40852dSDani Krishna Mohan 				      M98095_DAI_MAS | M98095_DAI_DLY |
3306b40852dSDani Krishna Mohan 				      M98095_DAI_BCI | M98095_DAI_WCI,
3316b40852dSDani Krishna Mohan 				      regval);
3325febe8dbSRajeshwari Shinde 
3336b40852dSDani Krishna Mohan 	error |= max98095_i2c_write(M98095_DAI_CLOCK,
3345febe8dbSRajeshwari Shinde 				    M98095_DAI_BSEL64);
3355febe8dbSRajeshwari Shinde 
3365febe8dbSRajeshwari Shinde 	if (error < 0) {
3375febe8dbSRajeshwari Shinde 		debug("%s: Error setting i2s format.\n", __func__);
3385febe8dbSRajeshwari Shinde 		return -1;
3395febe8dbSRajeshwari Shinde 	}
3405febe8dbSRajeshwari Shinde 
3415febe8dbSRajeshwari Shinde 	return 0;
3425febe8dbSRajeshwari Shinde }
3435febe8dbSRajeshwari Shinde 
3445febe8dbSRajeshwari Shinde /*
3455febe8dbSRajeshwari Shinde  * resets the audio codec
3465febe8dbSRajeshwari Shinde  *
3475febe8dbSRajeshwari Shinde  * @return -1 for error and 0 success.
3485febe8dbSRajeshwari Shinde  */
max98095_reset(void)3495febe8dbSRajeshwari Shinde static int max98095_reset(void)
3505febe8dbSRajeshwari Shinde {
3515febe8dbSRajeshwari Shinde 	int i, ret;
3525febe8dbSRajeshwari Shinde 
3535febe8dbSRajeshwari Shinde 	/*
3545febe8dbSRajeshwari Shinde 	 * Gracefully reset the DSP core and the codec hardware in a proper
3555febe8dbSRajeshwari Shinde 	 * sequence.
3565febe8dbSRajeshwari Shinde 	 */
3575febe8dbSRajeshwari Shinde 	ret = max98095_i2c_write(M98095_00F_HOST_CFG, 0);
3585febe8dbSRajeshwari Shinde 	if (ret != 0) {
3595febe8dbSRajeshwari Shinde 		debug("%s: Failed to reset DSP: %d\n", __func__, ret);
3605febe8dbSRajeshwari Shinde 		return ret;
3615febe8dbSRajeshwari Shinde 	}
3625febe8dbSRajeshwari Shinde 
3635febe8dbSRajeshwari Shinde 	ret = max98095_i2c_write(M98095_097_PWR_SYS, 0);
3645febe8dbSRajeshwari Shinde 	if (ret != 0) {
3655febe8dbSRajeshwari Shinde 		debug("%s: Failed to reset codec: %d\n", __func__, ret);
3665febe8dbSRajeshwari Shinde 		return ret;
3675febe8dbSRajeshwari Shinde 	}
3685febe8dbSRajeshwari Shinde 
3695febe8dbSRajeshwari Shinde 	/*
3705febe8dbSRajeshwari Shinde 	 * Reset to hardware default for registers, as there is not a soft
3715febe8dbSRajeshwari Shinde 	 * reset hardware control register.
3725febe8dbSRajeshwari Shinde 	 */
3735febe8dbSRajeshwari Shinde 	for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) {
3745febe8dbSRajeshwari Shinde 		ret = max98095_i2c_write(i, 0);
3755febe8dbSRajeshwari Shinde 		if (ret < 0) {
3765febe8dbSRajeshwari Shinde 			debug("%s: Failed to reset: %d\n", __func__, ret);
3775febe8dbSRajeshwari Shinde 			return ret;
3785febe8dbSRajeshwari Shinde 		}
3795febe8dbSRajeshwari Shinde 	}
3805febe8dbSRajeshwari Shinde 
3815febe8dbSRajeshwari Shinde 	return 0;
3825febe8dbSRajeshwari Shinde }
3835febe8dbSRajeshwari Shinde 
3845febe8dbSRajeshwari Shinde /*
3855febe8dbSRajeshwari Shinde  * Intialise max98095 codec device
3865febe8dbSRajeshwari Shinde  *
3875febe8dbSRajeshwari Shinde  * @param max98095	max98095 information
3885febe8dbSRajeshwari Shinde  *
3895febe8dbSRajeshwari Shinde  * @returns -1 for error  and 0 Success.
3905febe8dbSRajeshwari Shinde  */
max98095_device_init(struct max98095_priv * max98095,enum en_max_audio_interface aif_id)3916b40852dSDani Krishna Mohan static int max98095_device_init(struct max98095_priv *max98095,
3926b40852dSDani Krishna Mohan 				enum en_max_audio_interface aif_id)
3935febe8dbSRajeshwari Shinde {
3945febe8dbSRajeshwari Shinde 	unsigned char id;
3955febe8dbSRajeshwari Shinde 	int error = 0;
3965febe8dbSRajeshwari Shinde 
3975febe8dbSRajeshwari Shinde 	/* reset the codec, the DSP core, and disable all interrupts */
3985febe8dbSRajeshwari Shinde 	error = max98095_reset();
3995febe8dbSRajeshwari Shinde 	if (error != 0) {
4005febe8dbSRajeshwari Shinde 		debug("Reset\n");
4015febe8dbSRajeshwari Shinde 		return error;
4025febe8dbSRajeshwari Shinde 	}
4035febe8dbSRajeshwari Shinde 
4045febe8dbSRajeshwari Shinde 	/* initialize private data */
4055febe8dbSRajeshwari Shinde 	max98095->sysclk = -1U;
4065febe8dbSRajeshwari Shinde 	max98095->rate = -1U;
4075febe8dbSRajeshwari Shinde 	max98095->fmt = -1U;
4085febe8dbSRajeshwari Shinde 
4095febe8dbSRajeshwari Shinde 	error = max98095_i2c_read(M98095_0FF_REV_ID, &id);
4105febe8dbSRajeshwari Shinde 	if (error < 0) {
4115febe8dbSRajeshwari Shinde 		debug("%s: Failure reading hardware revision: %d\n",
4125febe8dbSRajeshwari Shinde 		      __func__, id);
4135febe8dbSRajeshwari Shinde 		goto err_access;
4145febe8dbSRajeshwari Shinde 	}
4155febe8dbSRajeshwari Shinde 	debug("%s: Hardware revision: %c\n", __func__, (id - 0x40) + 'A');
4165febe8dbSRajeshwari Shinde 
4175febe8dbSRajeshwari Shinde 	error |= max98095_i2c_write(M98095_097_PWR_SYS, M98095_PWRSV);
4185febe8dbSRajeshwari Shinde 
4195febe8dbSRajeshwari Shinde 	/*
4205febe8dbSRajeshwari Shinde 	 * initialize registers to hardware default configuring audio
4215febe8dbSRajeshwari Shinde 	 * interface2 to DAC
4225febe8dbSRajeshwari Shinde 	 */
4236b40852dSDani Krishna Mohan 	if (aif_id == AIF1)
4245febe8dbSRajeshwari Shinde 		error |= max98095_i2c_write(M98095_048_MIX_DAC_LR,
4256b40852dSDani Krishna Mohan 					    M98095_DAI1L_TO_DACL |
4266b40852dSDani Krishna Mohan 					    M98095_DAI1R_TO_DACR);
4276b40852dSDani Krishna Mohan 	else
4286b40852dSDani Krishna Mohan 		error |= max98095_i2c_write(M98095_048_MIX_DAC_LR,
4296b40852dSDani Krishna Mohan 					    M98095_DAI2M_TO_DACL |
4306b40852dSDani Krishna Mohan 					    M98095_DAI2M_TO_DACR);
4315febe8dbSRajeshwari Shinde 
4325febe8dbSRajeshwari Shinde 	error |= max98095_i2c_write(M98095_092_PWR_EN_OUT,
4335febe8dbSRajeshwari Shinde 				    M98095_SPK_SPREADSPECTRUM);
4345febe8dbSRajeshwari Shinde 	error |= max98095_i2c_write(M98095_04E_CFG_HP, M98095_HPNORMAL);
4356b40852dSDani Krishna Mohan 	if (aif_id == AIF1)
4365febe8dbSRajeshwari Shinde 		error |= max98095_i2c_write(M98095_02C_DAI1_IOCFG,
4375febe8dbSRajeshwari Shinde 					    M98095_S1NORMAL | M98095_SDATA);
4386b40852dSDani Krishna Mohan 	else
4395febe8dbSRajeshwari Shinde 		error |= max98095_i2c_write(M98095_036_DAI2_IOCFG,
4405febe8dbSRajeshwari Shinde 					    M98095_S2NORMAL | M98095_SDATA);
4415febe8dbSRajeshwari Shinde 
4425febe8dbSRajeshwari Shinde 	/* take the codec out of the shut down */
4435febe8dbSRajeshwari Shinde 	error |= max98095_update_bits(M98095_097_PWR_SYS, M98095_SHDNRUN,
4445febe8dbSRajeshwari Shinde 				      M98095_SHDNRUN);
4455febe8dbSRajeshwari Shinde 	/* route DACL and DACR output to HO and Spekers */
4465febe8dbSRajeshwari Shinde 	error |= max98095_i2c_write(M98095_050_MIX_SPK_LEFT, 0x01); /* DACL */
4475febe8dbSRajeshwari Shinde 	error |= max98095_i2c_write(M98095_051_MIX_SPK_RIGHT, 0x01);/* DACR */
4485febe8dbSRajeshwari Shinde 	error |= max98095_i2c_write(M98095_04C_MIX_HP_LEFT, 0x01);  /* DACL */
4495febe8dbSRajeshwari Shinde 	error |= max98095_i2c_write(M98095_04D_MIX_HP_RIGHT, 0x01); /* DACR */
4505febe8dbSRajeshwari Shinde 
4515febe8dbSRajeshwari Shinde 	/* power Enable */
4525febe8dbSRajeshwari Shinde 	error |= max98095_i2c_write(M98095_091_PWR_EN_OUT, 0xF3);
4535febe8dbSRajeshwari Shinde 
4545febe8dbSRajeshwari Shinde 	/* set Volume */
4555febe8dbSRajeshwari Shinde 	error |= max98095_i2c_write(M98095_064_LVL_HP_L, 15);
4565febe8dbSRajeshwari Shinde 	error |= max98095_i2c_write(M98095_065_LVL_HP_R, 15);
4575febe8dbSRajeshwari Shinde 	error |= max98095_i2c_write(M98095_067_LVL_SPK_L, 16);
4585febe8dbSRajeshwari Shinde 	error |= max98095_i2c_write(M98095_068_LVL_SPK_R, 16);
4595febe8dbSRajeshwari Shinde 
4605febe8dbSRajeshwari Shinde 	/* Enable DAIs */
4615febe8dbSRajeshwari Shinde 	error |= max98095_i2c_write(M98095_093_BIAS_CTRL, 0x30);
4626b40852dSDani Krishna Mohan 	if (aif_id == AIF1)
4636b40852dSDani Krishna Mohan 		error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x01);
4646b40852dSDani Krishna Mohan 	else
4655febe8dbSRajeshwari Shinde 		error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x07);
4665febe8dbSRajeshwari Shinde 
4675febe8dbSRajeshwari Shinde err_access:
4685febe8dbSRajeshwari Shinde 	if (error < 0)
4695febe8dbSRajeshwari Shinde 		return -1;
4705febe8dbSRajeshwari Shinde 
4715febe8dbSRajeshwari Shinde 	return 0;
4725febe8dbSRajeshwari Shinde }
4735febe8dbSRajeshwari Shinde 
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)4745febe8dbSRajeshwari Shinde static int max98095_do_init(struct sound_codec_info *pcodec_info,
4756b40852dSDani Krishna Mohan 			    enum en_max_audio_interface aif_id,
4765febe8dbSRajeshwari Shinde 			    int sampling_rate, int mclk_freq,
4775febe8dbSRajeshwari Shinde 			    int bits_per_sample)
4785febe8dbSRajeshwari Shinde {
4795febe8dbSRajeshwari Shinde 	int ret = 0;
4805febe8dbSRajeshwari Shinde 
4815febe8dbSRajeshwari Shinde 	/* Enable codec clock */
4825febe8dbSRajeshwari Shinde 	set_xclkout();
4835febe8dbSRajeshwari Shinde 
4845febe8dbSRajeshwari Shinde 	/* shift the device address by 1 for 7 bit addressing */
4855febe8dbSRajeshwari Shinde 	g_max98095_i2c_dev_addr = pcodec_info->i2c_dev_addr >> 1;
4865febe8dbSRajeshwari Shinde 
4876b40852dSDani Krishna Mohan 	if (pcodec_info->codec_type == CODEC_MAX_98095) {
4885febe8dbSRajeshwari Shinde 		g_max98095_info.devtype = MAX98095;
4896b40852dSDani Krishna Mohan 	} else {
4905febe8dbSRajeshwari Shinde 		debug("%s: Codec id [%d] not defined\n", __func__,
4915febe8dbSRajeshwari Shinde 		      pcodec_info->codec_type);
4925febe8dbSRajeshwari Shinde 		return -1;
4935febe8dbSRajeshwari Shinde 	}
4945febe8dbSRajeshwari Shinde 
4956b40852dSDani Krishna Mohan 	ret = max98095_device_init(&g_max98095_info, aif_id);
4965febe8dbSRajeshwari Shinde 	if (ret < 0) {
4975febe8dbSRajeshwari Shinde 		debug("%s: max98095 codec chip init failed\n", __func__);
4985febe8dbSRajeshwari Shinde 		return ret;
4995febe8dbSRajeshwari Shinde 	}
5005febe8dbSRajeshwari Shinde 
5015febe8dbSRajeshwari Shinde 	ret = max98095_set_sysclk(&g_max98095_info, mclk_freq);
5025febe8dbSRajeshwari Shinde 	if (ret < 0) {
5035febe8dbSRajeshwari Shinde 		debug("%s: max98095 codec set sys clock failed\n", __func__);
5045febe8dbSRajeshwari Shinde 		return ret;
5055febe8dbSRajeshwari Shinde 	}
5065febe8dbSRajeshwari Shinde 
5076b40852dSDani Krishna Mohan 	ret = max98095_hw_params(&g_max98095_info, aif_id, sampling_rate,
5085febe8dbSRajeshwari Shinde 				 bits_per_sample);
5095febe8dbSRajeshwari Shinde 
5105febe8dbSRajeshwari Shinde 	if (ret == 0) {
5115febe8dbSRajeshwari Shinde 		ret = max98095_set_fmt(&g_max98095_info,
5125febe8dbSRajeshwari Shinde 				       SND_SOC_DAIFMT_I2S |
5135febe8dbSRajeshwari Shinde 				       SND_SOC_DAIFMT_NB_NF |
5146b40852dSDani Krishna Mohan 				       SND_SOC_DAIFMT_CBS_CFS,
5156b40852dSDani Krishna Mohan 				       aif_id);
5165febe8dbSRajeshwari Shinde 	}
5175febe8dbSRajeshwari Shinde 
5185febe8dbSRajeshwari Shinde 	return ret;
5195febe8dbSRajeshwari Shinde }
5205febe8dbSRajeshwari Shinde 
get_max98095_codec_values(struct sound_codec_info * pcodec_info,const void * blob)5215febe8dbSRajeshwari Shinde static int get_max98095_codec_values(struct sound_codec_info *pcodec_info,
5225febe8dbSRajeshwari Shinde 				const void *blob)
5235febe8dbSRajeshwari Shinde {
5245febe8dbSRajeshwari Shinde 	int error = 0;
5250f925822SMasahiro Yamada #if CONFIG_IS_ENABLED(OF_CONTROL)
5265febe8dbSRajeshwari Shinde 	enum fdt_compat_id compat;
5275febe8dbSRajeshwari Shinde 	int node;
5285febe8dbSRajeshwari Shinde 	int parent;
5295febe8dbSRajeshwari Shinde 
5305febe8dbSRajeshwari Shinde 	/* Get the node from FDT for codec */
5315febe8dbSRajeshwari Shinde 	node = fdtdec_next_compatible(blob, 0, COMPAT_MAXIM_98095_CODEC);
5325febe8dbSRajeshwari Shinde 	if (node <= 0) {
5335febe8dbSRajeshwari Shinde 		debug("EXYNOS_SOUND: No node for codec in device tree\n");
5345febe8dbSRajeshwari Shinde 		debug("node = %d\n", node);
5355febe8dbSRajeshwari Shinde 		return -1;
5365febe8dbSRajeshwari Shinde 	}
5375febe8dbSRajeshwari Shinde 
5385febe8dbSRajeshwari Shinde 	parent = fdt_parent_offset(blob, node);
5395febe8dbSRajeshwari Shinde 	if (parent < 0) {
5405febe8dbSRajeshwari Shinde 		debug("%s: Cannot find node parent\n", __func__);
5415febe8dbSRajeshwari Shinde 		return -1;
5425febe8dbSRajeshwari Shinde 	}
5435febe8dbSRajeshwari Shinde 
5445febe8dbSRajeshwari Shinde 	compat = fdtdec_lookup(blob, parent);
5455febe8dbSRajeshwari Shinde 	switch (compat) {
5465febe8dbSRajeshwari Shinde 	case COMPAT_SAMSUNG_S3C2440_I2C:
5475febe8dbSRajeshwari Shinde 		pcodec_info->i2c_bus = i2c_get_bus_num_fdt(parent);
5485febe8dbSRajeshwari Shinde 		error |= pcodec_info->i2c_bus;
5495febe8dbSRajeshwari Shinde 		debug("i2c bus = %d\n", pcodec_info->i2c_bus);
5505febe8dbSRajeshwari Shinde 		pcodec_info->i2c_dev_addr = fdtdec_get_int(blob, node,
5515febe8dbSRajeshwari Shinde 							"reg", 0);
5525febe8dbSRajeshwari Shinde 		error |= pcodec_info->i2c_dev_addr;
5535febe8dbSRajeshwari Shinde 		debug("i2c dev addr = %x\n", pcodec_info->i2c_dev_addr);
5545febe8dbSRajeshwari Shinde 		break;
5555febe8dbSRajeshwari Shinde 	default:
5565febe8dbSRajeshwari Shinde 		debug("%s: Unknown compat id %d\n", __func__, compat);
5575febe8dbSRajeshwari Shinde 		return -1;
5585febe8dbSRajeshwari Shinde 	}
5595febe8dbSRajeshwari Shinde #else
5605febe8dbSRajeshwari Shinde 	pcodec_info->i2c_bus = AUDIO_I2C_BUS;
5615febe8dbSRajeshwari Shinde 	pcodec_info->i2c_dev_addr = AUDIO_I2C_REG;
5625febe8dbSRajeshwari Shinde 	debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr);
5635febe8dbSRajeshwari Shinde #endif
5645febe8dbSRajeshwari Shinde 	pcodec_info->codec_type = CODEC_MAX_98095;
5655febe8dbSRajeshwari Shinde 	if (error == -1) {
5665febe8dbSRajeshwari Shinde 		debug("fail to get max98095 codec node properties\n");
5675febe8dbSRajeshwari Shinde 		return -1;
5685febe8dbSRajeshwari Shinde 	}
5695febe8dbSRajeshwari Shinde 
5705febe8dbSRajeshwari Shinde 	return 0;
5715febe8dbSRajeshwari Shinde }
5725febe8dbSRajeshwari Shinde 
5735febe8dbSRajeshwari Shinde /* 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)5746b40852dSDani Krishna Mohan int max98095_init(const void *blob, enum en_max_audio_interface aif_id,
5756b40852dSDani Krishna Mohan 		  int sampling_rate, int mclk_freq,
5765febe8dbSRajeshwari Shinde 		  int bits_per_sample)
5775febe8dbSRajeshwari Shinde {
5785febe8dbSRajeshwari Shinde 	int ret;
5795febe8dbSRajeshwari Shinde 	int old_bus = i2c_get_bus_num();
5805febe8dbSRajeshwari Shinde 	struct sound_codec_info *pcodec_info = &g_codec_info;
5815febe8dbSRajeshwari Shinde 
5825febe8dbSRajeshwari Shinde 	if (get_max98095_codec_values(pcodec_info, blob) < 0) {
5835febe8dbSRajeshwari Shinde 		debug("FDT Codec values failed\n");
5845febe8dbSRajeshwari Shinde 		return -1;
5855febe8dbSRajeshwari Shinde 	}
5865febe8dbSRajeshwari Shinde 
5875febe8dbSRajeshwari Shinde 	i2c_set_bus_num(pcodec_info->i2c_bus);
5886b40852dSDani Krishna Mohan 	ret = max98095_do_init(pcodec_info, aif_id, sampling_rate, mclk_freq,
5895febe8dbSRajeshwari Shinde 			       bits_per_sample);
5905febe8dbSRajeshwari Shinde 	i2c_set_bus_num(old_bus);
5915febe8dbSRajeshwari Shinde 
5925febe8dbSRajeshwari Shinde 	return ret;
5935febe8dbSRajeshwari Shinde }
594