brcm2708: add 3.14 support
[openwrt.git] / target / linux / brcm2708 / patches-3.14 / 0049-Add-IQaudIO-Sound-Card-support-for-Raspberry-Pi.patch
1 From deaa651db204a6add9cb0189350922625fd1a311 Mon Sep 17 00:00:00 2001
2 From: Gordon Garrity <gordon@iqaudio.com>
3 Date: Sat, 8 Mar 2014 16:56:57 +0000
4 Subject: [PATCH 49/54] Add IQaudIO Sound Card support for Raspberry Pi
5
6 ---
7  arch/arm/configs/bcmrpi_defconfig |   1 +
8  arch/arm/mach-bcm2708/bcm2708.c   |  22 ++
9  sound/soc/bcm/Kconfig             |   7 +
10  sound/soc/bcm/Makefile            |   2 +
11  sound/soc/bcm/iqaudio-dac.c       | 111 +++++++
12  sound/soc/codecs/Kconfig          |   4 +
13  sound/soc/codecs/Makefile         |   2 +
14  sound/soc/codecs/pcm512x.c        | 677 ++++++++++++++++++++++++++++++++++++++
15  sound/soc/codecs/pcm512x.h        | 142 ++++++++
16  9 files changed, 968 insertions(+)
17  create mode 100644 sound/soc/bcm/iqaudio-dac.c
18  create mode 100644 sound/soc/codecs/pcm512x.c
19  create mode 100644 sound/soc/codecs/pcm512x.h
20
21 diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
22 index 3d3c8ab..a024670 100644
23 --- a/arch/arm/configs/bcmrpi_defconfig
24 +++ b/arch/arm/configs/bcmrpi_defconfig
25 @@ -750,6 +750,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m
26  CONFIG_SND_SOC_I2C_AND_SPI=m
27  CONFIG_SND_SOC_PCM5102A=m
28  CONFIG_SND_SOC_PCM1794A=m
29 +CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
30  CONFIG_SOUND_PRIME=m
31  CONFIG_HIDRAW=y
32  CONFIG_HID_A4TECH=m
33 diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
34 index beb2eca..95a47fa 100644
35 --- a/arch/arm/mach-bcm2708/bcm2708.c
36 +++ b/arch/arm/mach-bcm2708/bcm2708.c
37 @@ -680,6 +680,22 @@ static struct platform_device snd_pcm1794a_codec_device = {
38  };
39  #endif
40  
41 +
42 +#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE)
43 +static struct platform_device snd_rpi_iqaudio_dac_device = {
44 +        .name = "snd-rpi-iqaudio-dac",
45 +        .id = 0,
46 +        .num_resources = 0,
47 +};
48 +
49 +// Use the actual device name rather than generic driver name
50 +static struct i2c_board_info __initdata snd_pcm512x_i2c_devices[] = {
51 +       {
52 +               I2C_BOARD_INFO("pcm5122", 0x4c)
53 +       },
54 +};
55 +#endif
56 +
57  int __init bcm_register_device(struct platform_device *pdev)
58  {
59         int ret;
60 @@ -822,6 +838,12 @@ void __init bcm2708_init(void)
61          bcm_register_device(&snd_pcm1794a_codec_device);
62  #endif
63  
64 +#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE)
65 +        bcm_register_device(&snd_rpi_iqaudio_dac_device);
66 +        i2c_register_board_info(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices));
67 +#endif
68 +
69 +
70         for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
71                 struct amba_device *d = amba_devs[i];
72                 amba_device_register(d, &iomem_resource);
73 diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig
74 index e563dbc..84e4f27 100644
75 --- a/sound/soc/bcm/Kconfig
76 +++ b/sound/soc/bcm/Kconfig
77 @@ -39,3 +39,10 @@ config SND_BCM2708_SOC_RPI_DAC
78          select SND_SOC_PCM1794A
79          help
80           Say Y or M if you want to add support for RPi-DAC.
81 +
82 +config SND_BCM2708_SOC_IQAUDIO_DAC
83 +       tristate "Support for IQaudIO-DAC"
84 +       depends on SND_BCM2708_SOC_I2S
85 +       select SND_SOC_PCM512x
86 +       help
87 +         Say Y or M if you want to add support for IQaudIO-DAC.
88 diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile
89 index 826df7d..d597fb0 100644
90 --- a/sound/soc/bcm/Makefile
91 +++ b/sound/soc/bcm/Makefile
92 @@ -12,7 +12,9 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o
93  snd-soc-hifiberry-dac-objs := hifiberry_dac.o
94  snd-soc-hifiberry-digi-objs := hifiberry_digi.o
95  snd-soc-rpi-dac-objs := rpi-dac.o
96 +snd-soc-iqaudio-dac-objs := iqaudio-dac.o
97  
98  obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
99  obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
100  obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o
101 +obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o
102 diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c
103 new file mode 100644
104 index 0000000..515f044
105 --- /dev/null
106 +++ b/sound/soc/bcm/iqaudio-dac.c
107 @@ -0,0 +1,111 @@
108 +/*
109 + * ASoC Driver for IQaudIO DAC
110 + *
111 + * Author:     Florian Meier <florian.meier@koalo.de>
112 + *             Copyright 2013
113 + *
114 + * This program is free software; you can redistribute it and/or
115 + * modify it under the terms of the GNU General Public License
116 + * version 2 as published by the Free Software Foundation.
117 + *
118 + * This program is distributed in the hope that it will be useful, but
119 + * WITHOUT ANY WARRANTY; without even the implied warranty of
120 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
121 + * General Public License for more details.
122 + */
123 +
124 +#include <linux/module.h>
125 +#include <linux/platform_device.h>
126 +
127 +#include <sound/core.h>
128 +#include <sound/pcm.h>
129 +#include <sound/pcm_params.h>
130 +#include <sound/soc.h>
131 +#include <sound/jack.h>
132 +
133 +static int snd_rpi_iqaudio_dac_init(struct snd_soc_pcm_runtime *rtd)
134 +{
135 +// NOT USED    struct snd_soc_codec *codec = rtd->codec;
136 +
137 +       return 0;
138 +}
139 +
140 +static int snd_rpi_iqaudio_dac_hw_params(struct snd_pcm_substream *substream,
141 +                                      struct snd_pcm_hw_params *params)
142 +{
143 +       struct snd_soc_pcm_runtime *rtd = substream->private_data;
144 +// NOT USED    struct snd_soc_dai *codec_dai = rtd->codec_dai;
145 +// NOT USED    struct snd_soc_codec *codec = rtd->codec;
146 +       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
147 +
148 +       unsigned int sample_bits =
149 +               snd_pcm_format_physical_width(params_format(params));
150 +
151 +       return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2);
152 +}
153 +
154 +/* machine stream operations */
155 +static struct snd_soc_ops snd_rpi_iqaudio_dac_ops = {
156 +       .hw_params = snd_rpi_iqaudio_dac_hw_params,
157 +};
158 +
159 +static struct snd_soc_dai_link snd_rpi_iqaudio_dac_dai[] = {
160 +{
161 +       .name           = "IQaudIO DAC",
162 +       .stream_name    = "IQaudIO DAC HiFi",
163 +       .cpu_dai_name   = "bcm2708-i2s.0",
164 +       .codec_dai_name = "pcm512x-hifi",
165 +       .platform_name  = "bcm2708-i2s.0",
166 +       .codec_name     = "pcm512x.1-004c",
167 +       .dai_fmt        = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
168 +                               SND_SOC_DAIFMT_CBS_CFS,
169 +       .ops            = &snd_rpi_iqaudio_dac_ops,
170 +       .init           = snd_rpi_iqaudio_dac_init,
171 +},
172 +};
173 +
174 +/* audio machine driver */
175 +static struct snd_soc_card snd_rpi_iqaudio_dac = {
176 +       .name         = "snd_rpi_iqaudio_dac",
177 +       .dai_link     = snd_rpi_iqaudio_dac_dai,
178 +       .num_links    = ARRAY_SIZE(snd_rpi_iqaudio_dac_dai),
179 +};
180 +
181 +static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev)
182 +{
183 +       int ret = 0;
184 +
185 +       snd_rpi_iqaudio_dac.dev = &pdev->dev;
186 +       ret = snd_soc_register_card(&snd_rpi_iqaudio_dac);
187 +       if (ret)
188 +               dev_err(&pdev->dev,
189 +                       "snd_soc_register_card() failed: %d\n", ret);
190 +
191 +       return ret;
192 +}
193 +
194 +static int snd_rpi_iqaudio_dac_remove(struct platform_device *pdev)
195 +{
196 +       return snd_soc_unregister_card(&snd_rpi_iqaudio_dac);
197 +}
198 +
199 +static const struct of_device_id iqaudio_of_match[] = {
200 +       { .compatible = "iqaudio,iqaudio-dac", },
201 +       {},
202 +};
203 +
204 +static struct platform_driver snd_rpi_iqaudio_dac_driver = {
205 +       .driver = {
206 +               .name   = "snd-rpi-iqaudio-dac",
207 +               .owner  = THIS_MODULE,
208 +               .of_match_table = iqaudio_of_match,
209 +       },
210 +       .probe          = snd_rpi_iqaudio_dac_probe,
211 +       .remove         = snd_rpi_iqaudio_dac_remove,
212 +};
213 +
214 +module_platform_driver(snd_rpi_iqaudio_dac_driver);
215 +
216 +MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>");
217 +MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC");
218 +MODULE_LICENSE("GPL v2");
219 diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
220 index 4d2569e..ac28805 100644
221 --- a/sound/soc/codecs/Kconfig
222 +++ b/sound/soc/codecs/Kconfig
223 @@ -61,6 +61,7 @@ config SND_SOC_ALL_CODECS
224         select SND_SOC_PCM3008
225         select SND_SOC_PCM1794A
226         select SND_SOC_PCM5102A
227 +       select SND_SOC_PCM512x if SND_SOC_I2C_AND_SPI
228         select SND_SOC_RT5631 if I2C
229         select SND_SOC_RT5640 if I2C
230         select SND_SOC_SGTL5000 if I2C
231 @@ -321,6 +322,9 @@ config SND_SOC_PCM1794A
232  config SND_SOC_PCM5102A
233         tristate
234  
235 +config SND_SOC_PCM512x
236 +       tristate
237 +
238  config SND_SOC_RT5631
239         tristate
240  
241 diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
242 index 9b806a2..61461c1 100644
243 --- a/sound/soc/codecs/Makefile
244 +++ b/sound/soc/codecs/Makefile
245 @@ -48,6 +48,7 @@ snd-soc-pcm1792a-codec-objs := pcm1792a.o
246  snd-soc-pcm3008-objs := pcm3008.o
247  snd-soc-pcm1794a-objs := pcm1794a.o
248  snd-soc-pcm5102a-objs := pcm5102a.o
249 +snd-soc-pcm512x-objs := pcm512x.o
250  snd-soc-rt5631-objs := rt5631.o
251  snd-soc-rt5640-objs := rt5640.o
252  snd-soc-sgtl5000-objs := sgtl5000.o
253 @@ -183,6 +184,7 @@ obj-$(CONFIG_SND_SOC_PCM1792A)      += snd-soc-pcm1792a-codec.o
254  obj-$(CONFIG_SND_SOC_PCM3008)  += snd-soc-pcm3008.o
255  obj-$(CONFIG_SND_SOC_PCM1794A) += snd-soc-pcm1794a.o
256  obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o
257 +obj-$(CONFIG_SND_SOC_PCM512x)  += snd-soc-pcm512x.o
258  obj-$(CONFIG_SND_SOC_RT5631)   += snd-soc-rt5631.o
259  obj-$(CONFIG_SND_SOC_RT5640)   += snd-soc-rt5640.o
260  obj-$(CONFIG_SND_SOC_SGTL5000)  += snd-soc-sgtl5000.o
261 diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
262 new file mode 100644
263 index 0000000..55b6200
264 --- /dev/null
265 +++ b/sound/soc/codecs/pcm512x.c
266 @@ -0,0 +1,677 @@
267 +/*
268 + * Driver for the PCM512x CODECs
269 + *
270 + * Author:     Mark Brown <broonie@linaro.org>
271 + *             Copyright 2014 Linaro Ltd
272 + *
273 + * This program is free software; you can redistribute it and/or
274 + * modify it under the terms of the GNU General Public License
275 + * version 2 as published by the Free Software Foundation.
276 + *
277 + * This program is distributed in the hope that it will be useful, but
278 + * WITHOUT ANY WARRANTY; without even the implied warranty of
279 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
280 + * General Public License for more details.
281 + */
282 +
283 +
284 +#include <linux/init.h>
285 +#include <linux/module.h>
286 +#include <linux/clk.h>
287 +#include <linux/i2c.h>
288 +#include <linux/pm_runtime.h>
289 +#include <linux/regmap.h>
290 +#include <linux/regulator/consumer.h>
291 +#include <linux/spi/spi.h>
292 +#include <sound/soc.h>
293 +#include <sound/soc-dapm.h>
294 +#include <sound/tlv.h>
295 +
296 +#include "pcm512x.h"
297 +
298 +#define PCM512x_NUM_SUPPLIES 3
299 +static const char *pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = {
300 +       "AVDD",
301 +       "DVDD",
302 +       "CPVDD",
303 +};
304 +
305 +struct pcm512x_priv {
306 +       struct regmap *regmap;
307 +       struct clk *sclk;
308 +       struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES];
309 +       struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES];
310 +};
311 +
312 +/*
313 + * We can't use the same notifier block for more than one supply and
314 + * there's no way I can see to get from a callback to the caller
315 + * except container_of().
316 + */
317 +#define PCM512x_REGULATOR_EVENT(n) \
318 +static int pcm512x_regulator_event_##n(struct notifier_block *nb, \
319 +                                     unsigned long event, void *data)    \
320 +{ \
321 +       struct pcm512x_priv *pcm512x = container_of(nb, struct pcm512x_priv, \
322 +                                                   supply_nb[n]); \
323 +       if (event & REGULATOR_EVENT_DISABLE) { \
324 +               regcache_mark_dirty(pcm512x->regmap);   \
325 +               regcache_cache_only(pcm512x->regmap, true);     \
326 +       } \
327 +       return 0; \
328 +}
329 +
330 +PCM512x_REGULATOR_EVENT(0)
331 +PCM512x_REGULATOR_EVENT(1)
332 +PCM512x_REGULATOR_EVENT(2)
333 +
334 +static const struct reg_default pcm512x_reg_defaults[] = {
335 +       { PCM512x_RESET,            0x00 },
336 +       { PCM512x_POWER,            0x00 },
337 +       { PCM512x_MUTE,             0x00 },
338 +       { PCM512x_DSP,              0x00 },
339 +       { PCM512x_PLL_REF,          0x00 },
340 +       { PCM512x_DAC_ROUTING,      0x11 },
341 +       { PCM512x_DSP_PROGRAM,      0x01 },
342 +       { PCM512x_CLKDET,           0x00 },
343 +       { PCM512x_AUTO_MUTE,        0x00 },
344 +       { PCM512x_ERROR_DETECT,     0x00 },
345 +       { PCM512x_DIGITAL_VOLUME_1, 0x00 },
346 +       { PCM512x_DIGITAL_VOLUME_2, 0x30 },
347 +       { PCM512x_DIGITAL_VOLUME_3, 0x30 },
348 +       { PCM512x_DIGITAL_MUTE_1,   0x22 },
349 +       { PCM512x_DIGITAL_MUTE_2,   0x00 },
350 +       { PCM512x_DIGITAL_MUTE_3,   0x07 },
351 +};
352 +
353 +static bool pcm512x_readable(struct device *dev, unsigned int reg)
354 +{
355 +       switch (reg) {
356 +       case PCM512x_RESET:
357 +       case PCM512x_POWER:
358 +       case PCM512x_MUTE:
359 +       case PCM512x_PLL_EN:
360 +       case PCM512x_SPI_MISO_FUNCTION:
361 +       case PCM512x_DSP:
362 +       case PCM512x_GPIO_EN:
363 +       case PCM512x_BCLK_LRCLK_CFG:
364 +       case PCM512x_DSP_GPIO_INPUT:
365 +       case PCM512x_MASTER_MODE:
366 +       case PCM512x_PLL_REF:
367 +       case PCM512x_PLL_COEFF_0:
368 +       case PCM512x_PLL_COEFF_1:
369 +       case PCM512x_PLL_COEFF_2:
370 +       case PCM512x_PLL_COEFF_3:
371 +       case PCM512x_PLL_COEFF_4:
372 +       case PCM512x_DSP_CLKDIV:
373 +       case PCM512x_DAC_CLKDIV:
374 +       case PCM512x_NCP_CLKDIV:
375 +       case PCM512x_OSR_CLKDIV:
376 +       case PCM512x_MASTER_CLKDIV_1:
377 +       case PCM512x_MASTER_CLKDIV_2:
378 +       case PCM512x_FS_SPEED_MODE:
379 +       case PCM512x_IDAC_1:
380 +       case PCM512x_IDAC_2:
381 +       case PCM512x_ERROR_DETECT:
382 +       case PCM512x_I2S_1:
383 +       case PCM512x_I2S_2:
384 +       case PCM512x_DAC_ROUTING:
385 +       case PCM512x_DSP_PROGRAM:
386 +       case PCM512x_CLKDET:
387 +       case PCM512x_AUTO_MUTE:
388 +       case PCM512x_DIGITAL_VOLUME_1:
389 +       case PCM512x_DIGITAL_VOLUME_2:
390 +       case PCM512x_DIGITAL_VOLUME_3:
391 +       case PCM512x_DIGITAL_MUTE_1:
392 +       case PCM512x_DIGITAL_MUTE_2:
393 +       case PCM512x_DIGITAL_MUTE_3:
394 +       case PCM512x_GPIO_OUTPUT_1:
395 +       case PCM512x_GPIO_OUTPUT_2:
396 +       case PCM512x_GPIO_OUTPUT_3:
397 +       case PCM512x_GPIO_OUTPUT_4:
398 +       case PCM512x_GPIO_OUTPUT_5:
399 +       case PCM512x_GPIO_OUTPUT_6:
400 +       case PCM512x_GPIO_CONTROL_1:
401 +       case PCM512x_GPIO_CONTROL_2:
402 +       case PCM512x_OVERFLOW:
403 +       case PCM512x_RATE_DET_1:
404 +       case PCM512x_RATE_DET_2:
405 +       case PCM512x_RATE_DET_3:
406 +       case PCM512x_RATE_DET_4:
407 +       case PCM512x_ANALOG_MUTE_DET:
408 +       case PCM512x_GPIN:
409 +       case PCM512x_DIGITAL_MUTE_DET:
410 +               return true;
411 +       default:
412 +               return false;
413 +       }
414 +}
415 +
416 +static bool pcm512x_volatile(struct device *dev, unsigned int reg)
417 +{
418 +       switch (reg) {
419 +       case PCM512x_PLL_EN:
420 +       case PCM512x_OVERFLOW:
421 +       case PCM512x_RATE_DET_1:
422 +       case PCM512x_RATE_DET_2:
423 +       case PCM512x_RATE_DET_3:
424 +       case PCM512x_RATE_DET_4:
425 +       case PCM512x_ANALOG_MUTE_DET:
426 +       case PCM512x_GPIN:
427 +       case PCM512x_DIGITAL_MUTE_DET:
428 +               return true;
429 +       default:
430 +               return false;
431 +       }
432 +}
433 +
434 +static const DECLARE_TLV_DB_SCALE(digital_tlv, -10350, 50, 1);
435 +
436 +static const char *pcm512x_dsp_program_texts[] = {
437 +       "FIR interpolation with de-emphasis",
438 +       "Low latency IIR with de-emphasis",
439 +       "High attenuation with de-emphasis",
440 +       "Ringing-less low latency FIR",
441 +};
442 +
443 +static const unsigned int pcm512x_dsp_program_values[] = {
444 +       1,
445 +       2,
446 +       3,
447 +       5,
448 +       7,
449 +};
450 +
451 +static const SOC_VALUE_ENUM_SINGLE_DECL(pcm512x_dsp_program,
452 +                                       PCM512x_DSP_PROGRAM, 0, 0x1f,
453 +                                       pcm512x_dsp_program_texts,
454 +                                       pcm512x_dsp_program_values);
455 +
456 +static const char *pcm512x_clk_missing_text[] = {
457 +       "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s"
458 +};
459 +
460 +static const struct soc_enum pcm512x_clk_missing =
461 +       SOC_ENUM_SINGLE(PCM512x_CLKDET, 0,  7, pcm512x_clk_missing_text);
462 +
463 +static const char *pcm512x_autom_text[] = {
464 +       "21ms", "106ms", "213ms", "533ms", "1.07s", "2.13s", "5.33s", "10.66s"
465 +};
466 +
467 +static const struct soc_enum pcm512x_autom_l =
468 +       SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATML_SHIFT, 7,
469 +                       pcm512x_autom_text);
470 +
471 +static const struct soc_enum pcm512x_autom_r =
472 +       SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATMR_SHIFT, 7,
473 +                       pcm512x_autom_text);
474 +
475 +static const char *pcm512x_ramp_rate_text[] = {
476 +       "1 sample/update", "2 samples/update", "4 samples/update",
477 +       "Immediate"
478 +};
479 +
480 +static const struct soc_enum pcm512x_vndf =
481 +       SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDF_SHIFT, 4,
482 +                       pcm512x_ramp_rate_text);
483 +
484 +static const struct soc_enum pcm512x_vnuf =
485 +       SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUF_SHIFT, 4,
486 +                       pcm512x_ramp_rate_text);
487 +
488 +static const struct soc_enum pcm512x_vedf =
489 +       SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDF_SHIFT, 4,
490 +                       pcm512x_ramp_rate_text);
491 +
492 +static const char *pcm512x_ramp_step_text[] = {
493 +       "4dB/step", "2dB/step", "1dB/step", "0.5dB/step"
494 +};
495 +
496 +static const struct soc_enum pcm512x_vnds =
497 +       SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDS_SHIFT, 4,
498 +                       pcm512x_ramp_step_text);
499 +
500 +static const struct soc_enum pcm512x_vnus =
501 +       SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUS_SHIFT, 4,
502 +                       pcm512x_ramp_step_text);
503 +
504 +static const struct soc_enum pcm512x_veds =
505 +       SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDS_SHIFT, 4,
506 +                       pcm512x_ramp_step_text);
507 +
508 +static const struct snd_kcontrol_new pcm512x_controls[] = {
509 +SOC_DOUBLE_R_TLV("Playback Digital Volume", PCM512x_DIGITAL_VOLUME_2,
510 +                PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv),
511 +SOC_DOUBLE("Playback Digital Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT,
512 +          PCM512x_RQMR_SHIFT, 1, 1),
513 +
514 +SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1),
515 +SOC_VALUE_ENUM("DSP Program", pcm512x_dsp_program),
516 +
517 +SOC_ENUM("Clock Missing Period", pcm512x_clk_missing),
518 +SOC_ENUM("Auto Mute Time Left", pcm512x_autom_l),
519 +SOC_ENUM("Auto Mute Time Right", pcm512x_autom_r),
520 +SOC_SINGLE("Auto Mute Mono Switch", PCM512x_DIGITAL_MUTE_3,
521 +          PCM512x_ACTL_SHIFT, 1, 0),
522 +SOC_DOUBLE("Auto Mute Switch", PCM512x_DIGITAL_MUTE_3, PCM512x_AMLE_SHIFT,
523 +          PCM512x_AMLR_SHIFT, 1, 0),
524 +
525 +SOC_ENUM("Volume Ramp Down Rate", pcm512x_vndf),
526 +SOC_ENUM("Volume Ramp Down Step", pcm512x_vnds),
527 +SOC_ENUM("Volume Ramp Up Rate", pcm512x_vnuf),
528 +SOC_ENUM("Volume Ramp Up Step", pcm512x_vnus),
529 +SOC_ENUM("Volume Ramp Down Emergency Rate", pcm512x_vedf),
530 +SOC_ENUM("Volume Ramp Down Emergency Step", pcm512x_veds),
531 +};
532 +
533 +static const struct snd_soc_dapm_widget pcm512x_dapm_widgets[] = {
534 +SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
535 +SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),
536 +
537 +SND_SOC_DAPM_OUTPUT("OUTL"),
538 +SND_SOC_DAPM_OUTPUT("OUTR"),
539 +};
540 +
541 +static const struct snd_soc_dapm_route pcm512x_dapm_routes[] = {
542 +       { "DACL", NULL, "Playback" },
543 +       { "DACR", NULL, "Playback" },
544 +
545 +       { "OUTL", NULL, "DACL" },
546 +       { "OUTR", NULL, "DACR" },
547 +};
548 +
549 +static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
550 +                                 enum snd_soc_bias_level level)
551 +{
552 +       struct pcm512x_priv *pcm512x = dev_get_drvdata(codec->dev);
553 +       int ret;
554 +
555 +       switch (level) {
556 +       case SND_SOC_BIAS_ON:
557 +       case SND_SOC_BIAS_PREPARE:
558 +               break;
559 +
560 +       case SND_SOC_BIAS_STANDBY:
561 +               ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
562 +                                        PCM512x_RQST, 0);
563 +               if (ret != 0) {
564 +                       dev_err(codec->dev, "Failed to remove standby: %d\n",
565 +                               ret);
566 +                       return ret;
567 +               }
568 +               break;
569 +
570 +       case SND_SOC_BIAS_OFF:
571 +               ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
572 +                                        PCM512x_RQST, PCM512x_RQST);
573 +               if (ret != 0) {
574 +                       dev_err(codec->dev, "Failed to request standby: %d\n",
575 +                               ret);
576 +                       return ret;
577 +               }
578 +               break;
579 +       }
580 +
581 +       codec->dapm.bias_level = level;
582 +
583 +       return 0;
584 +}
585 +
586 +static struct snd_soc_dai_driver pcm512x_dai = {
587 +       .name = "pcm512x-hifi",
588 +       .playback = {
589 +               .stream_name = "Playback",
590 +               .channels_min = 2,
591 +               .channels_max = 2,
592 +               .rates = SNDRV_PCM_RATE_8000_192000,
593 +               .formats = SNDRV_PCM_FMTBIT_S16_LE |
594 +                          SNDRV_PCM_FMTBIT_S24_LE |
595 +                          SNDRV_PCM_FMTBIT_S32_LE
596 +       },
597 +};
598 +
599 +static struct snd_soc_codec_driver pcm512x_codec_driver = {
600 +       .set_bias_level = pcm512x_set_bias_level,
601 +       .idle_bias_off = true,
602 +
603 +       .controls = pcm512x_controls,
604 +       .num_controls = ARRAY_SIZE(pcm512x_controls),
605 +       .dapm_widgets = pcm512x_dapm_widgets,
606 +       .num_dapm_widgets = ARRAY_SIZE(pcm512x_dapm_widgets),
607 +       .dapm_routes = pcm512x_dapm_routes,
608 +       .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes),
609 +};
610 +
611 +static const struct regmap_config pcm512x_regmap = {
612 +       .reg_bits = 8,
613 +       .val_bits = 8,
614 +
615 +       .readable_reg = pcm512x_readable,
616 +       .volatile_reg = pcm512x_volatile,
617 +
618 +       .max_register = PCM512x_MAX_REGISTER,
619 +       .reg_defaults = pcm512x_reg_defaults,
620 +       .num_reg_defaults = ARRAY_SIZE(pcm512x_reg_defaults),
621 +       .cache_type = REGCACHE_RBTREE,
622 +};
623 +
624 +static const struct of_device_id pcm512x_of_match[] = {
625 +       { .compatible = "ti,pcm5121", },
626 +       { .compatible = "ti,pcm5122", },
627 +       { }
628 +};
629 +MODULE_DEVICE_TABLE(of, pcm512x_of_match);
630 +
631 +static int pcm512x_probe(struct device *dev, struct regmap *regmap)
632 +{
633 +       struct pcm512x_priv *pcm512x;
634 +       int i, ret;
635 +
636 +       pcm512x = devm_kzalloc(dev, sizeof(struct pcm512x_priv), GFP_KERNEL);
637 +       if (!pcm512x)
638 +               return -ENOMEM;
639 +
640 +       dev_set_drvdata(dev, pcm512x);
641 +       pcm512x->regmap = regmap;
642 +
643 +       for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++)
644 +               pcm512x->supplies[i].supply = pcm512x_supply_names[i];
645 +
646 +       ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pcm512x->supplies),
647 +                                     pcm512x->supplies);
648 +       if (ret != 0) {
649 +               dev_err(dev, "Failed to get supplies: %d\n", ret);
650 +               return ret;
651 +       }
652 +
653 +       pcm512x->supply_nb[0].notifier_call = pcm512x_regulator_event_0;
654 +       pcm512x->supply_nb[1].notifier_call = pcm512x_regulator_event_1;
655 +       pcm512x->supply_nb[2].notifier_call = pcm512x_regulator_event_2;
656 +
657 +       for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) {
658 +               ret = regulator_register_notifier(pcm512x->supplies[i].consumer,
659 +                                                 &pcm512x->supply_nb[i]);
660 +               if (ret != 0) {
661 +                       dev_err(dev,
662 +                               "Failed to register regulator notifier: %d\n",
663 +                               ret);
664 +               }
665 +       }
666 +
667 +       ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies),
668 +                                   pcm512x->supplies);
669 +       if (ret != 0) {
670 +               dev_err(dev, "Failed to enable supplies: %d\n", ret);
671 +               return ret;
672 +       }
673 +
674 +       /* Reset the device, verifying I/O in the process for I2C */
675 +       ret = regmap_write(regmap, PCM512x_RESET,
676 +                          PCM512x_RSTM | PCM512x_RSTR);
677 +       if (ret != 0) {
678 +               dev_err(dev, "Failed to reset device: %d\n", ret);
679 +               goto err;
680 +       }
681 +
682 +       ret = regmap_write(regmap, PCM512x_RESET, 0);
683 +       if (ret != 0) {
684 +               dev_err(dev, "Failed to reset device: %d\n", ret);
685 +               goto err;
686 +       }
687 +
688 +       pcm512x->sclk = devm_clk_get(dev, NULL);
689 +       if (IS_ERR(pcm512x->sclk)) {
690 +               if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER)
691 +                       return -EPROBE_DEFER;
692 +
693 +               dev_info(dev, "No SCLK, using BCLK: %ld\n",
694 +                        PTR_ERR(pcm512x->sclk));
695 +
696 +               /* Disable reporting of missing SCLK as an error */
697 +               regmap_update_bits(regmap, PCM512x_ERROR_DETECT,
698 +                                  PCM512x_IDCH, PCM512x_IDCH);
699 +
700 +               /* Switch PLL input to BCLK */
701 +               regmap_update_bits(regmap, PCM512x_PLL_REF,
702 +                                  PCM512x_SREF, PCM512x_SREF);
703 +       } else {
704 +               ret = clk_prepare_enable(pcm512x->sclk);
705 +               if (ret != 0) {
706 +                       dev_err(dev, "Failed to enable SCLK: %d\n", ret);
707 +                       return ret;
708 +               }
709 +       }
710 +
711 +       /* Default to standby mode */
712 +       ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
713 +                                PCM512x_RQST, PCM512x_RQST);
714 +       if (ret != 0) {
715 +               dev_err(dev, "Failed to request standby: %d\n",
716 +                       ret);
717 +               goto err_clk;
718 +       }
719 +
720 +       pm_runtime_set_active(dev);
721 +       pm_runtime_enable(dev);
722 +       pm_runtime_idle(dev);
723 +
724 +       ret = snd_soc_register_codec(dev, &pcm512x_codec_driver,
725 +                                   &pcm512x_dai, 1);
726 +       if (ret != 0) {
727 +               dev_err(dev, "Failed to register CODEC: %d\n", ret);
728 +               goto err_pm;
729 +       }
730 +
731 +       dev_info(dev, "Completed initialisation - pcm512x_probe");
732 +
733 +       return 0;
734 +
735 +err_pm:
736 +       pm_runtime_disable(dev);
737 +err_clk:
738 +       if (!IS_ERR(pcm512x->sclk))
739 +               clk_disable_unprepare(pcm512x->sclk);
740 +err:
741 +       regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
742 +                                    pcm512x->supplies);
743 +       return ret;
744 +}
745 +
746 +static void pcm512x_remove(struct device *dev)
747 +{
748 +       struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
749 +
750 +       snd_soc_unregister_codec(dev);
751 +       pm_runtime_disable(dev);
752 +       if (!IS_ERR(pcm512x->sclk))
753 +               clk_disable_unprepare(pcm512x->sclk);
754 +       regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
755 +                              pcm512x->supplies);
756 +}
757 +
758 +/* TODO
759 +static int pcm512x_suspend(struct device *dev)
760 +{
761 +       struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
762 +       int ret;
763 +
764 +       ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
765 +                                PCM512x_RQPD, PCM512x_RQPD);
766 +       if (ret != 0) {
767 +               dev_err(dev, "Failed to request power down: %d\n", ret);
768 +               return ret;
769 +       }
770 +
771 +       ret = regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
772 +                                    pcm512x->supplies);
773 +       if (ret != 0) {
774 +               dev_err(dev, "Failed to disable supplies: %d\n", ret);
775 +               return ret;
776 +       }
777 +
778 +       if (!IS_ERR(pcm512x->sclk))
779 +               clk_disable_unprepare(pcm512x->sclk);
780 +
781 +       return 0;
782 +}
783 +
784 +static int pcm512x_resume(struct device *dev)
785 +{
786 +       struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
787 +       int ret;
788 +
789 +       if (!IS_ERR(pcm512x->sclk)) {
790 +               ret = clk_prepare_enable(pcm512x->sclk);
791 +               if (ret != 0) {
792 +                       dev_err(dev, "Failed to enable SCLK: %d\n", ret);
793 +                       return ret;
794 +               }
795 +       }
796 +
797 +       ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies),
798 +                                   pcm512x->supplies);
799 +       if (ret != 0) {
800 +               dev_err(dev, "Failed to enable supplies: %d\n", ret);
801 +               return ret;
802 +       }
803 +
804 +       regcache_cache_only(pcm512x->regmap, false);
805 +       ret = regcache_sync(pcm512x->regmap);
806 +       if (ret != 0) {
807 +               dev_err(dev, "Failed to sync cache: %d\n", ret);
808 +               return ret;
809 +       }
810 +
811 +       ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
812 +                                PCM512x_RQPD, 0);
813 +       if (ret != 0) {
814 +               dev_err(dev, "Failed to remove power down: %d\n", ret);
815 +               return ret;
816 +       }
817 +
818 +       return 0;
819 +}
820 +
821 +// END OF PCM512x_suspend and resume calls TODO
822 +*/
823 +
824 +static const struct dev_pm_ops pcm512x_pm_ops = {
825 +       SET_RUNTIME_PM_OPS(pcm512x_suspend, pcm512x_resume, NULL)
826 +};
827 +
828 +#if IS_ENABLED(CONFIG_I2C)
829 +static int pcm512x_i2c_probe(struct i2c_client *i2c,
830 +                            const struct i2c_device_id *id)
831 +{
832 +       struct regmap *regmap;
833 +
834 +       regmap = devm_regmap_init_i2c(i2c, &pcm512x_regmap);
835 +       if (IS_ERR(regmap))
836 +               return PTR_ERR(regmap);
837 +
838 +       return pcm512x_probe(&i2c->dev, regmap);
839 +}
840 +
841 +static int pcm512x_i2c_remove(struct i2c_client *i2c)
842 +{
843 +       pcm512x_remove(&i2c->dev);
844 +       return 0;
845 +}
846 +
847 +static const struct i2c_device_id pcm512x_i2c_id[] = {
848 +       { "pcm5121", },
849 +       { "pcm5122", },
850 +       { }
851 +};
852 +MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id);
853 +
854 +static struct i2c_driver pcm512x_i2c_driver = {
855 +       .probe          = pcm512x_i2c_probe,
856 +       .remove         = pcm512x_i2c_remove,
857 +       .id_table       = pcm512x_i2c_id,
858 +       .driver         = {
859 +               .name   = "pcm512x",
860 +               .owner  = THIS_MODULE,
861 +               .of_match_table = pcm512x_of_match,
862 +               .pm     = &pcm512x_pm_ops,
863 +       },
864 +};
865 +#endif
866 +
867 +#if defined(CONFIG_SPI_MASTER)
868 +static int pcm512x_spi_probe(struct spi_device *spi)
869 +{
870 +       struct regmap *regmap;
871 +       int ret;
872 +
873 +       regmap = devm_regmap_init_spi(spi, &pcm512x_regmap);
874 +       if (IS_ERR(regmap)) {
875 +               ret = PTR_ERR(regmap);
876 +               return ret;
877 +       }
878 +
879 +       return pcm512x_probe(&spi->dev, regmap);
880 +}
881 +
882 +static int pcm512x_spi_remove(struct spi_device *spi)
883 +{
884 +       pcm512x_remove(&spi->dev);
885 +       return 0;
886 +}
887 +
888 +static const struct spi_device_id pcm512x_spi_id[] = {
889 +       { "pcm5121", },
890 +       { "pcm5122", },
891 +       { },
892 +};
893 +MODULE_DEVICE_TABLE(spi, pcm512x_spi_id);
894 +
895 +static struct spi_driver pcm512x_spi_driver = {
896 +       .probe          = pcm512x_spi_probe,
897 +       .remove         = pcm512x_spi_remove,
898 +       .id_table       = pcm512x_spi_id,
899 +       .driver = {
900 +               .name   = "pcm512x",
901 +               .owner  = THIS_MODULE,
902 +               .of_match_table = pcm512x_of_match,
903 +               .pm     = &pcm512x_pm_ops,
904 +       },
905 +};
906 +#endif
907 +
908 +static int __init pcm512x_modinit(void)
909 +{
910 +       int ret = 0;
911 +
912 +#if IS_ENABLED(CONFIG_I2C)
913 +       ret = i2c_add_driver(&pcm512x_i2c_driver);
914 +       if (ret) {
915 +               printk(KERN_ERR "Failed to register pcm512x I2C driver: %d\n",
916 +                      ret);
917 +       }
918 +#endif
919 +#if defined(CONFIG_SPI_MASTER)
920 +       ret = spi_register_driver(&pcm512x_spi_driver);
921 +       if (ret != 0) {
922 +               printk(KERN_ERR "Failed to register pcm512x SPI driver: %d\n",
923 +                      ret);
924 +       }
925 +#endif
926 +       return ret;
927 +}
928 +module_init(pcm512x_modinit);
929 +
930 +static void __exit pcm512x_exit(void)
931 +{
932 +#if IS_ENABLED(CONFIG_I2C)
933 +       i2c_del_driver(&pcm512x_i2c_driver);
934 +#endif
935 +#if defined(CONFIG_SPI_MASTER)
936 +       spi_unregister_driver(&pcm512x_spi_driver);
937 +#endif
938 +}
939 +module_exit(pcm512x_exit);
940 +
941 +MODULE_DESCRIPTION("ASoC PCM512x codec driver");
942 +MODULE_AUTHOR("Mark Brown <broonie@linaro.org>");
943 +MODULE_LICENSE("GPL v2");
944 diff --git a/sound/soc/codecs/pcm512x.h b/sound/soc/codecs/pcm512x.h
945 new file mode 100644
946 index 0000000..b2f518e
947 --- /dev/null
948 +++ b/sound/soc/codecs/pcm512x.h
949 @@ -0,0 +1,142 @@
950 +/*
951 + * Driver for the PCM512x CODECs
952 + *
953 + * Author:     Mark Brown <broonie@linaro.org>
954 + *             Copyright 2014 Linaro Ltd
955 + *
956 + * This program is free software; you can redistribute it and/or
957 + * modify it under the terms of the GNU General Public License
958 + * version 2 as published by the Free Software Foundation.
959 + *
960 + * This program is distributed in the hope that it will be useful, but
961 + * WITHOUT ANY WARRANTY; without even the implied warranty of
962 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
963 + * General Public License for more details.
964 + */
965 +
966 +#ifndef _SND_SOC_PCM512X
967 +#define _SND_SOC_PCM512X
968 +
969 +#define PCM512x_PAGE_0_BASE 0
970 +
971 +#define PCM512x_PAGE              0
972 +
973 +#define PCM512x_RESET             (PCM512x_PAGE_0_BASE +   1)
974 +#define PCM512x_POWER             (PCM512x_PAGE_0_BASE +   2)
975 +#define PCM512x_MUTE              (PCM512x_PAGE_0_BASE +   3)
976 +#define PCM512x_PLL_EN            (PCM512x_PAGE_0_BASE +   4)
977 +#define PCM512x_SPI_MISO_FUNCTION (PCM512x_PAGE_0_BASE +   6)
978 +#define PCM512x_DSP               (PCM512x_PAGE_0_BASE +   7)
979 +#define PCM512x_GPIO_EN           (PCM512x_PAGE_0_BASE +   8)
980 +#define PCM512x_BCLK_LRCLK_CFG    (PCM512x_PAGE_0_BASE +   9)
981 +#define PCM512x_DSP_GPIO_INPUT    (PCM512x_PAGE_0_BASE +  10)
982 +#define PCM512x_MASTER_MODE       (PCM512x_PAGE_0_BASE +  12)
983 +#define PCM512x_PLL_REF           (PCM512x_PAGE_0_BASE +  13)
984 +#define PCM512x_PLL_COEFF_0       (PCM512x_PAGE_0_BASE +  20)
985 +#define PCM512x_PLL_COEFF_1       (PCM512x_PAGE_0_BASE +  21)
986 +#define PCM512x_PLL_COEFF_2       (PCM512x_PAGE_0_BASE +  22)
987 +#define PCM512x_PLL_COEFF_3       (PCM512x_PAGE_0_BASE +  23)
988 +#define PCM512x_PLL_COEFF_4       (PCM512x_PAGE_0_BASE +  24)
989 +#define PCM512x_DSP_CLKDIV        (PCM512x_PAGE_0_BASE +  27)
990 +#define PCM512x_DAC_CLKDIV        (PCM512x_PAGE_0_BASE +  28)
991 +#define PCM512x_NCP_CLKDIV        (PCM512x_PAGE_0_BASE +  29)
992 +#define PCM512x_OSR_CLKDIV        (PCM512x_PAGE_0_BASE +  30)
993 +#define PCM512x_MASTER_CLKDIV_1   (PCM512x_PAGE_0_BASE +  32)
994 +#define PCM512x_MASTER_CLKDIV_2   (PCM512x_PAGE_0_BASE +  33)
995 +#define PCM512x_FS_SPEED_MODE     (PCM512x_PAGE_0_BASE +  34)
996 +#define PCM512x_IDAC_1            (PCM512x_PAGE_0_BASE +  35)
997 +#define PCM512x_IDAC_2            (PCM512x_PAGE_0_BASE +  36)
998 +#define PCM512x_ERROR_DETECT      (PCM512x_PAGE_0_BASE +  37)
999 +#define PCM512x_I2S_1             (PCM512x_PAGE_0_BASE +  40)
1000 +#define PCM512x_I2S_2             (PCM512x_PAGE_0_BASE +  41)
1001 +#define PCM512x_DAC_ROUTING       (PCM512x_PAGE_0_BASE +  42)
1002 +#define PCM512x_DSP_PROGRAM       (PCM512x_PAGE_0_BASE +  43)
1003 +#define PCM512x_CLKDET            (PCM512x_PAGE_0_BASE +  44)
1004 +#define PCM512x_AUTO_MUTE         (PCM512x_PAGE_0_BASE +  59)
1005 +#define PCM512x_DIGITAL_VOLUME_1  (PCM512x_PAGE_0_BASE +  60)
1006 +#define PCM512x_DIGITAL_VOLUME_2  (PCM512x_PAGE_0_BASE +  61)
1007 +#define PCM512x_DIGITAL_VOLUME_3  (PCM512x_PAGE_0_BASE +  62)
1008 +#define PCM512x_DIGITAL_MUTE_1    (PCM512x_PAGE_0_BASE +  63)
1009 +#define PCM512x_DIGITAL_MUTE_2    (PCM512x_PAGE_0_BASE +  64)
1010 +#define PCM512x_DIGITAL_MUTE_3    (PCM512x_PAGE_0_BASE +  65)
1011 +#define PCM512x_GPIO_OUTPUT_1     (PCM512x_PAGE_0_BASE +  80)
1012 +#define PCM512x_GPIO_OUTPUT_2     (PCM512x_PAGE_0_BASE +  81)
1013 +#define PCM512x_GPIO_OUTPUT_3     (PCM512x_PAGE_0_BASE +  82)
1014 +#define PCM512x_GPIO_OUTPUT_4     (PCM512x_PAGE_0_BASE +  83)
1015 +#define PCM512x_GPIO_OUTPUT_5     (PCM512x_PAGE_0_BASE +  84)
1016 +#define PCM512x_GPIO_OUTPUT_6     (PCM512x_PAGE_0_BASE +  85)
1017 +#define PCM512x_GPIO_CONTROL_1    (PCM512x_PAGE_0_BASE +  86)
1018 +#define PCM512x_GPIO_CONTROL_2    (PCM512x_PAGE_0_BASE +  87)
1019 +#define PCM512x_OVERFLOW          (PCM512x_PAGE_0_BASE +  90)
1020 +#define PCM512x_RATE_DET_1        (PCM512x_PAGE_0_BASE +  91)
1021 +#define PCM512x_RATE_DET_2        (PCM512x_PAGE_0_BASE +  92)
1022 +#define PCM512x_RATE_DET_3        (PCM512x_PAGE_0_BASE +  93)
1023 +#define PCM512x_RATE_DET_4        (PCM512x_PAGE_0_BASE +  94)
1024 +#define PCM512x_ANALOG_MUTE_DET   (PCM512x_PAGE_0_BASE + 108)
1025 +#define PCM512x_GPIN              (PCM512x_PAGE_0_BASE + 119)
1026 +#define PCM512x_DIGITAL_MUTE_DET  (PCM512x_PAGE_0_BASE + 120)
1027 +
1028 +#define PCM512x_MAX_REGISTER      (PCM512x_PAGE_0_BASE + 120)
1029 +
1030 +/* Page 0, Register 1 - reset */
1031 +#define PCM512x_RSTR (1 << 0)
1032 +#define PCM512x_RSTM (1 << 4)
1033 +
1034 +/* Page 0, Register 2 - power */
1035 +#define PCM512x_RQPD       (1 << 0)
1036 +#define PCM512x_RQPD_SHIFT 0
1037 +#define PCM512x_RQST       (1 << 4)
1038 +#define PCM512x_RQST_SHIFT 4
1039 +
1040 +/* Page 0, Register 3 - mute */
1041 +#define PCM512x_RQMR_SHIFT 0
1042 +#define PCM512x_RQML_SHIFT 4
1043 +
1044 +/* Page 0, Register 4 - PLL */
1045 +#define PCM512x_PLCE       (1 << 0)
1046 +#define PCM512x_RLCE_SHIFT 0
1047 +#define PCM512x_PLCK       (1 << 4)
1048 +#define PCM512x_PLCK_SHIFT 4
1049 +
1050 +/* Page 0, Register 7 - DSP */
1051 +#define PCM512x_SDSL       (1 << 0)
1052 +#define PCM512x_SDSL_SHIFT 0
1053 +#define PCM512x_DEMP       (1 << 4)
1054 +#define PCM512x_DEMP_SHIFT 4
1055 +
1056 +/* Page 0, Register 13 - PLL reference */
1057 +#define PCM512x_SREF (1 << 4)
1058 +
1059 +/* Page 0, Register 37 - Error detection */
1060 +#define PCM512x_IPLK (1 << 0)
1061 +#define PCM512x_DCAS (1 << 1)
1062 +#define PCM512x_IDCM (1 << 2)
1063 +#define PCM512x_IDCH (1 << 3)
1064 +#define PCM512x_IDSK (1 << 4)
1065 +#define PCM512x_IDBK (1 << 5)
1066 +#define PCM512x_IDFS (1 << 6)
1067 +
1068 +/* Page 0, Register 42 - DAC routing */
1069 +#define PCM512x_AUPR_SHIFT 0
1070 +#define PCM512x_AUPL_SHIFT 4
1071 +
1072 +/* Page 0, Register 59 - auto mute */
1073 +#define PCM512x_ATMR_SHIFT 0
1074 +#define PCM512x_ATML_SHIFT 4
1075 +
1076 +/* Page 0, Register 63 - ramp rates */
1077 +#define PCM512x_VNDF_SHIFT 6
1078 +#define PCM512x_VNDS_SHIFT 4
1079 +#define PCM512x_VNUF_SHIFT 2
1080 +#define PCM512x_VNUS_SHIFT 0
1081 +
1082 +/* Page 0, Register 64 - emergency ramp rates */
1083 +#define PCM512x_VEDF_SHIFT 6
1084 +#define PCM512x_VEDS_SHIFT 4
1085 +
1086 +/* Page 0, Register 65 - Digital mute enables */
1087 +#define PCM512x_ACTL_SHIFT 2
1088 +#define PCM512x_AMLE_SHIFT 1
1089 +#define PCM512x_AMLR_SHIFT 0
1090 +
1091 +#endif
1092 -- 
1093 1.9.1
1094