xref: /openbmc/linux/sound/soc/codecs/tlv320dac33.c (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
12b27bdccSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2c8bf93f0SPeter Ujfalusi /*
3c8bf93f0SPeter Ujfalusi  * ALSA SoC Texas Instruments TLV320DAC33 codec driver
4c8bf93f0SPeter Ujfalusi  *
593864cf0SPeter Ujfalusi  * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
6c8bf93f0SPeter Ujfalusi  *
7c8bf93f0SPeter Ujfalusi  * Copyright:   (C) 2009 Nokia Corporation
8c8bf93f0SPeter Ujfalusi  */
9c8bf93f0SPeter Ujfalusi 
10c8bf93f0SPeter Ujfalusi #include <linux/module.h>
11c8bf93f0SPeter Ujfalusi #include <linux/moduleparam.h>
12c8bf93f0SPeter Ujfalusi #include <linux/init.h>
13c8bf93f0SPeter Ujfalusi #include <linux/delay.h>
14c8bf93f0SPeter Ujfalusi #include <linux/pm.h>
15c8bf93f0SPeter Ujfalusi #include <linux/i2c.h>
16c8bf93f0SPeter Ujfalusi #include <linux/interrupt.h>
17c8bf93f0SPeter Ujfalusi #include <linux/gpio.h>
183a7aaed7SIlkka Koskinen #include <linux/regulator/consumer.h>
195a0e3ad6STejun Heo #include <linux/slab.h>
20c8bf93f0SPeter Ujfalusi #include <sound/core.h>
21c8bf93f0SPeter Ujfalusi #include <sound/pcm.h>
22c8bf93f0SPeter Ujfalusi #include <sound/pcm_params.h>
23c8bf93f0SPeter Ujfalusi #include <sound/soc.h>
24c8bf93f0SPeter Ujfalusi #include <sound/initval.h>
25c8bf93f0SPeter Ujfalusi #include <sound/tlv.h>
26c8bf93f0SPeter Ujfalusi 
27c8bf93f0SPeter Ujfalusi #include <sound/tlv320dac33-plat.h>
28c8bf93f0SPeter Ujfalusi #include "tlv320dac33.h"
29c8bf93f0SPeter Ujfalusi 
30549675edSPeter Ujfalusi /*
31549675edSPeter Ujfalusi  * The internal FIFO is 24576 bytes long
32549675edSPeter Ujfalusi  * It can be configured to hold 16bit or 24bit samples
33549675edSPeter Ujfalusi  * In 16bit configuration the FIFO can hold 6144 stereo samples
34549675edSPeter Ujfalusi  * In 24bit configuration the FIFO can hold 4096 stereo samples
35549675edSPeter Ujfalusi  */
36549675edSPeter Ujfalusi #define DAC33_FIFO_SIZE_16BIT	6144
37549675edSPeter Ujfalusi #define DAC33_FIFO_SIZE_24BIT	4096
38549675edSPeter Ujfalusi #define DAC33_MODE7_MARGIN	10	/* Safety margin for FIFO in Mode7 */
394260393eSPeter Ujfalusi 
4076f47127SPeter Ujfalusi #define BURST_BASEFREQ_HZ	49152000
4176f47127SPeter Ujfalusi 
42f57d2cfaSPeter Ujfalusi #define SAMPLES_TO_US(rate, samples) \
43c29429f3SAxel Lin 	(1000000000 / (((rate) * 1000) / (samples)))
44f57d2cfaSPeter Ujfalusi 
45f57d2cfaSPeter Ujfalusi #define US_TO_SAMPLES(rate, us) \
46c29429f3SAxel Lin 	((rate) / (1000000 / ((us) < 1000000 ? (us) : 1000000)))
47f57d2cfaSPeter Ujfalusi 
48a577b318SPeter Ujfalusi #define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \
49c29429f3SAxel Lin 	(((samples)*5000) / (((burstrate)*5000) / ((burstrate) - (playrate))))
50a577b318SPeter Ujfalusi 
51e6968a17SMark Brown static void dac33_calculate_times(struct snd_pcm_substream *substream,
52cd21ac8cSKuninori Morimoto 				  struct snd_soc_component *component);
53e6968a17SMark Brown static int dac33_prepare_chip(struct snd_pcm_substream *substream,
54cd21ac8cSKuninori Morimoto 			      struct snd_soc_component *component);
55f57d2cfaSPeter Ujfalusi 
56c8bf93f0SPeter Ujfalusi enum dac33_state {
57c8bf93f0SPeter Ujfalusi 	DAC33_IDLE = 0,
58c8bf93f0SPeter Ujfalusi 	DAC33_PREFILL,
59c8bf93f0SPeter Ujfalusi 	DAC33_PLAYBACK,
60c8bf93f0SPeter Ujfalusi 	DAC33_FLUSH,
61c8bf93f0SPeter Ujfalusi };
62c8bf93f0SPeter Ujfalusi 
637427b4b9SPeter Ujfalusi enum dac33_fifo_modes {
647427b4b9SPeter Ujfalusi 	DAC33_FIFO_BYPASS = 0,
657427b4b9SPeter Ujfalusi 	DAC33_FIFO_MODE1,
6628e05d98SPeter Ujfalusi 	DAC33_FIFO_MODE7,
677427b4b9SPeter Ujfalusi 	DAC33_FIFO_LAST_MODE,
687427b4b9SPeter Ujfalusi };
697427b4b9SPeter Ujfalusi 
703a7aaed7SIlkka Koskinen #define DAC33_NUM_SUPPLIES 3
713a7aaed7SIlkka Koskinen static const char *dac33_supply_names[DAC33_NUM_SUPPLIES] = {
723a7aaed7SIlkka Koskinen 	"AVDD",
733a7aaed7SIlkka Koskinen 	"DVDD",
743a7aaed7SIlkka Koskinen 	"IOVDD",
753a7aaed7SIlkka Koskinen };
763a7aaed7SIlkka Koskinen 
77c8bf93f0SPeter Ujfalusi struct tlv320dac33_priv {
78c8bf93f0SPeter Ujfalusi 	struct mutex mutex;
79c8bf93f0SPeter Ujfalusi 	struct work_struct work;
80cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component;
813a7aaed7SIlkka Koskinen 	struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
820b61d2b9SPeter Ujfalusi 	struct snd_pcm_substream *substream;
83c8bf93f0SPeter Ujfalusi 	int power_gpio;
84c8bf93f0SPeter Ujfalusi 	int chip_power;
85c8bf93f0SPeter Ujfalusi 	int irq;
86c8bf93f0SPeter Ujfalusi 	unsigned int refclk;
87c8bf93f0SPeter Ujfalusi 
88c8bf93f0SPeter Ujfalusi 	unsigned int alarm_threshold;	/* set to be half of LATENCY_TIME_MS */
897427b4b9SPeter Ujfalusi 	enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
90549675edSPeter Ujfalusi 	unsigned int fifo_size;		/* Size of the FIFO in samples */
91c8bf93f0SPeter Ujfalusi 	unsigned int nsample;		/* burst read amount from host */
92f430a27fSPeter Ujfalusi 	int mode1_latency;		/* latency caused by the i2c writes in
93f430a27fSPeter Ujfalusi 					 * us */
946aceabb4SPeter Ujfalusi 	u8 burst_bclkdiv;		/* BCLK divider value in burst mode */
95c4305af4SKuninori Morimoto 	u8 *reg_cache;
9676f47127SPeter Ujfalusi 	unsigned int burst_rate;	/* Interface speed in Burst modes */
97c8bf93f0SPeter Ujfalusi 
98eeb309a8SPeter Ujfalusi 	int keep_bclk;			/* Keep the BCLK continuously running
99eeb309a8SPeter Ujfalusi 					 * in FIFO modes */
100f57d2cfaSPeter Ujfalusi 	spinlock_t lock;
101f57d2cfaSPeter Ujfalusi 	unsigned long long t_stamp1;	/* Time stamp for FIFO modes to */
102f57d2cfaSPeter Ujfalusi 	unsigned long long t_stamp2;	/* calculate the FIFO caused delay */
103f57d2cfaSPeter Ujfalusi 
104f57d2cfaSPeter Ujfalusi 	unsigned int mode1_us_burst;	/* Time to burst read n number of
105f57d2cfaSPeter Ujfalusi 					 * samples */
106f57d2cfaSPeter Ujfalusi 	unsigned int mode7_us_to_lthr;	/* Time to reach lthr from uthr */
107c8bf93f0SPeter Ujfalusi 
1089d7db2b2SPeter Ujfalusi 	unsigned int uthr;
1099d7db2b2SPeter Ujfalusi 
110c8bf93f0SPeter Ujfalusi 	enum dac33_state state;
111ce9544dcSKuninori Morimoto 	struct i2c_client *i2c;
112c8bf93f0SPeter Ujfalusi };
113c8bf93f0SPeter Ujfalusi 
114c8bf93f0SPeter Ujfalusi static const u8 dac33_reg[DAC33_CACHEREGNUM] = {
115c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x00 - 0x03 */
116c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x04 - 0x07 */
117c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x08 - 0x0b */
118c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x0c - 0x0f */
119c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x10 - 0x13 */
120c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x14 - 0x17 */
121c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x18 - 0x1b */
122c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x1c - 0x1f */
123c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x20 - 0x23 */
124c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x24 - 0x27 */
125c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x28 - 0x2b */
126c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x80, /* 0x2c - 0x2f */
127c8bf93f0SPeter Ujfalusi 0x80, 0x00, 0x00, 0x00, /* 0x30 - 0x33 */
128c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x34 - 0x37 */
129c8bf93f0SPeter Ujfalusi 0x00, 0x00,             /* 0x38 - 0x39 */
130c8bf93f0SPeter Ujfalusi /* Registers 0x3a - 0x3f are reserved  */
131c8bf93f0SPeter Ujfalusi             0x00, 0x00, /* 0x3a - 0x3b */
132c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x3c - 0x3f */
133c8bf93f0SPeter Ujfalusi 
134c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x40 - 0x43 */
135c8bf93f0SPeter Ujfalusi 0x00, 0x80,             /* 0x44 - 0x45 */
136c8bf93f0SPeter Ujfalusi /* Registers 0x46 - 0x47 are reserved  */
137c8bf93f0SPeter Ujfalusi             0x80, 0x80, /* 0x46 - 0x47 */
138c8bf93f0SPeter Ujfalusi 
139c8bf93f0SPeter Ujfalusi 0x80, 0x00, 0x00,       /* 0x48 - 0x4a */
140c8bf93f0SPeter Ujfalusi /* Registers 0x4b - 0x7c are reserved  */
141c8bf93f0SPeter Ujfalusi                   0x00, /* 0x4b        */
142c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x4c - 0x4f */
143c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x50 - 0x53 */
144c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x54 - 0x57 */
145c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5b */
146c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x5c - 0x5f */
147c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x60 - 0x63 */
148c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x64 - 0x67 */
149c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x68 - 0x6b */
150c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x6c - 0x6f */
151c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x73 */
152c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x74 - 0x77 */
153c8bf93f0SPeter Ujfalusi 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7b */
154c8bf93f0SPeter Ujfalusi 0x00,                   /* 0x7c        */
155c8bf93f0SPeter Ujfalusi 
156c8bf93f0SPeter Ujfalusi       0xda, 0x33, 0x03, /* 0x7d - 0x7f */
157c8bf93f0SPeter Ujfalusi };
158c8bf93f0SPeter Ujfalusi 
159c8bf93f0SPeter Ujfalusi /* Register read and write */
dac33_read_reg_cache(struct snd_soc_component * component,unsigned reg)160cd21ac8cSKuninori Morimoto static inline unsigned int dac33_read_reg_cache(struct snd_soc_component *component,
161c8bf93f0SPeter Ujfalusi 						unsigned reg)
162c8bf93f0SPeter Ujfalusi {
163cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
164c4305af4SKuninori Morimoto 	u8 *cache = dac33->reg_cache;
165c8bf93f0SPeter Ujfalusi 	if (reg >= DAC33_CACHEREGNUM)
166c8bf93f0SPeter Ujfalusi 		return 0;
167c8bf93f0SPeter Ujfalusi 
168c8bf93f0SPeter Ujfalusi 	return cache[reg];
169c8bf93f0SPeter Ujfalusi }
170c8bf93f0SPeter Ujfalusi 
dac33_write_reg_cache(struct snd_soc_component * component,u8 reg,u8 value)171cd21ac8cSKuninori Morimoto static inline void dac33_write_reg_cache(struct snd_soc_component *component,
172c8bf93f0SPeter Ujfalusi 					 u8 reg, u8 value)
173c8bf93f0SPeter Ujfalusi {
174cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
175c4305af4SKuninori Morimoto 	u8 *cache = dac33->reg_cache;
176c8bf93f0SPeter Ujfalusi 	if (reg >= DAC33_CACHEREGNUM)
177c8bf93f0SPeter Ujfalusi 		return;
178c8bf93f0SPeter Ujfalusi 
179c8bf93f0SPeter Ujfalusi 	cache[reg] = value;
180c8bf93f0SPeter Ujfalusi }
181c8bf93f0SPeter Ujfalusi 
dac33_read(struct snd_soc_component * component,unsigned int reg,u8 * value)182cd21ac8cSKuninori Morimoto static int dac33_read(struct snd_soc_component *component, unsigned int reg,
183c8bf93f0SPeter Ujfalusi 		      u8 *value)
184c8bf93f0SPeter Ujfalusi {
185cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
186911a0f0bSPeter Ujfalusi 	int val, ret = 0;
187c8bf93f0SPeter Ujfalusi 
188c8bf93f0SPeter Ujfalusi 	*value = reg & 0xff;
189c8bf93f0SPeter Ujfalusi 
190c8bf93f0SPeter Ujfalusi 	/* If powered off, return the cached value */
191c8bf93f0SPeter Ujfalusi 	if (dac33->chip_power) {
192ce9544dcSKuninori Morimoto 		val = i2c_smbus_read_byte_data(dac33->i2c, value[0]);
193c8bf93f0SPeter Ujfalusi 		if (val < 0) {
194cd21ac8cSKuninori Morimoto 			dev_err(component->dev, "Read failed (%d)\n", val);
195cd21ac8cSKuninori Morimoto 			value[0] = dac33_read_reg_cache(component, reg);
196911a0f0bSPeter Ujfalusi 			ret = val;
197c8bf93f0SPeter Ujfalusi 		} else {
198c8bf93f0SPeter Ujfalusi 			value[0] = val;
199cd21ac8cSKuninori Morimoto 			dac33_write_reg_cache(component, reg, val);
200c8bf93f0SPeter Ujfalusi 		}
201c8bf93f0SPeter Ujfalusi 	} else {
202cd21ac8cSKuninori Morimoto 		value[0] = dac33_read_reg_cache(component, reg);
203c8bf93f0SPeter Ujfalusi 	}
204c8bf93f0SPeter Ujfalusi 
205911a0f0bSPeter Ujfalusi 	return ret;
206c8bf93f0SPeter Ujfalusi }
207c8bf93f0SPeter Ujfalusi 
dac33_write(struct snd_soc_component * component,unsigned int reg,unsigned int value)208cd21ac8cSKuninori Morimoto static int dac33_write(struct snd_soc_component *component, unsigned int reg,
209c8bf93f0SPeter Ujfalusi 		       unsigned int value)
210c8bf93f0SPeter Ujfalusi {
211cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
212c8bf93f0SPeter Ujfalusi 	u8 data[2];
213c8bf93f0SPeter Ujfalusi 	int ret = 0;
214c8bf93f0SPeter Ujfalusi 
215c8bf93f0SPeter Ujfalusi 	/*
216c8bf93f0SPeter Ujfalusi 	 * data is
217c8bf93f0SPeter Ujfalusi 	 *   D15..D8 dac33 register offset
218c8bf93f0SPeter Ujfalusi 	 *   D7...D0 register data
219c8bf93f0SPeter Ujfalusi 	 */
220c8bf93f0SPeter Ujfalusi 	data[0] = reg & 0xff;
221c8bf93f0SPeter Ujfalusi 	data[1] = value & 0xff;
222c8bf93f0SPeter Ujfalusi 
223cd21ac8cSKuninori Morimoto 	dac33_write_reg_cache(component, data[0], data[1]);
224c8bf93f0SPeter Ujfalusi 	if (dac33->chip_power) {
225ce9544dcSKuninori Morimoto 		ret = i2c_master_send(dac33->i2c, data, 2);
226c8bf93f0SPeter Ujfalusi 		if (ret != 2)
227cd21ac8cSKuninori Morimoto 			dev_err(component->dev, "Write failed (%d)\n", ret);
228c8bf93f0SPeter Ujfalusi 		else
229c8bf93f0SPeter Ujfalusi 			ret = 0;
230c8bf93f0SPeter Ujfalusi 	}
231c8bf93f0SPeter Ujfalusi 
232c8bf93f0SPeter Ujfalusi 	return ret;
233c8bf93f0SPeter Ujfalusi }
234c8bf93f0SPeter Ujfalusi 
dac33_write_locked(struct snd_soc_component * component,unsigned int reg,unsigned int value)235cd21ac8cSKuninori Morimoto static int dac33_write_locked(struct snd_soc_component *component, unsigned int reg,
2363d3dd0d3SKuninori Morimoto 			      unsigned int value)
2373d3dd0d3SKuninori Morimoto {
238cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
2393d3dd0d3SKuninori Morimoto 	int ret;
2403d3dd0d3SKuninori Morimoto 
2413d3dd0d3SKuninori Morimoto 	mutex_lock(&dac33->mutex);
242cd21ac8cSKuninori Morimoto 	ret = dac33_write(component, reg, value);
2433d3dd0d3SKuninori Morimoto 	mutex_unlock(&dac33->mutex);
2443d3dd0d3SKuninori Morimoto 
2453d3dd0d3SKuninori Morimoto 	return ret;
2463d3dd0d3SKuninori Morimoto }
2473d3dd0d3SKuninori Morimoto 
248c8bf93f0SPeter Ujfalusi #define DAC33_I2C_ADDR_AUTOINC	0x80
dac33_write16(struct snd_soc_component * component,unsigned int reg,unsigned int value)249cd21ac8cSKuninori Morimoto static int dac33_write16(struct snd_soc_component *component, unsigned int reg,
250c8bf93f0SPeter Ujfalusi 		       unsigned int value)
251c8bf93f0SPeter Ujfalusi {
252cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
253c8bf93f0SPeter Ujfalusi 	u8 data[3];
254c8bf93f0SPeter Ujfalusi 	int ret = 0;
255c8bf93f0SPeter Ujfalusi 
256c8bf93f0SPeter Ujfalusi 	/*
257c8bf93f0SPeter Ujfalusi 	 * data is
258c8bf93f0SPeter Ujfalusi 	 *   D23..D16 dac33 register offset
259c8bf93f0SPeter Ujfalusi 	 *   D15..D8  register data MSB
260c8bf93f0SPeter Ujfalusi 	 *   D7...D0  register data LSB
261c8bf93f0SPeter Ujfalusi 	 */
262c8bf93f0SPeter Ujfalusi 	data[0] = reg & 0xff;
263c8bf93f0SPeter Ujfalusi 	data[1] = (value >> 8) & 0xff;
264c8bf93f0SPeter Ujfalusi 	data[2] = value & 0xff;
265c8bf93f0SPeter Ujfalusi 
266cd21ac8cSKuninori Morimoto 	dac33_write_reg_cache(component, data[0], data[1]);
267cd21ac8cSKuninori Morimoto 	dac33_write_reg_cache(component, data[0] + 1, data[2]);
268c8bf93f0SPeter Ujfalusi 
269c8bf93f0SPeter Ujfalusi 	if (dac33->chip_power) {
270c8bf93f0SPeter Ujfalusi 		/* We need to set autoincrement mode for 16 bit writes */
271c8bf93f0SPeter Ujfalusi 		data[0] |= DAC33_I2C_ADDR_AUTOINC;
272ce9544dcSKuninori Morimoto 		ret = i2c_master_send(dac33->i2c, data, 3);
273c8bf93f0SPeter Ujfalusi 		if (ret != 3)
274cd21ac8cSKuninori Morimoto 			dev_err(component->dev, "Write failed (%d)\n", ret);
275c8bf93f0SPeter Ujfalusi 		else
276c8bf93f0SPeter Ujfalusi 			ret = 0;
277c8bf93f0SPeter Ujfalusi 	}
278c8bf93f0SPeter Ujfalusi 
279c8bf93f0SPeter Ujfalusi 	return ret;
280c8bf93f0SPeter Ujfalusi }
281c8bf93f0SPeter Ujfalusi 
dac33_init_chip(struct snd_soc_component * component)282cd21ac8cSKuninori Morimoto static void dac33_init_chip(struct snd_soc_component *component)
283c8bf93f0SPeter Ujfalusi {
284cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
285c8bf93f0SPeter Ujfalusi 
286ef909d67SPeter Ujfalusi 	if (unlikely(!dac33->chip_power))
287c8bf93f0SPeter Ujfalusi 		return;
288c8bf93f0SPeter Ujfalusi 
289ef909d67SPeter Ujfalusi 	/* A : DAC sample rate Fsref/1.5 */
290cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
291ef909d67SPeter Ujfalusi 	/* B : DAC src=normal, not muted */
292cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
293ef909d67SPeter Ujfalusi 					     DAC33_DACSRCL_LEFT);
294ef909d67SPeter Ujfalusi 	/* C : (defaults) */
295cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_DAC_CTRL_C, 0x00);
296ef909d67SPeter Ujfalusi 
297ef909d67SPeter Ujfalusi 	/* 73 : volume soft stepping control,
298ef909d67SPeter Ujfalusi 	 clock source = internal osc (?) */
299cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
300ef909d67SPeter Ujfalusi 
301ef909d67SPeter Ujfalusi 	/* Restore only selected registers (gains mostly) */
302cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_LDAC_DIG_VOL_CTRL,
303cd21ac8cSKuninori Morimoto 		    dac33_read_reg_cache(component, DAC33_LDAC_DIG_VOL_CTRL));
304cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_RDAC_DIG_VOL_CTRL,
305cd21ac8cSKuninori Morimoto 		    dac33_read_reg_cache(component, DAC33_RDAC_DIG_VOL_CTRL));
306ef909d67SPeter Ujfalusi 
307cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_LINEL_TO_LLO_VOL,
308cd21ac8cSKuninori Morimoto 		    dac33_read_reg_cache(component, DAC33_LINEL_TO_LLO_VOL));
309cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_LINER_TO_RLO_VOL,
310cd21ac8cSKuninori Morimoto 		    dac33_read_reg_cache(component, DAC33_LINER_TO_RLO_VOL));
311399b82e4SPeter Ujfalusi 
312cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_OUT_AMP_CTRL,
313cd21ac8cSKuninori Morimoto 		    dac33_read_reg_cache(component, DAC33_OUT_AMP_CTRL));
314399b82e4SPeter Ujfalusi 
315cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_LDAC_PWR_CTRL,
316cd21ac8cSKuninori Morimoto 		    dac33_read_reg_cache(component, DAC33_LDAC_PWR_CTRL));
317cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_RDAC_PWR_CTRL,
318cd21ac8cSKuninori Morimoto 		    dac33_read_reg_cache(component, DAC33_RDAC_PWR_CTRL));
319c8bf93f0SPeter Ujfalusi }
320c8bf93f0SPeter Ujfalusi 
dac33_read_id(struct snd_soc_component * component)321cd21ac8cSKuninori Morimoto static inline int dac33_read_id(struct snd_soc_component *component)
322239fe55cSPeter Ujfalusi {
323911a0f0bSPeter Ujfalusi 	int i, ret = 0;
324239fe55cSPeter Ujfalusi 	u8 reg;
325239fe55cSPeter Ujfalusi 
326911a0f0bSPeter Ujfalusi 	for (i = 0; i < 3; i++) {
327cd21ac8cSKuninori Morimoto 		ret = dac33_read(component, DAC33_DEVICE_ID_MSB + i, &reg);
328911a0f0bSPeter Ujfalusi 		if (ret < 0)
329911a0f0bSPeter Ujfalusi 			break;
330911a0f0bSPeter Ujfalusi 	}
331911a0f0bSPeter Ujfalusi 
332911a0f0bSPeter Ujfalusi 	return ret;
333c8bf93f0SPeter Ujfalusi }
334c8bf93f0SPeter Ujfalusi 
dac33_soft_power(struct snd_soc_component * component,int power)335cd21ac8cSKuninori Morimoto static inline void dac33_soft_power(struct snd_soc_component *component, int power)
336c8bf93f0SPeter Ujfalusi {
337c8bf93f0SPeter Ujfalusi 	u8 reg;
338c8bf93f0SPeter Ujfalusi 
339cd21ac8cSKuninori Morimoto 	reg = dac33_read_reg_cache(component, DAC33_PWR_CTRL);
340c8bf93f0SPeter Ujfalusi 	if (power)
341c8bf93f0SPeter Ujfalusi 		reg |= DAC33_PDNALLB;
342c8bf93f0SPeter Ujfalusi 	else
343c3746a07SPeter Ujfalusi 		reg &= ~(DAC33_PDNALLB | DAC33_OSCPDNB |
344c3746a07SPeter Ujfalusi 			 DAC33_DACRPDNB | DAC33_DACLPDNB);
345cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_PWR_CTRL, reg);
346c8bf93f0SPeter Ujfalusi }
347c8bf93f0SPeter Ujfalusi 
dac33_disable_digital(struct snd_soc_component * component)348cd21ac8cSKuninori Morimoto static inline void dac33_disable_digital(struct snd_soc_component *component)
349a6cea965SPeter Ujfalusi {
350a6cea965SPeter Ujfalusi 	u8 reg;
351a6cea965SPeter Ujfalusi 
352a6cea965SPeter Ujfalusi 	/* Stop the DAI clock */
353cd21ac8cSKuninori Morimoto 	reg = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_B);
354a6cea965SPeter Ujfalusi 	reg &= ~DAC33_BCLKON;
355cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_SER_AUDIOIF_CTRL_B, reg);
356a6cea965SPeter Ujfalusi 
357a6cea965SPeter Ujfalusi 	/* Power down the Oscillator, and DACs */
358cd21ac8cSKuninori Morimoto 	reg = dac33_read_reg_cache(component, DAC33_PWR_CTRL);
359a6cea965SPeter Ujfalusi 	reg &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
360cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_PWR_CTRL, reg);
361a6cea965SPeter Ujfalusi }
362a6cea965SPeter Ujfalusi 
dac33_hard_power(struct snd_soc_component * component,int power)363cd21ac8cSKuninori Morimoto static int dac33_hard_power(struct snd_soc_component *component, int power)
364c8bf93f0SPeter Ujfalusi {
365cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
366ad05c03bSPeter Ujfalusi 	int ret = 0;
367c8bf93f0SPeter Ujfalusi 
368c8bf93f0SPeter Ujfalusi 	mutex_lock(&dac33->mutex);
369ad05c03bSPeter Ujfalusi 
370ad05c03bSPeter Ujfalusi 	/* Safety check */
371ad05c03bSPeter Ujfalusi 	if (unlikely(power == dac33->chip_power)) {
372cd21ac8cSKuninori Morimoto 		dev_dbg(component->dev, "Trying to set the same power state: %s\n",
373ad05c03bSPeter Ujfalusi 			power ? "ON" : "OFF");
374ad05c03bSPeter Ujfalusi 		goto exit;
375ad05c03bSPeter Ujfalusi 	}
376ad05c03bSPeter Ujfalusi 
377c8bf93f0SPeter Ujfalusi 	if (power) {
3783a7aaed7SIlkka Koskinen 		ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
3793a7aaed7SIlkka Koskinen 					  dac33->supplies);
3803a7aaed7SIlkka Koskinen 		if (ret != 0) {
381cd21ac8cSKuninori Morimoto 			dev_err(component->dev,
3823a7aaed7SIlkka Koskinen 				"Failed to enable supplies: %d\n", ret);
3833a7aaed7SIlkka Koskinen 			goto exit;
3843a7aaed7SIlkka Koskinen 		}
3853a7aaed7SIlkka Koskinen 
3863a7aaed7SIlkka Koskinen 		if (dac33->power_gpio >= 0)
387c8bf93f0SPeter Ujfalusi 			gpio_set_value(dac33->power_gpio, 1);
3883a7aaed7SIlkka Koskinen 
389c8bf93f0SPeter Ujfalusi 		dac33->chip_power = 1;
390c8bf93f0SPeter Ujfalusi 	} else {
391cd21ac8cSKuninori Morimoto 		dac33_soft_power(component, 0);
3923a7aaed7SIlkka Koskinen 		if (dac33->power_gpio >= 0)
393c8bf93f0SPeter Ujfalusi 			gpio_set_value(dac33->power_gpio, 0);
3943a7aaed7SIlkka Koskinen 
3953a7aaed7SIlkka Koskinen 		ret = regulator_bulk_disable(ARRAY_SIZE(dac33->supplies),
3963a7aaed7SIlkka Koskinen 					     dac33->supplies);
3973a7aaed7SIlkka Koskinen 		if (ret != 0) {
398cd21ac8cSKuninori Morimoto 			dev_err(component->dev,
3993a7aaed7SIlkka Koskinen 				"Failed to disable supplies: %d\n", ret);
4003a7aaed7SIlkka Koskinen 			goto exit;
4013a7aaed7SIlkka Koskinen 		}
4023a7aaed7SIlkka Koskinen 
403c8bf93f0SPeter Ujfalusi 		dac33->chip_power = 0;
404c8bf93f0SPeter Ujfalusi 	}
405c8bf93f0SPeter Ujfalusi 
4063a7aaed7SIlkka Koskinen exit:
4073a7aaed7SIlkka Koskinen 	mutex_unlock(&dac33->mutex);
4083a7aaed7SIlkka Koskinen 	return ret;
409c8bf93f0SPeter Ujfalusi }
410c8bf93f0SPeter Ujfalusi 
dac33_playback_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)411a6cea965SPeter Ujfalusi static int dac33_playback_event(struct snd_soc_dapm_widget *w,
412ad05c03bSPeter Ujfalusi 		struct snd_kcontrol *kcontrol, int event)
413ad05c03bSPeter Ujfalusi {
414cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
415cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
416ad05c03bSPeter Ujfalusi 
417ad05c03bSPeter Ujfalusi 	switch (event) {
418ad05c03bSPeter Ujfalusi 	case SND_SOC_DAPM_PRE_PMU:
419ad05c03bSPeter Ujfalusi 		if (likely(dac33->substream)) {
420cd21ac8cSKuninori Morimoto 			dac33_calculate_times(dac33->substream, component);
421cd21ac8cSKuninori Morimoto 			dac33_prepare_chip(dac33->substream, component);
422ad05c03bSPeter Ujfalusi 		}
423ad05c03bSPeter Ujfalusi 		break;
424a6cea965SPeter Ujfalusi 	case SND_SOC_DAPM_POST_PMD:
425cd21ac8cSKuninori Morimoto 		dac33_disable_digital(component);
426a6cea965SPeter Ujfalusi 		break;
427ad05c03bSPeter Ujfalusi 	}
428ad05c03bSPeter Ujfalusi 	return 0;
429ad05c03bSPeter Ujfalusi }
430ad05c03bSPeter Ujfalusi 
dac33_get_fifo_mode(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)4317427b4b9SPeter Ujfalusi static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
432c8bf93f0SPeter Ujfalusi 			 struct snd_ctl_elem_value *ucontrol)
433c8bf93f0SPeter Ujfalusi {
434cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
435cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
436c8bf93f0SPeter Ujfalusi 
4378733f99cSTakashi Iwai 	ucontrol->value.enumerated.item[0] = dac33->fifo_mode;
438c8bf93f0SPeter Ujfalusi 
439c8bf93f0SPeter Ujfalusi 	return 0;
440c8bf93f0SPeter Ujfalusi }
441c8bf93f0SPeter Ujfalusi 
dac33_set_fifo_mode(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)4427427b4b9SPeter Ujfalusi static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
443c8bf93f0SPeter Ujfalusi 			 struct snd_ctl_elem_value *ucontrol)
444c8bf93f0SPeter Ujfalusi {
445cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
446cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
447c8bf93f0SPeter Ujfalusi 	int ret = 0;
448c8bf93f0SPeter Ujfalusi 
4498733f99cSTakashi Iwai 	if (dac33->fifo_mode == ucontrol->value.enumerated.item[0])
450c8bf93f0SPeter Ujfalusi 		return 0;
451c8bf93f0SPeter Ujfalusi 	/* Do not allow changes while stream is running*/
4525e518eddSKuninori Morimoto 	if (snd_soc_component_active(component))
453c8bf93f0SPeter Ujfalusi 		return -EPERM;
454c8bf93f0SPeter Ujfalusi 
4558733f99cSTakashi Iwai 	if (ucontrol->value.enumerated.item[0] >= DAC33_FIFO_LAST_MODE)
456c8bf93f0SPeter Ujfalusi 		ret = -EINVAL;
457c8bf93f0SPeter Ujfalusi 	else
4588733f99cSTakashi Iwai 		dac33->fifo_mode = ucontrol->value.enumerated.item[0];
459c8bf93f0SPeter Ujfalusi 
460c8bf93f0SPeter Ujfalusi 	return ret;
461c8bf93f0SPeter Ujfalusi }
462c8bf93f0SPeter Ujfalusi 
4637427b4b9SPeter Ujfalusi /* Codec operation modes */
4647427b4b9SPeter Ujfalusi static const char *dac33_fifo_mode_texts[] = {
46528e05d98SPeter Ujfalusi 	"Bypass", "Mode 1", "Mode 7"
4667427b4b9SPeter Ujfalusi };
4677427b4b9SPeter Ujfalusi 
468d77c290aSTakashi Iwai static SOC_ENUM_SINGLE_EXT_DECL(dac33_fifo_mode_enum, dac33_fifo_mode_texts);
4697427b4b9SPeter Ujfalusi 
470cf4bb698SPeter Ujfalusi /* L/R Line Output Gain */
471cf4bb698SPeter Ujfalusi static const char *lr_lineout_gain_texts[] = {
472cf4bb698SPeter Ujfalusi 	"Line -12dB DAC 0dB", "Line -6dB DAC 6dB",
473cf4bb698SPeter Ujfalusi 	"Line 0dB DAC 12dB", "Line 6dB DAC 18dB",
474cf4bb698SPeter Ujfalusi };
475cf4bb698SPeter Ujfalusi 
476d77c290aSTakashi Iwai static SOC_ENUM_SINGLE_DECL(l_lineout_gain_enum,
477d77c290aSTakashi Iwai 			    DAC33_LDAC_PWR_CTRL, 0,
478cf4bb698SPeter Ujfalusi 			    lr_lineout_gain_texts);
479cf4bb698SPeter Ujfalusi 
480d77c290aSTakashi Iwai static SOC_ENUM_SINGLE_DECL(r_lineout_gain_enum,
481d77c290aSTakashi Iwai 			    DAC33_RDAC_PWR_CTRL, 0,
482cf4bb698SPeter Ujfalusi 			    lr_lineout_gain_texts);
483cf4bb698SPeter Ujfalusi 
484c8bf93f0SPeter Ujfalusi /*
485c8bf93f0SPeter Ujfalusi  * DACL/R digital volume control:
486c8bf93f0SPeter Ujfalusi  * from 0 dB to -63.5 in 0.5 dB steps
487c8bf93f0SPeter Ujfalusi  * Need to be inverted later on:
488c8bf93f0SPeter Ujfalusi  * 0x00 == 0 dB
489c8bf93f0SPeter Ujfalusi  * 0x7f == -63.5 dB
490c8bf93f0SPeter Ujfalusi  */
491c8bf93f0SPeter Ujfalusi static DECLARE_TLV_DB_SCALE(dac_digivol_tlv, -6350, 50, 0);
492c8bf93f0SPeter Ujfalusi 
493c8bf93f0SPeter Ujfalusi static const struct snd_kcontrol_new dac33_snd_controls[] = {
494c8bf93f0SPeter Ujfalusi 	SOC_DOUBLE_R_TLV("DAC Digital Playback Volume",
495c8bf93f0SPeter Ujfalusi 		DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL,
496c8bf93f0SPeter Ujfalusi 		0, 0x7f, 1, dac_digivol_tlv),
497c8bf93f0SPeter Ujfalusi 	SOC_DOUBLE_R("DAC Digital Playback Switch",
498c8bf93f0SPeter Ujfalusi 		 DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL, 7, 1, 1),
499c8bf93f0SPeter Ujfalusi 	SOC_DOUBLE_R("Line to Line Out Volume",
500c8bf93f0SPeter Ujfalusi 		 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1),
501cf4bb698SPeter Ujfalusi 	SOC_ENUM("Left Line Output Gain", l_lineout_gain_enum),
502cf4bb698SPeter Ujfalusi 	SOC_ENUM("Right Line Output Gain", r_lineout_gain_enum),
503c8bf93f0SPeter Ujfalusi };
504c8bf93f0SPeter Ujfalusi 
505a577b318SPeter Ujfalusi static const struct snd_kcontrol_new dac33_mode_snd_controls[] = {
506a577b318SPeter Ujfalusi 	SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum,
507a577b318SPeter Ujfalusi 		 dac33_get_fifo_mode, dac33_set_fifo_mode),
508a577b318SPeter Ujfalusi };
509a577b318SPeter Ujfalusi 
510c8bf93f0SPeter Ujfalusi /* Analog bypass */
511c8bf93f0SPeter Ujfalusi static const struct snd_kcontrol_new dac33_dapm_abypassl_control =
512c8bf93f0SPeter Ujfalusi 	SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1);
513c8bf93f0SPeter Ujfalusi 
514c8bf93f0SPeter Ujfalusi static const struct snd_kcontrol_new dac33_dapm_abypassr_control =
515c8bf93f0SPeter Ujfalusi 	SOC_DAPM_SINGLE("Switch", DAC33_LINER_TO_RLO_VOL, 7, 1, 1);
516c8bf93f0SPeter Ujfalusi 
517399b82e4SPeter Ujfalusi /* LOP L/R invert selection */
518399b82e4SPeter Ujfalusi static const char *dac33_lr_lom_texts[] = {"DAC", "LOP"};
519399b82e4SPeter Ujfalusi 
520d77c290aSTakashi Iwai static SOC_ENUM_SINGLE_DECL(dac33_left_lom_enum,
521d77c290aSTakashi Iwai 			    DAC33_OUT_AMP_CTRL, 3,
522399b82e4SPeter Ujfalusi 			    dac33_lr_lom_texts);
523399b82e4SPeter Ujfalusi 
524399b82e4SPeter Ujfalusi static const struct snd_kcontrol_new dac33_dapm_left_lom_control =
525399b82e4SPeter Ujfalusi SOC_DAPM_ENUM("Route", dac33_left_lom_enum);
526399b82e4SPeter Ujfalusi 
527d77c290aSTakashi Iwai static SOC_ENUM_SINGLE_DECL(dac33_right_lom_enum,
528d77c290aSTakashi Iwai 			    DAC33_OUT_AMP_CTRL, 2,
529399b82e4SPeter Ujfalusi 			    dac33_lr_lom_texts);
530399b82e4SPeter Ujfalusi 
531399b82e4SPeter Ujfalusi static const struct snd_kcontrol_new dac33_dapm_right_lom_control =
532399b82e4SPeter Ujfalusi SOC_DAPM_ENUM("Route", dac33_right_lom_enum);
533399b82e4SPeter Ujfalusi 
534c8bf93f0SPeter Ujfalusi static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
535c8bf93f0SPeter Ujfalusi 	SND_SOC_DAPM_OUTPUT("LEFT_LO"),
536c8bf93f0SPeter Ujfalusi 	SND_SOC_DAPM_OUTPUT("RIGHT_LO"),
537c8bf93f0SPeter Ujfalusi 
538c8bf93f0SPeter Ujfalusi 	SND_SOC_DAPM_INPUT("LINEL"),
539c8bf93f0SPeter Ujfalusi 	SND_SOC_DAPM_INPUT("LINER"),
540c8bf93f0SPeter Ujfalusi 
54176eac39cSPeter Ujfalusi 	SND_SOC_DAPM_DAC("DACL", "Left Playback", SND_SOC_NOPM, 0, 0),
54276eac39cSPeter Ujfalusi 	SND_SOC_DAPM_DAC("DACR", "Right Playback", SND_SOC_NOPM, 0, 0),
543c8bf93f0SPeter Ujfalusi 
544c8bf93f0SPeter Ujfalusi 	/* Analog bypass */
545c8bf93f0SPeter Ujfalusi 	SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0,
546c8bf93f0SPeter Ujfalusi 				&dac33_dapm_abypassl_control),
547c8bf93f0SPeter Ujfalusi 	SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0,
548c8bf93f0SPeter Ujfalusi 				&dac33_dapm_abypassr_control),
549c8bf93f0SPeter Ujfalusi 
550399b82e4SPeter Ujfalusi 	SND_SOC_DAPM_MUX("Left LOM Inverted From", SND_SOC_NOPM, 0, 0,
551399b82e4SPeter Ujfalusi 		&dac33_dapm_left_lom_control),
552399b82e4SPeter Ujfalusi 	SND_SOC_DAPM_MUX("Right LOM Inverted From", SND_SOC_NOPM, 0, 0,
553399b82e4SPeter Ujfalusi 		&dac33_dapm_right_lom_control),
554399b82e4SPeter Ujfalusi 	/*
555399b82e4SPeter Ujfalusi 	 * For DAPM path, when only the anlog bypass path is enabled, and the
556399b82e4SPeter Ujfalusi 	 * LOP inverted from the corresponding DAC side.
557399b82e4SPeter Ujfalusi 	 * This is needed, so we can attach the DAC power supply in this case.
558399b82e4SPeter Ujfalusi 	 */
559399b82e4SPeter Ujfalusi 	SND_SOC_DAPM_PGA("Left Bypass PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
560399b82e4SPeter Ujfalusi 	SND_SOC_DAPM_PGA("Right Bypass PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
561399b82e4SPeter Ujfalusi 
5629e87186fSPeter Ujfalusi 	SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amplifier",
563c8bf93f0SPeter Ujfalusi 			 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
5649e87186fSPeter Ujfalusi 	SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amplifier",
565c8bf93f0SPeter Ujfalusi 			 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
566ad05c03bSPeter Ujfalusi 
56776eac39cSPeter Ujfalusi 	SND_SOC_DAPM_SUPPLY("Left DAC Power",
56876eac39cSPeter Ujfalusi 			    DAC33_LDAC_PWR_CTRL, 2, 0, NULL, 0),
56976eac39cSPeter Ujfalusi 	SND_SOC_DAPM_SUPPLY("Right DAC Power",
57076eac39cSPeter Ujfalusi 			    DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0),
57176eac39cSPeter Ujfalusi 
5724b8ffdb9SPeter Ujfalusi 	SND_SOC_DAPM_SUPPLY("Codec Power",
5734b8ffdb9SPeter Ujfalusi 			    DAC33_PWR_CTRL, 4, 0, NULL, 0),
5744b8ffdb9SPeter Ujfalusi 
575a6cea965SPeter Ujfalusi 	SND_SOC_DAPM_PRE("Pre Playback", dac33_playback_event),
576a6cea965SPeter Ujfalusi 	SND_SOC_DAPM_POST("Post Playback", dac33_playback_event),
577c8bf93f0SPeter Ujfalusi };
578c8bf93f0SPeter Ujfalusi 
579c8bf93f0SPeter Ujfalusi static const struct snd_soc_dapm_route audio_map[] = {
580c8bf93f0SPeter Ujfalusi 	/* Analog bypass */
581c8bf93f0SPeter Ujfalusi 	{"Analog Left Bypass", "Switch", "LINEL"},
582c8bf93f0SPeter Ujfalusi 	{"Analog Right Bypass", "Switch", "LINER"},
583c8bf93f0SPeter Ujfalusi 
5849e87186fSPeter Ujfalusi 	{"Output Left Amplifier", NULL, "DACL"},
5859e87186fSPeter Ujfalusi 	{"Output Right Amplifier", NULL, "DACR"},
586c8bf93f0SPeter Ujfalusi 
587399b82e4SPeter Ujfalusi 	{"Left Bypass PGA", NULL, "Analog Left Bypass"},
588399b82e4SPeter Ujfalusi 	{"Right Bypass PGA", NULL, "Analog Right Bypass"},
589c8bf93f0SPeter Ujfalusi 
590399b82e4SPeter Ujfalusi 	{"Left LOM Inverted From", "DAC", "Left Bypass PGA"},
591399b82e4SPeter Ujfalusi 	{"Right LOM Inverted From", "DAC", "Right Bypass PGA"},
592399b82e4SPeter Ujfalusi 	{"Left LOM Inverted From", "LOP", "Analog Left Bypass"},
593399b82e4SPeter Ujfalusi 	{"Right LOM Inverted From", "LOP", "Analog Right Bypass"},
594399b82e4SPeter Ujfalusi 
595399b82e4SPeter Ujfalusi 	{"Output Left Amplifier", NULL, "Left LOM Inverted From"},
596399b82e4SPeter Ujfalusi 	{"Output Right Amplifier", NULL, "Right LOM Inverted From"},
597399b82e4SPeter Ujfalusi 
598399b82e4SPeter Ujfalusi 	{"DACL", NULL, "Left DAC Power"},
599399b82e4SPeter Ujfalusi 	{"DACR", NULL, "Right DAC Power"},
600399b82e4SPeter Ujfalusi 
601399b82e4SPeter Ujfalusi 	{"Left Bypass PGA", NULL, "Left DAC Power"},
602399b82e4SPeter Ujfalusi 	{"Right Bypass PGA", NULL, "Right DAC Power"},
60376eac39cSPeter Ujfalusi 
604c8bf93f0SPeter Ujfalusi 	/* output */
6059e87186fSPeter Ujfalusi 	{"LEFT_LO", NULL, "Output Left Amplifier"},
6069e87186fSPeter Ujfalusi 	{"RIGHT_LO", NULL, "Output Right Amplifier"},
6074b8ffdb9SPeter Ujfalusi 
6084b8ffdb9SPeter Ujfalusi 	{"LEFT_LO", NULL, "Codec Power"},
6094b8ffdb9SPeter Ujfalusi 	{"RIGHT_LO", NULL, "Codec Power"},
610c8bf93f0SPeter Ujfalusi };
611c8bf93f0SPeter Ujfalusi 
dac33_set_bias_level(struct snd_soc_component * component,enum snd_soc_bias_level level)612cd21ac8cSKuninori Morimoto static int dac33_set_bias_level(struct snd_soc_component *component,
613c8bf93f0SPeter Ujfalusi 				enum snd_soc_bias_level level)
614c8bf93f0SPeter Ujfalusi {
6153a7aaed7SIlkka Koskinen 	int ret;
6163a7aaed7SIlkka Koskinen 
617c8bf93f0SPeter Ujfalusi 	switch (level) {
618c8bf93f0SPeter Ujfalusi 	case SND_SOC_BIAS_ON:
619c8bf93f0SPeter Ujfalusi 		break;
620c8bf93f0SPeter Ujfalusi 	case SND_SOC_BIAS_PREPARE:
621c8bf93f0SPeter Ujfalusi 		break;
622c8bf93f0SPeter Ujfalusi 	case SND_SOC_BIAS_STANDBY:
623cd21ac8cSKuninori Morimoto 		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
624cd21ac8cSKuninori Morimoto 			/* Coming from OFF, switch on the component */
625cd21ac8cSKuninori Morimoto 			ret = dac33_hard_power(component, 1);
6263a7aaed7SIlkka Koskinen 			if (ret != 0)
6273a7aaed7SIlkka Koskinen 				return ret;
6283a7aaed7SIlkka Koskinen 
629cd21ac8cSKuninori Morimoto 			dac33_init_chip(component);
630ad05c03bSPeter Ujfalusi 		}
631c8bf93f0SPeter Ujfalusi 		break;
632c8bf93f0SPeter Ujfalusi 	case SND_SOC_BIAS_OFF:
633cd21ac8cSKuninori Morimoto 		/* Do not power off, when the component is already off */
634cd21ac8cSKuninori Morimoto 		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
6352d4cdd6fSPeter Ujfalusi 			return 0;
636cd21ac8cSKuninori Morimoto 		ret = dac33_hard_power(component, 0);
6373a7aaed7SIlkka Koskinen 		if (ret != 0)
6383a7aaed7SIlkka Koskinen 			return ret;
639c8bf93f0SPeter Ujfalusi 		break;
640c8bf93f0SPeter Ujfalusi 	}
641c8bf93f0SPeter Ujfalusi 
642c8bf93f0SPeter Ujfalusi 	return 0;
643c8bf93f0SPeter Ujfalusi }
644c8bf93f0SPeter Ujfalusi 
dac33_prefill_handler(struct tlv320dac33_priv * dac33)645d4f102d4SPeter Ujfalusi static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
646d4f102d4SPeter Ujfalusi {
647cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component = dac33->component;
64884eae18cSPeter Ujfalusi 	unsigned int delay;
649a3b55791SPeter Ujfalusi 	unsigned long flags;
650d4f102d4SPeter Ujfalusi 
651d4f102d4SPeter Ujfalusi 	switch (dac33->fifo_mode) {
652d4f102d4SPeter Ujfalusi 	case DAC33_FIFO_MODE1:
653cd21ac8cSKuninori Morimoto 		dac33_write16(component, DAC33_NSAMPLE_MSB,
654f430a27fSPeter Ujfalusi 			DAC33_THRREG(dac33->nsample));
655f57d2cfaSPeter Ujfalusi 
656f57d2cfaSPeter Ujfalusi 		/* Take the timestamps */
657a3b55791SPeter Ujfalusi 		spin_lock_irqsave(&dac33->lock, flags);
658f57d2cfaSPeter Ujfalusi 		dac33->t_stamp2 = ktime_to_us(ktime_get());
659f57d2cfaSPeter Ujfalusi 		dac33->t_stamp1 = dac33->t_stamp2;
660a3b55791SPeter Ujfalusi 		spin_unlock_irqrestore(&dac33->lock, flags);
661f57d2cfaSPeter Ujfalusi 
662cd21ac8cSKuninori Morimoto 		dac33_write16(component, DAC33_PREFILL_MSB,
663d4f102d4SPeter Ujfalusi 				DAC33_THRREG(dac33->alarm_threshold));
664f4d59328SPeter Ujfalusi 		/* Enable Alarm Threshold IRQ with a delay */
66584eae18cSPeter Ujfalusi 		delay = SAMPLES_TO_US(dac33->burst_rate,
66684eae18cSPeter Ujfalusi 				     dac33->alarm_threshold) + 1000;
66784eae18cSPeter Ujfalusi 		usleep_range(delay, delay + 500);
668cd21ac8cSKuninori Morimoto 		dac33_write(component, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
669d4f102d4SPeter Ujfalusi 		break;
67028e05d98SPeter Ujfalusi 	case DAC33_FIFO_MODE7:
671f57d2cfaSPeter Ujfalusi 		/* Take the timestamp */
672a3b55791SPeter Ujfalusi 		spin_lock_irqsave(&dac33->lock, flags);
673f57d2cfaSPeter Ujfalusi 		dac33->t_stamp1 = ktime_to_us(ktime_get());
674f57d2cfaSPeter Ujfalusi 		/* Move back the timestamp with drain time */
675f57d2cfaSPeter Ujfalusi 		dac33->t_stamp1 -= dac33->mode7_us_to_lthr;
676a3b55791SPeter Ujfalusi 		spin_unlock_irqrestore(&dac33->lock, flags);
677f57d2cfaSPeter Ujfalusi 
678cd21ac8cSKuninori Morimoto 		dac33_write16(component, DAC33_PREFILL_MSB,
679549675edSPeter Ujfalusi 				DAC33_THRREG(DAC33_MODE7_MARGIN));
680f57d2cfaSPeter Ujfalusi 
681f57d2cfaSPeter Ujfalusi 		/* Enable Upper Threshold IRQ */
682cd21ac8cSKuninori Morimoto 		dac33_write(component, DAC33_FIFO_IRQ_MASK, DAC33_MUT);
68328e05d98SPeter Ujfalusi 		break;
684d4f102d4SPeter Ujfalusi 	default:
685cd21ac8cSKuninori Morimoto 		dev_warn(component->dev, "Unhandled FIFO mode: %d\n",
686d4f102d4SPeter Ujfalusi 							dac33->fifo_mode);
687d4f102d4SPeter Ujfalusi 		break;
688d4f102d4SPeter Ujfalusi 	}
689d4f102d4SPeter Ujfalusi }
690d4f102d4SPeter Ujfalusi 
dac33_playback_handler(struct tlv320dac33_priv * dac33)691d4f102d4SPeter Ujfalusi static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
692d4f102d4SPeter Ujfalusi {
693cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component = dac33->component;
694a3b55791SPeter Ujfalusi 	unsigned long flags;
695d4f102d4SPeter Ujfalusi 
696d4f102d4SPeter Ujfalusi 	switch (dac33->fifo_mode) {
697d4f102d4SPeter Ujfalusi 	case DAC33_FIFO_MODE1:
698f57d2cfaSPeter Ujfalusi 		/* Take the timestamp */
699a3b55791SPeter Ujfalusi 		spin_lock_irqsave(&dac33->lock, flags);
700f57d2cfaSPeter Ujfalusi 		dac33->t_stamp2 = ktime_to_us(ktime_get());
701a3b55791SPeter Ujfalusi 		spin_unlock_irqrestore(&dac33->lock, flags);
702f57d2cfaSPeter Ujfalusi 
703cd21ac8cSKuninori Morimoto 		dac33_write16(component, DAC33_NSAMPLE_MSB,
704d4f102d4SPeter Ujfalusi 				DAC33_THRREG(dac33->nsample));
705d4f102d4SPeter Ujfalusi 		break;
70628e05d98SPeter Ujfalusi 	case DAC33_FIFO_MODE7:
70728e05d98SPeter Ujfalusi 		/* At the moment we are not using interrupts in mode7 */
70828e05d98SPeter Ujfalusi 		break;
709d4f102d4SPeter Ujfalusi 	default:
710cd21ac8cSKuninori Morimoto 		dev_warn(component->dev, "Unhandled FIFO mode: %d\n",
711d4f102d4SPeter Ujfalusi 							dac33->fifo_mode);
712d4f102d4SPeter Ujfalusi 		break;
713d4f102d4SPeter Ujfalusi 	}
714d4f102d4SPeter Ujfalusi }
715d4f102d4SPeter Ujfalusi 
dac33_work(struct work_struct * work)716c8bf93f0SPeter Ujfalusi static void dac33_work(struct work_struct *work)
717c8bf93f0SPeter Ujfalusi {
718cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component;
719c8bf93f0SPeter Ujfalusi 	struct tlv320dac33_priv *dac33;
720c8bf93f0SPeter Ujfalusi 	u8 reg;
721c8bf93f0SPeter Ujfalusi 
722c8bf93f0SPeter Ujfalusi 	dac33 = container_of(work, struct tlv320dac33_priv, work);
723cd21ac8cSKuninori Morimoto 	component = dac33->component;
724c8bf93f0SPeter Ujfalusi 
725c8bf93f0SPeter Ujfalusi 	mutex_lock(&dac33->mutex);
726c8bf93f0SPeter Ujfalusi 	switch (dac33->state) {
727c8bf93f0SPeter Ujfalusi 	case DAC33_PREFILL:
728c8bf93f0SPeter Ujfalusi 		dac33->state = DAC33_PLAYBACK;
729d4f102d4SPeter Ujfalusi 		dac33_prefill_handler(dac33);
730c8bf93f0SPeter Ujfalusi 		break;
731c8bf93f0SPeter Ujfalusi 	case DAC33_PLAYBACK:
732d4f102d4SPeter Ujfalusi 		dac33_playback_handler(dac33);
733c8bf93f0SPeter Ujfalusi 		break;
734c8bf93f0SPeter Ujfalusi 	case DAC33_IDLE:
735c8bf93f0SPeter Ujfalusi 		break;
736c8bf93f0SPeter Ujfalusi 	case DAC33_FLUSH:
737c8bf93f0SPeter Ujfalusi 		dac33->state = DAC33_IDLE;
738c8bf93f0SPeter Ujfalusi 		/* Mask all interrupts from dac33 */
739cd21ac8cSKuninori Morimoto 		dac33_write(component, DAC33_FIFO_IRQ_MASK, 0);
740c8bf93f0SPeter Ujfalusi 
741c8bf93f0SPeter Ujfalusi 		/* flush fifo */
742cd21ac8cSKuninori Morimoto 		reg = dac33_read_reg_cache(component, DAC33_FIFO_CTRL_A);
743c8bf93f0SPeter Ujfalusi 		reg |= DAC33_FIFOFLUSH;
744cd21ac8cSKuninori Morimoto 		dac33_write(component, DAC33_FIFO_CTRL_A, reg);
745c8bf93f0SPeter Ujfalusi 		break;
746c8bf93f0SPeter Ujfalusi 	}
747c8bf93f0SPeter Ujfalusi 	mutex_unlock(&dac33->mutex);
748c8bf93f0SPeter Ujfalusi }
749c8bf93f0SPeter Ujfalusi 
dac33_interrupt_handler(int irq,void * dev)750c8bf93f0SPeter Ujfalusi static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
751c8bf93f0SPeter Ujfalusi {
752cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component = dev;
753cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
754a3b55791SPeter Ujfalusi 	unsigned long flags;
755c8bf93f0SPeter Ujfalusi 
756a3b55791SPeter Ujfalusi 	spin_lock_irqsave(&dac33->lock, flags);
757f57d2cfaSPeter Ujfalusi 	dac33->t_stamp1 = ktime_to_us(ktime_get());
758a3b55791SPeter Ujfalusi 	spin_unlock_irqrestore(&dac33->lock, flags);
759f57d2cfaSPeter Ujfalusi 
760f57d2cfaSPeter Ujfalusi 	/* Do not schedule the workqueue in Mode7 */
761f57d2cfaSPeter Ujfalusi 	if (dac33->fifo_mode != DAC33_FIFO_MODE7)
76288910982SBhaktipriya Shridhar 		schedule_work(&dac33->work);
763c8bf93f0SPeter Ujfalusi 
764c8bf93f0SPeter Ujfalusi 	return IRQ_HANDLED;
765c8bf93f0SPeter Ujfalusi }
766c8bf93f0SPeter Ujfalusi 
dac33_oscwait(struct snd_soc_component * component)767cd21ac8cSKuninori Morimoto static void dac33_oscwait(struct snd_soc_component *component)
768c8bf93f0SPeter Ujfalusi {
76984eae18cSPeter Ujfalusi 	int timeout = 60;
770c8bf93f0SPeter Ujfalusi 	u8 reg;
771c8bf93f0SPeter Ujfalusi 
772c8bf93f0SPeter Ujfalusi 	do {
77384eae18cSPeter Ujfalusi 		usleep_range(1000, 2000);
774cd21ac8cSKuninori Morimoto 		dac33_read(component, DAC33_INT_OSC_STATUS, &reg);
775c8bf93f0SPeter Ujfalusi 	} while (((reg & 0x03) != DAC33_OSCSTATUS_NORMAL) && timeout--);
776c8bf93f0SPeter Ujfalusi 	if ((reg & 0x03) != DAC33_OSCSTATUS_NORMAL)
777cd21ac8cSKuninori Morimoto 		dev_err(component->dev,
778c8bf93f0SPeter Ujfalusi 			"internal oscillator calibration failed\n");
779c8bf93f0SPeter Ujfalusi }
780c8bf93f0SPeter Ujfalusi 
dac33_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)7810b61d2b9SPeter Ujfalusi static int dac33_startup(struct snd_pcm_substream *substream,
7820b61d2b9SPeter Ujfalusi 			   struct snd_soc_dai *dai)
7830b61d2b9SPeter Ujfalusi {
784cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component = dai->component;
785cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
7860b61d2b9SPeter Ujfalusi 
7870b61d2b9SPeter Ujfalusi 	/* Stream started, save the substream pointer */
7880b61d2b9SPeter Ujfalusi 	dac33->substream = substream;
7890b61d2b9SPeter Ujfalusi 
7900b61d2b9SPeter Ujfalusi 	return 0;
7910b61d2b9SPeter Ujfalusi }
7920b61d2b9SPeter Ujfalusi 
dac33_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)7930b61d2b9SPeter Ujfalusi static void dac33_shutdown(struct snd_pcm_substream *substream,
7940b61d2b9SPeter Ujfalusi 			     struct snd_soc_dai *dai)
7950b61d2b9SPeter Ujfalusi {
796cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component = dai->component;
797cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
7980b61d2b9SPeter Ujfalusi 
7990b61d2b9SPeter Ujfalusi 	dac33->substream = NULL;
8000b61d2b9SPeter Ujfalusi }
8010b61d2b9SPeter Ujfalusi 
802549675edSPeter Ujfalusi #define CALC_BURST_RATE(bclkdiv, bclk_per_sample) \
803549675edSPeter Ujfalusi 	(BURST_BASEFREQ_HZ / bclkdiv / bclk_per_sample)
dac33_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)804c8bf93f0SPeter Ujfalusi static int dac33_hw_params(struct snd_pcm_substream *substream,
805c8bf93f0SPeter Ujfalusi 			   struct snd_pcm_hw_params *params,
806c8bf93f0SPeter Ujfalusi 			   struct snd_soc_dai *dai)
807c8bf93f0SPeter Ujfalusi {
808cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component = dai->component;
809cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
810c8bf93f0SPeter Ujfalusi 
811c8bf93f0SPeter Ujfalusi 	/* Check parameters for validity */
812c8bf93f0SPeter Ujfalusi 	switch (params_rate(params)) {
813c8bf93f0SPeter Ujfalusi 	case 44100:
814c8bf93f0SPeter Ujfalusi 	case 48000:
815c8bf93f0SPeter Ujfalusi 		break;
816c8bf93f0SPeter Ujfalusi 	default:
817cd21ac8cSKuninori Morimoto 		dev_err(component->dev, "unsupported rate %d\n",
818c8bf93f0SPeter Ujfalusi 			params_rate(params));
819c8bf93f0SPeter Ujfalusi 		return -EINVAL;
820c8bf93f0SPeter Ujfalusi 	}
821c8bf93f0SPeter Ujfalusi 
822c60f23cbSMark Brown 	switch (params_width(params)) {
823c60f23cbSMark Brown 	case 16:
824549675edSPeter Ujfalusi 		dac33->fifo_size = DAC33_FIFO_SIZE_16BIT;
825549675edSPeter Ujfalusi 		dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 32);
826c8bf93f0SPeter Ujfalusi 		break;
827c60f23cbSMark Brown 	case 32:
8280d99d2b0SPeter Ujfalusi 		dac33->fifo_size = DAC33_FIFO_SIZE_24BIT;
8290d99d2b0SPeter Ujfalusi 		dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 64);
8300d99d2b0SPeter Ujfalusi 		break;
831c8bf93f0SPeter Ujfalusi 	default:
832cd21ac8cSKuninori Morimoto 		dev_err(component->dev, "unsupported width %d\n",
833c60f23cbSMark Brown 			params_width(params));
834c8bf93f0SPeter Ujfalusi 		return -EINVAL;
835c8bf93f0SPeter Ujfalusi 	}
836c8bf93f0SPeter Ujfalusi 
837c8bf93f0SPeter Ujfalusi 	return 0;
838c8bf93f0SPeter Ujfalusi }
839c8bf93f0SPeter Ujfalusi 
840c8bf93f0SPeter Ujfalusi #define CALC_OSCSET(rate, refclk) ( \
8417833ae0eSPeter Ujfalusi 	((((rate * 10000) / refclk) * 4096) + 7000) / 10000)
842c8bf93f0SPeter Ujfalusi #define CALC_RATIOSET(rate, refclk) ( \
843c8bf93f0SPeter Ujfalusi 	((((refclk  * 100000) / rate) * 16384) + 50000) / 100000)
844c8bf93f0SPeter Ujfalusi 
845c8bf93f0SPeter Ujfalusi /*
846c8bf93f0SPeter Ujfalusi  * tlv320dac33 is strict on the sequence of the register writes, if the register
847c8bf93f0SPeter Ujfalusi  * writes happens in different order, than dac33 might end up in unknown state.
848c8bf93f0SPeter Ujfalusi  * Use the known, working sequence of register writes to initialize the dac33.
849c8bf93f0SPeter Ujfalusi  */
dac33_prepare_chip(struct snd_pcm_substream * substream,struct snd_soc_component * component)850e6968a17SMark Brown static int dac33_prepare_chip(struct snd_pcm_substream *substream,
851cd21ac8cSKuninori Morimoto 			      struct snd_soc_component *component)
852c8bf93f0SPeter Ujfalusi {
853cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
854c8bf93f0SPeter Ujfalusi 	unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
855aec242dcSPeter Ujfalusi 	u8 aictrl_a, aictrl_b, fifoctrl_a;
856c8bf93f0SPeter Ujfalusi 
857c8bf93f0SPeter Ujfalusi 	switch (substream->runtime->rate) {
858c8bf93f0SPeter Ujfalusi 	case 44100:
859c8bf93f0SPeter Ujfalusi 	case 48000:
860c8bf93f0SPeter Ujfalusi 		oscset = CALC_OSCSET(substream->runtime->rate, dac33->refclk);
861c8bf93f0SPeter Ujfalusi 		ratioset = CALC_RATIOSET(substream->runtime->rate,
862c8bf93f0SPeter Ujfalusi 					 dac33->refclk);
863c8bf93f0SPeter Ujfalusi 		break;
864c8bf93f0SPeter Ujfalusi 	default:
865cd21ac8cSKuninori Morimoto 		dev_err(component->dev, "unsupported rate %d\n",
866c8bf93f0SPeter Ujfalusi 			substream->runtime->rate);
867c8bf93f0SPeter Ujfalusi 		return -EINVAL;
868c8bf93f0SPeter Ujfalusi 	}
869c8bf93f0SPeter Ujfalusi 
870c8bf93f0SPeter Ujfalusi 
871cd21ac8cSKuninori Morimoto 	aictrl_a = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_A);
872c8bf93f0SPeter Ujfalusi 	aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK);
873e5e878c1SPeter Ujfalusi 	/* Read FIFO control A, and clear FIFO flush bit */
874cd21ac8cSKuninori Morimoto 	fifoctrl_a = dac33_read_reg_cache(component, DAC33_FIFO_CTRL_A);
875e5e878c1SPeter Ujfalusi 	fifoctrl_a &= ~DAC33_FIFOFLUSH;
876e5e878c1SPeter Ujfalusi 
877c8bf93f0SPeter Ujfalusi 	fifoctrl_a &= ~DAC33_WIDTH;
878c8bf93f0SPeter Ujfalusi 	switch (substream->runtime->format) {
879c8bf93f0SPeter Ujfalusi 	case SNDRV_PCM_FORMAT_S16_LE:
880c8bf93f0SPeter Ujfalusi 		aictrl_a |= (DAC33_NCYCL_16 | DAC33_WLEN_16);
881c8bf93f0SPeter Ujfalusi 		fifoctrl_a |= DAC33_WIDTH;
882c8bf93f0SPeter Ujfalusi 		break;
8830d99d2b0SPeter Ujfalusi 	case SNDRV_PCM_FORMAT_S32_LE:
8840d99d2b0SPeter Ujfalusi 		aictrl_a |= (DAC33_NCYCL_32 | DAC33_WLEN_24);
8850d99d2b0SPeter Ujfalusi 		break;
886c8bf93f0SPeter Ujfalusi 	default:
887cd21ac8cSKuninori Morimoto 		dev_err(component->dev, "unsupported format %d\n",
888c8bf93f0SPeter Ujfalusi 			substream->runtime->format);
889c8bf93f0SPeter Ujfalusi 		return -EINVAL;
890c8bf93f0SPeter Ujfalusi 	}
891c8bf93f0SPeter Ujfalusi 
892c8bf93f0SPeter Ujfalusi 	mutex_lock(&dac33->mutex);
893ad05c03bSPeter Ujfalusi 
894ad05c03bSPeter Ujfalusi 	if (!dac33->chip_power) {
895ad05c03bSPeter Ujfalusi 		/*
896ad05c03bSPeter Ujfalusi 		 * Chip is not powered yet.
897ad05c03bSPeter Ujfalusi 		 * Do the init in the dac33_set_bias_level later.
898ad05c03bSPeter Ujfalusi 		 */
899ad05c03bSPeter Ujfalusi 		mutex_unlock(&dac33->mutex);
900ad05c03bSPeter Ujfalusi 		return 0;
901ad05c03bSPeter Ujfalusi 	}
902ad05c03bSPeter Ujfalusi 
903cd21ac8cSKuninori Morimoto 	dac33_soft_power(component, 0);
904cd21ac8cSKuninori Morimoto 	dac33_soft_power(component, 1);
905c8bf93f0SPeter Ujfalusi 
906cd21ac8cSKuninori Morimoto 	reg_tmp = dac33_read_reg_cache(component, DAC33_INT_OSC_CTRL);
907cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_INT_OSC_CTRL, reg_tmp);
908c8bf93f0SPeter Ujfalusi 
909c8bf93f0SPeter Ujfalusi 	/* Write registers 0x08 and 0x09 (MSB, LSB) */
910cd21ac8cSKuninori Morimoto 	dac33_write16(component, DAC33_INT_OSC_FREQ_RAT_A, oscset);
911c8bf93f0SPeter Ujfalusi 
91282a58a8bSPeter Ujfalusi 	/* OSC calibration time */
913cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_CALIB_TIME, 96);
914c8bf93f0SPeter Ujfalusi 
915c8bf93f0SPeter Ujfalusi 	/* adjustment treshold & step */
916cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) |
917c8bf93f0SPeter Ujfalusi 						 DAC33_ADJSTEP(1));
918c8bf93f0SPeter Ujfalusi 
919c8bf93f0SPeter Ujfalusi 	/* div=4 / gain=1 / div */
920cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_INT_OSC_CTRL_C, DAC33_REFDIV(4));
921c8bf93f0SPeter Ujfalusi 
922cd21ac8cSKuninori Morimoto 	pwr_ctrl = dac33_read_reg_cache(component, DAC33_PWR_CTRL);
923c8bf93f0SPeter Ujfalusi 	pwr_ctrl |= DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB;
924cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_PWR_CTRL, pwr_ctrl);
925c8bf93f0SPeter Ujfalusi 
926cd21ac8cSKuninori Morimoto 	dac33_oscwait(component);
927c8bf93f0SPeter Ujfalusi 
9287427b4b9SPeter Ujfalusi 	if (dac33->fifo_mode) {
929aec242dcSPeter Ujfalusi 		/* Generic for all FIFO modes */
930c8bf93f0SPeter Ujfalusi 		/* 50-51 : ASRC Control registers */
931cd21ac8cSKuninori Morimoto 		dac33_write(component, DAC33_ASRC_CTRL_A, DAC33_SRCLKDIV(1));
932cd21ac8cSKuninori Morimoto 		dac33_write(component, DAC33_ASRC_CTRL_B, 1); /* ??? */
933c8bf93f0SPeter Ujfalusi 
934c8bf93f0SPeter Ujfalusi 		/* Write registers 0x34 and 0x35 (MSB, LSB) */
935cd21ac8cSKuninori Morimoto 		dac33_write16(component, DAC33_SRC_REF_CLK_RATIO_A, ratioset);
936c8bf93f0SPeter Ujfalusi 
937c8bf93f0SPeter Ujfalusi 		/* Set interrupts to high active */
938cd21ac8cSKuninori Morimoto 		dac33_write(component, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH);
939c8bf93f0SPeter Ujfalusi 	} else {
940aec242dcSPeter Ujfalusi 		/* FIFO bypass mode */
941c8bf93f0SPeter Ujfalusi 		/* 50-51 : ASRC Control registers */
942cd21ac8cSKuninori Morimoto 		dac33_write(component, DAC33_ASRC_CTRL_A, DAC33_SRCBYP);
943cd21ac8cSKuninori Morimoto 		dac33_write(component, DAC33_ASRC_CTRL_B, 0); /* ??? */
944c8bf93f0SPeter Ujfalusi 	}
945c8bf93f0SPeter Ujfalusi 
946aec242dcSPeter Ujfalusi 	/* Interrupt behaviour configuration */
947aec242dcSPeter Ujfalusi 	switch (dac33->fifo_mode) {
948aec242dcSPeter Ujfalusi 	case DAC33_FIFO_MODE1:
949cd21ac8cSKuninori Morimoto 		dac33_write(component, DAC33_FIFO_IRQ_MODE_B,
950aec242dcSPeter Ujfalusi 			    DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
951aec242dcSPeter Ujfalusi 		break;
95228e05d98SPeter Ujfalusi 	case DAC33_FIFO_MODE7:
953cd21ac8cSKuninori Morimoto 		dac33_write(component, DAC33_FIFO_IRQ_MODE_A,
954f57d2cfaSPeter Ujfalusi 			DAC33_UTM(DAC33_FIFO_IRQ_MODE_LEVEL));
95528e05d98SPeter Ujfalusi 		break;
956aec242dcSPeter Ujfalusi 	default:
957aec242dcSPeter Ujfalusi 		/* in FIFO bypass mode, the interrupts are not used */
958aec242dcSPeter Ujfalusi 		break;
959aec242dcSPeter Ujfalusi 	}
960aec242dcSPeter Ujfalusi 
961cd21ac8cSKuninori Morimoto 	aictrl_b = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_B);
962aec242dcSPeter Ujfalusi 
963aec242dcSPeter Ujfalusi 	switch (dac33->fifo_mode) {
964aec242dcSPeter Ujfalusi 	case DAC33_FIFO_MODE1:
965aec242dcSPeter Ujfalusi 		/*
966aec242dcSPeter Ujfalusi 		 * For mode1:
967aec242dcSPeter Ujfalusi 		 * Disable the FIFO bypass (Enable the use of FIFO)
968aec242dcSPeter Ujfalusi 		 * Select nSample mode
969aec242dcSPeter Ujfalusi 		 * BCLK is only running when data is needed by DAC33
970aec242dcSPeter Ujfalusi 		 */
971c8bf93f0SPeter Ujfalusi 		fifoctrl_a &= ~DAC33_FBYPAS;
972aec242dcSPeter Ujfalusi 		fifoctrl_a &= ~DAC33_FAUTO;
973eeb309a8SPeter Ujfalusi 		if (dac33->keep_bclk)
974eeb309a8SPeter Ujfalusi 			aictrl_b |= DAC33_BCLKON;
975eeb309a8SPeter Ujfalusi 		else
976aec242dcSPeter Ujfalusi 			aictrl_b &= ~DAC33_BCLKON;
977aec242dcSPeter Ujfalusi 		break;
97828e05d98SPeter Ujfalusi 	case DAC33_FIFO_MODE7:
97928e05d98SPeter Ujfalusi 		/*
98028e05d98SPeter Ujfalusi 		 * For mode1:
98128e05d98SPeter Ujfalusi 		 * Disable the FIFO bypass (Enable the use of FIFO)
98228e05d98SPeter Ujfalusi 		 * Select Threshold mode
98328e05d98SPeter Ujfalusi 		 * BCLK is only running when data is needed by DAC33
98428e05d98SPeter Ujfalusi 		 */
98528e05d98SPeter Ujfalusi 		fifoctrl_a &= ~DAC33_FBYPAS;
98628e05d98SPeter Ujfalusi 		fifoctrl_a |= DAC33_FAUTO;
987eeb309a8SPeter Ujfalusi 		if (dac33->keep_bclk)
988eeb309a8SPeter Ujfalusi 			aictrl_b |= DAC33_BCLKON;
989eeb309a8SPeter Ujfalusi 		else
99028e05d98SPeter Ujfalusi 			aictrl_b &= ~DAC33_BCLKON;
99128e05d98SPeter Ujfalusi 		break;
992aec242dcSPeter Ujfalusi 	default:
993aec242dcSPeter Ujfalusi 		/*
994aec242dcSPeter Ujfalusi 		 * For FIFO bypass mode:
995aec242dcSPeter Ujfalusi 		 * Enable the FIFO bypass (Disable the FIFO use)
99625985edcSLucas De Marchi 		 * Set the BCLK as continuous
997aec242dcSPeter Ujfalusi 		 */
998c8bf93f0SPeter Ujfalusi 		fifoctrl_a |= DAC33_FBYPAS;
999aec242dcSPeter Ujfalusi 		aictrl_b |= DAC33_BCLKON;
1000aec242dcSPeter Ujfalusi 		break;
1001aec242dcSPeter Ujfalusi 	}
1002aec242dcSPeter Ujfalusi 
1003cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_FIFO_CTRL_A, fifoctrl_a);
1004cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
1005cd21ac8cSKuninori Morimoto 	dac33_write(component, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
1006c8bf93f0SPeter Ujfalusi 
10076aceabb4SPeter Ujfalusi 	/*
10086aceabb4SPeter Ujfalusi 	 * BCLK divide ratio
10096aceabb4SPeter Ujfalusi 	 * 0: 1.5
10106aceabb4SPeter Ujfalusi 	 * 1: 1
10116aceabb4SPeter Ujfalusi 	 * 2: 2
10126aceabb4SPeter Ujfalusi 	 * ...
10136aceabb4SPeter Ujfalusi 	 * 254: 254
10146aceabb4SPeter Ujfalusi 	 * 255: 255
10156aceabb4SPeter Ujfalusi 	 */
10166cd6cedeSPeter Ujfalusi 	if (dac33->fifo_mode)
1017cd21ac8cSKuninori Morimoto 		dac33_write(component, DAC33_SER_AUDIOIF_CTRL_C,
10186aceabb4SPeter Ujfalusi 							dac33->burst_bclkdiv);
10196cd6cedeSPeter Ujfalusi 	else
10200d99d2b0SPeter Ujfalusi 		if (substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE)
1021cd21ac8cSKuninori Morimoto 			dac33_write(component, DAC33_SER_AUDIOIF_CTRL_C, 32);
10220d99d2b0SPeter Ujfalusi 		else
1023cd21ac8cSKuninori Morimoto 			dac33_write(component, DAC33_SER_AUDIOIF_CTRL_C, 16);
10246cd6cedeSPeter Ujfalusi 
1025aec242dcSPeter Ujfalusi 	switch (dac33->fifo_mode) {
1026aec242dcSPeter Ujfalusi 	case DAC33_FIFO_MODE1:
1027cd21ac8cSKuninori Morimoto 		dac33_write16(component, DAC33_ATHR_MSB,
1028c8bf93f0SPeter Ujfalusi 			      DAC33_THRREG(dac33->alarm_threshold));
1029aec242dcSPeter Ujfalusi 		break;
103028e05d98SPeter Ujfalusi 	case DAC33_FIFO_MODE7:
103128e05d98SPeter Ujfalusi 		/*
103228e05d98SPeter Ujfalusi 		 * Configure the threshold levels, and leave 10 sample space
103328e05d98SPeter Ujfalusi 		 * at the bottom, and also at the top of the FIFO
103428e05d98SPeter Ujfalusi 		 */
1035cd21ac8cSKuninori Morimoto 		dac33_write16(component, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr));
1036cd21ac8cSKuninori Morimoto 		dac33_write16(component, DAC33_LTHR_MSB,
1037549675edSPeter Ujfalusi 			      DAC33_THRREG(DAC33_MODE7_MARGIN));
103828e05d98SPeter Ujfalusi 		break;
1039aec242dcSPeter Ujfalusi 	default:
1040aec242dcSPeter Ujfalusi 		break;
1041c8bf93f0SPeter Ujfalusi 	}
1042c8bf93f0SPeter Ujfalusi 
1043c8bf93f0SPeter Ujfalusi 	mutex_unlock(&dac33->mutex);
1044c8bf93f0SPeter Ujfalusi 
1045c8bf93f0SPeter Ujfalusi 	return 0;
1046c8bf93f0SPeter Ujfalusi }
1047c8bf93f0SPeter Ujfalusi 
dac33_calculate_times(struct snd_pcm_substream * substream,struct snd_soc_component * component)1048e6968a17SMark Brown static void dac33_calculate_times(struct snd_pcm_substream *substream,
1049cd21ac8cSKuninori Morimoto 				  struct snd_soc_component *component)
1050c8bf93f0SPeter Ujfalusi {
1051cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
1052f430a27fSPeter Ujfalusi 	unsigned int period_size = substream->runtime->period_size;
1053f430a27fSPeter Ujfalusi 	unsigned int rate = substream->runtime->rate;
1054c8bf93f0SPeter Ujfalusi 	unsigned int nsample_limit;
1055c8bf93f0SPeter Ujfalusi 
105655abb59cSPeter Ujfalusi 	/* In bypass mode we don't need to calculate */
105755abb59cSPeter Ujfalusi 	if (!dac33->fifo_mode)
105855abb59cSPeter Ujfalusi 		return;
105955abb59cSPeter Ujfalusi 
1060f430a27fSPeter Ujfalusi 	switch (dac33->fifo_mode) {
1061f430a27fSPeter Ujfalusi 	case DAC33_FIFO_MODE1:
1062f430a27fSPeter Ujfalusi 		/* Number of samples under i2c latency */
1063f430a27fSPeter Ujfalusi 		dac33->alarm_threshold = US_TO_SAMPLES(rate,
1064f430a27fSPeter Ujfalusi 						dac33->mode1_latency);
1065549675edSPeter Ujfalusi 		nsample_limit = dac33->fifo_size - dac33->alarm_threshold;
10661bc13b2eSPeter Ujfalusi 
1067a577b318SPeter Ujfalusi 		if (period_size <= dac33->alarm_threshold)
1068a577b318SPeter Ujfalusi 			/*
1069a577b318SPeter Ujfalusi 			 * Configure nSamaple to number of periods,
1070a577b318SPeter Ujfalusi 			 * which covers the latency requironment.
1071a577b318SPeter Ujfalusi 			 */
1072a577b318SPeter Ujfalusi 			dac33->nsample = period_size *
1073a577b318SPeter Ujfalusi 				((dac33->alarm_threshold / period_size) +
107439e69cefSPierre-Louis Bossart 				 ((dac33->alarm_threshold % period_size) ?
1075a577b318SPeter Ujfalusi 				1 : 0));
10761bc13b2eSPeter Ujfalusi 		else if (period_size > nsample_limit)
10771bc13b2eSPeter Ujfalusi 			dac33->nsample = nsample_limit;
1078a577b318SPeter Ujfalusi 		else
1079a577b318SPeter Ujfalusi 			dac33->nsample = period_size;
1080f57d2cfaSPeter Ujfalusi 
1081f57d2cfaSPeter Ujfalusi 		dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
1082f57d2cfaSPeter Ujfalusi 						      dac33->nsample);
1083f57d2cfaSPeter Ujfalusi 		dac33->t_stamp1 = 0;
1084f57d2cfaSPeter Ujfalusi 		dac33->t_stamp2 = 0;
1085f57d2cfaSPeter Ujfalusi 		break;
1086f57d2cfaSPeter Ujfalusi 	case DAC33_FIFO_MODE7:
10873591f4cdSPeter Ujfalusi 		dac33->uthr = UTHR_FROM_PERIOD_SIZE(period_size, rate,
1088a577b318SPeter Ujfalusi 						    dac33->burst_rate) + 9;
1089549675edSPeter Ujfalusi 		if (dac33->uthr > (dac33->fifo_size - DAC33_MODE7_MARGIN))
1090549675edSPeter Ujfalusi 			dac33->uthr = dac33->fifo_size - DAC33_MODE7_MARGIN;
1091549675edSPeter Ujfalusi 		if (dac33->uthr < (DAC33_MODE7_MARGIN + 10))
1092549675edSPeter Ujfalusi 			dac33->uthr = (DAC33_MODE7_MARGIN + 10);
10933591f4cdSPeter Ujfalusi 
1094f57d2cfaSPeter Ujfalusi 		dac33->mode7_us_to_lthr =
1095f57d2cfaSPeter Ujfalusi 				SAMPLES_TO_US(substream->runtime->rate,
1096549675edSPeter Ujfalusi 					dac33->uthr - DAC33_MODE7_MARGIN + 1);
1097f57d2cfaSPeter Ujfalusi 		dac33->t_stamp1 = 0;
1098f57d2cfaSPeter Ujfalusi 		break;
1099f57d2cfaSPeter Ujfalusi 	default:
1100f57d2cfaSPeter Ujfalusi 		break;
1101c8bf93f0SPeter Ujfalusi 	}
1102c8bf93f0SPeter Ujfalusi 
1103c8bf93f0SPeter Ujfalusi }
1104c8bf93f0SPeter Ujfalusi 
dac33_pcm_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)1105c8bf93f0SPeter Ujfalusi static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
1106c8bf93f0SPeter Ujfalusi 			     struct snd_soc_dai *dai)
1107c8bf93f0SPeter Ujfalusi {
1108cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component = dai->component;
1109cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
1110c8bf93f0SPeter Ujfalusi 	int ret = 0;
1111c8bf93f0SPeter Ujfalusi 
1112c8bf93f0SPeter Ujfalusi 	switch (cmd) {
1113c8bf93f0SPeter Ujfalusi 	case SNDRV_PCM_TRIGGER_START:
1114c8bf93f0SPeter Ujfalusi 	case SNDRV_PCM_TRIGGER_RESUME:
1115c8bf93f0SPeter Ujfalusi 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
11167427b4b9SPeter Ujfalusi 		if (dac33->fifo_mode) {
1117c8bf93f0SPeter Ujfalusi 			dac33->state = DAC33_PREFILL;
111888910982SBhaktipriya Shridhar 			schedule_work(&dac33->work);
1119c8bf93f0SPeter Ujfalusi 		}
1120c8bf93f0SPeter Ujfalusi 		break;
1121c8bf93f0SPeter Ujfalusi 	case SNDRV_PCM_TRIGGER_STOP:
1122c8bf93f0SPeter Ujfalusi 	case SNDRV_PCM_TRIGGER_SUSPEND:
1123c8bf93f0SPeter Ujfalusi 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
11247427b4b9SPeter Ujfalusi 		if (dac33->fifo_mode) {
1125c8bf93f0SPeter Ujfalusi 			dac33->state = DAC33_FLUSH;
112688910982SBhaktipriya Shridhar 			schedule_work(&dac33->work);
1127c8bf93f0SPeter Ujfalusi 		}
1128c8bf93f0SPeter Ujfalusi 		break;
1129c8bf93f0SPeter Ujfalusi 	default:
1130c8bf93f0SPeter Ujfalusi 		ret = -EINVAL;
1131c8bf93f0SPeter Ujfalusi 	}
1132c8bf93f0SPeter Ujfalusi 
1133c8bf93f0SPeter Ujfalusi 	return ret;
1134c8bf93f0SPeter Ujfalusi }
1135c8bf93f0SPeter Ujfalusi 
dac33_dai_delay(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)1136f57d2cfaSPeter Ujfalusi static snd_pcm_sframes_t dac33_dai_delay(
1137f57d2cfaSPeter Ujfalusi 			struct snd_pcm_substream *substream,
1138f57d2cfaSPeter Ujfalusi 			struct snd_soc_dai *dai)
1139f57d2cfaSPeter Ujfalusi {
1140cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component = dai->component;
1141cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
1142f57d2cfaSPeter Ujfalusi 	unsigned long long t0, t1, t_now;
11439d7db2b2SPeter Ujfalusi 	unsigned int time_delta, uthr;
1144f57d2cfaSPeter Ujfalusi 	int samples_out, samples_in, samples;
1145f57d2cfaSPeter Ujfalusi 	snd_pcm_sframes_t delay = 0;
1146a3b55791SPeter Ujfalusi 	unsigned long flags;
1147f57d2cfaSPeter Ujfalusi 
1148f57d2cfaSPeter Ujfalusi 	switch (dac33->fifo_mode) {
1149f57d2cfaSPeter Ujfalusi 	case DAC33_FIFO_BYPASS:
1150f57d2cfaSPeter Ujfalusi 		break;
1151f57d2cfaSPeter Ujfalusi 	case DAC33_FIFO_MODE1:
1152a3b55791SPeter Ujfalusi 		spin_lock_irqsave(&dac33->lock, flags);
1153f57d2cfaSPeter Ujfalusi 		t0 = dac33->t_stamp1;
1154f57d2cfaSPeter Ujfalusi 		t1 = dac33->t_stamp2;
1155a3b55791SPeter Ujfalusi 		spin_unlock_irqrestore(&dac33->lock, flags);
1156f57d2cfaSPeter Ujfalusi 		t_now = ktime_to_us(ktime_get());
1157f57d2cfaSPeter Ujfalusi 
1158f57d2cfaSPeter Ujfalusi 		/* We have not started to fill the FIFO yet, delay is 0 */
1159f57d2cfaSPeter Ujfalusi 		if (!t1)
1160f57d2cfaSPeter Ujfalusi 			goto out;
1161f57d2cfaSPeter Ujfalusi 
1162f57d2cfaSPeter Ujfalusi 		if (t0 > t1) {
1163f57d2cfaSPeter Ujfalusi 			/*
1164f57d2cfaSPeter Ujfalusi 			 * Phase 1:
1165f57d2cfaSPeter Ujfalusi 			 * After Alarm threshold, and before nSample write
1166f57d2cfaSPeter Ujfalusi 			 */
1167f57d2cfaSPeter Ujfalusi 			time_delta = t_now - t0;
1168f57d2cfaSPeter Ujfalusi 			samples_out = time_delta ? US_TO_SAMPLES(
1169f57d2cfaSPeter Ujfalusi 						substream->runtime->rate,
1170f57d2cfaSPeter Ujfalusi 						time_delta) : 0;
1171f57d2cfaSPeter Ujfalusi 
1172f57d2cfaSPeter Ujfalusi 			if (likely(dac33->alarm_threshold > samples_out))
1173f57d2cfaSPeter Ujfalusi 				delay = dac33->alarm_threshold - samples_out;
1174f57d2cfaSPeter Ujfalusi 			else
1175f57d2cfaSPeter Ujfalusi 				delay = 0;
1176f57d2cfaSPeter Ujfalusi 		} else if ((t_now - t1) <= dac33->mode1_us_burst) {
1177f57d2cfaSPeter Ujfalusi 			/*
1178f57d2cfaSPeter Ujfalusi 			 * Phase 2:
1179f57d2cfaSPeter Ujfalusi 			 * After nSample write (during burst operation)
1180f57d2cfaSPeter Ujfalusi 			 */
1181f57d2cfaSPeter Ujfalusi 			time_delta = t_now - t0;
1182f57d2cfaSPeter Ujfalusi 			samples_out = time_delta ? US_TO_SAMPLES(
1183f57d2cfaSPeter Ujfalusi 						substream->runtime->rate,
1184f57d2cfaSPeter Ujfalusi 						time_delta) : 0;
1185f57d2cfaSPeter Ujfalusi 
1186f57d2cfaSPeter Ujfalusi 			time_delta = t_now - t1;
1187f57d2cfaSPeter Ujfalusi 			samples_in = time_delta ? US_TO_SAMPLES(
1188f57d2cfaSPeter Ujfalusi 						dac33->burst_rate,
1189f57d2cfaSPeter Ujfalusi 						time_delta) : 0;
1190f57d2cfaSPeter Ujfalusi 
1191f57d2cfaSPeter Ujfalusi 			samples = dac33->alarm_threshold;
1192f57d2cfaSPeter Ujfalusi 			samples += (samples_in - samples_out);
1193f57d2cfaSPeter Ujfalusi 
1194f57d2cfaSPeter Ujfalusi 			if (likely(samples > 0))
1195f57d2cfaSPeter Ujfalusi 				delay = samples;
1196f57d2cfaSPeter Ujfalusi 			else
1197f57d2cfaSPeter Ujfalusi 				delay = 0;
1198f57d2cfaSPeter Ujfalusi 		} else {
1199f57d2cfaSPeter Ujfalusi 			/*
1200f57d2cfaSPeter Ujfalusi 			 * Phase 3:
1201f57d2cfaSPeter Ujfalusi 			 * After burst operation, before next alarm threshold
1202f57d2cfaSPeter Ujfalusi 			 */
1203f57d2cfaSPeter Ujfalusi 			time_delta = t_now - t0;
1204f57d2cfaSPeter Ujfalusi 			samples_out = time_delta ? US_TO_SAMPLES(
1205f57d2cfaSPeter Ujfalusi 						substream->runtime->rate,
1206f57d2cfaSPeter Ujfalusi 						time_delta) : 0;
1207f57d2cfaSPeter Ujfalusi 
1208f57d2cfaSPeter Ujfalusi 			samples_in = dac33->nsample;
1209f57d2cfaSPeter Ujfalusi 			samples = dac33->alarm_threshold;
1210f57d2cfaSPeter Ujfalusi 			samples += (samples_in - samples_out);
1211f57d2cfaSPeter Ujfalusi 
1212f57d2cfaSPeter Ujfalusi 			if (likely(samples > 0))
1213549675edSPeter Ujfalusi 				delay = samples > dac33->fifo_size ?
1214549675edSPeter Ujfalusi 					dac33->fifo_size : samples;
1215f57d2cfaSPeter Ujfalusi 			else
1216f57d2cfaSPeter Ujfalusi 				delay = 0;
1217f57d2cfaSPeter Ujfalusi 		}
1218f57d2cfaSPeter Ujfalusi 		break;
1219f57d2cfaSPeter Ujfalusi 	case DAC33_FIFO_MODE7:
1220a3b55791SPeter Ujfalusi 		spin_lock_irqsave(&dac33->lock, flags);
1221f57d2cfaSPeter Ujfalusi 		t0 = dac33->t_stamp1;
12229d7db2b2SPeter Ujfalusi 		uthr = dac33->uthr;
1223a3b55791SPeter Ujfalusi 		spin_unlock_irqrestore(&dac33->lock, flags);
1224f57d2cfaSPeter Ujfalusi 		t_now = ktime_to_us(ktime_get());
1225f57d2cfaSPeter Ujfalusi 
1226f57d2cfaSPeter Ujfalusi 		/* We have not started to fill the FIFO yet, delay is 0 */
1227f57d2cfaSPeter Ujfalusi 		if (!t0)
1228f57d2cfaSPeter Ujfalusi 			goto out;
1229f57d2cfaSPeter Ujfalusi 
1230f57d2cfaSPeter Ujfalusi 		if (t_now <= t0) {
1231f57d2cfaSPeter Ujfalusi 			/*
1232f57d2cfaSPeter Ujfalusi 			 * Either the timestamps are messed or equal. Report
1233f57d2cfaSPeter Ujfalusi 			 * maximum delay
1234f57d2cfaSPeter Ujfalusi 			 */
12359d7db2b2SPeter Ujfalusi 			delay = uthr;
1236f57d2cfaSPeter Ujfalusi 			goto out;
1237f57d2cfaSPeter Ujfalusi 		}
1238f57d2cfaSPeter Ujfalusi 
1239f57d2cfaSPeter Ujfalusi 		time_delta = t_now - t0;
1240f57d2cfaSPeter Ujfalusi 		if (time_delta <= dac33->mode7_us_to_lthr) {
1241f57d2cfaSPeter Ujfalusi 			/*
1242f57d2cfaSPeter Ujfalusi 			* Phase 1:
1243f57d2cfaSPeter Ujfalusi 			* After burst (draining phase)
1244f57d2cfaSPeter Ujfalusi 			*/
1245f57d2cfaSPeter Ujfalusi 			samples_out = US_TO_SAMPLES(
1246f57d2cfaSPeter Ujfalusi 					substream->runtime->rate,
1247f57d2cfaSPeter Ujfalusi 					time_delta);
1248f57d2cfaSPeter Ujfalusi 
12499d7db2b2SPeter Ujfalusi 			if (likely(uthr > samples_out))
12509d7db2b2SPeter Ujfalusi 				delay = uthr - samples_out;
1251f57d2cfaSPeter Ujfalusi 			else
1252f57d2cfaSPeter Ujfalusi 				delay = 0;
1253f57d2cfaSPeter Ujfalusi 		} else {
1254f57d2cfaSPeter Ujfalusi 			/*
1255f57d2cfaSPeter Ujfalusi 			* Phase 2:
1256f57d2cfaSPeter Ujfalusi 			* During burst operation
1257f57d2cfaSPeter Ujfalusi 			*/
1258f57d2cfaSPeter Ujfalusi 			time_delta = time_delta - dac33->mode7_us_to_lthr;
1259f57d2cfaSPeter Ujfalusi 
1260f57d2cfaSPeter Ujfalusi 			samples_out = US_TO_SAMPLES(
1261f57d2cfaSPeter Ujfalusi 					substream->runtime->rate,
1262f57d2cfaSPeter Ujfalusi 					time_delta);
1263f57d2cfaSPeter Ujfalusi 			samples_in = US_TO_SAMPLES(
1264f57d2cfaSPeter Ujfalusi 					dac33->burst_rate,
1265f57d2cfaSPeter Ujfalusi 					time_delta);
1266549675edSPeter Ujfalusi 			delay = DAC33_MODE7_MARGIN + samples_in - samples_out;
1267f57d2cfaSPeter Ujfalusi 
12689d7db2b2SPeter Ujfalusi 			if (unlikely(delay > uthr))
12699d7db2b2SPeter Ujfalusi 				delay = uthr;
1270f57d2cfaSPeter Ujfalusi 		}
1271f57d2cfaSPeter Ujfalusi 		break;
1272f57d2cfaSPeter Ujfalusi 	default:
1273cd21ac8cSKuninori Morimoto 		dev_warn(component->dev, "Unhandled FIFO mode: %d\n",
1274f57d2cfaSPeter Ujfalusi 							dac33->fifo_mode);
1275f57d2cfaSPeter Ujfalusi 		break;
1276f57d2cfaSPeter Ujfalusi 	}
1277f57d2cfaSPeter Ujfalusi out:
1278f57d2cfaSPeter Ujfalusi 	return delay;
1279f57d2cfaSPeter Ujfalusi }
1280f57d2cfaSPeter Ujfalusi 
dac33_set_dai_sysclk(struct snd_soc_dai * codec_dai,int clk_id,unsigned int freq,int dir)1281c8bf93f0SPeter Ujfalusi static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1282c8bf93f0SPeter Ujfalusi 		int clk_id, unsigned int freq, int dir)
1283c8bf93f0SPeter Ujfalusi {
1284cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component = codec_dai->component;
1285cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
1286c8bf93f0SPeter Ujfalusi 	u8 ioc_reg, asrcb_reg;
1287c8bf93f0SPeter Ujfalusi 
1288cd21ac8cSKuninori Morimoto 	ioc_reg = dac33_read_reg_cache(component, DAC33_INT_OSC_CTRL);
1289cd21ac8cSKuninori Morimoto 	asrcb_reg = dac33_read_reg_cache(component, DAC33_ASRC_CTRL_B);
1290c8bf93f0SPeter Ujfalusi 	switch (clk_id) {
1291c8bf93f0SPeter Ujfalusi 	case TLV320DAC33_MCLK:
1292c8bf93f0SPeter Ujfalusi 		ioc_reg |= DAC33_REFSEL;
1293c8bf93f0SPeter Ujfalusi 		asrcb_reg |= DAC33_SRCREFSEL;
1294c8bf93f0SPeter Ujfalusi 		break;
1295c8bf93f0SPeter Ujfalusi 	case TLV320DAC33_SLEEPCLK:
1296c8bf93f0SPeter Ujfalusi 		ioc_reg &= ~DAC33_REFSEL;
1297c8bf93f0SPeter Ujfalusi 		asrcb_reg &= ~DAC33_SRCREFSEL;
1298c8bf93f0SPeter Ujfalusi 		break;
1299c8bf93f0SPeter Ujfalusi 	default:
1300cd21ac8cSKuninori Morimoto 		dev_err(component->dev, "Invalid clock ID (%d)\n", clk_id);
1301c8bf93f0SPeter Ujfalusi 		break;
1302c8bf93f0SPeter Ujfalusi 	}
1303c8bf93f0SPeter Ujfalusi 	dac33->refclk = freq;
1304c8bf93f0SPeter Ujfalusi 
1305cd21ac8cSKuninori Morimoto 	dac33_write_reg_cache(component, DAC33_INT_OSC_CTRL, ioc_reg);
1306cd21ac8cSKuninori Morimoto 	dac33_write_reg_cache(component, DAC33_ASRC_CTRL_B, asrcb_reg);
1307c8bf93f0SPeter Ujfalusi 
1308c8bf93f0SPeter Ujfalusi 	return 0;
1309c8bf93f0SPeter Ujfalusi }
1310c8bf93f0SPeter Ujfalusi 
dac33_set_dai_fmt(struct snd_soc_dai * codec_dai,unsigned int fmt)1311c8bf93f0SPeter Ujfalusi static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
1312c8bf93f0SPeter Ujfalusi 			     unsigned int fmt)
1313c8bf93f0SPeter Ujfalusi {
1314cd21ac8cSKuninori Morimoto 	struct snd_soc_component *component = codec_dai->component;
1315cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
1316c8bf93f0SPeter Ujfalusi 	u8 aictrl_a, aictrl_b;
1317c8bf93f0SPeter Ujfalusi 
1318cd21ac8cSKuninori Morimoto 	aictrl_a = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_A);
1319cd21ac8cSKuninori Morimoto 	aictrl_b = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_B);
1320894bf75bSMark Brown 
1321894bf75bSMark Brown 	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
1322894bf75bSMark Brown 	case SND_SOC_DAIFMT_CBP_CFP:
1323c8bf93f0SPeter Ujfalusi 		aictrl_a |= (DAC33_MSBCLK | DAC33_MSWCLK);
1324c8bf93f0SPeter Ujfalusi 		break;
1325894bf75bSMark Brown 	case SND_SOC_DAIFMT_CBC_CFC:
1326adcb8bc0SPeter Ujfalusi 		if (dac33->fifo_mode) {
1327894bf75bSMark Brown 			dev_err(component->dev, "FIFO mode requires provider mode\n");
1328adcb8bc0SPeter Ujfalusi 			return -EINVAL;
1329adcb8bc0SPeter Ujfalusi 		} else
1330c8bf93f0SPeter Ujfalusi 			aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK);
1331c8bf93f0SPeter Ujfalusi 		break;
1332c8bf93f0SPeter Ujfalusi 	default:
1333c8bf93f0SPeter Ujfalusi 		return -EINVAL;
1334c8bf93f0SPeter Ujfalusi 	}
1335c8bf93f0SPeter Ujfalusi 
1336c8bf93f0SPeter Ujfalusi 	aictrl_a &= ~DAC33_AFMT_MASK;
1337c8bf93f0SPeter Ujfalusi 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1338c8bf93f0SPeter Ujfalusi 	case SND_SOC_DAIFMT_I2S:
1339c8bf93f0SPeter Ujfalusi 		aictrl_a |= DAC33_AFMT_I2S;
1340c8bf93f0SPeter Ujfalusi 		break;
1341c8bf93f0SPeter Ujfalusi 	case SND_SOC_DAIFMT_DSP_A:
1342c8bf93f0SPeter Ujfalusi 		aictrl_a |= DAC33_AFMT_DSP;
1343c8bf93f0SPeter Ujfalusi 		aictrl_b &= ~DAC33_DATA_DELAY_MASK;
134444f497b4SPeter Ujfalusi 		aictrl_b |= DAC33_DATA_DELAY(0);
1345c8bf93f0SPeter Ujfalusi 		break;
1346c8bf93f0SPeter Ujfalusi 	case SND_SOC_DAIFMT_RIGHT_J:
1347c8bf93f0SPeter Ujfalusi 		aictrl_a |= DAC33_AFMT_RIGHT_J;
1348c8bf93f0SPeter Ujfalusi 		break;
1349c8bf93f0SPeter Ujfalusi 	case SND_SOC_DAIFMT_LEFT_J:
1350c8bf93f0SPeter Ujfalusi 		aictrl_a |= DAC33_AFMT_LEFT_J;
1351c8bf93f0SPeter Ujfalusi 		break;
1352c8bf93f0SPeter Ujfalusi 	default:
1353cd21ac8cSKuninori Morimoto 		dev_err(component->dev, "Unsupported format (%u)\n",
1354c8bf93f0SPeter Ujfalusi 			fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1355c8bf93f0SPeter Ujfalusi 		return -EINVAL;
1356c8bf93f0SPeter Ujfalusi 	}
1357c8bf93f0SPeter Ujfalusi 
1358cd21ac8cSKuninori Morimoto 	dac33_write_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
1359cd21ac8cSKuninori Morimoto 	dac33_write_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
1360c8bf93f0SPeter Ujfalusi 
1361c8bf93f0SPeter Ujfalusi 	return 0;
1362c8bf93f0SPeter Ujfalusi }
1363c8bf93f0SPeter Ujfalusi 
dac33_soc_probe(struct snd_soc_component * component)1364cd21ac8cSKuninori Morimoto static int dac33_soc_probe(struct snd_soc_component *component)
1365c8bf93f0SPeter Ujfalusi {
1366cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
1367c8bf93f0SPeter Ujfalusi 	int ret = 0;
1368c8bf93f0SPeter Ujfalusi 
1369cd21ac8cSKuninori Morimoto 	dac33->component = component;
1370c8bf93f0SPeter Ujfalusi 
1371f0fba2adSLiam Girdwood 	/* Read the tlv320dac33 ID registers */
1372cd21ac8cSKuninori Morimoto 	ret = dac33_hard_power(component, 1);
1373f0fba2adSLiam Girdwood 	if (ret != 0) {
1374cd21ac8cSKuninori Morimoto 		dev_err(component->dev, "Failed to power up component: %d\n", ret);
1375f0fba2adSLiam Girdwood 		goto err_power;
1376f0fba2adSLiam Girdwood 	}
1377cd21ac8cSKuninori Morimoto 	ret = dac33_read_id(component);
1378cd21ac8cSKuninori Morimoto 	dac33_hard_power(component, 0);
1379c8bf93f0SPeter Ujfalusi 
1380911a0f0bSPeter Ujfalusi 	if (ret < 0) {
1381cd21ac8cSKuninori Morimoto 		dev_err(component->dev, "Failed to read chip ID: %d\n", ret);
1382911a0f0bSPeter Ujfalusi 		ret = -ENODEV;
1383911a0f0bSPeter Ujfalusi 		goto err_power;
1384911a0f0bSPeter Ujfalusi 	}
1385911a0f0bSPeter Ujfalusi 
1386f0fba2adSLiam Girdwood 	/* Check if the IRQ number is valid and request it */
1387f0fba2adSLiam Girdwood 	if (dac33->irq >= 0) {
1388f0fba2adSLiam Girdwood 		ret = request_irq(dac33->irq, dac33_interrupt_handler,
138988e24c3aSYong Zhang 				  IRQF_TRIGGER_RISING,
1390cd21ac8cSKuninori Morimoto 				  component->name, component);
1391c8bf93f0SPeter Ujfalusi 		if (ret < 0) {
1392cd21ac8cSKuninori Morimoto 			dev_err(component->dev, "Could not request IRQ%d (%d)\n",
1393f0fba2adSLiam Girdwood 						dac33->irq, ret);
1394f0fba2adSLiam Girdwood 			dac33->irq = -1;
1395f0fba2adSLiam Girdwood 		}
1396f0fba2adSLiam Girdwood 		if (dac33->irq != -1) {
1397f0fba2adSLiam Girdwood 			INIT_WORK(&dac33->work, dac33_work);
1398f0fba2adSLiam Girdwood 		}
1399c8bf93f0SPeter Ujfalusi 	}
1400c8bf93f0SPeter Ujfalusi 
1401a577b318SPeter Ujfalusi 	/* Only add the FIFO controls, if we have valid IRQ number */
14023591f4cdSPeter Ujfalusi 	if (dac33->irq >= 0)
1403cd21ac8cSKuninori Morimoto 		snd_soc_add_component_controls(component, dac33_mode_snd_controls,
1404a577b318SPeter Ujfalusi 				     ARRAY_SIZE(dac33_mode_snd_controls));
14053591f4cdSPeter Ujfalusi 
1406f0fba2adSLiam Girdwood err_power:
1407c8bf93f0SPeter Ujfalusi 	return ret;
1408c8bf93f0SPeter Ujfalusi }
1409c8bf93f0SPeter Ujfalusi 
dac33_soc_remove(struct snd_soc_component * component)1410cd21ac8cSKuninori Morimoto static void dac33_soc_remove(struct snd_soc_component *component)
1411c8bf93f0SPeter Ujfalusi {
1412cd21ac8cSKuninori Morimoto 	struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
1413c8bf93f0SPeter Ujfalusi 
1414f0fba2adSLiam Girdwood 	if (dac33->irq >= 0) {
1415cd21ac8cSKuninori Morimoto 		free_irq(dac33->irq, dac33->component);
141688910982SBhaktipriya Shridhar 		flush_work(&dac33->work);
1417f0fba2adSLiam Girdwood 	}
1418c8bf93f0SPeter Ujfalusi }
1419c8bf93f0SPeter Ujfalusi 
1420cd21ac8cSKuninori Morimoto static const struct snd_soc_component_driver soc_component_dev_tlv320dac33 = {
14213d3dd0d3SKuninori Morimoto 	.read			= dac33_read_reg_cache,
14223d3dd0d3SKuninori Morimoto 	.write			= dac33_write_locked,
1423f0fba2adSLiam Girdwood 	.set_bias_level		= dac33_set_bias_level,
1424c8bf93f0SPeter Ujfalusi 	.probe			= dac33_soc_probe,
1425c8bf93f0SPeter Ujfalusi 	.remove			= dac33_soc_remove,
14268066eb55SPeter Ujfalusi 	.controls		= dac33_snd_controls,
14278066eb55SPeter Ujfalusi 	.num_controls		= ARRAY_SIZE(dac33_snd_controls),
14288066eb55SPeter Ujfalusi 	.dapm_widgets		= dac33_dapm_widgets,
14298066eb55SPeter Ujfalusi 	.num_dapm_widgets	= ARRAY_SIZE(dac33_dapm_widgets),
14308066eb55SPeter Ujfalusi 	.dapm_routes		= audio_map,
14318066eb55SPeter Ujfalusi 	.num_dapm_routes	= ARRAY_SIZE(audio_map),
1432cd21ac8cSKuninori Morimoto 	.use_pmdown_time	= 1,
1433cd21ac8cSKuninori Morimoto 	.endianness		= 1,
1434c8bf93f0SPeter Ujfalusi };
1435c8bf93f0SPeter Ujfalusi 
1436c8bf93f0SPeter Ujfalusi #define DAC33_RATES	(SNDRV_PCM_RATE_44100 | \
1437c8bf93f0SPeter Ujfalusi 			 SNDRV_PCM_RATE_48000)
14380d99d2b0SPeter Ujfalusi #define DAC33_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
1439c8bf93f0SPeter Ujfalusi 
144085e7652dSLars-Peter Clausen static const struct snd_soc_dai_ops dac33_dai_ops = {
14410b61d2b9SPeter Ujfalusi 	.startup	= dac33_startup,
1442c8bf93f0SPeter Ujfalusi 	.shutdown	= dac33_shutdown,
1443c8bf93f0SPeter Ujfalusi 	.hw_params	= dac33_hw_params,
1444c8bf93f0SPeter Ujfalusi 	.trigger	= dac33_pcm_trigger,
1445f57d2cfaSPeter Ujfalusi 	.delay		= dac33_dai_delay,
1446c8bf93f0SPeter Ujfalusi 	.set_sysclk	= dac33_set_dai_sysclk,
1447c8bf93f0SPeter Ujfalusi 	.set_fmt	= dac33_set_dai_fmt,
1448c8bf93f0SPeter Ujfalusi };
1449c8bf93f0SPeter Ujfalusi 
1450f0fba2adSLiam Girdwood static struct snd_soc_dai_driver dac33_dai = {
1451f0fba2adSLiam Girdwood 	.name = "tlv320dac33-hifi",
1452c8bf93f0SPeter Ujfalusi 	.playback = {
1453c8bf93f0SPeter Ujfalusi 		.stream_name = "Playback",
1454c8bf93f0SPeter Ujfalusi 		.channels_min = 2,
1455c8bf93f0SPeter Ujfalusi 		.channels_max = 2,
1456c8bf93f0SPeter Ujfalusi 		.rates = DAC33_RATES,
14573a4cbf88SMark Brown 		.formats = DAC33_FORMATS,
14588d725b2bSPeter Ujfalusi 		.sig_bits = 24,
14593a4cbf88SMark Brown 	},
1460c8bf93f0SPeter Ujfalusi 	.ops = &dac33_dai_ops,
1461c8bf93f0SPeter Ujfalusi };
1462c8bf93f0SPeter Ujfalusi 
dac33_i2c_probe(struct i2c_client * client)14639ba0daa6SStephen Kitt static int dac33_i2c_probe(struct i2c_client *client)
1464c8bf93f0SPeter Ujfalusi {
1465c8bf93f0SPeter Ujfalusi 	struct tlv320dac33_platform_data *pdata;
1466c8bf93f0SPeter Ujfalusi 	struct tlv320dac33_priv *dac33;
14673a7aaed7SIlkka Koskinen 	int ret, i;
1468c8bf93f0SPeter Ujfalusi 
1469c8bf93f0SPeter Ujfalusi 	if (client->dev.platform_data == NULL) {
1470c8bf93f0SPeter Ujfalusi 		dev_err(&client->dev, "Platform data not set\n");
1471c8bf93f0SPeter Ujfalusi 		return -ENODEV;
1472c8bf93f0SPeter Ujfalusi 	}
1473c8bf93f0SPeter Ujfalusi 	pdata = client->dev.platform_data;
1474c8bf93f0SPeter Ujfalusi 
1475a54877d7SAxel Lin 	dac33 = devm_kzalloc(&client->dev, sizeof(struct tlv320dac33_priv),
1476a54877d7SAxel Lin 			     GFP_KERNEL);
1477c8bf93f0SPeter Ujfalusi 	if (dac33 == NULL)
1478c8bf93f0SPeter Ujfalusi 		return -ENOMEM;
1479c8bf93f0SPeter Ujfalusi 
1480c4305af4SKuninori Morimoto 	dac33->reg_cache = devm_kmemdup(&client->dev,
1481c4305af4SKuninori Morimoto 					dac33_reg,
1482c4305af4SKuninori Morimoto 					ARRAY_SIZE(dac33_reg) * sizeof(u8),
1483c4305af4SKuninori Morimoto 					GFP_KERNEL);
1484c4305af4SKuninori Morimoto 	if (!dac33->reg_cache)
1485c4305af4SKuninori Morimoto 		return -ENOMEM;
1486c4305af4SKuninori Morimoto 
1487ce9544dcSKuninori Morimoto 	dac33->i2c = client;
1488c8bf93f0SPeter Ujfalusi 	mutex_init(&dac33->mutex);
1489f57d2cfaSPeter Ujfalusi 	spin_lock_init(&dac33->lock);
1490c8bf93f0SPeter Ujfalusi 
1491c8bf93f0SPeter Ujfalusi 	i2c_set_clientdata(client, dac33);
1492c8bf93f0SPeter Ujfalusi 
1493c8bf93f0SPeter Ujfalusi 	dac33->power_gpio = pdata->power_gpio;
14946aceabb4SPeter Ujfalusi 	dac33->burst_bclkdiv = pdata->burst_bclkdiv;
1495eeb309a8SPeter Ujfalusi 	dac33->keep_bclk = pdata->keep_bclk;
1496f430a27fSPeter Ujfalusi 	dac33->mode1_latency = pdata->mode1_latency;
1497f430a27fSPeter Ujfalusi 	if (!dac33->mode1_latency)
1498f430a27fSPeter Ujfalusi 		dac33->mode1_latency = 10000; /* 10ms */
1499c8bf93f0SPeter Ujfalusi 	dac33->irq = client->irq;
1500c8bf93f0SPeter Ujfalusi 	/* Disable FIFO use by default */
15017427b4b9SPeter Ujfalusi 	dac33->fifo_mode = DAC33_FIFO_BYPASS;
1502c8bf93f0SPeter Ujfalusi 
1503c8bf93f0SPeter Ujfalusi 	/* Check if the reset GPIO number is valid and request it */
1504c8bf93f0SPeter Ujfalusi 	if (dac33->power_gpio >= 0) {
1505c8bf93f0SPeter Ujfalusi 		ret = gpio_request(dac33->power_gpio, "tlv320dac33 reset");
1506c8bf93f0SPeter Ujfalusi 		if (ret < 0) {
1507f0fba2adSLiam Girdwood 			dev_err(&client->dev,
1508c8bf93f0SPeter Ujfalusi 				"Failed to request reset GPIO (%d)\n",
1509c8bf93f0SPeter Ujfalusi 				dac33->power_gpio);
1510f0fba2adSLiam Girdwood 			goto err_gpio;
1511c8bf93f0SPeter Ujfalusi 		}
1512c8bf93f0SPeter Ujfalusi 		gpio_direction_output(dac33->power_gpio, 0);
1513c8bf93f0SPeter Ujfalusi 	}
1514c8bf93f0SPeter Ujfalusi 
15153a7aaed7SIlkka Koskinen 	for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++)
15163a7aaed7SIlkka Koskinen 		dac33->supplies[i].supply = dac33_supply_names[i];
15173a7aaed7SIlkka Koskinen 
1518e9382e3bSFabio Estevam 	ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(dac33->supplies),
15193a7aaed7SIlkka Koskinen 				 dac33->supplies);
15203a7aaed7SIlkka Koskinen 
15213a7aaed7SIlkka Koskinen 	if (ret != 0) {
1522f0fba2adSLiam Girdwood 		dev_err(&client->dev, "Failed to request supplies: %d\n", ret);
15233a7aaed7SIlkka Koskinen 		goto err_get;
15243a7aaed7SIlkka Koskinen 	}
15253a7aaed7SIlkka Koskinen 
1526cd21ac8cSKuninori Morimoto 	ret = devm_snd_soc_register_component(&client->dev,
1527cd21ac8cSKuninori Morimoto 			&soc_component_dev_tlv320dac33, &dac33_dai, 1);
1528f0fba2adSLiam Girdwood 	if (ret < 0)
1529e9382e3bSFabio Estevam 		goto err_get;
1530c8bf93f0SPeter Ujfalusi 
1531c8bf93f0SPeter Ujfalusi 	return ret;
15323a7aaed7SIlkka Koskinen err_get:
1533c8bf93f0SPeter Ujfalusi 	if (dac33->power_gpio >= 0)
1534c8bf93f0SPeter Ujfalusi 		gpio_free(dac33->power_gpio);
1535f0fba2adSLiam Girdwood err_gpio:
1536c8bf93f0SPeter Ujfalusi 	return ret;
1537c8bf93f0SPeter Ujfalusi }
1538c8bf93f0SPeter Ujfalusi 
dac33_i2c_remove(struct i2c_client * client)1539ed5c2f5fSUwe Kleine-König static void dac33_i2c_remove(struct i2c_client *client)
1540c8bf93f0SPeter Ujfalusi {
1541f0fba2adSLiam Girdwood 	struct tlv320dac33_priv *dac33 = i2c_get_clientdata(client);
1542239fe55cSPeter Ujfalusi 
1543239fe55cSPeter Ujfalusi 	if (unlikely(dac33->chip_power))
1544cd21ac8cSKuninori Morimoto 		dac33_hard_power(dac33->component, 0);
1545c8bf93f0SPeter Ujfalusi 
1546c8bf93f0SPeter Ujfalusi 	if (dac33->power_gpio >= 0)
1547c8bf93f0SPeter Ujfalusi 		gpio_free(dac33->power_gpio);
1548c8bf93f0SPeter Ujfalusi }
1549c8bf93f0SPeter Ujfalusi 
1550c8bf93f0SPeter Ujfalusi static const struct i2c_device_id tlv320dac33_i2c_id[] = {
1551c8bf93f0SPeter Ujfalusi 	{
1552c8bf93f0SPeter Ujfalusi 		.name = "tlv320dac33",
1553c8bf93f0SPeter Ujfalusi 		.driver_data = 0,
1554c8bf93f0SPeter Ujfalusi 	},
1555c8bf93f0SPeter Ujfalusi 	{ },
1556c8bf93f0SPeter Ujfalusi };
1557573f26e3SAxel Lin MODULE_DEVICE_TABLE(i2c, tlv320dac33_i2c_id);
1558c8bf93f0SPeter Ujfalusi 
1559c8bf93f0SPeter Ujfalusi static struct i2c_driver tlv320dac33_i2c_driver = {
1560c8bf93f0SPeter Ujfalusi 	.driver = {
1561f0fba2adSLiam Girdwood 		.name = "tlv320dac33-codec",
1562c8bf93f0SPeter Ujfalusi 	},
1563*9abcd240SUwe Kleine-König 	.probe		= dac33_i2c_probe,
15647a79e94eSBill Pemberton 	.remove		= dac33_i2c_remove,
1565c8bf93f0SPeter Ujfalusi 	.id_table	= tlv320dac33_i2c_id,
1566c8bf93f0SPeter Ujfalusi };
1567c8bf93f0SPeter Ujfalusi 
156863a47a75SSachin Kamat module_i2c_driver(tlv320dac33_i2c_driver);
1569c8bf93f0SPeter Ujfalusi 
1570c8bf93f0SPeter Ujfalusi MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver");
157193864cf0SPeter Ujfalusi MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
1572c8bf93f0SPeter Ujfalusi MODULE_LICENSE("GPL");
1573