xref: /linux/sound/soc/codecs/uda1380.c (revision 7604d8068e6253c143b27ce7e164ee8e7a9da5b9)
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;
40eaa53216SKuninori Morimoto 	struct i2c_client *i2c;
41c001bf63SKuninori Morimoto 	u16 *reg_cache;
421abd9184SPhilipp Zabel };
431abd9184SPhilipp Zabel 
44b7482f52SPhilipp Zabel /*
45b7482f52SPhilipp Zabel  * uda1380 register cache
46b7482f52SPhilipp Zabel  */
47b7482f52SPhilipp Zabel static const u16 uda1380_reg[UDA1380_CACHEREGNUM] = {
48b7482f52SPhilipp Zabel 	0x0502, 0x0000, 0x0000, 0x3f3f,
49b7482f52SPhilipp Zabel 	0x0202, 0x0000, 0x0000, 0x0000,
50b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
51b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
52b7482f52SPhilipp Zabel 	0x0000, 0xff00, 0x0000, 0x4800,
53b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
54b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
55b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
56b7482f52SPhilipp Zabel 	0x0000, 0x8000, 0x0002, 0x0000,
57b7482f52SPhilipp Zabel };
58b7482f52SPhilipp Zabel 
59ef9e5e5cSPhilipp Zabel static unsigned long uda1380_cache_dirty;
60ef9e5e5cSPhilipp Zabel 
61b7482f52SPhilipp Zabel /*
62b7482f52SPhilipp Zabel  * read uda1380 register cache
63b7482f52SPhilipp Zabel  */
64b7482f52SPhilipp Zabel static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec,
65b7482f52SPhilipp Zabel 	unsigned int reg)
66b7482f52SPhilipp Zabel {
67c001bf63SKuninori Morimoto 	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
68c001bf63SKuninori Morimoto 	u16 *cache = uda1380->reg_cache;
69c001bf63SKuninori Morimoto 
70b7482f52SPhilipp Zabel 	if (reg == UDA1380_RESET)
71b7482f52SPhilipp Zabel 		return 0;
72b7482f52SPhilipp Zabel 	if (reg >= UDA1380_CACHEREGNUM)
73b7482f52SPhilipp Zabel 		return -1;
74b7482f52SPhilipp Zabel 	return cache[reg];
75b7482f52SPhilipp Zabel }
76b7482f52SPhilipp Zabel 
77b7482f52SPhilipp Zabel /*
78b7482f52SPhilipp Zabel  * write uda1380 register cache
79b7482f52SPhilipp Zabel  */
80b7482f52SPhilipp Zabel static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
81b7482f52SPhilipp Zabel 	u16 reg, unsigned int value)
82b7482f52SPhilipp Zabel {
83c001bf63SKuninori Morimoto 	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
84c001bf63SKuninori Morimoto 	u16 *cache = uda1380->reg_cache;
85ef9e5e5cSPhilipp Zabel 
86b7482f52SPhilipp Zabel 	if (reg >= UDA1380_CACHEREGNUM)
87b7482f52SPhilipp Zabel 		return;
88ef9e5e5cSPhilipp Zabel 	if ((reg >= 0x10) && (cache[reg] != value))
89ef9e5e5cSPhilipp Zabel 		set_bit(reg - 0x10, &uda1380_cache_dirty);
90b7482f52SPhilipp Zabel 	cache[reg] = value;
91b7482f52SPhilipp Zabel }
92b7482f52SPhilipp Zabel 
93b7482f52SPhilipp Zabel /*
94b7482f52SPhilipp Zabel  * write to the UDA1380 register space
95b7482f52SPhilipp Zabel  */
96b7482f52SPhilipp Zabel static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
97b7482f52SPhilipp Zabel 	unsigned int value)
98b7482f52SPhilipp Zabel {
99eaa53216SKuninori Morimoto 	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
100b7482f52SPhilipp Zabel 	u8 data[3];
101b7482f52SPhilipp Zabel 
102b7482f52SPhilipp Zabel 	/* data is
103b7482f52SPhilipp Zabel 	 *   data[0] is register offset
104b7482f52SPhilipp Zabel 	 *   data[1] is MS byte
105b7482f52SPhilipp Zabel 	 *   data[2] is LS byte
106b7482f52SPhilipp Zabel 	 */
107b7482f52SPhilipp Zabel 	data[0] = reg;
108b7482f52SPhilipp Zabel 	data[1] = (value & 0xff00) >> 8;
109b7482f52SPhilipp Zabel 	data[2] = value & 0x00ff;
110b7482f52SPhilipp Zabel 
111b7482f52SPhilipp Zabel 	uda1380_write_reg_cache(codec, reg, value);
112b7482f52SPhilipp Zabel 
113b7482f52SPhilipp Zabel 	/* the interpolator & decimator regs must only be written when the
114b7482f52SPhilipp Zabel 	 * codec DAI is active.
115b7482f52SPhilipp Zabel 	 */
1165c898e74SLars-Peter Clausen 	if (!snd_soc_codec_is_active(codec) && (reg >= UDA1380_MVOL))
117b7482f52SPhilipp Zabel 		return 0;
118b7482f52SPhilipp Zabel 	pr_debug("uda1380: hw write %x val %x\n", reg, value);
119eaa53216SKuninori Morimoto 	if (i2c_master_send(uda1380->i2c, data, 3) == 3) {
120b7482f52SPhilipp Zabel 		unsigned int val;
121eaa53216SKuninori Morimoto 		i2c_master_send(uda1380->i2c, data, 1);
122eaa53216SKuninori Morimoto 		i2c_master_recv(uda1380->i2c, data, 2);
123b7482f52SPhilipp Zabel 		val = (data[0]<<8) | data[1];
124b7482f52SPhilipp Zabel 		if (val != value) {
125b7482f52SPhilipp Zabel 			pr_debug("uda1380: READ BACK VAL %x\n",
126b7482f52SPhilipp Zabel 					(data[0]<<8) | data[1]);
127b7482f52SPhilipp Zabel 			return -EIO;
128b7482f52SPhilipp Zabel 		}
129ef9e5e5cSPhilipp Zabel 		if (reg >= 0x10)
130ef9e5e5cSPhilipp Zabel 			clear_bit(reg - 0x10, &uda1380_cache_dirty);
131b7482f52SPhilipp Zabel 		return 0;
132b7482f52SPhilipp Zabel 	} else
133b7482f52SPhilipp Zabel 		return -EIO;
134b7482f52SPhilipp Zabel }
135b7482f52SPhilipp Zabel 
1368614d310SVasily Khoruzhick static void uda1380_sync_cache(struct snd_soc_codec *codec)
1378614d310SVasily Khoruzhick {
138eaa53216SKuninori Morimoto 	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
1398614d310SVasily Khoruzhick 	int reg;
1408614d310SVasily Khoruzhick 	u8 data[3];
141c001bf63SKuninori Morimoto 	u16 *cache = uda1380->reg_cache;
1428614d310SVasily Khoruzhick 
1438614d310SVasily Khoruzhick 	/* Sync reg_cache with the hardware */
1448614d310SVasily Khoruzhick 	for (reg = 0; reg < UDA1380_MVOL; reg++) {
1458614d310SVasily Khoruzhick 		data[0] = reg;
1468614d310SVasily Khoruzhick 		data[1] = (cache[reg] & 0xff00) >> 8;
1478614d310SVasily Khoruzhick 		data[2] = cache[reg] & 0x00ff;
148eaa53216SKuninori Morimoto 		if (i2c_master_send(uda1380->i2c, data, 3) != 3)
1498614d310SVasily Khoruzhick 			dev_err(codec->dev, "%s: write to reg 0x%x failed\n",
1508614d310SVasily Khoruzhick 				__func__, reg);
1518614d310SVasily Khoruzhick 	}
1528614d310SVasily Khoruzhick }
1538614d310SVasily Khoruzhick 
1548614d310SVasily Khoruzhick static int uda1380_reset(struct snd_soc_codec *codec)
1558614d310SVasily Khoruzhick {
1568614d310SVasily Khoruzhick 	struct uda1380_platform_data *pdata = codec->dev->platform_data;
157eaa53216SKuninori Morimoto 	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
1588614d310SVasily Khoruzhick 
1598614d310SVasily Khoruzhick 	if (gpio_is_valid(pdata->gpio_reset)) {
1608614d310SVasily Khoruzhick 		gpio_set_value(pdata->gpio_reset, 1);
1618614d310SVasily Khoruzhick 		mdelay(1);
1628614d310SVasily Khoruzhick 		gpio_set_value(pdata->gpio_reset, 0);
1638614d310SVasily Khoruzhick 	} else {
1648614d310SVasily Khoruzhick 		u8 data[3];
1658614d310SVasily Khoruzhick 
1668614d310SVasily Khoruzhick 		data[0] = UDA1380_RESET;
1678614d310SVasily Khoruzhick 		data[1] = 0;
1688614d310SVasily Khoruzhick 		data[2] = 0;
1698614d310SVasily Khoruzhick 
170eaa53216SKuninori Morimoto 		if (i2c_master_send(uda1380->i2c, data, 3) != 3) {
1718614d310SVasily Khoruzhick 			dev_err(codec->dev, "%s: failed\n", __func__);
1728614d310SVasily Khoruzhick 			return -EIO;
1738614d310SVasily Khoruzhick 		}
1748614d310SVasily Khoruzhick 	}
1758614d310SVasily Khoruzhick 
1768614d310SVasily Khoruzhick 	return 0;
1778614d310SVasily Khoruzhick }
178b7482f52SPhilipp Zabel 
179ef9e5e5cSPhilipp Zabel static void uda1380_flush_work(struct work_struct *work)
180ef9e5e5cSPhilipp Zabel {
181f0fba2adSLiam Girdwood 	struct uda1380_priv *uda1380 = container_of(work, struct uda1380_priv, work);
182f0fba2adSLiam Girdwood 	struct snd_soc_codec *uda1380_codec = uda1380->codec;
183ef9e5e5cSPhilipp Zabel 	int bit, reg;
184ef9e5e5cSPhilipp Zabel 
185984b3f57SAkinobu Mita 	for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
186ef9e5e5cSPhilipp Zabel 		reg = 0x10 + bit;
187ef9e5e5cSPhilipp Zabel 		pr_debug("uda1380: flush reg %x val %x:\n", reg,
188ef9e5e5cSPhilipp Zabel 				uda1380_read_reg_cache(uda1380_codec, reg));
189ef9e5e5cSPhilipp Zabel 		uda1380_write(uda1380_codec, reg,
190ef9e5e5cSPhilipp Zabel 				uda1380_read_reg_cache(uda1380_codec, reg));
191ef9e5e5cSPhilipp Zabel 		clear_bit(bit, &uda1380_cache_dirty);
192ef9e5e5cSPhilipp Zabel 	}
193f0fba2adSLiam Girdwood 
194ef9e5e5cSPhilipp Zabel }
195ef9e5e5cSPhilipp Zabel 
196b7482f52SPhilipp Zabel /* declarations of ALSA reg_elem_REAL controls */
197b7482f52SPhilipp Zabel static const char *uda1380_deemp[] = {
198b7482f52SPhilipp Zabel 	"None",
199b7482f52SPhilipp Zabel 	"32kHz",
200b7482f52SPhilipp Zabel 	"44.1kHz",
201b7482f52SPhilipp Zabel 	"48kHz",
202b7482f52SPhilipp Zabel 	"96kHz",
203b7482f52SPhilipp Zabel };
204b7482f52SPhilipp Zabel static const char *uda1380_input_sel[] = {
205b7482f52SPhilipp Zabel 	"Line",
206b7482f52SPhilipp Zabel 	"Mic + Line R",
207b7482f52SPhilipp Zabel 	"Line L",
208b7482f52SPhilipp Zabel 	"Mic",
209b7482f52SPhilipp Zabel };
210b7482f52SPhilipp Zabel static const char *uda1380_output_sel[] = {
211b7482f52SPhilipp Zabel 	"DAC",
212b7482f52SPhilipp Zabel 	"Analog Mixer",
213b7482f52SPhilipp Zabel };
214b7482f52SPhilipp Zabel static const char *uda1380_spf_mode[] = {
215b7482f52SPhilipp Zabel 	"Flat",
216b7482f52SPhilipp Zabel 	"Minimum1",
217b7482f52SPhilipp Zabel 	"Minimum2",
218b7482f52SPhilipp Zabel 	"Maximum"
219b7482f52SPhilipp Zabel };
220b7482f52SPhilipp Zabel static const char *uda1380_capture_sel[] = {
221b7482f52SPhilipp Zabel 	"ADC",
222b7482f52SPhilipp Zabel 	"Digital Mixer"
223b7482f52SPhilipp Zabel };
224b7482f52SPhilipp Zabel static const char *uda1380_sel_ns[] = {
225b7482f52SPhilipp Zabel 	"3rd-order",
226b7482f52SPhilipp Zabel 	"5th-order"
227b7482f52SPhilipp Zabel };
228b7482f52SPhilipp Zabel static const char *uda1380_mix_control[] = {
229b7482f52SPhilipp Zabel 	"off",
230b7482f52SPhilipp Zabel 	"PCM only",
231b7482f52SPhilipp Zabel 	"before sound processing",
232b7482f52SPhilipp Zabel 	"after sound processing"
233b7482f52SPhilipp Zabel };
234b7482f52SPhilipp Zabel static const char *uda1380_sdet_setting[] = {
235b7482f52SPhilipp Zabel 	"3200",
236b7482f52SPhilipp Zabel 	"4800",
237b7482f52SPhilipp Zabel 	"9600",
238b7482f52SPhilipp Zabel 	"19200"
239b7482f52SPhilipp Zabel };
240b7482f52SPhilipp Zabel static const char *uda1380_os_setting[] = {
241b7482f52SPhilipp Zabel 	"single-speed",
242b7482f52SPhilipp Zabel 	"double-speed (no mixing)",
243b7482f52SPhilipp Zabel 	"quad-speed (no mixing)"
244b7482f52SPhilipp Zabel };
245b7482f52SPhilipp Zabel 
246b7482f52SPhilipp Zabel static const struct soc_enum uda1380_deemp_enum[] = {
2471dbb348dSTakashi Iwai 	SOC_ENUM_SINGLE(UDA1380_DEEMP, 8, ARRAY_SIZE(uda1380_deemp),
2481dbb348dSTakashi Iwai 			uda1380_deemp),
2491dbb348dSTakashi Iwai 	SOC_ENUM_SINGLE(UDA1380_DEEMP, 0, ARRAY_SIZE(uda1380_deemp),
2501dbb348dSTakashi Iwai 			uda1380_deemp),
251b7482f52SPhilipp Zabel };
2521dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_input_sel_enum,
2531dbb348dSTakashi Iwai 			    UDA1380_ADC, 2, uda1380_input_sel);		/* SEL_MIC, SEL_LNA */
2541dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_output_sel_enum,
2551dbb348dSTakashi Iwai 			    UDA1380_PM, 7, uda1380_output_sel);		/* R02_EN_AVC */
2561dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_spf_enum,
2571dbb348dSTakashi Iwai 			    UDA1380_MODE, 14, uda1380_spf_mode);		/* M */
2581dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_capture_sel_enum,
2591dbb348dSTakashi Iwai 			    UDA1380_IFACE, 6, uda1380_capture_sel);	/* SEL_SOURCE */
2601dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_sel_ns_enum,
2611dbb348dSTakashi Iwai 			    UDA1380_MIXER, 14, uda1380_sel_ns);		/* SEL_NS */
2621dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_mix_enum,
2631dbb348dSTakashi Iwai 			    UDA1380_MIXER, 12, uda1380_mix_control);	/* MIX, MIX_POS */
2641dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_sdet_enum,
2651dbb348dSTakashi Iwai 			    UDA1380_MIXER, 4, uda1380_sdet_setting);	/* SD_VALUE */
2661dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_os_enum,
2671dbb348dSTakashi Iwai 			    UDA1380_MIXER, 0, uda1380_os_setting);	/* OS */
268b7482f52SPhilipp Zabel 
269b7482f52SPhilipp Zabel /*
270b7482f52SPhilipp Zabel  * from -48 dB in 1.5 dB steps (mute instead of -49.5 dB)
271b7482f52SPhilipp Zabel  */
272b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(amix_tlv, -4950, 150, 1);
273b7482f52SPhilipp Zabel 
274b7482f52SPhilipp Zabel /*
275b7482f52SPhilipp Zabel  * from -78 dB in 1 dB steps (3 dB steps, really. LSB are ignored),
276b7482f52SPhilipp Zabel  * from -66 dB in 0.5 dB steps (2 dB steps, really) and
277b7482f52SPhilipp Zabel  * from -52 dB in 0.25 dB steps
278b7482f52SPhilipp Zabel  */
2795ee0b8f8SLars-Peter Clausen static const DECLARE_TLV_DB_RANGE(mvol_tlv,
280b7482f52SPhilipp Zabel 	0, 15, TLV_DB_SCALE_ITEM(-8200, 100, 1),
281b7482f52SPhilipp Zabel 	16, 43, TLV_DB_SCALE_ITEM(-6600, 50, 0),
2825ee0b8f8SLars-Peter Clausen 	44, 252, TLV_DB_SCALE_ITEM(-5200, 25, 0)
2835ee0b8f8SLars-Peter Clausen );
284b7482f52SPhilipp Zabel 
285b7482f52SPhilipp Zabel /*
286b7482f52SPhilipp Zabel  * from -72 dB in 1.5 dB steps (6 dB steps really),
287b7482f52SPhilipp Zabel  * from -66 dB in 0.75 dB steps (3 dB steps really),
288b7482f52SPhilipp Zabel  * from -60 dB in 0.5 dB steps (2 dB steps really) and
289b7482f52SPhilipp Zabel  * from -46 dB in 0.25 dB steps
290b7482f52SPhilipp Zabel  */
2915ee0b8f8SLars-Peter Clausen static const DECLARE_TLV_DB_RANGE(vc_tlv,
292b7482f52SPhilipp Zabel 	0, 7, TLV_DB_SCALE_ITEM(-7800, 150, 1),
293b7482f52SPhilipp Zabel 	8, 15, TLV_DB_SCALE_ITEM(-6600, 75, 0),
294b7482f52SPhilipp Zabel 	16, 43, TLV_DB_SCALE_ITEM(-6000, 50, 0),
2955ee0b8f8SLars-Peter Clausen 	44, 228, TLV_DB_SCALE_ITEM(-4600, 25, 0)
2965ee0b8f8SLars-Peter Clausen );
297b7482f52SPhilipp Zabel 
298b7482f52SPhilipp Zabel /* from 0 to 6 dB in 2 dB steps if SPF mode != flat */
299b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(tr_tlv, 0, 200, 0);
300b7482f52SPhilipp Zabel 
301b7482f52SPhilipp Zabel /* from 0 to 24 dB in 2 dB steps, if SPF mode == maximum, otherwise cuts
302b7482f52SPhilipp Zabel  * off at 18 dB max) */
303b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(bb_tlv, 0, 200, 0);
304b7482f52SPhilipp Zabel 
305b7482f52SPhilipp Zabel /* from -63 to 24 dB in 0.5 dB steps (-128...48) */
306b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(dec_tlv, -6400, 50, 1);
307b7482f52SPhilipp Zabel 
308b7482f52SPhilipp Zabel /* from 0 to 24 dB in 3 dB steps */
309b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0);
310b7482f52SPhilipp Zabel 
311b7482f52SPhilipp Zabel /* from 0 to 30 dB in 2 dB steps */
312b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(vga_tlv, 0, 200, 0);
313b7482f52SPhilipp Zabel 
314b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_snd_controls[] = {
315b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Analog Mixer Volume", UDA1380_AMIX, 0, 8, 44, 1, amix_tlv),	/* AVCR, AVCL */
316b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Master Playback Volume", UDA1380_MVOL, 0, 8, 252, 1, mvol_tlv),	/* MVCL, MVCR */
317b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("ADC Playback Volume", UDA1380_MIXVOL, 8, 228, 1, vc_tlv),	/* VC2 */
318b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("PCM Playback Volume", UDA1380_MIXVOL, 0, 228, 1, vc_tlv),	/* VC1 */
319b7482f52SPhilipp Zabel 	SOC_ENUM("Sound Processing Filter", uda1380_spf_enum),				/* M */
320b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Tone Control - Treble", UDA1380_MODE, 4, 12, 3, 0, tr_tlv), 	/* TRL, TRR */
321b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Tone Control - Bass", UDA1380_MODE, 0, 8, 15, 0, bb_tlv),	/* BBL, BBR */
322b7482f52SPhilipp Zabel /**/	SOC_SINGLE("Master Playback Switch", UDA1380_DEEMP, 14, 1, 1),		/* MTM */
323b7482f52SPhilipp Zabel 	SOC_SINGLE("ADC Playback Switch", UDA1380_DEEMP, 11, 1, 1),		/* MT2 from decimation filter */
324b7482f52SPhilipp Zabel 	SOC_ENUM("ADC Playback De-emphasis", uda1380_deemp_enum[0]),		/* DE2 */
325b7482f52SPhilipp Zabel 	SOC_SINGLE("PCM Playback Switch", UDA1380_DEEMP, 3, 1, 1),		/* MT1, from digital data input */
326b7482f52SPhilipp Zabel 	SOC_ENUM("PCM Playback De-emphasis", uda1380_deemp_enum[1]),		/* DE1 */
327b7482f52SPhilipp Zabel 	SOC_SINGLE("DAC Polarity inverting Switch", UDA1380_MIXER, 15, 1, 0),	/* DA_POL_INV */
328b7482f52SPhilipp Zabel 	SOC_ENUM("Noise Shaper", uda1380_sel_ns_enum),				/* SEL_NS */
329b7482f52SPhilipp Zabel 	SOC_ENUM("Digital Mixer Signal Control", uda1380_mix_enum),		/* MIX_POS, MIX */
330b7482f52SPhilipp Zabel 	SOC_SINGLE("Silence Detector Switch", UDA1380_MIXER, 6, 1, 0),		/* SDET_ON */
331b7482f52SPhilipp Zabel 	SOC_ENUM("Silence Detector Setting", uda1380_sdet_enum),		/* SD_VALUE */
332b7482f52SPhilipp Zabel 	SOC_ENUM("Oversampling Input", uda1380_os_enum),			/* OS */
333b7482f52SPhilipp Zabel 	SOC_DOUBLE_S8_TLV("ADC Capture Volume", UDA1380_DEC, -128, 48, dec_tlv),	/* ML_DEC, MR_DEC */
334b7482f52SPhilipp Zabel /**/	SOC_SINGLE("ADC Capture Switch", UDA1380_PGA, 15, 1, 1),		/* MT_ADC */
335b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Line Capture Volume", UDA1380_PGA, 0, 8, 8, 0, pga_tlv), /* PGA_GAINCTRLL, PGA_GAINCTRLR */
336b7482f52SPhilipp Zabel 	SOC_SINGLE("ADC Polarity inverting Switch", UDA1380_ADC, 12, 1, 0),	/* ADCPOL_INV */
337b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("Mic Capture Volume", UDA1380_ADC, 8, 15, 0, vga_tlv),	/* VGA_CTRL */
338b7482f52SPhilipp Zabel 	SOC_SINGLE("DC Filter Bypass Switch", UDA1380_ADC, 1, 1, 0),		/* SKIP_DCFIL (before decimator) */
339b7482f52SPhilipp Zabel 	SOC_SINGLE("DC Filter Enable Switch", UDA1380_ADC, 0, 1, 0),		/* EN_DCFIL (at output of decimator) */
340b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Timing", UDA1380_AGC, 8, 7, 0),			/* TODO: enum, see table 62 */
341b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Target level", UDA1380_AGC, 2, 3, 1),			/* AGC_LEVEL */
342b7482f52SPhilipp Zabel 	/* -5.5, -8, -11.5, -14 dBFS */
343b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0),
344b7482f52SPhilipp Zabel };
345b7482f52SPhilipp Zabel 
346b7482f52SPhilipp Zabel /* Input mux */
347b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_input_mux_control =
348b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_input_sel_enum);
349b7482f52SPhilipp Zabel 
350b7482f52SPhilipp Zabel /* Output mux */
351b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_output_mux_control =
352b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_output_sel_enum);
353b7482f52SPhilipp Zabel 
354b7482f52SPhilipp Zabel /* Capture mux */
355b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_capture_mux_control =
356b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_capture_sel_enum);
357b7482f52SPhilipp Zabel 
358b7482f52SPhilipp Zabel 
359b7482f52SPhilipp Zabel static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
360b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
361b7482f52SPhilipp Zabel 		&uda1380_input_mux_control),
362b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM, 0, 0,
363b7482f52SPhilipp Zabel 		&uda1380_output_mux_control),
364b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0,
365b7482f52SPhilipp Zabel 		&uda1380_capture_mux_control),
366b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Left PGA", UDA1380_PM, 3, 0, NULL, 0),
367b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Right PGA", UDA1380_PM, 1, 0, NULL, 0),
368b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Mic LNA", UDA1380_PM, 4, 0, NULL, 0),
369b7482f52SPhilipp Zabel 	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", UDA1380_PM, 2, 0),
370b7482f52SPhilipp Zabel 	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", UDA1380_PM, 0, 0),
371b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINM"),
372b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINL"),
373b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINR"),
374b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MIXER("Analog Mixer", UDA1380_PM, 6, 0, NULL, 0),
375b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTLHP"),
376b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTRHP"),
377b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTL"),
378b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTR"),
379b7482f52SPhilipp Zabel 	SND_SOC_DAPM_DAC("DAC", "Playback", UDA1380_PM, 10, 0),
380b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("HeadPhone Driver", UDA1380_PM, 13, 0, NULL, 0),
381b7482f52SPhilipp Zabel };
382b7482f52SPhilipp Zabel 
38358fa8e45SAxel Lin static const struct snd_soc_dapm_route uda1380_dapm_routes[] = {
384b7482f52SPhilipp Zabel 
385b7482f52SPhilipp Zabel 	/* output mux */
386b7482f52SPhilipp Zabel 	{"HeadPhone Driver", NULL, "Output Mux"},
387b7482f52SPhilipp Zabel 	{"VOUTR", NULL, "Output Mux"},
388b7482f52SPhilipp Zabel 	{"VOUTL", NULL, "Output Mux"},
389b7482f52SPhilipp Zabel 
390b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "VINR"},
391b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "VINL"},
392b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "DAC"},
393b7482f52SPhilipp Zabel 
394b7482f52SPhilipp Zabel 	{"Output Mux", "DAC", "DAC"},
395b7482f52SPhilipp Zabel 	{"Output Mux", "Analog Mixer", "Analog Mixer"},
396b7482f52SPhilipp Zabel 
397b7482f52SPhilipp Zabel 	/* {"DAC", "Digital Mixer", "I2S" } */
398b7482f52SPhilipp Zabel 
399b7482f52SPhilipp Zabel 	/* headphone driver */
400b7482f52SPhilipp Zabel 	{"VOUTLHP", NULL, "HeadPhone Driver"},
401b7482f52SPhilipp Zabel 	{"VOUTRHP", NULL, "HeadPhone Driver"},
402b7482f52SPhilipp Zabel 
403b7482f52SPhilipp Zabel 	/* input mux */
404b7482f52SPhilipp Zabel 	{"Left ADC", NULL, "Input Mux"},
405b7482f52SPhilipp Zabel 	{"Input Mux", "Mic", "Mic LNA"},
406b7482f52SPhilipp Zabel 	{"Input Mux", "Mic + Line R", "Mic LNA"},
407b7482f52SPhilipp Zabel 	{"Input Mux", "Line L", "Left PGA"},
408b7482f52SPhilipp Zabel 	{"Input Mux", "Line", "Left PGA"},
409b7482f52SPhilipp Zabel 
410b7482f52SPhilipp Zabel 	/* right input */
411b7482f52SPhilipp Zabel 	{"Right ADC", "Mic + Line R", "Right PGA"},
412b7482f52SPhilipp Zabel 	{"Right ADC", "Line", "Right PGA"},
413b7482f52SPhilipp Zabel 
414b7482f52SPhilipp Zabel 	/* inputs */
415b7482f52SPhilipp Zabel 	{"Mic LNA", NULL, "VINM"},
416b7482f52SPhilipp Zabel 	{"Left PGA", NULL, "VINL"},
417b7482f52SPhilipp Zabel 	{"Right PGA", NULL, "VINR"},
418b7482f52SPhilipp Zabel };
419b7482f52SPhilipp Zabel 
4205b247442SPhilipp Zabel static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
421b7482f52SPhilipp Zabel 		unsigned int fmt)
422b7482f52SPhilipp Zabel {
423b7482f52SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
424b7482f52SPhilipp Zabel 	int iface;
425b7482f52SPhilipp Zabel 
426b7482f52SPhilipp Zabel 	/* set up DAI based upon fmt */
427b7482f52SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
428b7482f52SPhilipp Zabel 	iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK);
429b7482f52SPhilipp Zabel 
430b7482f52SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
431b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
432b7482f52SPhilipp Zabel 		iface |= R01_SFORI_I2S | R01_SFORO_I2S;
433b7482f52SPhilipp Zabel 		break;
434b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4355b247442SPhilipp Zabel 		iface |= R01_SFORI_LSB16 | R01_SFORO_LSB16;
436b7482f52SPhilipp Zabel 		break;
437b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4385b247442SPhilipp Zabel 		iface |= R01_SFORI_MSB | R01_SFORO_MSB;
4395b247442SPhilipp Zabel 	}
4405b247442SPhilipp Zabel 
4415f2a9384SPhilipp Zabel 	/* DATAI is slave only, so in single-link mode, this has to be slave */
4425f2a9384SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
4435f2a9384SPhilipp Zabel 		return -EINVAL;
4445b247442SPhilipp Zabel 
445810e4425SVasily Khoruzhick 	uda1380_write_reg_cache(codec, UDA1380_IFACE, iface);
4465b247442SPhilipp Zabel 
4475b247442SPhilipp Zabel 	return 0;
4485b247442SPhilipp Zabel }
4495b247442SPhilipp Zabel 
4505b247442SPhilipp Zabel static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
4515b247442SPhilipp Zabel 		unsigned int fmt)
4525b247442SPhilipp Zabel {
4535b247442SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
4545b247442SPhilipp Zabel 	int iface;
4555b247442SPhilipp Zabel 
4565b247442SPhilipp Zabel 	/* set up DAI based upon fmt */
4575b247442SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
4585b247442SPhilipp Zabel 	iface &= ~R01_SFORI_MASK;
4595b247442SPhilipp Zabel 
4605b247442SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
4615b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
4625b247442SPhilipp Zabel 		iface |= R01_SFORI_I2S;
4635b247442SPhilipp Zabel 		break;
4645b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4655b247442SPhilipp Zabel 		iface |= R01_SFORI_LSB16;
4665b247442SPhilipp Zabel 		break;
4675b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4685b247442SPhilipp Zabel 		iface |= R01_SFORI_MSB;
4695b247442SPhilipp Zabel 	}
4705b247442SPhilipp Zabel 
4715f2a9384SPhilipp Zabel 	/* DATAI is slave only, so this has to be slave */
4725f2a9384SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
4735f2a9384SPhilipp Zabel 		return -EINVAL;
4745f2a9384SPhilipp Zabel 
4755b247442SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
4765b247442SPhilipp Zabel 
4775b247442SPhilipp Zabel 	return 0;
4785b247442SPhilipp Zabel }
4795b247442SPhilipp Zabel 
4805b247442SPhilipp Zabel static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
4815b247442SPhilipp Zabel 		unsigned int fmt)
4825b247442SPhilipp Zabel {
4835b247442SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
4845b247442SPhilipp Zabel 	int iface;
4855b247442SPhilipp Zabel 
4865b247442SPhilipp Zabel 	/* set up DAI based upon fmt */
4875b247442SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
4885b247442SPhilipp Zabel 	iface &= ~(R01_SIM | R01_SFORO_MASK);
4895b247442SPhilipp Zabel 
4905b247442SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
4915b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
4925b247442SPhilipp Zabel 		iface |= R01_SFORO_I2S;
4935b247442SPhilipp Zabel 		break;
4945b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4955b247442SPhilipp Zabel 		iface |= R01_SFORO_LSB16;
4965b247442SPhilipp Zabel 		break;
4975b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4985b247442SPhilipp Zabel 		iface |= R01_SFORO_MSB;
499b7482f52SPhilipp Zabel 	}
500b7482f52SPhilipp Zabel 
501b7482f52SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
502b7482f52SPhilipp Zabel 		iface |= R01_SIM;
503b7482f52SPhilipp Zabel 
504b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
505b7482f52SPhilipp Zabel 
506b7482f52SPhilipp Zabel 	return 0;
507b7482f52SPhilipp Zabel }
508b7482f52SPhilipp Zabel 
509ef9e5e5cSPhilipp Zabel static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
510dee89c4dSMark Brown 		struct snd_soc_dai *dai)
511b7482f52SPhilipp Zabel {
512e6968a17SMark Brown 	struct snd_soc_codec *codec = dai->codec;
513b2c812e2SMark Brown 	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
514ef9e5e5cSPhilipp Zabel 	int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
515b7482f52SPhilipp Zabel 
516ef9e5e5cSPhilipp Zabel 	switch (cmd) {
517ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_START:
518ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
519ef9e5e5cSPhilipp Zabel 		uda1380_write_reg_cache(codec, UDA1380_MIXER,
520ef9e5e5cSPhilipp Zabel 					mixer & ~R14_SILENCE);
5211abd9184SPhilipp Zabel 		schedule_work(&uda1380->work);
522ef9e5e5cSPhilipp Zabel 		break;
523ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_STOP:
524ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
525ef9e5e5cSPhilipp Zabel 		uda1380_write_reg_cache(codec, UDA1380_MIXER,
526ef9e5e5cSPhilipp Zabel 					mixer | R14_SILENCE);
5271abd9184SPhilipp Zabel 		schedule_work(&uda1380->work);
528ef9e5e5cSPhilipp Zabel 		break;
529b7482f52SPhilipp Zabel 	}
530b7482f52SPhilipp Zabel 	return 0;
531b7482f52SPhilipp Zabel }
532b7482f52SPhilipp Zabel 
533b7482f52SPhilipp Zabel static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
534dee89c4dSMark Brown 				 struct snd_pcm_hw_params *params,
535dee89c4dSMark Brown 				 struct snd_soc_dai *dai)
536b7482f52SPhilipp Zabel {
537e6968a17SMark Brown 	struct snd_soc_codec *codec = dai->codec;
538b7482f52SPhilipp Zabel 	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
539b7482f52SPhilipp Zabel 
540b7482f52SPhilipp Zabel 	/* set WSPLL power and divider if running from this clock */
541b7482f52SPhilipp Zabel 	if (clk & R00_DAC_CLK) {
542b7482f52SPhilipp Zabel 		int rate = params_rate(params);
543b7482f52SPhilipp Zabel 		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
544b7482f52SPhilipp Zabel 		clk &= ~0x3; /* clear SEL_LOOP_DIV */
545b7482f52SPhilipp Zabel 		switch (rate) {
546b7482f52SPhilipp Zabel 		case 6250 ... 12500:
547b7482f52SPhilipp Zabel 			clk |= 0x0;
548b7482f52SPhilipp Zabel 			break;
549b7482f52SPhilipp Zabel 		case 12501 ... 25000:
550b7482f52SPhilipp Zabel 			clk |= 0x1;
551b7482f52SPhilipp Zabel 			break;
552b7482f52SPhilipp Zabel 		case 25001 ... 50000:
553b7482f52SPhilipp Zabel 			clk |= 0x2;
554b7482f52SPhilipp Zabel 			break;
555b7482f52SPhilipp Zabel 		case 50001 ... 100000:
556b7482f52SPhilipp Zabel 			clk |= 0x3;
557b7482f52SPhilipp Zabel 			break;
558b7482f52SPhilipp Zabel 		}
559b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_PLL | pm);
560b7482f52SPhilipp Zabel 	}
561b7482f52SPhilipp Zabel 
562b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
563b7482f52SPhilipp Zabel 		clk |= R00_EN_DAC | R00_EN_INT;
564b7482f52SPhilipp Zabel 	else
565b7482f52SPhilipp Zabel 		clk |= R00_EN_ADC | R00_EN_DEC;
566b7482f52SPhilipp Zabel 
567b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, clk);
568b7482f52SPhilipp Zabel 	return 0;
569b7482f52SPhilipp Zabel }
570b7482f52SPhilipp Zabel 
571dee89c4dSMark Brown static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
572dee89c4dSMark Brown 				 struct snd_soc_dai *dai)
573b7482f52SPhilipp Zabel {
574ab64246cSLars-Peter Clausen 	struct snd_soc_codec *codec = dai->codec;
575b7482f52SPhilipp Zabel 	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
576b7482f52SPhilipp Zabel 
577b7482f52SPhilipp Zabel 	/* shut down WSPLL power if running from this clock */
578b7482f52SPhilipp Zabel 	if (clk & R00_DAC_CLK) {
579b7482f52SPhilipp Zabel 		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
580b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, ~R02_PON_PLL & pm);
581b7482f52SPhilipp Zabel 	}
582b7482f52SPhilipp Zabel 
583b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
584b7482f52SPhilipp Zabel 		clk &= ~(R00_EN_DAC | R00_EN_INT);
585b7482f52SPhilipp Zabel 	else
586b7482f52SPhilipp Zabel 		clk &= ~(R00_EN_ADC | R00_EN_DEC);
587b7482f52SPhilipp Zabel 
588b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, clk);
589b7482f52SPhilipp Zabel }
590b7482f52SPhilipp Zabel 
591b7482f52SPhilipp Zabel static int uda1380_set_bias_level(struct snd_soc_codec *codec,
592b7482f52SPhilipp Zabel 	enum snd_soc_bias_level level)
593b7482f52SPhilipp Zabel {
594b7482f52SPhilipp Zabel 	int pm = uda1380_read_reg_cache(codec, UDA1380_PM);
5958614d310SVasily Khoruzhick 	int reg;
5968614d310SVasily Khoruzhick 	struct uda1380_platform_data *pdata = codec->dev->platform_data;
5978614d310SVasily Khoruzhick 
598b7482f52SPhilipp Zabel 	switch (level) {
599b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_ON:
600b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_PREPARE:
6018614d310SVasily Khoruzhick 		/* ADC, DAC on */
602b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
603b7482f52SPhilipp Zabel 		break;
604b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_STANDBY:
6059f061718SLars-Peter Clausen 		if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
6068614d310SVasily Khoruzhick 			if (gpio_is_valid(pdata->gpio_power)) {
6078614d310SVasily Khoruzhick 				gpio_set_value(pdata->gpio_power, 1);
6088e3dce4dSVasily Khoruzhick 				mdelay(1);
6098614d310SVasily Khoruzhick 				uda1380_reset(codec);
6108614d310SVasily Khoruzhick 			}
6118614d310SVasily Khoruzhick 
6128614d310SVasily Khoruzhick 			uda1380_sync_cache(codec);
6138614d310SVasily Khoruzhick 		}
614b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, 0x0);
615b7482f52SPhilipp Zabel 		break;
6168614d310SVasily Khoruzhick 	case SND_SOC_BIAS_OFF:
6178614d310SVasily Khoruzhick 		if (!gpio_is_valid(pdata->gpio_power))
6188614d310SVasily Khoruzhick 			break;
6198614d310SVasily Khoruzhick 
6208614d310SVasily Khoruzhick 		gpio_set_value(pdata->gpio_power, 0);
6218614d310SVasily Khoruzhick 
6228614d310SVasily Khoruzhick 		/* Mark mixer regs cache dirty to sync them with
6238614d310SVasily Khoruzhick 		 * codec regs on power on.
6248614d310SVasily Khoruzhick 		 */
6258614d310SVasily Khoruzhick 		for (reg = UDA1380_MVOL; reg < UDA1380_CACHEREGNUM; reg++)
6268614d310SVasily Khoruzhick 			set_bit(reg - 0x10, &uda1380_cache_dirty);
627b7482f52SPhilipp Zabel 	}
628b7482f52SPhilipp Zabel 	return 0;
629b7482f52SPhilipp Zabel }
630b7482f52SPhilipp Zabel 
631b7482f52SPhilipp Zabel #define UDA1380_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
632b7482f52SPhilipp Zabel 		       SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
633b7482f52SPhilipp Zabel 		       SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
634b7482f52SPhilipp Zabel 
63585e7652dSLars-Peter Clausen static const struct snd_soc_dai_ops uda1380_dai_ops = {
6366335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
6376335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
63865ec1cd1SMark Brown 	.trigger	= uda1380_trigger,
6396335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_both,
6406335d055SEric Miao };
6416335d055SEric Miao 
64285e7652dSLars-Peter Clausen static const struct snd_soc_dai_ops uda1380_dai_ops_playback = {
6436335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
6446335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
64565ec1cd1SMark Brown 	.trigger	= uda1380_trigger,
6466335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_playback,
6476335d055SEric Miao };
6486335d055SEric Miao 
64985e7652dSLars-Peter Clausen static const struct snd_soc_dai_ops uda1380_dai_ops_capture = {
6506335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
6516335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
65265ec1cd1SMark Brown 	.trigger	= uda1380_trigger,
6536335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_capture,
6546335d055SEric Miao };
6556335d055SEric Miao 
656f0fba2adSLiam Girdwood static struct snd_soc_dai_driver uda1380_dai[] = {
657b7482f52SPhilipp Zabel {
658f0fba2adSLiam Girdwood 	.name = "uda1380-hifi",
659b7482f52SPhilipp Zabel 	.playback = {
660b7482f52SPhilipp Zabel 		.stream_name = "Playback",
661b7482f52SPhilipp Zabel 		.channels_min = 1,
662b7482f52SPhilipp Zabel 		.channels_max = 2,
663b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
664b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
665b7482f52SPhilipp Zabel 	.capture = {
666b7482f52SPhilipp Zabel 		.stream_name = "Capture",
667b7482f52SPhilipp Zabel 		.channels_min = 1,
668b7482f52SPhilipp Zabel 		.channels_max = 2,
669b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
670b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
6716335d055SEric Miao 	.ops = &uda1380_dai_ops,
672b7482f52SPhilipp Zabel },
673b7482f52SPhilipp Zabel { /* playback only - dual interface */
674f0fba2adSLiam Girdwood 	.name = "uda1380-hifi-playback",
675b7482f52SPhilipp Zabel 	.playback = {
676b7482f52SPhilipp Zabel 		.stream_name = "Playback",
677b7482f52SPhilipp Zabel 		.channels_min = 1,
678b7482f52SPhilipp Zabel 		.channels_max = 2,
679b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
680b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
681b7482f52SPhilipp Zabel 	},
6826335d055SEric Miao 	.ops = &uda1380_dai_ops_playback,
683b7482f52SPhilipp Zabel },
684b7482f52SPhilipp Zabel { /* capture only - dual interface*/
685f0fba2adSLiam Girdwood 	.name = "uda1380-hifi-capture",
686b7482f52SPhilipp Zabel 	.capture = {
687b7482f52SPhilipp Zabel 		.stream_name = "Capture",
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_capture,
694b7482f52SPhilipp Zabel },
695b7482f52SPhilipp Zabel };
696b7482f52SPhilipp Zabel 
697f0fba2adSLiam Girdwood static int uda1380_probe(struct snd_soc_codec *codec)
698b7482f52SPhilipp Zabel {
699f0fba2adSLiam Girdwood 	struct uda1380_platform_data *pdata =codec->dev->platform_data;
700f0fba2adSLiam Girdwood 	struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
701f0fba2adSLiam Girdwood 	int ret;
702b7482f52SPhilipp Zabel 
7038614d310SVasily Khoruzhick 	uda1380->codec = codec;
704b7482f52SPhilipp Zabel 
705222e728cSLars-Peter Clausen 	if (!gpio_is_valid(pdata->gpio_power)) {
706f0fba2adSLiam Girdwood 		ret = uda1380_reset(codec);
70768020db8SAxel Lin 		if (ret)
708222e728cSLars-Peter Clausen 			return ret;
7098614d310SVasily Khoruzhick 	}
710b7482f52SPhilipp Zabel 
711f0fba2adSLiam Girdwood 	INIT_WORK(&uda1380->work, uda1380_flush_work);
712f0fba2adSLiam Girdwood 
713b7482f52SPhilipp Zabel 	/* set clock input */
7141abd9184SPhilipp Zabel 	switch (pdata->dac_clk) {
715b7482f52SPhilipp Zabel 	case UDA1380_DAC_CLK_SYSCLK:
7168614d310SVasily Khoruzhick 		uda1380_write_reg_cache(codec, UDA1380_CLK, 0);
717b7482f52SPhilipp Zabel 		break;
718b7482f52SPhilipp Zabel 	case UDA1380_DAC_CLK_WSPLL:
7198614d310SVasily Khoruzhick 		uda1380_write_reg_cache(codec, UDA1380_CLK,
7208614d310SVasily Khoruzhick 			R00_DAC_CLK);
721b7482f52SPhilipp Zabel 		break;
722b7482f52SPhilipp Zabel 	}
723b7482f52SPhilipp Zabel 
7241abd9184SPhilipp Zabel 	return 0;
7251abd9184SPhilipp Zabel }
726b7482f52SPhilipp Zabel 
727a180ba45SBhumika Goyal static const struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
728f0fba2adSLiam Girdwood 	.probe =	uda1380_probe,
729*7604d806SKuninori Morimoto 	.read =		uda1380_read_reg_cache,
730*7604d806SKuninori Morimoto 	.write =	uda1380_write,
731f0fba2adSLiam Girdwood 	.set_bias_level = uda1380_set_bias_level,
732e8125f04SLars-Peter Clausen 	.suspend_bias_off = true,
733e8125f04SLars-Peter Clausen 
73468509edeSKuninori Morimoto 	.component_driver = {
73558fa8e45SAxel Lin 		.controls		= uda1380_snd_controls,
73658fa8e45SAxel Lin 		.num_controls		= ARRAY_SIZE(uda1380_snd_controls),
73758fa8e45SAxel Lin 		.dapm_widgets		= uda1380_dapm_widgets,
73858fa8e45SAxel Lin 		.num_dapm_widgets	= ARRAY_SIZE(uda1380_dapm_widgets),
73958fa8e45SAxel Lin 		.dapm_routes		= uda1380_dapm_routes,
74058fa8e45SAxel Lin 		.num_dapm_routes	= ARRAY_SIZE(uda1380_dapm_routes),
74168509edeSKuninori Morimoto 	},
742f0fba2adSLiam Girdwood };
743f0fba2adSLiam Girdwood 
7447a79e94eSBill Pemberton static int uda1380_i2c_probe(struct i2c_client *i2c,
74588fc39d7SJean Delvare 			     const struct i2c_device_id *id)
746b7482f52SPhilipp Zabel {
747222e728cSLars-Peter Clausen 	struct uda1380_platform_data *pdata = i2c->dev.platform_data;
7481abd9184SPhilipp Zabel 	struct uda1380_priv *uda1380;
749b7482f52SPhilipp Zabel 	int ret;
750b7482f52SPhilipp Zabel 
751222e728cSLars-Peter Clausen 	if (!pdata)
752222e728cSLars-Peter Clausen 		return -EINVAL;
753222e728cSLars-Peter Clausen 
7546ce91ad4SAxel Lin 	uda1380 = devm_kzalloc(&i2c->dev, sizeof(struct uda1380_priv),
7556ce91ad4SAxel Lin 			       GFP_KERNEL);
7561abd9184SPhilipp Zabel 	if (uda1380 == NULL)
7571abd9184SPhilipp Zabel 		return -ENOMEM;
7581abd9184SPhilipp Zabel 
759222e728cSLars-Peter Clausen 	if (gpio_is_valid(pdata->gpio_reset)) {
760222e728cSLars-Peter Clausen 		ret = devm_gpio_request_one(&i2c->dev, pdata->gpio_reset,
761222e728cSLars-Peter Clausen 			GPIOF_OUT_INIT_LOW, "uda1380 reset");
762222e728cSLars-Peter Clausen 		if (ret)
763222e728cSLars-Peter Clausen 			return ret;
764222e728cSLars-Peter Clausen 	}
765222e728cSLars-Peter Clausen 
766222e728cSLars-Peter Clausen 	if (gpio_is_valid(pdata->gpio_power)) {
767222e728cSLars-Peter Clausen 		ret = devm_gpio_request_one(&i2c->dev, pdata->gpio_power,
768222e728cSLars-Peter Clausen 			GPIOF_OUT_INIT_LOW, "uda1380 power");
769222e728cSLars-Peter Clausen 		if (ret)
770222e728cSLars-Peter Clausen 			return ret;
771222e728cSLars-Peter Clausen 	}
772222e728cSLars-Peter Clausen 
773c001bf63SKuninori Morimoto 	uda1380->reg_cache = devm_kmemdup(&i2c->dev,
774c001bf63SKuninori Morimoto 					uda1380_reg,
775c001bf63SKuninori Morimoto 					ARRAY_SIZE(uda1380_reg) * sizeof(u16),
776c001bf63SKuninori Morimoto 					GFP_KERNEL);
777c001bf63SKuninori Morimoto 	if (!uda1380->reg_cache)
778c001bf63SKuninori Morimoto 		return -ENOMEM;
779c001bf63SKuninori Morimoto 
7801abd9184SPhilipp Zabel 	i2c_set_clientdata(i2c, uda1380);
781eaa53216SKuninori Morimoto 	uda1380->i2c = i2c;
782b7482f52SPhilipp Zabel 
783f0fba2adSLiam Girdwood 	ret =  snd_soc_register_codec(&i2c->dev,
784f0fba2adSLiam Girdwood 			&soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
785b7482f52SPhilipp Zabel 	return ret;
786b7482f52SPhilipp Zabel }
787b7482f52SPhilipp Zabel 
7887a79e94eSBill Pemberton static int uda1380_i2c_remove(struct i2c_client *i2c)
789b7482f52SPhilipp Zabel {
790f0fba2adSLiam Girdwood 	snd_soc_unregister_codec(&i2c->dev);
791b7482f52SPhilipp Zabel 	return 0;
792b7482f52SPhilipp Zabel }
793b7482f52SPhilipp Zabel 
79488fc39d7SJean Delvare static const struct i2c_device_id uda1380_i2c_id[] = {
79588fc39d7SJean Delvare 	{ "uda1380", 0 },
79688fc39d7SJean Delvare 	{ }
79788fc39d7SJean Delvare };
79888fc39d7SJean Delvare MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
799b7482f52SPhilipp Zabel 
800ea22a26eSJavier Martinez Canillas static const struct of_device_id uda1380_of_match[] = {
801ea22a26eSJavier Martinez Canillas 	{ .compatible = "nxp,uda1380", },
802ea22a26eSJavier Martinez Canillas 	{ }
803ea22a26eSJavier Martinez Canillas };
804ea22a26eSJavier Martinez Canillas MODULE_DEVICE_TABLE(of, uda1380_of_match);
805ea22a26eSJavier Martinez Canillas 
806b7482f52SPhilipp Zabel static struct i2c_driver uda1380_i2c_driver = {
807b7482f52SPhilipp Zabel 	.driver = {
808f0fba2adSLiam Girdwood 		.name =  "uda1380-codec",
809ea22a26eSJavier Martinez Canillas 		.of_match_table = uda1380_of_match,
810b7482f52SPhilipp Zabel 	},
81188fc39d7SJean Delvare 	.probe =    uda1380_i2c_probe,
8127a79e94eSBill Pemberton 	.remove =   uda1380_i2c_remove,
81388fc39d7SJean Delvare 	.id_table = uda1380_i2c_id,
814b7482f52SPhilipp Zabel };
815b7482f52SPhilipp Zabel 
8164a5cf132SKuninori Morimoto module_i2c_driver(uda1380_i2c_driver);
81764089b84SMark Brown 
818b7482f52SPhilipp Zabel MODULE_AUTHOR("Giorgio Padrin");
819b7482f52SPhilipp Zabel MODULE_DESCRIPTION("Audio support for codec Philips UDA1380");
820b7482f52SPhilipp Zabel MODULE_LICENSE("GPL");
821