xref: /linux/sound/soc/codecs/uda1380.c (revision d2912cb15bdda8ba4a5dd73396ad62641af2f520)
1*d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2b7482f52SPhilipp Zabel /*
3b7482f52SPhilipp Zabel  * uda1380.c - Philips UDA1380 ALSA SoC audio driver
4b7482f52SPhilipp Zabel  *
51abd9184SPhilipp Zabel  * Copyright (c) 2007-2009 Philipp Zabel <philipp.zabel@gmail.com>
6b7482f52SPhilipp Zabel  *
7b7482f52SPhilipp Zabel  * Modified by Richard Purdie <richard@openedhand.com> to fit into SoC
8b7482f52SPhilipp Zabel  * codec model.
9b7482f52SPhilipp Zabel  *
10b7482f52SPhilipp Zabel  * Copyright (c) 2005 Giorgio Padrin <giorgio@mandarinlogiq.org>
11b7482f52SPhilipp Zabel  * Copyright 2005 Openedhand Ltd.
12b7482f52SPhilipp Zabel  */
13b7482f52SPhilipp Zabel 
14b7482f52SPhilipp Zabel #include <linux/module.h>
15b7482f52SPhilipp Zabel #include <linux/init.h>
16b7482f52SPhilipp Zabel #include <linux/types.h>
17b7482f52SPhilipp Zabel #include <linux/slab.h>
18b7482f52SPhilipp Zabel #include <linux/errno.h>
191abd9184SPhilipp Zabel #include <linux/gpio.h>
20b7482f52SPhilipp Zabel #include <linux/delay.h>
21b7482f52SPhilipp Zabel #include <linux/i2c.h>
22ef9e5e5cSPhilipp Zabel #include <linux/workqueue.h>
23b7482f52SPhilipp Zabel #include <sound/core.h>
24b7482f52SPhilipp Zabel #include <sound/control.h>
25b7482f52SPhilipp Zabel #include <sound/initval.h>
26b7482f52SPhilipp Zabel #include <sound/soc.h>
27b7482f52SPhilipp Zabel #include <sound/tlv.h>
281abd9184SPhilipp Zabel #include <sound/uda1380.h>
29b7482f52SPhilipp Zabel 
30b7482f52SPhilipp Zabel #include "uda1380.h"
31b7482f52SPhilipp Zabel 
321abd9184SPhilipp Zabel /* codec private data */
331abd9184SPhilipp Zabel struct uda1380_priv {
34b40822d9SKuninori Morimoto 	struct snd_soc_component *component;
351abd9184SPhilipp Zabel 	unsigned int dac_clk;
361abd9184SPhilipp Zabel 	struct work_struct work;
37eaa53216SKuninori Morimoto 	struct i2c_client *i2c;
38c001bf63SKuninori Morimoto 	u16 *reg_cache;
391abd9184SPhilipp Zabel };
401abd9184SPhilipp Zabel 
41b7482f52SPhilipp Zabel /*
42b7482f52SPhilipp Zabel  * uda1380 register cache
43b7482f52SPhilipp Zabel  */
44b7482f52SPhilipp Zabel static const u16 uda1380_reg[UDA1380_CACHEREGNUM] = {
45b7482f52SPhilipp Zabel 	0x0502, 0x0000, 0x0000, 0x3f3f,
46b7482f52SPhilipp Zabel 	0x0202, 0x0000, 0x0000, 0x0000,
47b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
48b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
49b7482f52SPhilipp Zabel 	0x0000, 0xff00, 0x0000, 0x4800,
50b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
51b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
52b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
53b7482f52SPhilipp Zabel 	0x0000, 0x8000, 0x0002, 0x0000,
54b7482f52SPhilipp Zabel };
55b7482f52SPhilipp Zabel 
56ef9e5e5cSPhilipp Zabel static unsigned long uda1380_cache_dirty;
57ef9e5e5cSPhilipp Zabel 
58b7482f52SPhilipp Zabel /*
59b7482f52SPhilipp Zabel  * read uda1380 register cache
60b7482f52SPhilipp Zabel  */
61b40822d9SKuninori Morimoto static inline unsigned int uda1380_read_reg_cache(struct snd_soc_component *component,
62b7482f52SPhilipp Zabel 	unsigned int reg)
63b7482f52SPhilipp Zabel {
64b40822d9SKuninori Morimoto 	struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
65c001bf63SKuninori Morimoto 	u16 *cache = uda1380->reg_cache;
66c001bf63SKuninori Morimoto 
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  */
77b40822d9SKuninori Morimoto static inline void uda1380_write_reg_cache(struct snd_soc_component *component,
78b7482f52SPhilipp Zabel 	u16 reg, unsigned int value)
79b7482f52SPhilipp Zabel {
80b40822d9SKuninori Morimoto 	struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
81c001bf63SKuninori Morimoto 	u16 *cache = uda1380->reg_cache;
82ef9e5e5cSPhilipp Zabel 
83b7482f52SPhilipp Zabel 	if (reg >= UDA1380_CACHEREGNUM)
84b7482f52SPhilipp Zabel 		return;
85ef9e5e5cSPhilipp Zabel 	if ((reg >= 0x10) && (cache[reg] != value))
86ef9e5e5cSPhilipp Zabel 		set_bit(reg - 0x10, &uda1380_cache_dirty);
87b7482f52SPhilipp Zabel 	cache[reg] = value;
88b7482f52SPhilipp Zabel }
89b7482f52SPhilipp Zabel 
90b7482f52SPhilipp Zabel /*
91b7482f52SPhilipp Zabel  * write to the UDA1380 register space
92b7482f52SPhilipp Zabel  */
93b40822d9SKuninori Morimoto static int uda1380_write(struct snd_soc_component *component, unsigned int reg,
94b7482f52SPhilipp Zabel 	unsigned int value)
95b7482f52SPhilipp Zabel {
96b40822d9SKuninori Morimoto 	struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
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 
108b40822d9SKuninori Morimoto 	uda1380_write_reg_cache(component, reg, value);
109b7482f52SPhilipp Zabel 
110b7482f52SPhilipp Zabel 	/* the interpolator & decimator regs must only be written when the
111b7482f52SPhilipp Zabel 	 * codec DAI is active.
112b7482f52SPhilipp Zabel 	 */
113b40822d9SKuninori Morimoto 	if (!snd_soc_component_is_active(component) && (reg >= UDA1380_MVOL))
114b7482f52SPhilipp Zabel 		return 0;
115b7482f52SPhilipp Zabel 	pr_debug("uda1380: hw write %x val %x\n", reg, value);
116eaa53216SKuninori Morimoto 	if (i2c_master_send(uda1380->i2c, data, 3) == 3) {
117b7482f52SPhilipp Zabel 		unsigned int val;
118eaa53216SKuninori Morimoto 		i2c_master_send(uda1380->i2c, data, 1);
119eaa53216SKuninori Morimoto 		i2c_master_recv(uda1380->i2c, 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 
133b40822d9SKuninori Morimoto static void uda1380_sync_cache(struct snd_soc_component *component)
1348614d310SVasily Khoruzhick {
135b40822d9SKuninori Morimoto 	struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
1368614d310SVasily Khoruzhick 	int reg;
1378614d310SVasily Khoruzhick 	u8 data[3];
138c001bf63SKuninori Morimoto 	u16 *cache = uda1380->reg_cache;
1398614d310SVasily Khoruzhick 
1408614d310SVasily Khoruzhick 	/* Sync reg_cache with the hardware */
1418614d310SVasily Khoruzhick 	for (reg = 0; reg < UDA1380_MVOL; reg++) {
1428614d310SVasily Khoruzhick 		data[0] = reg;
1438614d310SVasily Khoruzhick 		data[1] = (cache[reg] & 0xff00) >> 8;
1448614d310SVasily Khoruzhick 		data[2] = cache[reg] & 0x00ff;
145eaa53216SKuninori Morimoto 		if (i2c_master_send(uda1380->i2c, data, 3) != 3)
146b40822d9SKuninori Morimoto 			dev_err(component->dev, "%s: write to reg 0x%x failed\n",
1478614d310SVasily Khoruzhick 				__func__, reg);
1488614d310SVasily Khoruzhick 	}
1498614d310SVasily Khoruzhick }
1508614d310SVasily Khoruzhick 
151b40822d9SKuninori Morimoto static int uda1380_reset(struct snd_soc_component *component)
1528614d310SVasily Khoruzhick {
153b40822d9SKuninori Morimoto 	struct uda1380_platform_data *pdata = component->dev->platform_data;
154b40822d9SKuninori Morimoto 	struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
1558614d310SVasily Khoruzhick 
1568614d310SVasily Khoruzhick 	if (gpio_is_valid(pdata->gpio_reset)) {
1578614d310SVasily Khoruzhick 		gpio_set_value(pdata->gpio_reset, 1);
1588614d310SVasily Khoruzhick 		mdelay(1);
1598614d310SVasily Khoruzhick 		gpio_set_value(pdata->gpio_reset, 0);
1608614d310SVasily Khoruzhick 	} else {
1618614d310SVasily Khoruzhick 		u8 data[3];
1628614d310SVasily Khoruzhick 
1638614d310SVasily Khoruzhick 		data[0] = UDA1380_RESET;
1648614d310SVasily Khoruzhick 		data[1] = 0;
1658614d310SVasily Khoruzhick 		data[2] = 0;
1668614d310SVasily Khoruzhick 
167eaa53216SKuninori Morimoto 		if (i2c_master_send(uda1380->i2c, data, 3) != 3) {
168b40822d9SKuninori Morimoto 			dev_err(component->dev, "%s: failed\n", __func__);
1698614d310SVasily Khoruzhick 			return -EIO;
1708614d310SVasily Khoruzhick 		}
1718614d310SVasily Khoruzhick 	}
1728614d310SVasily Khoruzhick 
1738614d310SVasily Khoruzhick 	return 0;
1748614d310SVasily Khoruzhick }
175b7482f52SPhilipp Zabel 
176ef9e5e5cSPhilipp Zabel static void uda1380_flush_work(struct work_struct *work)
177ef9e5e5cSPhilipp Zabel {
178f0fba2adSLiam Girdwood 	struct uda1380_priv *uda1380 = container_of(work, struct uda1380_priv, work);
179b40822d9SKuninori Morimoto 	struct snd_soc_component *uda1380_component = uda1380->component;
180ef9e5e5cSPhilipp Zabel 	int bit, reg;
181ef9e5e5cSPhilipp Zabel 
182984b3f57SAkinobu Mita 	for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
183ef9e5e5cSPhilipp Zabel 		reg = 0x10 + bit;
184ef9e5e5cSPhilipp Zabel 		pr_debug("uda1380: flush reg %x val %x:\n", reg,
185b40822d9SKuninori Morimoto 				uda1380_read_reg_cache(uda1380_component, reg));
186b40822d9SKuninori Morimoto 		uda1380_write(uda1380_component, reg,
187b40822d9SKuninori Morimoto 				uda1380_read_reg_cache(uda1380_component, reg));
188ef9e5e5cSPhilipp Zabel 		clear_bit(bit, &uda1380_cache_dirty);
189ef9e5e5cSPhilipp Zabel 	}
190f0fba2adSLiam Girdwood 
191ef9e5e5cSPhilipp Zabel }
192ef9e5e5cSPhilipp Zabel 
193b7482f52SPhilipp Zabel /* declarations of ALSA reg_elem_REAL controls */
194b7482f52SPhilipp Zabel static const char *uda1380_deemp[] = {
195b7482f52SPhilipp Zabel 	"None",
196b7482f52SPhilipp Zabel 	"32kHz",
197b7482f52SPhilipp Zabel 	"44.1kHz",
198b7482f52SPhilipp Zabel 	"48kHz",
199b7482f52SPhilipp Zabel 	"96kHz",
200b7482f52SPhilipp Zabel };
201b7482f52SPhilipp Zabel static const char *uda1380_input_sel[] = {
202b7482f52SPhilipp Zabel 	"Line",
203b7482f52SPhilipp Zabel 	"Mic + Line R",
204b7482f52SPhilipp Zabel 	"Line L",
205b7482f52SPhilipp Zabel 	"Mic",
206b7482f52SPhilipp Zabel };
207b7482f52SPhilipp Zabel static const char *uda1380_output_sel[] = {
208b7482f52SPhilipp Zabel 	"DAC",
209b7482f52SPhilipp Zabel 	"Analog Mixer",
210b7482f52SPhilipp Zabel };
211b7482f52SPhilipp Zabel static const char *uda1380_spf_mode[] = {
212b7482f52SPhilipp Zabel 	"Flat",
213b7482f52SPhilipp Zabel 	"Minimum1",
214b7482f52SPhilipp Zabel 	"Minimum2",
215b7482f52SPhilipp Zabel 	"Maximum"
216b7482f52SPhilipp Zabel };
217b7482f52SPhilipp Zabel static const char *uda1380_capture_sel[] = {
218b7482f52SPhilipp Zabel 	"ADC",
219b7482f52SPhilipp Zabel 	"Digital Mixer"
220b7482f52SPhilipp Zabel };
221b7482f52SPhilipp Zabel static const char *uda1380_sel_ns[] = {
222b7482f52SPhilipp Zabel 	"3rd-order",
223b7482f52SPhilipp Zabel 	"5th-order"
224b7482f52SPhilipp Zabel };
225b7482f52SPhilipp Zabel static const char *uda1380_mix_control[] = {
226b7482f52SPhilipp Zabel 	"off",
227b7482f52SPhilipp Zabel 	"PCM only",
228b7482f52SPhilipp Zabel 	"before sound processing",
229b7482f52SPhilipp Zabel 	"after sound processing"
230b7482f52SPhilipp Zabel };
231b7482f52SPhilipp Zabel static const char *uda1380_sdet_setting[] = {
232b7482f52SPhilipp Zabel 	"3200",
233b7482f52SPhilipp Zabel 	"4800",
234b7482f52SPhilipp Zabel 	"9600",
235b7482f52SPhilipp Zabel 	"19200"
236b7482f52SPhilipp Zabel };
237b7482f52SPhilipp Zabel static const char *uda1380_os_setting[] = {
238b7482f52SPhilipp Zabel 	"single-speed",
239b7482f52SPhilipp Zabel 	"double-speed (no mixing)",
240b7482f52SPhilipp Zabel 	"quad-speed (no mixing)"
241b7482f52SPhilipp Zabel };
242b7482f52SPhilipp Zabel 
243b7482f52SPhilipp Zabel static const struct soc_enum uda1380_deemp_enum[] = {
2441dbb348dSTakashi Iwai 	SOC_ENUM_SINGLE(UDA1380_DEEMP, 8, ARRAY_SIZE(uda1380_deemp),
2451dbb348dSTakashi Iwai 			uda1380_deemp),
2461dbb348dSTakashi Iwai 	SOC_ENUM_SINGLE(UDA1380_DEEMP, 0, ARRAY_SIZE(uda1380_deemp),
2471dbb348dSTakashi Iwai 			uda1380_deemp),
248b7482f52SPhilipp Zabel };
2491dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_input_sel_enum,
2501dbb348dSTakashi Iwai 			    UDA1380_ADC, 2, uda1380_input_sel);		/* SEL_MIC, SEL_LNA */
2511dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_output_sel_enum,
2521dbb348dSTakashi Iwai 			    UDA1380_PM, 7, uda1380_output_sel);		/* R02_EN_AVC */
2531dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_spf_enum,
2541dbb348dSTakashi Iwai 			    UDA1380_MODE, 14, uda1380_spf_mode);		/* M */
2551dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_capture_sel_enum,
2561dbb348dSTakashi Iwai 			    UDA1380_IFACE, 6, uda1380_capture_sel);	/* SEL_SOURCE */
2571dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_sel_ns_enum,
2581dbb348dSTakashi Iwai 			    UDA1380_MIXER, 14, uda1380_sel_ns);		/* SEL_NS */
2591dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_mix_enum,
2601dbb348dSTakashi Iwai 			    UDA1380_MIXER, 12, uda1380_mix_control);	/* MIX, MIX_POS */
2611dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_sdet_enum,
2621dbb348dSTakashi Iwai 			    UDA1380_MIXER, 4, uda1380_sdet_setting);	/* SD_VALUE */
2631dbb348dSTakashi Iwai static SOC_ENUM_SINGLE_DECL(uda1380_os_enum,
2641dbb348dSTakashi Iwai 			    UDA1380_MIXER, 0, uda1380_os_setting);	/* OS */
265b7482f52SPhilipp Zabel 
266b7482f52SPhilipp Zabel /*
267b7482f52SPhilipp Zabel  * from -48 dB in 1.5 dB steps (mute instead of -49.5 dB)
268b7482f52SPhilipp Zabel  */
269b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(amix_tlv, -4950, 150, 1);
270b7482f52SPhilipp Zabel 
271b7482f52SPhilipp Zabel /*
272b7482f52SPhilipp Zabel  * from -78 dB in 1 dB steps (3 dB steps, really. LSB are ignored),
273b7482f52SPhilipp Zabel  * from -66 dB in 0.5 dB steps (2 dB steps, really) and
274b7482f52SPhilipp Zabel  * from -52 dB in 0.25 dB steps
275b7482f52SPhilipp Zabel  */
2765ee0b8f8SLars-Peter Clausen static const DECLARE_TLV_DB_RANGE(mvol_tlv,
277b7482f52SPhilipp Zabel 	0, 15, TLV_DB_SCALE_ITEM(-8200, 100, 1),
278b7482f52SPhilipp Zabel 	16, 43, TLV_DB_SCALE_ITEM(-6600, 50, 0),
2795ee0b8f8SLars-Peter Clausen 	44, 252, TLV_DB_SCALE_ITEM(-5200, 25, 0)
2805ee0b8f8SLars-Peter Clausen );
281b7482f52SPhilipp Zabel 
282b7482f52SPhilipp Zabel /*
283b7482f52SPhilipp Zabel  * from -72 dB in 1.5 dB steps (6 dB steps really),
284b7482f52SPhilipp Zabel  * from -66 dB in 0.75 dB steps (3 dB steps really),
285b7482f52SPhilipp Zabel  * from -60 dB in 0.5 dB steps (2 dB steps really) and
286b7482f52SPhilipp Zabel  * from -46 dB in 0.25 dB steps
287b7482f52SPhilipp Zabel  */
2885ee0b8f8SLars-Peter Clausen static const DECLARE_TLV_DB_RANGE(vc_tlv,
289b7482f52SPhilipp Zabel 	0, 7, TLV_DB_SCALE_ITEM(-7800, 150, 1),
290b7482f52SPhilipp Zabel 	8, 15, TLV_DB_SCALE_ITEM(-6600, 75, 0),
291b7482f52SPhilipp Zabel 	16, 43, TLV_DB_SCALE_ITEM(-6000, 50, 0),
2925ee0b8f8SLars-Peter Clausen 	44, 228, TLV_DB_SCALE_ITEM(-4600, 25, 0)
2935ee0b8f8SLars-Peter Clausen );
294b7482f52SPhilipp Zabel 
295b7482f52SPhilipp Zabel /* from 0 to 6 dB in 2 dB steps if SPF mode != flat */
296b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(tr_tlv, 0, 200, 0);
297b7482f52SPhilipp Zabel 
298b7482f52SPhilipp Zabel /* from 0 to 24 dB in 2 dB steps, if SPF mode == maximum, otherwise cuts
299b7482f52SPhilipp Zabel  * off at 18 dB max) */
300b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(bb_tlv, 0, 200, 0);
301b7482f52SPhilipp Zabel 
302b7482f52SPhilipp Zabel /* from -63 to 24 dB in 0.5 dB steps (-128...48) */
303b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(dec_tlv, -6400, 50, 1);
304b7482f52SPhilipp Zabel 
305b7482f52SPhilipp Zabel /* from 0 to 24 dB in 3 dB steps */
306b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0);
307b7482f52SPhilipp Zabel 
308b7482f52SPhilipp Zabel /* from 0 to 30 dB in 2 dB steps */
309b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(vga_tlv, 0, 200, 0);
310b7482f52SPhilipp Zabel 
311b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_snd_controls[] = {
312b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Analog Mixer Volume", UDA1380_AMIX, 0, 8, 44, 1, amix_tlv),	/* AVCR, AVCL */
313b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Master Playback Volume", UDA1380_MVOL, 0, 8, 252, 1, mvol_tlv),	/* MVCL, MVCR */
314b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("ADC Playback Volume", UDA1380_MIXVOL, 8, 228, 1, vc_tlv),	/* VC2 */
315b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("PCM Playback Volume", UDA1380_MIXVOL, 0, 228, 1, vc_tlv),	/* VC1 */
316b7482f52SPhilipp Zabel 	SOC_ENUM("Sound Processing Filter", uda1380_spf_enum),				/* M */
317b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Tone Control - Treble", UDA1380_MODE, 4, 12, 3, 0, tr_tlv), 	/* TRL, TRR */
318b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Tone Control - Bass", UDA1380_MODE, 0, 8, 15, 0, bb_tlv),	/* BBL, BBR */
319b7482f52SPhilipp Zabel /**/	SOC_SINGLE("Master Playback Switch", UDA1380_DEEMP, 14, 1, 1),		/* MTM */
320b7482f52SPhilipp Zabel 	SOC_SINGLE("ADC Playback Switch", UDA1380_DEEMP, 11, 1, 1),		/* MT2 from decimation filter */
321b7482f52SPhilipp Zabel 	SOC_ENUM("ADC Playback De-emphasis", uda1380_deemp_enum[0]),		/* DE2 */
322b7482f52SPhilipp Zabel 	SOC_SINGLE("PCM Playback Switch", UDA1380_DEEMP, 3, 1, 1),		/* MT1, from digital data input */
323b7482f52SPhilipp Zabel 	SOC_ENUM("PCM Playback De-emphasis", uda1380_deemp_enum[1]),		/* DE1 */
324b7482f52SPhilipp Zabel 	SOC_SINGLE("DAC Polarity inverting Switch", UDA1380_MIXER, 15, 1, 0),	/* DA_POL_INV */
325b7482f52SPhilipp Zabel 	SOC_ENUM("Noise Shaper", uda1380_sel_ns_enum),				/* SEL_NS */
326b7482f52SPhilipp Zabel 	SOC_ENUM("Digital Mixer Signal Control", uda1380_mix_enum),		/* MIX_POS, MIX */
327b7482f52SPhilipp Zabel 	SOC_SINGLE("Silence Detector Switch", UDA1380_MIXER, 6, 1, 0),		/* SDET_ON */
328b7482f52SPhilipp Zabel 	SOC_ENUM("Silence Detector Setting", uda1380_sdet_enum),		/* SD_VALUE */
329b7482f52SPhilipp Zabel 	SOC_ENUM("Oversampling Input", uda1380_os_enum),			/* OS */
330b7482f52SPhilipp Zabel 	SOC_DOUBLE_S8_TLV("ADC Capture Volume", UDA1380_DEC, -128, 48, dec_tlv),	/* ML_DEC, MR_DEC */
331b7482f52SPhilipp Zabel /**/	SOC_SINGLE("ADC Capture Switch", UDA1380_PGA, 15, 1, 1),		/* MT_ADC */
332b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Line Capture Volume", UDA1380_PGA, 0, 8, 8, 0, pga_tlv), /* PGA_GAINCTRLL, PGA_GAINCTRLR */
333b7482f52SPhilipp Zabel 	SOC_SINGLE("ADC Polarity inverting Switch", UDA1380_ADC, 12, 1, 0),	/* ADCPOL_INV */
334b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("Mic Capture Volume", UDA1380_ADC, 8, 15, 0, vga_tlv),	/* VGA_CTRL */
335b7482f52SPhilipp Zabel 	SOC_SINGLE("DC Filter Bypass Switch", UDA1380_ADC, 1, 1, 0),		/* SKIP_DCFIL (before decimator) */
336b7482f52SPhilipp Zabel 	SOC_SINGLE("DC Filter Enable Switch", UDA1380_ADC, 0, 1, 0),		/* EN_DCFIL (at output of decimator) */
337b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Timing", UDA1380_AGC, 8, 7, 0),			/* TODO: enum, see table 62 */
338b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Target level", UDA1380_AGC, 2, 3, 1),			/* AGC_LEVEL */
339b7482f52SPhilipp Zabel 	/* -5.5, -8, -11.5, -14 dBFS */
340b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0),
341b7482f52SPhilipp Zabel };
342b7482f52SPhilipp Zabel 
343b7482f52SPhilipp Zabel /* Input mux */
344b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_input_mux_control =
345b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_input_sel_enum);
346b7482f52SPhilipp Zabel 
347b7482f52SPhilipp Zabel /* Output mux */
348b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_output_mux_control =
349b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_output_sel_enum);
350b7482f52SPhilipp Zabel 
351b7482f52SPhilipp Zabel /* Capture mux */
352b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_capture_mux_control =
353b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_capture_sel_enum);
354b7482f52SPhilipp Zabel 
355b7482f52SPhilipp Zabel 
356b7482f52SPhilipp Zabel static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
357b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
358b7482f52SPhilipp Zabel 		&uda1380_input_mux_control),
359b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM, 0, 0,
360b7482f52SPhilipp Zabel 		&uda1380_output_mux_control),
361b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0,
362b7482f52SPhilipp Zabel 		&uda1380_capture_mux_control),
363b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Left PGA", UDA1380_PM, 3, 0, NULL, 0),
364b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Right PGA", UDA1380_PM, 1, 0, NULL, 0),
365b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Mic LNA", UDA1380_PM, 4, 0, NULL, 0),
366b7482f52SPhilipp Zabel 	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", UDA1380_PM, 2, 0),
367b7482f52SPhilipp Zabel 	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", UDA1380_PM, 0, 0),
368b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINM"),
369b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINL"),
370b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINR"),
371b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MIXER("Analog Mixer", UDA1380_PM, 6, 0, NULL, 0),
372b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTLHP"),
373b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTRHP"),
374b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTL"),
375b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTR"),
376b7482f52SPhilipp Zabel 	SND_SOC_DAPM_DAC("DAC", "Playback", UDA1380_PM, 10, 0),
377b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("HeadPhone Driver", UDA1380_PM, 13, 0, NULL, 0),
378b7482f52SPhilipp Zabel };
379b7482f52SPhilipp Zabel 
38058fa8e45SAxel Lin static const struct snd_soc_dapm_route uda1380_dapm_routes[] = {
381b7482f52SPhilipp Zabel 
382b7482f52SPhilipp Zabel 	/* output mux */
383b7482f52SPhilipp Zabel 	{"HeadPhone Driver", NULL, "Output Mux"},
384b7482f52SPhilipp Zabel 	{"VOUTR", NULL, "Output Mux"},
385b7482f52SPhilipp Zabel 	{"VOUTL", NULL, "Output Mux"},
386b7482f52SPhilipp Zabel 
387b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "VINR"},
388b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "VINL"},
389b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "DAC"},
390b7482f52SPhilipp Zabel 
391b7482f52SPhilipp Zabel 	{"Output Mux", "DAC", "DAC"},
392b7482f52SPhilipp Zabel 	{"Output Mux", "Analog Mixer", "Analog Mixer"},
393b7482f52SPhilipp Zabel 
394b7482f52SPhilipp Zabel 	/* {"DAC", "Digital Mixer", "I2S" } */
395b7482f52SPhilipp Zabel 
396b7482f52SPhilipp Zabel 	/* headphone driver */
397b7482f52SPhilipp Zabel 	{"VOUTLHP", NULL, "HeadPhone Driver"},
398b7482f52SPhilipp Zabel 	{"VOUTRHP", NULL, "HeadPhone Driver"},
399b7482f52SPhilipp Zabel 
400b7482f52SPhilipp Zabel 	/* input mux */
401b7482f52SPhilipp Zabel 	{"Left ADC", NULL, "Input Mux"},
402b7482f52SPhilipp Zabel 	{"Input Mux", "Mic", "Mic LNA"},
403b7482f52SPhilipp Zabel 	{"Input Mux", "Mic + Line R", "Mic LNA"},
404b7482f52SPhilipp Zabel 	{"Input Mux", "Line L", "Left PGA"},
405b7482f52SPhilipp Zabel 	{"Input Mux", "Line", "Left PGA"},
406b7482f52SPhilipp Zabel 
407b7482f52SPhilipp Zabel 	/* right input */
408b7482f52SPhilipp Zabel 	{"Right ADC", "Mic + Line R", "Right PGA"},
409b7482f52SPhilipp Zabel 	{"Right ADC", "Line", "Right PGA"},
410b7482f52SPhilipp Zabel 
411b7482f52SPhilipp Zabel 	/* inputs */
412b7482f52SPhilipp Zabel 	{"Mic LNA", NULL, "VINM"},
413b7482f52SPhilipp Zabel 	{"Left PGA", NULL, "VINL"},
414b7482f52SPhilipp Zabel 	{"Right PGA", NULL, "VINR"},
415b7482f52SPhilipp Zabel };
416b7482f52SPhilipp Zabel 
4175b247442SPhilipp Zabel static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
418b7482f52SPhilipp Zabel 		unsigned int fmt)
419b7482f52SPhilipp Zabel {
420b40822d9SKuninori Morimoto 	struct snd_soc_component *component = codec_dai->component;
421b7482f52SPhilipp Zabel 	int iface;
422b7482f52SPhilipp Zabel 
423b7482f52SPhilipp Zabel 	/* set up DAI based upon fmt */
424b40822d9SKuninori Morimoto 	iface = uda1380_read_reg_cache(component, UDA1380_IFACE);
425b7482f52SPhilipp Zabel 	iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK);
426b7482f52SPhilipp Zabel 
427b7482f52SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
428b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
429b7482f52SPhilipp Zabel 		iface |= R01_SFORI_I2S | R01_SFORO_I2S;
430b7482f52SPhilipp Zabel 		break;
431b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4325b247442SPhilipp Zabel 		iface |= R01_SFORI_LSB16 | R01_SFORO_LSB16;
433b7482f52SPhilipp Zabel 		break;
434b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4355b247442SPhilipp Zabel 		iface |= R01_SFORI_MSB | R01_SFORO_MSB;
4365b247442SPhilipp Zabel 	}
4375b247442SPhilipp Zabel 
4385f2a9384SPhilipp Zabel 	/* DATAI is slave only, so in single-link mode, this has to be slave */
4395f2a9384SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
4405f2a9384SPhilipp Zabel 		return -EINVAL;
4415b247442SPhilipp Zabel 
442b40822d9SKuninori Morimoto 	uda1380_write_reg_cache(component, UDA1380_IFACE, iface);
4435b247442SPhilipp Zabel 
4445b247442SPhilipp Zabel 	return 0;
4455b247442SPhilipp Zabel }
4465b247442SPhilipp Zabel 
4475b247442SPhilipp Zabel static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
4485b247442SPhilipp Zabel 		unsigned int fmt)
4495b247442SPhilipp Zabel {
450b40822d9SKuninori Morimoto 	struct snd_soc_component *component = codec_dai->component;
4515b247442SPhilipp Zabel 	int iface;
4525b247442SPhilipp Zabel 
4535b247442SPhilipp Zabel 	/* set up DAI based upon fmt */
454b40822d9SKuninori Morimoto 	iface = uda1380_read_reg_cache(component, UDA1380_IFACE);
4555b247442SPhilipp Zabel 	iface &= ~R01_SFORI_MASK;
4565b247442SPhilipp Zabel 
4575b247442SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
4585b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
4595b247442SPhilipp Zabel 		iface |= R01_SFORI_I2S;
4605b247442SPhilipp Zabel 		break;
4615b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4625b247442SPhilipp Zabel 		iface |= R01_SFORI_LSB16;
4635b247442SPhilipp Zabel 		break;
4645b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4655b247442SPhilipp Zabel 		iface |= R01_SFORI_MSB;
4665b247442SPhilipp Zabel 	}
4675b247442SPhilipp Zabel 
4685f2a9384SPhilipp Zabel 	/* DATAI is slave only, so this has to be slave */
4695f2a9384SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
4705f2a9384SPhilipp Zabel 		return -EINVAL;
4715f2a9384SPhilipp Zabel 
472b40822d9SKuninori Morimoto 	uda1380_write(component, UDA1380_IFACE, iface);
4735b247442SPhilipp Zabel 
4745b247442SPhilipp Zabel 	return 0;
4755b247442SPhilipp Zabel }
4765b247442SPhilipp Zabel 
4775b247442SPhilipp Zabel static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
4785b247442SPhilipp Zabel 		unsigned int fmt)
4795b247442SPhilipp Zabel {
480b40822d9SKuninori Morimoto 	struct snd_soc_component *component = codec_dai->component;
4815b247442SPhilipp Zabel 	int iface;
4825b247442SPhilipp Zabel 
4835b247442SPhilipp Zabel 	/* set up DAI based upon fmt */
484b40822d9SKuninori Morimoto 	iface = uda1380_read_reg_cache(component, UDA1380_IFACE);
4855b247442SPhilipp Zabel 	iface &= ~(R01_SIM | R01_SFORO_MASK);
4865b247442SPhilipp Zabel 
4875b247442SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
4885b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
4895b247442SPhilipp Zabel 		iface |= R01_SFORO_I2S;
4905b247442SPhilipp Zabel 		break;
4915b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4925b247442SPhilipp Zabel 		iface |= R01_SFORO_LSB16;
4935b247442SPhilipp Zabel 		break;
4945b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4955b247442SPhilipp Zabel 		iface |= R01_SFORO_MSB;
496b7482f52SPhilipp Zabel 	}
497b7482f52SPhilipp Zabel 
498b7482f52SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
499b7482f52SPhilipp Zabel 		iface |= R01_SIM;
500b7482f52SPhilipp Zabel 
501b40822d9SKuninori Morimoto 	uda1380_write(component, UDA1380_IFACE, iface);
502b7482f52SPhilipp Zabel 
503b7482f52SPhilipp Zabel 	return 0;
504b7482f52SPhilipp Zabel }
505b7482f52SPhilipp Zabel 
506ef9e5e5cSPhilipp Zabel static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
507dee89c4dSMark Brown 		struct snd_soc_dai *dai)
508b7482f52SPhilipp Zabel {
509b40822d9SKuninori Morimoto 	struct snd_soc_component *component = dai->component;
510b40822d9SKuninori Morimoto 	struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
511b40822d9SKuninori Morimoto 	int mixer = uda1380_read_reg_cache(component, UDA1380_MIXER);
512b7482f52SPhilipp Zabel 
513ef9e5e5cSPhilipp Zabel 	switch (cmd) {
514ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_START:
515ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
516b40822d9SKuninori Morimoto 		uda1380_write_reg_cache(component, UDA1380_MIXER,
517ef9e5e5cSPhilipp Zabel 					mixer & ~R14_SILENCE);
5181abd9184SPhilipp Zabel 		schedule_work(&uda1380->work);
519ef9e5e5cSPhilipp Zabel 		break;
520ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_STOP:
521ef9e5e5cSPhilipp Zabel 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
522b40822d9SKuninori Morimoto 		uda1380_write_reg_cache(component, UDA1380_MIXER,
523ef9e5e5cSPhilipp Zabel 					mixer | R14_SILENCE);
5241abd9184SPhilipp Zabel 		schedule_work(&uda1380->work);
525ef9e5e5cSPhilipp Zabel 		break;
526b7482f52SPhilipp Zabel 	}
527b7482f52SPhilipp Zabel 	return 0;
528b7482f52SPhilipp Zabel }
529b7482f52SPhilipp Zabel 
530b7482f52SPhilipp Zabel static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
531dee89c4dSMark Brown 				 struct snd_pcm_hw_params *params,
532dee89c4dSMark Brown 				 struct snd_soc_dai *dai)
533b7482f52SPhilipp Zabel {
534b40822d9SKuninori Morimoto 	struct snd_soc_component *component = dai->component;
535b40822d9SKuninori Morimoto 	u16 clk = uda1380_read_reg_cache(component, UDA1380_CLK);
536b7482f52SPhilipp Zabel 
537b7482f52SPhilipp Zabel 	/* set WSPLL power and divider if running from this clock */
538b7482f52SPhilipp Zabel 	if (clk & R00_DAC_CLK) {
539b7482f52SPhilipp Zabel 		int rate = params_rate(params);
540b40822d9SKuninori Morimoto 		u16 pm = uda1380_read_reg_cache(component, UDA1380_PM);
541b7482f52SPhilipp Zabel 		clk &= ~0x3; /* clear SEL_LOOP_DIV */
542b7482f52SPhilipp Zabel 		switch (rate) {
543b7482f52SPhilipp Zabel 		case 6250 ... 12500:
544b7482f52SPhilipp Zabel 			clk |= 0x0;
545b7482f52SPhilipp Zabel 			break;
546b7482f52SPhilipp Zabel 		case 12501 ... 25000:
547b7482f52SPhilipp Zabel 			clk |= 0x1;
548b7482f52SPhilipp Zabel 			break;
549b7482f52SPhilipp Zabel 		case 25001 ... 50000:
550b7482f52SPhilipp Zabel 			clk |= 0x2;
551b7482f52SPhilipp Zabel 			break;
552b7482f52SPhilipp Zabel 		case 50001 ... 100000:
553b7482f52SPhilipp Zabel 			clk |= 0x3;
554b7482f52SPhilipp Zabel 			break;
555b7482f52SPhilipp Zabel 		}
556b40822d9SKuninori Morimoto 		uda1380_write(component, UDA1380_PM, R02_PON_PLL | pm);
557b7482f52SPhilipp Zabel 	}
558b7482f52SPhilipp Zabel 
559b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
560b7482f52SPhilipp Zabel 		clk |= R00_EN_DAC | R00_EN_INT;
561b7482f52SPhilipp Zabel 	else
562b7482f52SPhilipp Zabel 		clk |= R00_EN_ADC | R00_EN_DEC;
563b7482f52SPhilipp Zabel 
564b40822d9SKuninori Morimoto 	uda1380_write(component, UDA1380_CLK, clk);
565b7482f52SPhilipp Zabel 	return 0;
566b7482f52SPhilipp Zabel }
567b7482f52SPhilipp Zabel 
568dee89c4dSMark Brown static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
569dee89c4dSMark Brown 				 struct snd_soc_dai *dai)
570b7482f52SPhilipp Zabel {
571b40822d9SKuninori Morimoto 	struct snd_soc_component *component = dai->component;
572b40822d9SKuninori Morimoto 	u16 clk = uda1380_read_reg_cache(component, UDA1380_CLK);
573b7482f52SPhilipp Zabel 
574b7482f52SPhilipp Zabel 	/* shut down WSPLL power if running from this clock */
575b7482f52SPhilipp Zabel 	if (clk & R00_DAC_CLK) {
576b40822d9SKuninori Morimoto 		u16 pm = uda1380_read_reg_cache(component, UDA1380_PM);
577b40822d9SKuninori Morimoto 		uda1380_write(component, UDA1380_PM, ~R02_PON_PLL & pm);
578b7482f52SPhilipp Zabel 	}
579b7482f52SPhilipp Zabel 
580b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
581b7482f52SPhilipp Zabel 		clk &= ~(R00_EN_DAC | R00_EN_INT);
582b7482f52SPhilipp Zabel 	else
583b7482f52SPhilipp Zabel 		clk &= ~(R00_EN_ADC | R00_EN_DEC);
584b7482f52SPhilipp Zabel 
585b40822d9SKuninori Morimoto 	uda1380_write(component, UDA1380_CLK, clk);
586b7482f52SPhilipp Zabel }
587b7482f52SPhilipp Zabel 
588b40822d9SKuninori Morimoto static int uda1380_set_bias_level(struct snd_soc_component *component,
589b7482f52SPhilipp Zabel 	enum snd_soc_bias_level level)
590b7482f52SPhilipp Zabel {
591b40822d9SKuninori Morimoto 	int pm = uda1380_read_reg_cache(component, UDA1380_PM);
5928614d310SVasily Khoruzhick 	int reg;
593b40822d9SKuninori Morimoto 	struct uda1380_platform_data *pdata = component->dev->platform_data;
5948614d310SVasily Khoruzhick 
595b7482f52SPhilipp Zabel 	switch (level) {
596b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_ON:
597b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_PREPARE:
5988614d310SVasily Khoruzhick 		/* ADC, DAC on */
599b40822d9SKuninori Morimoto 		uda1380_write(component, UDA1380_PM, R02_PON_BIAS | pm);
600b7482f52SPhilipp Zabel 		break;
601b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_STANDBY:
602b40822d9SKuninori Morimoto 		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
6038614d310SVasily Khoruzhick 			if (gpio_is_valid(pdata->gpio_power)) {
6048614d310SVasily Khoruzhick 				gpio_set_value(pdata->gpio_power, 1);
6058e3dce4dSVasily Khoruzhick 				mdelay(1);
606b40822d9SKuninori Morimoto 				uda1380_reset(component);
6078614d310SVasily Khoruzhick 			}
6088614d310SVasily Khoruzhick 
609b40822d9SKuninori Morimoto 			uda1380_sync_cache(component);
6108614d310SVasily Khoruzhick 		}
611b40822d9SKuninori Morimoto 		uda1380_write(component, UDA1380_PM, 0x0);
612b7482f52SPhilipp Zabel 		break;
6138614d310SVasily Khoruzhick 	case SND_SOC_BIAS_OFF:
6148614d310SVasily Khoruzhick 		if (!gpio_is_valid(pdata->gpio_power))
6158614d310SVasily Khoruzhick 			break;
6168614d310SVasily Khoruzhick 
6178614d310SVasily Khoruzhick 		gpio_set_value(pdata->gpio_power, 0);
6188614d310SVasily Khoruzhick 
6198614d310SVasily Khoruzhick 		/* Mark mixer regs cache dirty to sync them with
6208614d310SVasily Khoruzhick 		 * codec regs on power on.
6218614d310SVasily Khoruzhick 		 */
6228614d310SVasily Khoruzhick 		for (reg = UDA1380_MVOL; reg < UDA1380_CACHEREGNUM; reg++)
6238614d310SVasily Khoruzhick 			set_bit(reg - 0x10, &uda1380_cache_dirty);
624b7482f52SPhilipp Zabel 	}
625b7482f52SPhilipp Zabel 	return 0;
626b7482f52SPhilipp Zabel }
627b7482f52SPhilipp Zabel 
628b7482f52SPhilipp Zabel #define UDA1380_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
629b7482f52SPhilipp Zabel 		       SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
630b7482f52SPhilipp Zabel 		       SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
631b7482f52SPhilipp Zabel 
63285e7652dSLars-Peter Clausen static const struct snd_soc_dai_ops uda1380_dai_ops = {
6336335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
6346335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
63565ec1cd1SMark Brown 	.trigger	= uda1380_trigger,
6366335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_both,
6376335d055SEric Miao };
6386335d055SEric Miao 
63985e7652dSLars-Peter Clausen static const struct snd_soc_dai_ops uda1380_dai_ops_playback = {
6406335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
6416335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
64265ec1cd1SMark Brown 	.trigger	= uda1380_trigger,
6436335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_playback,
6446335d055SEric Miao };
6456335d055SEric Miao 
64685e7652dSLars-Peter Clausen static const struct snd_soc_dai_ops uda1380_dai_ops_capture = {
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_capture,
6516335d055SEric Miao };
6526335d055SEric Miao 
653f0fba2adSLiam Girdwood static struct snd_soc_dai_driver uda1380_dai[] = {
654b7482f52SPhilipp Zabel {
655f0fba2adSLiam Girdwood 	.name = "uda1380-hifi",
656b7482f52SPhilipp Zabel 	.playback = {
657b7482f52SPhilipp Zabel 		.stream_name = "Playback",
658b7482f52SPhilipp Zabel 		.channels_min = 1,
659b7482f52SPhilipp Zabel 		.channels_max = 2,
660b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
661b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
662b7482f52SPhilipp Zabel 	.capture = {
663b7482f52SPhilipp Zabel 		.stream_name = "Capture",
664b7482f52SPhilipp Zabel 		.channels_min = 1,
665b7482f52SPhilipp Zabel 		.channels_max = 2,
666b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
667b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
6686335d055SEric Miao 	.ops = &uda1380_dai_ops,
669b7482f52SPhilipp Zabel },
670b7482f52SPhilipp Zabel { /* playback only - dual interface */
671f0fba2adSLiam Girdwood 	.name = "uda1380-hifi-playback",
672b7482f52SPhilipp Zabel 	.playback = {
673b7482f52SPhilipp Zabel 		.stream_name = "Playback",
674b7482f52SPhilipp Zabel 		.channels_min = 1,
675b7482f52SPhilipp Zabel 		.channels_max = 2,
676b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
677b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
678b7482f52SPhilipp Zabel 	},
6796335d055SEric Miao 	.ops = &uda1380_dai_ops_playback,
680b7482f52SPhilipp Zabel },
681b7482f52SPhilipp Zabel { /* capture only - dual interface*/
682f0fba2adSLiam Girdwood 	.name = "uda1380-hifi-capture",
683b7482f52SPhilipp Zabel 	.capture = {
684b7482f52SPhilipp Zabel 		.stream_name = "Capture",
685b7482f52SPhilipp Zabel 		.channels_min = 1,
686b7482f52SPhilipp Zabel 		.channels_max = 2,
687b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
688b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
689b7482f52SPhilipp Zabel 	},
6906335d055SEric Miao 	.ops = &uda1380_dai_ops_capture,
691b7482f52SPhilipp Zabel },
692b7482f52SPhilipp Zabel };
693b7482f52SPhilipp Zabel 
694b40822d9SKuninori Morimoto static int uda1380_probe(struct snd_soc_component *component)
695b7482f52SPhilipp Zabel {
696b40822d9SKuninori Morimoto 	struct uda1380_platform_data *pdata =component->dev->platform_data;
697b40822d9SKuninori Morimoto 	struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
698f0fba2adSLiam Girdwood 	int ret;
699b7482f52SPhilipp Zabel 
700b40822d9SKuninori Morimoto 	uda1380->component = component;
701b7482f52SPhilipp Zabel 
702222e728cSLars-Peter Clausen 	if (!gpio_is_valid(pdata->gpio_power)) {
703b40822d9SKuninori Morimoto 		ret = uda1380_reset(component);
70468020db8SAxel Lin 		if (ret)
705222e728cSLars-Peter Clausen 			return ret;
7068614d310SVasily Khoruzhick 	}
707b7482f52SPhilipp Zabel 
708f0fba2adSLiam Girdwood 	INIT_WORK(&uda1380->work, uda1380_flush_work);
709f0fba2adSLiam Girdwood 
710b7482f52SPhilipp Zabel 	/* set clock input */
7111abd9184SPhilipp Zabel 	switch (pdata->dac_clk) {
712b7482f52SPhilipp Zabel 	case UDA1380_DAC_CLK_SYSCLK:
713b40822d9SKuninori Morimoto 		uda1380_write_reg_cache(component, UDA1380_CLK, 0);
714b7482f52SPhilipp Zabel 		break;
715b7482f52SPhilipp Zabel 	case UDA1380_DAC_CLK_WSPLL:
716b40822d9SKuninori Morimoto 		uda1380_write_reg_cache(component, UDA1380_CLK,
7178614d310SVasily Khoruzhick 			R00_DAC_CLK);
718b7482f52SPhilipp Zabel 		break;
719b7482f52SPhilipp Zabel 	}
720b7482f52SPhilipp Zabel 
7211abd9184SPhilipp Zabel 	return 0;
7221abd9184SPhilipp Zabel }
723b7482f52SPhilipp Zabel 
724b40822d9SKuninori Morimoto static const struct snd_soc_component_driver soc_component_dev_uda1380 = {
725f0fba2adSLiam Girdwood 	.probe			= uda1380_probe,
7267604d806SKuninori Morimoto 	.read			= uda1380_read_reg_cache,
7277604d806SKuninori Morimoto 	.write			= uda1380_write,
728f0fba2adSLiam Girdwood 	.set_bias_level		= uda1380_set_bias_level,
72958fa8e45SAxel Lin 	.controls		= uda1380_snd_controls,
73058fa8e45SAxel Lin 	.num_controls		= ARRAY_SIZE(uda1380_snd_controls),
73158fa8e45SAxel Lin 	.dapm_widgets		= uda1380_dapm_widgets,
73258fa8e45SAxel Lin 	.num_dapm_widgets	= ARRAY_SIZE(uda1380_dapm_widgets),
73358fa8e45SAxel Lin 	.dapm_routes		= uda1380_dapm_routes,
73458fa8e45SAxel Lin 	.num_dapm_routes	= ARRAY_SIZE(uda1380_dapm_routes),
735b40822d9SKuninori Morimoto 	.suspend_bias_off	= 1,
736b40822d9SKuninori Morimoto 	.idle_bias_on		= 1,
737b40822d9SKuninori Morimoto 	.use_pmdown_time	= 1,
738b40822d9SKuninori Morimoto 	.endianness		= 1,
739b40822d9SKuninori Morimoto 	.non_legacy_dai_naming	= 1,
740f0fba2adSLiam Girdwood };
741f0fba2adSLiam Girdwood 
7427a79e94eSBill Pemberton static int uda1380_i2c_probe(struct i2c_client *i2c,
74388fc39d7SJean Delvare 			     const struct i2c_device_id *id)
744b7482f52SPhilipp Zabel {
745222e728cSLars-Peter Clausen 	struct uda1380_platform_data *pdata = i2c->dev.platform_data;
7461abd9184SPhilipp Zabel 	struct uda1380_priv *uda1380;
747b7482f52SPhilipp Zabel 	int ret;
748b7482f52SPhilipp Zabel 
749222e728cSLars-Peter Clausen 	if (!pdata)
750222e728cSLars-Peter Clausen 		return -EINVAL;
751222e728cSLars-Peter Clausen 
7526ce91ad4SAxel Lin 	uda1380 = devm_kzalloc(&i2c->dev, sizeof(struct uda1380_priv),
7536ce91ad4SAxel Lin 			       GFP_KERNEL);
7541abd9184SPhilipp Zabel 	if (uda1380 == NULL)
7551abd9184SPhilipp Zabel 		return -ENOMEM;
7561abd9184SPhilipp Zabel 
757222e728cSLars-Peter Clausen 	if (gpio_is_valid(pdata->gpio_reset)) {
758222e728cSLars-Peter Clausen 		ret = devm_gpio_request_one(&i2c->dev, pdata->gpio_reset,
759222e728cSLars-Peter Clausen 			GPIOF_OUT_INIT_LOW, "uda1380 reset");
760222e728cSLars-Peter Clausen 		if (ret)
761222e728cSLars-Peter Clausen 			return ret;
762222e728cSLars-Peter Clausen 	}
763222e728cSLars-Peter Clausen 
764222e728cSLars-Peter Clausen 	if (gpio_is_valid(pdata->gpio_power)) {
765222e728cSLars-Peter Clausen 		ret = devm_gpio_request_one(&i2c->dev, pdata->gpio_power,
766222e728cSLars-Peter Clausen 			GPIOF_OUT_INIT_LOW, "uda1380 power");
767222e728cSLars-Peter Clausen 		if (ret)
768222e728cSLars-Peter Clausen 			return ret;
769222e728cSLars-Peter Clausen 	}
770222e728cSLars-Peter Clausen 
771c001bf63SKuninori Morimoto 	uda1380->reg_cache = devm_kmemdup(&i2c->dev,
772c001bf63SKuninori Morimoto 					uda1380_reg,
773c001bf63SKuninori Morimoto 					ARRAY_SIZE(uda1380_reg) * sizeof(u16),
774c001bf63SKuninori Morimoto 					GFP_KERNEL);
775c001bf63SKuninori Morimoto 	if (!uda1380->reg_cache)
776c001bf63SKuninori Morimoto 		return -ENOMEM;
777c001bf63SKuninori Morimoto 
7781abd9184SPhilipp Zabel 	i2c_set_clientdata(i2c, uda1380);
779eaa53216SKuninori Morimoto 	uda1380->i2c = i2c;
780b7482f52SPhilipp Zabel 
781b40822d9SKuninori Morimoto 	ret = devm_snd_soc_register_component(&i2c->dev,
782b40822d9SKuninori Morimoto 			&soc_component_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
783b7482f52SPhilipp Zabel 	return ret;
784b7482f52SPhilipp Zabel }
785b7482f52SPhilipp Zabel 
78688fc39d7SJean Delvare static const struct i2c_device_id uda1380_i2c_id[] = {
78788fc39d7SJean Delvare 	{ "uda1380", 0 },
78888fc39d7SJean Delvare 	{ }
78988fc39d7SJean Delvare };
79088fc39d7SJean Delvare MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
791b7482f52SPhilipp Zabel 
792ea22a26eSJavier Martinez Canillas static const struct of_device_id uda1380_of_match[] = {
793ea22a26eSJavier Martinez Canillas 	{ .compatible = "nxp,uda1380", },
794ea22a26eSJavier Martinez Canillas 	{ }
795ea22a26eSJavier Martinez Canillas };
796ea22a26eSJavier Martinez Canillas MODULE_DEVICE_TABLE(of, uda1380_of_match);
797ea22a26eSJavier Martinez Canillas 
798b7482f52SPhilipp Zabel static struct i2c_driver uda1380_i2c_driver = {
799b7482f52SPhilipp Zabel 	.driver = {
800f0fba2adSLiam Girdwood 		.name =  "uda1380-codec",
801ea22a26eSJavier Martinez Canillas 		.of_match_table = uda1380_of_match,
802b7482f52SPhilipp Zabel 	},
80388fc39d7SJean Delvare 	.probe =    uda1380_i2c_probe,
80488fc39d7SJean Delvare 	.id_table = uda1380_i2c_id,
805b7482f52SPhilipp Zabel };
806b7482f52SPhilipp Zabel 
8074a5cf132SKuninori Morimoto module_i2c_driver(uda1380_i2c_driver);
80864089b84SMark Brown 
809b7482f52SPhilipp Zabel MODULE_AUTHOR("Giorgio Padrin");
810b7482f52SPhilipp Zabel MODULE_DESCRIPTION("Audio support for codec Philips UDA1380");
811b7482f52SPhilipp Zabel MODULE_LICENSE("GPL");
812