xref: /linux/sound/soc/codecs/uda1380.c (revision 68020db8ac1046e50c758545b75850eb356a0651)
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/tlv.h>
311abd9184SPhilipp Zabel #include <sound/uda1380.h>
32b7482f52SPhilipp Zabel 
33b7482f52SPhilipp Zabel #include "uda1380.h"
34b7482f52SPhilipp Zabel 
351abd9184SPhilipp Zabel /* codec private data */
361abd9184SPhilipp Zabel struct uda1380_priv {
37f0fba2adSLiam Girdwood 	struct snd_soc_codec *codec;
381abd9184SPhilipp Zabel 	unsigned int dac_clk;
391abd9184SPhilipp Zabel 	struct work_struct work;
408614d310SVasily Khoruzhick 	void *control_data;
411abd9184SPhilipp Zabel };
421abd9184SPhilipp Zabel 
43b7482f52SPhilipp Zabel /*
44b7482f52SPhilipp Zabel  * uda1380 register cache
45b7482f52SPhilipp Zabel  */
46b7482f52SPhilipp Zabel static const u16 uda1380_reg[UDA1380_CACHEREGNUM] = {
47b7482f52SPhilipp Zabel 	0x0502, 0x0000, 0x0000, 0x3f3f,
48b7482f52SPhilipp Zabel 	0x0202, 0x0000, 0x0000, 0x0000,
49b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
50b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
51b7482f52SPhilipp Zabel 	0x0000, 0xff00, 0x0000, 0x4800,
52b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
53b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
54b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
55b7482f52SPhilipp Zabel 	0x0000, 0x8000, 0x0002, 0x0000,
56b7482f52SPhilipp Zabel };
57b7482f52SPhilipp Zabel 
58ef9e5e5cSPhilipp Zabel static unsigned long uda1380_cache_dirty;
59ef9e5e5cSPhilipp Zabel 
60b7482f52SPhilipp Zabel /*
61b7482f52SPhilipp Zabel  * read uda1380 register cache
62b7482f52SPhilipp Zabel  */
63b7482f52SPhilipp Zabel static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec,
64b7482f52SPhilipp Zabel 	unsigned int reg)
65b7482f52SPhilipp Zabel {
66b7482f52SPhilipp Zabel 	u16 *cache = codec->reg_cache;
67b7482f52SPhilipp Zabel 	if (reg == UDA1380_RESET)
68b7482f52SPhilipp Zabel 		return 0;
69b7482f52SPhilipp Zabel 	if (reg >= UDA1380_CACHEREGNUM)
70b7482f52SPhilipp Zabel 		return -1;
71b7482f52SPhilipp Zabel 	return cache[reg];
72b7482f52SPhilipp Zabel }
73b7482f52SPhilipp Zabel 
74b7482f52SPhilipp Zabel /*
75b7482f52SPhilipp Zabel  * write uda1380 register cache
76b7482f52SPhilipp Zabel  */
77b7482f52SPhilipp Zabel static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
78b7482f52SPhilipp Zabel 	u16 reg, unsigned int value)
79b7482f52SPhilipp Zabel {
80b7482f52SPhilipp Zabel 	u16 *cache = codec->reg_cache;
81ef9e5e5cSPhilipp Zabel 
82b7482f52SPhilipp Zabel 	if (reg >= UDA1380_CACHEREGNUM)
83b7482f52SPhilipp Zabel 		return;
84ef9e5e5cSPhilipp Zabel 	if ((reg >= 0x10) && (cache[reg] != value))
85ef9e5e5cSPhilipp Zabel 		set_bit(reg - 0x10, &uda1380_cache_dirty);
86b7482f52SPhilipp Zabel 	cache[reg] = value;
87b7482f52SPhilipp Zabel }
88b7482f52SPhilipp Zabel 
89b7482f52SPhilipp Zabel /*
90b7482f52SPhilipp Zabel  * write to the UDA1380 register space
91b7482f52SPhilipp Zabel  */
92b7482f52SPhilipp Zabel static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
93b7482f52SPhilipp Zabel 	unsigned int value)
94b7482f52SPhilipp Zabel {
95b7482f52SPhilipp Zabel 	u8 data[3];
96b7482f52SPhilipp Zabel 
97b7482f52SPhilipp Zabel 	/* data is
98b7482f52SPhilipp Zabel 	 *   data[0] is register offset
99b7482f52SPhilipp Zabel 	 *   data[1] is MS byte
100b7482f52SPhilipp Zabel 	 *   data[2] is LS byte
101b7482f52SPhilipp Zabel 	 */
102b7482f52SPhilipp Zabel 	data[0] = reg;
103b7482f52SPhilipp Zabel 	data[1] = (value & 0xff00) >> 8;
104b7482f52SPhilipp Zabel 	data[2] = value & 0x00ff;
105b7482f52SPhilipp Zabel 
106b7482f52SPhilipp Zabel 	uda1380_write_reg_cache(codec, reg, value);
107b7482f52SPhilipp Zabel 
108b7482f52SPhilipp Zabel 	/* the interpolator & decimator regs must only be written when the
109b7482f52SPhilipp Zabel 	 * codec DAI is active.
110b7482f52SPhilipp Zabel 	 */
111b7482f52SPhilipp Zabel 	if (!codec->active && (reg >= UDA1380_MVOL))
112b7482f52SPhilipp Zabel 		return 0;
113b7482f52SPhilipp Zabel 	pr_debug("uda1380: hw write %x val %x\n", reg, value);
114b7482f52SPhilipp Zabel 	if (codec->hw_write(codec->control_data, data, 3) == 3) {
115b7482f52SPhilipp Zabel 		unsigned int val;
116b7482f52SPhilipp Zabel 		i2c_master_send(codec->control_data, data, 1);
117b7482f52SPhilipp Zabel 		i2c_master_recv(codec->control_data, data, 2);
118b7482f52SPhilipp Zabel 		val = (data[0]<<8) | data[1];
119b7482f52SPhilipp Zabel 		if (val != value) {
120b7482f52SPhilipp Zabel 			pr_debug("uda1380: READ BACK VAL %x\n",
121b7482f52SPhilipp Zabel 					(data[0]<<8) | data[1]);
122b7482f52SPhilipp Zabel 			return -EIO;
123b7482f52SPhilipp Zabel 		}
124ef9e5e5cSPhilipp Zabel 		if (reg >= 0x10)
125ef9e5e5cSPhilipp Zabel 			clear_bit(reg - 0x10, &uda1380_cache_dirty);
126b7482f52SPhilipp Zabel 		return 0;
127b7482f52SPhilipp Zabel 	} else
128b7482f52SPhilipp Zabel 		return -EIO;
129b7482f52SPhilipp Zabel }
130b7482f52SPhilipp Zabel 
1318614d310SVasily Khoruzhick static void uda1380_sync_cache(struct snd_soc_codec *codec)
1328614d310SVasily Khoruzhick {
1338614d310SVasily Khoruzhick 	int reg;
1348614d310SVasily Khoruzhick 	u8 data[3];
1358614d310SVasily Khoruzhick 	u16 *cache = codec->reg_cache;
1368614d310SVasily Khoruzhick 
1378614d310SVasily Khoruzhick 	/* Sync reg_cache with the hardware */
1388614d310SVasily Khoruzhick 	for (reg = 0; reg < UDA1380_MVOL; reg++) {
1398614d310SVasily Khoruzhick 		data[0] = reg;
1408614d310SVasily Khoruzhick 		data[1] = (cache[reg] & 0xff00) >> 8;
1418614d310SVasily Khoruzhick 		data[2] = cache[reg] & 0x00ff;
1428614d310SVasily Khoruzhick 		if (codec->hw_write(codec->control_data, data, 3) != 3)
1438614d310SVasily Khoruzhick 			dev_err(codec->dev, "%s: write to reg 0x%x failed\n",
1448614d310SVasily Khoruzhick 				__func__, reg);
1458614d310SVasily Khoruzhick 	}
1468614d310SVasily Khoruzhick }
1478614d310SVasily Khoruzhick 
1488614d310SVasily Khoruzhick static int uda1380_reset(struct snd_soc_codec *codec)
1498614d310SVasily Khoruzhick {
1508614d310SVasily Khoruzhick 	struct uda1380_platform_data *pdata = codec->dev->platform_data;
1518614d310SVasily Khoruzhick 
1528614d310SVasily Khoruzhick 	if (gpio_is_valid(pdata->gpio_reset)) {
1538614d310SVasily Khoruzhick 		gpio_set_value(pdata->gpio_reset, 1);
1548614d310SVasily Khoruzhick 		mdelay(1);
1558614d310SVasily Khoruzhick 		gpio_set_value(pdata->gpio_reset, 0);
1568614d310SVasily Khoruzhick 	} else {
1578614d310SVasily Khoruzhick 		u8 data[3];
1588614d310SVasily Khoruzhick 
1598614d310SVasily Khoruzhick 		data[0] = UDA1380_RESET;
1608614d310SVasily Khoruzhick 		data[1] = 0;
1618614d310SVasily Khoruzhick 		data[2] = 0;
1628614d310SVasily Khoruzhick 
1638614d310SVasily Khoruzhick 		if (codec->hw_write(codec->control_data, data, 3) != 3) {
1648614d310SVasily Khoruzhick 			dev_err(codec->dev, "%s: failed\n", __func__);
1658614d310SVasily Khoruzhick 			return -EIO;
1668614d310SVasily Khoruzhick 		}
1678614d310SVasily Khoruzhick 	}
1688614d310SVasily Khoruzhick 
1698614d310SVasily Khoruzhick 	return 0;
1708614d310SVasily Khoruzhick }
171b7482f52SPhilipp Zabel 
172ef9e5e5cSPhilipp Zabel static void uda1380_flush_work(struct work_struct *work)
173ef9e5e5cSPhilipp Zabel {
174f0fba2adSLiam Girdwood 	struct uda1380_priv *uda1380 = container_of(work, struct uda1380_priv, work);
175f0fba2adSLiam Girdwood 	struct snd_soc_codec *uda1380_codec = uda1380->codec;
176ef9e5e5cSPhilipp Zabel 	int bit, reg;
177ef9e5e5cSPhilipp Zabel 
178984b3f57SAkinobu Mita 	for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
179ef9e5e5cSPhilipp Zabel 		reg = 0x10 + bit;
180ef9e5e5cSPhilipp Zabel 		pr_debug("uda1380: flush reg %x val %x:\n", reg,
181ef9e5e5cSPhilipp Zabel 				uda1380_read_reg_cache(uda1380_codec, reg));
182ef9e5e5cSPhilipp Zabel 		uda1380_write(uda1380_codec, reg,
183ef9e5e5cSPhilipp Zabel 				uda1380_read_reg_cache(uda1380_codec, reg));
184ef9e5e5cSPhilipp Zabel 		clear_bit(bit, &uda1380_cache_dirty);
185ef9e5e5cSPhilipp Zabel 	}
186f0fba2adSLiam Girdwood 
187ef9e5e5cSPhilipp Zabel }
188ef9e5e5cSPhilipp Zabel 
189b7482f52SPhilipp Zabel /* declarations of ALSA reg_elem_REAL controls */
190b7482f52SPhilipp Zabel static const char *uda1380_deemp[] = {
191b7482f52SPhilipp Zabel 	"None",
192b7482f52SPhilipp Zabel 	"32kHz",
193b7482f52SPhilipp Zabel 	"44.1kHz",
194b7482f52SPhilipp Zabel 	"48kHz",
195b7482f52SPhilipp Zabel 	"96kHz",
196b7482f52SPhilipp Zabel };
197b7482f52SPhilipp Zabel static const char *uda1380_input_sel[] = {
198b7482f52SPhilipp Zabel 	"Line",
199b7482f52SPhilipp Zabel 	"Mic + Line R",
200b7482f52SPhilipp Zabel 	"Line L",
201b7482f52SPhilipp Zabel 	"Mic",
202b7482f52SPhilipp Zabel };
203b7482f52SPhilipp Zabel static const char *uda1380_output_sel[] = {
204b7482f52SPhilipp Zabel 	"DAC",
205b7482f52SPhilipp Zabel 	"Analog Mixer",
206b7482f52SPhilipp Zabel };
207b7482f52SPhilipp Zabel static const char *uda1380_spf_mode[] = {
208b7482f52SPhilipp Zabel 	"Flat",
209b7482f52SPhilipp Zabel 	"Minimum1",
210b7482f52SPhilipp Zabel 	"Minimum2",
211b7482f52SPhilipp Zabel 	"Maximum"
212b7482f52SPhilipp Zabel };
213b7482f52SPhilipp Zabel static const char *uda1380_capture_sel[] = {
214b7482f52SPhilipp Zabel 	"ADC",
215b7482f52SPhilipp Zabel 	"Digital Mixer"
216b7482f52SPhilipp Zabel };
217b7482f52SPhilipp Zabel static const char *uda1380_sel_ns[] = {
218b7482f52SPhilipp Zabel 	"3rd-order",
219b7482f52SPhilipp Zabel 	"5th-order"
220b7482f52SPhilipp Zabel };
221b7482f52SPhilipp Zabel static const char *uda1380_mix_control[] = {
222b7482f52SPhilipp Zabel 	"off",
223b7482f52SPhilipp Zabel 	"PCM only",
224b7482f52SPhilipp Zabel 	"before sound processing",
225b7482f52SPhilipp Zabel 	"after sound processing"
226b7482f52SPhilipp Zabel };
227b7482f52SPhilipp Zabel static const char *uda1380_sdet_setting[] = {
228b7482f52SPhilipp Zabel 	"3200",
229b7482f52SPhilipp Zabel 	"4800",
230b7482f52SPhilipp Zabel 	"9600",
231b7482f52SPhilipp Zabel 	"19200"
232b7482f52SPhilipp Zabel };
233b7482f52SPhilipp Zabel static const char *uda1380_os_setting[] = {
234b7482f52SPhilipp Zabel 	"single-speed",
235b7482f52SPhilipp Zabel 	"double-speed (no mixing)",
236b7482f52SPhilipp Zabel 	"quad-speed (no mixing)"
237b7482f52SPhilipp Zabel };
238b7482f52SPhilipp Zabel 
239b7482f52SPhilipp Zabel static const struct soc_enum uda1380_deemp_enum[] = {
240b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_DEEMP, 8, 5, uda1380_deemp),
241b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_DEEMP, 0, 5, uda1380_deemp),
242b7482f52SPhilipp Zabel };
243b7482f52SPhilipp Zabel static const struct soc_enum uda1380_input_sel_enum =
244b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_ADC, 2, 4, uda1380_input_sel);		/* SEL_MIC, SEL_LNA */
245b7482f52SPhilipp Zabel static const struct soc_enum uda1380_output_sel_enum =
246b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_PM, 7, 2, uda1380_output_sel);		/* R02_EN_AVC */
247b7482f52SPhilipp Zabel static const struct soc_enum uda1380_spf_enum =
248b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MODE, 14, 4, uda1380_spf_mode);		/* M */
249b7482f52SPhilipp Zabel static const struct soc_enum uda1380_capture_sel_enum =
250b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_IFACE, 6, 2, uda1380_capture_sel);	/* SEL_SOURCE */
251b7482f52SPhilipp Zabel static const struct soc_enum uda1380_sel_ns_enum =
252b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 14, 2, uda1380_sel_ns);		/* SEL_NS */
253b7482f52SPhilipp Zabel static const struct soc_enum uda1380_mix_enum =
254b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 12, 4, uda1380_mix_control);	/* MIX, MIX_POS */
255b7482f52SPhilipp Zabel static const struct soc_enum uda1380_sdet_enum =
256b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 4, 4, uda1380_sdet_setting);	/* SD_VALUE */
257b7482f52SPhilipp Zabel static const struct soc_enum uda1380_os_enum =
258b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 0, 3, uda1380_os_setting);	/* OS */
259b7482f52SPhilipp Zabel 
260b7482f52SPhilipp Zabel /*
261b7482f52SPhilipp Zabel  * from -48 dB in 1.5 dB steps (mute instead of -49.5 dB)
262b7482f52SPhilipp Zabel  */
263b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(amix_tlv, -4950, 150, 1);
264b7482f52SPhilipp Zabel 
265b7482f52SPhilipp Zabel /*
266b7482f52SPhilipp Zabel  * from -78 dB in 1 dB steps (3 dB steps, really. LSB are ignored),
267b7482f52SPhilipp Zabel  * from -66 dB in 0.5 dB steps (2 dB steps, really) and
268b7482f52SPhilipp Zabel  * from -52 dB in 0.25 dB steps
269b7482f52SPhilipp Zabel  */
270b7482f52SPhilipp Zabel static const unsigned int mvol_tlv[] = {
271b7482f52SPhilipp Zabel 	TLV_DB_RANGE_HEAD(3),
272b7482f52SPhilipp Zabel 	0, 15, TLV_DB_SCALE_ITEM(-8200, 100, 1),
273b7482f52SPhilipp Zabel 	16, 43, TLV_DB_SCALE_ITEM(-6600, 50, 0),
274b7482f52SPhilipp Zabel 	44, 252, TLV_DB_SCALE_ITEM(-5200, 25, 0),
275b7482f52SPhilipp Zabel };
276b7482f52SPhilipp Zabel 
277b7482f52SPhilipp Zabel /*
278b7482f52SPhilipp Zabel  * from -72 dB in 1.5 dB steps (6 dB steps really),
279b7482f52SPhilipp Zabel  * from -66 dB in 0.75 dB steps (3 dB steps really),
280b7482f52SPhilipp Zabel  * from -60 dB in 0.5 dB steps (2 dB steps really) and
281b7482f52SPhilipp Zabel  * from -46 dB in 0.25 dB steps
282b7482f52SPhilipp Zabel  */
283b7482f52SPhilipp Zabel static const unsigned int vc_tlv[] = {
284b7482f52SPhilipp Zabel 	TLV_DB_RANGE_HEAD(4),
285b7482f52SPhilipp Zabel 	0, 7, TLV_DB_SCALE_ITEM(-7800, 150, 1),
286b7482f52SPhilipp Zabel 	8, 15, TLV_DB_SCALE_ITEM(-6600, 75, 0),
287b7482f52SPhilipp Zabel 	16, 43, TLV_DB_SCALE_ITEM(-6000, 50, 0),
288b7482f52SPhilipp Zabel 	44, 228, TLV_DB_SCALE_ITEM(-4600, 25, 0),
289b7482f52SPhilipp Zabel };
290b7482f52SPhilipp Zabel 
291b7482f52SPhilipp Zabel /* from 0 to 6 dB in 2 dB steps if SPF mode != flat */
292b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(tr_tlv, 0, 200, 0);
293b7482f52SPhilipp Zabel 
294b7482f52SPhilipp Zabel /* from 0 to 24 dB in 2 dB steps, if SPF mode == maximum, otherwise cuts
295b7482f52SPhilipp Zabel  * off at 18 dB max) */
296b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(bb_tlv, 0, 200, 0);
297b7482f52SPhilipp Zabel 
298b7482f52SPhilipp Zabel /* from -63 to 24 dB in 0.5 dB steps (-128...48) */
299b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(dec_tlv, -6400, 50, 1);
300b7482f52SPhilipp Zabel 
301b7482f52SPhilipp Zabel /* from 0 to 24 dB in 3 dB steps */
302b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0);
303b7482f52SPhilipp Zabel 
304b7482f52SPhilipp Zabel /* from 0 to 30 dB in 2 dB steps */
305b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(vga_tlv, 0, 200, 0);
306b7482f52SPhilipp Zabel 
307b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_snd_controls[] = {
308b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Analog Mixer Volume", UDA1380_AMIX, 0, 8, 44, 1, amix_tlv),	/* AVCR, AVCL */
309b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Master Playback Volume", UDA1380_MVOL, 0, 8, 252, 1, mvol_tlv),	/* MVCL, MVCR */
310b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("ADC Playback Volume", UDA1380_MIXVOL, 8, 228, 1, vc_tlv),	/* VC2 */
311b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("PCM Playback Volume", UDA1380_MIXVOL, 0, 228, 1, vc_tlv),	/* VC1 */
312b7482f52SPhilipp Zabel 	SOC_ENUM("Sound Processing Filter", uda1380_spf_enum),				/* M */
313b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Tone Control - Treble", UDA1380_MODE, 4, 12, 3, 0, tr_tlv), 	/* TRL, TRR */
314b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Tone Control - Bass", UDA1380_MODE, 0, 8, 15, 0, bb_tlv),	/* BBL, BBR */
315b7482f52SPhilipp Zabel /**/	SOC_SINGLE("Master Playback Switch", UDA1380_DEEMP, 14, 1, 1),		/* MTM */
316b7482f52SPhilipp Zabel 	SOC_SINGLE("ADC Playback Switch", UDA1380_DEEMP, 11, 1, 1),		/* MT2 from decimation filter */
317b7482f52SPhilipp Zabel 	SOC_ENUM("ADC Playback De-emphasis", uda1380_deemp_enum[0]),		/* DE2 */
318b7482f52SPhilipp Zabel 	SOC_SINGLE("PCM Playback Switch", UDA1380_DEEMP, 3, 1, 1),		/* MT1, from digital data input */
319b7482f52SPhilipp Zabel 	SOC_ENUM("PCM Playback De-emphasis", uda1380_deemp_enum[1]),		/* DE1 */
320b7482f52SPhilipp Zabel 	SOC_SINGLE("DAC Polarity inverting Switch", UDA1380_MIXER, 15, 1, 0),	/* DA_POL_INV */
321b7482f52SPhilipp Zabel 	SOC_ENUM("Noise Shaper", uda1380_sel_ns_enum),				/* SEL_NS */
322b7482f52SPhilipp Zabel 	SOC_ENUM("Digital Mixer Signal Control", uda1380_mix_enum),		/* MIX_POS, MIX */
323b7482f52SPhilipp Zabel 	SOC_SINGLE("Silence Detector Switch", UDA1380_MIXER, 6, 1, 0),		/* SDET_ON */
324b7482f52SPhilipp Zabel 	SOC_ENUM("Silence Detector Setting", uda1380_sdet_enum),		/* SD_VALUE */
325b7482f52SPhilipp Zabel 	SOC_ENUM("Oversampling Input", uda1380_os_enum),			/* OS */
326b7482f52SPhilipp Zabel 	SOC_DOUBLE_S8_TLV("ADC Capture Volume", UDA1380_DEC, -128, 48, dec_tlv),	/* ML_DEC, MR_DEC */
327b7482f52SPhilipp Zabel /**/	SOC_SINGLE("ADC Capture Switch", UDA1380_PGA, 15, 1, 1),		/* MT_ADC */
328b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Line Capture Volume", UDA1380_PGA, 0, 8, 8, 0, pga_tlv), /* PGA_GAINCTRLL, PGA_GAINCTRLR */
329b7482f52SPhilipp Zabel 	SOC_SINGLE("ADC Polarity inverting Switch", UDA1380_ADC, 12, 1, 0),	/* ADCPOL_INV */
330b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("Mic Capture Volume", UDA1380_ADC, 8, 15, 0, vga_tlv),	/* VGA_CTRL */
331b7482f52SPhilipp Zabel 	SOC_SINGLE("DC Filter Bypass Switch", UDA1380_ADC, 1, 1, 0),		/* SKIP_DCFIL (before decimator) */
332b7482f52SPhilipp Zabel 	SOC_SINGLE("DC Filter Enable Switch", UDA1380_ADC, 0, 1, 0),		/* EN_DCFIL (at output of decimator) */
333b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Timing", UDA1380_AGC, 8, 7, 0),			/* TODO: enum, see table 62 */
334b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Target level", UDA1380_AGC, 2, 3, 1),			/* AGC_LEVEL */
335b7482f52SPhilipp Zabel 	/* -5.5, -8, -11.5, -14 dBFS */
336b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0),
337b7482f52SPhilipp Zabel };
338b7482f52SPhilipp Zabel 
339b7482f52SPhilipp Zabel /* Input mux */
340b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_input_mux_control =
341b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_input_sel_enum);
342b7482f52SPhilipp Zabel 
343b7482f52SPhilipp Zabel /* Output mux */
344b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_output_mux_control =
345b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_output_sel_enum);
346b7482f52SPhilipp Zabel 
347b7482f52SPhilipp Zabel /* Capture mux */
348b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_capture_mux_control =
349b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_capture_sel_enum);
350b7482f52SPhilipp Zabel 
351b7482f52SPhilipp Zabel 
352b7482f52SPhilipp Zabel static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
353b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
354b7482f52SPhilipp Zabel 		&uda1380_input_mux_control),
355b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM, 0, 0,
356b7482f52SPhilipp Zabel 		&uda1380_output_mux_control),
357b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0,
358b7482f52SPhilipp Zabel 		&uda1380_capture_mux_control),
359b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Left PGA", UDA1380_PM, 3, 0, NULL, 0),
360b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Right PGA", UDA1380_PM, 1, 0, NULL, 0),
361b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Mic LNA", UDA1380_PM, 4, 0, NULL, 0),
362b7482f52SPhilipp Zabel 	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", UDA1380_PM, 2, 0),
363b7482f52SPhilipp Zabel 	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", UDA1380_PM, 0, 0),
364b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINM"),
365b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINL"),
366b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINR"),
367b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MIXER("Analog Mixer", UDA1380_PM, 6, 0, NULL, 0),
368b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTLHP"),
369b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTRHP"),
370b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTL"),
371b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTR"),
372b7482f52SPhilipp Zabel 	SND_SOC_DAPM_DAC("DAC", "Playback", UDA1380_PM, 10, 0),
373b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("HeadPhone Driver", UDA1380_PM, 13, 0, NULL, 0),
374b7482f52SPhilipp Zabel };
375b7482f52SPhilipp Zabel 
376b7482f52SPhilipp Zabel static const struct snd_soc_dapm_route audio_map[] = {
377b7482f52SPhilipp Zabel 
378b7482f52SPhilipp Zabel 	/* output mux */
379b7482f52SPhilipp Zabel 	{"HeadPhone Driver", NULL, "Output Mux"},
380b7482f52SPhilipp Zabel 	{"VOUTR", NULL, "Output Mux"},
381b7482f52SPhilipp Zabel 	{"VOUTL", NULL, "Output Mux"},
382b7482f52SPhilipp Zabel 
383b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "VINR"},
384b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "VINL"},
385b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "DAC"},
386b7482f52SPhilipp Zabel 
387b7482f52SPhilipp Zabel 	{"Output Mux", "DAC", "DAC"},
388b7482f52SPhilipp Zabel 	{"Output Mux", "Analog Mixer", "Analog Mixer"},
389b7482f52SPhilipp Zabel 
390b7482f52SPhilipp Zabel 	/* {"DAC", "Digital Mixer", "I2S" } */
391b7482f52SPhilipp Zabel 
392b7482f52SPhilipp Zabel 	/* headphone driver */
393b7482f52SPhilipp Zabel 	{"VOUTLHP", NULL, "HeadPhone Driver"},
394b7482f52SPhilipp Zabel 	{"VOUTRHP", NULL, "HeadPhone Driver"},
395b7482f52SPhilipp Zabel 
396b7482f52SPhilipp Zabel 	/* input mux */
397b7482f52SPhilipp Zabel 	{"Left ADC", NULL, "Input Mux"},
398b7482f52SPhilipp Zabel 	{"Input Mux", "Mic", "Mic LNA"},
399b7482f52SPhilipp Zabel 	{"Input Mux", "Mic + Line R", "Mic LNA"},
400b7482f52SPhilipp Zabel 	{"Input Mux", "Line L", "Left PGA"},
401b7482f52SPhilipp Zabel 	{"Input Mux", "Line", "Left PGA"},
402b7482f52SPhilipp Zabel 
403b7482f52SPhilipp Zabel 	/* right input */
404b7482f52SPhilipp Zabel 	{"Right ADC", "Mic + Line R", "Right PGA"},
405b7482f52SPhilipp Zabel 	{"Right ADC", "Line", "Right PGA"},
406b7482f52SPhilipp Zabel 
407b7482f52SPhilipp Zabel 	/* inputs */
408b7482f52SPhilipp Zabel 	{"Mic LNA", NULL, "VINM"},
409b7482f52SPhilipp Zabel 	{"Left PGA", NULL, "VINL"},
410b7482f52SPhilipp Zabel 	{"Right PGA", NULL, "VINR"},
411b7482f52SPhilipp Zabel };
412b7482f52SPhilipp Zabel 
413b7482f52SPhilipp Zabel static int uda1380_add_widgets(struct snd_soc_codec *codec)
414b7482f52SPhilipp Zabel {
415ce6120ccSLiam Girdwood 	struct snd_soc_dapm_context *dapm = &codec->dapm;
416b7482f52SPhilipp Zabel 
417ce6120ccSLiam Girdwood 	snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
418ce6120ccSLiam Girdwood 				  ARRAY_SIZE(uda1380_dapm_widgets));
419ce6120ccSLiam Girdwood 	snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
420b7482f52SPhilipp Zabel 
421b7482f52SPhilipp Zabel 	return 0;
422b7482f52SPhilipp Zabel }
423b7482f52SPhilipp Zabel 
4245b247442SPhilipp Zabel static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
425b7482f52SPhilipp Zabel 		unsigned int fmt)
426b7482f52SPhilipp Zabel {
427b7482f52SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
428b7482f52SPhilipp Zabel 	int iface;
429b7482f52SPhilipp Zabel 
430b7482f52SPhilipp Zabel 	/* set up DAI based upon fmt */
431b7482f52SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
432b7482f52SPhilipp Zabel 	iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK);
433b7482f52SPhilipp Zabel 
434b7482f52SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
435b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
436b7482f52SPhilipp Zabel 		iface |= R01_SFORI_I2S | R01_SFORO_I2S;
437b7482f52SPhilipp Zabel 		break;
438b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4395b247442SPhilipp Zabel 		iface |= R01_SFORI_LSB16 | R01_SFORO_LSB16;
440b7482f52SPhilipp Zabel 		break;
441b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4425b247442SPhilipp Zabel 		iface |= R01_SFORI_MSB | R01_SFORO_MSB;
4435b247442SPhilipp Zabel 	}
4445b247442SPhilipp Zabel 
4455f2a9384SPhilipp Zabel 	/* DATAI is slave only, so in single-link mode, this has to be slave */
4465f2a9384SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
4475f2a9384SPhilipp Zabel 		return -EINVAL;
4485b247442SPhilipp Zabel 
4495b247442SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
4505b247442SPhilipp Zabel 
4515b247442SPhilipp Zabel 	return 0;
4525b247442SPhilipp Zabel }
4535b247442SPhilipp Zabel 
4545b247442SPhilipp Zabel static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
4555b247442SPhilipp Zabel 		unsigned int fmt)
4565b247442SPhilipp Zabel {
4575b247442SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
4585b247442SPhilipp Zabel 	int iface;
4595b247442SPhilipp Zabel 
4605b247442SPhilipp Zabel 	/* set up DAI based upon fmt */
4615b247442SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
4625b247442SPhilipp Zabel 	iface &= ~R01_SFORI_MASK;
4635b247442SPhilipp Zabel 
4645b247442SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
4655b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
4665b247442SPhilipp Zabel 		iface |= R01_SFORI_I2S;
4675b247442SPhilipp Zabel 		break;
4685b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4695b247442SPhilipp Zabel 		iface |= R01_SFORI_LSB16;
4705b247442SPhilipp Zabel 		break;
4715b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4725b247442SPhilipp Zabel 		iface |= R01_SFORI_MSB;
4735b247442SPhilipp Zabel 	}
4745b247442SPhilipp Zabel 
4755f2a9384SPhilipp Zabel 	/* DATAI is slave only, so this has to be slave */
4765f2a9384SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
4775f2a9384SPhilipp Zabel 		return -EINVAL;
4785f2a9384SPhilipp Zabel 
4795b247442SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
4805b247442SPhilipp Zabel 
4815b247442SPhilipp Zabel 	return 0;
4825b247442SPhilipp Zabel }
4835b247442SPhilipp Zabel 
4845b247442SPhilipp Zabel static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
4855b247442SPhilipp Zabel 		unsigned int fmt)
4865b247442SPhilipp Zabel {
4875b247442SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
4885b247442SPhilipp Zabel 	int iface;
4895b247442SPhilipp Zabel 
4905b247442SPhilipp Zabel 	/* set up DAI based upon fmt */
4915b247442SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
4925b247442SPhilipp Zabel 	iface &= ~(R01_SIM | R01_SFORO_MASK);
4935b247442SPhilipp Zabel 
4945b247442SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
4955b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
4965b247442SPhilipp Zabel 		iface |= R01_SFORO_I2S;
4975b247442SPhilipp Zabel 		break;
4985b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4995b247442SPhilipp Zabel 		iface |= R01_SFORO_LSB16;
5005b247442SPhilipp Zabel 		break;
5015b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
5025b247442SPhilipp Zabel 		iface |= R01_SFORO_MSB;
503b7482f52SPhilipp Zabel 	}
504b7482f52SPhilipp Zabel 
505b7482f52SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
506b7482f52SPhilipp Zabel 		iface |= R01_SIM;
507b7482f52SPhilipp Zabel 
508b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
509b7482f52SPhilipp Zabel 
510b7482f52SPhilipp Zabel 	return 0;
511b7482f52SPhilipp Zabel }
512b7482f52SPhilipp Zabel 
513ef9e5e5cSPhilipp Zabel static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
514dee89c4dSMark Brown 		struct snd_soc_dai *dai)
515b7482f52SPhilipp Zabel {
516b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
517f0fba2adSLiam Girdwood 	struct snd_soc_codec *codec = rtd->codec;
518b2c812e2SMark Brown 	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
519ef9e5e5cSPhilipp Zabel 	int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
520b7482f52SPhilipp Zabel 
521ef9e5e5cSPhilipp Zabel 	switch (cmd) {
522ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_START:
523ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
524ef9e5e5cSPhilipp Zabel 		uda1380_write_reg_cache(codec, UDA1380_MIXER,
525ef9e5e5cSPhilipp Zabel 					mixer & ~R14_SILENCE);
5261abd9184SPhilipp Zabel 		schedule_work(&uda1380->work);
527ef9e5e5cSPhilipp Zabel 		break;
528ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_STOP:
529ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
530ef9e5e5cSPhilipp Zabel 		uda1380_write_reg_cache(codec, UDA1380_MIXER,
531ef9e5e5cSPhilipp Zabel 					mixer | R14_SILENCE);
5321abd9184SPhilipp Zabel 		schedule_work(&uda1380->work);
533ef9e5e5cSPhilipp Zabel 		break;
534b7482f52SPhilipp Zabel 	}
535b7482f52SPhilipp Zabel 	return 0;
536b7482f52SPhilipp Zabel }
537b7482f52SPhilipp Zabel 
538b7482f52SPhilipp Zabel static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
539dee89c4dSMark Brown 				 struct snd_pcm_hw_params *params,
540dee89c4dSMark Brown 				 struct snd_soc_dai *dai)
541b7482f52SPhilipp Zabel {
542b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
543f0fba2adSLiam Girdwood 	struct snd_soc_codec *codec = rtd->codec;
544b7482f52SPhilipp Zabel 	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
545b7482f52SPhilipp Zabel 
546b7482f52SPhilipp Zabel 	/* set WSPLL power and divider if running from this clock */
547b7482f52SPhilipp Zabel 	if (clk & R00_DAC_CLK) {
548b7482f52SPhilipp Zabel 		int rate = params_rate(params);
549b7482f52SPhilipp Zabel 		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
550b7482f52SPhilipp Zabel 		clk &= ~0x3; /* clear SEL_LOOP_DIV */
551b7482f52SPhilipp Zabel 		switch (rate) {
552b7482f52SPhilipp Zabel 		case 6250 ... 12500:
553b7482f52SPhilipp Zabel 			clk |= 0x0;
554b7482f52SPhilipp Zabel 			break;
555b7482f52SPhilipp Zabel 		case 12501 ... 25000:
556b7482f52SPhilipp Zabel 			clk |= 0x1;
557b7482f52SPhilipp Zabel 			break;
558b7482f52SPhilipp Zabel 		case 25001 ... 50000:
559b7482f52SPhilipp Zabel 			clk |= 0x2;
560b7482f52SPhilipp Zabel 			break;
561b7482f52SPhilipp Zabel 		case 50001 ... 100000:
562b7482f52SPhilipp Zabel 			clk |= 0x3;
563b7482f52SPhilipp Zabel 			break;
564b7482f52SPhilipp Zabel 		}
565b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_PLL | pm);
566b7482f52SPhilipp Zabel 	}
567b7482f52SPhilipp Zabel 
568b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
569b7482f52SPhilipp Zabel 		clk |= R00_EN_DAC | R00_EN_INT;
570b7482f52SPhilipp Zabel 	else
571b7482f52SPhilipp Zabel 		clk |= R00_EN_ADC | R00_EN_DEC;
572b7482f52SPhilipp Zabel 
573b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, clk);
574b7482f52SPhilipp Zabel 	return 0;
575b7482f52SPhilipp Zabel }
576b7482f52SPhilipp Zabel 
577dee89c4dSMark Brown static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
578dee89c4dSMark Brown 				 struct snd_soc_dai *dai)
579b7482f52SPhilipp Zabel {
580b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
581f0fba2adSLiam Girdwood 	struct snd_soc_codec *codec = rtd->codec;
582b7482f52SPhilipp Zabel 	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
583b7482f52SPhilipp Zabel 
584b7482f52SPhilipp Zabel 	/* shut down WSPLL power if running from this clock */
585b7482f52SPhilipp Zabel 	if (clk & R00_DAC_CLK) {
586b7482f52SPhilipp Zabel 		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
587b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, ~R02_PON_PLL & pm);
588b7482f52SPhilipp Zabel 	}
589b7482f52SPhilipp Zabel 
590b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
591b7482f52SPhilipp Zabel 		clk &= ~(R00_EN_DAC | R00_EN_INT);
592b7482f52SPhilipp Zabel 	else
593b7482f52SPhilipp Zabel 		clk &= ~(R00_EN_ADC | R00_EN_DEC);
594b7482f52SPhilipp Zabel 
595b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, clk);
596b7482f52SPhilipp Zabel }
597b7482f52SPhilipp Zabel 
598b7482f52SPhilipp Zabel static int uda1380_set_bias_level(struct snd_soc_codec *codec,
599b7482f52SPhilipp Zabel 	enum snd_soc_bias_level level)
600b7482f52SPhilipp Zabel {
601b7482f52SPhilipp Zabel 	int pm = uda1380_read_reg_cache(codec, UDA1380_PM);
6028614d310SVasily Khoruzhick 	int reg;
6038614d310SVasily Khoruzhick 	struct uda1380_platform_data *pdata = codec->dev->platform_data;
6048614d310SVasily Khoruzhick 
605ce6120ccSLiam Girdwood 	if (codec->dapm.bias_level == level)
6068614d310SVasily Khoruzhick 		return 0;
607b7482f52SPhilipp Zabel 
608b7482f52SPhilipp Zabel 	switch (level) {
609b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_ON:
610b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_PREPARE:
6118614d310SVasily Khoruzhick 		/* ADC, DAC on */
612b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
613b7482f52SPhilipp Zabel 		break;
614b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_STANDBY:
615ce6120ccSLiam Girdwood 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
6168614d310SVasily Khoruzhick 			if (gpio_is_valid(pdata->gpio_power)) {
6178614d310SVasily Khoruzhick 				gpio_set_value(pdata->gpio_power, 1);
6188e3dce4dSVasily Khoruzhick 				mdelay(1);
6198614d310SVasily Khoruzhick 				uda1380_reset(codec);
6208614d310SVasily Khoruzhick 			}
6218614d310SVasily Khoruzhick 
6228614d310SVasily Khoruzhick 			uda1380_sync_cache(codec);
6238614d310SVasily Khoruzhick 		}
624b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, 0x0);
625b7482f52SPhilipp Zabel 		break;
6268614d310SVasily Khoruzhick 	case SND_SOC_BIAS_OFF:
6278614d310SVasily Khoruzhick 		if (!gpio_is_valid(pdata->gpio_power))
6288614d310SVasily Khoruzhick 			break;
6298614d310SVasily Khoruzhick 
6308614d310SVasily Khoruzhick 		gpio_set_value(pdata->gpio_power, 0);
6318614d310SVasily Khoruzhick 
6328614d310SVasily Khoruzhick 		/* Mark mixer regs cache dirty to sync them with
6338614d310SVasily Khoruzhick 		 * codec regs on power on.
6348614d310SVasily Khoruzhick 		 */
6358614d310SVasily Khoruzhick 		for (reg = UDA1380_MVOL; reg < UDA1380_CACHEREGNUM; reg++)
6368614d310SVasily Khoruzhick 			set_bit(reg - 0x10, &uda1380_cache_dirty);
637b7482f52SPhilipp Zabel 	}
638ce6120ccSLiam Girdwood 	codec->dapm.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 
64685e7652dSLars-Peter Clausen static const 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 
65385e7652dSLars-Peter Clausen static const 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 
66085e7652dSLars-Peter Clausen static const 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 
70884b315eeSLars-Peter Clausen static int uda1380_suspend(struct snd_soc_codec *codec)
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 
7268614d310SVasily Khoruzhick 	uda1380->codec = codec;
727b7482f52SPhilipp Zabel 
7288614d310SVasily Khoruzhick 	codec->hw_write = (hw_write_t)i2c_master_send;
7298614d310SVasily Khoruzhick 	codec->control_data = uda1380->control_data;
7308614d310SVasily Khoruzhick 
7318614d310SVasily Khoruzhick 	if (!pdata)
732f0fba2adSLiam Girdwood 		return -EINVAL;
733ef9e5e5cSPhilipp Zabel 
7348614d310SVasily Khoruzhick 	if (gpio_is_valid(pdata->gpio_reset)) {
735*68020db8SAxel Lin 		ret = gpio_request_one(pdata->gpio_reset, GPIOF_OUT_INIT_LOW,
736*68020db8SAxel Lin 				       "uda1380 reset");
737f0fba2adSLiam Girdwood 		if (ret)
7388614d310SVasily Khoruzhick 			goto err_out;
7398614d310SVasily Khoruzhick 	}
7408614d310SVasily Khoruzhick 
7418614d310SVasily Khoruzhick 	if (gpio_is_valid(pdata->gpio_power)) {
742*68020db8SAxel Lin 		ret = gpio_request_one(pdata->gpio_power, GPIOF_OUT_INIT_LOW,
743*68020db8SAxel Lin 				   "uda1380 power");
7448614d310SVasily Khoruzhick 		if (ret)
745*68020db8SAxel Lin 			goto err_free_gpio;
7468614d310SVasily Khoruzhick 	} else {
747f0fba2adSLiam Girdwood 		ret = uda1380_reset(codec);
748*68020db8SAxel Lin 		if (ret)
749*68020db8SAxel Lin 			goto err_free_gpio;
7508614d310SVasily Khoruzhick 	}
751b7482f52SPhilipp Zabel 
752f0fba2adSLiam Girdwood 	INIT_WORK(&uda1380->work, uda1380_flush_work);
753f0fba2adSLiam Girdwood 
754b7482f52SPhilipp Zabel 	/* power on device */
755b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
756b7482f52SPhilipp Zabel 	/* set clock input */
7571abd9184SPhilipp Zabel 	switch (pdata->dac_clk) {
758b7482f52SPhilipp Zabel 	case UDA1380_DAC_CLK_SYSCLK:
7598614d310SVasily Khoruzhick 		uda1380_write_reg_cache(codec, UDA1380_CLK, 0);
760b7482f52SPhilipp Zabel 		break;
761b7482f52SPhilipp Zabel 	case UDA1380_DAC_CLK_WSPLL:
7628614d310SVasily Khoruzhick 		uda1380_write_reg_cache(codec, UDA1380_CLK,
7638614d310SVasily Khoruzhick 			R00_DAC_CLK);
764b7482f52SPhilipp Zabel 		break;
765b7482f52SPhilipp Zabel 	}
766b7482f52SPhilipp Zabel 
7673e8e1952SIan Molton 	snd_soc_add_controls(codec, uda1380_snd_controls,
7683e8e1952SIan Molton 				ARRAY_SIZE(uda1380_snd_controls));
769b7482f52SPhilipp Zabel 	uda1380_add_widgets(codec);
770b7482f52SPhilipp Zabel 
7711abd9184SPhilipp Zabel 	return 0;
7721abd9184SPhilipp Zabel 
773*68020db8SAxel Lin err_free_gpio:
7748614d310SVasily Khoruzhick 	if (gpio_is_valid(pdata->gpio_reset))
7758614d310SVasily Khoruzhick 		gpio_free(pdata->gpio_reset);
7768614d310SVasily Khoruzhick err_out:
7771abd9184SPhilipp Zabel 	return ret;
7781abd9184SPhilipp Zabel }
7791abd9184SPhilipp Zabel 
780f0fba2adSLiam Girdwood /* power down chip */
781f0fba2adSLiam Girdwood static int uda1380_remove(struct snd_soc_codec *codec)
7821abd9184SPhilipp Zabel {
7831abd9184SPhilipp Zabel 	struct uda1380_platform_data *pdata =codec->dev->platform_data;
7841abd9184SPhilipp Zabel 
785f0fba2adSLiam Girdwood 	uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
7861abd9184SPhilipp Zabel 
7871abd9184SPhilipp Zabel 	gpio_free(pdata->gpio_reset);
7881abd9184SPhilipp Zabel 	gpio_free(pdata->gpio_power);
7891abd9184SPhilipp Zabel 
790f0fba2adSLiam Girdwood 	return 0;
7911abd9184SPhilipp Zabel }
792b7482f52SPhilipp Zabel 
793f0fba2adSLiam Girdwood static struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
794f0fba2adSLiam Girdwood 	.probe =	uda1380_probe,
795f0fba2adSLiam Girdwood 	.remove =	uda1380_remove,
796f0fba2adSLiam Girdwood 	.suspend =	uda1380_suspend,
797f0fba2adSLiam Girdwood 	.resume =	uda1380_resume,
798f0fba2adSLiam Girdwood 	.read =		uda1380_read_reg_cache,
799f0fba2adSLiam Girdwood 	.write =	uda1380_write,
800f0fba2adSLiam Girdwood 	.set_bias_level = uda1380_set_bias_level,
801f0fba2adSLiam Girdwood 	.reg_cache_size = ARRAY_SIZE(uda1380_reg),
802f0fba2adSLiam Girdwood 	.reg_word_size = sizeof(u16),
803f0fba2adSLiam Girdwood 	.reg_cache_default = uda1380_reg,
804f0fba2adSLiam Girdwood 	.reg_cache_step = 1,
805f0fba2adSLiam Girdwood };
806f0fba2adSLiam Girdwood 
807b7482f52SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
8081abd9184SPhilipp Zabel static __devinit int uda1380_i2c_probe(struct i2c_client *i2c,
80988fc39d7SJean Delvare 				      const struct i2c_device_id *id)
810b7482f52SPhilipp Zabel {
8111abd9184SPhilipp Zabel 	struct uda1380_priv *uda1380;
812b7482f52SPhilipp Zabel 	int ret;
813b7482f52SPhilipp Zabel 
8141abd9184SPhilipp Zabel 	uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL);
8151abd9184SPhilipp Zabel 	if (uda1380 == NULL)
8161abd9184SPhilipp Zabel 		return -ENOMEM;
8171abd9184SPhilipp Zabel 
8181abd9184SPhilipp Zabel 	i2c_set_clientdata(i2c, uda1380);
8198614d310SVasily Khoruzhick 	uda1380->control_data = i2c;
820b7482f52SPhilipp Zabel 
821f0fba2adSLiam Girdwood 	ret =  snd_soc_register_codec(&i2c->dev,
822f0fba2adSLiam Girdwood 			&soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
823f0fba2adSLiam Girdwood 	if (ret < 0)
8241abd9184SPhilipp Zabel 		kfree(uda1380);
825b7482f52SPhilipp Zabel 	return ret;
826b7482f52SPhilipp Zabel }
827b7482f52SPhilipp Zabel 
8281abd9184SPhilipp Zabel static int __devexit uda1380_i2c_remove(struct i2c_client *i2c)
829b7482f52SPhilipp Zabel {
830f0fba2adSLiam Girdwood 	snd_soc_unregister_codec(&i2c->dev);
831f0fba2adSLiam Girdwood 	kfree(i2c_get_clientdata(i2c));
832b7482f52SPhilipp Zabel 	return 0;
833b7482f52SPhilipp Zabel }
834b7482f52SPhilipp Zabel 
83588fc39d7SJean Delvare static const struct i2c_device_id uda1380_i2c_id[] = {
83688fc39d7SJean Delvare 	{ "uda1380", 0 },
83788fc39d7SJean Delvare 	{ }
83888fc39d7SJean Delvare };
83988fc39d7SJean Delvare MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
840b7482f52SPhilipp Zabel 
841b7482f52SPhilipp Zabel static struct i2c_driver uda1380_i2c_driver = {
842b7482f52SPhilipp Zabel 	.driver = {
843f0fba2adSLiam Girdwood 		.name =  "uda1380-codec",
844b7482f52SPhilipp Zabel 		.owner = THIS_MODULE,
845b7482f52SPhilipp Zabel 	},
84688fc39d7SJean Delvare 	.probe =    uda1380_i2c_probe,
8471abd9184SPhilipp Zabel 	.remove =   __devexit_p(uda1380_i2c_remove),
84888fc39d7SJean Delvare 	.id_table = uda1380_i2c_id,
849b7482f52SPhilipp Zabel };
850b7482f52SPhilipp Zabel #endif
851b7482f52SPhilipp Zabel 
852c9b3a40fSTakashi Iwai static int __init uda1380_modinit(void)
85364089b84SMark Brown {
854ef149770SAxel Lin 	int ret = 0;
8551abd9184SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
8561abd9184SPhilipp Zabel 	ret = i2c_add_driver(&uda1380_i2c_driver);
8571abd9184SPhilipp Zabel 	if (ret != 0)
8581abd9184SPhilipp Zabel 		pr_err("Failed to register UDA1380 I2C driver: %d\n", ret);
8591abd9184SPhilipp Zabel #endif
860ef149770SAxel Lin 	return ret;
86164089b84SMark Brown }
86264089b84SMark Brown module_init(uda1380_modinit);
86364089b84SMark Brown 
86464089b84SMark Brown static void __exit uda1380_exit(void)
86564089b84SMark Brown {
8661abd9184SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
8671abd9184SPhilipp Zabel 	i2c_del_driver(&uda1380_i2c_driver);
8681abd9184SPhilipp Zabel #endif
86964089b84SMark Brown }
87064089b84SMark Brown module_exit(uda1380_exit);
87164089b84SMark Brown 
872b7482f52SPhilipp Zabel MODULE_AUTHOR("Giorgio Padrin");
873b7482f52SPhilipp Zabel MODULE_DESCRIPTION("Audio support for codec Philips UDA1380");
874b7482f52SPhilipp Zabel MODULE_LICENSE("GPL");
875