xref: /linux/sound/soc/codecs/uda1380.c (revision 65ec1cd1e2c6228752d2f167b01e6d291014d249)
1b7482f52SPhilipp Zabel /*
2b7482f52SPhilipp Zabel  * uda1380.c - Philips UDA1380 ALSA SoC audio driver
3b7482f52SPhilipp Zabel  *
4b7482f52SPhilipp Zabel  * This program is free software; you can redistribute it and/or modify
5b7482f52SPhilipp Zabel  * it under the terms of the GNU General Public License version 2 as
6b7482f52SPhilipp Zabel  * published by the Free Software Foundation.
7b7482f52SPhilipp Zabel  *
8b7482f52SPhilipp Zabel  * Copyright (c) 2007 Philipp Zabel <philipp.zabel@gmail.com>
9b7482f52SPhilipp Zabel  * Improved support for DAPM and audio routing/mixing capabilities,
10b7482f52SPhilipp Zabel  * added TLV support.
11b7482f52SPhilipp Zabel  *
12b7482f52SPhilipp Zabel  * Modified by Richard Purdie <richard@openedhand.com> to fit into SoC
13b7482f52SPhilipp Zabel  * codec model.
14b7482f52SPhilipp Zabel  *
15b7482f52SPhilipp Zabel  * Copyright (c) 2005 Giorgio Padrin <giorgio@mandarinlogiq.org>
16b7482f52SPhilipp Zabel  * Copyright 2005 Openedhand Ltd.
17b7482f52SPhilipp Zabel  */
18b7482f52SPhilipp Zabel 
19b7482f52SPhilipp Zabel #include <linux/module.h>
20b7482f52SPhilipp Zabel #include <linux/init.h>
21b7482f52SPhilipp Zabel #include <linux/types.h>
22b7482f52SPhilipp Zabel #include <linux/string.h>
23b7482f52SPhilipp Zabel #include <linux/slab.h>
24b7482f52SPhilipp Zabel #include <linux/errno.h>
25b7482f52SPhilipp Zabel #include <linux/ioctl.h>
26b7482f52SPhilipp Zabel #include <linux/delay.h>
27b7482f52SPhilipp Zabel #include <linux/i2c.h>
28ef9e5e5cSPhilipp Zabel #include <linux/workqueue.h>
29b7482f52SPhilipp Zabel #include <sound/core.h>
30b7482f52SPhilipp Zabel #include <sound/control.h>
31b7482f52SPhilipp Zabel #include <sound/initval.h>
32b7482f52SPhilipp Zabel #include <sound/info.h>
33b7482f52SPhilipp Zabel #include <sound/soc.h>
34b7482f52SPhilipp Zabel #include <sound/soc-dapm.h>
35b7482f52SPhilipp Zabel #include <sound/tlv.h>
36b7482f52SPhilipp Zabel 
37b7482f52SPhilipp Zabel #include "uda1380.h"
38b7482f52SPhilipp Zabel 
39ef9e5e5cSPhilipp Zabel static struct work_struct uda1380_work;
40ef9e5e5cSPhilipp Zabel static struct snd_soc_codec *uda1380_codec;
41ef9e5e5cSPhilipp Zabel 
42b7482f52SPhilipp Zabel /*
43b7482f52SPhilipp Zabel  * uda1380 register cache
44b7482f52SPhilipp Zabel  */
45b7482f52SPhilipp Zabel static const u16 uda1380_reg[UDA1380_CACHEREGNUM] = {
46b7482f52SPhilipp Zabel 	0x0502, 0x0000, 0x0000, 0x3f3f,
47b7482f52SPhilipp Zabel 	0x0202, 0x0000, 0x0000, 0x0000,
48b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
49b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
50b7482f52SPhilipp Zabel 	0x0000, 0xff00, 0x0000, 0x4800,
51b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
52b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
53b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
54b7482f52SPhilipp Zabel 	0x0000, 0x8000, 0x0002, 0x0000,
55b7482f52SPhilipp Zabel };
56b7482f52SPhilipp Zabel 
57ef9e5e5cSPhilipp Zabel static unsigned long uda1380_cache_dirty;
58ef9e5e5cSPhilipp Zabel 
59b7482f52SPhilipp Zabel /*
60b7482f52SPhilipp Zabel  * read uda1380 register cache
61b7482f52SPhilipp Zabel  */
62b7482f52SPhilipp Zabel static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec,
63b7482f52SPhilipp Zabel 	unsigned int reg)
64b7482f52SPhilipp Zabel {
65b7482f52SPhilipp Zabel 	u16 *cache = codec->reg_cache;
66b7482f52SPhilipp Zabel 	if (reg == UDA1380_RESET)
67b7482f52SPhilipp Zabel 		return 0;
68b7482f52SPhilipp Zabel 	if (reg >= UDA1380_CACHEREGNUM)
69b7482f52SPhilipp Zabel 		return -1;
70b7482f52SPhilipp Zabel 	return cache[reg];
71b7482f52SPhilipp Zabel }
72b7482f52SPhilipp Zabel 
73b7482f52SPhilipp Zabel /*
74b7482f52SPhilipp Zabel  * write uda1380 register cache
75b7482f52SPhilipp Zabel  */
76b7482f52SPhilipp Zabel static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
77b7482f52SPhilipp Zabel 	u16 reg, unsigned int value)
78b7482f52SPhilipp Zabel {
79b7482f52SPhilipp Zabel 	u16 *cache = codec->reg_cache;
80ef9e5e5cSPhilipp Zabel 
81b7482f52SPhilipp Zabel 	if (reg >= UDA1380_CACHEREGNUM)
82b7482f52SPhilipp Zabel 		return;
83ef9e5e5cSPhilipp Zabel 	if ((reg >= 0x10) && (cache[reg] != value))
84ef9e5e5cSPhilipp Zabel 		set_bit(reg - 0x10, &uda1380_cache_dirty);
85b7482f52SPhilipp Zabel 	cache[reg] = value;
86b7482f52SPhilipp Zabel }
87b7482f52SPhilipp Zabel 
88b7482f52SPhilipp Zabel /*
89b7482f52SPhilipp Zabel  * write to the UDA1380 register space
90b7482f52SPhilipp Zabel  */
91b7482f52SPhilipp Zabel static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
92b7482f52SPhilipp Zabel 	unsigned int value)
93b7482f52SPhilipp Zabel {
94b7482f52SPhilipp Zabel 	u8 data[3];
95b7482f52SPhilipp Zabel 
96b7482f52SPhilipp Zabel 	/* data is
97b7482f52SPhilipp Zabel 	 *   data[0] is register offset
98b7482f52SPhilipp Zabel 	 *   data[1] is MS byte
99b7482f52SPhilipp Zabel 	 *   data[2] is LS byte
100b7482f52SPhilipp Zabel 	 */
101b7482f52SPhilipp Zabel 	data[0] = reg;
102b7482f52SPhilipp Zabel 	data[1] = (value & 0xff00) >> 8;
103b7482f52SPhilipp Zabel 	data[2] = value & 0x00ff;
104b7482f52SPhilipp Zabel 
105b7482f52SPhilipp Zabel 	uda1380_write_reg_cache(codec, reg, value);
106b7482f52SPhilipp Zabel 
107b7482f52SPhilipp Zabel 	/* the interpolator & decimator regs must only be written when the
108b7482f52SPhilipp Zabel 	 * codec DAI is active.
109b7482f52SPhilipp Zabel 	 */
110b7482f52SPhilipp Zabel 	if (!codec->active && (reg >= UDA1380_MVOL))
111b7482f52SPhilipp Zabel 		return 0;
112b7482f52SPhilipp Zabel 	pr_debug("uda1380: hw write %x val %x\n", reg, value);
113b7482f52SPhilipp Zabel 	if (codec->hw_write(codec->control_data, data, 3) == 3) {
114b7482f52SPhilipp Zabel 		unsigned int val;
115b7482f52SPhilipp Zabel 		i2c_master_send(codec->control_data, data, 1);
116b7482f52SPhilipp Zabel 		i2c_master_recv(codec->control_data, data, 2);
117b7482f52SPhilipp Zabel 		val = (data[0]<<8) | data[1];
118b7482f52SPhilipp Zabel 		if (val != value) {
119b7482f52SPhilipp Zabel 			pr_debug("uda1380: READ BACK VAL %x\n",
120b7482f52SPhilipp Zabel 					(data[0]<<8) | data[1]);
121b7482f52SPhilipp Zabel 			return -EIO;
122b7482f52SPhilipp Zabel 		}
123ef9e5e5cSPhilipp Zabel 		if (reg >= 0x10)
124ef9e5e5cSPhilipp Zabel 			clear_bit(reg - 0x10, &uda1380_cache_dirty);
125b7482f52SPhilipp Zabel 		return 0;
126b7482f52SPhilipp Zabel 	} else
127b7482f52SPhilipp Zabel 		return -EIO;
128b7482f52SPhilipp Zabel }
129b7482f52SPhilipp Zabel 
130b7482f52SPhilipp Zabel #define uda1380_reset(c)	uda1380_write(c, UDA1380_RESET, 0)
131b7482f52SPhilipp Zabel 
132ef9e5e5cSPhilipp Zabel static void uda1380_flush_work(struct work_struct *work)
133ef9e5e5cSPhilipp Zabel {
134ef9e5e5cSPhilipp Zabel 	int bit, reg;
135ef9e5e5cSPhilipp Zabel 
136ef9e5e5cSPhilipp Zabel 	for_each_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
137ef9e5e5cSPhilipp Zabel 		reg = 0x10 + bit;
138ef9e5e5cSPhilipp Zabel 		pr_debug("uda1380: flush reg %x val %x:\n", reg,
139ef9e5e5cSPhilipp Zabel 				uda1380_read_reg_cache(uda1380_codec, reg));
140ef9e5e5cSPhilipp Zabel 		uda1380_write(uda1380_codec, reg,
141ef9e5e5cSPhilipp Zabel 				uda1380_read_reg_cache(uda1380_codec, reg));
142ef9e5e5cSPhilipp Zabel 		clear_bit(bit, &uda1380_cache_dirty);
143ef9e5e5cSPhilipp Zabel 	}
144ef9e5e5cSPhilipp Zabel }
145ef9e5e5cSPhilipp Zabel 
146b7482f52SPhilipp Zabel /* declarations of ALSA reg_elem_REAL controls */
147b7482f52SPhilipp Zabel static const char *uda1380_deemp[] = {
148b7482f52SPhilipp Zabel 	"None",
149b7482f52SPhilipp Zabel 	"32kHz",
150b7482f52SPhilipp Zabel 	"44.1kHz",
151b7482f52SPhilipp Zabel 	"48kHz",
152b7482f52SPhilipp Zabel 	"96kHz",
153b7482f52SPhilipp Zabel };
154b7482f52SPhilipp Zabel static const char *uda1380_input_sel[] = {
155b7482f52SPhilipp Zabel 	"Line",
156b7482f52SPhilipp Zabel 	"Mic + Line R",
157b7482f52SPhilipp Zabel 	"Line L",
158b7482f52SPhilipp Zabel 	"Mic",
159b7482f52SPhilipp Zabel };
160b7482f52SPhilipp Zabel static const char *uda1380_output_sel[] = {
161b7482f52SPhilipp Zabel 	"DAC",
162b7482f52SPhilipp Zabel 	"Analog Mixer",
163b7482f52SPhilipp Zabel };
164b7482f52SPhilipp Zabel static const char *uda1380_spf_mode[] = {
165b7482f52SPhilipp Zabel 	"Flat",
166b7482f52SPhilipp Zabel 	"Minimum1",
167b7482f52SPhilipp Zabel 	"Minimum2",
168b7482f52SPhilipp Zabel 	"Maximum"
169b7482f52SPhilipp Zabel };
170b7482f52SPhilipp Zabel static const char *uda1380_capture_sel[] = {
171b7482f52SPhilipp Zabel 	"ADC",
172b7482f52SPhilipp Zabel 	"Digital Mixer"
173b7482f52SPhilipp Zabel };
174b7482f52SPhilipp Zabel static const char *uda1380_sel_ns[] = {
175b7482f52SPhilipp Zabel 	"3rd-order",
176b7482f52SPhilipp Zabel 	"5th-order"
177b7482f52SPhilipp Zabel };
178b7482f52SPhilipp Zabel static const char *uda1380_mix_control[] = {
179b7482f52SPhilipp Zabel 	"off",
180b7482f52SPhilipp Zabel 	"PCM only",
181b7482f52SPhilipp Zabel 	"before sound processing",
182b7482f52SPhilipp Zabel 	"after sound processing"
183b7482f52SPhilipp Zabel };
184b7482f52SPhilipp Zabel static const char *uda1380_sdet_setting[] = {
185b7482f52SPhilipp Zabel 	"3200",
186b7482f52SPhilipp Zabel 	"4800",
187b7482f52SPhilipp Zabel 	"9600",
188b7482f52SPhilipp Zabel 	"19200"
189b7482f52SPhilipp Zabel };
190b7482f52SPhilipp Zabel static const char *uda1380_os_setting[] = {
191b7482f52SPhilipp Zabel 	"single-speed",
192b7482f52SPhilipp Zabel 	"double-speed (no mixing)",
193b7482f52SPhilipp Zabel 	"quad-speed (no mixing)"
194b7482f52SPhilipp Zabel };
195b7482f52SPhilipp Zabel 
196b7482f52SPhilipp Zabel static const struct soc_enum uda1380_deemp_enum[] = {
197b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_DEEMP, 8, 5, uda1380_deemp),
198b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_DEEMP, 0, 5, uda1380_deemp),
199b7482f52SPhilipp Zabel };
200b7482f52SPhilipp Zabel static const struct soc_enum uda1380_input_sel_enum =
201b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_ADC, 2, 4, uda1380_input_sel);		/* SEL_MIC, SEL_LNA */
202b7482f52SPhilipp Zabel static const struct soc_enum uda1380_output_sel_enum =
203b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_PM, 7, 2, uda1380_output_sel);		/* R02_EN_AVC */
204b7482f52SPhilipp Zabel static const struct soc_enum uda1380_spf_enum =
205b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MODE, 14, 4, uda1380_spf_mode);		/* M */
206b7482f52SPhilipp Zabel static const struct soc_enum uda1380_capture_sel_enum =
207b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_IFACE, 6, 2, uda1380_capture_sel);	/* SEL_SOURCE */
208b7482f52SPhilipp Zabel static const struct soc_enum uda1380_sel_ns_enum =
209b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 14, 2, uda1380_sel_ns);		/* SEL_NS */
210b7482f52SPhilipp Zabel static const struct soc_enum uda1380_mix_enum =
211b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 12, 4, uda1380_mix_control);	/* MIX, MIX_POS */
212b7482f52SPhilipp Zabel static const struct soc_enum uda1380_sdet_enum =
213b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 4, 4, uda1380_sdet_setting);	/* SD_VALUE */
214b7482f52SPhilipp Zabel static const struct soc_enum uda1380_os_enum =
215b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 0, 3, uda1380_os_setting);	/* OS */
216b7482f52SPhilipp Zabel 
217b7482f52SPhilipp Zabel /*
218b7482f52SPhilipp Zabel  * from -48 dB in 1.5 dB steps (mute instead of -49.5 dB)
219b7482f52SPhilipp Zabel  */
220b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(amix_tlv, -4950, 150, 1);
221b7482f52SPhilipp Zabel 
222b7482f52SPhilipp Zabel /*
223b7482f52SPhilipp Zabel  * from -78 dB in 1 dB steps (3 dB steps, really. LSB are ignored),
224b7482f52SPhilipp Zabel  * from -66 dB in 0.5 dB steps (2 dB steps, really) and
225b7482f52SPhilipp Zabel  * from -52 dB in 0.25 dB steps
226b7482f52SPhilipp Zabel  */
227b7482f52SPhilipp Zabel static const unsigned int mvol_tlv[] = {
228b7482f52SPhilipp Zabel 	TLV_DB_RANGE_HEAD(3),
229b7482f52SPhilipp Zabel 	0, 15, TLV_DB_SCALE_ITEM(-8200, 100, 1),
230b7482f52SPhilipp Zabel 	16, 43, TLV_DB_SCALE_ITEM(-6600, 50, 0),
231b7482f52SPhilipp Zabel 	44, 252, TLV_DB_SCALE_ITEM(-5200, 25, 0),
232b7482f52SPhilipp Zabel };
233b7482f52SPhilipp Zabel 
234b7482f52SPhilipp Zabel /*
235b7482f52SPhilipp Zabel  * from -72 dB in 1.5 dB steps (6 dB steps really),
236b7482f52SPhilipp Zabel  * from -66 dB in 0.75 dB steps (3 dB steps really),
237b7482f52SPhilipp Zabel  * from -60 dB in 0.5 dB steps (2 dB steps really) and
238b7482f52SPhilipp Zabel  * from -46 dB in 0.25 dB steps
239b7482f52SPhilipp Zabel  */
240b7482f52SPhilipp Zabel static const unsigned int vc_tlv[] = {
241b7482f52SPhilipp Zabel 	TLV_DB_RANGE_HEAD(4),
242b7482f52SPhilipp Zabel 	0, 7, TLV_DB_SCALE_ITEM(-7800, 150, 1),
243b7482f52SPhilipp Zabel 	8, 15, TLV_DB_SCALE_ITEM(-6600, 75, 0),
244b7482f52SPhilipp Zabel 	16, 43, TLV_DB_SCALE_ITEM(-6000, 50, 0),
245b7482f52SPhilipp Zabel 	44, 228, TLV_DB_SCALE_ITEM(-4600, 25, 0),
246b7482f52SPhilipp Zabel };
247b7482f52SPhilipp Zabel 
248b7482f52SPhilipp Zabel /* from 0 to 6 dB in 2 dB steps if SPF mode != flat */
249b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(tr_tlv, 0, 200, 0);
250b7482f52SPhilipp Zabel 
251b7482f52SPhilipp Zabel /* from 0 to 24 dB in 2 dB steps, if SPF mode == maximum, otherwise cuts
252b7482f52SPhilipp Zabel  * off at 18 dB max) */
253b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(bb_tlv, 0, 200, 0);
254b7482f52SPhilipp Zabel 
255b7482f52SPhilipp Zabel /* from -63 to 24 dB in 0.5 dB steps (-128...48) */
256b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(dec_tlv, -6400, 50, 1);
257b7482f52SPhilipp Zabel 
258b7482f52SPhilipp Zabel /* from 0 to 24 dB in 3 dB steps */
259b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0);
260b7482f52SPhilipp Zabel 
261b7482f52SPhilipp Zabel /* from 0 to 30 dB in 2 dB steps */
262b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(vga_tlv, 0, 200, 0);
263b7482f52SPhilipp Zabel 
264b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_snd_controls[] = {
265b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Analog Mixer Volume", UDA1380_AMIX, 0, 8, 44, 1, amix_tlv),	/* AVCR, AVCL */
266b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Master Playback Volume", UDA1380_MVOL, 0, 8, 252, 1, mvol_tlv),	/* MVCL, MVCR */
267b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("ADC Playback Volume", UDA1380_MIXVOL, 8, 228, 1, vc_tlv),	/* VC2 */
268b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("PCM Playback Volume", UDA1380_MIXVOL, 0, 228, 1, vc_tlv),	/* VC1 */
269b7482f52SPhilipp Zabel 	SOC_ENUM("Sound Processing Filter", uda1380_spf_enum),				/* M */
270b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Tone Control - Treble", UDA1380_MODE, 4, 12, 3, 0, tr_tlv), 	/* TRL, TRR */
271b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Tone Control - Bass", UDA1380_MODE, 0, 8, 15, 0, bb_tlv),	/* BBL, BBR */
272b7482f52SPhilipp Zabel /**/	SOC_SINGLE("Master Playback Switch", UDA1380_DEEMP, 14, 1, 1),		/* MTM */
273b7482f52SPhilipp Zabel 	SOC_SINGLE("ADC Playback Switch", UDA1380_DEEMP, 11, 1, 1),		/* MT2 from decimation filter */
274b7482f52SPhilipp Zabel 	SOC_ENUM("ADC Playback De-emphasis", uda1380_deemp_enum[0]),		/* DE2 */
275b7482f52SPhilipp Zabel 	SOC_SINGLE("PCM Playback Switch", UDA1380_DEEMP, 3, 1, 1),		/* MT1, from digital data input */
276b7482f52SPhilipp Zabel 	SOC_ENUM("PCM Playback De-emphasis", uda1380_deemp_enum[1]),		/* DE1 */
277b7482f52SPhilipp Zabel 	SOC_SINGLE("DAC Polarity inverting Switch", UDA1380_MIXER, 15, 1, 0),	/* DA_POL_INV */
278b7482f52SPhilipp Zabel 	SOC_ENUM("Noise Shaper", uda1380_sel_ns_enum),				/* SEL_NS */
279b7482f52SPhilipp Zabel 	SOC_ENUM("Digital Mixer Signal Control", uda1380_mix_enum),		/* MIX_POS, MIX */
280b7482f52SPhilipp Zabel 	SOC_SINGLE("Silence Detector Switch", UDA1380_MIXER, 6, 1, 0),		/* SDET_ON */
281b7482f52SPhilipp Zabel 	SOC_ENUM("Silence Detector Setting", uda1380_sdet_enum),		/* SD_VALUE */
282b7482f52SPhilipp Zabel 	SOC_ENUM("Oversampling Input", uda1380_os_enum),			/* OS */
283b7482f52SPhilipp Zabel 	SOC_DOUBLE_S8_TLV("ADC Capture Volume", UDA1380_DEC, -128, 48, dec_tlv),	/* ML_DEC, MR_DEC */
284b7482f52SPhilipp Zabel /**/	SOC_SINGLE("ADC Capture Switch", UDA1380_PGA, 15, 1, 1),		/* MT_ADC */
285b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Line Capture Volume", UDA1380_PGA, 0, 8, 8, 0, pga_tlv), /* PGA_GAINCTRLL, PGA_GAINCTRLR */
286b7482f52SPhilipp Zabel 	SOC_SINGLE("ADC Polarity inverting Switch", UDA1380_ADC, 12, 1, 0),	/* ADCPOL_INV */
287b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("Mic Capture Volume", UDA1380_ADC, 8, 15, 0, vga_tlv),	/* VGA_CTRL */
288b7482f52SPhilipp Zabel 	SOC_SINGLE("DC Filter Bypass Switch", UDA1380_ADC, 1, 1, 0),		/* SKIP_DCFIL (before decimator) */
289b7482f52SPhilipp Zabel 	SOC_SINGLE("DC Filter Enable Switch", UDA1380_ADC, 0, 1, 0),		/* EN_DCFIL (at output of decimator) */
290b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Timing", UDA1380_AGC, 8, 7, 0),			/* TODO: enum, see table 62 */
291b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Target level", UDA1380_AGC, 2, 3, 1),			/* AGC_LEVEL */
292b7482f52SPhilipp Zabel 	/* -5.5, -8, -11.5, -14 dBFS */
293b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0),
294b7482f52SPhilipp Zabel };
295b7482f52SPhilipp Zabel 
296b7482f52SPhilipp Zabel /* Input mux */
297b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_input_mux_control =
298b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_input_sel_enum);
299b7482f52SPhilipp Zabel 
300b7482f52SPhilipp Zabel /* Output mux */
301b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_output_mux_control =
302b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_output_sel_enum);
303b7482f52SPhilipp Zabel 
304b7482f52SPhilipp Zabel /* Capture mux */
305b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_capture_mux_control =
306b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_capture_sel_enum);
307b7482f52SPhilipp Zabel 
308b7482f52SPhilipp Zabel 
309b7482f52SPhilipp Zabel static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
310b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
311b7482f52SPhilipp Zabel 		&uda1380_input_mux_control),
312b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM, 0, 0,
313b7482f52SPhilipp Zabel 		&uda1380_output_mux_control),
314b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0,
315b7482f52SPhilipp Zabel 		&uda1380_capture_mux_control),
316b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Left PGA", UDA1380_PM, 3, 0, NULL, 0),
317b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Right PGA", UDA1380_PM, 1, 0, NULL, 0),
318b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Mic LNA", UDA1380_PM, 4, 0, NULL, 0),
319b7482f52SPhilipp Zabel 	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", UDA1380_PM, 2, 0),
320b7482f52SPhilipp Zabel 	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", UDA1380_PM, 0, 0),
321b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINM"),
322b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINL"),
323b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINR"),
324b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MIXER("Analog Mixer", UDA1380_PM, 6, 0, NULL, 0),
325b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTLHP"),
326b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTRHP"),
327b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTL"),
328b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTR"),
329b7482f52SPhilipp Zabel 	SND_SOC_DAPM_DAC("DAC", "Playback", UDA1380_PM, 10, 0),
330b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("HeadPhone Driver", UDA1380_PM, 13, 0, NULL, 0),
331b7482f52SPhilipp Zabel };
332b7482f52SPhilipp Zabel 
333b7482f52SPhilipp Zabel static const struct snd_soc_dapm_route audio_map[] = {
334b7482f52SPhilipp Zabel 
335b7482f52SPhilipp Zabel 	/* output mux */
336b7482f52SPhilipp Zabel 	{"HeadPhone Driver", NULL, "Output Mux"},
337b7482f52SPhilipp Zabel 	{"VOUTR", NULL, "Output Mux"},
338b7482f52SPhilipp Zabel 	{"VOUTL", NULL, "Output Mux"},
339b7482f52SPhilipp Zabel 
340b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "VINR"},
341b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "VINL"},
342b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "DAC"},
343b7482f52SPhilipp Zabel 
344b7482f52SPhilipp Zabel 	{"Output Mux", "DAC", "DAC"},
345b7482f52SPhilipp Zabel 	{"Output Mux", "Analog Mixer", "Analog Mixer"},
346b7482f52SPhilipp Zabel 
347b7482f52SPhilipp Zabel 	/* {"DAC", "Digital Mixer", "I2S" } */
348b7482f52SPhilipp Zabel 
349b7482f52SPhilipp Zabel 	/* headphone driver */
350b7482f52SPhilipp Zabel 	{"VOUTLHP", NULL, "HeadPhone Driver"},
351b7482f52SPhilipp Zabel 	{"VOUTRHP", NULL, "HeadPhone Driver"},
352b7482f52SPhilipp Zabel 
353b7482f52SPhilipp Zabel 	/* input mux */
354b7482f52SPhilipp Zabel 	{"Left ADC", NULL, "Input Mux"},
355b7482f52SPhilipp Zabel 	{"Input Mux", "Mic", "Mic LNA"},
356b7482f52SPhilipp Zabel 	{"Input Mux", "Mic + Line R", "Mic LNA"},
357b7482f52SPhilipp Zabel 	{"Input Mux", "Line L", "Left PGA"},
358b7482f52SPhilipp Zabel 	{"Input Mux", "Line", "Left PGA"},
359b7482f52SPhilipp Zabel 
360b7482f52SPhilipp Zabel 	/* right input */
361b7482f52SPhilipp Zabel 	{"Right ADC", "Mic + Line R", "Right PGA"},
362b7482f52SPhilipp Zabel 	{"Right ADC", "Line", "Right PGA"},
363b7482f52SPhilipp Zabel 
364b7482f52SPhilipp Zabel 	/* inputs */
365b7482f52SPhilipp Zabel 	{"Mic LNA", NULL, "VINM"},
366b7482f52SPhilipp Zabel 	{"Left PGA", NULL, "VINL"},
367b7482f52SPhilipp Zabel 	{"Right PGA", NULL, "VINR"},
368b7482f52SPhilipp Zabel };
369b7482f52SPhilipp Zabel 
370b7482f52SPhilipp Zabel static int uda1380_add_widgets(struct snd_soc_codec *codec)
371b7482f52SPhilipp Zabel {
372b7482f52SPhilipp Zabel 	snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets,
373b7482f52SPhilipp Zabel 				  ARRAY_SIZE(uda1380_dapm_widgets));
374b7482f52SPhilipp Zabel 
375b7482f52SPhilipp Zabel 	snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
376b7482f52SPhilipp Zabel 
377b7482f52SPhilipp Zabel 	snd_soc_dapm_new_widgets(codec);
378b7482f52SPhilipp Zabel 	return 0;
379b7482f52SPhilipp Zabel }
380b7482f52SPhilipp Zabel 
3815b247442SPhilipp Zabel static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
382b7482f52SPhilipp Zabel 		unsigned int fmt)
383b7482f52SPhilipp Zabel {
384b7482f52SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
385b7482f52SPhilipp Zabel 	int iface;
386b7482f52SPhilipp Zabel 
387b7482f52SPhilipp Zabel 	/* set up DAI based upon fmt */
388b7482f52SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
389b7482f52SPhilipp Zabel 	iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK);
390b7482f52SPhilipp Zabel 
391b7482f52SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
392b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
393b7482f52SPhilipp Zabel 		iface |= R01_SFORI_I2S | R01_SFORO_I2S;
394b7482f52SPhilipp Zabel 		break;
395b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
3965b247442SPhilipp Zabel 		iface |= R01_SFORI_LSB16 | R01_SFORO_LSB16;
397b7482f52SPhilipp Zabel 		break;
398b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
3995b247442SPhilipp Zabel 		iface |= R01_SFORI_MSB | R01_SFORO_MSB;
4005b247442SPhilipp Zabel 	}
4015b247442SPhilipp Zabel 
4025f2a9384SPhilipp Zabel 	/* DATAI is slave only, so in single-link mode, this has to be slave */
4035f2a9384SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
4045f2a9384SPhilipp Zabel 		return -EINVAL;
4055b247442SPhilipp Zabel 
4065b247442SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
4075b247442SPhilipp Zabel 
4085b247442SPhilipp Zabel 	return 0;
4095b247442SPhilipp Zabel }
4105b247442SPhilipp Zabel 
4115b247442SPhilipp Zabel static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
4125b247442SPhilipp Zabel 		unsigned int fmt)
4135b247442SPhilipp Zabel {
4145b247442SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
4155b247442SPhilipp Zabel 	int iface;
4165b247442SPhilipp Zabel 
4175b247442SPhilipp Zabel 	/* set up DAI based upon fmt */
4185b247442SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
4195b247442SPhilipp Zabel 	iface &= ~R01_SFORI_MASK;
4205b247442SPhilipp Zabel 
4215b247442SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
4225b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
4235b247442SPhilipp Zabel 		iface |= R01_SFORI_I2S;
4245b247442SPhilipp Zabel 		break;
4255b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4265b247442SPhilipp Zabel 		iface |= R01_SFORI_LSB16;
4275b247442SPhilipp Zabel 		break;
4285b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4295b247442SPhilipp Zabel 		iface |= R01_SFORI_MSB;
4305b247442SPhilipp Zabel 	}
4315b247442SPhilipp Zabel 
4325f2a9384SPhilipp Zabel 	/* DATAI is slave only, so this has to be slave */
4335f2a9384SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
4345f2a9384SPhilipp Zabel 		return -EINVAL;
4355f2a9384SPhilipp Zabel 
4365b247442SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
4375b247442SPhilipp Zabel 
4385b247442SPhilipp Zabel 	return 0;
4395b247442SPhilipp Zabel }
4405b247442SPhilipp Zabel 
4415b247442SPhilipp Zabel static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
4425b247442SPhilipp Zabel 		unsigned int fmt)
4435b247442SPhilipp Zabel {
4445b247442SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
4455b247442SPhilipp Zabel 	int iface;
4465b247442SPhilipp Zabel 
4475b247442SPhilipp Zabel 	/* set up DAI based upon fmt */
4485b247442SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
4495b247442SPhilipp Zabel 	iface &= ~(R01_SIM | R01_SFORO_MASK);
4505b247442SPhilipp Zabel 
4515b247442SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
4525b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
4535b247442SPhilipp Zabel 		iface |= R01_SFORO_I2S;
4545b247442SPhilipp Zabel 		break;
4555b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4565b247442SPhilipp Zabel 		iface |= R01_SFORO_LSB16;
4575b247442SPhilipp Zabel 		break;
4585b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4595b247442SPhilipp Zabel 		iface |= R01_SFORO_MSB;
460b7482f52SPhilipp Zabel 	}
461b7482f52SPhilipp Zabel 
462b7482f52SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
463b7482f52SPhilipp Zabel 		iface |= R01_SIM;
464b7482f52SPhilipp Zabel 
465b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
466b7482f52SPhilipp Zabel 
467b7482f52SPhilipp Zabel 	return 0;
468b7482f52SPhilipp Zabel }
469b7482f52SPhilipp Zabel 
470ef9e5e5cSPhilipp Zabel static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
471dee89c4dSMark Brown 		struct snd_soc_dai *dai)
472b7482f52SPhilipp Zabel {
473b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
474b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = rtd->socdev;
4756627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
476ef9e5e5cSPhilipp Zabel 	int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
477b7482f52SPhilipp Zabel 
478ef9e5e5cSPhilipp Zabel 	switch (cmd) {
479ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_START:
480ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
481ef9e5e5cSPhilipp Zabel 		uda1380_write_reg_cache(codec, UDA1380_MIXER,
482ef9e5e5cSPhilipp Zabel 					mixer & ~R14_SILENCE);
483ef9e5e5cSPhilipp Zabel 		schedule_work(&uda1380_work);
484ef9e5e5cSPhilipp Zabel 		break;
485ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_STOP:
486ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
487ef9e5e5cSPhilipp Zabel 		uda1380_write_reg_cache(codec, UDA1380_MIXER,
488ef9e5e5cSPhilipp Zabel 					mixer | R14_SILENCE);
489ef9e5e5cSPhilipp Zabel 		schedule_work(&uda1380_work);
490ef9e5e5cSPhilipp Zabel 		break;
491b7482f52SPhilipp Zabel 	}
492b7482f52SPhilipp Zabel 	return 0;
493b7482f52SPhilipp Zabel }
494b7482f52SPhilipp Zabel 
495b7482f52SPhilipp Zabel static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
496dee89c4dSMark Brown 				 struct snd_pcm_hw_params *params,
497dee89c4dSMark Brown 				 struct snd_soc_dai *dai)
498b7482f52SPhilipp Zabel {
499b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
500b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = rtd->socdev;
5016627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
502b7482f52SPhilipp Zabel 	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
503b7482f52SPhilipp Zabel 
504b7482f52SPhilipp Zabel 	/* set WSPLL power and divider if running from this clock */
505b7482f52SPhilipp Zabel 	if (clk & R00_DAC_CLK) {
506b7482f52SPhilipp Zabel 		int rate = params_rate(params);
507b7482f52SPhilipp Zabel 		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
508b7482f52SPhilipp Zabel 		clk &= ~0x3; /* clear SEL_LOOP_DIV */
509b7482f52SPhilipp Zabel 		switch (rate) {
510b7482f52SPhilipp Zabel 		case 6250 ... 12500:
511b7482f52SPhilipp Zabel 			clk |= 0x0;
512b7482f52SPhilipp Zabel 			break;
513b7482f52SPhilipp Zabel 		case 12501 ... 25000:
514b7482f52SPhilipp Zabel 			clk |= 0x1;
515b7482f52SPhilipp Zabel 			break;
516b7482f52SPhilipp Zabel 		case 25001 ... 50000:
517b7482f52SPhilipp Zabel 			clk |= 0x2;
518b7482f52SPhilipp Zabel 			break;
519b7482f52SPhilipp Zabel 		case 50001 ... 100000:
520b7482f52SPhilipp Zabel 			clk |= 0x3;
521b7482f52SPhilipp Zabel 			break;
522b7482f52SPhilipp Zabel 		}
523b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_PLL | pm);
524b7482f52SPhilipp Zabel 	}
525b7482f52SPhilipp Zabel 
526b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
527b7482f52SPhilipp Zabel 		clk |= R00_EN_DAC | R00_EN_INT;
528b7482f52SPhilipp Zabel 	else
529b7482f52SPhilipp Zabel 		clk |= R00_EN_ADC | R00_EN_DEC;
530b7482f52SPhilipp Zabel 
531b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, clk);
532b7482f52SPhilipp Zabel 	return 0;
533b7482f52SPhilipp Zabel }
534b7482f52SPhilipp Zabel 
535dee89c4dSMark Brown static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
536dee89c4dSMark Brown 				 struct snd_soc_dai *dai)
537b7482f52SPhilipp Zabel {
538b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
539b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = rtd->socdev;
5406627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
541b7482f52SPhilipp Zabel 	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
542b7482f52SPhilipp Zabel 
543b7482f52SPhilipp Zabel 	/* shut down WSPLL power if running from this clock */
544b7482f52SPhilipp Zabel 	if (clk & R00_DAC_CLK) {
545b7482f52SPhilipp Zabel 		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
546b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, ~R02_PON_PLL & pm);
547b7482f52SPhilipp Zabel 	}
548b7482f52SPhilipp Zabel 
549b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
550b7482f52SPhilipp Zabel 		clk &= ~(R00_EN_DAC | R00_EN_INT);
551b7482f52SPhilipp Zabel 	else
552b7482f52SPhilipp Zabel 		clk &= ~(R00_EN_ADC | R00_EN_DEC);
553b7482f52SPhilipp Zabel 
554b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, clk);
555b7482f52SPhilipp Zabel }
556b7482f52SPhilipp Zabel 
557b7482f52SPhilipp Zabel static int uda1380_set_bias_level(struct snd_soc_codec *codec,
558b7482f52SPhilipp Zabel 	enum snd_soc_bias_level level)
559b7482f52SPhilipp Zabel {
560b7482f52SPhilipp Zabel 	int pm = uda1380_read_reg_cache(codec, UDA1380_PM);
561b7482f52SPhilipp Zabel 
562b7482f52SPhilipp Zabel 	switch (level) {
563b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_ON:
564b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_PREPARE:
565b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
566b7482f52SPhilipp Zabel 		break;
567b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_STANDBY:
568b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_BIAS);
569b7482f52SPhilipp Zabel 		break;
570b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_OFF:
571b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, 0x0);
572b7482f52SPhilipp Zabel 		break;
573b7482f52SPhilipp Zabel 	}
574b7482f52SPhilipp Zabel 	codec->bias_level = level;
575b7482f52SPhilipp Zabel 	return 0;
576b7482f52SPhilipp Zabel }
577b7482f52SPhilipp Zabel 
578b7482f52SPhilipp Zabel #define UDA1380_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
579b7482f52SPhilipp Zabel 		       SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
580b7482f52SPhilipp Zabel 		       SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
581b7482f52SPhilipp Zabel 
5826335d055SEric Miao static struct snd_soc_dai_ops uda1380_dai_ops = {
5836335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
5846335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
585*65ec1cd1SMark Brown 	.trigger	= uda1380_trigger,
5866335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_both,
5876335d055SEric Miao };
5886335d055SEric Miao 
5896335d055SEric Miao static struct snd_soc_dai_ops uda1380_dai_ops_playback = {
5906335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
5916335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
592*65ec1cd1SMark Brown 	.trigger	= uda1380_trigger,
5936335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_playback,
5946335d055SEric Miao };
5956335d055SEric Miao 
5966335d055SEric Miao static struct snd_soc_dai_ops uda1380_dai_ops_capture = {
5976335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
5986335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
599*65ec1cd1SMark Brown 	.trigger	= uda1380_trigger,
6006335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_capture,
6016335d055SEric Miao };
6026335d055SEric Miao 
603e550e17fSLiam Girdwood struct snd_soc_dai uda1380_dai[] = {
604b7482f52SPhilipp Zabel {
605b7482f52SPhilipp Zabel 	.name = "UDA1380",
606b7482f52SPhilipp Zabel 	.playback = {
607b7482f52SPhilipp Zabel 		.stream_name = "Playback",
608b7482f52SPhilipp Zabel 		.channels_min = 1,
609b7482f52SPhilipp Zabel 		.channels_max = 2,
610b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
611b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
612b7482f52SPhilipp Zabel 	.capture = {
613b7482f52SPhilipp Zabel 		.stream_name = "Capture",
614b7482f52SPhilipp Zabel 		.channels_min = 1,
615b7482f52SPhilipp Zabel 		.channels_max = 2,
616b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
617b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
6186335d055SEric Miao 	.ops = &uda1380_dai_ops,
619b7482f52SPhilipp Zabel },
620b7482f52SPhilipp Zabel { /* playback only - dual interface */
621b7482f52SPhilipp Zabel 	.name = "UDA1380",
622b7482f52SPhilipp Zabel 	.playback = {
623b7482f52SPhilipp Zabel 		.stream_name = "Playback",
624b7482f52SPhilipp Zabel 		.channels_min = 1,
625b7482f52SPhilipp Zabel 		.channels_max = 2,
626b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
627b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
628b7482f52SPhilipp Zabel 	},
6296335d055SEric Miao 	.ops = &uda1380_dai_ops_playback,
630b7482f52SPhilipp Zabel },
631b7482f52SPhilipp Zabel { /* capture only - dual interface*/
632b7482f52SPhilipp Zabel 	.name = "UDA1380",
633b7482f52SPhilipp Zabel 	.capture = {
634b7482f52SPhilipp Zabel 		.stream_name = "Capture",
635b7482f52SPhilipp Zabel 		.channels_min = 1,
636b7482f52SPhilipp Zabel 		.channels_max = 2,
637b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
638b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
639b7482f52SPhilipp Zabel 	},
6406335d055SEric Miao 	.ops = &uda1380_dai_ops_capture,
641b7482f52SPhilipp Zabel },
642b7482f52SPhilipp Zabel };
643b7482f52SPhilipp Zabel EXPORT_SYMBOL_GPL(uda1380_dai);
644b7482f52SPhilipp Zabel 
645b7482f52SPhilipp Zabel static int uda1380_suspend(struct platform_device *pdev, pm_message_t state)
646b7482f52SPhilipp Zabel {
647b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
6486627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
649b7482f52SPhilipp Zabel 
650b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
651b7482f52SPhilipp Zabel 	return 0;
652b7482f52SPhilipp Zabel }
653b7482f52SPhilipp Zabel 
654b7482f52SPhilipp Zabel static int uda1380_resume(struct platform_device *pdev)
655b7482f52SPhilipp Zabel {
656b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
6576627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
658b7482f52SPhilipp Zabel 	int i;
659b7482f52SPhilipp Zabel 	u8 data[2];
660b7482f52SPhilipp Zabel 	u16 *cache = codec->reg_cache;
661b7482f52SPhilipp Zabel 
662b7482f52SPhilipp Zabel 	/* Sync reg_cache with the hardware */
663b7482f52SPhilipp Zabel 	for (i = 0; i < ARRAY_SIZE(uda1380_reg); i++) {
664b7482f52SPhilipp Zabel 		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
665b7482f52SPhilipp Zabel 		data[1] = cache[i] & 0x00ff;
666b7482f52SPhilipp Zabel 		codec->hw_write(codec->control_data, data, 2);
667b7482f52SPhilipp Zabel 	}
668b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
669b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, codec->suspend_bias_level);
670b7482f52SPhilipp Zabel 	return 0;
671b7482f52SPhilipp Zabel }
672b7482f52SPhilipp Zabel 
673b7482f52SPhilipp Zabel /*
674b7482f52SPhilipp Zabel  * initialise the UDA1380 driver
675b7482f52SPhilipp Zabel  * register mixer and dsp interfaces with the kernel
676b7482f52SPhilipp Zabel  */
677b7482f52SPhilipp Zabel static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
678b7482f52SPhilipp Zabel {
6796627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
680b7482f52SPhilipp Zabel 	int ret = 0;
681b7482f52SPhilipp Zabel 
682b7482f52SPhilipp Zabel 	codec->name = "UDA1380";
683b7482f52SPhilipp Zabel 	codec->owner = THIS_MODULE;
684b7482f52SPhilipp Zabel 	codec->read = uda1380_read_reg_cache;
685b7482f52SPhilipp Zabel 	codec->write = uda1380_write;
686b7482f52SPhilipp Zabel 	codec->set_bias_level = uda1380_set_bias_level;
687b7482f52SPhilipp Zabel 	codec->dai = uda1380_dai;
688b7482f52SPhilipp Zabel 	codec->num_dai = ARRAY_SIZE(uda1380_dai);
689b7482f52SPhilipp Zabel 	codec->reg_cache = kmemdup(uda1380_reg, sizeof(uda1380_reg),
690b7482f52SPhilipp Zabel 				   GFP_KERNEL);
691b7482f52SPhilipp Zabel 	if (codec->reg_cache == NULL)
692b7482f52SPhilipp Zabel 		return -ENOMEM;
6938ddd4407SMark Brown 	codec->reg_cache_size = ARRAY_SIZE(uda1380_reg);
6948ddd4407SMark Brown 	codec->reg_cache_step = 1;
695b7482f52SPhilipp Zabel 	uda1380_reset(codec);
696b7482f52SPhilipp Zabel 
697ef9e5e5cSPhilipp Zabel 	uda1380_codec = codec;
698ef9e5e5cSPhilipp Zabel 	INIT_WORK(&uda1380_work, uda1380_flush_work);
699ef9e5e5cSPhilipp Zabel 
700b7482f52SPhilipp Zabel 	/* register pcms */
701b7482f52SPhilipp Zabel 	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
702b7482f52SPhilipp Zabel 	if (ret < 0) {
703b7482f52SPhilipp Zabel 		pr_err("uda1380: failed to create pcms\n");
704b7482f52SPhilipp Zabel 		goto pcm_err;
705b7482f52SPhilipp Zabel 	}
706b7482f52SPhilipp Zabel 
707b7482f52SPhilipp Zabel 	/* power on device */
708b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
709b7482f52SPhilipp Zabel 	/* set clock input */
710b7482f52SPhilipp Zabel 	switch (dac_clk) {
711b7482f52SPhilipp Zabel 	case UDA1380_DAC_CLK_SYSCLK:
712b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_CLK, 0);
713b7482f52SPhilipp Zabel 		break;
714b7482f52SPhilipp Zabel 	case UDA1380_DAC_CLK_WSPLL:
715b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK);
716b7482f52SPhilipp Zabel 		break;
717b7482f52SPhilipp Zabel 	}
718b7482f52SPhilipp Zabel 
719b7482f52SPhilipp Zabel 	/* uda1380 init */
7203e8e1952SIan Molton 	snd_soc_add_controls(codec, uda1380_snd_controls,
7213e8e1952SIan Molton 				ARRAY_SIZE(uda1380_snd_controls));
722b7482f52SPhilipp Zabel 	uda1380_add_widgets(codec);
723968a6025SMark Brown 	ret = snd_soc_init_card(socdev);
724b7482f52SPhilipp Zabel 	if (ret < 0) {
725b7482f52SPhilipp Zabel 		pr_err("uda1380: failed to register card\n");
726b7482f52SPhilipp Zabel 		goto card_err;
727b7482f52SPhilipp Zabel 	}
728b7482f52SPhilipp Zabel 
729b7482f52SPhilipp Zabel 	return ret;
730b7482f52SPhilipp Zabel 
731b7482f52SPhilipp Zabel card_err:
732b7482f52SPhilipp Zabel 	snd_soc_free_pcms(socdev);
733b7482f52SPhilipp Zabel 	snd_soc_dapm_free(socdev);
734b7482f52SPhilipp Zabel pcm_err:
735b7482f52SPhilipp Zabel 	kfree(codec->reg_cache);
736b7482f52SPhilipp Zabel 	return ret;
737b7482f52SPhilipp Zabel }
738b7482f52SPhilipp Zabel 
739b7482f52SPhilipp Zabel static struct snd_soc_device *uda1380_socdev;
740b7482f52SPhilipp Zabel 
741b7482f52SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
742b7482f52SPhilipp Zabel 
74388fc39d7SJean Delvare static int uda1380_i2c_probe(struct i2c_client *i2c,
74488fc39d7SJean Delvare 			     const struct i2c_device_id *id)
745b7482f52SPhilipp Zabel {
746b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = uda1380_socdev;
747b7482f52SPhilipp Zabel 	struct uda1380_setup_data *setup = socdev->codec_data;
7486627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
749b7482f52SPhilipp Zabel 	int ret;
750b7482f52SPhilipp Zabel 
751b7482f52SPhilipp Zabel 	i2c_set_clientdata(i2c, codec);
752b7482f52SPhilipp Zabel 	codec->control_data = i2c;
753b7482f52SPhilipp Zabel 
754b7482f52SPhilipp Zabel 	ret = uda1380_init(socdev, setup->dac_clk);
75588fc39d7SJean Delvare 	if (ret < 0)
756b7482f52SPhilipp Zabel 		pr_err("uda1380: failed to initialise UDA1380\n");
757b7482f52SPhilipp Zabel 
758b7482f52SPhilipp Zabel 	return ret;
759b7482f52SPhilipp Zabel }
760b7482f52SPhilipp Zabel 
76188fc39d7SJean Delvare static int uda1380_i2c_remove(struct i2c_client *client)
762b7482f52SPhilipp Zabel {
763b7482f52SPhilipp Zabel 	struct snd_soc_codec *codec = i2c_get_clientdata(client);
764b7482f52SPhilipp Zabel 	kfree(codec->reg_cache);
765b7482f52SPhilipp Zabel 	return 0;
766b7482f52SPhilipp Zabel }
767b7482f52SPhilipp Zabel 
76888fc39d7SJean Delvare static const struct i2c_device_id uda1380_i2c_id[] = {
76988fc39d7SJean Delvare 	{ "uda1380", 0 },
77088fc39d7SJean Delvare 	{ }
77188fc39d7SJean Delvare };
77288fc39d7SJean Delvare MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
773b7482f52SPhilipp Zabel 
774b7482f52SPhilipp Zabel static struct i2c_driver uda1380_i2c_driver = {
775b7482f52SPhilipp Zabel 	.driver = {
776b7482f52SPhilipp Zabel 		.name =  "UDA1380 I2C Codec",
777b7482f52SPhilipp Zabel 		.owner = THIS_MODULE,
778b7482f52SPhilipp Zabel 	},
77988fc39d7SJean Delvare 	.probe =    uda1380_i2c_probe,
78088fc39d7SJean Delvare 	.remove =   uda1380_i2c_remove,
78188fc39d7SJean Delvare 	.id_table = uda1380_i2c_id,
782b7482f52SPhilipp Zabel };
783b7482f52SPhilipp Zabel 
78488fc39d7SJean Delvare static int uda1380_add_i2c_device(struct platform_device *pdev,
78588fc39d7SJean Delvare 				  const struct uda1380_setup_data *setup)
78688fc39d7SJean Delvare {
78788fc39d7SJean Delvare 	struct i2c_board_info info;
78888fc39d7SJean Delvare 	struct i2c_adapter *adapter;
78988fc39d7SJean Delvare 	struct i2c_client *client;
79088fc39d7SJean Delvare 	int ret;
79188fc39d7SJean Delvare 
79288fc39d7SJean Delvare 	ret = i2c_add_driver(&uda1380_i2c_driver);
79388fc39d7SJean Delvare 	if (ret != 0) {
79488fc39d7SJean Delvare 		dev_err(&pdev->dev, "can't add i2c driver\n");
79588fc39d7SJean Delvare 		return ret;
79688fc39d7SJean Delvare 	}
79788fc39d7SJean Delvare 
79888fc39d7SJean Delvare 	memset(&info, 0, sizeof(struct i2c_board_info));
79988fc39d7SJean Delvare 	info.addr = setup->i2c_address;
80088fc39d7SJean Delvare 	strlcpy(info.type, "uda1380", I2C_NAME_SIZE);
80188fc39d7SJean Delvare 
80288fc39d7SJean Delvare 	adapter = i2c_get_adapter(setup->i2c_bus);
80388fc39d7SJean Delvare 	if (!adapter) {
80488fc39d7SJean Delvare 		dev_err(&pdev->dev, "can't get i2c adapter %d\n",
80588fc39d7SJean Delvare 			setup->i2c_bus);
80688fc39d7SJean Delvare 		goto err_driver;
80788fc39d7SJean Delvare 	}
80888fc39d7SJean Delvare 
80988fc39d7SJean Delvare 	client = i2c_new_device(adapter, &info);
81088fc39d7SJean Delvare 	i2c_put_adapter(adapter);
81188fc39d7SJean Delvare 	if (!client) {
81288fc39d7SJean Delvare 		dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
81388fc39d7SJean Delvare 			(unsigned int)info.addr);
81488fc39d7SJean Delvare 		goto err_driver;
81588fc39d7SJean Delvare 	}
81688fc39d7SJean Delvare 
81788fc39d7SJean Delvare 	return 0;
81888fc39d7SJean Delvare 
81988fc39d7SJean Delvare err_driver:
82088fc39d7SJean Delvare 	i2c_del_driver(&uda1380_i2c_driver);
82188fc39d7SJean Delvare 	return -ENODEV;
82288fc39d7SJean Delvare }
823b7482f52SPhilipp Zabel #endif
824b7482f52SPhilipp Zabel 
825b7482f52SPhilipp Zabel static int uda1380_probe(struct platform_device *pdev)
826b7482f52SPhilipp Zabel {
827b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
828b7482f52SPhilipp Zabel 	struct uda1380_setup_data *setup;
829b7482f52SPhilipp Zabel 	struct snd_soc_codec *codec;
830b7c9d852SMark Brown 	int ret;
831b7482f52SPhilipp Zabel 
832b7482f52SPhilipp Zabel 	setup = socdev->codec_data;
833b7482f52SPhilipp Zabel 	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
834b7482f52SPhilipp Zabel 	if (codec == NULL)
835b7482f52SPhilipp Zabel 		return -ENOMEM;
836b7482f52SPhilipp Zabel 
8376627a653SMark Brown 	socdev->card->codec = codec;
838b7482f52SPhilipp Zabel 	mutex_init(&codec->mutex);
839b7482f52SPhilipp Zabel 	INIT_LIST_HEAD(&codec->dapm_widgets);
840b7482f52SPhilipp Zabel 	INIT_LIST_HEAD(&codec->dapm_paths);
841b7482f52SPhilipp Zabel 
842b7482f52SPhilipp Zabel 	uda1380_socdev = socdev;
843b7c9d852SMark Brown 	ret = -ENODEV;
844b7c9d852SMark Brown 
845b7482f52SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
846b7482f52SPhilipp Zabel 	if (setup->i2c_address) {
847b7482f52SPhilipp Zabel 		codec->hw_write = (hw_write_t)i2c_master_send;
84888fc39d7SJean Delvare 		ret = uda1380_add_i2c_device(pdev, setup);
849b7482f52SPhilipp Zabel 	}
850b7482f52SPhilipp Zabel #endif
8513051e41aSJean Delvare 
8523051e41aSJean Delvare 	if (ret != 0)
8533051e41aSJean Delvare 		kfree(codec);
854b7482f52SPhilipp Zabel 	return ret;
855b7482f52SPhilipp Zabel }
856b7482f52SPhilipp Zabel 
857b7482f52SPhilipp Zabel /* power down chip */
858b7482f52SPhilipp Zabel static int uda1380_remove(struct platform_device *pdev)
859b7482f52SPhilipp Zabel {
860b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
8616627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
862b7482f52SPhilipp Zabel 
863b7482f52SPhilipp Zabel 	if (codec->control_data)
864b7482f52SPhilipp Zabel 		uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
865b7482f52SPhilipp Zabel 
866b7482f52SPhilipp Zabel 	snd_soc_free_pcms(socdev);
867b7482f52SPhilipp Zabel 	snd_soc_dapm_free(socdev);
868b7482f52SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
86988fc39d7SJean Delvare 	i2c_unregister_device(codec->control_data);
870b7482f52SPhilipp Zabel 	i2c_del_driver(&uda1380_i2c_driver);
871b7482f52SPhilipp Zabel #endif
872b7482f52SPhilipp Zabel 	kfree(codec);
873b7482f52SPhilipp Zabel 
874b7482f52SPhilipp Zabel 	return 0;
875b7482f52SPhilipp Zabel }
876b7482f52SPhilipp Zabel 
877b7482f52SPhilipp Zabel struct snd_soc_codec_device soc_codec_dev_uda1380 = {
878b7482f52SPhilipp Zabel 	.probe = 	uda1380_probe,
879b7482f52SPhilipp Zabel 	.remove = 	uda1380_remove,
880b7482f52SPhilipp Zabel 	.suspend = 	uda1380_suspend,
881b7482f52SPhilipp Zabel 	.resume =	uda1380_resume,
882b7482f52SPhilipp Zabel };
883b7482f52SPhilipp Zabel EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
884b7482f52SPhilipp Zabel 
885c9b3a40fSTakashi Iwai static int __init uda1380_modinit(void)
88664089b84SMark Brown {
88764089b84SMark Brown 	return snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
88864089b84SMark Brown }
88964089b84SMark Brown module_init(uda1380_modinit);
89064089b84SMark Brown 
89164089b84SMark Brown static void __exit uda1380_exit(void)
89264089b84SMark Brown {
89364089b84SMark Brown 	snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
89464089b84SMark Brown }
89564089b84SMark Brown module_exit(uda1380_exit);
89664089b84SMark Brown 
897b7482f52SPhilipp Zabel MODULE_AUTHOR("Giorgio Padrin");
898b7482f52SPhilipp Zabel MODULE_DESCRIPTION("Audio support for codec Philips UDA1380");
899b7482f52SPhilipp Zabel MODULE_LICENSE("GPL");
900