xref: /linux/sound/soc/codecs/uda1380.c (revision 6335d05548eece40092000aa91b64a50310d69d5)
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  *
8b7482f52SPhilipp Zabel  * Copyright (c) 2007 Philipp Zabel <philipp.zabel@gmail.com>
9b7482f52SPhilipp Zabel  * Improved support for DAPM and audio routing/mixing capabilities,
10b7482f52SPhilipp Zabel  * added TLV support.
11b7482f52SPhilipp Zabel  *
12b7482f52SPhilipp Zabel  * Modified by Richard Purdie <richard@openedhand.com> to fit into SoC
13b7482f52SPhilipp Zabel  * codec model.
14b7482f52SPhilipp Zabel  *
15b7482f52SPhilipp Zabel  * Copyright (c) 2005 Giorgio Padrin <giorgio@mandarinlogiq.org>
16b7482f52SPhilipp Zabel  * Copyright 2005 Openedhand Ltd.
17b7482f52SPhilipp Zabel  */
18b7482f52SPhilipp Zabel 
19b7482f52SPhilipp Zabel #include <linux/module.h>
20b7482f52SPhilipp Zabel #include <linux/init.h>
21b7482f52SPhilipp Zabel #include <linux/types.h>
22b7482f52SPhilipp Zabel #include <linux/string.h>
23b7482f52SPhilipp Zabel #include <linux/slab.h>
24b7482f52SPhilipp Zabel #include <linux/errno.h>
25b7482f52SPhilipp Zabel #include <linux/ioctl.h>
26b7482f52SPhilipp Zabel #include <linux/delay.h>
27b7482f52SPhilipp Zabel #include <linux/i2c.h>
28b7482f52SPhilipp Zabel #include <sound/core.h>
29b7482f52SPhilipp Zabel #include <sound/control.h>
30b7482f52SPhilipp Zabel #include <sound/initval.h>
31b7482f52SPhilipp Zabel #include <sound/info.h>
32b7482f52SPhilipp Zabel #include <sound/soc.h>
33b7482f52SPhilipp Zabel #include <sound/soc-dapm.h>
34b7482f52SPhilipp Zabel #include <sound/tlv.h>
35b7482f52SPhilipp Zabel 
36b7482f52SPhilipp Zabel #include "uda1380.h"
37b7482f52SPhilipp Zabel 
38b7482f52SPhilipp Zabel #define UDA1380_VERSION "0.6"
39b7482f52SPhilipp Zabel 
40b7482f52SPhilipp Zabel /*
41b7482f52SPhilipp Zabel  * uda1380 register cache
42b7482f52SPhilipp Zabel  */
43b7482f52SPhilipp Zabel static const u16 uda1380_reg[UDA1380_CACHEREGNUM] = {
44b7482f52SPhilipp Zabel 	0x0502, 0x0000, 0x0000, 0x3f3f,
45b7482f52SPhilipp Zabel 	0x0202, 0x0000, 0x0000, 0x0000,
46b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
47b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
48b7482f52SPhilipp Zabel 	0x0000, 0xff00, 0x0000, 0x4800,
49b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
50b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
51b7482f52SPhilipp Zabel 	0x0000, 0x0000, 0x0000, 0x0000,
52b7482f52SPhilipp Zabel 	0x0000, 0x8000, 0x0002, 0x0000,
53b7482f52SPhilipp Zabel };
54b7482f52SPhilipp Zabel 
55b7482f52SPhilipp Zabel /*
56b7482f52SPhilipp Zabel  * read uda1380 register cache
57b7482f52SPhilipp Zabel  */
58b7482f52SPhilipp Zabel static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec,
59b7482f52SPhilipp Zabel 	unsigned int reg)
60b7482f52SPhilipp Zabel {
61b7482f52SPhilipp Zabel 	u16 *cache = codec->reg_cache;
62b7482f52SPhilipp Zabel 	if (reg == UDA1380_RESET)
63b7482f52SPhilipp Zabel 		return 0;
64b7482f52SPhilipp Zabel 	if (reg >= UDA1380_CACHEREGNUM)
65b7482f52SPhilipp Zabel 		return -1;
66b7482f52SPhilipp Zabel 	return cache[reg];
67b7482f52SPhilipp Zabel }
68b7482f52SPhilipp Zabel 
69b7482f52SPhilipp Zabel /*
70b7482f52SPhilipp Zabel  * write uda1380 register cache
71b7482f52SPhilipp Zabel  */
72b7482f52SPhilipp Zabel static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
73b7482f52SPhilipp Zabel 	u16 reg, unsigned int value)
74b7482f52SPhilipp Zabel {
75b7482f52SPhilipp Zabel 	u16 *cache = codec->reg_cache;
76b7482f52SPhilipp Zabel 	if (reg >= UDA1380_CACHEREGNUM)
77b7482f52SPhilipp Zabel 		return;
78b7482f52SPhilipp Zabel 	cache[reg] = value;
79b7482f52SPhilipp Zabel }
80b7482f52SPhilipp Zabel 
81b7482f52SPhilipp Zabel /*
82b7482f52SPhilipp Zabel  * write to the UDA1380 register space
83b7482f52SPhilipp Zabel  */
84b7482f52SPhilipp Zabel static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
85b7482f52SPhilipp Zabel 	unsigned int value)
86b7482f52SPhilipp Zabel {
87b7482f52SPhilipp Zabel 	u8 data[3];
88b7482f52SPhilipp Zabel 
89b7482f52SPhilipp Zabel 	/* data is
90b7482f52SPhilipp Zabel 	 *   data[0] is register offset
91b7482f52SPhilipp Zabel 	 *   data[1] is MS byte
92b7482f52SPhilipp Zabel 	 *   data[2] is LS byte
93b7482f52SPhilipp Zabel 	 */
94b7482f52SPhilipp Zabel 	data[0] = reg;
95b7482f52SPhilipp Zabel 	data[1] = (value & 0xff00) >> 8;
96b7482f52SPhilipp Zabel 	data[2] = value & 0x00ff;
97b7482f52SPhilipp Zabel 
98b7482f52SPhilipp Zabel 	uda1380_write_reg_cache(codec, reg, value);
99b7482f52SPhilipp Zabel 
100b7482f52SPhilipp Zabel 	/* the interpolator & decimator regs must only be written when the
101b7482f52SPhilipp Zabel 	 * codec DAI is active.
102b7482f52SPhilipp Zabel 	 */
103b7482f52SPhilipp Zabel 	if (!codec->active && (reg >= UDA1380_MVOL))
104b7482f52SPhilipp Zabel 		return 0;
105b7482f52SPhilipp Zabel 	pr_debug("uda1380: hw write %x val %x\n", reg, value);
106b7482f52SPhilipp Zabel 	if (codec->hw_write(codec->control_data, data, 3) == 3) {
107b7482f52SPhilipp Zabel 		unsigned int val;
108b7482f52SPhilipp Zabel 		i2c_master_send(codec->control_data, data, 1);
109b7482f52SPhilipp Zabel 		i2c_master_recv(codec->control_data, data, 2);
110b7482f52SPhilipp Zabel 		val = (data[0]<<8) | data[1];
111b7482f52SPhilipp Zabel 		if (val != value) {
112b7482f52SPhilipp Zabel 			pr_debug("uda1380: READ BACK VAL %x\n",
113b7482f52SPhilipp Zabel 					(data[0]<<8) | data[1]);
114b7482f52SPhilipp Zabel 			return -EIO;
115b7482f52SPhilipp Zabel 		}
116b7482f52SPhilipp Zabel 		return 0;
117b7482f52SPhilipp Zabel 	} else
118b7482f52SPhilipp Zabel 		return -EIO;
119b7482f52SPhilipp Zabel }
120b7482f52SPhilipp Zabel 
121b7482f52SPhilipp Zabel #define uda1380_reset(c)	uda1380_write(c, UDA1380_RESET, 0)
122b7482f52SPhilipp Zabel 
123b7482f52SPhilipp Zabel /* declarations of ALSA reg_elem_REAL controls */
124b7482f52SPhilipp Zabel static const char *uda1380_deemp[] = {
125b7482f52SPhilipp Zabel 	"None",
126b7482f52SPhilipp Zabel 	"32kHz",
127b7482f52SPhilipp Zabel 	"44.1kHz",
128b7482f52SPhilipp Zabel 	"48kHz",
129b7482f52SPhilipp Zabel 	"96kHz",
130b7482f52SPhilipp Zabel };
131b7482f52SPhilipp Zabel static const char *uda1380_input_sel[] = {
132b7482f52SPhilipp Zabel 	"Line",
133b7482f52SPhilipp Zabel 	"Mic + Line R",
134b7482f52SPhilipp Zabel 	"Line L",
135b7482f52SPhilipp Zabel 	"Mic",
136b7482f52SPhilipp Zabel };
137b7482f52SPhilipp Zabel static const char *uda1380_output_sel[] = {
138b7482f52SPhilipp Zabel 	"DAC",
139b7482f52SPhilipp Zabel 	"Analog Mixer",
140b7482f52SPhilipp Zabel };
141b7482f52SPhilipp Zabel static const char *uda1380_spf_mode[] = {
142b7482f52SPhilipp Zabel 	"Flat",
143b7482f52SPhilipp Zabel 	"Minimum1",
144b7482f52SPhilipp Zabel 	"Minimum2",
145b7482f52SPhilipp Zabel 	"Maximum"
146b7482f52SPhilipp Zabel };
147b7482f52SPhilipp Zabel static const char *uda1380_capture_sel[] = {
148b7482f52SPhilipp Zabel 	"ADC",
149b7482f52SPhilipp Zabel 	"Digital Mixer"
150b7482f52SPhilipp Zabel };
151b7482f52SPhilipp Zabel static const char *uda1380_sel_ns[] = {
152b7482f52SPhilipp Zabel 	"3rd-order",
153b7482f52SPhilipp Zabel 	"5th-order"
154b7482f52SPhilipp Zabel };
155b7482f52SPhilipp Zabel static const char *uda1380_mix_control[] = {
156b7482f52SPhilipp Zabel 	"off",
157b7482f52SPhilipp Zabel 	"PCM only",
158b7482f52SPhilipp Zabel 	"before sound processing",
159b7482f52SPhilipp Zabel 	"after sound processing"
160b7482f52SPhilipp Zabel };
161b7482f52SPhilipp Zabel static const char *uda1380_sdet_setting[] = {
162b7482f52SPhilipp Zabel 	"3200",
163b7482f52SPhilipp Zabel 	"4800",
164b7482f52SPhilipp Zabel 	"9600",
165b7482f52SPhilipp Zabel 	"19200"
166b7482f52SPhilipp Zabel };
167b7482f52SPhilipp Zabel static const char *uda1380_os_setting[] = {
168b7482f52SPhilipp Zabel 	"single-speed",
169b7482f52SPhilipp Zabel 	"double-speed (no mixing)",
170b7482f52SPhilipp Zabel 	"quad-speed (no mixing)"
171b7482f52SPhilipp Zabel };
172b7482f52SPhilipp Zabel 
173b7482f52SPhilipp Zabel static const struct soc_enum uda1380_deemp_enum[] = {
174b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_DEEMP, 8, 5, uda1380_deemp),
175b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_DEEMP, 0, 5, uda1380_deemp),
176b7482f52SPhilipp Zabel };
177b7482f52SPhilipp Zabel static const struct soc_enum uda1380_input_sel_enum =
178b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_ADC, 2, 4, uda1380_input_sel);		/* SEL_MIC, SEL_LNA */
179b7482f52SPhilipp Zabel static const struct soc_enum uda1380_output_sel_enum =
180b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_PM, 7, 2, uda1380_output_sel);		/* R02_EN_AVC */
181b7482f52SPhilipp Zabel static const struct soc_enum uda1380_spf_enum =
182b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MODE, 14, 4, uda1380_spf_mode);		/* M */
183b7482f52SPhilipp Zabel static const struct soc_enum uda1380_capture_sel_enum =
184b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_IFACE, 6, 2, uda1380_capture_sel);	/* SEL_SOURCE */
185b7482f52SPhilipp Zabel static const struct soc_enum uda1380_sel_ns_enum =
186b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 14, 2, uda1380_sel_ns);		/* SEL_NS */
187b7482f52SPhilipp Zabel static const struct soc_enum uda1380_mix_enum =
188b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 12, 4, uda1380_mix_control);	/* MIX, MIX_POS */
189b7482f52SPhilipp Zabel static const struct soc_enum uda1380_sdet_enum =
190b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 4, 4, uda1380_sdet_setting);	/* SD_VALUE */
191b7482f52SPhilipp Zabel static const struct soc_enum uda1380_os_enum =
192b7482f52SPhilipp Zabel 	SOC_ENUM_SINGLE(UDA1380_MIXER, 0, 3, uda1380_os_setting);	/* OS */
193b7482f52SPhilipp Zabel 
194b7482f52SPhilipp Zabel /*
195b7482f52SPhilipp Zabel  * from -48 dB in 1.5 dB steps (mute instead of -49.5 dB)
196b7482f52SPhilipp Zabel  */
197b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(amix_tlv, -4950, 150, 1);
198b7482f52SPhilipp Zabel 
199b7482f52SPhilipp Zabel /*
200b7482f52SPhilipp Zabel  * from -78 dB in 1 dB steps (3 dB steps, really. LSB are ignored),
201b7482f52SPhilipp Zabel  * from -66 dB in 0.5 dB steps (2 dB steps, really) and
202b7482f52SPhilipp Zabel  * from -52 dB in 0.25 dB steps
203b7482f52SPhilipp Zabel  */
204b7482f52SPhilipp Zabel static const unsigned int mvol_tlv[] = {
205b7482f52SPhilipp Zabel 	TLV_DB_RANGE_HEAD(3),
206b7482f52SPhilipp Zabel 	0, 15, TLV_DB_SCALE_ITEM(-8200, 100, 1),
207b7482f52SPhilipp Zabel 	16, 43, TLV_DB_SCALE_ITEM(-6600, 50, 0),
208b7482f52SPhilipp Zabel 	44, 252, TLV_DB_SCALE_ITEM(-5200, 25, 0),
209b7482f52SPhilipp Zabel };
210b7482f52SPhilipp Zabel 
211b7482f52SPhilipp Zabel /*
212b7482f52SPhilipp Zabel  * from -72 dB in 1.5 dB steps (6 dB steps really),
213b7482f52SPhilipp Zabel  * from -66 dB in 0.75 dB steps (3 dB steps really),
214b7482f52SPhilipp Zabel  * from -60 dB in 0.5 dB steps (2 dB steps really) and
215b7482f52SPhilipp Zabel  * from -46 dB in 0.25 dB steps
216b7482f52SPhilipp Zabel  */
217b7482f52SPhilipp Zabel static const unsigned int vc_tlv[] = {
218b7482f52SPhilipp Zabel 	TLV_DB_RANGE_HEAD(4),
219b7482f52SPhilipp Zabel 	0, 7, TLV_DB_SCALE_ITEM(-7800, 150, 1),
220b7482f52SPhilipp Zabel 	8, 15, TLV_DB_SCALE_ITEM(-6600, 75, 0),
221b7482f52SPhilipp Zabel 	16, 43, TLV_DB_SCALE_ITEM(-6000, 50, 0),
222b7482f52SPhilipp Zabel 	44, 228, TLV_DB_SCALE_ITEM(-4600, 25, 0),
223b7482f52SPhilipp Zabel };
224b7482f52SPhilipp Zabel 
225b7482f52SPhilipp Zabel /* from 0 to 6 dB in 2 dB steps if SPF mode != flat */
226b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(tr_tlv, 0, 200, 0);
227b7482f52SPhilipp Zabel 
228b7482f52SPhilipp Zabel /* from 0 to 24 dB in 2 dB steps, if SPF mode == maximum, otherwise cuts
229b7482f52SPhilipp Zabel  * off at 18 dB max) */
230b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(bb_tlv, 0, 200, 0);
231b7482f52SPhilipp Zabel 
232b7482f52SPhilipp Zabel /* from -63 to 24 dB in 0.5 dB steps (-128...48) */
233b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(dec_tlv, -6400, 50, 1);
234b7482f52SPhilipp Zabel 
235b7482f52SPhilipp Zabel /* from 0 to 24 dB in 3 dB steps */
236b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0);
237b7482f52SPhilipp Zabel 
238b7482f52SPhilipp Zabel /* from 0 to 30 dB in 2 dB steps */
239b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(vga_tlv, 0, 200, 0);
240b7482f52SPhilipp Zabel 
241b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_snd_controls[] = {
242b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Analog Mixer Volume", UDA1380_AMIX, 0, 8, 44, 1, amix_tlv),	/* AVCR, AVCL */
243b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Master Playback Volume", UDA1380_MVOL, 0, 8, 252, 1, mvol_tlv),	/* MVCL, MVCR */
244b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("ADC Playback Volume", UDA1380_MIXVOL, 8, 228, 1, vc_tlv),	/* VC2 */
245b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("PCM Playback Volume", UDA1380_MIXVOL, 0, 228, 1, vc_tlv),	/* VC1 */
246b7482f52SPhilipp Zabel 	SOC_ENUM("Sound Processing Filter", uda1380_spf_enum),				/* M */
247b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Tone Control - Treble", UDA1380_MODE, 4, 12, 3, 0, tr_tlv), 	/* TRL, TRR */
248b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Tone Control - Bass", UDA1380_MODE, 0, 8, 15, 0, bb_tlv),	/* BBL, BBR */
249b7482f52SPhilipp Zabel /**/	SOC_SINGLE("Master Playback Switch", UDA1380_DEEMP, 14, 1, 1),		/* MTM */
250b7482f52SPhilipp Zabel 	SOC_SINGLE("ADC Playback Switch", UDA1380_DEEMP, 11, 1, 1),		/* MT2 from decimation filter */
251b7482f52SPhilipp Zabel 	SOC_ENUM("ADC Playback De-emphasis", uda1380_deemp_enum[0]),		/* DE2 */
252b7482f52SPhilipp Zabel 	SOC_SINGLE("PCM Playback Switch", UDA1380_DEEMP, 3, 1, 1),		/* MT1, from digital data input */
253b7482f52SPhilipp Zabel 	SOC_ENUM("PCM Playback De-emphasis", uda1380_deemp_enum[1]),		/* DE1 */
254b7482f52SPhilipp Zabel 	SOC_SINGLE("DAC Polarity inverting Switch", UDA1380_MIXER, 15, 1, 0),	/* DA_POL_INV */
255b7482f52SPhilipp Zabel 	SOC_ENUM("Noise Shaper", uda1380_sel_ns_enum),				/* SEL_NS */
256b7482f52SPhilipp Zabel 	SOC_ENUM("Digital Mixer Signal Control", uda1380_mix_enum),		/* MIX_POS, MIX */
257b7482f52SPhilipp Zabel 	SOC_SINGLE("Silence Switch", UDA1380_MIXER, 7, 1, 0),			/* SILENCE, force DAC output to silence */
258b7482f52SPhilipp Zabel 	SOC_SINGLE("Silence Detector Switch", UDA1380_MIXER, 6, 1, 0),		/* SDET_ON */
259b7482f52SPhilipp Zabel 	SOC_ENUM("Silence Detector Setting", uda1380_sdet_enum),		/* SD_VALUE */
260b7482f52SPhilipp Zabel 	SOC_ENUM("Oversampling Input", uda1380_os_enum),			/* OS */
261b7482f52SPhilipp Zabel 	SOC_DOUBLE_S8_TLV("ADC Capture Volume", UDA1380_DEC, -128, 48, dec_tlv),	/* ML_DEC, MR_DEC */
262b7482f52SPhilipp Zabel /**/	SOC_SINGLE("ADC Capture Switch", UDA1380_PGA, 15, 1, 1),		/* MT_ADC */
263b7482f52SPhilipp Zabel 	SOC_DOUBLE_TLV("Line Capture Volume", UDA1380_PGA, 0, 8, 8, 0, pga_tlv), /* PGA_GAINCTRLL, PGA_GAINCTRLR */
264b7482f52SPhilipp Zabel 	SOC_SINGLE("ADC Polarity inverting Switch", UDA1380_ADC, 12, 1, 0),	/* ADCPOL_INV */
265b7482f52SPhilipp Zabel 	SOC_SINGLE_TLV("Mic Capture Volume", UDA1380_ADC, 8, 15, 0, vga_tlv),	/* VGA_CTRL */
266b7482f52SPhilipp Zabel 	SOC_SINGLE("DC Filter Bypass Switch", UDA1380_ADC, 1, 1, 0),		/* SKIP_DCFIL (before decimator) */
267b7482f52SPhilipp Zabel 	SOC_SINGLE("DC Filter Enable Switch", UDA1380_ADC, 0, 1, 0),		/* EN_DCFIL (at output of decimator) */
268b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Timing", UDA1380_AGC, 8, 7, 0),			/* TODO: enum, see table 62 */
269b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Target level", UDA1380_AGC, 2, 3, 1),			/* AGC_LEVEL */
270b7482f52SPhilipp Zabel 	/* -5.5, -8, -11.5, -14 dBFS */
271b7482f52SPhilipp Zabel 	SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0),
272b7482f52SPhilipp Zabel };
273b7482f52SPhilipp Zabel 
274b7482f52SPhilipp Zabel /* Input mux */
275b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_input_mux_control =
276b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_input_sel_enum);
277b7482f52SPhilipp Zabel 
278b7482f52SPhilipp Zabel /* Output mux */
279b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_output_mux_control =
280b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_output_sel_enum);
281b7482f52SPhilipp Zabel 
282b7482f52SPhilipp Zabel /* Capture mux */
283b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_capture_mux_control =
284b7482f52SPhilipp Zabel 	SOC_DAPM_ENUM("Route", uda1380_capture_sel_enum);
285b7482f52SPhilipp Zabel 
286b7482f52SPhilipp Zabel 
287b7482f52SPhilipp Zabel static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
288b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
289b7482f52SPhilipp Zabel 		&uda1380_input_mux_control),
290b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM, 0, 0,
291b7482f52SPhilipp Zabel 		&uda1380_output_mux_control),
292b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0,
293b7482f52SPhilipp Zabel 		&uda1380_capture_mux_control),
294b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Left PGA", UDA1380_PM, 3, 0, NULL, 0),
295b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Right PGA", UDA1380_PM, 1, 0, NULL, 0),
296b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("Mic LNA", UDA1380_PM, 4, 0, NULL, 0),
297b7482f52SPhilipp Zabel 	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", UDA1380_PM, 2, 0),
298b7482f52SPhilipp Zabel 	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", UDA1380_PM, 0, 0),
299b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINM"),
300b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINL"),
301b7482f52SPhilipp Zabel 	SND_SOC_DAPM_INPUT("VINR"),
302b7482f52SPhilipp Zabel 	SND_SOC_DAPM_MIXER("Analog Mixer", UDA1380_PM, 6, 0, NULL, 0),
303b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTLHP"),
304b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTRHP"),
305b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTL"),
306b7482f52SPhilipp Zabel 	SND_SOC_DAPM_OUTPUT("VOUTR"),
307b7482f52SPhilipp Zabel 	SND_SOC_DAPM_DAC("DAC", "Playback", UDA1380_PM, 10, 0),
308b7482f52SPhilipp Zabel 	SND_SOC_DAPM_PGA("HeadPhone Driver", UDA1380_PM, 13, 0, NULL, 0),
309b7482f52SPhilipp Zabel };
310b7482f52SPhilipp Zabel 
311b7482f52SPhilipp Zabel static const struct snd_soc_dapm_route audio_map[] = {
312b7482f52SPhilipp Zabel 
313b7482f52SPhilipp Zabel 	/* output mux */
314b7482f52SPhilipp Zabel 	{"HeadPhone Driver", NULL, "Output Mux"},
315b7482f52SPhilipp Zabel 	{"VOUTR", NULL, "Output Mux"},
316b7482f52SPhilipp Zabel 	{"VOUTL", NULL, "Output Mux"},
317b7482f52SPhilipp Zabel 
318b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "VINR"},
319b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "VINL"},
320b7482f52SPhilipp Zabel 	{"Analog Mixer", NULL, "DAC"},
321b7482f52SPhilipp Zabel 
322b7482f52SPhilipp Zabel 	{"Output Mux", "DAC", "DAC"},
323b7482f52SPhilipp Zabel 	{"Output Mux", "Analog Mixer", "Analog Mixer"},
324b7482f52SPhilipp Zabel 
325b7482f52SPhilipp Zabel 	/* {"DAC", "Digital Mixer", "I2S" } */
326b7482f52SPhilipp Zabel 
327b7482f52SPhilipp Zabel 	/* headphone driver */
328b7482f52SPhilipp Zabel 	{"VOUTLHP", NULL, "HeadPhone Driver"},
329b7482f52SPhilipp Zabel 	{"VOUTRHP", NULL, "HeadPhone Driver"},
330b7482f52SPhilipp Zabel 
331b7482f52SPhilipp Zabel 	/* input mux */
332b7482f52SPhilipp Zabel 	{"Left ADC", NULL, "Input Mux"},
333b7482f52SPhilipp Zabel 	{"Input Mux", "Mic", "Mic LNA"},
334b7482f52SPhilipp Zabel 	{"Input Mux", "Mic + Line R", "Mic LNA"},
335b7482f52SPhilipp Zabel 	{"Input Mux", "Line L", "Left PGA"},
336b7482f52SPhilipp Zabel 	{"Input Mux", "Line", "Left PGA"},
337b7482f52SPhilipp Zabel 
338b7482f52SPhilipp Zabel 	/* right input */
339b7482f52SPhilipp Zabel 	{"Right ADC", "Mic + Line R", "Right PGA"},
340b7482f52SPhilipp Zabel 	{"Right ADC", "Line", "Right PGA"},
341b7482f52SPhilipp Zabel 
342b7482f52SPhilipp Zabel 	/* inputs */
343b7482f52SPhilipp Zabel 	{"Mic LNA", NULL, "VINM"},
344b7482f52SPhilipp Zabel 	{"Left PGA", NULL, "VINL"},
345b7482f52SPhilipp Zabel 	{"Right PGA", NULL, "VINR"},
346b7482f52SPhilipp Zabel };
347b7482f52SPhilipp Zabel 
348b7482f52SPhilipp Zabel static int uda1380_add_widgets(struct snd_soc_codec *codec)
349b7482f52SPhilipp Zabel {
350b7482f52SPhilipp Zabel 	snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets,
351b7482f52SPhilipp Zabel 				  ARRAY_SIZE(uda1380_dapm_widgets));
352b7482f52SPhilipp Zabel 
353b7482f52SPhilipp Zabel 	snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
354b7482f52SPhilipp Zabel 
355b7482f52SPhilipp Zabel 	snd_soc_dapm_new_widgets(codec);
356b7482f52SPhilipp Zabel 	return 0;
357b7482f52SPhilipp Zabel }
358b7482f52SPhilipp Zabel 
3595b247442SPhilipp Zabel static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
360b7482f52SPhilipp Zabel 		unsigned int fmt)
361b7482f52SPhilipp Zabel {
362b7482f52SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
363b7482f52SPhilipp Zabel 	int iface;
364b7482f52SPhilipp Zabel 
365b7482f52SPhilipp Zabel 	/* set up DAI based upon fmt */
366b7482f52SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
367b7482f52SPhilipp Zabel 	iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK);
368b7482f52SPhilipp Zabel 
369b7482f52SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
370b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
371b7482f52SPhilipp Zabel 		iface |= R01_SFORI_I2S | R01_SFORO_I2S;
372b7482f52SPhilipp Zabel 		break;
373b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
3745b247442SPhilipp Zabel 		iface |= R01_SFORI_LSB16 | R01_SFORO_LSB16;
375b7482f52SPhilipp Zabel 		break;
376b7482f52SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
3775b247442SPhilipp Zabel 		iface |= R01_SFORI_MSB | R01_SFORO_MSB;
3785b247442SPhilipp Zabel 	}
3795b247442SPhilipp Zabel 
3805b247442SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
3815b247442SPhilipp Zabel 		iface |= R01_SIM;
3825b247442SPhilipp Zabel 
3835b247442SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
3845b247442SPhilipp Zabel 
3855b247442SPhilipp Zabel 	return 0;
3865b247442SPhilipp Zabel }
3875b247442SPhilipp Zabel 
3885b247442SPhilipp Zabel static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
3895b247442SPhilipp Zabel 		unsigned int fmt)
3905b247442SPhilipp Zabel {
3915b247442SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
3925b247442SPhilipp Zabel 	int iface;
3935b247442SPhilipp Zabel 
3945b247442SPhilipp Zabel 	/* set up DAI based upon fmt */
3955b247442SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
3965b247442SPhilipp Zabel 	iface &= ~R01_SFORI_MASK;
3975b247442SPhilipp Zabel 
3985b247442SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3995b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
4005b247442SPhilipp Zabel 		iface |= R01_SFORI_I2S;
4015b247442SPhilipp Zabel 		break;
4025b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4035b247442SPhilipp Zabel 		iface |= R01_SFORI_LSB16;
4045b247442SPhilipp Zabel 		break;
4055b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4065b247442SPhilipp Zabel 		iface |= R01_SFORI_MSB;
4075b247442SPhilipp Zabel 	}
4085b247442SPhilipp Zabel 
4095b247442SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
4105b247442SPhilipp Zabel 
4115b247442SPhilipp Zabel 	return 0;
4125b247442SPhilipp Zabel }
4135b247442SPhilipp Zabel 
4145b247442SPhilipp Zabel static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
4155b247442SPhilipp Zabel 		unsigned int fmt)
4165b247442SPhilipp Zabel {
4175b247442SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
4185b247442SPhilipp Zabel 	int iface;
4195b247442SPhilipp Zabel 
4205b247442SPhilipp Zabel 	/* set up DAI based upon fmt */
4215b247442SPhilipp Zabel 	iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
4225b247442SPhilipp Zabel 	iface &= ~(R01_SIM | R01_SFORO_MASK);
4235b247442SPhilipp Zabel 
4245b247442SPhilipp Zabel 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
4255b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_I2S:
4265b247442SPhilipp Zabel 		iface |= R01_SFORO_I2S;
4275b247442SPhilipp Zabel 		break;
4285b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_LSB:
4295b247442SPhilipp Zabel 		iface |= R01_SFORO_LSB16;
4305b247442SPhilipp Zabel 		break;
4315b247442SPhilipp Zabel 	case SND_SOC_DAIFMT_MSB:
4325b247442SPhilipp Zabel 		iface |= R01_SFORO_MSB;
433b7482f52SPhilipp Zabel 	}
434b7482f52SPhilipp Zabel 
435b7482f52SPhilipp Zabel 	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
436b7482f52SPhilipp Zabel 		iface |= R01_SIM;
437b7482f52SPhilipp Zabel 
438b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_IFACE, iface);
439b7482f52SPhilipp Zabel 
440b7482f52SPhilipp Zabel 	return 0;
441b7482f52SPhilipp Zabel }
442b7482f52SPhilipp Zabel 
443b7482f52SPhilipp Zabel /*
444b7482f52SPhilipp Zabel  * Flush reg cache
445b7482f52SPhilipp Zabel  * We can only write the interpolator and decimator registers
446b7482f52SPhilipp Zabel  * when the DAI is being clocked by the CPU DAI. It's up to the
447b7482f52SPhilipp Zabel  * machine and cpu DAI driver to do this before we are called.
448b7482f52SPhilipp Zabel  */
449dee89c4dSMark Brown static int uda1380_pcm_prepare(struct snd_pcm_substream *substream,
450dee89c4dSMark Brown 			       struct snd_soc_dai *dai)
451b7482f52SPhilipp Zabel {
452b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
453b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = rtd->socdev;
4546627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
455b7482f52SPhilipp Zabel 	int reg, reg_start, reg_end, clk;
456b7482f52SPhilipp Zabel 
457b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
458b7482f52SPhilipp Zabel 		reg_start = UDA1380_MVOL;
459b7482f52SPhilipp Zabel 		reg_end = UDA1380_MIXER;
460b7482f52SPhilipp Zabel 	} else {
461b7482f52SPhilipp Zabel 		reg_start = UDA1380_DEC;
462b7482f52SPhilipp Zabel 		reg_end = UDA1380_AGC;
463b7482f52SPhilipp Zabel 	}
464b7482f52SPhilipp Zabel 
465b7482f52SPhilipp Zabel 	/* FIXME disable DAC_CLK */
466b7482f52SPhilipp Zabel 	clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
467b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, clk & ~R00_DAC_CLK);
468b7482f52SPhilipp Zabel 
469b7482f52SPhilipp Zabel 	for (reg = reg_start; reg <= reg_end; reg++) {
470b7482f52SPhilipp Zabel 		pr_debug("uda1380: flush reg %x val %x:", reg,
471b7482f52SPhilipp Zabel 				uda1380_read_reg_cache(codec, reg));
472b7482f52SPhilipp Zabel 		uda1380_write(codec, reg, uda1380_read_reg_cache(codec, reg));
473b7482f52SPhilipp Zabel 	}
474b7482f52SPhilipp Zabel 
475111f6fbeSVasily Khoruzhick 	/* FIXME restore DAC_CLK */
476111f6fbeSVasily Khoruzhick 	uda1380_write(codec, UDA1380_CLK, clk);
477b7482f52SPhilipp Zabel 
478b7482f52SPhilipp Zabel 	return 0;
479b7482f52SPhilipp Zabel }
480b7482f52SPhilipp Zabel 
481b7482f52SPhilipp Zabel static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
482dee89c4dSMark Brown 				 struct snd_pcm_hw_params *params,
483dee89c4dSMark Brown 				 struct snd_soc_dai *dai)
484b7482f52SPhilipp Zabel {
485b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
486b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = rtd->socdev;
4876627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
488b7482f52SPhilipp Zabel 	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
489b7482f52SPhilipp Zabel 
490b7482f52SPhilipp Zabel 	/* set WSPLL power and divider if running from this clock */
491b7482f52SPhilipp Zabel 	if (clk & R00_DAC_CLK) {
492b7482f52SPhilipp Zabel 		int rate = params_rate(params);
493b7482f52SPhilipp Zabel 		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
494b7482f52SPhilipp Zabel 		clk &= ~0x3; /* clear SEL_LOOP_DIV */
495b7482f52SPhilipp Zabel 		switch (rate) {
496b7482f52SPhilipp Zabel 		case 6250 ... 12500:
497b7482f52SPhilipp Zabel 			clk |= 0x0;
498b7482f52SPhilipp Zabel 			break;
499b7482f52SPhilipp Zabel 		case 12501 ... 25000:
500b7482f52SPhilipp Zabel 			clk |= 0x1;
501b7482f52SPhilipp Zabel 			break;
502b7482f52SPhilipp Zabel 		case 25001 ... 50000:
503b7482f52SPhilipp Zabel 			clk |= 0x2;
504b7482f52SPhilipp Zabel 			break;
505b7482f52SPhilipp Zabel 		case 50001 ... 100000:
506b7482f52SPhilipp Zabel 			clk |= 0x3;
507b7482f52SPhilipp Zabel 			break;
508b7482f52SPhilipp Zabel 		}
509b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_PLL | pm);
510b7482f52SPhilipp Zabel 	}
511b7482f52SPhilipp Zabel 
512b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
513b7482f52SPhilipp Zabel 		clk |= R00_EN_DAC | R00_EN_INT;
514b7482f52SPhilipp Zabel 	else
515b7482f52SPhilipp Zabel 		clk |= R00_EN_ADC | R00_EN_DEC;
516b7482f52SPhilipp Zabel 
517b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, clk);
518b7482f52SPhilipp Zabel 	return 0;
519b7482f52SPhilipp Zabel }
520b7482f52SPhilipp Zabel 
521dee89c4dSMark Brown static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
522dee89c4dSMark Brown 				 struct snd_soc_dai *dai)
523b7482f52SPhilipp Zabel {
524b7482f52SPhilipp Zabel 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
525b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = rtd->socdev;
5266627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
527b7482f52SPhilipp Zabel 	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
528b7482f52SPhilipp Zabel 
529b7482f52SPhilipp Zabel 	/* shut down WSPLL power if running from this clock */
530b7482f52SPhilipp Zabel 	if (clk & R00_DAC_CLK) {
531b7482f52SPhilipp Zabel 		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
532b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, ~R02_PON_PLL & pm);
533b7482f52SPhilipp Zabel 	}
534b7482f52SPhilipp Zabel 
535b7482f52SPhilipp Zabel 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
536b7482f52SPhilipp Zabel 		clk &= ~(R00_EN_DAC | R00_EN_INT);
537b7482f52SPhilipp Zabel 	else
538b7482f52SPhilipp Zabel 		clk &= ~(R00_EN_ADC | R00_EN_DEC);
539b7482f52SPhilipp Zabel 
540b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, clk);
541b7482f52SPhilipp Zabel }
542b7482f52SPhilipp Zabel 
543e550e17fSLiam Girdwood static int uda1380_mute(struct snd_soc_dai *codec_dai, int mute)
544b7482f52SPhilipp Zabel {
545b7482f52SPhilipp Zabel 	struct snd_soc_codec *codec = codec_dai->codec;
546b7482f52SPhilipp Zabel 	u16 mute_reg = uda1380_read_reg_cache(codec, UDA1380_DEEMP) & ~R13_MTM;
547b7482f52SPhilipp Zabel 
548b7482f52SPhilipp Zabel 	/* FIXME: mute(codec,0) is called when the magician clock is already
549b7482f52SPhilipp Zabel 	 * set to WSPLL, but for some unknown reason writing to interpolator
550b7482f52SPhilipp Zabel 	 * registers works only when clocked by SYSCLK */
551b7482f52SPhilipp Zabel 	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
552b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, ~R00_DAC_CLK & clk);
553b7482f52SPhilipp Zabel 	if (mute)
554b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_DEEMP, mute_reg | R13_MTM);
555b7482f52SPhilipp Zabel 	else
556b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_DEEMP, mute_reg);
557b7482f52SPhilipp Zabel 	uda1380_write(codec, UDA1380_CLK, clk);
558b7482f52SPhilipp Zabel 	return 0;
559b7482f52SPhilipp Zabel }
560b7482f52SPhilipp Zabel 
561b7482f52SPhilipp Zabel static int uda1380_set_bias_level(struct snd_soc_codec *codec,
562b7482f52SPhilipp Zabel 	enum snd_soc_bias_level level)
563b7482f52SPhilipp Zabel {
564b7482f52SPhilipp Zabel 	int pm = uda1380_read_reg_cache(codec, UDA1380_PM);
565b7482f52SPhilipp Zabel 
566b7482f52SPhilipp Zabel 	switch (level) {
567b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_ON:
568b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_PREPARE:
569b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
570b7482f52SPhilipp Zabel 		break;
571b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_STANDBY:
572b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, R02_PON_BIAS);
573b7482f52SPhilipp Zabel 		break;
574b7482f52SPhilipp Zabel 	case SND_SOC_BIAS_OFF:
575b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_PM, 0x0);
576b7482f52SPhilipp Zabel 		break;
577b7482f52SPhilipp Zabel 	}
578b7482f52SPhilipp Zabel 	codec->bias_level = level;
579b7482f52SPhilipp Zabel 	return 0;
580b7482f52SPhilipp Zabel }
581b7482f52SPhilipp Zabel 
582b7482f52SPhilipp Zabel #define UDA1380_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
583b7482f52SPhilipp Zabel 		       SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
584b7482f52SPhilipp Zabel 		       SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
585b7482f52SPhilipp Zabel 
586*6335d055SEric Miao static struct snd_soc_dai_ops uda1380_dai_ops = {
587*6335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
588*6335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
589*6335d055SEric Miao 	.prepare	= uda1380_pcm_prepare,
590*6335d055SEric Miao 	.digital_mute	= uda1380_mute,
591*6335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_both,
592*6335d055SEric Miao };
593*6335d055SEric Miao 
594*6335d055SEric Miao static struct snd_soc_dai_ops uda1380_dai_ops_playback = {
595*6335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
596*6335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
597*6335d055SEric Miao 	.prepare	= uda1380_pcm_prepare,
598*6335d055SEric Miao 	.digital_mute	= uda1380_mute,
599*6335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_playback,
600*6335d055SEric Miao };
601*6335d055SEric Miao 
602*6335d055SEric Miao static struct snd_soc_dai_ops uda1380_dai_ops_capture = {
603*6335d055SEric Miao 	.hw_params	= uda1380_pcm_hw_params,
604*6335d055SEric Miao 	.shutdown	= uda1380_pcm_shutdown,
605*6335d055SEric Miao 	.prepare	= uda1380_pcm_prepare,
606*6335d055SEric Miao 	.set_fmt	= uda1380_set_dai_fmt_capture,
607*6335d055SEric Miao };
608*6335d055SEric Miao 
609e550e17fSLiam Girdwood struct snd_soc_dai uda1380_dai[] = {
610b7482f52SPhilipp Zabel {
611b7482f52SPhilipp Zabel 	.name = "UDA1380",
612b7482f52SPhilipp Zabel 	.playback = {
613b7482f52SPhilipp Zabel 		.stream_name = "Playback",
614b7482f52SPhilipp Zabel 		.channels_min = 1,
615b7482f52SPhilipp Zabel 		.channels_max = 2,
616b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
617b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
618b7482f52SPhilipp Zabel 	.capture = {
619b7482f52SPhilipp Zabel 		.stream_name = "Capture",
620b7482f52SPhilipp Zabel 		.channels_min = 1,
621b7482f52SPhilipp Zabel 		.channels_max = 2,
622b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
623b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
624*6335d055SEric Miao 	.ops = &uda1380_dai_ops,
625b7482f52SPhilipp Zabel },
626b7482f52SPhilipp Zabel { /* playback only - dual interface */
627b7482f52SPhilipp Zabel 	.name = "UDA1380",
628b7482f52SPhilipp Zabel 	.playback = {
629b7482f52SPhilipp Zabel 		.stream_name = "Playback",
630b7482f52SPhilipp Zabel 		.channels_min = 1,
631b7482f52SPhilipp Zabel 		.channels_max = 2,
632b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
633b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
634b7482f52SPhilipp Zabel 	},
635*6335d055SEric Miao 	.ops = &uda1380_dai_ops_playback,
636b7482f52SPhilipp Zabel },
637b7482f52SPhilipp Zabel { /* capture only - dual interface*/
638b7482f52SPhilipp Zabel 	.name = "UDA1380",
639b7482f52SPhilipp Zabel 	.capture = {
640b7482f52SPhilipp Zabel 		.stream_name = "Capture",
641b7482f52SPhilipp Zabel 		.channels_min = 1,
642b7482f52SPhilipp Zabel 		.channels_max = 2,
643b7482f52SPhilipp Zabel 		.rates = UDA1380_RATES,
644b7482f52SPhilipp Zabel 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
645b7482f52SPhilipp Zabel 	},
646*6335d055SEric Miao 	.ops = &uda1380_dai_ops_capture,
647b7482f52SPhilipp Zabel },
648b7482f52SPhilipp Zabel };
649b7482f52SPhilipp Zabel EXPORT_SYMBOL_GPL(uda1380_dai);
650b7482f52SPhilipp Zabel 
651b7482f52SPhilipp Zabel static int uda1380_suspend(struct platform_device *pdev, pm_message_t state)
652b7482f52SPhilipp Zabel {
653b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
6546627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
655b7482f52SPhilipp Zabel 
656b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
657b7482f52SPhilipp Zabel 	return 0;
658b7482f52SPhilipp Zabel }
659b7482f52SPhilipp Zabel 
660b7482f52SPhilipp Zabel static int uda1380_resume(struct platform_device *pdev)
661b7482f52SPhilipp Zabel {
662b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
6636627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
664b7482f52SPhilipp Zabel 	int i;
665b7482f52SPhilipp Zabel 	u8 data[2];
666b7482f52SPhilipp Zabel 	u16 *cache = codec->reg_cache;
667b7482f52SPhilipp Zabel 
668b7482f52SPhilipp Zabel 	/* Sync reg_cache with the hardware */
669b7482f52SPhilipp Zabel 	for (i = 0; i < ARRAY_SIZE(uda1380_reg); i++) {
670b7482f52SPhilipp Zabel 		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
671b7482f52SPhilipp Zabel 		data[1] = cache[i] & 0x00ff;
672b7482f52SPhilipp Zabel 		codec->hw_write(codec->control_data, data, 2);
673b7482f52SPhilipp Zabel 	}
674b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
675b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, codec->suspend_bias_level);
676b7482f52SPhilipp Zabel 	return 0;
677b7482f52SPhilipp Zabel }
678b7482f52SPhilipp Zabel 
679b7482f52SPhilipp Zabel /*
680b7482f52SPhilipp Zabel  * initialise the UDA1380 driver
681b7482f52SPhilipp Zabel  * register mixer and dsp interfaces with the kernel
682b7482f52SPhilipp Zabel  */
683b7482f52SPhilipp Zabel static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
684b7482f52SPhilipp Zabel {
6856627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
686b7482f52SPhilipp Zabel 	int ret = 0;
687b7482f52SPhilipp Zabel 
688b7482f52SPhilipp Zabel 	codec->name = "UDA1380";
689b7482f52SPhilipp Zabel 	codec->owner = THIS_MODULE;
690b7482f52SPhilipp Zabel 	codec->read = uda1380_read_reg_cache;
691b7482f52SPhilipp Zabel 	codec->write = uda1380_write;
692b7482f52SPhilipp Zabel 	codec->set_bias_level = uda1380_set_bias_level;
693b7482f52SPhilipp Zabel 	codec->dai = uda1380_dai;
694b7482f52SPhilipp Zabel 	codec->num_dai = ARRAY_SIZE(uda1380_dai);
695b7482f52SPhilipp Zabel 	codec->reg_cache = kmemdup(uda1380_reg, sizeof(uda1380_reg),
696b7482f52SPhilipp Zabel 				   GFP_KERNEL);
697b7482f52SPhilipp Zabel 	if (codec->reg_cache == NULL)
698b7482f52SPhilipp Zabel 		return -ENOMEM;
6998ddd4407SMark Brown 	codec->reg_cache_size = ARRAY_SIZE(uda1380_reg);
7008ddd4407SMark Brown 	codec->reg_cache_step = 1;
701b7482f52SPhilipp Zabel 	uda1380_reset(codec);
702b7482f52SPhilipp Zabel 
703b7482f52SPhilipp Zabel 	/* register pcms */
704b7482f52SPhilipp Zabel 	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
705b7482f52SPhilipp Zabel 	if (ret < 0) {
706b7482f52SPhilipp Zabel 		pr_err("uda1380: failed to create pcms\n");
707b7482f52SPhilipp Zabel 		goto pcm_err;
708b7482f52SPhilipp Zabel 	}
709b7482f52SPhilipp Zabel 
710b7482f52SPhilipp Zabel 	/* power on device */
711b7482f52SPhilipp Zabel 	uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
712b7482f52SPhilipp Zabel 	/* set clock input */
713b7482f52SPhilipp Zabel 	switch (dac_clk) {
714b7482f52SPhilipp Zabel 	case UDA1380_DAC_CLK_SYSCLK:
715b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_CLK, 0);
716b7482f52SPhilipp Zabel 		break;
717b7482f52SPhilipp Zabel 	case UDA1380_DAC_CLK_WSPLL:
718b7482f52SPhilipp Zabel 		uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK);
719b7482f52SPhilipp Zabel 		break;
720b7482f52SPhilipp Zabel 	}
721b7482f52SPhilipp Zabel 
722b7482f52SPhilipp Zabel 	/* uda1380 init */
7233e8e1952SIan Molton 	snd_soc_add_controls(codec, uda1380_snd_controls,
7243e8e1952SIan Molton 				ARRAY_SIZE(uda1380_snd_controls));
725b7482f52SPhilipp Zabel 	uda1380_add_widgets(codec);
726968a6025SMark Brown 	ret = snd_soc_init_card(socdev);
727b7482f52SPhilipp Zabel 	if (ret < 0) {
728b7482f52SPhilipp Zabel 		pr_err("uda1380: failed to register card\n");
729b7482f52SPhilipp Zabel 		goto card_err;
730b7482f52SPhilipp Zabel 	}
731b7482f52SPhilipp Zabel 
732b7482f52SPhilipp Zabel 	return ret;
733b7482f52SPhilipp Zabel 
734b7482f52SPhilipp Zabel card_err:
735b7482f52SPhilipp Zabel 	snd_soc_free_pcms(socdev);
736b7482f52SPhilipp Zabel 	snd_soc_dapm_free(socdev);
737b7482f52SPhilipp Zabel pcm_err:
738b7482f52SPhilipp Zabel 	kfree(codec->reg_cache);
739b7482f52SPhilipp Zabel 	return ret;
740b7482f52SPhilipp Zabel }
741b7482f52SPhilipp Zabel 
742b7482f52SPhilipp Zabel static struct snd_soc_device *uda1380_socdev;
743b7482f52SPhilipp Zabel 
744b7482f52SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
745b7482f52SPhilipp Zabel 
74688fc39d7SJean Delvare static int uda1380_i2c_probe(struct i2c_client *i2c,
74788fc39d7SJean Delvare 			     const struct i2c_device_id *id)
748b7482f52SPhilipp Zabel {
749b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = uda1380_socdev;
750b7482f52SPhilipp Zabel 	struct uda1380_setup_data *setup = socdev->codec_data;
7516627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
752b7482f52SPhilipp Zabel 	int ret;
753b7482f52SPhilipp Zabel 
754b7482f52SPhilipp Zabel 	i2c_set_clientdata(i2c, codec);
755b7482f52SPhilipp Zabel 	codec->control_data = i2c;
756b7482f52SPhilipp Zabel 
757b7482f52SPhilipp Zabel 	ret = uda1380_init(socdev, setup->dac_clk);
75888fc39d7SJean Delvare 	if (ret < 0)
759b7482f52SPhilipp Zabel 		pr_err("uda1380: failed to initialise UDA1380\n");
760b7482f52SPhilipp Zabel 
761b7482f52SPhilipp Zabel 	return ret;
762b7482f52SPhilipp Zabel }
763b7482f52SPhilipp Zabel 
76488fc39d7SJean Delvare static int uda1380_i2c_remove(struct i2c_client *client)
765b7482f52SPhilipp Zabel {
766b7482f52SPhilipp Zabel 	struct snd_soc_codec *codec = i2c_get_clientdata(client);
767b7482f52SPhilipp Zabel 	kfree(codec->reg_cache);
768b7482f52SPhilipp Zabel 	return 0;
769b7482f52SPhilipp Zabel }
770b7482f52SPhilipp Zabel 
77188fc39d7SJean Delvare static const struct i2c_device_id uda1380_i2c_id[] = {
77288fc39d7SJean Delvare 	{ "uda1380", 0 },
77388fc39d7SJean Delvare 	{ }
77488fc39d7SJean Delvare };
77588fc39d7SJean Delvare MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
776b7482f52SPhilipp Zabel 
777b7482f52SPhilipp Zabel static struct i2c_driver uda1380_i2c_driver = {
778b7482f52SPhilipp Zabel 	.driver = {
779b7482f52SPhilipp Zabel 		.name =  "UDA1380 I2C Codec",
780b7482f52SPhilipp Zabel 		.owner = THIS_MODULE,
781b7482f52SPhilipp Zabel 	},
78288fc39d7SJean Delvare 	.probe =    uda1380_i2c_probe,
78388fc39d7SJean Delvare 	.remove =   uda1380_i2c_remove,
78488fc39d7SJean Delvare 	.id_table = uda1380_i2c_id,
785b7482f52SPhilipp Zabel };
786b7482f52SPhilipp Zabel 
78788fc39d7SJean Delvare static int uda1380_add_i2c_device(struct platform_device *pdev,
78888fc39d7SJean Delvare 				  const struct uda1380_setup_data *setup)
78988fc39d7SJean Delvare {
79088fc39d7SJean Delvare 	struct i2c_board_info info;
79188fc39d7SJean Delvare 	struct i2c_adapter *adapter;
79288fc39d7SJean Delvare 	struct i2c_client *client;
79388fc39d7SJean Delvare 	int ret;
79488fc39d7SJean Delvare 
79588fc39d7SJean Delvare 	ret = i2c_add_driver(&uda1380_i2c_driver);
79688fc39d7SJean Delvare 	if (ret != 0) {
79788fc39d7SJean Delvare 		dev_err(&pdev->dev, "can't add i2c driver\n");
79888fc39d7SJean Delvare 		return ret;
79988fc39d7SJean Delvare 	}
80088fc39d7SJean Delvare 
80188fc39d7SJean Delvare 	memset(&info, 0, sizeof(struct i2c_board_info));
80288fc39d7SJean Delvare 	info.addr = setup->i2c_address;
80388fc39d7SJean Delvare 	strlcpy(info.type, "uda1380", I2C_NAME_SIZE);
80488fc39d7SJean Delvare 
80588fc39d7SJean Delvare 	adapter = i2c_get_adapter(setup->i2c_bus);
80688fc39d7SJean Delvare 	if (!adapter) {
80788fc39d7SJean Delvare 		dev_err(&pdev->dev, "can't get i2c adapter %d\n",
80888fc39d7SJean Delvare 			setup->i2c_bus);
80988fc39d7SJean Delvare 		goto err_driver;
81088fc39d7SJean Delvare 	}
81188fc39d7SJean Delvare 
81288fc39d7SJean Delvare 	client = i2c_new_device(adapter, &info);
81388fc39d7SJean Delvare 	i2c_put_adapter(adapter);
81488fc39d7SJean Delvare 	if (!client) {
81588fc39d7SJean Delvare 		dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
81688fc39d7SJean Delvare 			(unsigned int)info.addr);
81788fc39d7SJean Delvare 		goto err_driver;
81888fc39d7SJean Delvare 	}
81988fc39d7SJean Delvare 
82088fc39d7SJean Delvare 	return 0;
82188fc39d7SJean Delvare 
82288fc39d7SJean Delvare err_driver:
82388fc39d7SJean Delvare 	i2c_del_driver(&uda1380_i2c_driver);
82488fc39d7SJean Delvare 	return -ENODEV;
82588fc39d7SJean Delvare }
826b7482f52SPhilipp Zabel #endif
827b7482f52SPhilipp Zabel 
828b7482f52SPhilipp Zabel static int uda1380_probe(struct platform_device *pdev)
829b7482f52SPhilipp Zabel {
830b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
831b7482f52SPhilipp Zabel 	struct uda1380_setup_data *setup;
832b7482f52SPhilipp Zabel 	struct snd_soc_codec *codec;
833b7c9d852SMark Brown 	int ret;
834b7482f52SPhilipp Zabel 
835b7482f52SPhilipp Zabel 	pr_info("UDA1380 Audio Codec %s", UDA1380_VERSION);
836b7482f52SPhilipp Zabel 
837b7482f52SPhilipp Zabel 	setup = socdev->codec_data;
838b7482f52SPhilipp Zabel 	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
839b7482f52SPhilipp Zabel 	if (codec == NULL)
840b7482f52SPhilipp Zabel 		return -ENOMEM;
841b7482f52SPhilipp Zabel 
8426627a653SMark Brown 	socdev->card->codec = codec;
843b7482f52SPhilipp Zabel 	mutex_init(&codec->mutex);
844b7482f52SPhilipp Zabel 	INIT_LIST_HEAD(&codec->dapm_widgets);
845b7482f52SPhilipp Zabel 	INIT_LIST_HEAD(&codec->dapm_paths);
846b7482f52SPhilipp Zabel 
847b7482f52SPhilipp Zabel 	uda1380_socdev = socdev;
848b7c9d852SMark Brown 	ret = -ENODEV;
849b7c9d852SMark Brown 
850b7482f52SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
851b7482f52SPhilipp Zabel 	if (setup->i2c_address) {
852b7482f52SPhilipp Zabel 		codec->hw_write = (hw_write_t)i2c_master_send;
85388fc39d7SJean Delvare 		ret = uda1380_add_i2c_device(pdev, setup);
854b7482f52SPhilipp Zabel 	}
855b7482f52SPhilipp Zabel #endif
8563051e41aSJean Delvare 
8573051e41aSJean Delvare 	if (ret != 0)
8583051e41aSJean Delvare 		kfree(codec);
859b7482f52SPhilipp Zabel 	return ret;
860b7482f52SPhilipp Zabel }
861b7482f52SPhilipp Zabel 
862b7482f52SPhilipp Zabel /* power down chip */
863b7482f52SPhilipp Zabel static int uda1380_remove(struct platform_device *pdev)
864b7482f52SPhilipp Zabel {
865b7482f52SPhilipp Zabel 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
8666627a653SMark Brown 	struct snd_soc_codec *codec = socdev->card->codec;
867b7482f52SPhilipp Zabel 
868b7482f52SPhilipp Zabel 	if (codec->control_data)
869b7482f52SPhilipp Zabel 		uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
870b7482f52SPhilipp Zabel 
871b7482f52SPhilipp Zabel 	snd_soc_free_pcms(socdev);
872b7482f52SPhilipp Zabel 	snd_soc_dapm_free(socdev);
873b7482f52SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
87488fc39d7SJean Delvare 	i2c_unregister_device(codec->control_data);
875b7482f52SPhilipp Zabel 	i2c_del_driver(&uda1380_i2c_driver);
876b7482f52SPhilipp Zabel #endif
877b7482f52SPhilipp Zabel 	kfree(codec);
878b7482f52SPhilipp Zabel 
879b7482f52SPhilipp Zabel 	return 0;
880b7482f52SPhilipp Zabel }
881b7482f52SPhilipp Zabel 
882b7482f52SPhilipp Zabel struct snd_soc_codec_device soc_codec_dev_uda1380 = {
883b7482f52SPhilipp Zabel 	.probe = 	uda1380_probe,
884b7482f52SPhilipp Zabel 	.remove = 	uda1380_remove,
885b7482f52SPhilipp Zabel 	.suspend = 	uda1380_suspend,
886b7482f52SPhilipp Zabel 	.resume =	uda1380_resume,
887b7482f52SPhilipp Zabel };
888b7482f52SPhilipp Zabel EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
889b7482f52SPhilipp Zabel 
890c9b3a40fSTakashi Iwai static int __init uda1380_modinit(void)
89164089b84SMark Brown {
89264089b84SMark Brown 	return snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
89364089b84SMark Brown }
89464089b84SMark Brown module_init(uda1380_modinit);
89564089b84SMark Brown 
89664089b84SMark Brown static void __exit uda1380_exit(void)
89764089b84SMark Brown {
89864089b84SMark Brown 	snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
89964089b84SMark Brown }
90064089b84SMark Brown module_exit(uda1380_exit);
90164089b84SMark Brown 
902b7482f52SPhilipp Zabel MODULE_AUTHOR("Giorgio Padrin");
903b7482f52SPhilipp Zabel MODULE_DESCRIPTION("Audio support for codec Philips UDA1380");
904b7482f52SPhilipp Zabel MODULE_LICENSE("GPL");
905