xref: /linux/sound/soc/codecs/uda1380.c (revision f0fba2ad1b6b53d5360125c41953b7afcd6deff0)
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  *
81abd9184SPhilipp Zabel  * Copyright (c) 2007-2009 Philipp Zabel <philipp.zabel@gmail.com>
9b7482f52SPhilipp Zabel  *
10b7482f52SPhilipp Zabel  * Modified by Richard Purdie <richard@openedhand.com> to fit into SoC
11b7482f52SPhilipp Zabel  * codec model.
12b7482f52SPhilipp Zabel  *
13b7482f52SPhilipp Zabel  * Copyright (c) 2005 Giorgio Padrin <giorgio@mandarinlogiq.org>
14b7482f52SPhilipp Zabel  * Copyright 2005 Openedhand Ltd.
15b7482f52SPhilipp Zabel  */
16b7482f52SPhilipp Zabel 
17b7482f52SPhilipp Zabel #include <linux/module.h>
18b7482f52SPhilipp Zabel #include <linux/init.h>
19b7482f52SPhilipp Zabel #include <linux/types.h>
20b7482f52SPhilipp Zabel #include <linux/slab.h>
21b7482f52SPhilipp Zabel #include <linux/errno.h>
221abd9184SPhilipp Zabel #include <linux/gpio.h>
23b7482f52SPhilipp Zabel #include <linux/delay.h>
24b7482f52SPhilipp Zabel #include <linux/i2c.h>
25ef9e5e5cSPhilipp Zabel #include <linux/workqueue.h>
26b7482f52SPhilipp Zabel #include <sound/core.h>
27b7482f52SPhilipp Zabel #include <sound/control.h>
28b7482f52SPhilipp Zabel #include <sound/initval.h>
29b7482f52SPhilipp Zabel #include <sound/soc.h>
30b7482f52SPhilipp Zabel #include <sound/soc-dapm.h>
31b7482f52SPhilipp Zabel #include <sound/tlv.h>
321abd9184SPhilipp Zabel #include <sound/uda1380.h>
33b7482f52SPhilipp Zabel 
34b7482f52SPhilipp Zabel #include "uda1380.h"
35b7482f52SPhilipp Zabel 
361abd9184SPhilipp Zabel /* codec private data */
371abd9184SPhilipp Zabel struct uda1380_priv {
38*f0fba2adSLiam Girdwood 	struct snd_soc_codec *codec;
391abd9184SPhilipp Zabel 	u16 reg_cache[UDA1380_CACHEREGNUM];
401abd9184SPhilipp Zabel 	unsigned int dac_clk;
411abd9184SPhilipp Zabel 	struct work_struct work;
421abd9184SPhilipp Zabel };
431abd9184SPhilipp Zabel 
44b7482f52SPhilipp Zabel /*
45b7482f52SPhilipp Zabel  * uda1380 register cache
46b7482f52SPhilipp Zabel  */
47b7482f52SPhilipp Zabel static const u16 uda1380_reg[UDA1380_CACHEREGNUM] = {
48b7482f52SPhilipp Zabel 	0x0502, 0x0000, 0x0000, 0x3f3f,
49b7482f52SPhilipp Zabel 	0x0202, 0x0000, 0x0000, 0x0000,
50b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
51b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
52b7482f52SPhilipp Zabel 	0x0000, 0xff00, 0x0000, 0x4800,
53b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
54b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
55b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
56b7482f52SPhilipp Zabel 	0x0000, 0x8000, 0x0002, 0x0000,
57b7482f52SPhilipp Zabel };
58b7482f52SPhilipp Zabel 
59ef9e5e5cSPhilipp Zabel static unsigned long uda1380_cache_dirty;
60ef9e5e5cSPhilipp Zabel 
61b7482f52SPhilipp Zabel /*
62b7482f52SPhilipp Zabel  * read uda1380 register cache
63b7482f52SPhilipp Zabel  */
64b7482f52SPhilipp Zabel static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec,
65b7482f52SPhilipp Zabel 	unsigned int reg)
66b7482f52SPhilipp Zabel {
67b7482f52SPhilipp Zabel 	u16 *cache = codec->reg_cache;
68b7482f52SPhilipp Zabel 	if (reg == UDA1380_RESET)
69b7482f52SPhilipp Zabel 		return 0;
70b7482f52SPhilipp Zabel 	if (reg >= UDA1380_CACHEREGNUM)
71b7482f52SPhilipp Zabel 		return -1;
72b7482f52SPhilipp Zabel 	return cache[reg];
73b7482f52SPhilipp Zabel }
74b7482f52SPhilipp Zabel 
75b7482f52SPhilipp Zabel /*
76b7482f52SPhilipp Zabel  * write uda1380 register cache
77b7482f52SPhilipp Zabel  */
78b7482f52SPhilipp Zabel static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
79b7482f52SPhilipp Zabel 	u16 reg, unsigned int value)
80b7482f52SPhilipp Zabel {
81b7482f52SPhilipp Zabel 	u16 *cache = codec->reg_cache;
82ef9e5e5cSPhilipp Zabel 
83b7482f52SPhilipp Zabel 	if (reg >= UDA1380_CACHEREGNUM)
84b7482f52SPhilipp Zabel 		return;
85ef9e5e5cSPhilipp Zabel 	if ((reg >= 0x10) && (cache[reg] != value))
86ef9e5e5cSPhilipp Zabel 		set_bit(reg - 0x10, &uda1380_cache_dirty);
87b7482f52SPhilipp Zabel 	cache[reg] = value;
88b7482f52SPhilipp Zabel }
89b7482f52SPhilipp Zabel 
90b7482f52SPhilipp Zabel /*
91b7482f52SPhilipp Zabel  * write to the UDA1380 register space
92b7482f52SPhilipp Zabel  */
93b7482f52SPhilipp Zabel static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
94b7482f52SPhilipp Zabel 	unsigned int value)
95b7482f52SPhilipp Zabel {
96b7482f52SPhilipp Zabel 	u8 data[3];
97b7482f52SPhilipp Zabel 
98b7482f52SPhilipp Zabel 	/* data is
99b7482f52SPhilipp Zabel 	 *   data[0] is register offset
100b7482f52SPhilipp Zabel 	 *   data[1] is MS byte
101b7482f52SPhilipp Zabel 	 *   data[2] is LS byte
102b7482f52SPhilipp Zabel 	 */
103b7482f52SPhilipp Zabel 	data[0] = reg;
104b7482f52SPhilipp Zabel 	data[1] = (value & 0xff00) >> 8;
105b7482f52SPhilipp Zabel 	data[2] = value & 0x00ff;
106b7482f52SPhilipp Zabel 
107b7482f52SPhilipp Zabel 	uda1380_write_reg_cache(codec, reg, value);
108b7482f52SPhilipp Zabel 
109b7482f52SPhilipp Zabel 	/* the interpolator & decimator regs must only be written when the
110b7482f52SPhilipp Zabel 	 * codec DAI is active.
111b7482f52SPhilipp Zabel 	 */
112b7482f52SPhilipp Zabel 	if (!codec->active && (reg >= UDA1380_MVOL))
113b7482f52SPhilipp Zabel 		return 0;
114b7482f52SPhilipp Zabel 	pr_debug("uda1380: hw write %x val %x\n", reg, value);
115b7482f52SPhilipp Zabel 	if (codec->hw_write(codec->control_data, data, 3) == 3) {
116b7482f52SPhilipp Zabel 		unsigned int val;
117b7482f52SPhilipp Zabel 		i2c_master_send(codec->control_data, data, 1);
118b7482f52SPhilipp Zabel 		i2c_master_recv(codec->control_data, data, 2);
119b7482f52SPhilipp Zabel 		val = (data[0]<<8) | data[1];
120b7482f52SPhilipp Zabel 		if (val != value) {
121b7482f52SPhilipp Zabel 			pr_debug("uda1380: READ BACK VAL %x\n",
122b7482f52SPhilipp Zabel 					(data[0]<<8) | data[1]);
123b7482f52SPhilipp Zabel 			return -EIO;
124b7482f52SPhilipp Zabel 		}
125ef9e5e5cSPhilipp Zabel 		if (reg >= 0x10)
126ef9e5e5cSPhilipp Zabel 			clear_bit(reg - 0x10, &uda1380_cache_dirty);
127b7482f52SPhilipp Zabel 		return 0;
128b7482f52SPhilipp Zabel 	} else
129b7482f52SPhilipp Zabel 		return -EIO;
130b7482f52SPhilipp Zabel }
131b7482f52SPhilipp Zabel 
132b7482f52SPhilipp Zabel #define uda1380_reset(c)	uda1380_write(c, UDA1380_RESET, 0)
133b7482f52SPhilipp Zabel 
134ef9e5e5cSPhilipp Zabel static void uda1380_flush_work(struct work_struct *work)
135ef9e5e5cSPhilipp Zabel {
136*f0fba2adSLiam Girdwood 	struct uda1380_priv *uda1380 = container_of(work, struct uda1380_priv, work);
137*f0fba2adSLiam Girdwood 	struct snd_soc_codec *uda1380_codec = uda1380->codec;
138ef9e5e5cSPhilipp Zabel 	int bit, reg;
139ef9e5e5cSPhilipp Zabel 
140984b3f57SAkinobu Mita 	for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
141ef9e5e5cSPhilipp Zabel 		reg = 0x10 + bit;
142ef9e5e5cSPhilipp Zabel 		pr_debug("uda1380: flush reg %x val %x:\n", reg,
143ef9e5e5cSPhilipp Zabel 				uda1380_read_reg_cache(uda1380_codec, reg));
144ef9e5e5cSPhilipp Zabel 		uda1380_write(uda1380_codec, reg,
145ef9e5e5cSPhilipp Zabel 				uda1380_read_reg_cache(uda1380_codec, reg));
146ef9e5e5cSPhilipp Zabel 		clear_bit(bit, &uda1380_cache_dirty);
147ef9e5e5cSPhilipp Zabel 	}
148*f0fba2adSLiam Girdwood 
149ef9e5e5cSPhilipp Zabel }
150ef9e5e5cSPhilipp Zabel 
151b7482f52SPhilipp Zabel /* declarations of ALSA reg_elem_REAL controls */
152b7482f52SPhilipp Zabel static const char *uda1380_deemp[] = {
153b7482f52SPhilipp Zabel 	"None",
154b7482f52SPhilipp Zabel 	"32kHz",
155b7482f52SPhilipp Zabel 	"44.1kHz",
156b7482f52SPhilipp Zabel 	"48kHz",
157b7482f52SPhilipp Zabel 	"96kHz",
158b7482f52SPhilipp Zabel };
159b7482f52SPhilipp Zabel static const char *uda1380_input_sel[] = {
160b7482f52SPhilipp Zabel 	"Line",
161b7482f52SPhilipp Zabel 	"Mic + Line R",
162b7482f52SPhilipp Zabel 	"Line L",
163b7482f52SPhilipp Zabel 	"Mic",
164b7482f52SPhilipp Zabel };
165b7482f52SPhilipp Zabel static const char *uda1380_output_sel[] = {
166b7482f52SPhilipp Zabel 	"DAC",
167b7482f52SPhilipp Zabel 	"Analog Mixer",
168b7482f52SPhilipp Zabel };
169b7482f52SPhilipp Zabel static const char *uda1380_spf_mode[] = {
170b7482f52SPhilipp Zabel 	"Flat",
171b7482f52SPhilipp Zabel 	"Minimum1",
172b7482f52SPhilipp Zabel 	"Minimum2",
173b7482f52SPhilipp Zabel 	"Maximum"
174b7482f52SPhilipp Zabel };
175b7482f52SPhilipp Zabel static const char *uda1380_capture_sel[] = {
176b7482f52SPhilipp Zabel 	"ADC",
177b7482f52SPhilipp Zabel 	"Digital Mixer"
178b7482f52SPhilipp Zabel };
179b7482f52SPhilipp Zabel static const char *uda1380_sel_ns[] = {
180b7482f52SPhilipp Zabel 	"3rd-order",
181b7482f52SPhilipp Zabel 	"5th-order"
182b7482f52SPhilipp Zabel };
183b7482f52SPhilipp Zabel static const char *uda1380_mix_control[] = {
184b7482f52SPhilipp Zabel 	"off",
185b7482f52SPhilipp Zabel 	"PCM only",
186b7482f52SPhilipp Zabel 	"before sound processing",
187b7482f52SPhilipp Zabel 	"after sound processing"
188b7482f52SPhilipp Zabel };
189b7482f52SPhilipp Zabel static const char *uda1380_sdet_setting[] = {
190b7482f52SPhilipp Zabel 	"3200",
191b7482f52SPhilipp Zabel 	"4800",
192b7482f52SPhilipp Zabel 	"9600",
193b7482f52SPhilipp Zabel 	"19200"
194b7482f52SPhilipp Zabel };
195b7482f52SPhilipp Zabel static const char *uda1380_os_setting[] = {
196b7482f52SPhilipp Zabel 	"single-speed",
197b7482f52SPhilipp Zabel 	"double-speed (no mixing)",
198b7482f52SPhilipp Zabel 	"quad-speed (no mixing)"
199b7482f52SPhilipp Zabel };
200b7482f52SPhilipp Zabel 
201b7482f52SPhilipp Zabel static const struct soc_enum uda1380_deemp_enum[] = {
202b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_DEEMP, 8, 5, uda1380_deemp),
203b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_DEEMP, 0, 5, uda1380_deemp),
204b7482f52SPhilipp Zabel };
205b7482f52SPhilipp Zabel static const struct soc_enum uda1380_input_sel_enum =
206b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_ADC, 2, 4, uda1380_input_sel);		/* SEL_MIC, SEL_LNA */
207b7482f52SPhilipp Zabel static const struct soc_enum uda1380_output_sel_enum =
208b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_PM, 7, 2, uda1380_output_sel);		/* R02_EN_AVC */
209b7482f52SPhilipp Zabel static const struct soc_enum uda1380_spf_enum =
210b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MODE, 14, 4, uda1380_spf_mode);		/* M */
211b7482f52SPhilipp Zabel static const struct soc_enum uda1380_capture_sel_enum =
212b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_IFACE, 6, 2, uda1380_capture_sel);	/* SEL_SOURCE */
213b7482f52SPhilipp Zabel static const struct soc_enum uda1380_sel_ns_enum =
214b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 14, 2, uda1380_sel_ns);		/* SEL_NS */
215b7482f52SPhilipp Zabel static const struct soc_enum uda1380_mix_enum =
216b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 12, 4, uda1380_mix_control);	/* MIX, MIX_POS */
217b7482f52SPhilipp Zabel static const struct soc_enum uda1380_sdet_enum =
218b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 4, 4, uda1380_sdet_setting);	/* SD_VALUE */
219b7482f52SPhilipp Zabel static const struct soc_enum uda1380_os_enum =
220b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 0, 3, uda1380_os_setting);	/* OS */
221b7482f52SPhilipp Zabel 
222b7482f52SPhilipp Zabel /*
223b7482f52SPhilipp Zabel  * from -48 dB in 1.5 dB steps (mute instead of -49.5 dB)
224b7482f52SPhilipp Zabel  */
225b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(amix_tlv, -4950, 150, 1);
226b7482f52SPhilipp Zabel 
227b7482f52SPhilipp Zabel /*
228b7482f52SPhilipp Zabel  * from -78 dB in 1 dB steps (3 dB steps, really. LSB are ignored),
229b7482f52SPhilipp Zabel  * from -66 dB in 0.5 dB steps (2 dB steps, really) and
230b7482f52SPhilipp Zabel  * from -52 dB in 0.25 dB steps
231b7482f52SPhilipp Zabel  */
232b7482f52SPhilipp Zabel static const unsigned int mvol_tlv[] = {
233b7482f52SPhilipp Zabel 	TLV_DB_RANGE_HEAD(3),
234b7482f52SPhilipp Zabel 	0, 15, TLV_DB_SCALE_ITEM(-8200, 100, 1),
235b7482f52SPhilipp Zabel 	16, 43, TLV_DB_SCALE_ITEM(-6600, 50, 0),
236b7482f52SPhilipp Zabel 	44, 252, TLV_DB_SCALE_ITEM(-5200, 25, 0),
237b7482f52SPhilipp Zabel };
238b7482f52SPhilipp Zabel 
239b7482f52SPhilipp Zabel /*
240b7482f52SPhilipp Zabel  * from -72 dB in 1.5 dB steps (6 dB steps really),
241b7482f52SPhilipp Zabel  * from -66 dB in 0.75 dB steps (3 dB steps really),
242b7482f52SPhilipp Zabel  * from -60 dB in 0.5 dB steps (2 dB steps really) and
243b7482f52SPhilipp Zabel  * from -46 dB in 0.25 dB steps
244b7482f52SPhilipp Zabel  */
245b7482f52SPhilipp Zabel static const unsigned int vc_tlv[] = {
246b7482f52SPhilipp Zabel 	TLV_DB_RANGE_HEAD(4),
247b7482f52SPhilipp Zabel 	0, 7, TLV_DB_SCALE_ITEM(-7800, 150, 1),
248b7482f52SPhilipp Zabel 	8, 15, TLV_DB_SCALE_ITEM(-6600, 75, 0),
249b7482f52SPhilipp Zabel 	16, 43, TLV_DB_SCALE_ITEM(-6000, 50, 0),
250b7482f52SPhilipp Zabel 	44, 228, TLV_DB_SCALE_ITEM(-4600, 25, 0),
251b7482f52SPhilipp Zabel };
252b7482f52SPhilipp Zabel 
253b7482f52SPhilipp Zabel /* from 0 to 6 dB in 2 dB steps if SPF mode != flat */
254b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(tr_tlv, 0, 200, 0);
255b7482f52SPhilipp Zabel 
256b7482f52SPhilipp Zabel /* from 0 to 24 dB in 2 dB steps, if SPF mode == maximum, otherwise cuts
257b7482f52SPhilipp Zabel  * off at 18 dB max) */
258b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(bb_tlv, 0, 200, 0);
259b7482f52SPhilipp Zabel 
260b7482f52SPhilipp Zabel /* from -63 to 24 dB in 0.5 dB steps (-128...48) */
261b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(dec_tlv, -6400, 50, 1);
262b7482f52SPhilipp Zabel 
263b7482f52SPhilipp Zabel /* from 0 to 24 dB in 3 dB steps */
264b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0);
265b7482f52SPhilipp Zabel 
266b7482f52SPhilipp Zabel /* from 0 to 30 dB in 2 dB steps */
267b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(vga_tlv, 0, 200, 0);
268b7482f52SPhilipp Zabel 
269b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_snd_controls[] = {
270b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Analog Mixer Volume", UDA1380_AMIX, 0, 8, 44, 1, amix_tlv),	/* AVCR, AVCL */
271b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Master Playback Volume", UDA1380_MVOL, 0, 8, 252, 1, mvol_tlv),	/* MVCL, MVCR */
272b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("ADC Playback Volume", UDA1380_MIXVOL, 8, 228, 1, vc_tlv),	/* VC2 */
273b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("PCM Playback Volume", UDA1380_MIXVOL, 0, 228, 1, vc_tlv),	/* VC1 */
274b7482f52SPhilipp Zabel 	SOC_ENUM("Sound Processing Filter", uda1380_spf_enum),				/* M */
275b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Tone Control - Treble", UDA1380_MODE, 4, 12, 3, 0, tr_tlv), 	/* TRL, TRR */
276b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Tone Control - Bass", UDA1380_MODE, 0, 8, 15, 0, bb_tlv),	/* BBL, BBR */
277b7482f52SPhilipp Zabel /**/	SOC_SINGLE("Master Playback Switch", UDA1380_DEEMP, 14, 1, 1),		/* MTM */
278b7482f52SPhilipp Zabel 	SOC_SINGLE("ADC Playback Switch", UDA1380_DEEMP, 11, 1, 1),		/* MT2 from decimation filter */
279b7482f52SPhilipp Zabel 	SOC_ENUM("ADC Playback De-emphasis", uda1380_deemp_enum[0]),		/* DE2 */
280b7482f52SPhilipp Zabel 	SOC_SINGLE("PCM Playback Switch", UDA1380_DEEMP, 3, 1, 1),		/* MT1, from digital data input */
281b7482f52SPhilipp Zabel 	SOC_ENUM("PCM Playback De-emphasis", uda1380_deemp_enum[1]),		/* DE1 */
282b7482f52SPhilipp Zabel 	SOC_SINGLE("DAC Polarity inverting Switch", UDA1380_MIXER, 15, 1, 0),	/* DA_POL_INV */
283b7482f52SPhilipp Zabel 	SOC_ENUM("Noise Shaper", uda1380_sel_ns_enum),				/* SEL_NS */
284b7482f52SPhilipp Zabel 	SOC_ENUM("Digital Mixer Signal Control", uda1380_mix_enum),		/* MIX_POS, MIX */
285b7482f52SPhilipp Zabel 	SOC_SINGLE("Silence Detector Switch", UDA1380_MIXER, 6, 1, 0),		/* SDET_ON */
286b7482f52SPhilipp Zabel 	SOC_ENUM("Silence Detector Setting", uda1380_sdet_enum),		/* SD_VALUE */
287b7482f52SPhilipp Zabel 	SOC_ENUM("Oversampling Input", uda1380_os_enum),			/* OS */
288b7482f52SPhilipp Zabel 	SOC_DOUBLE_S8_TLV("ADC Capture Volume", UDA1380_DEC, -128, 48, dec_tlv),	/* ML_DEC, MR_DEC */
289b7482f52SPhilipp Zabel /**/	SOC_SINGLE("ADC Capture Switch", UDA1380_PGA, 15, 1, 1),		/* MT_ADC */
290b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Line Capture Volume", UDA1380_PGA, 0, 8, 8, 0, pga_tlv), /* PGA_GAINCTRLL, PGA_GAINCTRLR */
291b7482f52SPhilipp Zabel 	SOC_SINGLE("ADC Polarity inverting Switch", UDA1380_ADC, 12, 1, 0),	/* ADCPOL_INV */
292b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("Mic Capture Volume", UDA1380_ADC, 8, 15, 0, vga_tlv),	/* VGA_CTRL */
293b7482f52SPhilipp Zabel 	SOC_SINGLE("DC Filter Bypass Switch", UDA1380_ADC, 1, 1, 0),		/* SKIP_DCFIL (before decimator) */
294b7482f52SPhilipp Zabel 	SOC_SINGLE("DC Filter Enable Switch", UDA1380_ADC, 0, 1, 0),		/* EN_DCFIL (at output of decimator) */
295b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Timing", UDA1380_AGC, 8, 7, 0),			/* TODO: enum, see table 62 */
296b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Target level", UDA1380_AGC, 2, 3, 1),			/* AGC_LEVEL */
297b7482f52SPhilipp Zabel 	/* -5.5, -8, -11.5, -14 dBFS */
298b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0),
299b7482f52SPhilipp Zabel };
300b7482f52SPhilipp Zabel 
301b7482f52SPhilipp Zabel /* Input mux */
302b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_input_mux_control =
303b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_input_sel_enum);
304b7482f52SPhilipp Zabel 
305b7482f52SPhilipp Zabel /* Output mux */
306b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_output_mux_control =
307b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_output_sel_enum);
308b7482f52SPhilipp Zabel 
309b7482f52SPhilipp Zabel /* Capture mux */
310b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_capture_mux_control =
311b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_capture_sel_enum);
312b7482f52SPhilipp Zabel 
313b7482f52SPhilipp Zabel 
314b7482f52SPhilipp Zabel static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
315b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
316b7482f52SPhilipp Zabel 		&uda1380_input_mux_control),
317b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM, 0, 0,
318b7482f52SPhilipp Zabel 		&uda1380_output_mux_control),
319b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0,
320b7482f52SPhilipp Zabel 		&uda1380_capture_mux_control),
321b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Left PGA", UDA1380_PM, 3, 0, NULL, 0),
322b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Right PGA", UDA1380_PM, 1, 0, NULL, 0),
323b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Mic LNA", UDA1380_PM, 4, 0, NULL, 0),
324b7482f52SPhilipp Zabel 	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", UDA1380_PM, 2, 0),
325b7482f52SPhilipp Zabel 	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", UDA1380_PM, 0, 0),
326b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINM"),
327b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINL"),
328b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINR"),
329b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MIXER("Analog Mixer", UDA1380_PM, 6, 0, NULL, 0),
330b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTLHP"),
331b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTRHP"),
332b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTL"),
333b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTR"),
334b7482f52SPhilipp Zabel 	SND_SOC_DAPM_DAC("DAC", "Playback", UDA1380_PM, 10, 0),
335b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("HeadPhone Driver", UDA1380_PM, 13, 0, NULL, 0),
336b7482f52SPhilipp Zabel };
337b7482f52SPhilipp Zabel 
338b7482f52SPhilipp Zabel static const struct snd_soc_dapm_route audio_map[] = {
339b7482f52SPhilipp Zabel 
340b7482f52SPhilipp Zabel 	/* output mux */
341b7482f52SPhilipp Zabel 	{"HeadPhone Driver", NULL, "Output Mux"},
342b7482f52SPhilipp Zabel 	{"VOUTR", NULL, "Output Mux"},
343b7482f52SPhilipp Zabel 	{"VOUTL", NULL, "Output Mux"},
344b7482f52SPhilipp Zabel 
345b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "VINR"},
346b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "VINL"},
347b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "DAC"},
348b7482f52SPhilipp Zabel 
349b7482f52SPhilipp Zabel 	{"Output Mux", "DAC", "DAC"},
350b7482f52SPhilipp Zabel 	{"Output Mux", "Analog Mixer", "Analog Mixer"},
351b7482f52SPhilipp Zabel 
352b7482f52SPhilipp Zabel 	/* {"DAC", "Digital Mixer", "I2S" } */
353b7482f52SPhilipp Zabel 
354b7482f52SPhilipp Zabel 	/* headphone driver */
355b7482f52SPhilipp Zabel 	{"VOUTLHP", NULL, "HeadPhone Driver"},
356b7482f52SPhilipp Zabel 	{"VOUTRHP", NULL, "HeadPhone Driver"},
357b7482f52SPhilipp Zabel 
358b7482f52SPhilipp Zabel 	/* input mux */
359b7482f52SPhilipp Zabel 	{"Left ADC", NULL, "Input Mux"},
360b7482f52SPhilipp Zabel 	{"Input Mux", "Mic", "Mic LNA"},
361b7482f52SPhilipp Zabel 	{"Input Mux", "Mic + Line R", "Mic LNA"},
362b7482f52SPhilipp Zabel 	{"Input Mux", "Line L", "Left PGA"},
363b7482f52SPhilipp Zabel 	{"Input Mux", "Line", "Left PGA"},
364b7482f52SPhilipp Zabel 
365b7482f52SPhilipp Zabel 	/* right input */
366b7482f52SPhilipp Zabel 	{"Right ADC", "Mic + Line R", "Right PGA"},
367b7482f52SPhilipp Zabel 	{"Right ADC", "Line", "Right PGA"},
368b7482f52SPhilipp Zabel 
369b7482f52SPhilipp Zabel 	/* inputs */
370b7482f52SPhilipp Zabel 	{"Mic LNA", NULL, "VINM"},
371b7482f52SPhilipp Zabel 	{"Left PGA", NULL, "VINL"},
372b7482f52SPhilipp Zabel 	{"Right PGA", NULL, "VINR"},
373b7482f52SPhilipp Zabel };
374b7482f52SPhilipp Zabel 
375b7482f52SPhilipp Zabel static int uda1380_add_widgets(struct snd_soc_codec *codec)
376b7482f52SPhilipp Zabel {
377b7482f52SPhilipp Zabel 	snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets,
378b7482f52SPhilipp Zabel 				  ARRAY_SIZE(uda1380_dapm_widgets));
379b7482f52SPhilipp Zabel 
380b7482f52SPhilipp Zabel 	snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
381b7482f52SPhilipp Zabel 
382b7482f52SPhilipp Zabel 	return 0;
383b7482f52SPhilipp Zabel }
384b7482f52SPhilipp Zabel 
3855b247442SPhilipp Zabel static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
386b7482f52SPhilipp Zabel 		unsigned int fmt)
387b7482f52SPhilipp Zabel {
388b7482f52SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
389b7482f52SPhilipp Zabel 	int iface;
390b7482f52SPhilipp Zabel 
391b7482f52SPhilipp Zabel 	/* set up DAI based upon fmt */
392b7482f52SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
393b7482f52SPhilipp Zabel 	iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK);
394b7482f52SPhilipp Zabel 
395b7482f52SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
396b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
397b7482f52SPhilipp Zabel 		iface |= R01_SFORI_I2S | R01_SFORO_I2S;
398b7482f52SPhilipp Zabel 		break;
399b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4005b247442SPhilipp Zabel 		iface |= R01_SFORI_LSB16 | R01_SFORO_LSB16;
401b7482f52SPhilipp Zabel 		break;
402b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4035b247442SPhilipp Zabel 		iface |= R01_SFORI_MSB | R01_SFORO_MSB;
4045b247442SPhilipp Zabel 	}
4055b247442SPhilipp Zabel 
4065f2a9384SPhilipp Zabel 	/* DATAI is slave only, so in single-link mode, this has to be slave */
4075f2a9384SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
4085f2a9384SPhilipp Zabel 		return -EINVAL;
4095b247442SPhilipp Zabel 
4105b247442SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
4115b247442SPhilipp Zabel 
4125b247442SPhilipp Zabel 	return 0;
4135b247442SPhilipp Zabel }
4145b247442SPhilipp Zabel 
4155b247442SPhilipp Zabel static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
4165b247442SPhilipp Zabel 		unsigned int fmt)
4175b247442SPhilipp Zabel {
4185b247442SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
4195b247442SPhilipp Zabel 	int iface;
4205b247442SPhilipp Zabel 
4215b247442SPhilipp Zabel 	/* set up DAI based upon fmt */
4225b247442SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
4235b247442SPhilipp Zabel 	iface &= ~R01_SFORI_MASK;
4245b247442SPhilipp Zabel 
4255b247442SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
4265b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
4275b247442SPhilipp Zabel 		iface |= R01_SFORI_I2S;
4285b247442SPhilipp Zabel 		break;
4295b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4305b247442SPhilipp Zabel 		iface |= R01_SFORI_LSB16;
4315b247442SPhilipp Zabel 		break;
4325b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4335b247442SPhilipp Zabel 		iface |= R01_SFORI_MSB;
4345b247442SPhilipp Zabel 	}
4355b247442SPhilipp Zabel 
4365f2a9384SPhilipp Zabel 	/* DATAI is slave only, so this has to be slave */
4375f2a9384SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
4385f2a9384SPhilipp Zabel 		return -EINVAL;
4395f2a9384SPhilipp Zabel 
4405b247442SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
4415b247442SPhilipp Zabel 
4425b247442SPhilipp Zabel 	return 0;
4435b247442SPhilipp Zabel }
4445b247442SPhilipp Zabel 
4455b247442SPhilipp Zabel static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
4465b247442SPhilipp Zabel 		unsigned int fmt)
4475b247442SPhilipp Zabel {
4485b247442SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
4495b247442SPhilipp Zabel 	int iface;
4505b247442SPhilipp Zabel 
4515b247442SPhilipp Zabel 	/* set up DAI based upon fmt */
4525b247442SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
4535b247442SPhilipp Zabel 	iface &= ~(R01_SIM | R01_SFORO_MASK);
4545b247442SPhilipp Zabel 
4555b247442SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
4565b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
4575b247442SPhilipp Zabel 		iface |= R01_SFORO_I2S;
4585b247442SPhilipp Zabel 		break;
4595b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4605b247442SPhilipp Zabel 		iface |= R01_SFORO_LSB16;
4615b247442SPhilipp Zabel 		break;
4625b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4635b247442SPhilipp Zabel 		iface |= R01_SFORO_MSB;
464b7482f52SPhilipp Zabel 	}
465b7482f52SPhilipp Zabel 
466b7482f52SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
467b7482f52SPhilipp Zabel 		iface |= R01_SIM;
468b7482f52SPhilipp Zabel 
469b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
470b7482f52SPhilipp Zabel 
471b7482f52SPhilipp Zabel 	return 0;
472b7482f52SPhilipp Zabel }
473b7482f52SPhilipp Zabel 
474ef9e5e5cSPhilipp Zabel static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
475dee89c4dSMark Brown 		struct snd_soc_dai *dai)
476b7482f52SPhilipp Zabel {
477b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
478*f0fba2adSLiam Girdwood 	struct snd_soc_codec *codec = rtd->codec;
479b2c812e2SMark Brown 	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
480ef9e5e5cSPhilipp Zabel 	int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
481b7482f52SPhilipp Zabel 
482ef9e5e5cSPhilipp Zabel 	switch (cmd) {
483ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_START:
484ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
485ef9e5e5cSPhilipp Zabel 		uda1380_write_reg_cache(codec, UDA1380_MIXER,
486ef9e5e5cSPhilipp Zabel 					mixer & ~R14_SILENCE);
4871abd9184SPhilipp Zabel 		schedule_work(&uda1380->work);
488ef9e5e5cSPhilipp Zabel 		break;
489ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_STOP:
490ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
491ef9e5e5cSPhilipp Zabel 		uda1380_write_reg_cache(codec, UDA1380_MIXER,
492ef9e5e5cSPhilipp Zabel 					mixer | R14_SILENCE);
4931abd9184SPhilipp Zabel 		schedule_work(&uda1380->work);
494ef9e5e5cSPhilipp Zabel 		break;
495b7482f52SPhilipp Zabel 	}
496b7482f52SPhilipp Zabel 	return 0;
497b7482f52SPhilipp Zabel }
498b7482f52SPhilipp Zabel 
499b7482f52SPhilipp Zabel static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
500dee89c4dSMark Brown 				 struct snd_pcm_hw_params *params,
501dee89c4dSMark Brown 				 struct snd_soc_dai *dai)
502b7482f52SPhilipp Zabel {
503b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
504*f0fba2adSLiam Girdwood 	struct snd_soc_codec *codec = rtd->codec;
505b7482f52SPhilipp Zabel 	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
506b7482f52SPhilipp Zabel 
507b7482f52SPhilipp Zabel 	/* set WSPLL power and divider if running from this clock */
508b7482f52SPhilipp Zabel 	if (clk & R00_DAC_CLK) {
509b7482f52SPhilipp Zabel 		int rate = params_rate(params);
510b7482f52SPhilipp Zabel 		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
511b7482f52SPhilipp Zabel 		clk &= ~0x3; /* clear SEL_LOOP_DIV */
512b7482f52SPhilipp Zabel 		switch (rate) {
513b7482f52SPhilipp Zabel 		case 6250 ... 12500:
514b7482f52SPhilipp Zabel 			clk |= 0x0;
515b7482f52SPhilipp Zabel 			break;
516b7482f52SPhilipp Zabel 		case 12501 ... 25000:
517b7482f52SPhilipp Zabel 			clk |= 0x1;
518b7482f52SPhilipp Zabel 			break;
519b7482f52SPhilipp Zabel 		case 25001 ... 50000:
520b7482f52SPhilipp Zabel 			clk |= 0x2;
521b7482f52SPhilipp Zabel 			break;
522b7482f52SPhilipp Zabel 		case 50001 ... 100000:
523b7482f52SPhilipp Zabel 			clk |= 0x3;
524b7482f52SPhilipp Zabel 			break;
525b7482f52SPhilipp Zabel 		}
526b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_PLL | pm);
527b7482f52SPhilipp Zabel 	}
528b7482f52SPhilipp Zabel 
529b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
530b7482f52SPhilipp Zabel 		clk |= R00_EN_DAC | R00_EN_INT;
531b7482f52SPhilipp Zabel 	else
532b7482f52SPhilipp Zabel 		clk |= R00_EN_ADC | R00_EN_DEC;
533b7482f52SPhilipp Zabel 
534b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, clk);
535b7482f52SPhilipp Zabel 	return 0;
536b7482f52SPhilipp Zabel }
537b7482f52SPhilipp Zabel 
538dee89c4dSMark Brown static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
539dee89c4dSMark Brown 				 struct snd_soc_dai *dai)
540b7482f52SPhilipp Zabel {
541b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
542*f0fba2adSLiam Girdwood 	struct snd_soc_codec *codec = rtd->codec;
543b7482f52SPhilipp Zabel 	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
544b7482f52SPhilipp Zabel 
545b7482f52SPhilipp Zabel 	/* shut down WSPLL power if running from this clock */
546b7482f52SPhilipp Zabel 	if (clk & R00_DAC_CLK) {
547b7482f52SPhilipp Zabel 		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
548b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, ~R02_PON_PLL & pm);
549b7482f52SPhilipp Zabel 	}
550b7482f52SPhilipp Zabel 
551b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
552b7482f52SPhilipp Zabel 		clk &= ~(R00_EN_DAC | R00_EN_INT);
553b7482f52SPhilipp Zabel 	else
554b7482f52SPhilipp Zabel 		clk &= ~(R00_EN_ADC | R00_EN_DEC);
555b7482f52SPhilipp Zabel 
556b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, clk);
557b7482f52SPhilipp Zabel }
558b7482f52SPhilipp Zabel 
559b7482f52SPhilipp Zabel static int uda1380_set_bias_level(struct snd_soc_codec *codec,
560b7482f52SPhilipp Zabel 	enum snd_soc_bias_level level)
561b7482f52SPhilipp Zabel {
562b7482f52SPhilipp Zabel 	int pm = uda1380_read_reg_cache(codec, UDA1380_PM);
563b7482f52SPhilipp Zabel 
564b7482f52SPhilipp Zabel 	switch (level) {
565b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_ON:
566b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_PREPARE:
567b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
568b7482f52SPhilipp Zabel 		break;
569b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_STANDBY:
570b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_BIAS);
571b7482f52SPhilipp Zabel 		break;
572b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_OFF:
573b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, 0x0);
574b7482f52SPhilipp Zabel 		break;
575b7482f52SPhilipp Zabel 	}
576b7482f52SPhilipp Zabel 	codec->bias_level = level;
577b7482f52SPhilipp Zabel 	return 0;
578b7482f52SPhilipp Zabel }
579b7482f52SPhilipp Zabel 
580b7482f52SPhilipp Zabel #define UDA1380_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
581b7482f52SPhilipp Zabel 		       SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
582b7482f52SPhilipp Zabel 		       SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
583b7482f52SPhilipp Zabel 
5846335d055SEric Miao static struct snd_soc_dai_ops uda1380_dai_ops = {
5856335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
5866335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
58765ec1cd1SMark Brown 	.trigger	= uda1380_trigger,
5886335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_both,
5896335d055SEric Miao };
5906335d055SEric Miao 
5916335d055SEric Miao static struct snd_soc_dai_ops uda1380_dai_ops_playback = {
5926335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
5936335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
59465ec1cd1SMark Brown 	.trigger	= uda1380_trigger,
5956335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_playback,
5966335d055SEric Miao };
5976335d055SEric Miao 
5986335d055SEric Miao static struct snd_soc_dai_ops uda1380_dai_ops_capture = {
5996335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
6006335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
60165ec1cd1SMark Brown 	.trigger	= uda1380_trigger,
6026335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_capture,
6036335d055SEric Miao };
6046335d055SEric Miao 
605*f0fba2adSLiam Girdwood static struct snd_soc_dai_driver uda1380_dai[] = {
606b7482f52SPhilipp Zabel {
607*f0fba2adSLiam Girdwood 	.name = "uda1380-hifi",
608b7482f52SPhilipp Zabel 	.playback = {
609b7482f52SPhilipp Zabel 		.stream_name = "Playback",
610b7482f52SPhilipp Zabel 		.channels_min = 1,
611b7482f52SPhilipp Zabel 		.channels_max = 2,
612b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
613b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
614b7482f52SPhilipp Zabel 	.capture = {
615b7482f52SPhilipp Zabel 		.stream_name = "Capture",
616b7482f52SPhilipp Zabel 		.channels_min = 1,
617b7482f52SPhilipp Zabel 		.channels_max = 2,
618b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
619b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
6206335d055SEric Miao 	.ops = &uda1380_dai_ops,
621b7482f52SPhilipp Zabel },
622b7482f52SPhilipp Zabel { /* playback only - dual interface */
623*f0fba2adSLiam Girdwood 	.name = "uda1380-hifi-playback",
624b7482f52SPhilipp Zabel 	.playback = {
625b7482f52SPhilipp Zabel 		.stream_name = "Playback",
626b7482f52SPhilipp Zabel 		.channels_min = 1,
627b7482f52SPhilipp Zabel 		.channels_max = 2,
628b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
629b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
630b7482f52SPhilipp Zabel 	},
6316335d055SEric Miao 	.ops = &uda1380_dai_ops_playback,
632b7482f52SPhilipp Zabel },
633b7482f52SPhilipp Zabel { /* capture only - dual interface*/
634*f0fba2adSLiam Girdwood 	.name = "uda1380-hifi-capture",
635b7482f52SPhilipp Zabel 	.capture = {
636b7482f52SPhilipp Zabel 		.stream_name = "Capture",
637b7482f52SPhilipp Zabel 		.channels_min = 1,
638b7482f52SPhilipp Zabel 		.channels_max = 2,
639b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
640b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
641b7482f52SPhilipp Zabel 	},
6426335d055SEric Miao 	.ops = &uda1380_dai_ops_capture,
643b7482f52SPhilipp Zabel },
644b7482f52SPhilipp Zabel };
645b7482f52SPhilipp Zabel 
646*f0fba2adSLiam Girdwood static int uda1380_suspend(struct snd_soc_codec *codec, pm_message_t state)
647b7482f52SPhilipp Zabel {
648b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
649b7482f52SPhilipp Zabel 	return 0;
650b7482f52SPhilipp Zabel }
651b7482f52SPhilipp Zabel 
652*f0fba2adSLiam Girdwood static int uda1380_resume(struct snd_soc_codec *codec)
653b7482f52SPhilipp Zabel {
654b7482f52SPhilipp Zabel 	int i;
655b7482f52SPhilipp Zabel 	u8 data[2];
656b7482f52SPhilipp Zabel 	u16 *cache = codec->reg_cache;
657b7482f52SPhilipp Zabel 
658b7482f52SPhilipp Zabel 	/* Sync reg_cache with the hardware */
659b7482f52SPhilipp Zabel 	for (i = 0; i < ARRAY_SIZE(uda1380_reg); i++) {
660b7482f52SPhilipp Zabel 		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
661b7482f52SPhilipp Zabel 		data[1] = cache[i] & 0x00ff;
662b7482f52SPhilipp Zabel 		codec->hw_write(codec->control_data, data, 2);
663b7482f52SPhilipp Zabel 	}
664b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
665b7482f52SPhilipp Zabel 	return 0;
666b7482f52SPhilipp Zabel }
667b7482f52SPhilipp Zabel 
668*f0fba2adSLiam Girdwood static int uda1380_probe(struct snd_soc_codec *codec)
669b7482f52SPhilipp Zabel {
670*f0fba2adSLiam Girdwood 	struct uda1380_platform_data *pdata =codec->dev->platform_data;
671*f0fba2adSLiam Girdwood 	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
672*f0fba2adSLiam Girdwood 	int ret;
673b7482f52SPhilipp Zabel 
674*f0fba2adSLiam Girdwood 	codec->hw_write = (hw_write_t)i2c_master_send;
675b7482f52SPhilipp Zabel 
676*f0fba2adSLiam Girdwood 	if (!pdata || !pdata->gpio_power || !pdata->gpio_reset)
677*f0fba2adSLiam Girdwood 		return -EINVAL;
678ef9e5e5cSPhilipp Zabel 
679*f0fba2adSLiam Girdwood 	ret = gpio_request(pdata->gpio_power, "uda1380 power");
680*f0fba2adSLiam Girdwood 	if (ret)
681*f0fba2adSLiam Girdwood 		return ret;
682*f0fba2adSLiam Girdwood 	ret = gpio_request(pdata->gpio_reset, "uda1380 reset");
683*f0fba2adSLiam Girdwood 	if (ret)
684*f0fba2adSLiam Girdwood 		goto err_gpio;
685*f0fba2adSLiam Girdwood 
686*f0fba2adSLiam Girdwood 	gpio_direction_output(pdata->gpio_power, 1);
687*f0fba2adSLiam Girdwood 
688*f0fba2adSLiam Girdwood 	/* we may need to have the clock running here - pH5 */
689*f0fba2adSLiam Girdwood 	gpio_direction_output(pdata->gpio_reset, 1);
690*f0fba2adSLiam Girdwood 	udelay(5);
691*f0fba2adSLiam Girdwood 	gpio_set_value(pdata->gpio_reset, 0);
692*f0fba2adSLiam Girdwood 
693*f0fba2adSLiam Girdwood 	ret = uda1380_reset(codec);
694b7482f52SPhilipp Zabel 	if (ret < 0) {
695*f0fba2adSLiam Girdwood 		dev_err(codec->dev, "Failed to issue reset\n");
696*f0fba2adSLiam Girdwood 		goto err_reset;
697b7482f52SPhilipp Zabel 	}
698b7482f52SPhilipp Zabel 
699*f0fba2adSLiam Girdwood 	INIT_WORK(&uda1380->work, uda1380_flush_work);
700*f0fba2adSLiam Girdwood 
701b7482f52SPhilipp Zabel 	/* power on device */
702b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
703b7482f52SPhilipp Zabel 	/* set clock input */
7041abd9184SPhilipp Zabel 	switch (pdata->dac_clk) {
705b7482f52SPhilipp Zabel 	case UDA1380_DAC_CLK_SYSCLK:
706b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_CLK, 0);
707b7482f52SPhilipp Zabel 		break;
708b7482f52SPhilipp Zabel 	case UDA1380_DAC_CLK_WSPLL:
709b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK);
710b7482f52SPhilipp Zabel 		break;
711b7482f52SPhilipp Zabel 	}
712b7482f52SPhilipp Zabel 
7133e8e1952SIan Molton 	snd_soc_add_controls(codec, uda1380_snd_controls,
7143e8e1952SIan Molton 				ARRAY_SIZE(uda1380_snd_controls));
715b7482f52SPhilipp Zabel 	uda1380_add_widgets(codec);
716b7482f52SPhilipp Zabel 
7171abd9184SPhilipp Zabel 	return 0;
7181abd9184SPhilipp Zabel 
7191abd9184SPhilipp Zabel err_reset:
7201abd9184SPhilipp Zabel 	gpio_set_value(pdata->gpio_power, 0);
7211abd9184SPhilipp Zabel 	gpio_free(pdata->gpio_reset);
7221abd9184SPhilipp Zabel err_gpio:
7231abd9184SPhilipp Zabel 	gpio_free(pdata->gpio_power);
7241abd9184SPhilipp Zabel 	return ret;
7251abd9184SPhilipp Zabel }
7261abd9184SPhilipp Zabel 
727*f0fba2adSLiam Girdwood /* power down chip */
728*f0fba2adSLiam Girdwood static int uda1380_remove(struct snd_soc_codec *codec)
7291abd9184SPhilipp Zabel {
7301abd9184SPhilipp Zabel 	struct uda1380_platform_data *pdata =codec->dev->platform_data;
7311abd9184SPhilipp Zabel 
732*f0fba2adSLiam Girdwood 	uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
7331abd9184SPhilipp Zabel 
7341abd9184SPhilipp Zabel 	gpio_set_value(pdata->gpio_power, 0);
7351abd9184SPhilipp Zabel 	gpio_free(pdata->gpio_reset);
7361abd9184SPhilipp Zabel 	gpio_free(pdata->gpio_power);
7371abd9184SPhilipp Zabel 
738*f0fba2adSLiam Girdwood 	return 0;
7391abd9184SPhilipp Zabel }
740b7482f52SPhilipp Zabel 
741*f0fba2adSLiam Girdwood static struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
742*f0fba2adSLiam Girdwood 	.probe =	uda1380_probe,
743*f0fba2adSLiam Girdwood 	.remove =	uda1380_remove,
744*f0fba2adSLiam Girdwood 	.suspend =	uda1380_suspend,
745*f0fba2adSLiam Girdwood 	.resume =	uda1380_resume,
746*f0fba2adSLiam Girdwood 	.read = uda1380_read_reg_cache,
747*f0fba2adSLiam Girdwood 	.write = uda1380_write,
748*f0fba2adSLiam Girdwood 	.set_bias_level = uda1380_set_bias_level,
749*f0fba2adSLiam Girdwood 	.reg_cache_size = ARRAY_SIZE(uda1380_reg),
750*f0fba2adSLiam Girdwood 	.reg_word_size = sizeof(u16),
751*f0fba2adSLiam Girdwood 	.reg_cache_default = uda1380_reg,
752*f0fba2adSLiam Girdwood 	.reg_cache_step = 1,
753*f0fba2adSLiam Girdwood };
754*f0fba2adSLiam Girdwood 
755b7482f52SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
7561abd9184SPhilipp Zabel static __devinit int uda1380_i2c_probe(struct i2c_client *i2c,
75788fc39d7SJean Delvare 				      const struct i2c_device_id *id)
758b7482f52SPhilipp Zabel {
7591abd9184SPhilipp Zabel 	struct uda1380_priv *uda1380;
760b7482f52SPhilipp Zabel 	int ret;
761b7482f52SPhilipp Zabel 
7621abd9184SPhilipp Zabel 	uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL);
7631abd9184SPhilipp Zabel 	if (uda1380 == NULL)
7641abd9184SPhilipp Zabel 		return -ENOMEM;
7651abd9184SPhilipp Zabel 
7661abd9184SPhilipp Zabel 	i2c_set_clientdata(i2c, uda1380);
767b7482f52SPhilipp Zabel 
768*f0fba2adSLiam Girdwood 	ret =  snd_soc_register_codec(&i2c->dev,
769*f0fba2adSLiam Girdwood 			&soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
770*f0fba2adSLiam Girdwood 	if (ret < 0)
7711abd9184SPhilipp Zabel 		kfree(uda1380);
772b7482f52SPhilipp Zabel 	return ret;
773b7482f52SPhilipp Zabel }
774b7482f52SPhilipp Zabel 
7751abd9184SPhilipp Zabel static int __devexit uda1380_i2c_remove(struct i2c_client *i2c)
776b7482f52SPhilipp Zabel {
777*f0fba2adSLiam Girdwood 	snd_soc_unregister_codec(&i2c->dev);
778*f0fba2adSLiam Girdwood 	kfree(i2c_get_clientdata(i2c));
779b7482f52SPhilipp Zabel 	return 0;
780b7482f52SPhilipp Zabel }
781b7482f52SPhilipp Zabel 
78288fc39d7SJean Delvare static const struct i2c_device_id uda1380_i2c_id[] = {
78388fc39d7SJean Delvare 	{ "uda1380", 0 },
78488fc39d7SJean Delvare 	{ }
78588fc39d7SJean Delvare };
78688fc39d7SJean Delvare MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
787b7482f52SPhilipp Zabel 
788b7482f52SPhilipp Zabel static struct i2c_driver uda1380_i2c_driver = {
789b7482f52SPhilipp Zabel 	.driver = {
790*f0fba2adSLiam Girdwood 		.name =  "uda1380-codec",
791b7482f52SPhilipp Zabel 		.owner = THIS_MODULE,
792b7482f52SPhilipp Zabel 	},
79388fc39d7SJean Delvare 	.probe =    uda1380_i2c_probe,
7941abd9184SPhilipp Zabel 	.remove =   __devexit_p(uda1380_i2c_remove),
79588fc39d7SJean Delvare 	.id_table = uda1380_i2c_id,
796b7482f52SPhilipp Zabel };
797b7482f52SPhilipp Zabel #endif
798b7482f52SPhilipp Zabel 
799c9b3a40fSTakashi Iwai static int __init uda1380_modinit(void)
80064089b84SMark Brown {
8011abd9184SPhilipp Zabel 	int ret;
8021abd9184SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
8031abd9184SPhilipp Zabel 	ret = i2c_add_driver(&uda1380_i2c_driver);
8041abd9184SPhilipp Zabel 	if (ret != 0)
8051abd9184SPhilipp Zabel 		pr_err("Failed to register UDA1380 I2C driver: %d\n", ret);
8061abd9184SPhilipp Zabel #endif
8071abd9184SPhilipp Zabel 	return 0;
80864089b84SMark Brown }
80964089b84SMark Brown module_init(uda1380_modinit);
81064089b84SMark Brown 
81164089b84SMark Brown static void __exit uda1380_exit(void)
81264089b84SMark Brown {
8131abd9184SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
8141abd9184SPhilipp Zabel 	i2c_del_driver(&uda1380_i2c_driver);
8151abd9184SPhilipp Zabel #endif
81664089b84SMark Brown }
81764089b84SMark Brown module_exit(uda1380_exit);
81864089b84SMark Brown 
819b7482f52SPhilipp Zabel MODULE_AUTHOR("Giorgio Padrin");
820b7482f52SPhilipp Zabel MODULE_DESCRIPTION("Audio support for codec Philips UDA1380");
821b7482f52SPhilipp Zabel MODULE_LICENSE("GPL");
822