• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/sound/soc/s3c24xx/
1/*
2 * neo1973_wm8753.c  --  SoC audio for Neo1973
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 *         graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 *  This program is free software; you can redistribute  it and/or modify it
9 *  under  the terms of  the GNU General  Public License as published by the
10 *  Free Software Foundation;  either version 2 of the  License, or (at your
11 *  option) any later version.
12 *
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/timer.h>
18#include <linux/interrupt.h>
19#include <linux/platform_device.h>
20#include <linux/i2c.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25#include <sound/tlv.h>
26
27#include <asm/mach-types.h>
28#include <asm/hardware/scoop.h>
29#include <mach/regs-clock.h>
30#include <mach/regs-gpio.h>
31#include <mach/hardware.h>
32#include <linux/io.h>
33#include <mach/spi-gpio.h>
34
35#include <plat/regs-iis.h>
36
37#include "../codecs/wm8753.h"
38#include "lm4857.h"
39#include "s3c-dma.h"
40#include "s3c24xx-i2s.h"
41
42/* define the scenarios */
43#define NEO_AUDIO_OFF			0
44#define NEO_GSM_CALL_AUDIO_HANDSET	1
45#define NEO_GSM_CALL_AUDIO_HEADSET	2
46#define NEO_GSM_CALL_AUDIO_BLUETOOTH	3
47#define NEO_STEREO_TO_SPEAKERS		4
48#define NEO_STEREO_TO_HEADPHONES	5
49#define NEO_CAPTURE_HANDSET		6
50#define NEO_CAPTURE_HEADSET		7
51#define NEO_CAPTURE_BLUETOOTH		8
52
53static struct snd_soc_card neo1973;
54static struct i2c_client *i2c;
55
56static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
57	struct snd_pcm_hw_params *params)
58{
59	struct snd_soc_pcm_runtime *rtd = substream->private_data;
60	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
61	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
62	unsigned int pll_out = 0, bclk = 0;
63	int ret = 0;
64	unsigned long iis_clkrate;
65
66	pr_debug("Entered %s\n", __func__);
67
68	iis_clkrate = s3c24xx_i2s_get_clockrate();
69
70	switch (params_rate(params)) {
71	case 8000:
72	case 16000:
73		pll_out = 12288000;
74		break;
75	case 48000:
76		bclk = WM8753_BCLK_DIV_4;
77		pll_out = 12288000;
78		break;
79	case 96000:
80		bclk = WM8753_BCLK_DIV_2;
81		pll_out = 12288000;
82		break;
83	case 11025:
84		bclk = WM8753_BCLK_DIV_16;
85		pll_out = 11289600;
86		break;
87	case 22050:
88		bclk = WM8753_BCLK_DIV_8;
89		pll_out = 11289600;
90		break;
91	case 44100:
92		bclk = WM8753_BCLK_DIV_4;
93		pll_out = 11289600;
94		break;
95	case 88200:
96		bclk = WM8753_BCLK_DIV_2;
97		pll_out = 11289600;
98		break;
99	}
100
101	/* set codec DAI configuration */
102	ret = snd_soc_dai_set_fmt(codec_dai,
103		SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
104		SND_SOC_DAIFMT_CBM_CFM);
105	if (ret < 0)
106		return ret;
107
108	/* set cpu DAI configuration */
109	ret = snd_soc_dai_set_fmt(cpu_dai,
110		SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
111		SND_SOC_DAIFMT_CBM_CFM);
112	if (ret < 0)
113		return ret;
114
115	/* set the codec system clock for DAC and ADC */
116	ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out,
117		SND_SOC_CLOCK_IN);
118	if (ret < 0)
119		return ret;
120
121	/* set MCLK division for sample rate */
122	ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
123		S3C2410_IISMOD_32FS);
124	if (ret < 0)
125		return ret;
126
127	/* set codec BCLK division for sample rate */
128	ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk);
129	if (ret < 0)
130		return ret;
131
132	/* set prescaler division for sample rate */
133	ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
134		S3C24XX_PRESCALE(4, 4));
135	if (ret < 0)
136		return ret;
137
138	/* codec PLL input is PCLK/4 */
139	ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
140		iis_clkrate / 4, pll_out);
141	if (ret < 0)
142		return ret;
143
144	return 0;
145}
146
147static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
148{
149	struct snd_soc_pcm_runtime *rtd = substream->private_data;
150	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
151
152	pr_debug("Entered %s\n", __func__);
153
154	/* disable the PLL */
155	return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
156}
157
158/*
159 * Neo1973 WM8753 HiFi DAI opserations.
160 */
161static struct snd_soc_ops neo1973_hifi_ops = {
162	.hw_params = neo1973_hifi_hw_params,
163	.hw_free = neo1973_hifi_hw_free,
164};
165
166static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
167	struct snd_pcm_hw_params *params)
168{
169	struct snd_soc_pcm_runtime *rtd = substream->private_data;
170	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
171	unsigned int pcmdiv = 0;
172	int ret = 0;
173	unsigned long iis_clkrate;
174
175	pr_debug("Entered %s\n", __func__);
176
177	iis_clkrate = s3c24xx_i2s_get_clockrate();
178
179	if (params_rate(params) != 8000)
180		return -EINVAL;
181	if (params_channels(params) != 1)
182		return -EINVAL;
183
184	pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */
185
186	/* todo: gg check mode (DSP_B) against CSR datasheet */
187	/* set codec DAI configuration */
188	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B |
189		SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
190	if (ret < 0)
191		return ret;
192
193	/* set the codec system clock for DAC and ADC */
194	ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, 12288000,
195		SND_SOC_CLOCK_IN);
196	if (ret < 0)
197		return ret;
198
199	/* set codec PCM division for sample rate */
200	ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv);
201	if (ret < 0)
202		return ret;
203
204	/* configue and enable PLL for 12.288MHz output */
205	ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
206		iis_clkrate / 4, 12288000);
207	if (ret < 0)
208		return ret;
209
210	return 0;
211}
212
213static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
214{
215	struct snd_soc_pcm_runtime *rtd = substream->private_data;
216	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
217
218	pr_debug("Entered %s\n", __func__);
219
220	/* disable the PLL */
221	return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
222}
223
224static struct snd_soc_ops neo1973_voice_ops = {
225	.hw_params = neo1973_voice_hw_params,
226	.hw_free = neo1973_voice_hw_free,
227};
228
229static int neo1973_scenario;
230
231static int neo1973_get_scenario(struct snd_kcontrol *kcontrol,
232	struct snd_ctl_elem_value *ucontrol)
233{
234	ucontrol->value.integer.value[0] = neo1973_scenario;
235	return 0;
236}
237
238static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario)
239{
240	pr_debug("Entered %s\n", __func__);
241
242	switch (neo1973_scenario) {
243	case NEO_AUDIO_OFF:
244		snd_soc_dapm_disable_pin(codec, "Audio Out");
245		snd_soc_dapm_disable_pin(codec, "GSM Line Out");
246		snd_soc_dapm_disable_pin(codec, "GSM Line In");
247		snd_soc_dapm_disable_pin(codec, "Headset Mic");
248		snd_soc_dapm_disable_pin(codec, "Call Mic");
249		break;
250	case NEO_GSM_CALL_AUDIO_HANDSET:
251		snd_soc_dapm_enable_pin(codec, "Audio Out");
252		snd_soc_dapm_enable_pin(codec, "GSM Line Out");
253		snd_soc_dapm_enable_pin(codec, "GSM Line In");
254		snd_soc_dapm_disable_pin(codec, "Headset Mic");
255		snd_soc_dapm_enable_pin(codec, "Call Mic");
256		break;
257	case NEO_GSM_CALL_AUDIO_HEADSET:
258		snd_soc_dapm_enable_pin(codec, "Audio Out");
259		snd_soc_dapm_enable_pin(codec, "GSM Line Out");
260		snd_soc_dapm_enable_pin(codec, "GSM Line In");
261		snd_soc_dapm_enable_pin(codec, "Headset Mic");
262		snd_soc_dapm_disable_pin(codec, "Call Mic");
263		break;
264	case NEO_GSM_CALL_AUDIO_BLUETOOTH:
265		snd_soc_dapm_disable_pin(codec, "Audio Out");
266		snd_soc_dapm_enable_pin(codec, "GSM Line Out");
267		snd_soc_dapm_enable_pin(codec, "GSM Line In");
268		snd_soc_dapm_disable_pin(codec, "Headset Mic");
269		snd_soc_dapm_disable_pin(codec, "Call Mic");
270		break;
271	case NEO_STEREO_TO_SPEAKERS:
272		snd_soc_dapm_enable_pin(codec, "Audio Out");
273		snd_soc_dapm_disable_pin(codec, "GSM Line Out");
274		snd_soc_dapm_disable_pin(codec, "GSM Line In");
275		snd_soc_dapm_disable_pin(codec, "Headset Mic");
276		snd_soc_dapm_disable_pin(codec, "Call Mic");
277		break;
278	case NEO_STEREO_TO_HEADPHONES:
279		snd_soc_dapm_enable_pin(codec, "Audio Out");
280		snd_soc_dapm_disable_pin(codec, "GSM Line Out");
281		snd_soc_dapm_disable_pin(codec, "GSM Line In");
282		snd_soc_dapm_disable_pin(codec, "Headset Mic");
283		snd_soc_dapm_disable_pin(codec, "Call Mic");
284		break;
285	case NEO_CAPTURE_HANDSET:
286		snd_soc_dapm_disable_pin(codec, "Audio Out");
287		snd_soc_dapm_disable_pin(codec, "GSM Line Out");
288		snd_soc_dapm_disable_pin(codec, "GSM Line In");
289		snd_soc_dapm_disable_pin(codec, "Headset Mic");
290		snd_soc_dapm_enable_pin(codec, "Call Mic");
291		break;
292	case NEO_CAPTURE_HEADSET:
293		snd_soc_dapm_disable_pin(codec, "Audio Out");
294		snd_soc_dapm_disable_pin(codec, "GSM Line Out");
295		snd_soc_dapm_disable_pin(codec, "GSM Line In");
296		snd_soc_dapm_enable_pin(codec, "Headset Mic");
297		snd_soc_dapm_disable_pin(codec, "Call Mic");
298		break;
299	case NEO_CAPTURE_BLUETOOTH:
300		snd_soc_dapm_disable_pin(codec, "Audio Out");
301		snd_soc_dapm_disable_pin(codec, "GSM Line Out");
302		snd_soc_dapm_disable_pin(codec, "GSM Line In");
303		snd_soc_dapm_disable_pin(codec, "Headset Mic");
304		snd_soc_dapm_disable_pin(codec, "Call Mic");
305		break;
306	default:
307		snd_soc_dapm_disable_pin(codec, "Audio Out");
308		snd_soc_dapm_disable_pin(codec, "GSM Line Out");
309		snd_soc_dapm_disable_pin(codec, "GSM Line In");
310		snd_soc_dapm_disable_pin(codec, "Headset Mic");
311		snd_soc_dapm_disable_pin(codec, "Call Mic");
312	}
313
314	snd_soc_dapm_sync(codec);
315
316	return 0;
317}
318
319static int neo1973_set_scenario(struct snd_kcontrol *kcontrol,
320	struct snd_ctl_elem_value *ucontrol)
321{
322	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
323
324	pr_debug("Entered %s\n", __func__);
325
326	if (neo1973_scenario == ucontrol->value.integer.value[0])
327		return 0;
328
329	neo1973_scenario = ucontrol->value.integer.value[0];
330	set_scenario_endpoints(codec, neo1973_scenario);
331	return 1;
332}
333
334static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0};
335
336static void lm4857_write_regs(void)
337{
338	pr_debug("Entered %s\n", __func__);
339
340	if (i2c_master_send(i2c, lm4857_regs, 4) != 4)
341		printk(KERN_ERR "lm4857: i2c write failed\n");
342}
343
344static int lm4857_get_reg(struct snd_kcontrol *kcontrol,
345	struct snd_ctl_elem_value *ucontrol)
346{
347	struct soc_mixer_control *mc =
348		(struct soc_mixer_control *)kcontrol->private_value;
349	int reg = mc->reg;
350	int shift = mc->shift;
351	int mask = mc->max;
352
353	pr_debug("Entered %s\n", __func__);
354
355	ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask;
356	return 0;
357}
358
359static int lm4857_set_reg(struct snd_kcontrol *kcontrol,
360	struct snd_ctl_elem_value *ucontrol)
361{
362	struct soc_mixer_control *mc =
363		(struct soc_mixer_control *)kcontrol->private_value;
364	int reg = mc->reg;
365	int shift = mc->shift;
366	int mask = mc->max;
367
368	if (((lm4857_regs[reg] >> shift) & mask) ==
369		ucontrol->value.integer.value[0])
370		return 0;
371
372	lm4857_regs[reg] &= ~(mask << shift);
373	lm4857_regs[reg] |= ucontrol->value.integer.value[0] << shift;
374	lm4857_write_regs();
375	return 1;
376}
377
378static int lm4857_get_mode(struct snd_kcontrol *kcontrol,
379	struct snd_ctl_elem_value *ucontrol)
380{
381	u8 value = lm4857_regs[LM4857_CTRL] & 0x0F;
382
383	pr_debug("Entered %s\n", __func__);
384
385	if (value)
386		value -= 5;
387
388	ucontrol->value.integer.value[0] = value;
389	return 0;
390}
391
392static int lm4857_set_mode(struct snd_kcontrol *kcontrol,
393	struct snd_ctl_elem_value *ucontrol)
394{
395	u8 value = ucontrol->value.integer.value[0];
396
397	pr_debug("Entered %s\n", __func__);
398
399	if (value)
400		value += 5;
401
402	if ((lm4857_regs[LM4857_CTRL] & 0x0F) == value)
403		return 0;
404
405	lm4857_regs[LM4857_CTRL] &= 0xF0;
406	lm4857_regs[LM4857_CTRL] |= value;
407	lm4857_write_regs();
408	return 1;
409}
410
411static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
412	SND_SOC_DAPM_LINE("Audio Out", NULL),
413	SND_SOC_DAPM_LINE("GSM Line Out", NULL),
414	SND_SOC_DAPM_LINE("GSM Line In", NULL),
415	SND_SOC_DAPM_MIC("Headset Mic", NULL),
416	SND_SOC_DAPM_MIC("Call Mic", NULL),
417};
418
419
420static const struct snd_soc_dapm_route dapm_routes[] = {
421
422	/* Connections to the lm4857 amp */
423	{"Audio Out", NULL, "LOUT1"},
424	{"Audio Out", NULL, "ROUT1"},
425
426	/* Connections to the GSM Module */
427	{"GSM Line Out", NULL, "MONO1"},
428	{"GSM Line Out", NULL, "MONO2"},
429	{"RXP", NULL, "GSM Line In"},
430	{"RXN", NULL, "GSM Line In"},
431
432	/* Connections to Headset */
433	{"MIC1", NULL, "Mic Bias"},
434	{"Mic Bias", NULL, "Headset Mic"},
435
436	/* Call Mic */
437	{"MIC2", NULL, "Mic Bias"},
438	{"MIC2N", NULL, "Mic Bias"},
439	{"Mic Bias", NULL, "Call Mic"},
440
441	/* Connect the ALC pins */
442	{"ACIN", NULL, "ACOP"},
443};
444
445static const char *lm4857_mode[] = {
446	"Off",
447	"Call Speaker",
448	"Stereo Speakers",
449	"Stereo Speakers + Headphones",
450	"Headphones"
451};
452
453static const struct soc_enum lm4857_mode_enum[] = {
454	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode),
455};
456
457static const char *neo_scenarios[] = {
458	"Off",
459	"GSM Handset",
460	"GSM Headset",
461	"GSM Bluetooth",
462	"Speakers",
463	"Headphones",
464	"Capture Handset",
465	"Capture Headset",
466	"Capture Bluetooth"
467};
468
469static const struct soc_enum neo_scenario_enum[] = {
470	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(neo_scenarios), neo_scenarios),
471};
472
473static const DECLARE_TLV_DB_SCALE(stereo_tlv, -4050, 150, 0);
474static const DECLARE_TLV_DB_SCALE(mono_tlv, -3450, 150, 0);
475
476static const struct snd_kcontrol_new wm8753_neo1973_controls[] = {
477	SOC_SINGLE_EXT_TLV("Amp Left Playback Volume", LM4857_LVOL, 0, 31, 0,
478		lm4857_get_reg, lm4857_set_reg, stereo_tlv),
479	SOC_SINGLE_EXT_TLV("Amp Right Playback Volume", LM4857_RVOL, 0, 31, 0,
480		lm4857_get_reg, lm4857_set_reg, stereo_tlv),
481	SOC_SINGLE_EXT_TLV("Amp Mono Playback Volume", LM4857_MVOL, 0, 31, 0,
482		lm4857_get_reg, lm4857_set_reg, mono_tlv),
483	SOC_ENUM_EXT("Amp Mode", lm4857_mode_enum[0],
484		lm4857_get_mode, lm4857_set_mode),
485	SOC_ENUM_EXT("Neo Mode", neo_scenario_enum[0],
486		neo1973_get_scenario, neo1973_set_scenario),
487	SOC_SINGLE_EXT("Amp Spk 3D Playback Switch", LM4857_LVOL, 5, 1, 0,
488		lm4857_get_reg, lm4857_set_reg),
489	SOC_SINGLE_EXT("Amp HP 3d Playback Switch", LM4857_RVOL, 5, 1, 0,
490		lm4857_get_reg, lm4857_set_reg),
491	SOC_SINGLE_EXT("Amp Fast Wakeup Playback Switch", LM4857_CTRL, 5, 1, 0,
492		lm4857_get_reg, lm4857_set_reg),
493	SOC_SINGLE_EXT("Amp Earpiece 6dB Playback Switch", LM4857_CTRL, 4, 1, 0,
494		lm4857_get_reg, lm4857_set_reg),
495};
496
497/*
498 * This is an example machine initialisation for a wm8753 connected to a
499 * neo1973 II. It is missing logic to detect hp/mic insertions and logic
500 * to re-route the audio in such an event.
501 */
502static int neo1973_wm8753_init(struct snd_soc_codec *codec)
503{
504	int err;
505
506	pr_debug("Entered %s\n", __func__);
507
508	/* set up NC codec pins */
509	snd_soc_dapm_nc_pin(codec, "LOUT2");
510	snd_soc_dapm_nc_pin(codec, "ROUT2");
511	snd_soc_dapm_nc_pin(codec, "OUT3");
512	snd_soc_dapm_nc_pin(codec, "OUT4");
513	snd_soc_dapm_nc_pin(codec, "LINE1");
514	snd_soc_dapm_nc_pin(codec, "LINE2");
515
516	/* Add neo1973 specific widgets */
517	snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
518				  ARRAY_SIZE(wm8753_dapm_widgets));
519
520	/* set endpoints to default mode */
521	set_scenario_endpoints(codec, NEO_AUDIO_OFF);
522
523	/* add neo1973 specific controls */
524	err = snd_soc_add_controls(codec, wm8753_neo1973_controls,
525				ARRAY_SIZE(8753_neo1973_controls));
526	if (err < 0)
527		return err;
528
529	/* set up neo1973 specific audio routes */
530	err = snd_soc_dapm_add_routes(codec, dapm_routes,
531				      ARRAY_SIZE(dapm_routes));
532
533	snd_soc_dapm_sync(codec);
534	return 0;
535}
536
537/*
538 * BT Codec DAI
539 */
540static struct snd_soc_dai bt_dai = {
541	.name = "Bluetooth",
542	.id = 0,
543	.playback = {
544		.channels_min = 1,
545		.channels_max = 1,
546		.rates = SNDRV_PCM_RATE_8000,
547		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
548	.capture = {
549		.channels_min = 1,
550		.channels_max = 1,
551		.rates = SNDRV_PCM_RATE_8000,
552		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
553};
554
555static struct snd_soc_dai_link neo1973_dai[] = {
556{ /* Hifi Playback - for similatious use with voice below */
557	.name = "WM8753",
558	.stream_name = "WM8753 HiFi",
559	.cpu_dai = &s3c24xx_i2s_dai,
560	.codec_dai = &wm8753_dai[WM8753_DAI_HIFI],
561	.init = neo1973_wm8753_init,
562	.ops = &neo1973_hifi_ops,
563},
564{ /* Voice via BT */
565	.name = "Bluetooth",
566	.stream_name = "Voice",
567	.cpu_dai = &bt_dai,
568	.codec_dai = &wm8753_dai[WM8753_DAI_VOICE],
569	.ops = &neo1973_voice_ops,
570},
571};
572
573static struct snd_soc_card neo1973 = {
574	.name = "neo1973",
575	.platform = &s3c24xx_soc_platform,
576	.dai_link = neo1973_dai,
577	.num_links = ARRAY_SIZE(neo1973_dai),
578};
579
580static struct snd_soc_device neo1973_snd_devdata = {
581	.card = &neo1973,
582	.codec_dev = &soc_codec_dev_wm8753,
583};
584
585static int lm4857_i2c_probe(struct i2c_client *client,
586			    const struct i2c_device_id *id)
587{
588	pr_debug("Entered %s\n", __func__);
589
590	i2c = client;
591
592	lm4857_write_regs();
593	return 0;
594}
595
596static int lm4857_i2c_remove(struct i2c_client *client)
597{
598	pr_debug("Entered %s\n", __func__);
599
600	i2c = NULL;
601
602	return 0;
603}
604
605static u8 lm4857_state;
606
607static int lm4857_suspend(struct i2c_client *dev, pm_message_t state)
608{
609	pr_debug("Entered %s\n", __func__);
610
611	dev_dbg(&dev->dev, "lm4857_suspend\n");
612	lm4857_state = lm4857_regs[LM4857_CTRL] & 0xf;
613	if (lm4857_state) {
614		lm4857_regs[LM4857_CTRL] &= 0xf0;
615		lm4857_write_regs();
616	}
617	return 0;
618}
619
620static int lm4857_resume(struct i2c_client *dev)
621{
622	pr_debug("Entered %s\n", __func__);
623
624	if (lm4857_state) {
625		lm4857_regs[LM4857_CTRL] |= (lm4857_state & 0x0f);
626		lm4857_write_regs();
627	}
628	return 0;
629}
630
631static void lm4857_shutdown(struct i2c_client *dev)
632{
633	pr_debug("Entered %s\n", __func__);
634
635	dev_dbg(&dev->dev, "lm4857_shutdown\n");
636	lm4857_regs[LM4857_CTRL] &= 0xf0;
637	lm4857_write_regs();
638}
639
640static const struct i2c_device_id lm4857_i2c_id[] = {
641	{ "neo1973_lm4857", 0 },
642	{ }
643};
644
645static struct i2c_driver lm4857_i2c_driver = {
646	.driver = {
647		.name = "LM4857 I2C Amp",
648		.owner = THIS_MODULE,
649	},
650	.suspend =        lm4857_suspend,
651	.resume	=         lm4857_resume,
652	.shutdown =       lm4857_shutdown,
653	.probe =          lm4857_i2c_probe,
654	.remove =         lm4857_i2c_remove,
655	.id_table =       lm4857_i2c_id,
656};
657
658static struct platform_device *neo1973_snd_device;
659
660static int __init neo1973_init(void)
661{
662	int ret;
663
664	pr_debug("Entered %s\n", __func__);
665
666	if (!machine_is_neo1973_gta01()) {
667		printk(KERN_INFO
668			"Only GTA01 hardware supported by ASoC driver\n");
669		return -ENODEV;
670	}
671
672	neo1973_snd_device = platform_device_alloc("soc-audio", -1);
673	if (!neo1973_snd_device)
674		return -ENOMEM;
675
676	platform_set_drvdata(neo1973_snd_device, &neo1973_snd_devdata);
677	neo1973_snd_devdata.dev = &neo1973_snd_device->dev;
678	ret = platform_device_add(neo1973_snd_device);
679
680	if (ret) {
681		platform_device_put(neo1973_snd_device);
682		return ret;
683	}
684
685	ret = i2c_add_driver(&lm4857_i2c_driver);
686
687	if (ret != 0)
688		platform_device_unregister(neo1973_snd_device);
689
690	return ret;
691}
692
693static void __exit neo1973_exit(void)
694{
695	pr_debug("Entered %s\n", __func__);
696
697	i2c_del_driver(&lm4857_i2c_driver);
698	platform_device_unregister(neo1973_snd_device);
699}
700
701module_init(neo1973_init);
702module_exit(neo1973_exit);
703
704/* Module information */
705MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org");
706MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973");
707MODULE_LICENSE("GPL");
708