• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/sound/soc/codecs/
1/*
2 * wm8960.c  --  WM8960 ALSA SoC Audio driver
3 *
4 * Author: Liam Girdwood
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/pm.h>
16#include <linux/i2c.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24#include <sound/initval.h>
25#include <sound/tlv.h>
26#include <sound/wm8960.h>
27
28#include "wm8960.h"
29
30#define AUDIO_NAME "wm8960"
31
32struct snd_soc_codec_device soc_codec_dev_wm8960;
33
34/* R25 - Power 1 */
35#define WM8960_VMID_MASK 0x180
36#define WM8960_VREF      0x40
37
38/* R26 - Power 2 */
39#define WM8960_PWR2_LOUT1	0x40
40#define WM8960_PWR2_ROUT1	0x20
41#define WM8960_PWR2_OUT3	0x02
42
43/* R28 - Anti-pop 1 */
44#define WM8960_POBCTRL   0x80
45#define WM8960_BUFDCOPEN 0x10
46#define WM8960_BUFIOEN   0x08
47#define WM8960_SOFT_ST   0x04
48#define WM8960_HPSTBY    0x01
49
50/* R29 - Anti-pop 2 */
51#define WM8960_DISOP     0x40
52#define WM8960_DRES_MASK 0x30
53
54/*
55 * wm8960 register cache
56 * We can't read the WM8960 register space when we are
57 * using 2 wire for device control, so we cache them instead.
58 */
59static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
60	0x0097, 0x0097, 0x0000, 0x0000,
61	0x0000, 0x0008, 0x0000, 0x000a,
62	0x01c0, 0x0000, 0x00ff, 0x00ff,
63	0x0000, 0x0000, 0x0000, 0x0000,
64	0x0000, 0x007b, 0x0100, 0x0032,
65	0x0000, 0x00c3, 0x00c3, 0x01c0,
66	0x0000, 0x0000, 0x0000, 0x0000,
67	0x0000, 0x0000, 0x0000, 0x0000,
68	0x0100, 0x0100, 0x0050, 0x0050,
69	0x0050, 0x0050, 0x0000, 0x0000,
70	0x0000, 0x0000, 0x0040, 0x0000,
71	0x0000, 0x0050, 0x0050, 0x0000,
72	0x0002, 0x0037, 0x004d, 0x0080,
73	0x0008, 0x0031, 0x0026, 0x00e9,
74};
75
76struct wm8960_priv {
77	u16 reg_cache[WM8960_CACHEREGNUM];
78	struct snd_soc_codec codec;
79	struct snd_soc_dapm_widget *lout1;
80	struct snd_soc_dapm_widget *rout1;
81	struct snd_soc_dapm_widget *out3;
82	bool deemph;
83	int playback_fs;
84};
85
86#define wm8960_reset(c)	snd_soc_write(c, WM8960_RESET, 0)
87
88/* enumerated controls */
89static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted",
90	"Right Inverted", "Stereo Inversion"};
91static const char *wm8960_3d_upper_cutoff[] = {"High", "Low"};
92static const char *wm8960_3d_lower_cutoff[] = {"Low", "High"};
93static const char *wm8960_alcfunc[] = {"Off", "Right", "Left", "Stereo"};
94static const char *wm8960_alcmode[] = {"ALC", "Limiter"};
95
96static const struct soc_enum wm8960_enum[] = {
97	SOC_ENUM_SINGLE(WM8960_DACCTL1, 5, 4, wm8960_polarity),
98	SOC_ENUM_SINGLE(WM8960_DACCTL2, 5, 4, wm8960_polarity),
99	SOC_ENUM_SINGLE(WM8960_3D, 6, 2, wm8960_3d_upper_cutoff),
100	SOC_ENUM_SINGLE(WM8960_3D, 5, 2, wm8960_3d_lower_cutoff),
101	SOC_ENUM_SINGLE(WM8960_ALC1, 7, 4, wm8960_alcfunc),
102	SOC_ENUM_SINGLE(WM8960_ALC3, 8, 2, wm8960_alcmode),
103};
104
105static const int deemph_settings[] = { 0, 32000, 44100, 48000 };
106
107static int wm8960_set_deemph(struct snd_soc_codec *codec)
108{
109	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
110	int val, i, best;
111
112	/* If we're using deemphasis select the nearest available sample
113	 * rate.
114	 */
115	if (wm8960->deemph) {
116		best = 1;
117		for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
118			if (abs(deemph_settings[i] - wm8960->playback_fs) <
119			    abs(deemph_settings[best] - wm8960->playback_fs))
120				best = i;
121		}
122
123		val = best << 1;
124	} else {
125		val = 0;
126	}
127
128	dev_dbg(codec->dev, "Set deemphasis %d\n", val);
129
130	return snd_soc_update_bits(codec, WM8960_DACCTL1,
131				   0x6, val);
132}
133
134static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
135			     struct snd_ctl_elem_value *ucontrol)
136{
137	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
138	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
139
140	ucontrol->value.enumerated.item[0] = wm8960->deemph;
141	return 0;
142}
143
144static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
145			     struct snd_ctl_elem_value *ucontrol)
146{
147	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
148	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
149	int deemph = ucontrol->value.enumerated.item[0];
150
151	if (deemph > 1)
152		return -EINVAL;
153
154	wm8960->deemph = deemph;
155
156	return wm8960_set_deemph(codec);
157}
158
159static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0);
160static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1);
161static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0);
162static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
163
164static const struct snd_kcontrol_new wm8960_snd_controls[] = {
165SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL,
166		 0, 63, 0, adc_tlv),
167SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL,
168	6, 1, 0),
169SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL,
170	7, 1, 0),
171
172SOC_DOUBLE_R_TLV("Playback Volume", WM8960_LDAC, WM8960_RDAC,
173		 0, 255, 0, dac_tlv),
174
175SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8960_LOUT1, WM8960_ROUT1,
176		 0, 127, 0, out_tlv),
177SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8960_LOUT1, WM8960_ROUT1,
178	7, 1, 0),
179
180SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8960_LOUT2, WM8960_ROUT2,
181		 0, 127, 0, out_tlv),
182SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8960_LOUT2, WM8960_ROUT2,
183	7, 1, 0),
184SOC_SINGLE("Speaker DC Volume", WM8960_CLASSD3, 3, 5, 0),
185SOC_SINGLE("Speaker AC Volume", WM8960_CLASSD3, 0, 5, 0),
186
187SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0),
188SOC_ENUM("ADC Polarity", wm8960_enum[0]),
189SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0),
190
191SOC_ENUM("DAC Polarity", wm8960_enum[2]),
192SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
193		    wm8960_get_deemph, wm8960_put_deemph),
194
195SOC_ENUM("3D Filter Upper Cut-Off", wm8960_enum[2]),
196SOC_ENUM("3D Filter Lower Cut-Off", wm8960_enum[3]),
197SOC_SINGLE("3D Volume", WM8960_3D, 1, 15, 0),
198SOC_SINGLE("3D Switch", WM8960_3D, 0, 1, 0),
199
200SOC_ENUM("ALC Function", wm8960_enum[4]),
201SOC_SINGLE("ALC Max Gain", WM8960_ALC1, 4, 7, 0),
202SOC_SINGLE("ALC Target", WM8960_ALC1, 0, 15, 1),
203SOC_SINGLE("ALC Min Gain", WM8960_ALC2, 4, 7, 0),
204SOC_SINGLE("ALC Hold Time", WM8960_ALC2, 0, 15, 0),
205SOC_ENUM("ALC Mode", wm8960_enum[5]),
206SOC_SINGLE("ALC Decay", WM8960_ALC3, 4, 15, 0),
207SOC_SINGLE("ALC Attack", WM8960_ALC3, 0, 15, 0),
208
209SOC_SINGLE("Noise Gate Threshold", WM8960_NOISEG, 3, 31, 0),
210SOC_SINGLE("Noise Gate Switch", WM8960_NOISEG, 0, 1, 0),
211
212SOC_DOUBLE_R("ADC PCM Capture Volume", WM8960_LINPATH, WM8960_RINPATH,
213	0, 127, 0),
214
215SOC_SINGLE_TLV("Left Output Mixer Boost Bypass Volume",
216	       WM8960_BYPASS1, 4, 7, 1, bypass_tlv),
217SOC_SINGLE_TLV("Left Output Mixer LINPUT3 Volume",
218	       WM8960_LOUTMIX, 4, 7, 1, bypass_tlv),
219SOC_SINGLE_TLV("Right Output Mixer Boost Bypass Volume",
220	       WM8960_BYPASS2, 4, 7, 1, bypass_tlv),
221SOC_SINGLE_TLV("Right Output Mixer RINPUT3 Volume",
222	       WM8960_ROUTMIX, 4, 7, 1, bypass_tlv),
223};
224
225static const struct snd_kcontrol_new wm8960_lin_boost[] = {
226SOC_DAPM_SINGLE("LINPUT2 Switch", WM8960_LINPATH, 6, 1, 0),
227SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LINPATH, 7, 1, 0),
228SOC_DAPM_SINGLE("LINPUT1 Switch", WM8960_LINPATH, 8, 1, 0),
229};
230
231static const struct snd_kcontrol_new wm8960_lin[] = {
232SOC_DAPM_SINGLE("Boost Switch", WM8960_LINPATH, 3, 1, 0),
233};
234
235static const struct snd_kcontrol_new wm8960_rin_boost[] = {
236SOC_DAPM_SINGLE("RINPUT2 Switch", WM8960_RINPATH, 6, 1, 0),
237SOC_DAPM_SINGLE("RINPUT3 Switch", WM8960_RINPATH, 7, 1, 0),
238SOC_DAPM_SINGLE("RINPUT1 Switch", WM8960_RINPATH, 8, 1, 0),
239};
240
241static const struct snd_kcontrol_new wm8960_rin[] = {
242SOC_DAPM_SINGLE("Boost Switch", WM8960_RINPATH, 3, 1, 0),
243};
244
245static const struct snd_kcontrol_new wm8960_loutput_mixer[] = {
246SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_LOUTMIX, 8, 1, 0),
247SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LOUTMIX, 7, 1, 0),
248SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS1, 7, 1, 0),
249};
250
251static const struct snd_kcontrol_new wm8960_routput_mixer[] = {
252SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_ROUTMIX, 8, 1, 0),
253SOC_DAPM_SINGLE("RINPUT3 Switch", WM8960_ROUTMIX, 7, 1, 0),
254SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS2, 7, 1, 0),
255};
256
257static const struct snd_kcontrol_new wm8960_mono_out[] = {
258SOC_DAPM_SINGLE("Left Switch", WM8960_MONOMIX1, 7, 1, 0),
259SOC_DAPM_SINGLE("Right Switch", WM8960_MONOMIX2, 7, 1, 0),
260};
261
262static const struct snd_soc_dapm_widget wm8960_dapm_widgets[] = {
263SND_SOC_DAPM_INPUT("LINPUT1"),
264SND_SOC_DAPM_INPUT("RINPUT1"),
265SND_SOC_DAPM_INPUT("LINPUT2"),
266SND_SOC_DAPM_INPUT("RINPUT2"),
267SND_SOC_DAPM_INPUT("LINPUT3"),
268SND_SOC_DAPM_INPUT("RINPUT3"),
269
270SND_SOC_DAPM_MICBIAS("MICB", WM8960_POWER1, 1, 0),
271
272SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8960_POWER1, 5, 0,
273		   wm8960_lin_boost, ARRAY_SIZE(wm8960_lin_boost)),
274SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8960_POWER1, 4, 0,
275		   wm8960_rin_boost, ARRAY_SIZE(wm8960_rin_boost)),
276
277SND_SOC_DAPM_MIXER("Left Input Mixer", WM8960_POWER3, 5, 0,
278		   wm8960_lin, ARRAY_SIZE(wm8960_lin)),
279SND_SOC_DAPM_MIXER("Right Input Mixer", WM8960_POWER3, 4, 0,
280		   wm8960_rin, ARRAY_SIZE(wm8960_rin)),
281
282SND_SOC_DAPM_ADC("Left ADC", "Capture", WM8960_POWER2, 3, 0),
283SND_SOC_DAPM_ADC("Right ADC", "Capture", WM8960_POWER2, 2, 0),
284
285SND_SOC_DAPM_DAC("Left DAC", "Playback", WM8960_POWER2, 8, 0),
286SND_SOC_DAPM_DAC("Right DAC", "Playback", WM8960_POWER2, 7, 0),
287
288SND_SOC_DAPM_MIXER("Left Output Mixer", WM8960_POWER3, 3, 0,
289	&wm8960_loutput_mixer[0],
290	ARRAY_SIZE(wm8960_loutput_mixer)),
291SND_SOC_DAPM_MIXER("Right Output Mixer", WM8960_POWER3, 2, 0,
292	&wm8960_routput_mixer[0],
293	ARRAY_SIZE(wm8960_routput_mixer)),
294
295SND_SOC_DAPM_PGA("LOUT1 PGA", WM8960_POWER2, 6, 0, NULL, 0),
296SND_SOC_DAPM_PGA("ROUT1 PGA", WM8960_POWER2, 5, 0, NULL, 0),
297
298SND_SOC_DAPM_PGA("Left Speaker PGA", WM8960_POWER2, 4, 0, NULL, 0),
299SND_SOC_DAPM_PGA("Right Speaker PGA", WM8960_POWER2, 3, 0, NULL, 0),
300
301SND_SOC_DAPM_PGA("Right Speaker Output", WM8960_CLASSD1, 7, 0, NULL, 0),
302SND_SOC_DAPM_PGA("Left Speaker Output", WM8960_CLASSD1, 6, 0, NULL, 0),
303
304SND_SOC_DAPM_OUTPUT("SPK_LP"),
305SND_SOC_DAPM_OUTPUT("SPK_LN"),
306SND_SOC_DAPM_OUTPUT("HP_L"),
307SND_SOC_DAPM_OUTPUT("HP_R"),
308SND_SOC_DAPM_OUTPUT("SPK_RP"),
309SND_SOC_DAPM_OUTPUT("SPK_RN"),
310SND_SOC_DAPM_OUTPUT("OUT3"),
311};
312
313static const struct snd_soc_dapm_widget wm8960_dapm_widgets_out3[] = {
314SND_SOC_DAPM_MIXER("Mono Output Mixer", WM8960_POWER2, 1, 0,
315	&wm8960_mono_out[0],
316	ARRAY_SIZE(wm8960_mono_out)),
317};
318
319/* Represent OUT3 as a PGA so that it gets turned on with LOUT1/ROUT1 */
320static const struct snd_soc_dapm_widget wm8960_dapm_widgets_capless[] = {
321SND_SOC_DAPM_PGA("OUT3 VMID", WM8960_POWER2, 1, 0, NULL, 0),
322};
323
324static const struct snd_soc_dapm_route audio_paths[] = {
325	{ "Left Boost Mixer", "LINPUT1 Switch", "LINPUT1" },
326	{ "Left Boost Mixer", "LINPUT2 Switch", "LINPUT2" },
327	{ "Left Boost Mixer", "LINPUT3 Switch", "LINPUT3" },
328
329	{ "Left Input Mixer", "Boost Switch", "Left Boost Mixer", },
330	{ "Left Input Mixer", NULL, "LINPUT1", },  /* Really Boost Switch */
331	{ "Left Input Mixer", NULL, "LINPUT2" },
332	{ "Left Input Mixer", NULL, "LINPUT3" },
333
334	{ "Right Boost Mixer", "RINPUT1 Switch", "RINPUT1" },
335	{ "Right Boost Mixer", "RINPUT2 Switch", "RINPUT2" },
336	{ "Right Boost Mixer", "RINPUT3 Switch", "RINPUT3" },
337
338	{ "Right Input Mixer", "Boost Switch", "Right Boost Mixer", },
339	{ "Right Input Mixer", NULL, "RINPUT1", },  /* Really Boost Switch */
340	{ "Right Input Mixer", NULL, "RINPUT2" },
341	{ "Right Input Mixer", NULL, "LINPUT3" },
342
343	{ "Left ADC", NULL, "Left Input Mixer" },
344	{ "Right ADC", NULL, "Right Input Mixer" },
345
346	{ "Left Output Mixer", "LINPUT3 Switch", "LINPUT3" },
347	{ "Left Output Mixer", "Boost Bypass Switch", "Left Boost Mixer"} ,
348	{ "Left Output Mixer", "PCM Playback Switch", "Left DAC" },
349
350	{ "Right Output Mixer", "RINPUT3 Switch", "RINPUT3" },
351	{ "Right Output Mixer", "Boost Bypass Switch", "Right Boost Mixer" } ,
352	{ "Right Output Mixer", "PCM Playback Switch", "Right DAC" },
353
354	{ "LOUT1 PGA", NULL, "Left Output Mixer" },
355	{ "ROUT1 PGA", NULL, "Right Output Mixer" },
356
357	{ "HP_L", NULL, "LOUT1 PGA" },
358	{ "HP_R", NULL, "ROUT1 PGA" },
359
360	{ "Left Speaker PGA", NULL, "Left Output Mixer" },
361	{ "Right Speaker PGA", NULL, "Right Output Mixer" },
362
363	{ "Left Speaker Output", NULL, "Left Speaker PGA" },
364	{ "Right Speaker Output", NULL, "Right Speaker PGA" },
365
366	{ "SPK_LN", NULL, "Left Speaker Output" },
367	{ "SPK_LP", NULL, "Left Speaker Output" },
368	{ "SPK_RN", NULL, "Right Speaker Output" },
369	{ "SPK_RP", NULL, "Right Speaker Output" },
370};
371
372static const struct snd_soc_dapm_route audio_paths_out3[] = {
373	{ "Mono Output Mixer", "Left Switch", "Left Output Mixer" },
374	{ "Mono Output Mixer", "Right Switch", "Right Output Mixer" },
375
376	{ "OUT3", NULL, "Mono Output Mixer", }
377};
378
379static const struct snd_soc_dapm_route audio_paths_capless[] = {
380	{ "HP_L", NULL, "OUT3 VMID" },
381	{ "HP_R", NULL, "OUT3 VMID" },
382
383	{ "OUT3 VMID", NULL, "Left Output Mixer" },
384	{ "OUT3 VMID", NULL, "Right Output Mixer" },
385};
386
387static int wm8960_add_widgets(struct snd_soc_codec *codec)
388{
389	struct wm8960_data *pdata = codec->dev->platform_data;
390	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
391	struct snd_soc_dapm_widget *w;
392
393	snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets,
394				  ARRAY_SIZE(wm8960_dapm_widgets));
395
396	snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
397
398	/* In capless mode OUT3 is used to provide VMID for the
399	 * headphone outputs, otherwise it is used as a mono mixer.
400	 */
401	if (pdata && pdata->capless) {
402		snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_capless,
403					  ARRAY_SIZE(wm8960_dapm_widgets_capless));
404
405		snd_soc_dapm_add_routes(codec, audio_paths_capless,
406					ARRAY_SIZE(audio_paths_capless));
407	} else {
408		snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_out3,
409					  ARRAY_SIZE(wm8960_dapm_widgets_out3));
410
411		snd_soc_dapm_add_routes(codec, audio_paths_out3,
412					ARRAY_SIZE(audio_paths_out3));
413	}
414
415	/* We need to power up the headphone output stage out of
416	 * sequence for capless mode.  To save scanning the widget
417	 * list each time to find the desired power state do so now
418	 * and save the result.
419	 */
420	list_for_each_entry(w, &codec->dapm_widgets, list) {
421		if (strcmp(w->name, "LOUT1 PGA") == 0)
422			wm8960->lout1 = w;
423		if (strcmp(w->name, "ROUT1 PGA") == 0)
424			wm8960->rout1 = w;
425		if (strcmp(w->name, "OUT3 VMID") == 0)
426			wm8960->out3 = w;
427	}
428
429	return 0;
430}
431
432static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai,
433		unsigned int fmt)
434{
435	struct snd_soc_codec *codec = codec_dai->codec;
436	u16 iface = 0;
437
438	/* set master/slave audio interface */
439	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
440	case SND_SOC_DAIFMT_CBM_CFM:
441		iface |= 0x0040;
442		break;
443	case SND_SOC_DAIFMT_CBS_CFS:
444		break;
445	default:
446		return -EINVAL;
447	}
448
449	/* interface format */
450	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
451	case SND_SOC_DAIFMT_I2S:
452		iface |= 0x0002;
453		break;
454	case SND_SOC_DAIFMT_RIGHT_J:
455		break;
456	case SND_SOC_DAIFMT_LEFT_J:
457		iface |= 0x0001;
458		break;
459	case SND_SOC_DAIFMT_DSP_A:
460		iface |= 0x0003;
461		break;
462	case SND_SOC_DAIFMT_DSP_B:
463		iface |= 0x0013;
464		break;
465	default:
466		return -EINVAL;
467	}
468
469	/* clock inversion */
470	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
471	case SND_SOC_DAIFMT_NB_NF:
472		break;
473	case SND_SOC_DAIFMT_IB_IF:
474		iface |= 0x0090;
475		break;
476	case SND_SOC_DAIFMT_IB_NF:
477		iface |= 0x0080;
478		break;
479	case SND_SOC_DAIFMT_NB_IF:
480		iface |= 0x0010;
481		break;
482	default:
483		return -EINVAL;
484	}
485
486	/* set iface */
487	snd_soc_write(codec, WM8960_IFACE1, iface);
488	return 0;
489}
490
491static struct {
492	int rate;
493	unsigned int val;
494} alc_rates[] = {
495	{ 48000, 0 },
496	{ 44100, 0 },
497	{ 32000, 1 },
498	{ 22050, 2 },
499	{ 24000, 2 },
500	{ 16000, 3 },
501	{ 11250, 4 },
502	{ 12000, 4 },
503	{  8000, 5 },
504};
505
506static int wm8960_hw_params(struct snd_pcm_substream *substream,
507			    struct snd_pcm_hw_params *params,
508			    struct snd_soc_dai *dai)
509{
510	struct snd_soc_pcm_runtime *rtd = substream->private_data;
511	struct snd_soc_device *socdev = rtd->socdev;
512	struct snd_soc_codec *codec = socdev->card->codec;
513	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
514	u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
515	int i;
516
517	/* bit size */
518	switch (params_format(params)) {
519	case SNDRV_PCM_FORMAT_S16_LE:
520		break;
521	case SNDRV_PCM_FORMAT_S20_3LE:
522		iface |= 0x0004;
523		break;
524	case SNDRV_PCM_FORMAT_S24_LE:
525		iface |= 0x0008;
526		break;
527	}
528
529	/* Update filters for the new rate */
530	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
531		wm8960->playback_fs = params_rate(params);
532		wm8960_set_deemph(codec);
533	} else {
534		for (i = 0; i < ARRAY_SIZE(alc_rates); i++)
535			if (alc_rates[i].rate == params_rate(params))
536				snd_soc_update_bits(codec,
537						    WM8960_ADDCTL3, 0x7,
538						    alc_rates[i].val);
539	}
540
541	/* set iface */
542	snd_soc_write(codec, WM8960_IFACE1, iface);
543	return 0;
544}
545
546static int wm8960_mute(struct snd_soc_dai *dai, int mute)
547{
548	struct snd_soc_codec *codec = dai->codec;
549	u16 mute_reg = snd_soc_read(codec, WM8960_DACCTL1) & 0xfff7;
550
551	if (mute)
552		snd_soc_write(codec, WM8960_DACCTL1, mute_reg | 0x8);
553	else
554		snd_soc_write(codec, WM8960_DACCTL1, mute_reg);
555	return 0;
556}
557
558static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
559				      enum snd_soc_bias_level level)
560{
561	u16 reg;
562
563	switch (level) {
564	case SND_SOC_BIAS_ON:
565		break;
566
567	case SND_SOC_BIAS_PREPARE:
568		/* Set VMID to 2x50k */
569		reg = snd_soc_read(codec, WM8960_POWER1);
570		reg &= ~0x180;
571		reg |= 0x80;
572		snd_soc_write(codec, WM8960_POWER1, reg);
573		break;
574
575	case SND_SOC_BIAS_STANDBY:
576		if (codec->bias_level == SND_SOC_BIAS_OFF) {
577			/* Enable anti-pop features */
578			snd_soc_write(codec, WM8960_APOP1,
579				      WM8960_POBCTRL | WM8960_SOFT_ST |
580				      WM8960_BUFDCOPEN | WM8960_BUFIOEN);
581
582			/* Enable & ramp VMID at 2x50k */
583			reg = snd_soc_read(codec, WM8960_POWER1);
584			reg |= 0x80;
585			snd_soc_write(codec, WM8960_POWER1, reg);
586			msleep(100);
587
588			/* Enable VREF */
589			snd_soc_write(codec, WM8960_POWER1, reg | WM8960_VREF);
590
591			/* Disable anti-pop features */
592			snd_soc_write(codec, WM8960_APOP1, WM8960_BUFIOEN);
593		}
594
595		/* Set VMID to 2x250k */
596		reg = snd_soc_read(codec, WM8960_POWER1);
597		reg &= ~0x180;
598		reg |= 0x100;
599		snd_soc_write(codec, WM8960_POWER1, reg);
600		break;
601
602	case SND_SOC_BIAS_OFF:
603		/* Enable anti-pop features */
604		snd_soc_write(codec, WM8960_APOP1,
605			     WM8960_POBCTRL | WM8960_SOFT_ST |
606			     WM8960_BUFDCOPEN | WM8960_BUFIOEN);
607
608		/* Disable VMID and VREF, let them discharge */
609		snd_soc_write(codec, WM8960_POWER1, 0);
610		msleep(600);
611		break;
612	}
613
614	codec->bias_level = level;
615
616	return 0;
617}
618
619static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
620					 enum snd_soc_bias_level level)
621{
622	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
623	int reg;
624
625	switch (level) {
626	case SND_SOC_BIAS_ON:
627		break;
628
629	case SND_SOC_BIAS_PREPARE:
630		switch (codec->bias_level) {
631		case SND_SOC_BIAS_STANDBY:
632			/* Enable anti pop mode */
633			snd_soc_update_bits(codec, WM8960_APOP1,
634					    WM8960_POBCTRL | WM8960_SOFT_ST |
635					    WM8960_BUFDCOPEN,
636					    WM8960_POBCTRL | WM8960_SOFT_ST |
637					    WM8960_BUFDCOPEN);
638
639			/* Enable LOUT1, ROUT1 and OUT3 if they're enabled */
640			reg = 0;
641			if (wm8960->lout1 && wm8960->lout1->power)
642				reg |= WM8960_PWR2_LOUT1;
643			if (wm8960->rout1 && wm8960->rout1->power)
644				reg |= WM8960_PWR2_ROUT1;
645			if (wm8960->out3 && wm8960->out3->power)
646				reg |= WM8960_PWR2_OUT3;
647			snd_soc_update_bits(codec, WM8960_POWER2,
648					    WM8960_PWR2_LOUT1 |
649					    WM8960_PWR2_ROUT1 |
650					    WM8960_PWR2_OUT3, reg);
651
652			/* Enable VMID at 2*50k */
653			snd_soc_update_bits(codec, WM8960_POWER1,
654					    WM8960_VMID_MASK, 0x80);
655
656			/* Ramp */
657			msleep(100);
658
659			/* Enable VREF */
660			snd_soc_update_bits(codec, WM8960_POWER1,
661					    WM8960_VREF, WM8960_VREF);
662
663			msleep(100);
664			break;
665
666		case SND_SOC_BIAS_ON:
667			/* Enable anti-pop mode */
668			snd_soc_update_bits(codec, WM8960_APOP1,
669					    WM8960_POBCTRL | WM8960_SOFT_ST |
670					    WM8960_BUFDCOPEN,
671					    WM8960_POBCTRL | WM8960_SOFT_ST |
672					    WM8960_BUFDCOPEN);
673
674			/* Disable VMID and VREF */
675			snd_soc_update_bits(codec, WM8960_POWER1,
676					    WM8960_VREF | WM8960_VMID_MASK, 0);
677			break;
678
679		default:
680			break;
681		}
682		break;
683
684	case SND_SOC_BIAS_STANDBY:
685		switch (codec->bias_level) {
686		case SND_SOC_BIAS_PREPARE:
687			/* Disable HP discharge */
688			snd_soc_update_bits(codec, WM8960_APOP2,
689					    WM8960_DISOP | WM8960_DRES_MASK,
690					    0);
691
692			/* Disable anti-pop features */
693			snd_soc_update_bits(codec, WM8960_APOP1,
694					    WM8960_POBCTRL | WM8960_SOFT_ST |
695					    WM8960_BUFDCOPEN,
696					    WM8960_POBCTRL | WM8960_SOFT_ST |
697					    WM8960_BUFDCOPEN);
698			break;
699
700		default:
701			break;
702		}
703		break;
704
705	case SND_SOC_BIAS_OFF:
706		break;
707	}
708
709	codec->bias_level = level;
710
711	return 0;
712}
713
714/* PLL divisors */
715struct _pll_div {
716	u32 pre_div:1;
717	u32 n:4;
718	u32 k:24;
719};
720
721/* The size in bits of the pll divide multiplied by 10
722 * to allow rounding later */
723#define FIXED_PLL_SIZE ((1 << 24) * 10)
724
725static int pll_factors(unsigned int source, unsigned int target,
726		       struct _pll_div *pll_div)
727{
728	unsigned long long Kpart;
729	unsigned int K, Ndiv, Nmod;
730
731	pr_debug("WM8960 PLL: setting %dHz->%dHz\n", source, target);
732
733	/* Scale up target to PLL operating frequency */
734	target *= 4;
735
736	Ndiv = target / source;
737	if (Ndiv < 6) {
738		source >>= 1;
739		pll_div->pre_div = 1;
740		Ndiv = target / source;
741	} else
742		pll_div->pre_div = 0;
743
744	if ((Ndiv < 6) || (Ndiv > 12)) {
745		pr_err("WM8960 PLL: Unsupported N=%d\n", Ndiv);
746		return -EINVAL;
747	}
748
749	pll_div->n = Ndiv;
750	Nmod = target % source;
751	Kpart = FIXED_PLL_SIZE * (long long)Nmod;
752
753	do_div(Kpart, source);
754
755	K = Kpart & 0xFFFFFFFF;
756
757	/* Check if we need to round */
758	if ((K % 10) >= 5)
759		K += 5;
760
761	/* Move down to proper range now rounding is done */
762	K /= 10;
763
764	pll_div->k = K;
765
766	pr_debug("WM8960 PLL: N=%x K=%x pre_div=%d\n",
767		 pll_div->n, pll_div->k, pll_div->pre_div);
768
769	return 0;
770}
771
772static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
773		int source, unsigned int freq_in, unsigned int freq_out)
774{
775	struct snd_soc_codec *codec = codec_dai->codec;
776	u16 reg;
777	static struct _pll_div pll_div;
778	int ret;
779
780	if (freq_in && freq_out) {
781		ret = pll_factors(freq_in, freq_out, &pll_div);
782		if (ret != 0)
783			return ret;
784	}
785
786	/* Disable the PLL: even if we are changing the frequency the
787	 * PLL needs to be disabled while we do so. */
788	snd_soc_write(codec, WM8960_CLOCK1,
789		     snd_soc_read(codec, WM8960_CLOCK1) & ~1);
790	snd_soc_write(codec, WM8960_POWER2,
791		     snd_soc_read(codec, WM8960_POWER2) & ~1);
792
793	if (!freq_in || !freq_out)
794		return 0;
795
796	reg = snd_soc_read(codec, WM8960_PLL1) & ~0x3f;
797	reg |= pll_div.pre_div << 4;
798	reg |= pll_div.n;
799
800	if (pll_div.k) {
801		reg |= 0x20;
802
803		snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f);
804		snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff);
805		snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0x1ff);
806	}
807	snd_soc_write(codec, WM8960_PLL1, reg);
808
809	/* Turn it on */
810	snd_soc_write(codec, WM8960_POWER2,
811		     snd_soc_read(codec, WM8960_POWER2) | 1);
812	msleep(250);
813	snd_soc_write(codec, WM8960_CLOCK1,
814		     snd_soc_read(codec, WM8960_CLOCK1) | 1);
815
816	return 0;
817}
818
819static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
820		int div_id, int div)
821{
822	struct snd_soc_codec *codec = codec_dai->codec;
823	u16 reg;
824
825	switch (div_id) {
826	case WM8960_SYSCLKDIV:
827		reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1f9;
828		snd_soc_write(codec, WM8960_CLOCK1, reg | div);
829		break;
830	case WM8960_DACDIV:
831		reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1c7;
832		snd_soc_write(codec, WM8960_CLOCK1, reg | div);
833		break;
834	case WM8960_OPCLKDIV:
835		reg = snd_soc_read(codec, WM8960_PLL1) & 0x03f;
836		snd_soc_write(codec, WM8960_PLL1, reg | div);
837		break;
838	case WM8960_DCLKDIV:
839		reg = snd_soc_read(codec, WM8960_CLOCK2) & 0x03f;
840		snd_soc_write(codec, WM8960_CLOCK2, reg | div);
841		break;
842	case WM8960_TOCLKSEL:
843		reg = snd_soc_read(codec, WM8960_ADDCTL1) & 0x1fd;
844		snd_soc_write(codec, WM8960_ADDCTL1, reg | div);
845		break;
846	default:
847		return -EINVAL;
848	}
849
850	return 0;
851}
852
853#define WM8960_RATES SNDRV_PCM_RATE_8000_48000
854
855#define WM8960_FORMATS \
856	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
857	SNDRV_PCM_FMTBIT_S24_LE)
858
859static struct snd_soc_dai_ops wm8960_dai_ops = {
860	.hw_params = wm8960_hw_params,
861	.digital_mute = wm8960_mute,
862	.set_fmt = wm8960_set_dai_fmt,
863	.set_clkdiv = wm8960_set_dai_clkdiv,
864	.set_pll = wm8960_set_dai_pll,
865};
866
867struct snd_soc_dai wm8960_dai = {
868	.name = "WM8960",
869	.playback = {
870		.stream_name = "Playback",
871		.channels_min = 1,
872		.channels_max = 2,
873		.rates = WM8960_RATES,
874		.formats = WM8960_FORMATS,},
875	.capture = {
876		.stream_name = "Capture",
877		.channels_min = 1,
878		.channels_max = 2,
879		.rates = WM8960_RATES,
880		.formats = WM8960_FORMATS,},
881	.ops = &wm8960_dai_ops,
882	.symmetric_rates = 1,
883};
884EXPORT_SYMBOL_GPL(wm8960_dai);
885
886static int wm8960_suspend(struct platform_device *pdev, pm_message_t state)
887{
888	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
889	struct snd_soc_codec *codec = socdev->card->codec;
890
891	codec->set_bias_level(codec, SND_SOC_BIAS_OFF);
892	return 0;
893}
894
895static int wm8960_resume(struct platform_device *pdev)
896{
897	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
898	struct snd_soc_codec *codec = socdev->card->codec;
899	int i;
900	u8 data[2];
901	u16 *cache = codec->reg_cache;
902
903	/* Sync reg_cache with the hardware */
904	for (i = 0; i < ARRAY_SIZE(wm8960_reg); i++) {
905		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
906		data[1] = cache[i] & 0x00ff;
907		codec->hw_write(codec->control_data, data, 2);
908	}
909
910	codec->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
911
912	return 0;
913}
914
915static struct snd_soc_codec *wm8960_codec;
916
917static int wm8960_probe(struct platform_device *pdev)
918{
919	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
920	struct snd_soc_codec *codec;
921	int ret = 0;
922
923	if (wm8960_codec == NULL) {
924		dev_err(&pdev->dev, "Codec device not registered\n");
925		return -ENODEV;
926	}
927
928	socdev->card->codec = wm8960_codec;
929	codec = wm8960_codec;
930
931	/* register pcms */
932	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
933	if (ret < 0) {
934		dev_err(codec->dev, "failed to create pcms: %d\n", ret);
935		goto pcm_err;
936	}
937
938	snd_soc_add_controls(codec, wm8960_snd_controls,
939			     ARRAY_SIZE(wm8960_snd_controls));
940	wm8960_add_widgets(codec);
941
942	return ret;
943
944pcm_err:
945	return ret;
946}
947
948/* power down chip */
949static int wm8960_remove(struct platform_device *pdev)
950{
951	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
952
953	snd_soc_free_pcms(socdev);
954	snd_soc_dapm_free(socdev);
955
956	return 0;
957}
958
959struct snd_soc_codec_device soc_codec_dev_wm8960 = {
960	.probe = 	wm8960_probe,
961	.remove = 	wm8960_remove,
962	.suspend = 	wm8960_suspend,
963	.resume =	wm8960_resume,
964};
965EXPORT_SYMBOL_GPL(soc_codec_dev_wm8960);
966
967static int wm8960_register(struct wm8960_priv *wm8960,
968			   enum snd_soc_control_type control)
969{
970	struct wm8960_data *pdata = wm8960->codec.dev->platform_data;
971	struct snd_soc_codec *codec = &wm8960->codec;
972	int ret;
973	u16 reg;
974
975	if (wm8960_codec) {
976		dev_err(codec->dev, "Another WM8960 is registered\n");
977		ret = -EINVAL;
978		goto err;
979	}
980
981	codec->set_bias_level = wm8960_set_bias_level_out3;
982
983	if (!pdata) {
984		dev_warn(codec->dev, "No platform data supplied\n");
985	} else {
986		if (pdata->dres > WM8960_DRES_MAX) {
987			dev_err(codec->dev, "Invalid DRES: %d\n", pdata->dres);
988			pdata->dres = 0;
989		}
990
991		if (pdata->capless)
992			codec->set_bias_level = wm8960_set_bias_level_capless;
993	}
994
995	mutex_init(&codec->mutex);
996	INIT_LIST_HEAD(&codec->dapm_widgets);
997	INIT_LIST_HEAD(&codec->dapm_paths);
998
999	snd_soc_codec_set_drvdata(codec, wm8960);
1000	codec->name = "WM8960";
1001	codec->owner = THIS_MODULE;
1002	codec->bias_level = SND_SOC_BIAS_OFF;
1003	codec->dai = &wm8960_dai;
1004	codec->num_dai = 1;
1005	codec->reg_cache_size = WM8960_CACHEREGNUM;
1006	codec->reg_cache = &wm8960->reg_cache;
1007
1008	memcpy(codec->reg_cache, wm8960_reg, sizeof(wm8960_reg));
1009
1010	ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
1011	if (ret < 0) {
1012		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1013		goto err;
1014	}
1015
1016	ret = wm8960_reset(codec);
1017	if (ret < 0) {
1018		dev_err(codec->dev, "Failed to issue reset\n");
1019		goto err;
1020	}
1021
1022	wm8960_dai.dev = codec->dev;
1023
1024	codec->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1025
1026	/* Latch the update bits */
1027	reg = snd_soc_read(codec, WM8960_LINVOL);
1028	snd_soc_write(codec, WM8960_LINVOL, reg | 0x100);
1029	reg = snd_soc_read(codec, WM8960_RINVOL);
1030	snd_soc_write(codec, WM8960_RINVOL, reg | 0x100);
1031	reg = snd_soc_read(codec, WM8960_LADC);
1032	snd_soc_write(codec, WM8960_LADC, reg | 0x100);
1033	reg = snd_soc_read(codec, WM8960_RADC);
1034	snd_soc_write(codec, WM8960_RADC, reg | 0x100);
1035	reg = snd_soc_read(codec, WM8960_LDAC);
1036	snd_soc_write(codec, WM8960_LDAC, reg | 0x100);
1037	reg = snd_soc_read(codec, WM8960_RDAC);
1038	snd_soc_write(codec, WM8960_RDAC, reg | 0x100);
1039	reg = snd_soc_read(codec, WM8960_LOUT1);
1040	snd_soc_write(codec, WM8960_LOUT1, reg | 0x100);
1041	reg = snd_soc_read(codec, WM8960_ROUT1);
1042	snd_soc_write(codec, WM8960_ROUT1, reg | 0x100);
1043	reg = snd_soc_read(codec, WM8960_LOUT2);
1044	snd_soc_write(codec, WM8960_LOUT2, reg | 0x100);
1045	reg = snd_soc_read(codec, WM8960_ROUT2);
1046	snd_soc_write(codec, WM8960_ROUT2, reg | 0x100);
1047
1048	wm8960_codec = codec;
1049
1050	ret = snd_soc_register_codec(codec);
1051	if (ret != 0) {
1052		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1053		goto err;
1054	}
1055
1056	ret = snd_soc_register_dai(&wm8960_dai);
1057	if (ret != 0) {
1058		dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1059		goto err_codec;
1060	}
1061
1062	return 0;
1063
1064err_codec:
1065	snd_soc_unregister_codec(codec);
1066err:
1067	kfree(wm8960);
1068	return ret;
1069}
1070
1071static void wm8960_unregister(struct wm8960_priv *wm8960)
1072{
1073	wm8960->codec.set_bias_level(&wm8960->codec, SND_SOC_BIAS_OFF);
1074	snd_soc_unregister_dai(&wm8960_dai);
1075	snd_soc_unregister_codec(&wm8960->codec);
1076	kfree(wm8960);
1077	wm8960_codec = NULL;
1078}
1079
1080static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
1081				      const struct i2c_device_id *id)
1082{
1083	struct wm8960_priv *wm8960;
1084	struct snd_soc_codec *codec;
1085
1086	wm8960 = kzalloc(sizeof(struct wm8960_priv), GFP_KERNEL);
1087	if (wm8960 == NULL)
1088		return -ENOMEM;
1089
1090	codec = &wm8960->codec;
1091
1092	i2c_set_clientdata(i2c, wm8960);
1093	codec->control_data = i2c;
1094
1095	codec->dev = &i2c->dev;
1096
1097	return wm8960_register(wm8960, SND_SOC_I2C);
1098}
1099
1100static __devexit int wm8960_i2c_remove(struct i2c_client *client)
1101{
1102	struct wm8960_priv *wm8960 = i2c_get_clientdata(client);
1103	wm8960_unregister(wm8960);
1104	return 0;
1105}
1106
1107static const struct i2c_device_id wm8960_i2c_id[] = {
1108	{ "wm8960", 0 },
1109	{ }
1110};
1111MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id);
1112
1113static struct i2c_driver wm8960_i2c_driver = {
1114	.driver = {
1115		.name = "wm8960",
1116		.owner = THIS_MODULE,
1117	},
1118	.probe =    wm8960_i2c_probe,
1119	.remove =   __devexit_p(wm8960_i2c_remove),
1120	.id_table = wm8960_i2c_id,
1121};
1122
1123static int __init wm8960_modinit(void)
1124{
1125	int ret;
1126
1127	ret = i2c_add_driver(&wm8960_i2c_driver);
1128	if (ret != 0) {
1129		printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n",
1130		       ret);
1131	}
1132
1133	return ret;
1134}
1135module_init(wm8960_modinit);
1136
1137static void __exit wm8960_exit(void)
1138{
1139	i2c_del_driver(&wm8960_i2c_driver);
1140}
1141module_exit(wm8960_exit);
1142
1143
1144MODULE_DESCRIPTION("ASoC WM8960 driver");
1145MODULE_AUTHOR("Liam Girdwood");
1146MODULE_LICENSE("GPL");
1147