1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * wm8940.c  --  WM8940 ALSA Soc Audio driver
4 *
5 * Author: Jonathan Cameron <jic23@cam.ac.uk>
6 *
7 * Based on wm8510.c
8 *    Copyright  2006 Wolfson Microelectronics PLC.
9 *    Author:  Liam Girdwood <lrg@slimlogic.co.uk>
10 *
11 * Not currently handled:
12 * Notch filter control
13 * AUXMode (inverting vs mixer)
14 * No means to obtain current gain if alc enabled.
15 * No use made of gpio
16 * Fast VMID discharge for power down
17 * Soft Start
18 * DLR and ALR Swaps not enabled
19 * Digital Sidetone not supported
20 */
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/pm.h>
27#include <linux/i2c.h>
28#include <linux/regmap.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc.h>
34#include <sound/initval.h>
35#include <sound/tlv.h>
36
37#include "wm8940.h"
38
39struct wm8940_priv {
40	unsigned int sysclk;
41	struct regmap *regmap;
42};
43
44static bool wm8940_volatile_register(struct device *dev, unsigned int reg)
45{
46	switch (reg) {
47	case WM8940_SOFTRESET:
48		return true;
49	default:
50		return false;
51	}
52}
53
54static bool wm8940_readable_register(struct device *dev, unsigned int reg)
55{
56	switch (reg) {
57	case WM8940_SOFTRESET:
58	case WM8940_POWER1:
59	case WM8940_POWER2:
60	case WM8940_POWER3:
61	case WM8940_IFACE:
62	case WM8940_COMPANDINGCTL:
63	case WM8940_CLOCK:
64	case WM8940_ADDCNTRL:
65	case WM8940_GPIO:
66	case WM8940_CTLINT:
67	case WM8940_DAC:
68	case WM8940_DACVOL:
69	case WM8940_ADC:
70	case WM8940_ADCVOL:
71	case WM8940_NOTCH1:
72	case WM8940_NOTCH2:
73	case WM8940_NOTCH3:
74	case WM8940_NOTCH4:
75	case WM8940_NOTCH5:
76	case WM8940_NOTCH6:
77	case WM8940_NOTCH7:
78	case WM8940_NOTCH8:
79	case WM8940_DACLIM1:
80	case WM8940_DACLIM2:
81	case WM8940_ALC1:
82	case WM8940_ALC2:
83	case WM8940_ALC3:
84	case WM8940_NOISEGATE:
85	case WM8940_PLLN:
86	case WM8940_PLLK1:
87	case WM8940_PLLK2:
88	case WM8940_PLLK3:
89	case WM8940_ALC4:
90	case WM8940_INPUTCTL:
91	case WM8940_PGAGAIN:
92	case WM8940_ADCBOOST:
93	case WM8940_OUTPUTCTL:
94	case WM8940_SPKMIX:
95	case WM8940_SPKVOL:
96	case WM8940_MONOMIX:
97		return true;
98	default:
99		return false;
100	}
101}
102
103static const struct reg_default wm8940_reg_defaults[] = {
104	{  0x1, 0x0000 }, /* Power 1 */
105	{  0x2, 0x0000 }, /* Power 2 */
106	{  0x3, 0x0000 }, /* Power 3 */
107	{  0x4, 0x0010 }, /* Interface Control */
108	{  0x5, 0x0000 }, /* Companding Control */
109	{  0x6, 0x0140 }, /* Clock Control */
110	{  0x7, 0x0000 }, /* Additional Controls */
111	{  0x8, 0x0000 }, /* GPIO Control */
112	{  0x9, 0x0002 }, /* Auto Increment Control */
113	{  0xa, 0x0000 }, /* DAC Control */
114	{  0xb, 0x00FF }, /* DAC Volume */
115
116	{  0xe, 0x0100 }, /* ADC Control */
117	{  0xf, 0x00FF }, /* ADC Volume */
118	{ 0x10, 0x0000 }, /* Notch Filter 1 Control 1 */
119	{ 0x11, 0x0000 }, /* Notch Filter 1 Control 2 */
120	{ 0x12, 0x0000 }, /* Notch Filter 2 Control 1 */
121	{ 0x13, 0x0000 }, /* Notch Filter 2 Control 2 */
122	{ 0x14, 0x0000 }, /* Notch Filter 3 Control 1 */
123	{ 0x15, 0x0000 }, /* Notch Filter 3 Control 2 */
124	{ 0x16, 0x0000 }, /* Notch Filter 4 Control 1 */
125	{ 0x17, 0x0000 }, /* Notch Filter 4 Control 2 */
126	{ 0x18, 0x0032 }, /* DAC Limit Control 1 */
127	{ 0x19, 0x0000 }, /* DAC Limit Control 2 */
128
129	{ 0x20, 0x0038 }, /* ALC Control 1 */
130	{ 0x21, 0x000B }, /* ALC Control 2 */
131	{ 0x22, 0x0032 }, /* ALC Control 3 */
132	{ 0x23, 0x0000 }, /* Noise Gate */
133	{ 0x24, 0x0041 }, /* PLLN */
134	{ 0x25, 0x000C }, /* PLLK1 */
135	{ 0x26, 0x0093 }, /* PLLK2 */
136	{ 0x27, 0x00E9 }, /* PLLK3 */
137
138	{ 0x2a, 0x0030 }, /* ALC Control 4 */
139
140	{ 0x2c, 0x0002 }, /* Input Control */
141	{ 0x2d, 0x0050 }, /* PGA Gain */
142
143	{ 0x2f, 0x0002 }, /* ADC Boost Control */
144
145	{ 0x31, 0x0002 }, /* Output Control */
146	{ 0x32, 0x0000 }, /* Speaker Mixer Control */
147
148	{ 0x36, 0x0079 }, /* Speaker Volume */
149
150	{ 0x38, 0x0000 }, /* Mono Mixer Control */
151};
152
153static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" };
154static SOC_ENUM_SINGLE_DECL(wm8940_adc_companding_enum,
155			    WM8940_COMPANDINGCTL, 1, wm8940_companding);
156static SOC_ENUM_SINGLE_DECL(wm8940_dac_companding_enum,
157			    WM8940_COMPANDINGCTL, 3, wm8940_companding);
158
159static const char *wm8940_alc_mode_text[] = {"ALC", "Limiter"};
160static SOC_ENUM_SINGLE_DECL(wm8940_alc_mode_enum,
161			    WM8940_ALC3, 8, wm8940_alc_mode_text);
162
163static const char *wm8940_mic_bias_level_text[] = {"0.9", "0.65"};
164static SOC_ENUM_SINGLE_DECL(wm8940_mic_bias_level_enum,
165			    WM8940_INPUTCTL, 8, wm8940_mic_bias_level_text);
166
167static const char *wm8940_filter_mode_text[] = {"Audio", "Application"};
168static SOC_ENUM_SINGLE_DECL(wm8940_filter_mode_enum,
169			    WM8940_ADC, 7, wm8940_filter_mode_text);
170
171static DECLARE_TLV_DB_SCALE(wm8940_spk_vol_tlv, -5700, 100, 1);
172static DECLARE_TLV_DB_SCALE(wm8940_att_tlv, -1000, 1000, 0);
173static DECLARE_TLV_DB_SCALE(wm8940_pga_vol_tlv, -1200, 75, 0);
174static DECLARE_TLV_DB_SCALE(wm8940_alc_min_tlv, -1200, 600, 0);
175static DECLARE_TLV_DB_SCALE(wm8940_alc_max_tlv, 675, 600, 0);
176static DECLARE_TLV_DB_SCALE(wm8940_alc_tar_tlv, -2250, 50, 0);
177static DECLARE_TLV_DB_SCALE(wm8940_lim_boost_tlv, 0, 100, 0);
178static DECLARE_TLV_DB_SCALE(wm8940_lim_thresh_tlv, -600, 100, 0);
179static DECLARE_TLV_DB_SCALE(wm8940_adc_tlv, -12750, 50, 1);
180static DECLARE_TLV_DB_SCALE(wm8940_capture_boost_vol_tlv, 0, 2000, 0);
181
182static const struct snd_kcontrol_new wm8940_snd_controls[] = {
183	SOC_SINGLE("Digital Loopback Switch", WM8940_COMPANDINGCTL,
184		   6, 1, 0),
185	SOC_ENUM("DAC Companding", wm8940_dac_companding_enum),
186	SOC_ENUM("ADC Companding", wm8940_adc_companding_enum),
187
188	SOC_ENUM("ALC Mode", wm8940_alc_mode_enum),
189	SOC_SINGLE("ALC Switch", WM8940_ALC1, 8, 1, 0),
190	SOC_SINGLE_TLV("ALC Capture Max Gain", WM8940_ALC1,
191		       3, 7, 1, wm8940_alc_max_tlv),
192	SOC_SINGLE_TLV("ALC Capture Min Gain", WM8940_ALC1,
193		       0, 7, 0, wm8940_alc_min_tlv),
194	SOC_SINGLE_TLV("ALC Capture Target", WM8940_ALC2,
195		       0, 14, 0, wm8940_alc_tar_tlv),
196	SOC_SINGLE("ALC Capture Hold", WM8940_ALC2, 4, 10, 0),
197	SOC_SINGLE("ALC Capture Decay", WM8940_ALC3, 4, 10, 0),
198	SOC_SINGLE("ALC Capture Attach", WM8940_ALC3, 0, 10, 0),
199	SOC_SINGLE("ALC ZC Switch", WM8940_ALC4, 1, 1, 0),
200	SOC_SINGLE("ALC Capture Noise Gate Switch", WM8940_NOISEGATE,
201		   3, 1, 0),
202	SOC_SINGLE("ALC Capture Noise Gate Threshold", WM8940_NOISEGATE,
203		   0, 7, 0),
204
205	SOC_SINGLE("DAC Playback Limiter Switch", WM8940_DACLIM1, 8, 1, 0),
206	SOC_SINGLE("DAC Playback Limiter Attack", WM8940_DACLIM1, 0, 9, 0),
207	SOC_SINGLE("DAC Playback Limiter Decay", WM8940_DACLIM1, 4, 11, 0),
208	SOC_SINGLE_TLV("DAC Playback Limiter Threshold", WM8940_DACLIM2,
209		       4, 9, 1, wm8940_lim_thresh_tlv),
210	SOC_SINGLE_TLV("DAC Playback Limiter Boost", WM8940_DACLIM2,
211		       0, 12, 0, wm8940_lim_boost_tlv),
212
213	SOC_SINGLE("Capture PGA ZC Switch", WM8940_PGAGAIN, 7, 1, 0),
214	SOC_SINGLE_TLV("Capture PGA Volume", WM8940_PGAGAIN,
215		       0, 63, 0, wm8940_pga_vol_tlv),
216	SOC_SINGLE_TLV("Digital Playback Volume", WM8940_DACVOL,
217		       0, 255, 0, wm8940_adc_tlv),
218	SOC_SINGLE_TLV("Digital Capture Volume", WM8940_ADCVOL,
219		       0, 255, 0, wm8940_adc_tlv),
220	SOC_ENUM("Mic Bias Level", wm8940_mic_bias_level_enum),
221	SOC_SINGLE_TLV("Capture Boost Volue", WM8940_ADCBOOST,
222		       8, 1, 0, wm8940_capture_boost_vol_tlv),
223	SOC_SINGLE_TLV("Speaker Playback Volume", WM8940_SPKVOL,
224		       0, 63, 0, wm8940_spk_vol_tlv),
225	SOC_SINGLE("Speaker Playback Switch", WM8940_SPKVOL,  6, 1, 1),
226
227	SOC_SINGLE_TLV("Speaker Mixer Line Bypass Volume", WM8940_SPKVOL,
228		       8, 1, 1, wm8940_att_tlv),
229	SOC_SINGLE("Speaker Playback ZC Switch", WM8940_SPKVOL, 7, 1, 0),
230
231	SOC_SINGLE("Mono Out Switch", WM8940_MONOMIX, 6, 1, 1),
232	SOC_SINGLE_TLV("Mono Mixer Line Bypass Volume", WM8940_MONOMIX,
233		       7, 1, 1, wm8940_att_tlv),
234
235	SOC_SINGLE("High Pass Filter Switch", WM8940_ADC, 8, 1, 0),
236	SOC_ENUM("High Pass Filter Mode", wm8940_filter_mode_enum),
237	SOC_SINGLE("High Pass Filter Cut Off", WM8940_ADC, 4, 7, 0),
238	SOC_SINGLE("ADC Inversion Switch", WM8940_ADC, 0, 1, 0),
239	SOC_SINGLE("DAC Inversion Switch", WM8940_DAC, 0, 1, 0),
240	SOC_SINGLE("DAC Auto Mute Switch", WM8940_DAC, 2, 1, 0),
241	SOC_SINGLE("ZC Timeout Clock Switch", WM8940_ADDCNTRL, 0, 1, 0),
242};
243
244static const struct snd_kcontrol_new wm8940_speaker_mixer_controls[] = {
245	SOC_DAPM_SINGLE("Line Bypass Switch", WM8940_SPKMIX, 1, 1, 0),
246	SOC_DAPM_SINGLE("Aux Playback Switch", WM8940_SPKMIX, 5, 1, 0),
247	SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_SPKMIX, 0, 1, 0),
248};
249
250static const struct snd_kcontrol_new wm8940_mono_mixer_controls[] = {
251	SOC_DAPM_SINGLE("Line Bypass Switch", WM8940_MONOMIX, 1, 1, 0),
252	SOC_DAPM_SINGLE("Aux Playback Switch", WM8940_MONOMIX, 2, 1, 0),
253	SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_MONOMIX, 0, 1, 0),
254};
255
256static DECLARE_TLV_DB_SCALE(wm8940_boost_vol_tlv, -1500, 300, 1);
257static const struct snd_kcontrol_new wm8940_input_boost_controls[] = {
258	SOC_DAPM_SINGLE("Mic PGA Switch", WM8940_PGAGAIN, 6, 1, 1),
259	SOC_DAPM_SINGLE_TLV("Aux Volume", WM8940_ADCBOOST,
260			    0, 7, 0, wm8940_boost_vol_tlv),
261	SOC_DAPM_SINGLE_TLV("Mic Volume", WM8940_ADCBOOST,
262			    4, 7, 0, wm8940_boost_vol_tlv),
263};
264
265static const struct snd_kcontrol_new wm8940_micpga_controls[] = {
266	SOC_DAPM_SINGLE("AUX Switch", WM8940_INPUTCTL, 2, 1, 0),
267	SOC_DAPM_SINGLE("MICP Switch", WM8940_INPUTCTL, 0, 1, 0),
268	SOC_DAPM_SINGLE("MICN Switch", WM8940_INPUTCTL, 1, 1, 0),
269};
270
271static const struct snd_soc_dapm_widget wm8940_dapm_widgets[] = {
272	SND_SOC_DAPM_MIXER("Speaker Mixer", WM8940_POWER3, 2, 0,
273			   &wm8940_speaker_mixer_controls[0],
274			   ARRAY_SIZE(wm8940_speaker_mixer_controls)),
275	SND_SOC_DAPM_MIXER("Mono Mixer", WM8940_POWER3, 3, 0,
276			   &wm8940_mono_mixer_controls[0],
277			   ARRAY_SIZE(wm8940_mono_mixer_controls)),
278	SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8940_POWER3, 0, 0),
279
280	SND_SOC_DAPM_PGA("SpkN Out", WM8940_POWER3, 5, 0, NULL, 0),
281	SND_SOC_DAPM_PGA("SpkP Out", WM8940_POWER3, 6, 0, NULL, 0),
282	SND_SOC_DAPM_PGA("Mono Out", WM8940_POWER3, 7, 0, NULL, 0),
283	SND_SOC_DAPM_OUTPUT("MONOOUT"),
284	SND_SOC_DAPM_OUTPUT("SPKOUTP"),
285	SND_SOC_DAPM_OUTPUT("SPKOUTN"),
286
287	SND_SOC_DAPM_PGA("Aux Input", WM8940_POWER1, 6, 0, NULL, 0),
288	SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8940_POWER2, 0, 0),
289	SND_SOC_DAPM_MIXER("Mic PGA", WM8940_POWER2, 2, 0,
290			   &wm8940_micpga_controls[0],
291			   ARRAY_SIZE(wm8940_micpga_controls)),
292	SND_SOC_DAPM_MIXER("Boost Mixer", WM8940_POWER2, 4, 0,
293			   &wm8940_input_boost_controls[0],
294			   ARRAY_SIZE(wm8940_input_boost_controls)),
295	SND_SOC_DAPM_MICBIAS("Mic Bias", WM8940_POWER1, 4, 0),
296
297	SND_SOC_DAPM_INPUT("MICN"),
298	SND_SOC_DAPM_INPUT("MICP"),
299	SND_SOC_DAPM_INPUT("AUX"),
300};
301
302static const struct snd_soc_dapm_route wm8940_dapm_routes[] = {
303	/* Mono output mixer */
304	{"Mono Mixer", "PCM Playback Switch", "DAC"},
305	{"Mono Mixer", "Aux Playback Switch", "Aux Input"},
306	{"Mono Mixer", "Line Bypass Switch", "Boost Mixer"},
307
308	/* Speaker output mixer */
309	{"Speaker Mixer", "PCM Playback Switch", "DAC"},
310	{"Speaker Mixer", "Aux Playback Switch", "Aux Input"},
311	{"Speaker Mixer", "Line Bypass Switch", "Boost Mixer"},
312
313	/* Outputs */
314	{"Mono Out", NULL, "Mono Mixer"},
315	{"MONOOUT", NULL, "Mono Out"},
316	{"SpkN Out", NULL, "Speaker Mixer"},
317	{"SpkP Out", NULL, "Speaker Mixer"},
318	{"SPKOUTN", NULL, "SpkN Out"},
319	{"SPKOUTP", NULL, "SpkP Out"},
320
321	/*  Microphone PGA */
322	{"Mic PGA", "MICN Switch", "MICN"},
323	{"Mic PGA", "MICP Switch", "MICP"},
324	{"Mic PGA", "AUX Switch", "AUX"},
325
326	/* Boost Mixer */
327	{"Boost Mixer", "Mic PGA Switch", "Mic PGA"},
328	{"Boost Mixer", "Mic Volume",  "MICP"},
329	{"Boost Mixer", "Aux Volume", "Aux Input"},
330
331	{"ADC", NULL, "Boost Mixer"},
332};
333
334#define wm8940_reset(c) snd_soc_component_write(c, WM8940_SOFTRESET, 0);
335
336static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
337			      unsigned int fmt)
338{
339	struct snd_soc_component *component = codec_dai->component;
340	u16 iface = snd_soc_component_read(component, WM8940_IFACE) & 0xFE67;
341	u16 clk = snd_soc_component_read(component, WM8940_CLOCK) & 0x1fe;
342
343	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
344	case SND_SOC_DAIFMT_CBM_CFM:
345		clk |= 1;
346		break;
347	case SND_SOC_DAIFMT_CBS_CFS:
348		break;
349	default:
350		return -EINVAL;
351	}
352	snd_soc_component_write(component, WM8940_CLOCK, clk);
353
354	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
355	case SND_SOC_DAIFMT_I2S:
356		iface |= (2 << 3);
357		break;
358	case SND_SOC_DAIFMT_LEFT_J:
359		iface |= (1 << 3);
360		break;
361	case SND_SOC_DAIFMT_RIGHT_J:
362		break;
363	case SND_SOC_DAIFMT_DSP_A:
364		iface |= (3 << 3);
365		break;
366	case SND_SOC_DAIFMT_DSP_B:
367		iface |= (3 << 3) | (1 << 7);
368		break;
369	}
370
371	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
372	case SND_SOC_DAIFMT_NB_NF:
373		break;
374	case SND_SOC_DAIFMT_NB_IF:
375		iface |= (1 << 7);
376		break;
377	case SND_SOC_DAIFMT_IB_NF:
378		iface |= (1 << 8);
379		break;
380	case SND_SOC_DAIFMT_IB_IF:
381		iface |= (1 << 8) | (1 << 7);
382		break;
383	}
384
385	snd_soc_component_write(component, WM8940_IFACE, iface);
386
387	return 0;
388}
389
390static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
391				struct snd_pcm_hw_params *params,
392				struct snd_soc_dai *dai)
393{
394	struct snd_soc_component *component = dai->component;
395	u16 iface = snd_soc_component_read(component, WM8940_IFACE) & 0xFD9F;
396	u16 addcntrl = snd_soc_component_read(component, WM8940_ADDCNTRL) & 0xFFF1;
397	u16 companding =  snd_soc_component_read(component,
398						WM8940_COMPANDINGCTL) & 0xFFDF;
399	int ret;
400
401	/* LoutR control */
402	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE
403	    && params_channels(params) == 2)
404		iface |= (1 << 9);
405
406	switch (params_rate(params)) {
407	case 8000:
408		addcntrl |= (0x5 << 1);
409		break;
410	case 11025:
411		addcntrl |= (0x4 << 1);
412		break;
413	case 16000:
414		addcntrl |= (0x3 << 1);
415		break;
416	case 22050:
417		addcntrl |= (0x2 << 1);
418		break;
419	case 32000:
420		addcntrl |= (0x1 << 1);
421		break;
422	case 44100:
423	case 48000:
424		break;
425	}
426	ret = snd_soc_component_write(component, WM8940_ADDCNTRL, addcntrl);
427	if (ret)
428		goto error_ret;
429
430	switch (params_width(params)) {
431	case 8:
432		companding = companding | (1 << 5);
433		break;
434	case 16:
435		break;
436	case 20:
437		iface |= (1 << 5);
438		break;
439	case 24:
440		iface |= (2 << 5);
441		break;
442	case 32:
443		iface |= (3 << 5);
444		break;
445	}
446	ret = snd_soc_component_write(component, WM8940_COMPANDINGCTL, companding);
447	if (ret)
448		goto error_ret;
449	ret = snd_soc_component_write(component, WM8940_IFACE, iface);
450
451error_ret:
452	return ret;
453}
454
455static int wm8940_mute(struct snd_soc_dai *dai, int mute, int direction)
456{
457	struct snd_soc_component *component = dai->component;
458	u16 mute_reg = snd_soc_component_read(component, WM8940_DAC) & 0xffbf;
459
460	if (mute)
461		mute_reg |= 0x40;
462
463	return snd_soc_component_write(component, WM8940_DAC, mute_reg);
464}
465
466static int wm8940_set_bias_level(struct snd_soc_component *component,
467				 enum snd_soc_bias_level level)
468{
469	struct wm8940_priv *wm8940 = snd_soc_component_get_drvdata(component);
470	u16 val;
471	u16 pwr_reg = snd_soc_component_read(component, WM8940_POWER1) & 0x1F0;
472	int ret = 0;
473
474	switch (level) {
475	case SND_SOC_BIAS_ON:
476		/* ensure bufioen and biasen */
477		pwr_reg |= (1 << 2) | (1 << 3);
478		/* Enable thermal shutdown */
479		val = snd_soc_component_read(component, WM8940_OUTPUTCTL);
480		ret = snd_soc_component_write(component, WM8940_OUTPUTCTL, val | 0x2);
481		if (ret)
482			break;
483		/* set vmid to 75k */
484		ret = snd_soc_component_write(component, WM8940_POWER1, pwr_reg | 0x1);
485		break;
486	case SND_SOC_BIAS_PREPARE:
487		/* ensure bufioen and biasen */
488		pwr_reg |= (1 << 2) | (1 << 3);
489		ret = snd_soc_component_write(component, WM8940_POWER1, pwr_reg | 0x1);
490		break;
491	case SND_SOC_BIAS_STANDBY:
492		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
493			ret = regcache_sync(wm8940->regmap);
494			if (ret < 0) {
495				dev_err(component->dev, "Failed to sync cache: %d\n", ret);
496				return ret;
497			}
498		}
499
500		/* ensure bufioen and biasen */
501		pwr_reg |= (1 << 2) | (1 << 3);
502		/* set vmid to 300k for standby */
503		ret = snd_soc_component_write(component, WM8940_POWER1, pwr_reg | 0x2);
504		break;
505	case SND_SOC_BIAS_OFF:
506		ret = snd_soc_component_write(component, WM8940_POWER1, pwr_reg);
507		break;
508	}
509
510	return ret;
511}
512
513struct pll_ {
514	unsigned int pre_scale:2;
515	unsigned int n:4;
516	unsigned int k;
517};
518
519static struct pll_ pll_div;
520
521/* The size in bits of the pll divide multiplied by 10
522 * to allow rounding later */
523#define FIXED_PLL_SIZE ((1 << 24) * 10)
524static void pll_factors(unsigned int target, unsigned int source)
525{
526	unsigned long long Kpart;
527	unsigned int K, Ndiv, Nmod;
528	/* The left shift ist to avoid accuracy loss when right shifting */
529	Ndiv = target / source;
530
531	if (Ndiv > 12) {
532		source <<= 1;
533		/* Multiply by 2 */
534		pll_div.pre_scale = 0;
535		Ndiv = target / source;
536	} else if (Ndiv < 3) {
537		source >>= 2;
538		/* Divide by 4 */
539		pll_div.pre_scale = 3;
540		Ndiv = target / source;
541	} else if (Ndiv < 6) {
542		source >>= 1;
543		/* divide by 2 */
544		pll_div.pre_scale = 2;
545		Ndiv = target / source;
546	} else
547		pll_div.pre_scale = 1;
548
549	if ((Ndiv < 6) || (Ndiv > 12))
550		printk(KERN_WARNING
551			"WM8940 N value %d outwith recommended range!d\n",
552			Ndiv);
553
554	pll_div.n = Ndiv;
555	Nmod = target % source;
556	Kpart = FIXED_PLL_SIZE * (long long)Nmod;
557
558	do_div(Kpart, source);
559
560	K = Kpart & 0xFFFFFFFF;
561
562	/* Check if we need to round */
563	if ((K % 10) >= 5)
564		K += 5;
565
566	/* Move down to proper range now rounding is done */
567	K /= 10;
568
569	pll_div.k = K;
570}
571
572/* Untested at the moment */
573static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
574		int source, unsigned int freq_in, unsigned int freq_out)
575{
576	struct snd_soc_component *component = codec_dai->component;
577	u16 reg;
578
579	/* Turn off PLL */
580	reg = snd_soc_component_read(component, WM8940_POWER1);
581	snd_soc_component_write(component, WM8940_POWER1, reg & 0x1df);
582
583	if (freq_in == 0 || freq_out == 0) {
584		/* Clock CODEC directly from MCLK */
585		reg = snd_soc_component_read(component, WM8940_CLOCK);
586		snd_soc_component_write(component, WM8940_CLOCK, reg & 0x0ff);
587		/* Pll power down */
588		snd_soc_component_write(component, WM8940_PLLN, (1 << 7));
589		return 0;
590	}
591
592	/* Pll is followed by a frequency divide by 4 */
593	pll_factors(freq_out*4, freq_in);
594	if (pll_div.k)
595		snd_soc_component_write(component, WM8940_PLLN,
596			     (pll_div.pre_scale << 4) | pll_div.n | (1 << 6));
597	else /* No factional component */
598		snd_soc_component_write(component, WM8940_PLLN,
599			     (pll_div.pre_scale << 4) | pll_div.n);
600	snd_soc_component_write(component, WM8940_PLLK1, pll_div.k >> 18);
601	snd_soc_component_write(component, WM8940_PLLK2, (pll_div.k >> 9) & 0x1ff);
602	snd_soc_component_write(component, WM8940_PLLK3, pll_div.k & 0x1ff);
603	/* Enable the PLL */
604	reg = snd_soc_component_read(component, WM8940_POWER1);
605	snd_soc_component_write(component, WM8940_POWER1, reg | 0x020);
606
607	/* Run CODEC from PLL instead of MCLK */
608	reg = snd_soc_component_read(component, WM8940_CLOCK);
609	snd_soc_component_write(component, WM8940_CLOCK, reg | 0x100);
610
611	return 0;
612}
613
614static int wm8940_set_dai_sysclk(struct snd_soc_dai *codec_dai,
615				 int clk_id, unsigned int freq, int dir)
616{
617	struct snd_soc_component *component = codec_dai->component;
618	struct wm8940_priv *wm8940 = snd_soc_component_get_drvdata(component);
619
620	switch (freq) {
621	case 11289600:
622	case 12000000:
623	case 12288000:
624	case 16934400:
625	case 18432000:
626		wm8940->sysclk = freq;
627		return 0;
628	}
629	return -EINVAL;
630}
631
632static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
633				 int div_id, int div)
634{
635	struct snd_soc_component *component = codec_dai->component;
636	u16 reg;
637	int ret = 0;
638
639	switch (div_id) {
640	case WM8940_BCLKDIV:
641		reg = snd_soc_component_read(component, WM8940_CLOCK) & 0xFFE3;
642		ret = snd_soc_component_write(component, WM8940_CLOCK, reg | (div << 2));
643		break;
644	case WM8940_MCLKDIV:
645		reg = snd_soc_component_read(component, WM8940_CLOCK) & 0xFF1F;
646		ret = snd_soc_component_write(component, WM8940_CLOCK, reg | (div << 5));
647		break;
648	case WM8940_OPCLKDIV:
649		reg = snd_soc_component_read(component, WM8940_GPIO) & 0xFFCF;
650		ret = snd_soc_component_write(component, WM8940_GPIO, reg | (div << 4));
651		break;
652	}
653	return ret;
654}
655
656#define WM8940_RATES SNDRV_PCM_RATE_8000_48000
657
658#define WM8940_FORMATS (SNDRV_PCM_FMTBIT_S8 |				\
659			SNDRV_PCM_FMTBIT_S16_LE |			\
660			SNDRV_PCM_FMTBIT_S20_3LE |			\
661			SNDRV_PCM_FMTBIT_S24_LE |			\
662			SNDRV_PCM_FMTBIT_S32_LE)
663
664static const struct snd_soc_dai_ops wm8940_dai_ops = {
665	.hw_params = wm8940_i2s_hw_params,
666	.set_sysclk = wm8940_set_dai_sysclk,
667	.mute_stream = wm8940_mute,
668	.set_fmt = wm8940_set_dai_fmt,
669	.set_clkdiv = wm8940_set_dai_clkdiv,
670	.set_pll = wm8940_set_dai_pll,
671	.no_capture_mute = 1,
672};
673
674static struct snd_soc_dai_driver wm8940_dai = {
675	.name = "wm8940-hifi",
676	.playback = {
677		.stream_name = "Playback",
678		.channels_min = 1,
679		.channels_max = 2,
680		.rates = WM8940_RATES,
681		.formats = WM8940_FORMATS,
682	},
683	.capture = {
684		.stream_name = "Capture",
685		.channels_min = 1,
686		.channels_max = 2,
687		.rates = WM8940_RATES,
688		.formats = WM8940_FORMATS,
689	},
690	.ops = &wm8940_dai_ops,
691	.symmetric_rates = 1,
692};
693
694static int wm8940_probe(struct snd_soc_component *component)
695{
696	struct wm8940_setup_data *pdata = component->dev->platform_data;
697	int ret;
698	u16 reg;
699
700	ret = wm8940_reset(component);
701	if (ret < 0) {
702		dev_err(component->dev, "Failed to issue reset\n");
703		return ret;
704	}
705
706	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
707
708	ret = snd_soc_component_write(component, WM8940_POWER1, 0x180);
709	if (ret < 0)
710		return ret;
711
712	if (!pdata)
713		dev_warn(component->dev, "No platform data supplied\n");
714	else {
715		reg = snd_soc_component_read(component, WM8940_OUTPUTCTL);
716		ret = snd_soc_component_write(component, WM8940_OUTPUTCTL, reg | pdata->vroi);
717		if (ret < 0)
718			return ret;
719	}
720
721	return ret;
722}
723
724static const struct snd_soc_component_driver soc_component_dev_wm8940 = {
725	.probe			= wm8940_probe,
726	.set_bias_level		= wm8940_set_bias_level,
727	.controls		= wm8940_snd_controls,
728	.num_controls		= ARRAY_SIZE(wm8940_snd_controls),
729	.dapm_widgets		= wm8940_dapm_widgets,
730	.num_dapm_widgets	= ARRAY_SIZE(wm8940_dapm_widgets),
731	.dapm_routes		= wm8940_dapm_routes,
732	.num_dapm_routes	= ARRAY_SIZE(wm8940_dapm_routes),
733	.suspend_bias_off	= 1,
734	.idle_bias_on		= 1,
735	.use_pmdown_time	= 1,
736	.endianness		= 1,
737	.non_legacy_dai_naming	= 1,
738};
739
740static const struct regmap_config wm8940_regmap = {
741	.reg_bits = 8,
742	.val_bits = 16,
743
744	.max_register = WM8940_MONOMIX,
745	.reg_defaults = wm8940_reg_defaults,
746	.num_reg_defaults = ARRAY_SIZE(wm8940_reg_defaults),
747	.cache_type = REGCACHE_RBTREE,
748
749	.readable_reg = wm8940_readable_register,
750	.volatile_reg = wm8940_volatile_register,
751};
752
753static int wm8940_i2c_probe(struct i2c_client *i2c,
754			    const struct i2c_device_id *id)
755{
756	struct wm8940_priv *wm8940;
757	int ret;
758
759	wm8940 = devm_kzalloc(&i2c->dev, sizeof(struct wm8940_priv),
760			      GFP_KERNEL);
761	if (wm8940 == NULL)
762		return -ENOMEM;
763
764	wm8940->regmap = devm_regmap_init_i2c(i2c, &wm8940_regmap);
765	if (IS_ERR(wm8940->regmap))
766		return PTR_ERR(wm8940->regmap);
767
768	i2c_set_clientdata(i2c, wm8940);
769
770	ret = devm_snd_soc_register_component(&i2c->dev,
771			&soc_component_dev_wm8940, &wm8940_dai, 1);
772
773	return ret;
774}
775
776static const struct i2c_device_id wm8940_i2c_id[] = {
777	{ "wm8940", 0 },
778	{ }
779};
780MODULE_DEVICE_TABLE(i2c, wm8940_i2c_id);
781
782static struct i2c_driver wm8940_i2c_driver = {
783	.driver = {
784		.name = "wm8940",
785	},
786	.probe =    wm8940_i2c_probe,
787	.id_table = wm8940_i2c_id,
788};
789
790module_i2c_driver(wm8940_i2c_driver);
791
792MODULE_DESCRIPTION("ASoC WM8940 driver");
793MODULE_AUTHOR("Jonathan Cameron");
794MODULE_LICENSE("GPL");
795