aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2008-07-29 06:42:31 -0400
committerJaroslav Kysela <perex@perex.cz>2008-07-29 15:32:24 -0400
commitd8e3bb7385da0bcdda4ffa600489fa1439b14673 (patch)
tree98f74a59af2890b4aa60f3a2096a32e087d28a94
parentdc641378b5ee220aa29ed8b8f51b7af9a19a7719 (diff)
ALSA: ASoC: Add Texas Instruments TLV320AIC26 codec driver
ASoC Codec driver for the TLV320AIC26 device. As it stands, this driver doesn't support all the modes and clocking options of the AIC16, but it is a start. Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/tlv320aic26.c519
-rw-r--r--sound/soc/codecs/tlv320aic26.h93
4 files changed, 618 insertions, 0 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1db04a28a53d..9e09fa5f2d45 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -47,6 +47,10 @@ config SND_SOC_CS4270_VD33_ERRATA
47 bool 47 bool
48 depends on SND_SOC_CS4270 48 depends on SND_SOC_CS4270
49 49
50config SND_SOC_TLV320AIC26
51 tristate "TI TLV320AIC26 Codec support"
52 depends on SND_SOC && SPI
53
50config SND_SOC_TLV320AIC3X 54config SND_SOC_TLV320AIC3X
51 tristate 55 tristate
52 depends on I2C 56 depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index d7b97abcf729..dc0357e20fea 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -9,6 +9,7 @@ snd-soc-wm8990-objs := wm8990.o
9snd-soc-wm9712-objs := wm9712.o 9snd-soc-wm9712-objs := wm9712.o
10snd-soc-wm9713-objs := wm9713.o 10snd-soc-wm9713-objs := wm9713.o
11snd-soc-cs4270-objs := cs4270.o 11snd-soc-cs4270-objs := cs4270.o
12snd-soc-tlv320aic26-objs := tlv320aic26.o
12snd-soc-tlv320aic3x-objs := tlv320aic3x.o 13snd-soc-tlv320aic3x-objs := tlv320aic3x.o
13 14
14obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 15obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
@@ -22,4 +23,5 @@ obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
22obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 23obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
23obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o 24obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
24obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 25obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
26obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
25obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 27obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
new file mode 100644
index 000000000000..4621fda5705e
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -0,0 +1,519 @@
1/*
2 * Texas Instruments TLV320AIC26 low power audio CODEC
3 * ALSA SoC CODEC driver
4 *
5 * Copyright (C) 2008 Secret Lab Technologies Ltd.
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/init.h>
11#include <linux/delay.h>
12#include <linux/pm.h>
13#include <linux/device.h>
14#include <linux/sysfs.h>
15#include <linux/spi/spi.h>
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/pcm_params.h>
19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21#include <sound/soc-of-simple.h>
22#include <sound/initval.h>
23
24#include "tlv320aic26.h"
25
26MODULE_DESCRIPTION("ASoC TLV320AIC26 codec driver");
27MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
28MODULE_LICENSE("GPL");
29
30/* AIC26 driver private data */
31struct aic26 {
32 struct spi_device *spi;
33 struct snd_soc_codec codec;
34 u16 reg_cache[AIC26_NUM_REGS]; /* shadow registers */
35 int master;
36 int datfm;
37 int mclk;
38
39 /* Keyclick parameters */
40 int keyclick_amplitude;
41 int keyclick_freq;
42 int keyclick_len;
43};
44
45/* ---------------------------------------------------------------------
46 * Register access routines
47 */
48static unsigned int aic26_reg_read(struct snd_soc_codec *codec,
49 unsigned int reg)
50{
51 struct aic26 *aic26 = codec->private_data;
52 u16 *cache = codec->reg_cache;
53 u16 cmd, value;
54 u8 buffer[2];
55 int rc;
56
57 if (reg >= AIC26_NUM_REGS) {
58 WARN_ON_ONCE(1);
59 return 0;
60 }
61
62 /* Do SPI transfer; first 16bits are command; remaining is
63 * register contents */
64 cmd = AIC26_READ_COMMAND_WORD(reg);
65 buffer[0] = (cmd >> 8) & 0xff;
66 buffer[1] = cmd & 0xff;
67 rc = spi_write_then_read(aic26->spi, buffer, 2, buffer, 2);
68 if (rc) {
69 dev_err(&aic26->spi->dev, "AIC26 reg read error\n");
70 return -EIO;
71 }
72 value = (buffer[0] << 8) | buffer[1];
73
74 /* Update the cache before returning with the value */
75 cache[reg] = value;
76 return value;
77}
78
79static unsigned int aic26_reg_read_cache(struct snd_soc_codec *codec,
80 unsigned int reg)
81{
82 u16 *cache = codec->reg_cache;
83
84 if (reg >= AIC26_NUM_REGS) {
85 WARN_ON_ONCE(1);
86 return 0;
87 }
88
89 return cache[reg];
90}
91
92static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg,
93 unsigned int value)
94{
95 struct aic26 *aic26 = codec->private_data;
96 u16 *cache = codec->reg_cache;
97 u16 cmd;
98 u8 buffer[4];
99 int rc;
100
101 if (reg >= AIC26_NUM_REGS) {
102 WARN_ON_ONCE(1);
103 return -EINVAL;
104 }
105
106 /* Do SPI transfer; first 16bits are command; remaining is data
107 * to write into register */
108 cmd = AIC26_WRITE_COMMAND_WORD(reg);
109 buffer[0] = (cmd >> 8) & 0xff;
110 buffer[1] = cmd & 0xff;
111 buffer[2] = value >> 8;
112 buffer[3] = value;
113 rc = spi_write(aic26->spi, buffer, 4);
114 if (rc) {
115 dev_err(&aic26->spi->dev, "AIC26 reg read error\n");
116 return -EIO;
117 }
118
119 /* update cache before returning */
120 cache[reg] = value;
121 return 0;
122}
123
124/* ---------------------------------------------------------------------
125 * Digital Audio Interface Operations
126 */
127static int aic26_hw_params(struct snd_pcm_substream *substream,
128 struct snd_pcm_hw_params *params)
129{
130 struct snd_soc_pcm_runtime *rtd = substream->private_data;
131 struct snd_soc_device *socdev = rtd->socdev;
132 struct snd_soc_codec *codec = socdev->codec;
133 struct aic26 *aic26 = codec->private_data;
134 int fsref, divisor, wlen, pval, jval, dval, qval;
135 u16 reg;
136
137 dev_dbg(&aic26->spi->dev, "aic26_hw_params(substream=%p, params=%p)\n",
138 substream, params);
139 dev_dbg(&aic26->spi->dev, "rate=%i format=%i\n", params_rate(params),
140 params_format(params));
141
142 switch (params_rate(params)) {
143 case 8000: fsref = 48000; divisor = AIC26_DIV_6; break;
144 case 11025: fsref = 44100; divisor = AIC26_DIV_4; break;
145 case 12000: fsref = 48000; divisor = AIC26_DIV_4; break;
146 case 16000: fsref = 48000; divisor = AIC26_DIV_3; break;
147 case 22050: fsref = 44100; divisor = AIC26_DIV_2; break;
148 case 24000: fsref = 48000; divisor = AIC26_DIV_2; break;
149 case 32000: fsref = 48000; divisor = AIC26_DIV_1_5; break;
150 case 44100: fsref = 44100; divisor = AIC26_DIV_1; break;
151 case 48000: fsref = 48000; divisor = AIC26_DIV_1; break;
152 default:
153 dev_dbg(&aic26->spi->dev, "bad rate\n"); return -EINVAL;
154 }
155
156 /* select data word length */
157 switch (params_format(params)) {
158 case SNDRV_PCM_FORMAT_S8: wlen = AIC26_WLEN_16; break;
159 case SNDRV_PCM_FORMAT_S16_BE: wlen = AIC26_WLEN_16; break;
160 case SNDRV_PCM_FORMAT_S24_BE: wlen = AIC26_WLEN_24; break;
161 case SNDRV_PCM_FORMAT_S32_BE: wlen = AIC26_WLEN_32; break;
162 default:
163 dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
164 }
165
166 /* Configure PLL */
167 pval = 1;
168 jval = (fsref == 44100) ? 7 : 8;
169 dval = (fsref == 44100) ? 5264 : 1920;
170 qval = 0;
171 reg = 0x8000 | qval << 11 | pval << 8 | jval << 2;
172 aic26_reg_write(codec, AIC26_REG_PLL_PROG1, reg);
173 reg = dval << 2;
174 aic26_reg_write(codec, AIC26_REG_PLL_PROG2, reg);
175
176 /* Audio Control 3 (master mode, fsref rate) */
177 reg = aic26_reg_read_cache(codec, AIC26_REG_AUDIO_CTRL3);
178 reg &= ~0xf800;
179 if (aic26->master)
180 reg |= 0x0800;
181 if (fsref == 48000)
182 reg |= 0x2000;
183 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
184
185 /* Audio Control 1 (FSref divisor) */
186 reg = aic26_reg_read_cache(codec, AIC26_REG_AUDIO_CTRL1);
187 reg &= ~0x0fff;
188 reg |= wlen | aic26->datfm | (divisor << 3) | divisor;
189 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL1, reg);
190
191 return 0;
192}
193
194/**
195 * aic26_mute - Mute control to reduce noise when changing audio format
196 */
197static int aic26_mute(struct snd_soc_dai *dai, int mute)
198{
199 struct snd_soc_codec *codec = dai->codec;
200 struct aic26 *aic26 = codec->private_data;
201 u16 reg = aic26_reg_read_cache(codec, AIC26_REG_DAC_GAIN);
202
203 dev_dbg(&aic26->spi->dev, "aic26_mute(dai=%p, mute=%i)\n",
204 dai, mute);
205
206 if (mute)
207 reg |= 0x8080;
208 else
209 reg &= ~0x8080;
210 aic26_reg_write(codec, AIC26_REG_DAC_GAIN, reg);
211
212 return 0;
213}
214
215static int aic26_set_sysclk(struct snd_soc_dai *codec_dai,
216 int clk_id, unsigned int freq, int dir)
217{
218 struct snd_soc_codec *codec = codec_dai->codec;
219 struct aic26 *aic26 = codec->private_data;
220
221 dev_dbg(&aic26->spi->dev, "aic26_set_sysclk(dai=%p, clk_id==%i,"
222 " freq=%i, dir=%i)\n",
223 codec_dai, clk_id, freq, dir);
224
225 /* MCLK needs to fall between 2MHz and 50 MHz */
226 if ((freq < 2000000) || (freq > 50000000))
227 return -EINVAL;
228
229 aic26->mclk = freq;
230 return 0;
231}
232
233static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
234{
235 struct snd_soc_codec *codec = codec_dai->codec;
236 struct aic26 *aic26 = codec->private_data;
237
238 dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n",
239 codec_dai, fmt);
240
241 /* set master/slave audio interface */
242 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
243 case SND_SOC_DAIFMT_CBM_CFM: aic26->master = 1; break;
244 case SND_SOC_DAIFMT_CBS_CFS: aic26->master = 0; break;
245 default:
246 dev_dbg(&aic26->spi->dev, "bad master\n"); return -EINVAL;
247 }
248
249 /* interface format */
250 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
251 case SND_SOC_DAIFMT_I2S: aic26->datfm = AIC26_DATFM_I2S; break;
252 case SND_SOC_DAIFMT_DSP_A: aic26->datfm = AIC26_DATFM_DSP; break;
253 case SND_SOC_DAIFMT_RIGHT_J: aic26->datfm = AIC26_DATFM_RIGHTJ; break;
254 case SND_SOC_DAIFMT_LEFT_J: aic26->datfm = AIC26_DATFM_LEFTJ; break;
255 default:
256 dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
257 }
258
259 return 0;
260}
261
262/* ---------------------------------------------------------------------
263 * Digital Audio Interface Definition
264 */
265#define AIC26_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
266 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
267 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
268 SNDRV_PCM_RATE_48000)
269#define AIC26_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |\
270 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE)
271
272struct snd_soc_dai aic26_dai = {
273 .name = "tlv320aic26",
274 .playback = {
275 .stream_name = "Playback",
276 .channels_min = 2,
277 .channels_max = 2,
278 .rates = AIC26_RATES,
279 .formats = AIC26_FORMATS,
280 },
281 .capture = {
282 .stream_name = "Capture",
283 .channels_min = 2,
284 .channels_max = 2,
285 .rates = AIC26_RATES,
286 .formats = AIC26_FORMATS,
287 },
288 .ops = {
289 .hw_params = aic26_hw_params,
290 },
291 .dai_ops = {
292 .digital_mute = aic26_mute,
293 .set_sysclk = aic26_set_sysclk,
294 .set_fmt = aic26_set_fmt,
295 },
296};
297EXPORT_SYMBOL_GPL(aic26_dai);
298
299/* ---------------------------------------------------------------------
300 * ALSA controls
301 */
302static const char *aic26_capture_src_text[] = {"Mic", "Aux"};
303static const struct soc_enum aic26_capture_src_enum =
304 SOC_ENUM_SINGLE(AIC26_REG_AUDIO_CTRL1, 12, 2, aic26_capture_src_text);
305
306static const struct snd_kcontrol_new aic26_snd_controls[] = {
307 /* Output */
308 SOC_DOUBLE("PCM Playback Volume", AIC26_REG_DAC_GAIN, 8, 0, 0x7f, 1),
309 SOC_DOUBLE("PCM Playback Switch", AIC26_REG_DAC_GAIN, 15, 7, 1, 1),
310 SOC_SINGLE("PCM Capture Volume", AIC26_REG_ADC_GAIN, 8, 0x7f, 0),
311 SOC_SINGLE("PCM Capture Mute", AIC26_REG_ADC_GAIN, 15, 1, 1),
312 SOC_SINGLE("Keyclick activate", AIC26_REG_AUDIO_CTRL2, 15, 0x1, 0),
313 SOC_SINGLE("Keyclick amplitude", AIC26_REG_AUDIO_CTRL2, 12, 0x7, 0),
314 SOC_SINGLE("Keyclick frequency", AIC26_REG_AUDIO_CTRL2, 8, 0x7, 0),
315 SOC_SINGLE("Keyclick period", AIC26_REG_AUDIO_CTRL2, 4, 0xf, 0),
316 SOC_ENUM("Capture Source", aic26_capture_src_enum),
317};
318
319/* ---------------------------------------------------------------------
320 * SoC CODEC portion of driver: probe and release routines
321 */
322static int aic26_probe(struct platform_device *pdev)
323{
324 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
325 struct snd_soc_codec *codec;
326 struct snd_kcontrol *kcontrol;
327 struct aic26 *aic26;
328 int i, ret, err;
329
330 dev_info(&pdev->dev, "Probing AIC26 SoC CODEC driver\n");
331 dev_dbg(&pdev->dev, "socdev=%p\n", socdev);
332 dev_dbg(&pdev->dev, "codec_data=%p\n", socdev->codec_data);
333
334 /* Fetch the relevant aic26 private data here (it's already been
335 * stored in the .codec pointer) */
336 aic26 = socdev->codec_data;
337 if (aic26 == NULL) {
338 dev_err(&pdev->dev, "aic26: missing codec pointer\n");
339 return -ENODEV;
340 }
341 codec = &aic26->codec;
342 socdev->codec = codec;
343
344 dev_dbg(&pdev->dev, "Registering PCMs, dev=%p, socdev->dev=%p\n",
345 &pdev->dev, socdev->dev);
346 /* register pcms */
347 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
348 if (ret < 0) {
349 dev_err(&pdev->dev, "aic26: failed to create pcms\n");
350 return -ENODEV;
351 }
352
353 /* register controls */
354 dev_dbg(&pdev->dev, "Registering controls\n");
355 for (i = 0; i < ARRAY_SIZE(aic26_snd_controls); i++) {
356 kcontrol = snd_soc_cnew(&aic26_snd_controls[i], codec, NULL);
357 err = snd_ctl_add(codec->card, kcontrol);
358 WARN_ON(err < 0);
359 }
360
361 /* CODEC is setup, we can register the card now */
362 dev_dbg(&pdev->dev, "Registering card\n");
363 ret = snd_soc_register_card(socdev);
364 if (ret < 0) {
365 dev_err(&pdev->dev, "aic26: failed to register card\n");
366 goto card_err;
367 }
368 return 0;
369
370 card_err:
371 snd_soc_free_pcms(socdev);
372 return ret;
373}
374
375static int aic26_remove(struct platform_device *pdev)
376{
377 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
378 snd_soc_free_pcms(socdev);
379 return 0;
380}
381
382struct snd_soc_codec_device aic26_soc_codec_dev = {
383 .probe = aic26_probe,
384 .remove = aic26_remove,
385};
386
387/* ---------------------------------------------------------------------
388 * SPI device portion of driver: sysfs files for debugging
389 */
390
391static ssize_t aic26_keyclick_show(struct device *dev,
392 struct device_attribute *attr, char *buf)
393{
394 struct aic26 *aic26 = dev_get_drvdata(dev);
395 int val, amp, freq, len;
396
397 val = aic26_reg_read_cache(&aic26->codec, AIC26_REG_AUDIO_CTRL2);
398 amp = (val >> 12) & 0x7;
399 freq = (125 << ((val >> 8) & 0x7)) >> 1;
400 len = 2 * (1 + ((val >> 4) & 0xf));
401
402 return sprintf(buf, "amp=%x freq=%iHz len=%iclks\n", amp, freq, len);
403}
404
405/* Any write to the keyclick attribute will trigger the keyclick event */
406static ssize_t aic26_keyclick_set(struct device *dev,
407 struct device_attribute *attr,
408 const char *buf, size_t count)
409{
410 struct aic26 *aic26 = dev_get_drvdata(dev);
411 int val;
412
413 val = aic26_reg_read_cache(&aic26->codec, AIC26_REG_AUDIO_CTRL2);
414 val |= 0x8000;
415 aic26_reg_write(&aic26->codec, AIC26_REG_AUDIO_CTRL2, val);
416
417 return count;
418}
419
420DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
421
422/* ---------------------------------------------------------------------
423 * SPI device portion of driver: probe and release routines and SPI
424 * driver registration.
425 */
426static int aic26_spi_probe(struct spi_device *spi)
427{
428 struct aic26 *aic26;
429 int rc, i, reg;
430
431 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
432
433 /* Allocate driver data */
434 aic26 = kzalloc(sizeof *aic26, GFP_KERNEL);
435 if (!aic26)
436 return -ENOMEM;
437
438 /* Initialize the driver data */
439 aic26->spi = spi;
440 dev_set_drvdata(&spi->dev, aic26);
441
442 /* Setup what we can in the codec structure so that the register
443 * access functions will work as expected. More will be filled
444 * out when it is probed by the SoC CODEC part of this driver */
445 aic26->codec.private_data = aic26;
446 aic26->codec.name = "aic26";
447 aic26->codec.owner = THIS_MODULE;
448 aic26->codec.dai = &aic26_dai;
449 aic26->codec.num_dai = 1;
450 aic26->codec.read = aic26_reg_read;
451 aic26->codec.write = aic26_reg_write;
452 aic26->master = 1;
453 mutex_init(&aic26->codec.mutex);
454 INIT_LIST_HEAD(&aic26->codec.dapm_widgets);
455 INIT_LIST_HEAD(&aic26->codec.dapm_paths);
456 aic26->codec.reg_cache_size = AIC26_NUM_REGS;
457 aic26->codec.reg_cache = aic26->reg_cache;
458
459 /* Reset the codec to power on defaults */
460 aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00);
461
462 /* Power up CODEC */
463 aic26_reg_write(&aic26->codec, AIC26_REG_POWER_CTRL, 0);
464
465 /* Audio Control 3 (master mode, fsref rate) */
466 reg = aic26_reg_read(&aic26->codec, AIC26_REG_AUDIO_CTRL3);
467 reg &= ~0xf800;
468 reg |= 0x0800; /* set master mode */
469 aic26_reg_write(&aic26->codec, AIC26_REG_AUDIO_CTRL3, reg);
470
471 /* Fill register cache */
472 for (i = 0; i < ARRAY_SIZE(aic26->reg_cache); i++)
473 aic26_reg_read(&aic26->codec, i);
474
475 /* Register the sysfs files for debugging */
476 /* Create SysFS files */
477 rc = device_create_file(&spi->dev, &dev_attr_keyclick);
478 if (rc)
479 dev_info(&spi->dev, "error creating sysfs files\n");
480
481#if defined(CONFIG_SND_SOC_OF_SIMPLE)
482 /* Tell the of_soc helper about this codec */
483 of_snd_soc_register_codec(&aic26_soc_codec_dev, aic26, &aic26_dai,
484 spi->dev.archdata.of_node);
485#endif
486
487 dev_dbg(&spi->dev, "SPI device initialized\n");
488 return 0;
489}
490
491static int aic26_spi_remove(struct spi_device *spi)
492{
493 struct aic26 *aic26 = dev_get_drvdata(&spi->dev);
494
495 kfree(aic26);
496
497 return 0;
498}
499
500static struct spi_driver aic26_spi = {
501 .driver = {
502 .name = "tlv320aic26",
503 .owner = THIS_MODULE,
504 },
505 .probe = aic26_spi_probe,
506 .remove = aic26_spi_remove,
507};
508
509static int __init aic26_init(void)
510{
511 return spi_register_driver(&aic26_spi);
512}
513module_init(aic26_init);
514
515static void __exit aic26_exit(void)
516{
517 spi_unregister_driver(&aic26_spi);
518}
519module_exit(aic26_exit);
diff --git a/sound/soc/codecs/tlv320aic26.h b/sound/soc/codecs/tlv320aic26.h
new file mode 100644
index 000000000000..62b1f2261429
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic26.h
@@ -0,0 +1,93 @@
1/*
2 * Texas Instruments TLV320AIC26 low power audio CODEC
3 * register definitions
4 *
5 * Copyright (C) 2008 Secret Lab Technologies Ltd.
6 */
7
8#ifndef _TLV320AIC16_H_
9#define _TLV320AIC16_H_
10
11/* AIC26 Registers */
12#define AIC26_READ_COMMAND_WORD(addr) ((1 << 15) | (addr << 5))
13#define AIC26_WRITE_COMMAND_WORD(addr) ((0 << 15) | (addr << 5))
14#define AIC26_PAGE_ADDR(page, offset) ((page << 6) | offset)
15#define AIC26_NUM_REGS AIC26_PAGE_ADDR(3, 0)
16
17/* Page 0: Auxillary data registers */
18#define AIC26_REG_BAT1 AIC26_PAGE_ADDR(0, 0x05)
19#define AIC26_REG_BAT2 AIC26_PAGE_ADDR(0, 0x06)
20#define AIC26_REG_AUX AIC26_PAGE_ADDR(0, 0x07)
21#define AIC26_REG_TEMP1 AIC26_PAGE_ADDR(0, 0x09)
22#define AIC26_REG_TEMP2 AIC26_PAGE_ADDR(0, 0x0A)
23
24/* Page 1: Auxillary control registers */
25#define AIC26_REG_AUX_ADC AIC26_PAGE_ADDR(1, 0x00)
26#define AIC26_REG_STATUS AIC26_PAGE_ADDR(1, 0x01)
27#define AIC26_REG_REFERENCE AIC26_PAGE_ADDR(1, 0x03)
28#define AIC26_REG_RESET AIC26_PAGE_ADDR(1, 0x04)
29
30/* Page 2: Audio control registers */
31#define AIC26_REG_AUDIO_CTRL1 AIC26_PAGE_ADDR(2, 0x00)
32#define AIC26_REG_ADC_GAIN AIC26_PAGE_ADDR(2, 0x01)
33#define AIC26_REG_DAC_GAIN AIC26_PAGE_ADDR(2, 0x02)
34#define AIC26_REG_SIDETONE AIC26_PAGE_ADDR(2, 0x03)
35#define AIC26_REG_AUDIO_CTRL2 AIC26_PAGE_ADDR(2, 0x04)
36#define AIC26_REG_POWER_CTRL AIC26_PAGE_ADDR(2, 0x05)
37#define AIC26_REG_AUDIO_CTRL3 AIC26_PAGE_ADDR(2, 0x06)
38
39#define AIC26_REG_FILTER_COEFF_L_N0 AIC26_PAGE_ADDR(2, 0x07)
40#define AIC26_REG_FILTER_COEFF_L_N1 AIC26_PAGE_ADDR(2, 0x08)
41#define AIC26_REG_FILTER_COEFF_L_N2 AIC26_PAGE_ADDR(2, 0x09)
42#define AIC26_REG_FILTER_COEFF_L_N3 AIC26_PAGE_ADDR(2, 0x0A)
43#define AIC26_REG_FILTER_COEFF_L_N4 AIC26_PAGE_ADDR(2, 0x0B)
44#define AIC26_REG_FILTER_COEFF_L_N5 AIC26_PAGE_ADDR(2, 0x0C)
45#define AIC26_REG_FILTER_COEFF_L_D1 AIC26_PAGE_ADDR(2, 0x0D)
46#define AIC26_REG_FILTER_COEFF_L_D2 AIC26_PAGE_ADDR(2, 0x0E)
47#define AIC26_REG_FILTER_COEFF_L_D4 AIC26_PAGE_ADDR(2, 0x0F)
48#define AIC26_REG_FILTER_COEFF_L_D5 AIC26_PAGE_ADDR(2, 0x10)
49#define AIC26_REG_FILTER_COEFF_R_N0 AIC26_PAGE_ADDR(2, 0x11)
50#define AIC26_REG_FILTER_COEFF_R_N1 AIC26_PAGE_ADDR(2, 0x12)
51#define AIC26_REG_FILTER_COEFF_R_N2 AIC26_PAGE_ADDR(2, 0x13)
52#define AIC26_REG_FILTER_COEFF_R_N3 AIC26_PAGE_ADDR(2, 0x14)
53#define AIC26_REG_FILTER_COEFF_R_N4 AIC26_PAGE_ADDR(2, 0x15)
54#define AIC26_REG_FILTER_COEFF_R_N5 AIC26_PAGE_ADDR(2, 0x16)
55#define AIC26_REG_FILTER_COEFF_R_D1 AIC26_PAGE_ADDR(2, 0x17)
56#define AIC26_REG_FILTER_COEFF_R_D2 AIC26_PAGE_ADDR(2, 0x18)
57#define AIC26_REG_FILTER_COEFF_R_D4 AIC26_PAGE_ADDR(2, 0x19)
58#define AIC26_REG_FILTER_COEFF_R_D5 AIC26_PAGE_ADDR(2, 0x1A)
59
60#define AIC26_REG_PLL_PROG1 AIC26_PAGE_ADDR(2, 0x1B)
61#define AIC26_REG_PLL_PROG2 AIC26_PAGE_ADDR(2, 0x1C)
62#define AIC26_REG_AUDIO_CTRL4 AIC26_PAGE_ADDR(2, 0x1D)
63#define AIC26_REG_AUDIO_CTRL5 AIC26_PAGE_ADDR(2, 0x1E)
64
65/* fsref dividers; used in register 'Audio Control 1' */
66enum aic26_divisors {
67 AIC26_DIV_1 = 0,
68 AIC26_DIV_1_5 = 1,
69 AIC26_DIV_2 = 2,
70 AIC26_DIV_3 = 3,
71 AIC26_DIV_4 = 4,
72 AIC26_DIV_5 = 5,
73 AIC26_DIV_5_5 = 6,
74 AIC26_DIV_6 = 7,
75};
76
77/* Digital data format */
78enum aic26_datfm {
79 AIC26_DATFM_I2S = 0 << 8,
80 AIC26_DATFM_DSP = 1 << 8,
81 AIC26_DATFM_RIGHTJ = 2 << 8, /* right justified */
82 AIC26_DATFM_LEFTJ = 3 << 8, /* left justified */
83};
84
85/* Sample word length in bits; used in register 'Audio Control 1' */
86enum aic26_wlen {
87 AIC26_WLEN_16 = 0 << 10,
88 AIC26_WLEN_20 = 1 << 10,
89 AIC26_WLEN_24 = 2 << 10,
90 AIC26_WLEN_32 = 3 << 10,
91};
92
93#endif /* _TLV320AIC16_H_ */