]> rtime.felk.cvut.cz Git - mcf548x/linux.git/blob - sound/soc/codecs/ad1836.c
ASoC: multi-component - ASoC Multi-Component Support
[mcf548x/linux.git] / sound / soc / codecs / ad1836.c
1 /*
2  * File:         sound/soc/codecs/ad1836.c
3  * Author:       Barry Song <Barry.Song@analog.com>
4  *
5  * Created:      Aug 04 2009
6  * Description:  Driver for AD1836 sound chip
7  *
8  * Modified:
9  *               Copyright 2009 Analog Devices Inc.
10  *
11  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  */
18
19 #include <linux/init.h>
20 #include <linux/slab.h>
21 #include <linux/module.h>
22 #include <linux/kernel.h>
23 #include <linux/device.h>
24 #include <sound/core.h>
25 #include <sound/pcm.h>
26 #include <sound/pcm_params.h>
27 #include <sound/initval.h>
28 #include <sound/soc.h>
29 #include <sound/tlv.h>
30 #include <sound/soc-dapm.h>
31 #include <linux/spi/spi.h>
32 #include "ad1836.h"
33
34 /* codec private data */
35 struct ad1836_priv {
36         enum snd_soc_control_type control_type;
37         void *control_data;
38 };
39
40 /*
41  * AD1836 volume/mute/de-emphasis etc. controls
42  */
43 static const char *ad1836_deemp[] = {"None", "44.1kHz", "32kHz", "48kHz"};
44
45 static const struct soc_enum ad1836_deemp_enum =
46         SOC_ENUM_SINGLE(AD1836_DAC_CTRL1, 8, 4, ad1836_deemp);
47
48 static const struct snd_kcontrol_new ad1836_snd_controls[] = {
49         /* DAC volume control */
50         SOC_DOUBLE_R("DAC1 Volume", AD1836_DAC_L1_VOL,
51                         AD1836_DAC_R1_VOL, 0, 0x3FF, 0),
52         SOC_DOUBLE_R("DAC2 Volume", AD1836_DAC_L2_VOL,
53                         AD1836_DAC_R2_VOL, 0, 0x3FF, 0),
54         SOC_DOUBLE_R("DAC3 Volume", AD1836_DAC_L3_VOL,
55                         AD1836_DAC_R3_VOL, 0, 0x3FF, 0),
56
57         /* ADC switch control */
58         SOC_DOUBLE("ADC1 Switch", AD1836_ADC_CTRL2, AD1836_ADCL1_MUTE,
59                 AD1836_ADCR1_MUTE, 1, 1),
60         SOC_DOUBLE("ADC2 Switch", AD1836_ADC_CTRL2, AD1836_ADCL2_MUTE,
61                 AD1836_ADCR2_MUTE, 1, 1),
62
63         /* DAC switch control */
64         SOC_DOUBLE("DAC1 Switch", AD1836_DAC_CTRL2, AD1836_DACL1_MUTE,
65                 AD1836_DACR1_MUTE, 1, 1),
66         SOC_DOUBLE("DAC2 Switch", AD1836_DAC_CTRL2, AD1836_DACL2_MUTE,
67                 AD1836_DACR2_MUTE, 1, 1),
68         SOC_DOUBLE("DAC3 Switch", AD1836_DAC_CTRL2, AD1836_DACL3_MUTE,
69                 AD1836_DACR3_MUTE, 1, 1),
70
71         /* ADC high-pass filter */
72         SOC_SINGLE("ADC High Pass Filter Switch", AD1836_ADC_CTRL1,
73                         AD1836_ADC_HIGHPASS_FILTER, 1, 0),
74
75         /* DAC de-emphasis */
76         SOC_ENUM("Playback Deemphasis", ad1836_deemp_enum),
77 };
78
79 static const struct snd_soc_dapm_widget ad1836_dapm_widgets[] = {
80         SND_SOC_DAPM_DAC("DAC", "Playback", AD1836_DAC_CTRL1,
81                                 AD1836_DAC_POWERDOWN, 1),
82         SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
83         SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1836_ADC_CTRL1,
84                                 AD1836_ADC_POWERDOWN, 1, NULL, 0),
85         SND_SOC_DAPM_OUTPUT("DAC1OUT"),
86         SND_SOC_DAPM_OUTPUT("DAC2OUT"),
87         SND_SOC_DAPM_OUTPUT("DAC3OUT"),
88         SND_SOC_DAPM_INPUT("ADC1IN"),
89         SND_SOC_DAPM_INPUT("ADC2IN"),
90 };
91
92 static const struct snd_soc_dapm_route audio_paths[] = {
93         { "DAC", NULL, "ADC_PWR" },
94         { "ADC", NULL, "ADC_PWR" },
95         { "DAC1OUT", "DAC1 Switch", "DAC" },
96         { "DAC2OUT", "DAC2 Switch", "DAC" },
97         { "DAC3OUT", "DAC3 Switch", "DAC" },
98         { "ADC", "ADC1 Switch", "ADC1IN" },
99         { "ADC", "ADC2 Switch", "ADC2IN" },
100 };
101
102 /*
103  * DAI ops entries
104  */
105
106 static int ad1836_set_dai_fmt(struct snd_soc_dai *codec_dai,
107                 unsigned int fmt)
108 {
109         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
110         /* at present, we support adc aux mode to interface with
111          * blackfin sport tdm mode
112          */
113         case SND_SOC_DAIFMT_DSP_A:
114                 break;
115         default:
116                 return -EINVAL;
117         }
118
119         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
120         case SND_SOC_DAIFMT_IB_IF:
121                 break;
122         default:
123                 return -EINVAL;
124         }
125
126         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
127         /* ALCLK,ABCLK are both output, AD1836 can only be master */
128         case SND_SOC_DAIFMT_CBM_CFM:
129                 break;
130         default:
131                 return -EINVAL;
132         }
133
134         return 0;
135 }
136
137 static int ad1836_hw_params(struct snd_pcm_substream *substream,
138                 struct snd_pcm_hw_params *params,
139                 struct snd_soc_dai *dai)
140 {
141         int word_len = 0;
142
143         struct snd_soc_pcm_runtime *rtd = substream->private_data;
144         struct snd_soc_codec *codec = rtd->codec;
145
146         /* bit size */
147         switch (params_format(params)) {
148         case SNDRV_PCM_FORMAT_S16_LE:
149                 word_len = 3;
150                 break;
151         case SNDRV_PCM_FORMAT_S20_3LE:
152                 word_len = 1;
153                 break;
154         case SNDRV_PCM_FORMAT_S24_LE:
155         case SNDRV_PCM_FORMAT_S32_LE:
156                 word_len = 0;
157                 break;
158         }
159
160         snd_soc_update_bits(codec, AD1836_DAC_CTRL1,
161                 AD1836_DAC_WORD_LEN_MASK, word_len);
162
163         snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
164                 AD1836_ADC_WORD_LEN_MASK, word_len);
165
166         return 0;
167 }
168
169 #ifdef CONFIG_PM
170 static int ad1836_soc_suspend(struct snd_soc_codec *codec,
171                 pm_message_t state)
172 {
173         /* reset clock control mode */
174         u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
175         adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
176
177         return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
178 }
179
180 static int ad1836_soc_resume(struct snd_soc_codec *codec)
181 {
182         /* restore clock control mode */
183         u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
184         adc_ctrl2 |= AD1836_ADC_AUX;
185
186         return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
187 }
188 #else
189 #define ad1836_soc_suspend NULL
190 #define ad1836_soc_resume  NULL
191 #endif
192
193 static struct snd_soc_dai_ops ad1836_dai_ops = {
194         .hw_params = ad1836_hw_params,
195         .set_fmt = ad1836_set_dai_fmt,
196 };
197
198 /* codec DAI instance */
199 static struct snd_soc_dai_driver ad1836_dai = {
200         .name = "ad1836-hifi",
201         .playback = {
202                 .stream_name = "Playback",
203                 .channels_min = 2,
204                 .channels_max = 6,
205                 .rates = SNDRV_PCM_RATE_48000,
206                 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
207                         SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
208         },
209         .capture = {
210                 .stream_name = "Capture",
211                 .channels_min = 2,
212                 .channels_max = 4,
213                 .rates = SNDRV_PCM_RATE_48000,
214                 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
215                         SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
216         },
217         .ops = &ad1836_dai_ops,
218 };
219
220 static int ad1836_probe(struct snd_soc_codec *codec)
221 {
222         struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
223         int ret = 0;
224
225         codec->control_data = ad1836->control_data;
226         ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
227         if (ret < 0) {
228                 dev_err(codec->dev, "failed to set cache I/O: %d\n",
229                                 ret);
230                 kfree(ad1836);
231                 return ret;
232         }
233
234         /* default setting for ad1836 */
235         /* de-emphasis: 48kHz, power-on dac */
236         snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300);
237         /* unmute dac channels */
238         snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0);
239         /* high-pass filter enable, power-on adc */
240         snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100);
241         /* unmute adc channles, adc aux mode */
242         snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180);
243         /* left/right diff:PGA/MUX */
244         snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
245         /* volume */
246         snd_soc_write(codec, AD1836_DAC_L1_VOL, 0x3FF);
247         snd_soc_write(codec, AD1836_DAC_R1_VOL, 0x3FF);
248         snd_soc_write(codec, AD1836_DAC_L2_VOL, 0x3FF);
249         snd_soc_write(codec, AD1836_DAC_R2_VOL, 0x3FF);
250         snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF);
251         snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF);
252
253         snd_soc_add_controls(codec, ad1836_snd_controls,
254                              ARRAY_SIZE(ad1836_snd_controls));
255         snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
256                                   ARRAY_SIZE(ad1836_dapm_widgets));
257         snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
258
259         return ret;
260 }
261
262 /* power down chip */
263 static int ad1836_remove(struct snd_soc_codec *codec)
264 {
265         /* reset clock control mode */
266         u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
267         adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
268
269         return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
270 }
271
272 static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
273         .probe =        ad1836_probe,
274         .remove =       ad1836_remove,
275         .suspend =      ad1836_soc_suspend,
276         .resume =       ad1836_soc_resume,
277         .reg_cache_size = AD1836_NUM_REGS,
278         .reg_word_size = sizeof(u16),
279 };
280
281 static int __devinit ad1836_spi_probe(struct spi_device *spi)
282 {
283         struct ad1836_priv *ad1836;
284         int ret;
285
286         ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL);
287         if (ad1836 == NULL)
288                 return -ENOMEM;
289
290         spi_set_drvdata(spi, ad1836);
291         ad1836->control_data = spi;
292         ad1836->control_type = SND_SOC_SPI;
293
294         ret = snd_soc_register_codec(&spi->dev,
295                         &soc_codec_dev_ad1836, &ad1836_dai, 1);
296         if (ret < 0)
297                 kfree(ad1836);
298         return ret;
299 }
300
301 static int __devexit ad1836_spi_remove(struct spi_device *spi)
302 {
303         snd_soc_unregister_codec(&spi->dev);
304         kfree(spi_get_drvdata(spi));
305         return 0;
306 }
307
308 static struct spi_driver ad1836_spi_driver = {
309         .driver = {
310                 .name   = "ad1836-codec",
311                 .owner  = THIS_MODULE,
312         },
313         .probe          = ad1836_spi_probe,
314         .remove         = __devexit_p(ad1836_spi_remove),
315 };
316
317 static int __init ad1836_init(void)
318 {
319         int ret;
320
321         ret = spi_register_driver(&ad1836_spi_driver);
322         if (ret != 0) {
323                 printk(KERN_ERR "Failed to register ad1836 SPI driver: %d\n",
324                                 ret);
325         }
326
327         return ret;
328 }
329 module_init(ad1836_init);
330
331 static void __exit ad1836_exit(void)
332 {
333         spi_unregister_driver(&ad1836_spi_driver);
334 }
335 module_exit(ad1836_exit);
336
337 MODULE_DESCRIPTION("ASoC ad1836 driver");
338 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
339 MODULE_LICENSE("GPL");