xref: /linux/sound/soc/codecs/uda1380.c (revision 8614d310a2ba78cfc73ab12da112c3115801f94e)
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 {
38f0fba2adSLiam 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;
42*8614d310SVasily Khoruzhick 	void *control_data;
431abd9184SPhilipp Zabel };
441abd9184SPhilipp Zabel 
45b7482f52SPhilipp Zabel /*
46b7482f52SPhilipp Zabel  * uda1380 register cache
47b7482f52SPhilipp Zabel  */
48b7482f52SPhilipp Zabel static const u16 uda1380_reg[UDA1380_CACHEREGNUM] = {
49b7482f52SPhilipp Zabel 	0x0502, 0x0000, 0x0000, 0x3f3f,
50b7482f52SPhilipp Zabel 	0x0202, 0x0000, 0x0000, 0x0000,
51b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
52b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
53b7482f52SPhilipp Zabel 	0x0000, 0xff00, 0x0000, 0x4800,
54b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
55b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
56b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
57b7482f52SPhilipp Zabel 	0x0000, 0x8000, 0x0002, 0x0000,
58b7482f52SPhilipp Zabel };
59b7482f52SPhilipp Zabel 
60ef9e5e5cSPhilipp Zabel static unsigned long uda1380_cache_dirty;
61ef9e5e5cSPhilipp Zabel 
62b7482f52SPhilipp Zabel /*
63b7482f52SPhilipp Zabel  * read uda1380 register cache
64b7482f52SPhilipp Zabel  */
65b7482f52SPhilipp Zabel static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec,
66b7482f52SPhilipp Zabel 	unsigned int reg)
67b7482f52SPhilipp Zabel {
68b7482f52SPhilipp Zabel 	u16 *cache = codec->reg_cache;
69b7482f52SPhilipp Zabel 	if (reg == UDA1380_RESET)
70b7482f52SPhilipp Zabel 		return 0;
71b7482f52SPhilipp Zabel 	if (reg >= UDA1380_CACHEREGNUM)
72b7482f52SPhilipp Zabel 		return -1;
73b7482f52SPhilipp Zabel 	return cache[reg];
74b7482f52SPhilipp Zabel }
75b7482f52SPhilipp Zabel 
76b7482f52SPhilipp Zabel /*
77b7482f52SPhilipp Zabel  * write uda1380 register cache
78b7482f52SPhilipp Zabel  */
79b7482f52SPhilipp Zabel static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
80b7482f52SPhilipp Zabel 	u16 reg, unsigned int value)
81b7482f52SPhilipp Zabel {
82b7482f52SPhilipp Zabel 	u16 *cache = codec->reg_cache;
83ef9e5e5cSPhilipp Zabel 
84b7482f52SPhilipp Zabel 	if (reg >= UDA1380_CACHEREGNUM)
85b7482f52SPhilipp Zabel 		return;
86ef9e5e5cSPhilipp Zabel 	if ((reg >= 0x10) && (cache[reg] != value))
87ef9e5e5cSPhilipp Zabel 		set_bit(reg - 0x10, &uda1380_cache_dirty);
88b7482f52SPhilipp Zabel 	cache[reg] = value;
89b7482f52SPhilipp Zabel }
90b7482f52SPhilipp Zabel 
91b7482f52SPhilipp Zabel /*
92b7482f52SPhilipp Zabel  * write to the UDA1380 register space
93b7482f52SPhilipp Zabel  */
94b7482f52SPhilipp Zabel static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
95b7482f52SPhilipp Zabel 	unsigned int value)
96b7482f52SPhilipp Zabel {
97b7482f52SPhilipp Zabel 	u8 data[3];
98b7482f52SPhilipp Zabel 
99b7482f52SPhilipp Zabel 	/* data is
100b7482f52SPhilipp Zabel 	 *   data[0] is register offset
101b7482f52SPhilipp Zabel 	 *   data[1] is MS byte
102b7482f52SPhilipp Zabel 	 *   data[2] is LS byte
103b7482f52SPhilipp Zabel 	 */
104b7482f52SPhilipp Zabel 	data[0] = reg;
105b7482f52SPhilipp Zabel 	data[1] = (value & 0xff00) >> 8;
106b7482f52SPhilipp Zabel 	data[2] = value & 0x00ff;
107b7482f52SPhilipp Zabel 
108b7482f52SPhilipp Zabel 	uda1380_write_reg_cache(codec, reg, value);
109b7482f52SPhilipp Zabel 
110b7482f52SPhilipp Zabel 	/* the interpolator & decimator regs must only be written when the
111b7482f52SPhilipp Zabel 	 * codec DAI is active.
112b7482f52SPhilipp Zabel 	 */
113b7482f52SPhilipp Zabel 	if (!codec->active && (reg >= UDA1380_MVOL))
114b7482f52SPhilipp Zabel 		return 0;
115b7482f52SPhilipp Zabel 	pr_debug("uda1380: hw write %x val %x\n", reg, value);
116b7482f52SPhilipp Zabel 	if (codec->hw_write(codec->control_data, data, 3) == 3) {
117b7482f52SPhilipp Zabel 		unsigned int val;
118b7482f52SPhilipp Zabel 		i2c_master_send(codec->control_data, data, 1);
119b7482f52SPhilipp Zabel 		i2c_master_recv(codec->control_data, data, 2);
120b7482f52SPhilipp Zabel 		val = (data[0]<<8) | data[1];
121b7482f52SPhilipp Zabel 		if (val != value) {
122b7482f52SPhilipp Zabel 			pr_debug("uda1380: READ BACK VAL %x\n",
123b7482f52SPhilipp Zabel 					(data[0]<<8) | data[1]);
124b7482f52SPhilipp Zabel 			return -EIO;
125b7482f52SPhilipp Zabel 		}
126ef9e5e5cSPhilipp Zabel 		if (reg >= 0x10)
127ef9e5e5cSPhilipp Zabel 			clear_bit(reg - 0x10, &uda1380_cache_dirty);
128b7482f52SPhilipp Zabel 		return 0;
129b7482f52SPhilipp Zabel 	} else
130b7482f52SPhilipp Zabel 		return -EIO;
131b7482f52SPhilipp Zabel }
132b7482f52SPhilipp Zabel 
133*8614d310SVasily Khoruzhick static void uda1380_sync_cache(struct snd_soc_codec *codec)
134*8614d310SVasily Khoruzhick {
135*8614d310SVasily Khoruzhick 	int reg;
136*8614d310SVasily Khoruzhick 	u8 data[3];
137*8614d310SVasily Khoruzhick 	u16 *cache = codec->reg_cache;
138*8614d310SVasily Khoruzhick 
139*8614d310SVasily Khoruzhick 	/* Sync reg_cache with the hardware */
140*8614d310SVasily Khoruzhick 	for (reg = 0; reg < UDA1380_MVOL; reg++) {
141*8614d310SVasily Khoruzhick 		data[0] = reg;
142*8614d310SVasily Khoruzhick 		data[1] = (cache[reg] & 0xff00) >> 8;
143*8614d310SVasily Khoruzhick 		data[2] = cache[reg] & 0x00ff;
144*8614d310SVasily Khoruzhick 		if (codec->hw_write(codec->control_data, data, 3) != 3)
145*8614d310SVasily Khoruzhick 			dev_err(codec->dev, "%s: write to reg 0x%x failed\n",
146*8614d310SVasily Khoruzhick 				__func__, reg);
147*8614d310SVasily Khoruzhick 	}
148*8614d310SVasily Khoruzhick }
149*8614d310SVasily Khoruzhick 
150*8614d310SVasily Khoruzhick static int uda1380_reset(struct snd_soc_codec *codec)
151*8614d310SVasily Khoruzhick {
152*8614d310SVasily Khoruzhick 	struct uda1380_platform_data *pdata = codec->dev->platform_data;
153*8614d310SVasily Khoruzhick 
154*8614d310SVasily Khoruzhick 	if (gpio_is_valid(pdata->gpio_reset)) {
155*8614d310SVasily Khoruzhick 		gpio_set_value(pdata->gpio_reset, 1);
156*8614d310SVasily Khoruzhick 		mdelay(1);
157*8614d310SVasily Khoruzhick 		gpio_set_value(pdata->gpio_reset, 0);
158*8614d310SVasily Khoruzhick 	} else {
159*8614d310SVasily Khoruzhick 		u8 data[3];
160*8614d310SVasily Khoruzhick 
161*8614d310SVasily Khoruzhick 		data[0] = UDA1380_RESET;
162*8614d310SVasily Khoruzhick 		data[1] = 0;
163*8614d310SVasily Khoruzhick 		data[2] = 0;
164*8614d310SVasily Khoruzhick 
165*8614d310SVasily Khoruzhick 		if (codec->hw_write(codec->control_data, data, 3) != 3) {
166*8614d310SVasily Khoruzhick 			dev_err(codec->dev, "%s: failed\n", __func__);
167*8614d310SVasily Khoruzhick 			return -EIO;
168*8614d310SVasily Khoruzhick 		}
169*8614d310SVasily Khoruzhick 	}
170*8614d310SVasily Khoruzhick 
171*8614d310SVasily Khoruzhick 	return 0;
172*8614d310SVasily Khoruzhick }
173b7482f52SPhilipp Zabel 
174ef9e5e5cSPhilipp Zabel static void uda1380_flush_work(struct work_struct *work)
175ef9e5e5cSPhilipp Zabel {
176f0fba2adSLiam Girdwood 	struct uda1380_priv *uda1380 = container_of(work, struct uda1380_priv, work);
177f0fba2adSLiam Girdwood 	struct snd_soc_codec *uda1380_codec = uda1380->codec;
178ef9e5e5cSPhilipp Zabel 	int bit, reg;
179ef9e5e5cSPhilipp Zabel 
180984b3f57SAkinobu Mita 	for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
181ef9e5e5cSPhilipp Zabel 		reg = 0x10 + bit;
182ef9e5e5cSPhilipp Zabel 		pr_debug("uda1380: flush reg %x val %x:\n", reg,
183ef9e5e5cSPhilipp Zabel 				uda1380_read_reg_cache(uda1380_codec, reg));
184ef9e5e5cSPhilipp Zabel 		uda1380_write(uda1380_codec, reg,
185ef9e5e5cSPhilipp Zabel 				uda1380_read_reg_cache(uda1380_codec, reg));
186ef9e5e5cSPhilipp Zabel 		clear_bit(bit, &uda1380_cache_dirty);
187ef9e5e5cSPhilipp Zabel 	}
188f0fba2adSLiam Girdwood 
189ef9e5e5cSPhilipp Zabel }
190ef9e5e5cSPhilipp Zabel 
191b7482f52SPhilipp Zabel /* declarations of ALSA reg_elem_REAL controls */
192b7482f52SPhilipp Zabel static const char *uda1380_deemp[] = {
193b7482f52SPhilipp Zabel 	"None",
194b7482f52SPhilipp Zabel 	"32kHz",
195b7482f52SPhilipp Zabel 	"44.1kHz",
196b7482f52SPhilipp Zabel 	"48kHz",
197b7482f52SPhilipp Zabel 	"96kHz",
198b7482f52SPhilipp Zabel };
199b7482f52SPhilipp Zabel static const char *uda1380_input_sel[] = {
200b7482f52SPhilipp Zabel 	"Line",
201b7482f52SPhilipp Zabel 	"Mic + Line R",
202b7482f52SPhilipp Zabel 	"Line L",
203b7482f52SPhilipp Zabel 	"Mic",
204b7482f52SPhilipp Zabel };
205b7482f52SPhilipp Zabel static const char *uda1380_output_sel[] = {
206b7482f52SPhilipp Zabel 	"DAC",
207b7482f52SPhilipp Zabel 	"Analog Mixer",
208b7482f52SPhilipp Zabel };
209b7482f52SPhilipp Zabel static const char *uda1380_spf_mode[] = {
210b7482f52SPhilipp Zabel 	"Flat",
211b7482f52SPhilipp Zabel 	"Minimum1",
212b7482f52SPhilipp Zabel 	"Minimum2",
213b7482f52SPhilipp Zabel 	"Maximum"
214b7482f52SPhilipp Zabel };
215b7482f52SPhilipp Zabel static const char *uda1380_capture_sel[] = {
216b7482f52SPhilipp Zabel 	"ADC",
217b7482f52SPhilipp Zabel 	"Digital Mixer"
218b7482f52SPhilipp Zabel };
219b7482f52SPhilipp Zabel static const char *uda1380_sel_ns[] = {
220b7482f52SPhilipp Zabel 	"3rd-order",
221b7482f52SPhilipp Zabel 	"5th-order"
222b7482f52SPhilipp Zabel };
223b7482f52SPhilipp Zabel static const char *uda1380_mix_control[] = {
224b7482f52SPhilipp Zabel 	"off",
225b7482f52SPhilipp Zabel 	"PCM only",
226b7482f52SPhilipp Zabel 	"before sound processing",
227b7482f52SPhilipp Zabel 	"after sound processing"
228b7482f52SPhilipp Zabel };
229b7482f52SPhilipp Zabel static const char *uda1380_sdet_setting[] = {
230b7482f52SPhilipp Zabel 	"3200",
231b7482f52SPhilipp Zabel 	"4800",
232b7482f52SPhilipp Zabel 	"9600",
233b7482f52SPhilipp Zabel 	"19200"
234b7482f52SPhilipp Zabel };
235b7482f52SPhilipp Zabel static const char *uda1380_os_setting[] = {
236b7482f52SPhilipp Zabel 	"single-speed",
237b7482f52SPhilipp Zabel 	"double-speed (no mixing)",
238b7482f52SPhilipp Zabel 	"quad-speed (no mixing)"
239b7482f52SPhilipp Zabel };
240b7482f52SPhilipp Zabel 
241b7482f52SPhilipp Zabel static const struct soc_enum uda1380_deemp_enum[] = {
242b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_DEEMP, 8, 5, uda1380_deemp),
243b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_DEEMP, 0, 5, uda1380_deemp),
244b7482f52SPhilipp Zabel };
245b7482f52SPhilipp Zabel static const struct soc_enum uda1380_input_sel_enum =
246b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_ADC, 2, 4, uda1380_input_sel);		/* SEL_MIC, SEL_LNA */
247b7482f52SPhilipp Zabel static const struct soc_enum uda1380_output_sel_enum =
248b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_PM, 7, 2, uda1380_output_sel);		/* R02_EN_AVC */
249b7482f52SPhilipp Zabel static const struct soc_enum uda1380_spf_enum =
250b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MODE, 14, 4, uda1380_spf_mode);		/* M */
251b7482f52SPhilipp Zabel static const struct soc_enum uda1380_capture_sel_enum =
252b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_IFACE, 6, 2, uda1380_capture_sel);	/* SEL_SOURCE */
253b7482f52SPhilipp Zabel static const struct soc_enum uda1380_sel_ns_enum =
254b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 14, 2, uda1380_sel_ns);		/* SEL_NS */
255b7482f52SPhilipp Zabel static const struct soc_enum uda1380_mix_enum =
256b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 12, 4, uda1380_mix_control);	/* MIX, MIX_POS */
257b7482f52SPhilipp Zabel static const struct soc_enum uda1380_sdet_enum =
258b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 4, 4, uda1380_sdet_setting);	/* SD_VALUE */
259b7482f52SPhilipp Zabel static const struct soc_enum uda1380_os_enum =
260b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 0, 3, uda1380_os_setting);	/* OS */
261b7482f52SPhilipp Zabel 
262b7482f52SPhilipp Zabel /*
263b7482f52SPhilipp Zabel  * from -48 dB in 1.5 dB steps (mute instead of -49.5 dB)
264b7482f52SPhilipp Zabel  */
265b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(amix_tlv, -4950, 150, 1);
266b7482f52SPhilipp Zabel 
267b7482f52SPhilipp Zabel /*
268b7482f52SPhilipp Zabel  * from -78 dB in 1 dB steps (3 dB steps, really. LSB are ignored),
269b7482f52SPhilipp Zabel  * from -66 dB in 0.5 dB steps (2 dB steps, really) and
270b7482f52SPhilipp Zabel  * from -52 dB in 0.25 dB steps
271b7482f52SPhilipp Zabel  */
272b7482f52SPhilipp Zabel static const unsigned int mvol_tlv[] = {
273b7482f52SPhilipp Zabel 	TLV_DB_RANGE_HEAD(3),
274b7482f52SPhilipp Zabel 	0, 15, TLV_DB_SCALE_ITEM(-8200, 100, 1),
275b7482f52SPhilipp Zabel 	16, 43, TLV_DB_SCALE_ITEM(-6600, 50, 0),
276b7482f52SPhilipp Zabel 	44, 252, TLV_DB_SCALE_ITEM(-5200, 25, 0),
277b7482f52SPhilipp Zabel };
278b7482f52SPhilipp Zabel 
279b7482f52SPhilipp Zabel /*
280b7482f52SPhilipp Zabel  * from -72 dB in 1.5 dB steps (6 dB steps really),
281b7482f52SPhilipp Zabel  * from -66 dB in 0.75 dB steps (3 dB steps really),
282b7482f52SPhilipp Zabel  * from -60 dB in 0.5 dB steps (2 dB steps really) and
283b7482f52SPhilipp Zabel  * from -46 dB in 0.25 dB steps
284b7482f52SPhilipp Zabel  */
285b7482f52SPhilipp Zabel static const unsigned int vc_tlv[] = {
286b7482f52SPhilipp Zabel 	TLV_DB_RANGE_HEAD(4),
287b7482f52SPhilipp Zabel 	0, 7, TLV_DB_SCALE_ITEM(-7800, 150, 1),
288b7482f52SPhilipp Zabel 	8, 15, TLV_DB_SCALE_ITEM(-6600, 75, 0),
289b7482f52SPhilipp Zabel 	16, 43, TLV_DB_SCALE_ITEM(-6000, 50, 0),
290b7482f52SPhilipp Zabel 	44, 228, TLV_DB_SCALE_ITEM(-4600, 25, 0),
291b7482f52SPhilipp Zabel };
292b7482f52SPhilipp Zabel 
293b7482f52SPhilipp Zabel /* from 0 to 6 dB in 2 dB steps if SPF mode != flat */
294b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(tr_tlv, 0, 200, 0);
295b7482f52SPhilipp Zabel 
296b7482f52SPhilipp Zabel /* from 0 to 24 dB in 2 dB steps, if SPF mode == maximum, otherwise cuts
297b7482f52SPhilipp Zabel  * off at 18 dB max) */
298b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(bb_tlv, 0, 200, 0);
299b7482f52SPhilipp Zabel 
300b7482f52SPhilipp Zabel /* from -63 to 24 dB in 0.5 dB steps (-128...48) */
301b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(dec_tlv, -6400, 50, 1);
302b7482f52SPhilipp Zabel 
303b7482f52SPhilipp Zabel /* from 0 to 24 dB in 3 dB steps */
304b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0);
305b7482f52SPhilipp Zabel 
306b7482f52SPhilipp Zabel /* from 0 to 30 dB in 2 dB steps */
307b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(vga_tlv, 0, 200, 0);
308b7482f52SPhilipp Zabel 
309b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_snd_controls[] = {
310b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Analog Mixer Volume", UDA1380_AMIX, 0, 8, 44, 1, amix_tlv),	/* AVCR, AVCL */
311b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Master Playback Volume", UDA1380_MVOL, 0, 8, 252, 1, mvol_tlv),	/* MVCL, MVCR */
312b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("ADC Playback Volume", UDA1380_MIXVOL, 8, 228, 1, vc_tlv),	/* VC2 */
313b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("PCM Playback Volume", UDA1380_MIXVOL, 0, 228, 1, vc_tlv),	/* VC1 */
314b7482f52SPhilipp Zabel 	SOC_ENUM("Sound Processing Filter", uda1380_spf_enum),				/* M */
315b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Tone Control - Treble", UDA1380_MODE, 4, 12, 3, 0, tr_tlv), 	/* TRL, TRR */
316b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Tone Control - Bass", UDA1380_MODE, 0, 8, 15, 0, bb_tlv),	/* BBL, BBR */
317b7482f52SPhilipp Zabel /**/	SOC_SINGLE("Master Playback Switch", UDA1380_DEEMP, 14, 1, 1),		/* MTM */
318b7482f52SPhilipp Zabel 	SOC_SINGLE("ADC Playback Switch", UDA1380_DEEMP, 11, 1, 1),		/* MT2 from decimation filter */
319b7482f52SPhilipp Zabel 	SOC_ENUM("ADC Playback De-emphasis", uda1380_deemp_enum[0]),		/* DE2 */
320b7482f52SPhilipp Zabel 	SOC_SINGLE("PCM Playback Switch", UDA1380_DEEMP, 3, 1, 1),		/* MT1, from digital data input */
321b7482f52SPhilipp Zabel 	SOC_ENUM("PCM Playback De-emphasis", uda1380_deemp_enum[1]),		/* DE1 */
322b7482f52SPhilipp Zabel 	SOC_SINGLE("DAC Polarity inverting Switch", UDA1380_MIXER, 15, 1, 0),	/* DA_POL_INV */
323b7482f52SPhilipp Zabel 	SOC_ENUM("Noise Shaper", uda1380_sel_ns_enum),				/* SEL_NS */
324b7482f52SPhilipp Zabel 	SOC_ENUM("Digital Mixer Signal Control", uda1380_mix_enum),		/* MIX_POS, MIX */
325b7482f52SPhilipp Zabel 	SOC_SINGLE("Silence Detector Switch", UDA1380_MIXER, 6, 1, 0),		/* SDET_ON */
326b7482f52SPhilipp Zabel 	SOC_ENUM("Silence Detector Setting", uda1380_sdet_enum),		/* SD_VALUE */
327b7482f52SPhilipp Zabel 	SOC_ENUM("Oversampling Input", uda1380_os_enum),			/* OS */
328b7482f52SPhilipp Zabel 	SOC_DOUBLE_S8_TLV("ADC Capture Volume", UDA1380_DEC, -128, 48, dec_tlv),	/* ML_DEC, MR_DEC */
329b7482f52SPhilipp Zabel /**/	SOC_SINGLE("ADC Capture Switch", UDA1380_PGA, 15, 1, 1),		/* MT_ADC */
330b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Line Capture Volume", UDA1380_PGA, 0, 8, 8, 0, pga_tlv), /* PGA_GAINCTRLL, PGA_GAINCTRLR */
331b7482f52SPhilipp Zabel 	SOC_SINGLE("ADC Polarity inverting Switch", UDA1380_ADC, 12, 1, 0),	/* ADCPOL_INV */
332b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("Mic Capture Volume", UDA1380_ADC, 8, 15, 0, vga_tlv),	/* VGA_CTRL */
333b7482f52SPhilipp Zabel 	SOC_SINGLE("DC Filter Bypass Switch", UDA1380_ADC, 1, 1, 0),		/* SKIP_DCFIL (before decimator) */
334b7482f52SPhilipp Zabel 	SOC_SINGLE("DC Filter Enable Switch", UDA1380_ADC, 0, 1, 0),		/* EN_DCFIL (at output of decimator) */
335b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Timing", UDA1380_AGC, 8, 7, 0),			/* TODO: enum, see table 62 */
336b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Target level", UDA1380_AGC, 2, 3, 1),			/* AGC_LEVEL */
337b7482f52SPhilipp Zabel 	/* -5.5, -8, -11.5, -14 dBFS */
338b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0),
339b7482f52SPhilipp Zabel };
340b7482f52SPhilipp Zabel 
341b7482f52SPhilipp Zabel /* Input mux */
342b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_input_mux_control =
343b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_input_sel_enum);
344b7482f52SPhilipp Zabel 
345b7482f52SPhilipp Zabel /* Output mux */
346b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_output_mux_control =
347b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_output_sel_enum);
348b7482f52SPhilipp Zabel 
349b7482f52SPhilipp Zabel /* Capture mux */
350b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_capture_mux_control =
351b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_capture_sel_enum);
352b7482f52SPhilipp Zabel 
353b7482f52SPhilipp Zabel 
354b7482f52SPhilipp Zabel static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
355b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
356b7482f52SPhilipp Zabel 		&uda1380_input_mux_control),
357b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM, 0, 0,
358b7482f52SPhilipp Zabel 		&uda1380_output_mux_control),
359b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0,
360b7482f52SPhilipp Zabel 		&uda1380_capture_mux_control),
361b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Left PGA", UDA1380_PM, 3, 0, NULL, 0),
362b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Right PGA", UDA1380_PM, 1, 0, NULL, 0),
363b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Mic LNA", UDA1380_PM, 4, 0, NULL, 0),
364b7482f52SPhilipp Zabel 	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", UDA1380_PM, 2, 0),
365b7482f52SPhilipp Zabel 	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", UDA1380_PM, 0, 0),
366b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINM"),
367b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINL"),
368b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINR"),
369b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MIXER("Analog Mixer", UDA1380_PM, 6, 0, NULL, 0),
370b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTLHP"),
371b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTRHP"),
372b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTL"),
373b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTR"),
374b7482f52SPhilipp Zabel 	SND_SOC_DAPM_DAC("DAC", "Playback", UDA1380_PM, 10, 0),
375b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("HeadPhone Driver", UDA1380_PM, 13, 0, NULL, 0),
376b7482f52SPhilipp Zabel };
377b7482f52SPhilipp Zabel 
378b7482f52SPhilipp Zabel static const struct snd_soc_dapm_route audio_map[] = {
379b7482f52SPhilipp Zabel 
380b7482f52SPhilipp Zabel 	/* output mux */
381b7482f52SPhilipp Zabel 	{"HeadPhone Driver", NULL, "Output Mux"},
382b7482f52SPhilipp Zabel 	{"VOUTR", NULL, "Output Mux"},
383b7482f52SPhilipp Zabel 	{"VOUTL", NULL, "Output Mux"},
384b7482f52SPhilipp Zabel 
385b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "VINR"},
386b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "VINL"},
387b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "DAC"},
388b7482f52SPhilipp Zabel 
389b7482f52SPhilipp Zabel 	{"Output Mux", "DAC", "DAC"},
390b7482f52SPhilipp Zabel 	{"Output Mux", "Analog Mixer", "Analog Mixer"},
391b7482f52SPhilipp Zabel 
392b7482f52SPhilipp Zabel 	/* {"DAC", "Digital Mixer", "I2S" } */
393b7482f52SPhilipp Zabel 
394b7482f52SPhilipp Zabel 	/* headphone driver */
395b7482f52SPhilipp Zabel 	{"VOUTLHP", NULL, "HeadPhone Driver"},
396b7482f52SPhilipp Zabel 	{"VOUTRHP", NULL, "HeadPhone Driver"},
397b7482f52SPhilipp Zabel 
398b7482f52SPhilipp Zabel 	/* input mux */
399b7482f52SPhilipp Zabel 	{"Left ADC", NULL, "Input Mux"},
400b7482f52SPhilipp Zabel 	{"Input Mux", "Mic", "Mic LNA"},
401b7482f52SPhilipp Zabel 	{"Input Mux", "Mic + Line R", "Mic LNA"},
402b7482f52SPhilipp Zabel 	{"Input Mux", "Line L", "Left PGA"},
403b7482f52SPhilipp Zabel 	{"Input Mux", "Line", "Left PGA"},
404b7482f52SPhilipp Zabel 
405b7482f52SPhilipp Zabel 	/* right input */
406b7482f52SPhilipp Zabel 	{"Right ADC", "Mic + Line R", "Right PGA"},
407b7482f52SPhilipp Zabel 	{"Right ADC", "Line", "Right PGA"},
408b7482f52SPhilipp Zabel 
409b7482f52SPhilipp Zabel 	/* inputs */
410b7482f52SPhilipp Zabel 	{"Mic LNA", NULL, "VINM"},
411b7482f52SPhilipp Zabel 	{"Left PGA", NULL, "VINL"},
412b7482f52SPhilipp Zabel 	{"Right PGA", NULL, "VINR"},
413b7482f52SPhilipp Zabel };
414b7482f52SPhilipp Zabel 
415b7482f52SPhilipp Zabel static int uda1380_add_widgets(struct snd_soc_codec *codec)
416b7482f52SPhilipp Zabel {
417b7482f52SPhilipp Zabel 	snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets,
418b7482f52SPhilipp Zabel 				  ARRAY_SIZE(uda1380_dapm_widgets));
419b7482f52SPhilipp Zabel 
420b7482f52SPhilipp Zabel 	snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
421b7482f52SPhilipp Zabel 
422b7482f52SPhilipp Zabel 	return 0;
423b7482f52SPhilipp Zabel }
424b7482f52SPhilipp Zabel 
4255b247442SPhilipp Zabel static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
426b7482f52SPhilipp Zabel 		unsigned int fmt)
427b7482f52SPhilipp Zabel {
428b7482f52SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
429b7482f52SPhilipp Zabel 	int iface;
430b7482f52SPhilipp Zabel 
431b7482f52SPhilipp Zabel 	/* set up DAI based upon fmt */
432b7482f52SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
433b7482f52SPhilipp Zabel 	iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK);
434b7482f52SPhilipp Zabel 
435b7482f52SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
436b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
437b7482f52SPhilipp Zabel 		iface |= R01_SFORI_I2S | R01_SFORO_I2S;
438b7482f52SPhilipp Zabel 		break;
439b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4405b247442SPhilipp Zabel 		iface |= R01_SFORI_LSB16 | R01_SFORO_LSB16;
441b7482f52SPhilipp Zabel 		break;
442b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4435b247442SPhilipp Zabel 		iface |= R01_SFORI_MSB | R01_SFORO_MSB;
4445b247442SPhilipp Zabel 	}
4455b247442SPhilipp Zabel 
4465f2a9384SPhilipp Zabel 	/* DATAI is slave only, so in single-link mode, this has to be slave */
4475f2a9384SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
4485f2a9384SPhilipp Zabel 		return -EINVAL;
4495b247442SPhilipp Zabel 
4505b247442SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
4515b247442SPhilipp Zabel 
4525b247442SPhilipp Zabel 	return 0;
4535b247442SPhilipp Zabel }
4545b247442SPhilipp Zabel 
4555b247442SPhilipp Zabel static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
4565b247442SPhilipp Zabel 		unsigned int fmt)
4575b247442SPhilipp Zabel {
4585b247442SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
4595b247442SPhilipp Zabel 	int iface;
4605b247442SPhilipp Zabel 
4615b247442SPhilipp Zabel 	/* set up DAI based upon fmt */
4625b247442SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
4635b247442SPhilipp Zabel 	iface &= ~R01_SFORI_MASK;
4645b247442SPhilipp Zabel 
4655b247442SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
4665b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
4675b247442SPhilipp Zabel 		iface |= R01_SFORI_I2S;
4685b247442SPhilipp Zabel 		break;
4695b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4705b247442SPhilipp Zabel 		iface |= R01_SFORI_LSB16;
4715b247442SPhilipp Zabel 		break;
4725b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4735b247442SPhilipp Zabel 		iface |= R01_SFORI_MSB;
4745b247442SPhilipp Zabel 	}
4755b247442SPhilipp Zabel 
4765f2a9384SPhilipp Zabel 	/* DATAI is slave only, so this has to be slave */
4775f2a9384SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
4785f2a9384SPhilipp Zabel 		return -EINVAL;
4795f2a9384SPhilipp Zabel 
4805b247442SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
4815b247442SPhilipp Zabel 
4825b247442SPhilipp Zabel 	return 0;
4835b247442SPhilipp Zabel }
4845b247442SPhilipp Zabel 
4855b247442SPhilipp Zabel static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
4865b247442SPhilipp Zabel 		unsigned int fmt)
4875b247442SPhilipp Zabel {
4885b247442SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
4895b247442SPhilipp Zabel 	int iface;
4905b247442SPhilipp Zabel 
4915b247442SPhilipp Zabel 	/* set up DAI based upon fmt */
4925b247442SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
4935b247442SPhilipp Zabel 	iface &= ~(R01_SIM | R01_SFORO_MASK);
4945b247442SPhilipp Zabel 
4955b247442SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
4965b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
4975b247442SPhilipp Zabel 		iface |= R01_SFORO_I2S;
4985b247442SPhilipp Zabel 		break;
4995b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
5005b247442SPhilipp Zabel 		iface |= R01_SFORO_LSB16;
5015b247442SPhilipp Zabel 		break;
5025b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
5035b247442SPhilipp Zabel 		iface |= R01_SFORO_MSB;
504b7482f52SPhilipp Zabel 	}
505b7482f52SPhilipp Zabel 
506b7482f52SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
507b7482f52SPhilipp Zabel 		iface |= R01_SIM;
508b7482f52SPhilipp Zabel 
509b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
510b7482f52SPhilipp Zabel 
511b7482f52SPhilipp Zabel 	return 0;
512b7482f52SPhilipp Zabel }
513b7482f52SPhilipp Zabel 
514ef9e5e5cSPhilipp Zabel static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
515dee89c4dSMark Brown 		struct snd_soc_dai *dai)
516b7482f52SPhilipp Zabel {
517b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
518f0fba2adSLiam Girdwood 	struct snd_soc_codec *codec = rtd->codec;
519b2c812e2SMark Brown 	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
520ef9e5e5cSPhilipp Zabel 	int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
521b7482f52SPhilipp Zabel 
522ef9e5e5cSPhilipp Zabel 	switch (cmd) {
523ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_START:
524ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
525ef9e5e5cSPhilipp Zabel 		uda1380_write_reg_cache(codec, UDA1380_MIXER,
526ef9e5e5cSPhilipp Zabel 					mixer & ~R14_SILENCE);
5271abd9184SPhilipp Zabel 		schedule_work(&uda1380->work);
528ef9e5e5cSPhilipp Zabel 		break;
529ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_STOP:
530ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
531ef9e5e5cSPhilipp Zabel 		uda1380_write_reg_cache(codec, UDA1380_MIXER,
532ef9e5e5cSPhilipp Zabel 					mixer | R14_SILENCE);
5331abd9184SPhilipp Zabel 		schedule_work(&uda1380->work);
534ef9e5e5cSPhilipp Zabel 		break;
535b7482f52SPhilipp Zabel 	}
536b7482f52SPhilipp Zabel 	return 0;
537b7482f52SPhilipp Zabel }
538b7482f52SPhilipp Zabel 
539b7482f52SPhilipp Zabel static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
540dee89c4dSMark Brown 				 struct snd_pcm_hw_params *params,
541dee89c4dSMark Brown 				 struct snd_soc_dai *dai)
542b7482f52SPhilipp Zabel {
543b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
544f0fba2adSLiam Girdwood 	struct snd_soc_codec *codec = rtd->codec;
545b7482f52SPhilipp Zabel 	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
546b7482f52SPhilipp Zabel 
547b7482f52SPhilipp Zabel 	/* set WSPLL power and divider if running from this clock */
548b7482f52SPhilipp Zabel 	if (clk & R00_DAC_CLK) {
549b7482f52SPhilipp Zabel 		int rate = params_rate(params);
550b7482f52SPhilipp Zabel 		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
551b7482f52SPhilipp Zabel 		clk &= ~0x3; /* clear SEL_LOOP_DIV */
552b7482f52SPhilipp Zabel 		switch (rate) {
553b7482f52SPhilipp Zabel 		case 6250 ... 12500:
554b7482f52SPhilipp Zabel 			clk |= 0x0;
555b7482f52SPhilipp Zabel 			break;
556b7482f52SPhilipp Zabel 		case 12501 ... 25000:
557b7482f52SPhilipp Zabel 			clk |= 0x1;
558b7482f52SPhilipp Zabel 			break;
559b7482f52SPhilipp Zabel 		case 25001 ... 50000:
560b7482f52SPhilipp Zabel 			clk |= 0x2;
561b7482f52SPhilipp Zabel 			break;
562b7482f52SPhilipp Zabel 		case 50001 ... 100000:
563b7482f52SPhilipp Zabel 			clk |= 0x3;
564b7482f52SPhilipp Zabel 			break;
565b7482f52SPhilipp Zabel 		}
566b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_PLL | pm);
567b7482f52SPhilipp Zabel 	}
568b7482f52SPhilipp Zabel 
569b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
570b7482f52SPhilipp Zabel 		clk |= R00_EN_DAC | R00_EN_INT;
571b7482f52SPhilipp Zabel 	else
572b7482f52SPhilipp Zabel 		clk |= R00_EN_ADC | R00_EN_DEC;
573b7482f52SPhilipp Zabel 
574b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, clk);
575b7482f52SPhilipp Zabel 	return 0;
576b7482f52SPhilipp Zabel }
577b7482f52SPhilipp Zabel 
578dee89c4dSMark Brown static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
579dee89c4dSMark Brown 				 struct snd_soc_dai *dai)
580b7482f52SPhilipp Zabel {
581b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
582f0fba2adSLiam Girdwood 	struct snd_soc_codec *codec = rtd->codec;
583b7482f52SPhilipp Zabel 	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
584b7482f52SPhilipp Zabel 
585b7482f52SPhilipp Zabel 	/* shut down WSPLL power if running from this clock */
586b7482f52SPhilipp Zabel 	if (clk & R00_DAC_CLK) {
587b7482f52SPhilipp Zabel 		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
588b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, ~R02_PON_PLL & pm);
589b7482f52SPhilipp Zabel 	}
590b7482f52SPhilipp Zabel 
591b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
592b7482f52SPhilipp Zabel 		clk &= ~(R00_EN_DAC | R00_EN_INT);
593b7482f52SPhilipp Zabel 	else
594b7482f52SPhilipp Zabel 		clk &= ~(R00_EN_ADC | R00_EN_DEC);
595b7482f52SPhilipp Zabel 
596b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, clk);
597b7482f52SPhilipp Zabel }
598b7482f52SPhilipp Zabel 
599b7482f52SPhilipp Zabel static int uda1380_set_bias_level(struct snd_soc_codec *codec,
600b7482f52SPhilipp Zabel 	enum snd_soc_bias_level level)
601b7482f52SPhilipp Zabel {
602b7482f52SPhilipp Zabel 	int pm = uda1380_read_reg_cache(codec, UDA1380_PM);
603*8614d310SVasily Khoruzhick 	int reg;
604*8614d310SVasily Khoruzhick 	struct uda1380_platform_data *pdata = codec->dev->platform_data;
605*8614d310SVasily Khoruzhick 
606*8614d310SVasily Khoruzhick 	if (codec->bias_level == level)
607*8614d310SVasily Khoruzhick 		return 0;
608b7482f52SPhilipp Zabel 
609b7482f52SPhilipp Zabel 	switch (level) {
610b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_ON:
611b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_PREPARE:
612*8614d310SVasily Khoruzhick 		/* ADC, DAC on */
613b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
614b7482f52SPhilipp Zabel 		break;
615b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_STANDBY:
616*8614d310SVasily Khoruzhick 		if (codec->bias_level == SND_SOC_BIAS_OFF) {
617*8614d310SVasily Khoruzhick 			if (gpio_is_valid(pdata->gpio_power)) {
618*8614d310SVasily Khoruzhick 				gpio_set_value(pdata->gpio_power, 1);
619*8614d310SVasily Khoruzhick 				uda1380_reset(codec);
620*8614d310SVasily Khoruzhick 			}
621*8614d310SVasily Khoruzhick 
622*8614d310SVasily Khoruzhick 			uda1380_sync_cache(codec);
623*8614d310SVasily Khoruzhick 		}
624b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, 0x0);
625b7482f52SPhilipp Zabel 		break;
626*8614d310SVasily Khoruzhick 	case SND_SOC_BIAS_OFF:
627*8614d310SVasily Khoruzhick 		if (!gpio_is_valid(pdata->gpio_power))
628*8614d310SVasily Khoruzhick 			break;
629*8614d310SVasily Khoruzhick 
630*8614d310SVasily Khoruzhick 		gpio_set_value(pdata->gpio_power, 0);
631*8614d310SVasily Khoruzhick 
632*8614d310SVasily Khoruzhick 		/* Mark mixer regs cache dirty to sync them with
633*8614d310SVasily Khoruzhick 		 * codec regs on power on.
634*8614d310SVasily Khoruzhick 		 */
635*8614d310SVasily Khoruzhick 		for (reg = UDA1380_MVOL; reg < UDA1380_CACHEREGNUM; reg++)
636*8614d310SVasily Khoruzhick 			set_bit(reg - 0x10, &uda1380_cache_dirty);
637b7482f52SPhilipp Zabel 	}
638b7482f52SPhilipp Zabel 	codec->bias_level = level;
639b7482f52SPhilipp Zabel 	return 0;
640b7482f52SPhilipp Zabel }
641b7482f52SPhilipp Zabel 
642b7482f52SPhilipp Zabel #define UDA1380_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
643b7482f52SPhilipp Zabel 		       SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
644b7482f52SPhilipp Zabel 		       SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
645b7482f52SPhilipp Zabel 
6466335d055SEric Miao static struct snd_soc_dai_ops uda1380_dai_ops = {
6476335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
6486335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
64965ec1cd1SMark Brown 	.trigger	= uda1380_trigger,
6506335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_both,
6516335d055SEric Miao };
6526335d055SEric Miao 
6536335d055SEric Miao static struct snd_soc_dai_ops uda1380_dai_ops_playback = {
6546335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
6556335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
65665ec1cd1SMark Brown 	.trigger	= uda1380_trigger,
6576335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_playback,
6586335d055SEric Miao };
6596335d055SEric Miao 
6606335d055SEric Miao static struct snd_soc_dai_ops uda1380_dai_ops_capture = {
6616335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
6626335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
66365ec1cd1SMark Brown 	.trigger	= uda1380_trigger,
6646335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_capture,
6656335d055SEric Miao };
6666335d055SEric Miao 
667f0fba2adSLiam Girdwood static struct snd_soc_dai_driver uda1380_dai[] = {
668b7482f52SPhilipp Zabel {
669f0fba2adSLiam Girdwood 	.name = "uda1380-hifi",
670b7482f52SPhilipp Zabel 	.playback = {
671b7482f52SPhilipp Zabel 		.stream_name = "Playback",
672b7482f52SPhilipp Zabel 		.channels_min = 1,
673b7482f52SPhilipp Zabel 		.channels_max = 2,
674b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
675b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
676b7482f52SPhilipp Zabel 	.capture = {
677b7482f52SPhilipp Zabel 		.stream_name = "Capture",
678b7482f52SPhilipp Zabel 		.channels_min = 1,
679b7482f52SPhilipp Zabel 		.channels_max = 2,
680b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
681b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
6826335d055SEric Miao 	.ops = &uda1380_dai_ops,
683b7482f52SPhilipp Zabel },
684b7482f52SPhilipp Zabel { /* playback only - dual interface */
685f0fba2adSLiam Girdwood 	.name = "uda1380-hifi-playback",
686b7482f52SPhilipp Zabel 	.playback = {
687b7482f52SPhilipp Zabel 		.stream_name = "Playback",
688b7482f52SPhilipp Zabel 		.channels_min = 1,
689b7482f52SPhilipp Zabel 		.channels_max = 2,
690b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
691b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
692b7482f52SPhilipp Zabel 	},
6936335d055SEric Miao 	.ops = &uda1380_dai_ops_playback,
694b7482f52SPhilipp Zabel },
695b7482f52SPhilipp Zabel { /* capture only - dual interface*/
696f0fba2adSLiam Girdwood 	.name = "uda1380-hifi-capture",
697b7482f52SPhilipp Zabel 	.capture = {
698b7482f52SPhilipp Zabel 		.stream_name = "Capture",
699b7482f52SPhilipp Zabel 		.channels_min = 1,
700b7482f52SPhilipp Zabel 		.channels_max = 2,
701b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
702b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
703b7482f52SPhilipp Zabel 	},
7046335d055SEric Miao 	.ops = &uda1380_dai_ops_capture,
705b7482f52SPhilipp Zabel },
706b7482f52SPhilipp Zabel };
707b7482f52SPhilipp Zabel 
708f0fba2adSLiam Girdwood static int uda1380_suspend(struct snd_soc_codec *codec, pm_message_t state)
709b7482f52SPhilipp Zabel {
710b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
711b7482f52SPhilipp Zabel 	return 0;
712b7482f52SPhilipp Zabel }
713b7482f52SPhilipp Zabel 
714f0fba2adSLiam Girdwood static int uda1380_resume(struct snd_soc_codec *codec)
715b7482f52SPhilipp Zabel {
716b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
717b7482f52SPhilipp Zabel 	return 0;
718b7482f52SPhilipp Zabel }
719b7482f52SPhilipp Zabel 
720f0fba2adSLiam Girdwood static int uda1380_probe(struct snd_soc_codec *codec)
721b7482f52SPhilipp Zabel {
722f0fba2adSLiam Girdwood 	struct uda1380_platform_data *pdata =codec->dev->platform_data;
723f0fba2adSLiam Girdwood 	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
724f0fba2adSLiam Girdwood 	int ret;
725b7482f52SPhilipp Zabel 
726*8614d310SVasily Khoruzhick 	uda1380->codec = codec;
727b7482f52SPhilipp Zabel 
728*8614d310SVasily Khoruzhick 	codec->hw_write = (hw_write_t)i2c_master_send;
729*8614d310SVasily Khoruzhick 	codec->control_data = uda1380->control_data;
730*8614d310SVasily Khoruzhick 
731*8614d310SVasily Khoruzhick 	if (!pdata)
732f0fba2adSLiam Girdwood 		return -EINVAL;
733ef9e5e5cSPhilipp Zabel 
734*8614d310SVasily Khoruzhick 	if (gpio_is_valid(pdata->gpio_reset)) {
735f0fba2adSLiam Girdwood 		ret = gpio_request(pdata->gpio_reset, "uda1380 reset");
736f0fba2adSLiam Girdwood 		if (ret)
737*8614d310SVasily Khoruzhick 			goto err_out;
738*8614d310SVasily Khoruzhick 		ret = gpio_direction_output(pdata->gpio_reset, 0);
739*8614d310SVasily Khoruzhick 		if (ret)
740*8614d310SVasily Khoruzhick 			goto err_gpio_reset_conf;
741*8614d310SVasily Khoruzhick 	}
742*8614d310SVasily Khoruzhick 
743*8614d310SVasily Khoruzhick 	if (gpio_is_valid(pdata->gpio_power)) {
744*8614d310SVasily Khoruzhick 		ret = gpio_request(pdata->gpio_power, "uda1380 power");
745*8614d310SVasily Khoruzhick 		if (ret)
746f0fba2adSLiam Girdwood 			goto err_gpio;
747*8614d310SVasily Khoruzhick 		ret = gpio_direction_output(pdata->gpio_power, 0);
748*8614d310SVasily Khoruzhick 		if (ret)
749*8614d310SVasily Khoruzhick 			goto err_gpio_power_conf;
750*8614d310SVasily Khoruzhick 	} else {
751f0fba2adSLiam Girdwood 		ret = uda1380_reset(codec);
752*8614d310SVasily Khoruzhick 		if (ret) {
753f0fba2adSLiam Girdwood 			dev_err(codec->dev, "Failed to issue reset\n");
754f0fba2adSLiam Girdwood 			goto err_reset;
755b7482f52SPhilipp Zabel 		}
756*8614d310SVasily Khoruzhick 	}
757b7482f52SPhilipp Zabel 
758f0fba2adSLiam Girdwood 	INIT_WORK(&uda1380->work, uda1380_flush_work);
759f0fba2adSLiam Girdwood 
760b7482f52SPhilipp Zabel 	/* power on device */
761b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
762b7482f52SPhilipp Zabel 	/* set clock input */
7631abd9184SPhilipp Zabel 	switch (pdata->dac_clk) {
764b7482f52SPhilipp Zabel 	case UDA1380_DAC_CLK_SYSCLK:
765*8614d310SVasily Khoruzhick 		uda1380_write_reg_cache(codec, UDA1380_CLK, 0);
766b7482f52SPhilipp Zabel 		break;
767b7482f52SPhilipp Zabel 	case UDA1380_DAC_CLK_WSPLL:
768*8614d310SVasily Khoruzhick 		uda1380_write_reg_cache(codec, UDA1380_CLK,
769*8614d310SVasily Khoruzhick 			R00_DAC_CLK);
770b7482f52SPhilipp Zabel 		break;
771b7482f52SPhilipp Zabel 	}
772b7482f52SPhilipp Zabel 
7733e8e1952SIan Molton 	snd_soc_add_controls(codec, uda1380_snd_controls,
7743e8e1952SIan Molton 				ARRAY_SIZE(uda1380_snd_controls));
775b7482f52SPhilipp Zabel 	uda1380_add_widgets(codec);
776b7482f52SPhilipp Zabel 
7771abd9184SPhilipp Zabel 	return 0;
7781abd9184SPhilipp Zabel 
7791abd9184SPhilipp Zabel err_reset:
780*8614d310SVasily Khoruzhick err_gpio_power_conf:
781*8614d310SVasily Khoruzhick 	if (gpio_is_valid(pdata->gpio_power))
7821abd9184SPhilipp Zabel 		gpio_free(pdata->gpio_power);
783*8614d310SVasily Khoruzhick 
784*8614d310SVasily Khoruzhick err_gpio_reset_conf:
785*8614d310SVasily Khoruzhick err_gpio:
786*8614d310SVasily Khoruzhick 	if (gpio_is_valid(pdata->gpio_reset))
787*8614d310SVasily Khoruzhick 		gpio_free(pdata->gpio_reset);
788*8614d310SVasily Khoruzhick err_out:
7891abd9184SPhilipp Zabel 	return ret;
7901abd9184SPhilipp Zabel }
7911abd9184SPhilipp Zabel 
792f0fba2adSLiam Girdwood /* power down chip */
793f0fba2adSLiam Girdwood static int uda1380_remove(struct snd_soc_codec *codec)
7941abd9184SPhilipp Zabel {
7951abd9184SPhilipp Zabel 	struct uda1380_platform_data *pdata =codec->dev->platform_data;
7961abd9184SPhilipp Zabel 
797f0fba2adSLiam Girdwood 	uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
7981abd9184SPhilipp Zabel 
7991abd9184SPhilipp Zabel 	gpio_free(pdata->gpio_reset);
8001abd9184SPhilipp Zabel 	gpio_free(pdata->gpio_power);
8011abd9184SPhilipp Zabel 
802f0fba2adSLiam Girdwood 	return 0;
8031abd9184SPhilipp Zabel }
804b7482f52SPhilipp Zabel 
805f0fba2adSLiam Girdwood static struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
806f0fba2adSLiam Girdwood 	.probe =	uda1380_probe,
807f0fba2adSLiam Girdwood 	.remove =	uda1380_remove,
808f0fba2adSLiam Girdwood 	.suspend =	uda1380_suspend,
809f0fba2adSLiam Girdwood 	.resume =	uda1380_resume,
810f0fba2adSLiam Girdwood 	.read =		uda1380_read_reg_cache,
811f0fba2adSLiam Girdwood 	.write =	uda1380_write,
812f0fba2adSLiam Girdwood 	.set_bias_level = uda1380_set_bias_level,
813f0fba2adSLiam Girdwood 	.reg_cache_size = ARRAY_SIZE(uda1380_reg),
814f0fba2adSLiam Girdwood 	.reg_word_size = sizeof(u16),
815f0fba2adSLiam Girdwood 	.reg_cache_default = uda1380_reg,
816f0fba2adSLiam Girdwood 	.reg_cache_step = 1,
817f0fba2adSLiam Girdwood };
818f0fba2adSLiam Girdwood 
819b7482f52SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
8201abd9184SPhilipp Zabel static __devinit int uda1380_i2c_probe(struct i2c_client *i2c,
82188fc39d7SJean Delvare 				      const struct i2c_device_id *id)
822b7482f52SPhilipp Zabel {
8231abd9184SPhilipp Zabel 	struct uda1380_priv *uda1380;
824b7482f52SPhilipp Zabel 	int ret;
825b7482f52SPhilipp Zabel 
8261abd9184SPhilipp Zabel 	uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL);
8271abd9184SPhilipp Zabel 	if (uda1380 == NULL)
8281abd9184SPhilipp Zabel 		return -ENOMEM;
8291abd9184SPhilipp Zabel 
8301abd9184SPhilipp Zabel 	i2c_set_clientdata(i2c, uda1380);
831*8614d310SVasily Khoruzhick 	uda1380->control_data = i2c;
832b7482f52SPhilipp Zabel 
833f0fba2adSLiam Girdwood 	ret =  snd_soc_register_codec(&i2c->dev,
834f0fba2adSLiam Girdwood 			&soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
835f0fba2adSLiam Girdwood 	if (ret < 0)
8361abd9184SPhilipp Zabel 		kfree(uda1380);
837b7482f52SPhilipp Zabel 	return ret;
838b7482f52SPhilipp Zabel }
839b7482f52SPhilipp Zabel 
8401abd9184SPhilipp Zabel static int __devexit uda1380_i2c_remove(struct i2c_client *i2c)
841b7482f52SPhilipp Zabel {
842f0fba2adSLiam Girdwood 	snd_soc_unregister_codec(&i2c->dev);
843f0fba2adSLiam Girdwood 	kfree(i2c_get_clientdata(i2c));
844b7482f52SPhilipp Zabel 	return 0;
845b7482f52SPhilipp Zabel }
846b7482f52SPhilipp Zabel 
84788fc39d7SJean Delvare static const struct i2c_device_id uda1380_i2c_id[] = {
84888fc39d7SJean Delvare 	{ "uda1380", 0 },
84988fc39d7SJean Delvare 	{ }
85088fc39d7SJean Delvare };
85188fc39d7SJean Delvare MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
852b7482f52SPhilipp Zabel 
853b7482f52SPhilipp Zabel static struct i2c_driver uda1380_i2c_driver = {
854b7482f52SPhilipp Zabel 	.driver = {
855f0fba2adSLiam Girdwood 		.name =  "uda1380-codec",
856b7482f52SPhilipp Zabel 		.owner = THIS_MODULE,
857b7482f52SPhilipp Zabel 	},
85888fc39d7SJean Delvare 	.probe =    uda1380_i2c_probe,
8591abd9184SPhilipp Zabel 	.remove =   __devexit_p(uda1380_i2c_remove),
86088fc39d7SJean Delvare 	.id_table = uda1380_i2c_id,
861b7482f52SPhilipp Zabel };
862b7482f52SPhilipp Zabel #endif
863b7482f52SPhilipp Zabel 
864c9b3a40fSTakashi Iwai static int __init uda1380_modinit(void)
86564089b84SMark Brown {
8661abd9184SPhilipp Zabel 	int ret;
8671abd9184SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
8681abd9184SPhilipp Zabel 	ret = i2c_add_driver(&uda1380_i2c_driver);
8691abd9184SPhilipp Zabel 	if (ret != 0)
8701abd9184SPhilipp Zabel 		pr_err("Failed to register UDA1380 I2C driver: %d\n", ret);
8711abd9184SPhilipp Zabel #endif
8721abd9184SPhilipp Zabel 	return 0;
87364089b84SMark Brown }
87464089b84SMark Brown module_init(uda1380_modinit);
87564089b84SMark Brown 
87664089b84SMark Brown static void __exit uda1380_exit(void)
87764089b84SMark Brown {
8781abd9184SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
8791abd9184SPhilipp Zabel 	i2c_del_driver(&uda1380_i2c_driver);
8801abd9184SPhilipp Zabel #endif
88164089b84SMark Brown }
88264089b84SMark Brown module_exit(uda1380_exit);
88364089b84SMark Brown 
884b7482f52SPhilipp Zabel MODULE_AUTHOR("Giorgio Padrin");
885b7482f52SPhilipp Zabel MODULE_DESCRIPTION("Audio support for codec Philips UDA1380");
886b7482f52SPhilipp Zabel MODULE_LICENSE("GPL");
887