aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/aoa/codecs/tas.c2
-rw-r--r--sound/core/control.c64
-rw-r--r--sound/core/init.c2
-rw-r--r--sound/core/pcm_lib.c14
-rw-r--r--sound/firewire/Kconfig11
-rw-r--r--sound/firewire/Makefile2
-rw-r--r--sound/firewire/isight.c755
-rw-r--r--sound/firewire/iso-resources.c5
-rw-r--r--sound/firewire/packets-buffer.c2
-rw-r--r--sound/i2c/other/Makefile2
-rw-r--r--sound/i2c/other/tea575x-tuner.c153
-rw-r--r--sound/oss/Kconfig4
-rw-r--r--sound/oss/Makefile1
-rw-r--r--sound/oss/ac97_codec.c1203
-rw-r--r--sound/oss/au1550_ac97.c2147
-rw-r--r--sound/pci/Kconfig27
-rw-r--r--sound/pci/Makefile1
-rw-r--r--sound/pci/asihpi/asihpi.c328
-rw-r--r--sound/pci/asihpi/hpi6000.c39
-rw-r--r--sound/pci/asihpi/hpi6205.c95
-rw-r--r--sound/pci/asihpi/hpi_internal.h19
-rw-r--r--sound/pci/asihpi/hpicmn.c10
-rw-r--r--sound/pci/asihpi/hpicmn.h2
-rw-r--r--sound/pci/asihpi/hpifunc.c27
-rw-r--r--sound/pci/asihpi/hpimsgx.c31
-rw-r--r--sound/pci/asihpi/hpioctl.c63
-rw-r--r--sound/pci/au88x0/au8810.h2
-rw-r--r--sound/pci/au88x0/au8820.h2
-rw-r--r--sound/pci/au88x0/au8830.h2
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c13
-rw-r--r--sound/pci/emu10k1/emufx.c5
-rw-r--r--sound/pci/emu10k1/emumixer.c10
-rw-r--r--sound/pci/es1968.c78
-rw-r--r--sound/pci/fm801.c371
-rw-r--r--sound/pci/intel8x0m.c4
-rw-r--r--sound/pci/lola/Makefile4
-rw-r--r--sound/pci/lola/lola.c791
-rw-r--r--sound/pci/lola/lola.h527
-rw-r--r--sound/pci/lola/lola_clock.c323
-rw-r--r--sound/pci/lola/lola_mixer.c839
-rw-r--r--sound/pci/lola/lola_pcm.c706
-rw-r--r--sound/pci/lola/lola_proc.c222
-rw-r--r--sound/ppc/tumbler.c2
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c2
-rw-r--r--sound/soc/au1x/db1200.c2
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c13
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c166
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c42
-rw-r--r--sound/soc/blackfin/bf5xx-ad193x.c56
-rw-r--r--sound/soc/blackfin/bf5xx-ad1980.c45
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c42
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c23
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c172
-rw-r--r--sound/soc/blackfin/bf5xx-sport.c159
-rw-r--r--sound/soc/blackfin/bf5xx-sport.h16
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c42
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.c23
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.c110
-rw-r--r--sound/soc/codecs/88pm860x-codec.c2
-rw-r--r--sound/soc/codecs/Kconfig20
-rw-r--r--sound/soc/codecs/Makefile10
-rw-r--r--sound/soc/codecs/ad193x.c23
-rw-r--r--sound/soc/codecs/ad1980.c2
-rw-r--r--sound/soc/codecs/ad73311.c2
-rw-r--r--sound/soc/codecs/ak4535.c19
-rw-r--r--sound/soc/codecs/ak4641.c664
-rw-r--r--sound/soc/codecs/ak4641.h47
-rw-r--r--sound/soc/codecs/ak4671.c18
-rw-r--r--sound/soc/codecs/cx20442.c18
-rw-r--r--sound/soc/codecs/dmic.c26
-rw-r--r--sound/soc/codecs/jz4740.c18
-rw-r--r--sound/soc/codecs/max98088.c87
-rw-r--r--sound/soc/codecs/max98088.h13
-rw-r--r--sound/soc/codecs/max98095.c2396
-rw-r--r--sound/soc/codecs/max98095.h299
-rw-r--r--sound/soc/codecs/sn95031.c17
-rw-r--r--sound/soc/codecs/spdif_transciever.c8
-rw-r--r--sound/soc/codecs/ssm2602.c472
-rw-r--r--sound/soc/codecs/ssm2602.h6
-rw-r--r--sound/soc/codecs/tlv320aic23.c19
-rw-r--r--sound/soc/codecs/tlv320aic3x.c3
-rw-r--r--sound/soc/codecs/tlv320dac33.c17
-rw-r--r--sound/soc/codecs/tlv320dac33.h2
-rw-r--r--sound/soc/codecs/tpa6130a2.c4
-rw-r--r--sound/soc/codecs/tpa6130a2.h2
-rw-r--r--sound/soc/codecs/twl6040.c6
-rw-r--r--sound/soc/codecs/uda134x.c2
-rw-r--r--sound/soc/codecs/wm1250-ev1.c108
-rw-r--r--sound/soc/codecs/wm8711.c18
-rw-r--r--sound/soc/codecs/wm8728.c18
-rw-r--r--sound/soc/codecs/wm8731.c22
-rw-r--r--sound/soc/codecs/wm8903.c46
-rw-r--r--sound/soc/codecs/wm8915.c2931
-rw-r--r--sound/soc/codecs/wm8915.h3717
-rw-r--r--sound/soc/codecs/wm8958-dsp2.c1051
-rw-r--r--sound/soc/codecs/wm8962.c63
-rw-r--r--sound/soc/codecs/wm8993.c3
-rw-r--r--sound/soc/codecs/wm8994.c395
-rw-r--r--sound/soc/codecs/wm8994.h97
-rw-r--r--sound/soc/codecs/wm8995.c4
-rw-r--r--sound/soc/codecs/wm9705.c18
-rw-r--r--sound/soc/codecs/wm9712.c18
-rw-r--r--sound/soc/codecs/wm9713.c19
-rw-r--r--sound/soc/codecs/wm_hubs.c24
-rw-r--r--sound/soc/davinci/davinci-mcasp.c21
-rw-r--r--sound/soc/imx/imx-ssi.c6
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c2
-rw-r--r--sound/soc/jz4740/qi_lb60.c46
-rw-r--r--sound/soc/mid-x86/sst_platform.c10
-rw-r--r--sound/soc/omap/omap-mcbsp.c6
-rw-r--r--sound/soc/omap/omap-mcbsp.h2
-rw-r--r--sound/soc/omap/omap-pcm.c7
-rw-r--r--sound/soc/omap/omap-pcm.h2
-rw-r--r--sound/soc/omap/rx51.c2
-rw-r--r--sound/soc/pxa/Kconfig9
-rw-r--r--sound/soc/pxa/Makefile2
-rw-r--r--sound/soc/pxa/corgi.c2
-rw-r--r--sound/soc/pxa/hx4700.c255
-rw-r--r--sound/soc/pxa/poodle.c2
-rw-r--r--sound/soc/pxa/spitz.c41
-rw-r--r--sound/soc/samsung/Kconfig15
-rw-r--r--sound/soc/samsung/Makefile4
-rw-r--r--sound/soc/samsung/goni_wm8994.c9
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c1
-rw-r--r--sound/soc/samsung/smdk_wm8580pcm.c206
-rw-r--r--sound/soc/samsung/speyside.c332
-rw-r--r--sound/soc/sh/fsi.c188
-rw-r--r--sound/soc/soc-cache.c612
-rw-r--r--sound/soc/soc-core.c193
-rw-r--r--sound/soc/soc-dapm.c611
-rw-r--r--sound/soc/soc-jack.c2
-rw-r--r--sound/soc/soc-utils.c53
-rw-r--r--sound/soc/tegra/Kconfig38
-rw-r--r--sound/soc/tegra/Makefile14
-rw-r--r--sound/soc/tegra/harmony.c394
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c9
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.h2
-rw-r--r--sound/soc/tegra/tegra_i2s.c2
-rw-r--r--sound/soc/tegra/tegra_wm8903.c475
-rw-r--r--sound/soc/tegra/trimslice.c228
-rw-r--r--sound/usb/6fire/control.c105
-rw-r--r--sound/usb/6fire/control.h17
-rw-r--r--sound/usb/6fire/firmware.c73
-rw-r--r--sound/usb/6fire/pcm.c97
-rw-r--r--sound/usb/Kconfig10
-rw-r--r--sound/usb/clock.c11
-rw-r--r--sound/usb/debug.h2
-rw-r--r--sound/usb/format.c1
-rw-r--r--sound/usb/mixer.c10
-rw-r--r--sound/usb/mixer_quirks.c12
-rw-r--r--sound/usb/quirks-table.h47
-rw-r--r--sound/usb/quirks.c1
152 files changed, 20055 insertions, 6731 deletions
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index 58804c7acfcf..fd2188c3df2b 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -170,7 +170,7 @@ static void tas_set_volume(struct tas *tas)
170 /* analysing the volume and mixer tables shows 170 /* analysing the volume and mixer tables shows
171 * that they are similar enough when we shift 171 * that they are similar enough when we shift
172 * the mixer table down by 4 bits. The error 172 * the mixer table down by 4 bits. The error
173 * is minuscule, in just one item the error 173 * is miniscule, in just one item the error
174 * is 1, at a value of 0x07f17b (mixer table 174 * is 1, at a value of 0x07f17b (mixer table
175 * value is 0x07f17a) */ 175 * value is 0x07f17a) */
176 tmp = tas_gaintable[left]; 176 tmp = tas_gaintable[left];
diff --git a/sound/core/control.c b/sound/core/control.c
index a08ad57c49b6..5d98194bcad5 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -366,6 +366,70 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
366EXPORT_SYMBOL(snd_ctl_add); 366EXPORT_SYMBOL(snd_ctl_add);
367 367
368/** 368/**
369 * snd_ctl_replace - replace the control instance of the card
370 * @card: the card instance
371 * @kcontrol: the control instance to replace
372 * @add_on_replace: add the control if not already added
373 *
374 * Replaces the given control. If the given control does not exist
375 * and the add_on_replace flag is set, the control is added. If the
376 * control exists, it is destroyed first.
377 *
378 * Returns zero if successful, or a negative error code on failure.
379 *
380 * It frees automatically the control which cannot be added or replaced.
381 */
382int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol,
383 bool add_on_replace)
384{
385 struct snd_ctl_elem_id id;
386 unsigned int idx;
387 struct snd_kcontrol *old;
388 int ret;
389
390 if (!kcontrol)
391 return -EINVAL;
392 if (snd_BUG_ON(!card || !kcontrol->info)) {
393 ret = -EINVAL;
394 goto error;
395 }
396 id = kcontrol->id;
397 down_write(&card->controls_rwsem);
398 old = snd_ctl_find_id(card, &id);
399 if (!old) {
400 if (add_on_replace)
401 goto add;
402 up_write(&card->controls_rwsem);
403 ret = -EINVAL;
404 goto error;
405 }
406 ret = snd_ctl_remove(card, old);
407 if (ret < 0) {
408 up_write(&card->controls_rwsem);
409 goto error;
410 }
411add:
412 if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
413 up_write(&card->controls_rwsem);
414 ret = -ENOMEM;
415 goto error;
416 }
417 list_add_tail(&kcontrol->list, &card->controls);
418 card->controls_count += kcontrol->count;
419 kcontrol->id.numid = card->last_numid + 1;
420 card->last_numid += kcontrol->count;
421 up_write(&card->controls_rwsem);
422 for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
423 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
424 return 0;
425
426error:
427 snd_ctl_free_one(kcontrol);
428 return ret;
429}
430EXPORT_SYMBOL(snd_ctl_replace);
431
432/**
369 * snd_ctl_remove - remove the control from the card and release it 433 * snd_ctl_remove - remove the control from the card and release it
370 * @card: the card instance 434 * @card: the card instance
371 * @kcontrol: the control instance to remove 435 * @kcontrol: the control instance to remove
diff --git a/sound/core/init.c b/sound/core/init.c
index a0080aa45ae9..30ecad41403c 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -514,7 +514,7 @@ static void snd_card_set_id_no_lock(struct snd_card *card, const char *nid)
514 id = card->id; 514 id = card->id;
515 515
516 if (*id == '\0') 516 if (*id == '\0')
517 strcpy(id, "default"); 517 strcpy(id, "Default");
518 518
519 while (1) { 519 while (1) {
520 if (loops-- == 0) { 520 if (loops-- == 0) {
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 64449cb8f873..abfeff1611ce 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -189,6 +189,7 @@ static void xrun(struct snd_pcm_substream *substream)
189#define XRUN_LOG_CNT 10 189#define XRUN_LOG_CNT 10
190 190
191struct hwptr_log_entry { 191struct hwptr_log_entry {
192 unsigned int in_interrupt;
192 unsigned long jiffies; 193 unsigned long jiffies;
193 snd_pcm_uframes_t pos; 194 snd_pcm_uframes_t pos;
194 snd_pcm_uframes_t period_size; 195 snd_pcm_uframes_t period_size;
@@ -204,7 +205,7 @@ struct snd_pcm_hwptr_log {
204}; 205};
205 206
206static void xrun_log(struct snd_pcm_substream *substream, 207static void xrun_log(struct snd_pcm_substream *substream,
207 snd_pcm_uframes_t pos) 208 snd_pcm_uframes_t pos, int in_interrupt)
208{ 209{
209 struct snd_pcm_runtime *runtime = substream->runtime; 210 struct snd_pcm_runtime *runtime = substream->runtime;
210 struct snd_pcm_hwptr_log *log = runtime->hwptr_log; 211 struct snd_pcm_hwptr_log *log = runtime->hwptr_log;
@@ -220,6 +221,7 @@ static void xrun_log(struct snd_pcm_substream *substream,
220 return; 221 return;
221 } 222 }
222 entry = &log->entries[log->idx]; 223 entry = &log->entries[log->idx];
224 entry->in_interrupt = in_interrupt;
223 entry->jiffies = jiffies; 225 entry->jiffies = jiffies;
224 entry->pos = pos; 226 entry->pos = pos;
225 entry->period_size = runtime->period_size; 227 entry->period_size = runtime->period_size;
@@ -246,9 +248,11 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
246 entry = &log->entries[idx]; 248 entry = &log->entries[idx];
247 if (entry->period_size == 0) 249 if (entry->period_size == 0)
248 break; 250 break;
249 snd_printd("hwptr log: %s: j=%lu, pos=%ld/%ld/%ld, " 251 snd_printd("hwptr log: %s: %sj=%lu, pos=%ld/%ld/%ld, "
250 "hwptr=%ld/%ld\n", 252 "hwptr=%ld/%ld\n",
251 name, entry->jiffies, (unsigned long)entry->pos, 253 name, entry->in_interrupt ? "[Q] " : "",
254 entry->jiffies,
255 (unsigned long)entry->pos,
252 (unsigned long)entry->period_size, 256 (unsigned long)entry->period_size,
253 (unsigned long)entry->buffer_size, 257 (unsigned long)entry->buffer_size,
254 (unsigned long)entry->old_hw_ptr, 258 (unsigned long)entry->old_hw_ptr,
@@ -262,7 +266,7 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
262#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */ 266#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */
263 267
264#define hw_ptr_error(substream, fmt, args...) do { } while (0) 268#define hw_ptr_error(substream, fmt, args...) do { } while (0)
265#define xrun_log(substream, pos) do { } while (0) 269#define xrun_log(substream, pos, in_interrupt) do { } while (0)
266#define xrun_log_show(substream) do { } while (0) 270#define xrun_log_show(substream) do { } while (0)
267 271
268#endif 272#endif
@@ -326,7 +330,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
326 } 330 }
327 pos -= pos % runtime->min_align; 331 pos -= pos % runtime->min_align;
328 if (xrun_debug(substream, XRUN_DEBUG_LOG)) 332 if (xrun_debug(substream, XRUN_DEBUG_LOG))
329 xrun_log(substream, pos); 333 xrun_log(substream, pos, in_interrupt);
330 hw_base = runtime->hw_ptr_base; 334 hw_base = runtime->hw_ptr_base;
331 new_hw_ptr = hw_base + pos; 335 new_hw_ptr = hw_base + pos;
332 if (in_interrupt) { 336 if (in_interrupt) {
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
index e486f48660fb..26071489970b 100644
--- a/sound/firewire/Kconfig
+++ b/sound/firewire/Kconfig
@@ -22,4 +22,15 @@ config SND_FIREWIRE_SPEAKERS
22 To compile this driver as a module, choose M here: the module 22 To compile this driver as a module, choose M here: the module
23 will be called snd-firewire-speakers. 23 will be called snd-firewire-speakers.
24 24
25config SND_ISIGHT
26 tristate "Apple iSight microphone"
27 select SND_PCM
28 select SND_FIREWIRE_LIB
29 help
30 Say Y here to include support for the front and rear microphones
31 of the Apple iSight web camera.
32
33 To compile this driver as a module, choose M here: the module
34 will be called snd-isight.
35
25endif # SND_FIREWIRE 36endif # SND_FIREWIRE
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile
index e5b1634d9ad4..d71ed8935f76 100644
--- a/sound/firewire/Makefile
+++ b/sound/firewire/Makefile
@@ -1,6 +1,8 @@
1snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \ 1snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \
2 fcp.o cmp.o amdtp.o 2 fcp.o cmp.o amdtp.o
3snd-firewire-speakers-objs := speakers.o 3snd-firewire-speakers-objs := speakers.o
4snd-isight-objs := isight.o
4 5
5obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o 6obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o
6obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o 7obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o
8obj-$(CONFIG_SND_ISIGHT) += snd-isight.o
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c
new file mode 100644
index 000000000000..86ee16ca365e
--- /dev/null
+++ b/sound/firewire/isight.c
@@ -0,0 +1,755 @@
1/*
2 * Apple iSight audio driver
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
8#include <asm/byteorder.h>
9#include <linux/delay.h>
10#include <linux/device.h>
11#include <linux/firewire.h>
12#include <linux/firewire-constants.h>
13#include <linux/module.h>
14#include <linux/mod_devicetable.h>
15#include <linux/mutex.h>
16#include <linux/string.h>
17#include <sound/control.h>
18#include <sound/core.h>
19#include <sound/initval.h>
20#include <sound/pcm.h>
21#include <sound/tlv.h>
22#include "lib.h"
23#include "iso-resources.h"
24#include "packets-buffer.h"
25
26#define OUI_APPLE 0x000a27
27#define MODEL_APPLE_ISIGHT 0x000008
28#define SW_ISIGHT_AUDIO 0x000010
29
30#define REG_AUDIO_ENABLE 0x000
31#define AUDIO_ENABLE 0x80000000
32#define REG_DEF_AUDIO_GAIN 0x204
33#define REG_GAIN_RAW_START 0x210
34#define REG_GAIN_RAW_END 0x214
35#define REG_GAIN_DB_START 0x218
36#define REG_GAIN_DB_END 0x21c
37#define REG_SAMPLE_RATE_INQUIRY 0x280
38#define REG_ISO_TX_CONFIG 0x300
39#define SPEED_SHIFT 16
40#define REG_SAMPLE_RATE 0x400
41#define RATE_48000 0x80000000
42#define REG_GAIN 0x500
43#define REG_MUTE 0x504
44
45#define MAX_FRAMES_PER_PACKET 475
46
47#define QUEUE_LENGTH 20
48
49struct isight {
50 struct snd_card *card;
51 struct fw_unit *unit;
52 struct fw_device *device;
53 u64 audio_base;
54 struct fw_address_handler iris_handler;
55 struct snd_pcm_substream *pcm;
56 struct mutex mutex;
57 struct iso_packets_buffer buffer;
58 struct fw_iso_resources resources;
59 struct fw_iso_context *context;
60 bool pcm_active;
61 bool pcm_running;
62 bool first_packet;
63 int packet_index;
64 u32 total_samples;
65 unsigned int buffer_pointer;
66 unsigned int period_counter;
67 s32 gain_min, gain_max;
68 unsigned int gain_tlv[4];
69};
70
71struct audio_payload {
72 __be32 sample_count;
73 __be32 signature;
74 __be32 sample_total;
75 __be32 reserved;
76 __be16 samples[2 * MAX_FRAMES_PER_PACKET];
77};
78
79MODULE_DESCRIPTION("iSight audio driver");
80MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
81MODULE_LICENSE("GPL v2");
82
83static struct fw_iso_packet audio_packet = {
84 .payload_length = sizeof(struct audio_payload),
85 .interrupt = 1,
86 .header_length = 4,
87};
88
89static void isight_update_pointers(struct isight *isight, unsigned int count)
90{
91 struct snd_pcm_runtime *runtime = isight->pcm->runtime;
92 unsigned int ptr;
93
94 smp_wmb(); /* update buffer data before buffer pointer */
95
96 ptr = isight->buffer_pointer;
97 ptr += count;
98 if (ptr >= runtime->buffer_size)
99 ptr -= runtime->buffer_size;
100 ACCESS_ONCE(isight->buffer_pointer) = ptr;
101
102 isight->period_counter += count;
103 if (isight->period_counter >= runtime->period_size) {
104 isight->period_counter -= runtime->period_size;
105 snd_pcm_period_elapsed(isight->pcm);
106 }
107}
108
109static void isight_samples(struct isight *isight,
110 const __be16 *samples, unsigned int count)
111{
112 struct snd_pcm_runtime *runtime;
113 unsigned int count1;
114
115 if (!ACCESS_ONCE(isight->pcm_running))
116 return;
117
118 runtime = isight->pcm->runtime;
119 if (isight->buffer_pointer + count <= runtime->buffer_size) {
120 memcpy(runtime->dma_area + isight->buffer_pointer * 4,
121 samples, count * 4);
122 } else {
123 count1 = runtime->buffer_size - isight->buffer_pointer;
124 memcpy(runtime->dma_area + isight->buffer_pointer * 4,
125 samples, count1 * 4);
126 samples += count1 * 2;
127 memcpy(runtime->dma_area, samples, (count - count1) * 4);
128 }
129
130 isight_update_pointers(isight, count);
131}
132
133static void isight_pcm_abort(struct isight *isight)
134{
135 unsigned long flags;
136
137 if (ACCESS_ONCE(isight->pcm_active)) {
138 snd_pcm_stream_lock_irqsave(isight->pcm, flags);
139 if (snd_pcm_running(isight->pcm))
140 snd_pcm_stop(isight->pcm, SNDRV_PCM_STATE_XRUN);
141 snd_pcm_stream_unlock_irqrestore(isight->pcm, flags);
142 }
143}
144
145static void isight_dropped_samples(struct isight *isight, unsigned int total)
146{
147 struct snd_pcm_runtime *runtime;
148 u32 dropped;
149 unsigned int count1;
150
151 if (!ACCESS_ONCE(isight->pcm_running))
152 return;
153
154 runtime = isight->pcm->runtime;
155 dropped = total - isight->total_samples;
156 if (dropped < runtime->buffer_size) {
157 if (isight->buffer_pointer + dropped <= runtime->buffer_size) {
158 memset(runtime->dma_area + isight->buffer_pointer * 4,
159 0, dropped * 4);
160 } else {
161 count1 = runtime->buffer_size - isight->buffer_pointer;
162 memset(runtime->dma_area + isight->buffer_pointer * 4,
163 0, count1 * 4);
164 memset(runtime->dma_area, 0, (dropped - count1) * 4);
165 }
166 isight_update_pointers(isight, dropped);
167 } else {
168 isight_pcm_abort(isight);
169 }
170}
171
172static void isight_packet(struct fw_iso_context *context, u32 cycle,
173 size_t header_length, void *header, void *data)
174{
175 struct isight *isight = data;
176 const struct audio_payload *payload;
177 unsigned int index, length, count, total;
178 int err;
179
180 if (isight->packet_index < 0)
181 return;
182 index = isight->packet_index;
183 payload = isight->buffer.packets[index].buffer;
184 length = be32_to_cpup(header) >> 16;
185
186 if (likely(length >= 16 &&
187 payload->signature == cpu_to_be32(0x73676874/*"sght"*/))) {
188 count = be32_to_cpu(payload->sample_count);
189 if (likely(count <= (length - 16) / 4)) {
190 total = be32_to_cpu(payload->sample_total);
191 if (unlikely(total != isight->total_samples)) {
192 if (!isight->first_packet)
193 isight_dropped_samples(isight, total);
194 isight->first_packet = false;
195 isight->total_samples = total;
196 }
197
198 isight_samples(isight, payload->samples, count);
199 isight->total_samples += count;
200 }
201 }
202
203 err = fw_iso_context_queue(isight->context, &audio_packet,
204 &isight->buffer.iso_buffer,
205 isight->buffer.packets[index].offset);
206 if (err < 0) {
207 dev_err(&isight->unit->device, "queueing error: %d\n", err);
208 isight_pcm_abort(isight);
209 isight->packet_index = -1;
210 return;
211 }
212
213 if (++index >= QUEUE_LENGTH)
214 index = 0;
215 isight->packet_index = index;
216}
217
218static int isight_connect(struct isight *isight)
219{
220 int ch, err, rcode, errors = 0;
221 __be32 value;
222
223retry_after_bus_reset:
224 ch = fw_iso_resources_allocate(&isight->resources,
225 sizeof(struct audio_payload),
226 isight->device->max_speed);
227 if (ch < 0) {
228 err = ch;
229 goto error;
230 }
231
232 value = cpu_to_be32(ch | (isight->device->max_speed << SPEED_SHIFT));
233 for (;;) {
234 rcode = fw_run_transaction(
235 isight->device->card,
236 TCODE_WRITE_QUADLET_REQUEST,
237 isight->device->node_id,
238 isight->resources.generation,
239 isight->device->max_speed,
240 isight->audio_base + REG_ISO_TX_CONFIG,
241 &value, 4);
242 if (rcode == RCODE_COMPLETE) {
243 return 0;
244 } else if (rcode == RCODE_GENERATION) {
245 fw_iso_resources_free(&isight->resources);
246 goto retry_after_bus_reset;
247 } else if (rcode_is_permanent_error(rcode) || ++errors >= 3) {
248 err = -EIO;
249 goto err_resources;
250 }
251 msleep(5);
252 }
253
254err_resources:
255 fw_iso_resources_free(&isight->resources);
256error:
257 return err;
258}
259
260static int isight_open(struct snd_pcm_substream *substream)
261{
262 static const struct snd_pcm_hardware hardware = {
263 .info = SNDRV_PCM_INFO_MMAP |
264 SNDRV_PCM_INFO_MMAP_VALID |
265 SNDRV_PCM_INFO_BATCH |
266 SNDRV_PCM_INFO_INTERLEAVED |
267 SNDRV_PCM_INFO_BLOCK_TRANSFER,
268 .formats = SNDRV_PCM_FMTBIT_S16_BE,
269 .rates = SNDRV_PCM_RATE_48000,
270 .rate_min = 48000,
271 .rate_max = 48000,
272 .channels_min = 2,
273 .channels_max = 2,
274 .buffer_bytes_max = 4 * 1024 * 1024,
275 .period_bytes_min = MAX_FRAMES_PER_PACKET * 4,
276 .period_bytes_max = 1024 * 1024,
277 .periods_min = 2,
278 .periods_max = UINT_MAX,
279 };
280 struct isight *isight = substream->private_data;
281
282 substream->runtime->hw = hardware;
283
284 return iso_packets_buffer_init(&isight->buffer, isight->unit,
285 QUEUE_LENGTH,
286 sizeof(struct audio_payload),
287 DMA_FROM_DEVICE);
288}
289
290static int isight_close(struct snd_pcm_substream *substream)
291{
292 struct isight *isight = substream->private_data;
293
294 iso_packets_buffer_destroy(&isight->buffer, isight->unit);
295
296 return 0;
297}
298
299static int isight_hw_params(struct snd_pcm_substream *substream,
300 struct snd_pcm_hw_params *hw_params)
301{
302 struct isight *isight = substream->private_data;
303 int err;
304
305 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
306 params_buffer_bytes(hw_params));
307 if (err < 0)
308 return err;
309
310 ACCESS_ONCE(isight->pcm_active) = true;
311
312 return 0;
313}
314
315static int reg_read(struct isight *isight, int offset, __be32 *value)
316{
317 return snd_fw_transaction(isight->unit, TCODE_READ_QUADLET_REQUEST,
318 isight->audio_base + offset, value, 4);
319}
320
321static int reg_write(struct isight *isight, int offset, __be32 value)
322{
323 return snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST,
324 isight->audio_base + offset, &value, 4);
325}
326
327static void isight_stop_streaming(struct isight *isight)
328{
329 if (!isight->context)
330 return;
331
332 fw_iso_context_stop(isight->context);
333 fw_iso_context_destroy(isight->context);
334 isight->context = NULL;
335 fw_iso_resources_free(&isight->resources);
336 reg_write(isight, REG_AUDIO_ENABLE, 0);
337}
338
339static int isight_hw_free(struct snd_pcm_substream *substream)
340{
341 struct isight *isight = substream->private_data;
342
343 ACCESS_ONCE(isight->pcm_active) = false;
344
345 mutex_lock(&isight->mutex);
346 isight_stop_streaming(isight);
347 mutex_unlock(&isight->mutex);
348
349 return snd_pcm_lib_free_vmalloc_buffer(substream);
350}
351
352static int isight_start_streaming(struct isight *isight)
353{
354 unsigned int i;
355 int err;
356
357 if (isight->context) {
358 if (isight->packet_index < 0)
359 isight_stop_streaming(isight);
360 else
361 return 0;
362 }
363
364 err = reg_write(isight, REG_SAMPLE_RATE, cpu_to_be32(RATE_48000));
365 if (err < 0)
366 goto error;
367
368 err = isight_connect(isight);
369 if (err < 0)
370 goto error;
371
372 err = reg_write(isight, REG_AUDIO_ENABLE, cpu_to_be32(AUDIO_ENABLE));
373 if (err < 0)
374 goto err_resources;
375
376 isight->context = fw_iso_context_create(isight->device->card,
377 FW_ISO_CONTEXT_RECEIVE,
378 isight->resources.channel,
379 isight->device->max_speed,
380 4, isight_packet, isight);
381 if (IS_ERR(isight->context)) {
382 err = PTR_ERR(isight->context);
383 isight->context = NULL;
384 goto err_resources;
385 }
386
387 for (i = 0; i < QUEUE_LENGTH; ++i) {
388 err = fw_iso_context_queue(isight->context, &audio_packet,
389 &isight->buffer.iso_buffer,
390 isight->buffer.packets[i].offset);
391 if (err < 0)
392 goto err_context;
393 }
394
395 isight->first_packet = true;
396 isight->packet_index = 0;
397
398 err = fw_iso_context_start(isight->context, -1, 0,
399 FW_ISO_CONTEXT_MATCH_ALL_TAGS/*?*/);
400 if (err < 0)
401 goto err_context;
402
403 return 0;
404
405err_context:
406 fw_iso_context_destroy(isight->context);
407 isight->context = NULL;
408err_resources:
409 fw_iso_resources_free(&isight->resources);
410 reg_write(isight, REG_AUDIO_ENABLE, 0);
411error:
412 return err;
413}
414
415static int isight_prepare(struct snd_pcm_substream *substream)
416{
417 struct isight *isight = substream->private_data;
418 int err;
419
420 isight->buffer_pointer = 0;
421 isight->period_counter = 0;
422
423 mutex_lock(&isight->mutex);
424 err = isight_start_streaming(isight);
425 mutex_unlock(&isight->mutex);
426
427 return err;
428}
429
430static int isight_trigger(struct snd_pcm_substream *substream, int cmd)
431{
432 struct isight *isight = substream->private_data;
433
434 switch (cmd) {
435 case SNDRV_PCM_TRIGGER_START:
436 ACCESS_ONCE(isight->pcm_running) = true;
437 break;
438 case SNDRV_PCM_TRIGGER_STOP:
439 ACCESS_ONCE(isight->pcm_running) = false;
440 break;
441 default:
442 return -EINVAL;
443 }
444 return 0;
445}
446
447static snd_pcm_uframes_t isight_pointer(struct snd_pcm_substream *substream)
448{
449 struct isight *isight = substream->private_data;
450
451 return ACCESS_ONCE(isight->buffer_pointer);
452}
453
454static int isight_create_pcm(struct isight *isight)
455{
456 static struct snd_pcm_ops ops = {
457 .open = isight_open,
458 .close = isight_close,
459 .ioctl = snd_pcm_lib_ioctl,
460 .hw_params = isight_hw_params,
461 .hw_free = isight_hw_free,
462 .prepare = isight_prepare,
463 .trigger = isight_trigger,
464 .pointer = isight_pointer,
465 .page = snd_pcm_lib_get_vmalloc_page,
466 .mmap = snd_pcm_lib_mmap_vmalloc,
467 };
468 struct snd_pcm *pcm;
469 int err;
470
471 err = snd_pcm_new(isight->card, "iSight", 0, 0, 1, &pcm);
472 if (err < 0)
473 return err;
474 pcm->private_data = isight;
475 strcpy(pcm->name, "iSight");
476 isight->pcm = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
477 isight->pcm->ops = &ops;
478
479 return 0;
480}
481
482static int isight_gain_info(struct snd_kcontrol *ctl,
483 struct snd_ctl_elem_info *info)
484{
485 struct isight *isight = ctl->private_data;
486
487 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
488 info->count = 1;
489 info->value.integer.min = isight->gain_min;
490 info->value.integer.max = isight->gain_max;
491
492 return 0;
493}
494
495static int isight_gain_get(struct snd_kcontrol *ctl,
496 struct snd_ctl_elem_value *value)
497{
498 struct isight *isight = ctl->private_data;
499 __be32 gain;
500 int err;
501
502 err = reg_read(isight, REG_GAIN, &gain);
503 if (err < 0)
504 return err;
505
506 value->value.integer.value[0] = (s32)be32_to_cpu(gain);
507
508 return 0;
509}
510
511static int isight_gain_put(struct snd_kcontrol *ctl,
512 struct snd_ctl_elem_value *value)
513{
514 struct isight *isight = ctl->private_data;
515
516 if (value->value.integer.value[0] < isight->gain_min ||
517 value->value.integer.value[0] > isight->gain_max)
518 return -EINVAL;
519
520 return reg_write(isight, REG_GAIN,
521 cpu_to_be32(value->value.integer.value[0]));
522}
523
524static int isight_mute_get(struct snd_kcontrol *ctl,
525 struct snd_ctl_elem_value *value)
526{
527 struct isight *isight = ctl->private_data;
528 __be32 mute;
529 int err;
530
531 err = reg_read(isight, REG_MUTE, &mute);
532 if (err < 0)
533 return err;
534
535 value->value.integer.value[0] = !mute;
536
537 return 0;
538}
539
540static int isight_mute_put(struct snd_kcontrol *ctl,
541 struct snd_ctl_elem_value *value)
542{
543 struct isight *isight = ctl->private_data;
544
545 return reg_write(isight, REG_MUTE,
546 (__force __be32)!value->value.integer.value[0]);
547}
548
549static int isight_create_mixer(struct isight *isight)
550{
551 static const struct snd_kcontrol_new gain_control = {
552 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
553 .name = "Mic Capture Volume",
554 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
555 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
556 .info = isight_gain_info,
557 .get = isight_gain_get,
558 .put = isight_gain_put,
559 };
560 static const struct snd_kcontrol_new mute_control = {
561 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
562 .name = "Mic Capture Switch",
563 .info = snd_ctl_boolean_mono_info,
564 .get = isight_mute_get,
565 .put = isight_mute_put,
566 };
567 __be32 value;
568 struct snd_kcontrol *ctl;
569 int err;
570
571 err = reg_read(isight, REG_GAIN_RAW_START, &value);
572 if (err < 0)
573 return err;
574 isight->gain_min = be32_to_cpu(value);
575
576 err = reg_read(isight, REG_GAIN_RAW_END, &value);
577 if (err < 0)
578 return err;
579 isight->gain_max = be32_to_cpu(value);
580
581 isight->gain_tlv[0] = SNDRV_CTL_TLVT_DB_MINMAX;
582 isight->gain_tlv[1] = 2 * sizeof(unsigned int);
583
584 err = reg_read(isight, REG_GAIN_DB_START, &value);
585 if (err < 0)
586 return err;
587 isight->gain_tlv[2] = (s32)be32_to_cpu(value) * 100;
588
589 err = reg_read(isight, REG_GAIN_DB_END, &value);
590 if (err < 0)
591 return err;
592 isight->gain_tlv[3] = (s32)be32_to_cpu(value) * 100;
593
594 ctl = snd_ctl_new1(&gain_control, isight);
595 if (ctl)
596 ctl->tlv.p = isight->gain_tlv;
597 err = snd_ctl_add(isight->card, ctl);
598 if (err < 0)
599 return err;
600
601 err = snd_ctl_add(isight->card, snd_ctl_new1(&mute_control, isight));
602 if (err < 0)
603 return err;
604
605 return 0;
606}
607
608static void isight_card_free(struct snd_card *card)
609{
610 struct isight *isight = card->private_data;
611
612 fw_iso_resources_destroy(&isight->resources);
613 fw_unit_put(isight->unit);
614 fw_device_put(isight->device);
615 mutex_destroy(&isight->mutex);
616}
617
618static u64 get_unit_base(struct fw_unit *unit)
619{
620 struct fw_csr_iterator i;
621 int key, value;
622
623 fw_csr_iterator_init(&i, unit->directory);
624 while (fw_csr_iterator_next(&i, &key, &value))
625 if (key == CSR_OFFSET)
626 return CSR_REGISTER_BASE + value * 4;
627 return 0;
628}
629
630static int isight_probe(struct device *unit_dev)
631{
632 struct fw_unit *unit = fw_unit(unit_dev);
633 struct fw_device *fw_dev = fw_parent_device(unit);
634 struct snd_card *card;
635 struct isight *isight;
636 int err;
637
638 err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*isight), &card);
639 if (err < 0)
640 return err;
641 snd_card_set_dev(card, unit_dev);
642
643 isight = card->private_data;
644 isight->card = card;
645 mutex_init(&isight->mutex);
646 isight->unit = fw_unit_get(unit);
647 isight->device = fw_device_get(fw_dev);
648 isight->audio_base = get_unit_base(unit);
649 if (!isight->audio_base) {
650 dev_err(&unit->device, "audio unit base not found\n");
651 err = -ENXIO;
652 goto err_unit;
653 }
654 fw_iso_resources_init(&isight->resources, unit);
655
656 card->private_free = isight_card_free;
657
658 strcpy(card->driver, "iSight");
659 strcpy(card->shortname, "Apple iSight");
660 snprintf(card->longname, sizeof(card->longname),
661 "Apple iSight (GUID %08x%08x) at %s, S%d",
662 fw_dev->config_rom[3], fw_dev->config_rom[4],
663 dev_name(&unit->device), 100 << fw_dev->max_speed);
664 strcpy(card->mixername, "iSight");
665
666 err = isight_create_pcm(isight);
667 if (err < 0)
668 goto error;
669
670 err = isight_create_mixer(isight);
671 if (err < 0)
672 goto error;
673
674 err = snd_card_register(card);
675 if (err < 0)
676 goto error;
677
678 dev_set_drvdata(unit_dev, isight);
679
680 return 0;
681
682err_unit:
683 fw_unit_put(isight->unit);
684 fw_device_put(isight->device);
685 mutex_destroy(&isight->mutex);
686error:
687 snd_card_free(card);
688 return err;
689}
690
691static int isight_remove(struct device *dev)
692{
693 struct isight *isight = dev_get_drvdata(dev);
694
695 isight_pcm_abort(isight);
696
697 snd_card_disconnect(isight->card);
698
699 mutex_lock(&isight->mutex);
700 isight_stop_streaming(isight);
701 mutex_unlock(&isight->mutex);
702
703 snd_card_free_when_closed(isight->card);
704
705 return 0;
706}
707
708static void isight_bus_reset(struct fw_unit *unit)
709{
710 struct isight *isight = dev_get_drvdata(&unit->device);
711
712 if (fw_iso_resources_update(&isight->resources) < 0) {
713 isight_pcm_abort(isight);
714
715 mutex_lock(&isight->mutex);
716 isight_stop_streaming(isight);
717 mutex_unlock(&isight->mutex);
718 }
719}
720
721static const struct ieee1394_device_id isight_id_table[] = {
722 {
723 .match_flags = IEEE1394_MATCH_SPECIFIER_ID |
724 IEEE1394_MATCH_VERSION,
725 .specifier_id = OUI_APPLE,
726 .version = SW_ISIGHT_AUDIO,
727 },
728 { }
729};
730MODULE_DEVICE_TABLE(ieee1394, isight_id_table);
731
732static struct fw_driver isight_driver = {
733 .driver = {
734 .owner = THIS_MODULE,
735 .name = KBUILD_MODNAME,
736 .bus = &fw_bus_type,
737 .probe = isight_probe,
738 .remove = isight_remove,
739 },
740 .update = isight_bus_reset,
741 .id_table = isight_id_table,
742};
743
744static int __init alsa_isight_init(void)
745{
746 return driver_register(&isight_driver.driver);
747}
748
749static void __exit alsa_isight_exit(void)
750{
751 driver_unregister(&isight_driver.driver);
752}
753
754module_init(alsa_isight_init);
755module_exit(alsa_isight_exit);
diff --git a/sound/firewire/iso-resources.c b/sound/firewire/iso-resources.c
index 775dbd5f3445..9d4a6714f9ec 100644
--- a/sound/firewire/iso-resources.c
+++ b/sound/firewire/iso-resources.c
@@ -36,6 +36,7 @@ int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit)
36 36
37 return 0; 37 return 0;
38} 38}
39EXPORT_SYMBOL(fw_iso_resources_init);
39 40
40/** 41/**
41 * fw_iso_resources_destroy - destroy a resource manager 42 * fw_iso_resources_destroy - destroy a resource manager
@@ -48,6 +49,7 @@ void fw_iso_resources_destroy(struct fw_iso_resources *r)
48 mutex_destroy(&r->mutex); 49 mutex_destroy(&r->mutex);
49 fw_unit_put(r->unit); 50 fw_unit_put(r->unit);
50} 51}
52EXPORT_SYMBOL(fw_iso_resources_destroy);
51 53
52static unsigned int packet_bandwidth(unsigned int max_payload_bytes, int speed) 54static unsigned int packet_bandwidth(unsigned int max_payload_bytes, int speed)
53{ 55{
@@ -152,6 +154,7 @@ retry_after_bus_reset:
152 154
153 return channel; 155 return channel;
154} 156}
157EXPORT_SYMBOL(fw_iso_resources_allocate);
155 158
156/** 159/**
157 * fw_iso_resources_update - update resource allocations after a bus reset 160 * fw_iso_resources_update - update resource allocations after a bus reset
@@ -203,6 +206,7 @@ int fw_iso_resources_update(struct fw_iso_resources *r)
203 206
204 return channel; 207 return channel;
205} 208}
209EXPORT_SYMBOL(fw_iso_resources_update);
206 210
207/** 211/**
208 * fw_iso_resources_free - frees allocated resources 212 * fw_iso_resources_free - frees allocated resources
@@ -230,3 +234,4 @@ void fw_iso_resources_free(struct fw_iso_resources *r)
230 234
231 mutex_unlock(&r->mutex); 235 mutex_unlock(&r->mutex);
232} 236}
237EXPORT_SYMBOL(fw_iso_resources_free);
diff --git a/sound/firewire/packets-buffer.c b/sound/firewire/packets-buffer.c
index 1e20e60ba6a6..3c61ca2e6152 100644
--- a/sound/firewire/packets-buffer.c
+++ b/sound/firewire/packets-buffer.c
@@ -60,6 +60,7 @@ err_packets:
60error: 60error:
61 return err; 61 return err;
62} 62}
63EXPORT_SYMBOL(iso_packets_buffer_init);
63 64
64/** 65/**
65 * iso_packets_buffer_destroy - frees packet buffer resources 66 * iso_packets_buffer_destroy - frees packet buffer resources
@@ -72,3 +73,4 @@ void iso_packets_buffer_destroy(struct iso_packets_buffer *b,
72 fw_iso_buffer_destroy(&b->iso_buffer, fw_parent_device(unit)->card); 73 fw_iso_buffer_destroy(&b->iso_buffer, fw_parent_device(unit)->card);
73 kfree(b->packets); 74 kfree(b->packets);
74} 75}
76EXPORT_SYMBOL(iso_packets_buffer_destroy);
diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile
index 2dad40f3f622..c95d8f1aae87 100644
--- a/sound/i2c/other/Makefile
+++ b/sound/i2c/other/Makefile
@@ -14,4 +14,4 @@ snd-tea575x-tuner-objs := tea575x-tuner.o
14obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o 14obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o
15obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o 15obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o
16obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o 16obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o
17obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o 17obj-$(CONFIG_SND_TEA575X) += snd-tea575x-tuner.o
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index ee538f1ae846..4831800239d3 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -37,8 +37,8 @@ static int radio_nr = -1;
37module_param(radio_nr, int, 0); 37module_param(radio_nr, int, 0);
38 38
39#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) 39#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
40#define FREQ_LO (87 * 16000) 40#define FREQ_LO (50UL * 16000)
41#define FREQ_HI (108 * 16000) 41#define FREQ_HI (150UL * 16000)
42 42
43/* 43/*
44 * definitions 44 * definitions
@@ -77,27 +77,95 @@ static struct v4l2_queryctrl radio_qctrl[] = {
77 * lowlevel part 77 * lowlevel part
78 */ 78 */
79 79
80static void snd_tea575x_write(struct snd_tea575x *tea, unsigned int val)
81{
82 u16 l;
83 u8 data;
84
85 tea->ops->set_direction(tea, 1);
86 udelay(16);
87
88 for (l = 25; l > 0; l--) {
89 data = (val >> 24) & TEA575X_DATA;
90 val <<= 1; /* shift data */
91 tea->ops->set_pins(tea, data | TEA575X_WREN);
92 udelay(2);
93 tea->ops->set_pins(tea, data | TEA575X_WREN | TEA575X_CLK);
94 udelay(2);
95 tea->ops->set_pins(tea, data | TEA575X_WREN);
96 udelay(2);
97 }
98
99 if (!tea->mute)
100 tea->ops->set_pins(tea, 0);
101}
102
103static unsigned int snd_tea575x_read(struct snd_tea575x *tea)
104{
105 u16 l, rdata;
106 u32 data = 0;
107
108 tea->ops->set_direction(tea, 0);
109 tea->ops->set_pins(tea, 0);
110 udelay(16);
111
112 for (l = 24; l--;) {
113 tea->ops->set_pins(tea, TEA575X_CLK);
114 udelay(2);
115 if (!l)
116 tea->tuned = tea->ops->get_pins(tea) & TEA575X_MOST ? 0 : 1;
117 tea->ops->set_pins(tea, 0);
118 udelay(2);
119 data <<= 1; /* shift data */
120 rdata = tea->ops->get_pins(tea);
121 if (!l)
122 tea->stereo = (rdata & TEA575X_MOST) ? 0 : 1;
123 if (rdata & TEA575X_DATA)
124 data++;
125 udelay(2);
126 }
127
128 if (tea->mute)
129 tea->ops->set_pins(tea, TEA575X_WREN);
130
131 return data;
132}
133
134static void snd_tea575x_get_freq(struct snd_tea575x *tea)
135{
136 unsigned long freq;
137
138 freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK;
139 /* freq *= 12.5 */
140 freq *= 125;
141 freq /= 10;
142 /* crystal fixup */
143 if (tea->tea5759)
144 freq += TEA575X_FMIF;
145 else
146 freq -= TEA575X_FMIF;
147
148 tea->freq = freq * 16; /* from kHz */
149}
150
80static void snd_tea575x_set_freq(struct snd_tea575x *tea) 151static void snd_tea575x_set_freq(struct snd_tea575x *tea)
81{ 152{
82 unsigned long freq; 153 unsigned long freq;
83 154
84 freq = tea->freq / 16; /* to kHz */ 155 freq = clamp(tea->freq, FREQ_LO, FREQ_HI);
85 if (freq > 108000) 156 freq /= 16; /* to kHz */
86 freq = 108000;
87 if (freq < 87000)
88 freq = 87000;
89 /* crystal fixup */ 157 /* crystal fixup */
90 if (tea->tea5759) 158 if (tea->tea5759)
91 freq -= tea->freq_fixup; 159 freq -= TEA575X_FMIF;
92 else 160 else
93 freq += tea->freq_fixup; 161 freq += TEA575X_FMIF;
94 /* freq /= 12.5 */ 162 /* freq /= 12.5 */
95 freq *= 10; 163 freq *= 10;
96 freq /= 125; 164 freq /= 125;
97 165
98 tea->val &= ~TEA575X_BIT_FREQ_MASK; 166 tea->val &= ~TEA575X_BIT_FREQ_MASK;
99 tea->val |= freq & TEA575X_BIT_FREQ_MASK; 167 tea->val |= freq & TEA575X_BIT_FREQ_MASK;
100 tea->ops->write(tea, tea->val); 168 snd_tea575x_write(tea, tea->val);
101} 169}
102 170
103/* 171/*
@@ -109,29 +177,34 @@ static int vidioc_querycap(struct file *file, void *priv,
109{ 177{
110 struct snd_tea575x *tea = video_drvdata(file); 178 struct snd_tea575x *tea = video_drvdata(file);
111 179
112 strcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757");
113 strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver)); 180 strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver));
114 strlcpy(v->card, "Maestro Radio", sizeof(v->card)); 181 strlcpy(v->card, tea->card, sizeof(v->card));
115 sprintf(v->bus_info, "PCI"); 182 strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card));
183 strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info));
116 v->version = RADIO_VERSION; 184 v->version = RADIO_VERSION;
117 v->capabilities = V4L2_CAP_TUNER; 185 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
118 return 0; 186 return 0;
119} 187}
120 188
121static int vidioc_g_tuner(struct file *file, void *priv, 189static int vidioc_g_tuner(struct file *file, void *priv,
122 struct v4l2_tuner *v) 190 struct v4l2_tuner *v)
123{ 191{
192 struct snd_tea575x *tea = video_drvdata(file);
193
124 if (v->index > 0) 194 if (v->index > 0)
125 return -EINVAL; 195 return -EINVAL;
126 196
197 snd_tea575x_read(tea);
198
127 strcpy(v->name, "FM"); 199 strcpy(v->name, "FM");
128 v->type = V4L2_TUNER_RADIO; 200 v->type = V4L2_TUNER_RADIO;
201 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
129 v->rangelow = FREQ_LO; 202 v->rangelow = FREQ_LO;
130 v->rangehigh = FREQ_HI; 203 v->rangehigh = FREQ_HI;
131 v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; 204 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
132 v->capability = V4L2_TUNER_CAP_LOW; 205 v->audmode = tea->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO;
133 v->audmode = V4L2_TUNER_MODE_MONO; 206 v->signal = tea->tuned ? 0xffff : 0;
134 v->signal = 0xffff; 207
135 return 0; 208 return 0;
136} 209}
137 210
@@ -148,7 +221,10 @@ static int vidioc_g_frequency(struct file *file, void *priv,
148{ 221{
149 struct snd_tea575x *tea = video_drvdata(file); 222 struct snd_tea575x *tea = video_drvdata(file);
150 223
224 if (f->tuner != 0)
225 return -EINVAL;
151 f->type = V4L2_TUNER_RADIO; 226 f->type = V4L2_TUNER_RADIO;
227 snd_tea575x_get_freq(tea);
152 f->frequency = tea->freq; 228 f->frequency = tea->freq;
153 return 0; 229 return 0;
154} 230}
@@ -158,6 +234,9 @@ static int vidioc_s_frequency(struct file *file, void *priv,
158{ 234{
159 struct snd_tea575x *tea = video_drvdata(file); 235 struct snd_tea575x *tea = video_drvdata(file);
160 236
237 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
238 return -EINVAL;
239
161 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) 240 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
162 return -EINVAL; 241 return -EINVAL;
163 242
@@ -209,10 +288,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
209 288
210 switch (ctrl->id) { 289 switch (ctrl->id) {
211 case V4L2_CID_AUDIO_MUTE: 290 case V4L2_CID_AUDIO_MUTE:
212 if (tea->ops->mute) { 291 ctrl->value = tea->mute;
213 ctrl->value = tea->mute; 292 return 0;
214 return 0;
215 }
216 } 293 }
217 return -EINVAL; 294 return -EINVAL;
218} 295}
@@ -224,11 +301,11 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
224 301
225 switch (ctrl->id) { 302 switch (ctrl->id) {
226 case V4L2_CID_AUDIO_MUTE: 303 case V4L2_CID_AUDIO_MUTE:
227 if (tea->ops->mute) { 304 if (tea->mute != ctrl->value) {
228 tea->ops->mute(tea, ctrl->value);
229 tea->mute = ctrl->value; 305 tea->mute = ctrl->value;
230 return 0; 306 snd_tea575x_set_freq(tea);
231 } 307 }
308 return 0;
232 } 309 }
233 return -EINVAL; 310 return -EINVAL;
234} 311}
@@ -293,18 +370,16 @@ static struct video_device tea575x_radio = {
293/* 370/*
294 * initialize all the tea575x chips 371 * initialize all the tea575x chips
295 */ 372 */
296void snd_tea575x_init(struct snd_tea575x *tea) 373int snd_tea575x_init(struct snd_tea575x *tea)
297{ 374{
298 int retval; 375 int retval;
299 unsigned int val;
300 struct video_device *tea575x_radio_inst; 376 struct video_device *tea575x_radio_inst;
301 377
302 val = tea->ops->read(tea); 378 tea->mute = 1;
303 if (val == 0x1ffffff || val == 0) { 379
304 snd_printk(KERN_ERR 380 snd_tea575x_write(tea, 0x55AA);
305 "tea575x-tuner: Cannot find TEA575x chip\n"); 381 if (snd_tea575x_read(tea) != 0x55AA)
306 return; 382 return -ENODEV;
307 }
308 383
309 tea->in_use = 0; 384 tea->in_use = 0;
310 tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; 385 tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40;
@@ -313,7 +388,7 @@ void snd_tea575x_init(struct snd_tea575x *tea)
313 tea575x_radio_inst = video_device_alloc(); 388 tea575x_radio_inst = video_device_alloc();
314 if (tea575x_radio_inst == NULL) { 389 if (tea575x_radio_inst == NULL) {
315 printk(KERN_ERR "tea575x-tuner: not enough memory\n"); 390 printk(KERN_ERR "tea575x-tuner: not enough memory\n");
316 return; 391 return -ENOMEM;
317 } 392 }
318 393
319 memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio)); 394 memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio));
@@ -328,17 +403,13 @@ void snd_tea575x_init(struct snd_tea575x *tea)
328 if (retval) { 403 if (retval) {
329 printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); 404 printk(KERN_ERR "tea575x-tuner: can't register video device!\n");
330 kfree(tea575x_radio_inst); 405 kfree(tea575x_radio_inst);
331 return; 406 return retval;
332 } 407 }
333 408
334 snd_tea575x_set_freq(tea); 409 snd_tea575x_set_freq(tea);
335
336 /* mute on init */
337 if (tea->ops->mute) {
338 tea->ops->mute(tea, 1);
339 tea->mute = 1;
340 }
341 tea->vd = tea575x_radio_inst; 410 tea->vd = tea575x_radio_inst;
411
412 return 0;
342} 413}
343 414
344void snd_tea575x_exit(struct snd_tea575x *tea) 415void snd_tea575x_exit(struct snd_tea575x *tea)
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 76c090218073..6c93e051f9ae 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -22,10 +22,6 @@ config SOUND_VWSND
22 <file:Documentation/sound/oss/vwsnd> for more info on this driver's 22 <file:Documentation/sound/oss/vwsnd> for more info on this driver's
23 capabilities. 23 capabilities.
24 24
25config SOUND_AU1550_AC97
26 tristate "Au1550/Au1200 AC97 Sound"
27 depends on SOC_AU1550 || SOC_AU1200
28
29config SOUND_MSNDCLAS 25config SOUND_MSNDCLAS
30 tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey" 26 tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey"
31 depends on (m || !STANDALONE) && ISA 27 depends on (m || !STANDALONE) && ISA
diff --git a/sound/oss/Makefile b/sound/oss/Makefile
index 90ffb99c6b17..77f21b68bf0f 100644
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -25,7 +25,6 @@ obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o
25obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o 25obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o
26obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o 26obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o
27obj-$(CONFIG_SOUND_VWSND) += vwsnd.o 27obj-$(CONFIG_SOUND_VWSND) += vwsnd.o
28obj-$(CONFIG_SOUND_AU1550_AC97) += au1550_ac97.o ac97_codec.o
29obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o 28obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o
30 29
31obj-$(CONFIG_DMASOUND) += dmasound/ 30obj-$(CONFIG_DMASOUND) += dmasound/
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c
deleted file mode 100644
index 0cd23d94888f..000000000000
--- a/sound/oss/ac97_codec.c
+++ /dev/null
@@ -1,1203 +0,0 @@
1/*
2 * ac97_codec.c: Generic AC97 mixer/modem module
3 *
4 * Derived from ac97 mixer in maestro and trident driver.
5 *
6 * Copyright 2000 Silicon Integrated System Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 **************************************************************************
23 *
24 * The Intel Audio Codec '97 specification is available at:
25 * http://download.intel.com/support/motherboards/desktop/sb/ac97_r23.pdf
26 *
27 **************************************************************************
28 *
29 * History
30 * May 02, 2003 Liam Girdwood <lrg@slimlogic.co.uk>
31 * Removed non existent WM9700
32 * Added support for WM9705, WM9708, WM9709, WM9710, WM9711
33 * WM9712 and WM9717
34 * Mar 28, 2002 Randolph Bentson <bentson@holmsjoen.com>
35 * corrections to support WM9707 in ViewPad 1000
36 * v0.4 Mar 15 2000 Ollie Lho
37 * dual codecs support verified with 4 channels output
38 * v0.3 Feb 22 2000 Ollie Lho
39 * bug fix for record mask setting
40 * v0.2 Feb 10 2000 Ollie Lho
41 * add ac97_read_proc for /proc/driver/{vendor}/ac97
42 * v0.1 Jan 14 2000 Ollie Lho <ollie@sis.com.tw>
43 * Isolated from trident.c to support multiple ac97 codec
44 */
45#include <linux/module.h>
46#include <linux/kernel.h>
47#include <linux/slab.h>
48#include <linux/string.h>
49#include <linux/errno.h>
50#include <linux/bitops.h>
51#include <linux/delay.h>
52#include <linux/pci.h>
53#include <linux/ac97_codec.h>
54#include <asm/uaccess.h>
55#include <linux/mutex.h>
56
57#define CODEC_ID_BUFSZ 14
58
59static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel);
60static void ac97_write_mixer(struct ac97_codec *codec, int oss_channel,
61 unsigned int left, unsigned int right);
62static void ac97_set_mixer(struct ac97_codec *codec, unsigned int oss_mixer, unsigned int val );
63static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask);
64static int ac97_mixer_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg);
65
66static int ac97_init_mixer(struct ac97_codec *codec);
67
68static int wolfson_init03(struct ac97_codec * codec);
69static int wolfson_init04(struct ac97_codec * codec);
70static int wolfson_init05(struct ac97_codec * codec);
71static int wolfson_init11(struct ac97_codec * codec);
72static int wolfson_init13(struct ac97_codec * codec);
73static int tritech_init(struct ac97_codec * codec);
74static int tritech_maestro_init(struct ac97_codec * codec);
75static int sigmatel_9708_init(struct ac97_codec *codec);
76static int sigmatel_9721_init(struct ac97_codec *codec);
77static int sigmatel_9744_init(struct ac97_codec *codec);
78static int ad1886_init(struct ac97_codec *codec);
79static int eapd_control(struct ac97_codec *codec, int);
80static int crystal_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
81static int cmedia_init(struct ac97_codec * codec);
82static int cmedia_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
83static int generic_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
84
85
86/*
87 * AC97 operations.
88 *
89 * If you are adding a codec then you should be able to use
90 * eapd_ops - any codec that supports EAPD amp control (most)
91 * null_ops - any ancient codec that supports nothing
92 *
93 * The three functions are
94 * init - used for non AC97 standard initialisation
95 * amplifier - used to do amplifier control (1=on 0=off)
96 * digital - switch to digital modes (0 = analog)
97 *
98 * Not all codecs support all features, not all drivers use all the
99 * operations yet
100 */
101
102static struct ac97_ops null_ops = { NULL, NULL, NULL };
103static struct ac97_ops default_ops = { NULL, eapd_control, NULL };
104static struct ac97_ops default_digital_ops = { NULL, eapd_control, generic_digital_control};
105static struct ac97_ops wolfson_ops03 = { wolfson_init03, NULL, NULL };
106static struct ac97_ops wolfson_ops04 = { wolfson_init04, NULL, NULL };
107static struct ac97_ops wolfson_ops05 = { wolfson_init05, NULL, NULL };
108static struct ac97_ops wolfson_ops11 = { wolfson_init11, NULL, NULL };
109static struct ac97_ops wolfson_ops13 = { wolfson_init13, NULL, NULL };
110static struct ac97_ops tritech_ops = { tritech_init, NULL, NULL };
111static struct ac97_ops tritech_m_ops = { tritech_maestro_init, NULL, NULL };
112static struct ac97_ops sigmatel_9708_ops = { sigmatel_9708_init, NULL, NULL };
113static struct ac97_ops sigmatel_9721_ops = { sigmatel_9721_init, NULL, NULL };
114static struct ac97_ops sigmatel_9744_ops = { sigmatel_9744_init, NULL, NULL };
115static struct ac97_ops crystal_digital_ops = { NULL, eapd_control, crystal_digital_control };
116static struct ac97_ops ad1886_ops = { ad1886_init, eapd_control, NULL };
117static struct ac97_ops cmedia_ops = { NULL, eapd_control, NULL};
118static struct ac97_ops cmedia_digital_ops = { cmedia_init, eapd_control, cmedia_digital_control};
119
120/* sorted by vendor/device id */
121static const struct {
122 u32 id;
123 char *name;
124 struct ac97_ops *ops;
125 int flags;
126} ac97_codec_ids[] = {
127 {0x41445303, "Analog Devices AD1819", &null_ops},
128 {0x41445340, "Analog Devices AD1881", &null_ops},
129 {0x41445348, "Analog Devices AD1881A", &null_ops},
130 {0x41445360, "Analog Devices AD1885", &default_ops},
131 {0x41445361, "Analog Devices AD1886", &ad1886_ops},
132 {0x41445370, "Analog Devices AD1981", &null_ops},
133 {0x41445372, "Analog Devices AD1981A", &null_ops},
134 {0x41445374, "Analog Devices AD1981B", &null_ops},
135 {0x41445460, "Analog Devices AD1885", &default_ops},
136 {0x41445461, "Analog Devices AD1886", &ad1886_ops},
137 {0x414B4D00, "Asahi Kasei AK4540", &null_ops},
138 {0x414B4D01, "Asahi Kasei AK4542", &null_ops},
139 {0x414B4D02, "Asahi Kasei AK4543", &null_ops},
140 {0x414C4326, "ALC100P", &null_ops},
141 {0x414C4710, "ALC200/200P", &null_ops},
142 {0x414C4720, "ALC650", &default_digital_ops},
143 {0x434D4941, "CMedia", &cmedia_ops, AC97_NO_PCM_VOLUME },
144 {0x434D4942, "CMedia", &cmedia_ops, AC97_NO_PCM_VOLUME },
145 {0x434D4961, "CMedia", &cmedia_digital_ops, AC97_NO_PCM_VOLUME },
146 {0x43525900, "Cirrus Logic CS4297", &default_ops},
147 {0x43525903, "Cirrus Logic CS4297", &default_ops},
148 {0x43525913, "Cirrus Logic CS4297A rev A", &default_ops},
149 {0x43525914, "Cirrus Logic CS4297A rev B", &default_ops},
150 {0x43525923, "Cirrus Logic CS4298", &null_ops},
151 {0x4352592B, "Cirrus Logic CS4294", &null_ops},
152 {0x4352592D, "Cirrus Logic CS4294", &null_ops},
153 {0x43525931, "Cirrus Logic CS4299 rev A", &crystal_digital_ops},
154 {0x43525933, "Cirrus Logic CS4299 rev C", &crystal_digital_ops},
155 {0x43525934, "Cirrus Logic CS4299 rev D", &crystal_digital_ops},
156 {0x43585430, "CXT48", &default_ops, AC97_DELUDED_MODEM },
157 {0x43585442, "CXT66", &default_ops, AC97_DELUDED_MODEM },
158 {0x44543031, "Diamond Technology DT0893", &default_ops},
159 {0x45838308, "ESS Allegro ES1988", &null_ops},
160 {0x49434511, "ICE1232", &null_ops}, /* I hope --jk */
161 {0x4e534331, "National Semiconductor LM4549", &null_ops},
162 {0x53494c22, "Silicon Laboratory Si3036", &null_ops},
163 {0x53494c23, "Silicon Laboratory Si3038", &null_ops},
164 {0x545200FF, "TriTech TR?????", &tritech_m_ops},
165 {0x54524102, "TriTech TR28022", &null_ops},
166 {0x54524103, "TriTech TR28023", &null_ops},
167 {0x54524106, "TriTech TR28026", &null_ops},
168 {0x54524108, "TriTech TR28028", &tritech_ops},
169 {0x54524123, "TriTech TR A5", &null_ops},
170 {0x574D4C03, "Wolfson WM9703/07/08/17", &wolfson_ops03},
171 {0x574D4C04, "Wolfson WM9704M/WM9704Q", &wolfson_ops04},
172 {0x574D4C05, "Wolfson WM9705/WM9710", &wolfson_ops05},
173 {0x574D4C09, "Wolfson WM9709", &null_ops},
174 {0x574D4C12, "Wolfson WM9711/9712", &wolfson_ops11},
175 {0x574D4C13, "Wolfson WM9713", &wolfson_ops13, AC97_DEFAULT_POWER_OFF},
176 {0x83847600, "SigmaTel STAC????", &null_ops},
177 {0x83847604, "SigmaTel STAC9701/3/4/5", &null_ops},
178 {0x83847605, "SigmaTel STAC9704", &null_ops},
179 {0x83847608, "SigmaTel STAC9708", &sigmatel_9708_ops},
180 {0x83847609, "SigmaTel STAC9721/23", &sigmatel_9721_ops},
181 {0x83847644, "SigmaTel STAC9744/45", &sigmatel_9744_ops},
182 {0x83847652, "SigmaTel STAC9752/53", &default_ops},
183 {0x83847656, "SigmaTel STAC9756/57", &sigmatel_9744_ops},
184 {0x83847666, "SigmaTel STAC9750T", &sigmatel_9744_ops},
185 {0x83847684, "SigmaTel STAC9783/84?", &null_ops},
186 {0x57454301, "Winbond 83971D", &null_ops},
187};
188
189/* this table has default mixer values for all OSS mixers. */
190static struct mixer_defaults {
191 int mixer;
192 unsigned int value;
193} mixer_defaults[SOUND_MIXER_NRDEVICES] = {
194 /* all values 0 -> 100 in bytes */
195 {SOUND_MIXER_VOLUME, 0x4343},
196 {SOUND_MIXER_BASS, 0x4343},
197 {SOUND_MIXER_TREBLE, 0x4343},
198 {SOUND_MIXER_PCM, 0x4343},
199 {SOUND_MIXER_SPEAKER, 0x4343},
200 {SOUND_MIXER_LINE, 0x4343},
201 {SOUND_MIXER_MIC, 0x0000},
202 {SOUND_MIXER_CD, 0x4343},
203 {SOUND_MIXER_ALTPCM, 0x4343},
204 {SOUND_MIXER_IGAIN, 0x4343},
205 {SOUND_MIXER_LINE1, 0x4343},
206 {SOUND_MIXER_PHONEIN, 0x4343},
207 {SOUND_MIXER_PHONEOUT, 0x4343},
208 {SOUND_MIXER_VIDEO, 0x4343},
209 {-1,0}
210};
211
212/* table to scale scale from OSS mixer value to AC97 mixer register value */
213static struct ac97_mixer_hw {
214 unsigned char offset;
215 int scale;
216} ac97_hw[SOUND_MIXER_NRDEVICES]= {
217 [SOUND_MIXER_VOLUME] = {AC97_MASTER_VOL_STEREO,64},
218 [SOUND_MIXER_BASS] = {AC97_MASTER_TONE, 16},
219 [SOUND_MIXER_TREBLE] = {AC97_MASTER_TONE, 16},
220 [SOUND_MIXER_PCM] = {AC97_PCMOUT_VOL, 32},
221 [SOUND_MIXER_SPEAKER] = {AC97_PCBEEP_VOL, 16},
222 [SOUND_MIXER_LINE] = {AC97_LINEIN_VOL, 32},
223 [SOUND_MIXER_MIC] = {AC97_MIC_VOL, 32},
224 [SOUND_MIXER_CD] = {AC97_CD_VOL, 32},
225 [SOUND_MIXER_ALTPCM] = {AC97_HEADPHONE_VOL, 64},
226 [SOUND_MIXER_IGAIN] = {AC97_RECORD_GAIN, 16},
227 [SOUND_MIXER_LINE1] = {AC97_AUX_VOL, 32},
228 [SOUND_MIXER_PHONEIN] = {AC97_PHONE_VOL, 32},
229 [SOUND_MIXER_PHONEOUT] = {AC97_MASTER_VOL_MONO, 64},
230 [SOUND_MIXER_VIDEO] = {AC97_VIDEO_VOL, 32},
231};
232
233/* the following tables allow us to go from OSS <-> ac97 quickly. */
234enum ac97_recsettings {
235 AC97_REC_MIC=0,
236 AC97_REC_CD,
237 AC97_REC_VIDEO,
238 AC97_REC_AUX,
239 AC97_REC_LINE,
240 AC97_REC_STEREO, /* combination of all enabled outputs.. */
241 AC97_REC_MONO, /*.. or the mono equivalent */
242 AC97_REC_PHONE
243};
244
245static const unsigned int ac97_rm2oss[] = {
246 [AC97_REC_MIC] = SOUND_MIXER_MIC,
247 [AC97_REC_CD] = SOUND_MIXER_CD,
248 [AC97_REC_VIDEO] = SOUND_MIXER_VIDEO,
249 [AC97_REC_AUX] = SOUND_MIXER_LINE1,
250 [AC97_REC_LINE] = SOUND_MIXER_LINE,
251 [AC97_REC_STEREO]= SOUND_MIXER_IGAIN,
252 [AC97_REC_PHONE] = SOUND_MIXER_PHONEIN
253};
254
255/* indexed by bit position */
256static const unsigned int ac97_oss_rm[] = {
257 [SOUND_MIXER_MIC] = AC97_REC_MIC,
258 [SOUND_MIXER_CD] = AC97_REC_CD,
259 [SOUND_MIXER_VIDEO] = AC97_REC_VIDEO,
260 [SOUND_MIXER_LINE1] = AC97_REC_AUX,
261 [SOUND_MIXER_LINE] = AC97_REC_LINE,
262 [SOUND_MIXER_IGAIN] = AC97_REC_STEREO,
263 [SOUND_MIXER_PHONEIN] = AC97_REC_PHONE
264};
265
266static LIST_HEAD(codecs);
267static LIST_HEAD(codec_drivers);
268static DEFINE_MUTEX(codec_mutex);
269
270/* reads the given OSS mixer from the ac97 the caller must have insured that the ac97 knows
271 about that given mixer, and should be holding a spinlock for the card */
272static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel)
273{
274 u16 val;
275 int ret = 0;
276 int scale;
277 struct ac97_mixer_hw *mh = &ac97_hw[oss_channel];
278
279 val = codec->codec_read(codec , mh->offset);
280
281 if (val & AC97_MUTE) {
282 ret = 0;
283 } else if (AC97_STEREO_MASK & (1 << oss_channel)) {
284 /* nice stereo mixers .. */
285 int left,right;
286
287 left = (val >> 8) & 0x7f;
288 right = val & 0x7f;
289
290 if (oss_channel == SOUND_MIXER_IGAIN) {
291 right = (right * 100) / mh->scale;
292 left = (left * 100) / mh->scale;
293 } else {
294 /* these may have 5 or 6 bit resolution */
295 if(oss_channel == SOUND_MIXER_VOLUME || oss_channel == SOUND_MIXER_ALTPCM)
296 scale = (1 << codec->bit_resolution);
297 else
298 scale = mh->scale;
299
300 right = 100 - ((right * 100) / scale);
301 left = 100 - ((left * 100) / scale);
302 }
303 ret = left | (right << 8);
304 } else if (oss_channel == SOUND_MIXER_SPEAKER) {
305 ret = 100 - ((((val & 0x1e)>>1) * 100) / mh->scale);
306 } else if (oss_channel == SOUND_MIXER_PHONEIN) {
307 ret = 100 - (((val & 0x1f) * 100) / mh->scale);
308 } else if (oss_channel == SOUND_MIXER_PHONEOUT) {
309 scale = (1 << codec->bit_resolution);
310 ret = 100 - (((val & 0x1f) * 100) / scale);
311 } else if (oss_channel == SOUND_MIXER_MIC) {
312 ret = 100 - (((val & 0x1f) * 100) / mh->scale);
313 /* the low bit is optional in the tone sliders and masking
314 it lets us avoid the 0xf 'bypass'.. */
315 } else if (oss_channel == SOUND_MIXER_BASS) {
316 ret = 100 - ((((val >> 8) & 0xe) * 100) / mh->scale);
317 } else if (oss_channel == SOUND_MIXER_TREBLE) {
318 ret = 100 - (((val & 0xe) * 100) / mh->scale);
319 }
320
321#ifdef DEBUG
322 printk("ac97_codec: read OSS mixer %2d (%s ac97 register 0x%02x), "
323 "0x%04x -> 0x%04x\n",
324 oss_channel, codec->id ? "Secondary" : "Primary",
325 mh->offset, val, ret);
326#endif
327
328 return ret;
329}
330
331/* write the OSS encoded volume to the given OSS encoded mixer, again caller's job to
332 make sure all is well in arg land, call with spinlock held */
333static void ac97_write_mixer(struct ac97_codec *codec, int oss_channel,
334 unsigned int left, unsigned int right)
335{
336 u16 val = 0;
337 int scale;
338 struct ac97_mixer_hw *mh = &ac97_hw[oss_channel];
339
340#ifdef DEBUG
341 printk("ac97_codec: wrote OSS mixer %2d (%s ac97 register 0x%02x), "
342 "left vol:%2d, right vol:%2d:",
343 oss_channel, codec->id ? "Secondary" : "Primary",
344 mh->offset, left, right);
345#endif
346
347 if (AC97_STEREO_MASK & (1 << oss_channel)) {
348 /* stereo mixers */
349 if (left == 0 && right == 0) {
350 val = AC97_MUTE;
351 } else {
352 if (oss_channel == SOUND_MIXER_IGAIN) {
353 right = (right * mh->scale) / 100;
354 left = (left * mh->scale) / 100;
355 if (right >= mh->scale)
356 right = mh->scale-1;
357 if (left >= mh->scale)
358 left = mh->scale-1;
359 } else {
360 /* these may have 5 or 6 bit resolution */
361 if (oss_channel == SOUND_MIXER_VOLUME ||
362 oss_channel == SOUND_MIXER_ALTPCM)
363 scale = (1 << codec->bit_resolution);
364 else
365 scale = mh->scale;
366
367 right = ((100 - right) * scale) / 100;
368 left = ((100 - left) * scale) / 100;
369 if (right >= scale)
370 right = scale-1;
371 if (left >= scale)
372 left = scale-1;
373 }
374 val = (left << 8) | right;
375 }
376 } else if (oss_channel == SOUND_MIXER_BASS) {
377 val = codec->codec_read(codec , mh->offset) & ~0x0f00;
378 left = ((100 - left) * mh->scale) / 100;
379 if (left >= mh->scale)
380 left = mh->scale-1;
381 val |= (left << 8) & 0x0e00;
382 } else if (oss_channel == SOUND_MIXER_TREBLE) {
383 val = codec->codec_read(codec , mh->offset) & ~0x000f;
384 left = ((100 - left) * mh->scale) / 100;
385 if (left >= mh->scale)
386 left = mh->scale-1;
387 val |= left & 0x000e;
388 } else if(left == 0) {
389 val = AC97_MUTE;
390 } else if (oss_channel == SOUND_MIXER_SPEAKER) {
391 left = ((100 - left) * mh->scale) / 100;
392 if (left >= mh->scale)
393 left = mh->scale-1;
394 val = left << 1;
395 } else if (oss_channel == SOUND_MIXER_PHONEIN) {
396 left = ((100 - left) * mh->scale) / 100;
397 if (left >= mh->scale)
398 left = mh->scale-1;
399 val = left;
400 } else if (oss_channel == SOUND_MIXER_PHONEOUT) {
401 scale = (1 << codec->bit_resolution);
402 left = ((100 - left) * scale) / 100;
403 if (left >= mh->scale)
404 left = mh->scale-1;
405 val = left;
406 } else if (oss_channel == SOUND_MIXER_MIC) {
407 val = codec->codec_read(codec , mh->offset) & ~0x801f;
408 left = ((100 - left) * mh->scale) / 100;
409 if (left >= mh->scale)
410 left = mh->scale-1;
411 val |= left;
412 /* the low bit is optional in the tone sliders and masking
413 it lets us avoid the 0xf 'bypass'.. */
414 }
415#ifdef DEBUG
416 printk(" 0x%04x", val);
417#endif
418
419 codec->codec_write(codec, mh->offset, val);
420
421#ifdef DEBUG
422 val = codec->codec_read(codec, mh->offset);
423 printk(" -> 0x%04x\n", val);
424#endif
425}
426
427/* a thin wrapper for write_mixer */
428static void ac97_set_mixer(struct ac97_codec *codec, unsigned int oss_mixer, unsigned int val )
429{
430 unsigned int left,right;
431
432 /* cleanse input a little */
433 right = ((val >> 8) & 0xff) ;
434 left = (val & 0xff) ;
435
436 if (right > 100) right = 100;
437 if (left > 100) left = 100;
438
439 codec->mixer_state[oss_mixer] = (right << 8) | left;
440 codec->write_mixer(codec, oss_mixer, left, right);
441}
442
443/* read or write the recmask, the ac97 can really have left and right recording
444 inputs independently set, but OSS doesn't seem to want us to express that to
445 the user. the caller guarantees that we have a supported bit set, and they
446 must be holding the card's spinlock */
447static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask)
448{
449 unsigned int val;
450
451 if (rw) {
452 /* read it from the card */
453 val = codec->codec_read(codec, AC97_RECORD_SELECT);
454#ifdef DEBUG
455 printk("ac97_codec: ac97 recmask to set to 0x%04x\n", val);
456#endif
457 return (1 << ac97_rm2oss[val & 0x07]);
458 }
459
460 /* else, write the first set in the mask as the
461 output */
462 /* clear out current set value first (AC97 supports only 1 input!) */
463 val = (1 << ac97_rm2oss[codec->codec_read(codec, AC97_RECORD_SELECT) & 0x07]);
464 if (mask != val)
465 mask &= ~val;
466
467 val = ffs(mask);
468 val = ac97_oss_rm[val-1];
469 val |= val << 8; /* set both channels */
470
471#ifdef DEBUG
472 printk("ac97_codec: setting ac97 recmask to 0x%04x\n", val);
473#endif
474
475 codec->codec_write(codec, AC97_RECORD_SELECT, val);
476
477 return 0;
478};
479
480static int ac97_mixer_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg)
481{
482 int i, val = 0;
483
484 if (cmd == SOUND_MIXER_INFO) {
485 mixer_info info;
486 memset(&info, 0, sizeof(info));
487 strlcpy(info.id, codec->name, sizeof(info.id));
488 strlcpy(info.name, codec->name, sizeof(info.name));
489 info.modify_counter = codec->modcnt;
490 if (copy_to_user((void __user *)arg, &info, sizeof(info)))
491 return -EFAULT;
492 return 0;
493 }
494 if (cmd == SOUND_OLD_MIXER_INFO) {
495 _old_mixer_info info;
496 memset(&info, 0, sizeof(info));
497 strlcpy(info.id, codec->name, sizeof(info.id));
498 strlcpy(info.name, codec->name, sizeof(info.name));
499 if (copy_to_user((void __user *)arg, &info, sizeof(info)))
500 return -EFAULT;
501 return 0;
502 }
503
504 if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
505 return -EINVAL;
506
507 if (cmd == OSS_GETVERSION)
508 return put_user(SOUND_VERSION, (int __user *)arg);
509
510 if (_SIOC_DIR(cmd) == _SIOC_READ) {
511 switch (_IOC_NR(cmd)) {
512 case SOUND_MIXER_RECSRC: /* give them the current record source */
513 if (!codec->recmask_io) {
514 val = 0;
515 } else {
516 val = codec->recmask_io(codec, 1, 0);
517 }
518 break;
519
520 case SOUND_MIXER_DEVMASK: /* give them the supported mixers */
521 val = codec->supported_mixers;
522 break;
523
524 case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
525 val = codec->record_sources;
526 break;
527
528 case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
529 val = codec->stereo_mixers;
530 break;
531
532 case SOUND_MIXER_CAPS:
533 val = SOUND_CAP_EXCL_INPUT;
534 break;
535
536 default: /* read a specific mixer */
537 i = _IOC_NR(cmd);
538
539 if (!supported_mixer(codec, i))
540 return -EINVAL;
541
542 /* do we ever want to touch the hardware? */
543 /* val = codec->read_mixer(codec, i); */
544 val = codec->mixer_state[i];
545 break;
546 }
547 return put_user(val, (int __user *)arg);
548 }
549
550 if (_SIOC_DIR(cmd) == (_SIOC_WRITE|_SIOC_READ)) {
551 codec->modcnt++;
552 if (get_user(val, (int __user *)arg))
553 return -EFAULT;
554
555 switch (_IOC_NR(cmd)) {
556 case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
557 if (!codec->recmask_io) return -EINVAL;
558 if (!val) return 0;
559 if (!(val &= codec->record_sources)) return -EINVAL;
560
561 codec->recmask_io(codec, 0, val);
562
563 return 0;
564 default: /* write a specific mixer */
565 i = _IOC_NR(cmd);
566
567 if (!supported_mixer(codec, i))
568 return -EINVAL;
569
570 ac97_set_mixer(codec, i, val);
571
572 return 0;
573 }
574 }
575 return -EINVAL;
576}
577
578/**
579 * codec_id - Turn id1/id2 into a PnP string
580 * @id1: Vendor ID1
581 * @id2: Vendor ID2
582 * @buf: CODEC_ID_BUFSZ byte buffer
583 *
584 * Fills buf with a zero terminated PnP ident string for the id1/id2
585 * pair. For convenience the return is the passed in buffer pointer.
586 */
587
588static char *codec_id(u16 id1, u16 id2, char *buf)
589{
590 if(id1&0x8080) {
591 snprintf(buf, CODEC_ID_BUFSZ, "0x%04x:0x%04x", id1, id2);
592 } else {
593 buf[0] = (id1 >> 8);
594 buf[1] = (id1 & 0xFF);
595 buf[2] = (id2 >> 8);
596 snprintf(buf+3, CODEC_ID_BUFSZ - 3, "%d", id2&0xFF);
597 }
598 return buf;
599}
600
601/**
602 * ac97_check_modem - Check if the Codec is a modem
603 * @codec: codec to check
604 *
605 * Return true if the device is an AC97 1.0 or AC97 2.0 modem
606 */
607
608static int ac97_check_modem(struct ac97_codec *codec)
609{
610 /* Check for an AC97 1.0 soft modem (ID1) */
611 if(codec->codec_read(codec, AC97_RESET) & 2)
612 return 1;
613 /* Check for an AC97 2.x soft modem */
614 codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L);
615 if(codec->codec_read(codec, AC97_EXTENDED_MODEM_ID) & 1)
616 return 1;
617 return 0;
618}
619
620
621/**
622 * ac97_alloc_codec - Allocate an AC97 codec
623 *
624 * Returns a new AC97 codec structure. AC97 codecs may become
625 * refcounted soon so this interface is needed. Returns with
626 * one reference taken.
627 */
628
629struct ac97_codec *ac97_alloc_codec(void)
630{
631 struct ac97_codec *codec = kzalloc(sizeof(struct ac97_codec), GFP_KERNEL);
632 if(!codec)
633 return NULL;
634
635 spin_lock_init(&codec->lock);
636 INIT_LIST_HEAD(&codec->list);
637 return codec;
638}
639
640EXPORT_SYMBOL(ac97_alloc_codec);
641
642/**
643 * ac97_release_codec - Release an AC97 codec
644 * @codec: codec to release
645 *
646 * Release an allocated AC97 codec. This will be refcounted in
647 * time but for the moment is trivial. Calls the unregister
648 * handler if the codec is now defunct.
649 */
650
651void ac97_release_codec(struct ac97_codec *codec)
652{
653 /* Remove from the list first, we don't want to be
654 "rediscovered" */
655 mutex_lock(&codec_mutex);
656 list_del(&codec->list);
657 mutex_unlock(&codec_mutex);
658 /*
659 * The driver needs to deal with internal
660 * locking to avoid accidents here.
661 */
662 if(codec->driver)
663 codec->driver->remove(codec, codec->driver);
664 kfree(codec);
665}
666
667EXPORT_SYMBOL(ac97_release_codec);
668
669/**
670 * ac97_probe_codec - Initialize and setup AC97-compatible codec
671 * @codec: (in/out) Kernel info for a single AC97 codec
672 *
673 * Reset the AC97 codec, then initialize the mixer and
674 * the rest of the @codec structure.
675 *
676 * The codec_read and codec_write fields of @codec are
677 * required to be setup and working when this function
678 * is called. All other fields are set by this function.
679 *
680 * codec_wait field of @codec can optionally be provided
681 * when calling this function. If codec_wait is not %NULL,
682 * this function will call codec_wait any time it is
683 * necessary to wait for the audio chip to reach the
684 * codec-ready state. If codec_wait is %NULL, then
685 * the default behavior is to call schedule_timeout.
686 * Currently codec_wait is used to wait for AC97 codec
687 * reset to complete.
688 *
689 * Some codecs will power down when a register reset is
690 * performed. We now check for such codecs.
691 *
692 * Returns 1 (true) on success, or 0 (false) on failure.
693 */
694
695int ac97_probe_codec(struct ac97_codec *codec)
696{
697 u16 id1, id2;
698 u16 audio;
699 int i;
700 char cidbuf[CODEC_ID_BUFSZ];
701 u16 f;
702 struct list_head *l;
703 struct ac97_driver *d;
704
705 /* wait for codec-ready state */
706 if (codec->codec_wait)
707 codec->codec_wait(codec);
708 else
709 udelay(10);
710
711 /* will the codec power down if register reset ? */
712 id1 = codec->codec_read(codec, AC97_VENDOR_ID1);
713 id2 = codec->codec_read(codec, AC97_VENDOR_ID2);
714 codec->name = NULL;
715 codec->codec_ops = &null_ops;
716 for (i = 0; i < ARRAY_SIZE(ac97_codec_ids); i++) {
717 if (ac97_codec_ids[i].id == ((id1 << 16) | id2)) {
718 codec->type = ac97_codec_ids[i].id;
719 codec->name = ac97_codec_ids[i].name;
720 codec->codec_ops = ac97_codec_ids[i].ops;
721 codec->flags = ac97_codec_ids[i].flags;
722 break;
723 }
724 }
725
726 codec->model = (id1 << 16) | id2;
727 if ((codec->flags & AC97_DEFAULT_POWER_OFF) == 0) {
728 /* reset codec and wait for the ready bit before we continue */
729 codec->codec_write(codec, AC97_RESET, 0L);
730 if (codec->codec_wait)
731 codec->codec_wait(codec);
732 else
733 udelay(10);
734 }
735
736 /* probing AC97 codec, AC97 2.0 says that bit 15 of register 0x00 (reset) should
737 * be read zero.
738 *
739 * FIXME: is the following comment outdated? -jgarzik
740 * Probing of AC97 in this way is not reliable, it is not even SAFE !!
741 */
742 if ((audio = codec->codec_read(codec, AC97_RESET)) & 0x8000) {
743 printk(KERN_ERR "ac97_codec: %s ac97 codec not present\n",
744 (codec->id & 0x2) ? (codec->id&1 ? "4th" : "Tertiary")
745 : (codec->id&1 ? "Secondary": "Primary"));
746 return 0;
747 }
748
749 /* probe for Modem Codec */
750 codec->modem = ac97_check_modem(codec);
751
752 /* enable SPDIF */
753 f = codec->codec_read(codec, AC97_EXTENDED_STATUS);
754 if((codec->codec_ops == &null_ops) && (f & 4))
755 codec->codec_ops = &default_digital_ops;
756
757 /* A device which thinks its a modem but isn't */
758 if(codec->flags & AC97_DELUDED_MODEM)
759 codec->modem = 0;
760
761 if (codec->name == NULL)
762 codec->name = "Unknown";
763 printk(KERN_INFO "ac97_codec: AC97 %s codec, id: %s (%s)\n",
764 codec->modem ? "Modem" : (audio ? "Audio" : ""),
765 codec_id(id1, id2, cidbuf), codec->name);
766
767 if(!ac97_init_mixer(codec))
768 return 0;
769
770 /*
771 * Attach last so the caller can override the mixer
772 * callbacks.
773 */
774
775 mutex_lock(&codec_mutex);
776 list_add(&codec->list, &codecs);
777
778 list_for_each(l, &codec_drivers) {
779 d = list_entry(l, struct ac97_driver, list);
780 if ((codec->model ^ d->codec_id) & d->codec_mask)
781 continue;
782 if(d->probe(codec, d) == 0)
783 {
784 codec->driver = d;
785 break;
786 }
787 }
788
789 mutex_unlock(&codec_mutex);
790 return 1;
791}
792
793static int ac97_init_mixer(struct ac97_codec *codec)
794{
795 u16 cap;
796 int i;
797
798 cap = codec->codec_read(codec, AC97_RESET);
799
800 /* mixer masks */
801 codec->supported_mixers = AC97_SUPPORTED_MASK;
802 codec->stereo_mixers = AC97_STEREO_MASK;
803 codec->record_sources = AC97_RECORD_MASK;
804 if (!(cap & 0x04))
805 codec->supported_mixers &= ~(SOUND_MASK_BASS|SOUND_MASK_TREBLE);
806 if (!(cap & 0x10))
807 codec->supported_mixers &= ~SOUND_MASK_ALTPCM;
808
809
810 /* detect bit resolution */
811 codec->codec_write(codec, AC97_MASTER_VOL_STEREO, 0x2020);
812 if(codec->codec_read(codec, AC97_MASTER_VOL_STEREO) == 0x2020)
813 codec->bit_resolution = 6;
814 else
815 codec->bit_resolution = 5;
816
817 /* generic OSS to AC97 wrapper */
818 codec->read_mixer = ac97_read_mixer;
819 codec->write_mixer = ac97_write_mixer;
820 codec->recmask_io = ac97_recmask_io;
821 codec->mixer_ioctl = ac97_mixer_ioctl;
822
823 /* initialize mixer channel volumes */
824 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
825 struct mixer_defaults *md = &mixer_defaults[i];
826 if (md->mixer == -1)
827 break;
828 if (!supported_mixer(codec, md->mixer))
829 continue;
830 ac97_set_mixer(codec, md->mixer, md->value);
831 }
832
833 /* codec specific initialization for 4-6 channel output or secondary codec stuff */
834 if (codec->codec_ops->init != NULL) {
835 codec->codec_ops->init(codec);
836 }
837
838 /*
839 * Volume is MUTE only on this device. We have to initialise
840 * it but its useless beyond that.
841 */
842 if(codec->flags & AC97_NO_PCM_VOLUME)
843 {
844 codec->supported_mixers &= ~SOUND_MASK_PCM;
845 printk(KERN_WARNING "AC97 codec does not have proper volume support.\n");
846 }
847 return 1;
848}
849
850#define AC97_SIGMATEL_ANALOG 0x6c /* Analog Special */
851#define AC97_SIGMATEL_DAC2INVERT 0x6e
852#define AC97_SIGMATEL_BIAS1 0x70
853#define AC97_SIGMATEL_BIAS2 0x72
854#define AC97_SIGMATEL_MULTICHN 0x74 /* Multi-Channel programming */
855#define AC97_SIGMATEL_CIC1 0x76
856#define AC97_SIGMATEL_CIC2 0x78
857
858
859static int sigmatel_9708_init(struct ac97_codec * codec)
860{
861 u16 codec72, codec6c;
862
863 codec72 = codec->codec_read(codec, AC97_SIGMATEL_BIAS2) & 0x8000;
864 codec6c = codec->codec_read(codec, AC97_SIGMATEL_ANALOG);
865
866 if ((codec72==0) && (codec6c==0)) {
867 codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);
868 codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x1000);
869 codec->codec_write(codec, AC97_SIGMATEL_BIAS1, 0xabba);
870 codec->codec_write(codec, AC97_SIGMATEL_BIAS2, 0x0007);
871 } else if ((codec72==0x8000) && (codec6c==0)) {
872 codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);
873 codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x1001);
874 codec->codec_write(codec, AC97_SIGMATEL_DAC2INVERT, 0x0008);
875 } else if ((codec72==0x8000) && (codec6c==0x0080)) {
876 /* nothing */
877 }
878 codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x0000);
879 return 0;
880}
881
882
883static int sigmatel_9721_init(struct ac97_codec * codec)
884{
885 /* Only set up secondary codec */
886 if (codec->id == 0)
887 return 0;
888
889 codec->codec_write(codec, AC97_SURROUND_MASTER, 0L);
890
891 /* initialize SigmaTel STAC9721/23 as secondary codec, decoding AC link
892 sloc 3,4 = 0x01, slot 7,8 = 0x00, */
893 codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x00);
894
895 /* we don't have the crystal when we are on an AMR card, so use
896 BIT_CLK as our clock source. Write the magic word ABBA and read
897 back to enable register 0x78 */
898 codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);
899 codec->codec_read(codec, AC97_SIGMATEL_CIC1);
900
901 /* sync all the clocks*/
902 codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x3802);
903
904 return 0;
905}
906
907
908static int sigmatel_9744_init(struct ac97_codec * codec)
909{
910 // patch for SigmaTel
911 codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);
912 codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x0000); // is this correct? --jk
913 codec->codec_write(codec, AC97_SIGMATEL_BIAS1, 0xabba);
914 codec->codec_write(codec, AC97_SIGMATEL_BIAS2, 0x0002);
915 codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x0000);
916 return 0;
917}
918
919static int cmedia_init(struct ac97_codec *codec)
920{
921 /* Initialise the CMedia 9739 */
922 /*
923 We could set various options here
924 Register 0x20 bit 0x100 sets mic as center bass
925 Also do multi_channel_ctrl &=~0x3000 |=0x1000
926
927 For now we set up the GPIO and PC beep
928 */
929
930 u16 v;
931
932 /* MIC */
933 codec->codec_write(codec, 0x64, 0x3000);
934 v = codec->codec_read(codec, 0x64);
935 v &= ~0x8000;
936 codec->codec_write(codec, 0x64, v);
937 codec->codec_write(codec, 0x70, 0x0100);
938 codec->codec_write(codec, 0x72, 0x0020);
939 return 0;
940}
941
942#define AC97_WM97XX_FMIXER_VOL 0x72
943#define AC97_WM97XX_RMIXER_VOL 0x74
944#define AC97_WM97XX_TEST 0x5a
945#define AC97_WM9704_RPCM_VOL 0x70
946#define AC97_WM9711_OUT3VOL 0x16
947
948static int wolfson_init03(struct ac97_codec * codec)
949{
950 /* this is known to work for the ViewSonic ViewPad 1000 */
951 codec->codec_write(codec, AC97_WM97XX_FMIXER_VOL, 0x0808);
952 codec->codec_write(codec, AC97_GENERAL_PURPOSE, 0x8000);
953 return 0;
954}
955
956static int wolfson_init04(struct ac97_codec * codec)
957{
958 codec->codec_write(codec, AC97_WM97XX_FMIXER_VOL, 0x0808);
959 codec->codec_write(codec, AC97_WM97XX_RMIXER_VOL, 0x0808);
960
961 // patch for DVD noise
962 codec->codec_write(codec, AC97_WM97XX_TEST, 0x0200);
963
964 // init vol as PCM vol
965 codec->codec_write(codec, AC97_WM9704_RPCM_VOL,
966 codec->codec_read(codec, AC97_PCMOUT_VOL));
967
968 /* set rear surround volume */
969 codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000);
970 return 0;
971}
972
973/* WM9705, WM9710 */
974static int wolfson_init05(struct ac97_codec * codec)
975{
976 /* set front mixer volume */
977 codec->codec_write(codec, AC97_WM97XX_FMIXER_VOL, 0x0808);
978 return 0;
979}
980
981/* WM9711, WM9712 */
982static int wolfson_init11(struct ac97_codec * codec)
983{
984 /* stop pop's during suspend/resume */
985 codec->codec_write(codec, AC97_WM97XX_TEST,
986 codec->codec_read(codec, AC97_WM97XX_TEST) & 0xffbf);
987
988 /* set out3 volume */
989 codec->codec_write(codec, AC97_WM9711_OUT3VOL, 0x0808);
990 return 0;
991}
992
993/* WM9713 */
994static int wolfson_init13(struct ac97_codec * codec)
995{
996 codec->codec_write(codec, AC97_RECORD_GAIN, 0x00a0);
997 codec->codec_write(codec, AC97_POWER_CONTROL, 0x0000);
998 codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0xDA00);
999 codec->codec_write(codec, AC97_EXTEND_MODEM_STAT, 0x3810);
1000 codec->codec_write(codec, AC97_PHONE_VOL, 0x0808);
1001 codec->codec_write(codec, AC97_PCBEEP_VOL, 0x0808);
1002
1003 return 0;
1004}
1005
1006static int tritech_init(struct ac97_codec * codec)
1007{
1008 codec->codec_write(codec, 0x26, 0x0300);
1009 codec->codec_write(codec, 0x26, 0x0000);
1010 codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000);
1011 codec->codec_write(codec, AC97_RESERVED_3A, 0x0000);
1012 return 0;
1013}
1014
1015
1016/* copied from drivers/sound/maestro.c */
1017static int tritech_maestro_init(struct ac97_codec * codec)
1018{
1019 /* no idea what this does */
1020 codec->codec_write(codec, 0x2A, 0x0001);
1021 codec->codec_write(codec, 0x2C, 0x0000);
1022 codec->codec_write(codec, 0x2C, 0XFFFF);
1023 return 0;
1024}
1025
1026
1027
1028/*
1029 * Presario700 workaround
1030 * for Jack Sense/SPDIF Register mis-setting causing
1031 * no audible output
1032 * by Santiago Nullo 04/05/2002
1033 */
1034
1035#define AC97_AD1886_JACK_SENSE 0x72
1036
1037static int ad1886_init(struct ac97_codec * codec)
1038{
1039 /* from AD1886 Specs */
1040 codec->codec_write(codec, AC97_AD1886_JACK_SENSE, 0x0010);
1041 return 0;
1042}
1043
1044
1045
1046
1047/*
1048 * This is basically standard AC97. It should work as a default for
1049 * almost all modern codecs. Note that some cards wire EAPD *backwards*
1050 * That side of it is up to the card driver not us to cope with.
1051 *
1052 */
1053
1054static int eapd_control(struct ac97_codec * codec, int on)
1055{
1056 if(on)
1057 codec->codec_write(codec, AC97_POWER_CONTROL,
1058 codec->codec_read(codec, AC97_POWER_CONTROL)|0x8000);
1059 else
1060 codec->codec_write(codec, AC97_POWER_CONTROL,
1061 codec->codec_read(codec, AC97_POWER_CONTROL)&~0x8000);
1062 return 0;
1063}
1064
1065static int generic_digital_control(struct ac97_codec *codec, int slots, int rate, int mode)
1066{
1067 u16 reg;
1068
1069 reg = codec->codec_read(codec, AC97_SPDIF_CONTROL);
1070
1071 switch(rate)
1072 {
1073 /* Off by default */
1074 default:
1075 case 0:
1076 reg = codec->codec_read(codec, AC97_EXTENDED_STATUS);
1077 codec->codec_write(codec, AC97_EXTENDED_STATUS, (reg & ~AC97_EA_SPDIF));
1078 if(rate == 0)
1079 return 0;
1080 return -EINVAL;
1081 case 1:
1082 reg = (reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_48K;
1083 break;
1084 case 2:
1085 reg = (reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_44K;
1086 break;
1087 case 3:
1088 reg = (reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_32K;
1089 break;
1090 }
1091
1092 reg &= ~AC97_SC_CC_MASK;
1093 reg |= (mode & AUDIO_CCMASK) << 6;
1094
1095 if(mode & AUDIO_DIGITAL)
1096 reg |= 2;
1097 if(mode & AUDIO_PRO)
1098 reg |= 1;
1099 if(mode & AUDIO_DRS)
1100 reg |= 0x4000;
1101
1102 codec->codec_write(codec, AC97_SPDIF_CONTROL, reg);
1103
1104 reg = codec->codec_read(codec, AC97_EXTENDED_STATUS);
1105 reg &= (AC97_EA_SLOT_MASK);
1106 reg |= AC97_EA_VRA | AC97_EA_SPDIF | slots;
1107 codec->codec_write(codec, AC97_EXTENDED_STATUS, reg);
1108
1109 reg = codec->codec_read(codec, AC97_EXTENDED_STATUS);
1110 if(!(reg & 0x0400))
1111 {
1112 codec->codec_write(codec, AC97_EXTENDED_STATUS, reg & ~ AC97_EA_SPDIF);
1113 return -EINVAL;
1114 }
1115 return 0;
1116}
1117
1118/*
1119 * Crystal digital audio control (CS4299)
1120 */
1121
1122static int crystal_digital_control(struct ac97_codec *codec, int slots, int rate, int mode)
1123{
1124 u16 cv;
1125
1126 if(mode & AUDIO_DIGITAL)
1127 return -EINVAL;
1128
1129 switch(rate)
1130 {
1131 case 0: cv = 0x0; break; /* SPEN off */
1132 case 48000: cv = 0x8004; break; /* 48KHz digital */
1133 case 44100: cv = 0x8104; break; /* 44.1KHz digital */
1134 case 32768: /* 32Khz */
1135 default:
1136 return -EINVAL;
1137 }
1138 codec->codec_write(codec, 0x68, cv);
1139 return 0;
1140}
1141
1142/*
1143 * CMedia digital audio control
1144 * Needs more work.
1145 */
1146
1147static int cmedia_digital_control(struct ac97_codec *codec, int slots, int rate, int mode)
1148{
1149 u16 cv;
1150
1151 if(mode & AUDIO_DIGITAL)
1152 return -EINVAL;
1153
1154 switch(rate)
1155 {
1156 case 0: cv = 0x0001; break; /* SPEN off */
1157 case 48000: cv = 0x0009; break; /* 48KHz digital */
1158 default:
1159 return -EINVAL;
1160 }
1161 codec->codec_write(codec, 0x2A, 0x05c4);
1162 codec->codec_write(codec, 0x6C, cv);
1163
1164 /* Switch on mix to surround */
1165 cv = codec->codec_read(codec, 0x64);
1166 cv &= ~0x0200;
1167 if(mode)
1168 cv |= 0x0200;
1169 codec->codec_write(codec, 0x64, cv);
1170 return 0;
1171}
1172
1173
1174/* copied from drivers/sound/maestro.c */
1175#if 0 /* there has been 1 person on the planet with a pt101 that we
1176 know of. If they care, they can put this back in :) */
1177static int pt101_init(struct ac97_codec * codec)
1178{
1179 printk(KERN_INFO "ac97_codec: PT101 Codec detected, initializing but _not_ installing mixer device.\n");
1180 /* who knows.. */
1181 codec->codec_write(codec, 0x2A, 0x0001);
1182 codec->codec_write(codec, 0x2C, 0x0000);
1183 codec->codec_write(codec, 0x2C, 0xFFFF);
1184 codec->codec_write(codec, 0x10, 0x9F1F);
1185 codec->codec_write(codec, 0x12, 0x0808);
1186 codec->codec_write(codec, 0x14, 0x9F1F);
1187 codec->codec_write(codec, 0x16, 0x9F1F);
1188 codec->codec_write(codec, 0x18, 0x0404);
1189 codec->codec_write(codec, 0x1A, 0x0000);
1190 codec->codec_write(codec, 0x1C, 0x0000);
1191 codec->codec_write(codec, 0x02, 0x0404);
1192 codec->codec_write(codec, 0x04, 0x0808);
1193 codec->codec_write(codec, 0x0C, 0x801F);
1194 codec->codec_write(codec, 0x0E, 0x801F);
1195 return 0;
1196}
1197#endif
1198
1199
1200EXPORT_SYMBOL(ac97_probe_codec);
1201
1202MODULE_LICENSE("GPL");
1203
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
deleted file mode 100644
index a8f626d99c5b..000000000000
--- a/sound/oss/au1550_ac97.c
+++ /dev/null
@@ -1,2147 +0,0 @@
1/*
2 * au1550_ac97.c -- Sound driver for Alchemy Au1550 MIPS Internet Edge
3 * Processor.
4 *
5 * Copyright 2004 Embedded Edge, LLC
6 * dan@embeddededge.com
7 *
8 * Mostly copied from the au1000.c driver and some from the
9 * PowerMac dbdma driver.
10 * We assume the processor can do memory coherent DMA.
11 *
12 * Ported to 2.6 by Matt Porter <mporter@kernel.crashing.org>
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version.
18 *
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
22 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 */
35
36#undef DEBUG
37
38#include <linux/module.h>
39#include <linux/string.h>
40#include <linux/ioport.h>
41#include <linux/sched.h>
42#include <linux/delay.h>
43#include <linux/sound.h>
44#include <linux/slab.h>
45#include <linux/soundcard.h>
46#include <linux/init.h>
47#include <linux/interrupt.h>
48#include <linux/kernel.h>
49#include <linux/poll.h>
50#include <linux/bitops.h>
51#include <linux/spinlock.h>
52#include <linux/ac97_codec.h>
53#include <linux/mutex.h>
54
55#include <asm/io.h>
56#include <asm/uaccess.h>
57#include <asm/hardirq.h>
58#include <asm/mach-au1x00/au1xxx_psc.h>
59#include <asm/mach-au1x00/au1xxx_dbdma.h>
60#include <asm/mach-au1x00/au1xxx.h>
61
62#undef OSS_DOCUMENTED_MIXER_SEMANTICS
63
64/* misc stuff */
65#define POLL_COUNT 0x50000
66#define AC97_EXT_DACS (AC97_EXTID_SDAC | AC97_EXTID_CDAC | AC97_EXTID_LDAC)
67
68/* The number of DBDMA ring descriptors to allocate. No sense making
69 * this too large....if you can't keep up with a few you aren't likely
70 * to be able to with lots of them, either.
71 */
72#define NUM_DBDMA_DESCRIPTORS 4
73
74#define err(format, arg...) printk(KERN_ERR format "\n" , ## arg)
75
76/* Boot options
77 * 0 = no VRA, 1 = use VRA if codec supports it
78 */
79static DEFINE_MUTEX(au1550_ac97_mutex);
80static int vra = 1;
81module_param(vra, bool, 0);
82MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it");
83
84static struct au1550_state {
85 /* soundcore stuff */
86 int dev_audio;
87
88 struct ac97_codec *codec;
89 unsigned codec_base_caps; /* AC'97 reg 00h, "Reset Register" */
90 unsigned codec_ext_caps; /* AC'97 reg 28h, "Extended Audio ID" */
91 int no_vra; /* do not use VRA */
92
93 spinlock_t lock;
94 struct mutex open_mutex;
95 struct mutex sem;
96 fmode_t open_mode;
97 wait_queue_head_t open_wait;
98
99 struct dmabuf {
100 u32 dmanr;
101 unsigned sample_rate;
102 unsigned src_factor;
103 unsigned sample_size;
104 int num_channels;
105 int dma_bytes_per_sample;
106 int user_bytes_per_sample;
107 int cnt_factor;
108
109 void *rawbuf;
110 unsigned buforder;
111 unsigned numfrag;
112 unsigned fragshift;
113 void *nextIn;
114 void *nextOut;
115 int count;
116 unsigned total_bytes;
117 unsigned error;
118 wait_queue_head_t wait;
119
120 /* redundant, but makes calculations easier */
121 unsigned fragsize;
122 unsigned dma_fragsize;
123 unsigned dmasize;
124 unsigned dma_qcount;
125
126 /* OSS stuff */
127 unsigned mapped:1;
128 unsigned ready:1;
129 unsigned stopped:1;
130 unsigned ossfragshift;
131 int ossmaxfrags;
132 unsigned subdivision;
133 } dma_dac, dma_adc;
134} au1550_state;
135
136static unsigned
137ld2(unsigned int x)
138{
139 unsigned r = 0;
140
141 if (x >= 0x10000) {
142 x >>= 16;
143 r += 16;
144 }
145 if (x >= 0x100) {
146 x >>= 8;
147 r += 8;
148 }
149 if (x >= 0x10) {
150 x >>= 4;
151 r += 4;
152 }
153 if (x >= 4) {
154 x >>= 2;
155 r += 2;
156 }
157 if (x >= 2)
158 r++;
159 return r;
160}
161
162static void
163au1550_delay(int msec)
164{
165 if (in_interrupt())
166 return;
167
168 schedule_timeout_uninterruptible(msecs_to_jiffies(msec));
169}
170
171static u16
172rdcodec(struct ac97_codec *codec, u8 addr)
173{
174 struct au1550_state *s = codec->private_data;
175 unsigned long flags;
176 u32 cmd, val;
177 u16 data;
178 int i;
179
180 spin_lock_irqsave(&s->lock, flags);
181
182 for (i = 0; i < POLL_COUNT; i++) {
183 val = au_readl(PSC_AC97STAT);
184 au_sync();
185 if (!(val & PSC_AC97STAT_CP))
186 break;
187 }
188 if (i == POLL_COUNT)
189 err("rdcodec: codec cmd pending expired!");
190
191 cmd = (u32)PSC_AC97CDC_INDX(addr);
192 cmd |= PSC_AC97CDC_RD; /* read command */
193 au_writel(cmd, PSC_AC97CDC);
194 au_sync();
195
196 /* now wait for the data
197 */
198 for (i = 0; i < POLL_COUNT; i++) {
199 val = au_readl(PSC_AC97STAT);
200 au_sync();
201 if (!(val & PSC_AC97STAT_CP))
202 break;
203 }
204 if (i == POLL_COUNT) {
205 err("rdcodec: read poll expired!");
206 data = 0;
207 goto out;
208 }
209
210 /* wait for command done?
211 */
212 for (i = 0; i < POLL_COUNT; i++) {
213 val = au_readl(PSC_AC97EVNT);
214 au_sync();
215 if (val & PSC_AC97EVNT_CD)
216 break;
217 }
218 if (i == POLL_COUNT) {
219 err("rdcodec: read cmdwait expired!");
220 data = 0;
221 goto out;
222 }
223
224 data = au_readl(PSC_AC97CDC) & 0xffff;
225 au_sync();
226
227 /* Clear command done event.
228 */
229 au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT);
230 au_sync();
231
232 out:
233 spin_unlock_irqrestore(&s->lock, flags);
234
235 return data;
236}
237
238
239static void
240wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
241{
242 struct au1550_state *s = codec->private_data;
243 unsigned long flags;
244 u32 cmd, val;
245 int i;
246
247 spin_lock_irqsave(&s->lock, flags);
248
249 for (i = 0; i < POLL_COUNT; i++) {
250 val = au_readl(PSC_AC97STAT);
251 au_sync();
252 if (!(val & PSC_AC97STAT_CP))
253 break;
254 }
255 if (i == POLL_COUNT)
256 err("wrcodec: codec cmd pending expired!");
257
258 cmd = (u32)PSC_AC97CDC_INDX(addr);
259 cmd |= (u32)data;
260 au_writel(cmd, PSC_AC97CDC);
261 au_sync();
262
263 for (i = 0; i < POLL_COUNT; i++) {
264 val = au_readl(PSC_AC97STAT);
265 au_sync();
266 if (!(val & PSC_AC97STAT_CP))
267 break;
268 }
269 if (i == POLL_COUNT)
270 err("wrcodec: codec cmd pending expired!");
271
272 for (i = 0; i < POLL_COUNT; i++) {
273 val = au_readl(PSC_AC97EVNT);
274 au_sync();
275 if (val & PSC_AC97EVNT_CD)
276 break;
277 }
278 if (i == POLL_COUNT)
279 err("wrcodec: read cmdwait expired!");
280
281 /* Clear command done event.
282 */
283 au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT);
284 au_sync();
285
286 spin_unlock_irqrestore(&s->lock, flags);
287}
288
289static void
290waitcodec(struct ac97_codec *codec)
291{
292 u16 temp;
293 u32 val;
294 int i;
295
296 /* codec_wait is used to wait for a ready state after
297 * an AC97C_RESET.
298 */
299 au1550_delay(10);
300
301 /* first poll the CODEC_READY tag bit
302 */
303 for (i = 0; i < POLL_COUNT; i++) {
304 val = au_readl(PSC_AC97STAT);
305 au_sync();
306 if (val & PSC_AC97STAT_CR)
307 break;
308 }
309 if (i == POLL_COUNT) {
310 err("waitcodec: CODEC_READY poll expired!");
311 return;
312 }
313
314 /* get AC'97 powerdown control/status register
315 */
316 temp = rdcodec(codec, AC97_POWER_CONTROL);
317
318 /* If anything is powered down, power'em up
319 */
320 if (temp & 0x7f00) {
321 /* Power on
322 */
323 wrcodec(codec, AC97_POWER_CONTROL, 0);
324 au1550_delay(100);
325
326 /* Reread
327 */
328 temp = rdcodec(codec, AC97_POWER_CONTROL);
329 }
330
331 /* Check if Codec REF,ANL,DAC,ADC ready
332 */
333 if ((temp & 0x7f0f) != 0x000f)
334 err("codec reg 26 status (0x%x) not ready!!", temp);
335}
336
337/* stop the ADC before calling */
338static void
339set_adc_rate(struct au1550_state *s, unsigned rate)
340{
341 struct dmabuf *adc = &s->dma_adc;
342 struct dmabuf *dac = &s->dma_dac;
343 unsigned adc_rate, dac_rate;
344 u16 ac97_extstat;
345
346 if (s->no_vra) {
347 /* calc SRC factor
348 */
349 adc->src_factor = ((96000 / rate) + 1) >> 1;
350 adc->sample_rate = 48000 / adc->src_factor;
351 return;
352 }
353
354 adc->src_factor = 1;
355
356 ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
357
358 rate = rate > 48000 ? 48000 : rate;
359
360 /* enable VRA
361 */
362 wrcodec(s->codec, AC97_EXTENDED_STATUS,
363 ac97_extstat | AC97_EXTSTAT_VRA);
364
365 /* now write the sample rate
366 */
367 wrcodec(s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
368
369 /* read it back for actual supported rate
370 */
371 adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
372
373 pr_debug("set_adc_rate: set to %d Hz\n", adc_rate);
374
375 /* some codec's don't allow unequal DAC and ADC rates, in which case
376 * writing one rate reg actually changes both.
377 */
378 dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
379 if (dac->num_channels > 2)
380 wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
381 if (dac->num_channels > 4)
382 wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
383
384 adc->sample_rate = adc_rate;
385 dac->sample_rate = dac_rate;
386}
387
388/* stop the DAC before calling */
389static void
390set_dac_rate(struct au1550_state *s, unsigned rate)
391{
392 struct dmabuf *dac = &s->dma_dac;
393 struct dmabuf *adc = &s->dma_adc;
394 unsigned adc_rate, dac_rate;
395 u16 ac97_extstat;
396
397 if (s->no_vra) {
398 /* calc SRC factor
399 */
400 dac->src_factor = ((96000 / rate) + 1) >> 1;
401 dac->sample_rate = 48000 / dac->src_factor;
402 return;
403 }
404
405 dac->src_factor = 1;
406
407 ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
408
409 rate = rate > 48000 ? 48000 : rate;
410
411 /* enable VRA
412 */
413 wrcodec(s->codec, AC97_EXTENDED_STATUS,
414 ac97_extstat | AC97_EXTSTAT_VRA);
415
416 /* now write the sample rate
417 */
418 wrcodec(s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
419
420 /* I don't support different sample rates for multichannel,
421 * so make these channels the same.
422 */
423 if (dac->num_channels > 2)
424 wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
425 if (dac->num_channels > 4)
426 wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
427 /* read it back for actual supported rate
428 */
429 dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
430
431 pr_debug("set_dac_rate: set to %d Hz\n", dac_rate);
432
433 /* some codec's don't allow unequal DAC and ADC rates, in which case
434 * writing one rate reg actually changes both.
435 */
436 adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
437
438 dac->sample_rate = dac_rate;
439 adc->sample_rate = adc_rate;
440}
441
442static void
443stop_dac(struct au1550_state *s)
444{
445 struct dmabuf *db = &s->dma_dac;
446 u32 stat;
447 unsigned long flags;
448
449 if (db->stopped)
450 return;
451
452 spin_lock_irqsave(&s->lock, flags);
453
454 au_writel(PSC_AC97PCR_TP, PSC_AC97PCR);
455 au_sync();
456
457 /* Wait for Transmit Busy to show disabled.
458 */
459 do {
460 stat = au_readl(PSC_AC97STAT);
461 au_sync();
462 } while ((stat & PSC_AC97STAT_TB) != 0);
463
464 au1xxx_dbdma_reset(db->dmanr);
465
466 db->stopped = 1;
467
468 spin_unlock_irqrestore(&s->lock, flags);
469}
470
471static void
472stop_adc(struct au1550_state *s)
473{
474 struct dmabuf *db = &s->dma_adc;
475 unsigned long flags;
476 u32 stat;
477
478 if (db->stopped)
479 return;
480
481 spin_lock_irqsave(&s->lock, flags);
482
483 au_writel(PSC_AC97PCR_RP, PSC_AC97PCR);
484 au_sync();
485
486 /* Wait for Receive Busy to show disabled.
487 */
488 do {
489 stat = au_readl(PSC_AC97STAT);
490 au_sync();
491 } while ((stat & PSC_AC97STAT_RB) != 0);
492
493 au1xxx_dbdma_reset(db->dmanr);
494
495 db->stopped = 1;
496
497 spin_unlock_irqrestore(&s->lock, flags);
498}
499
500
501static void
502set_xmit_slots(int num_channels)
503{
504 u32 ac97_config, stat;
505
506 ac97_config = au_readl(PSC_AC97CFG);
507 au_sync();
508 ac97_config &= ~(PSC_AC97CFG_TXSLOT_MASK | PSC_AC97CFG_DE_ENABLE);
509 au_writel(ac97_config, PSC_AC97CFG);
510 au_sync();
511
512 switch (num_channels) {
513 case 6: /* stereo with surround and center/LFE,
514 * slots 3,4,6,7,8,9
515 */
516 ac97_config |= PSC_AC97CFG_TXSLOT_ENA(6);
517 ac97_config |= PSC_AC97CFG_TXSLOT_ENA(9);
518
519 case 4: /* stereo with surround, slots 3,4,7,8 */
520 ac97_config |= PSC_AC97CFG_TXSLOT_ENA(7);
521 ac97_config |= PSC_AC97CFG_TXSLOT_ENA(8);
522
523 case 2: /* stereo, slots 3,4 */
524 case 1: /* mono */
525 ac97_config |= PSC_AC97CFG_TXSLOT_ENA(3);
526 ac97_config |= PSC_AC97CFG_TXSLOT_ENA(4);
527 }
528
529 au_writel(ac97_config, PSC_AC97CFG);
530 au_sync();
531
532 ac97_config |= PSC_AC97CFG_DE_ENABLE;
533 au_writel(ac97_config, PSC_AC97CFG);
534 au_sync();
535
536 /* Wait for Device ready.
537 */
538 do {
539 stat = au_readl(PSC_AC97STAT);
540 au_sync();
541 } while ((stat & PSC_AC97STAT_DR) == 0);
542}
543
544static void
545set_recv_slots(int num_channels)
546{
547 u32 ac97_config, stat;
548
549 ac97_config = au_readl(PSC_AC97CFG);
550 au_sync();
551 ac97_config &= ~(PSC_AC97CFG_RXSLOT_MASK | PSC_AC97CFG_DE_ENABLE);
552 au_writel(ac97_config, PSC_AC97CFG);
553 au_sync();
554
555 /* Always enable slots 3 and 4 (stereo). Slot 6 is
556 * optional Mic ADC, which we don't support yet.
557 */
558 ac97_config |= PSC_AC97CFG_RXSLOT_ENA(3);
559 ac97_config |= PSC_AC97CFG_RXSLOT_ENA(4);
560
561 au_writel(ac97_config, PSC_AC97CFG);
562 au_sync();
563
564 ac97_config |= PSC_AC97CFG_DE_ENABLE;
565 au_writel(ac97_config, PSC_AC97CFG);
566 au_sync();
567
568 /* Wait for Device ready.
569 */
570 do {
571 stat = au_readl(PSC_AC97STAT);
572 au_sync();
573 } while ((stat & PSC_AC97STAT_DR) == 0);
574}
575
576/* Hold spinlock for both start_dac() and start_adc() calls */
577static void
578start_dac(struct au1550_state *s)
579{
580 struct dmabuf *db = &s->dma_dac;
581
582 if (!db->stopped)
583 return;
584
585 set_xmit_slots(db->num_channels);
586 au_writel(PSC_AC97PCR_TC, PSC_AC97PCR);
587 au_sync();
588 au_writel(PSC_AC97PCR_TS, PSC_AC97PCR);
589 au_sync();
590
591 au1xxx_dbdma_start(db->dmanr);
592
593 db->stopped = 0;
594}
595
596static void
597start_adc(struct au1550_state *s)
598{
599 struct dmabuf *db = &s->dma_adc;
600 int i;
601
602 if (!db->stopped)
603 return;
604
605 /* Put two buffers on the ring to get things started.
606 */
607 for (i=0; i<2; i++) {
608 au1xxx_dbdma_put_dest(db->dmanr, virt_to_phys(db->nextIn),
609 db->dma_fragsize, DDMA_FLAGS_IE);
610
611 db->nextIn += db->dma_fragsize;
612 if (db->nextIn >= db->rawbuf + db->dmasize)
613 db->nextIn -= db->dmasize;
614 }
615
616 set_recv_slots(db->num_channels);
617 au1xxx_dbdma_start(db->dmanr);
618 au_writel(PSC_AC97PCR_RC, PSC_AC97PCR);
619 au_sync();
620 au_writel(PSC_AC97PCR_RS, PSC_AC97PCR);
621 au_sync();
622
623 db->stopped = 0;
624}
625
626static int
627prog_dmabuf(struct au1550_state *s, struct dmabuf *db)
628{
629 unsigned user_bytes_per_sec;
630 unsigned bufs;
631 unsigned rate = db->sample_rate;
632
633 if (!db->rawbuf) {
634 db->ready = db->mapped = 0;
635 db->buforder = 5; /* 32 * PAGE_SIZE */
636 db->rawbuf = kmalloc((PAGE_SIZE << db->buforder), GFP_KERNEL);
637 if (!db->rawbuf)
638 return -ENOMEM;
639 }
640
641 db->cnt_factor = 1;
642 if (db->sample_size == 8)
643 db->cnt_factor *= 2;
644 if (db->num_channels == 1)
645 db->cnt_factor *= 2;
646 db->cnt_factor *= db->src_factor;
647
648 db->count = 0;
649 db->dma_qcount = 0;
650 db->nextIn = db->nextOut = db->rawbuf;
651
652 db->user_bytes_per_sample = (db->sample_size>>3) * db->num_channels;
653 db->dma_bytes_per_sample = 2 * ((db->num_channels == 1) ?
654 2 : db->num_channels);
655
656 user_bytes_per_sec = rate * db->user_bytes_per_sample;
657 bufs = PAGE_SIZE << db->buforder;
658 if (db->ossfragshift) {
659 if ((1000 << db->ossfragshift) < user_bytes_per_sec)
660 db->fragshift = ld2(user_bytes_per_sec/1000);
661 else
662 db->fragshift = db->ossfragshift;
663 } else {
664 db->fragshift = ld2(user_bytes_per_sec / 100 /
665 (db->subdivision ? db->subdivision : 1));
666 if (db->fragshift < 3)
667 db->fragshift = 3;
668 }
669
670 db->fragsize = 1 << db->fragshift;
671 db->dma_fragsize = db->fragsize * db->cnt_factor;
672 db->numfrag = bufs / db->dma_fragsize;
673
674 while (db->numfrag < 4 && db->fragshift > 3) {
675 db->fragshift--;
676 db->fragsize = 1 << db->fragshift;
677 db->dma_fragsize = db->fragsize * db->cnt_factor;
678 db->numfrag = bufs / db->dma_fragsize;
679 }
680
681 if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
682 db->numfrag = db->ossmaxfrags;
683
684 db->dmasize = db->dma_fragsize * db->numfrag;
685 memset(db->rawbuf, 0, bufs);
686
687 pr_debug("prog_dmabuf: rate=%d, samplesize=%d, channels=%d\n",
688 rate, db->sample_size, db->num_channels);
689 pr_debug("prog_dmabuf: fragsize=%d, cnt_factor=%d, dma_fragsize=%d\n",
690 db->fragsize, db->cnt_factor, db->dma_fragsize);
691 pr_debug("prog_dmabuf: numfrag=%d, dmasize=%d\n", db->numfrag, db->dmasize);
692
693 db->ready = 1;
694 return 0;
695}
696
697static int
698prog_dmabuf_adc(struct au1550_state *s)
699{
700 stop_adc(s);
701 return prog_dmabuf(s, &s->dma_adc);
702
703}
704
705static int
706prog_dmabuf_dac(struct au1550_state *s)
707{
708 stop_dac(s);
709 return prog_dmabuf(s, &s->dma_dac);
710}
711
712
713static void dac_dma_interrupt(int irq, void *dev_id)
714{
715 struct au1550_state *s = (struct au1550_state *) dev_id;
716 struct dmabuf *db = &s->dma_dac;
717 u32 ac97c_stat;
718
719 spin_lock(&s->lock);
720
721 ac97c_stat = au_readl(PSC_AC97STAT);
722 if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE))
723 pr_debug("AC97C status = 0x%08x\n", ac97c_stat);
724 db->dma_qcount--;
725
726 if (db->count >= db->fragsize) {
727 if (au1xxx_dbdma_put_source(db->dmanr,
728 virt_to_phys(db->nextOut), db->fragsize,
729 DDMA_FLAGS_IE) == 0) {
730 err("qcount < 2 and no ring room!");
731 }
732 db->nextOut += db->fragsize;
733 if (db->nextOut >= db->rawbuf + db->dmasize)
734 db->nextOut -= db->dmasize;
735 db->count -= db->fragsize;
736 db->total_bytes += db->dma_fragsize;
737 db->dma_qcount++;
738 }
739
740 /* wake up anybody listening */
741 if (waitqueue_active(&db->wait))
742 wake_up(&db->wait);
743
744 spin_unlock(&s->lock);
745}
746
747
748static void adc_dma_interrupt(int irq, void *dev_id)
749{
750 struct au1550_state *s = (struct au1550_state *)dev_id;
751 struct dmabuf *dp = &s->dma_adc;
752 u32 obytes;
753 char *obuf;
754
755 spin_lock(&s->lock);
756
757 /* Pull the buffer from the dma queue.
758 */
759 au1xxx_dbdma_get_dest(dp->dmanr, (void *)(&obuf), &obytes);
760
761 if ((dp->count + obytes) > dp->dmasize) {
762 /* Overrun. Stop ADC and log the error
763 */
764 spin_unlock(&s->lock);
765 stop_adc(s);
766 dp->error++;
767 err("adc overrun");
768 return;
769 }
770
771 /* Put a new empty buffer on the destination DMA.
772 */
773 au1xxx_dbdma_put_dest(dp->dmanr, virt_to_phys(dp->nextIn),
774 dp->dma_fragsize, DDMA_FLAGS_IE);
775
776 dp->nextIn += dp->dma_fragsize;
777 if (dp->nextIn >= dp->rawbuf + dp->dmasize)
778 dp->nextIn -= dp->dmasize;
779
780 dp->count += obytes;
781 dp->total_bytes += obytes;
782
783 /* wake up anybody listening
784 */
785 if (waitqueue_active(&dp->wait))
786 wake_up(&dp->wait);
787
788 spin_unlock(&s->lock);
789}
790
791static loff_t
792au1550_llseek(struct file *file, loff_t offset, int origin)
793{
794 return -ESPIPE;
795}
796
797
798static int
799au1550_open_mixdev(struct inode *inode, struct file *file)
800{
801 mutex_lock(&au1550_ac97_mutex);
802 file->private_data = &au1550_state;
803 mutex_unlock(&au1550_ac97_mutex);
804 return 0;
805}
806
807static int
808au1550_release_mixdev(struct inode *inode, struct file *file)
809{
810 return 0;
811}
812
813static int
814mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
815 unsigned long arg)
816{
817 return codec->mixer_ioctl(codec, cmd, arg);
818}
819
820static long
821au1550_ioctl_mixdev(struct file *file, unsigned int cmd, unsigned long arg)
822{
823 struct au1550_state *s = file->private_data;
824 struct ac97_codec *codec = s->codec;
825 int ret;
826
827 mutex_lock(&au1550_ac97_mutex);
828 ret = mixdev_ioctl(codec, cmd, arg);
829 mutex_unlock(&au1550_ac97_mutex);
830
831 return ret;
832}
833
834static /*const */ struct file_operations au1550_mixer_fops = {
835 .owner = THIS_MODULE,
836 .llseek = au1550_llseek,
837 .unlocked_ioctl = au1550_ioctl_mixdev,
838 .open = au1550_open_mixdev,
839 .release = au1550_release_mixdev,
840};
841
842static int
843drain_dac(struct au1550_state *s, int nonblock)
844{
845 unsigned long flags;
846 int count, tmo;
847
848 if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped)
849 return 0;
850
851 for (;;) {
852 spin_lock_irqsave(&s->lock, flags);
853 count = s->dma_dac.count;
854 spin_unlock_irqrestore(&s->lock, flags);
855 if (count <= s->dma_dac.fragsize)
856 break;
857 if (signal_pending(current))
858 break;
859 if (nonblock)
860 return -EBUSY;
861 tmo = 1000 * count / (s->no_vra ?
862 48000 : s->dma_dac.sample_rate);
863 tmo /= s->dma_dac.dma_bytes_per_sample;
864 au1550_delay(tmo);
865 }
866 if (signal_pending(current))
867 return -ERESTARTSYS;
868 return 0;
869}
870
871static inline u8 S16_TO_U8(s16 ch)
872{
873 return (u8) (ch >> 8) + 0x80;
874}
875static inline s16 U8_TO_S16(u8 ch)
876{
877 return (s16) (ch - 0x80) << 8;
878}
879
880/*
881 * Translates user samples to dma buffer suitable for AC'97 DAC data:
882 * If mono, copy left channel to right channel in dma buffer.
883 * If 8 bit samples, cvt to 16-bit before writing to dma buffer.
884 * If interpolating (no VRA), duplicate every audio frame src_factor times.
885 */
886static int
887translate_from_user(struct dmabuf *db, char* dmabuf, char* userbuf,
888 int dmacount)
889{
890 int sample, i;
891 int interp_bytes_per_sample;
892 int num_samples;
893 int mono = (db->num_channels == 1);
894 char usersample[12];
895 s16 ch, dmasample[6];
896
897 if (db->sample_size == 16 && !mono && db->src_factor == 1) {
898 /* no translation necessary, just copy
899 */
900 if (copy_from_user(dmabuf, userbuf, dmacount))
901 return -EFAULT;
902 return dmacount;
903 }
904
905 interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
906 num_samples = dmacount / interp_bytes_per_sample;
907
908 for (sample = 0; sample < num_samples; sample++) {
909 if (copy_from_user(usersample, userbuf,
910 db->user_bytes_per_sample)) {
911 return -EFAULT;
912 }
913
914 for (i = 0; i < db->num_channels; i++) {
915 if (db->sample_size == 8)
916 ch = U8_TO_S16(usersample[i]);
917 else
918 ch = *((s16 *) (&usersample[i * 2]));
919 dmasample[i] = ch;
920 if (mono)
921 dmasample[i + 1] = ch; /* right channel */
922 }
923
924 /* duplicate every audio frame src_factor times
925 */
926 for (i = 0; i < db->src_factor; i++)
927 memcpy(dmabuf, dmasample, db->dma_bytes_per_sample);
928
929 userbuf += db->user_bytes_per_sample;
930 dmabuf += interp_bytes_per_sample;
931 }
932
933 return num_samples * interp_bytes_per_sample;
934}
935
936/*
937 * Translates AC'97 ADC samples to user buffer:
938 * If mono, send only left channel to user buffer.
939 * If 8 bit samples, cvt from 16 to 8 bit before writing to user buffer.
940 * If decimating (no VRA), skip over src_factor audio frames.
941 */
942static int
943translate_to_user(struct dmabuf *db, char* userbuf, char* dmabuf,
944 int dmacount)
945{
946 int sample, i;
947 int interp_bytes_per_sample;
948 int num_samples;
949 int mono = (db->num_channels == 1);
950 char usersample[12];
951
952 if (db->sample_size == 16 && !mono && db->src_factor == 1) {
953 /* no translation necessary, just copy
954 */
955 if (copy_to_user(userbuf, dmabuf, dmacount))
956 return -EFAULT;
957 return dmacount;
958 }
959
960 interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
961 num_samples = dmacount / interp_bytes_per_sample;
962
963 for (sample = 0; sample < num_samples; sample++) {
964 for (i = 0; i < db->num_channels; i++) {
965 if (db->sample_size == 8)
966 usersample[i] =
967 S16_TO_U8(*((s16 *) (&dmabuf[i * 2])));
968 else
969 *((s16 *) (&usersample[i * 2])) =
970 *((s16 *) (&dmabuf[i * 2]));
971 }
972
973 if (copy_to_user(userbuf, usersample,
974 db->user_bytes_per_sample)) {
975 return -EFAULT;
976 }
977
978 userbuf += db->user_bytes_per_sample;
979 dmabuf += interp_bytes_per_sample;
980 }
981
982 return num_samples * interp_bytes_per_sample;
983}
984
985/*
986 * Copy audio data to/from user buffer from/to dma buffer, taking care
987 * that we wrap when reading/writing the dma buffer. Returns actual byte
988 * count written to or read from the dma buffer.
989 */
990static int
991copy_dmabuf_user(struct dmabuf *db, char* userbuf, int count, int to_user)
992{
993 char *bufptr = to_user ? db->nextOut : db->nextIn;
994 char *bufend = db->rawbuf + db->dmasize;
995 int cnt, ret;
996
997 if (bufptr + count > bufend) {
998 int partial = (int) (bufend - bufptr);
999 if (to_user) {
1000 if ((cnt = translate_to_user(db, userbuf,
1001 bufptr, partial)) < 0)
1002 return cnt;
1003 ret = cnt;
1004 if ((cnt = translate_to_user(db, userbuf + partial,
1005 db->rawbuf,
1006 count - partial)) < 0)
1007 return cnt;
1008 ret += cnt;
1009 } else {
1010 if ((cnt = translate_from_user(db, bufptr, userbuf,
1011 partial)) < 0)
1012 return cnt;
1013 ret = cnt;
1014 if ((cnt = translate_from_user(db, db->rawbuf,
1015 userbuf + partial,
1016 count - partial)) < 0)
1017 return cnt;
1018 ret += cnt;
1019 }
1020 } else {
1021 if (to_user)
1022 ret = translate_to_user(db, userbuf, bufptr, count);
1023 else
1024 ret = translate_from_user(db, bufptr, userbuf, count);
1025 }
1026
1027 return ret;
1028}
1029
1030
1031static ssize_t
1032au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
1033{
1034 struct au1550_state *s = file->private_data;
1035 struct dmabuf *db = &s->dma_adc;
1036 DECLARE_WAITQUEUE(wait, current);
1037 ssize_t ret;
1038 unsigned long flags;
1039 int cnt, usercnt, avail;
1040
1041 if (db->mapped)
1042 return -ENXIO;
1043 if (!access_ok(VERIFY_WRITE, buffer, count))
1044 return -EFAULT;
1045 ret = 0;
1046
1047 count *= db->cnt_factor;
1048
1049 mutex_lock(&s->sem);
1050 add_wait_queue(&db->wait, &wait);
1051
1052 while (count > 0) {
1053 /* wait for samples in ADC dma buffer
1054 */
1055 do {
1056 spin_lock_irqsave(&s->lock, flags);
1057 if (db->stopped)
1058 start_adc(s);
1059 avail = db->count;
1060 if (avail <= 0)
1061 __set_current_state(TASK_INTERRUPTIBLE);
1062 spin_unlock_irqrestore(&s->lock, flags);
1063 if (avail <= 0) {
1064 if (file->f_flags & O_NONBLOCK) {
1065 if (!ret)
1066 ret = -EAGAIN;
1067 goto out;
1068 }
1069 mutex_unlock(&s->sem);
1070 schedule();
1071 if (signal_pending(current)) {
1072 if (!ret)
1073 ret = -ERESTARTSYS;
1074 goto out2;
1075 }
1076 mutex_lock(&s->sem);
1077 }
1078 } while (avail <= 0);
1079
1080 /* copy from nextOut to user
1081 */
1082 if ((cnt = copy_dmabuf_user(db, buffer,
1083 count > avail ?
1084 avail : count, 1)) < 0) {
1085 if (!ret)
1086 ret = -EFAULT;
1087 goto out;
1088 }
1089
1090 spin_lock_irqsave(&s->lock, flags);
1091 db->count -= cnt;
1092 db->nextOut += cnt;
1093 if (db->nextOut >= db->rawbuf + db->dmasize)
1094 db->nextOut -= db->dmasize;
1095 spin_unlock_irqrestore(&s->lock, flags);
1096
1097 count -= cnt;
1098 usercnt = cnt / db->cnt_factor;
1099 buffer += usercnt;
1100 ret += usercnt;
1101 } /* while (count > 0) */
1102
1103out:
1104 mutex_unlock(&s->sem);
1105out2:
1106 remove_wait_queue(&db->wait, &wait);
1107 set_current_state(TASK_RUNNING);
1108 return ret;
1109}
1110
1111static ssize_t
1112au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
1113{
1114 struct au1550_state *s = file->private_data;
1115 struct dmabuf *db = &s->dma_dac;
1116 DECLARE_WAITQUEUE(wait, current);
1117 ssize_t ret = 0;
1118 unsigned long flags;
1119 int cnt, usercnt, avail;
1120
1121 pr_debug("write: count=%d\n", count);
1122
1123 if (db->mapped)
1124 return -ENXIO;
1125 if (!access_ok(VERIFY_READ, buffer, count))
1126 return -EFAULT;
1127
1128 count *= db->cnt_factor;
1129
1130 mutex_lock(&s->sem);
1131 add_wait_queue(&db->wait, &wait);
1132
1133 while (count > 0) {
1134 /* wait for space in playback buffer
1135 */
1136 do {
1137 spin_lock_irqsave(&s->lock, flags);
1138 avail = (int) db->dmasize - db->count;
1139 if (avail <= 0)
1140 __set_current_state(TASK_INTERRUPTIBLE);
1141 spin_unlock_irqrestore(&s->lock, flags);
1142 if (avail <= 0) {
1143 if (file->f_flags & O_NONBLOCK) {
1144 if (!ret)
1145 ret = -EAGAIN;
1146 goto out;
1147 }
1148 mutex_unlock(&s->sem);
1149 schedule();
1150 if (signal_pending(current)) {
1151 if (!ret)
1152 ret = -ERESTARTSYS;
1153 goto out2;
1154 }
1155 mutex_lock(&s->sem);
1156 }
1157 } while (avail <= 0);
1158
1159 /* copy from user to nextIn
1160 */
1161 if ((cnt = copy_dmabuf_user(db, (char *) buffer,
1162 count > avail ?
1163 avail : count, 0)) < 0) {
1164 if (!ret)
1165 ret = -EFAULT;
1166 goto out;
1167 }
1168
1169 spin_lock_irqsave(&s->lock, flags);
1170 db->count += cnt;
1171 db->nextIn += cnt;
1172 if (db->nextIn >= db->rawbuf + db->dmasize)
1173 db->nextIn -= db->dmasize;
1174
1175 /* If the data is available, we want to keep two buffers
1176 * on the dma queue. If the queue count reaches zero,
1177 * we know the dma has stopped.
1178 */
1179 while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) {
1180 if (au1xxx_dbdma_put_source(db->dmanr,
1181 virt_to_phys(db->nextOut), db->fragsize,
1182 DDMA_FLAGS_IE) == 0) {
1183 err("qcount < 2 and no ring room!");
1184 }
1185 db->nextOut += db->fragsize;
1186 if (db->nextOut >= db->rawbuf + db->dmasize)
1187 db->nextOut -= db->dmasize;
1188 db->total_bytes += db->dma_fragsize;
1189 if (db->dma_qcount == 0)
1190 start_dac(s);
1191 db->dma_qcount++;
1192 }
1193 spin_unlock_irqrestore(&s->lock, flags);
1194
1195 count -= cnt;
1196 usercnt = cnt / db->cnt_factor;
1197 buffer += usercnt;
1198 ret += usercnt;
1199 } /* while (count > 0) */
1200
1201out:
1202 mutex_unlock(&s->sem);
1203out2:
1204 remove_wait_queue(&db->wait, &wait);
1205 set_current_state(TASK_RUNNING);
1206 return ret;
1207}
1208
1209
1210/* No kernel lock - we have our own spinlock */
1211static unsigned int
1212au1550_poll(struct file *file, struct poll_table_struct *wait)
1213{
1214 struct au1550_state *s = file->private_data;
1215 unsigned long flags;
1216 unsigned int mask = 0;
1217
1218 if (file->f_mode & FMODE_WRITE) {
1219 if (!s->dma_dac.ready)
1220 return 0;
1221 poll_wait(file, &s->dma_dac.wait, wait);
1222 }
1223 if (file->f_mode & FMODE_READ) {
1224 if (!s->dma_adc.ready)
1225 return 0;
1226 poll_wait(file, &s->dma_adc.wait, wait);
1227 }
1228
1229 spin_lock_irqsave(&s->lock, flags);
1230
1231 if (file->f_mode & FMODE_READ) {
1232 if (s->dma_adc.count >= (signed)s->dma_adc.dma_fragsize)
1233 mask |= POLLIN | POLLRDNORM;
1234 }
1235 if (file->f_mode & FMODE_WRITE) {
1236 if (s->dma_dac.mapped) {
1237 if (s->dma_dac.count >=
1238 (signed)s->dma_dac.dma_fragsize)
1239 mask |= POLLOUT | POLLWRNORM;
1240 } else {
1241 if ((signed) s->dma_dac.dmasize >=
1242 s->dma_dac.count + (signed)s->dma_dac.dma_fragsize)
1243 mask |= POLLOUT | POLLWRNORM;
1244 }
1245 }
1246 spin_unlock_irqrestore(&s->lock, flags);
1247 return mask;
1248}
1249
1250static int
1251au1550_mmap(struct file *file, struct vm_area_struct *vma)
1252{
1253 struct au1550_state *s = file->private_data;
1254 struct dmabuf *db;
1255 unsigned long size;
1256 int ret = 0;
1257
1258 mutex_lock(&au1550_ac97_mutex);
1259 mutex_lock(&s->sem);
1260 if (vma->vm_flags & VM_WRITE)
1261 db = &s->dma_dac;
1262 else if (vma->vm_flags & VM_READ)
1263 db = &s->dma_adc;
1264 else {
1265 ret = -EINVAL;
1266 goto out;
1267 }
1268 if (vma->vm_pgoff != 0) {
1269 ret = -EINVAL;
1270 goto out;
1271 }
1272 size = vma->vm_end - vma->vm_start;
1273 if (size > (PAGE_SIZE << db->buforder)) {
1274 ret = -EINVAL;
1275 goto out;
1276 }
1277 if (remap_pfn_range(vma, vma->vm_start, page_to_pfn(virt_to_page(db->rawbuf)),
1278 size, vma->vm_page_prot)) {
1279 ret = -EAGAIN;
1280 goto out;
1281 }
1282 vma->vm_flags &= ~VM_IO;
1283 db->mapped = 1;
1284out:
1285 mutex_unlock(&s->sem);
1286 mutex_unlock(&au1550_ac97_mutex);
1287 return ret;
1288}
1289
1290#ifdef DEBUG
1291static struct ioctl_str_t {
1292 unsigned int cmd;
1293 const char *str;
1294} ioctl_str[] = {
1295 {SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
1296 {SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
1297 {SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
1298 {SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
1299 {SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
1300 {SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
1301 {SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
1302 {SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
1303 {SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
1304 {SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
1305 {SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
1306 {SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
1307 {SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
1308 {SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
1309 {SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
1310 {SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
1311 {SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
1312 {SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
1313 {SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
1314 {SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
1315 {SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
1316 {SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
1317 {SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
1318 {SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
1319 {SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
1320 {SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
1321 {SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
1322 {SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
1323 {SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
1324 {OSS_GETVERSION, "OSS_GETVERSION"},
1325 {SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
1326 {SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
1327 {SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
1328 {SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
1329};
1330#endif
1331
1332static int
1333dma_count_done(struct dmabuf *db)
1334{
1335 if (db->stopped)
1336 return 0;
1337
1338 return db->dma_fragsize - au1xxx_get_dma_residue(db->dmanr);
1339}
1340
1341
1342static int
1343au1550_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1344{
1345 struct au1550_state *s = file->private_data;
1346 unsigned long flags;
1347 audio_buf_info abinfo;
1348 count_info cinfo;
1349 int count;
1350 int val, mapped, ret, diff;
1351
1352 mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
1353 ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
1354
1355#ifdef DEBUG
1356 for (count = 0; count < ARRAY_SIZE(ioctl_str); count++) {
1357 if (ioctl_str[count].cmd == cmd)
1358 break;
1359 }
1360 if (count < ARRAY_SIZE(ioctl_str))
1361 pr_debug("ioctl %s, arg=0x%lxn", ioctl_str[count].str, arg);
1362 else
1363 pr_debug("ioctl 0x%x unknown, arg=0x%lx\n", cmd, arg);
1364#endif
1365
1366 switch (cmd) {
1367 case OSS_GETVERSION:
1368 return put_user(SOUND_VERSION, (int *) arg);
1369
1370 case SNDCTL_DSP_SYNC:
1371 if (file->f_mode & FMODE_WRITE)
1372 return drain_dac(s, file->f_flags & O_NONBLOCK);
1373 return 0;
1374
1375 case SNDCTL_DSP_SETDUPLEX:
1376 return 0;
1377
1378 case SNDCTL_DSP_GETCAPS:
1379 return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
1380 DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
1381
1382 case SNDCTL_DSP_RESET:
1383 if (file->f_mode & FMODE_WRITE) {
1384 stop_dac(s);
1385 synchronize_irq();
1386 s->dma_dac.count = s->dma_dac.total_bytes = 0;
1387 s->dma_dac.nextIn = s->dma_dac.nextOut =
1388 s->dma_dac.rawbuf;
1389 }
1390 if (file->f_mode & FMODE_READ) {
1391 stop_adc(s);
1392 synchronize_irq();
1393 s->dma_adc.count = s->dma_adc.total_bytes = 0;
1394 s->dma_adc.nextIn = s->dma_adc.nextOut =
1395 s->dma_adc.rawbuf;
1396 }
1397 return 0;
1398
1399 case SNDCTL_DSP_SPEED:
1400 if (get_user(val, (int *) arg))
1401 return -EFAULT;
1402 if (val >= 0) {
1403 if (file->f_mode & FMODE_READ) {
1404 stop_adc(s);
1405 set_adc_rate(s, val);
1406 }
1407 if (file->f_mode & FMODE_WRITE) {
1408 stop_dac(s);
1409 set_dac_rate(s, val);
1410 }
1411 if (s->open_mode & FMODE_READ)
1412 if ((ret = prog_dmabuf_adc(s)))
1413 return ret;
1414 if (s->open_mode & FMODE_WRITE)
1415 if ((ret = prog_dmabuf_dac(s)))
1416 return ret;
1417 }
1418 return put_user((file->f_mode & FMODE_READ) ?
1419 s->dma_adc.sample_rate :
1420 s->dma_dac.sample_rate,
1421 (int *)arg);
1422
1423 case SNDCTL_DSP_STEREO:
1424 if (get_user(val, (int *) arg))
1425 return -EFAULT;
1426 if (file->f_mode & FMODE_READ) {
1427 stop_adc(s);
1428 s->dma_adc.num_channels = val ? 2 : 1;
1429 if ((ret = prog_dmabuf_adc(s)))
1430 return ret;
1431 }
1432 if (file->f_mode & FMODE_WRITE) {
1433 stop_dac(s);
1434 s->dma_dac.num_channels = val ? 2 : 1;
1435 if (s->codec_ext_caps & AC97_EXT_DACS) {
1436 /* disable surround and center/lfe in AC'97
1437 */
1438 u16 ext_stat = rdcodec(s->codec,
1439 AC97_EXTENDED_STATUS);
1440 wrcodec(s->codec, AC97_EXTENDED_STATUS,
1441 ext_stat | (AC97_EXTSTAT_PRI |
1442 AC97_EXTSTAT_PRJ |
1443 AC97_EXTSTAT_PRK));
1444 }
1445 if ((ret = prog_dmabuf_dac(s)))
1446 return ret;
1447 }
1448 return 0;
1449
1450 case SNDCTL_DSP_CHANNELS:
1451 if (get_user(val, (int *) arg))
1452 return -EFAULT;
1453 if (val != 0) {
1454 if (file->f_mode & FMODE_READ) {
1455 if (val < 0 || val > 2)
1456 return -EINVAL;
1457 stop_adc(s);
1458 s->dma_adc.num_channels = val;
1459 if ((ret = prog_dmabuf_adc(s)))
1460 return ret;
1461 }
1462 if (file->f_mode & FMODE_WRITE) {
1463 switch (val) {
1464 case 1:
1465 case 2:
1466 break;
1467 case 3:
1468 case 5:
1469 return -EINVAL;
1470 case 4:
1471 if (!(s->codec_ext_caps &
1472 AC97_EXTID_SDAC))
1473 return -EINVAL;
1474 break;
1475 case 6:
1476 if ((s->codec_ext_caps &
1477 AC97_EXT_DACS) != AC97_EXT_DACS)
1478 return -EINVAL;
1479 break;
1480 default:
1481 return -EINVAL;
1482 }
1483
1484 stop_dac(s);
1485 if (val <= 2 &&
1486 (s->codec_ext_caps & AC97_EXT_DACS)) {
1487 /* disable surround and center/lfe
1488 * channels in AC'97
1489 */
1490 u16 ext_stat =
1491 rdcodec(s->codec,
1492 AC97_EXTENDED_STATUS);
1493 wrcodec(s->codec,
1494 AC97_EXTENDED_STATUS,
1495 ext_stat | (AC97_EXTSTAT_PRI |
1496 AC97_EXTSTAT_PRJ |
1497 AC97_EXTSTAT_PRK));
1498 } else if (val >= 4) {
1499 /* enable surround, center/lfe
1500 * channels in AC'97
1501 */
1502 u16 ext_stat =
1503 rdcodec(s->codec,
1504 AC97_EXTENDED_STATUS);
1505 ext_stat &= ~AC97_EXTSTAT_PRJ;
1506 if (val == 6)
1507 ext_stat &=
1508 ~(AC97_EXTSTAT_PRI |
1509 AC97_EXTSTAT_PRK);
1510 wrcodec(s->codec,
1511 AC97_EXTENDED_STATUS,
1512 ext_stat);
1513 }
1514
1515 s->dma_dac.num_channels = val;
1516 if ((ret = prog_dmabuf_dac(s)))
1517 return ret;
1518 }
1519 }
1520 return put_user(val, (int *) arg);
1521
1522 case SNDCTL_DSP_GETFMTS: /* Returns a mask */
1523 return put_user(AFMT_S16_LE | AFMT_U8, (int *) arg);
1524
1525 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
1526 if (get_user(val, (int *) arg))
1527 return -EFAULT;
1528 if (val != AFMT_QUERY) {
1529 if (file->f_mode & FMODE_READ) {
1530 stop_adc(s);
1531 if (val == AFMT_S16_LE)
1532 s->dma_adc.sample_size = 16;
1533 else {
1534 val = AFMT_U8;
1535 s->dma_adc.sample_size = 8;
1536 }
1537 if ((ret = prog_dmabuf_adc(s)))
1538 return ret;
1539 }
1540 if (file->f_mode & FMODE_WRITE) {
1541 stop_dac(s);
1542 if (val == AFMT_S16_LE)
1543 s->dma_dac.sample_size = 16;
1544 else {
1545 val = AFMT_U8;
1546 s->dma_dac.sample_size = 8;
1547 }
1548 if ((ret = prog_dmabuf_dac(s)))
1549 return ret;
1550 }
1551 } else {
1552 if (file->f_mode & FMODE_READ)
1553 val = (s->dma_adc.sample_size == 16) ?
1554 AFMT_S16_LE : AFMT_U8;
1555 else
1556 val = (s->dma_dac.sample_size == 16) ?
1557 AFMT_S16_LE : AFMT_U8;
1558 }
1559 return put_user(val, (int *) arg);
1560
1561 case SNDCTL_DSP_POST:
1562 return 0;
1563
1564 case SNDCTL_DSP_GETTRIGGER:
1565 val = 0;
1566 spin_lock_irqsave(&s->lock, flags);
1567 if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
1568 val |= PCM_ENABLE_INPUT;
1569 if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
1570 val |= PCM_ENABLE_OUTPUT;
1571 spin_unlock_irqrestore(&s->lock, flags);
1572 return put_user(val, (int *) arg);
1573
1574 case SNDCTL_DSP_SETTRIGGER:
1575 if (get_user(val, (int *) arg))
1576 return -EFAULT;
1577 if (file->f_mode & FMODE_READ) {
1578 if (val & PCM_ENABLE_INPUT) {
1579 spin_lock_irqsave(&s->lock, flags);
1580 start_adc(s);
1581 spin_unlock_irqrestore(&s->lock, flags);
1582 } else
1583 stop_adc(s);
1584 }
1585 if (file->f_mode & FMODE_WRITE) {
1586 if (val & PCM_ENABLE_OUTPUT) {
1587 spin_lock_irqsave(&s->lock, flags);
1588 start_dac(s);
1589 spin_unlock_irqrestore(&s->lock, flags);
1590 } else
1591 stop_dac(s);
1592 }
1593 return 0;
1594
1595 case SNDCTL_DSP_GETOSPACE:
1596 if (!(file->f_mode & FMODE_WRITE))
1597 return -EINVAL;
1598 abinfo.fragsize = s->dma_dac.fragsize;
1599 spin_lock_irqsave(&s->lock, flags);
1600 count = s->dma_dac.count;
1601 count -= dma_count_done(&s->dma_dac);
1602 spin_unlock_irqrestore(&s->lock, flags);
1603 if (count < 0)
1604 count = 0;
1605 abinfo.bytes = (s->dma_dac.dmasize - count) /
1606 s->dma_dac.cnt_factor;
1607 abinfo.fragstotal = s->dma_dac.numfrag;
1608 abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
1609 pr_debug("ioctl SNDCTL_DSP_GETOSPACE: bytes=%d, fragments=%d\n", abinfo.bytes, abinfo.fragments);
1610 return copy_to_user((void *) arg, &abinfo,
1611 sizeof(abinfo)) ? -EFAULT : 0;
1612
1613 case SNDCTL_DSP_GETISPACE:
1614 if (!(file->f_mode & FMODE_READ))
1615 return -EINVAL;
1616 abinfo.fragsize = s->dma_adc.fragsize;
1617 spin_lock_irqsave(&s->lock, flags);
1618 count = s->dma_adc.count;
1619 count += dma_count_done(&s->dma_adc);
1620 spin_unlock_irqrestore(&s->lock, flags);
1621 if (count < 0)
1622 count = 0;
1623 abinfo.bytes = count / s->dma_adc.cnt_factor;
1624 abinfo.fragstotal = s->dma_adc.numfrag;
1625 abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
1626 return copy_to_user((void *) arg, &abinfo,
1627 sizeof(abinfo)) ? -EFAULT : 0;
1628
1629 case SNDCTL_DSP_NONBLOCK:
1630 spin_lock(&file->f_lock);
1631 file->f_flags |= O_NONBLOCK;
1632 spin_unlock(&file->f_lock);
1633 return 0;
1634
1635 case SNDCTL_DSP_GETODELAY:
1636 if (!(file->f_mode & FMODE_WRITE))
1637 return -EINVAL;
1638 spin_lock_irqsave(&s->lock, flags);
1639 count = s->dma_dac.count;
1640 count -= dma_count_done(&s->dma_dac);
1641 spin_unlock_irqrestore(&s->lock, flags);
1642 if (count < 0)
1643 count = 0;
1644 count /= s->dma_dac.cnt_factor;
1645 return put_user(count, (int *) arg);
1646
1647 case SNDCTL_DSP_GETIPTR:
1648 if (!(file->f_mode & FMODE_READ))
1649 return -EINVAL;
1650 spin_lock_irqsave(&s->lock, flags);
1651 cinfo.bytes = s->dma_adc.total_bytes;
1652 count = s->dma_adc.count;
1653 if (!s->dma_adc.stopped) {
1654 diff = dma_count_done(&s->dma_adc);
1655 count += diff;
1656 cinfo.bytes += diff;
1657 cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) + diff -
1658 virt_to_phys(s->dma_adc.rawbuf);
1659 } else
1660 cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) -
1661 virt_to_phys(s->dma_adc.rawbuf);
1662 if (s->dma_adc.mapped)
1663 s->dma_adc.count &= (s->dma_adc.dma_fragsize-1);
1664 spin_unlock_irqrestore(&s->lock, flags);
1665 if (count < 0)
1666 count = 0;
1667 cinfo.blocks = count >> s->dma_adc.fragshift;
1668 return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
1669
1670 case SNDCTL_DSP_GETOPTR:
1671 if (!(file->f_mode & FMODE_READ))
1672 return -EINVAL;
1673 spin_lock_irqsave(&s->lock, flags);
1674 cinfo.bytes = s->dma_dac.total_bytes;
1675 count = s->dma_dac.count;
1676 if (!s->dma_dac.stopped) {
1677 diff = dma_count_done(&s->dma_dac);
1678 count -= diff;
1679 cinfo.bytes += diff;
1680 cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) + diff -
1681 virt_to_phys(s->dma_dac.rawbuf);
1682 } else
1683 cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) -
1684 virt_to_phys(s->dma_dac.rawbuf);
1685 if (s->dma_dac.mapped)
1686 s->dma_dac.count &= (s->dma_dac.dma_fragsize-1);
1687 spin_unlock_irqrestore(&s->lock, flags);
1688 if (count < 0)
1689 count = 0;
1690 cinfo.blocks = count >> s->dma_dac.fragshift;
1691 return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
1692
1693 case SNDCTL_DSP_GETBLKSIZE:
1694 if (file->f_mode & FMODE_WRITE)
1695 return put_user(s->dma_dac.fragsize, (int *) arg);
1696 else
1697 return put_user(s->dma_adc.fragsize, (int *) arg);
1698
1699 case SNDCTL_DSP_SETFRAGMENT:
1700 if (get_user(val, (int *) arg))
1701 return -EFAULT;
1702 if (file->f_mode & FMODE_READ) {
1703 stop_adc(s);
1704 s->dma_adc.ossfragshift = val & 0xffff;
1705 s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
1706 if (s->dma_adc.ossfragshift < 4)
1707 s->dma_adc.ossfragshift = 4;
1708 if (s->dma_adc.ossfragshift > 15)
1709 s->dma_adc.ossfragshift = 15;
1710 if (s->dma_adc.ossmaxfrags < 4)
1711 s->dma_adc.ossmaxfrags = 4;
1712 if ((ret = prog_dmabuf_adc(s)))
1713 return ret;
1714 }
1715 if (file->f_mode & FMODE_WRITE) {
1716 stop_dac(s);
1717 s->dma_dac.ossfragshift = val & 0xffff;
1718 s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
1719 if (s->dma_dac.ossfragshift < 4)
1720 s->dma_dac.ossfragshift = 4;
1721 if (s->dma_dac.ossfragshift > 15)
1722 s->dma_dac.ossfragshift = 15;
1723 if (s->dma_dac.ossmaxfrags < 4)
1724 s->dma_dac.ossmaxfrags = 4;
1725 if ((ret = prog_dmabuf_dac(s)))
1726 return ret;
1727 }
1728 return 0;
1729
1730 case SNDCTL_DSP_SUBDIVIDE:
1731 if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
1732 (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
1733 return -EINVAL;
1734 if (get_user(val, (int *) arg))
1735 return -EFAULT;
1736 if (val != 1 && val != 2 && val != 4)
1737 return -EINVAL;
1738 if (file->f_mode & FMODE_READ) {
1739 stop_adc(s);
1740 s->dma_adc.subdivision = val;
1741 if ((ret = prog_dmabuf_adc(s)))
1742 return ret;
1743 }
1744 if (file->f_mode & FMODE_WRITE) {
1745 stop_dac(s);
1746 s->dma_dac.subdivision = val;
1747 if ((ret = prog_dmabuf_dac(s)))
1748 return ret;
1749 }
1750 return 0;
1751
1752 case SOUND_PCM_READ_RATE:
1753 return put_user((file->f_mode & FMODE_READ) ?
1754 s->dma_adc.sample_rate :
1755 s->dma_dac.sample_rate,
1756 (int *)arg);
1757
1758 case SOUND_PCM_READ_CHANNELS:
1759 if (file->f_mode & FMODE_READ)
1760 return put_user(s->dma_adc.num_channels, (int *)arg);
1761 else
1762 return put_user(s->dma_dac.num_channels, (int *)arg);
1763
1764 case SOUND_PCM_READ_BITS:
1765 if (file->f_mode & FMODE_READ)
1766 return put_user(s->dma_adc.sample_size, (int *)arg);
1767 else
1768 return put_user(s->dma_dac.sample_size, (int *)arg);
1769
1770 case SOUND_PCM_WRITE_FILTER:
1771 case SNDCTL_DSP_SETSYNCRO:
1772 case SOUND_PCM_READ_FILTER:
1773 return -EINVAL;
1774 }
1775
1776 return mixdev_ioctl(s->codec, cmd, arg);
1777}
1778
1779static long
1780au1550_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1781{
1782 int ret;
1783
1784 mutex_lock(&au1550_ac97_mutex);
1785 ret = au1550_ioctl(file, cmd, arg);
1786 mutex_unlock(&au1550_ac97_mutex);
1787
1788 return ret;
1789}
1790
1791static int
1792au1550_open(struct inode *inode, struct file *file)
1793{
1794 int minor = MINOR(inode->i_rdev);
1795 DECLARE_WAITQUEUE(wait, current);
1796 struct au1550_state *s = &au1550_state;
1797 int ret;
1798
1799#ifdef DEBUG
1800 if (file->f_flags & O_NONBLOCK)
1801 pr_debug("open: non-blocking\n");
1802 else
1803 pr_debug("open: blocking\n");
1804#endif
1805
1806 file->private_data = s;
1807 mutex_lock(&au1550_ac97_mutex);
1808 /* wait for device to become free */
1809 mutex_lock(&s->open_mutex);
1810 while (s->open_mode & file->f_mode) {
1811 ret = -EBUSY;
1812 if (file->f_flags & O_NONBLOCK)
1813 goto out;
1814 add_wait_queue(&s->open_wait, &wait);
1815 __set_current_state(TASK_INTERRUPTIBLE);
1816 mutex_unlock(&s->open_mutex);
1817 schedule();
1818 remove_wait_queue(&s->open_wait, &wait);
1819 set_current_state(TASK_RUNNING);
1820 ret = -ERESTARTSYS;
1821 if (signal_pending(current))
1822 goto out2;
1823 mutex_lock(&s->open_mutex);
1824 }
1825
1826 stop_dac(s);
1827 stop_adc(s);
1828
1829 if (file->f_mode & FMODE_READ) {
1830 s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
1831 s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
1832 s->dma_adc.num_channels = 1;
1833 s->dma_adc.sample_size = 8;
1834 set_adc_rate(s, 8000);
1835 if ((minor & 0xf) == SND_DEV_DSP16)
1836 s->dma_adc.sample_size = 16;
1837 }
1838
1839 if (file->f_mode & FMODE_WRITE) {
1840 s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
1841 s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
1842 s->dma_dac.num_channels = 1;
1843 s->dma_dac.sample_size = 8;
1844 set_dac_rate(s, 8000);
1845 if ((minor & 0xf) == SND_DEV_DSP16)
1846 s->dma_dac.sample_size = 16;
1847 }
1848
1849 if (file->f_mode & FMODE_READ) {
1850 if ((ret = prog_dmabuf_adc(s)))
1851 goto out;
1852 }
1853 if (file->f_mode & FMODE_WRITE) {
1854 if ((ret = prog_dmabuf_dac(s)))
1855 goto out;
1856 }
1857
1858 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
1859 mutex_init(&s->sem);
1860 ret = 0;
1861out:
1862 mutex_unlock(&s->open_mutex);
1863out2:
1864 mutex_unlock(&au1550_ac97_mutex);
1865 return ret;
1866}
1867
1868static int
1869au1550_release(struct inode *inode, struct file *file)
1870{
1871 struct au1550_state *s = file->private_data;
1872
1873 mutex_lock(&au1550_ac97_mutex);
1874
1875 if (file->f_mode & FMODE_WRITE) {
1876 mutex_unlock(&au1550_ac97_mutex);
1877 drain_dac(s, file->f_flags & O_NONBLOCK);
1878 mutex_lock(&au1550_ac97_mutex);
1879 }
1880
1881 mutex_lock(&s->open_mutex);
1882 if (file->f_mode & FMODE_WRITE) {
1883 stop_dac(s);
1884 kfree(s->dma_dac.rawbuf);
1885 s->dma_dac.rawbuf = NULL;
1886 }
1887 if (file->f_mode & FMODE_READ) {
1888 stop_adc(s);
1889 kfree(s->dma_adc.rawbuf);
1890 s->dma_adc.rawbuf = NULL;
1891 }
1892 s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
1893 mutex_unlock(&s->open_mutex);
1894 wake_up(&s->open_wait);
1895 mutex_unlock(&au1550_ac97_mutex);
1896 return 0;
1897}
1898
1899static /*const */ struct file_operations au1550_audio_fops = {
1900 .owner = THIS_MODULE,
1901 .llseek = au1550_llseek,
1902 .read = au1550_read,
1903 .write = au1550_write,
1904 .poll = au1550_poll,
1905 .unlocked_ioctl = au1550_unlocked_ioctl,
1906 .mmap = au1550_mmap,
1907 .open = au1550_open,
1908 .release = au1550_release,
1909};
1910
1911MODULE_AUTHOR("Advanced Micro Devices (AMD), dan@embeddededge.com");
1912MODULE_DESCRIPTION("Au1550 AC97 Audio Driver");
1913MODULE_LICENSE("GPL");
1914
1915
1916static int __devinit
1917au1550_probe(void)
1918{
1919 struct au1550_state *s = &au1550_state;
1920 int val;
1921
1922 memset(s, 0, sizeof(struct au1550_state));
1923
1924 init_waitqueue_head(&s->dma_adc.wait);
1925 init_waitqueue_head(&s->dma_dac.wait);
1926 init_waitqueue_head(&s->open_wait);
1927 mutex_init(&s->open_mutex);
1928 spin_lock_init(&s->lock);
1929
1930 s->codec = ac97_alloc_codec();
1931 if(s->codec == NULL) {
1932 err("Out of memory");
1933 return -1;
1934 }
1935 s->codec->private_data = s;
1936 s->codec->id = 0;
1937 s->codec->codec_read = rdcodec;
1938 s->codec->codec_write = wrcodec;
1939 s->codec->codec_wait = waitcodec;
1940
1941 if (!request_mem_region(CPHYSADDR(AC97_PSC_SEL),
1942 0x30, "Au1550 AC97")) {
1943 err("AC'97 ports in use");
1944 }
1945
1946 /* Allocate the DMA Channels
1947 */
1948 if ((s->dma_dac.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_MEM_CHAN,
1949 DBDMA_AC97_TX_CHAN, dac_dma_interrupt, (void *)s)) == 0) {
1950 err("Can't get DAC DMA");
1951 goto err_dma1;
1952 }
1953 au1xxx_dbdma_set_devwidth(s->dma_dac.dmanr, 16);
1954 if (au1xxx_dbdma_ring_alloc(s->dma_dac.dmanr,
1955 NUM_DBDMA_DESCRIPTORS) == 0) {
1956 err("Can't get DAC DMA descriptors");
1957 goto err_dma1;
1958 }
1959
1960 if ((s->dma_adc.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_AC97_RX_CHAN,
1961 DBDMA_MEM_CHAN, adc_dma_interrupt, (void *)s)) == 0) {
1962 err("Can't get ADC DMA");
1963 goto err_dma2;
1964 }
1965 au1xxx_dbdma_set_devwidth(s->dma_adc.dmanr, 16);
1966 if (au1xxx_dbdma_ring_alloc(s->dma_adc.dmanr,
1967 NUM_DBDMA_DESCRIPTORS) == 0) {
1968 err("Can't get ADC DMA descriptors");
1969 goto err_dma2;
1970 }
1971
1972 pr_info("DAC: DMA%d, ADC: DMA%d", DBDMA_AC97_TX_CHAN, DBDMA_AC97_RX_CHAN);
1973
1974 /* register devices */
1975
1976 if ((s->dev_audio = register_sound_dsp(&au1550_audio_fops, -1)) < 0)
1977 goto err_dev1;
1978 if ((s->codec->dev_mixer =
1979 register_sound_mixer(&au1550_mixer_fops, -1)) < 0)
1980 goto err_dev2;
1981
1982 /* The GPIO for the appropriate PSC was configured by the
1983 * board specific start up.
1984 *
1985 * configure PSC for AC'97
1986 */
1987 au_writel(0, AC97_PSC_CTRL); /* Disable PSC */
1988 au_sync();
1989 au_writel((PSC_SEL_CLK_SERCLK | PSC_SEL_PS_AC97MODE), AC97_PSC_SEL);
1990 au_sync();
1991
1992 /* cold reset the AC'97
1993 */
1994 au_writel(PSC_AC97RST_RST, PSC_AC97RST);
1995 au_sync();
1996 au1550_delay(10);
1997 au_writel(0, PSC_AC97RST);
1998 au_sync();
1999
2000 /* need to delay around 500msec(bleech) to give
2001 some CODECs enough time to wakeup */
2002 au1550_delay(500);
2003
2004 /* warm reset the AC'97 to start the bitclk
2005 */
2006 au_writel(PSC_AC97RST_SNC, PSC_AC97RST);
2007 au_sync();
2008 udelay(100);
2009 au_writel(0, PSC_AC97RST);
2010 au_sync();
2011
2012 /* Enable PSC
2013 */
2014 au_writel(PSC_CTRL_ENABLE, AC97_PSC_CTRL);
2015 au_sync();
2016
2017 /* Wait for PSC ready.
2018 */
2019 do {
2020 val = au_readl(PSC_AC97STAT);
2021 au_sync();
2022 } while ((val & PSC_AC97STAT_SR) == 0);
2023
2024 /* Configure AC97 controller.
2025 * Deep FIFO, 16-bit sample, DMA, make sure DMA matches fifo size.
2026 */
2027 val = PSC_AC97CFG_SET_LEN(16);
2028 val |= PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8;
2029
2030 /* Enable device so we can at least
2031 * talk over the AC-link.
2032 */
2033 au_writel(val, PSC_AC97CFG);
2034 au_writel(PSC_AC97MSK_ALLMASK, PSC_AC97MSK);
2035 au_sync();
2036 val |= PSC_AC97CFG_DE_ENABLE;
2037 au_writel(val, PSC_AC97CFG);
2038 au_sync();
2039
2040 /* Wait for Device ready.
2041 */
2042 do {
2043 val = au_readl(PSC_AC97STAT);
2044 au_sync();
2045 } while ((val & PSC_AC97STAT_DR) == 0);
2046
2047 /* codec init */
2048 if (!ac97_probe_codec(s->codec))
2049 goto err_dev3;
2050
2051 s->codec_base_caps = rdcodec(s->codec, AC97_RESET);
2052 s->codec_ext_caps = rdcodec(s->codec, AC97_EXTENDED_ID);
2053 pr_info("AC'97 Base/Extended ID = %04x/%04x",
2054 s->codec_base_caps, s->codec_ext_caps);
2055
2056 if (!(s->codec_ext_caps & AC97_EXTID_VRA)) {
2057 /* codec does not support VRA
2058 */
2059 s->no_vra = 1;
2060 } else if (!vra) {
2061 /* Boot option says disable VRA
2062 */
2063 u16 ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
2064 wrcodec(s->codec, AC97_EXTENDED_STATUS,
2065 ac97_extstat & ~AC97_EXTSTAT_VRA);
2066 s->no_vra = 1;
2067 }
2068 if (s->no_vra)
2069 pr_info("no VRA, interpolating and decimating");
2070
2071 /* set mic to be the recording source */
2072 val = SOUND_MASK_MIC;
2073 mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC,
2074 (unsigned long) &val);
2075
2076 return 0;
2077
2078 err_dev3:
2079 unregister_sound_mixer(s->codec->dev_mixer);
2080 err_dev2:
2081 unregister_sound_dsp(s->dev_audio);
2082 err_dev1:
2083 au1xxx_dbdma_chan_free(s->dma_adc.dmanr);
2084 err_dma2:
2085 au1xxx_dbdma_chan_free(s->dma_dac.dmanr);
2086 err_dma1:
2087 release_mem_region(CPHYSADDR(AC97_PSC_SEL), 0x30);
2088
2089 ac97_release_codec(s->codec);
2090 return -1;
2091}
2092
2093static void __devinit
2094au1550_remove(void)
2095{
2096 struct au1550_state *s = &au1550_state;
2097
2098 if (!s)
2099 return;
2100 synchronize_irq();
2101 au1xxx_dbdma_chan_free(s->dma_adc.dmanr);
2102 au1xxx_dbdma_chan_free(s->dma_dac.dmanr);
2103 release_mem_region(CPHYSADDR(AC97_PSC_SEL), 0x30);
2104 unregister_sound_dsp(s->dev_audio);
2105 unregister_sound_mixer(s->codec->dev_mixer);
2106 ac97_release_codec(s->codec);
2107}
2108
2109static int __init
2110init_au1550(void)
2111{
2112 return au1550_probe();
2113}
2114
2115static void __exit
2116cleanup_au1550(void)
2117{
2118 au1550_remove();
2119}
2120
2121module_init(init_au1550);
2122module_exit(cleanup_au1550);
2123
2124#ifndef MODULE
2125
2126static int __init
2127au1550_setup(char *options)
2128{
2129 char *this_opt;
2130
2131 if (!options || !*options)
2132 return 0;
2133
2134 while ((this_opt = strsep(&options, ","))) {
2135 if (!*this_opt)
2136 continue;
2137 if (!strncmp(this_opt, "vra", 3)) {
2138 vra = 1;
2139 }
2140 }
2141
2142 return 1;
2143}
2144
2145__setup("au1550_audio=", au1550_setup);
2146
2147#endif /* MODULE */
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 389cd7931668..e90d103e177e 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -534,6 +534,14 @@ config SND_ES1968_INPUT
534 If you say N the buttons will directly control the master volume. 534 If you say N the buttons will directly control the master volume.
535 It is recommended to say Y. 535 It is recommended to say Y.
536 536
537config SND_ES1968_RADIO
538 bool "Enable TEA5757 radio tuner support for es1968"
539 depends on SND_ES1968
540 depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_ES1968
541 help
542 Say Y here to include support for TEA5757 radio tuner integrated on
543 some MediaForte cards (e.g. SF64-PCE2).
544
537config SND_FM801 545config SND_FM801
538 tristate "ForteMedia FM801" 546 tristate "ForteMedia FM801"
539 select SND_OPL3_LIB 547 select SND_OPL3_LIB
@@ -552,13 +560,13 @@ config SND_FM801_TEA575X_BOOL
552 depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801 560 depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801
553 help 561 help
554 Say Y here to include support for soundcards based on the ForteMedia 562 Say Y here to include support for soundcards based on the ForteMedia
555 FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media 563 FM801 chip with a TEA5757 tuner (MediaForte SF256-PCS, SF256-PCP and
556 Forte SF256-PCS-02) into the snd-fm801 driver. 564 SF64-PCR) into the snd-fm801 driver.
557 565
558config SND_FM801_TEA575X 566config SND_TEA575X
559 tristate 567 tristate
560 depends on SND_FM801_TEA575X_BOOL 568 depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO
561 default SND_FM801 569 default SND_FM801 || SND_ES1968
562 570
563source "sound/pci/hda/Kconfig" 571source "sound/pci/hda/Kconfig"
564 572
@@ -658,6 +666,15 @@ config SND_KORG1212
658 To compile this driver as a module, choose M here: the module 666 To compile this driver as a module, choose M here: the module
659 will be called snd-korg1212. 667 will be called snd-korg1212.
660 668
669config SND_LOLA
670 tristate "Digigram Lola"
671 select SND_PCM
672 help
673 Say Y to include support for Digigram Lola boards.
674
675 To compile this driver as a module, choose M here: the module
676 will be called snd-lola.
677
661config SND_LX6464ES 678config SND_LX6464ES
662 tristate "Digigram LX6464ES" 679 tristate "Digigram LX6464ES"
663 select SND_PCM 680 select SND_PCM
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index 9cf4348ec137..54fe325e3aa5 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_SND) += \
64 ca0106/ \ 64 ca0106/ \
65 cs46xx/ \ 65 cs46xx/ \
66 cs5535audio/ \ 66 cs5535audio/ \
67 lola/ \
67 lx6464es/ \ 68 lx6464es/ \
68 echoaudio/ \ 69 echoaudio/ \
69 emu10k1/ \ 70 emu10k1/ \
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index f8ccc9677c6f..2ca6f4f85b41 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -42,10 +42,29 @@
42#include <sound/tlv.h> 42#include <sound/tlv.h>
43#include <sound/hwdep.h> 43#include <sound/hwdep.h>
44 44
45
45MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
46MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); 47MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
47MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); 48MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
48 49
50#if defined CONFIG_SND_DEBUG
51/* copied from pcm_lib.c, hope later patch will make that version public
52and this copy can be removed */
53static void pcm_debug_name(struct snd_pcm_substream *substream,
54 char *name, size_t len)
55{
56 snprintf(name, len, "pcmC%dD%d%c:%d",
57 substream->pcm->card->number,
58 substream->pcm->device,
59 substream->stream ? 'c' : 'p',
60 substream->number);
61}
62#define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name))
63#else
64#define pcm_debug_name(s, n, l) do { } while (0)
65#define DEBUG_NAME(name, substream) do { } while (0)
66#endif
67
49#if defined CONFIG_SND_DEBUG_VERBOSE 68#if defined CONFIG_SND_DEBUG_VERBOSE
50/** 69/**
51 * snd_printddd - very verbose debug printk 70 * snd_printddd - very verbose debug printk
@@ -58,7 +77,7 @@ MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
58#define snd_printddd(format, args...) \ 77#define snd_printddd(format, args...) \
59 __snd_printk(3, __FILE__, __LINE__, format, ##args) 78 __snd_printk(3, __FILE__, __LINE__, format, ##args)
60#else 79#else
61#define snd_printddd(format, args...) do { } while (0) 80#define snd_printddd(format, args...) do { } while (0)
62#endif 81#endif
63 82
64static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ 83static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
@@ -101,13 +120,6 @@ static int adapter_fs = DEFAULT_SAMPLERATE;
101#define PERIOD_BYTES_MIN 2048 120#define PERIOD_BYTES_MIN 2048
102#define BUFFER_BYTES_MAX (512 * 1024) 121#define BUFFER_BYTES_MAX (512 * 1024)
103 122
104/* convert stream to character */
105#define SCHR(s) ((s == SNDRV_PCM_STREAM_PLAYBACK) ? 'P' : 'C')
106
107/*#define TIMER_MILLISECONDS 20
108#define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000)
109*/
110
111#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7) 123#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
112 124
113struct clk_source { 125struct clk_source {
@@ -136,7 +148,7 @@ struct snd_card_asihpi {
136 u32 h_mixer; 148 u32 h_mixer;
137 struct clk_cache cc; 149 struct clk_cache cc;
138 150
139 u16 support_mmap; 151 u16 can_dma;
140 u16 support_grouping; 152 u16 support_grouping;
141 u16 support_mrx; 153 u16 support_mrx;
142 u16 update_interval_frames; 154 u16 update_interval_frames;
@@ -155,6 +167,7 @@ struct snd_card_asihpi_pcm {
155 unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */ 167 unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */
156 unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */ 168 unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */
157 unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */ 169 unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */
170 unsigned int drained_count;
158 struct snd_pcm_substream *substream; 171 struct snd_pcm_substream *substream;
159 u32 h_stream; 172 u32 h_stream;
160 struct hpi_format format; 173 struct hpi_format format;
@@ -288,19 +301,26 @@ static u16 handle_error(u16 err, int line, char *filename)
288#define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__) 301#define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
289 302
290/***************************** GENERAL PCM ****************/ 303/***************************** GENERAL PCM ****************/
291static void print_hwparams(struct snd_pcm_hw_params *p) 304
305static void print_hwparams(struct snd_pcm_substream *substream,
306 struct snd_pcm_hw_params *p)
292{ 307{
293 snd_printd("HWPARAMS \n"); 308 DEBUG_NAME(substream, name);
294 snd_printd("samplerate %d \n", params_rate(p)); 309 snd_printd("%s HWPARAMS\n", name);
295 snd_printd("Channels %d \n", params_channels(p)); 310 snd_printd(" samplerate %d Hz\n", params_rate(p));
296 snd_printd("Format %d \n", params_format(p)); 311 snd_printd(" channels %d\n", params_channels(p));
297 snd_printd("subformat %d \n", params_subformat(p)); 312 snd_printd(" format %d\n", params_format(p));
298 snd_printd("Buffer bytes %d \n", params_buffer_bytes(p)); 313 snd_printd(" subformat %d\n", params_subformat(p));
299 snd_printd("Period bytes %d \n", params_period_bytes(p)); 314 snd_printd(" buffer %d B\n", params_buffer_bytes(p));
300 snd_printd("access %d \n", params_access(p)); 315 snd_printd(" period %d B\n", params_period_bytes(p));
301 snd_printd("period_size %d \n", params_period_size(p)); 316 snd_printd(" access %d\n", params_access(p));
302 snd_printd("periods %d \n", params_periods(p)); 317 snd_printd(" period_size %d\n", params_period_size(p));
303 snd_printd("buffer_size %d \n", params_buffer_size(p)); 318 snd_printd(" periods %d\n", params_periods(p));
319 snd_printd(" buffer_size %d\n", params_buffer_size(p));
320 snd_printd(" %d B/s\n", params_rate(p) *
321 params_channels(p) *
322 snd_pcm_format_width(params_format(p)) / 8);
323
304} 324}
305 325
306static snd_pcm_format_t hpi_to_alsa_formats[] = { 326static snd_pcm_format_t hpi_to_alsa_formats[] = {
@@ -451,7 +471,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
451 int width; 471 int width;
452 unsigned int bytes_per_sec; 472 unsigned int bytes_per_sec;
453 473
454 print_hwparams(params); 474 print_hwparams(substream, params);
455 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); 475 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
456 if (err < 0) 476 if (err < 0)
457 return err; 477 return err;
@@ -459,10 +479,6 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
459 if (err) 479 if (err)
460 return err; 480 return err;
461 481
462 snd_printdd("format %d, %d chans, %d_hz\n",
463 format, params_channels(params),
464 params_rate(params));
465
466 hpi_handle_error(hpi_format_create(&dpcm->format, 482 hpi_handle_error(hpi_format_create(&dpcm->format,
467 params_channels(params), 483 params_channels(params),
468 format, params_rate(params), 0, 0)); 484 format, params_rate(params), 0, 0));
@@ -477,8 +493,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
477 } 493 }
478 494
479 dpcm->hpi_buffer_attached = 0; 495 dpcm->hpi_buffer_attached = 0;
480 if (card->support_mmap) { 496 if (card->can_dma) {
481
482 err = hpi_stream_host_buffer_attach(dpcm->h_stream, 497 err = hpi_stream_host_buffer_attach(dpcm->h_stream,
483 params_buffer_bytes(params), runtime->dma_addr); 498 params_buffer_bytes(params), runtime->dma_addr);
484 if (err == 0) { 499 if (err == 0) {
@@ -509,8 +524,6 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
509 dpcm->bytes_per_sec = bytes_per_sec; 524 dpcm->bytes_per_sec = bytes_per_sec;
510 dpcm->buffer_bytes = params_buffer_bytes(params); 525 dpcm->buffer_bytes = params_buffer_bytes(params);
511 dpcm->period_bytes = params_period_bytes(params); 526 dpcm->period_bytes = params_period_bytes(params);
512 snd_printdd("buffer_bytes=%d, period_bytes=%d, bps=%d\n",
513 dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec);
514 527
515 return 0; 528 return 0;
516} 529}
@@ -564,9 +577,10 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
564 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); 577 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
565 struct snd_pcm_substream *s; 578 struct snd_pcm_substream *s;
566 u16 e; 579 u16 e;
580 DEBUG_NAME(substream, name);
581
582 snd_printdd("%s trigger\n", name);
567 583
568 snd_printdd("%c%d trigger\n",
569 SCHR(substream->stream), substream->number);
570 switch (cmd) { 584 switch (cmd) {
571 case SNDRV_PCM_TRIGGER_START: 585 case SNDRV_PCM_TRIGGER_START:
572 snd_pcm_group_for_each_entry(s, substream) { 586 snd_pcm_group_for_each_entry(s, substream) {
@@ -580,8 +594,8 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
580 if (substream->stream != s->stream) 594 if (substream->stream != s->stream)
581 continue; 595 continue;
582 596
583 if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && 597 ds->drained_count = 0;
584 (card->support_mmap)) { 598 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
585 /* How do I know how much valid data is present 599 /* How do I know how much valid data is present
586 * in buffer? Must be at least one period! 600 * in buffer? Must be at least one period!
587 * Guessing 2 periods, but if 601 * Guessing 2 periods, but if
@@ -599,9 +613,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
599 } 613 }
600 614
601 if (card->support_grouping) { 615 if (card->support_grouping) {
602 snd_printdd("\t%c%d group\n", 616 snd_printdd("%d group\n", s->number);
603 SCHR(s->stream),
604 s->number);
605 e = hpi_stream_group_add( 617 e = hpi_stream_group_add(
606 dpcm->h_stream, 618 dpcm->h_stream,
607 ds->h_stream); 619 ds->h_stream);
@@ -618,7 +630,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
618 /* start the master stream */ 630 /* start the master stream */
619 snd_card_asihpi_pcm_timer_start(substream); 631 snd_card_asihpi_pcm_timer_start(substream);
620 if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || 632 if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ||
621 !card->support_mmap) 633 !card->can_dma)
622 hpi_handle_error(hpi_stream_start(dpcm->h_stream)); 634 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
623 break; 635 break;
624 636
@@ -636,9 +648,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
636 s->runtime->status->state = SNDRV_PCM_STATE_SETUP; 648 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
637 649
638 if (card->support_grouping) { 650 if (card->support_grouping) {
639 snd_printdd("\t%c%d group\n", 651 snd_printdd("%d group\n", s->number);
640 SCHR(s->stream),
641 s->number);
642 snd_pcm_trigger_done(s, substream); 652 snd_pcm_trigger_done(s, substream);
643 } else 653 } else
644 break; 654 break;
@@ -732,9 +742,9 @@ static void snd_card_asihpi_timer_function(unsigned long data)
732 int loops = 0; 742 int loops = 0;
733 u16 state; 743 u16 state;
734 u32 buffer_size, bytes_avail, samples_played, on_card_bytes; 744 u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
745 DEBUG_NAME(substream, name);
735 746
736 snd_printdd("%c%d snd_card_asihpi_timer_function\n", 747 snd_printdd("%s snd_card_asihpi_timer_function\n", name);
737 SCHR(substream->stream), substream->number);
738 748
739 /* find minimum newdata and buffer pos in group */ 749 /* find minimum newdata and buffer pos in group */
740 snd_pcm_group_for_each_entry(s, substream) { 750 snd_pcm_group_for_each_entry(s, substream) {
@@ -756,6 +766,9 @@ static void snd_card_asihpi_timer_function(unsigned long data)
756 /* number of bytes in on-card buffer */ 766 /* number of bytes in on-card buffer */
757 runtime->delay = on_card_bytes; 767 runtime->delay = on_card_bytes;
758 768
769 if (!card->can_dma)
770 on_card_bytes = bytes_avail;
771
759 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { 772 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
760 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail; 773 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
761 if (state == HPI_STATE_STOPPED) { 774 if (state == HPI_STATE_STOPPED) {
@@ -763,12 +776,18 @@ static void snd_card_asihpi_timer_function(unsigned long data)
763 (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { 776 (on_card_bytes < ds->pcm_buf_host_rw_ofs)) {
764 hpi_handle_error(hpi_stream_start(ds->h_stream)); 777 hpi_handle_error(hpi_stream_start(ds->h_stream));
765 snd_printdd("P%d start\n", s->number); 778 snd_printdd("P%d start\n", s->number);
779 ds->drained_count = 0;
766 } 780 }
767 } else if (state == HPI_STATE_DRAINED) { 781 } else if (state == HPI_STATE_DRAINED) {
768 snd_printd(KERN_WARNING "P%d drained\n", 782 snd_printd(KERN_WARNING "P%d drained\n",
769 s->number); 783 s->number);
770 /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); 784 ds->drained_count++;
771 continue; */ 785 if (ds->drained_count > 2) {
786 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
787 continue;
788 }
789 } else {
790 ds->drained_count = 0;
772 } 791 }
773 } else 792 } else
774 pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs; 793 pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
@@ -786,16 +805,18 @@ static void snd_card_asihpi_timer_function(unsigned long data)
786 newdata); 805 newdata);
787 } 806 }
788 807
789 snd_printdd("hw_ptr x%04lX, appl_ptr x%04lX\n", 808 snd_printdd("hw_ptr 0x%04lX, appl_ptr 0x%04lX\n",
790 (unsigned long)frames_to_bytes(runtime, 809 (unsigned long)frames_to_bytes(runtime,
791 runtime->status->hw_ptr), 810 runtime->status->hw_ptr),
792 (unsigned long)frames_to_bytes(runtime, 811 (unsigned long)frames_to_bytes(runtime,
793 runtime->control->appl_ptr)); 812 runtime->control->appl_ptr));
794 813
795 snd_printdd("%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," 814 snd_printdd("%d S=%d, "
796 " aux=x%04X space=x%04X\n", 815 "rw=0x%04X, dma=0x%04X, left=0x%04X, "
797 loops, SCHR(s->stream), s->number, 816 "aux=0x%04X space=0x%04X\n",
798 state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail, 817 s->number, state,
818 ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs,
819 (int)bytes_avail,
799 (int)on_card_bytes, buffer_size-bytes_avail); 820 (int)on_card_bytes, buffer_size-bytes_avail);
800 loops++; 821 loops++;
801 } 822 }
@@ -814,7 +835,7 @@ static void snd_card_asihpi_timer_function(unsigned long data)
814 835
815 next_jiffies = max(next_jiffies, 1U); 836 next_jiffies = max(next_jiffies, 1U);
816 dpcm->timer.expires = jiffies + next_jiffies; 837 dpcm->timer.expires = jiffies + next_jiffies;
817 snd_printdd("jif %d buf pos x%04X newdata x%04X xfer x%04X\n", 838 snd_printdd("jif %d buf pos 0x%04X newdata 0x%04X xfer 0x%04X\n",
818 next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); 839 next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
819 840
820 snd_pcm_group_for_each_entry(s, substream) { 841 snd_pcm_group_for_each_entry(s, substream) {
@@ -826,30 +847,63 @@ static void snd_card_asihpi_timer_function(unsigned long data)
826 847
827 ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs; 848 ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
828 849
829 if (xfercount && (on_card_bytes <= ds->period_bytes)) { 850 if (xfercount &&
830 if (card->support_mmap) { 851 /* Limit use of on card fifo for playback */
831 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { 852 ((on_card_bytes <= ds->period_bytes) ||
832 snd_printddd("P%d write x%04x\n", 853 (s->stream == SNDRV_PCM_STREAM_CAPTURE)))
854
855 {
856
857 unsigned int buf_ofs = ds->pcm_buf_host_rw_ofs % ds->buffer_bytes;
858 unsigned int xfer1, xfer2;
859 char *pd = &s->runtime->dma_area[buf_ofs];
860
861 if (card->can_dma) { /* buffer wrap is handled at lower level */
862 xfer1 = xfercount;
863 xfer2 = 0;
864 } else {
865 xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs);
866 xfer2 = xfercount - xfer1;
867 }
868
869 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
870 snd_printddd("P%d write1 0x%04X 0x%04X\n",
871 s->number, xfer1, buf_ofs);
872 hpi_handle_error(
873 hpi_outstream_write_buf(
874 ds->h_stream, pd, xfer1,
875 &ds->format));
876
877 if (xfer2) {
878 pd = s->runtime->dma_area;
879
880 snd_printddd("P%d write2 0x%04X 0x%04X\n",
833 s->number, 881 s->number,
834 ds->period_bytes); 882 xfercount - xfer1, buf_ofs);
835 hpi_handle_error( 883 hpi_handle_error(
836 hpi_outstream_write_buf( 884 hpi_outstream_write_buf(
837 ds->h_stream, 885 ds->h_stream, pd,
838 &s->runtime-> 886 xfercount - xfer1,
839 dma_area[0],
840 xfercount,
841 &ds->format)); 887 &ds->format));
842 } else { 888 }
843 snd_printddd("C%d read x%04x\n", 889 } else {
844 s->number, 890 snd_printddd("C%d read1 0x%04x\n",
845 xfercount); 891 s->number, xfer1);
892 hpi_handle_error(
893 hpi_instream_read_buf(
894 ds->h_stream,
895 pd, xfer1));
896 if (xfer2) {
897 pd = s->runtime->dma_area;
898 snd_printddd("C%d read2 0x%04x\n",
899 s->number, xfer2);
846 hpi_handle_error( 900 hpi_handle_error(
847 hpi_instream_read_buf( 901 hpi_instream_read_buf(
848 ds->h_stream, 902 ds->h_stream,
849 NULL, xfercount)); 903 pd, xfer2));
850 } 904 }
851 ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount; 905 }
852 } /* else R/W will be handled by read/write callbacks */ 906 ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount;
853 ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs; 907 ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs;
854 snd_pcm_period_elapsed(s); 908 snd_pcm_period_elapsed(s);
855 } 909 }
@@ -863,7 +917,7 @@ static void snd_card_asihpi_timer_function(unsigned long data)
863static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, 917static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
864 unsigned int cmd, void *arg) 918 unsigned int cmd, void *arg)
865{ 919{
866 snd_printdd(KERN_INFO "Playback ioctl %d\n", cmd); 920 snd_printddd(KERN_INFO "P%d ioctl %d\n", substream->number, cmd);
867 return snd_pcm_lib_ioctl(substream, cmd, arg); 921 return snd_pcm_lib_ioctl(substream, cmd, arg);
868} 922}
869 923
@@ -873,7 +927,7 @@ static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
873 struct snd_pcm_runtime *runtime = substream->runtime; 927 struct snd_pcm_runtime *runtime = substream->runtime;
874 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 928 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
875 929
876 snd_printdd("playback prepare %d\n", substream->number); 930 snd_printdd("P%d prepare\n", substream->number);
877 931
878 hpi_handle_error(hpi_outstream_reset(dpcm->h_stream)); 932 hpi_handle_error(hpi_outstream_reset(dpcm->h_stream));
879 dpcm->pcm_buf_host_rw_ofs = 0; 933 dpcm->pcm_buf_host_rw_ofs = 0;
@@ -890,7 +944,7 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
890 snd_pcm_uframes_t ptr; 944 snd_pcm_uframes_t ptr;
891 945
892 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); 946 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
893 snd_printddd("playback_pointer=x%04lx\n", (unsigned long)ptr); 947 snd_printddd("P%d pointer = 0x%04lx\n", substream->number, (unsigned long)ptr);
894 return ptr; 948 return ptr;
895} 949}
896 950
@@ -986,11 +1040,9 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
986 SNDRV_PCM_INFO_DOUBLE | 1040 SNDRV_PCM_INFO_DOUBLE |
987 SNDRV_PCM_INFO_BATCH | 1041 SNDRV_PCM_INFO_BATCH |
988 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1042 SNDRV_PCM_INFO_BLOCK_TRANSFER |
989 SNDRV_PCM_INFO_PAUSE; 1043 SNDRV_PCM_INFO_PAUSE |
990 1044 SNDRV_PCM_INFO_MMAP |
991 if (card->support_mmap) 1045 SNDRV_PCM_INFO_MMAP_VALID;
992 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP |
993 SNDRV_PCM_INFO_MMAP_VALID;
994 1046
995 if (card->support_grouping) 1047 if (card->support_grouping)
996 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START; 1048 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
@@ -998,7 +1050,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
998 /* struct is copied, so can create initializer dynamically */ 1050 /* struct is copied, so can create initializer dynamically */
999 runtime->hw = snd_card_asihpi_playback; 1051 runtime->hw = snd_card_asihpi_playback;
1000 1052
1001 if (card->support_mmap) 1053 if (card->can_dma)
1002 err = snd_pcm_hw_constraint_pow2(runtime, 0, 1054 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1003 SNDRV_PCM_HW_PARAM_BUFFER_BYTES); 1055 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1004 if (err < 0) 1056 if (err < 0)
@@ -1028,58 +1080,6 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1028 return 0; 1080 return 0;
1029} 1081}
1030 1082
1031static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,
1032 int channel,
1033 snd_pcm_uframes_t pos,
1034 void __user *src,
1035 snd_pcm_uframes_t count)
1036{
1037 struct snd_pcm_runtime *runtime = substream->runtime;
1038 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1039 unsigned int len;
1040
1041 len = frames_to_bytes(runtime, count);
1042
1043 if (copy_from_user(runtime->dma_area, src, len))
1044 return -EFAULT;
1045
1046 snd_printddd("playback copy%d %u bytes\n",
1047 substream->number, len);
1048
1049 hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream,
1050 runtime->dma_area, len, &dpcm->format));
1051
1052 dpcm->pcm_buf_host_rw_ofs += len;
1053
1054 return 0;
1055}
1056
1057static int snd_card_asihpi_playback_silence(struct snd_pcm_substream *
1058 substream, int channel,
1059 snd_pcm_uframes_t pos,
1060 snd_pcm_uframes_t count)
1061{
1062 /* Usually writes silence to DMA buffer, which should be overwritten
1063 by real audio later. Our fifos cannot be overwritten, and are not
1064 free-running DMAs. Silence is output on fifo underflow.
1065 This callback is still required to allow the copy callback to be used.
1066 */
1067 return 0;
1068}
1069
1070static struct snd_pcm_ops snd_card_asihpi_playback_ops = {
1071 .open = snd_card_asihpi_playback_open,
1072 .close = snd_card_asihpi_playback_close,
1073 .ioctl = snd_card_asihpi_playback_ioctl,
1074 .hw_params = snd_card_asihpi_pcm_hw_params,
1075 .hw_free = snd_card_asihpi_hw_free,
1076 .prepare = snd_card_asihpi_playback_prepare,
1077 .trigger = snd_card_asihpi_trigger,
1078 .pointer = snd_card_asihpi_playback_pointer,
1079 .copy = snd_card_asihpi_playback_copy,
1080 .silence = snd_card_asihpi_playback_silence,
1081};
1082
1083static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = { 1083static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
1084 .open = snd_card_asihpi_playback_open, 1084 .open = snd_card_asihpi_playback_open,
1085 .close = snd_card_asihpi_playback_close, 1085 .close = snd_card_asihpi_playback_close,
@@ -1211,18 +1211,16 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1211 snd_card_asihpi_capture_format(card, dpcm->h_stream, 1211 snd_card_asihpi_capture_format(card, dpcm->h_stream,
1212 &snd_card_asihpi_capture); 1212 &snd_card_asihpi_capture);
1213 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture); 1213 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
1214 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED; 1214 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED |
1215 1215 SNDRV_PCM_INFO_MMAP |
1216 if (card->support_mmap) 1216 SNDRV_PCM_INFO_MMAP_VALID;
1217 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP |
1218 SNDRV_PCM_INFO_MMAP_VALID;
1219 1217
1220 if (card->support_grouping) 1218 if (card->support_grouping)
1221 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START; 1219 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
1222 1220
1223 runtime->hw = snd_card_asihpi_capture; 1221 runtime->hw = snd_card_asihpi_capture;
1224 1222
1225 if (card->support_mmap) 1223 if (card->can_dma)
1226 err = snd_pcm_hw_constraint_pow2(runtime, 0, 1224 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1227 SNDRV_PCM_HW_PARAM_BUFFER_BYTES); 1225 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1228 if (err < 0) 1226 if (err < 0)
@@ -1246,28 +1244,6 @@ static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1246 return 0; 1244 return 0;
1247} 1245}
1248 1246
1249static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream,
1250 int channel, snd_pcm_uframes_t pos,
1251 void __user *dst, snd_pcm_uframes_t count)
1252{
1253 struct snd_pcm_runtime *runtime = substream->runtime;
1254 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1255 u32 len;
1256
1257 len = frames_to_bytes(runtime, count);
1258
1259 snd_printddd("capture copy%d %d bytes\n", substream->number, len);
1260 hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream,
1261 runtime->dma_area, len));
1262
1263 dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len;
1264
1265 if (copy_to_user(dst, runtime->dma_area, len))
1266 return -EFAULT;
1267
1268 return 0;
1269}
1270
1271static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { 1247static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1272 .open = snd_card_asihpi_capture_open, 1248 .open = snd_card_asihpi_capture_open,
1273 .close = snd_card_asihpi_capture_close, 1249 .close = snd_card_asihpi_capture_close,
@@ -1279,18 +1255,6 @@ static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1279 .pointer = snd_card_asihpi_capture_pointer, 1255 .pointer = snd_card_asihpi_capture_pointer,
1280}; 1256};
1281 1257
1282static struct snd_pcm_ops snd_card_asihpi_capture_ops = {
1283 .open = snd_card_asihpi_capture_open,
1284 .close = snd_card_asihpi_capture_close,
1285 .ioctl = snd_card_asihpi_capture_ioctl,
1286 .hw_params = snd_card_asihpi_pcm_hw_params,
1287 .hw_free = snd_card_asihpi_hw_free,
1288 .prepare = snd_card_asihpi_capture_prepare,
1289 .trigger = snd_card_asihpi_trigger,
1290 .pointer = snd_card_asihpi_capture_pointer,
1291 .copy = snd_card_asihpi_capture_copy
1292};
1293
1294static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, 1258static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1295 int device, int substreams) 1259 int device, int substreams)
1296{ 1260{
@@ -1303,17 +1267,10 @@ static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1303 if (err < 0) 1267 if (err < 0)
1304 return err; 1268 return err;
1305 /* pointer to ops struct is stored, dont change ops afterwards! */ 1269 /* pointer to ops struct is stored, dont change ops afterwards! */
1306 if (asihpi->support_mmap) {
1307 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, 1270 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1308 &snd_card_asihpi_playback_mmap_ops); 1271 &snd_card_asihpi_playback_mmap_ops);
1309 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 1272 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1310 &snd_card_asihpi_capture_mmap_ops); 1273 &snd_card_asihpi_capture_mmap_ops);
1311 } else {
1312 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1313 &snd_card_asihpi_playback_ops);
1314 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1315 &snd_card_asihpi_capture_ops);
1316 }
1317 1274
1318 pcm->private_data = asihpi; 1275 pcm->private_data = asihpi;
1319 pcm->info_flags = 0; 1276 pcm->info_flags = 0;
@@ -1413,14 +1370,16 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1413 struct hpi_control *hpi_ctl, 1370 struct hpi_control *hpi_ctl,
1414 char *name) 1371 char *name)
1415{ 1372{
1416 char *dir = ""; 1373 char *dir;
1417 memset(snd_control, 0, sizeof(*snd_control)); 1374 memset(snd_control, 0, sizeof(*snd_control));
1418 snd_control->name = hpi_ctl->name; 1375 snd_control->name = hpi_ctl->name;
1419 snd_control->private_value = hpi_ctl->h_control; 1376 snd_control->private_value = hpi_ctl->h_control;
1420 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1377 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1421 snd_control->index = 0; 1378 snd_control->index = 0;
1422 1379
1423 if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM) 1380 if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE)
1381 dir = ""; /* clock is neither capture nor playback */
1382 else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
1424 dir = "Capture "; /* On or towards a PCM capture destination*/ 1383 dir = "Capture "; /* On or towards a PCM capture destination*/
1425 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) && 1384 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1426 (!hpi_ctl->dst_node_type)) 1385 (!hpi_ctl->dst_node_type))
@@ -1433,7 +1392,7 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1433 dir = "Playback "; /* PCM Playback source, or output node */ 1392 dir = "Playback "; /* PCM Playback source, or output node */
1434 1393
1435 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type) 1394 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1436 sprintf(hpi_ctl->name, "%s%d %s%d %s%s", 1395 sprintf(hpi_ctl->name, "%s %d %s %d %s%s",
1437 asihpi_src_names[hpi_ctl->src_node_type], 1396 asihpi_src_names[hpi_ctl->src_node_type],
1438 hpi_ctl->src_node_index, 1397 hpi_ctl->src_node_index,
1439 asihpi_dst_names[hpi_ctl->dst_node_type], 1398 asihpi_dst_names[hpi_ctl->dst_node_type],
@@ -2875,14 +2834,14 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2875 if (err) 2834 if (err)
2876 asihpi->update_interval_frames = 512; 2835 asihpi->update_interval_frames = 512;
2877 2836
2878 if (!asihpi->support_mmap) 2837 if (!asihpi->can_dma)
2879 asihpi->update_interval_frames *= 2; 2838 asihpi->update_interval_frames *= 2;
2880 2839
2881 hpi_handle_error(hpi_instream_open(asihpi->adapter_index, 2840 hpi_handle_error(hpi_instream_open(asihpi->adapter_index,
2882 0, &h_stream)); 2841 0, &h_stream));
2883 2842
2884 err = hpi_instream_host_buffer_free(h_stream); 2843 err = hpi_instream_host_buffer_free(h_stream);
2885 asihpi->support_mmap = (!err); 2844 asihpi->can_dma = (!err);
2886 2845
2887 hpi_handle_error(hpi_instream_close(h_stream)); 2846 hpi_handle_error(hpi_instream_close(h_stream));
2888 2847
@@ -2894,8 +2853,8 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2894 asihpi->out_max_chans = 2; 2853 asihpi->out_max_chans = 2;
2895 } 2854 }
2896 2855
2897 snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n", 2856 snd_printk(KERN_INFO "has dma:%d, grouping:%d, mrx:%d\n",
2898 asihpi->support_mmap, 2857 asihpi->can_dma,
2899 asihpi->support_grouping, 2858 asihpi->support_grouping,
2900 asihpi->support_mrx 2859 asihpi->support_mrx
2901 ); 2860 );
@@ -2925,10 +2884,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2925 by enable_hwdep module param*/ 2884 by enable_hwdep module param*/
2926 snd_asihpi_hpi_new(asihpi, 0, NULL); 2885 snd_asihpi_hpi_new(asihpi, 0, NULL);
2927 2886
2928 if (asihpi->support_mmap) 2887 strcpy(card->driver, "ASIHPI");
2929 strcpy(card->driver, "ASIHPI-MMAP");
2930 else
2931 strcpy(card->driver, "ASIHPI");
2932 2888
2933 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type); 2889 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
2934 sprintf(card->longname, "%s %i", 2890 sprintf(card->longname, "%s %i",
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
index 8c8aac4c567e..df4aed5295dd 100644
--- a/sound/pci/asihpi/hpi6000.c
+++ b/sound/pci/asihpi/hpi6000.c
@@ -200,8 +200,8 @@ static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
200static void subsys_create_adapter(struct hpi_message *phm, 200static void subsys_create_adapter(struct hpi_message *phm,
201 struct hpi_response *phr); 201 struct hpi_response *phr);
202 202
203static void subsys_delete_adapter(struct hpi_message *phm, 203static void adapter_delete(struct hpi_adapter_obj *pao,
204 struct hpi_response *phr); 204 struct hpi_message *phm, struct hpi_response *phr);
205 205
206static void adapter_get_asserts(struct hpi_adapter_obj *pao, 206static void adapter_get_asserts(struct hpi_adapter_obj *pao,
207 struct hpi_message *phm, struct hpi_response *phr); 207 struct hpi_message *phm, struct hpi_response *phr);
@@ -222,9 +222,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
222 case HPI_SUBSYS_CREATE_ADAPTER: 222 case HPI_SUBSYS_CREATE_ADAPTER:
223 subsys_create_adapter(phm, phr); 223 subsys_create_adapter(phm, phr);
224 break; 224 break;
225 case HPI_SUBSYS_DELETE_ADAPTER:
226 subsys_delete_adapter(phm, phr);
227 break;
228 default: 225 default:
229 phr->error = HPI_ERROR_INVALID_FUNC; 226 phr->error = HPI_ERROR_INVALID_FUNC;
230 break; 227 break;
@@ -279,6 +276,10 @@ static void adapter_message(struct hpi_adapter_obj *pao,
279 adapter_get_asserts(pao, phm, phr); 276 adapter_get_asserts(pao, phm, phr);
280 break; 277 break;
281 278
279 case HPI_ADAPTER_DELETE:
280 adapter_delete(pao, phm, phr);
281 break;
282
282 default: 283 default:
283 hw_message(pao, phm, phr); 284 hw_message(pao, phm, phr);
284 break; 285 break;
@@ -333,26 +334,22 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
333{ 334{
334 struct hpi_adapter_obj *pao = NULL; 335 struct hpi_adapter_obj *pao = NULL;
335 336
336 /* subsytem messages get executed by every HPI. */
337 /* All other messages are ignored unless the adapter index matches */
338 /* an adapter in the HPI */
339 /*HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->wObject, phm->wFunction); */
340
341 /* if Dsp has crashed then do not communicate with it any more */
342 if (phm->object != HPI_OBJ_SUBSYSTEM) { 337 if (phm->object != HPI_OBJ_SUBSYSTEM) {
343 pao = hpi_find_adapter(phm->adapter_index); 338 pao = hpi_find_adapter(phm->adapter_index);
344 if (!pao) { 339 if (!pao) {
345 HPI_DEBUG_LOG(DEBUG, 340 hpi_init_response(phr, phm->object, phm->function,
346 " %d,%d refused, for another HPI?\n", 341 HPI_ERROR_BAD_ADAPTER_NUMBER);
347 phm->object, phm->function); 342 HPI_DEBUG_LOG(DEBUG, "invalid adapter index: %d \n",
343 phm->adapter_index);
348 return; 344 return;
349 } 345 }
350 346
347 /* Don't even try to communicate with crashed DSP */
351 if (pao->dsp_crashed >= 10) { 348 if (pao->dsp_crashed >= 10) {
352 hpi_init_response(phr, phm->object, phm->function, 349 hpi_init_response(phr, phm->object, phm->function,
353 HPI_ERROR_DSP_HARDWARE); 350 HPI_ERROR_DSP_HARDWARE);
354 HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n", 351 HPI_DEBUG_LOG(DEBUG, "adapter %d dsp crashed\n",
355 phm->object, phm->function); 352 phm->adapter_index);
356 return; 353 return;
357 } 354 }
358 } 355 }
@@ -463,15 +460,9 @@ static void subsys_create_adapter(struct hpi_message *phm,
463 phr->error = 0; 460 phr->error = 0;
464} 461}
465 462
466static void subsys_delete_adapter(struct hpi_message *phm, 463static void adapter_delete(struct hpi_adapter_obj *pao,
467 struct hpi_response *phr) 464 struct hpi_message *phm, struct hpi_response *phr)
468{ 465{
469 struct hpi_adapter_obj *pao = NULL;
470
471 pao = hpi_find_adapter(phm->obj_index);
472 if (!pao)
473 return;
474
475 delete_adapter_obj(pao); 466 delete_adapter_obj(pao);
476 hpi_delete_adapter(pao); 467 hpi_delete_adapter(pao);
477 phr->error = 0; 468 phr->error = 0;
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
index 22e9f08dea6d..9d5df54a6b46 100644
--- a/sound/pci/asihpi/hpi6205.c
+++ b/sound/pci/asihpi/hpi6205.c
@@ -152,8 +152,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
152 152
153static void subsys_create_adapter(struct hpi_message *phm, 153static void subsys_create_adapter(struct hpi_message *phm,
154 struct hpi_response *phr); 154 struct hpi_response *phr);
155static void subsys_delete_adapter(struct hpi_message *phm, 155static void adapter_delete(struct hpi_adapter_obj *pao,
156 struct hpi_response *phr); 156 struct hpi_message *phm, struct hpi_response *phr);
157 157
158static u16 create_adapter_obj(struct hpi_adapter_obj *pao, 158static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
159 u32 *pos_error_code); 159 u32 *pos_error_code);
@@ -223,15 +223,13 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
223 223
224/*****************************************************************************/ 224/*****************************************************************************/
225 225
226static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) 226static void subsys_message(struct hpi_adapter_obj *pao,
227 struct hpi_message *phm, struct hpi_response *phr)
227{ 228{
228 switch (phm->function) { 229 switch (phm->function) {
229 case HPI_SUBSYS_CREATE_ADAPTER: 230 case HPI_SUBSYS_CREATE_ADAPTER:
230 subsys_create_adapter(phm, phr); 231 subsys_create_adapter(phm, phr);
231 break; 232 break;
232 case HPI_SUBSYS_DELETE_ADAPTER:
233 subsys_delete_adapter(phm, phr);
234 break;
235 default: 233 default:
236 phr->error = HPI_ERROR_INVALID_FUNC; 234 phr->error = HPI_ERROR_INVALID_FUNC;
237 break; 235 break;
@@ -279,6 +277,10 @@ static void adapter_message(struct hpi_adapter_obj *pao,
279 struct hpi_message *phm, struct hpi_response *phr) 277 struct hpi_message *phm, struct hpi_response *phr)
280{ 278{
281 switch (phm->function) { 279 switch (phm->function) {
280 case HPI_ADAPTER_DELETE:
281 adapter_delete(pao, phm, phr);
282 break;
283
282 default: 284 default:
283 hw_message(pao, phm, phr); 285 hw_message(pao, phm, phr);
284 break; 286 break;
@@ -371,36 +373,17 @@ static void instream_message(struct hpi_adapter_obj *pao,
371/** Entry point to this HPI backend 373/** Entry point to this HPI backend
372 * All calls to the HPI start here 374 * All calls to the HPI start here
373 */ 375 */
374void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) 376void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
377 struct hpi_response *phr)
375{ 378{
376 struct hpi_adapter_obj *pao = NULL; 379 if (pao && (pao->dsp_crashed >= 10)
377 380 && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
378 /* subsytem messages are processed by every HPI. 381 /* allow last resort debug read even after crash */
379 * All other messages are ignored unless the adapter index matches 382 hpi_init_response(phr, phm->object, phm->function,
380 * an adapter in the HPI 383 HPI_ERROR_DSP_HARDWARE);
381 */ 384 HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", phm->object,
382 /* HPI_DEBUG_LOG(DEBUG, "HPI Obj=%d, Func=%d\n", phm->wObject, 385 phm->function);
383 phm->wFunction); */ 386 return;
384
385 /* if Dsp has crashed then do not communicate with it any more */
386 if (phm->object != HPI_OBJ_SUBSYSTEM) {
387 pao = hpi_find_adapter(phm->adapter_index);
388 if (!pao) {
389 HPI_DEBUG_LOG(DEBUG,
390 " %d,%d refused, for another HPI?\n",
391 phm->object, phm->function);
392 return;
393 }
394
395 if ((pao->dsp_crashed >= 10)
396 && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
397 /* allow last resort debug read even after crash */
398 hpi_init_response(phr, phm->object, phm->function,
399 HPI_ERROR_DSP_HARDWARE);
400 HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n",
401 phm->object, phm->function);
402 return;
403 }
404 } 387 }
405 388
406 /* Init default response */ 389 /* Init default response */
@@ -412,7 +395,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
412 case HPI_TYPE_MESSAGE: 395 case HPI_TYPE_MESSAGE:
413 switch (phm->object) { 396 switch (phm->object) {
414 case HPI_OBJ_SUBSYSTEM: 397 case HPI_OBJ_SUBSYSTEM:
415 subsys_message(phm, phr); 398 subsys_message(pao, phm, phr);
416 break; 399 break;
417 400
418 case HPI_OBJ_ADAPTER: 401 case HPI_OBJ_ADAPTER:
@@ -444,6 +427,26 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
444 } 427 }
445} 428}
446 429
430void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
431{
432 struct hpi_adapter_obj *pao = NULL;
433
434 if (phm->object != HPI_OBJ_SUBSYSTEM) {
435 /* normal messages must have valid adapter index */
436 pao = hpi_find_adapter(phm->adapter_index);
437 } else {
438 /* subsys messages don't address an adapter */
439 _HPI_6205(NULL, phm, phr);
440 return;
441 }
442
443 if (pao)
444 _HPI_6205(pao, phm, phr);
445 else
446 hpi_init_response(phr, phm->object, phm->function,
447 HPI_ERROR_BAD_ADAPTER_NUMBER);
448}
449
447/*****************************************************************************/ 450/*****************************************************************************/
448/* SUBSYSTEM */ 451/* SUBSYSTEM */
449 452
@@ -491,13 +494,11 @@ static void subsys_create_adapter(struct hpi_message *phm,
491} 494}
492 495
493/** delete an adapter - required by WDM driver */ 496/** delete an adapter - required by WDM driver */
494static void subsys_delete_adapter(struct hpi_message *phm, 497static void adapter_delete(struct hpi_adapter_obj *pao,
495 struct hpi_response *phr) 498 struct hpi_message *phm, struct hpi_response *phr)
496{ 499{
497 struct hpi_adapter_obj *pao;
498 struct hpi_hw_obj *phw; 500 struct hpi_hw_obj *phw;
499 501
500 pao = hpi_find_adapter(phm->obj_index);
501 if (!pao) { 502 if (!pao) {
502 phr->error = HPI_ERROR_INVALID_OBJ_INDEX; 503 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
503 return; 504 return;
@@ -563,11 +564,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
563 } 564 }
564 565
565 err = adapter_boot_load_dsp(pao, pos_error_code); 566 err = adapter_boot_load_dsp(pao, pos_error_code);
566 if (err) 567 if (err) {
568 HPI_DEBUG_LOG(ERROR, "DSP code load failed\n");
567 /* no need to clean up as SubSysCreateAdapter */ 569 /* no need to clean up as SubSysCreateAdapter */
568 /* calls DeleteAdapter on error. */ 570 /* calls DeleteAdapter on error. */
569 return err; 571 return err;
570 572 }
571 HPI_DEBUG_LOG(INFO, "load DSP code OK\n"); 573 HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
572 574
573 /* allow boot load even if mem alloc wont work */ 575 /* allow boot load even if mem alloc wont work */
@@ -604,6 +606,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
604 control_cache.number_of_controls, 606 control_cache.number_of_controls,
605 interface->control_cache.size_in_bytes, 607 interface->control_cache.size_in_bytes,
606 p_control_cache_virtual); 608 p_control_cache_virtual);
609
607 if (!phw->p_cache) 610 if (!phw->p_cache)
608 err = HPI_ERROR_MEMORY_ALLOC; 611 err = HPI_ERROR_MEMORY_ALLOC;
609 } 612 }
@@ -675,16 +678,14 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
675} 678}
676 679
677/** Free memory areas allocated by adapter 680/** Free memory areas allocated by adapter
678 * this routine is called from SubSysDeleteAdapter, 681 * this routine is called from AdapterDelete,
679 * and SubSysCreateAdapter if duplicate index 682 * and SubSysCreateAdapter if duplicate index
680*/ 683*/
681static void delete_adapter_obj(struct hpi_adapter_obj *pao) 684static void delete_adapter_obj(struct hpi_adapter_obj *pao)
682{ 685{
683 struct hpi_hw_obj *phw; 686 struct hpi_hw_obj *phw = pao->priv;
684 int i; 687 int i;
685 688
686 phw = pao->priv;
687
688 if (hpios_locked_mem_valid(&phw->h_control_cache)) { 689 if (hpios_locked_mem_valid(&phw->h_control_cache)) {
689 hpios_locked_mem_free(&phw->h_control_cache); 690 hpios_locked_mem_free(&phw->h_control_cache);
690 hpi_free_control_cache(phw->p_cache); 691 hpi_free_control_cache(phw->p_cache);
@@ -1275,6 +1276,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1275 case HPI_ADAPTER_FAMILY_ASI(0x6300): 1276 case HPI_ADAPTER_FAMILY_ASI(0x6300):
1276 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400); 1277 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400);
1277 break; 1278 break;
1279 case HPI_ADAPTER_FAMILY_ASI(0x5500):
1278 case HPI_ADAPTER_FAMILY_ASI(0x5600): 1280 case HPI_ADAPTER_FAMILY_ASI(0x5600):
1279 case HPI_ADAPTER_FAMILY_ASI(0x6500): 1281 case HPI_ADAPTER_FAMILY_ASI(0x6500):
1280 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600); 1282 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600);
@@ -2059,7 +2061,6 @@ static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
2059static void send_dsp_command(struct hpi_hw_obj *phw, int cmd) 2061static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
2060{ 2062{
2061 struct bus_master_interface *interface = phw->p_interface_buffer; 2063 struct bus_master_interface *interface = phw->p_interface_buffer;
2062
2063 u32 r; 2064 u32 r;
2064 2065
2065 interface->host_cmd = cmd; 2066 interface->host_cmd = cmd;
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
index 3b9fd115da36..bf5eced76bac 100644
--- a/sound/pci/asihpi/hpi_internal.h
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -294,7 +294,7 @@ enum HPI_CONTROL_ATTRIBUTES {
294 294
295/* These defines are used to fill in protocol information for an Ethernet packet 295/* These defines are used to fill in protocol information for an Ethernet packet
296 sent using HMI on CS18102 */ 296 sent using HMI on CS18102 */
297/** ID supplied by Cirrius for ASI packets. */ 297/** ID supplied by Cirrus for ASI packets. */
298#define HPI_ETHERNET_PACKET_ID 0x85 298#define HPI_ETHERNET_PACKET_ID 0x85
299/** Simple packet - no special routing required */ 299/** Simple packet - no special routing required */
300#define HPI_ETHERNET_PACKET_V1 0x01 300#define HPI_ETHERNET_PACKET_V1 0x01
@@ -307,7 +307,7 @@ enum HPI_CONTROL_ATTRIBUTES {
307/** This packet must make its way to the host across the HPI interface */ 307/** This packet must make its way to the host across the HPI interface */
308#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41 308#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41
309 309
310#define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */ 310#define HPI_ETHERNET_UDP_PORT 44600 /**< HPI UDP service */
311 311
312/** Default network timeout in milli-seconds. */ 312/** Default network timeout in milli-seconds. */
313#define HPI_ETHERNET_TIMEOUT_MS 500 313#define HPI_ETHERNET_TIMEOUT_MS 500
@@ -397,14 +397,14 @@ enum HPI_FUNCTION_IDS {
397 HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1), 397 HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1),
398 HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2), 398 HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2),
399 HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3), 399 HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3),
400 HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), 400 /* HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), */
401 HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5), 401 HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5),
402 HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6), 402 HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6),
403 HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), 403 /* HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), */
404 HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8), 404 HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8),
405 HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9), 405 HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9),
406 HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), 406 /* HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), */
407 HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), 407 /* HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), */
408 HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12), 408 HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12),
409 HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13), 409 HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13),
410 HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14), 410 HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14),
@@ -433,7 +433,8 @@ enum HPI_FUNCTION_IDS {
433 HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18), 433 HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18),
434 HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19), 434 HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19),
435 HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20), 435 HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20),
436#define HPI_ADAPTER_FUNCTION_COUNT 20 436 HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21),
437#define HPI_ADAPTER_FUNCTION_COUNT 21
437 438
438 HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1), 439 HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1),
439 HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2), 440 HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2),
@@ -1561,8 +1562,6 @@ void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr);
1561u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource, 1562u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource,
1562 u16 *pw_adapter_index); 1563 u16 *pw_adapter_index);
1563 1564
1564u16 hpi_subsys_delete_adapter(u16 adapter_index);
1565
1566u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer, 1565u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer,
1567 struct hpi_hostbuffer_status **pp_status); 1566 struct hpi_hostbuffer_status **pp_status);
1568 1567
@@ -1584,9 +1583,7 @@ void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR);
1584 1583
1585/*////////////////////////////////////////////////////////////////////////// */ 1584/*////////////////////////////////////////////////////////////////////////// */
1586/* declarations for individual HPI entry points */ 1585/* declarations for individual HPI entry points */
1587hpi_handler_func HPI_1000;
1588hpi_handler_func HPI_6000; 1586hpi_handler_func HPI_6000;
1589hpi_handler_func HPI_6205; 1587hpi_handler_func HPI_6205;
1590hpi_handler_func HPI_COMMON;
1591 1588
1592#endif /* _HPI_INTERNAL_H_ */ 1589#endif /* _HPI_INTERNAL_H_ */
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
index 3e9c5c289764..b15a02e91f82 100644
--- a/sound/pci/asihpi/hpicmn.c
+++ b/sound/pci/asihpi/hpicmn.c
@@ -227,8 +227,9 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
227 if (info->control_type) { 227 if (info->control_type) {
228 pC->p_info[info->control_index] = info; 228 pC->p_info[info->control_index] = info;
229 cached++; 229 cached++;
230 } else /* dummy cache entry */ 230 } else { /* dummy cache entry */
231 pC->p_info[info->control_index] = NULL; 231 pC->p_info[info->control_index] = NULL;
232 }
232 233
233 byte_count += info->size_in32bit_words * 4; 234 byte_count += info->size_in32bit_words * 4;
234 235
@@ -298,7 +299,7 @@ struct pad_ofs_size {
298 unsigned int field_size; 299 unsigned int field_size;
299}; 300};
300 301
301static struct pad_ofs_size pad_desc[] = { 302static const struct pad_ofs_size pad_desc[] = {
302 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */ 303 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
303 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */ 304 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */
304 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */ 305 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */
@@ -617,6 +618,10 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
617 } 618 }
618} 619}
619 620
621/** Allocate control cache.
622
623\return Cache pointer, or NULL if allocation fails.
624*/
620struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count, 625struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
621 const u32 size_in_bytes, u8 *p_dsp_control_buffer) 626 const u32 size_in_bytes, u8 *p_dsp_control_buffer)
622{ 627{
@@ -667,7 +672,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
667 phr->u.s.num_adapters = adapters.gw_num_adapters; 672 phr->u.s.num_adapters = adapters.gw_num_adapters;
668 break; 673 break;
669 case HPI_SUBSYS_CREATE_ADAPTER: 674 case HPI_SUBSYS_CREATE_ADAPTER:
670 case HPI_SUBSYS_DELETE_ADAPTER:
671 break; 675 break;
672 default: 676 default:
673 phr->error = HPI_ERROR_INVALID_FUNC; 677 phr->error = HPI_ERROR_INVALID_FUNC;
diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h
index 590f0b69e655..d53cdf6e535f 100644
--- a/sound/pci/asihpi/hpicmn.h
+++ b/sound/pci/asihpi/hpicmn.h
@@ -60,3 +60,5 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *pC,
60 struct hpi_message *phm, struct hpi_response *phr); 60 struct hpi_message *phm, struct hpi_response *phr);
61 61
62u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr); 62u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr);
63
64hpi_handler_func HPI_COMMON;
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
index c38fc9487560..7397b169b89f 100644
--- a/sound/pci/asihpi/hpifunc.c
+++ b/sound/pci/asihpi/hpifunc.c
@@ -105,33 +105,6 @@ u16 hpi_subsys_get_version_ex(u32 *pversion_ex)
105 return hr.error; 105 return hr.error;
106} 106}
107 107
108u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource,
109 u16 *pw_adapter_index)
110{
111 struct hpi_message hm;
112 struct hpi_response hr;
113
114 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
115 HPI_SUBSYS_CREATE_ADAPTER);
116 hm.u.s.resource = *p_resource;
117
118 hpi_send_recv(&hm, &hr);
119
120 *pw_adapter_index = hr.u.s.adapter_index;
121 return hr.error;
122}
123
124u16 hpi_subsys_delete_adapter(u16 adapter_index)
125{
126 struct hpi_message hm;
127 struct hpi_response hr;
128 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
129 HPI_SUBSYS_DELETE_ADAPTER);
130 hm.obj_index = adapter_index;
131 hpi_send_recv(&hm, &hr);
132 return hr.error;
133}
134
135u16 hpi_subsys_get_num_adapters(int *pn_num_adapters) 108u16 hpi_subsys_get_num_adapters(int *pn_num_adapters)
136{ 109{
137 struct hpi_message hm; 110 struct hpi_message hm;
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c
index 360028b9abf5..7352a5f7b4f7 100644
--- a/sound/pci/asihpi/hpimsgx.c
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -211,24 +211,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
211 HPIMSGX__init(phm, phr); 211 HPIMSGX__init(phm, phr);
212 break; 212 break;
213 213
214 case HPI_SUBSYS_DELETE_ADAPTER:
215 HPIMSGX__cleanup(phm->obj_index, h_owner);
216 {
217 struct hpi_message hm;
218 struct hpi_response hr;
219 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
220 HPI_ADAPTER_CLOSE);
221 hm.adapter_index = phm->obj_index;
222 hw_entry_point(&hm, &hr);
223 }
224 if ((phm->obj_index < HPI_MAX_ADAPTERS)
225 && hpi_entry_points[phm->obj_index]) {
226 hpi_entry_points[phm->obj_index] (phm, phr);
227 hpi_entry_points[phm->obj_index] = NULL;
228 } else
229 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
230
231 break;
232 default: 214 default:
233 /* Must explicitly handle every subsys message in this switch */ 215 /* Must explicitly handle every subsys message in this switch */
234 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 216 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function,
@@ -247,6 +229,19 @@ static void adapter_message(struct hpi_message *phm, struct hpi_response *phr,
247 case HPI_ADAPTER_CLOSE: 229 case HPI_ADAPTER_CLOSE:
248 adapter_close(phm, phr); 230 adapter_close(phm, phr);
249 break; 231 break;
232 case HPI_ADAPTER_DELETE:
233 HPIMSGX__cleanup(phm->adapter_index, h_owner);
234 {
235 struct hpi_message hm;
236 struct hpi_response hr;
237 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
238 HPI_ADAPTER_CLOSE);
239 hm.adapter_index = phm->adapter_index;
240 hw_entry_point(&hm, &hr);
241 }
242 hw_entry_point(phm, phr);
243 break;
244
250 default: 245 default:
251 hw_entry_point(phm, phr); 246 hw_entry_point(phm, phr);
252 break; 247 break;
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index cd624f13ff8e..d8e7047512f8 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -25,6 +25,7 @@ Common Linux HPI ioctl and module probe/remove functions
25#include "hpidebug.h" 25#include "hpidebug.h"
26#include "hpimsgx.h" 26#include "hpimsgx.h"
27#include "hpioctl.h" 27#include "hpioctl.h"
28#include "hpicmn.h"
28 29
29#include <linux/fs.h> 30#include <linux/fs.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
@@ -161,26 +162,24 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
161 goto out; 162 goto out;
162 } 163 }
163 164
164 pa = &adapters[hm->h.adapter_index]; 165 switch (hm->h.function) {
166 case HPI_SUBSYS_CREATE_ADAPTER:
167 case HPI_ADAPTER_DELETE:
168 /* Application must not use these functions! */
169 hr->h.size = sizeof(hr->h);
170 hr->h.error = HPI_ERROR_INVALID_OPERATION;
171 hr->h.function = hm->h.function;
172 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
173 if (uncopied_bytes)
174 err = -EFAULT;
175 else
176 err = 0;
177 goto out;
178 }
179
165 hr->h.size = res_max_size; 180 hr->h.size = res_max_size;
166 if (hm->h.object == HPI_OBJ_SUBSYSTEM) { 181 if (hm->h.object == HPI_OBJ_SUBSYSTEM) {
167 switch (hm->h.function) { 182 hpi_send_recv_f(&hm->m0, &hr->r0, file);
168 case HPI_SUBSYS_CREATE_ADAPTER:
169 case HPI_SUBSYS_DELETE_ADAPTER:
170 /* Application must not use these functions! */
171 hr->h.size = sizeof(hr->h);
172 hr->h.error = HPI_ERROR_INVALID_OPERATION;
173 hr->h.function = hm->h.function;
174 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
175 if (uncopied_bytes)
176 err = -EFAULT;
177 else
178 err = 0;
179 goto out;
180
181 default:
182 hpi_send_recv_f(&hm->m0, &hr->r0, file);
183 }
184 } else { 183 } else {
185 u16 __user *ptr = NULL; 184 u16 __user *ptr = NULL;
186 u32 size = 0; 185 u32 size = 0;
@@ -188,8 +187,9 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
188 /* -1=no data 0=read from user mem, 1=write to user mem */ 187 /* -1=no data 0=read from user mem, 1=write to user mem */
189 int wrflag = -1; 188 int wrflag = -1;
190 u32 adapter = hm->h.adapter_index; 189 u32 adapter = hm->h.adapter_index;
190 pa = &adapters[adapter];
191 191
192 if ((hm->h.adapter_index > HPI_MAX_ADAPTERS) || (!pa->type)) { 192 if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) {
193 hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER, 193 hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER,
194 HPI_ADAPTER_OPEN, 194 HPI_ADAPTER_OPEN,
195 HPI_ERROR_BAD_ADAPTER_NUMBER); 195 HPI_ERROR_BAD_ADAPTER_NUMBER);
@@ -317,7 +317,7 @@ out:
317int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, 317int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
318 const struct pci_device_id *pci_id) 318 const struct pci_device_id *pci_id)
319{ 319{
320 int err, idx, nm; 320 int idx, nm;
321 unsigned int memlen; 321 unsigned int memlen;
322 struct hpi_message hm; 322 struct hpi_message hm;
323 struct hpi_response hr; 323 struct hpi_response hr;
@@ -351,11 +351,8 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
351 nm = HPI_MAX_ADAPTER_MEM_SPACES; 351 nm = HPI_MAX_ADAPTER_MEM_SPACES;
352 352
353 for (idx = 0; idx < nm; idx++) { 353 for (idx = 0; idx < nm; idx++) {
354 HPI_DEBUG_LOG(INFO, "resource %d %s %08llx-%08llx %04llx\n", 354 HPI_DEBUG_LOG(INFO, "resource %d %pR\n", idx,
355 idx, pci_dev->resource[idx].name, 355 &pci_dev->resource[idx]);
356 (unsigned long long)pci_resource_start(pci_dev, idx),
357 (unsigned long long)pci_resource_end(pci_dev, idx),
358 (unsigned long long)pci_resource_flags(pci_dev, idx));
359 356
360 if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) { 357 if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) {
361 memlen = pci_resource_len(pci_dev, idx); 358 memlen = pci_resource_len(pci_dev, idx);
@@ -395,17 +392,20 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
395 392
396 adapter.index = hr.u.s.adapter_index; 393 adapter.index = hr.u.s.adapter_index;
397 adapter.type = hr.u.s.adapter_type; 394 adapter.type = hr.u.s.adapter_type;
395
396 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
397 HPI_ADAPTER_OPEN);
398 hm.adapter_index = adapter.index; 398 hm.adapter_index = adapter.index;
399 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
399 400
400 err = hpi_adapter_open(adapter.index); 401 if (hr.error)
401 if (err)
402 goto err; 402 goto err;
403 403
404 adapter.snd_card_asihpi = NULL; 404 adapter.snd_card_asihpi = NULL;
405 /* WARNING can't init mutex in 'adapter' 405 /* WARNING can't init mutex in 'adapter'
406 * and then copy it to adapters[] ?!?! 406 * and then copy it to adapters[] ?!?!
407 */ 407 */
408 adapters[hr.u.s.adapter_index] = adapter; 408 adapters[adapter.index] = adapter;
409 mutex_init(&adapters[adapter.index].mutex); 409 mutex_init(&adapters[adapter.index].mutex);
410 pci_set_drvdata(pci_dev, &adapters[adapter.index]); 410 pci_set_drvdata(pci_dev, &adapters[adapter.index]);
411 411
@@ -440,10 +440,9 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
440 struct hpi_adapter *pa; 440 struct hpi_adapter *pa;
441 pa = pci_get_drvdata(pci_dev); 441 pa = pci_get_drvdata(pci_dev);
442 442
443 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, 443 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
444 HPI_SUBSYS_DELETE_ADAPTER); 444 HPI_ADAPTER_DELETE);
445 hm.obj_index = pa->index; 445 hm.adapter_index = pa->index;
446 hm.adapter_index = HPI_ADAPTER_INDEX_INVALID;
447 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); 446 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
448 447
449 /* unmap PCI memory space, mapped during device init. */ 448 /* unmap PCI memory space, mapped during device init. */
diff --git a/sound/pci/au88x0/au8810.h b/sound/pci/au88x0/au8810.h
index 5d69c31fe3f4..79fbee3845eb 100644
--- a/sound/pci/au88x0/au8810.h
+++ b/sound/pci/au88x0/au8810.h
@@ -4,7 +4,7 @@
4 4
5#define CHIP_AU8810 5#define CHIP_AU8810
6 6
7#define CARD_NAME "Aureal Advantage 3D Sound Processor" 7#define CARD_NAME "Aureal Advantage"
8#define CARD_NAME_SHORT "au8810" 8#define CARD_NAME_SHORT "au8810"
9 9
10#define NR_ADB 0x10 10#define NR_ADB 0x10
diff --git a/sound/pci/au88x0/au8820.h b/sound/pci/au88x0/au8820.h
index abbe85e4f7a9..cafdb9668a34 100644
--- a/sound/pci/au88x0/au8820.h
+++ b/sound/pci/au88x0/au8820.h
@@ -11,7 +11,7 @@
11 11
12#define CHIP_AU8820 12#define CHIP_AU8820
13 13
14#define CARD_NAME "Aureal Vortex 3D Sound Processor" 14#define CARD_NAME "Aureal Vortex"
15#define CARD_NAME_SHORT "au8820" 15#define CARD_NAME_SHORT "au8820"
16 16
17/* Number of ADB and WT channels */ 17/* Number of ADB and WT channels */
diff --git a/sound/pci/au88x0/au8830.h b/sound/pci/au88x0/au8830.h
index 04ece1b1c218..999b29ab34ad 100644
--- a/sound/pci/au88x0/au8830.h
+++ b/sound/pci/au88x0/au8830.h
@@ -11,7 +11,7 @@
11 11
12#define CHIP_AU8830 12#define CHIP_AU8830
13 13
14#define CARD_NAME "Aureal Vortex 2 3D Sound Processor" 14#define CARD_NAME "Aureal Vortex 2"
15#define CARD_NAME_SHORT "au8830" 15#define CARD_NAME_SHORT "au8830"
16 16
17#define NR_ADB 0x20 17#define NR_ADB 0x20
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index 62e959120c44..c5f7ae46afef 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -426,11 +426,11 @@ static struct snd_pcm_ops snd_vortex_playback_ops = {
426*/ 426*/
427 427
428static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = { 428static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = {
429 "AU88x0 ADB", 429 CARD_NAME " ADB",
430 "AU88x0 SPDIF", 430 CARD_NAME " SPDIF",
431 "AU88x0 A3D", 431 CARD_NAME " A3D",
432 "AU88x0 WT", 432 CARD_NAME " WT",
433 "AU88x0 I2S", 433 CARD_NAME " I2S",
434}; 434};
435static char *vortex_pcm_name[VORTEX_PCM_LAST] = { 435static char *vortex_pcm_name[VORTEX_PCM_LAST] = {
436 "adb", 436 "adb",
@@ -527,7 +527,8 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
527 nr_capt, &pcm); 527 nr_capt, &pcm);
528 if (err < 0) 528 if (err < 0)
529 return err; 529 return err;
530 strcpy(pcm->name, vortex_pcm_name[idx]); 530 snprintf(pcm->name, sizeof(pcm->name),
531 "%s %s", CARD_NAME_SHORT, vortex_pcm_name[idx]);
531 chip->pcm[idx] = pcm; 532 chip->pcm[idx] = pcm;
532 // This is an evil hack, but it saves a lot of duplicated code. 533 // This is an evil hack, but it saves a lot of duplicated code.
533 VORTEX_PCM_TYPE(pcm) = idx; 534 VORTEX_PCM_TYPE(pcm) = idx;
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 7a9401462c1c..dae4050ede5c 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -303,6 +303,9 @@ static const u32 db_table[101] = {
303static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); 303static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1);
304static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0); 304static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0);
305 305
306/* EMU10K1 bass/treble db gain */
307static const DECLARE_TLV_DB_SCALE(snd_emu10k1_bass_treble_db_scale, -1200, 60, 0);
308
306static const u32 onoff_table[2] = { 309static const u32 onoff_table[2] = {
307 0x00000000, 0x00000001 310 0x00000000, 0x00000001
308}; 311};
@@ -2163,6 +2166,7 @@ static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2163 ctl->min = 0; 2166 ctl->min = 0;
2164 ctl->max = 40; 2167 ctl->max = 40;
2165 ctl->value[0] = ctl->value[1] = 20; 2168 ctl->value[0] = ctl->value[1] = 20;
2169 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
2166 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS; 2170 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
2167 ctl = &controls[i + 1]; 2171 ctl = &controls[i + 1];
2168 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2172 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
@@ -2172,6 +2176,7 @@ static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2172 ctl->min = 0; 2176 ctl->min = 0;
2173 ctl->max = 40; 2177 ctl->max = 40;
2174 ctl->value[0] = ctl->value[1] = 20; 2178 ctl->value[0] = ctl->value[1] = 20;
2179 ctl->tlv = snd_emu10k1_bass_treble_db_scale;
2175 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE; 2180 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
2176 2181
2177#define BASS_GPR 0x8c 2182#define BASS_GPR 0x8c
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 05afe06e353a..9d890a5aec5a 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -1729,8 +1729,6 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1729 "Master Mono Playback Volume", 1729 "Master Mono Playback Volume",
1730 "PCM Out Path & Mute", 1730 "PCM Out Path & Mute",
1731 "Mono Output Select", 1731 "Mono Output Select",
1732 "Front Playback Switch",
1733 "Front Playback Volume",
1734 "Surround Playback Switch", 1732 "Surround Playback Switch",
1735 "Surround Playback Volume", 1733 "Surround Playback Volume",
1736 "Center Playback Switch", 1734 "Center Playback Switch",
@@ -1879,6 +1877,8 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1879 emu->rear_ac97 = 1; 1877 emu->rear_ac97 = 1;
1880 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT); 1878 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
1881 snd_ac97_write_cache(emu->ac97, AC97_HEADPHONE, 0x0202); 1879 snd_ac97_write_cache(emu->ac97, AC97_HEADPHONE, 0x0202);
1880 remove_ctl(card,"Front Playback Volume");
1881 remove_ctl(card,"Front Playback Switch");
1882 } 1882 }
1883 /* remove unused AC97 controls */ 1883 /* remove unused AC97 controls */
1884 snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202); 1884 snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
@@ -1913,6 +1913,12 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1913 for (; *c; c += 2) 1913 for (; *c; c += 2)
1914 rename_ctl(card, c[0], c[1]); 1914 rename_ctl(card, c[0], c[1]);
1915 1915
1916 if (emu->card_capabilities->subsystem == 0x80401102) { /* SB Live! Platinum CT4760P */
1917 remove_ctl(card, "Center Playback Volume");
1918 remove_ctl(card, "LFE Playback Volume");
1919 remove_ctl(card, "Wave Center Playback Volume");
1920 remove_ctl(card, "Wave LFE Playback Volume");
1921 }
1916 if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */ 1922 if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */
1917 rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume"); 1923 rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume");
1918 rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume"); 1924 rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume");
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 7c17f45d876d..ab0a6156a704 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -112,6 +112,10 @@
112#include <sound/ac97_codec.h> 112#include <sound/ac97_codec.h>
113#include <sound/initval.h> 113#include <sound/initval.h>
114 114
115#ifdef CONFIG_SND_ES1968_RADIO
116#include <sound/tea575x-tuner.h>
117#endif
118
115#define CARD_NAME "ESS Maestro1/2" 119#define CARD_NAME "ESS Maestro1/2"
116#define DRIVER_NAME "ES1968" 120#define DRIVER_NAME "ES1968"
117 121
@@ -553,6 +557,10 @@ struct es1968 {
553 spinlock_t ac97_lock; 557 spinlock_t ac97_lock;
554 struct tasklet_struct hwvol_tq; 558 struct tasklet_struct hwvol_tq;
555#endif 559#endif
560
561#ifdef CONFIG_SND_ES1968_RADIO
562 struct snd_tea575x tea;
563#endif
556}; 564};
557 565
558static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); 566static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
@@ -2571,6 +2579,63 @@ static int __devinit snd_es1968_input_register(struct es1968 *chip)
2571} 2579}
2572#endif /* CONFIG_SND_ES1968_INPUT */ 2580#endif /* CONFIG_SND_ES1968_INPUT */
2573 2581
2582#ifdef CONFIG_SND_ES1968_RADIO
2583#define GPIO_DATA 0x60
2584#define IO_MASK 4 /* mask register offset from GPIO_DATA
2585 bits 1=unmask write to given bit */
2586#define IO_DIR 8 /* direction register offset from GPIO_DATA
2587 bits 0/1=read/write direction */
2588/* mask bits for GPIO lines */
2589#define STR_DATA 0x0040 /* GPIO6 */
2590#define STR_CLK 0x0080 /* GPIO7 */
2591#define STR_WREN 0x0100 /* GPIO8 */
2592#define STR_MOST 0x0200 /* GPIO9 */
2593
2594static void snd_es1968_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
2595{
2596 struct es1968 *chip = tea->private_data;
2597 unsigned long io = chip->io_port + GPIO_DATA;
2598 u16 val = 0;
2599
2600 val |= (pins & TEA575X_DATA) ? STR_DATA : 0;
2601 val |= (pins & TEA575X_CLK) ? STR_CLK : 0;
2602 val |= (pins & TEA575X_WREN) ? STR_WREN : 0;
2603
2604 outw(val, io);
2605}
2606
2607static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea)
2608{
2609 struct es1968 *chip = tea->private_data;
2610 unsigned long io = chip->io_port + GPIO_DATA;
2611 u16 val = inw(io);
2612
2613 return (val & STR_DATA) ? TEA575X_DATA : 0 |
2614 (val & STR_MOST) ? TEA575X_MOST : 0;
2615}
2616
2617static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output)
2618{
2619 struct es1968 *chip = tea->private_data;
2620 unsigned long io = chip->io_port + GPIO_DATA;
2621 u16 odir = inw(io + IO_DIR);
2622
2623 if (output) {
2624 outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
2625 outw(odir | STR_DATA | STR_CLK | STR_WREN, io + IO_DIR);
2626 } else {
2627 outw(~(STR_CLK | STR_WREN | STR_DATA | STR_MOST), io + IO_MASK);
2628 outw((odir & ~(STR_DATA | STR_MOST)) | STR_CLK | STR_WREN, io + IO_DIR);
2629 }
2630}
2631
2632static struct snd_tea575x_ops snd_es1968_tea_ops = {
2633 .set_pins = snd_es1968_tea575x_set_pins,
2634 .get_pins = snd_es1968_tea575x_get_pins,
2635 .set_direction = snd_es1968_tea575x_set_direction,
2636};
2637#endif
2638
2574static int snd_es1968_free(struct es1968 *chip) 2639static int snd_es1968_free(struct es1968 *chip)
2575{ 2640{
2576#ifdef CONFIG_SND_ES1968_INPUT 2641#ifdef CONFIG_SND_ES1968_INPUT
@@ -2585,6 +2650,10 @@ static int snd_es1968_free(struct es1968 *chip)
2585 outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */ 2650 outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */
2586 } 2651 }
2587 2652
2653#ifdef CONFIG_SND_ES1968_RADIO
2654 snd_tea575x_exit(&chip->tea);
2655#endif
2656
2588 if (chip->irq >= 0) 2657 if (chip->irq >= 0)
2589 free_irq(chip->irq, chip); 2658 free_irq(chip->irq, chip);
2590 snd_es1968_free_gameport(chip); 2659 snd_es1968_free_gameport(chip);
@@ -2723,6 +2792,15 @@ static int __devinit snd_es1968_create(struct snd_card *card,
2723 2792
2724 snd_card_set_dev(card, &pci->dev); 2793 snd_card_set_dev(card, &pci->dev);
2725 2794
2795#ifdef CONFIG_SND_ES1968_RADIO
2796 chip->tea.private_data = chip;
2797 chip->tea.ops = &snd_es1968_tea_ops;
2798 strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card));
2799 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
2800 if (!snd_tea575x_init(&chip->tea))
2801 printk(KERN_INFO "es1968: detected TEA575x radio\n");
2802#endif
2803
2726 *chip_ret = chip; 2804 *chip_ret = chip;
2727 2805
2728 return 0; 2806 return 0;
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index e1baad74ea4b..eacd4901a308 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -38,7 +38,6 @@
38 38
39#ifdef CONFIG_SND_FM801_TEA575X_BOOL 39#ifdef CONFIG_SND_FM801_TEA575X_BOOL
40#include <sound/tea575x-tuner.h> 40#include <sound/tea575x-tuner.h>
41#define TEA575X_RADIO 1
42#endif 41#endif
43 42
44MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 43MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
@@ -53,7 +52,7 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card *
53/* 52/*
54 * Enable TEA575x tuner 53 * Enable TEA575x tuner
55 * 1 = MediaForte 256-PCS 54 * 1 = MediaForte 256-PCS
56 * 2 = MediaForte 256-PCPR 55 * 2 = MediaForte 256-PCP
57 * 3 = MediaForte 64-PCR 56 * 3 = MediaForte 64-PCR
58 * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card 57 * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card
59 * High 16-bits are video (radio) device number + 1 58 * High 16-bits are video (radio) device number + 1
@@ -67,7 +66,7 @@ MODULE_PARM_DESC(id, "ID string for the FM801 soundcard.");
67module_param_array(enable, bool, NULL, 0444); 66module_param_array(enable, bool, NULL, 0444);
68MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); 67MODULE_PARM_DESC(enable, "Enable FM801 soundcard.");
69module_param_array(tea575x_tuner, int, NULL, 0444); 68module_param_array(tea575x_tuner, int, NULL, 0444);
70MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (1 = SF256-PCS, 2=SF256-PCPR, 3=SF64-PCR, +16=tuner-only)."); 69MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only).");
71 70
72#define TUNER_ONLY (1<<4) 71#define TUNER_ONLY (1<<4)
73#define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF) 72#define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF)
@@ -196,7 +195,7 @@ struct fm801 {
196 spinlock_t reg_lock; 195 spinlock_t reg_lock;
197 struct snd_info_entry *proc_entry; 196 struct snd_info_entry *proc_entry;
198 197
199#ifdef TEA575X_RADIO 198#ifdef CONFIG_SND_FM801_TEA575X_BOOL
200 struct snd_tea575x tea; 199 struct snd_tea575x tea;
201#endif 200#endif
202 201
@@ -715,310 +714,89 @@ static int __devinit snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pc
715 * TEA5757 radio 714 * TEA5757 radio
716 */ 715 */
717 716
718#ifdef TEA575X_RADIO 717#ifdef CONFIG_SND_FM801_TEA575X_BOOL
719
720/* 256PCS GPIO numbers */
721#define TEA_256PCS_DATA 1
722#define TEA_256PCS_WRITE_ENABLE 2 /* inverted */
723#define TEA_256PCS_BUS_CLOCK 3
724
725static void snd_fm801_tea575x_256pcs_write(struct snd_tea575x *tea, unsigned int val)
726{
727 struct fm801 *chip = tea->private_data;
728 unsigned short reg;
729 int i = 25;
730 718
731 spin_lock_irq(&chip->reg_lock); 719/* GPIO to TEA575x maps */
732 reg = inw(FM801_REG(chip, GPIO_CTRL)); 720struct snd_fm801_tea575x_gpio {
733 /* use GPIO lines and set write enable bit */ 721 u8 data, clk, wren, most;
734 reg |= FM801_GPIO_GS(TEA_256PCS_DATA) | 722 char *name;
735 FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) | 723};
736 FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK);
737 /* all of lines are in the write direction */
738 /* clear data and clock lines */
739 reg &= ~(FM801_GPIO_GD(TEA_256PCS_DATA) |
740 FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) |
741 FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) |
742 FM801_GPIO_GP(TEA_256PCS_DATA) |
743 FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK) |
744 FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE));
745 outw(reg, FM801_REG(chip, GPIO_CTRL));
746 udelay(1);
747
748 while (i--) {
749 if (val & (1 << i))
750 reg |= FM801_GPIO_GP(TEA_256PCS_DATA);
751 else
752 reg &= ~FM801_GPIO_GP(TEA_256PCS_DATA);
753 outw(reg, FM801_REG(chip, GPIO_CTRL));
754 udelay(1);
755 reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
756 outw(reg, FM801_REG(chip, GPIO_CTRL));
757 reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
758 outw(reg, FM801_REG(chip, GPIO_CTRL));
759 udelay(1);
760 }
761 724
762 /* and reset the write enable bit */ 725static struct snd_fm801_tea575x_gpio snd_fm801_tea575x_gpios[] = {
763 reg |= FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE) | 726 { .data = 1, .clk = 3, .wren = 2, .most = 0, .name = "SF256-PCS" },
764 FM801_GPIO_GP(TEA_256PCS_DATA); 727 { .data = 1, .clk = 0, .wren = 2, .most = 3, .name = "SF256-PCP" },
765 outw(reg, FM801_REG(chip, GPIO_CTRL)); 728 { .data = 2, .clk = 0, .wren = 1, .most = 3, .name = "SF64-PCR" },
766 spin_unlock_irq(&chip->reg_lock); 729};
767}
768 730
769static unsigned int snd_fm801_tea575x_256pcs_read(struct snd_tea575x *tea) 731static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
770{ 732{
771 struct fm801 *chip = tea->private_data; 733 struct fm801 *chip = tea->private_data;
772 unsigned short reg; 734 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
773 unsigned int val = 0; 735 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1];
774 int i;
775
776 spin_lock_irq(&chip->reg_lock);
777 reg = inw(FM801_REG(chip, GPIO_CTRL));
778 /* use GPIO lines, set data direction to input */
779 reg |= FM801_GPIO_GS(TEA_256PCS_DATA) |
780 FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) |
781 FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK) |
782 FM801_GPIO_GD(TEA_256PCS_DATA) |
783 FM801_GPIO_GP(TEA_256PCS_DATA) |
784 FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE);
785 /* all of lines are in the write direction, except data */
786 /* clear data, write enable and clock lines */
787 reg &= ~(FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) |
788 FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) |
789 FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK));
790
791 for (i = 0; i < 24; i++) {
792 reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
793 outw(reg, FM801_REG(chip, GPIO_CTRL));
794 udelay(1);
795 reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
796 outw(reg, FM801_REG(chip, GPIO_CTRL));
797 udelay(1);
798 val <<= 1;
799 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCS_DATA))
800 val |= 1;
801 }
802 736
803 spin_unlock_irq(&chip->reg_lock); 737 reg &= ~(FM801_GPIO_GP(gpio.data) |
738 FM801_GPIO_GP(gpio.clk) |
739 FM801_GPIO_GP(gpio.wren));
804 740
805 return val; 741 reg |= (pins & TEA575X_DATA) ? FM801_GPIO_GP(gpio.data) : 0;
806} 742 reg |= (pins & TEA575X_CLK) ? FM801_GPIO_GP(gpio.clk) : 0;
743 /* WRITE_ENABLE is inverted */
744 reg |= (pins & TEA575X_WREN) ? 0 : FM801_GPIO_GP(gpio.wren);
807 745
808/* 256PCPR GPIO numbers */
809#define TEA_256PCPR_BUS_CLOCK 0
810#define TEA_256PCPR_DATA 1
811#define TEA_256PCPR_WRITE_ENABLE 2 /* inverted */
812
813static void snd_fm801_tea575x_256pcpr_write(struct snd_tea575x *tea, unsigned int val)
814{
815 struct fm801 *chip = tea->private_data;
816 unsigned short reg;
817 int i = 25;
818
819 spin_lock_irq(&chip->reg_lock);
820 reg = inw(FM801_REG(chip, GPIO_CTRL));
821 /* use GPIO lines and set write enable bit */
822 reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) |
823 FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) |
824 FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK);
825 /* all of lines are in the write direction */
826 /* clear data and clock lines */
827 reg &= ~(FM801_GPIO_GD(TEA_256PCPR_DATA) |
828 FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) |
829 FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) |
830 FM801_GPIO_GP(TEA_256PCPR_DATA) |
831 FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK) |
832 FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE));
833 outw(reg, FM801_REG(chip, GPIO_CTRL)); 746 outw(reg, FM801_REG(chip, GPIO_CTRL));
834 udelay(1);
835
836 while (i--) {
837 if (val & (1 << i))
838 reg |= FM801_GPIO_GP(TEA_256PCPR_DATA);
839 else
840 reg &= ~FM801_GPIO_GP(TEA_256PCPR_DATA);
841 outw(reg, FM801_REG(chip, GPIO_CTRL));
842 udelay(1);
843 reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
844 outw(reg, FM801_REG(chip, GPIO_CTRL));
845 reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
846 outw(reg, FM801_REG(chip, GPIO_CTRL));
847 udelay(1);
848 }
849
850 /* and reset the write enable bit */
851 reg |= FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE) |
852 FM801_GPIO_GP(TEA_256PCPR_DATA);
853 outw(reg, FM801_REG(chip, GPIO_CTRL));
854 spin_unlock_irq(&chip->reg_lock);
855} 747}
856 748
857static unsigned int snd_fm801_tea575x_256pcpr_read(struct snd_tea575x *tea) 749static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea)
858{ 750{
859 struct fm801 *chip = tea->private_data; 751 struct fm801 *chip = tea->private_data;
860 unsigned short reg; 752 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
861 unsigned int val = 0; 753 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1];
862 int i;
863
864 spin_lock_irq(&chip->reg_lock);
865 reg = inw(FM801_REG(chip, GPIO_CTRL));
866 /* use GPIO lines, set data direction to input */
867 reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) |
868 FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) |
869 FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK) |
870 FM801_GPIO_GD(TEA_256PCPR_DATA) |
871 FM801_GPIO_GP(TEA_256PCPR_DATA) |
872 FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE);
873 /* all of lines are in the write direction, except data */
874 /* clear data, write enable and clock lines */
875 reg &= ~(FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) |
876 FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) |
877 FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK));
878
879 for (i = 0; i < 24; i++) {
880 reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
881 outw(reg, FM801_REG(chip, GPIO_CTRL));
882 udelay(1);
883 reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
884 outw(reg, FM801_REG(chip, GPIO_CTRL));
885 udelay(1);
886 val <<= 1;
887 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCPR_DATA))
888 val |= 1;
889 }
890 754
891 spin_unlock_irq(&chip->reg_lock); 755 return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 |
892 756 (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0;
893 return val;
894} 757}
895 758
896/* 64PCR GPIO numbers */ 759static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output)
897#define TEA_64PCR_BUS_CLOCK 0
898#define TEA_64PCR_WRITE_ENABLE 1 /* inverted */
899#define TEA_64PCR_DATA 2
900
901static void snd_fm801_tea575x_64pcr_write(struct snd_tea575x *tea, unsigned int val)
902{ 760{
903 struct fm801 *chip = tea->private_data; 761 struct fm801 *chip = tea->private_data;
904 unsigned short reg; 762 unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL));
905 int i = 25; 763 struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1];
906 764
907 spin_lock_irq(&chip->reg_lock);
908 reg = inw(FM801_REG(chip, GPIO_CTRL));
909 /* use GPIO lines and set write enable bit */ 765 /* use GPIO lines and set write enable bit */
910 reg |= FM801_GPIO_GS(TEA_64PCR_DATA) | 766 reg |= FM801_GPIO_GS(gpio.data) |
911 FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) | 767 FM801_GPIO_GS(gpio.wren) |
912 FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK); 768 FM801_GPIO_GS(gpio.clk) |
913 /* all of lines are in the write direction */ 769 FM801_GPIO_GS(gpio.most);
914 /* clear data and clock lines */ 770 if (output) {
915 reg &= ~(FM801_GPIO_GD(TEA_64PCR_DATA) | 771 /* all of lines are in the write direction */
916 FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) | 772 /* clear data and clock lines */
917 FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) | 773 reg &= ~(FM801_GPIO_GD(gpio.data) |
918 FM801_GPIO_GP(TEA_64PCR_DATA) | 774 FM801_GPIO_GD(gpio.wren) |
919 FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK) | 775 FM801_GPIO_GD(gpio.clk) |
920 FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE)); 776 FM801_GPIO_GP(gpio.data) |
921 outw(reg, FM801_REG(chip, GPIO_CTRL)); 777 FM801_GPIO_GP(gpio.clk) |
922 udelay(1); 778 FM801_GPIO_GP(gpio.wren));
923 779 } else {
924 while (i--) { 780 /* use GPIO lines, set data direction to input */
925 if (val & (1 << i)) 781 reg |= FM801_GPIO_GD(gpio.data) |
926 reg |= FM801_GPIO_GP(TEA_64PCR_DATA); 782 FM801_GPIO_GD(gpio.most) |
927 else 783 FM801_GPIO_GP(gpio.data) |
928 reg &= ~FM801_GPIO_GP(TEA_64PCR_DATA); 784 FM801_GPIO_GP(gpio.most) |
929 outw(reg, FM801_REG(chip, GPIO_CTRL)); 785 FM801_GPIO_GP(gpio.wren);
930 udelay(1); 786 /* all of lines are in the write direction, except data */
931 reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); 787 /* clear data, write enable and clock lines */
932 outw(reg, FM801_REG(chip, GPIO_CTRL)); 788 reg &= ~(FM801_GPIO_GD(gpio.wren) |
933 reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); 789 FM801_GPIO_GD(gpio.clk) |
934 outw(reg, FM801_REG(chip, GPIO_CTRL)); 790 FM801_GPIO_GP(gpio.clk));
935 udelay(1);
936 } 791 }
937 792
938 /* and reset the write enable bit */
939 reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE) |
940 FM801_GPIO_GP(TEA_64PCR_DATA);
941 outw(reg, FM801_REG(chip, GPIO_CTRL)); 793 outw(reg, FM801_REG(chip, GPIO_CTRL));
942 spin_unlock_irq(&chip->reg_lock);
943}
944
945static unsigned int snd_fm801_tea575x_64pcr_read(struct snd_tea575x *tea)
946{
947 struct fm801 *chip = tea->private_data;
948 unsigned short reg;
949 unsigned int val = 0;
950 int i;
951
952 spin_lock_irq(&chip->reg_lock);
953 reg = inw(FM801_REG(chip, GPIO_CTRL));
954 /* use GPIO lines, set data direction to input */
955 reg |= FM801_GPIO_GS(TEA_64PCR_DATA) |
956 FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) |
957 FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK) |
958 FM801_GPIO_GD(TEA_64PCR_DATA) |
959 FM801_GPIO_GP(TEA_64PCR_DATA) |
960 FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
961 /* all of lines are in the write direction, except data */
962 /* clear data, write enable and clock lines */
963 reg &= ~(FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) |
964 FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) |
965 FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK));
966
967 for (i = 0; i < 24; i++) {
968 reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
969 outw(reg, FM801_REG(chip, GPIO_CTRL));
970 udelay(1);
971 reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
972 outw(reg, FM801_REG(chip, GPIO_CTRL));
973 udelay(1);
974 val <<= 1;
975 if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_64PCR_DATA))
976 val |= 1;
977 }
978
979 spin_unlock_irq(&chip->reg_lock);
980
981 return val;
982} 794}
983 795
984static void snd_fm801_tea575x_64pcr_mute(struct snd_tea575x *tea, 796static struct snd_tea575x_ops snd_fm801_tea_ops = {
985 unsigned int mute) 797 .set_pins = snd_fm801_tea575x_set_pins,
986{ 798 .get_pins = snd_fm801_tea575x_get_pins,
987 struct fm801 *chip = tea->private_data; 799 .set_direction = snd_fm801_tea575x_set_direction,
988 unsigned short reg;
989
990 spin_lock_irq(&chip->reg_lock);
991
992 reg = inw(FM801_REG(chip, GPIO_CTRL));
993 if (mute)
994 /* 0xf800 (mute) */
995 reg &= ~FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
996 else
997 /* 0xf802 (unmute) */
998 reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
999 outw(reg, FM801_REG(chip, GPIO_CTRL));
1000 udelay(1);
1001
1002 spin_unlock_irq(&chip->reg_lock);
1003}
1004
1005static struct snd_tea575x_ops snd_fm801_tea_ops[3] = {
1006 {
1007 /* 1 = MediaForte 256-PCS */
1008 .write = snd_fm801_tea575x_256pcs_write,
1009 .read = snd_fm801_tea575x_256pcs_read,
1010 },
1011 {
1012 /* 2 = MediaForte 256-PCPR */
1013 .write = snd_fm801_tea575x_256pcpr_write,
1014 .read = snd_fm801_tea575x_256pcpr_read,
1015 },
1016 {
1017 /* 3 = MediaForte 64-PCR */
1018 .write = snd_fm801_tea575x_64pcr_write,
1019 .read = snd_fm801_tea575x_64pcr_read,
1020 .mute = snd_fm801_tea575x_64pcr_mute,
1021 }
1022}; 800};
1023#endif 801#endif
1024 802
@@ -1371,7 +1149,7 @@ static int snd_fm801_free(struct fm801 *chip)
1371 outw(cmdw, FM801_REG(chip, IRQ_MASK)); 1149 outw(cmdw, FM801_REG(chip, IRQ_MASK));
1372 1150
1373 __end_hw: 1151 __end_hw:
1374#ifdef TEA575X_RADIO 1152#ifdef CONFIG_SND_FM801_TEA575X_BOOL
1375 snd_tea575x_exit(&chip->tea); 1153 snd_tea575x_exit(&chip->tea);
1376#endif 1154#endif
1377 if (chip->irq >= 0) 1155 if (chip->irq >= 0)
@@ -1450,16 +1228,25 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1450 1228
1451 snd_card_set_dev(card, &pci->dev); 1229 snd_card_set_dev(card, &pci->dev);
1452 1230
1453#ifdef TEA575X_RADIO 1231#ifdef CONFIG_SND_FM801_TEA575X_BOOL
1232 chip->tea.private_data = chip;
1233 chip->tea.ops = &snd_fm801_tea_ops;
1234 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
1454 if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && 1235 if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 &&
1455 (tea575x_tuner & TUNER_TYPE_MASK) < 4) { 1236 (tea575x_tuner & TUNER_TYPE_MASK) < 4) {
1456 chip->tea.dev_nr = tea575x_tuner >> 16; 1237 if (snd_tea575x_init(&chip->tea))
1457 chip->tea.card = card; 1238 snd_printk(KERN_ERR "TEA575x radio not found\n");
1458 chip->tea.freq_fixup = 10700; 1239 } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0)
1459 chip->tea.private_data = chip; 1240 /* autodetect tuner connection */
1460 chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & TUNER_TYPE_MASK) - 1]; 1241 for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) {
1461 snd_tea575x_init(&chip->tea); 1242 chip->tea575x_tuner = tea575x_tuner;
1462 } 1243 if (!snd_tea575x_init(&chip->tea)) {
1244 snd_printk(KERN_INFO "detected TEA575x radio type %s\n",
1245 snd_fm801_tea575x_gpios[tea575x_tuner - 1].name);
1246 break;
1247 }
1248 }
1249 strlcpy(chip->tea.card, snd_fm801_tea575x_gpios[(tea575x_tuner & TUNER_TYPE_MASK) - 1].name, sizeof(chip->tea.card));
1463#endif 1250#endif
1464 1251
1465 *rchip = chip; 1252 *rchip = chip;
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 27709f0cd2a6..f3353b49c785 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -235,8 +235,8 @@ static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0m_ids) = {
235 { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */ 235 { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */
236 { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */ 236 { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */
237 { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */ 237 { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */
238 { PCI_VDEVICE(AMD, 0x746e), DEVICE_INTEL }, /* AMD8111 */
238#if 0 239#if 0
239 { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */
240 { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */ 240 { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */
241#endif 241#endif
242 { 0, } 242 { 0, }
@@ -1261,9 +1261,9 @@ static struct shortname_table {
1261 { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" }, 1261 { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" },
1262 { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" }, 1262 { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" },
1263 { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" }, 1263 { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" },
1264 { 0x746e, "AMD AMD8111" },
1264#if 0 1265#if 0
1265 { 0x5455, "ALi M5455" }, 1266 { 0x5455, "ALi M5455" },
1266 { 0x746d, "AMD AMD8111" },
1267#endif 1267#endif
1268 { 0 }, 1268 { 0 },
1269}; 1269};
diff --git a/sound/pci/lola/Makefile b/sound/pci/lola/Makefile
new file mode 100644
index 000000000000..8178a2a59d00
--- /dev/null
+++ b/sound/pci/lola/Makefile
@@ -0,0 +1,4 @@
1snd-lola-y := lola.o lola_pcm.o lola_clock.o lola_mixer.o
2snd-lola-$(CONFIG_SND_DEBUG) += lola_proc.o
3
4obj-$(CONFIG_SND_LOLA) += snd-lola.o
diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c
new file mode 100644
index 000000000000..34b24286d279
--- /dev/null
+++ b/sound/pci/lola/lola.c
@@ -0,0 +1,791 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/moduleparam.h>
24#include <linux/dma-mapping.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/slab.h>
28#include <linux/pci.h>
29#include <sound/core.h>
30#include <sound/control.h>
31#include <sound/pcm.h>
32#include <sound/initval.h>
33#include "lola.h"
34
35/* Standard options */
36static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
37static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
38static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
39
40module_param_array(index, int, NULL, 0444);
41MODULE_PARM_DESC(index, "Index value for Digigram Lola driver.");
42module_param_array(id, charp, NULL, 0444);
43MODULE_PARM_DESC(id, "ID string for Digigram Lola driver.");
44module_param_array(enable, bool, NULL, 0444);
45MODULE_PARM_DESC(enable, "Enable Digigram Lola driver.");
46
47/* Lola-specific options */
48
49/* for instance use always max granularity which is compatible
50 * with all sample rates
51 */
52static int granularity[SNDRV_CARDS] = {
53 [0 ... (SNDRV_CARDS - 1)] = LOLA_GRANULARITY_MAX
54};
55
56/* below a sample_rate of 16kHz the analogue audio quality is NOT excellent */
57static int sample_rate_min[SNDRV_CARDS] = {
58 [0 ... (SNDRV_CARDS - 1) ] = 16000
59};
60
61module_param_array(granularity, int, NULL, 0444);
62MODULE_PARM_DESC(granularity, "Granularity value");
63module_param_array(sample_rate_min, int, NULL, 0444);
64MODULE_PARM_DESC(sample_rate_min, "Minimal sample rate");
65
66/*
67 */
68
69MODULE_LICENSE("GPL");
70MODULE_SUPPORTED_DEVICE("{{Digigram, Lola}}");
71MODULE_DESCRIPTION("Digigram Lola driver");
72MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
73
74#ifdef CONFIG_SND_DEBUG_VERBOSE
75static int debug;
76module_param(debug, int, 0644);
77#define verbose_debug(fmt, args...) \
78 do { if (debug > 1) printk(KERN_DEBUG SFX fmt, ##args); } while (0)
79#else
80#define verbose_debug(fmt, args...)
81#endif
82
83/*
84 * pseudo-codec read/write via CORB/RIRB
85 */
86
87static int corb_send_verb(struct lola *chip, unsigned int nid,
88 unsigned int verb, unsigned int data,
89 unsigned int extdata)
90{
91 unsigned long flags;
92 int ret = -EIO;
93
94 chip->last_cmd_nid = nid;
95 chip->last_verb = verb;
96 chip->last_data = data;
97 chip->last_extdata = extdata;
98 data |= (nid << 20) | (verb << 8);
99
100 spin_lock_irqsave(&chip->reg_lock, flags);
101 if (chip->rirb.cmds < LOLA_CORB_ENTRIES - 1) {
102 unsigned int wp = chip->corb.wp + 1;
103 wp %= LOLA_CORB_ENTRIES;
104 chip->corb.wp = wp;
105 chip->corb.buf[wp * 2] = cpu_to_le32(data);
106 chip->corb.buf[wp * 2 + 1] = cpu_to_le32(extdata);
107 lola_writew(chip, BAR0, CORBWP, wp);
108 chip->rirb.cmds++;
109 smp_wmb();
110 ret = 0;
111 }
112 spin_unlock_irqrestore(&chip->reg_lock, flags);
113 return ret;
114}
115
116static void lola_queue_unsol_event(struct lola *chip, unsigned int res,
117 unsigned int res_ex)
118{
119 lola_update_ext_clock_freq(chip, res);
120}
121
122/* retrieve RIRB entry - called from interrupt handler */
123static void lola_update_rirb(struct lola *chip)
124{
125 unsigned int rp, wp;
126 u32 res, res_ex;
127
128 wp = lola_readw(chip, BAR0, RIRBWP);
129 if (wp == chip->rirb.wp)
130 return;
131 chip->rirb.wp = wp;
132
133 while (chip->rirb.rp != wp) {
134 chip->rirb.rp++;
135 chip->rirb.rp %= LOLA_CORB_ENTRIES;
136
137 rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
138 res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
139 res = le32_to_cpu(chip->rirb.buf[rp]);
140 if (res_ex & LOLA_RIRB_EX_UNSOL_EV)
141 lola_queue_unsol_event(chip, res, res_ex);
142 else if (chip->rirb.cmds) {
143 chip->res = res;
144 chip->res_ex = res_ex;
145 smp_wmb();
146 chip->rirb.cmds--;
147 }
148 }
149}
150
151static int rirb_get_response(struct lola *chip, unsigned int *val,
152 unsigned int *extval)
153{
154 unsigned long timeout;
155
156 again:
157 timeout = jiffies + msecs_to_jiffies(1000);
158 for (;;) {
159 if (chip->polling_mode) {
160 spin_lock_irq(&chip->reg_lock);
161 lola_update_rirb(chip);
162 spin_unlock_irq(&chip->reg_lock);
163 }
164 if (!chip->rirb.cmds) {
165 *val = chip->res;
166 if (extval)
167 *extval = chip->res_ex;
168 verbose_debug("get_response: %x, %x\n",
169 chip->res, chip->res_ex);
170 if (chip->res_ex & LOLA_RIRB_EX_ERROR) {
171 printk(KERN_WARNING SFX "RIRB ERROR: "
172 "NID=%x, verb=%x, data=%x, ext=%x\n",
173 chip->last_cmd_nid,
174 chip->last_verb, chip->last_data,
175 chip->last_extdata);
176 return -EIO;
177 }
178 return 0;
179 }
180 if (time_after(jiffies, timeout))
181 break;
182 udelay(20);
183 cond_resched();
184 }
185 printk(KERN_WARNING SFX "RIRB response error\n");
186 if (!chip->polling_mode) {
187 printk(KERN_WARNING SFX "switching to polling mode\n");
188 chip->polling_mode = 1;
189 goto again;
190 }
191 return -EIO;
192}
193
194/* aynchronous write of a codec verb with data */
195int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
196 unsigned int data, unsigned int extdata)
197{
198 verbose_debug("codec_write NID=%x, verb=%x, data=%x, ext=%x\n",
199 nid, verb, data, extdata);
200 return corb_send_verb(chip, nid, verb, data, extdata);
201}
202
203/* write a codec verb with data and read the returned status */
204int lola_codec_read(struct lola *chip, unsigned int nid, unsigned int verb,
205 unsigned int data, unsigned int extdata,
206 unsigned int *val, unsigned int *extval)
207{
208 int err;
209
210 verbose_debug("codec_read NID=%x, verb=%x, data=%x, ext=%x\n",
211 nid, verb, data, extdata);
212 err = corb_send_verb(chip, nid, verb, data, extdata);
213 if (err < 0)
214 return err;
215 err = rirb_get_response(chip, val, extval);
216 return err;
217}
218
219/* flush all pending codec writes */
220int lola_codec_flush(struct lola *chip)
221{
222 unsigned int tmp;
223 return rirb_get_response(chip, &tmp, NULL);
224}
225
226/*
227 * interrupt handler
228 */
229static irqreturn_t lola_interrupt(int irq, void *dev_id)
230{
231 struct lola *chip = dev_id;
232 unsigned int notify_ins, notify_outs, error_ins, error_outs;
233 int handled = 0;
234 int i;
235
236 notify_ins = notify_outs = error_ins = error_outs = 0;
237 spin_lock(&chip->reg_lock);
238 for (;;) {
239 unsigned int status, in_sts, out_sts;
240 unsigned int reg;
241
242 status = lola_readl(chip, BAR1, DINTSTS);
243 if (!status || status == -1)
244 break;
245
246 in_sts = lola_readl(chip, BAR1, DIINTSTS);
247 out_sts = lola_readl(chip, BAR1, DOINTSTS);
248
249 /* clear Input Interrupts */
250 for (i = 0; in_sts && i < chip->pcm[CAPT].num_streams; i++) {
251 if (!(in_sts & (1 << i)))
252 continue;
253 in_sts &= ~(1 << i);
254 reg = lola_dsd_read(chip, i, STS);
255 if (reg & LOLA_DSD_STS_DESE) /* error */
256 error_ins |= (1 << i);
257 if (reg & LOLA_DSD_STS_BCIS) /* notify */
258 notify_ins |= (1 << i);
259 /* clear */
260 lola_dsd_write(chip, i, STS, reg);
261 }
262
263 /* clear Output Interrupts */
264 for (i = 0; out_sts && i < chip->pcm[PLAY].num_streams; i++) {
265 if (!(out_sts & (1 << i)))
266 continue;
267 out_sts &= ~(1 << i);
268 reg = lola_dsd_read(chip, i + MAX_STREAM_IN_COUNT, STS);
269 if (reg & LOLA_DSD_STS_DESE) /* error */
270 error_outs |= (1 << i);
271 if (reg & LOLA_DSD_STS_BCIS) /* notify */
272 notify_outs |= (1 << i);
273 lola_dsd_write(chip, i + MAX_STREAM_IN_COUNT, STS, reg);
274 }
275
276 if (status & LOLA_DINT_CTRL) {
277 unsigned char rbsts; /* ring status is byte access */
278 rbsts = lola_readb(chip, BAR0, RIRBSTS);
279 rbsts &= LOLA_RIRB_INT_MASK;
280 if (rbsts)
281 lola_writeb(chip, BAR0, RIRBSTS, rbsts);
282 rbsts = lola_readb(chip, BAR0, CORBSTS);
283 rbsts &= LOLA_CORB_INT_MASK;
284 if (rbsts)
285 lola_writeb(chip, BAR0, CORBSTS, rbsts);
286
287 lola_update_rirb(chip);
288 }
289
290 if (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR)) {
291 /* clear global fifo error interrupt */
292 lola_writel(chip, BAR1, DINTSTS,
293 (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR)));
294 }
295 handled = 1;
296 }
297 spin_unlock(&chip->reg_lock);
298
299 lola_pcm_update(chip, &chip->pcm[CAPT], notify_ins);
300 lola_pcm_update(chip, &chip->pcm[PLAY], notify_outs);
301
302 return IRQ_RETVAL(handled);
303}
304
305
306/*
307 * controller
308 */
309static int reset_controller(struct lola *chip)
310{
311 unsigned int gctl = lola_readl(chip, BAR0, GCTL);
312 unsigned long end_time;
313
314 if (gctl) {
315 /* to be sure */
316 lola_writel(chip, BAR1, BOARD_MODE, 0);
317 return 0;
318 }
319
320 chip->cold_reset = 1;
321 lola_writel(chip, BAR0, GCTL, LOLA_GCTL_RESET);
322 end_time = jiffies + msecs_to_jiffies(200);
323 do {
324 msleep(1);
325 gctl = lola_readl(chip, BAR0, GCTL);
326 if (gctl)
327 break;
328 } while (time_before(jiffies, end_time));
329 if (!gctl) {
330 printk(KERN_ERR SFX "cannot reset controller\n");
331 return -EIO;
332 }
333 return 0;
334}
335
336static void lola_irq_enable(struct lola *chip)
337{
338 unsigned int val;
339
340 /* enalbe all I/O streams */
341 val = (1 << chip->pcm[PLAY].num_streams) - 1;
342 lola_writel(chip, BAR1, DOINTCTL, val);
343 val = (1 << chip->pcm[CAPT].num_streams) - 1;
344 lola_writel(chip, BAR1, DIINTCTL, val);
345
346 /* enable global irqs */
347 val = LOLA_DINT_GLOBAL | LOLA_DINT_CTRL | LOLA_DINT_FIFOERR |
348 LOLA_DINT_MUERR;
349 lola_writel(chip, BAR1, DINTCTL, val);
350}
351
352static void lola_irq_disable(struct lola *chip)
353{
354 lola_writel(chip, BAR1, DINTCTL, 0);
355 lola_writel(chip, BAR1, DIINTCTL, 0);
356 lola_writel(chip, BAR1, DOINTCTL, 0);
357}
358
359static int setup_corb_rirb(struct lola *chip)
360{
361 int err;
362 unsigned char tmp;
363 unsigned long end_time;
364
365 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
366 snd_dma_pci_data(chip->pci),
367 PAGE_SIZE, &chip->rb);
368 if (err < 0)
369 return err;
370
371 chip->corb.addr = chip->rb.addr;
372 chip->corb.buf = (u32 *)chip->rb.area;
373 chip->rirb.addr = chip->rb.addr + 2048;
374 chip->rirb.buf = (u32 *)(chip->rb.area + 2048);
375
376 /* disable ringbuffer DMAs */
377 lola_writeb(chip, BAR0, RIRBCTL, 0);
378 lola_writeb(chip, BAR0, CORBCTL, 0);
379
380 end_time = jiffies + msecs_to_jiffies(200);
381 do {
382 if (!lola_readb(chip, BAR0, RIRBCTL) &&
383 !lola_readb(chip, BAR0, CORBCTL))
384 break;
385 msleep(1);
386 } while (time_before(jiffies, end_time));
387
388 /* CORB set up */
389 lola_writel(chip, BAR0, CORBLBASE, (u32)chip->corb.addr);
390 lola_writel(chip, BAR0, CORBUBASE, upper_32_bits(chip->corb.addr));
391 /* set the corb size to 256 entries */
392 lola_writeb(chip, BAR0, CORBSIZE, 0x02);
393 /* set the corb write pointer to 0 */
394 lola_writew(chip, BAR0, CORBWP, 0);
395 /* reset the corb hw read pointer */
396 lola_writew(chip, BAR0, CORBRP, LOLA_RBRWP_CLR);
397 /* enable corb dma */
398 lola_writeb(chip, BAR0, CORBCTL, LOLA_RBCTL_DMA_EN);
399 /* clear flags if set */
400 tmp = lola_readb(chip, BAR0, CORBSTS) & LOLA_CORB_INT_MASK;
401 if (tmp)
402 lola_writeb(chip, BAR0, CORBSTS, tmp);
403 chip->corb.wp = 0;
404
405 /* RIRB set up */
406 lola_writel(chip, BAR0, RIRBLBASE, (u32)chip->rirb.addr);
407 lola_writel(chip, BAR0, RIRBUBASE, upper_32_bits(chip->rirb.addr));
408 /* set the rirb size to 256 entries */
409 lola_writeb(chip, BAR0, RIRBSIZE, 0x02);
410 /* reset the rirb hw write pointer */
411 lola_writew(chip, BAR0, RIRBWP, LOLA_RBRWP_CLR);
412 /* set N=1, get RIRB response interrupt for new entry */
413 lola_writew(chip, BAR0, RINTCNT, 1);
414 /* enable rirb dma and response irq */
415 lola_writeb(chip, BAR0, RIRBCTL, LOLA_RBCTL_DMA_EN | LOLA_RBCTL_IRQ_EN);
416 /* clear flags if set */
417 tmp = lola_readb(chip, BAR0, RIRBSTS) & LOLA_RIRB_INT_MASK;
418 if (tmp)
419 lola_writeb(chip, BAR0, RIRBSTS, tmp);
420 chip->rirb.rp = chip->rirb.cmds = 0;
421
422 return 0;
423}
424
425static void stop_corb_rirb(struct lola *chip)
426{
427 /* disable ringbuffer DMAs */
428 lola_writeb(chip, BAR0, RIRBCTL, 0);
429 lola_writeb(chip, BAR0, CORBCTL, 0);
430}
431
432static void lola_reset_setups(struct lola *chip)
433{
434 /* update the granularity */
435 lola_set_granularity(chip, chip->granularity, true);
436 /* update the sample clock */
437 lola_set_clock_index(chip, chip->clock.cur_index);
438 /* enable unsolicited events of the clock widget */
439 lola_enable_clock_events(chip);
440 /* update the analog gains */
441 lola_setup_all_analog_gains(chip, CAPT, false); /* input, update */
442 /* update SRC configuration if applicable */
443 lola_set_src_config(chip, chip->input_src_mask, false);
444 /* update the analog outputs */
445 lola_setup_all_analog_gains(chip, PLAY, false); /* output, update */
446}
447
448static int lola_parse_tree(struct lola *chip)
449{
450 unsigned int val;
451 int nid, err;
452
453 err = lola_read_param(chip, 0, LOLA_PAR_VENDOR_ID, &val);
454 if (err < 0) {
455 printk(KERN_ERR SFX "Can't read VENDOR_ID\n");
456 return err;
457 }
458 val >>= 16;
459 if (val != 0x1369) {
460 printk(KERN_ERR SFX "Unknown codec vendor 0x%x\n", val);
461 return -EINVAL;
462 }
463
464 err = lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val);
465 if (err < 0) {
466 printk(KERN_ERR SFX "Can't read FUNCTION_TYPE for 0x%x\n", nid);
467 return err;
468 }
469 if (val != 1) {
470 printk(KERN_ERR SFX "Unknown function type %d\n", val);
471 return -EINVAL;
472 }
473
474 err = lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val);
475 if (err < 0) {
476 printk(KERN_ERR SFX "Can't read SPECCAPS\n");
477 return err;
478 }
479 chip->lola_caps = val;
480 chip->pin[CAPT].num_pins = LOLA_AFG_INPUT_PIN_COUNT(chip->lola_caps);
481 chip->pin[PLAY].num_pins = LOLA_AFG_OUTPUT_PIN_COUNT(chip->lola_caps);
482 snd_printdd(SFX "speccaps=0x%x, pins in=%d, out=%d\n",
483 chip->lola_caps,
484 chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins);
485
486 if (chip->pin[CAPT].num_pins > MAX_AUDIO_INOUT_COUNT ||
487 chip->pin[PLAY].num_pins > MAX_AUDIO_INOUT_COUNT) {
488 printk(KERN_ERR SFX "Invalid Lola-spec caps 0x%x\n", val);
489 return -EINVAL;
490 }
491
492 nid = 0x02;
493 err = lola_init_pcm(chip, CAPT, &nid);
494 if (err < 0)
495 return err;
496 err = lola_init_pcm(chip, PLAY, &nid);
497 if (err < 0)
498 return err;
499
500 err = lola_init_pins(chip, CAPT, &nid);
501 if (err < 0)
502 return err;
503 err = lola_init_pins(chip, PLAY, &nid);
504 if (err < 0)
505 return err;
506
507 if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) {
508 err = lola_init_clock_widget(chip, nid);
509 if (err < 0)
510 return err;
511 nid++;
512 }
513 if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) {
514 err = lola_init_mixer_widget(chip, nid);
515 if (err < 0)
516 return err;
517 nid++;
518 }
519
520 /* enable unsolicited events of the clock widget */
521 err = lola_enable_clock_events(chip);
522 if (err < 0)
523 return err;
524
525 /* if last ResetController was not a ColdReset, we don't know
526 * the state of the card; initialize here again
527 */
528 if (!chip->cold_reset) {
529 lola_reset_setups(chip);
530 chip->cold_reset = 1;
531 } else {
532 /* set the granularity if it is not the default */
533 if (chip->granularity != LOLA_GRANULARITY_MIN)
534 lola_set_granularity(chip, chip->granularity, true);
535 }
536
537 return 0;
538}
539
540static void lola_stop_hw(struct lola *chip)
541{
542 stop_corb_rirb(chip);
543 lola_irq_disable(chip);
544}
545
546static void lola_free(struct lola *chip)
547{
548 if (chip->initialized)
549 lola_stop_hw(chip);
550 lola_free_pcm(chip);
551 lola_free_mixer(chip);
552 if (chip->irq >= 0)
553 free_irq(chip->irq, (void *)chip);
554 if (chip->bar[0].remap_addr)
555 iounmap(chip->bar[0].remap_addr);
556 if (chip->bar[1].remap_addr)
557 iounmap(chip->bar[1].remap_addr);
558 if (chip->rb.area)
559 snd_dma_free_pages(&chip->rb);
560 pci_release_regions(chip->pci);
561 pci_disable_device(chip->pci);
562 kfree(chip);
563}
564
565static int lola_dev_free(struct snd_device *device)
566{
567 lola_free(device->device_data);
568 return 0;
569}
570
571static int __devinit lola_create(struct snd_card *card, struct pci_dev *pci,
572 int dev, struct lola **rchip)
573{
574 struct lola *chip;
575 int err;
576 unsigned int dever;
577 static struct snd_device_ops ops = {
578 .dev_free = lola_dev_free,
579 };
580
581 *rchip = NULL;
582
583 err = pci_enable_device(pci);
584 if (err < 0)
585 return err;
586
587 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
588 if (!chip) {
589 snd_printk(KERN_ERR SFX "cannot allocate chip\n");
590 pci_disable_device(pci);
591 return -ENOMEM;
592 }
593
594 spin_lock_init(&chip->reg_lock);
595 mutex_init(&chip->open_mutex);
596 chip->card = card;
597 chip->pci = pci;
598 chip->irq = -1;
599
600 chip->granularity = granularity[dev];
601 switch (chip->granularity) {
602 case 8:
603 chip->sample_rate_max = 48000;
604 break;
605 case 16:
606 chip->sample_rate_max = 96000;
607 break;
608 case 32:
609 chip->sample_rate_max = 192000;
610 break;
611 default:
612 snd_printk(KERN_WARNING SFX
613 "Invalid granularity %d, reset to %d\n",
614 chip->granularity, LOLA_GRANULARITY_MAX);
615 chip->granularity = LOLA_GRANULARITY_MAX;
616 chip->sample_rate_max = 192000;
617 break;
618 }
619 chip->sample_rate_min = sample_rate_min[dev];
620 if (chip->sample_rate_min > chip->sample_rate_max) {
621 snd_printk(KERN_WARNING SFX
622 "Invalid sample_rate_min %d, reset to 16000\n",
623 chip->sample_rate_min);
624 chip->sample_rate_min = 16000;
625 }
626
627 err = pci_request_regions(pci, DRVNAME);
628 if (err < 0) {
629 kfree(chip);
630 pci_disable_device(pci);
631 return err;
632 }
633
634 chip->bar[0].addr = pci_resource_start(pci, 0);
635 chip->bar[0].remap_addr = pci_ioremap_bar(pci, 0);
636 chip->bar[1].addr = pci_resource_start(pci, 2);
637 chip->bar[1].remap_addr = pci_ioremap_bar(pci, 2);
638 if (!chip->bar[0].remap_addr || !chip->bar[1].remap_addr) {
639 snd_printk(KERN_ERR SFX "ioremap error\n");
640 err = -ENXIO;
641 goto errout;
642 }
643
644 pci_set_master(pci);
645
646 err = reset_controller(chip);
647 if (err < 0)
648 goto errout;
649
650 if (request_irq(pci->irq, lola_interrupt, IRQF_SHARED,
651 DRVNAME, chip)) {
652 printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq);
653 err = -EBUSY;
654 goto errout;
655 }
656 chip->irq = pci->irq;
657 synchronize_irq(chip->irq);
658
659 dever = lola_readl(chip, BAR1, DEVER);
660 chip->pcm[CAPT].num_streams = (dever >> 0) & 0x3ff;
661 chip->pcm[PLAY].num_streams = (dever >> 10) & 0x3ff;
662 chip->version = (dever >> 24) & 0xff;
663 snd_printdd(SFX "streams in=%d, out=%d, version=0x%x\n",
664 chip->pcm[CAPT].num_streams, chip->pcm[PLAY].num_streams,
665 chip->version);
666
667 /* Test LOLA_BAR1_DEVER */
668 if (chip->pcm[CAPT].num_streams > MAX_STREAM_IN_COUNT ||
669 chip->pcm[PLAY].num_streams > MAX_STREAM_OUT_COUNT ||
670 (!chip->pcm[CAPT].num_streams &&
671 !chip->pcm[PLAY].num_streams)) {
672 printk(KERN_ERR SFX "invalid DEVER = %x\n", dever);
673 err = -EINVAL;
674 goto errout;
675 }
676
677 err = setup_corb_rirb(chip);
678 if (err < 0)
679 goto errout;
680
681 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
682 if (err < 0) {
683 snd_printk(KERN_ERR SFX "Error creating device [card]!\n");
684 goto errout;
685 }
686
687 strcpy(card->driver, "Lola");
688 strlcpy(card->shortname, "Digigram Lola", sizeof(card->shortname));
689 snprintf(card->longname, sizeof(card->longname),
690 "%s at 0x%lx irq %i",
691 card->shortname, chip->bar[0].addr, chip->irq);
692 strcpy(card->mixername, card->shortname);
693
694 lola_irq_enable(chip);
695
696 chip->initialized = 1;
697 *rchip = chip;
698 return 0;
699
700 errout:
701 lola_free(chip);
702 return err;
703}
704
705static int __devinit lola_probe(struct pci_dev *pci,
706 const struct pci_device_id *pci_id)
707{
708 static int dev;
709 struct snd_card *card;
710 struct lola *chip;
711 int err;
712
713 if (dev >= SNDRV_CARDS)
714 return -ENODEV;
715 if (!enable[dev]) {
716 dev++;
717 return -ENOENT;
718 }
719
720 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
721 if (err < 0) {
722 snd_printk(KERN_ERR SFX "Error creating card!\n");
723 return err;
724 }
725
726 snd_card_set_dev(card, &pci->dev);
727
728 err = lola_create(card, pci, dev, &chip);
729 if (err < 0)
730 goto out_free;
731 card->private_data = chip;
732
733 err = lola_parse_tree(chip);
734 if (err < 0)
735 goto out_free;
736
737 err = lola_create_pcm(chip);
738 if (err < 0)
739 goto out_free;
740
741 err = lola_create_mixer(chip);
742 if (err < 0)
743 goto out_free;
744
745 lola_proc_debug_new(chip);
746
747 err = snd_card_register(card);
748 if (err < 0)
749 goto out_free;
750
751 pci_set_drvdata(pci, card);
752 dev++;
753 return err;
754out_free:
755 snd_card_free(card);
756 return err;
757}
758
759static void __devexit lola_remove(struct pci_dev *pci)
760{
761 snd_card_free(pci_get_drvdata(pci));
762 pci_set_drvdata(pci, NULL);
763}
764
765/* PCI IDs */
766static DEFINE_PCI_DEVICE_TABLE(lola_ids) = {
767 { PCI_VDEVICE(DIGIGRAM, 0x0001) },
768 { 0, }
769};
770MODULE_DEVICE_TABLE(pci, lola_ids);
771
772/* pci_driver definition */
773static struct pci_driver driver = {
774 .name = DRVNAME,
775 .id_table = lola_ids,
776 .probe = lola_probe,
777 .remove = __devexit_p(lola_remove),
778};
779
780static int __init alsa_card_lola_init(void)
781{
782 return pci_register_driver(&driver);
783}
784
785static void __exit alsa_card_lola_exit(void)
786{
787 pci_unregister_driver(&driver);
788}
789
790module_init(alsa_card_lola_init)
791module_exit(alsa_card_lola_exit)
diff --git a/sound/pci/lola/lola.h b/sound/pci/lola/lola.h
new file mode 100644
index 000000000000..d5708e29b16d
--- /dev/null
+++ b/sound/pci/lola/lola.h
@@ -0,0 +1,527 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#ifndef _LOLA_H
22#define _LOLA_H
23
24#define DRVNAME "snd-lola"
25#define SFX DRVNAME ": "
26
27/*
28 * Lola HD Audio Registers BAR0
29 */
30#define LOLA_BAR0_GCAP 0x00
31#define LOLA_BAR0_VMIN 0x02
32#define LOLA_BAR0_VMAJ 0x03
33#define LOLA_BAR0_OUTPAY 0x04
34#define LOLA_BAR0_INPAY 0x06
35#define LOLA_BAR0_GCTL 0x08
36#define LOLA_BAR0_WAKEEN 0x0c
37#define LOLA_BAR0_STATESTS 0x0e
38#define LOLA_BAR0_GSTS 0x10
39#define LOLA_BAR0_OUTSTRMPAY 0x18
40#define LOLA_BAR0_INSTRMPAY 0x1a
41#define LOLA_BAR0_INTCTL 0x20
42#define LOLA_BAR0_INTSTS 0x24
43#define LOLA_BAR0_WALCLK 0x30
44#define LOLA_BAR0_SSYNC 0x38
45
46#define LOLA_BAR0_CORBLBASE 0x40
47#define LOLA_BAR0_CORBUBASE 0x44
48#define LOLA_BAR0_CORBWP 0x48 /* no ULONG access */
49#define LOLA_BAR0_CORBRP 0x4a /* no ULONG access */
50#define LOLA_BAR0_CORBCTL 0x4c /* no ULONG access */
51#define LOLA_BAR0_CORBSTS 0x4d /* UCHAR access only */
52#define LOLA_BAR0_CORBSIZE 0x4e /* no ULONG access */
53
54#define LOLA_BAR0_RIRBLBASE 0x50
55#define LOLA_BAR0_RIRBUBASE 0x54
56#define LOLA_BAR0_RIRBWP 0x58
57#define LOLA_BAR0_RINTCNT 0x5a /* no ULONG access */
58#define LOLA_BAR0_RIRBCTL 0x5c
59#define LOLA_BAR0_RIRBSTS 0x5d /* UCHAR access only */
60#define LOLA_BAR0_RIRBSIZE 0x5e /* no ULONG access */
61
62#define LOLA_BAR0_ICW 0x60
63#define LOLA_BAR0_IRR 0x64
64#define LOLA_BAR0_ICS 0x68
65#define LOLA_BAR0_DPLBASE 0x70
66#define LOLA_BAR0_DPUBASE 0x74
67
68/* stream register offsets from stream base 0x80 */
69#define LOLA_BAR0_SD0_OFFSET 0x80
70#define LOLA_REG0_SD_CTL 0x00
71#define LOLA_REG0_SD_STS 0x03
72#define LOLA_REG0_SD_LPIB 0x04
73#define LOLA_REG0_SD_CBL 0x08
74#define LOLA_REG0_SD_LVI 0x0c
75#define LOLA_REG0_SD_FIFOW 0x0e
76#define LOLA_REG0_SD_FIFOSIZE 0x10
77#define LOLA_REG0_SD_FORMAT 0x12
78#define LOLA_REG0_SD_BDLPL 0x18
79#define LOLA_REG0_SD_BDLPU 0x1c
80
81/*
82 * Lola Digigram Registers BAR1
83 */
84#define LOLA_BAR1_FPGAVER 0x00
85#define LOLA_BAR1_DEVER 0x04
86#define LOLA_BAR1_UCBMV 0x08
87#define LOLA_BAR1_JTAG 0x0c
88#define LOLA_BAR1_UARTRX 0x10
89#define LOLA_BAR1_UARTTX 0x14
90#define LOLA_BAR1_UARTCR 0x18
91#define LOLA_BAR1_NVRAMVER 0x1c
92#define LOLA_BAR1_CTRLSPI 0x20
93#define LOLA_BAR1_DSPI 0x24
94#define LOLA_BAR1_AISPI 0x28
95#define LOLA_BAR1_GRAN 0x2c
96
97#define LOLA_BAR1_DINTCTL 0x80
98#define LOLA_BAR1_DIINTCTL 0x84
99#define LOLA_BAR1_DOINTCTL 0x88
100#define LOLA_BAR1_LRC 0x90
101#define LOLA_BAR1_DINTSTS 0x94
102#define LOLA_BAR1_DIINTSTS 0x98
103#define LOLA_BAR1_DOINTSTS 0x9c
104
105#define LOLA_BAR1_DSD0_OFFSET 0xa0
106#define LOLA_BAR1_DSD_SIZE 0x18
107
108#define LOLA_BAR1_DSDnSTS 0x00
109#define LOLA_BAR1_DSDnLPIB 0x04
110#define LOLA_BAR1_DSDnCTL 0x08
111#define LOLA_BAR1_DSDnLVI 0x0c
112#define LOLA_BAR1_DSDnBDPL 0x10
113#define LOLA_BAR1_DSDnBDPU 0x14
114
115#define LOLA_BAR1_SSYNC 0x03e8
116
117#define LOLA_BAR1_BOARD_CTRL 0x0f00
118#define LOLA_BAR1_BOARD_MODE 0x0f02
119
120#define LOLA_BAR1_SOURCE_GAIN_ENABLE 0x1000
121#define LOLA_BAR1_DEST00_MIX_GAIN_ENABLE 0x1004
122#define LOLA_BAR1_DEST31_MIX_GAIN_ENABLE 0x1080
123#define LOLA_BAR1_SOURCE00_01_GAIN 0x1084
124#define LOLA_BAR1_SOURCE30_31_GAIN 0x10c0
125#define LOLA_BAR1_SOURCE_GAIN(src) \
126 (LOLA_BAR1_SOURCE00_01_GAIN + (src) * 2)
127#define LOLA_BAR1_DEST00_MIX00_01_GAIN 0x10c4
128#define LOLA_BAR1_DEST00_MIX30_31_GAIN 0x1100
129#define LOLA_BAR1_DEST01_MIX00_01_GAIN 0x1104
130#define LOLA_BAR1_DEST01_MIX30_31_GAIN 0x1140
131#define LOLA_BAR1_DEST31_MIX00_01_GAIN 0x1884
132#define LOLA_BAR1_DEST31_MIX30_31_GAIN 0x18c0
133#define LOLA_BAR1_MIX_GAIN(dest, mix) \
134 (LOLA_BAR1_DEST00_MIX00_01_GAIN + (dest) * 0x40 + (mix) * 2)
135#define LOLA_BAR1_ANALOG_CLIP_IN 0x18c4
136#define LOLA_BAR1_PEAKMETERS_SOURCE00_01 0x18c8
137#define LOLA_BAR1_PEAKMETERS_SOURCE30_31 0x1904
138#define LOLA_BAR1_PEAKMETERS_SOURCE(src) \
139 (LOLA_BAR1_PEAKMETERS_SOURCE00_01 + (src) * 2)
140#define LOLA_BAR1_PEAKMETERS_DEST00_01 0x1908
141#define LOLA_BAR1_PEAKMETERS_DEST30_31 0x1944
142#define LOLA_BAR1_PEAKMETERS_DEST(dest) \
143 (LOLA_BAR1_PEAKMETERS_DEST00_01 + (dest) * 2)
144#define LOLA_BAR1_PEAKMETERS_AGC00_01 0x1948
145#define LOLA_BAR1_PEAKMETERS_AGC14_15 0x1964
146#define LOLA_BAR1_PEAKMETERS_AGC(x) \
147 (LOLA_BAR1_PEAKMETERS_AGC00_01 + (x) * 2)
148
149/* GCTL reset bit */
150#define LOLA_GCTL_RESET (1 << 0)
151/* GCTL unsolicited response enable bit */
152#define LOLA_GCTL_UREN (1 << 8)
153
154/* CORB/RIRB control, read/write pointer */
155#define LOLA_RBCTL_DMA_EN 0x02 /* enable DMA */
156#define LOLA_RBCTL_IRQ_EN 0x01 /* enable IRQ */
157#define LOLA_RBRWP_CLR 0x8000 /* read/write pointer clear */
158
159#define LOLA_RIRB_EX_UNSOL_EV 0x40000000
160#define LOLA_RIRB_EX_ERROR 0x80000000
161
162/* CORB int mask: CMEI[0] */
163#define LOLA_CORB_INT_CMEI 0x01
164#define LOLA_CORB_INT_MASK LOLA_CORB_INT_CMEI
165
166/* RIRB int mask: overrun[2], response[0] */
167#define LOLA_RIRB_INT_RESPONSE 0x01
168#define LOLA_RIRB_INT_OVERRUN 0x04
169#define LOLA_RIRB_INT_MASK (LOLA_RIRB_INT_RESPONSE | LOLA_RIRB_INT_OVERRUN)
170
171/* DINTCTL and DINTSTS */
172#define LOLA_DINT_GLOBAL 0x80000000 /* global interrupt enable bit */
173#define LOLA_DINT_CTRL 0x40000000 /* controller interrupt enable bit */
174#define LOLA_DINT_FIFOERR 0x20000000 /* global fifo error enable bit */
175#define LOLA_DINT_MUERR 0x10000000 /* global microcontroller underrun error */
176
177/* DSDnCTL bits */
178#define LOLA_DSD_CTL_SRST 0x01 /* stream reset bit */
179#define LOLA_DSD_CTL_SRUN 0x02 /* stream DMA start bit */
180#define LOLA_DSD_CTL_IOCE 0x04 /* interrupt on completion enable */
181#define LOLA_DSD_CTL_DEIE 0x10 /* descriptor error interrupt enable */
182#define LOLA_DSD_CTL_VLRCV 0x20 /* valid LRCountValue information in bits 8..31 */
183#define LOLA_LRC_MASK 0xffffff00
184
185/* DSDnSTS */
186#define LOLA_DSD_STS_BCIS 0x04 /* buffer completion interrupt status */
187#define LOLA_DSD_STS_DESE 0x10 /* descriptor error interrupt */
188#define LOLA_DSD_STS_FIFORDY 0x20 /* fifo ready */
189
190#define LOLA_CORB_ENTRIES 256
191
192#define MAX_STREAM_IN_COUNT 16
193#define MAX_STREAM_OUT_COUNT 16
194#define MAX_STREAM_COUNT 16
195#define MAX_PINS MAX_STREAM_COUNT
196#define MAX_STREAM_BUFFER_COUNT 16
197#define MAX_AUDIO_INOUT_COUNT 16
198
199#define LOLA_CLOCK_TYPE_INTERNAL 0
200#define LOLA_CLOCK_TYPE_AES 1
201#define LOLA_CLOCK_TYPE_AES_SYNC 2
202#define LOLA_CLOCK_TYPE_WORDCLOCK 3
203#define LOLA_CLOCK_TYPE_ETHERSOUND 4
204#define LOLA_CLOCK_TYPE_VIDEO 5
205
206#define LOLA_CLOCK_FORMAT_NONE 0
207#define LOLA_CLOCK_FORMAT_NTSC 1
208#define LOLA_CLOCK_FORMAT_PAL 2
209
210#define MAX_SAMPLE_CLOCK_COUNT 48
211
212/* parameters used with mixer widget's mixer capabilities */
213#define LOLA_PEAK_METER_CAN_AGC_MASK 1
214#define LOLA_PEAK_METER_CAN_ANALOG_CLIP_MASK 2
215
216struct lola_bar {
217 unsigned long addr;
218 void __iomem *remap_addr;
219};
220
221/* CORB/RIRB */
222struct lola_rb {
223 u32 *buf; /* CORB/RIRB buffer, 8 byte per each entry */
224 dma_addr_t addr; /* physical address of CORB/RIRB buffer */
225 unsigned short rp, wp; /* read/write pointers */
226 int cmds; /* number of pending requests */
227};
228
229/* Pin widget setup */
230struct lola_pin {
231 unsigned int nid;
232 bool is_analog;
233 unsigned int amp_mute;
234 unsigned int amp_step_size;
235 unsigned int amp_num_steps;
236 unsigned int amp_offset;
237 unsigned int max_level;
238 unsigned int config_default_reg;
239 unsigned int fixed_gain_list_len;
240 unsigned int cur_gain_step;
241};
242
243struct lola_pin_array {
244 unsigned int num_pins;
245 unsigned int num_analog_pins;
246 struct lola_pin pins[MAX_PINS];
247};
248
249/* Clock widget setup */
250struct lola_sample_clock {
251 unsigned int type;
252 unsigned int format;
253 unsigned int freq;
254};
255
256struct lola_clock_widget {
257 unsigned int nid;
258 unsigned int items;
259 unsigned int cur_index;
260 unsigned int cur_freq;
261 bool cur_valid;
262 struct lola_sample_clock sample_clock[MAX_SAMPLE_CLOCK_COUNT];
263 unsigned int idx_lookup[MAX_SAMPLE_CLOCK_COUNT];
264};
265
266#define LOLA_MIXER_DIM 32
267struct lola_mixer_array {
268 u32 src_gain_enable;
269 u32 dest_mix_gain_enable[LOLA_MIXER_DIM];
270 u16 src_gain[LOLA_MIXER_DIM];
271 u16 dest_mix_gain[LOLA_MIXER_DIM][LOLA_MIXER_DIM];
272};
273
274/* Mixer widget setup */
275struct lola_mixer_widget {
276 unsigned int nid;
277 unsigned int caps;
278 struct lola_mixer_array __user *array;
279 struct lola_mixer_array *array_saved;
280 unsigned int src_stream_outs;
281 unsigned int src_phys_ins;
282 unsigned int dest_stream_ins;
283 unsigned int dest_phys_outs;
284 unsigned int src_stream_out_ofs;
285 unsigned int dest_phys_out_ofs;
286 unsigned int src_mask;
287 unsigned int dest_mask;
288};
289
290/* Audio stream */
291struct lola_stream {
292 unsigned int nid; /* audio widget NID */
293 unsigned int index; /* array index */
294 unsigned int dsd; /* DSD index */
295 bool can_float;
296 struct snd_pcm_substream *substream; /* assigned PCM substream */
297 struct lola_stream *master; /* master stream (for multi-channel) */
298
299 /* buffer setup */
300 unsigned int bufsize;
301 unsigned int period_bytes;
302 unsigned int frags;
303
304 /* format + channel setup */
305 unsigned int format_verb;
306
307 /* flags */
308 unsigned int opened:1;
309 unsigned int prepared:1;
310 unsigned int paused:1;
311 unsigned int running:1;
312};
313
314#define PLAY SNDRV_PCM_STREAM_PLAYBACK
315#define CAPT SNDRV_PCM_STREAM_CAPTURE
316
317struct lola_pcm {
318 unsigned int num_streams;
319 struct snd_dma_buffer bdl; /* BDL buffer */
320 struct lola_stream streams[MAX_STREAM_COUNT];
321};
322
323/* card instance */
324struct lola {
325 struct snd_card *card;
326 struct pci_dev *pci;
327
328 /* pci resources */
329 struct lola_bar bar[2];
330 int irq;
331
332 /* locks */
333 spinlock_t reg_lock;
334 struct mutex open_mutex;
335
336 /* CORB/RIRB */
337 struct lola_rb corb;
338 struct lola_rb rirb;
339 unsigned int res, res_ex; /* last read values */
340 /* last command (for debugging) */
341 unsigned int last_cmd_nid, last_verb, last_data, last_extdata;
342
343 /* CORB/RIRB buffers */
344 struct snd_dma_buffer rb;
345
346 /* unsolicited events */
347 unsigned int last_unsol_res;
348
349 /* streams */
350 struct lola_pcm pcm[2];
351
352 /* input src */
353 unsigned int input_src_caps_mask;
354 unsigned int input_src_mask;
355
356 /* pins */
357 struct lola_pin_array pin[2];
358
359 /* clock */
360 struct lola_clock_widget clock;
361 int ref_count_rate;
362 unsigned int sample_rate;
363
364 /* mixer */
365 struct lola_mixer_widget mixer;
366
367 /* hw info */
368 unsigned int version;
369 unsigned int lola_caps;
370
371 /* parameters */
372 unsigned int granularity;
373 unsigned int sample_rate_min;
374 unsigned int sample_rate_max;
375
376 /* flags */
377 unsigned int initialized:1;
378 unsigned int cold_reset:1;
379 unsigned int polling_mode:1;
380
381 /* for debugging */
382 unsigned int debug_res;
383 unsigned int debug_res_ex;
384};
385
386#define BAR0 0
387#define BAR1 1
388
389/* Helper macros */
390#define lola_readl(chip, idx, name) \
391 readl((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
392#define lola_readw(chip, idx, name) \
393 readw((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
394#define lola_readb(chip, idx, name) \
395 readb((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
396#define lola_writel(chip, idx, name, val) \
397 writel((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
398#define lola_writew(chip, idx, name, val) \
399 writew((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
400#define lola_writeb(chip, idx, name, val) \
401 writeb((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
402
403#define lola_dsd_read(chip, dsd, name) \
404 readl((chip)->bar[BAR1].remap_addr + LOLA_BAR1_DSD0_OFFSET + \
405 (LOLA_BAR1_DSD_SIZE * (dsd)) + LOLA_BAR1_DSDn##name)
406#define lola_dsd_write(chip, dsd, name, val) \
407 writel((val), (chip)->bar[BAR1].remap_addr + LOLA_BAR1_DSD0_OFFSET + \
408 (LOLA_BAR1_DSD_SIZE * (dsd)) + LOLA_BAR1_DSDn##name)
409
410/* GET verbs HDAudio */
411#define LOLA_VERB_GET_STREAM_FORMAT 0xa00
412#define LOLA_VERB_GET_AMP_GAIN_MUTE 0xb00
413#define LOLA_VERB_PARAMETERS 0xf00
414#define LOLA_VERB_GET_POWER_STATE 0xf05
415#define LOLA_VERB_GET_CONV 0xf06
416#define LOLA_VERB_GET_UNSOLICITED_RESPONSE 0xf08
417#define LOLA_VERB_GET_DIGI_CONVERT_1 0xf0d
418#define LOLA_VERB_GET_CONFIG_DEFAULT 0xf1c
419#define LOLA_VERB_GET_SUBSYSTEM_ID 0xf20
420/* GET verbs Digigram */
421#define LOLA_VERB_GET_FIXED_GAIN 0xfc0
422#define LOLA_VERB_GET_GAIN_SELECT 0xfc1
423#define LOLA_VERB_GET_MAX_LEVEL 0xfc2
424#define LOLA_VERB_GET_CLOCK_LIST 0xfc3
425#define LOLA_VERB_GET_CLOCK_SELECT 0xfc4
426#define LOLA_VERB_GET_CLOCK_STATUS 0xfc5
427
428/* SET verbs HDAudio */
429#define LOLA_VERB_SET_STREAM_FORMAT 0x200
430#define LOLA_VERB_SET_AMP_GAIN_MUTE 0x300
431#define LOLA_VERB_SET_POWER_STATE 0x705
432#define LOLA_VERB_SET_CHANNEL_STREAMID 0x706
433#define LOLA_VERB_SET_UNSOLICITED_ENABLE 0x708
434#define LOLA_VERB_SET_DIGI_CONVERT_1 0x70d
435/* SET verbs Digigram */
436#define LOLA_VERB_SET_GAIN_SELECT 0xf81
437#define LOLA_VERB_SET_CLOCK_SELECT 0xf84
438#define LOLA_VERB_SET_GRANULARITY_STEPS 0xf86
439#define LOLA_VERB_SET_SOURCE_GAIN 0xf87
440#define LOLA_VERB_SET_MIX_GAIN 0xf88
441#define LOLA_VERB_SET_DESTINATION_GAIN 0xf89
442#define LOLA_VERB_SET_SRC 0xf8a
443
444/* Parameter IDs used with LOLA_VERB_PARAMETERS */
445#define LOLA_PAR_VENDOR_ID 0x00
446#define LOLA_PAR_FUNCTION_TYPE 0x05
447#define LOLA_PAR_AUDIO_WIDGET_CAP 0x09
448#define LOLA_PAR_PCM 0x0a
449#define LOLA_PAR_STREAM_FORMATS 0x0b
450#define LOLA_PAR_PIN_CAP 0x0c
451#define LOLA_PAR_AMP_IN_CAP 0x0d
452#define LOLA_PAR_CONNLIST_LEN 0x0e
453#define LOLA_PAR_POWER_STATE 0x0f
454#define LOLA_PAR_GPIO_CAP 0x11
455#define LOLA_PAR_AMP_OUT_CAP 0x12
456#define LOLA_PAR_SPECIFIC_CAPS 0x80
457#define LOLA_PAR_FIXED_GAIN_LIST 0x81
458
459/* extract results of LOLA_PAR_SPECIFIC_CAPS */
460#define LOLA_AFG_MIXER_WIDGET_PRESENT(res) ((res & (1 << 21)) != 0)
461#define LOLA_AFG_CLOCK_WIDGET_PRESENT(res) ((res & (1 << 20)) != 0)
462#define LOLA_AFG_INPUT_PIN_COUNT(res) ((res >> 10) & 0x2ff)
463#define LOLA_AFG_OUTPUT_PIN_COUNT(res) ((res) & 0x2ff)
464
465/* extract results of LOLA_PAR_AMP_IN_CAP / LOLA_PAR_AMP_OUT_CAP */
466#define LOLA_AMP_MUTE_CAPABLE(res) ((res & (1 << 31)) != 0)
467#define LOLA_AMP_STEP_SIZE(res) ((res >> 24) & 0x7f)
468#define LOLA_AMP_NUM_STEPS(res) ((res >> 12) & 0x3ff)
469#define LOLA_AMP_OFFSET(res) ((res) & 0x3ff)
470
471#define LOLA_GRANULARITY_MIN 8
472#define LOLA_GRANULARITY_MAX 32
473#define LOLA_GRANULARITY_STEP 8
474
475/* parameters used with unsolicited command/response */
476#define LOLA_UNSOLICITED_TAG_MASK 0x3f
477#define LOLA_UNSOLICITED_TAG 0x1a
478#define LOLA_UNSOLICITED_ENABLE 0x80
479#define LOLA_UNSOL_RESP_TAG_OFFSET 26
480
481/* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */
482#define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res) ((res >> 2) & 0x1f)
483#define LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(res) ((res >> 7) & 0x1f)
484
485int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
486 unsigned int data, unsigned int extdata);
487int lola_codec_read(struct lola *chip, unsigned int nid, unsigned int verb,
488 unsigned int data, unsigned int extdata,
489 unsigned int *val, unsigned int *extval);
490int lola_codec_flush(struct lola *chip);
491#define lola_read_param(chip, nid, param, val) \
492 lola_codec_read(chip, nid, LOLA_VERB_PARAMETERS, param, 0, val, NULL)
493
494/* PCM */
495int lola_create_pcm(struct lola *chip);
496void lola_free_pcm(struct lola *chip);
497int lola_init_pcm(struct lola *chip, int dir, int *nidp);
498void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits);
499
500/* clock */
501int lola_init_clock_widget(struct lola *chip, int nid);
502int lola_set_granularity(struct lola *chip, unsigned int val, bool force);
503int lola_enable_clock_events(struct lola *chip);
504int lola_set_clock_index(struct lola *chip, unsigned int idx);
505int lola_set_clock(struct lola *chip, int idx);
506int lola_set_sample_rate(struct lola *chip, int rate);
507bool lola_update_ext_clock_freq(struct lola *chip, unsigned int val);
508unsigned int lola_sample_rate_convert(unsigned int coded);
509
510/* mixer */
511int lola_init_pins(struct lola *chip, int dir, int *nidp);
512int lola_init_mixer_widget(struct lola *chip, int nid);
513void lola_free_mixer(struct lola *chip);
514int lola_create_mixer(struct lola *chip);
515int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute);
516void lola_save_mixer(struct lola *chip);
517void lola_restore_mixer(struct lola *chip);
518int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update);
519
520/* proc */
521#ifdef CONFIG_SND_DEBUG
522void lola_proc_debug_new(struct lola *chip);
523#else
524#define lola_proc_debug_new(chip)
525#endif
526
527#endif /* _LOLA_H */
diff --git a/sound/pci/lola/lola_clock.c b/sound/pci/lola/lola_clock.c
new file mode 100644
index 000000000000..72f8ef0ac865
--- /dev/null
+++ b/sound/pci/lola/lola_clock.c
@@ -0,0 +1,323 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include "lola.h"
27
28unsigned int lola_sample_rate_convert(unsigned int coded)
29{
30 unsigned int freq;
31
32 /* base frequency */
33 switch (coded & 0x3) {
34 case 0: freq = 48000; break;
35 case 1: freq = 44100; break;
36 case 2: freq = 32000; break;
37 default: return 0; /* error */
38 }
39
40 /* multiplier / devisor */
41 switch (coded & 0x1c) {
42 case (0 << 2): break;
43 case (4 << 2): break;
44 case (1 << 2): freq *= 2; break;
45 case (2 << 2): freq *= 4; break;
46 case (5 << 2): freq /= 2; break;
47 case (6 << 2): freq /= 4; break;
48 default: return 0; /* error */
49 }
50
51 /* ajustement */
52 switch (coded & 0x60) {
53 case (0 << 5): break;
54 case (1 << 5): freq = (freq * 999) / 1000; break;
55 case (2 << 5): freq = (freq * 1001) / 1000; break;
56 default: return 0; /* error */
57 }
58 return freq;
59}
60
61/*
62 * Granualrity
63 */
64
65#define LOLA_MAXFREQ_AT_GRANULARITY_MIN 48000
66#define LOLA_MAXFREQ_AT_GRANULARITY_BELOW_MAX 96000
67
68static bool check_gran_clock_compatibility(struct lola *chip,
69 unsigned int val,
70 unsigned int freq)
71{
72 if (!chip->granularity)
73 return true;
74
75 if (val < LOLA_GRANULARITY_MIN || val > LOLA_GRANULARITY_MAX ||
76 (val % LOLA_GRANULARITY_STEP) != 0)
77 return false;
78
79 if (val == LOLA_GRANULARITY_MIN) {
80 if (freq > LOLA_MAXFREQ_AT_GRANULARITY_MIN)
81 return false;
82 } else if (val < LOLA_GRANULARITY_MAX) {
83 if (freq > LOLA_MAXFREQ_AT_GRANULARITY_BELOW_MAX)
84 return false;
85 }
86 return true;
87}
88
89int lola_set_granularity(struct lola *chip, unsigned int val, bool force)
90{
91 int err;
92
93 if (!force) {
94 if (val == chip->granularity)
95 return 0;
96#if 0
97 /* change Gran only if there are no streams allocated ! */
98 if (chip->audio_in_alloc_mask || chip->audio_out_alloc_mask)
99 return -EBUSY;
100#endif
101 if (!check_gran_clock_compatibility(chip, val,
102 chip->clock.cur_freq))
103 return -EINVAL;
104 }
105
106 chip->granularity = val;
107 val /= LOLA_GRANULARITY_STEP;
108
109 /* audio function group */
110 err = lola_codec_write(chip, 1, LOLA_VERB_SET_GRANULARITY_STEPS,
111 val, 0);
112 if (err < 0)
113 return err;
114 /* this can be a very slow function !!! */
115 usleep_range(400 * val, 20000);
116 return lola_codec_flush(chip);
117}
118
119/*
120 * Clock widget handling
121 */
122
123int __devinit lola_init_clock_widget(struct lola *chip, int nid)
124{
125 unsigned int val;
126 int i, j, nitems, nb_verbs, idx, idx_list;
127 int err;
128
129 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
130 if (err < 0) {
131 printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
132 return err;
133 }
134
135 if ((val & 0xfff00000) != 0x01f00000) { /* test SubType and Type */
136 snd_printdd("No valid clock widget\n");
137 return 0;
138 }
139
140 chip->clock.nid = nid;
141 chip->clock.items = val & 0xff;
142 snd_printdd("clock_list nid=%x, entries=%d\n", nid,
143 chip->clock.items);
144 if (chip->clock.items > MAX_SAMPLE_CLOCK_COUNT) {
145 printk(KERN_ERR SFX "CLOCK_LIST too big: %d\n",
146 chip->clock.items);
147 return -EINVAL;
148 }
149
150 nitems = chip->clock.items;
151 nb_verbs = (nitems + 3) / 4;
152 idx = 0;
153 idx_list = 0;
154 for (i = 0; i < nb_verbs; i++) {
155 unsigned int res_ex;
156 unsigned short items[4];
157
158 err = lola_codec_read(chip, nid, LOLA_VERB_GET_CLOCK_LIST,
159 idx, 0, &val, &res_ex);
160 if (err < 0) {
161 printk(KERN_ERR SFX "Can't read CLOCK_LIST\n");
162 return -EINVAL;
163 }
164
165 items[0] = val & 0xfff;
166 items[1] = (val >> 16) & 0xfff;
167 items[2] = res_ex & 0xfff;
168 items[3] = (res_ex >> 16) & 0xfff;
169
170 for (j = 0; j < 4; j++) {
171 unsigned char type = items[j] >> 8;
172 unsigned int freq = items[j] & 0xff;
173 int format = LOLA_CLOCK_FORMAT_NONE;
174 bool add_clock = true;
175 if (type == LOLA_CLOCK_TYPE_INTERNAL) {
176 freq = lola_sample_rate_convert(freq);
177 if (freq < chip->sample_rate_min)
178 add_clock = false;
179 else if (freq == 48000) {
180 chip->clock.cur_index = idx_list;
181 chip->clock.cur_freq = 48000;
182 chip->clock.cur_valid = true;
183 }
184 } else if (type == LOLA_CLOCK_TYPE_VIDEO) {
185 freq = lola_sample_rate_convert(freq);
186 if (freq < chip->sample_rate_min)
187 add_clock = false;
188 /* video clock has a format (0:NTSC, 1:PAL)*/
189 if (items[j] & 0x80)
190 format = LOLA_CLOCK_FORMAT_NTSC;
191 else
192 format = LOLA_CLOCK_FORMAT_PAL;
193 }
194 if (add_clock) {
195 struct lola_sample_clock *sc;
196 sc = &chip->clock.sample_clock[idx_list];
197 sc->type = type;
198 sc->format = format;
199 sc->freq = freq;
200 /* keep the index used with the board */
201 chip->clock.idx_lookup[idx_list] = idx;
202 idx_list++;
203 } else {
204 chip->clock.items--;
205 }
206 if (++idx >= nitems)
207 break;
208 }
209 }
210 return 0;
211}
212
213/* enable unsolicited events of the clock widget */
214int lola_enable_clock_events(struct lola *chip)
215{
216 unsigned int res;
217 int err;
218
219 err = lola_codec_read(chip, chip->clock.nid,
220 LOLA_VERB_SET_UNSOLICITED_ENABLE,
221 LOLA_UNSOLICITED_ENABLE | LOLA_UNSOLICITED_TAG,
222 0, &res, NULL);
223 if (err < 0)
224 return err;
225 if (res) {
226 printk(KERN_WARNING SFX "error in enable_clock_events %d\n",
227 res);
228 return -EINVAL;
229 }
230 return 0;
231}
232
233int lola_set_clock_index(struct lola *chip, unsigned int idx)
234{
235 unsigned int res;
236 int err;
237
238 err = lola_codec_read(chip, chip->clock.nid,
239 LOLA_VERB_SET_CLOCK_SELECT,
240 chip->clock.idx_lookup[idx],
241 0, &res, NULL);
242 if (err < 0)
243 return err;
244 if (res) {
245 printk(KERN_WARNING SFX "error in set_clock %d\n", res);
246 return -EINVAL;
247 }
248 return 0;
249}
250
251bool lola_update_ext_clock_freq(struct lola *chip, unsigned int val)
252{
253 unsigned int tag;
254
255 /* the current EXTERNAL clock information gets updated by interrupt
256 * with an unsolicited response
257 */
258 if (!val)
259 return false;
260 tag = (val >> LOLA_UNSOL_RESP_TAG_OFFSET) & LOLA_UNSOLICITED_TAG_MASK;
261 if (tag != LOLA_UNSOLICITED_TAG)
262 return false;
263
264 /* only for current = external clocks */
265 if (chip->clock.sample_clock[chip->clock.cur_index].type !=
266 LOLA_CLOCK_TYPE_INTERNAL) {
267 chip->clock.cur_freq = lola_sample_rate_convert(val & 0x7f);
268 chip->clock.cur_valid = (val & 0x100) != 0;
269 }
270 return true;
271}
272
273int lola_set_clock(struct lola *chip, int idx)
274{
275 int freq = 0;
276 bool valid = false;
277
278 if (idx == chip->clock.cur_index) {
279 /* current clock is allowed */
280 freq = chip->clock.cur_freq;
281 valid = chip->clock.cur_valid;
282 } else if (chip->clock.sample_clock[idx].type ==
283 LOLA_CLOCK_TYPE_INTERNAL) {
284 /* internal clocks allowed */
285 freq = chip->clock.sample_clock[idx].freq;
286 valid = true;
287 }
288
289 if (!freq || !valid)
290 return -EINVAL;
291
292 if (!check_gran_clock_compatibility(chip, chip->granularity, freq))
293 return -EINVAL;
294
295 if (idx != chip->clock.cur_index) {
296 int err = lola_set_clock_index(chip, idx);
297 if (err < 0)
298 return err;
299 /* update new settings */
300 chip->clock.cur_index = idx;
301 chip->clock.cur_freq = freq;
302 chip->clock.cur_valid = true;
303 }
304 return 0;
305}
306
307int lola_set_sample_rate(struct lola *chip, int rate)
308{
309 int i;
310
311 if (chip->clock.cur_freq == rate && chip->clock.cur_valid)
312 return 0;
313 /* search for new dwClockIndex */
314 for (i = 0; i < chip->clock.items; i++) {
315 if (chip->clock.sample_clock[i].type == LOLA_CLOCK_TYPE_INTERNAL &&
316 chip->clock.sample_clock[i].freq == rate)
317 break;
318 }
319 if (i >= chip->clock.items)
320 return -EINVAL;
321 return lola_set_clock(chip, i);
322}
323
diff --git a/sound/pci/lola/lola_mixer.c b/sound/pci/lola/lola_mixer.c
new file mode 100644
index 000000000000..5d518f1a712c
--- /dev/null
+++ b/sound/pci/lola/lola_mixer.c
@@ -0,0 +1,839 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/vmalloc.h>
24#include <linux/io.h>
25#include <sound/core.h>
26#include <sound/control.h>
27#include <sound/pcm.h>
28#include <sound/tlv.h>
29#include "lola.h"
30
31static int __devinit lola_init_pin(struct lola *chip, struct lola_pin *pin,
32 int dir, int nid)
33{
34 unsigned int val;
35 int err;
36
37 pin->nid = nid;
38 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
39 if (err < 0) {
40 printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
41 return err;
42 }
43 val &= 0x00f00fff; /* test TYPE and bits 0..11 */
44 if (val == 0x00400200) /* Type = 4, Digital = 1 */
45 pin->is_analog = false;
46 else if (val == 0x0040000a && dir == CAPT) /* Dig=0, InAmp/ovrd */
47 pin->is_analog = true;
48 else if (val == 0x0040000c && dir == PLAY) /* Dig=0, OutAmp/ovrd */
49 pin->is_analog = true;
50 else {
51 printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n", val, nid);
52 return -EINVAL;
53 }
54
55 /* analog parameters only following, so continue in case of Digital pin
56 */
57 if (!pin->is_analog)
58 return 0;
59
60 if (dir == PLAY)
61 err = lola_read_param(chip, nid, LOLA_PAR_AMP_OUT_CAP, &val);
62 else
63 err = lola_read_param(chip, nid, LOLA_PAR_AMP_IN_CAP, &val);
64 if (err < 0) {
65 printk(KERN_ERR SFX "Can't read AMP-caps for 0x%x\n", nid);
66 return err;
67 }
68
69 pin->amp_mute = LOLA_AMP_MUTE_CAPABLE(val);
70 pin->amp_step_size = LOLA_AMP_STEP_SIZE(val);
71 pin->amp_num_steps = LOLA_AMP_NUM_STEPS(val);
72 if (pin->amp_num_steps) {
73 /* zero as mute state */
74 pin->amp_num_steps++;
75 pin->amp_step_size++;
76 }
77 pin->amp_offset = LOLA_AMP_OFFSET(val);
78
79 err = lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val,
80 NULL);
81 if (err < 0) {
82 printk(KERN_ERR SFX "Can't get MAX_LEVEL 0x%x\n", nid);
83 return err;
84 }
85 pin->max_level = val & 0x3ff; /* 10 bits */
86
87 pin->config_default_reg = 0;
88 pin->fixed_gain_list_len = 0;
89 pin->cur_gain_step = 0;
90
91 return 0;
92}
93
94int __devinit lola_init_pins(struct lola *chip, int dir, int *nidp)
95{
96 int i, err, nid;
97 nid = *nidp;
98 for (i = 0; i < chip->pin[dir].num_pins; i++, nid++) {
99 err = lola_init_pin(chip, &chip->pin[dir].pins[i], dir, nid);
100 if (err < 0)
101 return err;
102 if (chip->pin[dir].pins[i].is_analog)
103 chip->pin[dir].num_analog_pins++;
104 }
105 *nidp = nid;
106 return 0;
107}
108
109void lola_free_mixer(struct lola *chip)
110{
111 if (chip->mixer.array_saved)
112 vfree(chip->mixer.array_saved);
113}
114
115int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
116{
117 unsigned int val;
118 int err;
119
120 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
121 if (err < 0) {
122 printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
123 return err;
124 }
125
126 if ((val & 0xfff00000) != 0x02f00000) { /* test SubType and Type */
127 snd_printdd("No valid mixer widget\n");
128 return 0;
129 }
130
131 chip->mixer.nid = nid;
132 chip->mixer.caps = val;
133 chip->mixer.array = (struct lola_mixer_array __iomem *)
134 (chip->bar[BAR1].remap_addr + LOLA_BAR1_SOURCE_GAIN_ENABLE);
135
136 /* reserve memory to copy mixer data for sleep mode transitions */
137 chip->mixer.array_saved = vmalloc(sizeof(struct lola_mixer_array));
138
139 /* mixer matrix sources are physical input data and play streams */
140 chip->mixer.src_stream_outs = chip->pcm[PLAY].num_streams;
141 chip->mixer.src_phys_ins = chip->pin[CAPT].num_pins;
142
143 /* mixer matrix destinations are record streams and physical output */
144 chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
145 chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;
146
147 /* mixer matrix can have unused areas between PhysIn and
148 * Play or Record and PhysOut zones
149 */
150 chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
151 LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
152 chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
153 LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(val);
154
155 /* example : MixerMatrix of LoLa881
156 * 0-------8------16-------8------16
157 * | | | | |
158 * | INPUT | | INPUT | |
159 * | -> |unused | -> |unused |
160 * | RECORD| | OUTPUT| |
161 * | | | | |
162 * 8--------------------------------
163 * | | | | |
164 * | | | | |
165 * |unused |unused |unused |unused |
166 * | | | | |
167 * | | | | |
168 * 16-------------------------------
169 * | | | | |
170 * | PLAY | | PLAY | |
171 * | -> |unused | -> |unused |
172 * | RECORD| | OUTPUT| |
173 * | | | | |
174 * 8--------------------------------
175 * | | | | |
176 * | | | | |
177 * |unused |unused |unused |unused |
178 * | | | | |
179 * | | | | |
180 * 16-------------------------------
181 */
182 if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
183 chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) {
184 printk(KERN_ERR SFX "Invalid mixer widget size\n");
185 return -EINVAL;
186 }
187
188 chip->mixer.src_mask = ((1U << chip->mixer.src_phys_ins) - 1) |
189 (((1U << chip->mixer.src_stream_outs) - 1)
190 << chip->mixer.src_stream_out_ofs);
191 chip->mixer.dest_mask = ((1U << chip->mixer.dest_stream_ins) - 1) |
192 (((1U << chip->mixer.dest_phys_outs) - 1)
193 << chip->mixer.dest_phys_out_ofs);
194
195 return 0;
196}
197
198static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
199 unsigned short gain, bool on)
200{
201 unsigned int oldval, val;
202
203 if (!(chip->mixer.src_mask & (1 << id)))
204 return -EINVAL;
205 writew(gain, &chip->mixer.array->src_gain[id]);
206 oldval = val = readl(&chip->mixer.array->src_gain_enable);
207 if (on)
208 val |= (1 << id);
209 else
210 val &= ~(1 << id);
211 writel(val, &chip->mixer.array->src_gain_enable);
212 lola_codec_flush(chip);
213 /* inform micro-controller about the new source gain */
214 return lola_codec_write(chip, chip->mixer.nid,
215 LOLA_VERB_SET_SOURCE_GAIN, id, 0);
216}
217
218#if 0 /* not used */
219static int lola_mixer_set_src_gains(struct lola *chip, unsigned int mask,
220 unsigned short *gains)
221{
222 int i;
223
224 if ((chip->mixer.src_mask & mask) != mask)
225 return -EINVAL;
226 for (i = 0; i < LOLA_MIXER_DIM; i++) {
227 if (mask & (1 << i)) {
228 writew(*gains, &chip->mixer.array->src_gain[i]);
229 gains++;
230 }
231 }
232 writel(mask, &chip->mixer.array->src_gain_enable);
233 lola_codec_flush(chip);
234 if (chip->mixer.caps & LOLA_PEAK_METER_CAN_AGC_MASK) {
235 /* update for all srcs at once */
236 return lola_codec_write(chip, chip->mixer.nid,
237 LOLA_VERB_SET_SOURCE_GAIN, 0x80, 0);
238 }
239 /* update manually */
240 for (i = 0; i < LOLA_MIXER_DIM; i++) {
241 if (mask & (1 << i)) {
242 lola_codec_write(chip, chip->mixer.nid,
243 LOLA_VERB_SET_SOURCE_GAIN, i, 0);
244 }
245 }
246 return 0;
247}
248#endif /* not used */
249
250static int lola_mixer_set_mapping_gain(struct lola *chip,
251 unsigned int src, unsigned int dest,
252 unsigned short gain, bool on)
253{
254 unsigned int val;
255
256 if (!(chip->mixer.src_mask & (1 << src)) ||
257 !(chip->mixer.dest_mask & (1 << dest)))
258 return -EINVAL;
259 if (on)
260 writew(gain, &chip->mixer.array->dest_mix_gain[dest][src]);
261 val = readl(&chip->mixer.array->dest_mix_gain_enable[dest]);
262 if (on)
263 val |= (1 << src);
264 else
265 val &= ~(1 << src);
266 writel(val, &chip->mixer.array->dest_mix_gain_enable[dest]);
267 lola_codec_flush(chip);
268 return lola_codec_write(chip, chip->mixer.nid, LOLA_VERB_SET_MIX_GAIN,
269 src, dest);
270}
271
272static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
273 unsigned int mask, unsigned short *gains)
274{
275 int i;
276
277 if (!(chip->mixer.dest_mask & (1 << id)) ||
278 (chip->mixer.src_mask & mask) != mask)
279 return -EINVAL;
280 for (i = 0; i < LOLA_MIXER_DIM; i++) {
281 if (mask & (1 << i)) {
282 writew(*gains, &chip->mixer.array->dest_mix_gain[id][i]);
283 gains++;
284 }
285 }
286 writel(mask, &chip->mixer.array->dest_mix_gain_enable[id]);
287 lola_codec_flush(chip);
288 /* update for all dests at once */
289 return lola_codec_write(chip, chip->mixer.nid,
290 LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
291}
292
293/*
294 */
295
296static int set_analog_volume(struct lola *chip, int dir,
297 unsigned int idx, unsigned int val,
298 bool external_call);
299
300int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute)
301{
302 struct lola_pin *pin;
303 int idx, max_idx;
304
305 pin = chip->pin[dir].pins;
306 max_idx = chip->pin[dir].num_pins;
307 for (idx = 0; idx < max_idx; idx++) {
308 if (pin[idx].is_analog) {
309 unsigned int val = mute ? 0 : pin[idx].cur_gain_step;
310 /* set volume and do not save the value */
311 set_analog_volume(chip, dir, idx, val, false);
312 }
313 }
314 return lola_codec_flush(chip);
315}
316
317void lola_save_mixer(struct lola *chip)
318{
319 /* mute analog output */
320 if (chip->mixer.array_saved) {
321 /* store contents of mixer array */
322 memcpy_fromio(chip->mixer.array_saved, chip->mixer.array,
323 sizeof(*chip->mixer.array));
324 }
325 lola_setup_all_analog_gains(chip, PLAY, true); /* output mute */
326}
327
328void lola_restore_mixer(struct lola *chip)
329{
330 int i;
331
332 /*lola_reset_setups(chip);*/
333 if (chip->mixer.array_saved) {
334 /* restore contents of mixer array */
335 memcpy_toio(chip->mixer.array, chip->mixer.array_saved,
336 sizeof(*chip->mixer.array));
337 /* inform micro-controller about all restored values
338 * and ignore return values
339 */
340 for (i = 0; i < chip->mixer.src_phys_ins; i++)
341 lola_codec_write(chip, chip->mixer.nid,
342 LOLA_VERB_SET_SOURCE_GAIN,
343 i, 0);
344 for (i = 0; i < chip->mixer.src_stream_outs; i++)
345 lola_codec_write(chip, chip->mixer.nid,
346 LOLA_VERB_SET_SOURCE_GAIN,
347 chip->mixer.src_stream_out_ofs + i, 0);
348 for (i = 0; i < chip->mixer.dest_stream_ins; i++)
349 lola_codec_write(chip, chip->mixer.nid,
350 LOLA_VERB_SET_DESTINATION_GAIN,
351 i, 0);
352 for (i = 0; i < chip->mixer.dest_phys_outs; i++)
353 lola_codec_write(chip, chip->mixer.nid,
354 LOLA_VERB_SET_DESTINATION_GAIN,
355 chip->mixer.dest_phys_out_ofs + i, 0);
356 lola_codec_flush(chip);
357 }
358}
359
360/*
361 */
362
363static int set_analog_volume(struct lola *chip, int dir,
364 unsigned int idx, unsigned int val,
365 bool external_call)
366{
367 struct lola_pin *pin;
368 int err;
369
370 if (idx >= chip->pin[dir].num_pins)
371 return -EINVAL;
372 pin = &chip->pin[dir].pins[idx];
373 if (!pin->is_analog || pin->amp_num_steps <= val)
374 return -EINVAL;
375 if (external_call && pin->cur_gain_step == val)
376 return 0;
377 if (external_call)
378 lola_codec_flush(chip);
379 err = lola_codec_write(chip, pin->nid,
380 LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
381 if (err < 0)
382 return err;
383 if (external_call)
384 pin->cur_gain_step = val;
385 return 0;
386}
387
388int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update)
389{
390 int ret = 0;
391 int success = 0;
392 int n, err;
393
394 /* SRC can be activated and the dwInputSRCMask is valid? */
395 if ((chip->input_src_caps_mask & src_mask) != src_mask)
396 return -EINVAL;
397 /* handle all even Inputs - SRC is a stereo setting !!! */
398 for (n = 0; n < chip->pin[CAPT].num_pins; n += 2) {
399 unsigned int mask = 3U << n; /* handle the stereo case */
400 unsigned int new_src, src_state;
401 if (!(chip->input_src_caps_mask & mask))
402 continue;
403 /* if one IO needs SRC, both stereo IO will get SRC */
404 new_src = (src_mask & mask) != 0;
405 if (update) {
406 src_state = (chip->input_src_mask & mask) != 0;
407 if (src_state == new_src)
408 continue; /* nothing to change for this IO */
409 }
410 err = lola_codec_write(chip, chip->pcm[CAPT].streams[n].nid,
411 LOLA_VERB_SET_SRC, new_src, 0);
412 if (!err)
413 success++;
414 else
415 ret = err;
416 }
417 if (success)
418 ret = lola_codec_flush(chip);
419 if (!ret)
420 chip->input_src_mask = src_mask;
421 return ret;
422}
423
424/*
425 */
426static int init_mixer_values(struct lola *chip)
427{
428 int i;
429
430 /* all src on */
431 lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);
432
433 /* clear all matrix */
434 memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
435 /* set src gain to 0dB */
436 for (i = 0; i < chip->mixer.src_phys_ins; i++)
437 lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */
438 for (i = 0; i < chip->mixer.src_stream_outs; i++)
439 lola_mixer_set_src_gain(chip,
440 i + chip->mixer.src_stream_out_ofs,
441 336, true); /* 0dB */
442 /* set 1:1 dest gain */
443 for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
444 int src = i % chip->mixer.src_phys_ins;
445 lola_mixer_set_mapping_gain(chip, src, i, 336, true);
446 }
447 for (i = 0; i < chip->mixer.src_stream_outs; i++) {
448 int src = chip->mixer.src_stream_out_ofs + i;
449 int dst = chip->mixer.dest_phys_out_ofs +
450 i % chip->mixer.dest_phys_outs;
451 lola_mixer_set_mapping_gain(chip, src, dst, 336, true);
452 }
453 return 0;
454}
455
456/*
457 * analog mixer control element
458 */
459static int lola_analog_vol_info(struct snd_kcontrol *kcontrol,
460 struct snd_ctl_elem_info *uinfo)
461{
462 struct lola *chip = snd_kcontrol_chip(kcontrol);
463 int dir = kcontrol->private_value;
464
465 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
466 uinfo->count = chip->pin[dir].num_pins;
467 uinfo->value.integer.min = 0;
468 uinfo->value.integer.max = chip->pin[dir].pins[0].amp_num_steps;
469 return 0;
470}
471
472static int lola_analog_vol_get(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_value *ucontrol)
474{
475 struct lola *chip = snd_kcontrol_chip(kcontrol);
476 int dir = kcontrol->private_value;
477 int i;
478
479 for (i = 0; i < chip->pin[dir].num_pins; i++)
480 ucontrol->value.integer.value[i] =
481 chip->pin[dir].pins[i].cur_gain_step;
482 return 0;
483}
484
485static int lola_analog_vol_put(struct snd_kcontrol *kcontrol,
486 struct snd_ctl_elem_value *ucontrol)
487{
488 struct lola *chip = snd_kcontrol_chip(kcontrol);
489 int dir = kcontrol->private_value;
490 int i, err;
491
492 for (i = 0; i < chip->pin[dir].num_pins; i++) {
493 err = set_analog_volume(chip, dir, i,
494 ucontrol->value.integer.value[i],
495 true);
496 if (err < 0)
497 return err;
498 }
499 return 0;
500}
501
502static int lola_analog_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
503 unsigned int size, unsigned int __user *tlv)
504{
505 struct lola *chip = snd_kcontrol_chip(kcontrol);
506 int dir = kcontrol->private_value;
507 unsigned int val1, val2;
508 struct lola_pin *pin;
509
510 if (size < 4 * sizeof(unsigned int))
511 return -ENOMEM;
512 pin = &chip->pin[dir].pins[0];
513
514 val2 = pin->amp_step_size * 25;
515 val1 = -1 * (int)pin->amp_offset * (int)val2;
516#ifdef TLV_DB_SCALE_MUTE
517 val2 |= TLV_DB_SCALE_MUTE;
518#endif
519 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, tlv))
520 return -EFAULT;
521 if (put_user(2 * sizeof(unsigned int), tlv + 1))
522 return -EFAULT;
523 if (put_user(val1, tlv + 2))
524 return -EFAULT;
525 if (put_user(val2, tlv + 3))
526 return -EFAULT;
527 return 0;
528}
529
530static struct snd_kcontrol_new lola_analog_mixer __devinitdata = {
531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
532 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
533 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
534 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK),
535 .info = lola_analog_vol_info,
536 .get = lola_analog_vol_get,
537 .put = lola_analog_vol_put,
538 .tlv.c = lola_analog_vol_tlv,
539};
540
541static int __devinit create_analog_mixer(struct lola *chip, int dir, char *name)
542{
543 if (!chip->pin[dir].num_pins)
544 return 0;
545 /* no analog volumes on digital only adapters */
546 if (chip->pin[dir].num_pins != chip->pin[dir].num_analog_pins)
547 return 0;
548 lola_analog_mixer.name = name;
549 lola_analog_mixer.private_value = dir;
550 return snd_ctl_add(chip->card,
551 snd_ctl_new1(&lola_analog_mixer, chip));
552}
553
554/*
555 * Hardware sample rate converter on digital input
556 */
557static int lola_input_src_info(struct snd_kcontrol *kcontrol,
558 struct snd_ctl_elem_info *uinfo)
559{
560 struct lola *chip = snd_kcontrol_chip(kcontrol);
561
562 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
563 uinfo->count = chip->pin[CAPT].num_pins;
564 uinfo->value.integer.min = 0;
565 uinfo->value.integer.max = 1;
566 return 0;
567}
568
569static int lola_input_src_get(struct snd_kcontrol *kcontrol,
570 struct snd_ctl_elem_value *ucontrol)
571{
572 struct lola *chip = snd_kcontrol_chip(kcontrol);
573 int i;
574
575 for (i = 0; i < chip->pin[CAPT].num_pins; i++)
576 ucontrol->value.integer.value[i] =
577 !!(chip->input_src_mask & (1 << i));
578 return 0;
579}
580
581static int lola_input_src_put(struct snd_kcontrol *kcontrol,
582 struct snd_ctl_elem_value *ucontrol)
583{
584 struct lola *chip = snd_kcontrol_chip(kcontrol);
585 int i;
586 unsigned int mask;
587
588 mask = 0;
589 for (i = 0; i < chip->pin[CAPT].num_pins; i++)
590 if (ucontrol->value.integer.value[i])
591 mask |= 1 << i;
592 return lola_set_src_config(chip, mask, true);
593}
594
595static struct snd_kcontrol_new lola_input_src_mixer __devinitdata = {
596 .name = "Digital SRC Capture Switch",
597 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
598 .info = lola_input_src_info,
599 .get = lola_input_src_get,
600 .put = lola_input_src_put,
601};
602
603/*
604 * Lola16161 or Lola881 can have Hardware sample rate converters
605 * on its digital input pins
606 */
607static int __devinit create_input_src_mixer(struct lola *chip)
608{
609 if (!chip->input_src_caps_mask)
610 return 0;
611
612 return snd_ctl_add(chip->card,
613 snd_ctl_new1(&lola_input_src_mixer, chip));
614}
615
616/*
617 * src gain mixer
618 */
619static int lola_src_gain_info(struct snd_kcontrol *kcontrol,
620 struct snd_ctl_elem_info *uinfo)
621{
622 unsigned int count = (kcontrol->private_value >> 8) & 0xff;
623
624 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
625 uinfo->count = count;
626 uinfo->value.integer.min = 0;
627 uinfo->value.integer.max = 409;
628 return 0;
629}
630
631static int lola_src_gain_get(struct snd_kcontrol *kcontrol,
632 struct snd_ctl_elem_value *ucontrol)
633{
634 struct lola *chip = snd_kcontrol_chip(kcontrol);
635 unsigned int ofs = kcontrol->private_value & 0xff;
636 unsigned int count = (kcontrol->private_value >> 8) & 0xff;
637 unsigned int mask, i;
638
639 mask = readl(&chip->mixer.array->src_gain_enable);
640 for (i = 0; i < count; i++) {
641 unsigned int idx = ofs + i;
642 unsigned short val;
643 if (!(chip->mixer.src_mask & (1 << idx)))
644 return -EINVAL;
645 if (mask & (1 << idx))
646 val = readw(&chip->mixer.array->src_gain[idx]) + 1;
647 else
648 val = 0;
649 ucontrol->value.integer.value[i] = val;
650 }
651 return 0;
652}
653
654static int lola_src_gain_put(struct snd_kcontrol *kcontrol,
655 struct snd_ctl_elem_value *ucontrol)
656{
657 struct lola *chip = snd_kcontrol_chip(kcontrol);
658 unsigned int ofs = kcontrol->private_value & 0xff;
659 unsigned int count = (kcontrol->private_value >> 8) & 0xff;
660 int i, err;
661
662 for (i = 0; i < count; i++) {
663 unsigned int idx = ofs + i;
664 unsigned short val = ucontrol->value.integer.value[i];
665 if (val)
666 val--;
667 err = lola_mixer_set_src_gain(chip, idx, val, !!val);
668 if (err < 0)
669 return err;
670 }
671 return 0;
672}
673
674/* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */
675static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv, -8425, 25, 1);
676
677static struct snd_kcontrol_new lola_src_gain_mixer __devinitdata = {
678 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
679 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
680 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
681 .info = lola_src_gain_info,
682 .get = lola_src_gain_get,
683 .put = lola_src_gain_put,
684 .tlv.p = lola_src_gain_tlv,
685};
686
687static int __devinit create_src_gain_mixer(struct lola *chip,
688 int num, int ofs, char *name)
689{
690 lola_src_gain_mixer.name = name;
691 lola_src_gain_mixer.private_value = ofs + (num << 8);
692 return snd_ctl_add(chip->card,
693 snd_ctl_new1(&lola_src_gain_mixer, chip));
694}
695
696/*
697 * destination gain (matrix-like) mixer
698 */
699static int lola_dest_gain_info(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_info *uinfo)
701{
702 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
703
704 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
705 uinfo->count = src_num;
706 uinfo->value.integer.min = 0;
707 uinfo->value.integer.max = 433;
708 return 0;
709}
710
711static int lola_dest_gain_get(struct snd_kcontrol *kcontrol,
712 struct snd_ctl_elem_value *ucontrol)
713{
714 struct lola *chip = snd_kcontrol_chip(kcontrol);
715 unsigned int src_ofs = kcontrol->private_value & 0xff;
716 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
717 unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
718 unsigned int dst, mask, i;
719
720 dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
721 mask = readl(&chip->mixer.array->dest_mix_gain_enable[dst]);
722 for (i = 0; i < src_num; i++) {
723 unsigned int src = src_ofs + i;
724 unsigned short val;
725 if (!(chip->mixer.src_mask & (1 << src)))
726 return -EINVAL;
727 if (mask & (1 << dst))
728 val = readw(&chip->mixer.array->dest_mix_gain[dst][src]) + 1;
729 else
730 val = 0;
731 ucontrol->value.integer.value[i] = val;
732 }
733 return 0;
734}
735
736static int lola_dest_gain_put(struct snd_kcontrol *kcontrol,
737 struct snd_ctl_elem_value *ucontrol)
738{
739 struct lola *chip = snd_kcontrol_chip(kcontrol);
740 unsigned int src_ofs = kcontrol->private_value & 0xff;
741 unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
742 unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
743 unsigned int dst, mask;
744 unsigned short gains[MAX_STREAM_COUNT];
745 int i, num;
746
747 mask = 0;
748 num = 0;
749 for (i = 0; i < src_num; i++) {
750 unsigned short val = ucontrol->value.integer.value[i];
751 if (val) {
752 gains[num++] = val - 1;
753 mask |= 1 << i;
754 }
755 }
756 mask <<= src_ofs;
757 dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
758 return lola_mixer_set_dest_gains(chip, dst, mask, gains);
759}
760
761static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv, -8425, 25, 1);
762
763static struct snd_kcontrol_new lola_dest_gain_mixer __devinitdata = {
764 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
765 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
766 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
767 .info = lola_dest_gain_info,
768 .get = lola_dest_gain_get,
769 .put = lola_dest_gain_put,
770 .tlv.p = lola_dest_gain_tlv,
771};
772
773static int __devinit create_dest_gain_mixer(struct lola *chip,
774 int src_num, int src_ofs,
775 int num, int ofs, char *name)
776{
777 lola_dest_gain_mixer.count = num;
778 lola_dest_gain_mixer.name = name;
779 lola_dest_gain_mixer.private_value =
780 src_ofs + (src_num << 8) + (ofs << 16) + (num << 24);
781 return snd_ctl_add(chip->card,
782 snd_ctl_new1(&lola_dest_gain_mixer, chip));
783}
784
785/*
786 */
787int __devinit lola_create_mixer(struct lola *chip)
788{
789 int err;
790
791 err = create_analog_mixer(chip, PLAY, "Analog Playback Volume");
792 if (err < 0)
793 return err;
794 err = create_analog_mixer(chip, CAPT, "Analog Capture Volume");
795 if (err < 0)
796 return err;
797 err = create_input_src_mixer(chip);
798 if (err < 0)
799 return err;
800 err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
801 "Line Source Gain Volume");
802 if (err < 0)
803 return err;
804 err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
805 chip->mixer.src_stream_out_ofs,
806 "Stream Source Gain Volume");
807 if (err < 0)
808 return err;
809 err = create_dest_gain_mixer(chip,
810 chip->mixer.src_phys_ins, 0,
811 chip->mixer.dest_stream_ins, 0,
812 "Line Capture Volume");
813 if (err < 0)
814 return err;
815 err = create_dest_gain_mixer(chip,
816 chip->mixer.src_stream_outs,
817 chip->mixer.src_stream_out_ofs,
818 chip->mixer.dest_stream_ins, 0,
819 "Stream-Loopback Capture Volume");
820 if (err < 0)
821 return err;
822 err = create_dest_gain_mixer(chip,
823 chip->mixer.src_phys_ins, 0,
824 chip->mixer.dest_phys_outs,
825 chip->mixer.dest_phys_out_ofs,
826 "Line-Loopback Playback Volume");
827 if (err < 0)
828 return err;
829 err = create_dest_gain_mixer(chip,
830 chip->mixer.src_stream_outs,
831 chip->mixer.src_stream_out_ofs,
832 chip->mixer.dest_phys_outs,
833 chip->mixer.dest_phys_out_ofs,
834 "Stream Playback Volume");
835 if (err < 0)
836 return err;
837
838 return init_mixer_values(chip);
839}
diff --git a/sound/pci/lola/lola_pcm.c b/sound/pci/lola/lola_pcm.c
new file mode 100644
index 000000000000..c44db68eecb5
--- /dev/null
+++ b/sound/pci/lola/lola_pcm.c
@@ -0,0 +1,706 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/dma-mapping.h>
24#include <linux/pci.h>
25#include <linux/delay.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include "lola.h"
29
30#define LOLA_MAX_BDL_ENTRIES 8
31#define LOLA_MAX_BUF_SIZE (1024*1024*1024)
32#define LOLA_BDL_ENTRY_SIZE (16 * 16)
33
34static struct lola_pcm *lola_get_pcm(struct snd_pcm_substream *substream)
35{
36 struct lola *chip = snd_pcm_substream_chip(substream);
37 return &chip->pcm[substream->stream];
38}
39
40static struct lola_stream *lola_get_stream(struct snd_pcm_substream *substream)
41{
42 struct lola_pcm *pcm = lola_get_pcm(substream);
43 unsigned int idx = substream->number;
44 return &pcm->streams[idx];
45}
46
47static unsigned int lola_get_lrc(struct lola *chip)
48{
49 return lola_readl(chip, BAR1, LRC);
50}
51
52static unsigned int lola_get_tstamp(struct lola *chip, bool quick_no_sync)
53{
54 unsigned int tstamp = lola_get_lrc(chip) >> 8;
55 if (chip->granularity) {
56 unsigned int wait_banks = quick_no_sync ? 0 : 8;
57 tstamp += (wait_banks + 1) * chip->granularity - 1;
58 tstamp -= tstamp % chip->granularity;
59 }
60 return tstamp << 8;
61}
62
63/* clear any pending interrupt status */
64static void lola_stream_clear_pending_irq(struct lola *chip,
65 struct lola_stream *str)
66{
67 unsigned int val = lola_dsd_read(chip, str->dsd, STS);
68 val &= LOLA_DSD_STS_DESE | LOLA_DSD_STS_BCIS;
69 if (val)
70 lola_dsd_write(chip, str->dsd, STS, val);
71}
72
73static void lola_stream_start(struct lola *chip, struct lola_stream *str,
74 unsigned int tstamp)
75{
76 lola_stream_clear_pending_irq(chip, str);
77 lola_dsd_write(chip, str->dsd, CTL,
78 LOLA_DSD_CTL_SRUN |
79 LOLA_DSD_CTL_IOCE |
80 LOLA_DSD_CTL_DEIE |
81 LOLA_DSD_CTL_VLRCV |
82 tstamp);
83}
84
85static void lola_stream_stop(struct lola *chip, struct lola_stream *str,
86 unsigned int tstamp)
87{
88 lola_dsd_write(chip, str->dsd, CTL,
89 LOLA_DSD_CTL_IOCE |
90 LOLA_DSD_CTL_DEIE |
91 LOLA_DSD_CTL_VLRCV |
92 tstamp);
93 lola_stream_clear_pending_irq(chip, str);
94}
95
96static void wait_for_srst_clear(struct lola *chip, struct lola_stream *str)
97{
98 unsigned long end_time = jiffies + msecs_to_jiffies(200);
99 while (time_before(jiffies, end_time)) {
100 unsigned int val;
101 val = lola_dsd_read(chip, str->dsd, CTL);
102 if (!(val & LOLA_DSD_CTL_SRST))
103 return;
104 msleep(1);
105 }
106 printk(KERN_WARNING SFX "SRST not clear (stream %d)\n", str->dsd);
107}
108
109static int lola_stream_wait_for_fifo(struct lola *chip,
110 struct lola_stream *str,
111 bool ready)
112{
113 unsigned int val = ready ? LOLA_DSD_STS_FIFORDY : 0;
114 unsigned long end_time = jiffies + msecs_to_jiffies(200);
115 while (time_before(jiffies, end_time)) {
116 unsigned int reg = lola_dsd_read(chip, str->dsd, STS);
117 if ((reg & LOLA_DSD_STS_FIFORDY) == val)
118 return 0;
119 msleep(1);
120 }
121 printk(KERN_WARNING SFX "FIFO not ready (stream %d)\n", str->dsd);
122 return -EIO;
123}
124
125/* sync for FIFO ready/empty for all linked streams;
126 * clear paused flag when FIFO gets ready again
127 */
128static int lola_sync_wait_for_fifo(struct lola *chip,
129 struct snd_pcm_substream *substream,
130 bool ready)
131{
132 unsigned int val = ready ? LOLA_DSD_STS_FIFORDY : 0;
133 unsigned long end_time = jiffies + msecs_to_jiffies(200);
134 struct snd_pcm_substream *s;
135 int pending = 0;
136
137 while (time_before(jiffies, end_time)) {
138 pending = 0;
139 snd_pcm_group_for_each_entry(s, substream) {
140 struct lola_stream *str;
141 if (s->pcm->card != substream->pcm->card)
142 continue;
143 str = lola_get_stream(s);
144 if (str->prepared && str->paused) {
145 unsigned int reg;
146 reg = lola_dsd_read(chip, str->dsd, STS);
147 if ((reg & LOLA_DSD_STS_FIFORDY) != val) {
148 pending = str->dsd + 1;
149 break;
150 }
151 if (ready)
152 str->paused = 0;
153 }
154 }
155 if (!pending)
156 return 0;
157 msleep(1);
158 }
159 printk(KERN_WARNING SFX "FIFO not ready (pending %d)\n", pending - 1);
160 return -EIO;
161}
162
163/* finish pause - prepare for a new resume */
164static void lola_sync_pause(struct lola *chip,
165 struct snd_pcm_substream *substream)
166{
167 struct snd_pcm_substream *s;
168
169 lola_sync_wait_for_fifo(chip, substream, false);
170 snd_pcm_group_for_each_entry(s, substream) {
171 struct lola_stream *str;
172 if (s->pcm->card != substream->pcm->card)
173 continue;
174 str = lola_get_stream(s);
175 if (str->paused && str->prepared)
176 lola_dsd_write(chip, str->dsd, CTL, LOLA_DSD_CTL_SRUN |
177 LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE);
178 }
179 lola_sync_wait_for_fifo(chip, substream, true);
180}
181
182static void lola_stream_reset(struct lola *chip, struct lola_stream *str)
183{
184 if (str->prepared) {
185 if (str->paused)
186 lola_sync_pause(chip, str->substream);
187 str->prepared = 0;
188 lola_dsd_write(chip, str->dsd, CTL,
189 LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE);
190 lola_stream_wait_for_fifo(chip, str, false);
191 lola_stream_clear_pending_irq(chip, str);
192 lola_dsd_write(chip, str->dsd, CTL, LOLA_DSD_CTL_SRST);
193 lola_dsd_write(chip, str->dsd, LVI, 0);
194 lola_dsd_write(chip, str->dsd, BDPU, 0);
195 lola_dsd_write(chip, str->dsd, BDPL, 0);
196 wait_for_srst_clear(chip, str);
197 }
198}
199
200static struct snd_pcm_hardware lola_pcm_hw = {
201 .info = (SNDRV_PCM_INFO_MMAP |
202 SNDRV_PCM_INFO_INTERLEAVED |
203 SNDRV_PCM_INFO_BLOCK_TRANSFER |
204 SNDRV_PCM_INFO_MMAP_VALID |
205 SNDRV_PCM_INFO_PAUSE),
206 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
207 SNDRV_PCM_FMTBIT_S24_LE |
208 SNDRV_PCM_FMTBIT_S32_LE |
209 SNDRV_PCM_FMTBIT_FLOAT_LE),
210 .rates = SNDRV_PCM_RATE_8000_192000,
211 .rate_min = 8000,
212 .rate_max = 192000,
213 .channels_min = 1,
214 .channels_max = 2,
215 .buffer_bytes_max = LOLA_MAX_BUF_SIZE,
216 .period_bytes_min = 128,
217 .period_bytes_max = LOLA_MAX_BUF_SIZE / 2,
218 .periods_min = 2,
219 .periods_max = LOLA_MAX_BDL_ENTRIES,
220 .fifo_size = 0,
221};
222
223static int lola_pcm_open(struct snd_pcm_substream *substream)
224{
225 struct lola *chip = snd_pcm_substream_chip(substream);
226 struct lola_pcm *pcm = lola_get_pcm(substream);
227 struct lola_stream *str = lola_get_stream(substream);
228 struct snd_pcm_runtime *runtime = substream->runtime;
229
230 mutex_lock(&chip->open_mutex);
231 if (str->opened) {
232 mutex_unlock(&chip->open_mutex);
233 return -EBUSY;
234 }
235 str->substream = substream;
236 str->master = NULL;
237 str->opened = 1;
238 runtime->hw = lola_pcm_hw;
239 runtime->hw.channels_max = pcm->num_streams - str->index;
240 if (chip->sample_rate) {
241 /* sample rate is locked */
242 runtime->hw.rate_min = chip->sample_rate;
243 runtime->hw.rate_max = chip->sample_rate;
244 } else {
245 runtime->hw.rate_min = chip->sample_rate_min;
246 runtime->hw.rate_max = chip->sample_rate_max;
247 }
248 chip->ref_count_rate++;
249 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
250 /* period size = multiple of chip->granularity (8, 16 or 32 frames)*/
251 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
252 chip->granularity);
253 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
254 chip->granularity);
255 mutex_unlock(&chip->open_mutex);
256 return 0;
257}
258
259static void lola_cleanup_slave_streams(struct lola_pcm *pcm,
260 struct lola_stream *str)
261{
262 int i;
263 for (i = str->index + 1; i < pcm->num_streams; i++) {
264 struct lola_stream *s = &pcm->streams[i];
265 if (s->master != str)
266 break;
267 s->master = NULL;
268 s->opened = 0;
269 }
270}
271
272static int lola_pcm_close(struct snd_pcm_substream *substream)
273{
274 struct lola *chip = snd_pcm_substream_chip(substream);
275 struct lola_stream *str = lola_get_stream(substream);
276
277 mutex_lock(&chip->open_mutex);
278 if (str->substream == substream) {
279 str->substream = NULL;
280 str->opened = 0;
281 }
282 if (--chip->ref_count_rate == 0) {
283 /* release sample rate */
284 chip->sample_rate = 0;
285 }
286 mutex_unlock(&chip->open_mutex);
287 return 0;
288}
289
290static int lola_pcm_hw_params(struct snd_pcm_substream *substream,
291 struct snd_pcm_hw_params *hw_params)
292{
293 struct lola_stream *str = lola_get_stream(substream);
294
295 str->bufsize = 0;
296 str->period_bytes = 0;
297 str->format_verb = 0;
298 return snd_pcm_lib_malloc_pages(substream,
299 params_buffer_bytes(hw_params));
300}
301
302static int lola_pcm_hw_free(struct snd_pcm_substream *substream)
303{
304 struct lola *chip = snd_pcm_substream_chip(substream);
305 struct lola_pcm *pcm = lola_get_pcm(substream);
306 struct lola_stream *str = lola_get_stream(substream);
307
308 mutex_lock(&chip->open_mutex);
309 lola_stream_reset(chip, str);
310 lola_cleanup_slave_streams(pcm, str);
311 mutex_unlock(&chip->open_mutex);
312 return snd_pcm_lib_free_pages(substream);
313}
314
315/*
316 * set up a BDL entry
317 */
318static int setup_bdle(struct snd_pcm_substream *substream,
319 struct lola_stream *str, u32 **bdlp,
320 int ofs, int size)
321{
322 u32 *bdl = *bdlp;
323
324 while (size > 0) {
325 dma_addr_t addr;
326 int chunk;
327
328 if (str->frags >= LOLA_MAX_BDL_ENTRIES)
329 return -EINVAL;
330
331 addr = snd_pcm_sgbuf_get_addr(substream, ofs);
332 /* program the address field of the BDL entry */
333 bdl[0] = cpu_to_le32((u32)addr);
334 bdl[1] = cpu_to_le32(upper_32_bits(addr));
335 /* program the size field of the BDL entry */
336 chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size);
337 bdl[2] = cpu_to_le32(chunk);
338 /* program the IOC to enable interrupt
339 * only when the whole fragment is processed
340 */
341 size -= chunk;
342 bdl[3] = size ? 0 : cpu_to_le32(0x01);
343 bdl += 4;
344 str->frags++;
345 ofs += chunk;
346 }
347 *bdlp = bdl;
348 return ofs;
349}
350
351/*
352 * set up BDL entries
353 */
354static int lola_setup_periods(struct lola *chip, struct lola_pcm *pcm,
355 struct snd_pcm_substream *substream,
356 struct lola_stream *str)
357{
358 u32 *bdl;
359 int i, ofs, periods, period_bytes;
360
361 period_bytes = str->period_bytes;
362 periods = str->bufsize / period_bytes;
363
364 /* program the initial BDL entries */
365 bdl = (u32 *)(pcm->bdl.area + LOLA_BDL_ENTRY_SIZE * str->index);
366 ofs = 0;
367 str->frags = 0;
368 for (i = 0; i < periods; i++) {
369 ofs = setup_bdle(substream, str, &bdl, ofs, period_bytes);
370 if (ofs < 0)
371 goto error;
372 }
373 return 0;
374
375 error:
376 snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n",
377 str->bufsize, period_bytes);
378 return -EINVAL;
379}
380
381static unsigned int lola_get_format_verb(struct snd_pcm_substream *substream)
382{
383 unsigned int verb;
384
385 switch (substream->runtime->format) {
386 case SNDRV_PCM_FORMAT_S16_LE:
387 verb = 0x00000000;
388 break;
389 case SNDRV_PCM_FORMAT_S24_LE:
390 verb = 0x00000200;
391 break;
392 case SNDRV_PCM_FORMAT_S32_LE:
393 verb = 0x00000300;
394 break;
395 case SNDRV_PCM_FORMAT_FLOAT_LE:
396 verb = 0x00001300;
397 break;
398 default:
399 return 0;
400 }
401 verb |= substream->runtime->channels;
402 return verb;
403}
404
405static int lola_set_stream_config(struct lola *chip,
406 struct lola_stream *str,
407 int channels)
408{
409 int i, err;
410 unsigned int verb, val;
411
412 /* set format info for all channels
413 * (with only one command for the first channel)
414 */
415 err = lola_codec_read(chip, str->nid, LOLA_VERB_SET_STREAM_FORMAT,
416 str->format_verb, 0, &val, NULL);
417 if (err < 0) {
418 printk(KERN_ERR SFX "Cannot set stream format 0x%x\n",
419 str->format_verb);
420 return err;
421 }
422
423 /* update stream - channel config */
424 for (i = 0; i < channels; i++) {
425 verb = (str->index << 6) | i;
426 err = lola_codec_read(chip, str[i].nid,
427 LOLA_VERB_SET_CHANNEL_STREAMID, 0, verb,
428 &val, NULL);
429 if (err < 0) {
430 printk(KERN_ERR SFX "Cannot set stream channel %d\n", i);
431 return err;
432 }
433 }
434 return 0;
435}
436
437/*
438 * set up the SD for streaming
439 */
440static int lola_setup_controller(struct lola *chip, struct lola_pcm *pcm,
441 struct lola_stream *str)
442{
443 dma_addr_t bdl;
444
445 if (str->prepared)
446 return -EINVAL;
447
448 /* set up BDL */
449 bdl = pcm->bdl.addr + LOLA_BDL_ENTRY_SIZE * str->index;
450 lola_dsd_write(chip, str->dsd, BDPL, (u32)bdl);
451 lola_dsd_write(chip, str->dsd, BDPU, upper_32_bits(bdl));
452 /* program the stream LVI (last valid index) of the BDL */
453 lola_dsd_write(chip, str->dsd, LVI, str->frags - 1);
454 lola_stream_clear_pending_irq(chip, str);
455
456 lola_dsd_write(chip, str->dsd, CTL,
457 LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE | LOLA_DSD_CTL_SRUN);
458
459 str->prepared = 1;
460
461 return lola_stream_wait_for_fifo(chip, str, true);
462}
463
464static int lola_pcm_prepare(struct snd_pcm_substream *substream)
465{
466 struct lola *chip = snd_pcm_substream_chip(substream);
467 struct lola_pcm *pcm = lola_get_pcm(substream);
468 struct lola_stream *str = lola_get_stream(substream);
469 struct snd_pcm_runtime *runtime = substream->runtime;
470 unsigned int bufsize, period_bytes, format_verb;
471 int i, err;
472
473 mutex_lock(&chip->open_mutex);
474 lola_stream_reset(chip, str);
475 lola_cleanup_slave_streams(pcm, str);
476 if (str->index + runtime->channels > pcm->num_streams) {
477 mutex_unlock(&chip->open_mutex);
478 return -EINVAL;
479 }
480 for (i = 1; i < runtime->channels; i++) {
481 str[i].master = str;
482 str[i].opened = 1;
483 }
484 mutex_unlock(&chip->open_mutex);
485
486 bufsize = snd_pcm_lib_buffer_bytes(substream);
487 period_bytes = snd_pcm_lib_period_bytes(substream);
488 format_verb = lola_get_format_verb(substream);
489
490 str->bufsize = bufsize;
491 str->period_bytes = period_bytes;
492 str->format_verb = format_verb;
493
494 err = lola_setup_periods(chip, pcm, substream, str);
495 if (err < 0)
496 return err;
497
498 err = lola_set_sample_rate(chip, runtime->rate);
499 if (err < 0)
500 return err;
501 chip->sample_rate = runtime->rate; /* sample rate gets locked */
502
503 err = lola_set_stream_config(chip, str, runtime->channels);
504 if (err < 0)
505 return err;
506
507 err = lola_setup_controller(chip, pcm, str);
508 if (err < 0) {
509 lola_stream_reset(chip, str);
510 return err;
511 }
512
513 return 0;
514}
515
516static int lola_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
517{
518 struct lola *chip = snd_pcm_substream_chip(substream);
519 struct lola_stream *str;
520 struct snd_pcm_substream *s;
521 unsigned int start;
522 unsigned int tstamp;
523 bool sync_streams;
524
525 switch (cmd) {
526 case SNDRV_PCM_TRIGGER_START:
527 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
528 case SNDRV_PCM_TRIGGER_RESUME:
529 start = 1;
530 break;
531 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
532 case SNDRV_PCM_TRIGGER_SUSPEND:
533 case SNDRV_PCM_TRIGGER_STOP:
534 start = 0;
535 break;
536 default:
537 return -EINVAL;
538 }
539
540 /*
541 * sample correct synchronization is only needed starting several
542 * streams. On stop or if only one stream do as quick as possible
543 */
544 sync_streams = (start && snd_pcm_stream_linked(substream));
545 tstamp = lola_get_tstamp(chip, !sync_streams);
546 spin_lock(&chip->reg_lock);
547 snd_pcm_group_for_each_entry(s, substream) {
548 if (s->pcm->card != substream->pcm->card)
549 continue;
550 str = lola_get_stream(s);
551 if (start)
552 lola_stream_start(chip, str, tstamp);
553 else
554 lola_stream_stop(chip, str, tstamp);
555 str->running = start;
556 str->paused = !start;
557 snd_pcm_trigger_done(s, substream);
558 }
559 spin_unlock(&chip->reg_lock);
560 return 0;
561}
562
563static snd_pcm_uframes_t lola_pcm_pointer(struct snd_pcm_substream *substream)
564{
565 struct lola *chip = snd_pcm_substream_chip(substream);
566 struct lola_stream *str = lola_get_stream(substream);
567 unsigned int pos = lola_dsd_read(chip, str->dsd, LPIB);
568
569 if (pos >= str->bufsize)
570 pos = 0;
571 return bytes_to_frames(substream->runtime, pos);
572}
573
574void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits)
575{
576 int i;
577
578 for (i = 0; bits && i < pcm->num_streams; i++) {
579 if (bits & (1 << i)) {
580 struct lola_stream *str = &pcm->streams[i];
581 if (str->substream && str->running)
582 snd_pcm_period_elapsed(str->substream);
583 bits &= ~(1 << i);
584 }
585 }
586}
587
588static struct snd_pcm_ops lola_pcm_ops = {
589 .open = lola_pcm_open,
590 .close = lola_pcm_close,
591 .ioctl = snd_pcm_lib_ioctl,
592 .hw_params = lola_pcm_hw_params,
593 .hw_free = lola_pcm_hw_free,
594 .prepare = lola_pcm_prepare,
595 .trigger = lola_pcm_trigger,
596 .pointer = lola_pcm_pointer,
597 .page = snd_pcm_sgbuf_ops_page,
598};
599
600int __devinit lola_create_pcm(struct lola *chip)
601{
602 struct snd_pcm *pcm;
603 int i, err;
604
605 for (i = 0; i < 2; i++) {
606 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
607 snd_dma_pci_data(chip->pci),
608 PAGE_SIZE, &chip->pcm[i].bdl);
609 if (err < 0)
610 return err;
611 }
612
613 err = snd_pcm_new(chip->card, "Digigram Lola", 0,
614 chip->pcm[SNDRV_PCM_STREAM_PLAYBACK].num_streams,
615 chip->pcm[SNDRV_PCM_STREAM_CAPTURE].num_streams,
616 &pcm);
617 if (err < 0)
618 return err;
619 strlcpy(pcm->name, "Digigram Lola", sizeof(pcm->name));
620 pcm->private_data = chip;
621 for (i = 0; i < 2; i++) {
622 if (chip->pcm[i].num_streams)
623 snd_pcm_set_ops(pcm, i, &lola_pcm_ops);
624 }
625 /* buffer pre-allocation */
626 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
627 snd_dma_pci_data(chip->pci),
628 1024 * 64, 32 * 1024 * 1024);
629 return 0;
630}
631
632void lola_free_pcm(struct lola *chip)
633{
634 snd_dma_free_pages(&chip->pcm[0].bdl);
635 snd_dma_free_pages(&chip->pcm[1].bdl);
636}
637
638/*
639 */
640
641static int lola_init_stream(struct lola *chip, struct lola_stream *str,
642 int idx, int nid, int dir)
643{
644 unsigned int val;
645 int err;
646
647 str->nid = nid;
648 str->index = idx;
649 str->dsd = idx;
650 if (dir == PLAY)
651 str->dsd += MAX_STREAM_IN_COUNT;
652 err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
653 if (err < 0) {
654 printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid);
655 return err;
656 }
657 if (dir == PLAY) {
658 /* test TYPE and bits 0..11 (no test bit9 : Digital = 0/1) */
659 if ((val & 0x00f00dff) != 0x00000010) {
660 printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n",
661 val, nid);
662 return -EINVAL;
663 }
664 } else {
665 /* test TYPE and bits 0..11 (no test bit9 : Digital = 0/1)
666 * (bug : ignore bit8: Conn list = 0/1)
667 */
668 if ((val & 0x00f00cff) != 0x00100010) {
669 printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n",
670 val, nid);
671 return -EINVAL;
672 }
673 /* test bit9:DIGITAL and bit12:SRC_PRESENT*/
674 if ((val & 0x00001200) == 0x00001200)
675 chip->input_src_caps_mask |= (1 << idx);
676 }
677
678 err = lola_read_param(chip, nid, LOLA_PAR_STREAM_FORMATS, &val);
679 if (err < 0) {
680 printk(KERN_ERR SFX "Can't read FORMATS 0x%x\n", nid);
681 return err;
682 }
683 val &= 3;
684 if (val == 3)
685 str->can_float = true;
686 if (!(val & 1)) {
687 printk(KERN_ERR SFX "Invalid formats 0x%x for 0x%x", val, nid);
688 return -EINVAL;
689 }
690 return 0;
691}
692
693int __devinit lola_init_pcm(struct lola *chip, int dir, int *nidp)
694{
695 struct lola_pcm *pcm = &chip->pcm[dir];
696 int i, nid, err;
697
698 nid = *nidp;
699 for (i = 0; i < pcm->num_streams; i++, nid++) {
700 err = lola_init_stream(chip, &pcm->streams[i], i, nid, dir);
701 if (err < 0)
702 return err;
703 }
704 *nidp = nid;
705 return 0;
706}
diff --git a/sound/pci/lola/lola_proc.c b/sound/pci/lola/lola_proc.c
new file mode 100644
index 000000000000..9d7daf897c9d
--- /dev/null
+++ b/sound/pci/lola/lola_proc.c
@@ -0,0 +1,222 @@
1/*
2 * Support for Digigram Lola PCI-e boards
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59
18 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/io.h>
24#include <sound/core.h>
25#include <sound/info.h>
26#include <sound/pcm.h>
27#include "lola.h"
28
29static void print_audio_widget(struct snd_info_buffer *buffer,
30 struct lola *chip, int nid, const char *name)
31{
32 unsigned int val;
33
34 lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
35 snd_iprintf(buffer, "Node 0x%02x %s wcaps 0x%x\n", nid, name, val);
36 lola_read_param(chip, nid, LOLA_PAR_STREAM_FORMATS, &val);
37 snd_iprintf(buffer, " Formats: 0x%x\n", val);
38}
39
40static void print_pin_widget(struct snd_info_buffer *buffer,
41 struct lola *chip, int nid, unsigned int ampcap,
42 const char *name)
43{
44 unsigned int val;
45
46 lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
47 snd_iprintf(buffer, "Node 0x%02x %s wcaps 0x%x\n", nid, name, val);
48 if (val == 0x00400200)
49 return;
50 lola_read_param(chip, nid, ampcap, &val);
51 snd_iprintf(buffer, " Amp-Caps: 0x%x\n", val);
52 snd_iprintf(buffer, " mute=%d, step-size=%d, steps=%d, ofs=%d\n",
53 LOLA_AMP_MUTE_CAPABLE(val),
54 LOLA_AMP_STEP_SIZE(val),
55 LOLA_AMP_NUM_STEPS(val),
56 LOLA_AMP_OFFSET(val));
57 lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val, NULL);
58 snd_iprintf(buffer, " Max-level: 0x%x\n", val);
59}
60
61static void print_clock_widget(struct snd_info_buffer *buffer,
62 struct lola *chip, int nid)
63{
64 int i, j, num_clocks;
65 unsigned int val;
66
67 lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
68 snd_iprintf(buffer, "Node 0x%02x [Clock] wcaps 0x%x\n", nid, val);
69 num_clocks = val & 0xff;
70 for (i = 0; i < num_clocks; i += 4) {
71 unsigned int res_ex;
72 unsigned short items[4];
73 const char *name;
74
75 lola_codec_read(chip, nid, LOLA_VERB_GET_CLOCK_LIST,
76 i, 0, &val, &res_ex);
77 items[0] = val & 0xfff;
78 items[1] = (val >> 16) & 0xfff;
79 items[2] = res_ex & 0xfff;
80 items[3] = (res_ex >> 16) & 0xfff;
81 for (j = 0; j < 4; j++) {
82 unsigned char type = items[j] >> 8;
83 unsigned int freq = items[j] & 0xff;
84 if (i + j >= num_clocks)
85 break;
86 if (type == LOLA_CLOCK_TYPE_INTERNAL) {
87 name = "Internal";
88 freq = lola_sample_rate_convert(freq);
89 } else if (type == LOLA_CLOCK_TYPE_VIDEO) {
90 name = "Video";
91 freq = lola_sample_rate_convert(freq);
92 } else {
93 name = "Other";
94 }
95 snd_iprintf(buffer, " Clock %d: Type %d:%s, freq=%d\n",
96 i + j, type, name, freq);
97 }
98 }
99}
100
101static void print_mixer_widget(struct snd_info_buffer *buffer,
102 struct lola *chip, int nid)
103{
104 unsigned int val;
105
106 lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
107 snd_iprintf(buffer, "Node 0x%02x [Mixer] wcaps 0x%x\n", nid, val);
108}
109
110static void lola_proc_codec_read(struct snd_info_entry *entry,
111 struct snd_info_buffer *buffer)
112{
113 struct lola *chip = entry->private_data;
114 unsigned int val;
115 int i, nid;
116
117 lola_read_param(chip, 0, LOLA_PAR_VENDOR_ID, &val);
118 snd_iprintf(buffer, "Vendor: 0x%08x\n", val);
119 lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val);
120 snd_iprintf(buffer, "Function Type: %d\n", val);
121 lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val);
122 snd_iprintf(buffer, "Specific-Caps: 0x%08x\n", val);
123 snd_iprintf(buffer, " Pins-In %d, Pins-Out %d\n",
124 chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins);
125 nid = 2;
126 for (i = 0; i < chip->pcm[CAPT].num_streams; i++, nid++)
127 print_audio_widget(buffer, chip, nid, "[Audio-In]");
128 for (i = 0; i < chip->pcm[PLAY].num_streams; i++, nid++)
129 print_audio_widget(buffer, chip, nid, "[Audio-Out]");
130 for (i = 0; i < chip->pin[CAPT].num_pins; i++, nid++)
131 print_pin_widget(buffer, chip, nid, LOLA_PAR_AMP_IN_CAP,
132 "[Pin-In]");
133 for (i = 0; i < chip->pin[PLAY].num_pins; i++, nid++)
134 print_pin_widget(buffer, chip, nid, LOLA_PAR_AMP_OUT_CAP,
135 "[Pin-Out]");
136 if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) {
137 print_clock_widget(buffer, chip, nid);
138 nid++;
139 }
140 if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) {
141 print_mixer_widget(buffer, chip, nid);
142 nid++;
143 }
144}
145
146/* direct codec access for debugging */
147static void lola_proc_codec_rw_write(struct snd_info_entry *entry,
148 struct snd_info_buffer *buffer)
149{
150 struct lola *chip = entry->private_data;
151 char line[64];
152 unsigned int id, verb, data, extdata;
153 while (!snd_info_get_line(buffer, line, sizeof(line))) {
154 if (sscanf(line, "%i %i %i %i", &id, &verb, &data, &extdata) != 4)
155 continue;
156 lola_codec_read(chip, id, verb, data, extdata,
157 &chip->debug_res,
158 &chip->debug_res_ex);
159 }
160}
161
162static void lola_proc_codec_rw_read(struct snd_info_entry *entry,
163 struct snd_info_buffer *buffer)
164{
165 struct lola *chip = entry->private_data;
166 snd_iprintf(buffer, "0x%x 0x%x\n", chip->debug_res, chip->debug_res_ex);
167}
168
169/*
170 * dump some registers
171 */
172static void lola_proc_regs_read(struct snd_info_entry *entry,
173 struct snd_info_buffer *buffer)
174{
175 struct lola *chip = entry->private_data;
176 int i;
177
178 for (i = 0; i < 0x40; i += 4) {
179 snd_iprintf(buffer, "BAR0 %02x: %08x\n", i,
180 readl(chip->bar[BAR0].remap_addr + i));
181 }
182 snd_iprintf(buffer, "\n");
183 for (i = 0; i < 0x30; i += 4) {
184 snd_iprintf(buffer, "BAR1 %02x: %08x\n", i,
185 readl(chip->bar[BAR1].remap_addr + i));
186 }
187 snd_iprintf(buffer, "\n");
188 for (i = 0x80; i < 0xa0; i += 4) {
189 snd_iprintf(buffer, "BAR1 %02x: %08x\n", i,
190 readl(chip->bar[BAR1].remap_addr + i));
191 }
192 snd_iprintf(buffer, "\n");
193 for (i = 0; i < 32; i++) {
194 snd_iprintf(buffer, "DSD %02x STS %08x\n", i,
195 lola_dsd_read(chip, i, STS));
196 snd_iprintf(buffer, "DSD %02x LPIB %08x\n", i,
197 lola_dsd_read(chip, i, LPIB));
198 snd_iprintf(buffer, "DSD %02x CTL %08x\n", i,
199 lola_dsd_read(chip, i, CTL));
200 snd_iprintf(buffer, "DSD %02x LVIL %08x\n", i,
201 lola_dsd_read(chip, i, LVI));
202 snd_iprintf(buffer, "DSD %02x BDPL %08x\n", i,
203 lola_dsd_read(chip, i, BDPL));
204 snd_iprintf(buffer, "DSD %02x BDPU %08x\n", i,
205 lola_dsd_read(chip, i, BDPU));
206 }
207}
208
209void __devinit lola_proc_debug_new(struct lola *chip)
210{
211 struct snd_info_entry *entry;
212
213 if (!snd_card_proc_new(chip->card, "codec", &entry))
214 snd_info_set_text_ops(entry, chip, lola_proc_codec_read);
215 if (!snd_card_proc_new(chip->card, "codec_rw", &entry)) {
216 snd_info_set_text_ops(entry, chip, lola_proc_codec_rw_read);
217 entry->mode |= S_IWUSR;
218 entry->c.text.write = lola_proc_codec_rw_write;
219 }
220 if (!snd_card_proc_new(chip->card, "regs", &entry))
221 snd_info_set_text_ops(entry, chip, lola_proc_regs_read);
222}
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 961d98297695..9cea84c3e0c6 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -1000,7 +1000,7 @@ static void device_change_handler(struct work_struct *work)
1000 chip->lineout_sw_ctl); 1000 chip->lineout_sw_ctl);
1001 if (mix->anded_reset) 1001 if (mix->anded_reset)
1002 msleep(10); 1002 msleep(10);
1003 check_mute(chip, &mix->amp_mute, 1, mix->auto_mute_notify, 1003 check_mute(chip, &mix->amp_mute, !IS_G4DA, mix->auto_mute_notify,
1004 chip->speaker_sw_ctl); 1004 chip->speaker_sw_ctl);
1005 } else { 1005 } else {
1006 /* unmute speaker, mute others */ 1006 /* unmute speaker, mute others */
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index af3c73053ee4..28afbbf69ce0 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -184,7 +184,7 @@ static struct snd_soc_dai_link at91sam9g20ek_dai = {
184 .codec_dai_name = "wm8731-hifi", 184 .codec_dai_name = "wm8731-hifi",
185 .init = at91sam9g20ek_wm8731_init, 185 .init = at91sam9g20ek_wm8731_init,
186 .platform_name = "atmel-pcm-audio", 186 .platform_name = "atmel-pcm-audio",
187 .codec_name = "wm8731-codec.0-001b", 187 .codec_name = "wm8731.0-001b",
188 .ops = &at91sam9g20ek_ops, 188 .ops = &at91sam9g20ek_ops,
189}; 189};
190 190
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index cb99f04abe88..1d3e258c9ea8 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -77,7 +77,7 @@ static struct snd_soc_dai_link db1200_i2s_dai = {
77 .codec_dai_name = "wm8731-hifi", 77 .codec_dai_name = "wm8731-hifi",
78 .cpu_dai_name = "au1xpsc_i2s.1", 78 .cpu_dai_name = "au1xpsc_i2s.1",
79 .platform_name = "au1xpsc-pcm.1", 79 .platform_name = "au1xpsc-pcm.1",
80 .codec_name = "wm8731-codec.0-001b", 80 .codec_name = "wm8731.0-001b",
81 .ops = &db1200_i2s_wm8731_ops, 81 .ops = &db1200_i2s_wm8731_ops,
82}; 82};
83 83
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 5a2fd8abaefa..98b44b316e78 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -243,6 +243,9 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
243 243
244static int bf5xx_pcm_open(struct snd_pcm_substream *substream) 244static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
245{ 245{
246 struct snd_soc_pcm_runtime *rtd = substream->private_data;
247 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
248 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
246 struct snd_pcm_runtime *runtime = substream->runtime; 249 struct snd_pcm_runtime *runtime = substream->runtime;
247 int ret; 250 int ret;
248 251
@@ -314,6 +317,9 @@ static struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
314 317
315static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) 318static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
316{ 319{
320 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
321 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
322 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
317 struct snd_pcm_substream *substream = pcm->streams[stream].substream; 323 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
318 struct snd_dma_buffer *buf = &substream->dma_buffer; 324 struct snd_dma_buffer *buf = &substream->dma_buffer;
319 size_t size = bf5xx_pcm_hardware.buffer_bytes_max 325 size_t size = bf5xx_pcm_hardware.buffer_bytes_max
@@ -377,6 +383,9 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
377 struct snd_dma_buffer *buf; 383 struct snd_dma_buffer *buf;
378 int stream; 384 int stream;
379#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT) 385#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
386 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
387 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
388 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
380 size_t size = bf5xx_pcm_hardware.buffer_bytes_max * 389 size_t size = bf5xx_pcm_hardware.buffer_bytes_max *
381 sizeof(struct ac97_frame) / 4; 390 sizeof(struct ac97_frame) / 4;
382#endif 391#endif
@@ -405,8 +414,6 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
405 } 414 }
406#endif 415#endif
407 } 416 }
408 if (sport_handle)
409 sport_done(sport_handle);
410} 417}
411 418
412static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); 419static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
@@ -458,7 +465,7 @@ static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
458 465
459static struct platform_driver bf5xx_pcm_driver = { 466static struct platform_driver bf5xx_pcm_driver = {
460 .driver = { 467 .driver = {
461 .name = "bf5xx-pcm-audio", 468 .name = "bfin-ac97-pcm-audio",
462 .owner = THIS_MODULE, 469 .owner = THIS_MODULE,
463 }, 470 },
464 471
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index ffbac26b9bce..6d2162590889 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -41,48 +41,7 @@
41 * anomaly does not affect blackfin sound drivers. 41 * anomaly does not affect blackfin sound drivers.
42*/ 42*/
43 43
44static int *cmd_count; 44static struct sport_device *ac97_sport_handle;
45static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
46
47#define SPORT_REQ(x) \
48 [x] = {P_SPORT##x##_TFS, P_SPORT##x##_DTPRI, P_SPORT##x##_TSCLK, \
49 P_SPORT##x##_RFS, P_SPORT##x##_DRPRI, P_SPORT##x##_RSCLK, 0}
50static u16 sport_req[][7] = {
51#ifdef SPORT0_TCR1
52 SPORT_REQ(0),
53#endif
54#ifdef SPORT1_TCR1
55 SPORT_REQ(1),
56#endif
57#ifdef SPORT2_TCR1
58 SPORT_REQ(2),
59#endif
60#ifdef SPORT3_TCR1
61 SPORT_REQ(3),
62#endif
63};
64
65#define SPORT_PARAMS(x) \
66 [x] = { \
67 .dma_rx_chan = CH_SPORT##x##_RX, \
68 .dma_tx_chan = CH_SPORT##x##_TX, \
69 .err_irq = IRQ_SPORT##x##_ERROR, \
70 .regs = (struct sport_register *)SPORT##x##_TCR1, \
71 }
72static struct sport_param sport_params[4] = {
73#ifdef SPORT0_TCR1
74 SPORT_PARAMS(0),
75#endif
76#ifdef SPORT1_TCR1
77 SPORT_PARAMS(1),
78#endif
79#ifdef SPORT2_TCR1
80 SPORT_PARAMS(2),
81#endif
82#ifdef SPORT3_TCR1
83 SPORT_PARAMS(3),
84#endif
85};
86 45
87void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src, 46void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src,
88 size_t count, unsigned int chan_mask) 47 size_t count, unsigned int chan_mask)
@@ -140,7 +99,8 @@ static unsigned int sport_tx_curr_frag(struct sport_device *sport)
140 99
141static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data) 100static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
142{ 101{
143 struct sport_device *sport = sport_handle; 102 struct sport_device *sport = ac97_sport_handle;
103 int *cmd_count = sport->private_data;
144 int nextfrag = sport_tx_curr_frag(sport); 104 int nextfrag = sport_tx_curr_frag(sport);
145 struct ac97_frame *nextwrite; 105 struct ac97_frame *nextwrite;
146 106
@@ -161,6 +121,7 @@ static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
161static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97, 121static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97,
162 unsigned short reg) 122 unsigned short reg)
163{ 123{
124 struct sport_device *sport_handle = ac97_sport_handle;
164 struct ac97_frame out_frame[2], in_frame[2]; 125 struct ac97_frame out_frame[2], in_frame[2];
165 126
166 pr_debug("%s enter 0x%x\n", __func__, reg); 127 pr_debug("%s enter 0x%x\n", __func__, reg);
@@ -185,6 +146,8 @@ static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97,
185void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, 146void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
186 unsigned short val) 147 unsigned short val)
187{ 148{
149 struct sport_device *sport_handle = ac97_sport_handle;
150
188 pr_debug("%s enter 0x%x:0x%04x\n", __func__, reg, val); 151 pr_debug("%s enter 0x%x:0x%04x\n", __func__, reg, val);
189 152
190 if (sport_handle->tx_run) { 153 if (sport_handle->tx_run) {
@@ -203,28 +166,19 @@ void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
203 166
204static void bf5xx_ac97_warm_reset(struct snd_ac97 *ac97) 167static void bf5xx_ac97_warm_reset(struct snd_ac97 *ac97)
205{ 168{
206#if defined(CONFIG_BF54x) || defined(CONFIG_BF561) || \ 169 struct sport_device *sport_handle = ac97_sport_handle;
207 (defined(BF537_FAMILY) && (CONFIG_SND_BF5XX_SPORT_NUM == 1)) 170 u16 gpio = P_IDENT(sport_handle->pin_req[3]);
208
209#define CONCAT(a, b, c) a ## b ## c
210#define BFIN_SPORT_RFS(x) CONCAT(P_SPORT, x, _RFS)
211
212 u16 per = BFIN_SPORT_RFS(CONFIG_SND_BF5XX_SPORT_NUM);
213 u16 gpio = P_IDENT(BFIN_SPORT_RFS(CONFIG_SND_BF5XX_SPORT_NUM));
214 171
215 pr_debug("%s enter\n", __func__); 172 pr_debug("%s enter\n", __func__);
216 173
217 peripheral_free(per); 174 peripheral_free_list(sport_handle->pin_req);
218 gpio_request(gpio, "bf5xx-ac97"); 175 gpio_request(gpio, "bf5xx-ac97");
219 gpio_direction_output(gpio, 1); 176 gpio_direction_output(gpio, 1);
220 udelay(2); 177 udelay(2);
221 gpio_set_value(gpio, 0); 178 gpio_set_value(gpio, 0);
222 udelay(1); 179 udelay(1);
223 gpio_free(gpio); 180 gpio_free(gpio);
224 peripheral_request(per, "soc-audio"); 181 peripheral_request_list(sport_handle->pin_req, "soc-audio");
225#else
226 pr_info("%s: Not implemented\n", __func__);
227#endif
228} 182}
229 183
230static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97) 184static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97)
@@ -306,18 +260,32 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
306#define bf5xx_ac97_resume NULL 260#define bf5xx_ac97_resume NULL
307#endif 261#endif
308 262
309static int bf5xx_ac97_probe(struct snd_soc_dai *dai) 263static struct snd_soc_dai_driver bfin_ac97_dai = {
264 .ac97_control = 1,
265 .suspend = bf5xx_ac97_suspend,
266 .resume = bf5xx_ac97_resume,
267 .playback = {
268 .stream_name = "AC97 Playback",
269 .channels_min = 2,
270#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
271 .channels_max = 6,
272#else
273 .channels_max = 2,
274#endif
275 .rates = SNDRV_PCM_RATE_48000,
276 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
277 .capture = {
278 .stream_name = "AC97 Capture",
279 .channels_min = 2,
280 .channels_max = 2,
281 .rates = SNDRV_PCM_RATE_48000,
282 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
283};
284
285static int __devinit asoc_bfin_ac97_probe(struct platform_device *pdev)
310{ 286{
311 int ret = 0; 287 struct sport_device *sport_handle;
312 cmd_count = (int *)get_zeroed_page(GFP_KERNEL); 288 int ret;
313 if (cmd_count == NULL)
314 return -ENOMEM;
315
316 if (peripheral_request_list(sport_req[sport_num], "soc-audio")) {
317 pr_err("Requesting Peripherals failed\n");
318 ret = -EFAULT;
319 goto peripheral_err;
320 }
321 289
322#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 290#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
323 /* Request PB3 as reset pin */ 291 /* Request PB3 as reset pin */
@@ -329,12 +297,14 @@ static int bf5xx_ac97_probe(struct snd_soc_dai *dai)
329 } 297 }
330 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1); 298 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
331#endif 299#endif
332 sport_handle = sport_init(&sport_params[sport_num], 2, \ 300
333 sizeof(struct ac97_frame), NULL); 301 sport_handle = sport_init(pdev, 2, sizeof(struct ac97_frame),
302 PAGE_SIZE);
334 if (!sport_handle) { 303 if (!sport_handle) {
335 ret = -ENODEV; 304 ret = -ENODEV;
336 goto sport_err; 305 goto sport_err;
337 } 306 }
307
338 /*SPORT works in TDM mode to simulate AC97 transfers*/ 308 /*SPORT works in TDM mode to simulate AC97 transfers*/
339#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT) 309#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
340 ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1); 310 ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1);
@@ -361,67 +331,37 @@ static int bf5xx_ac97_probe(struct snd_soc_dai *dai)
361 goto sport_config_err; 331 goto sport_config_err;
362 } 332 }
363 333
334 ret = snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai);
335 if (ret) {
336 pr_err("Failed to register DAI: %d\n", ret);
337 goto sport_config_err;
338 }
339
340 ac97_sport_handle = sport_handle;
341
364 return 0; 342 return 0;
365 343
366sport_config_err: 344sport_config_err:
367 kfree(sport_handle); 345 sport_done(sport_handle);
368sport_err: 346sport_err:
369#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 347#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
370 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); 348 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
371gpio_err: 349gpio_err:
372#endif 350#endif
373 peripheral_free_list(sport_req[sport_num]);
374peripheral_err:
375 free_page((unsigned long)cmd_count);
376 cmd_count = NULL;
377 351
378 return ret; 352 return ret;
379} 353}
380 354
381static int bf5xx_ac97_remove(struct snd_soc_dai *dai) 355static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev)
382{ 356{
383 free_page((unsigned long)cmd_count); 357 struct sport_device *sport_handle = platform_get_drvdata(pdev);
384 cmd_count = NULL; 358
385 peripheral_free_list(sport_req[sport_num]); 359 snd_soc_unregister_dai(&pdev->dev);
360 sport_done(sport_handle);
386#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 361#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
387 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); 362 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
388#endif 363#endif
389 return 0;
390}
391
392struct snd_soc_dai_driver bfin_ac97_dai = {
393 .ac97_control = 1,
394 .probe = bf5xx_ac97_probe,
395 .remove = bf5xx_ac97_remove,
396 .suspend = bf5xx_ac97_suspend,
397 .resume = bf5xx_ac97_resume,
398 .playback = {
399 .stream_name = "AC97 Playback",
400 .channels_min = 2,
401#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
402 .channels_max = 6,
403#else
404 .channels_max = 2,
405#endif
406 .rates = SNDRV_PCM_RATE_48000,
407 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
408 .capture = {
409 .stream_name = "AC97 Capture",
410 .channels_min = 2,
411 .channels_max = 2,
412 .rates = SNDRV_PCM_RATE_48000,
413 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
414};
415EXPORT_SYMBOL_GPL(bfin_ac97_dai);
416
417static __devinit int asoc_bfin_ac97_probe(struct platform_device *pdev)
418{
419 return snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai);
420}
421 364
422static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev)
423{
424 snd_soc_unregister_dai(&pdev->dev);
425 return 0; 365 return 0;
426} 366}
427 367
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index 83012da9dfc2..ea4951cf5526 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -29,22 +29,12 @@
29#include <asm/portmux.h> 29#include <asm/portmux.h>
30 30
31#include "../codecs/ad1836.h" 31#include "../codecs/ad1836.h"
32#include "bf5xx-sport.h"
33 32
34#include "bf5xx-tdm-pcm.h" 33#include "bf5xx-tdm-pcm.h"
35#include "bf5xx-tdm.h" 34#include "bf5xx-tdm.h"
36 35
37static struct snd_soc_card bf5xx_ad1836; 36static struct snd_soc_card bf5xx_ad1836;
38 37
39static int bf5xx_ad1836_startup(struct snd_pcm_substream *substream)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
43
44 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
45 return 0;
46}
47
48static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream, 38static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
49 struct snd_pcm_hw_params *params) 39 struct snd_pcm_hw_params *params)
50{ 40{
@@ -75,23 +65,33 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
75} 65}
76 66
77static struct snd_soc_ops bf5xx_ad1836_ops = { 67static struct snd_soc_ops bf5xx_ad1836_ops = {
78 .startup = bf5xx_ad1836_startup,
79 .hw_params = bf5xx_ad1836_hw_params, 68 .hw_params = bf5xx_ad1836_hw_params,
80}; 69};
81 70
82static struct snd_soc_dai_link bf5xx_ad1836_dai = { 71static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
83 .name = "ad1836", 72 {
84 .stream_name = "AD1836", 73 .name = "ad1836",
85 .cpu_dai_name = "bf5xx-tdm", 74 .stream_name = "AD1836",
86 .codec_dai_name = "ad1836-hifi", 75 .cpu_dai_name = "bfin-tdm.0",
87 .platform_name = "bf5xx-tdm-pcm-audio", 76 .codec_dai_name = "ad1836-hifi",
88 .codec_name = "ad1836-codec.0", 77 .platform_name = "bfin-tdm-pcm-audio",
89 .ops = &bf5xx_ad1836_ops, 78 .codec_name = "ad1836.0",
79 .ops = &bf5xx_ad1836_ops,
80 },
81 {
82 .name = "ad1836",
83 .stream_name = "AD1836",
84 .cpu_dai_name = "bfin-tdm.1",
85 .codec_dai_name = "ad1836-hifi",
86 .platform_name = "bfin-tdm-pcm-audio",
87 .codec_name = "ad1836.0",
88 .ops = &bf5xx_ad1836_ops,
89 },
90}; 90};
91 91
92static struct snd_soc_card bf5xx_ad1836 = { 92static struct snd_soc_card bf5xx_ad1836 = {
93 .name = "bf5xx_ad1836", 93 .name = "bfin-ad1836",
94 .dai_link = &bf5xx_ad1836_dai, 94 .dai_link = &bf5xx_ad1836_dai[CONFIG_SND_BF5XX_SPORT_NUM],
95 .num_links = 1, 95 .num_links = 1,
96}; 96};
97 97
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
index d3ccb926b5e4..d6651c033cb7 100644
--- a/sound/soc/blackfin/bf5xx-ad193x.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -38,30 +38,28 @@
38#include <asm/portmux.h> 38#include <asm/portmux.h>
39 39
40#include "../codecs/ad193x.h" 40#include "../codecs/ad193x.h"
41#include "bf5xx-sport.h"
42 41
43#include "bf5xx-tdm-pcm.h" 42#include "bf5xx-tdm-pcm.h"
44#include "bf5xx-tdm.h" 43#include "bf5xx-tdm.h"
45 44
46static struct snd_soc_card bf5xx_ad193x; 45static struct snd_soc_card bf5xx_ad193x;
47 46
48static int bf5xx_ad193x_startup(struct snd_pcm_substream *substream)
49{
50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
51 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
52
53 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
54 return 0;
55}
56
57static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream, 47static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
58 struct snd_pcm_hw_params *params) 48 struct snd_pcm_hw_params *params)
59{ 49{
60 struct snd_soc_pcm_runtime *rtd = substream->private_data; 50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
61 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 51 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
62 struct snd_soc_dai *codec_dai = rtd->codec_dai; 52 struct snd_soc_dai *codec_dai = rtd->codec_dai;
53 unsigned int clk = 0;
63 unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7}; 54 unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7};
64 int ret = 0; 55 int ret = 0;
56
57 switch (params_rate(params)) {
58 case 48000:
59 clk = 12288000;
60 break;
61 }
62
65 /* set cpu DAI configuration */ 63 /* set cpu DAI configuration */
66 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | 64 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
67 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); 65 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
@@ -74,6 +72,12 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
74 if (ret < 0) 72 if (ret < 0)
75 return ret; 73 return ret;
76 74
75 /* set the codec system clock for DAC and ADC */
76 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
77 SND_SOC_CLOCK_IN);
78 if (ret < 0)
79 return ret;
80
77 /* set codec DAI slots, 8 channels, all channels are enabled */ 81 /* set codec DAI slots, 8 channels, all channels are enabled */
78 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 0xFF, 8, 32); 82 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 0xFF, 8, 32);
79 if (ret < 0) 83 if (ret < 0)
@@ -89,23 +93,33 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
89} 93}
90 94
91static struct snd_soc_ops bf5xx_ad193x_ops = { 95static struct snd_soc_ops bf5xx_ad193x_ops = {
92 .startup = bf5xx_ad193x_startup,
93 .hw_params = bf5xx_ad193x_hw_params, 96 .hw_params = bf5xx_ad193x_hw_params,
94}; 97};
95 98
96static struct snd_soc_dai_link bf5xx_ad193x_dai = { 99static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
97 .name = "ad193x", 100 {
98 .stream_name = "AD193X", 101 .name = "ad193x",
99 .cpu_dai_name = "bf5xx-tdm", 102 .stream_name = "AD193X",
100 .codec_dai_name ="ad193x-hifi", 103 .cpu_dai_name = "bfin-tdm.0",
101 .platform_name = "bf5xx-tdm-pcm-audio", 104 .codec_dai_name ="ad193x-hifi",
102 .codec_name = "ad193x-codec.5", 105 .platform_name = "bfin-tdm-pcm-audio",
103 .ops = &bf5xx_ad193x_ops, 106 .codec_name = "ad193x.5",
107 .ops = &bf5xx_ad193x_ops,
108 },
109 {
110 .name = "ad193x",
111 .stream_name = "AD193X",
112 .cpu_dai_name = "bfin-tdm.1",
113 .codec_dai_name ="ad193x-hifi",
114 .platform_name = "bfin-tdm-pcm-audio",
115 .codec_name = "ad193x.5",
116 .ops = &bf5xx_ad193x_ops,
117 },
104}; 118};
105 119
106static struct snd_soc_card bf5xx_ad193x = { 120static struct snd_soc_card bf5xx_ad193x = {
107 .name = "bf5xx_ad193x", 121 .name = "bfin-ad193x",
108 .dai_link = &bf5xx_ad193x_dai, 122 .dai_link = &bf5xx_ad193x_dai[CONFIG_SND_BF5XX_SPORT_NUM],
109 .num_links = 1, 123 .num_links = 1,
110}; 124};
111 125
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c
index d57c9c9c9883..06a84b211b52 100644
--- a/sound/soc/blackfin/bf5xx-ad1980.c
+++ b/sound/soc/blackfin/bf5xx-ad1980.c
@@ -47,39 +47,34 @@
47#include <asm/portmux.h> 47#include <asm/portmux.h>
48 48
49#include "../codecs/ad1980.h" 49#include "../codecs/ad1980.h"
50#include "bf5xx-sport.h" 50
51#include "bf5xx-ac97-pcm.h" 51#include "bf5xx-ac97-pcm.h"
52#include "bf5xx-ac97.h" 52#include "bf5xx-ac97.h"
53 53
54static struct snd_soc_card bf5xx_board; 54static struct snd_soc_card bf5xx_board;
55 55
56static int bf5xx_board_startup(struct snd_pcm_substream *substream) 56static struct snd_soc_dai_link bf5xx_board_dai[] = {
57{ 57 {
58 struct snd_soc_pcm_runtime *rtd = substream->private_data; 58 .name = "AC97",
59 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 59 .stream_name = "AC97 HiFi",
60 60 .cpu_dai_name = "bfin-ac97.0",
61 pr_debug("%s enter\n", __func__); 61 .codec_dai_name = "ad1980-hifi",
62 snd_soc_dai_set_drvdata(cpu_dai, sport_handle); 62 .platform_name = "bfin-ac97-pcm-audio",
63 return 0; 63 .codec_name = "ad1980",
64} 64 },
65 65 {
66static struct snd_soc_ops bf5xx_board_ops = { 66 .name = "AC97",
67 .startup = bf5xx_board_startup, 67 .stream_name = "AC97 HiFi",
68}; 68 .cpu_dai_name = "bfin-ac97.1",
69 69 .codec_dai_name = "ad1980-hifi",
70static struct snd_soc_dai_link bf5xx_board_dai = { 70 .platform_name = "bfin-ac97-pcm-audio",
71 .name = "AC97", 71 .codec_name = "ad1980",
72 .stream_name = "AC97 HiFi", 72 },
73 .cpu_dai_name = "bfin-ac97",
74 .codec_dai_name = "ad1980-hifi",
75 .platform_name = "bfin-pcm-audio",
76 .codec_name = "ad1980-codec",
77 .ops = &bf5xx_board_ops,
78}; 73};
79 74
80static struct snd_soc_card bf5xx_board = { 75static struct snd_soc_card bf5xx_board = {
81 .name = "bf5xx-board", 76 .name = "bfin-ad1980",
82 .dai_link = &bf5xx_board_dai, 77 .dai_link = &bf5xx_board_dai[CONFIG_SND_BF5XX_SPORT_NUM],
83 .num_links = 1, 78 .num_links = 1,
84}; 79};
85 80
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 732fb8bad076..732a247f2527 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -145,16 +145,6 @@ static int bf5xx_probe(struct platform_device *pdev)
145 return 0; 145 return 0;
146} 146}
147 147
148static int bf5xx_ad73311_startup(struct snd_pcm_substream *substream)
149{
150 struct snd_soc_pcm_runtime *rtd = substream->private_data;
151 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
152
153 pr_debug("%s enter\n", __func__);
154 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
155 return 0;
156}
157
158static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream, 148static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
159 struct snd_pcm_hw_params *params) 149 struct snd_pcm_hw_params *params)
160{ 150{
@@ -176,24 +166,34 @@ static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
176 166
177 167
178static struct snd_soc_ops bf5xx_ad73311_ops = { 168static struct snd_soc_ops bf5xx_ad73311_ops = {
179 .startup = bf5xx_ad73311_startup,
180 .hw_params = bf5xx_ad73311_hw_params, 169 .hw_params = bf5xx_ad73311_hw_params,
181}; 170};
182 171
183static struct snd_soc_dai_link bf5xx_ad73311_dai = { 172static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
184 .name = "ad73311", 173 {
185 .stream_name = "AD73311", 174 .name = "ad73311",
186 .cpu_dai_name = "bf5xx-i2s", 175 .stream_name = "AD73311",
187 .codec_dai_name = "ad73311-hifi", 176 .cpu_dai_name = "bfin-i2s.0",
188 .platform_name = "bfin-pcm-audio", 177 .codec_dai_name = "ad73311-hifi",
189 .codec_name = "ad73311-codec", 178 .platform_name = "bfin-i2s-pcm-audio",
190 .ops = &bf5xx_ad73311_ops, 179 .codec_name = "ad73311",
180 .ops = &bf5xx_ad73311_ops,
181 },
182 {
183 .name = "ad73311",
184 .stream_name = "AD73311",
185 .cpu_dai_name = "bfin-i2s.1",
186 .codec_dai_name = "ad73311-hifi",
187 .platform_name = "bfin-i2s-pcm-audio",
188 .codec_name = "ad73311",
189 .ops = &bf5xx_ad73311_ops,
190 },
191}; 191};
192 192
193static struct snd_soc_card bf5xx_ad73311 = { 193static struct snd_soc_card bf5xx_ad73311 = {
194 .name = "bf5xx_ad73311", 194 .name = "bfin-ad73311",
195 .probe = bf5xx_probe, 195 .probe = bf5xx_probe,
196 .dai_link = &bf5xx_ad73311_dai, 196 .dai_link = &bf5xx_ad73311_dai[CONFIG_SND_BF5XX_SPORT_NUM],
197 .num_links = 1, 197 .num_links = 1,
198}; 198};
199 199
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 890a0dccf902..b5101efd1c87 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -148,10 +148,15 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
148 148
149static int bf5xx_pcm_open(struct snd_pcm_substream *substream) 149static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
150{ 150{
151 struct snd_soc_pcm_runtime *rtd = substream->private_data;
152 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
153 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
151 struct snd_pcm_runtime *runtime = substream->runtime; 154 struct snd_pcm_runtime *runtime = substream->runtime;
155 struct snd_dma_buffer *buf = &substream->dma_buffer;
152 int ret; 156 int ret;
153 157
154 pr_debug("%s enter\n", __func__); 158 pr_debug("%s enter\n", __func__);
159
155 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware); 160 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
156 161
157 ret = snd_pcm_hw_constraint_integer(runtime, \ 162 ret = snd_pcm_hw_constraint_integer(runtime, \
@@ -159,9 +164,14 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
159 if (ret < 0) 164 if (ret < 0)
160 goto out; 165 goto out;
161 166
162 if (sport_handle != NULL) 167 if (sport_handle != NULL) {
168 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
169 sport_handle->tx_buf = buf->area;
170 else
171 sport_handle->rx_buf = buf->area;
172
163 runtime->private_data = sport_handle; 173 runtime->private_data = sport_handle;
164 else { 174 } else {
165 pr_err("sport_handle is NULL\n"); 175 pr_err("sport_handle is NULL\n");
166 return -1; 176 return -1;
167 } 177 }
@@ -214,11 +224,6 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
214 pr_debug("%s, area:%p, size:0x%08lx\n", __func__, 224 pr_debug("%s, area:%p, size:0x%08lx\n", __func__,
215 buf->area, buf->bytes); 225 buf->area, buf->bytes);
216 226
217 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
218 sport_handle->tx_buf = buf->area;
219 else
220 sport_handle->rx_buf = buf->area;
221
222 return 0; 227 return 0;
223} 228}
224 229
@@ -239,8 +244,6 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
239 dma_free_coherent(NULL, buf->bytes, buf->area, 0); 244 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
240 buf->area = NULL; 245 buf->area = NULL;
241 } 246 }
242 if (sport_handle)
243 sport_done(sport_handle);
244} 247}
245 248
246static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); 249static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
@@ -292,7 +295,7 @@ static int __devexit bfin_i2s_soc_platform_remove(struct platform_device *pdev)
292 295
293static struct platform_driver bfin_i2s_pcm_driver = { 296static struct platform_driver bfin_i2s_pcm_driver = {
294 .driver = { 297 .driver = {
295 .name = "bfin-pcm-audio", 298 .name = "bfin-i2s-pcm-audio",
296 .owner = THIS_MODULE, 299 .owner = THIS_MODULE,
297 }, 300 },
298 301
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index d453b1e9d607..00cc3e00b2fe 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -51,59 +51,24 @@ struct bf5xx_i2s_port {
51 int configured; 51 int configured;
52}; 52};
53 53
54static struct bf5xx_i2s_port bf5xx_i2s;
55static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
56
57static struct sport_param sport_params[2] = {
58 {
59 .dma_rx_chan = CH_SPORT0_RX,
60 .dma_tx_chan = CH_SPORT0_TX,
61 .err_irq = IRQ_SPORT0_ERROR,
62 .regs = (struct sport_register *)SPORT0_TCR1,
63 },
64 {
65 .dma_rx_chan = CH_SPORT1_RX,
66 .dma_tx_chan = CH_SPORT1_TX,
67 .err_irq = IRQ_SPORT1_ERROR,
68 .regs = (struct sport_register *)SPORT1_TCR1,
69 }
70};
71
72/*
73 * Setting the TFS pin selector for SPORT 0 based on whether the selected
74 * port id F or G. If the port is F then no conflict should exist for the
75 * TFS. When Port G is selected and EMAC then there is a conflict between
76 * the PHY interrupt line and TFS. Current settings prevent the conflict
77 * by ignoring the TFS pin when Port G is selected. This allows both
78 * codecs and EMAC using Port G concurrently.
79 */
80#ifdef CONFIG_BF527_SPORT0_PORTG
81#define LOCAL_SPORT0_TFS (0)
82#else
83#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
84#endif
85
86static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
87 P_SPORT0_DRPRI, P_SPORT0_RSCLK, LOCAL_SPORT0_TFS, 0},
88 {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, P_SPORT1_DRPRI,
89 P_SPORT1_RSCLK, P_SPORT1_TFS, 0} };
90
91static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 54static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
92 unsigned int fmt) 55 unsigned int fmt)
93{ 56{
57 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
58 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
94 int ret = 0; 59 int ret = 0;
95 60
96 /* interface format:support I2S,slave mode */ 61 /* interface format:support I2S,slave mode */
97 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 62 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
98 case SND_SOC_DAIFMT_I2S: 63 case SND_SOC_DAIFMT_I2S:
99 bf5xx_i2s.tcr1 |= TFSR | TCKFE; 64 bf5xx_i2s->tcr1 |= TFSR | TCKFE;
100 bf5xx_i2s.rcr1 |= RFSR | RCKFE; 65 bf5xx_i2s->rcr1 |= RFSR | RCKFE;
101 bf5xx_i2s.tcr2 |= TSFSE; 66 bf5xx_i2s->tcr2 |= TSFSE;
102 bf5xx_i2s.rcr2 |= RSFSE; 67 bf5xx_i2s->rcr2 |= RSFSE;
103 break; 68 break;
104 case SND_SOC_DAIFMT_DSP_A: 69 case SND_SOC_DAIFMT_DSP_A:
105 bf5xx_i2s.tcr1 |= TFSR; 70 bf5xx_i2s->tcr1 |= TFSR;
106 bf5xx_i2s.rcr1 |= RFSR; 71 bf5xx_i2s->rcr1 |= RFSR;
107 break; 72 break;
108 case SND_SOC_DAIFMT_LEFT_J: 73 case SND_SOC_DAIFMT_LEFT_J:
109 ret = -EINVAL; 74 ret = -EINVAL;
@@ -135,29 +100,35 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
135 struct snd_pcm_hw_params *params, 100 struct snd_pcm_hw_params *params,
136 struct snd_soc_dai *dai) 101 struct snd_soc_dai *dai)
137{ 102{
103 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
104 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
138 int ret = 0; 105 int ret = 0;
139 106
140 bf5xx_i2s.tcr2 &= ~0x1f; 107 bf5xx_i2s->tcr2 &= ~0x1f;
141 bf5xx_i2s.rcr2 &= ~0x1f; 108 bf5xx_i2s->rcr2 &= ~0x1f;
142 switch (params_format(params)) { 109 switch (params_format(params)) {
110 case SNDRV_PCM_FORMAT_S8:
111 bf5xx_i2s->tcr2 |= 7;
112 bf5xx_i2s->rcr2 |= 7;
113 sport_handle->wdsize = 1;
143 case SNDRV_PCM_FORMAT_S16_LE: 114 case SNDRV_PCM_FORMAT_S16_LE:
144 bf5xx_i2s.tcr2 |= 15; 115 bf5xx_i2s->tcr2 |= 15;
145 bf5xx_i2s.rcr2 |= 15; 116 bf5xx_i2s->rcr2 |= 15;
146 sport_handle->wdsize = 2; 117 sport_handle->wdsize = 2;
147 break; 118 break;
148 case SNDRV_PCM_FORMAT_S24_LE: 119 case SNDRV_PCM_FORMAT_S24_LE:
149 bf5xx_i2s.tcr2 |= 23; 120 bf5xx_i2s->tcr2 |= 23;
150 bf5xx_i2s.rcr2 |= 23; 121 bf5xx_i2s->rcr2 |= 23;
151 sport_handle->wdsize = 3; 122 sport_handle->wdsize = 3;
152 break; 123 break;
153 case SNDRV_PCM_FORMAT_S32_LE: 124 case SNDRV_PCM_FORMAT_S32_LE:
154 bf5xx_i2s.tcr2 |= 31; 125 bf5xx_i2s->tcr2 |= 31;
155 bf5xx_i2s.rcr2 |= 31; 126 bf5xx_i2s->rcr2 |= 31;
156 sport_handle->wdsize = 4; 127 sport_handle->wdsize = 4;
157 break; 128 break;
158 } 129 }
159 130
160 if (!bf5xx_i2s.configured) { 131 if (!bf5xx_i2s->configured) {
161 /* 132 /*
162 * TX and RX are not independent,they are enabled at the 133 * TX and RX are not independent,they are enabled at the
163 * same time, even if only one side is running. So, we 134 * same time, even if only one side is running. So, we
@@ -166,16 +137,16 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
166 * 137 *
167 * CPU DAI:slave mode. 138 * CPU DAI:slave mode.
168 */ 139 */
169 bf5xx_i2s.configured = 1; 140 bf5xx_i2s->configured = 1;
170 ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1, 141 ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
171 bf5xx_i2s.rcr2, 0, 0); 142 bf5xx_i2s->rcr2, 0, 0);
172 if (ret) { 143 if (ret) {
173 pr_err("SPORT is busy!\n"); 144 pr_err("SPORT is busy!\n");
174 return -EBUSY; 145 return -EBUSY;
175 } 146 }
176 147
177 ret = sport_config_tx(sport_handle, bf5xx_i2s.tcr1, 148 ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1,
178 bf5xx_i2s.tcr2, 0, 0); 149 bf5xx_i2s->tcr2, 0, 0);
179 if (ret) { 150 if (ret) {
180 pr_err("SPORT is busy!\n"); 151 pr_err("SPORT is busy!\n");
181 return -EBUSY; 152 return -EBUSY;
@@ -188,41 +159,19 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
188static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream, 159static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
189 struct snd_soc_dai *dai) 160 struct snd_soc_dai *dai)
190{ 161{
162 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
163 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
164
191 pr_debug("%s enter\n", __func__); 165 pr_debug("%s enter\n", __func__);
192 /* No active stream, SPORT is allowed to be configured again. */ 166 /* No active stream, SPORT is allowed to be configured again. */
193 if (!dai->active) 167 if (!dai->active)
194 bf5xx_i2s.configured = 0; 168 bf5xx_i2s->configured = 0;
195}
196
197static int bf5xx_i2s_probe(struct snd_soc_dai *dai)
198{
199 pr_debug("%s enter\n", __func__);
200 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
201 pr_err("Requesting Peripherals failed\n");
202 return -EFAULT;
203 }
204
205 /* request DMA for SPORT */
206 sport_handle = sport_init(&sport_params[sport_num], 4, \
207 2 * sizeof(u32), NULL);
208 if (!sport_handle) {
209 peripheral_free_list(&sport_req[sport_num][0]);
210 return -ENODEV;
211 }
212
213 return 0;
214}
215
216static int bf5xx_i2s_remove(struct snd_soc_dai *dai)
217{
218 pr_debug("%s enter\n", __func__);
219 peripheral_free_list(&sport_req[sport_num][0]);
220 return 0;
221} 169}
222 170
223#ifdef CONFIG_PM 171#ifdef CONFIG_PM
224static int bf5xx_i2s_suspend(struct snd_soc_dai *dai) 172static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
225{ 173{
174 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
226 175
227 pr_debug("%s : sport %d\n", __func__, dai->id); 176 pr_debug("%s : sport %d\n", __func__, dai->id);
228 177
@@ -235,19 +184,21 @@ static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
235 184
236static int bf5xx_i2s_resume(struct snd_soc_dai *dai) 185static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
237{ 186{
187 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
188 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
238 int ret; 189 int ret;
239 190
240 pr_debug("%s : sport %d\n", __func__, dai->id); 191 pr_debug("%s : sport %d\n", __func__, dai->id);
241 192
242 ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1, 193 ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
243 bf5xx_i2s.rcr2, 0, 0); 194 bf5xx_i2s->rcr2, 0, 0);
244 if (ret) { 195 if (ret) {
245 pr_err("SPORT is busy!\n"); 196 pr_err("SPORT is busy!\n");
246 return -EBUSY; 197 return -EBUSY;
247 } 198 }
248 199
249 ret = sport_config_tx(sport_handle, bf5xx_i2s.tcr1, 200 ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1,
250 bf5xx_i2s.tcr2, 0, 0); 201 bf5xx_i2s->tcr2, 0, 0);
251 if (ret) { 202 if (ret) {
252 pr_err("SPORT is busy!\n"); 203 pr_err("SPORT is busy!\n");
253 return -EBUSY; 204 return -EBUSY;
@@ -266,8 +217,11 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
266 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \ 217 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
267 SNDRV_PCM_RATE_96000) 218 SNDRV_PCM_RATE_96000)
268 219
269#define BF5XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\ 220#define BF5XX_I2S_FORMATS \
270 SNDRV_PCM_FMTBIT_S32_LE) 221 (SNDRV_PCM_FMTBIT_S8 | \
222 SNDRV_PCM_FMTBIT_S16_LE | \
223 SNDRV_PCM_FMTBIT_S24_LE | \
224 SNDRV_PCM_FMTBIT_S32_LE)
271 225
272static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = { 226static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
273 .shutdown = bf5xx_i2s_shutdown, 227 .shutdown = bf5xx_i2s_shutdown,
@@ -276,8 +230,6 @@ static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
276}; 230};
277 231
278static struct snd_soc_dai_driver bf5xx_i2s_dai = { 232static struct snd_soc_dai_driver bf5xx_i2s_dai = {
279 .probe = bf5xx_i2s_probe,
280 .remove = bf5xx_i2s_remove,
281 .suspend = bf5xx_i2s_suspend, 233 .suspend = bf5xx_i2s_suspend,
282 .resume = bf5xx_i2s_resume, 234 .resume = bf5xx_i2s_resume,
283 .playback = { 235 .playback = {
@@ -293,23 +245,45 @@ static struct snd_soc_dai_driver bf5xx_i2s_dai = {
293 .ops = &bf5xx_i2s_dai_ops, 245 .ops = &bf5xx_i2s_dai_ops,
294}; 246};
295 247
296static int bfin_i2s_drv_probe(struct platform_device *pdev) 248static int __devinit bf5xx_i2s_probe(struct platform_device *pdev)
297{ 249{
298 return snd_soc_register_dai(&pdev->dev, &bf5xx_i2s_dai); 250 struct sport_device *sport_handle;
251 int ret;
252
253 /* configure SPORT for I2S */
254 sport_handle = sport_init(pdev, 4, 2 * sizeof(u32),
255 sizeof(struct bf5xx_i2s_port));
256 if (!sport_handle)
257 return -ENODEV;
258
259 /* register with the ASoC layers */
260 ret = snd_soc_register_dai(&pdev->dev, &bf5xx_i2s_dai);
261 if (ret) {
262 pr_err("Failed to register DAI: %d\n", ret);
263 sport_done(sport_handle);
264 return ret;
265 }
266
267 return 0;
299} 268}
300 269
301static int __devexit bfin_i2s_drv_remove(struct platform_device *pdev) 270static int __devexit bf5xx_i2s_remove(struct platform_device *pdev)
302{ 271{
272 struct sport_device *sport_handle = platform_get_drvdata(pdev);
273
274 pr_debug("%s enter\n", __func__);
275
303 snd_soc_unregister_dai(&pdev->dev); 276 snd_soc_unregister_dai(&pdev->dev);
277 sport_done(sport_handle);
278
304 return 0; 279 return 0;
305} 280}
306 281
307static struct platform_driver bfin_i2s_driver = { 282static struct platform_driver bfin_i2s_driver = {
308 .probe = bfin_i2s_drv_probe, 283 .probe = bf5xx_i2s_probe,
309 .remove = __devexit_p(bfin_i2s_drv_remove), 284 .remove = __devexit_p(bf5xx_i2s_remove),
310
311 .driver = { 285 .driver = {
312 .name = "bf5xx-i2s", 286 .name = "bfin-i2s",
313 .owner = THIS_MODULE, 287 .owner = THIS_MODULE,
314 }, 288 },
315}; 289};
diff --git a/sound/soc/blackfin/bf5xx-sport.c b/sound/soc/blackfin/bf5xx-sport.c
index 99051ff0954e..a2d40349fcc4 100644
--- a/sound/soc/blackfin/bf5xx-sport.c
+++ b/sound/soc/blackfin/bf5xx-sport.c
@@ -42,8 +42,6 @@
42/* delay between frame sync pulse and first data bit in multichannel mode */ 42/* delay between frame sync pulse and first data bit in multichannel mode */
43#define FRAME_DELAY (1<<12) 43#define FRAME_DELAY (1<<12)
44 44
45struct sport_device *sport_handle;
46EXPORT_SYMBOL(sport_handle);
47/* note: multichannel is in units of 8 channels, 45/* note: multichannel is in units of 8 channels,
48 * tdm_count is # channels NOT / 8 ! */ 46 * tdm_count is # channels NOT / 8 ! */
49int sport_set_multichannel(struct sport_device *sport, 47int sport_set_multichannel(struct sport_device *sport,
@@ -798,86 +796,164 @@ int sport_set_err_callback(struct sport_device *sport,
798} 796}
799EXPORT_SYMBOL(sport_set_err_callback); 797EXPORT_SYMBOL(sport_set_err_callback);
800 798
801struct sport_device *sport_init(struct sport_param *param, unsigned wdsize, 799static int sport_config_pdev(struct platform_device *pdev, struct sport_param *param)
802 unsigned dummy_count, void *private_data)
803{ 800{
804 int ret; 801 /* Extract settings from platform data */
802 struct device *dev = &pdev->dev;
803 struct bfin_snd_platform_data *pdata = dev->platform_data;
804 struct resource *res;
805
806 param->num = pdev->id;
807
808 if (!pdata) {
809 dev_err(dev, "no platform_data\n");
810 return -ENODEV;
811 }
812 param->pin_req = pdata->pin_req;
813
814 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
815 if (!res) {
816 dev_err(dev, "no MEM resource\n");
817 return -ENODEV;
818 }
819 param->regs = (struct sport_register *)res->start;
820
821 /* first RX, then TX */
822 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
823 if (!res) {
824 dev_err(dev, "no rx DMA resource\n");
825 return -ENODEV;
826 }
827 param->dma_rx_chan = res->start;
828
829 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
830 if (!res) {
831 dev_err(dev, "no tx DMA resource\n");
832 return -ENODEV;
833 }
834 param->dma_tx_chan = res->start;
835
836 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
837 if (!res) {
838 dev_err(dev, "no irq resource\n");
839 return -ENODEV;
840 }
841 param->err_irq = res->start;
842
843 return 0;
844}
845
846struct sport_device *sport_init(struct platform_device *pdev,
847 unsigned int wdsize, unsigned int dummy_count, size_t priv_size)
848{
849 struct device *dev = &pdev->dev;
850 struct sport_param param;
805 struct sport_device *sport; 851 struct sport_device *sport;
806 pr_debug("%s enter\n", __func__); 852 int ret;
807 BUG_ON(param == NULL); 853
808 BUG_ON(wdsize == 0 || dummy_count == 0); 854 dev_dbg(dev, "%s enter\n", __func__);
809 sport = kmalloc(sizeof(struct sport_device), GFP_KERNEL); 855
810 if (!sport) { 856 param.wdsize = wdsize;
811 pr_err("Failed to allocate for sport device\n"); 857 param.dummy_count = dummy_count;
858 BUG_ON(param.wdsize == 0 || param.dummy_count == 0);
859
860 ret = sport_config_pdev(pdev, &param);
861 if (ret)
862 return NULL;
863
864 if (peripheral_request_list(param.pin_req, "soc-audio")) {
865 dev_err(dev, "requesting Peripherals failed\n");
812 return NULL; 866 return NULL;
813 } 867 }
814 868
815 memset(sport, 0, sizeof(struct sport_device)); 869 sport = kzalloc(sizeof(*sport), GFP_KERNEL);
816 sport->dma_rx_chan = param->dma_rx_chan; 870 if (!sport) {
817 sport->dma_tx_chan = param->dma_tx_chan; 871 dev_err(dev, "failed to allocate for sport device\n");
818 sport->err_irq = param->err_irq; 872 goto __init_err0;
819 sport->regs = param->regs; 873 }
820 sport->private_data = private_data; 874
875 sport->num = param.num;
876 sport->dma_rx_chan = param.dma_rx_chan;
877 sport->dma_tx_chan = param.dma_tx_chan;
878 sport->err_irq = param.err_irq;
879 sport->regs = param.regs;
880 sport->pin_req = param.pin_req;
821 881
822 if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) { 882 if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) {
823 pr_err("Failed to request RX dma %d\n", \ 883 dev_err(dev, "failed to request RX dma %d\n", sport->dma_rx_chan);
824 sport->dma_rx_chan);
825 goto __init_err1; 884 goto __init_err1;
826 } 885 }
827 if (set_dma_callback(sport->dma_rx_chan, rx_handler, sport) != 0) { 886 if (set_dma_callback(sport->dma_rx_chan, rx_handler, sport) != 0) {
828 pr_err("Failed to request RX irq %d\n", \ 887 dev_err(dev, "failed to request RX irq %d\n", sport->dma_rx_chan);
829 sport->dma_rx_chan);
830 goto __init_err2; 888 goto __init_err2;
831 } 889 }
832 890
833 if (request_dma(sport->dma_tx_chan, "SPORT TX Data") == -EBUSY) { 891 if (request_dma(sport->dma_tx_chan, "SPORT TX Data") == -EBUSY) {
834 pr_err("Failed to request TX dma %d\n", \ 892 dev_err(dev, "failed to request TX dma %d\n", sport->dma_tx_chan);
835 sport->dma_tx_chan);
836 goto __init_err2; 893 goto __init_err2;
837 } 894 }
838 895
839 if (set_dma_callback(sport->dma_tx_chan, tx_handler, sport) != 0) { 896 if (set_dma_callback(sport->dma_tx_chan, tx_handler, sport) != 0) {
840 pr_err("Failed to request TX irq %d\n", \ 897 dev_err(dev, "failed to request TX irq %d\n", sport->dma_tx_chan);
841 sport->dma_tx_chan);
842 goto __init_err3; 898 goto __init_err3;
843 } 899 }
844 900
845 if (request_irq(sport->err_irq, err_handler, IRQF_SHARED, "SPORT err", 901 if (request_irq(sport->err_irq, err_handler, IRQF_SHARED, "SPORT err",
846 sport) < 0) { 902 sport) < 0) {
847 pr_err("Failed to request err irq:%d\n", \ 903 dev_err(dev, "failed to request err irq %d\n", sport->err_irq);
848 sport->err_irq);
849 goto __init_err3; 904 goto __init_err3;
850 } 905 }
851 906
852 pr_err("dma rx:%d tx:%d, err irq:%d, regs:%p\n", 907 dev_info(dev, "dma rx:%d tx:%d, err irq:%d, regs:%p\n",
853 sport->dma_rx_chan, sport->dma_tx_chan, 908 sport->dma_rx_chan, sport->dma_tx_chan,
854 sport->err_irq, sport->regs); 909 sport->err_irq, sport->regs);
855 910
856 sport->wdsize = wdsize; 911 sport->wdsize = param.wdsize;
857 sport->dummy_count = dummy_count; 912 sport->dummy_count = param.dummy_count;
913
914 sport->private_data = kzalloc(priv_size, GFP_KERNEL);
915 if (!sport->private_data) {
916 dev_err(dev, "could not alloc priv data %zu bytes\n", priv_size);
917 goto __init_err4;
918 }
858 919
859 if (L1_DATA_A_LENGTH) 920 if (L1_DATA_A_LENGTH)
860 sport->dummy_buf = l1_data_sram_zalloc(dummy_count * 2); 921 sport->dummy_buf = l1_data_sram_zalloc(param.dummy_count * 2);
861 else 922 else
862 sport->dummy_buf = kzalloc(dummy_count * 2, GFP_KERNEL); 923 sport->dummy_buf = kzalloc(param.dummy_count * 2, GFP_KERNEL);
863 if (sport->dummy_buf == NULL) { 924 if (sport->dummy_buf == NULL) {
864 pr_err("Failed to allocate dummy buffer\n"); 925 dev_err(dev, "failed to allocate dummy buffer\n");
865 goto __error; 926 goto __error1;
866 } 927 }
867 928
868 ret = sport_config_rx_dummy(sport); 929 ret = sport_config_rx_dummy(sport);
869 if (ret) { 930 if (ret) {
870 pr_err("Failed to config rx dummy ring\n"); 931 dev_err(dev, "failed to config rx dummy ring\n");
871 goto __error; 932 goto __error2;
872 } 933 }
873 ret = sport_config_tx_dummy(sport); 934 ret = sport_config_tx_dummy(sport);
874 if (ret) { 935 if (ret) {
875 pr_err("Failed to config tx dummy ring\n"); 936 dev_err(dev, "failed to config tx dummy ring\n");
876 goto __error; 937 goto __error3;
877 } 938 }
878 939
940 platform_set_drvdata(pdev, sport);
941
879 return sport; 942 return sport;
880__error: 943__error3:
944 if (L1_DATA_A_LENGTH)
945 l1_data_sram_free(sport->dummy_rx_desc);
946 else
947 dma_free_coherent(NULL, 2*sizeof(struct dmasg),
948 sport->dummy_rx_desc, 0);
949__error2:
950 if (L1_DATA_A_LENGTH)
951 l1_data_sram_free(sport->dummy_buf);
952 else
953 kfree(sport->dummy_buf);
954__error1:
955 kfree(sport->private_data);
956__init_err4:
881 free_irq(sport->err_irq, sport); 957 free_irq(sport->err_irq, sport);
882__init_err3: 958__init_err3:
883 free_dma(sport->dma_tx_chan); 959 free_dma(sport->dma_tx_chan);
@@ -885,6 +961,8 @@ __init_err2:
885 free_dma(sport->dma_rx_chan); 961 free_dma(sport->dma_rx_chan);
886__init_err1: 962__init_err1:
887 kfree(sport); 963 kfree(sport);
964__init_err0:
965 peripheral_free_list(param.pin_req);
888 return NULL; 966 return NULL;
889} 967}
890EXPORT_SYMBOL(sport_init); 968EXPORT_SYMBOL(sport_init);
@@ -917,8 +995,9 @@ void sport_done(struct sport_device *sport)
917 free_dma(sport->dma_tx_chan); 995 free_dma(sport->dma_tx_chan);
918 free_irq(sport->err_irq, sport); 996 free_irq(sport->err_irq, sport);
919 997
998 kfree(sport->private_data);
999 peripheral_free_list(sport->pin_req);
920 kfree(sport); 1000 kfree(sport);
921 sport = NULL;
922} 1001}
923EXPORT_SYMBOL(sport_done); 1002EXPORT_SYMBOL(sport_done);
924 1003
diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h
index a86e8cc0b2d3..5ab60bd613ea 100644
--- a/sound/soc/blackfin/bf5xx-sport.h
+++ b/sound/soc/blackfin/bf5xx-sport.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * File: bf5xx_ac97_sport.h 2 * File: bf5xx_sport.h
3 * Based on: 3 * Based on:
4 * Author: Roy Huang <roy.huang@analog.com> 4 * Author: Roy Huang <roy.huang@analog.com>
5 * 5 *
@@ -33,15 +33,18 @@
33#include <linux/types.h> 33#include <linux/types.h>
34#include <linux/wait.h> 34#include <linux/wait.h>
35#include <linux/workqueue.h> 35#include <linux/workqueue.h>
36#include <linux/platform_device.h>
36#include <asm/dma.h> 37#include <asm/dma.h>
37#include <asm/bfin_sport.h> 38#include <asm/bfin_sport.h>
38 39
39#define DESC_ELEMENT_COUNT 9 40#define DESC_ELEMENT_COUNT 9
40 41
41struct sport_device { 42struct sport_device {
43 int num;
42 int dma_rx_chan; 44 int dma_rx_chan;
43 int dma_tx_chan; 45 int dma_tx_chan;
44 int err_irq; 46 int err_irq;
47 const unsigned short *pin_req;
45 struct sport_register *regs; 48 struct sport_register *regs;
46 49
47 unsigned char *rx_buf; 50 unsigned char *rx_buf;
@@ -103,17 +106,20 @@ struct sport_device {
103 void *private_data; 106 void *private_data;
104}; 107};
105 108
106extern struct sport_device *sport_handle;
107
108struct sport_param { 109struct sport_param {
110 int num;
109 int dma_rx_chan; 111 int dma_rx_chan;
110 int dma_tx_chan; 112 int dma_tx_chan;
111 int err_irq; 113 int err_irq;
114 const unsigned short *pin_req;
112 struct sport_register *regs; 115 struct sport_register *regs;
116 unsigned int wdsize;
117 unsigned int dummy_count;
118 void *private_data;
113}; 119};
114 120
115struct sport_device *sport_init(struct sport_param *param, unsigned wdsize, 121struct sport_device *sport_init(struct platform_device *pdev,
116 unsigned dummy_count, void *private_data); 122 unsigned int wdsize, unsigned int dummy_count, size_t priv_size);
117 123
118void sport_done(struct sport_device *sport); 124void sport_done(struct sport_device *sport);
119 125
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index ad28663f5bbd..767e772a815d 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -44,16 +44,6 @@
44 44
45static struct snd_soc_card bf5xx_ssm2602; 45static struct snd_soc_card bf5xx_ssm2602;
46 46
47static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream)
48{
49 struct snd_soc_pcm_runtime *rtd = substream->private_data;
50 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
51
52 pr_debug("%s enter\n", __func__);
53 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
54 return 0;
55}
56
57static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream, 47static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
58 struct snd_pcm_hw_params *params) 48 struct snd_pcm_hw_params *params)
59{ 49{
@@ -109,23 +99,33 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
109} 99}
110 100
111static struct snd_soc_ops bf5xx_ssm2602_ops = { 101static struct snd_soc_ops bf5xx_ssm2602_ops = {
112 .startup = bf5xx_ssm2602_startup,
113 .hw_params = bf5xx_ssm2602_hw_params, 102 .hw_params = bf5xx_ssm2602_hw_params,
114}; 103};
115 104
116static struct snd_soc_dai_link bf5xx_ssm2602_dai = { 105static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = {
117 .name = "ssm2602", 106 {
118 .stream_name = "SSM2602", 107 .name = "ssm2602",
119 .cpu_dai_name = "bf5xx-i2s", 108 .stream_name = "SSM2602",
120 .codec_dai_name = "ssm2602-hifi", 109 .cpu_dai_name = "bfin-i2s.0",
121 .platform_name = "bf5xx-pcm-audio", 110 .codec_dai_name = "ssm2602-hifi",
122 .codec_name = "ssm2602-codec.0-001b", 111 .platform_name = "bfin-i2s-pcm-audio",
123 .ops = &bf5xx_ssm2602_ops, 112 .codec_name = "ssm2602.0-001b",
113 .ops = &bf5xx_ssm2602_ops,
114 },
115 {
116 .name = "ssm2602",
117 .stream_name = "SSM2602",
118 .cpu_dai_name = "bfin-i2s.1",
119 .codec_dai_name = "ssm2602-hifi",
120 .platform_name = "bfin-i2s-pcm-audio",
121 .codec_name = "ssm2602.0-001b",
122 .ops = &bf5xx_ssm2602_ops,
123 },
124}; 124};
125 125
126static struct snd_soc_card bf5xx_ssm2602 = { 126static struct snd_soc_card bf5xx_ssm2602 = {
127 .name = "bf5xx_ssm2602", 127 .name = "bfin-ssm2602",
128 .dai_link = &bf5xx_ssm2602_dai, 128 .dai_link = &bf5xx_ssm2602_dai[CONFIG_SND_BF5XX_SPORT_NUM],
129 .num_links = 1, 129 .num_links = 1,
130}; 130};
131 131
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
index 74cf759b78a6..07cfc7a9e49a 100644
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.c
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c
@@ -154,7 +154,12 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
154 154
155static int bf5xx_pcm_open(struct snd_pcm_substream *substream) 155static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
156{ 156{
157 struct snd_soc_pcm_runtime *rtd = substream->private_data;
158 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
159 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
157 struct snd_pcm_runtime *runtime = substream->runtime; 160 struct snd_pcm_runtime *runtime = substream->runtime;
161 struct snd_dma_buffer *buf = &substream->dma_buffer;
162
158 int ret = 0; 163 int ret = 0;
159 164
160 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware); 165 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
@@ -164,9 +169,14 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
164 if (ret < 0) 169 if (ret < 0)
165 goto out; 170 goto out;
166 171
167 if (sport_handle != NULL) 172 if (sport_handle != NULL) {
173 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
174 sport_handle->tx_buf = buf->area;
175 else
176 sport_handle->rx_buf = buf->area;
177
168 runtime->private_data = sport_handle; 178 runtime->private_data = sport_handle;
169 else { 179 } else {
170 pr_err("sport_handle is NULL\n"); 180 pr_err("sport_handle is NULL\n");
171 ret = -ENODEV; 181 ret = -ENODEV;
172 } 182 }
@@ -249,11 +259,6 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
249 } 259 }
250 buf->bytes = size; 260 buf->bytes = size;
251 261
252 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
253 sport_handle->tx_buf = buf->area;
254 else
255 sport_handle->rx_buf = buf->area;
256
257 return 0; 262 return 0;
258} 263}
259 264
@@ -274,8 +279,6 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
274 dma_free_coherent(NULL, buf->bytes, buf->area, 0); 279 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
275 buf->area = NULL; 280 buf->area = NULL;
276 } 281 }
277 if (sport_handle)
278 sport_done(sport_handle);
279} 282}
280 283
281static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); 284static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
@@ -326,7 +329,7 @@ static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
326 329
327static struct platform_driver bfin_tdm_driver = { 330static struct platform_driver bfin_tdm_driver = {
328 .driver = { 331 .driver = {
329 .name = "bf5xx-tdm-pcm-audio", 332 .name = "bfin-tdm-pcm-audio",
330 .owner = THIS_MODULE, 333 .owner = THIS_MODULE,
331 }, 334 },
332 335
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
index 5515ac9e05c7..a822d1ee1380 100644
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -46,43 +46,6 @@
46#include "bf5xx-sport.h" 46#include "bf5xx-sport.h"
47#include "bf5xx-tdm.h" 47#include "bf5xx-tdm.h"
48 48
49static struct bf5xx_tdm_port bf5xx_tdm;
50static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
51
52static struct sport_param sport_params[2] = {
53 {
54 .dma_rx_chan = CH_SPORT0_RX,
55 .dma_tx_chan = CH_SPORT0_TX,
56 .err_irq = IRQ_SPORT0_ERROR,
57 .regs = (struct sport_register *)SPORT0_TCR1,
58 },
59 {
60 .dma_rx_chan = CH_SPORT1_RX,
61 .dma_tx_chan = CH_SPORT1_TX,
62 .err_irq = IRQ_SPORT1_ERROR,
63 .regs = (struct sport_register *)SPORT1_TCR1,
64 }
65};
66
67/*
68 * Setting the TFS pin selector for SPORT 0 based on whether the selected
69 * port id F or G. If the port is F then no conflict should exist for the
70 * TFS. When Port G is selected and EMAC then there is a conflict between
71 * the PHY interrupt line and TFS. Current settings prevent the conflict
72 * by ignoring the TFS pin when Port G is selected. This allows both
73 * codecs and EMAC using Port G concurrently.
74 */
75#ifdef CONFIG_BF527_SPORT0_PORTG
76#define LOCAL_SPORT0_TFS (0)
77#else
78#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
79#endif
80
81static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
82 P_SPORT0_DRPRI, P_SPORT0_RSCLK, LOCAL_SPORT0_TFS, 0},
83 {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, P_SPORT1_DRPRI,
84 P_SPORT1_RSCLK, P_SPORT1_TFS, 0} };
85
86static int bf5xx_tdm_set_dai_fmt(struct snd_soc_dai *cpu_dai, 49static int bf5xx_tdm_set_dai_fmt(struct snd_soc_dai *cpu_dai,
87 unsigned int fmt) 50 unsigned int fmt)
88{ 51{
@@ -119,14 +82,16 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
119 struct snd_pcm_hw_params *params, 82 struct snd_pcm_hw_params *params,
120 struct snd_soc_dai *dai) 83 struct snd_soc_dai *dai)
121{ 84{
85 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
86 struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
122 int ret = 0; 87 int ret = 0;
123 88
124 bf5xx_tdm.tcr2 &= ~0x1f; 89 bf5xx_tdm->tcr2 &= ~0x1f;
125 bf5xx_tdm.rcr2 &= ~0x1f; 90 bf5xx_tdm->rcr2 &= ~0x1f;
126 switch (params_format(params)) { 91 switch (params_format(params)) {
127 case SNDRV_PCM_FORMAT_S32_LE: 92 case SNDRV_PCM_FORMAT_S32_LE:
128 bf5xx_tdm.tcr2 |= 31; 93 bf5xx_tdm->tcr2 |= 31;
129 bf5xx_tdm.rcr2 |= 31; 94 bf5xx_tdm->rcr2 |= 31;
130 sport_handle->wdsize = 4; 95 sport_handle->wdsize = 4;
131 break; 96 break;
132 /* at present, we only support 32bit transfer */ 97 /* at present, we only support 32bit transfer */
@@ -136,7 +101,7 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
136 break; 101 break;
137 } 102 }
138 103
139 if (!bf5xx_tdm.configured) { 104 if (!bf5xx_tdm->configured) {
140 /* 105 /*
141 * TX and RX are not independent,they are enabled at the 106 * TX and RX are not independent,they are enabled at the
142 * same time, even if only one side is running. So, we 107 * same time, even if only one side is running. So, we
@@ -145,21 +110,21 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
145 * 110 *
146 * CPU DAI:slave mode. 111 * CPU DAI:slave mode.
147 */ 112 */
148 ret = sport_config_rx(sport_handle, bf5xx_tdm.rcr1, 113 ret = sport_config_rx(sport_handle, bf5xx_tdm->rcr1,
149 bf5xx_tdm.rcr2, 0, 0); 114 bf5xx_tdm->rcr2, 0, 0);
150 if (ret) { 115 if (ret) {
151 pr_err("SPORT is busy!\n"); 116 pr_err("SPORT is busy!\n");
152 return -EBUSY; 117 return -EBUSY;
153 } 118 }
154 119
155 ret = sport_config_tx(sport_handle, bf5xx_tdm.tcr1, 120 ret = sport_config_tx(sport_handle, bf5xx_tdm->tcr1,
156 bf5xx_tdm.tcr2, 0, 0); 121 bf5xx_tdm->tcr2, 0, 0);
157 if (ret) { 122 if (ret) {
158 pr_err("SPORT is busy!\n"); 123 pr_err("SPORT is busy!\n");
159 return -EBUSY; 124 return -EBUSY;
160 } 125 }
161 126
162 bf5xx_tdm.configured = 1; 127 bf5xx_tdm->configured = 1;
163 } 128 }
164 129
165 return 0; 130 return 0;
@@ -168,15 +133,20 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
168static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream, 133static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream,
169 struct snd_soc_dai *dai) 134 struct snd_soc_dai *dai)
170{ 135{
136 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
137 struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
138
171 /* No active stream, SPORT is allowed to be configured again. */ 139 /* No active stream, SPORT is allowed to be configured again. */
172 if (!dai->active) 140 if (!dai->active)
173 bf5xx_tdm.configured = 0; 141 bf5xx_tdm->configured = 0;
174} 142}
175 143
176static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai, 144static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
177 unsigned int tx_num, unsigned int *tx_slot, 145 unsigned int tx_num, unsigned int *tx_slot,
178 unsigned int rx_num, unsigned int *rx_slot) 146 unsigned int rx_num, unsigned int *rx_slot)
179{ 147{
148 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
149 struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
180 int i; 150 int i;
181 unsigned int slot; 151 unsigned int slot;
182 unsigned int tx_mapped = 0, rx_mapped = 0; 152 unsigned int tx_mapped = 0, rx_mapped = 0;
@@ -189,7 +159,7 @@ static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
189 slot = tx_slot[i]; 159 slot = tx_slot[i];
190 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) && 160 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
191 (!(tx_mapped & (1 << slot)))) { 161 (!(tx_mapped & (1 << slot)))) {
192 bf5xx_tdm.tx_map[i] = slot; 162 bf5xx_tdm->tx_map[i] = slot;
193 tx_mapped |= 1 << slot; 163 tx_mapped |= 1 << slot;
194 } else 164 } else
195 return -EINVAL; 165 return -EINVAL;
@@ -198,7 +168,7 @@ static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
198 slot = rx_slot[i]; 168 slot = rx_slot[i];
199 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) && 169 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
200 (!(rx_mapped & (1 << slot)))) { 170 (!(rx_mapped & (1 << slot)))) {
201 bf5xx_tdm.rx_map[i] = slot; 171 bf5xx_tdm->rx_map[i] = slot;
202 rx_mapped |= 1 << slot; 172 rx_mapped |= 1 << slot;
203 } else 173 } else
204 return -EINVAL; 174 return -EINVAL;
@@ -212,12 +182,14 @@ static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
212{ 182{
213 struct sport_device *sport = snd_soc_dai_get_drvdata(dai); 183 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
214 184
215 if (!dai->active)
216 return 0;
217 if (dai->capture_active)
218 sport_rx_stop(sport);
219 if (dai->playback_active) 185 if (dai->playback_active)
220 sport_tx_stop(sport); 186 sport_tx_stop(sport);
187 if (dai->capture_active)
188 sport_rx_stop(sport);
189
190 /* isolate sync/clock pins from codec while sports resume */
191 peripheral_free_list(sport->pin_req);
192
221 return 0; 193 return 0;
222} 194}
223 195
@@ -226,9 +198,6 @@ static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
226 int ret; 198 int ret;
227 struct sport_device *sport = snd_soc_dai_get_drvdata(dai); 199 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
228 200
229 if (!dai->active)
230 return 0;
231
232 ret = sport_set_multichannel(sport, 8, 0xFF, 1); 201 ret = sport_set_multichannel(sport, 8, 0xFF, 1);
233 if (ret) { 202 if (ret) {
234 pr_err("SPORT is busy!\n"); 203 pr_err("SPORT is busy!\n");
@@ -247,6 +216,8 @@ static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
247 ret = -EBUSY; 216 ret = -EBUSY;
248 } 217 }
249 218
219 peripheral_request_list(sport->pin_req, "soc-audio");
220
250 return 0; 221 return 0;
251} 222}
252 223
@@ -280,20 +251,14 @@ static struct snd_soc_dai_driver bf5xx_tdm_dai = {
280 251
281static int __devinit bfin_tdm_probe(struct platform_device *pdev) 252static int __devinit bfin_tdm_probe(struct platform_device *pdev)
282{ 253{
283 int ret = 0; 254 struct sport_device *sport_handle;
284 255 int ret;
285 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
286 pr_err("Requesting Peripherals failed\n");
287 return -EFAULT;
288 }
289 256
290 /* request DMA for SPORT */ 257 /* configure SPORT for TDM */
291 sport_handle = sport_init(&sport_params[sport_num], 4, \ 258 sport_handle = sport_init(pdev, 4, 8 * sizeof(u32),
292 8 * sizeof(u32), NULL); 259 sizeof(struct bf5xx_tdm_port));
293 if (!sport_handle) { 260 if (!sport_handle)
294 peripheral_free_list(&sport_req[sport_num][0]);
295 return -ENODEV; 261 return -ENODEV;
296 }
297 262
298 /* SPORT works in TDM mode */ 263 /* SPORT works in TDM mode */
299 ret = sport_set_multichannel(sport_handle, 8, 0xFF, 1); 264 ret = sport_set_multichannel(sport_handle, 8, 0xFF, 1);
@@ -323,18 +288,19 @@ static int __devinit bfin_tdm_probe(struct platform_device *pdev)
323 goto sport_config_err; 288 goto sport_config_err;
324 } 289 }
325 290
326 sport_handle->private_data = &bf5xx_tdm;
327 return 0; 291 return 0;
328 292
329sport_config_err: 293sport_config_err:
330 peripheral_free_list(&sport_req[sport_num][0]); 294 sport_done(sport_handle);
331 return ret; 295 return ret;
332} 296}
333 297
334static int __devexit bfin_tdm_remove(struct platform_device *pdev) 298static int __devexit bfin_tdm_remove(struct platform_device *pdev)
335{ 299{
336 peripheral_free_list(&sport_req[sport_num][0]); 300 struct sport_device *sport_handle = platform_get_drvdata(pdev);
301
337 snd_soc_unregister_dai(&pdev->dev); 302 snd_soc_unregister_dai(&pdev->dev);
303 sport_done(sport_handle);
338 304
339 return 0; 305 return 0;
340} 306}
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 06b6981b8d6d..19241576b6b5 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -120,7 +120,7 @@
120 */ 120 */
121#define PM860X_DAPM_OUTPUT(wname, wevent) \ 121#define PM860X_DAPM_OUTPUT(wname, wevent) \
122{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ 122{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \
123 .shift = 0, .invert = 0, .kcontrols = NULL, \ 123 .shift = 0, .invert = 0, .kcontrol_news = NULL, \
124 .num_kcontrols = 0, .event = wevent, \ 124 .num_kcontrols = 0, .event = wevent, \
125 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD, } 125 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD, }
126 126
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 6943e24a74a1..98175a096df2 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -16,10 +16,11 @@ config SND_SOC_ALL_CODECS
16 select SND_SOC_AD1836 if SPI_MASTER 16 select SND_SOC_AD1836 if SPI_MASTER
17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI 17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
19 select SND_SOC_AD73311
19 select SND_SOC_ADS117X 20 select SND_SOC_ADS117X
20 select SND_SOC_AD73311 if I2C
21 select SND_SOC_AK4104 if SPI_MASTER 21 select SND_SOC_AK4104 if SPI_MASTER
22 select SND_SOC_AK4535 if I2C 22 select SND_SOC_AK4535 if I2C
23 select SND_SOC_AK4641 if I2C
23 select SND_SOC_AK4642 if I2C 24 select SND_SOC_AK4642 if I2C
24 select SND_SOC_AK4671 if I2C 25 select SND_SOC_AK4671 if I2C
25 select SND_SOC_ALC5623 if I2C 26 select SND_SOC_ALC5623 if I2C
@@ -33,13 +34,14 @@ config SND_SOC_ALL_CODECS
33 select SND_SOC_JZ4740_CODEC if SOC_JZ4740 34 select SND_SOC_JZ4740_CODEC if SOC_JZ4740
34 select SND_SOC_LM4857 if I2C 35 select SND_SOC_LM4857 if I2C
35 select SND_SOC_MAX98088 if I2C 36 select SND_SOC_MAX98088 if I2C
37 select SND_SOC_MAX98095 if I2C
36 select SND_SOC_MAX9850 if I2C 38 select SND_SOC_MAX9850 if I2C
37 select SND_SOC_MAX9877 if I2C 39 select SND_SOC_MAX9877 if I2C
38 select SND_SOC_PCM3008 40 select SND_SOC_PCM3008
39 select SND_SOC_SGTL5000 if I2C 41 select SND_SOC_SGTL5000 if I2C
40 select SND_SOC_SN95031 if INTEL_SCU_IPC 42 select SND_SOC_SN95031 if INTEL_SCU_IPC
41 select SND_SOC_SPDIF 43 select SND_SOC_SPDIF
42 select SND_SOC_SSM2602 if I2C 44 select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI
43 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 45 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
44 select SND_SOC_TLV320AIC23 if I2C 46 select SND_SOC_TLV320AIC23 if I2C
45 select SND_SOC_TLV320AIC26 if SPI_MASTER 47 select SND_SOC_TLV320AIC26 if SPI_MASTER
@@ -52,6 +54,7 @@ config SND_SOC_ALL_CODECS
52 select SND_SOC_UDA134X 54 select SND_SOC_UDA134X
53 select SND_SOC_UDA1380 if I2C 55 select SND_SOC_UDA1380 if I2C
54 select SND_SOC_WL1273 if MFD_WL1273_CORE 56 select SND_SOC_WL1273 if MFD_WL1273_CORE
57 select SND_SOC_WM1250_EV1 if I2C
55 select SND_SOC_WM2000 if I2C 58 select SND_SOC_WM2000 if I2C
56 select SND_SOC_WM8350 if MFD_WM8350 59 select SND_SOC_WM8350 if MFD_WM8350
57 select SND_SOC_WM8400 if MFD_WM8400 60 select SND_SOC_WM8400 if MFD_WM8400
@@ -72,6 +75,7 @@ config SND_SOC_ALL_CODECS
72 select SND_SOC_WM8900 if I2C 75 select SND_SOC_WM8900 if I2C
73 select SND_SOC_WM8903 if I2C 76 select SND_SOC_WM8903 if I2C
74 select SND_SOC_WM8904 if I2C 77 select SND_SOC_WM8904 if I2C
78 select SND_SOC_WM8915 if I2C
75 select SND_SOC_WM8940 if I2C 79 select SND_SOC_WM8940 if I2C
76 select SND_SOC_WM8955 if I2C 80 select SND_SOC_WM8955 if I2C
77 select SND_SOC_WM8960 if I2C 81 select SND_SOC_WM8960 if I2C
@@ -136,6 +140,9 @@ config SND_SOC_AK4104
136config SND_SOC_AK4535 140config SND_SOC_AK4535
137 tristate 141 tristate
138 142
143config SND_SOC_AK4641
144 tristate
145
139config SND_SOC_AK4642 146config SND_SOC_AK4642
140 tristate 147 tristate
141 148
@@ -187,6 +194,9 @@ config SND_SOC_DMIC
187config SND_SOC_MAX98088 194config SND_SOC_MAX98088
188 tristate 195 tristate
189 196
197config SND_SOC_MAX98095
198 tristate
199
190config SND_SOC_MAX9850 200config SND_SOC_MAX9850
191 tristate 201 tristate
192 202
@@ -241,6 +251,9 @@ config SND_SOC_UDA1380
241config SND_SOC_WL1273 251config SND_SOC_WL1273
242 tristate 252 tristate
243 253
254config SND_SOC_WM1250_EV1
255 tristate
256
244config SND_SOC_WM8350 257config SND_SOC_WM8350
245 tristate 258 tristate
246 259
@@ -298,6 +311,9 @@ config SND_SOC_WM8903
298config SND_SOC_WM8904 311config SND_SOC_WM8904
299 tristate 312 tristate
300 313
314config SND_SOC_WM8915
315 tristate
316
301config SND_SOC_WM8940 317config SND_SOC_WM8940
302 tristate 318 tristate
303 319
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 379bc55f0723..fd8558406ef0 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -7,6 +7,7 @@ snd-soc-ad73311-objs := ad73311.o
7snd-soc-ads117x-objs := ads117x.o 7snd-soc-ads117x-objs := ads117x.o
8snd-soc-ak4104-objs := ak4104.o 8snd-soc-ak4104-objs := ak4104.o
9snd-soc-ak4535-objs := ak4535.o 9snd-soc-ak4535-objs := ak4535.o
10snd-soc-ak4641-objs := ak4641.o
10snd-soc-ak4642-objs := ak4642.o 11snd-soc-ak4642-objs := ak4642.o
11snd-soc-ak4671-objs := ak4671.o 12snd-soc-ak4671-objs := ak4671.o
12snd-soc-cq93vc-objs := cq93vc.o 13snd-soc-cq93vc-objs := cq93vc.o
@@ -19,6 +20,7 @@ snd-soc-dfbmcs320-objs := dfbmcs320.o
19snd-soc-dmic-objs := dmic.o 20snd-soc-dmic-objs := dmic.o
20snd-soc-l3-objs := l3.o 21snd-soc-l3-objs := l3.o
21snd-soc-max98088-objs := max98088.o 22snd-soc-max98088-objs := max98088.o
23snd-soc-max98095-objs := max98095.o
22snd-soc-max9850-objs := max9850.o 24snd-soc-max9850-objs := max9850.o
23snd-soc-pcm3008-objs := pcm3008.o 25snd-soc-pcm3008-objs := pcm3008.o
24snd-soc-sgtl5000-objs := sgtl5000.o 26snd-soc-sgtl5000-objs := sgtl5000.o
@@ -37,6 +39,7 @@ snd-soc-twl6040-objs := twl6040.o
37snd-soc-uda134x-objs := uda134x.o 39snd-soc-uda134x-objs := uda134x.o
38snd-soc-uda1380-objs := uda1380.o 40snd-soc-uda1380-objs := uda1380.o
39snd-soc-wl1273-objs := wl1273.o 41snd-soc-wl1273-objs := wl1273.o
42snd-soc-wm1250-ev1-objs := wm1250-ev1.o
40snd-soc-wm8350-objs := wm8350.o 43snd-soc-wm8350-objs := wm8350.o
41snd-soc-wm8400-objs := wm8400.o 44snd-soc-wm8400-objs := wm8400.o
42snd-soc-wm8510-objs := wm8510.o 45snd-soc-wm8510-objs := wm8510.o
@@ -56,6 +59,7 @@ snd-soc-wm8804-objs := wm8804.o
56snd-soc-wm8900-objs := wm8900.o 59snd-soc-wm8900-objs := wm8900.o
57snd-soc-wm8903-objs := wm8903.o 60snd-soc-wm8903-objs := wm8903.o
58snd-soc-wm8904-objs := wm8904.o 61snd-soc-wm8904-objs := wm8904.o
62snd-soc-wm8915-objs := wm8915.o
59snd-soc-wm8940-objs := wm8940.o 63snd-soc-wm8940-objs := wm8940.o
60snd-soc-wm8955-objs := wm8955.o 64snd-soc-wm8955-objs := wm8955.o
61snd-soc-wm8960-objs := wm8960.o 65snd-soc-wm8960-objs := wm8960.o
@@ -69,7 +73,7 @@ snd-soc-wm8988-objs := wm8988.o
69snd-soc-wm8990-objs := wm8990.o 73snd-soc-wm8990-objs := wm8990.o
70snd-soc-wm8991-objs := wm8991.o 74snd-soc-wm8991-objs := wm8991.o
71snd-soc-wm8993-objs := wm8993.o 75snd-soc-wm8993-objs := wm8993.o
72snd-soc-wm8994-objs := wm8994.o wm8994-tables.o 76snd-soc-wm8994-objs := wm8994.o wm8994-tables.o wm8958-dsp2.o
73snd-soc-wm8995-objs := wm8995.o 77snd-soc-wm8995-objs := wm8995.o
74snd-soc-wm9081-objs := wm9081.o 78snd-soc-wm9081-objs := wm9081.o
75snd-soc-wm9705-objs := wm9705.o 79snd-soc-wm9705-objs := wm9705.o
@@ -94,6 +98,7 @@ obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
94obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o 98obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
95obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 99obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
96obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 100obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
101obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
97obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 102obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
98obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 103obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
99obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o 104obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
@@ -108,6 +113,7 @@ obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
108obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 113obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
109obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 114obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
110obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o 115obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
116obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
111obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 117obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
112obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 118obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
113obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o 119obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
@@ -125,6 +131,7 @@ obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
125obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o 131obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
126obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 132obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
127obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o 133obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
134obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
128obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 135obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
129obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o 136obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
130obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 137obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
@@ -144,6 +151,7 @@ obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o
144obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 151obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
145obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 152obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
146obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o 153obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o
154obj-$(CONFIG_SND_SOC_WM8915) += snd-soc-wm8915.o
147obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o 155obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
148obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o 156obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o
149obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o 157obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index da46479bfcfa..2374ca5ffe68 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -23,8 +23,7 @@
23 23
24/* codec private data */ 24/* codec private data */
25struct ad193x_priv { 25struct ad193x_priv {
26 enum snd_soc_control_type bus_type; 26 enum snd_soc_control_type control_type;
27 void *control_data;
28 int sysclk; 27 int sysclk;
29}; 28};
30 29
@@ -354,14 +353,12 @@ static int ad193x_probe(struct snd_soc_codec *codec)
354 struct snd_soc_dapm_context *dapm = &codec->dapm; 353 struct snd_soc_dapm_context *dapm = &codec->dapm;
355 int ret; 354 int ret;
356 355
357 codec->control_data = ad193x->control_data; 356 if (ad193x->control_type == SND_SOC_I2C)
358 if (ad193x->bus_type == SND_SOC_I2C) 357 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->control_type);
359 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->bus_type);
360 else 358 else
361 ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->bus_type); 359 ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->control_type);
362 if (ret < 0) { 360 if (ret < 0) {
363 dev_err(codec->dev, "failed to set cache I/O: %d\n", 361 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
364 ret);
365 return ret; 362 return ret;
366 } 363 }
367 364
@@ -408,8 +405,7 @@ static int __devinit ad193x_spi_probe(struct spi_device *spi)
408 return -ENOMEM; 405 return -ENOMEM;
409 406
410 spi_set_drvdata(spi, ad193x); 407 spi_set_drvdata(spi, ad193x);
411 ad193x->control_data = spi; 408 ad193x->control_type = SND_SOC_SPI;
412 ad193x->bus_type = SND_SOC_SPI;
413 409
414 ret = snd_soc_register_codec(&spi->dev, 410 ret = snd_soc_register_codec(&spi->dev,
415 &soc_codec_dev_ad193x, &ad193x_dai, 1); 411 &soc_codec_dev_ad193x, &ad193x_dai, 1);
@@ -427,7 +423,7 @@ static int __devexit ad193x_spi_remove(struct spi_device *spi)
427 423
428static struct spi_driver ad193x_spi_driver = { 424static struct spi_driver ad193x_spi_driver = {
429 .driver = { 425 .driver = {
430 .name = "ad193x-codec", 426 .name = "ad193x",
431 .owner = THIS_MODULE, 427 .owner = THIS_MODULE,
432 }, 428 },
433 .probe = ad193x_spi_probe, 429 .probe = ad193x_spi_probe,
@@ -454,8 +450,7 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client,
454 return -ENOMEM; 450 return -ENOMEM;
455 451
456 i2c_set_clientdata(client, ad193x); 452 i2c_set_clientdata(client, ad193x);
457 ad193x->control_data = client; 453 ad193x->control_type = SND_SOC_I2C;
458 ad193x->bus_type = SND_SOC_I2C;
459 454
460 ret = snd_soc_register_codec(&client->dev, 455 ret = snd_soc_register_codec(&client->dev,
461 &soc_codec_dev_ad193x, &ad193x_dai, 1); 456 &soc_codec_dev_ad193x, &ad193x_dai, 1);
@@ -473,7 +468,7 @@ static int __devexit ad193x_i2c_remove(struct i2c_client *client)
473 468
474static struct i2c_driver ad193x_i2c_driver = { 469static struct i2c_driver ad193x_i2c_driver = {
475 .driver = { 470 .driver = {
476 .name = "ad193x-codec", 471 .name = "ad193x",
477 }, 472 },
478 .probe = ad193x_i2c_probe, 473 .probe = ad193x_i2c_probe,
479 .remove = __devexit_p(ad193x_i2c_remove), 474 .remove = __devexit_p(ad193x_i2c_remove),
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 34cb51ef2156..923b364a3e41 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -266,7 +266,7 @@ static int __devexit ad1980_remove(struct platform_device *pdev)
266 266
267static struct platform_driver ad1980_codec_driver = { 267static struct platform_driver ad1980_codec_driver = {
268 .driver = { 268 .driver = {
269 .name = "ad1980-codec", 269 .name = "ad1980",
270 .owner = THIS_MODULE, 270 .owner = THIS_MODULE,
271 }, 271 },
272 272
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index de799cd1ba72..8d793e993e9a 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -55,7 +55,7 @@ static int __devexit ad73311_remove(struct platform_device *pdev)
55 55
56static struct platform_driver ad73311_codec_driver = { 56static struct platform_driver ad73311_codec_driver = {
57 .driver = { 57 .driver = {
58 .name = "ad73311-codec", 58 .name = "ad73311",
59 .owner = THIS_MODULE, 59 .owner = THIS_MODULE,
60 }, 60 },
61 61
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 8b38739c88f8..e1a214ee757f 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -230,7 +230,7 @@ static const struct snd_soc_dapm_widget ak4535_dapm_widgets[] = {
230 SND_SOC_DAPM_INPUT("AIN"), 230 SND_SOC_DAPM_INPUT("AIN"),
231}; 231};
232 232
233static const struct snd_soc_dapm_route audio_map[] = { 233static const struct snd_soc_dapm_route ak4535_audio_map[] = {
234 /*stereo mixer */ 234 /*stereo mixer */
235 {"Stereo Mixer", "Playback Switch", "DAC"}, 235 {"Stereo Mixer", "Playback Switch", "DAC"},
236 {"Stereo Mixer", "Mic Sidetone Switch", "Mic"}, 236 {"Stereo Mixer", "Mic Sidetone Switch", "Mic"},
@@ -287,17 +287,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
287 {"Input Mixer", "Aux Capture Switch", "Aux In"}, 287 {"Input Mixer", "Aux Capture Switch", "Aux In"},
288}; 288};
289 289
290static int ak4535_add_widgets(struct snd_soc_codec *codec)
291{
292 struct snd_soc_dapm_context *dapm = &codec->dapm;
293
294 snd_soc_dapm_new_controls(dapm, ak4535_dapm_widgets,
295 ARRAY_SIZE(ak4535_dapm_widgets));
296 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
297
298 return 0;
299}
300
301static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai, 290static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai,
302 int clk_id, unsigned int freq, int dir) 291 int clk_id, unsigned int freq, int dir)
303{ 292{
@@ -457,8 +446,6 @@ static int ak4535_probe(struct snd_soc_codec *codec)
457 446
458 snd_soc_add_controls(codec, ak4535_snd_controls, 447 snd_soc_add_controls(codec, ak4535_snd_controls,
459 ARRAY_SIZE(ak4535_snd_controls)); 448 ARRAY_SIZE(ak4535_snd_controls));
460 ak4535_add_widgets(codec);
461
462 return 0; 449 return 0;
463} 450}
464 451
@@ -480,6 +467,10 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
480 .reg_cache_size = ARRAY_SIZE(ak4535_reg), 467 .reg_cache_size = ARRAY_SIZE(ak4535_reg),
481 .reg_word_size = sizeof(u8), 468 .reg_word_size = sizeof(u8),
482 .reg_cache_default = ak4535_reg, 469 .reg_cache_default = ak4535_reg,
470 .dapm_widgets = ak4535_dapm_widgets,
471 .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets),
472 .dapm_routes = ak4535_audio_map,
473 .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map),
483}; 474};
484 475
485#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 476#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
new file mode 100644
index 000000000000..ed96f247c2da
--- /dev/null
+++ b/sound/soc/codecs/ak4641.c
@@ -0,0 +1,664 @@
1/*
2 * ak4641.c -- AK4641 ALSA Soc Audio driver
3 *
4 * Copyright (C) 2008 Harald Welte <laforge@gnufiish.org>
5 * Copyright (C) 2011 Dmitry Artamonow <mad_soft@inbox.ru>
6 *
7 * Based on ak4535.c by Richard Purdie
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/gpio.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28#include <sound/ak4641.h>
29
30#include "ak4641.h"
31
32/* codec private data */
33struct ak4641_priv {
34 struct snd_soc_codec *codec;
35 unsigned int sysclk;
36 int deemph;
37 int playback_fs;
38};
39
40/*
41 * ak4641 register cache
42 */
43static const u8 ak4641_reg[AK4641_CACHEREGNUM] = {
44 0x00, 0x80, 0x00, 0x80,
45 0x02, 0x00, 0x11, 0x05,
46 0x00, 0x00, 0x36, 0x10,
47 0x00, 0x00, 0x57, 0x00,
48 0x88, 0x88, 0x08, 0x08
49};
50
51static const int deemph_settings[] = {44100, 0, 48000, 32000};
52
53static int ak4641_set_deemph(struct snd_soc_codec *codec)
54{
55 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
56 int i, best = 0;
57
58 for (i = 0 ; i < ARRAY_SIZE(deemph_settings); i++) {
59 /* if deemphasis is on, select the nearest available rate */
60 if (ak4641->deemph && deemph_settings[i] != 0 &&
61 abs(deemph_settings[i] - ak4641->playback_fs) <
62 abs(deemph_settings[best] - ak4641->playback_fs))
63 best = i;
64
65 if (!ak4641->deemph && deemph_settings[i] == 0)
66 best = i;
67 }
68
69 dev_dbg(codec->dev, "Set deemphasis %d\n", best);
70
71 return snd_soc_update_bits(codec, AK4641_DAC, 0x3, best);
72}
73
74static int ak4641_put_deemph(struct snd_kcontrol *kcontrol,
75 struct snd_ctl_elem_value *ucontrol)
76{
77 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
78 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
79 int deemph = ucontrol->value.enumerated.item[0];
80
81 if (deemph > 1)
82 return -EINVAL;
83
84 ak4641->deemph = deemph;
85
86 return ak4641_set_deemph(codec);
87}
88
89static int ak4641_get_deemph(struct snd_kcontrol *kcontrol,
90 struct snd_ctl_elem_value *ucontrol)
91{
92 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
93 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
94
95 ucontrol->value.enumerated.item[0] = ak4641->deemph;
96 return 0;
97};
98
99static const char *ak4641_mono_out[] = {"(L + R)/2", "Hi-Z"};
100static const char *ak4641_hp_out[] = {"Stereo", "Mono"};
101static const char *ak4641_mic_select[] = {"Internal", "External"};
102static const char *ak4641_mic_or_dac[] = {"Microphone", "Voice DAC"};
103
104
105static const DECLARE_TLV_DB_SCALE(mono_gain_tlv, -1700, 2300, 0);
106static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, 0, 2000, 0);
107static const DECLARE_TLV_DB_SCALE(eq_tlv, -1050, 150, 0);
108static const DECLARE_TLV_DB_SCALE(master_tlv, -12750, 50, 0);
109static const DECLARE_TLV_DB_SCALE(mic_stereo_sidetone_tlv, -2700, 300, 0);
110static const DECLARE_TLV_DB_SCALE(mic_mono_sidetone_tlv, -400, 400, 0);
111static const DECLARE_TLV_DB_SCALE(capture_tlv, -800, 50, 0);
112static const DECLARE_TLV_DB_SCALE(alc_tlv, -800, 50, 0);
113static const DECLARE_TLV_DB_SCALE(aux_in_tlv, -2100, 300, 0);
114
115
116static const struct soc_enum ak4641_mono_out_enum =
117 SOC_ENUM_SINGLE(AK4641_SIG1, 6, 2, ak4641_mono_out);
118static const struct soc_enum ak4641_hp_out_enum =
119 SOC_ENUM_SINGLE(AK4641_MODE2, 2, 2, ak4641_hp_out);
120static const struct soc_enum ak4641_mic_select_enum =
121 SOC_ENUM_SINGLE(AK4641_MIC, 1, 2, ak4641_mic_select);
122static const struct soc_enum ak4641_mic_or_dac_enum =
123 SOC_ENUM_SINGLE(AK4641_BTIF, 4, 2, ak4641_mic_or_dac);
124
125static const struct snd_kcontrol_new ak4641_snd_controls[] = {
126 SOC_ENUM("Mono 1 Output", ak4641_mono_out_enum),
127 SOC_SINGLE_TLV("Mono 1 Gain Volume", AK4641_SIG1, 7, 1, 1,
128 mono_gain_tlv),
129 SOC_ENUM("Headphone Output", ak4641_hp_out_enum),
130 SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
131 ak4641_get_deemph, ak4641_put_deemph),
132
133 SOC_SINGLE_TLV("Mic Boost Volume", AK4641_MIC, 0, 1, 0, mic_boost_tlv),
134
135 SOC_SINGLE("ALC Operation Time", AK4641_TIMER, 0, 3, 0),
136 SOC_SINGLE("ALC Recovery Time", AK4641_TIMER, 2, 3, 0),
137 SOC_SINGLE("ALC ZC Time", AK4641_TIMER, 4, 3, 0),
138
139 SOC_SINGLE("ALC 1 Switch", AK4641_ALC1, 5, 1, 0),
140
141 SOC_SINGLE_TLV("ALC Volume", AK4641_ALC2, 0, 71, 0, alc_tlv),
142 SOC_SINGLE("Left Out Enable Switch", AK4641_SIG2, 1, 1, 0),
143 SOC_SINGLE("Right Out Enable Switch", AK4641_SIG2, 0, 1, 0),
144
145 SOC_SINGLE_TLV("Capture Volume", AK4641_PGA, 0, 71, 0, capture_tlv),
146
147 SOC_DOUBLE_R_TLV("Master Playback Volume", AK4641_LATT,
148 AK4641_RATT, 0, 255, 1, master_tlv),
149
150 SOC_SINGLE_TLV("AUX In Volume", AK4641_VOL, 0, 15, 0, aux_in_tlv),
151
152 SOC_SINGLE("Equalizer Switch", AK4641_DAC, 2, 1, 0),
153 SOC_SINGLE_TLV("EQ1 100 Hz Volume", AK4641_EQLO, 0, 15, 1, eq_tlv),
154 SOC_SINGLE_TLV("EQ2 250 Hz Volume", AK4641_EQLO, 4, 15, 1, eq_tlv),
155 SOC_SINGLE_TLV("EQ3 1 kHz Volume", AK4641_EQMID, 0, 15, 1, eq_tlv),
156 SOC_SINGLE_TLV("EQ4 3.5 kHz Volume", AK4641_EQMID, 4, 15, 1, eq_tlv),
157 SOC_SINGLE_TLV("EQ5 10 kHz Volume", AK4641_EQHI, 0, 15, 1, eq_tlv),
158};
159
160/* Mono 1 Mixer */
161static const struct snd_kcontrol_new ak4641_mono1_mixer_controls[] = {
162 SOC_DAPM_SINGLE_TLV("Mic Mono Sidetone Volume", AK4641_VOL, 7, 1, 0,
163 mic_mono_sidetone_tlv),
164 SOC_DAPM_SINGLE("Mic Mono Sidetone Switch", AK4641_SIG1, 4, 1, 0),
165 SOC_DAPM_SINGLE("Mono Playback Switch", AK4641_SIG1, 5, 1, 0),
166};
167
168/* Stereo Mixer */
169static const struct snd_kcontrol_new ak4641_stereo_mixer_controls[] = {
170 SOC_DAPM_SINGLE_TLV("Mic Sidetone Volume", AK4641_VOL, 4, 7, 0,
171 mic_stereo_sidetone_tlv),
172 SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4641_SIG2, 4, 1, 0),
173 SOC_DAPM_SINGLE("Playback Switch", AK4641_SIG2, 7, 1, 0),
174 SOC_DAPM_SINGLE("Aux Bypass Switch", AK4641_SIG2, 5, 1, 0),
175};
176
177/* Input Mixer */
178static const struct snd_kcontrol_new ak4641_input_mixer_controls[] = {
179 SOC_DAPM_SINGLE("Mic Capture Switch", AK4641_MIC, 2, 1, 0),
180 SOC_DAPM_SINGLE("Aux Capture Switch", AK4641_MIC, 5, 1, 0),
181};
182
183/* Mic mux */
184static const struct snd_kcontrol_new ak4641_mic_mux_control =
185 SOC_DAPM_ENUM("Mic Select", ak4641_mic_select_enum);
186
187/* Input mux */
188static const struct snd_kcontrol_new ak4641_input_mux_control =
189 SOC_DAPM_ENUM("Input Select", ak4641_mic_or_dac_enum);
190
191/* mono 2 switch */
192static const struct snd_kcontrol_new ak4641_mono2_control =
193 SOC_DAPM_SINGLE("Switch", AK4641_SIG1, 0, 1, 0);
194
195/* ak4641 dapm widgets */
196static const struct snd_soc_dapm_widget ak4641_dapm_widgets[] = {
197 SND_SOC_DAPM_MIXER("Stereo Mixer", SND_SOC_NOPM, 0, 0,
198 &ak4641_stereo_mixer_controls[0],
199 ARRAY_SIZE(ak4641_stereo_mixer_controls)),
200 SND_SOC_DAPM_MIXER("Mono1 Mixer", SND_SOC_NOPM, 0, 0,
201 &ak4641_mono1_mixer_controls[0],
202 ARRAY_SIZE(ak4641_mono1_mixer_controls)),
203 SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM, 0, 0,
204 &ak4641_input_mixer_controls[0],
205 ARRAY_SIZE(ak4641_input_mixer_controls)),
206 SND_SOC_DAPM_MUX("Mic Mux", SND_SOC_NOPM, 0, 0,
207 &ak4641_mic_mux_control),
208 SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
209 &ak4641_input_mux_control),
210 SND_SOC_DAPM_SWITCH("Mono 2 Enable", SND_SOC_NOPM, 0, 0,
211 &ak4641_mono2_control),
212
213 SND_SOC_DAPM_OUTPUT("LOUT"),
214 SND_SOC_DAPM_OUTPUT("ROUT"),
215 SND_SOC_DAPM_OUTPUT("MOUT1"),
216 SND_SOC_DAPM_OUTPUT("MOUT2"),
217 SND_SOC_DAPM_OUTPUT("MICOUT"),
218
219 SND_SOC_DAPM_ADC("ADC", "HiFi Capture", AK4641_PM1, 0, 0),
220 SND_SOC_DAPM_PGA("Mic", AK4641_PM1, 1, 0, NULL, 0),
221 SND_SOC_DAPM_PGA("AUX In", AK4641_PM1, 2, 0, NULL, 0),
222 SND_SOC_DAPM_PGA("Mono Out", AK4641_PM1, 3, 0, NULL, 0),
223 SND_SOC_DAPM_PGA("Line Out", AK4641_PM1, 4, 0, NULL, 0),
224
225 SND_SOC_DAPM_DAC("DAC", "HiFi Playback", AK4641_PM2, 0, 0),
226 SND_SOC_DAPM_PGA("Mono Out 2", AK4641_PM2, 3, 0, NULL, 0),
227
228 SND_SOC_DAPM_ADC("Voice ADC", "Voice Capture", AK4641_BTIF, 0, 0),
229 SND_SOC_DAPM_ADC("Voice DAC", "Voice Playback", AK4641_BTIF, 1, 0),
230
231 SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4641_MIC, 3, 0),
232 SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4641_MIC, 4, 0),
233
234 SND_SOC_DAPM_INPUT("MICIN"),
235 SND_SOC_DAPM_INPUT("MICEXT"),
236 SND_SOC_DAPM_INPUT("AUX"),
237 SND_SOC_DAPM_INPUT("AIN"),
238};
239
240static const struct snd_soc_dapm_route ak4641_audio_map[] = {
241 /* Stereo Mixer */
242 {"Stereo Mixer", "Playback Switch", "DAC"},
243 {"Stereo Mixer", "Mic Sidetone Switch", "Input Mux"},
244 {"Stereo Mixer", "Aux Bypass Switch", "AUX In"},
245
246 /* Mono 1 Mixer */
247 {"Mono1 Mixer", "Mic Mono Sidetone Switch", "Input Mux"},
248 {"Mono1 Mixer", "Mono Playback Switch", "DAC"},
249
250 /* Mic */
251 {"Mic", NULL, "AIN"},
252 {"Mic Mux", "Internal", "Mic Int Bias"},
253 {"Mic Mux", "External", "Mic Ext Bias"},
254 {"Mic Int Bias", NULL, "MICIN"},
255 {"Mic Ext Bias", NULL, "MICEXT"},
256 {"MICOUT", NULL, "Mic Mux"},
257
258 /* Input Mux */
259 {"Input Mux", "Microphone", "Mic"},
260 {"Input Mux", "Voice DAC", "Voice DAC"},
261
262 /* Line Out */
263 {"LOUT", NULL, "Line Out"},
264 {"ROUT", NULL, "Line Out"},
265 {"Line Out", NULL, "Stereo Mixer"},
266
267 /* Mono 1 Out */
268 {"MOUT1", NULL, "Mono Out"},
269 {"Mono Out", NULL, "Mono1 Mixer"},
270
271 /* Mono 2 Out */
272 {"MOUT2", NULL, "Mono 2 Enable"},
273 {"Mono 2 Enable", "Switch", "Mono Out 2"},
274 {"Mono Out 2", NULL, "Stereo Mixer"},
275
276 {"Voice ADC", NULL, "Mono 2 Enable"},
277
278 /* Aux In */
279 {"AUX In", NULL, "AUX"},
280
281 /* ADC */
282 {"ADC", NULL, "Input Mixer"},
283 {"Input Mixer", "Mic Capture Switch", "Mic"},
284 {"Input Mixer", "Aux Capture Switch", "AUX In"},
285};
286
287static int ak4641_set_dai_sysclk(struct snd_soc_dai *codec_dai,
288 int clk_id, unsigned int freq, int dir)
289{
290 struct snd_soc_codec *codec = codec_dai->codec;
291 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
292
293 ak4641->sysclk = freq;
294 return 0;
295}
296
297static int ak4641_i2s_hw_params(struct snd_pcm_substream *substream,
298 struct snd_pcm_hw_params *params,
299 struct snd_soc_dai *dai)
300{
301 struct snd_soc_pcm_runtime *rtd = substream->private_data;
302 struct snd_soc_codec *codec = rtd->codec;
303 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
304 int rate = params_rate(params), fs = 256;
305 u8 mode2;
306
307 if (rate)
308 fs = ak4641->sysclk / rate;
309 else
310 return -EINVAL;
311
312 /* set fs */
313 switch (fs) {
314 case 1024:
315 mode2 = (0x2 << 5);
316 break;
317 case 512:
318 mode2 = (0x1 << 5);
319 break;
320 case 256:
321 mode2 = (0x0 << 5);
322 break;
323 default:
324 dev_err(codec->dev, "Error: unsupported fs=%d\n", fs);
325 return -EINVAL;
326 }
327
328 snd_soc_update_bits(codec, AK4641_MODE2, (0x3 << 5), mode2);
329
330 /* Update de-emphasis filter for the new rate */
331 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
332 ak4641->playback_fs = rate;
333 ak4641_set_deemph(codec);
334 };
335
336 return 0;
337}
338
339static int ak4641_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
340 unsigned int fmt)
341{
342 struct snd_soc_codec *codec = codec_dai->codec;
343 u8 btif;
344
345 /* interface format */
346 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
347 case SND_SOC_DAIFMT_I2S:
348 btif = (0x3 << 5);
349 break;
350 case SND_SOC_DAIFMT_LEFT_J:
351 btif = (0x2 << 5);
352 break;
353 case SND_SOC_DAIFMT_DSP_A: /* MSB after FRM */
354 btif = (0x0 << 5);
355 break;
356 case SND_SOC_DAIFMT_DSP_B: /* MSB during FRM */
357 btif = (0x1 << 5);
358 break;
359 default:
360 return -EINVAL;
361 }
362
363 return snd_soc_update_bits(codec, AK4641_BTIF, (0x3 << 5), btif);
364}
365
366static int ak4641_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
367 unsigned int fmt)
368{
369 struct snd_soc_codec *codec = codec_dai->codec;
370 u8 mode1 = 0;
371
372 /* interface format */
373 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
374 case SND_SOC_DAIFMT_I2S:
375 mode1 = 0x02;
376 break;
377 case SND_SOC_DAIFMT_LEFT_J:
378 mode1 = 0x01;
379 break;
380 default:
381 return -EINVAL;
382 }
383
384 return snd_soc_write(codec, AK4641_MODE1, mode1);
385}
386
387static int ak4641_mute(struct snd_soc_dai *dai, int mute)
388{
389 struct snd_soc_codec *codec = dai->codec;
390
391 return snd_soc_update_bits(codec, AK4641_DAC, 0x20, mute ? 0x20 : 0);
392}
393
394static int ak4641_set_bias_level(struct snd_soc_codec *codec,
395 enum snd_soc_bias_level level)
396{
397 struct ak4641_platform_data *pdata = codec->dev->platform_data;
398 int ret;
399
400 switch (level) {
401 case SND_SOC_BIAS_ON:
402 /* unmute */
403 snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0);
404 break;
405 case SND_SOC_BIAS_PREPARE:
406 /* mute */
407 snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0x20);
408 break;
409 case SND_SOC_BIAS_STANDBY:
410 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
411 if (pdata && gpio_is_valid(pdata->gpio_power))
412 gpio_set_value(pdata->gpio_power, 1);
413 mdelay(1);
414 if (pdata && gpio_is_valid(pdata->gpio_npdn))
415 gpio_set_value(pdata->gpio_npdn, 1);
416 mdelay(1);
417
418 ret = snd_soc_cache_sync(codec);
419 if (ret) {
420 dev_err(codec->dev,
421 "Failed to sync cache: %d\n", ret);
422 return ret;
423 }
424 }
425 snd_soc_update_bits(codec, AK4641_PM1, 0x80, 0x80);
426 snd_soc_update_bits(codec, AK4641_PM2, 0x80, 0);
427 break;
428 case SND_SOC_BIAS_OFF:
429 snd_soc_update_bits(codec, AK4641_PM1, 0x80, 0);
430 if (pdata && gpio_is_valid(pdata->gpio_npdn))
431 gpio_set_value(pdata->gpio_npdn, 0);
432 if (pdata && gpio_is_valid(pdata->gpio_power))
433 gpio_set_value(pdata->gpio_power, 0);
434 codec->cache_sync = 1;
435 break;
436 }
437 codec->dapm.bias_level = level;
438 return 0;
439}
440
441#define AK4641_RATES (SNDRV_PCM_RATE_8000_48000)
442#define AK4641_RATES_BT (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
443 SNDRV_PCM_RATE_16000)
444#define AK4641_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
445
446static struct snd_soc_dai_ops ak4641_i2s_dai_ops = {
447 .hw_params = ak4641_i2s_hw_params,
448 .set_fmt = ak4641_i2s_set_dai_fmt,
449 .digital_mute = ak4641_mute,
450 .set_sysclk = ak4641_set_dai_sysclk,
451};
452
453static struct snd_soc_dai_ops ak4641_pcm_dai_ops = {
454 .hw_params = NULL, /* rates are controlled by BT chip */
455 .set_fmt = ak4641_pcm_set_dai_fmt,
456 .digital_mute = ak4641_mute,
457 .set_sysclk = ak4641_set_dai_sysclk,
458};
459
460struct snd_soc_dai_driver ak4641_dai[] = {
461{
462 .name = "ak4641-hifi",
463 .id = 1,
464 .playback = {
465 .stream_name = "HiFi Playback",
466 .channels_min = 1,
467 .channels_max = 2,
468 .rates = AK4641_RATES,
469 .formats = AK4641_FORMATS,
470 },
471 .capture = {
472 .stream_name = "HiFi Capture",
473 .channels_min = 1,
474 .channels_max = 2,
475 .rates = AK4641_RATES,
476 .formats = AK4641_FORMATS,
477 },
478 .ops = &ak4641_i2s_dai_ops,
479 .symmetric_rates = 1,
480},
481{
482 .name = "ak4641-voice",
483 .id = 1,
484 .playback = {
485 .stream_name = "Voice Playback",
486 .channels_min = 1,
487 .channels_max = 1,
488 .rates = AK4641_RATES_BT,
489 .formats = AK4641_FORMATS,
490 },
491 .capture = {
492 .stream_name = "Voice Capture",
493 .channels_min = 1,
494 .channels_max = 1,
495 .rates = AK4641_RATES_BT,
496 .formats = AK4641_FORMATS,
497 },
498 .ops = &ak4641_pcm_dai_ops,
499 .symmetric_rates = 1,
500},
501};
502
503static int ak4641_suspend(struct snd_soc_codec *codec, pm_message_t state)
504{
505 ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF);
506 return 0;
507}
508
509static int ak4641_resume(struct snd_soc_codec *codec)
510{
511 ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
512 return 0;
513}
514
515static int ak4641_probe(struct snd_soc_codec *codec)
516{
517 struct ak4641_platform_data *pdata = codec->dev->platform_data;
518 int ret;
519
520
521 if (pdata) {
522 if (gpio_is_valid(pdata->gpio_power)) {
523 ret = gpio_request_one(pdata->gpio_power,
524 GPIOF_OUT_INIT_LOW, "ak4641 power");
525 if (ret)
526 goto err_out;
527 }
528 if (gpio_is_valid(pdata->gpio_npdn)) {
529 ret = gpio_request_one(pdata->gpio_npdn,
530 GPIOF_OUT_INIT_LOW, "ak4641 npdn");
531 if (ret)
532 goto err_gpio;
533
534 udelay(1); /* > 150 ns */
535 gpio_set_value(pdata->gpio_npdn, 1);
536 }
537 }
538
539 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
540 if (ret != 0) {
541 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
542 goto err_register;
543 }
544
545 /* power on device */
546 ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
547
548 return 0;
549
550err_register:
551 if (pdata) {
552 if (gpio_is_valid(pdata->gpio_power))
553 gpio_set_value(pdata->gpio_power, 0);
554 if (gpio_is_valid(pdata->gpio_npdn))
555 gpio_free(pdata->gpio_npdn);
556 }
557err_gpio:
558 if (pdata && gpio_is_valid(pdata->gpio_power))
559 gpio_free(pdata->gpio_power);
560err_out:
561 return ret;
562}
563
564static int ak4641_remove(struct snd_soc_codec *codec)
565{
566 struct ak4641_platform_data *pdata = codec->dev->platform_data;
567
568 ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF);
569
570 if (pdata) {
571 if (gpio_is_valid(pdata->gpio_power)) {
572 gpio_set_value(pdata->gpio_power, 0);
573 gpio_free(pdata->gpio_power);
574 }
575 if (gpio_is_valid(pdata->gpio_npdn))
576 gpio_free(pdata->gpio_npdn);
577 }
578 return 0;
579}
580
581
582static struct snd_soc_codec_driver soc_codec_dev_ak4641 = {
583 .probe = ak4641_probe,
584 .remove = ak4641_remove,
585 .suspend = ak4641_suspend,
586 .resume = ak4641_resume,
587 .controls = ak4641_snd_controls,
588 .num_controls = ARRAY_SIZE(ak4641_snd_controls),
589 .dapm_widgets = ak4641_dapm_widgets,
590 .num_dapm_widgets = ARRAY_SIZE(ak4641_dapm_widgets),
591 .dapm_routes = ak4641_audio_map,
592 .num_dapm_routes = ARRAY_SIZE(ak4641_audio_map),
593 .set_bias_level = ak4641_set_bias_level,
594 .reg_cache_size = ARRAY_SIZE(ak4641_reg),
595 .reg_word_size = sizeof(u8),
596 .reg_cache_default = ak4641_reg,
597 .reg_cache_step = 1,
598};
599
600
601static int __devinit ak4641_i2c_probe(struct i2c_client *i2c,
602 const struct i2c_device_id *id)
603{
604 struct ak4641_priv *ak4641;
605 int ret;
606
607 ak4641 = kzalloc(sizeof(struct ak4641_priv), GFP_KERNEL);
608 if (!ak4641)
609 return -ENOMEM;
610
611 i2c_set_clientdata(i2c, ak4641);
612
613 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4641,
614 ak4641_dai, ARRAY_SIZE(ak4641_dai));
615 if (ret < 0)
616 kfree(ak4641);
617
618 return ret;
619}
620
621static int __devexit ak4641_i2c_remove(struct i2c_client *i2c)
622{
623 snd_soc_unregister_codec(&i2c->dev);
624 kfree(i2c_get_clientdata(i2c));
625 return 0;
626}
627
628static const struct i2c_device_id ak4641_i2c_id[] = {
629 { "ak4641", 0 },
630 { }
631};
632MODULE_DEVICE_TABLE(i2c, ak4641_i2c_id);
633
634static struct i2c_driver ak4641_i2c_driver = {
635 .driver = {
636 .name = "ak4641",
637 .owner = THIS_MODULE,
638 },
639 .probe = ak4641_i2c_probe,
640 .remove = __devexit_p(ak4641_i2c_remove),
641 .id_table = ak4641_i2c_id,
642};
643
644static int __init ak4641_modinit(void)
645{
646 int ret;
647
648 ret = i2c_add_driver(&ak4641_i2c_driver);
649 if (ret != 0)
650 pr_err("Failed to register AK4641 I2C driver: %d\n", ret);
651
652 return ret;
653}
654module_init(ak4641_modinit);
655
656static void __exit ak4641_exit(void)
657{
658 i2c_del_driver(&ak4641_i2c_driver);
659}
660module_exit(ak4641_exit);
661
662MODULE_DESCRIPTION("SoC AK4641 driver");
663MODULE_AUTHOR("Harald Welte <laforge@gnufiish.org>");
664MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4641.h b/sound/soc/codecs/ak4641.h
new file mode 100644
index 000000000000..4a263248efea
--- /dev/null
+++ b/sound/soc/codecs/ak4641.h
@@ -0,0 +1,47 @@
1/*
2 * ak4641.h -- AK4641 SoC Audio driver
3 *
4 * Copyright 2008 Harald Welte <laforge@gnufiish.org>
5 *
6 * Based on ak4535.h
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _AK4641_H
14#define _AK4641_H
15
16/* AK4641 register space */
17
18#define AK4641_PM1 0x00
19#define AK4641_PM2 0x01
20#define AK4641_SIG1 0x02
21#define AK4641_SIG2 0x03
22#define AK4641_MODE1 0x04
23#define AK4641_MODE2 0x05
24#define AK4641_DAC 0x06
25#define AK4641_MIC 0x07
26#define AK4641_TIMER 0x08
27#define AK4641_ALC1 0x09
28#define AK4641_ALC2 0x0a
29#define AK4641_PGA 0x0b
30#define AK4641_LATT 0x0c
31#define AK4641_RATT 0x0d
32#define AK4641_VOL 0x0e
33#define AK4641_STATUS 0x0f
34#define AK4641_EQLO 0x10
35#define AK4641_EQMID 0x11
36#define AK4641_EQHI 0x12
37#define AK4641_BTIF 0x13
38
39#define AK4641_CACHEREGNUM 0x14
40
41
42
43#define AK4641_DAI_HIFI 0
44#define AK4641_DAI_VOICE 1
45
46
47#endif
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 2ec75abfa3e9..88b29f8c748b 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -352,7 +352,7 @@ static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = {
352 SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0), 352 SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0),
353}; 353};
354 354
355static const struct snd_soc_dapm_route intercon[] = { 355static const struct snd_soc_dapm_route ak4671_intercon[] = {
356 {"DAC Left", "NULL", "PMPLL"}, 356 {"DAC Left", "NULL", "PMPLL"},
357 {"DAC Right", "NULL", "PMPLL"}, 357 {"DAC Right", "NULL", "PMPLL"},
358 {"ADC Left", "NULL", "PMPLL"}, 358 {"ADC Left", "NULL", "PMPLL"},
@@ -433,17 +433,6 @@ static const struct snd_soc_dapm_route intercon[] = {
433 {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"}, 433 {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"},
434}; 434};
435 435
436static int ak4671_add_widgets(struct snd_soc_codec *codec)
437{
438 struct snd_soc_dapm_context *dapm = &codec->dapm;
439
440 snd_soc_dapm_new_controls(dapm, ak4671_dapm_widgets,
441 ARRAY_SIZE(ak4671_dapm_widgets));
442 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
443
444 return 0;
445}
446
447static int ak4671_hw_params(struct snd_pcm_substream *substream, 436static int ak4671_hw_params(struct snd_pcm_substream *substream,
448 struct snd_pcm_hw_params *params, 437 struct snd_pcm_hw_params *params,
449 struct snd_soc_dai *dai) 438 struct snd_soc_dai *dai)
@@ -650,7 +639,6 @@ static int ak4671_probe(struct snd_soc_codec *codec)
650 639
651 snd_soc_add_controls(codec, ak4671_snd_controls, 640 snd_soc_add_controls(codec, ak4671_snd_controls,
652 ARRAY_SIZE(ak4671_snd_controls)); 641 ARRAY_SIZE(ak4671_snd_controls));
653 ak4671_add_widgets(codec);
654 642
655 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 643 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
656 644
@@ -670,6 +658,10 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
670 .reg_cache_size = AK4671_CACHEREGNUM, 658 .reg_cache_size = AK4671_CACHEREGNUM,
671 .reg_word_size = sizeof(u8), 659 .reg_word_size = sizeof(u8),
672 .reg_cache_default = ak4671_reg, 660 .reg_cache_default = ak4671_reg,
661 .dapm_widgets = ak4671_dapm_widgets,
662 .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets),
663 .dapm_routes = ak4671_intercon,
664 .num_dapm_routes = ARRAY_SIZE(ak4671_intercon),
673}; 665};
674 666
675static int __devinit ak4671_i2c_probe(struct i2c_client *client, 667static int __devinit ak4671_i2c_probe(struct i2c_client *client,
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 0bb424af956f..d68ea532cc7f 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -86,18 +86,6 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = {
86 {"ADC", NULL, "Input Mixer"}, 86 {"ADC", NULL, "Input Mixer"},
87}; 87};
88 88
89static int cx20442_add_widgets(struct snd_soc_codec *codec)
90{
91 struct snd_soc_dapm_context *dapm = &codec->dapm;
92
93 snd_soc_dapm_new_controls(dapm, cx20442_dapm_widgets,
94 ARRAY_SIZE(cx20442_dapm_widgets));
95 snd_soc_dapm_add_routes(dapm, cx20442_audio_map,
96 ARRAY_SIZE(cx20442_audio_map));
97
98 return 0;
99}
100
101static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec, 89static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec,
102 unsigned int reg) 90 unsigned int reg)
103{ 91{
@@ -344,8 +332,6 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec)
344 return -ENOMEM; 332 return -ENOMEM;
345 snd_soc_codec_set_drvdata(codec, cx20442); 333 snd_soc_codec_set_drvdata(codec, cx20442);
346 334
347 cx20442_add_widgets(codec);
348
349 cx20442->control_data = NULL; 335 cx20442->control_data = NULL;
350 codec->hw_write = NULL; 336 codec->hw_write = NULL;
351 codec->card->pop_time = 0; 337 codec->card->pop_time = 0;
@@ -377,6 +363,10 @@ static struct snd_soc_codec_driver cx20442_codec_dev = {
377 .reg_word_size = sizeof(u8), 363 .reg_word_size = sizeof(u8),
378 .read = cx20442_read_reg_cache, 364 .read = cx20442_read_reg_cache,
379 .write = cx20442_write, 365 .write = cx20442_write,
366 .dapm_widgets = cx20442_dapm_widgets,
367 .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets),
368 .dapm_routes = cx20442_audio_map,
369 .num_dapm_routes = ARRAY_SIZE(cx20442_audio_map),
380}; 370};
381 371
382static int cx20442_platform_probe(struct platform_device *pdev) 372static int cx20442_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index 57e9dac88d38..f9a87737ec16 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -39,7 +39,31 @@ static struct snd_soc_dai_driver dmic_dai = {
39 }, 39 },
40}; 40};
41 41
42static struct snd_soc_codec_driver soc_dmic = {}; 42static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = {
43 SND_SOC_DAPM_AIF_OUT("DMIC AIF", "Capture", 0,
44 SND_SOC_NOPM, 0, 0),
45 SND_SOC_DAPM_INPUT("DMic"),
46};
47
48static const struct snd_soc_dapm_route intercon[] = {
49 {"DMIC AIF", NULL, "DMic"},
50};
51
52static int dmic_probe(struct snd_soc_codec *codec)
53{
54 struct snd_soc_dapm_context *dapm = &codec->dapm;
55
56 snd_soc_dapm_new_controls(dapm, dmic_dapm_widgets,
57 ARRAY_SIZE(dmic_dapm_widgets));
58 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
59 snd_soc_dapm_new_widgets(dapm);
60
61 return 0;
62}
63
64static struct snd_soc_codec_driver soc_dmic = {
65 .probe = dmic_probe,
66};
43 67
44static int __devinit dmic_dev_probe(struct platform_device *pdev) 68static int __devinit dmic_dev_probe(struct platform_device *pdev)
45{ 69{
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index f5ccdbf7ebc6..e373f8f06907 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -294,20 +294,9 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
294 294
295static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) 295static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
296{ 296{
297 struct snd_soc_dapm_context *dapm = &codec->dapm;
298
299 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, 297 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
300 JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); 298 JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
301 299
302 snd_soc_add_controls(codec, jz4740_codec_controls,
303 ARRAY_SIZE(jz4740_codec_controls));
304
305 snd_soc_dapm_new_controls(dapm, jz4740_codec_dapm_widgets,
306 ARRAY_SIZE(jz4740_codec_dapm_widgets));
307
308 snd_soc_dapm_add_routes(dapm, jz4740_codec_dapm_routes,
309 ARRAY_SIZE(jz4740_codec_dapm_routes));
310
311 jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 300 jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
312 301
313 return 0; 302 return 0;
@@ -348,6 +337,13 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
348 .reg_cache_default = jz4740_codec_regs, 337 .reg_cache_default = jz4740_codec_regs,
349 .reg_word_size = sizeof(u32), 338 .reg_word_size = sizeof(u32),
350 .reg_cache_size = 2, 339 .reg_cache_size = 2,
340
341 .controls = jz4740_codec_controls,
342 .num_controls = ARRAY_SIZE(jz4740_codec_controls),
343 .dapm_widgets = jz4740_codec_dapm_widgets,
344 .num_dapm_widgets = ARRAY_SIZE(jz4740_codec_dapm_widgets),
345 .dapm_routes = jz4740_codec_dapm_routes,
346 .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes),
351}; 347};
352 348
353static int __devinit jz4740_codec_probe(struct platform_device *pdev) 349static int __devinit jz4740_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index bd0517cb7980..4173b67c94d1 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -656,8 +656,6 @@ static const struct soc_enum max98088_exmode_enum =
656 ARRAY_SIZE(max98088_exmode_texts), 656 ARRAY_SIZE(max98088_exmode_texts),
657 max98088_exmode_texts, 657 max98088_exmode_texts,
658 max98088_exmode_values); 658 max98088_exmode_values);
659static const struct snd_kcontrol_new max98088_exmode_controls =
660 SOC_DAPM_VALUE_ENUM("Route", max98088_exmode_enum);
661 659
662static const char *max98088_ex_thresh[] = { /* volts PP */ 660static const char *max98088_ex_thresh[] = { /* volts PP */
663 "0.6", "1.2", "1.8", "2.4", "3.0", "3.6", "4.2", "4.8"}; 661 "0.6", "1.2", "1.8", "2.4", "3.0", "3.6", "4.2", "4.8"};
@@ -783,6 +781,7 @@ static const struct snd_kcontrol_new max98088_snd_controls[] = {
783 SOC_SINGLE("EQ1 Switch", M98088_REG_49_CFG_LEVEL, 0, 1, 0), 781 SOC_SINGLE("EQ1 Switch", M98088_REG_49_CFG_LEVEL, 0, 1, 0),
784 SOC_SINGLE("EQ2 Switch", M98088_REG_49_CFG_LEVEL, 1, 1, 0), 782 SOC_SINGLE("EQ2 Switch", M98088_REG_49_CFG_LEVEL, 1, 1, 0),
785 783
784 SOC_ENUM("EX Limiter Mode", max98088_exmode_enum),
786 SOC_ENUM("EX Limiter Threshold", max98088_ex_thresh_enum), 785 SOC_ENUM("EX Limiter Threshold", max98088_ex_thresh_enum),
787 786
788 SOC_ENUM("DAI1 Filter Mode", max98088_filter_mode_enum), 787 SOC_ENUM("DAI1 Filter Mode", max98088_filter_mode_enum),
@@ -808,10 +807,10 @@ static const struct snd_kcontrol_new max98088_snd_controls[] = {
808 807
809/* Left speaker mixer switch */ 808/* Left speaker mixer switch */
810static const struct snd_kcontrol_new max98088_left_speaker_mixer_controls[] = { 809static const struct snd_kcontrol_new max98088_left_speaker_mixer_controls[] = {
811 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0), 810 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0),
812 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0), 811 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0),
813 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0), 812 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0),
814 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0), 813 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0),
815 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 5, 1, 0), 814 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 5, 1, 0),
816 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 6, 1, 0), 815 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 6, 1, 0),
817 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 1, 1, 0), 816 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 1, 1, 0),
@@ -836,10 +835,10 @@ static const struct snd_kcontrol_new max98088_right_speaker_mixer_controls[] = {
836 835
837/* Left headphone mixer switch */ 836/* Left headphone mixer switch */
838static const struct snd_kcontrol_new max98088_left_hp_mixer_controls[] = { 837static const struct snd_kcontrol_new max98088_left_hp_mixer_controls[] = {
839 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0), 838 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0),
840 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0), 839 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0),
841 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0), 840 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0),
842 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0), 841 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0),
843 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_25_MIX_HP_LEFT, 5, 1, 0), 842 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_25_MIX_HP_LEFT, 5, 1, 0),
844 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_25_MIX_HP_LEFT, 6, 1, 0), 843 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_25_MIX_HP_LEFT, 6, 1, 0),
845 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_25_MIX_HP_LEFT, 1, 1, 0), 844 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_25_MIX_HP_LEFT, 1, 1, 0),
@@ -864,10 +863,10 @@ static const struct snd_kcontrol_new max98088_right_hp_mixer_controls[] = {
864 863
865/* Left earpiece/receiver mixer switch */ 864/* Left earpiece/receiver mixer switch */
866static const struct snd_kcontrol_new max98088_left_rec_mixer_controls[] = { 865static const struct snd_kcontrol_new max98088_left_rec_mixer_controls[] = {
867 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0), 866 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0),
868 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0), 867 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0),
869 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0), 868 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0),
870 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0), 869 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0),
871 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_28_MIX_REC_LEFT, 5, 1, 0), 870 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_28_MIX_REC_LEFT, 5, 1, 0),
872 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_28_MIX_REC_LEFT, 6, 1, 0), 871 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_28_MIX_REC_LEFT, 6, 1, 0),
873 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_28_MIX_REC_LEFT, 1, 1, 0), 872 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_28_MIX_REC_LEFT, 1, 1, 0),
@@ -1094,9 +1093,6 @@ static const struct snd_soc_dapm_widget max98088_dapm_widgets[] = {
1094 1093
1095 SND_SOC_DAPM_MICBIAS("MICBIAS", M98088_REG_4C_PWR_EN_IN, 3, 0), 1094 SND_SOC_DAPM_MICBIAS("MICBIAS", M98088_REG_4C_PWR_EN_IN, 3, 0),
1096 1095
1097 SND_SOC_DAPM_MUX("EX Limiter Mode", SND_SOC_NOPM, 0, 0,
1098 &max98088_exmode_controls),
1099
1100 SND_SOC_DAPM_OUTPUT("HPL"), 1096 SND_SOC_DAPM_OUTPUT("HPL"),
1101 SND_SOC_DAPM_OUTPUT("HPR"), 1097 SND_SOC_DAPM_OUTPUT("HPR"),
1102 SND_SOC_DAPM_OUTPUT("SPKL"), 1098 SND_SOC_DAPM_OUTPUT("SPKL"),
@@ -1112,7 +1108,7 @@ static const struct snd_soc_dapm_widget max98088_dapm_widgets[] = {
1112 SND_SOC_DAPM_INPUT("INB2"), 1108 SND_SOC_DAPM_INPUT("INB2"),
1113}; 1109};
1114 1110
1115static const struct snd_soc_dapm_route audio_map[] = { 1111static const struct snd_soc_dapm_route max98088_audio_map[] = {
1116 /* Left headphone output mixer */ 1112 /* Left headphone output mixer */
1117 {"Left HP Mixer", "Left DAC1 Switch", "DACL1"}, 1113 {"Left HP Mixer", "Left DAC1 Switch", "DACL1"},
1118 {"Left HP Mixer", "Left DAC2 Switch", "DACL2"}, 1114 {"Left HP Mixer", "Left DAC2 Switch", "DACL2"},
@@ -1226,22 +1222,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
1226 {"MIC2 Input", NULL, "MIC2"}, 1222 {"MIC2 Input", NULL, "MIC2"},
1227}; 1223};
1228 1224
1229static int max98088_add_widgets(struct snd_soc_codec *codec)
1230{
1231 struct snd_soc_dapm_context *dapm = &codec->dapm;
1232
1233 snd_soc_dapm_new_controls(dapm, max98088_dapm_widgets,
1234 ARRAY_SIZE(max98088_dapm_widgets));
1235
1236 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
1237
1238 snd_soc_add_controls(codec, max98088_snd_controls,
1239 ARRAY_SIZE(max98088_snd_controls));
1240
1241 snd_soc_dapm_new_widgets(dapm);
1242 return 0;
1243}
1244
1245/* codec mclk clock divider coefficients */ 1225/* codec mclk clock divider coefficients */
1246static const struct { 1226static const struct {
1247 u32 rate; 1227 u32 rate;
@@ -1586,6 +1566,36 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
1586 return 0; 1566 return 0;
1587} 1567}
1588 1568
1569static int max98088_dai1_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1570{
1571 struct snd_soc_codec *codec = codec_dai->codec;
1572 int reg;
1573
1574 if (mute)
1575 reg = M98088_DAI_MUTE;
1576 else
1577 reg = 0;
1578
1579 snd_soc_update_bits(codec, M98088_REG_2F_LVL_DAI1_PLAY,
1580 M98088_DAI_MUTE_MASK, reg);
1581 return 0;
1582}
1583
1584static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1585{
1586 struct snd_soc_codec *codec = codec_dai->codec;
1587 int reg;
1588
1589 if (mute)
1590 reg = M98088_DAI_MUTE;
1591 else
1592 reg = 0;
1593
1594 snd_soc_update_bits(codec, M98088_REG_31_LVL_DAI2_PLAY,
1595 M98088_DAI_MUTE_MASK, reg);
1596 return 0;
1597}
1598
1589static void max98088_sync_cache(struct snd_soc_codec *codec) 1599static void max98088_sync_cache(struct snd_soc_codec *codec)
1590{ 1600{
1591 u16 *reg_cache = codec->reg_cache; 1601 u16 *reg_cache = codec->reg_cache;
@@ -1647,12 +1657,14 @@ static struct snd_soc_dai_ops max98088_dai1_ops = {
1647 .set_sysclk = max98088_dai_set_sysclk, 1657 .set_sysclk = max98088_dai_set_sysclk,
1648 .set_fmt = max98088_dai1_set_fmt, 1658 .set_fmt = max98088_dai1_set_fmt,
1649 .hw_params = max98088_dai1_hw_params, 1659 .hw_params = max98088_dai1_hw_params,
1660 .digital_mute = max98088_dai1_digital_mute,
1650}; 1661};
1651 1662
1652static struct snd_soc_dai_ops max98088_dai2_ops = { 1663static struct snd_soc_dai_ops max98088_dai2_ops = {
1653 .set_sysclk = max98088_dai_set_sysclk, 1664 .set_sysclk = max98088_dai_set_sysclk,
1654 .set_fmt = max98088_dai2_set_fmt, 1665 .set_fmt = max98088_dai2_set_fmt,
1655 .hw_params = max98088_dai2_hw_params, 1666 .hw_params = max98088_dai2_hw_params,
1667 .digital_mute = max98088_dai2_digital_mute,
1656}; 1668};
1657 1669
1658static struct snd_soc_dai_driver max98088_dai[] = { 1670static struct snd_soc_dai_driver max98088_dai[] = {
@@ -2010,7 +2022,8 @@ static int max98088_probe(struct snd_soc_codec *codec)
2010 2022
2011 max98088_handle_pdata(codec); 2023 max98088_handle_pdata(codec);
2012 2024
2013 max98088_add_widgets(codec); 2025 snd_soc_add_controls(codec, max98088_snd_controls,
2026 ARRAY_SIZE(max98088_snd_controls));
2014 2027
2015err_access: 2028err_access:
2016 return ret; 2029 return ret;
@@ -2036,6 +2049,10 @@ static struct snd_soc_codec_driver soc_codec_dev_max98088 = {
2036 .reg_word_size = sizeof(u8), 2049 .reg_word_size = sizeof(u8),
2037 .reg_cache_default = max98088_reg, 2050 .reg_cache_default = max98088_reg,
2038 .volatile_register = max98088_volatile_register, 2051 .volatile_register = max98088_volatile_register,
2052 .dapm_widgets = max98088_dapm_widgets,
2053 .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets),
2054 .dapm_routes = max98088_audio_map,
2055 .num_dapm_routes = ARRAY_SIZE(max98088_audio_map),
2039}; 2056};
2040 2057
2041static int max98088_i2c_probe(struct i2c_client *i2c, 2058static int max98088_i2c_probe(struct i2c_client *i2c,
diff --git a/sound/soc/codecs/max98088.h b/sound/soc/codecs/max98088.h
index 56554c797fef..be89a4f4aab8 100644
--- a/sound/soc/codecs/max98088.h
+++ b/sound/soc/codecs/max98088.h
@@ -133,6 +133,19 @@
133 #define M98088_REC_LINEMODE (1<<7) 133 #define M98088_REC_LINEMODE (1<<7)
134 #define M98088_REC_LINEMODE_MASK (1<<7) 134 #define M98088_REC_LINEMODE_MASK (1<<7)
135 135
136/* M98088_REG_2D_MIX_SPK_CNTL */
137 #define M98088_MIX_SPKR_GAIN_MASK (3<<2)
138 #define M98088_MIX_SPKR_GAIN_SHIFT 2
139 #define M98088_MIX_SPKL_GAIN_MASK (3<<0)
140 #define M98088_MIX_SPKL_GAIN_SHIFT 0
141
142/* M98088_REG_2F_LVL_DAI1_PLAY, M98088_REG_31_LVL_DAI2_PLAY */
143 #define M98088_DAI_MUTE (1<<7)
144 #define M98088_DAI_MUTE_MASK (1<<7)
145 #define M98088_DAI_VOICE_GAIN_MASK (3<<4)
146 #define M98088_DAI_ATTENUATION_MASK (0xF<<0)
147 #define M98088_DAI_ATTENUATION_SHIFT 0
148
136/* M98088_REG_35_LVL_MIC1, M98088_REG_36_LVL_MIC2 */ 149/* M98088_REG_35_LVL_MIC1, M98088_REG_36_LVL_MIC2 */
137 #define M98088_MICPRE_MASK (3<<5) 150 #define M98088_MICPRE_MASK (3<<5)
138 #define M98088_MICPRE_SHIFT 5 151 #define M98088_MICPRE_SHIFT 5
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
new file mode 100644
index 000000000000..e1d282d477da
--- /dev/null
+++ b/sound/soc/codecs/max98095.c
@@ -0,0 +1,2396 @@
1/*
2 * max98095.c -- MAX98095 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/delay.h>
16#include <linux/pm.h>
17#include <linux/i2c.h>
18#include <linux/platform_device.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h>
23#include <sound/initval.h>
24#include <sound/tlv.h>
25#include <linux/slab.h>
26#include <asm/div64.h>
27#include <sound/max98095.h>
28#include "max98095.h"
29
30enum max98095_type {
31 MAX98095,
32};
33
34struct max98095_cdata {
35 unsigned int rate;
36 unsigned int fmt;
37 int eq_sel;
38 int bq_sel;
39};
40
41struct max98095_priv {
42 enum max98095_type devtype;
43 void *control_data;
44 struct max98095_pdata *pdata;
45 unsigned int sysclk;
46 struct max98095_cdata dai[3];
47 const char **eq_texts;
48 const char **bq_texts;
49 struct soc_enum eq_enum;
50 struct soc_enum bq_enum;
51 int eq_textcnt;
52 int bq_textcnt;
53 u8 lin_state;
54 unsigned int mic1pre;
55 unsigned int mic2pre;
56};
57
58static const u8 max98095_reg_def[M98095_REG_CNT] = {
59 0x00, /* 00 */
60 0x00, /* 01 */
61 0x00, /* 02 */
62 0x00, /* 03 */
63 0x00, /* 04 */
64 0x00, /* 05 */
65 0x00, /* 06 */
66 0x00, /* 07 */
67 0x00, /* 08 */
68 0x00, /* 09 */
69 0x00, /* 0A */
70 0x00, /* 0B */
71 0x00, /* 0C */
72 0x00, /* 0D */
73 0x00, /* 0E */
74 0x00, /* 0F */
75 0x00, /* 10 */
76 0x00, /* 11 */
77 0x00, /* 12 */
78 0x00, /* 13 */
79 0x00, /* 14 */
80 0x00, /* 15 */
81 0x00, /* 16 */
82 0x00, /* 17 */
83 0x00, /* 18 */
84 0x00, /* 19 */
85 0x00, /* 1A */
86 0x00, /* 1B */
87 0x00, /* 1C */
88 0x00, /* 1D */
89 0x00, /* 1E */
90 0x00, /* 1F */
91 0x00, /* 20 */
92 0x00, /* 21 */
93 0x00, /* 22 */
94 0x00, /* 23 */
95 0x00, /* 24 */
96 0x00, /* 25 */
97 0x00, /* 26 */
98 0x00, /* 27 */
99 0x00, /* 28 */
100 0x00, /* 29 */
101 0x00, /* 2A */
102 0x00, /* 2B */
103 0x00, /* 2C */
104 0x00, /* 2D */
105 0x00, /* 2E */
106 0x00, /* 2F */
107 0x00, /* 30 */
108 0x00, /* 31 */
109 0x00, /* 32 */
110 0x00, /* 33 */
111 0x00, /* 34 */
112 0x00, /* 35 */
113 0x00, /* 36 */
114 0x00, /* 37 */
115 0x00, /* 38 */
116 0x00, /* 39 */
117 0x00, /* 3A */
118 0x00, /* 3B */
119 0x00, /* 3C */
120 0x00, /* 3D */
121 0x00, /* 3E */
122 0x00, /* 3F */
123 0x00, /* 40 */
124 0x00, /* 41 */
125 0x00, /* 42 */
126 0x00, /* 43 */
127 0x00, /* 44 */
128 0x00, /* 45 */
129 0x00, /* 46 */
130 0x00, /* 47 */
131 0x00, /* 48 */
132 0x00, /* 49 */
133 0x00, /* 4A */
134 0x00, /* 4B */
135 0x00, /* 4C */
136 0x00, /* 4D */
137 0x00, /* 4E */
138 0x00, /* 4F */
139 0x00, /* 50 */
140 0x00, /* 51 */
141 0x00, /* 52 */
142 0x00, /* 53 */
143 0x00, /* 54 */
144 0x00, /* 55 */
145 0x00, /* 56 */
146 0x00, /* 57 */
147 0x00, /* 58 */
148 0x00, /* 59 */
149 0x00, /* 5A */
150 0x00, /* 5B */
151 0x00, /* 5C */
152 0x00, /* 5D */
153 0x00, /* 5E */
154 0x00, /* 5F */
155 0x00, /* 60 */
156 0x00, /* 61 */
157 0x00, /* 62 */
158 0x00, /* 63 */
159 0x00, /* 64 */
160 0x00, /* 65 */
161 0x00, /* 66 */
162 0x00, /* 67 */
163 0x00, /* 68 */
164 0x00, /* 69 */
165 0x00, /* 6A */
166 0x00, /* 6B */
167 0x00, /* 6C */
168 0x00, /* 6D */
169 0x00, /* 6E */
170 0x00, /* 6F */
171 0x00, /* 70 */
172 0x00, /* 71 */
173 0x00, /* 72 */
174 0x00, /* 73 */
175 0x00, /* 74 */
176 0x00, /* 75 */
177 0x00, /* 76 */
178 0x00, /* 77 */
179 0x00, /* 78 */
180 0x00, /* 79 */
181 0x00, /* 7A */
182 0x00, /* 7B */
183 0x00, /* 7C */
184 0x00, /* 7D */
185 0x00, /* 7E */
186 0x00, /* 7F */
187 0x00, /* 80 */
188 0x00, /* 81 */
189 0x00, /* 82 */
190 0x00, /* 83 */
191 0x00, /* 84 */
192 0x00, /* 85 */
193 0x00, /* 86 */
194 0x00, /* 87 */
195 0x00, /* 88 */
196 0x00, /* 89 */
197 0x00, /* 8A */
198 0x00, /* 8B */
199 0x00, /* 8C */
200 0x00, /* 8D */
201 0x00, /* 8E */
202 0x00, /* 8F */
203 0x00, /* 90 */
204 0x00, /* 91 */
205 0x30, /* 92 */
206 0xF0, /* 93 */
207 0x00, /* 94 */
208 0x00, /* 95 */
209 0x3F, /* 96 */
210 0x00, /* 97 */
211 0x00, /* 98 */
212 0x00, /* 99 */
213 0x00, /* 9A */
214 0x00, /* 9B */
215 0x00, /* 9C */
216 0x00, /* 9D */
217 0x00, /* 9E */
218 0x00, /* 9F */
219 0x00, /* A0 */
220 0x00, /* A1 */
221 0x00, /* A2 */
222 0x00, /* A3 */
223 0x00, /* A4 */
224 0x00, /* A5 */
225 0x00, /* A6 */
226 0x00, /* A7 */
227 0x00, /* A8 */
228 0x00, /* A9 */
229 0x00, /* AA */
230 0x00, /* AB */
231 0x00, /* AC */
232 0x00, /* AD */
233 0x00, /* AE */
234 0x00, /* AF */
235 0x00, /* B0 */
236 0x00, /* B1 */
237 0x00, /* B2 */
238 0x00, /* B3 */
239 0x00, /* B4 */
240 0x00, /* B5 */
241 0x00, /* B6 */
242 0x00, /* B7 */
243 0x00, /* B8 */
244 0x00, /* B9 */
245 0x00, /* BA */
246 0x00, /* BB */
247 0x00, /* BC */
248 0x00, /* BD */
249 0x00, /* BE */
250 0x00, /* BF */
251 0x00, /* C0 */
252 0x00, /* C1 */
253 0x00, /* C2 */
254 0x00, /* C3 */
255 0x00, /* C4 */
256 0x00, /* C5 */
257 0x00, /* C6 */
258 0x00, /* C7 */
259 0x00, /* C8 */
260 0x00, /* C9 */
261 0x00, /* CA */
262 0x00, /* CB */
263 0x00, /* CC */
264 0x00, /* CD */
265 0x00, /* CE */
266 0x00, /* CF */
267 0x00, /* D0 */
268 0x00, /* D1 */
269 0x00, /* D2 */
270 0x00, /* D3 */
271 0x00, /* D4 */
272 0x00, /* D5 */
273 0x00, /* D6 */
274 0x00, /* D7 */
275 0x00, /* D8 */
276 0x00, /* D9 */
277 0x00, /* DA */
278 0x00, /* DB */
279 0x00, /* DC */
280 0x00, /* DD */
281 0x00, /* DE */
282 0x00, /* DF */
283 0x00, /* E0 */
284 0x00, /* E1 */
285 0x00, /* E2 */
286 0x00, /* E3 */
287 0x00, /* E4 */
288 0x00, /* E5 */
289 0x00, /* E6 */
290 0x00, /* E7 */
291 0x00, /* E8 */
292 0x00, /* E9 */
293 0x00, /* EA */
294 0x00, /* EB */
295 0x00, /* EC */
296 0x00, /* ED */
297 0x00, /* EE */
298 0x00, /* EF */
299 0x00, /* F0 */
300 0x00, /* F1 */
301 0x00, /* F2 */
302 0x00, /* F3 */
303 0x00, /* F4 */
304 0x00, /* F5 */
305 0x00, /* F6 */
306 0x00, /* F7 */
307 0x00, /* F8 */
308 0x00, /* F9 */
309 0x00, /* FA */
310 0x00, /* FB */
311 0x00, /* FC */
312 0x00, /* FD */
313 0x00, /* FE */
314 0x00, /* FF */
315};
316
317static struct {
318 int readable;
319 int writable;
320} max98095_access[M98095_REG_CNT] = {
321 { 0x00, 0x00 }, /* 00 */
322 { 0xFF, 0x00 }, /* 01 */
323 { 0xFF, 0x00 }, /* 02 */
324 { 0xFF, 0x00 }, /* 03 */
325 { 0xFF, 0x00 }, /* 04 */
326 { 0xFF, 0x00 }, /* 05 */
327 { 0xFF, 0x00 }, /* 06 */
328 { 0xFF, 0x00 }, /* 07 */
329 { 0xFF, 0x00 }, /* 08 */
330 { 0xFF, 0x00 }, /* 09 */
331 { 0xFF, 0x00 }, /* 0A */
332 { 0xFF, 0x00 }, /* 0B */
333 { 0xFF, 0x00 }, /* 0C */
334 { 0xFF, 0x00 }, /* 0D */
335 { 0xFF, 0x00 }, /* 0E */
336 { 0xFF, 0x9F }, /* 0F */
337 { 0xFF, 0xFF }, /* 10 */
338 { 0xFF, 0xFF }, /* 11 */
339 { 0xFF, 0xFF }, /* 12 */
340 { 0xFF, 0xFF }, /* 13 */
341 { 0xFF, 0xFF }, /* 14 */
342 { 0xFF, 0xFF }, /* 15 */
343 { 0xFF, 0xFF }, /* 16 */
344 { 0xFF, 0xFF }, /* 17 */
345 { 0xFF, 0xFF }, /* 18 */
346 { 0xFF, 0xFF }, /* 19 */
347 { 0xFF, 0xFF }, /* 1A */
348 { 0xFF, 0xFF }, /* 1B */
349 { 0xFF, 0xFF }, /* 1C */
350 { 0xFF, 0xFF }, /* 1D */
351 { 0xFF, 0x77 }, /* 1E */
352 { 0xFF, 0x77 }, /* 1F */
353 { 0xFF, 0x77 }, /* 20 */
354 { 0xFF, 0x77 }, /* 21 */
355 { 0xFF, 0x77 }, /* 22 */
356 { 0xFF, 0x77 }, /* 23 */
357 { 0xFF, 0xFF }, /* 24 */
358 { 0xFF, 0x7F }, /* 25 */
359 { 0xFF, 0x31 }, /* 26 */
360 { 0xFF, 0xFF }, /* 27 */
361 { 0xFF, 0xFF }, /* 28 */
362 { 0xFF, 0xFF }, /* 29 */
363 { 0xFF, 0xF7 }, /* 2A */
364 { 0xFF, 0x2F }, /* 2B */
365 { 0xFF, 0xEF }, /* 2C */
366 { 0xFF, 0xFF }, /* 2D */
367 { 0xFF, 0xFF }, /* 2E */
368 { 0xFF, 0xFF }, /* 2F */
369 { 0xFF, 0xFF }, /* 30 */
370 { 0xFF, 0xFF }, /* 31 */
371 { 0xFF, 0xFF }, /* 32 */
372 { 0xFF, 0xFF }, /* 33 */
373 { 0xFF, 0xF7 }, /* 34 */
374 { 0xFF, 0x2F }, /* 35 */
375 { 0xFF, 0xCF }, /* 36 */
376 { 0xFF, 0xFF }, /* 37 */
377 { 0xFF, 0xFF }, /* 38 */
378 { 0xFF, 0xFF }, /* 39 */
379 { 0xFF, 0xFF }, /* 3A */
380 { 0xFF, 0xFF }, /* 3B */
381 { 0xFF, 0xFF }, /* 3C */
382 { 0xFF, 0xFF }, /* 3D */
383 { 0xFF, 0xF7 }, /* 3E */
384 { 0xFF, 0x2F }, /* 3F */
385 { 0xFF, 0xCF }, /* 40 */
386 { 0xFF, 0xFF }, /* 41 */
387 { 0xFF, 0x77 }, /* 42 */
388 { 0xFF, 0xFF }, /* 43 */
389 { 0xFF, 0xFF }, /* 44 */
390 { 0xFF, 0xFF }, /* 45 */
391 { 0xFF, 0xFF }, /* 46 */
392 { 0xFF, 0xFF }, /* 47 */
393 { 0xFF, 0xFF }, /* 48 */
394 { 0xFF, 0x0F }, /* 49 */
395 { 0xFF, 0xFF }, /* 4A */
396 { 0xFF, 0xFF }, /* 4B */
397 { 0xFF, 0x3F }, /* 4C */
398 { 0xFF, 0x3F }, /* 4D */
399 { 0xFF, 0x3F }, /* 4E */
400 { 0xFF, 0xFF }, /* 4F */
401 { 0xFF, 0x7F }, /* 50 */
402 { 0xFF, 0x7F }, /* 51 */
403 { 0xFF, 0x0F }, /* 52 */
404 { 0xFF, 0x3F }, /* 53 */
405 { 0xFF, 0x3F }, /* 54 */
406 { 0xFF, 0x3F }, /* 55 */
407 { 0xFF, 0xFF }, /* 56 */
408 { 0xFF, 0xFF }, /* 57 */
409 { 0xFF, 0xBF }, /* 58 */
410 { 0xFF, 0x1F }, /* 59 */
411 { 0xFF, 0xBF }, /* 5A */
412 { 0xFF, 0x1F }, /* 5B */
413 { 0xFF, 0xBF }, /* 5C */
414 { 0xFF, 0x3F }, /* 5D */
415 { 0xFF, 0x3F }, /* 5E */
416 { 0xFF, 0x7F }, /* 5F */
417 { 0xFF, 0x7F }, /* 60 */
418 { 0xFF, 0x47 }, /* 61 */
419 { 0xFF, 0x9F }, /* 62 */
420 { 0xFF, 0x9F }, /* 63 */
421 { 0xFF, 0x9F }, /* 64 */
422 { 0xFF, 0x9F }, /* 65 */
423 { 0xFF, 0x9F }, /* 66 */
424 { 0xFF, 0xBF }, /* 67 */
425 { 0xFF, 0xBF }, /* 68 */
426 { 0xFF, 0xFF }, /* 69 */
427 { 0xFF, 0xFF }, /* 6A */
428 { 0xFF, 0x7F }, /* 6B */
429 { 0xFF, 0xF7 }, /* 6C */
430 { 0xFF, 0xFF }, /* 6D */
431 { 0xFF, 0xFF }, /* 6E */
432 { 0xFF, 0x1F }, /* 6F */
433 { 0xFF, 0xF7 }, /* 70 */
434 { 0xFF, 0xFF }, /* 71 */
435 { 0xFF, 0xFF }, /* 72 */
436 { 0xFF, 0x1F }, /* 73 */
437 { 0xFF, 0xF7 }, /* 74 */
438 { 0xFF, 0xFF }, /* 75 */
439 { 0xFF, 0xFF }, /* 76 */
440 { 0xFF, 0x1F }, /* 77 */
441 { 0xFF, 0xF7 }, /* 78 */
442 { 0xFF, 0xFF }, /* 79 */
443 { 0xFF, 0xFF }, /* 7A */
444 { 0xFF, 0x1F }, /* 7B */
445 { 0xFF, 0xF7 }, /* 7C */
446 { 0xFF, 0xFF }, /* 7D */
447 { 0xFF, 0xFF }, /* 7E */
448 { 0xFF, 0x1F }, /* 7F */
449 { 0xFF, 0xF7 }, /* 80 */
450 { 0xFF, 0xFF }, /* 81 */
451 { 0xFF, 0xFF }, /* 82 */
452 { 0xFF, 0x1F }, /* 83 */
453 { 0xFF, 0x7F }, /* 84 */
454 { 0xFF, 0x0F }, /* 85 */
455 { 0xFF, 0xD8 }, /* 86 */
456 { 0xFF, 0xFF }, /* 87 */
457 { 0xFF, 0xEF }, /* 88 */
458 { 0xFF, 0xFE }, /* 89 */
459 { 0xFF, 0xFE }, /* 8A */
460 { 0xFF, 0xFF }, /* 8B */
461 { 0xFF, 0xFF }, /* 8C */
462 { 0xFF, 0x3F }, /* 8D */
463 { 0xFF, 0xFF }, /* 8E */
464 { 0xFF, 0x3F }, /* 8F */
465 { 0xFF, 0x8F }, /* 90 */
466 { 0xFF, 0xFF }, /* 91 */
467 { 0xFF, 0x3F }, /* 92 */
468 { 0xFF, 0xFF }, /* 93 */
469 { 0xFF, 0xFF }, /* 94 */
470 { 0xFF, 0x0F }, /* 95 */
471 { 0xFF, 0x3F }, /* 96 */
472 { 0xFF, 0x8C }, /* 97 */
473 { 0x00, 0x00 }, /* 98 */
474 { 0x00, 0x00 }, /* 99 */
475 { 0x00, 0x00 }, /* 9A */
476 { 0x00, 0x00 }, /* 9B */
477 { 0x00, 0x00 }, /* 9C */
478 { 0x00, 0x00 }, /* 9D */
479 { 0x00, 0x00 }, /* 9E */
480 { 0x00, 0x00 }, /* 9F */
481 { 0x00, 0x00 }, /* A0 */
482 { 0x00, 0x00 }, /* A1 */
483 { 0x00, 0x00 }, /* A2 */
484 { 0x00, 0x00 }, /* A3 */
485 { 0x00, 0x00 }, /* A4 */
486 { 0x00, 0x00 }, /* A5 */
487 { 0x00, 0x00 }, /* A6 */
488 { 0x00, 0x00 }, /* A7 */
489 { 0x00, 0x00 }, /* A8 */
490 { 0x00, 0x00 }, /* A9 */
491 { 0x00, 0x00 }, /* AA */
492 { 0x00, 0x00 }, /* AB */
493 { 0x00, 0x00 }, /* AC */
494 { 0x00, 0x00 }, /* AD */
495 { 0x00, 0x00 }, /* AE */
496 { 0x00, 0x00 }, /* AF */
497 { 0x00, 0x00 }, /* B0 */
498 { 0x00, 0x00 }, /* B1 */
499 { 0x00, 0x00 }, /* B2 */
500 { 0x00, 0x00 }, /* B3 */
501 { 0x00, 0x00 }, /* B4 */
502 { 0x00, 0x00 }, /* B5 */
503 { 0x00, 0x00 }, /* B6 */
504 { 0x00, 0x00 }, /* B7 */
505 { 0x00, 0x00 }, /* B8 */
506 { 0x00, 0x00 }, /* B9 */
507 { 0x00, 0x00 }, /* BA */
508 { 0x00, 0x00 }, /* BB */
509 { 0x00, 0x00 }, /* BC */
510 { 0x00, 0x00 }, /* BD */
511 { 0x00, 0x00 }, /* BE */
512 { 0x00, 0x00 }, /* BF */
513 { 0x00, 0x00 }, /* C0 */
514 { 0x00, 0x00 }, /* C1 */
515 { 0x00, 0x00 }, /* C2 */
516 { 0x00, 0x00 }, /* C3 */
517 { 0x00, 0x00 }, /* C4 */
518 { 0x00, 0x00 }, /* C5 */
519 { 0x00, 0x00 }, /* C6 */
520 { 0x00, 0x00 }, /* C7 */
521 { 0x00, 0x00 }, /* C8 */
522 { 0x00, 0x00 }, /* C9 */
523 { 0x00, 0x00 }, /* CA */
524 { 0x00, 0x00 }, /* CB */
525 { 0x00, 0x00 }, /* CC */
526 { 0x00, 0x00 }, /* CD */
527 { 0x00, 0x00 }, /* CE */
528 { 0x00, 0x00 }, /* CF */
529 { 0x00, 0x00 }, /* D0 */
530 { 0x00, 0x00 }, /* D1 */
531 { 0x00, 0x00 }, /* D2 */
532 { 0x00, 0x00 }, /* D3 */
533 { 0x00, 0x00 }, /* D4 */
534 { 0x00, 0x00 }, /* D5 */
535 { 0x00, 0x00 }, /* D6 */
536 { 0x00, 0x00 }, /* D7 */
537 { 0x00, 0x00 }, /* D8 */
538 { 0x00, 0x00 }, /* D9 */
539 { 0x00, 0x00 }, /* DA */
540 { 0x00, 0x00 }, /* DB */
541 { 0x00, 0x00 }, /* DC */
542 { 0x00, 0x00 }, /* DD */
543 { 0x00, 0x00 }, /* DE */
544 { 0x00, 0x00 }, /* DF */
545 { 0x00, 0x00 }, /* E0 */
546 { 0x00, 0x00 }, /* E1 */
547 { 0x00, 0x00 }, /* E2 */
548 { 0x00, 0x00 }, /* E3 */
549 { 0x00, 0x00 }, /* E4 */
550 { 0x00, 0x00 }, /* E5 */
551 { 0x00, 0x00 }, /* E6 */
552 { 0x00, 0x00 }, /* E7 */
553 { 0x00, 0x00 }, /* E8 */
554 { 0x00, 0x00 }, /* E9 */
555 { 0x00, 0x00 }, /* EA */
556 { 0x00, 0x00 }, /* EB */
557 { 0x00, 0x00 }, /* EC */
558 { 0x00, 0x00 }, /* ED */
559 { 0x00, 0x00 }, /* EE */
560 { 0x00, 0x00 }, /* EF */
561 { 0x00, 0x00 }, /* F0 */
562 { 0x00, 0x00 }, /* F1 */
563 { 0x00, 0x00 }, /* F2 */
564 { 0x00, 0x00 }, /* F3 */
565 { 0x00, 0x00 }, /* F4 */
566 { 0x00, 0x00 }, /* F5 */
567 { 0x00, 0x00 }, /* F6 */
568 { 0x00, 0x00 }, /* F7 */
569 { 0x00, 0x00 }, /* F8 */
570 { 0x00, 0x00 }, /* F9 */
571 { 0x00, 0x00 }, /* FA */
572 { 0x00, 0x00 }, /* FB */
573 { 0x00, 0x00 }, /* FC */
574 { 0x00, 0x00 }, /* FD */
575 { 0x00, 0x00 }, /* FE */
576 { 0xFF, 0x00 }, /* FF */
577};
578
579static int max98095_readable(struct snd_soc_codec *codec, unsigned int reg)
580{
581 if (reg >= M98095_REG_CNT)
582 return 0;
583 return max98095_access[reg].readable != 0;
584}
585
586static int max98095_volatile(struct snd_soc_codec *codec, unsigned int reg)
587{
588 if (reg > M98095_REG_MAX_CACHED)
589 return 1;
590
591 switch (reg) {
592 case M98095_000_HOST_DATA:
593 case M98095_001_HOST_INT_STS:
594 case M98095_002_HOST_RSP_STS:
595 case M98095_003_HOST_CMD_STS:
596 case M98095_004_CODEC_STS:
597 case M98095_005_DAI1_ALC_STS:
598 case M98095_006_DAI2_ALC_STS:
599 case M98095_007_JACK_AUTO_STS:
600 case M98095_008_JACK_MANUAL_STS:
601 case M98095_009_JACK_VBAT_STS:
602 case M98095_00A_ACC_ADC_STS:
603 case M98095_00B_MIC_NG_AGC_STS:
604 case M98095_00C_SPK_L_VOLT_STS:
605 case M98095_00D_SPK_R_VOLT_STS:
606 case M98095_00E_TEMP_SENSOR_STS:
607 return 1;
608 }
609
610 return 0;
611}
612
613/*
614 * Filter coefficients are in a separate register segment
615 * and they share the address space of the normal registers.
616 * The coefficient registers do not need or share the cache.
617 */
618static int max98095_hw_write(struct snd_soc_codec *codec, unsigned int reg,
619 unsigned int value)
620{
621 u8 data[2];
622
623 data[0] = reg;
624 data[1] = value;
625 if (codec->hw_write(codec->control_data, data, 2) == 2)
626 return 0;
627 else
628 return -EIO;
629}
630
631/*
632 * Load equalizer DSP coefficient configurations registers
633 */
634static void m98095_eq_band(struct snd_soc_codec *codec, unsigned int dai,
635 unsigned int band, u16 *coefs)
636{
637 unsigned int eq_reg;
638 unsigned int i;
639
640 BUG_ON(band > 4);
641 BUG_ON(dai > 1);
642
643 /* Load the base register address */
644 eq_reg = dai ? M98095_142_DAI2_EQ_BASE : M98095_110_DAI1_EQ_BASE;
645
646 /* Add the band address offset, note adjustment for word address */
647 eq_reg += band * (M98095_COEFS_PER_BAND << 1);
648
649 /* Step through the registers and coefs */
650 for (i = 0; i < M98095_COEFS_PER_BAND; i++) {
651 max98095_hw_write(codec, eq_reg++, M98095_BYTE1(coefs[i]));
652 max98095_hw_write(codec, eq_reg++, M98095_BYTE0(coefs[i]));
653 }
654}
655
656/*
657 * Load biquad filter coefficient configurations registers
658 */
659static void m98095_biquad_band(struct snd_soc_codec *codec, unsigned int dai,
660 unsigned int band, u16 *coefs)
661{
662 unsigned int bq_reg;
663 unsigned int i;
664
665 BUG_ON(band > 1);
666 BUG_ON(dai > 1);
667
668 /* Load the base register address */
669 bq_reg = dai ? M98095_17E_DAI2_BQ_BASE : M98095_174_DAI1_BQ_BASE;
670
671 /* Add the band address offset, note adjustment for word address */
672 bq_reg += band * (M98095_COEFS_PER_BAND << 1);
673
674 /* Step through the registers and coefs */
675 for (i = 0; i < M98095_COEFS_PER_BAND; i++) {
676 max98095_hw_write(codec, bq_reg++, M98095_BYTE1(coefs[i]));
677 max98095_hw_write(codec, bq_reg++, M98095_BYTE0(coefs[i]));
678 }
679}
680
681static const char * const max98095_fltr_mode[] = { "Voice", "Music" };
682static const struct soc_enum max98095_dai1_filter_mode_enum[] = {
683 SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 7, 2, max98095_fltr_mode),
684};
685static const struct soc_enum max98095_dai2_filter_mode_enum[] = {
686 SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 7, 2, max98095_fltr_mode),
687};
688
689static const char * const max98095_extmic_text[] = { "None", "MIC1", "MIC2" };
690
691static const struct soc_enum max98095_extmic_enum =
692 SOC_ENUM_SINGLE(M98095_087_CFG_MIC, 0, 3, max98095_extmic_text);
693
694static const struct snd_kcontrol_new max98095_extmic_mux =
695 SOC_DAPM_ENUM("External MIC Mux", max98095_extmic_enum);
696
697static const char * const max98095_linein_text[] = { "INA", "INB" };
698
699static const struct soc_enum max98095_linein_enum =
700 SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 6, 2, max98095_linein_text);
701
702static const struct snd_kcontrol_new max98095_linein_mux =
703 SOC_DAPM_ENUM("Linein Input Mux", max98095_linein_enum);
704
705static const char * const max98095_line_mode_text[] = {
706 "Stereo", "Differential"};
707
708static const struct soc_enum max98095_linein_mode_enum =
709 SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 7, 2, max98095_line_mode_text);
710
711static const struct soc_enum max98095_lineout_mode_enum =
712 SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 4, 2, max98095_line_mode_text);
713
714static const char * const max98095_dai_fltr[] = {
715 "Off", "Elliptical-HPF-16k", "Butterworth-HPF-16k",
716 "Elliptical-HPF-8k", "Butterworth-HPF-8k", "Butterworth-HPF-Fs/240"};
717static const struct soc_enum max98095_dai1_dac_filter_enum[] = {
718 SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 0, 6, max98095_dai_fltr),
719};
720static const struct soc_enum max98095_dai2_dac_filter_enum[] = {
721 SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 0, 6, max98095_dai_fltr),
722};
723static const struct soc_enum max98095_dai3_dac_filter_enum[] = {
724 SOC_ENUM_SINGLE(M98095_042_DAI3_FILTERS, 0, 6, max98095_dai_fltr),
725};
726
727static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol,
728 struct snd_ctl_elem_value *ucontrol)
729{
730 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
731 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
732 unsigned int sel = ucontrol->value.integer.value[0];
733
734 max98095->mic1pre = sel;
735 snd_soc_update_bits(codec, M98095_05F_LVL_MIC1, M98095_MICPRE_MASK,
736 (1+sel)<<M98095_MICPRE_SHIFT);
737
738 return 0;
739}
740
741static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol,
742 struct snd_ctl_elem_value *ucontrol)
743{
744 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
745 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
746
747 ucontrol->value.integer.value[0] = max98095->mic1pre;
748 return 0;
749}
750
751static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol,
752 struct snd_ctl_elem_value *ucontrol)
753{
754 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
755 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
756 unsigned int sel = ucontrol->value.integer.value[0];
757
758 max98095->mic2pre = sel;
759 snd_soc_update_bits(codec, M98095_060_LVL_MIC2, M98095_MICPRE_MASK,
760 (1+sel)<<M98095_MICPRE_SHIFT);
761
762 return 0;
763}
764
765static int max98095_mic2pre_get(struct snd_kcontrol *kcontrol,
766 struct snd_ctl_elem_value *ucontrol)
767{
768 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
769 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
770
771 ucontrol->value.integer.value[0] = max98095->mic2pre;
772 return 0;
773}
774
775static const unsigned int max98095_micboost_tlv[] = {
776 TLV_DB_RANGE_HEAD(2),
777 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
778 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
779};
780
781static const DECLARE_TLV_DB_SCALE(max98095_mic_tlv, 0, 100, 0);
782static const DECLARE_TLV_DB_SCALE(max98095_adc_tlv, -1200, 100, 0);
783static const DECLARE_TLV_DB_SCALE(max98095_adcboost_tlv, 0, 600, 0);
784
785static const unsigned int max98095_hp_tlv[] = {
786 TLV_DB_RANGE_HEAD(5),
787 0, 6, TLV_DB_SCALE_ITEM(-6700, 400, 0),
788 7, 14, TLV_DB_SCALE_ITEM(-4000, 300, 0),
789 15, 21, TLV_DB_SCALE_ITEM(-1700, 200, 0),
790 22, 27, TLV_DB_SCALE_ITEM(-400, 100, 0),
791 28, 31, TLV_DB_SCALE_ITEM(150, 50, 0),
792};
793
794static const unsigned int max98095_spk_tlv[] = {
795 TLV_DB_RANGE_HEAD(4),
796 0, 10, TLV_DB_SCALE_ITEM(-5900, 400, 0),
797 11, 18, TLV_DB_SCALE_ITEM(-1700, 200, 0),
798 19, 27, TLV_DB_SCALE_ITEM(-200, 100, 0),
799 28, 39, TLV_DB_SCALE_ITEM(650, 50, 0),
800};
801
802static const unsigned int max98095_rcv_lout_tlv[] = {
803 TLV_DB_RANGE_HEAD(5),
804 0, 6, TLV_DB_SCALE_ITEM(-6200, 400, 0),
805 7, 14, TLV_DB_SCALE_ITEM(-3500, 300, 0),
806 15, 21, TLV_DB_SCALE_ITEM(-1200, 200, 0),
807 22, 27, TLV_DB_SCALE_ITEM(100, 100, 0),
808 28, 31, TLV_DB_SCALE_ITEM(650, 50, 0),
809};
810
811static const unsigned int max98095_lin_tlv[] = {
812 TLV_DB_RANGE_HEAD(3),
813 0, 2, TLV_DB_SCALE_ITEM(-600, 300, 0),
814 3, 3, TLV_DB_SCALE_ITEM(300, 1100, 0),
815 4, 5, TLV_DB_SCALE_ITEM(1400, 600, 0),
816};
817
818static const struct snd_kcontrol_new max98095_snd_controls[] = {
819
820 SOC_DOUBLE_R_TLV("Headphone Volume", M98095_064_LVL_HP_L,
821 M98095_065_LVL_HP_R, 0, 31, 0, max98095_hp_tlv),
822
823 SOC_DOUBLE_R_TLV("Speaker Volume", M98095_067_LVL_SPK_L,
824 M98095_068_LVL_SPK_R, 0, 39, 0, max98095_spk_tlv),
825
826 SOC_SINGLE_TLV("Receiver Volume", M98095_066_LVL_RCV,
827 0, 31, 0, max98095_rcv_lout_tlv),
828
829 SOC_DOUBLE_R_TLV("Lineout Volume", M98095_062_LVL_LINEOUT1,
830 M98095_063_LVL_LINEOUT2, 0, 31, 0, max98095_rcv_lout_tlv),
831
832 SOC_DOUBLE_R("Headphone Switch", M98095_064_LVL_HP_L,
833 M98095_065_LVL_HP_R, 7, 1, 1),
834
835 SOC_DOUBLE_R("Speaker Switch", M98095_067_LVL_SPK_L,
836 M98095_068_LVL_SPK_R, 7, 1, 1),
837
838 SOC_SINGLE("Receiver Switch", M98095_066_LVL_RCV, 7, 1, 1),
839
840 SOC_DOUBLE_R("Lineout Switch", M98095_062_LVL_LINEOUT1,
841 M98095_063_LVL_LINEOUT2, 7, 1, 1),
842
843 SOC_SINGLE_TLV("MIC1 Volume", M98095_05F_LVL_MIC1, 0, 20, 1,
844 max98095_mic_tlv),
845
846 SOC_SINGLE_TLV("MIC2 Volume", M98095_060_LVL_MIC2, 0, 20, 1,
847 max98095_mic_tlv),
848
849 SOC_SINGLE_EXT_TLV("MIC1 Boost Volume",
850 M98095_05F_LVL_MIC1, 5, 2, 0,
851 max98095_mic1pre_get, max98095_mic1pre_set,
852 max98095_micboost_tlv),
853 SOC_SINGLE_EXT_TLV("MIC2 Boost Volume",
854 M98095_060_LVL_MIC2, 5, 2, 0,
855 max98095_mic2pre_get, max98095_mic2pre_set,
856 max98095_micboost_tlv),
857
858 SOC_SINGLE_TLV("Linein Volume", M98095_061_LVL_LINEIN, 0, 5, 1,
859 max98095_lin_tlv),
860
861 SOC_SINGLE_TLV("ADCL Volume", M98095_05D_LVL_ADC_L, 0, 15, 1,
862 max98095_adc_tlv),
863 SOC_SINGLE_TLV("ADCR Volume", M98095_05E_LVL_ADC_R, 0, 15, 1,
864 max98095_adc_tlv),
865
866 SOC_SINGLE_TLV("ADCL Boost Volume", M98095_05D_LVL_ADC_L, 4, 3, 0,
867 max98095_adcboost_tlv),
868 SOC_SINGLE_TLV("ADCR Boost Volume", M98095_05E_LVL_ADC_R, 4, 3, 0,
869 max98095_adcboost_tlv),
870
871 SOC_SINGLE("EQ1 Switch", M98095_088_CFG_LEVEL, 0, 1, 0),
872 SOC_SINGLE("EQ2 Switch", M98095_088_CFG_LEVEL, 1, 1, 0),
873
874 SOC_SINGLE("Biquad1 Switch", M98095_088_CFG_LEVEL, 2, 1, 0),
875 SOC_SINGLE("Biquad2 Switch", M98095_088_CFG_LEVEL, 3, 1, 0),
876
877 SOC_ENUM("DAI1 Filter Mode", max98095_dai1_filter_mode_enum),
878 SOC_ENUM("DAI2 Filter Mode", max98095_dai2_filter_mode_enum),
879 SOC_ENUM("DAI1 DAC Filter", max98095_dai1_dac_filter_enum),
880 SOC_ENUM("DAI2 DAC Filter", max98095_dai2_dac_filter_enum),
881 SOC_ENUM("DAI3 DAC Filter", max98095_dai3_dac_filter_enum),
882
883 SOC_ENUM("Linein Mode", max98095_linein_mode_enum),
884 SOC_ENUM("Lineout Mode", max98095_lineout_mode_enum),
885};
886
887/* Left speaker mixer switch */
888static const struct snd_kcontrol_new max98095_left_speaker_mixer_controls[] = {
889 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_050_MIX_SPK_LEFT, 0, 1, 0),
890 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_050_MIX_SPK_LEFT, 6, 1, 0),
891 SOC_DAPM_SINGLE("Mono DAC2 Switch", M98095_050_MIX_SPK_LEFT, 3, 1, 0),
892 SOC_DAPM_SINGLE("Mono DAC3 Switch", M98095_050_MIX_SPK_LEFT, 3, 1, 0),
893 SOC_DAPM_SINGLE("MIC1 Switch", M98095_050_MIX_SPK_LEFT, 4, 1, 0),
894 SOC_DAPM_SINGLE("MIC2 Switch", M98095_050_MIX_SPK_LEFT, 5, 1, 0),
895 SOC_DAPM_SINGLE("IN1 Switch", M98095_050_MIX_SPK_LEFT, 1, 1, 0),
896 SOC_DAPM_SINGLE("IN2 Switch", M98095_050_MIX_SPK_LEFT, 2, 1, 0),
897};
898
899/* Right speaker mixer switch */
900static const struct snd_kcontrol_new max98095_right_speaker_mixer_controls[] = {
901 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_051_MIX_SPK_RIGHT, 6, 1, 0),
902 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_051_MIX_SPK_RIGHT, 0, 1, 0),
903 SOC_DAPM_SINGLE("Mono DAC2 Switch", M98095_051_MIX_SPK_RIGHT, 3, 1, 0),
904 SOC_DAPM_SINGLE("Mono DAC3 Switch", M98095_051_MIX_SPK_RIGHT, 3, 1, 0),
905 SOC_DAPM_SINGLE("MIC1 Switch", M98095_051_MIX_SPK_RIGHT, 5, 1, 0),
906 SOC_DAPM_SINGLE("MIC2 Switch", M98095_051_MIX_SPK_RIGHT, 4, 1, 0),
907 SOC_DAPM_SINGLE("IN1 Switch", M98095_051_MIX_SPK_RIGHT, 1, 1, 0),
908 SOC_DAPM_SINGLE("IN2 Switch", M98095_051_MIX_SPK_RIGHT, 2, 1, 0),
909};
910
911/* Left headphone mixer switch */
912static const struct snd_kcontrol_new max98095_left_hp_mixer_controls[] = {
913 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04C_MIX_HP_LEFT, 0, 1, 0),
914 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04C_MIX_HP_LEFT, 5, 1, 0),
915 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04C_MIX_HP_LEFT, 3, 1, 0),
916 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04C_MIX_HP_LEFT, 4, 1, 0),
917 SOC_DAPM_SINGLE("IN1 Switch", M98095_04C_MIX_HP_LEFT, 1, 1, 0),
918 SOC_DAPM_SINGLE("IN2 Switch", M98095_04C_MIX_HP_LEFT, 2, 1, 0),
919};
920
921/* Right headphone mixer switch */
922static const struct snd_kcontrol_new max98095_right_hp_mixer_controls[] = {
923 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04D_MIX_HP_RIGHT, 5, 1, 0),
924 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04D_MIX_HP_RIGHT, 0, 1, 0),
925 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04D_MIX_HP_RIGHT, 3, 1, 0),
926 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04D_MIX_HP_RIGHT, 4, 1, 0),
927 SOC_DAPM_SINGLE("IN1 Switch", M98095_04D_MIX_HP_RIGHT, 1, 1, 0),
928 SOC_DAPM_SINGLE("IN2 Switch", M98095_04D_MIX_HP_RIGHT, 2, 1, 0),
929};
930
931/* Receiver earpiece mixer switch */
932static const struct snd_kcontrol_new max98095_mono_rcv_mixer_controls[] = {
933 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04F_MIX_RCV, 0, 1, 0),
934 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04F_MIX_RCV, 5, 1, 0),
935 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04F_MIX_RCV, 3, 1, 0),
936 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04F_MIX_RCV, 4, 1, 0),
937 SOC_DAPM_SINGLE("IN1 Switch", M98095_04F_MIX_RCV, 1, 1, 0),
938 SOC_DAPM_SINGLE("IN2 Switch", M98095_04F_MIX_RCV, 2, 1, 0),
939};
940
941/* Left lineout mixer switch */
942static const struct snd_kcontrol_new max98095_left_lineout_mixer_controls[] = {
943 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_053_MIX_LINEOUT1, 5, 1, 0),
944 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_053_MIX_LINEOUT1, 0, 1, 0),
945 SOC_DAPM_SINGLE("MIC1 Switch", M98095_053_MIX_LINEOUT1, 3, 1, 0),
946 SOC_DAPM_SINGLE("MIC2 Switch", M98095_053_MIX_LINEOUT1, 4, 1, 0),
947 SOC_DAPM_SINGLE("IN1 Switch", M98095_053_MIX_LINEOUT1, 1, 1, 0),
948 SOC_DAPM_SINGLE("IN2 Switch", M98095_053_MIX_LINEOUT1, 2, 1, 0),
949};
950
951/* Right lineout mixer switch */
952static const struct snd_kcontrol_new max98095_right_lineout_mixer_controls[] = {
953 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_054_MIX_LINEOUT2, 0, 1, 0),
954 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_054_MIX_LINEOUT2, 5, 1, 0),
955 SOC_DAPM_SINGLE("MIC1 Switch", M98095_054_MIX_LINEOUT2, 3, 1, 0),
956 SOC_DAPM_SINGLE("MIC2 Switch", M98095_054_MIX_LINEOUT2, 4, 1, 0),
957 SOC_DAPM_SINGLE("IN1 Switch", M98095_054_MIX_LINEOUT2, 1, 1, 0),
958 SOC_DAPM_SINGLE("IN2 Switch", M98095_054_MIX_LINEOUT2, 2, 1, 0),
959};
960
961/* Left ADC mixer switch */
962static const struct snd_kcontrol_new max98095_left_ADC_mixer_controls[] = {
963 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04A_MIX_ADC_LEFT, 7, 1, 0),
964 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04A_MIX_ADC_LEFT, 6, 1, 0),
965 SOC_DAPM_SINGLE("IN1 Switch", M98095_04A_MIX_ADC_LEFT, 3, 1, 0),
966 SOC_DAPM_SINGLE("IN2 Switch", M98095_04A_MIX_ADC_LEFT, 2, 1, 0),
967};
968
969/* Right ADC mixer switch */
970static const struct snd_kcontrol_new max98095_right_ADC_mixer_controls[] = {
971 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04B_MIX_ADC_RIGHT, 7, 1, 0),
972 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04B_MIX_ADC_RIGHT, 6, 1, 0),
973 SOC_DAPM_SINGLE("IN1 Switch", M98095_04B_MIX_ADC_RIGHT, 3, 1, 0),
974 SOC_DAPM_SINGLE("IN2 Switch", M98095_04B_MIX_ADC_RIGHT, 2, 1, 0),
975};
976
977static int max98095_mic_event(struct snd_soc_dapm_widget *w,
978 struct snd_kcontrol *kcontrol, int event)
979{
980 struct snd_soc_codec *codec = w->codec;
981 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
982
983 switch (event) {
984 case SND_SOC_DAPM_POST_PMU:
985 if (w->reg == M98095_05F_LVL_MIC1) {
986 snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK,
987 (1+max98095->mic1pre)<<M98095_MICPRE_SHIFT);
988 } else {
989 snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK,
990 (1+max98095->mic2pre)<<M98095_MICPRE_SHIFT);
991 }
992 break;
993 case SND_SOC_DAPM_POST_PMD:
994 snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK, 0);
995 break;
996 default:
997 return -EINVAL;
998 }
999
1000 return 0;
1001}
1002
1003/*
1004 * The line inputs are stereo inputs with the left and right
1005 * channels sharing a common PGA power control signal.
1006 */
1007static int max98095_line_pga(struct snd_soc_dapm_widget *w,
1008 int event, u8 channel)
1009{
1010 struct snd_soc_codec *codec = w->codec;
1011 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1012 u8 *state;
1013
1014 BUG_ON(!((channel == 1) || (channel == 2)));
1015
1016 state = &max98095->lin_state;
1017
1018 switch (event) {
1019 case SND_SOC_DAPM_POST_PMU:
1020 *state |= channel;
1021 snd_soc_update_bits(codec, w->reg,
1022 (1 << w->shift), (1 << w->shift));
1023 break;
1024 case SND_SOC_DAPM_POST_PMD:
1025 *state &= ~channel;
1026 if (*state == 0) {
1027 snd_soc_update_bits(codec, w->reg,
1028 (1 << w->shift), 0);
1029 }
1030 break;
1031 default:
1032 return -EINVAL;
1033 }
1034
1035 return 0;
1036}
1037
1038static int max98095_pga_in1_event(struct snd_soc_dapm_widget *w,
1039 struct snd_kcontrol *k, int event)
1040{
1041 return max98095_line_pga(w, event, 1);
1042}
1043
1044static int max98095_pga_in2_event(struct snd_soc_dapm_widget *w,
1045 struct snd_kcontrol *k, int event)
1046{
1047 return max98095_line_pga(w, event, 2);
1048}
1049
1050/*
1051 * The stereo line out mixer outputs to two stereo line outs.
1052 * The 2nd pair has a separate set of enables.
1053 */
1054static int max98095_lineout_event(struct snd_soc_dapm_widget *w,
1055 struct snd_kcontrol *kcontrol, int event)
1056{
1057 struct snd_soc_codec *codec = w->codec;
1058
1059 switch (event) {
1060 case SND_SOC_DAPM_POST_PMU:
1061 snd_soc_update_bits(codec, w->reg,
1062 (1 << (w->shift+2)), (1 << (w->shift+2)));
1063 break;
1064 case SND_SOC_DAPM_POST_PMD:
1065 snd_soc_update_bits(codec, w->reg,
1066 (1 << (w->shift+2)), 0);
1067 break;
1068 default:
1069 return -EINVAL;
1070 }
1071
1072 return 0;
1073}
1074
1075static const struct snd_soc_dapm_widget max98095_dapm_widgets[] = {
1076
1077 SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", M98095_090_PWR_EN_IN, 0, 0),
1078 SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", M98095_090_PWR_EN_IN, 1, 0),
1079
1080 SND_SOC_DAPM_DAC("DACL1", "HiFi Playback",
1081 M98095_091_PWR_EN_OUT, 0, 0),
1082 SND_SOC_DAPM_DAC("DACR1", "HiFi Playback",
1083 M98095_091_PWR_EN_OUT, 1, 0),
1084 SND_SOC_DAPM_DAC("DACM2", "Aux Playback",
1085 M98095_091_PWR_EN_OUT, 2, 0),
1086 SND_SOC_DAPM_DAC("DACM3", "Voice Playback",
1087 M98095_091_PWR_EN_OUT, 2, 0),
1088
1089 SND_SOC_DAPM_PGA("HP Left Out", M98095_091_PWR_EN_OUT,
1090 6, 0, NULL, 0),
1091 SND_SOC_DAPM_PGA("HP Right Out", M98095_091_PWR_EN_OUT,
1092 7, 0, NULL, 0),
1093
1094 SND_SOC_DAPM_PGA("SPK Left Out", M98095_091_PWR_EN_OUT,
1095 4, 0, NULL, 0),
1096 SND_SOC_DAPM_PGA("SPK Right Out", M98095_091_PWR_EN_OUT,
1097 5, 0, NULL, 0),
1098
1099 SND_SOC_DAPM_PGA("RCV Mono Out", M98095_091_PWR_EN_OUT,
1100 3, 0, NULL, 0),
1101
1102 SND_SOC_DAPM_PGA_E("LINE Left Out", M98095_092_PWR_EN_OUT,
1103 0, 0, NULL, 0, max98095_lineout_event, SND_SOC_DAPM_PRE_PMD),
1104 SND_SOC_DAPM_PGA_E("LINE Right Out", M98095_092_PWR_EN_OUT,
1105 1, 0, NULL, 0, max98095_lineout_event, SND_SOC_DAPM_PRE_PMD),
1106
1107 SND_SOC_DAPM_MUX("External MIC", SND_SOC_NOPM, 0, 0,
1108 &max98095_extmic_mux),
1109
1110 SND_SOC_DAPM_MUX("Linein Mux", SND_SOC_NOPM, 0, 0,
1111 &max98095_linein_mux),
1112
1113 SND_SOC_DAPM_MIXER("Left Headphone Mixer", SND_SOC_NOPM, 0, 0,
1114 &max98095_left_hp_mixer_controls[0],
1115 ARRAY_SIZE(max98095_left_hp_mixer_controls)),
1116
1117 SND_SOC_DAPM_MIXER("Right Headphone Mixer", SND_SOC_NOPM, 0, 0,
1118 &max98095_right_hp_mixer_controls[0],
1119 ARRAY_SIZE(max98095_right_hp_mixer_controls)),
1120
1121 SND_SOC_DAPM_MIXER("Left Speaker Mixer", SND_SOC_NOPM, 0, 0,
1122 &max98095_left_speaker_mixer_controls[0],
1123 ARRAY_SIZE(max98095_left_speaker_mixer_controls)),
1124
1125 SND_SOC_DAPM_MIXER("Right Speaker Mixer", SND_SOC_NOPM, 0, 0,
1126 &max98095_right_speaker_mixer_controls[0],
1127 ARRAY_SIZE(max98095_right_speaker_mixer_controls)),
1128
1129 SND_SOC_DAPM_MIXER("Receiver Mixer", SND_SOC_NOPM, 0, 0,
1130 &max98095_mono_rcv_mixer_controls[0],
1131 ARRAY_SIZE(max98095_mono_rcv_mixer_controls)),
1132
1133 SND_SOC_DAPM_MIXER("Left Lineout Mixer", SND_SOC_NOPM, 0, 0,
1134 &max98095_left_lineout_mixer_controls[0],
1135 ARRAY_SIZE(max98095_left_lineout_mixer_controls)),
1136
1137 SND_SOC_DAPM_MIXER("Right Lineout Mixer", SND_SOC_NOPM, 0, 0,
1138 &max98095_right_lineout_mixer_controls[0],
1139 ARRAY_SIZE(max98095_right_lineout_mixer_controls)),
1140
1141 SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
1142 &max98095_left_ADC_mixer_controls[0],
1143 ARRAY_SIZE(max98095_left_ADC_mixer_controls)),
1144
1145 SND_SOC_DAPM_MIXER("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
1146 &max98095_right_ADC_mixer_controls[0],
1147 ARRAY_SIZE(max98095_right_ADC_mixer_controls)),
1148
1149 SND_SOC_DAPM_PGA_E("MIC1 Input", M98095_05F_LVL_MIC1,
1150 5, 0, NULL, 0, max98095_mic_event,
1151 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1152
1153 SND_SOC_DAPM_PGA_E("MIC2 Input", M98095_060_LVL_MIC2,
1154 5, 0, NULL, 0, max98095_mic_event,
1155 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1156
1157 SND_SOC_DAPM_PGA_E("IN1 Input", M98095_090_PWR_EN_IN,
1158 7, 0, NULL, 0, max98095_pga_in1_event,
1159 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1160
1161 SND_SOC_DAPM_PGA_E("IN2 Input", M98095_090_PWR_EN_IN,
1162 7, 0, NULL, 0, max98095_pga_in2_event,
1163 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1164
1165 SND_SOC_DAPM_MICBIAS("MICBIAS1", M98095_090_PWR_EN_IN, 2, 0),
1166 SND_SOC_DAPM_MICBIAS("MICBIAS2", M98095_090_PWR_EN_IN, 3, 0),
1167
1168 SND_SOC_DAPM_OUTPUT("HPL"),
1169 SND_SOC_DAPM_OUTPUT("HPR"),
1170 SND_SOC_DAPM_OUTPUT("SPKL"),
1171 SND_SOC_DAPM_OUTPUT("SPKR"),
1172 SND_SOC_DAPM_OUTPUT("RCV"),
1173 SND_SOC_DAPM_OUTPUT("OUT1"),
1174 SND_SOC_DAPM_OUTPUT("OUT2"),
1175 SND_SOC_DAPM_OUTPUT("OUT3"),
1176 SND_SOC_DAPM_OUTPUT("OUT4"),
1177
1178 SND_SOC_DAPM_INPUT("MIC1"),
1179 SND_SOC_DAPM_INPUT("MIC2"),
1180 SND_SOC_DAPM_INPUT("INA1"),
1181 SND_SOC_DAPM_INPUT("INA2"),
1182 SND_SOC_DAPM_INPUT("INB1"),
1183 SND_SOC_DAPM_INPUT("INB2"),
1184};
1185
1186static const struct snd_soc_dapm_route max98095_audio_map[] = {
1187 /* Left headphone output mixer */
1188 {"Left Headphone Mixer", "Left DAC1 Switch", "DACL1"},
1189 {"Left Headphone Mixer", "Right DAC1 Switch", "DACR1"},
1190 {"Left Headphone Mixer", "MIC1 Switch", "MIC1 Input"},
1191 {"Left Headphone Mixer", "MIC2 Switch", "MIC2 Input"},
1192 {"Left Headphone Mixer", "IN1 Switch", "IN1 Input"},
1193 {"Left Headphone Mixer", "IN2 Switch", "IN2 Input"},
1194
1195 /* Right headphone output mixer */
1196 {"Right Headphone Mixer", "Left DAC1 Switch", "DACL1"},
1197 {"Right Headphone Mixer", "Right DAC1 Switch", "DACR1"},
1198 {"Right Headphone Mixer", "MIC1 Switch", "MIC1 Input"},
1199 {"Right Headphone Mixer", "MIC2 Switch", "MIC2 Input"},
1200 {"Right Headphone Mixer", "IN1 Switch", "IN1 Input"},
1201 {"Right Headphone Mixer", "IN2 Switch", "IN2 Input"},
1202
1203 /* Left speaker output mixer */
1204 {"Left Speaker Mixer", "Left DAC1 Switch", "DACL1"},
1205 {"Left Speaker Mixer", "Right DAC1 Switch", "DACR1"},
1206 {"Left Speaker Mixer", "Mono DAC2 Switch", "DACM2"},
1207 {"Left Speaker Mixer", "Mono DAC3 Switch", "DACM3"},
1208 {"Left Speaker Mixer", "MIC1 Switch", "MIC1 Input"},
1209 {"Left Speaker Mixer", "MIC2 Switch", "MIC2 Input"},
1210 {"Left Speaker Mixer", "IN1 Switch", "IN1 Input"},
1211 {"Left Speaker Mixer", "IN2 Switch", "IN2 Input"},
1212
1213 /* Right speaker output mixer */
1214 {"Right Speaker Mixer", "Left DAC1 Switch", "DACL1"},
1215 {"Right Speaker Mixer", "Right DAC1 Switch", "DACR1"},
1216 {"Right Speaker Mixer", "Mono DAC2 Switch", "DACM2"},
1217 {"Right Speaker Mixer", "Mono DAC3 Switch", "DACM3"},
1218 {"Right Speaker Mixer", "MIC1 Switch", "MIC1 Input"},
1219 {"Right Speaker Mixer", "MIC2 Switch", "MIC2 Input"},
1220 {"Right Speaker Mixer", "IN1 Switch", "IN1 Input"},
1221 {"Right Speaker Mixer", "IN2 Switch", "IN2 Input"},
1222
1223 /* Earpiece/Receiver output mixer */
1224 {"Receiver Mixer", "Left DAC1 Switch", "DACL1"},
1225 {"Receiver Mixer", "Right DAC1 Switch", "DACR1"},
1226 {"Receiver Mixer", "MIC1 Switch", "MIC1 Input"},
1227 {"Receiver Mixer", "MIC2 Switch", "MIC2 Input"},
1228 {"Receiver Mixer", "IN1 Switch", "IN1 Input"},
1229 {"Receiver Mixer", "IN2 Switch", "IN2 Input"},
1230
1231 /* Left Lineout output mixer */
1232 {"Left Lineout Mixer", "Left DAC1 Switch", "DACL1"},
1233 {"Left Lineout Mixer", "Right DAC1 Switch", "DACR1"},
1234 {"Left Lineout Mixer", "MIC1 Switch", "MIC1 Input"},
1235 {"Left Lineout Mixer", "MIC2 Switch", "MIC2 Input"},
1236 {"Left Lineout Mixer", "IN1 Switch", "IN1 Input"},
1237 {"Left Lineout Mixer", "IN2 Switch", "IN2 Input"},
1238
1239 /* Right lineout output mixer */
1240 {"Right Lineout Mixer", "Left DAC1 Switch", "DACL1"},
1241 {"Right Lineout Mixer", "Right DAC1 Switch", "DACR1"},
1242 {"Right Lineout Mixer", "MIC1 Switch", "MIC1 Input"},
1243 {"Right Lineout Mixer", "MIC2 Switch", "MIC2 Input"},
1244 {"Right Lineout Mixer", "IN1 Switch", "IN1 Input"},
1245 {"Right Lineout Mixer", "IN2 Switch", "IN2 Input"},
1246
1247 {"HP Left Out", NULL, "Left Headphone Mixer"},
1248 {"HP Right Out", NULL, "Right Headphone Mixer"},
1249 {"SPK Left Out", NULL, "Left Speaker Mixer"},
1250 {"SPK Right Out", NULL, "Right Speaker Mixer"},
1251 {"RCV Mono Out", NULL, "Receiver Mixer"},
1252 {"LINE Left Out", NULL, "Left Lineout Mixer"},
1253 {"LINE Right Out", NULL, "Right Lineout Mixer"},
1254
1255 {"HPL", NULL, "HP Left Out"},
1256 {"HPR", NULL, "HP Right Out"},
1257 {"SPKL", NULL, "SPK Left Out"},
1258 {"SPKR", NULL, "SPK Right Out"},
1259 {"RCV", NULL, "RCV Mono Out"},
1260 {"OUT1", NULL, "LINE Left Out"},
1261 {"OUT2", NULL, "LINE Right Out"},
1262 {"OUT3", NULL, "LINE Left Out"},
1263 {"OUT4", NULL, "LINE Right Out"},
1264
1265 /* Left ADC input mixer */
1266 {"Left ADC Mixer", "MIC1 Switch", "MIC1 Input"},
1267 {"Left ADC Mixer", "MIC2 Switch", "MIC2 Input"},
1268 {"Left ADC Mixer", "IN1 Switch", "IN1 Input"},
1269 {"Left ADC Mixer", "IN2 Switch", "IN2 Input"},
1270
1271 /* Right ADC input mixer */
1272 {"Right ADC Mixer", "MIC1 Switch", "MIC1 Input"},
1273 {"Right ADC Mixer", "MIC2 Switch", "MIC2 Input"},
1274 {"Right ADC Mixer", "IN1 Switch", "IN1 Input"},
1275 {"Right ADC Mixer", "IN2 Switch", "IN2 Input"},
1276
1277 /* Inputs */
1278 {"ADCL", NULL, "Left ADC Mixer"},
1279 {"ADCR", NULL, "Right ADC Mixer"},
1280
1281 {"IN1 Input", NULL, "INA1"},
1282 {"IN2 Input", NULL, "INA2"},
1283
1284 {"MIC1 Input", NULL, "MIC1"},
1285 {"MIC2 Input", NULL, "MIC2"},
1286};
1287
1288static int max98095_add_widgets(struct snd_soc_codec *codec)
1289{
1290 snd_soc_add_controls(codec, max98095_snd_controls,
1291 ARRAY_SIZE(max98095_snd_controls));
1292
1293 return 0;
1294}
1295
1296/* codec mclk clock divider coefficients */
1297static const struct {
1298 u32 rate;
1299 u8 sr;
1300} rate_table[] = {
1301 {8000, 0x01},
1302 {11025, 0x02},
1303 {16000, 0x03},
1304 {22050, 0x04},
1305 {24000, 0x05},
1306 {32000, 0x06},
1307 {44100, 0x07},
1308 {48000, 0x08},
1309 {88200, 0x09},
1310 {96000, 0x0A},
1311};
1312
1313static int rate_value(int rate, u8 *value)
1314{
1315 int i;
1316
1317 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
1318 if (rate_table[i].rate >= rate) {
1319 *value = rate_table[i].sr;
1320 return 0;
1321 }
1322 }
1323 *value = rate_table[0].sr;
1324 return -EINVAL;
1325}
1326
1327static int max98095_dai1_hw_params(struct snd_pcm_substream *substream,
1328 struct snd_pcm_hw_params *params,
1329 struct snd_soc_dai *dai)
1330{
1331 struct snd_soc_codec *codec = dai->codec;
1332 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1333 struct max98095_cdata *cdata;
1334 unsigned long long ni;
1335 unsigned int rate;
1336 u8 regval;
1337
1338 cdata = &max98095->dai[0];
1339
1340 rate = params_rate(params);
1341
1342 switch (params_format(params)) {
1343 case SNDRV_PCM_FORMAT_S16_LE:
1344 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
1345 M98095_DAI_WS, 0);
1346 break;
1347 case SNDRV_PCM_FORMAT_S24_LE:
1348 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
1349 M98095_DAI_WS, M98095_DAI_WS);
1350 break;
1351 default:
1352 return -EINVAL;
1353 }
1354
1355 if (rate_value(rate, &regval))
1356 return -EINVAL;
1357
1358 snd_soc_update_bits(codec, M98095_027_DAI1_CLKMODE,
1359 M98095_CLKMODE_MASK, regval);
1360 cdata->rate = rate;
1361
1362 /* Configure NI when operating as master */
1363 if (snd_soc_read(codec, M98095_02A_DAI1_FORMAT) & M98095_DAI_MAS) {
1364 if (max98095->sysclk == 0) {
1365 dev_err(codec->dev, "Invalid system clock frequency\n");
1366 return -EINVAL;
1367 }
1368 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
1369 * (unsigned long long int)rate;
1370 do_div(ni, (unsigned long long int)max98095->sysclk);
1371 snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI,
1372 (ni >> 8) & 0x7F);
1373 snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO,
1374 ni & 0xFF);
1375 }
1376
1377 /* Update sample rate mode */
1378 if (rate < 50000)
1379 snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS,
1380 M98095_DAI_DHF, 0);
1381 else
1382 snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS,
1383 M98095_DAI_DHF, M98095_DAI_DHF);
1384
1385 return 0;
1386}
1387
1388static int max98095_dai2_hw_params(struct snd_pcm_substream *substream,
1389 struct snd_pcm_hw_params *params,
1390 struct snd_soc_dai *dai)
1391{
1392 struct snd_soc_codec *codec = dai->codec;
1393 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1394 struct max98095_cdata *cdata;
1395 unsigned long long ni;
1396 unsigned int rate;
1397 u8 regval;
1398
1399 cdata = &max98095->dai[1];
1400
1401 rate = params_rate(params);
1402
1403 switch (params_format(params)) {
1404 case SNDRV_PCM_FORMAT_S16_LE:
1405 snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
1406 M98095_DAI_WS, 0);
1407 break;
1408 case SNDRV_PCM_FORMAT_S24_LE:
1409 snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
1410 M98095_DAI_WS, M98095_DAI_WS);
1411 break;
1412 default:
1413 return -EINVAL;
1414 }
1415
1416 if (rate_value(rate, &regval))
1417 return -EINVAL;
1418
1419 snd_soc_update_bits(codec, M98095_031_DAI2_CLKMODE,
1420 M98095_CLKMODE_MASK, regval);
1421 cdata->rate = rate;
1422
1423 /* Configure NI when operating as master */
1424 if (snd_soc_read(codec, M98095_034_DAI2_FORMAT) & M98095_DAI_MAS) {
1425 if (max98095->sysclk == 0) {
1426 dev_err(codec->dev, "Invalid system clock frequency\n");
1427 return -EINVAL;
1428 }
1429 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
1430 * (unsigned long long int)rate;
1431 do_div(ni, (unsigned long long int)max98095->sysclk);
1432 snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI,
1433 (ni >> 8) & 0x7F);
1434 snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO,
1435 ni & 0xFF);
1436 }
1437
1438 /* Update sample rate mode */
1439 if (rate < 50000)
1440 snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS,
1441 M98095_DAI_DHF, 0);
1442 else
1443 snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS,
1444 M98095_DAI_DHF, M98095_DAI_DHF);
1445
1446 return 0;
1447}
1448
1449static int max98095_dai3_hw_params(struct snd_pcm_substream *substream,
1450 struct snd_pcm_hw_params *params,
1451 struct snd_soc_dai *dai)
1452{
1453 struct snd_soc_codec *codec = dai->codec;
1454 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1455 struct max98095_cdata *cdata;
1456 unsigned long long ni;
1457 unsigned int rate;
1458 u8 regval;
1459
1460 cdata = &max98095->dai[2];
1461
1462 rate = params_rate(params);
1463
1464 switch (params_format(params)) {
1465 case SNDRV_PCM_FORMAT_S16_LE:
1466 snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
1467 M98095_DAI_WS, 0);
1468 break;
1469 case SNDRV_PCM_FORMAT_S24_LE:
1470 snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
1471 M98095_DAI_WS, M98095_DAI_WS);
1472 break;
1473 default:
1474 return -EINVAL;
1475 }
1476
1477 if (rate_value(rate, &regval))
1478 return -EINVAL;
1479
1480 snd_soc_update_bits(codec, M98095_03B_DAI3_CLKMODE,
1481 M98095_CLKMODE_MASK, regval);
1482 cdata->rate = rate;
1483
1484 /* Configure NI when operating as master */
1485 if (snd_soc_read(codec, M98095_03E_DAI3_FORMAT) & M98095_DAI_MAS) {
1486 if (max98095->sysclk == 0) {
1487 dev_err(codec->dev, "Invalid system clock frequency\n");
1488 return -EINVAL;
1489 }
1490 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
1491 * (unsigned long long int)rate;
1492 do_div(ni, (unsigned long long int)max98095->sysclk);
1493 snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI,
1494 (ni >> 8) & 0x7F);
1495 snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO,
1496 ni & 0xFF);
1497 }
1498
1499 /* Update sample rate mode */
1500 if (rate < 50000)
1501 snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS,
1502 M98095_DAI_DHF, 0);
1503 else
1504 snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS,
1505 M98095_DAI_DHF, M98095_DAI_DHF);
1506
1507 return 0;
1508}
1509
1510static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
1511 int clk_id, unsigned int freq, int dir)
1512{
1513 struct snd_soc_codec *codec = dai->codec;
1514 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1515
1516 /* Requested clock frequency is already setup */
1517 if (freq == max98095->sysclk)
1518 return 0;
1519
1520 max98095->sysclk = freq; /* remember current sysclk */
1521
1522 /* Setup clocks for slave mode, and using the PLL
1523 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
1524 * 0x02 (when master clk is 20MHz to 40MHz)..
1525 * 0x03 (when master clk is 40MHz to 60MHz)..
1526 */
1527 if ((freq >= 10000000) && (freq < 20000000)) {
1528 snd_soc_write(codec, M98095_026_SYS_CLK, 0x10);
1529 } else if ((freq >= 20000000) && (freq < 40000000)) {
1530 snd_soc_write(codec, M98095_026_SYS_CLK, 0x20);
1531 } else if ((freq >= 40000000) && (freq < 60000000)) {
1532 snd_soc_write(codec, M98095_026_SYS_CLK, 0x30);
1533 } else {
1534 dev_err(codec->dev, "Invalid master clock frequency\n");
1535 return -EINVAL;
1536 }
1537
1538 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
1539
1540 max98095->sysclk = freq;
1541 return 0;
1542}
1543
1544static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
1545 unsigned int fmt)
1546{
1547 struct snd_soc_codec *codec = codec_dai->codec;
1548 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1549 struct max98095_cdata *cdata;
1550 u8 regval = 0;
1551
1552 cdata = &max98095->dai[0];
1553
1554 if (fmt != cdata->fmt) {
1555 cdata->fmt = fmt;
1556
1557 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1558 case SND_SOC_DAIFMT_CBS_CFS:
1559 /* Slave mode PLL */
1560 snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI,
1561 0x80);
1562 snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO,
1563 0x00);
1564 break;
1565 case SND_SOC_DAIFMT_CBM_CFM:
1566 /* Set to master mode */
1567 regval |= M98095_DAI_MAS;
1568 break;
1569 case SND_SOC_DAIFMT_CBS_CFM:
1570 case SND_SOC_DAIFMT_CBM_CFS:
1571 default:
1572 dev_err(codec->dev, "Clock mode unsupported");
1573 return -EINVAL;
1574 }
1575
1576 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1577 case SND_SOC_DAIFMT_I2S:
1578 regval |= M98095_DAI_DLY;
1579 break;
1580 case SND_SOC_DAIFMT_LEFT_J:
1581 break;
1582 default:
1583 return -EINVAL;
1584 }
1585
1586 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1587 case SND_SOC_DAIFMT_NB_NF:
1588 break;
1589 case SND_SOC_DAIFMT_NB_IF:
1590 regval |= M98095_DAI_WCI;
1591 break;
1592 case SND_SOC_DAIFMT_IB_NF:
1593 regval |= M98095_DAI_BCI;
1594 break;
1595 case SND_SOC_DAIFMT_IB_IF:
1596 regval |= M98095_DAI_BCI|M98095_DAI_WCI;
1597 break;
1598 default:
1599 return -EINVAL;
1600 }
1601
1602 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
1603 M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
1604 M98095_DAI_WCI, regval);
1605
1606 snd_soc_write(codec, M98095_02B_DAI1_CLOCK, M98095_DAI_BSEL64);
1607 }
1608
1609 return 0;
1610}
1611
1612static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
1613 unsigned int fmt)
1614{
1615 struct snd_soc_codec *codec = codec_dai->codec;
1616 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1617 struct max98095_cdata *cdata;
1618 u8 regval = 0;
1619
1620 cdata = &max98095->dai[1];
1621
1622 if (fmt != cdata->fmt) {
1623 cdata->fmt = fmt;
1624
1625 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1626 case SND_SOC_DAIFMT_CBS_CFS:
1627 /* Slave mode PLL */
1628 snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI,
1629 0x80);
1630 snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO,
1631 0x00);
1632 break;
1633 case SND_SOC_DAIFMT_CBM_CFM:
1634 /* Set to master mode */
1635 regval |= M98095_DAI_MAS;
1636 break;
1637 case SND_SOC_DAIFMT_CBS_CFM:
1638 case SND_SOC_DAIFMT_CBM_CFS:
1639 default:
1640 dev_err(codec->dev, "Clock mode unsupported");
1641 return -EINVAL;
1642 }
1643
1644 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1645 case SND_SOC_DAIFMT_I2S:
1646 regval |= M98095_DAI_DLY;
1647 break;
1648 case SND_SOC_DAIFMT_LEFT_J:
1649 break;
1650 default:
1651 return -EINVAL;
1652 }
1653
1654 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1655 case SND_SOC_DAIFMT_NB_NF:
1656 break;
1657 case SND_SOC_DAIFMT_NB_IF:
1658 regval |= M98095_DAI_WCI;
1659 break;
1660 case SND_SOC_DAIFMT_IB_NF:
1661 regval |= M98095_DAI_BCI;
1662 break;
1663 case SND_SOC_DAIFMT_IB_IF:
1664 regval |= M98095_DAI_BCI|M98095_DAI_WCI;
1665 break;
1666 default:
1667 return -EINVAL;
1668 }
1669
1670 snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
1671 M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
1672 M98095_DAI_WCI, regval);
1673
1674 snd_soc_write(codec, M98095_035_DAI2_CLOCK,
1675 M98095_DAI_BSEL64);
1676 }
1677
1678 return 0;
1679}
1680
1681static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai,
1682 unsigned int fmt)
1683{
1684 struct snd_soc_codec *codec = codec_dai->codec;
1685 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1686 struct max98095_cdata *cdata;
1687 u8 regval = 0;
1688
1689 cdata = &max98095->dai[2];
1690
1691 if (fmt != cdata->fmt) {
1692 cdata->fmt = fmt;
1693
1694 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1695 case SND_SOC_DAIFMT_CBS_CFS:
1696 /* Slave mode PLL */
1697 snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI,
1698 0x80);
1699 snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO,
1700 0x00);
1701 break;
1702 case SND_SOC_DAIFMT_CBM_CFM:
1703 /* Set to master mode */
1704 regval |= M98095_DAI_MAS;
1705 break;
1706 case SND_SOC_DAIFMT_CBS_CFM:
1707 case SND_SOC_DAIFMT_CBM_CFS:
1708 default:
1709 dev_err(codec->dev, "Clock mode unsupported");
1710 return -EINVAL;
1711 }
1712
1713 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1714 case SND_SOC_DAIFMT_I2S:
1715 regval |= M98095_DAI_DLY;
1716 break;
1717 case SND_SOC_DAIFMT_LEFT_J:
1718 break;
1719 default:
1720 return -EINVAL;
1721 }
1722
1723 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1724 case SND_SOC_DAIFMT_NB_NF:
1725 break;
1726 case SND_SOC_DAIFMT_NB_IF:
1727 regval |= M98095_DAI_WCI;
1728 break;
1729 case SND_SOC_DAIFMT_IB_NF:
1730 regval |= M98095_DAI_BCI;
1731 break;
1732 case SND_SOC_DAIFMT_IB_IF:
1733 regval |= M98095_DAI_BCI|M98095_DAI_WCI;
1734 break;
1735 default:
1736 return -EINVAL;
1737 }
1738
1739 snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
1740 M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
1741 M98095_DAI_WCI, regval);
1742
1743 snd_soc_write(codec, M98095_03F_DAI3_CLOCK,
1744 M98095_DAI_BSEL64);
1745 }
1746
1747 return 0;
1748}
1749
1750static int max98095_set_bias_level(struct snd_soc_codec *codec,
1751 enum snd_soc_bias_level level)
1752{
1753 int ret;
1754
1755 switch (level) {
1756 case SND_SOC_BIAS_ON:
1757 break;
1758
1759 case SND_SOC_BIAS_PREPARE:
1760 break;
1761
1762 case SND_SOC_BIAS_STANDBY:
1763 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1764 ret = snd_soc_cache_sync(codec);
1765
1766 if (ret != 0) {
1767 dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
1768 return ret;
1769 }
1770 }
1771
1772 snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
1773 M98095_MBEN, M98095_MBEN);
1774 break;
1775
1776 case SND_SOC_BIAS_OFF:
1777 snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
1778 M98095_MBEN, 0);
1779 codec->cache_sync = 1;
1780 break;
1781 }
1782 codec->dapm.bias_level = level;
1783 return 0;
1784}
1785
1786#define MAX98095_RATES SNDRV_PCM_RATE_8000_96000
1787#define MAX98095_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
1788
1789static struct snd_soc_dai_ops max98095_dai1_ops = {
1790 .set_sysclk = max98095_dai_set_sysclk,
1791 .set_fmt = max98095_dai1_set_fmt,
1792 .hw_params = max98095_dai1_hw_params,
1793};
1794
1795static struct snd_soc_dai_ops max98095_dai2_ops = {
1796 .set_sysclk = max98095_dai_set_sysclk,
1797 .set_fmt = max98095_dai2_set_fmt,
1798 .hw_params = max98095_dai2_hw_params,
1799};
1800
1801static struct snd_soc_dai_ops max98095_dai3_ops = {
1802 .set_sysclk = max98095_dai_set_sysclk,
1803 .set_fmt = max98095_dai3_set_fmt,
1804 .hw_params = max98095_dai3_hw_params,
1805};
1806
1807static struct snd_soc_dai_driver max98095_dai[] = {
1808{
1809 .name = "HiFi",
1810 .playback = {
1811 .stream_name = "HiFi Playback",
1812 .channels_min = 1,
1813 .channels_max = 2,
1814 .rates = MAX98095_RATES,
1815 .formats = MAX98095_FORMATS,
1816 },
1817 .capture = {
1818 .stream_name = "HiFi Capture",
1819 .channels_min = 1,
1820 .channels_max = 2,
1821 .rates = MAX98095_RATES,
1822 .formats = MAX98095_FORMATS,
1823 },
1824 .ops = &max98095_dai1_ops,
1825},
1826{
1827 .name = "Aux",
1828 .playback = {
1829 .stream_name = "Aux Playback",
1830 .channels_min = 1,
1831 .channels_max = 1,
1832 .rates = MAX98095_RATES,
1833 .formats = MAX98095_FORMATS,
1834 },
1835 .ops = &max98095_dai2_ops,
1836},
1837{
1838 .name = "Voice",
1839 .playback = {
1840 .stream_name = "Voice Playback",
1841 .channels_min = 1,
1842 .channels_max = 1,
1843 .rates = MAX98095_RATES,
1844 .formats = MAX98095_FORMATS,
1845 },
1846 .ops = &max98095_dai3_ops,
1847}
1848
1849};
1850
1851static int max98095_get_eq_channel(const char *name)
1852{
1853 if (strcmp(name, "EQ1 Mode") == 0)
1854 return 0;
1855 if (strcmp(name, "EQ2 Mode") == 0)
1856 return 1;
1857 return -EINVAL;
1858}
1859
1860static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol,
1861 struct snd_ctl_elem_value *ucontrol)
1862{
1863 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1864 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1865 struct max98095_pdata *pdata = max98095->pdata;
1866 int channel = max98095_get_eq_channel(kcontrol->id.name);
1867 struct max98095_cdata *cdata;
1868 int sel = ucontrol->value.integer.value[0];
1869 struct max98095_eq_cfg *coef_set;
1870 int fs, best, best_val, i;
1871 int regmask, regsave;
1872
1873 BUG_ON(channel > 1);
1874
1875 if (!pdata || !max98095->eq_textcnt)
1876 return 0;
1877
1878 if (sel >= pdata->eq_cfgcnt)
1879 return -EINVAL;
1880
1881 cdata = &max98095->dai[channel];
1882 cdata->eq_sel = sel;
1883 fs = cdata->rate;
1884
1885 /* Find the selected configuration with nearest sample rate */
1886 best = 0;
1887 best_val = INT_MAX;
1888 for (i = 0; i < pdata->eq_cfgcnt; i++) {
1889 if (strcmp(pdata->eq_cfg[i].name, max98095->eq_texts[sel]) == 0 &&
1890 abs(pdata->eq_cfg[i].rate - fs) < best_val) {
1891 best = i;
1892 best_val = abs(pdata->eq_cfg[i].rate - fs);
1893 }
1894 }
1895
1896 dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
1897 pdata->eq_cfg[best].name,
1898 pdata->eq_cfg[best].rate, fs);
1899
1900 coef_set = &pdata->eq_cfg[best];
1901
1902 regmask = (channel == 0) ? M98095_EQ1EN : M98095_EQ2EN;
1903
1904 /* Disable filter while configuring, and save current on/off state */
1905 regsave = snd_soc_read(codec, M98095_088_CFG_LEVEL);
1906 snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, 0);
1907
1908 mutex_lock(&codec->mutex);
1909 snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
1910 m98095_eq_band(codec, channel, 0, coef_set->band1);
1911 m98095_eq_band(codec, channel, 1, coef_set->band2);
1912 m98095_eq_band(codec, channel, 2, coef_set->band3);
1913 m98095_eq_band(codec, channel, 3, coef_set->band4);
1914 m98095_eq_band(codec, channel, 4, coef_set->band5);
1915 snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, 0);
1916 mutex_unlock(&codec->mutex);
1917
1918 /* Restore the original on/off state */
1919 snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, regsave);
1920 return 0;
1921}
1922
1923static int max98095_get_eq_enum(struct snd_kcontrol *kcontrol,
1924 struct snd_ctl_elem_value *ucontrol)
1925{
1926 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1927 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1928 int channel = max98095_get_eq_channel(kcontrol->id.name);
1929 struct max98095_cdata *cdata;
1930
1931 cdata = &max98095->dai[channel];
1932 ucontrol->value.enumerated.item[0] = cdata->eq_sel;
1933
1934 return 0;
1935}
1936
1937static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
1938{
1939 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1940 struct max98095_pdata *pdata = max98095->pdata;
1941 struct max98095_eq_cfg *cfg;
1942 unsigned int cfgcnt;
1943 int i, j;
1944 const char **t;
1945 int ret;
1946
1947 struct snd_kcontrol_new controls[] = {
1948 SOC_ENUM_EXT("EQ1 Mode",
1949 max98095->eq_enum,
1950 max98095_get_eq_enum,
1951 max98095_put_eq_enum),
1952 SOC_ENUM_EXT("EQ2 Mode",
1953 max98095->eq_enum,
1954 max98095_get_eq_enum,
1955 max98095_put_eq_enum),
1956 };
1957
1958 cfg = pdata->eq_cfg;
1959 cfgcnt = pdata->eq_cfgcnt;
1960
1961 /* Setup an array of texts for the equalizer enum.
1962 * This is based on Mark Brown's equalizer driver code.
1963 */
1964 max98095->eq_textcnt = 0;
1965 max98095->eq_texts = NULL;
1966 for (i = 0; i < cfgcnt; i++) {
1967 for (j = 0; j < max98095->eq_textcnt; j++) {
1968 if (strcmp(cfg[i].name, max98095->eq_texts[j]) == 0)
1969 break;
1970 }
1971
1972 if (j != max98095->eq_textcnt)
1973 continue;
1974
1975 /* Expand the array */
1976 t = krealloc(max98095->eq_texts,
1977 sizeof(char *) * (max98095->eq_textcnt + 1),
1978 GFP_KERNEL);
1979 if (t == NULL)
1980 continue;
1981
1982 /* Store the new entry */
1983 t[max98095->eq_textcnt] = cfg[i].name;
1984 max98095->eq_textcnt++;
1985 max98095->eq_texts = t;
1986 }
1987
1988 /* Now point the soc_enum to .texts array items */
1989 max98095->eq_enum.texts = max98095->eq_texts;
1990 max98095->eq_enum.max = max98095->eq_textcnt;
1991
1992 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
1993 if (ret != 0)
1994 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
1995}
1996
1997static int max98095_get_bq_channel(const char *name)
1998{
1999 if (strcmp(name, "Biquad1 Mode") == 0)
2000 return 0;
2001 if (strcmp(name, "Biquad2 Mode") == 0)
2002 return 1;
2003 return -EINVAL;
2004}
2005
2006static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
2007 struct snd_ctl_elem_value *ucontrol)
2008{
2009 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2010 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2011 struct max98095_pdata *pdata = max98095->pdata;
2012 int channel = max98095_get_bq_channel(kcontrol->id.name);
2013 struct max98095_cdata *cdata;
2014 int sel = ucontrol->value.integer.value[0];
2015 struct max98095_biquad_cfg *coef_set;
2016 int fs, best, best_val, i;
2017 int regmask, regsave;
2018
2019 BUG_ON(channel > 1);
2020
2021 if (!pdata || !max98095->bq_textcnt)
2022 return 0;
2023
2024 if (sel >= pdata->bq_cfgcnt)
2025 return -EINVAL;
2026
2027 cdata = &max98095->dai[channel];
2028 cdata->bq_sel = sel;
2029 fs = cdata->rate;
2030
2031 /* Find the selected configuration with nearest sample rate */
2032 best = 0;
2033 best_val = INT_MAX;
2034 for (i = 0; i < pdata->bq_cfgcnt; i++) {
2035 if (strcmp(pdata->bq_cfg[i].name, max98095->bq_texts[sel]) == 0 &&
2036 abs(pdata->bq_cfg[i].rate - fs) < best_val) {
2037 best = i;
2038 best_val = abs(pdata->bq_cfg[i].rate - fs);
2039 }
2040 }
2041
2042 dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
2043 pdata->bq_cfg[best].name,
2044 pdata->bq_cfg[best].rate, fs);
2045
2046 coef_set = &pdata->bq_cfg[best];
2047
2048 regmask = (channel == 0) ? M98095_BQ1EN : M98095_BQ2EN;
2049
2050 /* Disable filter while configuring, and save current on/off state */
2051 regsave = snd_soc_read(codec, M98095_088_CFG_LEVEL);
2052 snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, 0);
2053
2054 mutex_lock(&codec->mutex);
2055 snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
2056 m98095_biquad_band(codec, channel, 0, coef_set->band1);
2057 m98095_biquad_band(codec, channel, 1, coef_set->band2);
2058 snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, 0);
2059 mutex_unlock(&codec->mutex);
2060
2061 /* Restore the original on/off state */
2062 snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, regsave);
2063 return 0;
2064}
2065
2066static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol,
2067 struct snd_ctl_elem_value *ucontrol)
2068{
2069 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2070 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2071 int channel = max98095_get_bq_channel(kcontrol->id.name);
2072 struct max98095_cdata *cdata;
2073
2074 cdata = &max98095->dai[channel];
2075 ucontrol->value.enumerated.item[0] = cdata->bq_sel;
2076
2077 return 0;
2078}
2079
2080static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
2081{
2082 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2083 struct max98095_pdata *pdata = max98095->pdata;
2084 struct max98095_biquad_cfg *cfg;
2085 unsigned int cfgcnt;
2086 int i, j;
2087 const char **t;
2088 int ret;
2089
2090 struct snd_kcontrol_new controls[] = {
2091 SOC_ENUM_EXT("Biquad1 Mode",
2092 max98095->bq_enum,
2093 max98095_get_bq_enum,
2094 max98095_put_bq_enum),
2095 SOC_ENUM_EXT("Biquad2 Mode",
2096 max98095->bq_enum,
2097 max98095_get_bq_enum,
2098 max98095_put_bq_enum),
2099 };
2100
2101 cfg = pdata->bq_cfg;
2102 cfgcnt = pdata->bq_cfgcnt;
2103
2104 /* Setup an array of texts for the biquad enum.
2105 * This is based on Mark Brown's equalizer driver code.
2106 */
2107 max98095->bq_textcnt = 0;
2108 max98095->bq_texts = NULL;
2109 for (i = 0; i < cfgcnt; i++) {
2110 for (j = 0; j < max98095->bq_textcnt; j++) {
2111 if (strcmp(cfg[i].name, max98095->bq_texts[j]) == 0)
2112 break;
2113 }
2114
2115 if (j != max98095->bq_textcnt)
2116 continue;
2117
2118 /* Expand the array */
2119 t = krealloc(max98095->bq_texts,
2120 sizeof(char *) * (max98095->bq_textcnt + 1),
2121 GFP_KERNEL);
2122 if (t == NULL)
2123 continue;
2124
2125 /* Store the new entry */
2126 t[max98095->bq_textcnt] = cfg[i].name;
2127 max98095->bq_textcnt++;
2128 max98095->bq_texts = t;
2129 }
2130
2131 /* Now point the soc_enum to .texts array items */
2132 max98095->bq_enum.texts = max98095->bq_texts;
2133 max98095->bq_enum.max = max98095->bq_textcnt;
2134
2135 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
2136 if (ret != 0)
2137 dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret);
2138}
2139
2140static void max98095_handle_pdata(struct snd_soc_codec *codec)
2141{
2142 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2143 struct max98095_pdata *pdata = max98095->pdata;
2144 u8 regval = 0;
2145
2146 if (!pdata) {
2147 dev_dbg(codec->dev, "No platform data\n");
2148 return;
2149 }
2150
2151 /* Configure mic for analog/digital mic mode */
2152 if (pdata->digmic_left_mode)
2153 regval |= M98095_DIGMIC_L;
2154
2155 if (pdata->digmic_right_mode)
2156 regval |= M98095_DIGMIC_R;
2157
2158 snd_soc_write(codec, M98095_087_CFG_MIC, regval);
2159
2160 /* Configure equalizers */
2161 if (pdata->eq_cfgcnt)
2162 max98095_handle_eq_pdata(codec);
2163
2164 /* Configure bi-quad filters */
2165 if (pdata->bq_cfgcnt)
2166 max98095_handle_bq_pdata(codec);
2167}
2168
2169#ifdef CONFIG_PM
2170static int max98095_suspend(struct snd_soc_codec *codec, pm_message_t state)
2171{
2172 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
2173
2174 return 0;
2175}
2176
2177static int max98095_resume(struct snd_soc_codec *codec)
2178{
2179 max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2180
2181 return 0;
2182}
2183#else
2184#define max98095_suspend NULL
2185#define max98095_resume NULL
2186#endif
2187
2188static int max98095_reset(struct snd_soc_codec *codec)
2189{
2190 int i, ret;
2191
2192 /* Gracefully reset the DSP core and the codec hardware
2193 * in a proper sequence */
2194 ret = snd_soc_write(codec, M98095_00F_HOST_CFG, 0);
2195 if (ret < 0) {
2196 dev_err(codec->dev, "Failed to reset DSP: %d\n", ret);
2197 return ret;
2198 }
2199
2200 ret = snd_soc_write(codec, M98095_097_PWR_SYS, 0);
2201 if (ret < 0) {
2202 dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
2203 return ret;
2204 }
2205
2206 /* Reset to hardware default for registers, as there is not
2207 * a soft reset hardware control register */
2208 for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) {
2209 ret = snd_soc_write(codec, i, max98095_reg_def[i]);
2210 if (ret < 0) {
2211 dev_err(codec->dev, "Failed to reset: %d\n", ret);
2212 return ret;
2213 }
2214 }
2215
2216 return ret;
2217}
2218
2219static int max98095_probe(struct snd_soc_codec *codec)
2220{
2221 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2222 struct max98095_cdata *cdata;
2223 int ret = 0;
2224
2225 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
2226 if (ret != 0) {
2227 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2228 return ret;
2229 }
2230
2231 /* reset the codec, the DSP core, and disable all interrupts */
2232 max98095_reset(codec);
2233
2234 /* initialize private data */
2235
2236 max98095->sysclk = (unsigned)-1;
2237 max98095->eq_textcnt = 0;
2238 max98095->bq_textcnt = 0;
2239
2240 cdata = &max98095->dai[0];
2241 cdata->rate = (unsigned)-1;
2242 cdata->fmt = (unsigned)-1;
2243 cdata->eq_sel = 0;
2244 cdata->bq_sel = 0;
2245
2246 cdata = &max98095->dai[1];
2247 cdata->rate = (unsigned)-1;
2248 cdata->fmt = (unsigned)-1;
2249 cdata->eq_sel = 0;
2250 cdata->bq_sel = 0;
2251
2252 cdata = &max98095->dai[2];
2253 cdata->rate = (unsigned)-1;
2254 cdata->fmt = (unsigned)-1;
2255 cdata->eq_sel = 0;
2256 cdata->bq_sel = 0;
2257
2258 max98095->lin_state = 0;
2259 max98095->mic1pre = 0;
2260 max98095->mic2pre = 0;
2261
2262 ret = snd_soc_read(codec, M98095_0FF_REV_ID);
2263 if (ret < 0) {
2264 dev_err(codec->dev, "Failed to read device revision: %d\n",
2265 ret);
2266 goto err_access;
2267 }
2268 dev_info(codec->dev, "revision %c\n", ret + 'A');
2269
2270 snd_soc_write(codec, M98095_097_PWR_SYS, M98095_PWRSV);
2271
2272 /* initialize registers cache to hardware default */
2273 max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2274
2275 snd_soc_write(codec, M98095_048_MIX_DAC_LR,
2276 M98095_DAI1L_TO_DACL|M98095_DAI1R_TO_DACR);
2277
2278 snd_soc_write(codec, M98095_049_MIX_DAC_M,
2279 M98095_DAI2M_TO_DACM|M98095_DAI3M_TO_DACM);
2280
2281 snd_soc_write(codec, M98095_092_PWR_EN_OUT, M98095_SPK_SPREADSPECTRUM);
2282 snd_soc_write(codec, M98095_045_CFG_DSP, M98095_DSPNORMAL);
2283 snd_soc_write(codec, M98095_04E_CFG_HP, M98095_HPNORMAL);
2284
2285 snd_soc_write(codec, M98095_02C_DAI1_IOCFG,
2286 M98095_S1NORMAL|M98095_SDATA);
2287
2288 snd_soc_write(codec, M98095_036_DAI2_IOCFG,
2289 M98095_S2NORMAL|M98095_SDATA);
2290
2291 snd_soc_write(codec, M98095_040_DAI3_IOCFG,
2292 M98095_S3NORMAL|M98095_SDATA);
2293
2294 max98095_handle_pdata(codec);
2295
2296 /* take the codec out of the shut down */
2297 snd_soc_update_bits(codec, M98095_097_PWR_SYS, M98095_SHDNRUN,
2298 M98095_SHDNRUN);
2299
2300 max98095_add_widgets(codec);
2301
2302err_access:
2303 return ret;
2304}
2305
2306static int max98095_remove(struct snd_soc_codec *codec)
2307{
2308 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
2309
2310 return 0;
2311}
2312
2313static struct snd_soc_codec_driver soc_codec_dev_max98095 = {
2314 .probe = max98095_probe,
2315 .remove = max98095_remove,
2316 .suspend = max98095_suspend,
2317 .resume = max98095_resume,
2318 .set_bias_level = max98095_set_bias_level,
2319 .reg_cache_size = ARRAY_SIZE(max98095_reg_def),
2320 .reg_word_size = sizeof(u8),
2321 .reg_cache_default = max98095_reg_def,
2322 .readable_register = max98095_readable,
2323 .volatile_register = max98095_volatile,
2324 .dapm_widgets = max98095_dapm_widgets,
2325 .num_dapm_widgets = ARRAY_SIZE(max98095_dapm_widgets),
2326 .dapm_routes = max98095_audio_map,
2327 .num_dapm_routes = ARRAY_SIZE(max98095_audio_map),
2328};
2329
2330static int max98095_i2c_probe(struct i2c_client *i2c,
2331 const struct i2c_device_id *id)
2332{
2333 struct max98095_priv *max98095;
2334 int ret;
2335
2336 max98095 = kzalloc(sizeof(struct max98095_priv), GFP_KERNEL);
2337 if (max98095 == NULL)
2338 return -ENOMEM;
2339
2340 max98095->devtype = id->driver_data;
2341 i2c_set_clientdata(i2c, max98095);
2342 max98095->control_data = i2c;
2343 max98095->pdata = i2c->dev.platform_data;
2344
2345 ret = snd_soc_register_codec(&i2c->dev,
2346 &soc_codec_dev_max98095, &max98095_dai[0], 3);
2347 if (ret < 0)
2348 kfree(max98095);
2349 return ret;
2350}
2351
2352static int __devexit max98095_i2c_remove(struct i2c_client *client)
2353{
2354 snd_soc_unregister_codec(&client->dev);
2355 kfree(i2c_get_clientdata(client));
2356
2357 return 0;
2358}
2359
2360static const struct i2c_device_id max98095_i2c_id[] = {
2361 { "max98095", MAX98095 },
2362 { }
2363};
2364MODULE_DEVICE_TABLE(i2c, max98095_i2c_id);
2365
2366static struct i2c_driver max98095_i2c_driver = {
2367 .driver = {
2368 .name = "max98095",
2369 .owner = THIS_MODULE,
2370 },
2371 .probe = max98095_i2c_probe,
2372 .remove = __devexit_p(max98095_i2c_remove),
2373 .id_table = max98095_i2c_id,
2374};
2375
2376static int __init max98095_init(void)
2377{
2378 int ret;
2379
2380 ret = i2c_add_driver(&max98095_i2c_driver);
2381 if (ret)
2382 pr_err("Failed to register max98095 I2C driver: %d\n", ret);
2383
2384 return ret;
2385}
2386module_init(max98095_init);
2387
2388static void __exit max98095_exit(void)
2389{
2390 i2c_del_driver(&max98095_i2c_driver);
2391}
2392module_exit(max98095_exit);
2393
2394MODULE_DESCRIPTION("ALSA SoC MAX98095 driver");
2395MODULE_AUTHOR("Peter Hsiang");
2396MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98095.h b/sound/soc/codecs/max98095.h
new file mode 100644
index 000000000000..891584a0eb03
--- /dev/null
+++ b/sound/soc/codecs/max98095.h
@@ -0,0 +1,299 @@
1/*
2 * max98095.h -- MAX98095 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _MAX98095_H
12#define _MAX98095_H
13
14/*
15 * MAX98095 Registers Definition
16 */
17
18#define M98095_000_HOST_DATA 0x00
19#define M98095_001_HOST_INT_STS 0x01
20#define M98095_002_HOST_RSP_STS 0x02
21#define M98095_003_HOST_CMD_STS 0x03
22#define M98095_004_CODEC_STS 0x04
23#define M98095_005_DAI1_ALC_STS 0x05
24#define M98095_006_DAI2_ALC_STS 0x06
25#define M98095_007_JACK_AUTO_STS 0x07
26#define M98095_008_JACK_MANUAL_STS 0x08
27#define M98095_009_JACK_VBAT_STS 0x09
28#define M98095_00A_ACC_ADC_STS 0x0A
29#define M98095_00B_MIC_NG_AGC_STS 0x0B
30#define M98095_00C_SPK_L_VOLT_STS 0x0C
31#define M98095_00D_SPK_R_VOLT_STS 0x0D
32#define M98095_00E_TEMP_SENSOR_STS 0x0E
33#define M98095_00F_HOST_CFG 0x0F
34#define M98095_010_HOST_INT_CFG 0x10
35#define M98095_011_HOST_INT_EN 0x11
36#define M98095_012_CODEC_INT_EN 0x12
37#define M98095_013_JACK_INT_EN 0x13
38#define M98095_014_JACK_INT_EN 0x14
39#define M98095_015_DEC 0x15
40#define M98095_016_RESERVED 0x16
41#define M98095_017_RESERVED 0x17
42#define M98095_018_KEYCODE3 0x18
43#define M98095_019_KEYCODE2 0x19
44#define M98095_01A_KEYCODE1 0x1A
45#define M98095_01B_KEYCODE0 0x1B
46#define M98095_01C_OEMCODE1 0x1C
47#define M98095_01D_OEMCODE0 0x1D
48#define M98095_01E_XCFG1 0x1E
49#define M98095_01F_XCFG2 0x1F
50#define M98095_020_XCFG3 0x20
51#define M98095_021_XCFG4 0x21
52#define M98095_022_XCFG5 0x22
53#define M98095_023_XCFG6 0x23
54#define M98095_024_XGPIO 0x24
55#define M98095_025_XCLKCFG 0x25
56#define M98095_026_SYS_CLK 0x26
57#define M98095_027_DAI1_CLKMODE 0x27
58#define M98095_028_DAI1_CLKCFG_HI 0x28
59#define M98095_029_DAI1_CLKCFG_LO 0x29
60#define M98095_02A_DAI1_FORMAT 0x2A
61#define M98095_02B_DAI1_CLOCK 0x2B
62#define M98095_02C_DAI1_IOCFG 0x2C
63#define M98095_02D_DAI1_TDM 0x2D
64#define M98095_02E_DAI1_FILTERS 0x2E
65#define M98095_02F_DAI1_LVL1 0x2F
66#define M98095_030_DAI1_LVL2 0x30
67#define M98095_031_DAI2_CLKMODE 0x31
68#define M98095_032_DAI2_CLKCFG_HI 0x32
69#define M98095_033_DAI2_CLKCFG_LO 0x33
70#define M98095_034_DAI2_FORMAT 0x34
71#define M98095_035_DAI2_CLOCK 0x35
72#define M98095_036_DAI2_IOCFG 0x36
73#define M98095_037_DAI2_TDM 0x37
74#define M98095_038_DAI2_FILTERS 0x38
75#define M98095_039_DAI2_LVL1 0x39
76#define M98095_03A_DAI2_LVL2 0x3A
77#define M98095_03B_DAI3_CLKMODE 0x3B
78#define M98095_03C_DAI3_CLKCFG_HI 0x3C
79#define M98095_03D_DAI3_CLKCFG_LO 0x3D
80#define M98095_03E_DAI3_FORMAT 0x3E
81#define M98095_03F_DAI3_CLOCK 0x3F
82#define M98095_040_DAI3_IOCFG 0x40
83#define M98095_041_DAI3_TDM 0x41
84#define M98095_042_DAI3_FILTERS 0x42
85#define M98095_043_DAI3_LVL1 0x43
86#define M98095_044_DAI3_LVL2 0x44
87#define M98095_045_CFG_DSP 0x45
88#define M98095_046_DAC_CTRL1 0x46
89#define M98095_047_DAC_CTRL2 0x47
90#define M98095_048_MIX_DAC_LR 0x48
91#define M98095_049_MIX_DAC_M 0x49
92#define M98095_04A_MIX_ADC_LEFT 0x4A
93#define M98095_04B_MIX_ADC_RIGHT 0x4B
94#define M98095_04C_MIX_HP_LEFT 0x4C
95#define M98095_04D_MIX_HP_RIGHT 0x4D
96#define M98095_04E_CFG_HP 0x4E
97#define M98095_04F_MIX_RCV 0x4F
98#define M98095_050_MIX_SPK_LEFT 0x50
99#define M98095_051_MIX_SPK_RIGHT 0x51
100#define M98095_052_MIX_SPK_CFG 0x52
101#define M98095_053_MIX_LINEOUT1 0x53
102#define M98095_054_MIX_LINEOUT2 0x54
103#define M98095_055_MIX_LINEOUT_CFG 0x55
104#define M98095_056_LVL_SIDETONE_DAI12 0x56
105#define M98095_057_LVL_SIDETONE_DAI3 0x57
106#define M98095_058_LVL_DAI1_PLAY 0x58
107#define M98095_059_LVL_DAI1_EQ 0x59
108#define M98095_05A_LVL_DAI2_PLAY 0x5A
109#define M98095_05B_LVL_DAI2_EQ 0x5B
110#define M98095_05C_LVL_DAI3_PLAY 0x5C
111#define M98095_05D_LVL_ADC_L 0x5D
112#define M98095_05E_LVL_ADC_R 0x5E
113#define M98095_05F_LVL_MIC1 0x5F
114#define M98095_060_LVL_MIC2 0x60
115#define M98095_061_LVL_LINEIN 0x61
116#define M98095_062_LVL_LINEOUT1 0x62
117#define M98095_063_LVL_LINEOUT2 0x63
118#define M98095_064_LVL_HP_L 0x64
119#define M98095_065_LVL_HP_R 0x65
120#define M98095_066_LVL_RCV 0x66
121#define M98095_067_LVL_SPK_L 0x67
122#define M98095_068_LVL_SPK_R 0x68
123#define M98095_069_MICAGC_CFG 0x69
124#define M98095_06A_MICAGC_THRESH 0x6A
125#define M98095_06B_SPK_NOISEGATE 0x6B
126#define M98095_06C_DAI1_ALC1_TIME 0x6C
127#define M98095_06D_DAI1_ALC1_COMP 0x6D
128#define M98095_06E_DAI1_ALC1_EXPN 0x6E
129#define M98095_06F_DAI1_ALC1_GAIN 0x6F
130#define M98095_070_DAI1_ALC2_TIME 0x70
131#define M98095_071_DAI1_ALC2_COMP 0x71
132#define M98095_072_DAI1_ALC2_EXPN 0x72
133#define M98095_073_DAI1_ALC2_GAIN 0x73
134#define M98095_074_DAI1_ALC3_TIME 0x74
135#define M98095_075_DAI1_ALC3_COMP 0x75
136#define M98095_076_DAI1_ALC3_EXPN 0x76
137#define M98095_077_DAI1_ALC3_GAIN 0x77
138#define M98095_078_DAI2_ALC1_TIME 0x78
139#define M98095_079_DAI2_ALC1_COMP 0x79
140#define M98095_07A_DAI2_ALC1_EXPN 0x7A
141#define M98095_07B_DAI2_ALC1_GAIN 0x7B
142#define M98095_07C_DAI2_ALC2_TIME 0x7C
143#define M98095_07D_DAI2_ALC2_COMP 0x7D
144#define M98095_07E_DAI2_ALC2_EXPN 0x7E
145#define M98095_07F_DAI2_ALC2_GAIN 0x7F
146#define M98095_080_DAI2_ALC3_TIME 0x80
147#define M98095_081_DAI2_ALC3_COMP 0x81
148#define M98095_082_DAI2_ALC3_EXPN 0x82
149#define M98095_083_DAI2_ALC3_GAIN 0x83
150#define M98095_084_HP_NOISE_GATE 0x84
151#define M98095_085_AUX_ADC 0x85
152#define M98095_086_CFG_LINE 0x86
153#define M98095_087_CFG_MIC 0x87
154#define M98095_088_CFG_LEVEL 0x88
155#define M98095_089_JACK_DET_AUTO 0x89
156#define M98095_08A_JACK_DET_MANUAL 0x8A
157#define M98095_08B_JACK_KEYSCAN_DBC 0x8B
158#define M98095_08C_JACK_KEYSCAN_DLY 0x8C
159#define M98095_08D_JACK_KEY_THRESH 0x8D
160#define M98095_08E_JACK_DC_SLEW 0x8E
161#define M98095_08F_JACK_TEST_CFG 0x8F
162#define M98095_090_PWR_EN_IN 0x90
163#define M98095_091_PWR_EN_OUT 0x91
164#define M98095_092_PWR_EN_OUT 0x92
165#define M98095_093_BIAS_CTRL 0x93
166#define M98095_094_PWR_DAC_21 0x94
167#define M98095_095_PWR_DAC_03 0x95
168#define M98095_096_PWR_DAC_CK 0x96
169#define M98095_097_PWR_SYS 0x97
170
171#define M98095_0FF_REV_ID 0xFF
172
173#define M98095_REG_CNT (0xFF+1)
174#define M98095_REG_MAX_CACHED 0X97
175
176/* MAX98095 Registers Bit Fields */
177
178/* M98095_00F_HOST_CFG */
179 #define M98095_SEG (1<<0)
180 #define M98095_XTEN (1<<1)
181 #define M98095_MDLLEN (1<<2)
182
183/* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */
184 #define M98095_CLKMODE_MASK 0xFF
185
186/* M98095_02A_DAI1_FORMAT, M98095_034_DAI2_FORMAT, M98095_03E_DAI3_FORMAT */
187 #define M98095_DAI_MAS (1<<7)
188 #define M98095_DAI_WCI (1<<6)
189 #define M98095_DAI_BCI (1<<5)
190 #define M98095_DAI_DLY (1<<4)
191 #define M98095_DAI_TDM (1<<2)
192 #define M98095_DAI_FSW (1<<1)
193 #define M98095_DAI_WS (1<<0)
194
195/* M98095_02B_DAI1_CLOCK, M98095_035_DAI2_CLOCK, M98095_03F_DAI3_CLOCK */
196 #define M98095_DAI_BSEL64 (1<<0)
197 #define M98095_DAI_DOSR_DIV2 (0<<5)
198 #define M98095_DAI_DOSR_DIV4 (1<<5)
199
200/* M98095_02C_DAI1_IOCFG, M98095_036_DAI2_IOCFG, M98095_040_DAI3_IOCFG */
201 #define M98095_S1NORMAL (1<<6)
202 #define M98095_S2NORMAL (2<<6)
203 #define M98095_S3NORMAL (3<<6)
204 #define M98095_SDATA (3<<0)
205
206/* M98095_02E_DAI1_FILTERS, M98095_038_DAI2_FILTERS, M98095_042_DAI3_FILTERS */
207 #define M98095_DAI_DHF (1<<3)
208
209/* M98095_045_DSP_CFG */
210 #define M98095_DSPNORMAL (5<<4)
211
212/* M98095_048_MIX_DAC_LR */
213 #define M98095_DAI1L_TO_DACR (1<<7)
214 #define M98095_DAI1R_TO_DACR (1<<6)
215 #define M98095_DAI2M_TO_DACR (1<<5)
216 #define M98095_DAI1L_TO_DACL (1<<3)
217 #define M98095_DAI1R_TO_DACL (1<<2)
218 #define M98095_DAI2M_TO_DACL (1<<1)
219 #define M98095_DAI3M_TO_DACL (1<<0)
220
221/* M98095_049_MIX_DAC_M */
222 #define M98095_DAI1L_TO_DACM (1<<3)
223 #define M98095_DAI1R_TO_DACM (1<<2)
224 #define M98095_DAI2M_TO_DACM (1<<1)
225 #define M98095_DAI3M_TO_DACM (1<<0)
226
227/* M98095_04E_MIX_HP_CFG */
228 #define M98095_HPNORMAL (3<<4)
229
230/* M98095_05F_LVL_MIC1, M98095_060_LVL_MIC2 */
231 #define M98095_MICPRE_MASK (3<<5)
232 #define M98095_MICPRE_SHIFT 5
233
234/* M98095_064_LVL_HP_L, M98095_065_LVL_HP_R */
235 #define M98095_HP_MUTE (1<<7)
236
237/* M98095_066_LVL_RCV */
238 #define M98095_REC_MUTE (1<<7)
239
240/* M98095_067_LVL_SPK_L, M98095_068_LVL_SPK_R */
241 #define M98095_SP_MUTE (1<<7)
242
243/* M98095_087_CFG_MIC */
244 #define M98095_MICSEL_MASK (3<<0)
245 #define M98095_DIGMIC_L (1<<2)
246 #define M98095_DIGMIC_R (1<<3)
247 #define M98095_DIGMIC2L (1<<4)
248 #define M98095_DIGMIC2R (1<<5)
249
250/* M98095_088_CFG_LEVEL */
251 #define M98095_VSEN (1<<6)
252 #define M98095_ZDEN (1<<5)
253 #define M98095_BQ2EN (1<<3)
254 #define M98095_BQ1EN (1<<2)
255 #define M98095_EQ2EN (1<<1)
256 #define M98095_EQ1EN (1<<0)
257
258/* M98095_090_PWR_EN_IN */
259 #define M98095_INEN (1<<7)
260 #define M98095_MB2EN (1<<3)
261 #define M98095_MB1EN (1<<2)
262 #define M98095_MBEN (3<<2)
263 #define M98095_ADREN (1<<1)
264 #define M98095_ADLEN (1<<0)
265
266/* M98095_091_PWR_EN_OUT */
267 #define M98095_HPLEN (1<<7)
268 #define M98095_HPREN (1<<6)
269 #define M98095_SPLEN (1<<5)
270 #define M98095_SPREN (1<<4)
271 #define M98095_RECEN (1<<3)
272 #define M98095_DALEN (1<<1)
273 #define M98095_DAREN (1<<0)
274
275/* M98095_092_PWR_EN_OUT */
276 #define M98095_SPK_FIXEDSPECTRUM (0<<4)
277 #define M98095_SPK_SPREADSPECTRUM (1<<4)
278
279/* M98095_097_PWR_SYS */
280 #define M98095_SHDNRUN (1<<7)
281 #define M98095_PERFMODE (1<<3)
282 #define M98095_HPPLYBACK (1<<2)
283 #define M98095_PWRSV8K (1<<1)
284 #define M98095_PWRSV (1<<0)
285
286#define M98095_COEFS_PER_BAND 5
287
288#define M98095_BYTE1(w) ((w >> 8) & 0xff)
289#define M98095_BYTE0(w) (w & 0xff)
290
291/* Equalizer filter coefficients */
292#define M98095_110_DAI1_EQ_BASE 0x10
293#define M98095_142_DAI2_EQ_BASE 0x42
294
295/* Biquad filter coefficients */
296#define M98095_174_DAI1_BQ_BASE 0x74
297#define M98095_17E_DAI2_BQ_BASE 0x7E
298
299#endif
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index 4d9fb279e146..84ffdebb8a8b 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -827,8 +827,6 @@ EXPORT_SYMBOL_GPL(sn95031_jack_detection);
827/* codec registration */ 827/* codec registration */
828static int sn95031_codec_probe(struct snd_soc_codec *codec) 828static int sn95031_codec_probe(struct snd_soc_codec *codec)
829{ 829{
830 int ret;
831
832 pr_debug("codec_probe called\n"); 830 pr_debug("codec_probe called\n");
833 831
834 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 832 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
@@ -879,16 +877,7 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
879 snd_soc_add_controls(codec, sn95031_snd_controls, 877 snd_soc_add_controls(codec, sn95031_snd_controls,
880 ARRAY_SIZE(sn95031_snd_controls)); 878 ARRAY_SIZE(sn95031_snd_controls));
881 879
882 ret = snd_soc_dapm_new_controls(&codec->dapm, sn95031_dapm_widgets, 880 return 0;
883 ARRAY_SIZE(sn95031_dapm_widgets));
884 if (ret)
885 pr_err("soc_dapm_new_control failed %d", ret);
886 ret = snd_soc_dapm_add_routes(&codec->dapm, sn95031_audio_map,
887 ARRAY_SIZE(sn95031_audio_map));
888 if (ret)
889 pr_err("soc_dapm_add_routes failed %d", ret);
890
891 return ret;
892} 881}
893 882
894static int sn95031_codec_remove(struct snd_soc_codec *codec) 883static int sn95031_codec_remove(struct snd_soc_codec *codec)
@@ -905,6 +894,10 @@ struct snd_soc_codec_driver sn95031_codec = {
905 .read = sn95031_read, 894 .read = sn95031_read,
906 .write = sn95031_write, 895 .write = sn95031_write,
907 .set_bias_level = sn95031_set_vaud_bias, 896 .set_bias_level = sn95031_set_vaud_bias,
897 .dapm_widgets = sn95031_dapm_widgets,
898 .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets),
899 .dapm_routes = sn95031_audio_map,
900 .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map),
908}; 901};
909 902
910static int __devinit sn95031_device_probe(struct platform_device *pdev) 903static int __devinit sn95031_device_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c
index 4c32b54913ad..6a1a7e705cd7 100644
--- a/sound/soc/codecs/spdif_transciever.c
+++ b/sound/soc/codecs/spdif_transciever.c
@@ -21,7 +21,7 @@
21#include <sound/pcm.h> 21#include <sound/pcm.h>
22#include <sound/initval.h> 22#include <sound/initval.h>
23 23
24MODULE_LICENSE("GPL"); 24#define DRV_NAME "spdif-dit"
25 25
26#define STUB_RATES SNDRV_PCM_RATE_8000_96000 26#define STUB_RATES SNDRV_PCM_RATE_8000_96000
27#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE 27#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE
@@ -56,7 +56,7 @@ static struct platform_driver spdif_dit_driver = {
56 .probe = spdif_dit_probe, 56 .probe = spdif_dit_probe,
57 .remove = spdif_dit_remove, 57 .remove = spdif_dit_remove,
58 .driver = { 58 .driver = {
59 .name = "spdif-dit", 59 .name = DRV_NAME,
60 .owner = THIS_MODULE, 60 .owner = THIS_MODULE,
61 }, 61 },
62}; 62};
@@ -74,3 +74,7 @@ static void __exit dit_exit(void)
74module_init(dit_modinit); 74module_init(dit_modinit);
75module_exit(dit_exit); 75module_exit(dit_exit);
76 76
77MODULE_AUTHOR("Steve Chen <schen@mvista.com>");
78MODULE_DESCRIPTION("SPDIF dummy codec driver");
79MODULE_LICENSE("GPL");
80MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 2727befd158e..84f4ad568556 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -32,6 +32,7 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/pm.h> 33#include <linux/pm.h>
34#include <linux/i2c.h> 34#include <linux/i2c.h>
35#include <linux/spi/spi.h>
35#include <linux/platform_device.h> 36#include <linux/platform_device.h>
36#include <linux/slab.h> 37#include <linux/slab.h>
37#include <sound/core.h> 38#include <sound/core.h>
@@ -39,18 +40,25 @@
39#include <sound/pcm_params.h> 40#include <sound/pcm_params.h>
40#include <sound/soc.h> 41#include <sound/soc.h>
41#include <sound/initval.h> 42#include <sound/initval.h>
43#include <sound/tlv.h>
42 44
43#include "ssm2602.h" 45#include "ssm2602.h"
44 46
45#define SSM2602_VERSION "0.1" 47#define SSM2602_VERSION "0.1"
46 48
49enum ssm2602_type {
50 SSM2602,
51 SSM2604,
52};
53
47/* codec private data */ 54/* codec private data */
48struct ssm2602_priv { 55struct ssm2602_priv {
49 unsigned int sysclk; 56 unsigned int sysclk;
50 enum snd_soc_control_type control_type; 57 enum snd_soc_control_type control_type;
51 void *control_data;
52 struct snd_pcm_substream *master_substream; 58 struct snd_pcm_substream *master_substream;
53 struct snd_pcm_substream *slave_substream; 59 struct snd_pcm_substream *slave_substream;
60
61 enum ssm2602_type type;
54}; 62};
55 63
56/* 64/*
@@ -60,60 +68,12 @@ struct ssm2602_priv {
60 * There is no point in caching the reset register 68 * There is no point in caching the reset register
61 */ 69 */
62static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = { 70static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = {
63 0x0017, 0x0017, 0x0079, 0x0079, 71 0x0097, 0x0097, 0x0079, 0x0079,
64 0x0000, 0x0000, 0x0000, 0x000a, 72 0x000a, 0x0008, 0x009f, 0x000a,
65 0x0000, 0x0000 73 0x0000, 0x0000
66}; 74};
67 75
68/* 76#define ssm2602_reset(c) snd_soc_write(c, SSM2602_RESET, 0)
69 * read ssm2602 register cache
70 */
71static inline unsigned int ssm2602_read_reg_cache(struct snd_soc_codec *codec,
72 unsigned int reg)
73{
74 u16 *cache = codec->reg_cache;
75 if (reg == SSM2602_RESET)
76 return 0;
77 if (reg >= SSM2602_CACHEREGNUM)
78 return -1;
79 return cache[reg];
80}
81
82/*
83 * write ssm2602 register cache
84 */
85static inline void ssm2602_write_reg_cache(struct snd_soc_codec *codec,
86 u16 reg, unsigned int value)
87{
88 u16 *cache = codec->reg_cache;
89 if (reg >= SSM2602_CACHEREGNUM)
90 return;
91 cache[reg] = value;
92}
93
94/*
95 * write to the ssm2602 register space
96 */
97static int ssm2602_write(struct snd_soc_codec *codec, unsigned int reg,
98 unsigned int value)
99{
100 u8 data[2];
101
102 /* data is
103 * D15..D9 ssm2602 register offset
104 * D8...D0 register data
105 */
106 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
107 data[1] = value & 0x00ff;
108
109 ssm2602_write_reg_cache(codec, reg, value);
110 if (codec->hw_write(codec->control_data, data, 2) == 2)
111 return 0;
112 else
113 return -EIO;
114}
115
116#define ssm2602_reset(c) ssm2602_write(c, SSM2602_RESET, 0)
117 77
118/*Appending several "None"s just for OSS mixer use*/ 78/*Appending several "None"s just for OSS mixer use*/
119static const char *ssm2602_input_select[] = { 79static const char *ssm2602_input_select[] = {
@@ -128,174 +88,187 @@ static const struct soc_enum ssm2602_enum[] = {
128 SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, 4, ssm2602_deemph), 88 SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, 4, ssm2602_deemph),
129}; 89};
130 90
131static const struct snd_kcontrol_new ssm2602_snd_controls[] = { 91static const unsigned int ssm260x_outmix_tlv[] = {
92 TLV_DB_RANGE_HEAD(2),
93 0, 47, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),
94 48, 127, TLV_DB_SCALE_ITEM(-7400, 100, 0),
95};
132 96
133SOC_DOUBLE_R("Master Playback Volume", SSM2602_LOUT1V, SSM2602_ROUT1V, 97static const DECLARE_TLV_DB_SCALE(ssm260x_inpga_tlv, -3450, 150, 0);
134 0, 127, 0), 98static const DECLARE_TLV_DB_SCALE(ssm260x_sidetone_tlv, -1500, 300, 0);
135SOC_DOUBLE_R("Master Playback ZC Switch", SSM2602_LOUT1V, SSM2602_ROUT1V,
136 7, 1, 0),
137 99
138SOC_DOUBLE_R("Capture Volume", SSM2602_LINVOL, SSM2602_RINVOL, 0, 31, 0), 100static const struct snd_kcontrol_new ssm260x_snd_controls[] = {
101SOC_DOUBLE_R_TLV("Capture Volume", SSM2602_LINVOL, SSM2602_RINVOL, 0, 45, 0,
102 ssm260x_inpga_tlv),
139SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1), 103SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1),
140 104
141SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0),
142SOC_SINGLE("Mic Boost2 (+20dB)", SSM2602_APANA, 7, 1, 0),
143SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1),
144
145SOC_SINGLE("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1),
146
147SOC_SINGLE("ADC High Pass Filter Switch", SSM2602_APDIGI, 0, 1, 1), 105SOC_SINGLE("ADC High Pass Filter Switch", SSM2602_APDIGI, 0, 1, 1),
148SOC_SINGLE("Store DC Offset Switch", SSM2602_APDIGI, 4, 1, 0), 106SOC_SINGLE("Store DC Offset Switch", SSM2602_APDIGI, 4, 1, 0),
149 107
150SOC_ENUM("Capture Source", ssm2602_enum[0]),
151
152SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]), 108SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]),
153}; 109};
154 110
111static const struct snd_kcontrol_new ssm2602_snd_controls[] = {
112SOC_DOUBLE_R_TLV("Master Playback Volume", SSM2602_LOUT1V, SSM2602_ROUT1V,
113 0, 127, 0, ssm260x_outmix_tlv),
114SOC_DOUBLE_R("Master Playback ZC Switch", SSM2602_LOUT1V, SSM2602_ROUT1V,
115 7, 1, 0),
116SOC_SINGLE_TLV("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1,
117 ssm260x_sidetone_tlv),
118
119SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0),
120SOC_SINGLE("Mic Boost2 (+20dB)", SSM2602_APANA, 8, 1, 0),
121SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1),
122};
123
155/* Output Mixer */ 124/* Output Mixer */
156static const struct snd_kcontrol_new ssm2602_output_mixer_controls[] = { 125static const struct snd_kcontrol_new ssm260x_output_mixer_controls[] = {
157SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0), 126SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0),
158SOC_DAPM_SINGLE("Mic Sidetone Switch", SSM2602_APANA, 5, 1, 0),
159SOC_DAPM_SINGLE("HiFi Playback Switch", SSM2602_APANA, 4, 1, 0), 127SOC_DAPM_SINGLE("HiFi Playback Switch", SSM2602_APANA, 4, 1, 0),
128SOC_DAPM_SINGLE("Mic Sidetone Switch", SSM2602_APANA, 5, 1, 0),
160}; 129};
161 130
162/* Input mux */ 131/* Input mux */
163static const struct snd_kcontrol_new ssm2602_input_mux_controls = 132static const struct snd_kcontrol_new ssm2602_input_mux_controls =
164SOC_DAPM_ENUM("Input Select", ssm2602_enum[0]); 133SOC_DAPM_ENUM("Input Select", ssm2602_enum[0]);
165 134
166static const struct snd_soc_dapm_widget ssm2602_dapm_widgets[] = { 135static const struct snd_soc_dapm_widget ssm260x_dapm_widgets[] = {
167SND_SOC_DAPM_MIXER("Output Mixer", SSM2602_PWR, 4, 1,
168 &ssm2602_output_mixer_controls[0],
169 ARRAY_SIZE(ssm2602_output_mixer_controls)),
170SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM2602_PWR, 3, 1), 136SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM2602_PWR, 3, 1),
137SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1),
138SND_SOC_DAPM_PGA("Line Input", SSM2602_PWR, 0, 1, NULL, 0),
139
140SND_SOC_DAPM_SUPPLY("Digital Core Power", SSM2602_ACTIVE, 0, 0, NULL, 0),
141
171SND_SOC_DAPM_OUTPUT("LOUT"), 142SND_SOC_DAPM_OUTPUT("LOUT"),
172SND_SOC_DAPM_OUTPUT("LHPOUT"),
173SND_SOC_DAPM_OUTPUT("ROUT"), 143SND_SOC_DAPM_OUTPUT("ROUT"),
174SND_SOC_DAPM_OUTPUT("RHPOUT"), 144SND_SOC_DAPM_INPUT("RLINEIN"),
175SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1), 145SND_SOC_DAPM_INPUT("LLINEIN"),
146};
147
148static const struct snd_soc_dapm_widget ssm2602_dapm_widgets[] = {
149SND_SOC_DAPM_MIXER("Output Mixer", SSM2602_PWR, 4, 1,
150 ssm260x_output_mixer_controls,
151 ARRAY_SIZE(ssm260x_output_mixer_controls)),
152
176SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &ssm2602_input_mux_controls), 153SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &ssm2602_input_mux_controls),
177SND_SOC_DAPM_PGA("Line Input", SSM2602_PWR, 0, 1, NULL, 0),
178SND_SOC_DAPM_MICBIAS("Mic Bias", SSM2602_PWR, 1, 1), 154SND_SOC_DAPM_MICBIAS("Mic Bias", SSM2602_PWR, 1, 1),
155
156SND_SOC_DAPM_OUTPUT("LHPOUT"),
157SND_SOC_DAPM_OUTPUT("RHPOUT"),
179SND_SOC_DAPM_INPUT("MICIN"), 158SND_SOC_DAPM_INPUT("MICIN"),
180SND_SOC_DAPM_INPUT("RLINEIN"),
181SND_SOC_DAPM_INPUT("LLINEIN"),
182}; 159};
183 160
184static const struct snd_soc_dapm_route audio_conn[] = { 161static const struct snd_soc_dapm_widget ssm2604_dapm_widgets[] = {
185 /* output mixer */ 162SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0,
163 ssm260x_output_mixer_controls,
164 ARRAY_SIZE(ssm260x_output_mixer_controls) - 1), /* Last element is the mic */
165};
166
167static const struct snd_soc_dapm_route ssm260x_routes[] = {
168 {"DAC", NULL, "Digital Core Power"},
169 {"ADC", NULL, "Digital Core Power"},
170
186 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 171 {"Output Mixer", "Line Bypass Switch", "Line Input"},
187 {"Output Mixer", "HiFi Playback Switch", "DAC"}, 172 {"Output Mixer", "HiFi Playback Switch", "DAC"},
173
174 {"ROUT", NULL, "Output Mixer"},
175 {"LOUT", NULL, "Output Mixer"},
176
177 {"Line Input", NULL, "LLINEIN"},
178 {"Line Input", NULL, "RLINEIN"},
179};
180
181static const struct snd_soc_dapm_route ssm2602_routes[] = {
188 {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"}, 182 {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
189 183
190 /* outputs */
191 {"RHPOUT", NULL, "Output Mixer"}, 184 {"RHPOUT", NULL, "Output Mixer"},
192 {"ROUT", NULL, "Output Mixer"},
193 {"LHPOUT", NULL, "Output Mixer"}, 185 {"LHPOUT", NULL, "Output Mixer"},
194 {"LOUT", NULL, "Output Mixer"},
195 186
196 /* input mux */
197 {"Input Mux", "Line", "Line Input"}, 187 {"Input Mux", "Line", "Line Input"},
198 {"Input Mux", "Mic", "Mic Bias"}, 188 {"Input Mux", "Mic", "Mic Bias"},
199 {"ADC", NULL, "Input Mux"}, 189 {"ADC", NULL, "Input Mux"},
200 190
201 /* inputs */
202 {"Line Input", NULL, "LLINEIN"},
203 {"Line Input", NULL, "RLINEIN"},
204 {"Mic Bias", NULL, "MICIN"}, 191 {"Mic Bias", NULL, "MICIN"},
205}; 192};
206 193
207static int ssm2602_add_widgets(struct snd_soc_codec *codec) 194static const struct snd_soc_dapm_route ssm2604_routes[] = {
208{ 195 {"ADC", NULL, "Line Input"},
209 struct snd_soc_dapm_context *dapm = &codec->dapm; 196};
210
211 snd_soc_dapm_new_controls(dapm, ssm2602_dapm_widgets,
212 ARRAY_SIZE(ssm2602_dapm_widgets));
213 snd_soc_dapm_add_routes(dapm, audio_conn, ARRAY_SIZE(audio_conn));
214
215 return 0;
216}
217 197
218struct _coeff_div { 198struct ssm2602_coeff {
219 u32 mclk; 199 u32 mclk;
220 u32 rate; 200 u32 rate;
221 u16 fs; 201 u8 srate;
222 u8 sr:4;
223 u8 bosr:1;
224 u8 usb:1;
225}; 202};
226 203
227/* codec mclk clock divider coefficients */ 204#define SSM2602_COEFF_SRATE(sr, bosr, usb) (((sr) << 2) | ((bosr) << 1) | (usb))
228static const struct _coeff_div coeff_div[] = { 205
206/* codec mclk clock coefficients */
207static const struct ssm2602_coeff ssm2602_coeff_table[] = {
229 /* 48k */ 208 /* 48k */
230 {12288000, 48000, 256, 0x0, 0x0, 0x0}, 209 {12288000, 48000, SSM2602_COEFF_SRATE(0x0, 0x0, 0x0)},
231 {18432000, 48000, 384, 0x0, 0x1, 0x0}, 210 {18432000, 48000, SSM2602_COEFF_SRATE(0x0, 0x1, 0x0)},
232 {12000000, 48000, 250, 0x0, 0x0, 0x1}, 211 {12000000, 48000, SSM2602_COEFF_SRATE(0x0, 0x0, 0x1)},
233 212
234 /* 32k */ 213 /* 32k */
235 {12288000, 32000, 384, 0x6, 0x0, 0x0}, 214 {12288000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x0)},
236 {18432000, 32000, 576, 0x6, 0x1, 0x0}, 215 {18432000, 32000, SSM2602_COEFF_SRATE(0x6, 0x1, 0x0)},
237 {12000000, 32000, 375, 0x6, 0x0, 0x1}, 216 {12000000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x1)},
238 217
239 /* 8k */ 218 /* 8k */
240 {12288000, 8000, 1536, 0x3, 0x0, 0x0}, 219 {12288000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x0)},
241 {18432000, 8000, 2304, 0x3, 0x1, 0x0}, 220 {18432000, 8000, SSM2602_COEFF_SRATE(0x3, 0x1, 0x0)},
242 {11289600, 8000, 1408, 0xb, 0x0, 0x0}, 221 {11289600, 8000, SSM2602_COEFF_SRATE(0xb, 0x0, 0x0)},
243 {16934400, 8000, 2112, 0xb, 0x1, 0x0}, 222 {16934400, 8000, SSM2602_COEFF_SRATE(0xb, 0x1, 0x0)},
244 {12000000, 8000, 1500, 0x3, 0x0, 0x1}, 223 {12000000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x1)},
245 224
246 /* 96k */ 225 /* 96k */
247 {12288000, 96000, 128, 0x7, 0x0, 0x0}, 226 {12288000, 96000, SSM2602_COEFF_SRATE(0x7, 0x0, 0x0)},
248 {18432000, 96000, 192, 0x7, 0x1, 0x0}, 227 {18432000, 96000, SSM2602_COEFF_SRATE(0x7, 0x1, 0x0)},
249 {12000000, 96000, 125, 0x7, 0x0, 0x1}, 228 {12000000, 96000, SSM2602_COEFF_SRATE(0x7, 0x0, 0x1)},
250 229
251 /* 44.1k */ 230 /* 44.1k */
252 {11289600, 44100, 256, 0x8, 0x0, 0x0}, 231 {11289600, 44100, SSM2602_COEFF_SRATE(0x8, 0x0, 0x0)},
253 {16934400, 44100, 384, 0x8, 0x1, 0x0}, 232 {16934400, 44100, SSM2602_COEFF_SRATE(0x8, 0x1, 0x0)},
254 {12000000, 44100, 272, 0x8, 0x1, 0x1}, 233 {12000000, 44100, SSM2602_COEFF_SRATE(0x8, 0x1, 0x1)},
255 234
256 /* 88.2k */ 235 /* 88.2k */
257 {11289600, 88200, 128, 0xf, 0x0, 0x0}, 236 {11289600, 88200, SSM2602_COEFF_SRATE(0xf, 0x0, 0x0)},
258 {16934400, 88200, 192, 0xf, 0x1, 0x0}, 237 {16934400, 88200, SSM2602_COEFF_SRATE(0xf, 0x1, 0x0)},
259 {12000000, 88200, 136, 0xf, 0x1, 0x1}, 238 {12000000, 88200, SSM2602_COEFF_SRATE(0xf, 0x1, 0x1)},
260}; 239};
261 240
262static inline int get_coeff(int mclk, int rate) 241static inline int ssm2602_get_coeff(int mclk, int rate)
263{ 242{
264 int i; 243 int i;
265 244
266 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { 245 for (i = 0; i < ARRAY_SIZE(ssm2602_coeff_table); i++) {
267 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) 246 if (ssm2602_coeff_table[i].rate == rate &&
268 return i; 247 ssm2602_coeff_table[i].mclk == mclk)
248 return ssm2602_coeff_table[i].srate;
269 } 249 }
270 return i; 250 return -EINVAL;
271} 251}
272 252
273static int ssm2602_hw_params(struct snd_pcm_substream *substream, 253static int ssm2602_hw_params(struct snd_pcm_substream *substream,
274 struct snd_pcm_hw_params *params, 254 struct snd_pcm_hw_params *params,
275 struct snd_soc_dai *dai) 255 struct snd_soc_dai *dai)
276{ 256{
277 u16 srate;
278 struct snd_soc_pcm_runtime *rtd = substream->private_data; 257 struct snd_soc_pcm_runtime *rtd = substream->private_data;
279 struct snd_soc_codec *codec = rtd->codec; 258 struct snd_soc_codec *codec = rtd->codec;
280 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 259 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
281 struct i2c_client *i2c = codec->control_data; 260 u16 iface = snd_soc_read(codec, SSM2602_IFACE) & 0xfff3;
282 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3; 261 int srate = ssm2602_get_coeff(ssm2602->sysclk, params_rate(params));
283 int i = get_coeff(ssm2602->sysclk, params_rate(params));
284 262
285 if (substream == ssm2602->slave_substream) { 263 if (substream == ssm2602->slave_substream) {
286 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n"); 264 dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n");
287 return 0; 265 return 0;
288 } 266 }
289 267
290 /*no match is found*/ 268 if (srate < 0)
291 if (i == ARRAY_SIZE(coeff_div)) 269 return srate;
292 return -EINVAL;
293
294 srate = (coeff_div[i].sr << 2) |
295 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
296 270
297 ssm2602_write(codec, SSM2602_ACTIVE, 0); 271 snd_soc_write(codec, SSM2602_SRATE, srate);
298 ssm2602_write(codec, SSM2602_SRATE, srate);
299 272
300 /* bit size */ 273 /* bit size */
301 switch (params_format(params)) { 274 switch (params_format(params)) {
@@ -311,8 +284,7 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
311 iface |= 0x000c; 284 iface |= 0x000c;
312 break; 285 break;
313 } 286 }
314 ssm2602_write(codec, SSM2602_IFACE, iface); 287 snd_soc_write(codec, SSM2602_IFACE, iface);
315 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
316 return 0; 288 return 0;
317} 289}
318 290
@@ -354,17 +326,6 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
354 return 0; 326 return 0;
355} 327}
356 328
357static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream,
358 struct snd_soc_dai *dai)
359{
360 struct snd_soc_pcm_runtime *rtd = substream->private_data;
361 struct snd_soc_codec *codec = rtd->codec;
362 /* set active */
363 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
364
365 return 0;
366}
367
368static void ssm2602_shutdown(struct snd_pcm_substream *substream, 329static void ssm2602_shutdown(struct snd_pcm_substream *substream,
369 struct snd_soc_dai *dai) 330 struct snd_soc_dai *dai)
370{ 331{
@@ -372,25 +333,22 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream,
372 struct snd_soc_codec *codec = rtd->codec; 333 struct snd_soc_codec *codec = rtd->codec;
373 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 334 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
374 335
375 /* deactivate */
376 if (!codec->active)
377 ssm2602_write(codec, SSM2602_ACTIVE, 0);
378
379 if (ssm2602->master_substream == substream) 336 if (ssm2602->master_substream == substream)
380 ssm2602->master_substream = ssm2602->slave_substream; 337 ssm2602->master_substream = ssm2602->slave_substream;
381 338
382 ssm2602->slave_substream = NULL; 339 ssm2602->slave_substream = NULL;
383} 340}
384 341
342
385static int ssm2602_mute(struct snd_soc_dai *dai, int mute) 343static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
386{ 344{
387 struct snd_soc_codec *codec = dai->codec; 345 struct snd_soc_codec *codec = dai->codec;
388 u16 mute_reg = ssm2602_read_reg_cache(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE; 346 u16 mute_reg = snd_soc_read(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE;
389 if (mute) 347 if (mute)
390 ssm2602_write(codec, SSM2602_APDIGI, 348 snd_soc_write(codec, SSM2602_APDIGI,
391 mute_reg | APDIGI_ENABLE_DAC_MUTE); 349 mute_reg | APDIGI_ENABLE_DAC_MUTE);
392 else 350 else
393 ssm2602_write(codec, SSM2602_APDIGI, mute_reg); 351 snd_soc_write(codec, SSM2602_APDIGI, mute_reg);
394 return 0; 352 return 0;
395} 353}
396 354
@@ -466,30 +424,29 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
466 } 424 }
467 425
468 /* set iface */ 426 /* set iface */
469 ssm2602_write(codec, SSM2602_IFACE, iface); 427 snd_soc_write(codec, SSM2602_IFACE, iface);
470 return 0; 428 return 0;
471} 429}
472 430
473static int ssm2602_set_bias_level(struct snd_soc_codec *codec, 431static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
474 enum snd_soc_bias_level level) 432 enum snd_soc_bias_level level)
475{ 433{
476 u16 reg = ssm2602_read_reg_cache(codec, SSM2602_PWR) & 0xff7f; 434 u16 reg = snd_soc_read(codec, SSM2602_PWR) & 0xff7f;
477 435
478 switch (level) { 436 switch (level) {
479 case SND_SOC_BIAS_ON: 437 case SND_SOC_BIAS_ON:
480 /* vref/mid, osc on, dac unmute */ 438 /* vref/mid, osc on, dac unmute */
481 ssm2602_write(codec, SSM2602_PWR, reg); 439 snd_soc_write(codec, SSM2602_PWR, reg);
482 break; 440 break;
483 case SND_SOC_BIAS_PREPARE: 441 case SND_SOC_BIAS_PREPARE:
484 break; 442 break;
485 case SND_SOC_BIAS_STANDBY: 443 case SND_SOC_BIAS_STANDBY:
486 /* everything off except vref/vmid, */ 444 /* everything off except vref/vmid, */
487 ssm2602_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN); 445 snd_soc_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN);
488 break; 446 break;
489 case SND_SOC_BIAS_OFF: 447 case SND_SOC_BIAS_OFF:
490 /* everything off, dac mute, inactive */ 448 /* everything off, dac mute, inactive */
491 ssm2602_write(codec, SSM2602_ACTIVE, 0); 449 snd_soc_write(codec, SSM2602_PWR, 0xffff);
492 ssm2602_write(codec, SSM2602_PWR, 0xffff);
493 break; 450 break;
494 451
495 } 452 }
@@ -506,7 +463,6 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
506 463
507static struct snd_soc_dai_ops ssm2602_dai_ops = { 464static struct snd_soc_dai_ops ssm2602_dai_ops = {
508 .startup = ssm2602_startup, 465 .startup = ssm2602_startup,
509 .prepare = ssm2602_pcm_prepare,
510 .hw_params = ssm2602_hw_params, 466 .hw_params = ssm2602_hw_params,
511 .shutdown = ssm2602_shutdown, 467 .shutdown = ssm2602_shutdown,
512 .digital_mute = ssm2602_mute, 468 .digital_mute = ssm2602_mute,
@@ -539,50 +495,87 @@ static int ssm2602_suspend(struct snd_soc_codec *codec, pm_message_t state)
539 495
540static int ssm2602_resume(struct snd_soc_codec *codec) 496static int ssm2602_resume(struct snd_soc_codec *codec)
541{ 497{
542 int i; 498 snd_soc_cache_sync(codec);
543 u8 data[2]; 499
544 u16 *cache = codec->reg_cache;
545
546 /* Sync reg_cache with the hardware */
547 for (i = 0; i < ARRAY_SIZE(ssm2602_reg); i++) {
548 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
549 data[1] = cache[i] & 0x00ff;
550 codec->hw_write(codec->control_data, data, 2);
551 }
552 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 500 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
501
553 return 0; 502 return 0;
554} 503}
555 504
556static int ssm2602_probe(struct snd_soc_codec *codec) 505static int ssm2602_probe(struct snd_soc_codec *codec)
557{ 506{
507 struct snd_soc_dapm_context *dapm = &codec->dapm;
508 int ret, reg;
509
510 reg = snd_soc_read(codec, SSM2602_LOUT1V);
511 snd_soc_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH);
512 reg = snd_soc_read(codec, SSM2602_ROUT1V);
513 snd_soc_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH);
514
515 ret = snd_soc_add_controls(codec, ssm2602_snd_controls,
516 ARRAY_SIZE(ssm2602_snd_controls));
517 if (ret)
518 return ret;
519
520 ret = snd_soc_dapm_new_controls(dapm, ssm2602_dapm_widgets,
521 ARRAY_SIZE(ssm2602_dapm_widgets));
522 if (ret)
523 return ret;
524
525 return snd_soc_dapm_add_routes(dapm, ssm2602_routes,
526 ARRAY_SIZE(ssm2602_routes));
527}
528
529static int ssm2604_probe(struct snd_soc_codec *codec)
530{
531 struct snd_soc_dapm_context *dapm = &codec->dapm;
532 int ret;
533
534 ret = snd_soc_dapm_new_controls(dapm, ssm2604_dapm_widgets,
535 ARRAY_SIZE(ssm2604_dapm_widgets));
536 if (ret)
537 return ret;
538
539 return snd_soc_dapm_add_routes(dapm, ssm2604_routes,
540 ARRAY_SIZE(ssm2604_routes));
541}
542
543static int ssm260x_probe(struct snd_soc_codec *codec)
544{
558 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 545 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
559 int ret = 0, reg; 546 int ret, reg;
560 547
561 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION); 548 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
562 549
563 codec->control_data = ssm2602->control_data; 550 ret = snd_soc_codec_set_cache_io(codec, 7, 9, ssm2602->control_type);
551 if (ret < 0) {
552 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
553 return ret;
554 }
564 555
565 ssm2602_reset(codec); 556 ret = ssm2602_reset(codec);
557 if (ret < 0) {
558 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
559 return ret;
560 }
566 561
567 /*power on device*/
568 ssm2602_write(codec, SSM2602_ACTIVE, 0);
569 /* set the update bits */ 562 /* set the update bits */
570 reg = ssm2602_read_reg_cache(codec, SSM2602_LINVOL); 563 reg = snd_soc_read(codec, SSM2602_LINVOL);
571 ssm2602_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH); 564 snd_soc_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH);
572 reg = ssm2602_read_reg_cache(codec, SSM2602_RINVOL); 565 reg = snd_soc_read(codec, SSM2602_RINVOL);
573 ssm2602_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH); 566 snd_soc_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH);
574 reg = ssm2602_read_reg_cache(codec, SSM2602_LOUT1V);
575 ssm2602_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH);
576 reg = ssm2602_read_reg_cache(codec, SSM2602_ROUT1V);
577 ssm2602_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH);
578 /*select Line in as default input*/ 567 /*select Line in as default input*/
579 ssm2602_write(codec, SSM2602_APANA, APANA_SELECT_DAC | 568 snd_soc_write(codec, SSM2602_APANA, APANA_SELECT_DAC |
580 APANA_ENABLE_MIC_BOOST); 569 APANA_ENABLE_MIC_BOOST);
581 ssm2602_write(codec, SSM2602_PWR, 0);
582 570
583 snd_soc_add_controls(codec, ssm2602_snd_controls, 571 switch (ssm2602->type) {
584 ARRAY_SIZE(ssm2602_snd_controls)); 572 case SSM2602:
585 ssm2602_add_widgets(codec); 573 ret = ssm2602_probe(codec);
574 break;
575 case SSM2604:
576 ret = ssm2604_probe(codec);
577 break;
578 }
586 579
587 return ret; 580 return ret;
588} 581}
@@ -595,18 +588,61 @@ static int ssm2602_remove(struct snd_soc_codec *codec)
595} 588}
596 589
597static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { 590static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
598 .probe = ssm2602_probe, 591 .probe = ssm260x_probe,
599 .remove = ssm2602_remove, 592 .remove = ssm2602_remove,
600 .suspend = ssm2602_suspend, 593 .suspend = ssm2602_suspend,
601 .resume = ssm2602_resume, 594 .resume = ssm2602_resume,
602 .read = ssm2602_read_reg_cache,
603 .write = ssm2602_write,
604 .set_bias_level = ssm2602_set_bias_level, 595 .set_bias_level = ssm2602_set_bias_level,
605 .reg_cache_size = sizeof(ssm2602_reg), 596 .reg_cache_size = ARRAY_SIZE(ssm2602_reg),
606 .reg_word_size = sizeof(u16), 597 .reg_word_size = sizeof(u16),
607 .reg_cache_default = ssm2602_reg, 598 .reg_cache_default = ssm2602_reg,
599
600 .controls = ssm260x_snd_controls,
601 .num_controls = ARRAY_SIZE(ssm260x_snd_controls),
602 .dapm_widgets = ssm260x_dapm_widgets,
603 .num_dapm_widgets = ARRAY_SIZE(ssm260x_dapm_widgets),
604 .dapm_routes = ssm260x_routes,
605 .num_dapm_routes = ARRAY_SIZE(ssm260x_routes),
608}; 606};
609 607
608#if defined(CONFIG_SPI_MASTER)
609static int __devinit ssm2602_spi_probe(struct spi_device *spi)
610{
611 struct ssm2602_priv *ssm2602;
612 int ret;
613
614 ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
615 if (ssm2602 == NULL)
616 return -ENOMEM;
617
618 spi_set_drvdata(spi, ssm2602);
619 ssm2602->control_type = SND_SOC_SPI;
620 ssm2602->type = SSM2602;
621
622 ret = snd_soc_register_codec(&spi->dev,
623 &soc_codec_dev_ssm2602, &ssm2602_dai, 1);
624 if (ret < 0)
625 kfree(ssm2602);
626 return ret;
627}
628
629static int __devexit ssm2602_spi_remove(struct spi_device *spi)
630{
631 snd_soc_unregister_codec(&spi->dev);
632 kfree(spi_get_drvdata(spi));
633 return 0;
634}
635
636static struct spi_driver ssm2602_spi_driver = {
637 .driver = {
638 .name = "ssm2602",
639 .owner = THIS_MODULE,
640 },
641 .probe = ssm2602_spi_probe,
642 .remove = __devexit_p(ssm2602_spi_remove),
643};
644#endif
645
610#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 646#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
611/* 647/*
612 * ssm2602 2 wire address is determined by GPIO5 648 * ssm2602 2 wire address is determined by GPIO5
@@ -614,7 +650,7 @@ static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
614 * low = 0x1a 650 * low = 0x1a
615 * high = 0x1b 651 * high = 0x1b
616 */ 652 */
617static int ssm2602_i2c_probe(struct i2c_client *i2c, 653static int __devinit ssm2602_i2c_probe(struct i2c_client *i2c,
618 const struct i2c_device_id *id) 654 const struct i2c_device_id *id)
619{ 655{
620 struct ssm2602_priv *ssm2602; 656 struct ssm2602_priv *ssm2602;
@@ -625,8 +661,8 @@ static int ssm2602_i2c_probe(struct i2c_client *i2c,
625 return -ENOMEM; 661 return -ENOMEM;
626 662
627 i2c_set_clientdata(i2c, ssm2602); 663 i2c_set_clientdata(i2c, ssm2602);
628 ssm2602->control_data = i2c;
629 ssm2602->control_type = SND_SOC_I2C; 664 ssm2602->control_type = SND_SOC_I2C;
665 ssm2602->type = id->driver_data;
630 666
631 ret = snd_soc_register_codec(&i2c->dev, 667 ret = snd_soc_register_codec(&i2c->dev,
632 &soc_codec_dev_ssm2602, &ssm2602_dai, 1); 668 &soc_codec_dev_ssm2602, &ssm2602_dai, 1);
@@ -635,7 +671,7 @@ static int ssm2602_i2c_probe(struct i2c_client *i2c,
635 return ret; 671 return ret;
636} 672}
637 673
638static int ssm2602_i2c_remove(struct i2c_client *client) 674static int __devexit ssm2602_i2c_remove(struct i2c_client *client)
639{ 675{
640 snd_soc_unregister_codec(&client->dev); 676 snd_soc_unregister_codec(&client->dev);
641 kfree(i2c_get_clientdata(client)); 677 kfree(i2c_get_clientdata(client));
@@ -643,7 +679,9 @@ static int ssm2602_i2c_remove(struct i2c_client *client)
643} 679}
644 680
645static const struct i2c_device_id ssm2602_i2c_id[] = { 681static const struct i2c_device_id ssm2602_i2c_id[] = {
646 { "ssm2602", 0 }, 682 { "ssm2602", SSM2602 },
683 { "ssm2603", SSM2602 },
684 { "ssm2604", SSM2604 },
647 { } 685 { }
648}; 686};
649MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id); 687MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id);
@@ -651,11 +689,11 @@ MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id);
651/* corgi i2c codec control layer */ 689/* corgi i2c codec control layer */
652static struct i2c_driver ssm2602_i2c_driver = { 690static struct i2c_driver ssm2602_i2c_driver = {
653 .driver = { 691 .driver = {
654 .name = "ssm2602-codec", 692 .name = "ssm2602",
655 .owner = THIS_MODULE, 693 .owner = THIS_MODULE,
656 }, 694 },
657 .probe = ssm2602_i2c_probe, 695 .probe = ssm2602_i2c_probe,
658 .remove = ssm2602_i2c_remove, 696 .remove = __devexit_p(ssm2602_i2c_remove),
659 .id_table = ssm2602_i2c_id, 697 .id_table = ssm2602_i2c_id,
660}; 698};
661#endif 699#endif
@@ -664,25 +702,35 @@ static struct i2c_driver ssm2602_i2c_driver = {
664static int __init ssm2602_modinit(void) 702static int __init ssm2602_modinit(void)
665{ 703{
666 int ret = 0; 704 int ret = 0;
705
706#if defined(CONFIG_SPI_MASTER)
707 ret = spi_register_driver(&ssm2602_spi_driver);
708 if (ret)
709 return ret;
710#endif
711
667#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 712#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
668 ret = i2c_add_driver(&ssm2602_i2c_driver); 713 ret = i2c_add_driver(&ssm2602_i2c_driver);
669 if (ret != 0) { 714 if (ret)
670 printk(KERN_ERR "Failed to register SSM2602 I2C driver: %d\n", 715 return ret;
671 ret);
672 }
673#endif 716#endif
717
674 return ret; 718 return ret;
675} 719}
676module_init(ssm2602_modinit); 720module_init(ssm2602_modinit);
677 721
678static void __exit ssm2602_exit(void) 722static void __exit ssm2602_exit(void)
679{ 723{
724#if defined(CONFIG_SPI_MASTER)
725 spi_unregister_driver(&ssm2602_spi_driver);
726#endif
727
680#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 728#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
681 i2c_del_driver(&ssm2602_i2c_driver); 729 i2c_del_driver(&ssm2602_i2c_driver);
682#endif 730#endif
683} 731}
684module_exit(ssm2602_exit); 732module_exit(ssm2602_exit);
685 733
686MODULE_DESCRIPTION("ASoC ssm2602 driver"); 734MODULE_DESCRIPTION("ASoC SSM2602/SSM2603/SSM2604 driver");
687MODULE_AUTHOR("Cliff Cai"); 735MODULE_AUTHOR("Cliff Cai");
688MODULE_LICENSE("GPL"); 736MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ssm2602.h b/sound/soc/codecs/ssm2602.h
index 42a47d0f8e25..b98c69168036 100644
--- a/sound/soc/codecs/ssm2602.h
+++ b/sound/soc/codecs/ssm2602.h
@@ -117,11 +117,5 @@
117#define SSM2602_CACHEREGNUM 10 117#define SSM2602_CACHEREGNUM 10
118 118
119#define SSM2602_SYSCLK 0 119#define SSM2602_SYSCLK 0
120#define SSM2602_DAI 0
121
122struct ssm2602_setup_data {
123 int i2c_bus;
124 unsigned short i2c_address;
125};
126 120
127#endif 121#endif
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 54a30ef0ec8b..33bb52f3f683 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -212,7 +212,7 @@ static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
212 SND_SOC_DAPM_INPUT("MICIN"), 212 SND_SOC_DAPM_INPUT("MICIN"),
213}; 213};
214 214
215static const struct snd_soc_dapm_route intercon[] = { 215static const struct snd_soc_dapm_route tlv320aic23_intercon[] = {
216 /* Output Mixer */ 216 /* Output Mixer */
217 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 217 {"Output Mixer", "Line Bypass Switch", "Line Input"},
218 {"Output Mixer", "Playback Switch", "DAC"}, 218 {"Output Mixer", "Playback Switch", "DAC"},
@@ -388,18 +388,6 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
388 return 0; 388 return 0;
389} 389}
390 390
391static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
392{
393 struct snd_soc_dapm_context *dapm = &codec->dapm;
394
395 snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
396 ARRAY_SIZE(tlv320aic23_dapm_widgets));
397 /* set up audio path interconnects */
398 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
399
400 return 0;
401}
402
403static int tlv320aic23_hw_params(struct snd_pcm_substream *substream, 391static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
404 struct snd_pcm_hw_params *params, 392 struct snd_pcm_hw_params *params,
405 struct snd_soc_dai *dai) 393 struct snd_soc_dai *dai)
@@ -676,7 +664,6 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec)
676 664
677 snd_soc_add_controls(codec, tlv320aic23_snd_controls, 665 snd_soc_add_controls(codec, tlv320aic23_snd_controls,
678 ARRAY_SIZE(tlv320aic23_snd_controls)); 666 ARRAY_SIZE(tlv320aic23_snd_controls));
679 tlv320aic23_add_widgets(codec);
680 667
681 return 0; 668 return 0;
682} 669}
@@ -698,6 +685,10 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
698 .read = tlv320aic23_read_reg_cache, 685 .read = tlv320aic23_read_reg_cache,
699 .write = tlv320aic23_write, 686 .write = tlv320aic23_write,
700 .set_bias_level = tlv320aic23_set_bias_level, 687 .set_bias_level = tlv320aic23_set_bias_level,
688 .dapm_widgets = tlv320aic23_dapm_widgets,
689 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
690 .dapm_routes = tlv320aic23_intercon,
691 .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon),
701}; 692};
702 693
703#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 694#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 6c43c13f0430..c3d96fc8c267 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -157,7 +157,8 @@ static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
157static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, 157static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
158 struct snd_ctl_elem_value *ucontrol) 158 struct snd_ctl_elem_value *ucontrol)
159{ 159{
160 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 160 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
161 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
161 struct soc_mixer_control *mc = 162 struct soc_mixer_control *mc =
162 (struct soc_mixer_control *)kcontrol->private_value; 163 (struct soc_mixer_control *)kcontrol->private_value;
163 unsigned int reg = mc->reg; 164 unsigned int reg = mc->reg;
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 082e9d51963f..faa5e9fb1471 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver 2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 * 3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> 4 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
5 * 5 *
6 * Copyright: (C) 2009 Nokia Corporation 6 * Copyright: (C) 2009 Nokia Corporation
7 * 7 *
@@ -587,6 +587,9 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
587 SND_SOC_DAPM_SUPPLY("Right DAC Power", 587 SND_SOC_DAPM_SUPPLY("Right DAC Power",
588 DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0), 588 DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0),
589 589
590 SND_SOC_DAPM_SUPPLY("Codec Power",
591 DAC33_PWR_CTRL, 4, 0, NULL, 0),
592
590 SND_SOC_DAPM_PRE("Pre Playback", dac33_playback_event), 593 SND_SOC_DAPM_PRE("Pre Playback", dac33_playback_event),
591 SND_SOC_DAPM_POST("Post Playback", dac33_playback_event), 594 SND_SOC_DAPM_POST("Post Playback", dac33_playback_event),
592}; 595};
@@ -619,6 +622,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
619 /* output */ 622 /* output */
620 {"LEFT_LO", NULL, "Output Left Amplifier"}, 623 {"LEFT_LO", NULL, "Output Left Amplifier"},
621 {"RIGHT_LO", NULL, "Output Right Amplifier"}, 624 {"RIGHT_LO", NULL, "Output Right Amplifier"},
625
626 {"LEFT_LO", NULL, "Codec Power"},
627 {"RIGHT_LO", NULL, "Codec Power"},
622}; 628};
623 629
624static int dac33_add_widgets(struct snd_soc_codec *codec) 630static int dac33_add_widgets(struct snd_soc_codec *codec)
@@ -636,13 +642,10 @@ static int dac33_add_widgets(struct snd_soc_codec *codec)
636static int dac33_set_bias_level(struct snd_soc_codec *codec, 642static int dac33_set_bias_level(struct snd_soc_codec *codec,
637 enum snd_soc_bias_level level) 643 enum snd_soc_bias_level level)
638{ 644{
639 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
640 int ret; 645 int ret;
641 646
642 switch (level) { 647 switch (level) {
643 case SND_SOC_BIAS_ON: 648 case SND_SOC_BIAS_ON:
644 if (!dac33->substream)
645 dac33_soft_power(codec, 1);
646 break; 649 break;
647 case SND_SOC_BIAS_PREPARE: 650 case SND_SOC_BIAS_PREPARE:
648 break; 651 break;
@@ -943,8 +946,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
943 /* Write registers 0x08 and 0x09 (MSB, LSB) */ 946 /* Write registers 0x08 and 0x09 (MSB, LSB) */
944 dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset); 947 dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset);
945 948
946 /* calib time: 128 is a nice number ;) */ 949 /* OSC calibration time */
947 dac33_write(codec, DAC33_CALIB_TIME, 128); 950 dac33_write(codec, DAC33_CALIB_TIME, 96);
948 951
949 /* adjustment treshold & step */ 952 /* adjustment treshold & step */
950 dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) | 953 dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) |
@@ -1655,5 +1658,5 @@ module_exit(dac33_module_exit);
1655 1658
1656 1659
1657MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver"); 1660MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver");
1658MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@nokia.com>"); 1661MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
1659MODULE_LICENSE("GPL"); 1662MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320dac33.h b/sound/soc/codecs/tlv320dac33.h
index 7c318b5da437..ed69670747bf 100644
--- a/sound/soc/codecs/tlv320dac33.h
+++ b/sound/soc/codecs/tlv320dac33.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver 2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 * 3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> 4 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
5 * 5 *
6 * Copyright: (C) 2009 Nokia Corporation 6 * Copyright: (C) 2009 Nokia Corporation
7 * 7 *
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 1f1ac8110bef..239e0c461068 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) Nokia Corporation 4 * Copyright (C) Nokia Corporation
5 * 5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> 6 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
@@ -495,7 +495,7 @@ static void __exit tpa6130a2_exit(void)
495 i2c_del_driver(&tpa6130a2_i2c_driver); 495 i2c_del_driver(&tpa6130a2_i2c_driver);
496} 496}
497 497
498MODULE_AUTHOR("Peter Ujfalusi"); 498MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
499MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver"); 499MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver");
500MODULE_LICENSE("GPL"); 500MODULE_LICENSE("GPL");
501 501
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index 5df49c8756b2..417444020ba6 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) Nokia Corporation 4 * Copyright (C) Nokia Corporation
5 * 5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> 6 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 255901c4460d..4c336636d4f5 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -960,9 +960,9 @@ static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -600, 600, 0);
960 960
961/* 961/*
962 * AFMGAIN volume control: 962 * AFMGAIN volume control:
963 * from 18 to 24 dB in 6 dB steps 963 * from -18 to 24 dB in 6 dB steps
964 */ 964 */
965static DECLARE_TLV_DB_SCALE(afm_amp_tlv, 1800, 600, 0); 965static DECLARE_TLV_DB_SCALE(afm_amp_tlv, -1800, 600, 0);
966 966
967/* 967/*
968 * HSGAIN volume control: 968 * HSGAIN volume control:
@@ -1049,7 +1049,7 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = {
1049 1049
1050 /* AFM gains */ 1050 /* AFM gains */
1051 SOC_DOUBLE_TLV("Aux FM Volume", 1051 SOC_DOUBLE_TLV("Aux FM Volume",
1052 TWL6040_REG_LINEGAIN, 0, 4, 0xF, 0, afm_amp_tlv), 1052 TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv),
1053 1053
1054 /* Playback gains */ 1054 /* Playback gains */
1055 SOC_TWL6040_DOUBLE_TLV("Headset Playback Volume", 1055 SOC_TWL6040_DOUBLE_TLV("Headset Playback Volume",
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 48ffd406a71d..a7b8f301bad3 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -601,9 +601,7 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
601 .reg_cache_step = 1, 601 .reg_cache_step = 1,
602 .read = uda134x_read_reg_cache, 602 .read = uda134x_read_reg_cache,
603 .write = uda134x_write, 603 .write = uda134x_write,
604#ifdef POWER_OFF_ON_STANDBY
605 .set_bias_level = uda134x_set_bias_level, 604 .set_bias_level = uda134x_set_bias_level,
606#endif
607}; 605};
608 606
609static int __devinit uda134x_codec_probe(struct platform_device *pdev) 607static int __devinit uda134x_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c
new file mode 100644
index 000000000000..14d0716bf009
--- /dev/null
+++ b/sound/soc/codecs/wm1250-ev1.c
@@ -0,0 +1,108 @@
1/*
2 * Driver for the 1250-EV1 audio I/O module
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/i2c.h>
16
17#include <sound/soc.h>
18#include <sound/soc-dapm.h>
19
20static const struct snd_soc_dapm_widget wm1250_ev1_dapm_widgets[] = {
21SND_SOC_DAPM_ADC("ADC", "wm1250-ev1 Capture", SND_SOC_NOPM, 0, 0),
22SND_SOC_DAPM_DAC("DAC", "wm1250-ev1 Playback", SND_SOC_NOPM, 0, 0),
23
24SND_SOC_DAPM_INPUT("WM1250 Input"),
25SND_SOC_DAPM_INPUT("WM1250 Output"),
26};
27
28static const struct snd_soc_dapm_route wm1250_ev1_dapm_routes[] = {
29 { "ADC", NULL, "WM1250 Input" },
30 { "WM1250 Output", NULL, "DAC" },
31};
32
33static struct snd_soc_dai_driver wm1250_ev1_dai = {
34 .name = "wm1250-ev1",
35 .playback = {
36 .stream_name = "Playback",
37 .channels_min = 1,
38 .channels_max = 1,
39 .rates = SNDRV_PCM_RATE_8000,
40 .formats = SNDRV_PCM_FMTBIT_S16_LE,
41 },
42 .capture = {
43 .stream_name = "Capture",
44 .channels_min = 1,
45 .channels_max = 1,
46 .rates = SNDRV_PCM_RATE_8000,
47 .formats = SNDRV_PCM_FMTBIT_S16_LE,
48 },
49};
50
51static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
52 .dapm_widgets = wm1250_ev1_dapm_widgets,
53 .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets),
54 .dapm_routes = wm1250_ev1_dapm_routes,
55 .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes),
56};
57
58static int __devinit wm1250_ev1_probe(struct i2c_client *i2c,
59 const struct i2c_device_id *id)
60{
61 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1,
62 &wm1250_ev1_dai, 1);
63}
64
65static int __devexit wm1250_ev1_remove(struct i2c_client *i2c)
66{
67 snd_soc_unregister_codec(&i2c->dev);
68
69 return 0;
70}
71
72static const struct i2c_device_id wm1250_ev1_i2c_id[] = {
73 { "wm1250-ev1", 0 },
74 { }
75};
76MODULE_DEVICE_TABLE(i2c, wm1250_ev1_i2c_id);
77
78static struct i2c_driver wm1250_ev1_i2c_driver = {
79 .driver = {
80 .name = "wm1250-ev1",
81 .owner = THIS_MODULE,
82 },
83 .probe = wm1250_ev1_probe,
84 .remove = __devexit_p(wm1250_ev1_remove),
85 .id_table = wm1250_ev1_i2c_id,
86};
87
88static int __init wm1250_ev1_modinit(void)
89{
90 int ret = 0;
91
92 ret = i2c_add_driver(&wm1250_ev1_i2c_driver);
93 if (ret != 0)
94 pr_err("Failed to register WM1250-EV1 I2C driver: %d\n", ret);
95
96 return ret;
97}
98module_init(wm1250_ev1_modinit);
99
100static void __exit wm1250_ev1_exit(void)
101{
102 i2c_del_driver(&wm1250_ev1_i2c_driver);
103}
104module_exit(wm1250_ev1_exit);
105
106MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
107MODULE_DESCRIPTION("WM1250-EV1 audio I/O module driver");
108MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 97c30382d3ff..a537e4af6ae7 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -77,7 +77,7 @@ SND_SOC_DAPM_OUTPUT("ROUT"),
77SND_SOC_DAPM_OUTPUT("RHPOUT"), 77SND_SOC_DAPM_OUTPUT("RHPOUT"),
78}; 78};
79 79
80static const struct snd_soc_dapm_route intercon[] = { 80static const struct snd_soc_dapm_route wm8711_intercon[] = {
81 /* output mixer */ 81 /* output mixer */
82 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 82 {"Output Mixer", "Line Bypass Switch", "Line Input"},
83 {"Output Mixer", "HiFi Playback Switch", "DAC"}, 83 {"Output Mixer", "HiFi Playback Switch", "DAC"},
@@ -89,17 +89,6 @@ static const struct snd_soc_dapm_route intercon[] = {
89 {"LOUT", NULL, "Output Mixer"}, 89 {"LOUT", NULL, "Output Mixer"},
90}; 90};
91 91
92static int wm8711_add_widgets(struct snd_soc_codec *codec)
93{
94 struct snd_soc_dapm_context *dapm = &codec->dapm;
95
96 snd_soc_dapm_new_controls(dapm, wm8711_dapm_widgets,
97 ARRAY_SIZE(wm8711_dapm_widgets));
98 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
99
100 return 0;
101}
102
103struct _coeff_div { 92struct _coeff_div {
104 u32 mclk; 93 u32 mclk;
105 u32 rate; 94 u32 rate;
@@ -398,7 +387,6 @@ static int wm8711_probe(struct snd_soc_codec *codec)
398 387
399 snd_soc_add_controls(codec, wm8711_snd_controls, 388 snd_soc_add_controls(codec, wm8711_snd_controls,
400 ARRAY_SIZE(wm8711_snd_controls)); 389 ARRAY_SIZE(wm8711_snd_controls));
401 wm8711_add_widgets(codec);
402 390
403 return ret; 391 return ret;
404 392
@@ -420,6 +408,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
420 .reg_cache_size = ARRAY_SIZE(wm8711_reg), 408 .reg_cache_size = ARRAY_SIZE(wm8711_reg),
421 .reg_word_size = sizeof(u16), 409 .reg_word_size = sizeof(u16),
422 .reg_cache_default = wm8711_reg, 410 .reg_cache_default = wm8711_reg,
411 .dapm_widgets = wm8711_dapm_widgets,
412 .num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets),
413 .dapm_routes = wm8711_intercon,
414 .num_dapm_routes = ARRAY_SIZE(wm8711_intercon),
423}; 415};
424 416
425#if defined(CONFIG_SPI_MASTER) 417#if defined(CONFIG_SPI_MASTER)
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 736b0352d0a7..86d4718d3a76 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -65,22 +65,11 @@ SND_SOC_DAPM_OUTPUT("VOUTL"),
65SND_SOC_DAPM_OUTPUT("VOUTR"), 65SND_SOC_DAPM_OUTPUT("VOUTR"),
66}; 66};
67 67
68static const struct snd_soc_dapm_route intercon[] = { 68static const struct snd_soc_dapm_route wm8728_intercon[] = {
69 {"VOUTL", NULL, "DAC"}, 69 {"VOUTL", NULL, "DAC"},
70 {"VOUTR", NULL, "DAC"}, 70 {"VOUTR", NULL, "DAC"},
71}; 71};
72 72
73static int wm8728_add_widgets(struct snd_soc_codec *codec)
74{
75 struct snd_soc_dapm_context *dapm = &codec->dapm;
76
77 snd_soc_dapm_new_controls(dapm, wm8728_dapm_widgets,
78 ARRAY_SIZE(wm8728_dapm_widgets));
79 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
80
81 return 0;
82}
83
84static int wm8728_mute(struct snd_soc_dai *dai, int mute) 73static int wm8728_mute(struct snd_soc_dai *dai, int mute)
85{ 74{
86 struct snd_soc_codec *codec = dai->codec; 75 struct snd_soc_codec *codec = dai->codec;
@@ -255,7 +244,6 @@ static int wm8728_probe(struct snd_soc_codec *codec)
255 244
256 snd_soc_add_controls(codec, wm8728_snd_controls, 245 snd_soc_add_controls(codec, wm8728_snd_controls,
257 ARRAY_SIZE(wm8728_snd_controls)); 246 ARRAY_SIZE(wm8728_snd_controls));
258 wm8728_add_widgets(codec);
259 247
260 return ret; 248 return ret;
261} 249}
@@ -275,6 +263,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
275 .reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults), 263 .reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults),
276 .reg_word_size = sizeof(u16), 264 .reg_word_size = sizeof(u16),
277 .reg_cache_default = wm8728_reg_defaults, 265 .reg_cache_default = wm8728_reg_defaults,
266 .dapm_widgets = wm8728_dapm_widgets,
267 .num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets),
268 .dapm_routes = wm8728_intercon,
269 .num_dapm_routes = ARRAY_SIZE(wm8728_intercon),
278}; 270};
279 271
280#if defined(CONFIG_SPI_MASTER) 272#if defined(CONFIG_SPI_MASTER)
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 0a67c31b2663..6dec7cee2cb4 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -201,7 +201,7 @@ static int wm8731_check_osc(struct snd_soc_dapm_widget *source,
201 return wm8731->sysclk_type == WM8731_SYSCLK_MCLK; 201 return wm8731->sysclk_type == WM8731_SYSCLK_MCLK;
202} 202}
203 203
204static const struct snd_soc_dapm_route intercon[] = { 204static const struct snd_soc_dapm_route wm8731_intercon[] = {
205 {"DAC", NULL, "OSC", wm8731_check_osc}, 205 {"DAC", NULL, "OSC", wm8731_check_osc},
206 {"ADC", NULL, "OSC", wm8731_check_osc}, 206 {"ADC", NULL, "OSC", wm8731_check_osc},
207 207
@@ -227,17 +227,6 @@ static const struct snd_soc_dapm_route intercon[] = {
227 {"Mic Bias", NULL, "MICIN"}, 227 {"Mic Bias", NULL, "MICIN"},
228}; 228};
229 229
230static int wm8731_add_widgets(struct snd_soc_codec *codec)
231{
232 struct snd_soc_dapm_context *dapm = &codec->dapm;
233
234 snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
235 ARRAY_SIZE(wm8731_dapm_widgets));
236 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
237
238 return 0;
239}
240
241struct _coeff_div { 230struct _coeff_div {
242 u32 mclk; 231 u32 mclk;
243 u32 rate; 232 u32 rate;
@@ -599,7 +588,6 @@ static int wm8731_probe(struct snd_soc_codec *codec)
599 588
600 snd_soc_add_controls(codec, wm8731_snd_controls, 589 snd_soc_add_controls(codec, wm8731_snd_controls,
601 ARRAY_SIZE(wm8731_snd_controls)); 590 ARRAY_SIZE(wm8731_snd_controls));
602 wm8731_add_widgets(codec);
603 591
604 /* Regulators will have been enabled by bias management */ 592 /* Regulators will have been enabled by bias management */
605 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 593 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
@@ -636,6 +624,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
636 .reg_cache_size = ARRAY_SIZE(wm8731_reg), 624 .reg_cache_size = ARRAY_SIZE(wm8731_reg),
637 .reg_word_size = sizeof(u16), 625 .reg_word_size = sizeof(u16),
638 .reg_cache_default = wm8731_reg, 626 .reg_cache_default = wm8731_reg,
627 .dapm_widgets = wm8731_dapm_widgets,
628 .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
629 .dapm_routes = wm8731_intercon,
630 .num_dapm_routes = ARRAY_SIZE(wm8731_intercon),
639}; 631};
640 632
641#if defined(CONFIG_SPI_MASTER) 633#if defined(CONFIG_SPI_MASTER)
@@ -667,7 +659,7 @@ static int __devexit wm8731_spi_remove(struct spi_device *spi)
667 659
668static struct spi_driver wm8731_spi_driver = { 660static struct spi_driver wm8731_spi_driver = {
669 .driver = { 661 .driver = {
670 .name = "wm8731-codec", 662 .name = "wm8731",
671 .owner = THIS_MODULE, 663 .owner = THIS_MODULE,
672 }, 664 },
673 .probe = wm8731_spi_probe, 665 .probe = wm8731_spi_probe,
@@ -711,7 +703,7 @@ MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
711 703
712static struct i2c_driver wm8731_i2c_driver = { 704static struct i2c_driver wm8731_i2c_driver = {
713 .driver = { 705 .driver = {
714 .name = "wm8731-codec", 706 .name = "wm8731",
715 .owner = THIS_MODULE, 707 .owner = THIS_MODULE,
716 }, 708 },
717 .probe = wm8731_i2c_probe, 709 .probe = wm8731_i2c_probe,
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index f52b623bb692..43e3d760766f 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -382,7 +382,8 @@ static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm,
382static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, 382static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
383 struct snd_ctl_elem_value *ucontrol) 383 struct snd_ctl_elem_value *ucontrol)
384{ 384{
385 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 385 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
386 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
386 struct snd_soc_codec *codec = widget->codec; 387 struct snd_soc_codec *codec = widget->codec;
387 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 388 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
388 u16 reg; 389 u16 reg;
@@ -634,6 +635,13 @@ static const struct soc_enum lsidetone_enum =
634static const struct soc_enum rsidetone_enum = 635static const struct soc_enum rsidetone_enum =
635 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text); 636 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text);
636 637
638static const char *adcinput_text[] = {
639 "ADC", "DMIC"
640};
641
642static const struct soc_enum adcinput_enum =
643 SOC_ENUM_SINGLE(WM8903_CLOCK_RATE_TEST_4, 9, 2, adcinput_text);
644
637static const char *aif_text[] = { 645static const char *aif_text[] = {
638 "Left", "Right" 646 "Left", "Right"
639}; 647};
@@ -692,7 +700,7 @@ SOC_ENUM("DRC Smoothing Threshold", drc_smoothing),
692SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup), 700SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup),
693 701
694SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT, 702SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT,
695 WM8903_ADC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv), 703 WM8903_ADC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
696SOC_ENUM("ADC Companding Mode", adc_companding), 704SOC_ENUM("ADC Companding Mode", adc_companding),
697SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0), 705SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0),
698 706
@@ -767,6 +775,9 @@ static const struct snd_kcontrol_new lsidetone_mux =
767static const struct snd_kcontrol_new rsidetone_mux = 775static const struct snd_kcontrol_new rsidetone_mux =
768 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum); 776 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum);
769 777
778static const struct snd_kcontrol_new adcinput_mux =
779 SOC_DAPM_ENUM("ADC Input", adcinput_enum);
780
770static const struct snd_kcontrol_new lcapture_mux = 781static const struct snd_kcontrol_new lcapture_mux =
771 SOC_DAPM_ENUM("Left Capture Mux", lcapture_enum); 782 SOC_DAPM_ENUM("Left Capture Mux", lcapture_enum);
772 783
@@ -817,6 +828,7 @@ SND_SOC_DAPM_INPUT("IN2L"),
817SND_SOC_DAPM_INPUT("IN2R"), 828SND_SOC_DAPM_INPUT("IN2R"),
818SND_SOC_DAPM_INPUT("IN3L"), 829SND_SOC_DAPM_INPUT("IN3L"),
819SND_SOC_DAPM_INPUT("IN3R"), 830SND_SOC_DAPM_INPUT("IN3R"),
831SND_SOC_DAPM_INPUT("DMICDAT"),
820 832
821SND_SOC_DAPM_OUTPUT("HPOUTL"), 833SND_SOC_DAPM_OUTPUT("HPOUTL"),
822SND_SOC_DAPM_OUTPUT("HPOUTR"), 834SND_SOC_DAPM_OUTPUT("HPOUTR"),
@@ -842,6 +854,9 @@ SND_SOC_DAPM_MUX("Right Input Mode Mux", SND_SOC_NOPM, 0, 0, &rinput_mode_mux),
842SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0), 854SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0),
843SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0), 855SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0),
844 856
857SND_SOC_DAPM_MUX("Left ADC Input", SND_SOC_NOPM, 0, 0, &adcinput_mux),
858SND_SOC_DAPM_MUX("Right ADC Input", SND_SOC_NOPM, 0, 0, &adcinput_mux),
859
845SND_SOC_DAPM_ADC("ADCL", NULL, WM8903_POWER_MANAGEMENT_6, 1, 0), 860SND_SOC_DAPM_ADC("ADCL", NULL, WM8903_POWER_MANAGEMENT_6, 1, 0),
846SND_SOC_DAPM_ADC("ADCR", NULL, WM8903_POWER_MANAGEMENT_6, 0, 0), 861SND_SOC_DAPM_ADC("ADCR", NULL, WM8903_POWER_MANAGEMENT_6, 0, 0),
847 862
@@ -930,7 +945,7 @@ SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0),
930SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0), 945SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0),
931}; 946};
932 947
933static const struct snd_soc_dapm_route intercon[] = { 948static const struct snd_soc_dapm_route wm8903_intercon[] = {
934 949
935 { "CLK_DSP", NULL, "CLK_SYS" }, 950 { "CLK_DSP", NULL, "CLK_SYS" },
936 { "Mic Bias", NULL, "CLK_SYS" }, 951 { "Mic Bias", NULL, "CLK_SYS" },
@@ -979,6 +994,11 @@ static const struct snd_soc_dapm_route intercon[] = {
979 { "Left Input PGA", NULL, "Left Input Mode Mux" }, 994 { "Left Input PGA", NULL, "Left Input Mode Mux" },
980 { "Right Input PGA", NULL, "Right Input Mode Mux" }, 995 { "Right Input PGA", NULL, "Right Input Mode Mux" },
981 996
997 { "Left ADC Input", "ADC", "Left Input PGA" },
998 { "Left ADC Input", "DMIC", "DMICDAT" },
999 { "Right ADC Input", "ADC", "Right Input PGA" },
1000 { "Right ADC Input", "DMIC", "DMICDAT" },
1001
982 { "Left Capture Mux", "Left", "ADCL" }, 1002 { "Left Capture Mux", "Left", "ADCL" },
983 { "Left Capture Mux", "Right", "ADCR" }, 1003 { "Left Capture Mux", "Right", "ADCR" },
984 1004
@@ -988,9 +1008,9 @@ static const struct snd_soc_dapm_route intercon[] = {
988 { "AIFTXL", NULL, "Left Capture Mux" }, 1008 { "AIFTXL", NULL, "Left Capture Mux" },
989 { "AIFTXR", NULL, "Right Capture Mux" }, 1009 { "AIFTXR", NULL, "Right Capture Mux" },
990 1010
991 { "ADCL", NULL, "Left Input PGA" }, 1011 { "ADCL", NULL, "Left ADC Input" },
992 { "ADCL", NULL, "CLK_DSP" }, 1012 { "ADCL", NULL, "CLK_DSP" },
993 { "ADCR", NULL, "Right Input PGA" }, 1013 { "ADCR", NULL, "Right ADC Input" },
994 { "ADCR", NULL, "CLK_DSP" }, 1014 { "ADCR", NULL, "CLK_DSP" },
995 1015
996 { "Left Playback Mux", "Left", "AIFRXL" }, 1016 { "Left Playback Mux", "Left", "AIFRXL" },
@@ -1087,17 +1107,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1087 { "Right Line Output PGA", NULL, "Charge Pump" }, 1107 { "Right Line Output PGA", NULL, "Charge Pump" },
1088}; 1108};
1089 1109
1090static int wm8903_add_widgets(struct snd_soc_codec *codec)
1091{
1092 struct snd_soc_dapm_context *dapm = &codec->dapm;
1093
1094 snd_soc_dapm_new_controls(dapm, wm8903_dapm_widgets,
1095 ARRAY_SIZE(wm8903_dapm_widgets));
1096 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
1097
1098 return 0;
1099}
1100
1101static int wm8903_set_bias_level(struct snd_soc_codec *codec, 1110static int wm8903_set_bias_level(struct snd_soc_codec *codec,
1102 enum snd_soc_bias_level level) 1111 enum snd_soc_bias_level level)
1103{ 1112{
@@ -2028,7 +2037,6 @@ static int wm8903_probe(struct snd_soc_codec *codec)
2028 2037
2029 snd_soc_add_controls(codec, wm8903_snd_controls, 2038 snd_soc_add_controls(codec, wm8903_snd_controls,
2030 ARRAY_SIZE(wm8903_snd_controls)); 2039 ARRAY_SIZE(wm8903_snd_controls));
2031 wm8903_add_widgets(codec);
2032 2040
2033 wm8903_init_gpio(codec); 2041 wm8903_init_gpio(codec);
2034 2042
@@ -2054,6 +2062,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
2054 .reg_cache_default = wm8903_reg_defaults, 2062 .reg_cache_default = wm8903_reg_defaults,
2055 .volatile_register = wm8903_volatile_register, 2063 .volatile_register = wm8903_volatile_register,
2056 .seq_notifier = wm8903_seq_notifier, 2064 .seq_notifier = wm8903_seq_notifier,
2065 .dapm_widgets = wm8903_dapm_widgets,
2066 .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets),
2067 .dapm_routes = wm8903_intercon,
2068 .num_dapm_routes = ARRAY_SIZE(wm8903_intercon),
2057}; 2069};
2058 2070
2059#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 2071#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/wm8915.c b/sound/soc/codecs/wm8915.c
new file mode 100644
index 000000000000..ccc9bd832794
--- /dev/null
+++ b/sound/soc/codecs/wm8915.c
@@ -0,0 +1,2931 @@
1/*
2 * wm8915.c - WM8915 audio codec interface
3 *
4 * Copyright 2011 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/completion.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/gcd.h>
20#include <linux/gpio.h>
21#include <linux/i2c.h>
22#include <linux/delay.h>
23#include <linux/regulator/consumer.h>
24#include <linux/slab.h>
25#include <linux/workqueue.h>
26#include <sound/core.h>
27#include <sound/jack.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/initval.h>
32#include <sound/tlv.h>
33#include <trace/events/asoc.h>
34
35#include <sound/wm8915.h>
36#include "wm8915.h"
37
38#define WM8915_AIFS 2
39
40#define HPOUT1L 1
41#define HPOUT1R 2
42#define HPOUT2L 4
43#define HPOUT2R 8
44
45#define WM8915_NUM_SUPPLIES 6
46static const char *wm8915_supply_names[WM8915_NUM_SUPPLIES] = {
47 "DCVDD",
48 "DBVDD",
49 "AVDD1",
50 "AVDD2",
51 "CPVDD",
52 "MICVDD",
53};
54
55struct wm8915_priv {
56 struct snd_soc_codec *codec;
57
58 int ldo1ena;
59
60 int sysclk;
61
62 int fll_src;
63 int fll_fref;
64 int fll_fout;
65
66 struct completion fll_lock;
67
68 u16 dcs_pending;
69 struct completion dcs_done;
70
71 u16 hpout_ena;
72 u16 hpout_pending;
73
74 struct regulator_bulk_data supplies[WM8915_NUM_SUPPLIES];
75 struct notifier_block disable_nb[WM8915_NUM_SUPPLIES];
76
77 struct wm8915_pdata pdata;
78
79 int rx_rate[WM8915_AIFS];
80
81 /* Platform dependant ReTune mobile configuration */
82 int num_retune_mobile_texts;
83 const char **retune_mobile_texts;
84 int retune_mobile_cfg[2];
85 struct soc_enum retune_mobile_enum;
86
87 struct snd_soc_jack *jack;
88 bool detecting;
89 bool jack_mic;
90 wm8915_polarity_fn polarity_cb;
91
92#ifdef CONFIG_GPIOLIB
93 struct gpio_chip gpio_chip;
94#endif
95};
96
97/* We can't use the same notifier block for more than one supply and
98 * there's no way I can see to get from a callback to the caller
99 * except container_of().
100 */
101#define WM8915_REGULATOR_EVENT(n) \
102static int wm8915_regulator_event_##n(struct notifier_block *nb, \
103 unsigned long event, void *data) \
104{ \
105 struct wm8915_priv *wm8915 = container_of(nb, struct wm8915_priv, \
106 disable_nb[n]); \
107 if (event & REGULATOR_EVENT_DISABLE) { \
108 wm8915->codec->cache_sync = 1; \
109 } \
110 return 0; \
111}
112
113WM8915_REGULATOR_EVENT(0)
114WM8915_REGULATOR_EVENT(1)
115WM8915_REGULATOR_EVENT(2)
116WM8915_REGULATOR_EVENT(3)
117WM8915_REGULATOR_EVENT(4)
118WM8915_REGULATOR_EVENT(5)
119
120static const u16 wm8915_reg[WM8915_MAX_REGISTER] = {
121 [WM8915_SOFTWARE_RESET] = 0x8915,
122 [WM8915_POWER_MANAGEMENT_7] = 0x10,
123 [WM8915_DAC1_HPOUT1_VOLUME] = 0x88,
124 [WM8915_DAC2_HPOUT2_VOLUME] = 0x88,
125 [WM8915_DAC1_LEFT_VOLUME] = 0x2c0,
126 [WM8915_DAC1_RIGHT_VOLUME] = 0x2c0,
127 [WM8915_DAC2_LEFT_VOLUME] = 0x2c0,
128 [WM8915_DAC2_RIGHT_VOLUME] = 0x2c0,
129 [WM8915_OUTPUT1_LEFT_VOLUME] = 0x80,
130 [WM8915_OUTPUT1_RIGHT_VOLUME] = 0x80,
131 [WM8915_OUTPUT2_LEFT_VOLUME] = 0x80,
132 [WM8915_OUTPUT2_RIGHT_VOLUME] = 0x80,
133 [WM8915_MICBIAS_1] = 0x39,
134 [WM8915_MICBIAS_2] = 0x39,
135 [WM8915_LDO_1] = 0x3,
136 [WM8915_LDO_2] = 0x13,
137 [WM8915_ACCESSORY_DETECT_MODE_1] = 0x4,
138 [WM8915_HEADPHONE_DETECT_1] = 0x20,
139 [WM8915_MIC_DETECT_1] = 0x7600,
140 [WM8915_MIC_DETECT_2] = 0xbf,
141 [WM8915_CHARGE_PUMP_1] = 0x1f25,
142 [WM8915_CHARGE_PUMP_2] = 0xab19,
143 [WM8915_DC_SERVO_5] = 0x2a2a,
144 [WM8915_CONTROL_INTERFACE_1] = 0x8004,
145 [WM8915_CLOCKING_1] = 0x10,
146 [WM8915_AIF_RATE] = 0x83,
147 [WM8915_FLL_CONTROL_4] = 0x5dc0,
148 [WM8915_FLL_CONTROL_5] = 0xc84,
149 [WM8915_FLL_EFS_2] = 0x2,
150 [WM8915_AIF1_TX_LRCLK_1] = 0x80,
151 [WM8915_AIF1_TX_LRCLK_2] = 0x8,
152 [WM8915_AIF1_RX_LRCLK_1] = 0x80,
153 [WM8915_AIF1TX_DATA_CONFIGURATION_1] = 0x1818,
154 [WM8915_AIF1RX_DATA_CONFIGURATION] = 0x1818,
155 [WM8915_AIF1TX_TEST] = 0x7,
156 [WM8915_AIF2_TX_LRCLK_1] = 0x80,
157 [WM8915_AIF2_TX_LRCLK_2] = 0x8,
158 [WM8915_AIF2_RX_LRCLK_1] = 0x80,
159 [WM8915_AIF2TX_DATA_CONFIGURATION_1] = 0x1818,
160 [WM8915_AIF2RX_DATA_CONFIGURATION] = 0x1818,
161 [WM8915_AIF2TX_TEST] = 0x1,
162 [WM8915_DSP1_TX_LEFT_VOLUME] = 0xc0,
163 [WM8915_DSP1_TX_RIGHT_VOLUME] = 0xc0,
164 [WM8915_DSP1_RX_LEFT_VOLUME] = 0xc0,
165 [WM8915_DSP1_RX_RIGHT_VOLUME] = 0xc0,
166 [WM8915_DSP1_TX_FILTERS] = 0x2000,
167 [WM8915_DSP1_RX_FILTERS_1] = 0x200,
168 [WM8915_DSP1_RX_FILTERS_2] = 0x10,
169 [WM8915_DSP1_DRC_1] = 0x98,
170 [WM8915_DSP1_DRC_2] = 0x845,
171 [WM8915_DSP1_RX_EQ_GAINS_1] = 0x6318,
172 [WM8915_DSP1_RX_EQ_GAINS_2] = 0x6300,
173 [WM8915_DSP1_RX_EQ_BAND_1_A] = 0xfca,
174 [WM8915_DSP1_RX_EQ_BAND_1_B] = 0x400,
175 [WM8915_DSP1_RX_EQ_BAND_1_PG] = 0xd8,
176 [WM8915_DSP1_RX_EQ_BAND_2_A] = 0x1eb5,
177 [WM8915_DSP1_RX_EQ_BAND_2_B] = 0xf145,
178 [WM8915_DSP1_RX_EQ_BAND_2_C] = 0xb75,
179 [WM8915_DSP1_RX_EQ_BAND_2_PG] = 0x1c5,
180 [WM8915_DSP1_RX_EQ_BAND_3_A] = 0x1c58,
181 [WM8915_DSP1_RX_EQ_BAND_3_B] = 0xf373,
182 [WM8915_DSP1_RX_EQ_BAND_3_C] = 0xa54,
183 [WM8915_DSP1_RX_EQ_BAND_3_PG] = 0x558,
184 [WM8915_DSP1_RX_EQ_BAND_4_A] = 0x168e,
185 [WM8915_DSP1_RX_EQ_BAND_4_B] = 0xf829,
186 [WM8915_DSP1_RX_EQ_BAND_4_C] = 0x7ad,
187 [WM8915_DSP1_RX_EQ_BAND_4_PG] = 0x1103,
188 [WM8915_DSP1_RX_EQ_BAND_5_A] = 0x564,
189 [WM8915_DSP1_RX_EQ_BAND_5_B] = 0x559,
190 [WM8915_DSP1_RX_EQ_BAND_5_PG] = 0x4000,
191 [WM8915_DSP2_TX_LEFT_VOLUME] = 0xc0,
192 [WM8915_DSP2_TX_RIGHT_VOLUME] = 0xc0,
193 [WM8915_DSP2_RX_LEFT_VOLUME] = 0xc0,
194 [WM8915_DSP2_RX_RIGHT_VOLUME] = 0xc0,
195 [WM8915_DSP2_TX_FILTERS] = 0x2000,
196 [WM8915_DSP2_RX_FILTERS_1] = 0x200,
197 [WM8915_DSP2_RX_FILTERS_2] = 0x10,
198 [WM8915_DSP2_DRC_1] = 0x98,
199 [WM8915_DSP2_DRC_2] = 0x845,
200 [WM8915_DSP2_RX_EQ_GAINS_1] = 0x6318,
201 [WM8915_DSP2_RX_EQ_GAINS_2] = 0x6300,
202 [WM8915_DSP2_RX_EQ_BAND_1_A] = 0xfca,
203 [WM8915_DSP2_RX_EQ_BAND_1_B] = 0x400,
204 [WM8915_DSP2_RX_EQ_BAND_1_PG] = 0xd8,
205 [WM8915_DSP2_RX_EQ_BAND_2_A] = 0x1eb5,
206 [WM8915_DSP2_RX_EQ_BAND_2_B] = 0xf145,
207 [WM8915_DSP2_RX_EQ_BAND_2_C] = 0xb75,
208 [WM8915_DSP2_RX_EQ_BAND_2_PG] = 0x1c5,
209 [WM8915_DSP2_RX_EQ_BAND_3_A] = 0x1c58,
210 [WM8915_DSP2_RX_EQ_BAND_3_B] = 0xf373,
211 [WM8915_DSP2_RX_EQ_BAND_3_C] = 0xa54,
212 [WM8915_DSP2_RX_EQ_BAND_3_PG] = 0x558,
213 [WM8915_DSP2_RX_EQ_BAND_4_A] = 0x168e,
214 [WM8915_DSP2_RX_EQ_BAND_4_B] = 0xf829,
215 [WM8915_DSP2_RX_EQ_BAND_4_C] = 0x7ad,
216 [WM8915_DSP2_RX_EQ_BAND_4_PG] = 0x1103,
217 [WM8915_DSP2_RX_EQ_BAND_5_A] = 0x564,
218 [WM8915_DSP2_RX_EQ_BAND_5_B] = 0x559,
219 [WM8915_DSP2_RX_EQ_BAND_5_PG] = 0x4000,
220 [WM8915_OVERSAMPLING] = 0xd,
221 [WM8915_SIDETONE] = 0x1040,
222 [WM8915_GPIO_1] = 0xa101,
223 [WM8915_GPIO_2] = 0xa101,
224 [WM8915_GPIO_3] = 0xa101,
225 [WM8915_GPIO_4] = 0xa101,
226 [WM8915_GPIO_5] = 0xa101,
227 [WM8915_PULL_CONTROL_2] = 0x140,
228 [WM8915_INTERRUPT_STATUS_1_MASK] = 0x1f,
229 [WM8915_INTERRUPT_STATUS_2_MASK] = 0x1ecf,
230 [WM8915_RIGHT_PDM_SPEAKER] = 0x1,
231 [WM8915_PDM_SPEAKER_MUTE_SEQUENCE] = 0x69,
232 [WM8915_PDM_SPEAKER_VOLUME] = 0x66,
233 [WM8915_WRITE_SEQUENCER_0] = 0x1,
234 [WM8915_WRITE_SEQUENCER_1] = 0x1,
235 [WM8915_WRITE_SEQUENCER_3] = 0x6,
236 [WM8915_WRITE_SEQUENCER_4] = 0x40,
237 [WM8915_WRITE_SEQUENCER_5] = 0x1,
238 [WM8915_WRITE_SEQUENCER_6] = 0xf,
239 [WM8915_WRITE_SEQUENCER_7] = 0x6,
240 [WM8915_WRITE_SEQUENCER_8] = 0x1,
241 [WM8915_WRITE_SEQUENCER_9] = 0x3,
242 [WM8915_WRITE_SEQUENCER_10] = 0x104,
243 [WM8915_WRITE_SEQUENCER_12] = 0x60,
244 [WM8915_WRITE_SEQUENCER_13] = 0x11,
245 [WM8915_WRITE_SEQUENCER_14] = 0x401,
246 [WM8915_WRITE_SEQUENCER_16] = 0x50,
247 [WM8915_WRITE_SEQUENCER_17] = 0x3,
248 [WM8915_WRITE_SEQUENCER_18] = 0x100,
249 [WM8915_WRITE_SEQUENCER_20] = 0x51,
250 [WM8915_WRITE_SEQUENCER_21] = 0x3,
251 [WM8915_WRITE_SEQUENCER_22] = 0x104,
252 [WM8915_WRITE_SEQUENCER_23] = 0xa,
253 [WM8915_WRITE_SEQUENCER_24] = 0x60,
254 [WM8915_WRITE_SEQUENCER_25] = 0x3b,
255 [WM8915_WRITE_SEQUENCER_26] = 0x502,
256 [WM8915_WRITE_SEQUENCER_27] = 0x100,
257 [WM8915_WRITE_SEQUENCER_28] = 0x2fff,
258 [WM8915_WRITE_SEQUENCER_32] = 0x2fff,
259 [WM8915_WRITE_SEQUENCER_36] = 0x2fff,
260 [WM8915_WRITE_SEQUENCER_40] = 0x2fff,
261 [WM8915_WRITE_SEQUENCER_44] = 0x2fff,
262 [WM8915_WRITE_SEQUENCER_48] = 0x2fff,
263 [WM8915_WRITE_SEQUENCER_52] = 0x2fff,
264 [WM8915_WRITE_SEQUENCER_56] = 0x2fff,
265 [WM8915_WRITE_SEQUENCER_60] = 0x2fff,
266 [WM8915_WRITE_SEQUENCER_64] = 0x1,
267 [WM8915_WRITE_SEQUENCER_65] = 0x1,
268 [WM8915_WRITE_SEQUENCER_67] = 0x6,
269 [WM8915_WRITE_SEQUENCER_68] = 0x40,
270 [WM8915_WRITE_SEQUENCER_69] = 0x1,
271 [WM8915_WRITE_SEQUENCER_70] = 0xf,
272 [WM8915_WRITE_SEQUENCER_71] = 0x6,
273 [WM8915_WRITE_SEQUENCER_72] = 0x1,
274 [WM8915_WRITE_SEQUENCER_73] = 0x3,
275 [WM8915_WRITE_SEQUENCER_74] = 0x104,
276 [WM8915_WRITE_SEQUENCER_76] = 0x60,
277 [WM8915_WRITE_SEQUENCER_77] = 0x11,
278 [WM8915_WRITE_SEQUENCER_78] = 0x401,
279 [WM8915_WRITE_SEQUENCER_80] = 0x50,
280 [WM8915_WRITE_SEQUENCER_81] = 0x3,
281 [WM8915_WRITE_SEQUENCER_82] = 0x100,
282 [WM8915_WRITE_SEQUENCER_84] = 0x60,
283 [WM8915_WRITE_SEQUENCER_85] = 0x3b,
284 [WM8915_WRITE_SEQUENCER_86] = 0x502,
285 [WM8915_WRITE_SEQUENCER_87] = 0x100,
286 [WM8915_WRITE_SEQUENCER_88] = 0x2fff,
287 [WM8915_WRITE_SEQUENCER_92] = 0x2fff,
288 [WM8915_WRITE_SEQUENCER_96] = 0x2fff,
289 [WM8915_WRITE_SEQUENCER_100] = 0x2fff,
290 [WM8915_WRITE_SEQUENCER_104] = 0x2fff,
291 [WM8915_WRITE_SEQUENCER_108] = 0x2fff,
292 [WM8915_WRITE_SEQUENCER_112] = 0x2fff,
293 [WM8915_WRITE_SEQUENCER_116] = 0x2fff,
294 [WM8915_WRITE_SEQUENCER_120] = 0x2fff,
295 [WM8915_WRITE_SEQUENCER_124] = 0x2fff,
296 [WM8915_WRITE_SEQUENCER_128] = 0x1,
297 [WM8915_WRITE_SEQUENCER_129] = 0x1,
298 [WM8915_WRITE_SEQUENCER_131] = 0x6,
299 [WM8915_WRITE_SEQUENCER_132] = 0x40,
300 [WM8915_WRITE_SEQUENCER_133] = 0x1,
301 [WM8915_WRITE_SEQUENCER_134] = 0xf,
302 [WM8915_WRITE_SEQUENCER_135] = 0x6,
303 [WM8915_WRITE_SEQUENCER_136] = 0x1,
304 [WM8915_WRITE_SEQUENCER_137] = 0x3,
305 [WM8915_WRITE_SEQUENCER_138] = 0x106,
306 [WM8915_WRITE_SEQUENCER_140] = 0x61,
307 [WM8915_WRITE_SEQUENCER_141] = 0x11,
308 [WM8915_WRITE_SEQUENCER_142] = 0x401,
309 [WM8915_WRITE_SEQUENCER_144] = 0x50,
310 [WM8915_WRITE_SEQUENCER_145] = 0x3,
311 [WM8915_WRITE_SEQUENCER_146] = 0x102,
312 [WM8915_WRITE_SEQUENCER_148] = 0x51,
313 [WM8915_WRITE_SEQUENCER_149] = 0x3,
314 [WM8915_WRITE_SEQUENCER_150] = 0x106,
315 [WM8915_WRITE_SEQUENCER_151] = 0xa,
316 [WM8915_WRITE_SEQUENCER_152] = 0x61,
317 [WM8915_WRITE_SEQUENCER_153] = 0x3b,
318 [WM8915_WRITE_SEQUENCER_154] = 0x502,
319 [WM8915_WRITE_SEQUENCER_155] = 0x100,
320 [WM8915_WRITE_SEQUENCER_156] = 0x2fff,
321 [WM8915_WRITE_SEQUENCER_160] = 0x2fff,
322 [WM8915_WRITE_SEQUENCER_164] = 0x2fff,
323 [WM8915_WRITE_SEQUENCER_168] = 0x2fff,
324 [WM8915_WRITE_SEQUENCER_172] = 0x2fff,
325 [WM8915_WRITE_SEQUENCER_176] = 0x2fff,
326 [WM8915_WRITE_SEQUENCER_180] = 0x2fff,
327 [WM8915_WRITE_SEQUENCER_184] = 0x2fff,
328 [WM8915_WRITE_SEQUENCER_188] = 0x2fff,
329 [WM8915_WRITE_SEQUENCER_192] = 0x1,
330 [WM8915_WRITE_SEQUENCER_193] = 0x1,
331 [WM8915_WRITE_SEQUENCER_195] = 0x6,
332 [WM8915_WRITE_SEQUENCER_196] = 0x40,
333 [WM8915_WRITE_SEQUENCER_197] = 0x1,
334 [WM8915_WRITE_SEQUENCER_198] = 0xf,
335 [WM8915_WRITE_SEQUENCER_199] = 0x6,
336 [WM8915_WRITE_SEQUENCER_200] = 0x1,
337 [WM8915_WRITE_SEQUENCER_201] = 0x3,
338 [WM8915_WRITE_SEQUENCER_202] = 0x106,
339 [WM8915_WRITE_SEQUENCER_204] = 0x61,
340 [WM8915_WRITE_SEQUENCER_205] = 0x11,
341 [WM8915_WRITE_SEQUENCER_206] = 0x401,
342 [WM8915_WRITE_SEQUENCER_208] = 0x50,
343 [WM8915_WRITE_SEQUENCER_209] = 0x3,
344 [WM8915_WRITE_SEQUENCER_210] = 0x102,
345 [WM8915_WRITE_SEQUENCER_212] = 0x61,
346 [WM8915_WRITE_SEQUENCER_213] = 0x3b,
347 [WM8915_WRITE_SEQUENCER_214] = 0x502,
348 [WM8915_WRITE_SEQUENCER_215] = 0x100,
349 [WM8915_WRITE_SEQUENCER_216] = 0x2fff,
350 [WM8915_WRITE_SEQUENCER_220] = 0x2fff,
351 [WM8915_WRITE_SEQUENCER_224] = 0x2fff,
352 [WM8915_WRITE_SEQUENCER_228] = 0x2fff,
353 [WM8915_WRITE_SEQUENCER_232] = 0x2fff,
354 [WM8915_WRITE_SEQUENCER_236] = 0x2fff,
355 [WM8915_WRITE_SEQUENCER_240] = 0x2fff,
356 [WM8915_WRITE_SEQUENCER_244] = 0x2fff,
357 [WM8915_WRITE_SEQUENCER_248] = 0x2fff,
358 [WM8915_WRITE_SEQUENCER_252] = 0x2fff,
359 [WM8915_WRITE_SEQUENCER_256] = 0x60,
360 [WM8915_WRITE_SEQUENCER_258] = 0x601,
361 [WM8915_WRITE_SEQUENCER_260] = 0x50,
362 [WM8915_WRITE_SEQUENCER_262] = 0x100,
363 [WM8915_WRITE_SEQUENCER_264] = 0x1,
364 [WM8915_WRITE_SEQUENCER_266] = 0x104,
365 [WM8915_WRITE_SEQUENCER_267] = 0x100,
366 [WM8915_WRITE_SEQUENCER_268] = 0x2fff,
367 [WM8915_WRITE_SEQUENCER_272] = 0x2fff,
368 [WM8915_WRITE_SEQUENCER_276] = 0x2fff,
369 [WM8915_WRITE_SEQUENCER_280] = 0x2fff,
370 [WM8915_WRITE_SEQUENCER_284] = 0x2fff,
371 [WM8915_WRITE_SEQUENCER_288] = 0x2fff,
372 [WM8915_WRITE_SEQUENCER_292] = 0x2fff,
373 [WM8915_WRITE_SEQUENCER_296] = 0x2fff,
374 [WM8915_WRITE_SEQUENCER_300] = 0x2fff,
375 [WM8915_WRITE_SEQUENCER_304] = 0x2fff,
376 [WM8915_WRITE_SEQUENCER_308] = 0x2fff,
377 [WM8915_WRITE_SEQUENCER_312] = 0x2fff,
378 [WM8915_WRITE_SEQUENCER_316] = 0x2fff,
379 [WM8915_WRITE_SEQUENCER_320] = 0x61,
380 [WM8915_WRITE_SEQUENCER_322] = 0x601,
381 [WM8915_WRITE_SEQUENCER_324] = 0x50,
382 [WM8915_WRITE_SEQUENCER_326] = 0x102,
383 [WM8915_WRITE_SEQUENCER_328] = 0x1,
384 [WM8915_WRITE_SEQUENCER_330] = 0x106,
385 [WM8915_WRITE_SEQUENCER_331] = 0x100,
386 [WM8915_WRITE_SEQUENCER_332] = 0x2fff,
387 [WM8915_WRITE_SEQUENCER_336] = 0x2fff,
388 [WM8915_WRITE_SEQUENCER_340] = 0x2fff,
389 [WM8915_WRITE_SEQUENCER_344] = 0x2fff,
390 [WM8915_WRITE_SEQUENCER_348] = 0x2fff,
391 [WM8915_WRITE_SEQUENCER_352] = 0x2fff,
392 [WM8915_WRITE_SEQUENCER_356] = 0x2fff,
393 [WM8915_WRITE_SEQUENCER_360] = 0x2fff,
394 [WM8915_WRITE_SEQUENCER_364] = 0x2fff,
395 [WM8915_WRITE_SEQUENCER_368] = 0x2fff,
396 [WM8915_WRITE_SEQUENCER_372] = 0x2fff,
397 [WM8915_WRITE_SEQUENCER_376] = 0x2fff,
398 [WM8915_WRITE_SEQUENCER_380] = 0x2fff,
399 [WM8915_WRITE_SEQUENCER_384] = 0x60,
400 [WM8915_WRITE_SEQUENCER_386] = 0x601,
401 [WM8915_WRITE_SEQUENCER_388] = 0x61,
402 [WM8915_WRITE_SEQUENCER_390] = 0x601,
403 [WM8915_WRITE_SEQUENCER_392] = 0x50,
404 [WM8915_WRITE_SEQUENCER_394] = 0x300,
405 [WM8915_WRITE_SEQUENCER_396] = 0x1,
406 [WM8915_WRITE_SEQUENCER_398] = 0x304,
407 [WM8915_WRITE_SEQUENCER_400] = 0x40,
408 [WM8915_WRITE_SEQUENCER_402] = 0xf,
409 [WM8915_WRITE_SEQUENCER_404] = 0x1,
410 [WM8915_WRITE_SEQUENCER_407] = 0x100,
411};
412
413static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0);
414static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0);
415static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
416static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0);
417static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0);
418static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0);
419static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
420
421static const char *sidetone_hpf_text[] = {
422 "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz"
423};
424
425static const struct soc_enum sidetone_hpf =
426 SOC_ENUM_SINGLE(WM8915_SIDETONE, 7, 6, sidetone_hpf_text);
427
428static const char *hpf_mode_text[] = {
429 "HiFi", "Custom", "Voice"
430};
431
432static const struct soc_enum dsp1tx_hpf_mode =
433 SOC_ENUM_SINGLE(WM8915_DSP1_TX_FILTERS, 3, 3, hpf_mode_text);
434
435static const struct soc_enum dsp2tx_hpf_mode =
436 SOC_ENUM_SINGLE(WM8915_DSP2_TX_FILTERS, 3, 3, hpf_mode_text);
437
438static const char *hpf_cutoff_text[] = {
439 "50Hz", "75Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
440};
441
442static const struct soc_enum dsp1tx_hpf_cutoff =
443 SOC_ENUM_SINGLE(WM8915_DSP1_TX_FILTERS, 0, 7, hpf_cutoff_text);
444
445static const struct soc_enum dsp2tx_hpf_cutoff =
446 SOC_ENUM_SINGLE(WM8915_DSP2_TX_FILTERS, 0, 7, hpf_cutoff_text);
447
448static void wm8915_set_retune_mobile(struct snd_soc_codec *codec, int block)
449{
450 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
451 struct wm8915_pdata *pdata = &wm8915->pdata;
452 int base, best, best_val, save, i, cfg, iface;
453
454 if (!wm8915->num_retune_mobile_texts)
455 return;
456
457 switch (block) {
458 case 0:
459 base = WM8915_DSP1_RX_EQ_GAINS_1;
460 if (snd_soc_read(codec, WM8915_POWER_MANAGEMENT_8) &
461 WM8915_DSP1RX_SRC)
462 iface = 1;
463 else
464 iface = 0;
465 break;
466 case 1:
467 base = WM8915_DSP1_RX_EQ_GAINS_2;
468 if (snd_soc_read(codec, WM8915_POWER_MANAGEMENT_8) &
469 WM8915_DSP2RX_SRC)
470 iface = 1;
471 else
472 iface = 0;
473 break;
474 default:
475 return;
476 }
477
478 /* Find the version of the currently selected configuration
479 * with the nearest sample rate. */
480 cfg = wm8915->retune_mobile_cfg[block];
481 best = 0;
482 best_val = INT_MAX;
483 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
484 if (strcmp(pdata->retune_mobile_cfgs[i].name,
485 wm8915->retune_mobile_texts[cfg]) == 0 &&
486 abs(pdata->retune_mobile_cfgs[i].rate
487 - wm8915->rx_rate[iface]) < best_val) {
488 best = i;
489 best_val = abs(pdata->retune_mobile_cfgs[i].rate
490 - wm8915->rx_rate[iface]);
491 }
492 }
493
494 dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
495 block,
496 pdata->retune_mobile_cfgs[best].name,
497 pdata->retune_mobile_cfgs[best].rate,
498 wm8915->rx_rate[iface]);
499
500 /* The EQ will be disabled while reconfiguring it, remember the
501 * current configuration.
502 */
503 save = snd_soc_read(codec, base);
504 save &= WM8915_DSP1RX_EQ_ENA;
505
506 for (i = 0; i < ARRAY_SIZE(pdata->retune_mobile_cfgs[best].regs); i++)
507 snd_soc_update_bits(codec, base + i, 0xffff,
508 pdata->retune_mobile_cfgs[best].regs[i]);
509
510 snd_soc_update_bits(codec, base, WM8915_DSP1RX_EQ_ENA, save);
511}
512
513/* Icky as hell but saves code duplication */
514static int wm8915_get_retune_mobile_block(const char *name)
515{
516 if (strcmp(name, "DSP1 EQ Mode") == 0)
517 return 0;
518 if (strcmp(name, "DSP2 EQ Mode") == 0)
519 return 1;
520 return -EINVAL;
521}
522
523static int wm8915_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol)
525{
526 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
528 struct wm8915_pdata *pdata = &wm8915->pdata;
529 int block = wm8915_get_retune_mobile_block(kcontrol->id.name);
530 int value = ucontrol->value.integer.value[0];
531
532 if (block < 0)
533 return block;
534
535 if (value >= pdata->num_retune_mobile_cfgs)
536 return -EINVAL;
537
538 wm8915->retune_mobile_cfg[block] = value;
539
540 wm8915_set_retune_mobile(codec, block);
541
542 return 0;
543}
544
545static int wm8915_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
546 struct snd_ctl_elem_value *ucontrol)
547{
548 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
549 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
550 int block = wm8915_get_retune_mobile_block(kcontrol->id.name);
551
552 ucontrol->value.enumerated.item[0] = wm8915->retune_mobile_cfg[block];
553
554 return 0;
555}
556
557static const struct snd_kcontrol_new wm8915_snd_controls[] = {
558SOC_DOUBLE_R_TLV("Capture Volume", WM8915_LEFT_LINE_INPUT_VOLUME,
559 WM8915_RIGHT_LINE_INPUT_VOLUME, 0, 31, 0, inpga_tlv),
560SOC_DOUBLE_R("Capture ZC Switch", WM8915_LEFT_LINE_INPUT_VOLUME,
561 WM8915_RIGHT_LINE_INPUT_VOLUME, 5, 1, 0),
562
563SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8915_DAC1_MIXER_VOLUMES,
564 0, 5, 24, 0, sidetone_tlv),
565SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8915_DAC2_MIXER_VOLUMES,
566 0, 5, 24, 0, sidetone_tlv),
567SOC_SINGLE("Sidetone LPF Switch", WM8915_SIDETONE, 12, 1, 0),
568SOC_ENUM("Sidetone HPF Cut-off", sidetone_hpf),
569SOC_SINGLE("Sidetone HPF Switch", WM8915_SIDETONE, 6, 1, 0),
570
571SOC_DOUBLE_R_TLV("DSP1 Capture Volume", WM8915_DSP1_TX_LEFT_VOLUME,
572 WM8915_DSP1_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
573SOC_DOUBLE_R_TLV("DSP2 Capture Volume", WM8915_DSP2_TX_LEFT_VOLUME,
574 WM8915_DSP2_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
575
576SOC_SINGLE("DSP1 Capture Notch Filter Switch", WM8915_DSP1_TX_FILTERS,
577 13, 1, 0),
578SOC_DOUBLE("DSP1 Capture HPF Switch", WM8915_DSP1_TX_FILTERS, 12, 11, 1, 0),
579SOC_ENUM("DSP1 Capture HPF Mode", dsp1tx_hpf_mode),
580SOC_ENUM("DSP1 Capture HPF Cutoff", dsp1tx_hpf_cutoff),
581
582SOC_SINGLE("DSP2 Capture Notch Filter Switch", WM8915_DSP2_TX_FILTERS,
583 13, 1, 0),
584SOC_DOUBLE("DSP2 Capture HPF Switch", WM8915_DSP2_TX_FILTERS, 12, 11, 1, 0),
585SOC_ENUM("DSP2 Capture HPF Mode", dsp2tx_hpf_mode),
586SOC_ENUM("DSP2 Capture HPF Cutoff", dsp2tx_hpf_cutoff),
587
588SOC_DOUBLE_R_TLV("DSP1 Playback Volume", WM8915_DSP1_RX_LEFT_VOLUME,
589 WM8915_DSP1_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
590SOC_SINGLE("DSP1 Playback Switch", WM8915_DSP1_RX_FILTERS_1, 9, 1, 1),
591
592SOC_DOUBLE_R_TLV("DSP2 Playback Volume", WM8915_DSP2_RX_LEFT_VOLUME,
593 WM8915_DSP2_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
594SOC_SINGLE("DSP2 Playback Switch", WM8915_DSP2_RX_FILTERS_1, 9, 1, 1),
595
596SOC_DOUBLE_R_TLV("DAC1 Volume", WM8915_DAC1_LEFT_VOLUME,
597 WM8915_DAC1_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
598SOC_DOUBLE_R("DAC1 Switch", WM8915_DAC1_LEFT_VOLUME,
599 WM8915_DAC1_RIGHT_VOLUME, 9, 1, 1),
600
601SOC_DOUBLE_R_TLV("DAC2 Volume", WM8915_DAC2_LEFT_VOLUME,
602 WM8915_DAC2_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
603SOC_DOUBLE_R("DAC2 Switch", WM8915_DAC2_LEFT_VOLUME,
604 WM8915_DAC2_RIGHT_VOLUME, 9, 1, 1),
605
606SOC_SINGLE("Speaker High Performance Switch", WM8915_OVERSAMPLING, 3, 1, 0),
607SOC_SINGLE("DMIC High Performance Switch", WM8915_OVERSAMPLING, 2, 1, 0),
608SOC_SINGLE("ADC High Performance Switch", WM8915_OVERSAMPLING, 1, 1, 0),
609SOC_SINGLE("DAC High Performance Switch", WM8915_OVERSAMPLING, 0, 1, 0),
610
611SOC_SINGLE("DAC Soft Mute Switch", WM8915_DAC_SOFTMUTE, 1, 1, 0),
612SOC_SINGLE("DAC Slow Soft Mute Switch", WM8915_DAC_SOFTMUTE, 0, 1, 0),
613
614SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8915_DAC1_HPOUT1_VOLUME, 0, 4,
615 8, 0, out_digital_tlv),
616SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8915_DAC2_HPOUT2_VOLUME, 0, 4,
617 8, 0, out_digital_tlv),
618
619SOC_DOUBLE_R_TLV("Output 1 Volume", WM8915_OUTPUT1_LEFT_VOLUME,
620 WM8915_OUTPUT1_RIGHT_VOLUME, 0, 12, 0, out_tlv),
621SOC_DOUBLE_R("Output 1 ZC Switch", WM8915_OUTPUT1_LEFT_VOLUME,
622 WM8915_OUTPUT1_RIGHT_VOLUME, 7, 1, 0),
623
624SOC_DOUBLE_R_TLV("Output 2 Volume", WM8915_OUTPUT2_LEFT_VOLUME,
625 WM8915_OUTPUT2_RIGHT_VOLUME, 0, 12, 0, out_tlv),
626SOC_DOUBLE_R("Output 2 ZC Switch", WM8915_OUTPUT2_LEFT_VOLUME,
627 WM8915_OUTPUT2_RIGHT_VOLUME, 7, 1, 0),
628
629SOC_DOUBLE_TLV("Speaker Volume", WM8915_PDM_SPEAKER_VOLUME, 0, 4, 8, 0,
630 spk_tlv),
631SOC_DOUBLE_R("Speaker Switch", WM8915_LEFT_PDM_SPEAKER,
632 WM8915_RIGHT_PDM_SPEAKER, 3, 1, 1),
633SOC_DOUBLE_R("Speaker ZC Switch", WM8915_LEFT_PDM_SPEAKER,
634 WM8915_RIGHT_PDM_SPEAKER, 2, 1, 0),
635
636SOC_SINGLE("DSP1 EQ Switch", WM8915_DSP1_RX_EQ_GAINS_1, 0, 1, 0),
637SOC_SINGLE("DSP2 EQ Switch", WM8915_DSP2_RX_EQ_GAINS_1, 0, 1, 0),
638};
639
640static const struct snd_kcontrol_new wm8915_eq_controls[] = {
641SOC_SINGLE_TLV("DSP1 EQ B1 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 11, 31, 0,
642 eq_tlv),
643SOC_SINGLE_TLV("DSP1 EQ B2 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 6, 31, 0,
644 eq_tlv),
645SOC_SINGLE_TLV("DSP1 EQ B3 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 1, 31, 0,
646 eq_tlv),
647SOC_SINGLE_TLV("DSP1 EQ B4 Volume", WM8915_DSP1_RX_EQ_GAINS_2, 11, 31, 0,
648 eq_tlv),
649SOC_SINGLE_TLV("DSP1 EQ B5 Volume", WM8915_DSP1_RX_EQ_GAINS_2, 6, 31, 0,
650 eq_tlv),
651
652SOC_SINGLE_TLV("DSP2 EQ B1 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 11, 31, 0,
653 eq_tlv),
654SOC_SINGLE_TLV("DSP2 EQ B2 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 6, 31, 0,
655 eq_tlv),
656SOC_SINGLE_TLV("DSP2 EQ B3 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 1, 31, 0,
657 eq_tlv),
658SOC_SINGLE_TLV("DSP2 EQ B4 Volume", WM8915_DSP2_RX_EQ_GAINS_2, 11, 31, 0,
659 eq_tlv),
660SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8915_DSP2_RX_EQ_GAINS_2, 6, 31, 0,
661 eq_tlv),
662};
663
664static int cp_event(struct snd_soc_dapm_widget *w,
665 struct snd_kcontrol *kcontrol, int event)
666{
667 switch (event) {
668 case SND_SOC_DAPM_POST_PMU:
669 msleep(5);
670 break;
671 default:
672 BUG();
673 return -EINVAL;
674 }
675
676 return 0;
677}
678
679static int rmv_short_event(struct snd_soc_dapm_widget *w,
680 struct snd_kcontrol *kcontrol, int event)
681{
682 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(w->codec);
683
684 /* Record which outputs we enabled */
685 switch (event) {
686 case SND_SOC_DAPM_PRE_PMD:
687 wm8915->hpout_pending &= ~w->shift;
688 break;
689 case SND_SOC_DAPM_PRE_PMU:
690 wm8915->hpout_pending |= w->shift;
691 break;
692 default:
693 BUG();
694 return -EINVAL;
695 }
696
697 return 0;
698}
699
700static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
701{
702 struct i2c_client *i2c = to_i2c_client(codec->dev);
703 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
704 int i, ret;
705 unsigned long timeout = 200;
706
707 snd_soc_write(codec, WM8915_DC_SERVO_2, mask);
708
709 /* Use the interrupt if possible */
710 do {
711 if (i2c->irq) {
712 timeout = wait_for_completion_timeout(&wm8915->dcs_done,
713 msecs_to_jiffies(200));
714 if (timeout == 0)
715 dev_err(codec->dev, "DC servo timed out\n");
716
717 } else {
718 msleep(1);
719 if (--i) {
720 timeout = 0;
721 break;
722 }
723 }
724
725 ret = snd_soc_read(codec, WM8915_DC_SERVO_2);
726 dev_dbg(codec->dev, "DC servo state: %x\n", ret);
727 } while (ret & mask);
728
729 if (timeout == 0)
730 dev_err(codec->dev, "DC servo timed out for %x\n", mask);
731 else
732 dev_dbg(codec->dev, "DC servo complete for %x\n", mask);
733}
734
735static void wm8915_seq_notifier(struct snd_soc_dapm_context *dapm,
736 enum snd_soc_dapm_type event, int subseq)
737{
738 struct snd_soc_codec *codec = container_of(dapm,
739 struct snd_soc_codec, dapm);
740 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
741 u16 val, mask;
742
743 /* Complete any pending DC servo starts */
744 if (wm8915->dcs_pending) {
745 dev_dbg(codec->dev, "Starting DC servo for %x\n",
746 wm8915->dcs_pending);
747
748 /* Trigger a startup sequence */
749 wait_for_dc_servo(codec, wm8915->dcs_pending
750 << WM8915_DCS_TRIG_STARTUP_0_SHIFT);
751
752 wm8915->dcs_pending = 0;
753 }
754
755 if (wm8915->hpout_pending != wm8915->hpout_ena) {
756 dev_dbg(codec->dev, "Applying RMV_SHORTs %x->%x\n",
757 wm8915->hpout_ena, wm8915->hpout_pending);
758
759 val = 0;
760 mask = 0;
761 if (wm8915->hpout_pending & HPOUT1L) {
762 val |= WM8915_HPOUT1L_RMV_SHORT;
763 mask |= WM8915_HPOUT1L_RMV_SHORT;
764 } else {
765 mask |= WM8915_HPOUT1L_RMV_SHORT |
766 WM8915_HPOUT1L_OUTP |
767 WM8915_HPOUT1L_DLY;
768 }
769
770 if (wm8915->hpout_pending & HPOUT1R) {
771 val |= WM8915_HPOUT1R_RMV_SHORT;
772 mask |= WM8915_HPOUT1R_RMV_SHORT;
773 } else {
774 mask |= WM8915_HPOUT1R_RMV_SHORT |
775 WM8915_HPOUT1R_OUTP |
776 WM8915_HPOUT1R_DLY;
777 }
778
779 snd_soc_update_bits(codec, WM8915_ANALOGUE_HP_1, mask, val);
780
781 val = 0;
782 mask = 0;
783 if (wm8915->hpout_pending & HPOUT2L) {
784 val |= WM8915_HPOUT2L_RMV_SHORT;
785 mask |= WM8915_HPOUT2L_RMV_SHORT;
786 } else {
787 mask |= WM8915_HPOUT2L_RMV_SHORT |
788 WM8915_HPOUT2L_OUTP |
789 WM8915_HPOUT2L_DLY;
790 }
791
792 if (wm8915->hpout_pending & HPOUT2R) {
793 val |= WM8915_HPOUT2R_RMV_SHORT;
794 mask |= WM8915_HPOUT2R_RMV_SHORT;
795 } else {
796 mask |= WM8915_HPOUT2R_RMV_SHORT |
797 WM8915_HPOUT2R_OUTP |
798 WM8915_HPOUT2R_DLY;
799 }
800
801 snd_soc_update_bits(codec, WM8915_ANALOGUE_HP_2, mask, val);
802
803 wm8915->hpout_ena = wm8915->hpout_pending;
804 }
805}
806
807static int dcs_start(struct snd_soc_dapm_widget *w,
808 struct snd_kcontrol *kcontrol, int event)
809{
810 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(w->codec);
811
812 switch (event) {
813 case SND_SOC_DAPM_POST_PMU:
814 wm8915->dcs_pending |= 1 << w->shift;
815 break;
816 default:
817 BUG();
818 return -EINVAL;
819 }
820
821 return 0;
822}
823
824static const char *sidetone_text[] = {
825 "IN1", "IN2",
826};
827
828static const struct soc_enum left_sidetone_enum =
829 SOC_ENUM_SINGLE(WM8915_SIDETONE, 0, 2, sidetone_text);
830
831static const struct snd_kcontrol_new left_sidetone =
832 SOC_DAPM_ENUM("Left Sidetone", left_sidetone_enum);
833
834static const struct soc_enum right_sidetone_enum =
835 SOC_ENUM_SINGLE(WM8915_SIDETONE, 1, 2, sidetone_text);
836
837static const struct snd_kcontrol_new right_sidetone =
838 SOC_DAPM_ENUM("Right Sidetone", right_sidetone_enum);
839
840static const char *spk_text[] = {
841 "DAC1L", "DAC1R", "DAC2L", "DAC2R"
842};
843
844static const struct soc_enum spkl_enum =
845 SOC_ENUM_SINGLE(WM8915_LEFT_PDM_SPEAKER, 0, 4, spk_text);
846
847static const struct snd_kcontrol_new spkl_mux =
848 SOC_DAPM_ENUM("SPKL", spkl_enum);
849
850static const struct soc_enum spkr_enum =
851 SOC_ENUM_SINGLE(WM8915_RIGHT_PDM_SPEAKER, 0, 4, spk_text);
852
853static const struct snd_kcontrol_new spkr_mux =
854 SOC_DAPM_ENUM("SPKR", spkr_enum);
855
856static const char *dsp1rx_text[] = {
857 "AIF1", "AIF2"
858};
859
860static const struct soc_enum dsp1rx_enum =
861 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 0, 2, dsp1rx_text);
862
863static const struct snd_kcontrol_new dsp1rx =
864 SOC_DAPM_ENUM("DSP1RX", dsp1rx_enum);
865
866static const char *dsp2rx_text[] = {
867 "AIF2", "AIF1"
868};
869
870static const struct soc_enum dsp2rx_enum =
871 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 4, 2, dsp2rx_text);
872
873static const struct snd_kcontrol_new dsp2rx =
874 SOC_DAPM_ENUM("DSP2RX", dsp2rx_enum);
875
876static const char *aif2tx_text[] = {
877 "DSP2", "DSP1", "AIF1"
878};
879
880static const struct soc_enum aif2tx_enum =
881 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 6, 3, aif2tx_text);
882
883static const struct snd_kcontrol_new aif2tx =
884 SOC_DAPM_ENUM("AIF2TX", aif2tx_enum);
885
886static const char *inmux_text[] = {
887 "ADC", "DMIC1", "DMIC2"
888};
889
890static const struct soc_enum in1_enum =
891 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_7, 0, 3, inmux_text);
892
893static const struct snd_kcontrol_new in1_mux =
894 SOC_DAPM_ENUM("IN1 Mux", in1_enum);
895
896static const struct soc_enum in2_enum =
897 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_7, 4, 3, inmux_text);
898
899static const struct snd_kcontrol_new in2_mux =
900 SOC_DAPM_ENUM("IN2 Mux", in2_enum);
901
902static const struct snd_kcontrol_new dac2r_mix[] = {
903SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING,
904 5, 1, 0),
905SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING,
906 4, 1, 0),
907SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, 1, 1, 0),
908SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, 0, 1, 0),
909};
910
911static const struct snd_kcontrol_new dac2l_mix[] = {
912SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC2_LEFT_MIXER_ROUTING,
913 5, 1, 0),
914SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC2_LEFT_MIXER_ROUTING,
915 4, 1, 0),
916SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, 1, 1, 0),
917SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, 0, 1, 0),
918};
919
920static const struct snd_kcontrol_new dac1r_mix[] = {
921SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING,
922 5, 1, 0),
923SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING,
924 4, 1, 0),
925SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, 1, 1, 0),
926SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, 0, 1, 0),
927};
928
929static const struct snd_kcontrol_new dac1l_mix[] = {
930SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC1_LEFT_MIXER_ROUTING,
931 5, 1, 0),
932SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC1_LEFT_MIXER_ROUTING,
933 4, 1, 0),
934SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, 1, 1, 0),
935SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, 0, 1, 0),
936};
937
938static const struct snd_kcontrol_new dsp1txl[] = {
939SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP1_TX_LEFT_MIXER_ROUTING,
940 1, 1, 0),
941SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP1_TX_LEFT_MIXER_ROUTING,
942 0, 1, 0),
943};
944
945static const struct snd_kcontrol_new dsp1txr[] = {
946SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP1_TX_RIGHT_MIXER_ROUTING,
947 1, 1, 0),
948SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP1_TX_RIGHT_MIXER_ROUTING,
949 0, 1, 0),
950};
951
952static const struct snd_kcontrol_new dsp2txl[] = {
953SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP2_TX_LEFT_MIXER_ROUTING,
954 1, 1, 0),
955SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP2_TX_LEFT_MIXER_ROUTING,
956 0, 1, 0),
957};
958
959static const struct snd_kcontrol_new dsp2txr[] = {
960SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP2_TX_RIGHT_MIXER_ROUTING,
961 1, 1, 0),
962SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP2_TX_RIGHT_MIXER_ROUTING,
963 0, 1, 0),
964};
965
966
967static const struct snd_soc_dapm_widget wm8915_dapm_widgets[] = {
968SND_SOC_DAPM_INPUT("IN1LN"),
969SND_SOC_DAPM_INPUT("IN1LP"),
970SND_SOC_DAPM_INPUT("IN1RN"),
971SND_SOC_DAPM_INPUT("IN1RP"),
972
973SND_SOC_DAPM_INPUT("IN2LN"),
974SND_SOC_DAPM_INPUT("IN2LP"),
975SND_SOC_DAPM_INPUT("IN2RN"),
976SND_SOC_DAPM_INPUT("IN2RP"),
977
978SND_SOC_DAPM_INPUT("DMIC1DAT"),
979SND_SOC_DAPM_INPUT("DMIC2DAT"),
980
981SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8915_AIF_CLOCKING_1, 0, 0, NULL, 0),
982SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8915_CLOCKING_1, 1, 0, NULL, 0),
983SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8915_CLOCKING_1, 2, 0, NULL, 0),
984SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8915_CHARGE_PUMP_1, 15, 0, cp_event,
985 SND_SOC_DAPM_POST_PMU),
986
987SND_SOC_DAPM_SUPPLY("LDO2", WM8915_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
988SND_SOC_DAPM_MICBIAS("MICB2", WM8915_POWER_MANAGEMENT_1, 9, 0),
989SND_SOC_DAPM_MICBIAS("MICB1", WM8915_POWER_MANAGEMENT_1, 8, 0),
990
991SND_SOC_DAPM_PGA("IN1L PGA", WM8915_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
992SND_SOC_DAPM_PGA("IN1R PGA", WM8915_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
993
994SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &in1_mux),
995SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &in1_mux),
996SND_SOC_DAPM_MUX("IN2L Mux", SND_SOC_NOPM, 0, 0, &in2_mux),
997SND_SOC_DAPM_MUX("IN2R Mux", SND_SOC_NOPM, 0, 0, &in2_mux),
998
999SND_SOC_DAPM_PGA("IN1L", WM8915_POWER_MANAGEMENT_7, 2, 0, NULL, 0),
1000SND_SOC_DAPM_PGA("IN1R", WM8915_POWER_MANAGEMENT_7, 3, 0, NULL, 0),
1001SND_SOC_DAPM_PGA("IN2L", WM8915_POWER_MANAGEMENT_7, 6, 0, NULL, 0),
1002SND_SOC_DAPM_PGA("IN2R", WM8915_POWER_MANAGEMENT_7, 7, 0, NULL, 0),
1003
1004SND_SOC_DAPM_SUPPLY("DMIC2", WM8915_POWER_MANAGEMENT_7, 9, 0, NULL, 0),
1005SND_SOC_DAPM_SUPPLY("DMIC1", WM8915_POWER_MANAGEMENT_7, 8, 0, NULL, 0),
1006
1007SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8915_POWER_MANAGEMENT_3, 5, 0),
1008SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8915_POWER_MANAGEMENT_3, 4, 0),
1009SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8915_POWER_MANAGEMENT_3, 3, 0),
1010SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8915_POWER_MANAGEMENT_3, 2, 0),
1011
1012SND_SOC_DAPM_ADC("ADCL", NULL, WM8915_POWER_MANAGEMENT_3, 1, 0),
1013SND_SOC_DAPM_ADC("ADCR", NULL, WM8915_POWER_MANAGEMENT_3, 0, 0),
1014
1015SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &left_sidetone),
1016SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &right_sidetone),
1017
1018SND_SOC_DAPM_AIF_IN("DSP2RXL", NULL, 0, WM8915_POWER_MANAGEMENT_3, 11, 0),
1019SND_SOC_DAPM_AIF_IN("DSP2RXR", NULL, 1, WM8915_POWER_MANAGEMENT_3, 10, 0),
1020SND_SOC_DAPM_AIF_IN("DSP1RXL", NULL, 0, WM8915_POWER_MANAGEMENT_3, 9, 0),
1021SND_SOC_DAPM_AIF_IN("DSP1RXR", NULL, 1, WM8915_POWER_MANAGEMENT_3, 8, 0),
1022
1023SND_SOC_DAPM_MIXER("DSP2TXL", WM8915_POWER_MANAGEMENT_5, 11, 0,
1024 dsp2txl, ARRAY_SIZE(dsp2txl)),
1025SND_SOC_DAPM_MIXER("DSP2TXR", WM8915_POWER_MANAGEMENT_5, 10, 0,
1026 dsp2txr, ARRAY_SIZE(dsp2txr)),
1027SND_SOC_DAPM_MIXER("DSP1TXL", WM8915_POWER_MANAGEMENT_5, 9, 0,
1028 dsp1txl, ARRAY_SIZE(dsp1txl)),
1029SND_SOC_DAPM_MIXER("DSP1TXR", WM8915_POWER_MANAGEMENT_5, 8, 0,
1030 dsp1txr, ARRAY_SIZE(dsp1txr)),
1031
1032SND_SOC_DAPM_MIXER("DAC2L Mixer", SND_SOC_NOPM, 0, 0,
1033 dac2l_mix, ARRAY_SIZE(dac2l_mix)),
1034SND_SOC_DAPM_MIXER("DAC2R Mixer", SND_SOC_NOPM, 0, 0,
1035 dac2r_mix, ARRAY_SIZE(dac2r_mix)),
1036SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,
1037 dac1l_mix, ARRAY_SIZE(dac1l_mix)),
1038SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
1039 dac1r_mix, ARRAY_SIZE(dac1r_mix)),
1040
1041SND_SOC_DAPM_DAC("DAC2L", NULL, WM8915_POWER_MANAGEMENT_5, 3, 0),
1042SND_SOC_DAPM_DAC("DAC2R", NULL, WM8915_POWER_MANAGEMENT_5, 2, 0),
1043SND_SOC_DAPM_DAC("DAC1L", NULL, WM8915_POWER_MANAGEMENT_5, 1, 0),
1044SND_SOC_DAPM_DAC("DAC1R", NULL, WM8915_POWER_MANAGEMENT_5, 0, 0),
1045
1046SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 1,
1047 WM8915_POWER_MANAGEMENT_4, 9, 0),
1048SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 2,
1049 WM8915_POWER_MANAGEMENT_4, 8, 0),
1050
1051SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 1,
1052 WM8915_POWER_MANAGEMENT_6, 9, 0),
1053SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 2,
1054 WM8915_POWER_MANAGEMENT_6, 8, 0),
1055
1056SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5,
1057 WM8915_POWER_MANAGEMENT_4, 5, 0),
1058SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 4,
1059 WM8915_POWER_MANAGEMENT_4, 4, 0),
1060SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 3,
1061 WM8915_POWER_MANAGEMENT_4, 3, 0),
1062SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 2,
1063 WM8915_POWER_MANAGEMENT_4, 2, 0),
1064SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 1,
1065 WM8915_POWER_MANAGEMENT_4, 1, 0),
1066SND_SOC_DAPM_AIF_IN("AIF1RX0", "AIF1 Playback", 0,
1067 WM8915_POWER_MANAGEMENT_4, 0, 0),
1068
1069SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 5,
1070 WM8915_POWER_MANAGEMENT_6, 5, 0),
1071SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 4,
1072 WM8915_POWER_MANAGEMENT_6, 4, 0),
1073SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 3,
1074 WM8915_POWER_MANAGEMENT_6, 3, 0),
1075SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 2,
1076 WM8915_POWER_MANAGEMENT_6, 2, 0),
1077SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 1,
1078 WM8915_POWER_MANAGEMENT_6, 1, 0),
1079SND_SOC_DAPM_AIF_OUT("AIF1TX0", "AIF1 Capture", 0,
1080 WM8915_POWER_MANAGEMENT_6, 0, 0),
1081
1082/* We route as stereo pairs so define some dummy widgets to squash
1083 * things down for now. RXA = 0,1, RXB = 2,3 and so on */
1084SND_SOC_DAPM_PGA("AIF1RXA", SND_SOC_NOPM, 0, 0, NULL, 0),
1085SND_SOC_DAPM_PGA("AIF1RXB", SND_SOC_NOPM, 0, 0, NULL, 0),
1086SND_SOC_DAPM_PGA("AIF1RXC", SND_SOC_NOPM, 0, 0, NULL, 0),
1087SND_SOC_DAPM_PGA("AIF2RX", SND_SOC_NOPM, 0, 0, NULL, 0),
1088SND_SOC_DAPM_PGA("DSP2TX", SND_SOC_NOPM, 0, 0, NULL, 0),
1089
1090SND_SOC_DAPM_MUX("DSP1RX", SND_SOC_NOPM, 0, 0, &dsp1rx),
1091SND_SOC_DAPM_MUX("DSP2RX", SND_SOC_NOPM, 0, 0, &dsp2rx),
1092SND_SOC_DAPM_MUX("AIF2TX", SND_SOC_NOPM, 0, 0, &aif2tx),
1093
1094SND_SOC_DAPM_MUX("SPKL", SND_SOC_NOPM, 0, 0, &spkl_mux),
1095SND_SOC_DAPM_MUX("SPKR", SND_SOC_NOPM, 0, 0, &spkr_mux),
1096SND_SOC_DAPM_PGA("SPKL PGA", WM8915_LEFT_PDM_SPEAKER, 4, 0, NULL, 0),
1097SND_SOC_DAPM_PGA("SPKR PGA", WM8915_RIGHT_PDM_SPEAKER, 4, 0, NULL, 0),
1098
1099SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8915_POWER_MANAGEMENT_1, 7, 0, NULL, 0),
1100SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8915_ANALOGUE_HP_2, 5, 0, NULL, 0),
1101SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8915_DC_SERVO_1, 2, 0, dcs_start,
1102 SND_SOC_DAPM_POST_PMU),
1103SND_SOC_DAPM_PGA_S("HPOUT2L_OUTP", 3, WM8915_ANALOGUE_HP_2, 6, 0, NULL, 0),
1104SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0,
1105 rmv_short_event,
1106 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1107
1108SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8915_POWER_MANAGEMENT_1, 6, 0,NULL, 0),
1109SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8915_ANALOGUE_HP_2, 1, 0, NULL, 0),
1110SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8915_DC_SERVO_1, 3, 0, dcs_start,
1111 SND_SOC_DAPM_POST_PMU),
1112SND_SOC_DAPM_PGA_S("HPOUT2R_OUTP", 3, WM8915_ANALOGUE_HP_2, 2, 0, NULL, 0),
1113SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0,
1114 rmv_short_event,
1115 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1116
1117SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8915_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
1118SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8915_ANALOGUE_HP_1, 5, 0, NULL, 0),
1119SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8915_DC_SERVO_1, 0, 0, dcs_start,
1120 SND_SOC_DAPM_POST_PMU),
1121SND_SOC_DAPM_PGA_S("HPOUT1L_OUTP", 3, WM8915_ANALOGUE_HP_1, 6, 0, NULL, 0),
1122SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0,
1123 rmv_short_event,
1124 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1125
1126SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8915_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
1127SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8915_ANALOGUE_HP_1, 1, 0, NULL, 0),
1128SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8915_DC_SERVO_1, 1, 0, dcs_start,
1129 SND_SOC_DAPM_POST_PMU),
1130SND_SOC_DAPM_PGA_S("HPOUT1R_OUTP", 3, WM8915_ANALOGUE_HP_1, 2, 0, NULL, 0),
1131SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0,
1132 rmv_short_event,
1133 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1134
1135SND_SOC_DAPM_OUTPUT("HPOUT1L"),
1136SND_SOC_DAPM_OUTPUT("HPOUT1R"),
1137SND_SOC_DAPM_OUTPUT("HPOUT2L"),
1138SND_SOC_DAPM_OUTPUT("HPOUT2R"),
1139SND_SOC_DAPM_OUTPUT("SPKDAT"),
1140};
1141
1142static const struct snd_soc_dapm_route wm8915_dapm_routes[] = {
1143 { "AIFCLK", NULL, "SYSCLK" },
1144 { "SYSDSPCLK", NULL, "SYSCLK" },
1145 { "Charge Pump", NULL, "SYSCLK" },
1146
1147 { "MICB1", NULL, "LDO2" },
1148 { "MICB2", NULL, "LDO2" },
1149
1150 { "IN1L PGA", NULL, "IN2LN" },
1151 { "IN1L PGA", NULL, "IN2LP" },
1152 { "IN1L PGA", NULL, "IN1LN" },
1153 { "IN1L PGA", NULL, "IN1LP" },
1154
1155 { "IN1R PGA", NULL, "IN2RN" },
1156 { "IN1R PGA", NULL, "IN2RP" },
1157 { "IN1R PGA", NULL, "IN1RN" },
1158 { "IN1R PGA", NULL, "IN1RP" },
1159
1160 { "ADCL", NULL, "IN1L PGA" },
1161
1162 { "ADCR", NULL, "IN1R PGA" },
1163
1164 { "DMIC1L", NULL, "DMIC1DAT" },
1165 { "DMIC1R", NULL, "DMIC1DAT" },
1166 { "DMIC2L", NULL, "DMIC2DAT" },
1167 { "DMIC2R", NULL, "DMIC2DAT" },
1168
1169 { "DMIC2L", NULL, "DMIC2" },
1170 { "DMIC2R", NULL, "DMIC2" },
1171 { "DMIC1L", NULL, "DMIC1" },
1172 { "DMIC1R", NULL, "DMIC1" },
1173
1174 { "IN1L Mux", "ADC", "ADCL" },
1175 { "IN1L Mux", "DMIC1", "DMIC1L" },
1176 { "IN1L Mux", "DMIC2", "DMIC2L" },
1177
1178 { "IN1R Mux", "ADC", "ADCR" },
1179 { "IN1R Mux", "DMIC1", "DMIC1R" },
1180 { "IN1R Mux", "DMIC2", "DMIC2R" },
1181
1182 { "IN2L Mux", "ADC", "ADCL" },
1183 { "IN2L Mux", "DMIC1", "DMIC1L" },
1184 { "IN2L Mux", "DMIC2", "DMIC2L" },
1185
1186 { "IN2R Mux", "ADC", "ADCR" },
1187 { "IN2R Mux", "DMIC1", "DMIC1R" },
1188 { "IN2R Mux", "DMIC2", "DMIC2R" },
1189
1190 { "Left Sidetone", "IN1", "IN1L Mux" },
1191 { "Left Sidetone", "IN2", "IN2L Mux" },
1192
1193 { "Right Sidetone", "IN1", "IN1R Mux" },
1194 { "Right Sidetone", "IN2", "IN2R Mux" },
1195
1196 { "DSP1TXL", "IN1 Switch", "IN1L Mux" },
1197 { "DSP1TXR", "IN1 Switch", "IN1R Mux" },
1198
1199 { "DSP2TXL", "IN1 Switch", "IN2L Mux" },
1200 { "DSP2TXR", "IN1 Switch", "IN2R Mux" },
1201
1202 { "AIF1TX0", NULL, "DSP1TXL" },
1203 { "AIF1TX1", NULL, "DSP1TXR" },
1204 { "AIF1TX2", NULL, "DSP2TXL" },
1205 { "AIF1TX3", NULL, "DSP2TXR" },
1206 { "AIF1TX4", NULL, "AIF2RX0" },
1207 { "AIF1TX5", NULL, "AIF2RX1" },
1208
1209 { "AIF1RX0", NULL, "AIFCLK" },
1210 { "AIF1RX1", NULL, "AIFCLK" },
1211 { "AIF1RX2", NULL, "AIFCLK" },
1212 { "AIF1RX3", NULL, "AIFCLK" },
1213 { "AIF1RX4", NULL, "AIFCLK" },
1214 { "AIF1RX5", NULL, "AIFCLK" },
1215
1216 { "AIF2RX0", NULL, "AIFCLK" },
1217 { "AIF2RX1", NULL, "AIFCLK" },
1218
1219 { "DSP1RXL", NULL, "SYSDSPCLK" },
1220 { "DSP1RXR", NULL, "SYSDSPCLK" },
1221 { "DSP2RXL", NULL, "SYSDSPCLK" },
1222 { "DSP2RXR", NULL, "SYSDSPCLK" },
1223 { "DSP1TXL", NULL, "SYSDSPCLK" },
1224 { "DSP1TXR", NULL, "SYSDSPCLK" },
1225 { "DSP2TXL", NULL, "SYSDSPCLK" },
1226 { "DSP2TXR", NULL, "SYSDSPCLK" },
1227
1228 { "AIF1RXA", NULL, "AIF1RX0" },
1229 { "AIF1RXA", NULL, "AIF1RX1" },
1230 { "AIF1RXB", NULL, "AIF1RX2" },
1231 { "AIF1RXB", NULL, "AIF1RX3" },
1232 { "AIF1RXC", NULL, "AIF1RX4" },
1233 { "AIF1RXC", NULL, "AIF1RX5" },
1234
1235 { "AIF2RX", NULL, "AIF2RX0" },
1236 { "AIF2RX", NULL, "AIF2RX1" },
1237
1238 { "AIF2TX", "DSP2", "DSP2TX" },
1239 { "AIF2TX", "DSP1", "DSP1RX" },
1240 { "AIF2TX", "AIF1", "AIF1RXC" },
1241
1242 { "DSP1RXL", NULL, "DSP1RX" },
1243 { "DSP1RXR", NULL, "DSP1RX" },
1244 { "DSP2RXL", NULL, "DSP2RX" },
1245 { "DSP2RXR", NULL, "DSP2RX" },
1246
1247 { "DSP2TX", NULL, "DSP2TXL" },
1248 { "DSP2TX", NULL, "DSP2TXR" },
1249
1250 { "DSP1RX", "AIF1", "AIF1RXA" },
1251 { "DSP1RX", "AIF2", "AIF2RX" },
1252
1253 { "DSP2RX", "AIF1", "AIF1RXB" },
1254 { "DSP2RX", "AIF2", "AIF2RX" },
1255
1256 { "DAC2L Mixer", "DSP2 Switch", "DSP2RXL" },
1257 { "DAC2L Mixer", "DSP1 Switch", "DSP1RXL" },
1258 { "DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
1259 { "DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },
1260
1261 { "DAC2R Mixer", "DSP2 Switch", "DSP2RXR" },
1262 { "DAC2R Mixer", "DSP1 Switch", "DSP1RXR" },
1263 { "DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
1264 { "DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
1265
1266 { "DAC1L Mixer", "DSP2 Switch", "DSP2RXL" },
1267 { "DAC1L Mixer", "DSP1 Switch", "DSP1RXL" },
1268 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
1269 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
1270
1271 { "DAC1R Mixer", "DSP2 Switch", "DSP2RXR" },
1272 { "DAC1R Mixer", "DSP1 Switch", "DSP1RXR" },
1273 { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
1274 { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
1275
1276 { "DAC1L", NULL, "DAC1L Mixer" },
1277 { "DAC1R", NULL, "DAC1R Mixer" },
1278 { "DAC2L", NULL, "DAC2L Mixer" },
1279 { "DAC2R", NULL, "DAC2R Mixer" },
1280
1281 { "HPOUT2L PGA", NULL, "Charge Pump" },
1282 { "HPOUT2L PGA", NULL, "DAC2L" },
1283 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" },
1284 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" },
1285 { "HPOUT2L_OUTP", NULL, "HPOUT2L_DCS" },
1286 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" },
1287
1288 { "HPOUT2R PGA", NULL, "Charge Pump" },
1289 { "HPOUT2R PGA", NULL, "DAC2R" },
1290 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" },
1291 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" },
1292 { "HPOUT2R_OUTP", NULL, "HPOUT2R_DCS" },
1293 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" },
1294
1295 { "HPOUT1L PGA", NULL, "Charge Pump" },
1296 { "HPOUT1L PGA", NULL, "DAC1L" },
1297 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" },
1298 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" },
1299 { "HPOUT1L_OUTP", NULL, "HPOUT1L_DCS" },
1300 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" },
1301
1302 { "HPOUT1R PGA", NULL, "Charge Pump" },
1303 { "HPOUT1R PGA", NULL, "DAC1R" },
1304 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" },
1305 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" },
1306 { "HPOUT1R_OUTP", NULL, "HPOUT1R_DCS" },
1307 { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_OUTP" },
1308
1309 { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" },
1310 { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" },
1311 { "HPOUT1L", NULL, "HPOUT1L_RMV_SHORT" },
1312 { "HPOUT1R", NULL, "HPOUT1R_RMV_SHORT" },
1313
1314 { "SPKL", "DAC1L", "DAC1L" },
1315 { "SPKL", "DAC1R", "DAC1R" },
1316 { "SPKL", "DAC2L", "DAC2L" },
1317 { "SPKL", "DAC2R", "DAC2R" },
1318
1319 { "SPKR", "DAC1L", "DAC1L" },
1320 { "SPKR", "DAC1R", "DAC1R" },
1321 { "SPKR", "DAC2L", "DAC2L" },
1322 { "SPKR", "DAC2R", "DAC2R" },
1323
1324 { "SPKL PGA", NULL, "SPKL" },
1325 { "SPKR PGA", NULL, "SPKR" },
1326
1327 { "SPKDAT", NULL, "SPKL PGA" },
1328 { "SPKDAT", NULL, "SPKR PGA" },
1329};
1330
1331static int wm8915_readable_register(struct snd_soc_codec *codec,
1332 unsigned int reg)
1333{
1334 /* Due to the sparseness of the register map the compiler
1335 * output from an explicit switch statement ends up being much
1336 * more efficient than a table.
1337 */
1338 switch (reg) {
1339 case WM8915_SOFTWARE_RESET:
1340 case WM8915_POWER_MANAGEMENT_1:
1341 case WM8915_POWER_MANAGEMENT_2:
1342 case WM8915_POWER_MANAGEMENT_3:
1343 case WM8915_POWER_MANAGEMENT_4:
1344 case WM8915_POWER_MANAGEMENT_5:
1345 case WM8915_POWER_MANAGEMENT_6:
1346 case WM8915_POWER_MANAGEMENT_7:
1347 case WM8915_POWER_MANAGEMENT_8:
1348 case WM8915_LEFT_LINE_INPUT_VOLUME:
1349 case WM8915_RIGHT_LINE_INPUT_VOLUME:
1350 case WM8915_LINE_INPUT_CONTROL:
1351 case WM8915_DAC1_HPOUT1_VOLUME:
1352 case WM8915_DAC2_HPOUT2_VOLUME:
1353 case WM8915_DAC1_LEFT_VOLUME:
1354 case WM8915_DAC1_RIGHT_VOLUME:
1355 case WM8915_DAC2_LEFT_VOLUME:
1356 case WM8915_DAC2_RIGHT_VOLUME:
1357 case WM8915_OUTPUT1_LEFT_VOLUME:
1358 case WM8915_OUTPUT1_RIGHT_VOLUME:
1359 case WM8915_OUTPUT2_LEFT_VOLUME:
1360 case WM8915_OUTPUT2_RIGHT_VOLUME:
1361 case WM8915_MICBIAS_1:
1362 case WM8915_MICBIAS_2:
1363 case WM8915_LDO_1:
1364 case WM8915_LDO_2:
1365 case WM8915_ACCESSORY_DETECT_MODE_1:
1366 case WM8915_ACCESSORY_DETECT_MODE_2:
1367 case WM8915_HEADPHONE_DETECT_1:
1368 case WM8915_HEADPHONE_DETECT_2:
1369 case WM8915_MIC_DETECT_1:
1370 case WM8915_MIC_DETECT_2:
1371 case WM8915_MIC_DETECT_3:
1372 case WM8915_CHARGE_PUMP_1:
1373 case WM8915_CHARGE_PUMP_2:
1374 case WM8915_DC_SERVO_1:
1375 case WM8915_DC_SERVO_2:
1376 case WM8915_DC_SERVO_3:
1377 case WM8915_DC_SERVO_5:
1378 case WM8915_DC_SERVO_6:
1379 case WM8915_DC_SERVO_7:
1380 case WM8915_DC_SERVO_READBACK_0:
1381 case WM8915_ANALOGUE_HP_1:
1382 case WM8915_ANALOGUE_HP_2:
1383 case WM8915_CHIP_REVISION:
1384 case WM8915_CONTROL_INTERFACE_1:
1385 case WM8915_WRITE_SEQUENCER_CTRL_1:
1386 case WM8915_WRITE_SEQUENCER_CTRL_2:
1387 case WM8915_AIF_CLOCKING_1:
1388 case WM8915_AIF_CLOCKING_2:
1389 case WM8915_CLOCKING_1:
1390 case WM8915_CLOCKING_2:
1391 case WM8915_AIF_RATE:
1392 case WM8915_FLL_CONTROL_1:
1393 case WM8915_FLL_CONTROL_2:
1394 case WM8915_FLL_CONTROL_3:
1395 case WM8915_FLL_CONTROL_4:
1396 case WM8915_FLL_CONTROL_5:
1397 case WM8915_FLL_CONTROL_6:
1398 case WM8915_FLL_EFS_1:
1399 case WM8915_FLL_EFS_2:
1400 case WM8915_AIF1_CONTROL:
1401 case WM8915_AIF1_BCLK:
1402 case WM8915_AIF1_TX_LRCLK_1:
1403 case WM8915_AIF1_TX_LRCLK_2:
1404 case WM8915_AIF1_RX_LRCLK_1:
1405 case WM8915_AIF1_RX_LRCLK_2:
1406 case WM8915_AIF1TX_DATA_CONFIGURATION_1:
1407 case WM8915_AIF1TX_DATA_CONFIGURATION_2:
1408 case WM8915_AIF1RX_DATA_CONFIGURATION:
1409 case WM8915_AIF1TX_CHANNEL_0_CONFIGURATION:
1410 case WM8915_AIF1TX_CHANNEL_1_CONFIGURATION:
1411 case WM8915_AIF1TX_CHANNEL_2_CONFIGURATION:
1412 case WM8915_AIF1TX_CHANNEL_3_CONFIGURATION:
1413 case WM8915_AIF1TX_CHANNEL_4_CONFIGURATION:
1414 case WM8915_AIF1TX_CHANNEL_5_CONFIGURATION:
1415 case WM8915_AIF1RX_CHANNEL_0_CONFIGURATION:
1416 case WM8915_AIF1RX_CHANNEL_1_CONFIGURATION:
1417 case WM8915_AIF1RX_CHANNEL_2_CONFIGURATION:
1418 case WM8915_AIF1RX_CHANNEL_3_CONFIGURATION:
1419 case WM8915_AIF1RX_CHANNEL_4_CONFIGURATION:
1420 case WM8915_AIF1RX_CHANNEL_5_CONFIGURATION:
1421 case WM8915_AIF1RX_MONO_CONFIGURATION:
1422 case WM8915_AIF1TX_TEST:
1423 case WM8915_AIF2_CONTROL:
1424 case WM8915_AIF2_BCLK:
1425 case WM8915_AIF2_TX_LRCLK_1:
1426 case WM8915_AIF2_TX_LRCLK_2:
1427 case WM8915_AIF2_RX_LRCLK_1:
1428 case WM8915_AIF2_RX_LRCLK_2:
1429 case WM8915_AIF2TX_DATA_CONFIGURATION_1:
1430 case WM8915_AIF2TX_DATA_CONFIGURATION_2:
1431 case WM8915_AIF2RX_DATA_CONFIGURATION:
1432 case WM8915_AIF2TX_CHANNEL_0_CONFIGURATION:
1433 case WM8915_AIF2TX_CHANNEL_1_CONFIGURATION:
1434 case WM8915_AIF2RX_CHANNEL_0_CONFIGURATION:
1435 case WM8915_AIF2RX_CHANNEL_1_CONFIGURATION:
1436 case WM8915_AIF2RX_MONO_CONFIGURATION:
1437 case WM8915_AIF2TX_TEST:
1438 case WM8915_DSP1_TX_LEFT_VOLUME:
1439 case WM8915_DSP1_TX_RIGHT_VOLUME:
1440 case WM8915_DSP1_RX_LEFT_VOLUME:
1441 case WM8915_DSP1_RX_RIGHT_VOLUME:
1442 case WM8915_DSP1_TX_FILTERS:
1443 case WM8915_DSP1_RX_FILTERS_1:
1444 case WM8915_DSP1_RX_FILTERS_2:
1445 case WM8915_DSP1_DRC_1:
1446 case WM8915_DSP1_DRC_2:
1447 case WM8915_DSP1_DRC_3:
1448 case WM8915_DSP1_DRC_4:
1449 case WM8915_DSP1_DRC_5:
1450 case WM8915_DSP1_RX_EQ_GAINS_1:
1451 case WM8915_DSP1_RX_EQ_GAINS_2:
1452 case WM8915_DSP1_RX_EQ_BAND_1_A:
1453 case WM8915_DSP1_RX_EQ_BAND_1_B:
1454 case WM8915_DSP1_RX_EQ_BAND_1_PG:
1455 case WM8915_DSP1_RX_EQ_BAND_2_A:
1456 case WM8915_DSP1_RX_EQ_BAND_2_B:
1457 case WM8915_DSP1_RX_EQ_BAND_2_C:
1458 case WM8915_DSP1_RX_EQ_BAND_2_PG:
1459 case WM8915_DSP1_RX_EQ_BAND_3_A:
1460 case WM8915_DSP1_RX_EQ_BAND_3_B:
1461 case WM8915_DSP1_RX_EQ_BAND_3_C:
1462 case WM8915_DSP1_RX_EQ_BAND_3_PG:
1463 case WM8915_DSP1_RX_EQ_BAND_4_A:
1464 case WM8915_DSP1_RX_EQ_BAND_4_B:
1465 case WM8915_DSP1_RX_EQ_BAND_4_C:
1466 case WM8915_DSP1_RX_EQ_BAND_4_PG:
1467 case WM8915_DSP1_RX_EQ_BAND_5_A:
1468 case WM8915_DSP1_RX_EQ_BAND_5_B:
1469 case WM8915_DSP1_RX_EQ_BAND_5_PG:
1470 case WM8915_DSP2_TX_LEFT_VOLUME:
1471 case WM8915_DSP2_TX_RIGHT_VOLUME:
1472 case WM8915_DSP2_RX_LEFT_VOLUME:
1473 case WM8915_DSP2_RX_RIGHT_VOLUME:
1474 case WM8915_DSP2_TX_FILTERS:
1475 case WM8915_DSP2_RX_FILTERS_1:
1476 case WM8915_DSP2_RX_FILTERS_2:
1477 case WM8915_DSP2_DRC_1:
1478 case WM8915_DSP2_DRC_2:
1479 case WM8915_DSP2_DRC_3:
1480 case WM8915_DSP2_DRC_4:
1481 case WM8915_DSP2_DRC_5:
1482 case WM8915_DSP2_RX_EQ_GAINS_1:
1483 case WM8915_DSP2_RX_EQ_GAINS_2:
1484 case WM8915_DSP2_RX_EQ_BAND_1_A:
1485 case WM8915_DSP2_RX_EQ_BAND_1_B:
1486 case WM8915_DSP2_RX_EQ_BAND_1_PG:
1487 case WM8915_DSP2_RX_EQ_BAND_2_A:
1488 case WM8915_DSP2_RX_EQ_BAND_2_B:
1489 case WM8915_DSP2_RX_EQ_BAND_2_C:
1490 case WM8915_DSP2_RX_EQ_BAND_2_PG:
1491 case WM8915_DSP2_RX_EQ_BAND_3_A:
1492 case WM8915_DSP2_RX_EQ_BAND_3_B:
1493 case WM8915_DSP2_RX_EQ_BAND_3_C:
1494 case WM8915_DSP2_RX_EQ_BAND_3_PG:
1495 case WM8915_DSP2_RX_EQ_BAND_4_A:
1496 case WM8915_DSP2_RX_EQ_BAND_4_B:
1497 case WM8915_DSP2_RX_EQ_BAND_4_C:
1498 case WM8915_DSP2_RX_EQ_BAND_4_PG:
1499 case WM8915_DSP2_RX_EQ_BAND_5_A:
1500 case WM8915_DSP2_RX_EQ_BAND_5_B:
1501 case WM8915_DSP2_RX_EQ_BAND_5_PG:
1502 case WM8915_DAC1_MIXER_VOLUMES:
1503 case WM8915_DAC1_LEFT_MIXER_ROUTING:
1504 case WM8915_DAC1_RIGHT_MIXER_ROUTING:
1505 case WM8915_DAC2_MIXER_VOLUMES:
1506 case WM8915_DAC2_LEFT_MIXER_ROUTING:
1507 case WM8915_DAC2_RIGHT_MIXER_ROUTING:
1508 case WM8915_DSP1_TX_LEFT_MIXER_ROUTING:
1509 case WM8915_DSP1_TX_RIGHT_MIXER_ROUTING:
1510 case WM8915_DSP2_TX_LEFT_MIXER_ROUTING:
1511 case WM8915_DSP2_TX_RIGHT_MIXER_ROUTING:
1512 case WM8915_DSP_TX_MIXER_SELECT:
1513 case WM8915_DAC_SOFTMUTE:
1514 case WM8915_OVERSAMPLING:
1515 case WM8915_SIDETONE:
1516 case WM8915_GPIO_1:
1517 case WM8915_GPIO_2:
1518 case WM8915_GPIO_3:
1519 case WM8915_GPIO_4:
1520 case WM8915_GPIO_5:
1521 case WM8915_PULL_CONTROL_1:
1522 case WM8915_PULL_CONTROL_2:
1523 case WM8915_INTERRUPT_STATUS_1:
1524 case WM8915_INTERRUPT_STATUS_2:
1525 case WM8915_INTERRUPT_RAW_STATUS_2:
1526 case WM8915_INTERRUPT_STATUS_1_MASK:
1527 case WM8915_INTERRUPT_STATUS_2_MASK:
1528 case WM8915_INTERRUPT_CONTROL:
1529 case WM8915_LEFT_PDM_SPEAKER:
1530 case WM8915_RIGHT_PDM_SPEAKER:
1531 case WM8915_PDM_SPEAKER_MUTE_SEQUENCE:
1532 case WM8915_PDM_SPEAKER_VOLUME:
1533 return 1;
1534 default:
1535 return 0;
1536 }
1537}
1538
1539static int wm8915_volatile_register(struct snd_soc_codec *codec,
1540 unsigned int reg)
1541{
1542 switch (reg) {
1543 case WM8915_SOFTWARE_RESET:
1544 case WM8915_CHIP_REVISION:
1545 case WM8915_LDO_1:
1546 case WM8915_LDO_2:
1547 case WM8915_INTERRUPT_STATUS_1:
1548 case WM8915_INTERRUPT_STATUS_2:
1549 case WM8915_INTERRUPT_RAW_STATUS_2:
1550 case WM8915_DC_SERVO_READBACK_0:
1551 case WM8915_DC_SERVO_2:
1552 case WM8915_DC_SERVO_6:
1553 case WM8915_DC_SERVO_7:
1554 case WM8915_FLL_CONTROL_6:
1555 case WM8915_MIC_DETECT_3:
1556 case WM8915_HEADPHONE_DETECT_1:
1557 case WM8915_HEADPHONE_DETECT_2:
1558 return 1;
1559 default:
1560 return 0;
1561 }
1562}
1563
1564static int wm8915_reset(struct snd_soc_codec *codec)
1565{
1566 return snd_soc_write(codec, WM8915_SOFTWARE_RESET, 0x8915);
1567}
1568
1569static int wm8915_set_bias_level(struct snd_soc_codec *codec,
1570 enum snd_soc_bias_level level)
1571{
1572 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
1573 int ret;
1574
1575 switch (level) {
1576 case SND_SOC_BIAS_ON:
1577 break;
1578
1579 case SND_SOC_BIAS_PREPARE:
1580 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
1581 snd_soc_update_bits(codec, WM8915_POWER_MANAGEMENT_1,
1582 WM8915_BG_ENA, WM8915_BG_ENA);
1583 msleep(2);
1584 }
1585 break;
1586
1587 case SND_SOC_BIAS_STANDBY:
1588 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1589 ret = regulator_bulk_enable(ARRAY_SIZE(wm8915->supplies),
1590 wm8915->supplies);
1591 if (ret != 0) {
1592 dev_err(codec->dev,
1593 "Failed to enable supplies: %d\n",
1594 ret);
1595 return ret;
1596 }
1597
1598 if (wm8915->pdata.ldo_ena >= 0) {
1599 gpio_set_value_cansleep(wm8915->pdata.ldo_ena,
1600 1);
1601 msleep(5);
1602 }
1603
1604 codec->cache_only = false;
1605 snd_soc_cache_sync(codec);
1606 }
1607
1608 snd_soc_update_bits(codec, WM8915_POWER_MANAGEMENT_1,
1609 WM8915_BG_ENA, 0);
1610 break;
1611
1612 case SND_SOC_BIAS_OFF:
1613 codec->cache_only = true;
1614 if (wm8915->pdata.ldo_ena >= 0)
1615 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
1616 regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies),
1617 wm8915->supplies);
1618 break;
1619 }
1620
1621 codec->dapm.bias_level = level;
1622
1623 return 0;
1624}
1625
1626static int wm8915_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1627{
1628 struct snd_soc_codec *codec = dai->codec;
1629 int aifctrl = 0;
1630 int bclk = 0;
1631 int lrclk_tx = 0;
1632 int lrclk_rx = 0;
1633 int aifctrl_reg, bclk_reg, lrclk_tx_reg, lrclk_rx_reg;
1634
1635 switch (dai->id) {
1636 case 0:
1637 aifctrl_reg = WM8915_AIF1_CONTROL;
1638 bclk_reg = WM8915_AIF1_BCLK;
1639 lrclk_tx_reg = WM8915_AIF1_TX_LRCLK_2;
1640 lrclk_rx_reg = WM8915_AIF1_RX_LRCLK_2;
1641 break;
1642 case 1:
1643 aifctrl_reg = WM8915_AIF2_CONTROL;
1644 bclk_reg = WM8915_AIF2_BCLK;
1645 lrclk_tx_reg = WM8915_AIF2_TX_LRCLK_2;
1646 lrclk_rx_reg = WM8915_AIF2_RX_LRCLK_2;
1647 break;
1648 default:
1649 BUG();
1650 return -EINVAL;
1651 }
1652
1653 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1654 case SND_SOC_DAIFMT_NB_NF:
1655 break;
1656 case SND_SOC_DAIFMT_IB_NF:
1657 bclk |= WM8915_AIF1_BCLK_INV;
1658 break;
1659 case SND_SOC_DAIFMT_NB_IF:
1660 lrclk_tx |= WM8915_AIF1TX_LRCLK_INV;
1661 lrclk_rx |= WM8915_AIF1RX_LRCLK_INV;
1662 break;
1663 case SND_SOC_DAIFMT_IB_IF:
1664 bclk |= WM8915_AIF1_BCLK_INV;
1665 lrclk_tx |= WM8915_AIF1TX_LRCLK_INV;
1666 lrclk_rx |= WM8915_AIF1RX_LRCLK_INV;
1667 break;
1668 }
1669
1670 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1671 case SND_SOC_DAIFMT_CBS_CFS:
1672 break;
1673 case SND_SOC_DAIFMT_CBS_CFM:
1674 lrclk_tx |= WM8915_AIF1TX_LRCLK_MSTR;
1675 lrclk_rx |= WM8915_AIF1RX_LRCLK_MSTR;
1676 break;
1677 case SND_SOC_DAIFMT_CBM_CFS:
1678 bclk |= WM8915_AIF1_BCLK_MSTR;
1679 break;
1680 case SND_SOC_DAIFMT_CBM_CFM:
1681 bclk |= WM8915_AIF1_BCLK_MSTR;
1682 lrclk_tx |= WM8915_AIF1TX_LRCLK_MSTR;
1683 lrclk_rx |= WM8915_AIF1RX_LRCLK_MSTR;
1684 break;
1685 default:
1686 return -EINVAL;
1687 }
1688
1689 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1690 case SND_SOC_DAIFMT_DSP_A:
1691 break;
1692 case SND_SOC_DAIFMT_DSP_B:
1693 aifctrl |= 1;
1694 break;
1695 case SND_SOC_DAIFMT_I2S:
1696 aifctrl |= 2;
1697 break;
1698 case SND_SOC_DAIFMT_LEFT_J:
1699 aifctrl |= 3;
1700 break;
1701 default:
1702 return -EINVAL;
1703 }
1704
1705 snd_soc_update_bits(codec, aifctrl_reg, WM8915_AIF1_FMT_MASK, aifctrl);
1706 snd_soc_update_bits(codec, bclk_reg,
1707 WM8915_AIF1_BCLK_INV | WM8915_AIF1_BCLK_MSTR,
1708 bclk);
1709 snd_soc_update_bits(codec, lrclk_tx_reg,
1710 WM8915_AIF1TX_LRCLK_INV |
1711 WM8915_AIF1TX_LRCLK_MSTR,
1712 lrclk_tx);
1713 snd_soc_update_bits(codec, lrclk_rx_reg,
1714 WM8915_AIF1RX_LRCLK_INV |
1715 WM8915_AIF1RX_LRCLK_MSTR,
1716 lrclk_rx);
1717
1718 return 0;
1719}
1720
1721static const int bclk_divs[] = {
1722 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
1723};
1724
1725static const int dsp_divs[] = {
1726 48000, 32000, 16000, 8000
1727};
1728
1729static int wm8915_hw_params(struct snd_pcm_substream *substream,
1730 struct snd_pcm_hw_params *params,
1731 struct snd_soc_dai *dai)
1732{
1733 struct snd_soc_codec *codec = dai->codec;
1734 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
1735 int bits, i, bclk_rate, best, cur_val;
1736 int aifdata = 0;
1737 int bclk = 0;
1738 int lrclk = 0;
1739 int dsp = 0;
1740 int aifdata_reg, bclk_reg, lrclk_reg, dsp_shift;
1741
1742 if (!wm8915->sysclk) {
1743 dev_err(codec->dev, "SYSCLK not configured\n");
1744 return -EINVAL;
1745 }
1746
1747 switch (dai->id) {
1748 case 0:
1749 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1750 (snd_soc_read(codec, WM8915_GPIO_1)) & WM8915_GP1_FN_MASK) {
1751 aifdata_reg = WM8915_AIF1RX_DATA_CONFIGURATION;
1752 lrclk_reg = WM8915_AIF1_RX_LRCLK_1;
1753 } else {
1754 aifdata_reg = WM8915_AIF1TX_DATA_CONFIGURATION_1;
1755 lrclk_reg = WM8915_AIF1_TX_LRCLK_1;
1756 }
1757 bclk_reg = WM8915_AIF1_BCLK;
1758 dsp_shift = 0;
1759 break;
1760 case 1:
1761 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1762 (snd_soc_read(codec, WM8915_GPIO_2)) & WM8915_GP2_FN_MASK) {
1763 aifdata_reg = WM8915_AIF2RX_DATA_CONFIGURATION;
1764 lrclk_reg = WM8915_AIF2_RX_LRCLK_1;
1765 } else {
1766 aifdata_reg = WM8915_AIF2TX_DATA_CONFIGURATION_1;
1767 lrclk_reg = WM8915_AIF2_TX_LRCLK_1;
1768 }
1769 bclk_reg = WM8915_AIF2_BCLK;
1770 dsp_shift = WM8915_DSP2_DIV_SHIFT;
1771 break;
1772 default:
1773 BUG();
1774 return -EINVAL;
1775 }
1776
1777 bclk_rate = snd_soc_params_to_bclk(params);
1778 if (bclk_rate < 0) {
1779 dev_err(codec->dev, "Unsupported BCLK rate: %d\n", bclk_rate);
1780 return bclk_rate;
1781 }
1782
1783 /* Needs looking at for TDM */
1784 bits = snd_pcm_format_width(params_format(params));
1785 if (bits < 0)
1786 return bits;
1787 aifdata |= (bits << WM8915_AIF1TX_WL_SHIFT) | bits;
1788
1789 for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) {
1790 if (dsp_divs[i] == params_rate(params))
1791 break;
1792 }
1793 if (i == ARRAY_SIZE(dsp_divs)) {
1794 dev_err(codec->dev, "Unsupported sample rate %dHz\n",
1795 params_rate(params));
1796 return -EINVAL;
1797 }
1798 dsp |= i << dsp_shift;
1799
1800 /* Pick a divisor for BCLK as close as we can get to ideal */
1801 best = 0;
1802 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1803 cur_val = (wm8915->sysclk / bclk_divs[i]) - bclk_rate;
1804 if (cur_val < 0) /* BCLK table is sorted */
1805 break;
1806 best = i;
1807 }
1808 bclk_rate = wm8915->sysclk / bclk_divs[best];
1809 dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
1810 bclk_divs[best], bclk_rate);
1811 bclk |= best;
1812
1813 lrclk = bclk_rate / params_rate(params);
1814 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
1815 lrclk, bclk_rate / lrclk);
1816
1817 snd_soc_update_bits(codec, aifdata_reg,
1818 WM8915_AIF1TX_WL_MASK |
1819 WM8915_AIF1TX_SLOT_LEN_MASK,
1820 aifdata);
1821 snd_soc_update_bits(codec, bclk_reg, WM8915_AIF1_BCLK_DIV_MASK, bclk);
1822 snd_soc_update_bits(codec, lrclk_reg, WM8915_AIF1RX_RATE_MASK,
1823 lrclk);
1824 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_2,
1825 WM8915_DSP1_DIV_SHIFT << dsp_shift, dsp);
1826
1827 wm8915->rx_rate[dai->id] = params_rate(params);
1828
1829 return 0;
1830}
1831
1832static int wm8915_set_sysclk(struct snd_soc_dai *dai,
1833 int clk_id, unsigned int freq, int dir)
1834{
1835 struct snd_soc_codec *codec = dai->codec;
1836 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
1837 int lfclk = 0;
1838 int ratediv = 0;
1839 int src;
1840 int old;
1841
1842 /* Disable SYSCLK while we reconfigure */
1843 old = snd_soc_read(codec, WM8915_AIF_CLOCKING_1);
1844 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
1845 WM8915_SYSCLK_ENA, 0);
1846
1847 switch (clk_id) {
1848 case WM8915_SYSCLK_MCLK1:
1849 wm8915->sysclk = freq;
1850 src = 0;
1851 break;
1852 case WM8915_SYSCLK_MCLK2:
1853 wm8915->sysclk = freq;
1854 src = 1;
1855 break;
1856 case WM8915_SYSCLK_FLL:
1857 wm8915->sysclk = freq;
1858 src = 2;
1859 break;
1860 default:
1861 dev_err(codec->dev, "Unsupported clock source %d\n", clk_id);
1862 return -EINVAL;
1863 }
1864
1865 switch (wm8915->sysclk) {
1866 case 6144000:
1867 snd_soc_update_bits(codec, WM8915_AIF_RATE,
1868 WM8915_SYSCLK_RATE, 0);
1869 break;
1870 case 24576000:
1871 ratediv = WM8915_SYSCLK_DIV;
1872 case 12288000:
1873 snd_soc_update_bits(codec, WM8915_AIF_RATE,
1874 WM8915_SYSCLK_RATE, WM8915_SYSCLK_RATE);
1875 break;
1876 case 32000:
1877 case 32768:
1878 lfclk = WM8915_LFCLK_ENA;
1879 break;
1880 default:
1881 dev_warn(codec->dev, "Unsupported clock rate %dHz\n",
1882 wm8915->sysclk);
1883 return -EINVAL;
1884 }
1885
1886 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
1887 WM8915_SYSCLK_SRC_MASK | WM8915_SYSCLK_DIV_MASK,
1888 src << WM8915_SYSCLK_SRC_SHIFT | ratediv);
1889 snd_soc_update_bits(codec, WM8915_CLOCKING_1, WM8915_LFCLK_ENA, lfclk);
1890 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
1891 WM8915_SYSCLK_ENA, old);
1892
1893 return 0;
1894}
1895
1896struct _fll_div {
1897 u16 fll_fratio;
1898 u16 fll_outdiv;
1899 u16 fll_refclk_div;
1900 u16 fll_loop_gain;
1901 u16 fll_ref_freq;
1902 u16 n;
1903 u16 theta;
1904 u16 lambda;
1905};
1906
1907static struct {
1908 unsigned int min;
1909 unsigned int max;
1910 u16 fll_fratio;
1911 int ratio;
1912} fll_fratios[] = {
1913 { 0, 64000, 4, 16 },
1914 { 64000, 128000, 3, 8 },
1915 { 128000, 256000, 2, 4 },
1916 { 256000, 1000000, 1, 2 },
1917 { 1000000, 13500000, 0, 1 },
1918};
1919
1920static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1921 unsigned int Fout)
1922{
1923 unsigned int target;
1924 unsigned int div;
1925 unsigned int fratio, gcd_fll;
1926 int i;
1927
1928 /* Fref must be <=13.5MHz */
1929 div = 1;
1930 fll_div->fll_refclk_div = 0;
1931 while ((Fref / div) > 13500000) {
1932 div *= 2;
1933 fll_div->fll_refclk_div++;
1934
1935 if (div > 8) {
1936 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1937 Fref);
1938 return -EINVAL;
1939 }
1940 }
1941
1942 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1943
1944 /* Apply the division for our remaining calculations */
1945 Fref /= div;
1946
1947 if (Fref >= 3000000)
1948 fll_div->fll_loop_gain = 5;
1949 else
1950 fll_div->fll_loop_gain = 0;
1951
1952 if (Fref >= 48000)
1953 fll_div->fll_ref_freq = 0;
1954 else
1955 fll_div->fll_ref_freq = 1;
1956
1957 /* Fvco should be 90-100MHz; don't check the upper bound */
1958 div = 2;
1959 while (Fout * div < 90000000) {
1960 div++;
1961 if (div > 64) {
1962 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1963 Fout);
1964 return -EINVAL;
1965 }
1966 }
1967 target = Fout * div;
1968 fll_div->fll_outdiv = div - 1;
1969
1970 pr_debug("FLL Fvco=%dHz\n", target);
1971
1972 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1973 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1974 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1975 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1976 fratio = fll_fratios[i].ratio;
1977 break;
1978 }
1979 }
1980 if (i == ARRAY_SIZE(fll_fratios)) {
1981 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1982 return -EINVAL;
1983 }
1984
1985 fll_div->n = target / (fratio * Fref);
1986
1987 if (target % Fref == 0) {
1988 fll_div->theta = 0;
1989 fll_div->lambda = 0;
1990 } else {
1991 gcd_fll = gcd(target, fratio * Fref);
1992
1993 fll_div->theta = (target - (fll_div->n * fratio * Fref))
1994 / gcd_fll;
1995 fll_div->lambda = (fratio * Fref) / gcd_fll;
1996 }
1997
1998 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1999 fll_div->n, fll_div->theta, fll_div->lambda);
2000 pr_debug("FLL_FRATIO=%x FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
2001 fll_div->fll_fratio, fll_div->fll_outdiv,
2002 fll_div->fll_refclk_div);
2003
2004 return 0;
2005}
2006
2007static int wm8915_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2008 unsigned int Fref, unsigned int Fout)
2009{
2010 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2011 struct _fll_div fll_div;
2012 unsigned long timeout;
2013 int ret, reg;
2014
2015 /* Any change? */
2016 if (source == wm8915->fll_src && Fref == wm8915->fll_fref &&
2017 Fout == wm8915->fll_fout)
2018 return 0;
2019
2020 if (Fout == 0) {
2021 dev_dbg(codec->dev, "FLL disabled\n");
2022
2023 wm8915->fll_fref = 0;
2024 wm8915->fll_fout = 0;
2025
2026 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_1,
2027 WM8915_FLL_ENA, 0);
2028
2029 return 0;
2030 }
2031
2032 ret = fll_factors(&fll_div, Fref, Fout);
2033 if (ret != 0)
2034 return ret;
2035
2036 switch (source) {
2037 case WM8915_FLL_MCLK1:
2038 reg = 0;
2039 break;
2040 case WM8915_FLL_MCLK2:
2041 reg = 1;
2042 case WM8915_FLL_DACLRCLK1:
2043 reg = 2;
2044 break;
2045 case WM8915_FLL_BCLK1:
2046 reg = 3;
2047 break;
2048 default:
2049 dev_err(codec->dev, "Unknown FLL source %d\n", ret);
2050 return -EINVAL;
2051 }
2052
2053 reg |= fll_div.fll_refclk_div << WM8915_FLL_REFCLK_DIV_SHIFT;
2054 reg |= fll_div.fll_ref_freq << WM8915_FLL_REF_FREQ_SHIFT;
2055
2056 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_5,
2057 WM8915_FLL_REFCLK_DIV_MASK | WM8915_FLL_REF_FREQ |
2058 WM8915_FLL_REFCLK_SRC_MASK, reg);
2059
2060 reg = 0;
2061 if (fll_div.theta || fll_div.lambda)
2062 reg |= WM8915_FLL_EFS_ENA | (3 << WM8915_FLL_LFSR_SEL_SHIFT);
2063 else
2064 reg |= 1 << WM8915_FLL_LFSR_SEL_SHIFT;
2065 snd_soc_write(codec, WM8915_FLL_EFS_2, reg);
2066
2067 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_2,
2068 WM8915_FLL_OUTDIV_MASK |
2069 WM8915_FLL_FRATIO_MASK,
2070 (fll_div.fll_outdiv << WM8915_FLL_OUTDIV_SHIFT) |
2071 (fll_div.fll_fratio));
2072
2073 snd_soc_write(codec, WM8915_FLL_CONTROL_3, fll_div.theta);
2074
2075 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_4,
2076 WM8915_FLL_N_MASK | WM8915_FLL_LOOP_GAIN_MASK,
2077 (fll_div.n << WM8915_FLL_N_SHIFT) |
2078 fll_div.fll_loop_gain);
2079
2080 snd_soc_write(codec, WM8915_FLL_EFS_1, fll_div.lambda);
2081
2082 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_1,
2083 WM8915_FLL_ENA, WM8915_FLL_ENA);
2084
2085 /* The FLL supports live reconfiguration - kick that in case we were
2086 * already enabled.
2087 */
2088 snd_soc_write(codec, WM8915_FLL_CONTROL_6, WM8915_FLL_SWITCH_CLK);
2089
2090 /* Wait for the FLL to lock, using the interrupt if possible */
2091 if (Fref > 1000000)
2092 timeout = usecs_to_jiffies(300);
2093 else
2094 timeout = msecs_to_jiffies(2);
2095
2096 wait_for_completion_timeout(&wm8915->fll_lock, timeout);
2097
2098 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
2099
2100 wm8915->fll_fref = Fref;
2101 wm8915->fll_fout = Fout;
2102 wm8915->fll_src = source;
2103
2104 return 0;
2105}
2106
2107#ifdef CONFIG_GPIOLIB
2108static inline struct wm8915_priv *gpio_to_wm8915(struct gpio_chip *chip)
2109{
2110 return container_of(chip, struct wm8915_priv, gpio_chip);
2111}
2112
2113static void wm8915_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
2114{
2115 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2116 struct snd_soc_codec *codec = wm8915->codec;
2117
2118 snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
2119 WM8915_GP1_LVL, !!value << WM8915_GP1_LVL_SHIFT);
2120}
2121
2122static int wm8915_gpio_direction_out(struct gpio_chip *chip,
2123 unsigned offset, int value)
2124{
2125 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2126 struct snd_soc_codec *codec = wm8915->codec;
2127 int val;
2128
2129 val = (1 << WM8915_GP1_FN_SHIFT) | (!!value << WM8915_GP1_LVL_SHIFT);
2130
2131 return snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
2132 WM8915_GP1_FN_MASK | WM8915_GP1_DIR |
2133 WM8915_GP1_LVL, val);
2134}
2135
2136static int wm8915_gpio_get(struct gpio_chip *chip, unsigned offset)
2137{
2138 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2139 struct snd_soc_codec *codec = wm8915->codec;
2140 int ret;
2141
2142 ret = snd_soc_read(codec, WM8915_GPIO_1 + offset);
2143 if (ret < 0)
2144 return ret;
2145
2146 return (ret & WM8915_GP1_LVL) != 0;
2147}
2148
2149static int wm8915_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
2150{
2151 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2152 struct snd_soc_codec *codec = wm8915->codec;
2153
2154 return snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
2155 WM8915_GP1_FN_MASK | WM8915_GP1_DIR,
2156 (1 << WM8915_GP1_FN_SHIFT) |
2157 (1 << WM8915_GP1_DIR_SHIFT));
2158}
2159
2160static struct gpio_chip wm8915_template_chip = {
2161 .label = "wm8915",
2162 .owner = THIS_MODULE,
2163 .direction_output = wm8915_gpio_direction_out,
2164 .set = wm8915_gpio_set,
2165 .direction_input = wm8915_gpio_direction_in,
2166 .get = wm8915_gpio_get,
2167 .can_sleep = 1,
2168};
2169
2170static void wm8915_init_gpio(struct snd_soc_codec *codec)
2171{
2172 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2173 int ret;
2174
2175 wm8915->gpio_chip = wm8915_template_chip;
2176 wm8915->gpio_chip.ngpio = 5;
2177 wm8915->gpio_chip.dev = codec->dev;
2178
2179 if (wm8915->pdata.gpio_base)
2180 wm8915->gpio_chip.base = wm8915->pdata.gpio_base;
2181 else
2182 wm8915->gpio_chip.base = -1;
2183
2184 ret = gpiochip_add(&wm8915->gpio_chip);
2185 if (ret != 0)
2186 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
2187}
2188
2189static void wm8915_free_gpio(struct snd_soc_codec *codec)
2190{
2191 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2192 int ret;
2193
2194 ret = gpiochip_remove(&wm8915->gpio_chip);
2195 if (ret != 0)
2196 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
2197}
2198#else
2199static void wm8915_init_gpio(struct snd_soc_codec *codec)
2200{
2201}
2202
2203static void wm8915_free_gpio(struct snd_soc_codec *codec)
2204{
2205}
2206#endif
2207
2208/**
2209 * wm8915_detect - Enable default WM8915 jack detection
2210 *
2211 * The WM8915 has advanced accessory detection support for headsets.
2212 * This function provides a default implementation which integrates
2213 * the majority of this functionality with minimal user configuration.
2214 *
2215 * This will detect headset, headphone and short circuit button and
2216 * will also detect inverted microphone ground connections and update
2217 * the polarity of the connections.
2218 */
2219int wm8915_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2220 wm8915_polarity_fn polarity_cb)
2221{
2222 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2223
2224 wm8915->jack = jack;
2225 wm8915->detecting = true;
2226 wm8915->polarity_cb = polarity_cb;
2227
2228 if (wm8915->polarity_cb)
2229 wm8915->polarity_cb(codec, 0);
2230
2231 /* Clear discarge to avoid noise during detection */
2232 snd_soc_update_bits(codec, WM8915_MICBIAS_1,
2233 WM8915_MICB1_DISCH, 0);
2234 snd_soc_update_bits(codec, WM8915_MICBIAS_2,
2235 WM8915_MICB2_DISCH, 0);
2236
2237 /* LDO2 powers the microphones, SYSCLK clocks detection */
2238 snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2");
2239 snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK");
2240
2241 /* We start off just enabling microphone detection - even a
2242 * plain headphone will trigger detection.
2243 */
2244 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2245 WM8915_MICD_ENA, WM8915_MICD_ENA);
2246
2247 /* Slowest detection rate, gives debounce for initial detection */
2248 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2249 WM8915_MICD_RATE_MASK,
2250 WM8915_MICD_RATE_MASK);
2251
2252 /* Enable interrupts and we're off */
2253 snd_soc_update_bits(codec, WM8915_INTERRUPT_STATUS_2_MASK,
2254 WM8915_IM_MICD_EINT, 0);
2255
2256 return 0;
2257}
2258EXPORT_SYMBOL_GPL(wm8915_detect);
2259
2260static void wm8915_micd(struct snd_soc_codec *codec)
2261{
2262 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2263 int val, reg;
2264
2265 val = snd_soc_read(codec, WM8915_MIC_DETECT_3);
2266
2267 dev_dbg(codec->dev, "Microphone event: %x\n", val);
2268
2269 if (!(val & WM8915_MICD_VALID)) {
2270 dev_warn(codec->dev, "Microphone detection state invalid\n");
2271 return;
2272 }
2273
2274 /* No accessory, reset everything and report removal */
2275 if (!(val & WM8915_MICD_STS)) {
2276 dev_dbg(codec->dev, "Jack removal detected\n");
2277 wm8915->jack_mic = false;
2278 wm8915->detecting = true;
2279 snd_soc_jack_report(wm8915->jack, 0,
2280 SND_JACK_HEADSET | SND_JACK_BTN_0);
2281 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2282 WM8915_MICD_RATE_MASK,
2283 WM8915_MICD_RATE_MASK);
2284 return;
2285 }
2286
2287 /* If the measurement is very high we've got a microphone but
2288 * do a little debounce to account for mechanical issues.
2289 */
2290 if (val & 0x400) {
2291 dev_dbg(codec->dev, "Microphone detected\n");
2292 snd_soc_jack_report(wm8915->jack, SND_JACK_HEADSET,
2293 SND_JACK_HEADSET | SND_JACK_BTN_0);
2294 wm8915->jack_mic = true;
2295 wm8915->detecting = false;
2296 }
2297
2298 /* If we detected a lower impedence during initial startup
2299 * then we probably have the wrong polarity, flip it. Don't
2300 * do this for the lowest impedences to speed up detection of
2301 * plain headphones.
2302 */
2303 if (wm8915->detecting && (val & 0x3f0)) {
2304 reg = snd_soc_read(codec, WM8915_ACCESSORY_DETECT_MODE_2);
2305 reg ^= WM8915_HPOUT1FB_SRC | WM8915_MICD_SRC |
2306 WM8915_MICD_BIAS_SRC;
2307 snd_soc_update_bits(codec, WM8915_ACCESSORY_DETECT_MODE_2,
2308 WM8915_HPOUT1FB_SRC | WM8915_MICD_SRC |
2309 WM8915_MICD_BIAS_SRC, reg);
2310
2311 if (wm8915->polarity_cb)
2312 wm8915->polarity_cb(codec,
2313 (reg & WM8915_MICD_SRC) != 0);
2314
2315 dev_dbg(codec->dev, "Set microphone polarity to %d\n",
2316 (reg & WM8915_MICD_SRC) != 0);
2317
2318 return;
2319 }
2320
2321 /* Don't distinguish between buttons, just report any low
2322 * impedence as BTN_0.
2323 */
2324 if (val & 0x3fc) {
2325 if (wm8915->jack_mic) {
2326 dev_dbg(codec->dev, "Mic button detected\n");
2327 snd_soc_jack_report(wm8915->jack,
2328 SND_JACK_HEADSET | SND_JACK_BTN_0,
2329 SND_JACK_HEADSET | SND_JACK_BTN_0);
2330 } else {
2331 dev_dbg(codec->dev, "Headphone detected\n");
2332 snd_soc_jack_report(wm8915->jack,
2333 SND_JACK_HEADPHONE,
2334 SND_JACK_HEADSET |
2335 SND_JACK_BTN_0);
2336 wm8915->detecting = false;
2337 }
2338 }
2339
2340 /* Increase poll rate to give better responsiveness for buttons */
2341 if (!wm8915->detecting)
2342 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2343 WM8915_MICD_RATE_MASK,
2344 5 << WM8915_MICD_RATE_SHIFT);
2345}
2346
2347static irqreturn_t wm8915_irq(int irq, void *data)
2348{
2349 struct snd_soc_codec *codec = data;
2350 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2351 int irq_val;
2352
2353 irq_val = snd_soc_read(codec, WM8915_INTERRUPT_STATUS_2);
2354 if (irq_val < 0) {
2355 dev_err(codec->dev, "Failed to read IRQ status: %d\n",
2356 irq_val);
2357 return IRQ_NONE;
2358 }
2359 irq_val &= ~snd_soc_read(codec, WM8915_INTERRUPT_STATUS_2_MASK);
2360
2361 if (irq_val & (WM8915_DCS_DONE_01_EINT | WM8915_DCS_DONE_23_EINT)) {
2362 dev_dbg(codec->dev, "DC servo IRQ\n");
2363 complete(&wm8915->dcs_done);
2364 }
2365
2366 if (irq_val & WM8915_FIFOS_ERR_EINT)
2367 dev_err(codec->dev, "Digital core FIFO error\n");
2368
2369 if (irq_val & WM8915_FLL_LOCK_EINT) {
2370 dev_dbg(codec->dev, "FLL locked\n");
2371 complete(&wm8915->fll_lock);
2372 }
2373
2374 if (irq_val & WM8915_MICD_EINT)
2375 wm8915_micd(codec);
2376
2377 if (irq_val) {
2378 snd_soc_write(codec, WM8915_INTERRUPT_STATUS_2, irq_val);
2379
2380 return IRQ_HANDLED;
2381 } else {
2382 return IRQ_NONE;
2383 }
2384}
2385
2386static void wm8915_retune_mobile_pdata(struct snd_soc_codec *codec)
2387{
2388 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2389 struct wm8915_pdata *pdata = &wm8915->pdata;
2390
2391 struct snd_kcontrol_new controls[] = {
2392 SOC_ENUM_EXT("DSP1 EQ Mode",
2393 wm8915->retune_mobile_enum,
2394 wm8915_get_retune_mobile_enum,
2395 wm8915_put_retune_mobile_enum),
2396 SOC_ENUM_EXT("DSP2 EQ Mode",
2397 wm8915->retune_mobile_enum,
2398 wm8915_get_retune_mobile_enum,
2399 wm8915_put_retune_mobile_enum),
2400 };
2401 int ret, i, j;
2402 const char **t;
2403
2404 /* We need an array of texts for the enum API but the number
2405 * of texts is likely to be less than the number of
2406 * configurations due to the sample rate dependency of the
2407 * configurations. */
2408 wm8915->num_retune_mobile_texts = 0;
2409 wm8915->retune_mobile_texts = NULL;
2410 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
2411 for (j = 0; j < wm8915->num_retune_mobile_texts; j++) {
2412 if (strcmp(pdata->retune_mobile_cfgs[i].name,
2413 wm8915->retune_mobile_texts[j]) == 0)
2414 break;
2415 }
2416
2417 if (j != wm8915->num_retune_mobile_texts)
2418 continue;
2419
2420 /* Expand the array... */
2421 t = krealloc(wm8915->retune_mobile_texts,
2422 sizeof(char *) *
2423 (wm8915->num_retune_mobile_texts + 1),
2424 GFP_KERNEL);
2425 if (t == NULL)
2426 continue;
2427
2428 /* ...store the new entry... */
2429 t[wm8915->num_retune_mobile_texts] =
2430 pdata->retune_mobile_cfgs[i].name;
2431
2432 /* ...and remember the new version. */
2433 wm8915->num_retune_mobile_texts++;
2434 wm8915->retune_mobile_texts = t;
2435 }
2436
2437 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
2438 wm8915->num_retune_mobile_texts);
2439
2440 wm8915->retune_mobile_enum.max = wm8915->num_retune_mobile_texts;
2441 wm8915->retune_mobile_enum.texts = wm8915->retune_mobile_texts;
2442
2443 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
2444 if (ret != 0)
2445 dev_err(codec->dev,
2446 "Failed to add ReTune Mobile controls: %d\n", ret);
2447}
2448
2449static int wm8915_probe(struct snd_soc_codec *codec)
2450{
2451 int ret;
2452 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2453 struct i2c_client *i2c = to_i2c_client(codec->dev);
2454 struct snd_soc_dapm_context *dapm = &codec->dapm;
2455 int i, irq_flags;
2456
2457 wm8915->codec = codec;
2458
2459 init_completion(&wm8915->dcs_done);
2460 init_completion(&wm8915->fll_lock);
2461
2462 dapm->idle_bias_off = true;
2463 dapm->bias_level = SND_SOC_BIAS_OFF;
2464
2465 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
2466 if (ret != 0) {
2467 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2468 goto err;
2469 }
2470
2471 for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++)
2472 wm8915->supplies[i].supply = wm8915_supply_names[i];
2473
2474 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8915->supplies),
2475 wm8915->supplies);
2476 if (ret != 0) {
2477 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2478 goto err;
2479 }
2480
2481 wm8915->disable_nb[0].notifier_call = wm8915_regulator_event_0;
2482 wm8915->disable_nb[1].notifier_call = wm8915_regulator_event_1;
2483 wm8915->disable_nb[2].notifier_call = wm8915_regulator_event_2;
2484 wm8915->disable_nb[3].notifier_call = wm8915_regulator_event_3;
2485 wm8915->disable_nb[4].notifier_call = wm8915_regulator_event_4;
2486 wm8915->disable_nb[5].notifier_call = wm8915_regulator_event_5;
2487
2488 /* This should really be moved into the regulator core */
2489 for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) {
2490 ret = regulator_register_notifier(wm8915->supplies[i].consumer,
2491 &wm8915->disable_nb[i]);
2492 if (ret != 0) {
2493 dev_err(codec->dev,
2494 "Failed to register regulator notifier: %d\n",
2495 ret);
2496 }
2497 }
2498
2499 ret = regulator_bulk_enable(ARRAY_SIZE(wm8915->supplies),
2500 wm8915->supplies);
2501 if (ret != 0) {
2502 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2503 goto err_get;
2504 }
2505
2506 if (wm8915->pdata.ldo_ena >= 0) {
2507 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 1);
2508 msleep(5);
2509 }
2510
2511 ret = snd_soc_read(codec, WM8915_SOFTWARE_RESET);
2512 if (ret < 0) {
2513 dev_err(codec->dev, "Failed to read ID register: %d\n", ret);
2514 goto err_enable;
2515 }
2516 if (ret != 0x8915) {
2517 dev_err(codec->dev, "Device is not a WM8915, ID %x\n", ret);
2518 ret = -EINVAL;
2519 goto err_enable;
2520 }
2521
2522 ret = snd_soc_read(codec, WM8915_CHIP_REVISION);
2523 if (ret < 0) {
2524 dev_err(codec->dev, "Failed to read device revision: %d\n",
2525 ret);
2526 goto err_enable;
2527 }
2528
2529 dev_info(codec->dev, "revision %c\n",
2530 (ret & WM8915_CHIP_REV_MASK) + 'A');
2531
2532 if (wm8915->pdata.ldo_ena >= 0) {
2533 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
2534 } else {
2535 ret = wm8915_reset(codec);
2536 if (ret < 0) {
2537 dev_err(codec->dev, "Failed to issue reset\n");
2538 goto err_enable;
2539 }
2540 }
2541
2542 codec->cache_only = true;
2543
2544 /* Apply platform data settings */
2545 snd_soc_update_bits(codec, WM8915_LINE_INPUT_CONTROL,
2546 WM8915_INL_MODE_MASK | WM8915_INR_MODE_MASK,
2547 wm8915->pdata.inl_mode << WM8915_INL_MODE_SHIFT |
2548 wm8915->pdata.inr_mode);
2549
2550 for (i = 0; i < ARRAY_SIZE(wm8915->pdata.gpio_default); i++) {
2551 if (!wm8915->pdata.gpio_default[i])
2552 continue;
2553
2554 snd_soc_write(codec, WM8915_GPIO_1 + i,
2555 wm8915->pdata.gpio_default[i] & 0xffff);
2556 }
2557
2558 if (wm8915->pdata.spkmute_seq)
2559 snd_soc_update_bits(codec, WM8915_PDM_SPEAKER_MUTE_SEQUENCE,
2560 WM8915_SPK_MUTE_ENDIAN |
2561 WM8915_SPK_MUTE_SEQ1_MASK,
2562 wm8915->pdata.spkmute_seq);
2563
2564 snd_soc_update_bits(codec, WM8915_ACCESSORY_DETECT_MODE_2,
2565 WM8915_MICD_BIAS_SRC | WM8915_HPOUT1FB_SRC |
2566 WM8915_MICD_SRC, wm8915->pdata.micdet_def);
2567
2568 /* Latch volume update bits */
2569 snd_soc_update_bits(codec, WM8915_LEFT_LINE_INPUT_VOLUME,
2570 WM8915_IN1_VU, WM8915_IN1_VU);
2571 snd_soc_update_bits(codec, WM8915_RIGHT_LINE_INPUT_VOLUME,
2572 WM8915_IN1_VU, WM8915_IN1_VU);
2573
2574 snd_soc_update_bits(codec, WM8915_DAC1_LEFT_VOLUME,
2575 WM8915_DAC1_VU, WM8915_DAC1_VU);
2576 snd_soc_update_bits(codec, WM8915_DAC1_RIGHT_VOLUME,
2577 WM8915_DAC1_VU, WM8915_DAC1_VU);
2578 snd_soc_update_bits(codec, WM8915_DAC2_LEFT_VOLUME,
2579 WM8915_DAC2_VU, WM8915_DAC2_VU);
2580 snd_soc_update_bits(codec, WM8915_DAC2_RIGHT_VOLUME,
2581 WM8915_DAC2_VU, WM8915_DAC2_VU);
2582
2583 snd_soc_update_bits(codec, WM8915_OUTPUT1_LEFT_VOLUME,
2584 WM8915_DAC1_VU, WM8915_DAC1_VU);
2585 snd_soc_update_bits(codec, WM8915_OUTPUT1_RIGHT_VOLUME,
2586 WM8915_DAC1_VU, WM8915_DAC1_VU);
2587 snd_soc_update_bits(codec, WM8915_OUTPUT2_LEFT_VOLUME,
2588 WM8915_DAC2_VU, WM8915_DAC2_VU);
2589 snd_soc_update_bits(codec, WM8915_OUTPUT2_RIGHT_VOLUME,
2590 WM8915_DAC2_VU, WM8915_DAC2_VU);
2591
2592 snd_soc_update_bits(codec, WM8915_DSP1_TX_LEFT_VOLUME,
2593 WM8915_DSP1TX_VU, WM8915_DSP1TX_VU);
2594 snd_soc_update_bits(codec, WM8915_DSP1_TX_RIGHT_VOLUME,
2595 WM8915_DSP1TX_VU, WM8915_DSP1TX_VU);
2596 snd_soc_update_bits(codec, WM8915_DSP2_TX_LEFT_VOLUME,
2597 WM8915_DSP2TX_VU, WM8915_DSP2TX_VU);
2598 snd_soc_update_bits(codec, WM8915_DSP2_TX_RIGHT_VOLUME,
2599 WM8915_DSP2TX_VU, WM8915_DSP2TX_VU);
2600
2601 snd_soc_update_bits(codec, WM8915_DSP1_RX_LEFT_VOLUME,
2602 WM8915_DSP1RX_VU, WM8915_DSP1RX_VU);
2603 snd_soc_update_bits(codec, WM8915_DSP1_RX_RIGHT_VOLUME,
2604 WM8915_DSP1RX_VU, WM8915_DSP1RX_VU);
2605 snd_soc_update_bits(codec, WM8915_DSP2_RX_LEFT_VOLUME,
2606 WM8915_DSP2RX_VU, WM8915_DSP2RX_VU);
2607 snd_soc_update_bits(codec, WM8915_DSP2_RX_RIGHT_VOLUME,
2608 WM8915_DSP2RX_VU, WM8915_DSP2RX_VU);
2609
2610 /* No support currently for the underclocked TDM modes and
2611 * pick a default TDM layout with each channel pair working with
2612 * slots 0 and 1. */
2613 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_0_CONFIGURATION,
2614 WM8915_AIF1RX_CHAN0_SLOTS_MASK |
2615 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2616 1 << WM8915_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
2617 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_1_CONFIGURATION,
2618 WM8915_AIF1RX_CHAN1_SLOTS_MASK |
2619 WM8915_AIF1RX_CHAN1_START_SLOT_MASK,
2620 1 << WM8915_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
2621 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_2_CONFIGURATION,
2622 WM8915_AIF1RX_CHAN2_SLOTS_MASK |
2623 WM8915_AIF1RX_CHAN2_START_SLOT_MASK,
2624 1 << WM8915_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
2625 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_3_CONFIGURATION,
2626 WM8915_AIF1RX_CHAN3_SLOTS_MASK |
2627 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2628 1 << WM8915_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
2629 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_4_CONFIGURATION,
2630 WM8915_AIF1RX_CHAN4_SLOTS_MASK |
2631 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2632 1 << WM8915_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
2633 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_5_CONFIGURATION,
2634 WM8915_AIF1RX_CHAN5_SLOTS_MASK |
2635 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2636 1 << WM8915_AIF1RX_CHAN5_SLOTS_SHIFT | 1);
2637
2638 snd_soc_update_bits(codec, WM8915_AIF2RX_CHANNEL_0_CONFIGURATION,
2639 WM8915_AIF2RX_CHAN0_SLOTS_MASK |
2640 WM8915_AIF2RX_CHAN0_START_SLOT_MASK,
2641 1 << WM8915_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
2642 snd_soc_update_bits(codec, WM8915_AIF2RX_CHANNEL_1_CONFIGURATION,
2643 WM8915_AIF2RX_CHAN1_SLOTS_MASK |
2644 WM8915_AIF2RX_CHAN1_START_SLOT_MASK,
2645 1 << WM8915_AIF2RX_CHAN1_SLOTS_SHIFT | 1);
2646
2647 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_0_CONFIGURATION,
2648 WM8915_AIF1TX_CHAN0_SLOTS_MASK |
2649 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2650 1 << WM8915_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
2651 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_1_CONFIGURATION,
2652 WM8915_AIF1TX_CHAN1_SLOTS_MASK |
2653 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2654 1 << WM8915_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2655 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_2_CONFIGURATION,
2656 WM8915_AIF1TX_CHAN2_SLOTS_MASK |
2657 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2658 1 << WM8915_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
2659 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_3_CONFIGURATION,
2660 WM8915_AIF1TX_CHAN3_SLOTS_MASK |
2661 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2662 1 << WM8915_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
2663 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_4_CONFIGURATION,
2664 WM8915_AIF1TX_CHAN4_SLOTS_MASK |
2665 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2666 1 << WM8915_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
2667 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_5_CONFIGURATION,
2668 WM8915_AIF1TX_CHAN5_SLOTS_MASK |
2669 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2670 1 << WM8915_AIF1TX_CHAN5_SLOTS_SHIFT | 1);
2671
2672 snd_soc_update_bits(codec, WM8915_AIF2TX_CHANNEL_0_CONFIGURATION,
2673 WM8915_AIF2TX_CHAN0_SLOTS_MASK |
2674 WM8915_AIF2TX_CHAN0_START_SLOT_MASK,
2675 1 << WM8915_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
2676 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_1_CONFIGURATION,
2677 WM8915_AIF2TX_CHAN1_SLOTS_MASK |
2678 WM8915_AIF2TX_CHAN1_START_SLOT_MASK,
2679 1 << WM8915_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2680
2681 if (wm8915->pdata.num_retune_mobile_cfgs)
2682 wm8915_retune_mobile_pdata(codec);
2683 else
2684 snd_soc_add_controls(codec, wm8915_eq_controls,
2685 ARRAY_SIZE(wm8915_eq_controls));
2686
2687 /* If the TX LRCLK pins are not in LRCLK mode configure the
2688 * AIFs to source their clocks from the RX LRCLKs.
2689 */
2690 if ((snd_soc_read(codec, WM8915_GPIO_1)))
2691 snd_soc_update_bits(codec, WM8915_AIF1_TX_LRCLK_2,
2692 WM8915_AIF1TX_LRCLK_MODE,
2693 WM8915_AIF1TX_LRCLK_MODE);
2694
2695 if ((snd_soc_read(codec, WM8915_GPIO_2)))
2696 snd_soc_update_bits(codec, WM8915_AIF2_TX_LRCLK_2,
2697 WM8915_AIF2TX_LRCLK_MODE,
2698 WM8915_AIF2TX_LRCLK_MODE);
2699
2700 regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2701
2702 wm8915_init_gpio(codec);
2703
2704 if (i2c->irq) {
2705 if (wm8915->pdata.irq_flags)
2706 irq_flags = wm8915->pdata.irq_flags;
2707 else
2708 irq_flags = IRQF_TRIGGER_LOW;
2709
2710 irq_flags |= IRQF_ONESHOT;
2711
2712 ret = request_threaded_irq(i2c->irq, NULL, wm8915_irq,
2713 irq_flags, "wm8915", codec);
2714 if (ret == 0) {
2715 /* Unmask the interrupt */
2716 snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL,
2717 WM8915_IM_IRQ, 0);
2718
2719 /* Enable error reporting and DC servo status */
2720 snd_soc_update_bits(codec,
2721 WM8915_INTERRUPT_STATUS_2_MASK,
2722 WM8915_IM_DCS_DONE_23_EINT |
2723 WM8915_IM_DCS_DONE_01_EINT |
2724 WM8915_IM_FLL_LOCK_EINT |
2725 WM8915_IM_FIFOS_ERR_EINT,
2726 0);
2727 } else {
2728 dev_err(codec->dev, "Failed to request IRQ: %d\n",
2729 ret);
2730 }
2731 }
2732
2733 return 0;
2734
2735err_enable:
2736 if (wm8915->pdata.ldo_ena >= 0)
2737 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
2738
2739 regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2740err_get:
2741 regulator_bulk_free(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2742err:
2743 return ret;
2744}
2745
2746static int wm8915_remove(struct snd_soc_codec *codec)
2747{
2748 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2749 struct i2c_client *i2c = to_i2c_client(codec->dev);
2750 int i;
2751
2752 snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL,
2753 WM8915_IM_IRQ, WM8915_IM_IRQ);
2754
2755 if (i2c->irq)
2756 free_irq(i2c->irq, codec);
2757
2758 wm8915_free_gpio(codec);
2759
2760 for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++)
2761 regulator_unregister_notifier(wm8915->supplies[i].consumer,
2762 &wm8915->disable_nb[i]);
2763 regulator_bulk_free(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2764
2765 return 0;
2766}
2767
2768static struct snd_soc_codec_driver soc_codec_dev_wm8915 = {
2769 .probe = wm8915_probe,
2770 .remove = wm8915_remove,
2771 .set_bias_level = wm8915_set_bias_level,
2772 .seq_notifier = wm8915_seq_notifier,
2773 .reg_cache_size = WM8915_MAX_REGISTER + 1,
2774 .reg_word_size = sizeof(u16),
2775 .reg_cache_default = wm8915_reg,
2776 .volatile_register = wm8915_volatile_register,
2777 .readable_register = wm8915_readable_register,
2778 .compress_type = SND_SOC_RBTREE_COMPRESSION,
2779 .controls = wm8915_snd_controls,
2780 .num_controls = ARRAY_SIZE(wm8915_snd_controls),
2781 .dapm_widgets = wm8915_dapm_widgets,
2782 .num_dapm_widgets = ARRAY_SIZE(wm8915_dapm_widgets),
2783 .dapm_routes = wm8915_dapm_routes,
2784 .num_dapm_routes = ARRAY_SIZE(wm8915_dapm_routes),
2785 .set_pll = wm8915_set_fll,
2786};
2787
2788#define WM8915_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
2789 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
2790#define WM8915_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
2791 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\
2792 SNDRV_PCM_FMTBIT_S32_LE)
2793
2794static struct snd_soc_dai_ops wm8915_dai_ops = {
2795 .set_fmt = wm8915_set_fmt,
2796 .hw_params = wm8915_hw_params,
2797 .set_sysclk = wm8915_set_sysclk,
2798};
2799
2800static struct snd_soc_dai_driver wm8915_dai[] = {
2801 {
2802 .name = "wm8915-aif1",
2803 .playback = {
2804 .stream_name = "AIF1 Playback",
2805 .channels_min = 1,
2806 .channels_max = 6,
2807 .rates = WM8915_RATES,
2808 .formats = WM8915_FORMATS,
2809 },
2810 .capture = {
2811 .stream_name = "AIF1 Capture",
2812 .channels_min = 1,
2813 .channels_max = 6,
2814 .rates = WM8915_RATES,
2815 .formats = WM8915_FORMATS,
2816 },
2817 .ops = &wm8915_dai_ops,
2818 },
2819 {
2820 .name = "wm8915-aif2",
2821 .playback = {
2822 .stream_name = "AIF2 Playback",
2823 .channels_min = 1,
2824 .channels_max = 2,
2825 .rates = WM8915_RATES,
2826 .formats = WM8915_FORMATS,
2827 },
2828 .capture = {
2829 .stream_name = "AIF2 Capture",
2830 .channels_min = 1,
2831 .channels_max = 2,
2832 .rates = WM8915_RATES,
2833 .formats = WM8915_FORMATS,
2834 },
2835 .ops = &wm8915_dai_ops,
2836 },
2837};
2838
2839static __devinit int wm8915_i2c_probe(struct i2c_client *i2c,
2840 const struct i2c_device_id *id)
2841{
2842 struct wm8915_priv *wm8915;
2843 int ret;
2844
2845 wm8915 = kzalloc(sizeof(struct wm8915_priv), GFP_KERNEL);
2846 if (wm8915 == NULL)
2847 return -ENOMEM;
2848
2849 i2c_set_clientdata(i2c, wm8915);
2850
2851 if (dev_get_platdata(&i2c->dev))
2852 memcpy(&wm8915->pdata, dev_get_platdata(&i2c->dev),
2853 sizeof(wm8915->pdata));
2854
2855 if (wm8915->pdata.ldo_ena > 0) {
2856 ret = gpio_request_one(wm8915->pdata.ldo_ena,
2857 GPIOF_OUT_INIT_LOW, "WM8915 ENA");
2858 if (ret < 0) {
2859 dev_err(&i2c->dev, "Failed to request GPIO %d: %d\n",
2860 wm8915->pdata.ldo_ena, ret);
2861 goto err;
2862 }
2863 }
2864
2865 ret = snd_soc_register_codec(&i2c->dev,
2866 &soc_codec_dev_wm8915, wm8915_dai,
2867 ARRAY_SIZE(wm8915_dai));
2868 if (ret < 0)
2869 goto err_gpio;
2870
2871 return ret;
2872
2873err_gpio:
2874 if (wm8915->pdata.ldo_ena > 0)
2875 gpio_free(wm8915->pdata.ldo_ena);
2876err:
2877 kfree(wm8915);
2878
2879 return ret;
2880}
2881
2882static __devexit int wm8915_i2c_remove(struct i2c_client *client)
2883{
2884 struct wm8915_priv *wm8915 = i2c_get_clientdata(client);
2885
2886 snd_soc_unregister_codec(&client->dev);
2887 if (wm8915->pdata.ldo_ena > 0)
2888 gpio_free(wm8915->pdata.ldo_ena);
2889 kfree(i2c_get_clientdata(client));
2890 return 0;
2891}
2892
2893static const struct i2c_device_id wm8915_i2c_id[] = {
2894 { "wm8915", 0 },
2895 { }
2896};
2897MODULE_DEVICE_TABLE(i2c, wm8915_i2c_id);
2898
2899static struct i2c_driver wm8915_i2c_driver = {
2900 .driver = {
2901 .name = "wm8915",
2902 .owner = THIS_MODULE,
2903 },
2904 .probe = wm8915_i2c_probe,
2905 .remove = __devexit_p(wm8915_i2c_remove),
2906 .id_table = wm8915_i2c_id,
2907};
2908
2909static int __init wm8915_modinit(void)
2910{
2911 int ret;
2912
2913 ret = i2c_add_driver(&wm8915_i2c_driver);
2914 if (ret != 0) {
2915 printk(KERN_ERR "Failed to register WM8915 I2C driver: %d\n",
2916 ret);
2917 }
2918
2919 return ret;
2920}
2921module_init(wm8915_modinit);
2922
2923static void __exit wm8915_exit(void)
2924{
2925 i2c_del_driver(&wm8915_i2c_driver);
2926}
2927module_exit(wm8915_exit);
2928
2929MODULE_DESCRIPTION("ASoC WM8915 driver");
2930MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2931MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8915.h b/sound/soc/codecs/wm8915.h
new file mode 100644
index 000000000000..200ffd7bf953
--- /dev/null
+++ b/sound/soc/codecs/wm8915.h
@@ -0,0 +1,3717 @@
1/*
2 * wm8915.h - WM8915 audio codec interface
3 *
4 * Copyright 2011 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef _WM8915_H
14#define _WM8915_H
15
16#define WM8915_SYSCLK_MCLK1 1
17#define WM8915_SYSCLK_MCLK2 2
18#define WM8915_SYSCLK_FLL 3
19
20#define WM8915_FLL_MCLK1 1
21#define WM8915_FLL_MCLK2 2
22#define WM8915_FLL_DACLRCLK1 3
23#define WM8915_FLL_BCLK1 4
24
25typedef void (*wm8915_polarity_fn)(struct snd_soc_codec *codec, int polarity);
26
27int wm8915_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
28 wm8915_polarity_fn polarity_cb);
29
30/*
31 * Register values.
32 */
33#define WM8915_SOFTWARE_RESET 0x00
34#define WM8915_POWER_MANAGEMENT_1 0x01
35#define WM8915_POWER_MANAGEMENT_2 0x02
36#define WM8915_POWER_MANAGEMENT_3 0x03
37#define WM8915_POWER_MANAGEMENT_4 0x04
38#define WM8915_POWER_MANAGEMENT_5 0x05
39#define WM8915_POWER_MANAGEMENT_6 0x06
40#define WM8915_POWER_MANAGEMENT_7 0x07
41#define WM8915_POWER_MANAGEMENT_8 0x08
42#define WM8915_LEFT_LINE_INPUT_VOLUME 0x10
43#define WM8915_RIGHT_LINE_INPUT_VOLUME 0x11
44#define WM8915_LINE_INPUT_CONTROL 0x12
45#define WM8915_DAC1_HPOUT1_VOLUME 0x15
46#define WM8915_DAC2_HPOUT2_VOLUME 0x16
47#define WM8915_DAC1_LEFT_VOLUME 0x18
48#define WM8915_DAC1_RIGHT_VOLUME 0x19
49#define WM8915_DAC2_LEFT_VOLUME 0x1A
50#define WM8915_DAC2_RIGHT_VOLUME 0x1B
51#define WM8915_OUTPUT1_LEFT_VOLUME 0x1C
52#define WM8915_OUTPUT1_RIGHT_VOLUME 0x1D
53#define WM8915_OUTPUT2_LEFT_VOLUME 0x1E
54#define WM8915_OUTPUT2_RIGHT_VOLUME 0x1F
55#define WM8915_MICBIAS_1 0x20
56#define WM8915_MICBIAS_2 0x21
57#define WM8915_LDO_1 0x28
58#define WM8915_LDO_2 0x29
59#define WM8915_ACCESSORY_DETECT_MODE_1 0x30
60#define WM8915_ACCESSORY_DETECT_MODE_2 0x31
61#define WM8915_HEADPHONE_DETECT_1 0x34
62#define WM8915_HEADPHONE_DETECT_2 0x35
63#define WM8915_MIC_DETECT_1 0x38
64#define WM8915_MIC_DETECT_2 0x39
65#define WM8915_MIC_DETECT_3 0x3A
66#define WM8915_CHARGE_PUMP_1 0x40
67#define WM8915_CHARGE_PUMP_2 0x41
68#define WM8915_DC_SERVO_1 0x50
69#define WM8915_DC_SERVO_2 0x51
70#define WM8915_DC_SERVO_3 0x52
71#define WM8915_DC_SERVO_5 0x54
72#define WM8915_DC_SERVO_6 0x55
73#define WM8915_DC_SERVO_7 0x56
74#define WM8915_DC_SERVO_READBACK_0 0x57
75#define WM8915_ANALOGUE_HP_1 0x60
76#define WM8915_ANALOGUE_HP_2 0x61
77#define WM8915_CHIP_REVISION 0x100
78#define WM8915_CONTROL_INTERFACE_1 0x101
79#define WM8915_WRITE_SEQUENCER_CTRL_1 0x110
80#define WM8915_WRITE_SEQUENCER_CTRL_2 0x111
81#define WM8915_AIF_CLOCKING_1 0x200
82#define WM8915_AIF_CLOCKING_2 0x201
83#define WM8915_CLOCKING_1 0x208
84#define WM8915_CLOCKING_2 0x209
85#define WM8915_AIF_RATE 0x210
86#define WM8915_FLL_CONTROL_1 0x220
87#define WM8915_FLL_CONTROL_2 0x221
88#define WM8915_FLL_CONTROL_3 0x222
89#define WM8915_FLL_CONTROL_4 0x223
90#define WM8915_FLL_CONTROL_5 0x224
91#define WM8915_FLL_CONTROL_6 0x225
92#define WM8915_FLL_EFS_1 0x226
93#define WM8915_FLL_EFS_2 0x227
94#define WM8915_AIF1_CONTROL 0x300
95#define WM8915_AIF1_BCLK 0x301
96#define WM8915_AIF1_TX_LRCLK_1 0x302
97#define WM8915_AIF1_TX_LRCLK_2 0x303
98#define WM8915_AIF1_RX_LRCLK_1 0x304
99#define WM8915_AIF1_RX_LRCLK_2 0x305
100#define WM8915_AIF1TX_DATA_CONFIGURATION_1 0x306
101#define WM8915_AIF1TX_DATA_CONFIGURATION_2 0x307
102#define WM8915_AIF1RX_DATA_CONFIGURATION 0x308
103#define WM8915_AIF1TX_CHANNEL_0_CONFIGURATION 0x309
104#define WM8915_AIF1TX_CHANNEL_1_CONFIGURATION 0x30A
105#define WM8915_AIF1TX_CHANNEL_2_CONFIGURATION 0x30B
106#define WM8915_AIF1TX_CHANNEL_3_CONFIGURATION 0x30C
107#define WM8915_AIF1TX_CHANNEL_4_CONFIGURATION 0x30D
108#define WM8915_AIF1TX_CHANNEL_5_CONFIGURATION 0x30E
109#define WM8915_AIF1RX_CHANNEL_0_CONFIGURATION 0x30F
110#define WM8915_AIF1RX_CHANNEL_1_CONFIGURATION 0x310
111#define WM8915_AIF1RX_CHANNEL_2_CONFIGURATION 0x311
112#define WM8915_AIF1RX_CHANNEL_3_CONFIGURATION 0x312
113#define WM8915_AIF1RX_CHANNEL_4_CONFIGURATION 0x313
114#define WM8915_AIF1RX_CHANNEL_5_CONFIGURATION 0x314
115#define WM8915_AIF1RX_MONO_CONFIGURATION 0x315
116#define WM8915_AIF1TX_TEST 0x31A
117#define WM8915_AIF2_CONTROL 0x320
118#define WM8915_AIF2_BCLK 0x321
119#define WM8915_AIF2_TX_LRCLK_1 0x322
120#define WM8915_AIF2_TX_LRCLK_2 0x323
121#define WM8915_AIF2_RX_LRCLK_1 0x324
122#define WM8915_AIF2_RX_LRCLK_2 0x325
123#define WM8915_AIF2TX_DATA_CONFIGURATION_1 0x326
124#define WM8915_AIF2TX_DATA_CONFIGURATION_2 0x327
125#define WM8915_AIF2RX_DATA_CONFIGURATION 0x328
126#define WM8915_AIF2TX_CHANNEL_0_CONFIGURATION 0x329
127#define WM8915_AIF2TX_CHANNEL_1_CONFIGURATION 0x32A
128#define WM8915_AIF2RX_CHANNEL_0_CONFIGURATION 0x32B
129#define WM8915_AIF2RX_CHANNEL_1_CONFIGURATION 0x32C
130#define WM8915_AIF2RX_MONO_CONFIGURATION 0x32D
131#define WM8915_AIF2TX_TEST 0x32F
132#define WM8915_DSP1_TX_LEFT_VOLUME 0x400
133#define WM8915_DSP1_TX_RIGHT_VOLUME 0x401
134#define WM8915_DSP1_RX_LEFT_VOLUME 0x402
135#define WM8915_DSP1_RX_RIGHT_VOLUME 0x403
136#define WM8915_DSP1_TX_FILTERS 0x410
137#define WM8915_DSP1_RX_FILTERS_1 0x420
138#define WM8915_DSP1_RX_FILTERS_2 0x421
139#define WM8915_DSP1_DRC_1 0x440
140#define WM8915_DSP1_DRC_2 0x441
141#define WM8915_DSP1_DRC_3 0x442
142#define WM8915_DSP1_DRC_4 0x443
143#define WM8915_DSP1_DRC_5 0x444
144#define WM8915_DSP1_RX_EQ_GAINS_1 0x480
145#define WM8915_DSP1_RX_EQ_GAINS_2 0x481
146#define WM8915_DSP1_RX_EQ_BAND_1_A 0x482
147#define WM8915_DSP1_RX_EQ_BAND_1_B 0x483
148#define WM8915_DSP1_RX_EQ_BAND_1_PG 0x484
149#define WM8915_DSP1_RX_EQ_BAND_2_A 0x485
150#define WM8915_DSP1_RX_EQ_BAND_2_B 0x486
151#define WM8915_DSP1_RX_EQ_BAND_2_C 0x487
152#define WM8915_DSP1_RX_EQ_BAND_2_PG 0x488
153#define WM8915_DSP1_RX_EQ_BAND_3_A 0x489
154#define WM8915_DSP1_RX_EQ_BAND_3_B 0x48A
155#define WM8915_DSP1_RX_EQ_BAND_3_C 0x48B
156#define WM8915_DSP1_RX_EQ_BAND_3_PG 0x48C
157#define WM8915_DSP1_RX_EQ_BAND_4_A 0x48D
158#define WM8915_DSP1_RX_EQ_BAND_4_B 0x48E
159#define WM8915_DSP1_RX_EQ_BAND_4_C 0x48F
160#define WM8915_DSP1_RX_EQ_BAND_4_PG 0x490
161#define WM8915_DSP1_RX_EQ_BAND_5_A 0x491
162#define WM8915_DSP1_RX_EQ_BAND_5_B 0x492
163#define WM8915_DSP1_RX_EQ_BAND_5_PG 0x493
164#define WM8915_DSP2_TX_LEFT_VOLUME 0x500
165#define WM8915_DSP2_TX_RIGHT_VOLUME 0x501
166#define WM8915_DSP2_RX_LEFT_VOLUME 0x502
167#define WM8915_DSP2_RX_RIGHT_VOLUME 0x503
168#define WM8915_DSP2_TX_FILTERS 0x510
169#define WM8915_DSP2_RX_FILTERS_1 0x520
170#define WM8915_DSP2_RX_FILTERS_2 0x521
171#define WM8915_DSP2_DRC_1 0x540
172#define WM8915_DSP2_DRC_2 0x541
173#define WM8915_DSP2_DRC_3 0x542
174#define WM8915_DSP2_DRC_4 0x543
175#define WM8915_DSP2_DRC_5 0x544
176#define WM8915_DSP2_RX_EQ_GAINS_1 0x580
177#define WM8915_DSP2_RX_EQ_GAINS_2 0x581
178#define WM8915_DSP2_RX_EQ_BAND_1_A 0x582
179#define WM8915_DSP2_RX_EQ_BAND_1_B 0x583
180#define WM8915_DSP2_RX_EQ_BAND_1_PG 0x584
181#define WM8915_DSP2_RX_EQ_BAND_2_A 0x585
182#define WM8915_DSP2_RX_EQ_BAND_2_B 0x586
183#define WM8915_DSP2_RX_EQ_BAND_2_C 0x587
184#define WM8915_DSP2_RX_EQ_BAND_2_PG 0x588
185#define WM8915_DSP2_RX_EQ_BAND_3_A 0x589
186#define WM8915_DSP2_RX_EQ_BAND_3_B 0x58A
187#define WM8915_DSP2_RX_EQ_BAND_3_C 0x58B
188#define WM8915_DSP2_RX_EQ_BAND_3_PG 0x58C
189#define WM8915_DSP2_RX_EQ_BAND_4_A 0x58D
190#define WM8915_DSP2_RX_EQ_BAND_4_B 0x58E
191#define WM8915_DSP2_RX_EQ_BAND_4_C 0x58F
192#define WM8915_DSP2_RX_EQ_BAND_4_PG 0x590
193#define WM8915_DSP2_RX_EQ_BAND_5_A 0x591
194#define WM8915_DSP2_RX_EQ_BAND_5_B 0x592
195#define WM8915_DSP2_RX_EQ_BAND_5_PG 0x593
196#define WM8915_DAC1_MIXER_VOLUMES 0x600
197#define WM8915_DAC1_LEFT_MIXER_ROUTING 0x601
198#define WM8915_DAC1_RIGHT_MIXER_ROUTING 0x602
199#define WM8915_DAC2_MIXER_VOLUMES 0x603
200#define WM8915_DAC2_LEFT_MIXER_ROUTING 0x604
201#define WM8915_DAC2_RIGHT_MIXER_ROUTING 0x605
202#define WM8915_DSP1_TX_LEFT_MIXER_ROUTING 0x606
203#define WM8915_DSP1_TX_RIGHT_MIXER_ROUTING 0x607
204#define WM8915_DSP2_TX_LEFT_MIXER_ROUTING 0x608
205#define WM8915_DSP2_TX_RIGHT_MIXER_ROUTING 0x609
206#define WM8915_DSP_TX_MIXER_SELECT 0x60A
207#define WM8915_DAC_SOFTMUTE 0x610
208#define WM8915_OVERSAMPLING 0x620
209#define WM8915_SIDETONE 0x621
210#define WM8915_GPIO_1 0x700
211#define WM8915_GPIO_2 0x701
212#define WM8915_GPIO_3 0x702
213#define WM8915_GPIO_4 0x703
214#define WM8915_GPIO_5 0x704
215#define WM8915_PULL_CONTROL_1 0x720
216#define WM8915_PULL_CONTROL_2 0x721
217#define WM8915_INTERRUPT_STATUS_1 0x730
218#define WM8915_INTERRUPT_STATUS_2 0x731
219#define WM8915_INTERRUPT_RAW_STATUS_2 0x732
220#define WM8915_INTERRUPT_STATUS_1_MASK 0x738
221#define WM8915_INTERRUPT_STATUS_2_MASK 0x739
222#define WM8915_INTERRUPT_CONTROL 0x740
223#define WM8915_LEFT_PDM_SPEAKER 0x800
224#define WM8915_RIGHT_PDM_SPEAKER 0x801
225#define WM8915_PDM_SPEAKER_MUTE_SEQUENCE 0x802
226#define WM8915_PDM_SPEAKER_VOLUME 0x803
227#define WM8915_WRITE_SEQUENCER_0 0x3000
228#define WM8915_WRITE_SEQUENCER_1 0x3001
229#define WM8915_WRITE_SEQUENCER_2 0x3002
230#define WM8915_WRITE_SEQUENCER_3 0x3003
231#define WM8915_WRITE_SEQUENCER_4 0x3004
232#define WM8915_WRITE_SEQUENCER_5 0x3005
233#define WM8915_WRITE_SEQUENCER_6 0x3006
234#define WM8915_WRITE_SEQUENCER_7 0x3007
235#define WM8915_WRITE_SEQUENCER_8 0x3008
236#define WM8915_WRITE_SEQUENCER_9 0x3009
237#define WM8915_WRITE_SEQUENCER_10 0x300A
238#define WM8915_WRITE_SEQUENCER_11 0x300B
239#define WM8915_WRITE_SEQUENCER_12 0x300C
240#define WM8915_WRITE_SEQUENCER_13 0x300D
241#define WM8915_WRITE_SEQUENCER_14 0x300E
242#define WM8915_WRITE_SEQUENCER_15 0x300F
243#define WM8915_WRITE_SEQUENCER_16 0x3010
244#define WM8915_WRITE_SEQUENCER_17 0x3011
245#define WM8915_WRITE_SEQUENCER_18 0x3012
246#define WM8915_WRITE_SEQUENCER_19 0x3013
247#define WM8915_WRITE_SEQUENCER_20 0x3014
248#define WM8915_WRITE_SEQUENCER_21 0x3015
249#define WM8915_WRITE_SEQUENCER_22 0x3016
250#define WM8915_WRITE_SEQUENCER_23 0x3017
251#define WM8915_WRITE_SEQUENCER_24 0x3018
252#define WM8915_WRITE_SEQUENCER_25 0x3019
253#define WM8915_WRITE_SEQUENCER_26 0x301A
254#define WM8915_WRITE_SEQUENCER_27 0x301B
255#define WM8915_WRITE_SEQUENCER_28 0x301C
256#define WM8915_WRITE_SEQUENCER_29 0x301D
257#define WM8915_WRITE_SEQUENCER_30 0x301E
258#define WM8915_WRITE_SEQUENCER_31 0x301F
259#define WM8915_WRITE_SEQUENCER_32 0x3020
260#define WM8915_WRITE_SEQUENCER_33 0x3021
261#define WM8915_WRITE_SEQUENCER_34 0x3022
262#define WM8915_WRITE_SEQUENCER_35 0x3023
263#define WM8915_WRITE_SEQUENCER_36 0x3024
264#define WM8915_WRITE_SEQUENCER_37 0x3025
265#define WM8915_WRITE_SEQUENCER_38 0x3026
266#define WM8915_WRITE_SEQUENCER_39 0x3027
267#define WM8915_WRITE_SEQUENCER_40 0x3028
268#define WM8915_WRITE_SEQUENCER_41 0x3029
269#define WM8915_WRITE_SEQUENCER_42 0x302A
270#define WM8915_WRITE_SEQUENCER_43 0x302B
271#define WM8915_WRITE_SEQUENCER_44 0x302C
272#define WM8915_WRITE_SEQUENCER_45 0x302D
273#define WM8915_WRITE_SEQUENCER_46 0x302E
274#define WM8915_WRITE_SEQUENCER_47 0x302F
275#define WM8915_WRITE_SEQUENCER_48 0x3030
276#define WM8915_WRITE_SEQUENCER_49 0x3031
277#define WM8915_WRITE_SEQUENCER_50 0x3032
278#define WM8915_WRITE_SEQUENCER_51 0x3033
279#define WM8915_WRITE_SEQUENCER_52 0x3034
280#define WM8915_WRITE_SEQUENCER_53 0x3035
281#define WM8915_WRITE_SEQUENCER_54 0x3036
282#define WM8915_WRITE_SEQUENCER_55 0x3037
283#define WM8915_WRITE_SEQUENCER_56 0x3038
284#define WM8915_WRITE_SEQUENCER_57 0x3039
285#define WM8915_WRITE_SEQUENCER_58 0x303A
286#define WM8915_WRITE_SEQUENCER_59 0x303B
287#define WM8915_WRITE_SEQUENCER_60 0x303C
288#define WM8915_WRITE_SEQUENCER_61 0x303D
289#define WM8915_WRITE_SEQUENCER_62 0x303E
290#define WM8915_WRITE_SEQUENCER_63 0x303F
291#define WM8915_WRITE_SEQUENCER_64 0x3040
292#define WM8915_WRITE_SEQUENCER_65 0x3041
293#define WM8915_WRITE_SEQUENCER_66 0x3042
294#define WM8915_WRITE_SEQUENCER_67 0x3043
295#define WM8915_WRITE_SEQUENCER_68 0x3044
296#define WM8915_WRITE_SEQUENCER_69 0x3045
297#define WM8915_WRITE_SEQUENCER_70 0x3046
298#define WM8915_WRITE_SEQUENCER_71 0x3047
299#define WM8915_WRITE_SEQUENCER_72 0x3048
300#define WM8915_WRITE_SEQUENCER_73 0x3049
301#define WM8915_WRITE_SEQUENCER_74 0x304A
302#define WM8915_WRITE_SEQUENCER_75 0x304B
303#define WM8915_WRITE_SEQUENCER_76 0x304C
304#define WM8915_WRITE_SEQUENCER_77 0x304D
305#define WM8915_WRITE_SEQUENCER_78 0x304E
306#define WM8915_WRITE_SEQUENCER_79 0x304F
307#define WM8915_WRITE_SEQUENCER_80 0x3050
308#define WM8915_WRITE_SEQUENCER_81 0x3051
309#define WM8915_WRITE_SEQUENCER_82 0x3052
310#define WM8915_WRITE_SEQUENCER_83 0x3053
311#define WM8915_WRITE_SEQUENCER_84 0x3054
312#define WM8915_WRITE_SEQUENCER_85 0x3055
313#define WM8915_WRITE_SEQUENCER_86 0x3056
314#define WM8915_WRITE_SEQUENCER_87 0x3057
315#define WM8915_WRITE_SEQUENCER_88 0x3058
316#define WM8915_WRITE_SEQUENCER_89 0x3059
317#define WM8915_WRITE_SEQUENCER_90 0x305A
318#define WM8915_WRITE_SEQUENCER_91 0x305B
319#define WM8915_WRITE_SEQUENCER_92 0x305C
320#define WM8915_WRITE_SEQUENCER_93 0x305D
321#define WM8915_WRITE_SEQUENCER_94 0x305E
322#define WM8915_WRITE_SEQUENCER_95 0x305F
323#define WM8915_WRITE_SEQUENCER_96 0x3060
324#define WM8915_WRITE_SEQUENCER_97 0x3061
325#define WM8915_WRITE_SEQUENCER_98 0x3062
326#define WM8915_WRITE_SEQUENCER_99 0x3063
327#define WM8915_WRITE_SEQUENCER_100 0x3064
328#define WM8915_WRITE_SEQUENCER_101 0x3065
329#define WM8915_WRITE_SEQUENCER_102 0x3066
330#define WM8915_WRITE_SEQUENCER_103 0x3067
331#define WM8915_WRITE_SEQUENCER_104 0x3068
332#define WM8915_WRITE_SEQUENCER_105 0x3069
333#define WM8915_WRITE_SEQUENCER_106 0x306A
334#define WM8915_WRITE_SEQUENCER_107 0x306B
335#define WM8915_WRITE_SEQUENCER_108 0x306C
336#define WM8915_WRITE_SEQUENCER_109 0x306D
337#define WM8915_WRITE_SEQUENCER_110 0x306E
338#define WM8915_WRITE_SEQUENCER_111 0x306F
339#define WM8915_WRITE_SEQUENCER_112 0x3070
340#define WM8915_WRITE_SEQUENCER_113 0x3071
341#define WM8915_WRITE_SEQUENCER_114 0x3072
342#define WM8915_WRITE_SEQUENCER_115 0x3073
343#define WM8915_WRITE_SEQUENCER_116 0x3074
344#define WM8915_WRITE_SEQUENCER_117 0x3075
345#define WM8915_WRITE_SEQUENCER_118 0x3076
346#define WM8915_WRITE_SEQUENCER_119 0x3077
347#define WM8915_WRITE_SEQUENCER_120 0x3078
348#define WM8915_WRITE_SEQUENCER_121 0x3079
349#define WM8915_WRITE_SEQUENCER_122 0x307A
350#define WM8915_WRITE_SEQUENCER_123 0x307B
351#define WM8915_WRITE_SEQUENCER_124 0x307C
352#define WM8915_WRITE_SEQUENCER_125 0x307D
353#define WM8915_WRITE_SEQUENCER_126 0x307E
354#define WM8915_WRITE_SEQUENCER_127 0x307F
355#define WM8915_WRITE_SEQUENCER_128 0x3080
356#define WM8915_WRITE_SEQUENCER_129 0x3081
357#define WM8915_WRITE_SEQUENCER_130 0x3082
358#define WM8915_WRITE_SEQUENCER_131 0x3083
359#define WM8915_WRITE_SEQUENCER_132 0x3084
360#define WM8915_WRITE_SEQUENCER_133 0x3085
361#define WM8915_WRITE_SEQUENCER_134 0x3086
362#define WM8915_WRITE_SEQUENCER_135 0x3087
363#define WM8915_WRITE_SEQUENCER_136 0x3088
364#define WM8915_WRITE_SEQUENCER_137 0x3089
365#define WM8915_WRITE_SEQUENCER_138 0x308A
366#define WM8915_WRITE_SEQUENCER_139 0x308B
367#define WM8915_WRITE_SEQUENCER_140 0x308C
368#define WM8915_WRITE_SEQUENCER_141 0x308D
369#define WM8915_WRITE_SEQUENCER_142 0x308E
370#define WM8915_WRITE_SEQUENCER_143 0x308F
371#define WM8915_WRITE_SEQUENCER_144 0x3090
372#define WM8915_WRITE_SEQUENCER_145 0x3091
373#define WM8915_WRITE_SEQUENCER_146 0x3092
374#define WM8915_WRITE_SEQUENCER_147 0x3093
375#define WM8915_WRITE_SEQUENCER_148 0x3094
376#define WM8915_WRITE_SEQUENCER_149 0x3095
377#define WM8915_WRITE_SEQUENCER_150 0x3096
378#define WM8915_WRITE_SEQUENCER_151 0x3097
379#define WM8915_WRITE_SEQUENCER_152 0x3098
380#define WM8915_WRITE_SEQUENCER_153 0x3099
381#define WM8915_WRITE_SEQUENCER_154 0x309A
382#define WM8915_WRITE_SEQUENCER_155 0x309B
383#define WM8915_WRITE_SEQUENCER_156 0x309C
384#define WM8915_WRITE_SEQUENCER_157 0x309D
385#define WM8915_WRITE_SEQUENCER_158 0x309E
386#define WM8915_WRITE_SEQUENCER_159 0x309F
387#define WM8915_WRITE_SEQUENCER_160 0x30A0
388#define WM8915_WRITE_SEQUENCER_161 0x30A1
389#define WM8915_WRITE_SEQUENCER_162 0x30A2
390#define WM8915_WRITE_SEQUENCER_163 0x30A3
391#define WM8915_WRITE_SEQUENCER_164 0x30A4
392#define WM8915_WRITE_SEQUENCER_165 0x30A5
393#define WM8915_WRITE_SEQUENCER_166 0x30A6
394#define WM8915_WRITE_SEQUENCER_167 0x30A7
395#define WM8915_WRITE_SEQUENCER_168 0x30A8
396#define WM8915_WRITE_SEQUENCER_169 0x30A9
397#define WM8915_WRITE_SEQUENCER_170 0x30AA
398#define WM8915_WRITE_SEQUENCER_171 0x30AB
399#define WM8915_WRITE_SEQUENCER_172 0x30AC
400#define WM8915_WRITE_SEQUENCER_173 0x30AD
401#define WM8915_WRITE_SEQUENCER_174 0x30AE
402#define WM8915_WRITE_SEQUENCER_175 0x30AF
403#define WM8915_WRITE_SEQUENCER_176 0x30B0
404#define WM8915_WRITE_SEQUENCER_177 0x30B1
405#define WM8915_WRITE_SEQUENCER_178 0x30B2
406#define WM8915_WRITE_SEQUENCER_179 0x30B3
407#define WM8915_WRITE_SEQUENCER_180 0x30B4
408#define WM8915_WRITE_SEQUENCER_181 0x30B5
409#define WM8915_WRITE_SEQUENCER_182 0x30B6
410#define WM8915_WRITE_SEQUENCER_183 0x30B7
411#define WM8915_WRITE_SEQUENCER_184 0x30B8
412#define WM8915_WRITE_SEQUENCER_185 0x30B9
413#define WM8915_WRITE_SEQUENCER_186 0x30BA
414#define WM8915_WRITE_SEQUENCER_187 0x30BB
415#define WM8915_WRITE_SEQUENCER_188 0x30BC
416#define WM8915_WRITE_SEQUENCER_189 0x30BD
417#define WM8915_WRITE_SEQUENCER_190 0x30BE
418#define WM8915_WRITE_SEQUENCER_191 0x30BF
419#define WM8915_WRITE_SEQUENCER_192 0x30C0
420#define WM8915_WRITE_SEQUENCER_193 0x30C1
421#define WM8915_WRITE_SEQUENCER_194 0x30C2
422#define WM8915_WRITE_SEQUENCER_195 0x30C3
423#define WM8915_WRITE_SEQUENCER_196 0x30C4
424#define WM8915_WRITE_SEQUENCER_197 0x30C5
425#define WM8915_WRITE_SEQUENCER_198 0x30C6
426#define WM8915_WRITE_SEQUENCER_199 0x30C7
427#define WM8915_WRITE_SEQUENCER_200 0x30C8
428#define WM8915_WRITE_SEQUENCER_201 0x30C9
429#define WM8915_WRITE_SEQUENCER_202 0x30CA
430#define WM8915_WRITE_SEQUENCER_203 0x30CB
431#define WM8915_WRITE_SEQUENCER_204 0x30CC
432#define WM8915_WRITE_SEQUENCER_205 0x30CD
433#define WM8915_WRITE_SEQUENCER_206 0x30CE
434#define WM8915_WRITE_SEQUENCER_207 0x30CF
435#define WM8915_WRITE_SEQUENCER_208 0x30D0
436#define WM8915_WRITE_SEQUENCER_209 0x30D1
437#define WM8915_WRITE_SEQUENCER_210 0x30D2
438#define WM8915_WRITE_SEQUENCER_211 0x30D3
439#define WM8915_WRITE_SEQUENCER_212 0x30D4
440#define WM8915_WRITE_SEQUENCER_213 0x30D5
441#define WM8915_WRITE_SEQUENCER_214 0x30D6
442#define WM8915_WRITE_SEQUENCER_215 0x30D7
443#define WM8915_WRITE_SEQUENCER_216 0x30D8
444#define WM8915_WRITE_SEQUENCER_217 0x30D9
445#define WM8915_WRITE_SEQUENCER_218 0x30DA
446#define WM8915_WRITE_SEQUENCER_219 0x30DB
447#define WM8915_WRITE_SEQUENCER_220 0x30DC
448#define WM8915_WRITE_SEQUENCER_221 0x30DD
449#define WM8915_WRITE_SEQUENCER_222 0x30DE
450#define WM8915_WRITE_SEQUENCER_223 0x30DF
451#define WM8915_WRITE_SEQUENCER_224 0x30E0
452#define WM8915_WRITE_SEQUENCER_225 0x30E1
453#define WM8915_WRITE_SEQUENCER_226 0x30E2
454#define WM8915_WRITE_SEQUENCER_227 0x30E3
455#define WM8915_WRITE_SEQUENCER_228 0x30E4
456#define WM8915_WRITE_SEQUENCER_229 0x30E5
457#define WM8915_WRITE_SEQUENCER_230 0x30E6
458#define WM8915_WRITE_SEQUENCER_231 0x30E7
459#define WM8915_WRITE_SEQUENCER_232 0x30E8
460#define WM8915_WRITE_SEQUENCER_233 0x30E9
461#define WM8915_WRITE_SEQUENCER_234 0x30EA
462#define WM8915_WRITE_SEQUENCER_235 0x30EB
463#define WM8915_WRITE_SEQUENCER_236 0x30EC
464#define WM8915_WRITE_SEQUENCER_237 0x30ED
465#define WM8915_WRITE_SEQUENCER_238 0x30EE
466#define WM8915_WRITE_SEQUENCER_239 0x30EF
467#define WM8915_WRITE_SEQUENCER_240 0x30F0
468#define WM8915_WRITE_SEQUENCER_241 0x30F1
469#define WM8915_WRITE_SEQUENCER_242 0x30F2
470#define WM8915_WRITE_SEQUENCER_243 0x30F3
471#define WM8915_WRITE_SEQUENCER_244 0x30F4
472#define WM8915_WRITE_SEQUENCER_245 0x30F5
473#define WM8915_WRITE_SEQUENCER_246 0x30F6
474#define WM8915_WRITE_SEQUENCER_247 0x30F7
475#define WM8915_WRITE_SEQUENCER_248 0x30F8
476#define WM8915_WRITE_SEQUENCER_249 0x30F9
477#define WM8915_WRITE_SEQUENCER_250 0x30FA
478#define WM8915_WRITE_SEQUENCER_251 0x30FB
479#define WM8915_WRITE_SEQUENCER_252 0x30FC
480#define WM8915_WRITE_SEQUENCER_253 0x30FD
481#define WM8915_WRITE_SEQUENCER_254 0x30FE
482#define WM8915_WRITE_SEQUENCER_255 0x30FF
483#define WM8915_WRITE_SEQUENCER_256 0x3100
484#define WM8915_WRITE_SEQUENCER_257 0x3101
485#define WM8915_WRITE_SEQUENCER_258 0x3102
486#define WM8915_WRITE_SEQUENCER_259 0x3103
487#define WM8915_WRITE_SEQUENCER_260 0x3104
488#define WM8915_WRITE_SEQUENCER_261 0x3105
489#define WM8915_WRITE_SEQUENCER_262 0x3106
490#define WM8915_WRITE_SEQUENCER_263 0x3107
491#define WM8915_WRITE_SEQUENCER_264 0x3108
492#define WM8915_WRITE_SEQUENCER_265 0x3109
493#define WM8915_WRITE_SEQUENCER_266 0x310A
494#define WM8915_WRITE_SEQUENCER_267 0x310B
495#define WM8915_WRITE_SEQUENCER_268 0x310C
496#define WM8915_WRITE_SEQUENCER_269 0x310D
497#define WM8915_WRITE_SEQUENCER_270 0x310E
498#define WM8915_WRITE_SEQUENCER_271 0x310F
499#define WM8915_WRITE_SEQUENCER_272 0x3110
500#define WM8915_WRITE_SEQUENCER_273 0x3111
501#define WM8915_WRITE_SEQUENCER_274 0x3112
502#define WM8915_WRITE_SEQUENCER_275 0x3113
503#define WM8915_WRITE_SEQUENCER_276 0x3114
504#define WM8915_WRITE_SEQUENCER_277 0x3115
505#define WM8915_WRITE_SEQUENCER_278 0x3116
506#define WM8915_WRITE_SEQUENCER_279 0x3117
507#define WM8915_WRITE_SEQUENCER_280 0x3118
508#define WM8915_WRITE_SEQUENCER_281 0x3119
509#define WM8915_WRITE_SEQUENCER_282 0x311A
510#define WM8915_WRITE_SEQUENCER_283 0x311B
511#define WM8915_WRITE_SEQUENCER_284 0x311C
512#define WM8915_WRITE_SEQUENCER_285 0x311D
513#define WM8915_WRITE_SEQUENCER_286 0x311E
514#define WM8915_WRITE_SEQUENCER_287 0x311F
515#define WM8915_WRITE_SEQUENCER_288 0x3120
516#define WM8915_WRITE_SEQUENCER_289 0x3121
517#define WM8915_WRITE_SEQUENCER_290 0x3122
518#define WM8915_WRITE_SEQUENCER_291 0x3123
519#define WM8915_WRITE_SEQUENCER_292 0x3124
520#define WM8915_WRITE_SEQUENCER_293 0x3125
521#define WM8915_WRITE_SEQUENCER_294 0x3126
522#define WM8915_WRITE_SEQUENCER_295 0x3127
523#define WM8915_WRITE_SEQUENCER_296 0x3128
524#define WM8915_WRITE_SEQUENCER_297 0x3129
525#define WM8915_WRITE_SEQUENCER_298 0x312A
526#define WM8915_WRITE_SEQUENCER_299 0x312B
527#define WM8915_WRITE_SEQUENCER_300 0x312C
528#define WM8915_WRITE_SEQUENCER_301 0x312D
529#define WM8915_WRITE_SEQUENCER_302 0x312E
530#define WM8915_WRITE_SEQUENCER_303 0x312F
531#define WM8915_WRITE_SEQUENCER_304 0x3130
532#define WM8915_WRITE_SEQUENCER_305 0x3131
533#define WM8915_WRITE_SEQUENCER_306 0x3132
534#define WM8915_WRITE_SEQUENCER_307 0x3133
535#define WM8915_WRITE_SEQUENCER_308 0x3134
536#define WM8915_WRITE_SEQUENCER_309 0x3135
537#define WM8915_WRITE_SEQUENCER_310 0x3136
538#define WM8915_WRITE_SEQUENCER_311 0x3137
539#define WM8915_WRITE_SEQUENCER_312 0x3138
540#define WM8915_WRITE_SEQUENCER_313 0x3139
541#define WM8915_WRITE_SEQUENCER_314 0x313A
542#define WM8915_WRITE_SEQUENCER_315 0x313B
543#define WM8915_WRITE_SEQUENCER_316 0x313C
544#define WM8915_WRITE_SEQUENCER_317 0x313D
545#define WM8915_WRITE_SEQUENCER_318 0x313E
546#define WM8915_WRITE_SEQUENCER_319 0x313F
547#define WM8915_WRITE_SEQUENCER_320 0x3140
548#define WM8915_WRITE_SEQUENCER_321 0x3141
549#define WM8915_WRITE_SEQUENCER_322 0x3142
550#define WM8915_WRITE_SEQUENCER_323 0x3143
551#define WM8915_WRITE_SEQUENCER_324 0x3144
552#define WM8915_WRITE_SEQUENCER_325 0x3145
553#define WM8915_WRITE_SEQUENCER_326 0x3146
554#define WM8915_WRITE_SEQUENCER_327 0x3147
555#define WM8915_WRITE_SEQUENCER_328 0x3148
556#define WM8915_WRITE_SEQUENCER_329 0x3149
557#define WM8915_WRITE_SEQUENCER_330 0x314A
558#define WM8915_WRITE_SEQUENCER_331 0x314B
559#define WM8915_WRITE_SEQUENCER_332 0x314C
560#define WM8915_WRITE_SEQUENCER_333 0x314D
561#define WM8915_WRITE_SEQUENCER_334 0x314E
562#define WM8915_WRITE_SEQUENCER_335 0x314F
563#define WM8915_WRITE_SEQUENCER_336 0x3150
564#define WM8915_WRITE_SEQUENCER_337 0x3151
565#define WM8915_WRITE_SEQUENCER_338 0x3152
566#define WM8915_WRITE_SEQUENCER_339 0x3153
567#define WM8915_WRITE_SEQUENCER_340 0x3154
568#define WM8915_WRITE_SEQUENCER_341 0x3155
569#define WM8915_WRITE_SEQUENCER_342 0x3156
570#define WM8915_WRITE_SEQUENCER_343 0x3157
571#define WM8915_WRITE_SEQUENCER_344 0x3158
572#define WM8915_WRITE_SEQUENCER_345 0x3159
573#define WM8915_WRITE_SEQUENCER_346 0x315A
574#define WM8915_WRITE_SEQUENCER_347 0x315B
575#define WM8915_WRITE_SEQUENCER_348 0x315C
576#define WM8915_WRITE_SEQUENCER_349 0x315D
577#define WM8915_WRITE_SEQUENCER_350 0x315E
578#define WM8915_WRITE_SEQUENCER_351 0x315F
579#define WM8915_WRITE_SEQUENCER_352 0x3160
580#define WM8915_WRITE_SEQUENCER_353 0x3161
581#define WM8915_WRITE_SEQUENCER_354 0x3162
582#define WM8915_WRITE_SEQUENCER_355 0x3163
583#define WM8915_WRITE_SEQUENCER_356 0x3164
584#define WM8915_WRITE_SEQUENCER_357 0x3165
585#define WM8915_WRITE_SEQUENCER_358 0x3166
586#define WM8915_WRITE_SEQUENCER_359 0x3167
587#define WM8915_WRITE_SEQUENCER_360 0x3168
588#define WM8915_WRITE_SEQUENCER_361 0x3169
589#define WM8915_WRITE_SEQUENCER_362 0x316A
590#define WM8915_WRITE_SEQUENCER_363 0x316B
591#define WM8915_WRITE_SEQUENCER_364 0x316C
592#define WM8915_WRITE_SEQUENCER_365 0x316D
593#define WM8915_WRITE_SEQUENCER_366 0x316E
594#define WM8915_WRITE_SEQUENCER_367 0x316F
595#define WM8915_WRITE_SEQUENCER_368 0x3170
596#define WM8915_WRITE_SEQUENCER_369 0x3171
597#define WM8915_WRITE_SEQUENCER_370 0x3172
598#define WM8915_WRITE_SEQUENCER_371 0x3173
599#define WM8915_WRITE_SEQUENCER_372 0x3174
600#define WM8915_WRITE_SEQUENCER_373 0x3175
601#define WM8915_WRITE_SEQUENCER_374 0x3176
602#define WM8915_WRITE_SEQUENCER_375 0x3177
603#define WM8915_WRITE_SEQUENCER_376 0x3178
604#define WM8915_WRITE_SEQUENCER_377 0x3179
605#define WM8915_WRITE_SEQUENCER_378 0x317A
606#define WM8915_WRITE_SEQUENCER_379 0x317B
607#define WM8915_WRITE_SEQUENCER_380 0x317C
608#define WM8915_WRITE_SEQUENCER_381 0x317D
609#define WM8915_WRITE_SEQUENCER_382 0x317E
610#define WM8915_WRITE_SEQUENCER_383 0x317F
611#define WM8915_WRITE_SEQUENCER_384 0x3180
612#define WM8915_WRITE_SEQUENCER_385 0x3181
613#define WM8915_WRITE_SEQUENCER_386 0x3182
614#define WM8915_WRITE_SEQUENCER_387 0x3183
615#define WM8915_WRITE_SEQUENCER_388 0x3184
616#define WM8915_WRITE_SEQUENCER_389 0x3185
617#define WM8915_WRITE_SEQUENCER_390 0x3186
618#define WM8915_WRITE_SEQUENCER_391 0x3187
619#define WM8915_WRITE_SEQUENCER_392 0x3188
620#define WM8915_WRITE_SEQUENCER_393 0x3189
621#define WM8915_WRITE_SEQUENCER_394 0x318A
622#define WM8915_WRITE_SEQUENCER_395 0x318B
623#define WM8915_WRITE_SEQUENCER_396 0x318C
624#define WM8915_WRITE_SEQUENCER_397 0x318D
625#define WM8915_WRITE_SEQUENCER_398 0x318E
626#define WM8915_WRITE_SEQUENCER_399 0x318F
627#define WM8915_WRITE_SEQUENCER_400 0x3190
628#define WM8915_WRITE_SEQUENCER_401 0x3191
629#define WM8915_WRITE_SEQUENCER_402 0x3192
630#define WM8915_WRITE_SEQUENCER_403 0x3193
631#define WM8915_WRITE_SEQUENCER_404 0x3194
632#define WM8915_WRITE_SEQUENCER_405 0x3195
633#define WM8915_WRITE_SEQUENCER_406 0x3196
634#define WM8915_WRITE_SEQUENCER_407 0x3197
635#define WM8915_WRITE_SEQUENCER_408 0x3198
636#define WM8915_WRITE_SEQUENCER_409 0x3199
637#define WM8915_WRITE_SEQUENCER_410 0x319A
638#define WM8915_WRITE_SEQUENCER_411 0x319B
639#define WM8915_WRITE_SEQUENCER_412 0x319C
640#define WM8915_WRITE_SEQUENCER_413 0x319D
641#define WM8915_WRITE_SEQUENCER_414 0x319E
642#define WM8915_WRITE_SEQUENCER_415 0x319F
643#define WM8915_WRITE_SEQUENCER_416 0x31A0
644#define WM8915_WRITE_SEQUENCER_417 0x31A1
645#define WM8915_WRITE_SEQUENCER_418 0x31A2
646#define WM8915_WRITE_SEQUENCER_419 0x31A3
647#define WM8915_WRITE_SEQUENCER_420 0x31A4
648#define WM8915_WRITE_SEQUENCER_421 0x31A5
649#define WM8915_WRITE_SEQUENCER_422 0x31A6
650#define WM8915_WRITE_SEQUENCER_423 0x31A7
651#define WM8915_WRITE_SEQUENCER_424 0x31A8
652#define WM8915_WRITE_SEQUENCER_425 0x31A9
653#define WM8915_WRITE_SEQUENCER_426 0x31AA
654#define WM8915_WRITE_SEQUENCER_427 0x31AB
655#define WM8915_WRITE_SEQUENCER_428 0x31AC
656#define WM8915_WRITE_SEQUENCER_429 0x31AD
657#define WM8915_WRITE_SEQUENCER_430 0x31AE
658#define WM8915_WRITE_SEQUENCER_431 0x31AF
659#define WM8915_WRITE_SEQUENCER_432 0x31B0
660#define WM8915_WRITE_SEQUENCER_433 0x31B1
661#define WM8915_WRITE_SEQUENCER_434 0x31B2
662#define WM8915_WRITE_SEQUENCER_435 0x31B3
663#define WM8915_WRITE_SEQUENCER_436 0x31B4
664#define WM8915_WRITE_SEQUENCER_437 0x31B5
665#define WM8915_WRITE_SEQUENCER_438 0x31B6
666#define WM8915_WRITE_SEQUENCER_439 0x31B7
667#define WM8915_WRITE_SEQUENCER_440 0x31B8
668#define WM8915_WRITE_SEQUENCER_441 0x31B9
669#define WM8915_WRITE_SEQUENCER_442 0x31BA
670#define WM8915_WRITE_SEQUENCER_443 0x31BB
671#define WM8915_WRITE_SEQUENCER_444 0x31BC
672#define WM8915_WRITE_SEQUENCER_445 0x31BD
673#define WM8915_WRITE_SEQUENCER_446 0x31BE
674#define WM8915_WRITE_SEQUENCER_447 0x31BF
675#define WM8915_WRITE_SEQUENCER_448 0x31C0
676#define WM8915_WRITE_SEQUENCER_449 0x31C1
677#define WM8915_WRITE_SEQUENCER_450 0x31C2
678#define WM8915_WRITE_SEQUENCER_451 0x31C3
679#define WM8915_WRITE_SEQUENCER_452 0x31C4
680#define WM8915_WRITE_SEQUENCER_453 0x31C5
681#define WM8915_WRITE_SEQUENCER_454 0x31C6
682#define WM8915_WRITE_SEQUENCER_455 0x31C7
683#define WM8915_WRITE_SEQUENCER_456 0x31C8
684#define WM8915_WRITE_SEQUENCER_457 0x31C9
685#define WM8915_WRITE_SEQUENCER_458 0x31CA
686#define WM8915_WRITE_SEQUENCER_459 0x31CB
687#define WM8915_WRITE_SEQUENCER_460 0x31CC
688#define WM8915_WRITE_SEQUENCER_461 0x31CD
689#define WM8915_WRITE_SEQUENCER_462 0x31CE
690#define WM8915_WRITE_SEQUENCER_463 0x31CF
691#define WM8915_WRITE_SEQUENCER_464 0x31D0
692#define WM8915_WRITE_SEQUENCER_465 0x31D1
693#define WM8915_WRITE_SEQUENCER_466 0x31D2
694#define WM8915_WRITE_SEQUENCER_467 0x31D3
695#define WM8915_WRITE_SEQUENCER_468 0x31D4
696#define WM8915_WRITE_SEQUENCER_469 0x31D5
697#define WM8915_WRITE_SEQUENCER_470 0x31D6
698#define WM8915_WRITE_SEQUENCER_471 0x31D7
699#define WM8915_WRITE_SEQUENCER_472 0x31D8
700#define WM8915_WRITE_SEQUENCER_473 0x31D9
701#define WM8915_WRITE_SEQUENCER_474 0x31DA
702#define WM8915_WRITE_SEQUENCER_475 0x31DB
703#define WM8915_WRITE_SEQUENCER_476 0x31DC
704#define WM8915_WRITE_SEQUENCER_477 0x31DD
705#define WM8915_WRITE_SEQUENCER_478 0x31DE
706#define WM8915_WRITE_SEQUENCER_479 0x31DF
707#define WM8915_WRITE_SEQUENCER_480 0x31E0
708#define WM8915_WRITE_SEQUENCER_481 0x31E1
709#define WM8915_WRITE_SEQUENCER_482 0x31E2
710#define WM8915_WRITE_SEQUENCER_483 0x31E3
711#define WM8915_WRITE_SEQUENCER_484 0x31E4
712#define WM8915_WRITE_SEQUENCER_485 0x31E5
713#define WM8915_WRITE_SEQUENCER_486 0x31E6
714#define WM8915_WRITE_SEQUENCER_487 0x31E7
715#define WM8915_WRITE_SEQUENCER_488 0x31E8
716#define WM8915_WRITE_SEQUENCER_489 0x31E9
717#define WM8915_WRITE_SEQUENCER_490 0x31EA
718#define WM8915_WRITE_SEQUENCER_491 0x31EB
719#define WM8915_WRITE_SEQUENCER_492 0x31EC
720#define WM8915_WRITE_SEQUENCER_493 0x31ED
721#define WM8915_WRITE_SEQUENCER_494 0x31EE
722#define WM8915_WRITE_SEQUENCER_495 0x31EF
723#define WM8915_WRITE_SEQUENCER_496 0x31F0
724#define WM8915_WRITE_SEQUENCER_497 0x31F1
725#define WM8915_WRITE_SEQUENCER_498 0x31F2
726#define WM8915_WRITE_SEQUENCER_499 0x31F3
727#define WM8915_WRITE_SEQUENCER_500 0x31F4
728#define WM8915_WRITE_SEQUENCER_501 0x31F5
729#define WM8915_WRITE_SEQUENCER_502 0x31F6
730#define WM8915_WRITE_SEQUENCER_503 0x31F7
731#define WM8915_WRITE_SEQUENCER_504 0x31F8
732#define WM8915_WRITE_SEQUENCER_505 0x31F9
733#define WM8915_WRITE_SEQUENCER_506 0x31FA
734#define WM8915_WRITE_SEQUENCER_507 0x31FB
735#define WM8915_WRITE_SEQUENCER_508 0x31FC
736#define WM8915_WRITE_SEQUENCER_509 0x31FD
737#define WM8915_WRITE_SEQUENCER_510 0x31FE
738#define WM8915_WRITE_SEQUENCER_511 0x31FF
739
740#define WM8915_REGISTER_COUNT 706
741#define WM8915_MAX_REGISTER 0x31FF
742
743/*
744 * Field Definitions.
745 */
746
747/*
748 * R0 (0x00) - Software Reset
749 */
750#define WM8915_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
751#define WM8915_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
752#define WM8915_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
753
754/*
755 * R1 (0x01) - Power Management (1)
756 */
757#define WM8915_MICB2_ENA 0x0200 /* MICB2_ENA */
758#define WM8915_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */
759#define WM8915_MICB2_ENA_SHIFT 9 /* MICB2_ENA */
760#define WM8915_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
761#define WM8915_MICB1_ENA 0x0100 /* MICB1_ENA */
762#define WM8915_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */
763#define WM8915_MICB1_ENA_SHIFT 8 /* MICB1_ENA */
764#define WM8915_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
765#define WM8915_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */
766#define WM8915_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */
767#define WM8915_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */
768#define WM8915_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */
769#define WM8915_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */
770#define WM8915_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */
771#define WM8915_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */
772#define WM8915_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */
773#define WM8915_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */
774#define WM8915_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */
775#define WM8915_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */
776#define WM8915_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
777#define WM8915_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */
778#define WM8915_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */
779#define WM8915_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */
780#define WM8915_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
781#define WM8915_BG_ENA 0x0001 /* BG_ENA */
782#define WM8915_BG_ENA_MASK 0x0001 /* BG_ENA */
783#define WM8915_BG_ENA_SHIFT 0 /* BG_ENA */
784#define WM8915_BG_ENA_WIDTH 1 /* BG_ENA */
785
786/*
787 * R2 (0x02) - Power Management (2)
788 */
789#define WM8915_OPCLK_ENA 0x0800 /* OPCLK_ENA */
790#define WM8915_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
791#define WM8915_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
792#define WM8915_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
793#define WM8915_INL_ENA 0x0020 /* INL_ENA */
794#define WM8915_INL_ENA_MASK 0x0020 /* INL_ENA */
795#define WM8915_INL_ENA_SHIFT 5 /* INL_ENA */
796#define WM8915_INL_ENA_WIDTH 1 /* INL_ENA */
797#define WM8915_INR_ENA 0x0010 /* INR_ENA */
798#define WM8915_INR_ENA_MASK 0x0010 /* INR_ENA */
799#define WM8915_INR_ENA_SHIFT 4 /* INR_ENA */
800#define WM8915_INR_ENA_WIDTH 1 /* INR_ENA */
801#define WM8915_LDO2_ENA 0x0002 /* LDO2_ENA */
802#define WM8915_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */
803#define WM8915_LDO2_ENA_SHIFT 1 /* LDO2_ENA */
804#define WM8915_LDO2_ENA_WIDTH 1 /* LDO2_ENA */
805
806/*
807 * R3 (0x03) - Power Management (3)
808 */
809#define WM8915_DSP2RXL_ENA 0x0800 /* DSP2RXL_ENA */
810#define WM8915_DSP2RXL_ENA_MASK 0x0800 /* DSP2RXL_ENA */
811#define WM8915_DSP2RXL_ENA_SHIFT 11 /* DSP2RXL_ENA */
812#define WM8915_DSP2RXL_ENA_WIDTH 1 /* DSP2RXL_ENA */
813#define WM8915_DSP2RXR_ENA 0x0400 /* DSP2RXR_ENA */
814#define WM8915_DSP2RXR_ENA_MASK 0x0400 /* DSP2RXR_ENA */
815#define WM8915_DSP2RXR_ENA_SHIFT 10 /* DSP2RXR_ENA */
816#define WM8915_DSP2RXR_ENA_WIDTH 1 /* DSP2RXR_ENA */
817#define WM8915_DSP1RXL_ENA 0x0200 /* DSP1RXL_ENA */
818#define WM8915_DSP1RXL_ENA_MASK 0x0200 /* DSP1RXL_ENA */
819#define WM8915_DSP1RXL_ENA_SHIFT 9 /* DSP1RXL_ENA */
820#define WM8915_DSP1RXL_ENA_WIDTH 1 /* DSP1RXL_ENA */
821#define WM8915_DSP1RXR_ENA 0x0100 /* DSP1RXR_ENA */
822#define WM8915_DSP1RXR_ENA_MASK 0x0100 /* DSP1RXR_ENA */
823#define WM8915_DSP1RXR_ENA_SHIFT 8 /* DSP1RXR_ENA */
824#define WM8915_DSP1RXR_ENA_WIDTH 1 /* DSP1RXR_ENA */
825#define WM8915_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */
826#define WM8915_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */
827#define WM8915_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */
828#define WM8915_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */
829#define WM8915_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */
830#define WM8915_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */
831#define WM8915_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */
832#define WM8915_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */
833#define WM8915_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */
834#define WM8915_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */
835#define WM8915_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */
836#define WM8915_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */
837#define WM8915_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */
838#define WM8915_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */
839#define WM8915_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */
840#define WM8915_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */
841#define WM8915_ADCL_ENA 0x0002 /* ADCL_ENA */
842#define WM8915_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
843#define WM8915_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
844#define WM8915_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
845#define WM8915_ADCR_ENA 0x0001 /* ADCR_ENA */
846#define WM8915_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
847#define WM8915_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
848#define WM8915_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
849
850/*
851 * R4 (0x04) - Power Management (4)
852 */
853#define WM8915_AIF2RX_CHAN1_ENA 0x0200 /* AIF2RX_CHAN1_ENA */
854#define WM8915_AIF2RX_CHAN1_ENA_MASK 0x0200 /* AIF2RX_CHAN1_ENA */
855#define WM8915_AIF2RX_CHAN1_ENA_SHIFT 9 /* AIF2RX_CHAN1_ENA */
856#define WM8915_AIF2RX_CHAN1_ENA_WIDTH 1 /* AIF2RX_CHAN1_ENA */
857#define WM8915_AIF2RX_CHAN0_ENA 0x0100 /* AIF2RX_CHAN0_ENA */
858#define WM8915_AIF2RX_CHAN0_ENA_MASK 0x0100 /* AIF2RX_CHAN0_ENA */
859#define WM8915_AIF2RX_CHAN0_ENA_SHIFT 8 /* AIF2RX_CHAN0_ENA */
860#define WM8915_AIF2RX_CHAN0_ENA_WIDTH 1 /* AIF2RX_CHAN0_ENA */
861#define WM8915_AIF1RX_CHAN5_ENA 0x0020 /* AIF1RX_CHAN5_ENA */
862#define WM8915_AIF1RX_CHAN5_ENA_MASK 0x0020 /* AIF1RX_CHAN5_ENA */
863#define WM8915_AIF1RX_CHAN5_ENA_SHIFT 5 /* AIF1RX_CHAN5_ENA */
864#define WM8915_AIF1RX_CHAN5_ENA_WIDTH 1 /* AIF1RX_CHAN5_ENA */
865#define WM8915_AIF1RX_CHAN4_ENA 0x0010 /* AIF1RX_CHAN4_ENA */
866#define WM8915_AIF1RX_CHAN4_ENA_MASK 0x0010 /* AIF1RX_CHAN4_ENA */
867#define WM8915_AIF1RX_CHAN4_ENA_SHIFT 4 /* AIF1RX_CHAN4_ENA */
868#define WM8915_AIF1RX_CHAN4_ENA_WIDTH 1 /* AIF1RX_CHAN4_ENA */
869#define WM8915_AIF1RX_CHAN3_ENA 0x0008 /* AIF1RX_CHAN3_ENA */
870#define WM8915_AIF1RX_CHAN3_ENA_MASK 0x0008 /* AIF1RX_CHAN3_ENA */
871#define WM8915_AIF1RX_CHAN3_ENA_SHIFT 3 /* AIF1RX_CHAN3_ENA */
872#define WM8915_AIF1RX_CHAN3_ENA_WIDTH 1 /* AIF1RX_CHAN3_ENA */
873#define WM8915_AIF1RX_CHAN2_ENA 0x0004 /* AIF1RX_CHAN2_ENA */
874#define WM8915_AIF1RX_CHAN2_ENA_MASK 0x0004 /* AIF1RX_CHAN2_ENA */
875#define WM8915_AIF1RX_CHAN2_ENA_SHIFT 2 /* AIF1RX_CHAN2_ENA */
876#define WM8915_AIF1RX_CHAN2_ENA_WIDTH 1 /* AIF1RX_CHAN2_ENA */
877#define WM8915_AIF1RX_CHAN1_ENA 0x0002 /* AIF1RX_CHAN1_ENA */
878#define WM8915_AIF1RX_CHAN1_ENA_MASK 0x0002 /* AIF1RX_CHAN1_ENA */
879#define WM8915_AIF1RX_CHAN1_ENA_SHIFT 1 /* AIF1RX_CHAN1_ENA */
880#define WM8915_AIF1RX_CHAN1_ENA_WIDTH 1 /* AIF1RX_CHAN1_ENA */
881#define WM8915_AIF1RX_CHAN0_ENA 0x0001 /* AIF1RX_CHAN0_ENA */
882#define WM8915_AIF1RX_CHAN0_ENA_MASK 0x0001 /* AIF1RX_CHAN0_ENA */
883#define WM8915_AIF1RX_CHAN0_ENA_SHIFT 0 /* AIF1RX_CHAN0_ENA */
884#define WM8915_AIF1RX_CHAN0_ENA_WIDTH 1 /* AIF1RX_CHAN0_ENA */
885
886/*
887 * R5 (0x05) - Power Management (5)
888 */
889#define WM8915_DSP2TXL_ENA 0x0800 /* DSP2TXL_ENA */
890#define WM8915_DSP2TXL_ENA_MASK 0x0800 /* DSP2TXL_ENA */
891#define WM8915_DSP2TXL_ENA_SHIFT 11 /* DSP2TXL_ENA */
892#define WM8915_DSP2TXL_ENA_WIDTH 1 /* DSP2TXL_ENA */
893#define WM8915_DSP2TXR_ENA 0x0400 /* DSP2TXR_ENA */
894#define WM8915_DSP2TXR_ENA_MASK 0x0400 /* DSP2TXR_ENA */
895#define WM8915_DSP2TXR_ENA_SHIFT 10 /* DSP2TXR_ENA */
896#define WM8915_DSP2TXR_ENA_WIDTH 1 /* DSP2TXR_ENA */
897#define WM8915_DSP1TXL_ENA 0x0200 /* DSP1TXL_ENA */
898#define WM8915_DSP1TXL_ENA_MASK 0x0200 /* DSP1TXL_ENA */
899#define WM8915_DSP1TXL_ENA_SHIFT 9 /* DSP1TXL_ENA */
900#define WM8915_DSP1TXL_ENA_WIDTH 1 /* DSP1TXL_ENA */
901#define WM8915_DSP1TXR_ENA 0x0100 /* DSP1TXR_ENA */
902#define WM8915_DSP1TXR_ENA_MASK 0x0100 /* DSP1TXR_ENA */
903#define WM8915_DSP1TXR_ENA_SHIFT 8 /* DSP1TXR_ENA */
904#define WM8915_DSP1TXR_ENA_WIDTH 1 /* DSP1TXR_ENA */
905#define WM8915_DAC2L_ENA 0x0008 /* DAC2L_ENA */
906#define WM8915_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */
907#define WM8915_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */
908#define WM8915_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */
909#define WM8915_DAC2R_ENA 0x0004 /* DAC2R_ENA */
910#define WM8915_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */
911#define WM8915_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */
912#define WM8915_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */
913#define WM8915_DAC1L_ENA 0x0002 /* DAC1L_ENA */
914#define WM8915_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */
915#define WM8915_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */
916#define WM8915_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */
917#define WM8915_DAC1R_ENA 0x0001 /* DAC1R_ENA */
918#define WM8915_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */
919#define WM8915_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */
920#define WM8915_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */
921
922/*
923 * R6 (0x06) - Power Management (6)
924 */
925#define WM8915_AIF2TX_CHAN1_ENA 0x0200 /* AIF2TX_CHAN1_ENA */
926#define WM8915_AIF2TX_CHAN1_ENA_MASK 0x0200 /* AIF2TX_CHAN1_ENA */
927#define WM8915_AIF2TX_CHAN1_ENA_SHIFT 9 /* AIF2TX_CHAN1_ENA */
928#define WM8915_AIF2TX_CHAN1_ENA_WIDTH 1 /* AIF2TX_CHAN1_ENA */
929#define WM8915_AIF2TX_CHAN0_ENA 0x0100 /* AIF2TX_CHAN0_ENA */
930#define WM8915_AIF2TX_CHAN0_ENA_MASK 0x0100 /* AIF2TX_CHAN0_ENA */
931#define WM8915_AIF2TX_CHAN0_ENA_SHIFT 8 /* AIF2TX_CHAN0_ENA */
932#define WM8915_AIF2TX_CHAN0_ENA_WIDTH 1 /* AIF2TX_CHAN0_ENA */
933#define WM8915_AIF1TX_CHAN5_ENA 0x0020 /* AIF1TX_CHAN5_ENA */
934#define WM8915_AIF1TX_CHAN5_ENA_MASK 0x0020 /* AIF1TX_CHAN5_ENA */
935#define WM8915_AIF1TX_CHAN5_ENA_SHIFT 5 /* AIF1TX_CHAN5_ENA */
936#define WM8915_AIF1TX_CHAN5_ENA_WIDTH 1 /* AIF1TX_CHAN5_ENA */
937#define WM8915_AIF1TX_CHAN4_ENA 0x0010 /* AIF1TX_CHAN4_ENA */
938#define WM8915_AIF1TX_CHAN4_ENA_MASK 0x0010 /* AIF1TX_CHAN4_ENA */
939#define WM8915_AIF1TX_CHAN4_ENA_SHIFT 4 /* AIF1TX_CHAN4_ENA */
940#define WM8915_AIF1TX_CHAN4_ENA_WIDTH 1 /* AIF1TX_CHAN4_ENA */
941#define WM8915_AIF1TX_CHAN3_ENA 0x0008 /* AIF1TX_CHAN3_ENA */
942#define WM8915_AIF1TX_CHAN3_ENA_MASK 0x0008 /* AIF1TX_CHAN3_ENA */
943#define WM8915_AIF1TX_CHAN3_ENA_SHIFT 3 /* AIF1TX_CHAN3_ENA */
944#define WM8915_AIF1TX_CHAN3_ENA_WIDTH 1 /* AIF1TX_CHAN3_ENA */
945#define WM8915_AIF1TX_CHAN2_ENA 0x0004 /* AIF1TX_CHAN2_ENA */
946#define WM8915_AIF1TX_CHAN2_ENA_MASK 0x0004 /* AIF1TX_CHAN2_ENA */
947#define WM8915_AIF1TX_CHAN2_ENA_SHIFT 2 /* AIF1TX_CHAN2_ENA */
948#define WM8915_AIF1TX_CHAN2_ENA_WIDTH 1 /* AIF1TX_CHAN2_ENA */
949#define WM8915_AIF1TX_CHAN1_ENA 0x0002 /* AIF1TX_CHAN1_ENA */
950#define WM8915_AIF1TX_CHAN1_ENA_MASK 0x0002 /* AIF1TX_CHAN1_ENA */
951#define WM8915_AIF1TX_CHAN1_ENA_SHIFT 1 /* AIF1TX_CHAN1_ENA */
952#define WM8915_AIF1TX_CHAN1_ENA_WIDTH 1 /* AIF1TX_CHAN1_ENA */
953#define WM8915_AIF1TX_CHAN0_ENA 0x0001 /* AIF1TX_CHAN0_ENA */
954#define WM8915_AIF1TX_CHAN0_ENA_MASK 0x0001 /* AIF1TX_CHAN0_ENA */
955#define WM8915_AIF1TX_CHAN0_ENA_SHIFT 0 /* AIF1TX_CHAN0_ENA */
956#define WM8915_AIF1TX_CHAN0_ENA_WIDTH 1 /* AIF1TX_CHAN0_ENA */
957
958/*
959 * R7 (0x07) - Power Management (7)
960 */
961#define WM8915_DMIC2_FN 0x0200 /* DMIC2_FN */
962#define WM8915_DMIC2_FN_MASK 0x0200 /* DMIC2_FN */
963#define WM8915_DMIC2_FN_SHIFT 9 /* DMIC2_FN */
964#define WM8915_DMIC2_FN_WIDTH 1 /* DMIC2_FN */
965#define WM8915_DMIC1_FN 0x0100 /* DMIC1_FN */
966#define WM8915_DMIC1_FN_MASK 0x0100 /* DMIC1_FN */
967#define WM8915_DMIC1_FN_SHIFT 8 /* DMIC1_FN */
968#define WM8915_DMIC1_FN_WIDTH 1 /* DMIC1_FN */
969#define WM8915_ADC_DMIC_DSP2R_ENA 0x0080 /* ADC_DMIC_DSP2R_ENA */
970#define WM8915_ADC_DMIC_DSP2R_ENA_MASK 0x0080 /* ADC_DMIC_DSP2R_ENA */
971#define WM8915_ADC_DMIC_DSP2R_ENA_SHIFT 7 /* ADC_DMIC_DSP2R_ENA */
972#define WM8915_ADC_DMIC_DSP2R_ENA_WIDTH 1 /* ADC_DMIC_DSP2R_ENA */
973#define WM8915_ADC_DMIC_DSP2L_ENA 0x0040 /* ADC_DMIC_DSP2L_ENA */
974#define WM8915_ADC_DMIC_DSP2L_ENA_MASK 0x0040 /* ADC_DMIC_DSP2L_ENA */
975#define WM8915_ADC_DMIC_DSP2L_ENA_SHIFT 6 /* ADC_DMIC_DSP2L_ENA */
976#define WM8915_ADC_DMIC_DSP2L_ENA_WIDTH 1 /* ADC_DMIC_DSP2L_ENA */
977#define WM8915_ADC_DMIC_SRC2_MASK 0x0030 /* ADC_DMIC_SRC2 - [5:4] */
978#define WM8915_ADC_DMIC_SRC2_SHIFT 4 /* ADC_DMIC_SRC2 - [5:4] */
979#define WM8915_ADC_DMIC_SRC2_WIDTH 2 /* ADC_DMIC_SRC2 - [5:4] */
980#define WM8915_ADC_DMIC_DSP1R_ENA 0x0008 /* ADC_DMIC_DSP1R_ENA */
981#define WM8915_ADC_DMIC_DSP1R_ENA_MASK 0x0008 /* ADC_DMIC_DSP1R_ENA */
982#define WM8915_ADC_DMIC_DSP1R_ENA_SHIFT 3 /* ADC_DMIC_DSP1R_ENA */
983#define WM8915_ADC_DMIC_DSP1R_ENA_WIDTH 1 /* ADC_DMIC_DSP1R_ENA */
984#define WM8915_ADC_DMIC_DSP1L_ENA 0x0004 /* ADC_DMIC_DSP1L_ENA */
985#define WM8915_ADC_DMIC_DSP1L_ENA_MASK 0x0004 /* ADC_DMIC_DSP1L_ENA */
986#define WM8915_ADC_DMIC_DSP1L_ENA_SHIFT 2 /* ADC_DMIC_DSP1L_ENA */
987#define WM8915_ADC_DMIC_DSP1L_ENA_WIDTH 1 /* ADC_DMIC_DSP1L_ENA */
988#define WM8915_ADC_DMIC_SRC1_MASK 0x0003 /* ADC_DMIC_SRC1 - [1:0] */
989#define WM8915_ADC_DMIC_SRC1_SHIFT 0 /* ADC_DMIC_SRC1 - [1:0] */
990#define WM8915_ADC_DMIC_SRC1_WIDTH 2 /* ADC_DMIC_SRC1 - [1:0] */
991
992/*
993 * R8 (0x08) - Power Management (8)
994 */
995#define WM8915_AIF2TX_SRC_MASK 0x00C0 /* AIF2TX_SRC - [7:6] */
996#define WM8915_AIF2TX_SRC_SHIFT 6 /* AIF2TX_SRC - [7:6] */
997#define WM8915_AIF2TX_SRC_WIDTH 2 /* AIF2TX_SRC - [7:6] */
998#define WM8915_DSP2RX_SRC 0x0010 /* DSP2RX_SRC */
999#define WM8915_DSP2RX_SRC_MASK 0x0010 /* DSP2RX_SRC */
1000#define WM8915_DSP2RX_SRC_SHIFT 4 /* DSP2RX_SRC */
1001#define WM8915_DSP2RX_SRC_WIDTH 1 /* DSP2RX_SRC */
1002#define WM8915_DSP1RX_SRC 0x0001 /* DSP1RX_SRC */
1003#define WM8915_DSP1RX_SRC_MASK 0x0001 /* DSP1RX_SRC */
1004#define WM8915_DSP1RX_SRC_SHIFT 0 /* DSP1RX_SRC */
1005#define WM8915_DSP1RX_SRC_WIDTH 1 /* DSP1RX_SRC */
1006
1007/*
1008 * R16 (0x10) - Left Line Input Volume
1009 */
1010#define WM8915_IN1_VU 0x0080 /* IN1_VU */
1011#define WM8915_IN1_VU_MASK 0x0080 /* IN1_VU */
1012#define WM8915_IN1_VU_SHIFT 7 /* IN1_VU */
1013#define WM8915_IN1_VU_WIDTH 1 /* IN1_VU */
1014#define WM8915_IN1L_ZC 0x0020 /* IN1L_ZC */
1015#define WM8915_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */
1016#define WM8915_IN1L_ZC_SHIFT 5 /* IN1L_ZC */
1017#define WM8915_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
1018#define WM8915_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
1019#define WM8915_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
1020#define WM8915_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
1021
1022/*
1023 * R17 (0x11) - Right Line Input Volume
1024 */
1025#define WM8915_IN1_VU 0x0080 /* IN1_VU */
1026#define WM8915_IN1_VU_MASK 0x0080 /* IN1_VU */
1027#define WM8915_IN1_VU_SHIFT 7 /* IN1_VU */
1028#define WM8915_IN1_VU_WIDTH 1 /* IN1_VU */
1029#define WM8915_IN1R_ZC 0x0020 /* IN1R_ZC */
1030#define WM8915_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */
1031#define WM8915_IN1R_ZC_SHIFT 5 /* IN1R_ZC */
1032#define WM8915_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
1033#define WM8915_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
1034#define WM8915_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
1035#define WM8915_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
1036
1037/*
1038 * R18 (0x12) - Line Input Control
1039 */
1040#define WM8915_INL_MODE_MASK 0x000C /* INL_MODE - [3:2] */
1041#define WM8915_INL_MODE_SHIFT 2 /* INL_MODE - [3:2] */
1042#define WM8915_INL_MODE_WIDTH 2 /* INL_MODE - [3:2] */
1043#define WM8915_INR_MODE_MASK 0x0003 /* INR_MODE - [1:0] */
1044#define WM8915_INR_MODE_SHIFT 0 /* INR_MODE - [1:0] */
1045#define WM8915_INR_MODE_WIDTH 2 /* INR_MODE - [1:0] */
1046
1047/*
1048 * R21 (0x15) - DAC1 HPOUT1 Volume
1049 */
1050#define WM8915_DAC1R_HPOUT1R_VOL_MASK 0x00F0 /* DAC1R_HPOUT1R_VOL - [7:4] */
1051#define WM8915_DAC1R_HPOUT1R_VOL_SHIFT 4 /* DAC1R_HPOUT1R_VOL - [7:4] */
1052#define WM8915_DAC1R_HPOUT1R_VOL_WIDTH 4 /* DAC1R_HPOUT1R_VOL - [7:4] */
1053#define WM8915_DAC1L_HPOUT1L_VOL_MASK 0x000F /* DAC1L_HPOUT1L_VOL - [3:0] */
1054#define WM8915_DAC1L_HPOUT1L_VOL_SHIFT 0 /* DAC1L_HPOUT1L_VOL - [3:0] */
1055#define WM8915_DAC1L_HPOUT1L_VOL_WIDTH 4 /* DAC1L_HPOUT1L_VOL - [3:0] */
1056
1057/*
1058 * R22 (0x16) - DAC2 HPOUT2 Volume
1059 */
1060#define WM8915_DAC2R_HPOUT2R_VOL_MASK 0x00F0 /* DAC2R_HPOUT2R_VOL - [7:4] */
1061#define WM8915_DAC2R_HPOUT2R_VOL_SHIFT 4 /* DAC2R_HPOUT2R_VOL - [7:4] */
1062#define WM8915_DAC2R_HPOUT2R_VOL_WIDTH 4 /* DAC2R_HPOUT2R_VOL - [7:4] */
1063#define WM8915_DAC2L_HPOUT2L_VOL_MASK 0x000F /* DAC2L_HPOUT2L_VOL - [3:0] */
1064#define WM8915_DAC2L_HPOUT2L_VOL_SHIFT 0 /* DAC2L_HPOUT2L_VOL - [3:0] */
1065#define WM8915_DAC2L_HPOUT2L_VOL_WIDTH 4 /* DAC2L_HPOUT2L_VOL - [3:0] */
1066
1067/*
1068 * R24 (0x18) - DAC1 Left Volume
1069 */
1070#define WM8915_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */
1071#define WM8915_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */
1072#define WM8915_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */
1073#define WM8915_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */
1074#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1075#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1076#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1077#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1078#define WM8915_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */
1079#define WM8915_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */
1080#define WM8915_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */
1081
1082/*
1083 * R25 (0x19) - DAC1 Right Volume
1084 */
1085#define WM8915_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */
1086#define WM8915_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */
1087#define WM8915_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */
1088#define WM8915_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */
1089#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1090#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1091#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1092#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1093#define WM8915_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */
1094#define WM8915_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */
1095#define WM8915_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */
1096
1097/*
1098 * R26 (0x1A) - DAC2 Left Volume
1099 */
1100#define WM8915_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */
1101#define WM8915_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */
1102#define WM8915_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */
1103#define WM8915_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */
1104#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1105#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1106#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1107#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1108#define WM8915_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */
1109#define WM8915_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */
1110#define WM8915_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */
1111
1112/*
1113 * R27 (0x1B) - DAC2 Right Volume
1114 */
1115#define WM8915_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */
1116#define WM8915_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */
1117#define WM8915_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */
1118#define WM8915_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */
1119#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1120#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1121#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1122#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1123#define WM8915_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */
1124#define WM8915_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */
1125#define WM8915_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */
1126
1127/*
1128 * R28 (0x1C) - Output1 Left Volume
1129 */
1130#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1131#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1132#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1133#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1134#define WM8915_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
1135#define WM8915_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
1136#define WM8915_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
1137#define WM8915_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
1138#define WM8915_HPOUT1L_VOL_MASK 0x000F /* HPOUT1L_VOL - [3:0] */
1139#define WM8915_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [3:0] */
1140#define WM8915_HPOUT1L_VOL_WIDTH 4 /* HPOUT1L_VOL - [3:0] */
1141
1142/*
1143 * R29 (0x1D) - Output1 Right Volume
1144 */
1145#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1146#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1147#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1148#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1149#define WM8915_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
1150#define WM8915_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
1151#define WM8915_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
1152#define WM8915_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
1153#define WM8915_HPOUT1R_VOL_MASK 0x000F /* HPOUT1R_VOL - [3:0] */
1154#define WM8915_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [3:0] */
1155#define WM8915_HPOUT1R_VOL_WIDTH 4 /* HPOUT1R_VOL - [3:0] */
1156
1157/*
1158 * R30 (0x1E) - Output2 Left Volume
1159 */
1160#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1161#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1162#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1163#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1164#define WM8915_HPOUT2L_ZC 0x0080 /* HPOUT2L_ZC */
1165#define WM8915_HPOUT2L_ZC_MASK 0x0080 /* HPOUT2L_ZC */
1166#define WM8915_HPOUT2L_ZC_SHIFT 7 /* HPOUT2L_ZC */
1167#define WM8915_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */
1168#define WM8915_HPOUT2L_VOL_MASK 0x000F /* HPOUT2L_VOL - [3:0] */
1169#define WM8915_HPOUT2L_VOL_SHIFT 0 /* HPOUT2L_VOL - [3:0] */
1170#define WM8915_HPOUT2L_VOL_WIDTH 4 /* HPOUT2L_VOL - [3:0] */
1171
1172/*
1173 * R31 (0x1F) - Output2 Right Volume
1174 */
1175#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1176#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1177#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1178#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1179#define WM8915_HPOUT2R_ZC 0x0080 /* HPOUT2R_ZC */
1180#define WM8915_HPOUT2R_ZC_MASK 0x0080 /* HPOUT2R_ZC */
1181#define WM8915_HPOUT2R_ZC_SHIFT 7 /* HPOUT2R_ZC */
1182#define WM8915_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */
1183#define WM8915_HPOUT2R_VOL_MASK 0x000F /* HPOUT2R_VOL - [3:0] */
1184#define WM8915_HPOUT2R_VOL_SHIFT 0 /* HPOUT2R_VOL - [3:0] */
1185#define WM8915_HPOUT2R_VOL_WIDTH 4 /* HPOUT2R_VOL - [3:0] */
1186
1187/*
1188 * R32 (0x20) - MICBIAS (1)
1189 */
1190#define WM8915_MICB1_RATE 0x0020 /* MICB1_RATE */
1191#define WM8915_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
1192#define WM8915_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
1193#define WM8915_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
1194#define WM8915_MICB1_MODE 0x0010 /* MICB1_MODE */
1195#define WM8915_MICB1_MODE_MASK 0x0010 /* MICB1_MODE */
1196#define WM8915_MICB1_MODE_SHIFT 4 /* MICB1_MODE */
1197#define WM8915_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
1198#define WM8915_MICB1_LVL_MASK 0x000E /* MICB1_LVL - [3:1] */
1199#define WM8915_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [3:1] */
1200#define WM8915_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [3:1] */
1201#define WM8915_MICB1_DISCH 0x0001 /* MICB1_DISCH */
1202#define WM8915_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */
1203#define WM8915_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */
1204#define WM8915_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
1205
1206/*
1207 * R33 (0x21) - MICBIAS (2)
1208 */
1209#define WM8915_MICB2_RATE 0x0020 /* MICB2_RATE */
1210#define WM8915_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
1211#define WM8915_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
1212#define WM8915_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
1213#define WM8915_MICB2_MODE 0x0010 /* MICB2_MODE */
1214#define WM8915_MICB2_MODE_MASK 0x0010 /* MICB2_MODE */
1215#define WM8915_MICB2_MODE_SHIFT 4 /* MICB2_MODE */
1216#define WM8915_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
1217#define WM8915_MICB2_LVL_MASK 0x000E /* MICB2_LVL - [3:1] */
1218#define WM8915_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [3:1] */
1219#define WM8915_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [3:1] */
1220#define WM8915_MICB2_DISCH 0x0001 /* MICB2_DISCH */
1221#define WM8915_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */
1222#define WM8915_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */
1223#define WM8915_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
1224
1225/*
1226 * R40 (0x28) - LDO 1
1227 */
1228#define WM8915_LDO1_MODE 0x0020 /* LDO1_MODE */
1229#define WM8915_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */
1230#define WM8915_LDO1_MODE_SHIFT 5 /* LDO1_MODE */
1231#define WM8915_LDO1_MODE_WIDTH 1 /* LDO1_MODE */
1232#define WM8915_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */
1233#define WM8915_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */
1234#define WM8915_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */
1235#define WM8915_LDO1_DISCH 0x0001 /* LDO1_DISCH */
1236#define WM8915_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */
1237#define WM8915_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */
1238#define WM8915_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */
1239
1240/*
1241 * R41 (0x29) - LDO 2
1242 */
1243#define WM8915_LDO2_MODE 0x0020 /* LDO2_MODE */
1244#define WM8915_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */
1245#define WM8915_LDO2_MODE_SHIFT 5 /* LDO2_MODE */
1246#define WM8915_LDO2_MODE_WIDTH 1 /* LDO2_MODE */
1247#define WM8915_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */
1248#define WM8915_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */
1249#define WM8915_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */
1250#define WM8915_LDO2_DISCH 0x0001 /* LDO2_DISCH */
1251#define WM8915_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */
1252#define WM8915_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
1253#define WM8915_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
1254
1255/*
1256 * R48 (0x30) - Accessory Detect Mode 1
1257 */
1258#define WM8915_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */
1259#define WM8915_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */
1260#define WM8915_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */
1261
1262/*
1263 * R49 (0x31) - Accessory Detect Mode 2
1264 */
1265#define WM8915_HPOUT1FB_SRC 0x0004 /* HPOUT1FB_SRC */
1266#define WM8915_HPOUT1FB_SRC_MASK 0x0004 /* HPOUT1FB_SRC */
1267#define WM8915_HPOUT1FB_SRC_SHIFT 2 /* HPOUT1FB_SRC */
1268#define WM8915_HPOUT1FB_SRC_WIDTH 1 /* HPOUT1FB_SRC */
1269#define WM8915_MICD_SRC 0x0002 /* MICD_SRC */
1270#define WM8915_MICD_SRC_MASK 0x0002 /* MICD_SRC */
1271#define WM8915_MICD_SRC_SHIFT 1 /* MICD_SRC */
1272#define WM8915_MICD_SRC_WIDTH 1 /* MICD_SRC */
1273#define WM8915_MICD_BIAS_SRC 0x0001 /* MICD_BIAS_SRC */
1274#define WM8915_MICD_BIAS_SRC_MASK 0x0001 /* MICD_BIAS_SRC */
1275#define WM8915_MICD_BIAS_SRC_SHIFT 0 /* MICD_BIAS_SRC */
1276#define WM8915_MICD_BIAS_SRC_WIDTH 1 /* MICD_BIAS_SRC */
1277
1278/*
1279 * R52 (0x34) - Headphone Detect 1
1280 */
1281#define WM8915_HP_HOLDTIME_MASK 0x00E0 /* HP_HOLDTIME - [7:5] */
1282#define WM8915_HP_HOLDTIME_SHIFT 5 /* HP_HOLDTIME - [7:5] */
1283#define WM8915_HP_HOLDTIME_WIDTH 3 /* HP_HOLDTIME - [7:5] */
1284#define WM8915_HP_CLK_DIV_MASK 0x0018 /* HP_CLK_DIV - [4:3] */
1285#define WM8915_HP_CLK_DIV_SHIFT 3 /* HP_CLK_DIV - [4:3] */
1286#define WM8915_HP_CLK_DIV_WIDTH 2 /* HP_CLK_DIV - [4:3] */
1287#define WM8915_HP_STEP_SIZE 0x0002 /* HP_STEP_SIZE */
1288#define WM8915_HP_STEP_SIZE_MASK 0x0002 /* HP_STEP_SIZE */
1289#define WM8915_HP_STEP_SIZE_SHIFT 1 /* HP_STEP_SIZE */
1290#define WM8915_HP_STEP_SIZE_WIDTH 1 /* HP_STEP_SIZE */
1291#define WM8915_HP_POLL 0x0001 /* HP_POLL */
1292#define WM8915_HP_POLL_MASK 0x0001 /* HP_POLL */
1293#define WM8915_HP_POLL_SHIFT 0 /* HP_POLL */
1294#define WM8915_HP_POLL_WIDTH 1 /* HP_POLL */
1295
1296/*
1297 * R53 (0x35) - Headphone Detect 2
1298 */
1299#define WM8915_HP_DONE 0x0080 /* HP_DONE */
1300#define WM8915_HP_DONE_MASK 0x0080 /* HP_DONE */
1301#define WM8915_HP_DONE_SHIFT 7 /* HP_DONE */
1302#define WM8915_HP_DONE_WIDTH 1 /* HP_DONE */
1303#define WM8915_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */
1304#define WM8915_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
1305#define WM8915_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
1306
1307/*
1308 * R56 (0x38) - Mic Detect 1
1309 */
1310#define WM8915_MICD_BIAS_STARTTIME_MASK 0xF000 /* MICD_BIAS_STARTTIME - [15:12] */
1311#define WM8915_MICD_BIAS_STARTTIME_SHIFT 12 /* MICD_BIAS_STARTTIME - [15:12] */
1312#define WM8915_MICD_BIAS_STARTTIME_WIDTH 4 /* MICD_BIAS_STARTTIME - [15:12] */
1313#define WM8915_MICD_RATE_MASK 0x0F00 /* MICD_RATE - [11:8] */
1314#define WM8915_MICD_RATE_SHIFT 8 /* MICD_RATE - [11:8] */
1315#define WM8915_MICD_RATE_WIDTH 4 /* MICD_RATE - [11:8] */
1316#define WM8915_MICD_DBTIME 0x0002 /* MICD_DBTIME */
1317#define WM8915_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */
1318#define WM8915_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */
1319#define WM8915_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */
1320#define WM8915_MICD_ENA 0x0001 /* MICD_ENA */
1321#define WM8915_MICD_ENA_MASK 0x0001 /* MICD_ENA */
1322#define WM8915_MICD_ENA_SHIFT 0 /* MICD_ENA */
1323#define WM8915_MICD_ENA_WIDTH 1 /* MICD_ENA */
1324
1325/*
1326 * R57 (0x39) - Mic Detect 2
1327 */
1328#define WM8915_MICD_LVL_SEL_MASK 0x00FF /* MICD_LVL_SEL - [7:0] */
1329#define WM8915_MICD_LVL_SEL_SHIFT 0 /* MICD_LVL_SEL - [7:0] */
1330#define WM8915_MICD_LVL_SEL_WIDTH 8 /* MICD_LVL_SEL - [7:0] */
1331
1332/*
1333 * R58 (0x3A) - Mic Detect 3
1334 */
1335#define WM8915_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */
1336#define WM8915_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */
1337#define WM8915_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */
1338#define WM8915_MICD_VALID 0x0002 /* MICD_VALID */
1339#define WM8915_MICD_VALID_MASK 0x0002 /* MICD_VALID */
1340#define WM8915_MICD_VALID_SHIFT 1 /* MICD_VALID */
1341#define WM8915_MICD_VALID_WIDTH 1 /* MICD_VALID */
1342#define WM8915_MICD_STS 0x0001 /* MICD_STS */
1343#define WM8915_MICD_STS_MASK 0x0001 /* MICD_STS */
1344#define WM8915_MICD_STS_SHIFT 0 /* MICD_STS */
1345#define WM8915_MICD_STS_WIDTH 1 /* MICD_STS */
1346
1347/*
1348 * R64 (0x40) - Charge Pump (1)
1349 */
1350#define WM8915_CP_ENA 0x8000 /* CP_ENA */
1351#define WM8915_CP_ENA_MASK 0x8000 /* CP_ENA */
1352#define WM8915_CP_ENA_SHIFT 15 /* CP_ENA */
1353#define WM8915_CP_ENA_WIDTH 1 /* CP_ENA */
1354
1355/*
1356 * R65 (0x41) - Charge Pump (2)
1357 */
1358#define WM8915_CP_DISCH 0x8000 /* CP_DISCH */
1359#define WM8915_CP_DISCH_MASK 0x8000 /* CP_DISCH */
1360#define WM8915_CP_DISCH_SHIFT 15 /* CP_DISCH */
1361#define WM8915_CP_DISCH_WIDTH 1 /* CP_DISCH */
1362
1363/*
1364 * R80 (0x50) - DC Servo (1)
1365 */
1366#define WM8915_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
1367#define WM8915_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
1368#define WM8915_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
1369#define WM8915_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
1370#define WM8915_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
1371#define WM8915_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
1372#define WM8915_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
1373#define WM8915_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
1374#define WM8915_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
1375#define WM8915_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
1376#define WM8915_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
1377#define WM8915_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
1378#define WM8915_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
1379#define WM8915_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
1380#define WM8915_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
1381#define WM8915_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
1382
1383/*
1384 * R81 (0x51) - DC Servo (2)
1385 */
1386#define WM8915_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
1387#define WM8915_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
1388#define WM8915_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
1389#define WM8915_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
1390#define WM8915_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
1391#define WM8915_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
1392#define WM8915_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
1393#define WM8915_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
1394#define WM8915_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
1395#define WM8915_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
1396#define WM8915_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
1397#define WM8915_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
1398#define WM8915_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
1399#define WM8915_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
1400#define WM8915_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
1401#define WM8915_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
1402#define WM8915_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
1403#define WM8915_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
1404#define WM8915_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
1405#define WM8915_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
1406#define WM8915_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
1407#define WM8915_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
1408#define WM8915_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
1409#define WM8915_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
1410#define WM8915_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
1411#define WM8915_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
1412#define WM8915_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
1413#define WM8915_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
1414#define WM8915_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
1415#define WM8915_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
1416#define WM8915_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
1417#define WM8915_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
1418#define WM8915_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
1419#define WM8915_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
1420#define WM8915_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
1421#define WM8915_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
1422#define WM8915_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
1423#define WM8915_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
1424#define WM8915_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
1425#define WM8915_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
1426#define WM8915_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
1427#define WM8915_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
1428#define WM8915_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
1429#define WM8915_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
1430#define WM8915_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
1431#define WM8915_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
1432#define WM8915_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
1433#define WM8915_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
1434#define WM8915_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
1435#define WM8915_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
1436#define WM8915_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
1437#define WM8915_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
1438#define WM8915_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
1439#define WM8915_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
1440#define WM8915_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
1441#define WM8915_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
1442#define WM8915_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
1443#define WM8915_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
1444#define WM8915_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
1445#define WM8915_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
1446#define WM8915_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
1447#define WM8915_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
1448#define WM8915_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
1449#define WM8915_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
1450
1451/*
1452 * R82 (0x52) - DC Servo (3)
1453 */
1454#define WM8915_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
1455#define WM8915_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
1456#define WM8915_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
1457#define WM8915_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
1458#define WM8915_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
1459#define WM8915_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
1460
1461/*
1462 * R84 (0x54) - DC Servo (5)
1463 */
1464#define WM8915_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */
1465#define WM8915_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */
1466#define WM8915_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */
1467#define WM8915_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
1468#define WM8915_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
1469#define WM8915_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
1470
1471/*
1472 * R85 (0x55) - DC Servo (6)
1473 */
1474#define WM8915_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */
1475#define WM8915_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
1476#define WM8915_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
1477#define WM8915_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
1478#define WM8915_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
1479#define WM8915_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
1480
1481/*
1482 * R86 (0x56) - DC Servo (7)
1483 */
1484#define WM8915_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
1485#define WM8915_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1486#define WM8915_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1487#define WM8915_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
1488#define WM8915_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
1489#define WM8915_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
1490
1491/*
1492 * R87 (0x57) - DC Servo Readback 0
1493 */
1494#define WM8915_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
1495#define WM8915_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
1496#define WM8915_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
1497#define WM8915_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
1498#define WM8915_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
1499#define WM8915_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
1500#define WM8915_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
1501#define WM8915_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
1502#define WM8915_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
1503
1504/*
1505 * R96 (0x60) - Analogue HP (1)
1506 */
1507#define WM8915_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
1508#define WM8915_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
1509#define WM8915_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
1510#define WM8915_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
1511#define WM8915_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
1512#define WM8915_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
1513#define WM8915_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
1514#define WM8915_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
1515#define WM8915_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
1516#define WM8915_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
1517#define WM8915_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
1518#define WM8915_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
1519#define WM8915_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
1520#define WM8915_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
1521#define WM8915_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
1522#define WM8915_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
1523#define WM8915_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
1524#define WM8915_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
1525#define WM8915_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
1526#define WM8915_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
1527#define WM8915_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
1528#define WM8915_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
1529#define WM8915_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
1530#define WM8915_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
1531
1532/*
1533 * R97 (0x61) - Analogue HP (2)
1534 */
1535#define WM8915_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */
1536#define WM8915_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */
1537#define WM8915_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */
1538#define WM8915_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */
1539#define WM8915_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */
1540#define WM8915_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */
1541#define WM8915_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */
1542#define WM8915_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */
1543#define WM8915_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */
1544#define WM8915_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */
1545#define WM8915_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */
1546#define WM8915_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */
1547#define WM8915_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */
1548#define WM8915_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */
1549#define WM8915_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */
1550#define WM8915_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */
1551#define WM8915_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */
1552#define WM8915_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */
1553#define WM8915_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */
1554#define WM8915_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */
1555#define WM8915_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */
1556#define WM8915_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */
1557#define WM8915_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */
1558#define WM8915_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */
1559
1560/*
1561 * R256 (0x100) - Chip Revision
1562 */
1563#define WM8915_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
1564#define WM8915_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
1565#define WM8915_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
1566
1567/*
1568 * R257 (0x101) - Control Interface (1)
1569 */
1570#define WM8915_AUTO_INC 0x0004 /* AUTO_INC */
1571#define WM8915_AUTO_INC_MASK 0x0004 /* AUTO_INC */
1572#define WM8915_AUTO_INC_SHIFT 2 /* AUTO_INC */
1573#define WM8915_AUTO_INC_WIDTH 1 /* AUTO_INC */
1574
1575/*
1576 * R272 (0x110) - Write Sequencer Ctrl (1)
1577 */
1578#define WM8915_WSEQ_ENA 0x8000 /* WSEQ_ENA */
1579#define WM8915_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
1580#define WM8915_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
1581#define WM8915_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1582#define WM8915_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1583#define WM8915_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1584#define WM8915_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1585#define WM8915_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1586#define WM8915_WSEQ_START 0x0100 /* WSEQ_START */
1587#define WM8915_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1588#define WM8915_WSEQ_START_SHIFT 8 /* WSEQ_START */
1589#define WM8915_WSEQ_START_WIDTH 1 /* WSEQ_START */
1590#define WM8915_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
1591#define WM8915_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
1592#define WM8915_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
1593
1594/*
1595 * R273 (0x111) - Write Sequencer Ctrl (2)
1596 */
1597#define WM8915_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */
1598#define WM8915_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */
1599#define WM8915_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */
1600#define WM8915_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1601#define WM8915_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */
1602#define WM8915_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */
1603#define WM8915_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */
1604
1605/*
1606 * R512 (0x200) - AIF Clocking (1)
1607 */
1608#define WM8915_SYSCLK_SRC_MASK 0x0018 /* SYSCLK_SRC - [4:3] */
1609#define WM8915_SYSCLK_SRC_SHIFT 3 /* SYSCLK_SRC - [4:3] */
1610#define WM8915_SYSCLK_SRC_WIDTH 2 /* SYSCLK_SRC - [4:3] */
1611#define WM8915_SYSCLK_INV 0x0004 /* SYSCLK_INV */
1612#define WM8915_SYSCLK_INV_MASK 0x0004 /* SYSCLK_INV */
1613#define WM8915_SYSCLK_INV_SHIFT 2 /* SYSCLK_INV */
1614#define WM8915_SYSCLK_INV_WIDTH 1 /* SYSCLK_INV */
1615#define WM8915_SYSCLK_DIV 0x0002 /* SYSCLK_DIV */
1616#define WM8915_SYSCLK_DIV_MASK 0x0002 /* SYSCLK_DIV */
1617#define WM8915_SYSCLK_DIV_SHIFT 1 /* SYSCLK_DIV */
1618#define WM8915_SYSCLK_DIV_WIDTH 1 /* SYSCLK_DIV */
1619#define WM8915_SYSCLK_ENA 0x0001 /* SYSCLK_ENA */
1620#define WM8915_SYSCLK_ENA_MASK 0x0001 /* SYSCLK_ENA */
1621#define WM8915_SYSCLK_ENA_SHIFT 0 /* SYSCLK_ENA */
1622#define WM8915_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
1623
1624/*
1625 * R513 (0x201) - AIF Clocking (2)
1626 */
1627#define WM8915_DSP2_DIV_MASK 0x0018 /* DSP2_DIV - [4:3] */
1628#define WM8915_DSP2_DIV_SHIFT 3 /* DSP2_DIV - [4:3] */
1629#define WM8915_DSP2_DIV_WIDTH 2 /* DSP2_DIV - [4:3] */
1630#define WM8915_DSP1_DIV_MASK 0x0003 /* DSP1_DIV - [1:0] */
1631#define WM8915_DSP1_DIV_SHIFT 0 /* DSP1_DIV - [1:0] */
1632#define WM8915_DSP1_DIV_WIDTH 2 /* DSP1_DIV - [1:0] */
1633
1634/*
1635 * R520 (0x208) - Clocking (1)
1636 */
1637#define WM8915_LFCLK_ENA 0x0020 /* LFCLK_ENA */
1638#define WM8915_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */
1639#define WM8915_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */
1640#define WM8915_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */
1641#define WM8915_TOCLK_ENA 0x0010 /* TOCLK_ENA */
1642#define WM8915_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
1643#define WM8915_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
1644#define WM8915_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
1645#define WM8915_AIFCLK_ENA 0x0004 /* AIFCLK_ENA */
1646#define WM8915_AIFCLK_ENA_MASK 0x0004 /* AIFCLK_ENA */
1647#define WM8915_AIFCLK_ENA_SHIFT 2 /* AIFCLK_ENA */
1648#define WM8915_AIFCLK_ENA_WIDTH 1 /* AIFCLK_ENA */
1649#define WM8915_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */
1650#define WM8915_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */
1651#define WM8915_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */
1652#define WM8915_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */
1653
1654/*
1655 * R521 (0x209) - Clocking (2)
1656 */
1657#define WM8915_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */
1658#define WM8915_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */
1659#define WM8915_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */
1660#define WM8915_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */
1661#define WM8915_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */
1662#define WM8915_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */
1663#define WM8915_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */
1664#define WM8915_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */
1665#define WM8915_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */
1666
1667/*
1668 * R528 (0x210) - AIF Rate
1669 */
1670#define WM8915_SYSCLK_RATE 0x0001 /* SYSCLK_RATE */
1671#define WM8915_SYSCLK_RATE_MASK 0x0001 /* SYSCLK_RATE */
1672#define WM8915_SYSCLK_RATE_SHIFT 0 /* SYSCLK_RATE */
1673#define WM8915_SYSCLK_RATE_WIDTH 1 /* SYSCLK_RATE */
1674
1675/*
1676 * R544 (0x220) - FLL Control (1)
1677 */
1678#define WM8915_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
1679#define WM8915_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
1680#define WM8915_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
1681#define WM8915_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
1682#define WM8915_FLL_ENA 0x0001 /* FLL_ENA */
1683#define WM8915_FLL_ENA_MASK 0x0001 /* FLL_ENA */
1684#define WM8915_FLL_ENA_SHIFT 0 /* FLL_ENA */
1685#define WM8915_FLL_ENA_WIDTH 1 /* FLL_ENA */
1686
1687/*
1688 * R545 (0x221) - FLL Control (2)
1689 */
1690#define WM8915_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
1691#define WM8915_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
1692#define WM8915_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
1693#define WM8915_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
1694#define WM8915_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
1695#define WM8915_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
1696
1697/*
1698 * R546 (0x222) - FLL Control (3)
1699 */
1700#define WM8915_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */
1701#define WM8915_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */
1702#define WM8915_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */
1703
1704/*
1705 * R547 (0x223) - FLL Control (4)
1706 */
1707#define WM8915_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
1708#define WM8915_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
1709#define WM8915_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
1710#define WM8915_FLL_LOOP_GAIN_MASK 0x000F /* FLL_LOOP_GAIN - [3:0] */
1711#define WM8915_FLL_LOOP_GAIN_SHIFT 0 /* FLL_LOOP_GAIN - [3:0] */
1712#define WM8915_FLL_LOOP_GAIN_WIDTH 4 /* FLL_LOOP_GAIN - [3:0] */
1713
1714/*
1715 * R548 (0x224) - FLL Control (5)
1716 */
1717#define WM8915_FLL_FRC_NCO_VAL_MASK 0x1F80 /* FLL_FRC_NCO_VAL - [12:7] */
1718#define WM8915_FLL_FRC_NCO_VAL_SHIFT 7 /* FLL_FRC_NCO_VAL - [12:7] */
1719#define WM8915_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [12:7] */
1720#define WM8915_FLL_FRC_NCO 0x0040 /* FLL_FRC_NCO */
1721#define WM8915_FLL_FRC_NCO_MASK 0x0040 /* FLL_FRC_NCO */
1722#define WM8915_FLL_FRC_NCO_SHIFT 6 /* FLL_FRC_NCO */
1723#define WM8915_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
1724#define WM8915_FLL_REFCLK_DIV_MASK 0x0018 /* FLL_REFCLK_DIV - [4:3] */
1725#define WM8915_FLL_REFCLK_DIV_SHIFT 3 /* FLL_REFCLK_DIV - [4:3] */
1726#define WM8915_FLL_REFCLK_DIV_WIDTH 2 /* FLL_REFCLK_DIV - [4:3] */
1727#define WM8915_FLL_REF_FREQ 0x0004 /* FLL_REF_FREQ */
1728#define WM8915_FLL_REF_FREQ_MASK 0x0004 /* FLL_REF_FREQ */
1729#define WM8915_FLL_REF_FREQ_SHIFT 2 /* FLL_REF_FREQ */
1730#define WM8915_FLL_REF_FREQ_WIDTH 1 /* FLL_REF_FREQ */
1731#define WM8915_FLL_REFCLK_SRC_MASK 0x0003 /* FLL_REFCLK_SRC - [1:0] */
1732#define WM8915_FLL_REFCLK_SRC_SHIFT 0 /* FLL_REFCLK_SRC - [1:0] */
1733#define WM8915_FLL_REFCLK_SRC_WIDTH 2 /* FLL_REFCLK_SRC - [1:0] */
1734
1735/*
1736 * R549 (0x225) - FLL Control (6)
1737 */
1738#define WM8915_FLL_REFCLK_SRC_STS_MASK 0x000C /* FLL_REFCLK_SRC_STS - [3:2] */
1739#define WM8915_FLL_REFCLK_SRC_STS_SHIFT 2 /* FLL_REFCLK_SRC_STS - [3:2] */
1740#define WM8915_FLL_REFCLK_SRC_STS_WIDTH 2 /* FLL_REFCLK_SRC_STS - [3:2] */
1741#define WM8915_FLL_SWITCH_CLK 0x0001 /* FLL_SWITCH_CLK */
1742#define WM8915_FLL_SWITCH_CLK_MASK 0x0001 /* FLL_SWITCH_CLK */
1743#define WM8915_FLL_SWITCH_CLK_SHIFT 0 /* FLL_SWITCH_CLK */
1744#define WM8915_FLL_SWITCH_CLK_WIDTH 1 /* FLL_SWITCH_CLK */
1745
1746/*
1747 * R550 (0x226) - FLL EFS 1
1748 */
1749#define WM8915_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */
1750#define WM8915_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */
1751#define WM8915_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */
1752
1753/*
1754 * R551 (0x227) - FLL EFS 2
1755 */
1756#define WM8915_FLL_LFSR_SEL_MASK 0x0006 /* FLL_LFSR_SEL - [2:1] */
1757#define WM8915_FLL_LFSR_SEL_SHIFT 1 /* FLL_LFSR_SEL - [2:1] */
1758#define WM8915_FLL_LFSR_SEL_WIDTH 2 /* FLL_LFSR_SEL - [2:1] */
1759#define WM8915_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */
1760#define WM8915_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */
1761#define WM8915_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */
1762#define WM8915_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */
1763
1764/*
1765 * R768 (0x300) - AIF1 Control
1766 */
1767#define WM8915_AIF1_TRI 0x0004 /* AIF1_TRI */
1768#define WM8915_AIF1_TRI_MASK 0x0004 /* AIF1_TRI */
1769#define WM8915_AIF1_TRI_SHIFT 2 /* AIF1_TRI */
1770#define WM8915_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
1771#define WM8915_AIF1_FMT_MASK 0x0003 /* AIF1_FMT - [1:0] */
1772#define WM8915_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [1:0] */
1773#define WM8915_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [1:0] */
1774
1775/*
1776 * R769 (0x301) - AIF1 BCLK
1777 */
1778#define WM8915_AIF1_BCLK_INV 0x0400 /* AIF1_BCLK_INV */
1779#define WM8915_AIF1_BCLK_INV_MASK 0x0400 /* AIF1_BCLK_INV */
1780#define WM8915_AIF1_BCLK_INV_SHIFT 10 /* AIF1_BCLK_INV */
1781#define WM8915_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
1782#define WM8915_AIF1_BCLK_FRC 0x0200 /* AIF1_BCLK_FRC */
1783#define WM8915_AIF1_BCLK_FRC_MASK 0x0200 /* AIF1_BCLK_FRC */
1784#define WM8915_AIF1_BCLK_FRC_SHIFT 9 /* AIF1_BCLK_FRC */
1785#define WM8915_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */
1786#define WM8915_AIF1_BCLK_MSTR 0x0100 /* AIF1_BCLK_MSTR */
1787#define WM8915_AIF1_BCLK_MSTR_MASK 0x0100 /* AIF1_BCLK_MSTR */
1788#define WM8915_AIF1_BCLK_MSTR_SHIFT 8 /* AIF1_BCLK_MSTR */
1789#define WM8915_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */
1790#define WM8915_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */
1791#define WM8915_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */
1792#define WM8915_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */
1793
1794/*
1795 * R770 (0x302) - AIF1 TX LRCLK(1)
1796 */
1797#define WM8915_AIF1TX_RATE_MASK 0x07FF /* AIF1TX_RATE - [10:0] */
1798#define WM8915_AIF1TX_RATE_SHIFT 0 /* AIF1TX_RATE - [10:0] */
1799#define WM8915_AIF1TX_RATE_WIDTH 11 /* AIF1TX_RATE - [10:0] */
1800
1801/*
1802 * R771 (0x303) - AIF1 TX LRCLK(2)
1803 */
1804#define WM8915_AIF1TX_LRCLK_MODE 0x0008 /* AIF1TX_LRCLK_MODE */
1805#define WM8915_AIF1TX_LRCLK_MODE_MASK 0x0008 /* AIF1TX_LRCLK_MODE */
1806#define WM8915_AIF1TX_LRCLK_MODE_SHIFT 3 /* AIF1TX_LRCLK_MODE */
1807#define WM8915_AIF1TX_LRCLK_MODE_WIDTH 1 /* AIF1TX_LRCLK_MODE */
1808#define WM8915_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */
1809#define WM8915_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */
1810#define WM8915_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */
1811#define WM8915_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */
1812#define WM8915_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */
1813#define WM8915_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */
1814#define WM8915_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */
1815#define WM8915_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */
1816#define WM8915_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */
1817#define WM8915_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */
1818#define WM8915_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */
1819#define WM8915_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */
1820
1821/*
1822 * R772 (0x304) - AIF1 RX LRCLK(1)
1823 */
1824#define WM8915_AIF1RX_RATE_MASK 0x07FF /* AIF1RX_RATE - [10:0] */
1825#define WM8915_AIF1RX_RATE_SHIFT 0 /* AIF1RX_RATE - [10:0] */
1826#define WM8915_AIF1RX_RATE_WIDTH 11 /* AIF1RX_RATE - [10:0] */
1827
1828/*
1829 * R773 (0x305) - AIF1 RX LRCLK(2)
1830 */
1831#define WM8915_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */
1832#define WM8915_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */
1833#define WM8915_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */
1834#define WM8915_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */
1835#define WM8915_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */
1836#define WM8915_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */
1837#define WM8915_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */
1838#define WM8915_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */
1839#define WM8915_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */
1840#define WM8915_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */
1841#define WM8915_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */
1842#define WM8915_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */
1843
1844/*
1845 * R774 (0x306) - AIF1TX Data Configuration (1)
1846 */
1847#define WM8915_AIF1TX_WL_MASK 0xFF00 /* AIF1TX_WL - [15:8] */
1848#define WM8915_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [15:8] */
1849#define WM8915_AIF1TX_WL_WIDTH 8 /* AIF1TX_WL - [15:8] */
1850#define WM8915_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */
1851#define WM8915_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */
1852#define WM8915_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */
1853
1854/*
1855 * R775 (0x307) - AIF1TX Data Configuration (2)
1856 */
1857#define WM8915_AIF1TX_DAT_TRI 0x0001 /* AIF1TX_DAT_TRI */
1858#define WM8915_AIF1TX_DAT_TRI_MASK 0x0001 /* AIF1TX_DAT_TRI */
1859#define WM8915_AIF1TX_DAT_TRI_SHIFT 0 /* AIF1TX_DAT_TRI */
1860#define WM8915_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */
1861
1862/*
1863 * R776 (0x308) - AIF1RX Data Configuration
1864 */
1865#define WM8915_AIF1RX_WL_MASK 0xFF00 /* AIF1RX_WL - [15:8] */
1866#define WM8915_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [15:8] */
1867#define WM8915_AIF1RX_WL_WIDTH 8 /* AIF1RX_WL - [15:8] */
1868#define WM8915_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */
1869#define WM8915_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */
1870#define WM8915_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */
1871
1872/*
1873 * R777 (0x309) - AIF1TX Channel 0 Configuration
1874 */
1875#define WM8915_AIF1TX_CHAN0_DAT_INV 0x8000 /* AIF1TX_CHAN0_DAT_INV */
1876#define WM8915_AIF1TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN0_DAT_INV */
1877#define WM8915_AIF1TX_CHAN0_DAT_INV_SHIFT 15 /* AIF1TX_CHAN0_DAT_INV */
1878#define WM8915_AIF1TX_CHAN0_DAT_INV_WIDTH 1 /* AIF1TX_CHAN0_DAT_INV */
1879#define WM8915_AIF1TX_CHAN0_SPACING_MASK 0x7E00 /* AIF1TX_CHAN0_SPACING - [14:9] */
1880#define WM8915_AIF1TX_CHAN0_SPACING_SHIFT 9 /* AIF1TX_CHAN0_SPACING - [14:9] */
1881#define WM8915_AIF1TX_CHAN0_SPACING_WIDTH 6 /* AIF1TX_CHAN0_SPACING - [14:9] */
1882#define WM8915_AIF1TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN0_SLOTS - [8:6] */
1883#define WM8915_AIF1TX_CHAN0_SLOTS_SHIFT 6 /* AIF1TX_CHAN0_SLOTS - [8:6] */
1884#define WM8915_AIF1TX_CHAN0_SLOTS_WIDTH 3 /* AIF1TX_CHAN0_SLOTS - [8:6] */
1885#define WM8915_AIF1TX_CHAN0_START_SLOT_MASK 0x003F /* AIF1TX_CHAN0_START_SLOT - [5:0] */
1886#define WM8915_AIF1TX_CHAN0_START_SLOT_SHIFT 0 /* AIF1TX_CHAN0_START_SLOT - [5:0] */
1887#define WM8915_AIF1TX_CHAN0_START_SLOT_WIDTH 6 /* AIF1TX_CHAN0_START_SLOT - [5:0] */
1888
1889/*
1890 * R778 (0x30A) - AIF1TX Channel 1 Configuration
1891 */
1892#define WM8915_AIF1TX_CHAN1_DAT_INV 0x8000 /* AIF1TX_CHAN1_DAT_INV */
1893#define WM8915_AIF1TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN1_DAT_INV */
1894#define WM8915_AIF1TX_CHAN1_DAT_INV_SHIFT 15 /* AIF1TX_CHAN1_DAT_INV */
1895#define WM8915_AIF1TX_CHAN1_DAT_INV_WIDTH 1 /* AIF1TX_CHAN1_DAT_INV */
1896#define WM8915_AIF1TX_CHAN1_SPACING_MASK 0x7E00 /* AIF1TX_CHAN1_SPACING - [14:9] */
1897#define WM8915_AIF1TX_CHAN1_SPACING_SHIFT 9 /* AIF1TX_CHAN1_SPACING - [14:9] */
1898#define WM8915_AIF1TX_CHAN1_SPACING_WIDTH 6 /* AIF1TX_CHAN1_SPACING - [14:9] */
1899#define WM8915_AIF1TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN1_SLOTS - [8:6] */
1900#define WM8915_AIF1TX_CHAN1_SLOTS_SHIFT 6 /* AIF1TX_CHAN1_SLOTS - [8:6] */
1901#define WM8915_AIF1TX_CHAN1_SLOTS_WIDTH 3 /* AIF1TX_CHAN1_SLOTS - [8:6] */
1902#define WM8915_AIF1TX_CHAN1_START_SLOT_MASK 0x003F /* AIF1TX_CHAN1_START_SLOT - [5:0] */
1903#define WM8915_AIF1TX_CHAN1_START_SLOT_SHIFT 0 /* AIF1TX_CHAN1_START_SLOT - [5:0] */
1904#define WM8915_AIF1TX_CHAN1_START_SLOT_WIDTH 6 /* AIF1TX_CHAN1_START_SLOT - [5:0] */
1905
1906/*
1907 * R779 (0x30B) - AIF1TX Channel 2 Configuration
1908 */
1909#define WM8915_AIF1TX_CHAN2_DAT_INV 0x8000 /* AIF1TX_CHAN2_DAT_INV */
1910#define WM8915_AIF1TX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN2_DAT_INV */
1911#define WM8915_AIF1TX_CHAN2_DAT_INV_SHIFT 15 /* AIF1TX_CHAN2_DAT_INV */
1912#define WM8915_AIF1TX_CHAN2_DAT_INV_WIDTH 1 /* AIF1TX_CHAN2_DAT_INV */
1913#define WM8915_AIF1TX_CHAN2_SPACING_MASK 0x7E00 /* AIF1TX_CHAN2_SPACING - [14:9] */
1914#define WM8915_AIF1TX_CHAN2_SPACING_SHIFT 9 /* AIF1TX_CHAN2_SPACING - [14:9] */
1915#define WM8915_AIF1TX_CHAN2_SPACING_WIDTH 6 /* AIF1TX_CHAN2_SPACING - [14:9] */
1916#define WM8915_AIF1TX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN2_SLOTS - [8:6] */
1917#define WM8915_AIF1TX_CHAN2_SLOTS_SHIFT 6 /* AIF1TX_CHAN2_SLOTS - [8:6] */
1918#define WM8915_AIF1TX_CHAN2_SLOTS_WIDTH 3 /* AIF1TX_CHAN2_SLOTS - [8:6] */
1919#define WM8915_AIF1TX_CHAN2_START_SLOT_MASK 0x003F /* AIF1TX_CHAN2_START_SLOT - [5:0] */
1920#define WM8915_AIF1TX_CHAN2_START_SLOT_SHIFT 0 /* AIF1TX_CHAN2_START_SLOT - [5:0] */
1921#define WM8915_AIF1TX_CHAN2_START_SLOT_WIDTH 6 /* AIF1TX_CHAN2_START_SLOT - [5:0] */
1922
1923/*
1924 * R780 (0x30C) - AIF1TX Channel 3 Configuration
1925 */
1926#define WM8915_AIF1TX_CHAN3_DAT_INV 0x8000 /* AIF1TX_CHAN3_DAT_INV */
1927#define WM8915_AIF1TX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN3_DAT_INV */
1928#define WM8915_AIF1TX_CHAN3_DAT_INV_SHIFT 15 /* AIF1TX_CHAN3_DAT_INV */
1929#define WM8915_AIF1TX_CHAN3_DAT_INV_WIDTH 1 /* AIF1TX_CHAN3_DAT_INV */
1930#define WM8915_AIF1TX_CHAN3_SPACING_MASK 0x7E00 /* AIF1TX_CHAN3_SPACING - [14:9] */
1931#define WM8915_AIF1TX_CHAN3_SPACING_SHIFT 9 /* AIF1TX_CHAN3_SPACING - [14:9] */
1932#define WM8915_AIF1TX_CHAN3_SPACING_WIDTH 6 /* AIF1TX_CHAN3_SPACING - [14:9] */
1933#define WM8915_AIF1TX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN3_SLOTS - [8:6] */
1934#define WM8915_AIF1TX_CHAN3_SLOTS_SHIFT 6 /* AIF1TX_CHAN3_SLOTS - [8:6] */
1935#define WM8915_AIF1TX_CHAN3_SLOTS_WIDTH 3 /* AIF1TX_CHAN3_SLOTS - [8:6] */
1936#define WM8915_AIF1TX_CHAN3_START_SLOT_MASK 0x003F /* AIF1TX_CHAN3_START_SLOT - [5:0] */
1937#define WM8915_AIF1TX_CHAN3_START_SLOT_SHIFT 0 /* AIF1TX_CHAN3_START_SLOT - [5:0] */
1938#define WM8915_AIF1TX_CHAN3_START_SLOT_WIDTH 6 /* AIF1TX_CHAN3_START_SLOT - [5:0] */
1939
1940/*
1941 * R781 (0x30D) - AIF1TX Channel 4 Configuration
1942 */
1943#define WM8915_AIF1TX_CHAN4_DAT_INV 0x8000 /* AIF1TX_CHAN4_DAT_INV */
1944#define WM8915_AIF1TX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN4_DAT_INV */
1945#define WM8915_AIF1TX_CHAN4_DAT_INV_SHIFT 15 /* AIF1TX_CHAN4_DAT_INV */
1946#define WM8915_AIF1TX_CHAN4_DAT_INV_WIDTH 1 /* AIF1TX_CHAN4_DAT_INV */
1947#define WM8915_AIF1TX_CHAN4_SPACING_MASK 0x7E00 /* AIF1TX_CHAN4_SPACING - [14:9] */
1948#define WM8915_AIF1TX_CHAN4_SPACING_SHIFT 9 /* AIF1TX_CHAN4_SPACING - [14:9] */
1949#define WM8915_AIF1TX_CHAN4_SPACING_WIDTH 6 /* AIF1TX_CHAN4_SPACING - [14:9] */
1950#define WM8915_AIF1TX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN4_SLOTS - [8:6] */
1951#define WM8915_AIF1TX_CHAN4_SLOTS_SHIFT 6 /* AIF1TX_CHAN4_SLOTS - [8:6] */
1952#define WM8915_AIF1TX_CHAN4_SLOTS_WIDTH 3 /* AIF1TX_CHAN4_SLOTS - [8:6] */
1953#define WM8915_AIF1TX_CHAN4_START_SLOT_MASK 0x003F /* AIF1TX_CHAN4_START_SLOT - [5:0] */
1954#define WM8915_AIF1TX_CHAN4_START_SLOT_SHIFT 0 /* AIF1TX_CHAN4_START_SLOT - [5:0] */
1955#define WM8915_AIF1TX_CHAN4_START_SLOT_WIDTH 6 /* AIF1TX_CHAN4_START_SLOT - [5:0] */
1956
1957/*
1958 * R782 (0x30E) - AIF1TX Channel 5 Configuration
1959 */
1960#define WM8915_AIF1TX_CHAN5_DAT_INV 0x8000 /* AIF1TX_CHAN5_DAT_INV */
1961#define WM8915_AIF1TX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN5_DAT_INV */
1962#define WM8915_AIF1TX_CHAN5_DAT_INV_SHIFT 15 /* AIF1TX_CHAN5_DAT_INV */
1963#define WM8915_AIF1TX_CHAN5_DAT_INV_WIDTH 1 /* AIF1TX_CHAN5_DAT_INV */
1964#define WM8915_AIF1TX_CHAN5_SPACING_MASK 0x7E00 /* AIF1TX_CHAN5_SPACING - [14:9] */
1965#define WM8915_AIF1TX_CHAN5_SPACING_SHIFT 9 /* AIF1TX_CHAN5_SPACING - [14:9] */
1966#define WM8915_AIF1TX_CHAN5_SPACING_WIDTH 6 /* AIF1TX_CHAN5_SPACING - [14:9] */
1967#define WM8915_AIF1TX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN5_SLOTS - [8:6] */
1968#define WM8915_AIF1TX_CHAN5_SLOTS_SHIFT 6 /* AIF1TX_CHAN5_SLOTS - [8:6] */
1969#define WM8915_AIF1TX_CHAN5_SLOTS_WIDTH 3 /* AIF1TX_CHAN5_SLOTS - [8:6] */
1970#define WM8915_AIF1TX_CHAN5_START_SLOT_MASK 0x003F /* AIF1TX_CHAN5_START_SLOT - [5:0] */
1971#define WM8915_AIF1TX_CHAN5_START_SLOT_SHIFT 0 /* AIF1TX_CHAN5_START_SLOT - [5:0] */
1972#define WM8915_AIF1TX_CHAN5_START_SLOT_WIDTH 6 /* AIF1TX_CHAN5_START_SLOT - [5:0] */
1973
1974/*
1975 * R783 (0x30F) - AIF1RX Channel 0 Configuration
1976 */
1977#define WM8915_AIF1RX_CHAN0_DAT_INV 0x8000 /* AIF1RX_CHAN0_DAT_INV */
1978#define WM8915_AIF1RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN0_DAT_INV */
1979#define WM8915_AIF1RX_CHAN0_DAT_INV_SHIFT 15 /* AIF1RX_CHAN0_DAT_INV */
1980#define WM8915_AIF1RX_CHAN0_DAT_INV_WIDTH 1 /* AIF1RX_CHAN0_DAT_INV */
1981#define WM8915_AIF1RX_CHAN0_SPACING_MASK 0x7E00 /* AIF1RX_CHAN0_SPACING - [14:9] */
1982#define WM8915_AIF1RX_CHAN0_SPACING_SHIFT 9 /* AIF1RX_CHAN0_SPACING - [14:9] */
1983#define WM8915_AIF1RX_CHAN0_SPACING_WIDTH 6 /* AIF1RX_CHAN0_SPACING - [14:9] */
1984#define WM8915_AIF1RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN0_SLOTS - [8:6] */
1985#define WM8915_AIF1RX_CHAN0_SLOTS_SHIFT 6 /* AIF1RX_CHAN0_SLOTS - [8:6] */
1986#define WM8915_AIF1RX_CHAN0_SLOTS_WIDTH 3 /* AIF1RX_CHAN0_SLOTS - [8:6] */
1987#define WM8915_AIF1RX_CHAN0_START_SLOT_MASK 0x003F /* AIF1RX_CHAN0_START_SLOT - [5:0] */
1988#define WM8915_AIF1RX_CHAN0_START_SLOT_SHIFT 0 /* AIF1RX_CHAN0_START_SLOT - [5:0] */
1989#define WM8915_AIF1RX_CHAN0_START_SLOT_WIDTH 6 /* AIF1RX_CHAN0_START_SLOT - [5:0] */
1990
1991/*
1992 * R784 (0x310) - AIF1RX Channel 1 Configuration
1993 */
1994#define WM8915_AIF1RX_CHAN1_DAT_INV 0x8000 /* AIF1RX_CHAN1_DAT_INV */
1995#define WM8915_AIF1RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN1_DAT_INV */
1996#define WM8915_AIF1RX_CHAN1_DAT_INV_SHIFT 15 /* AIF1RX_CHAN1_DAT_INV */
1997#define WM8915_AIF1RX_CHAN1_DAT_INV_WIDTH 1 /* AIF1RX_CHAN1_DAT_INV */
1998#define WM8915_AIF1RX_CHAN1_SPACING_MASK 0x7E00 /* AIF1RX_CHAN1_SPACING - [14:9] */
1999#define WM8915_AIF1RX_CHAN1_SPACING_SHIFT 9 /* AIF1RX_CHAN1_SPACING - [14:9] */
2000#define WM8915_AIF1RX_CHAN1_SPACING_WIDTH 6 /* AIF1RX_CHAN1_SPACING - [14:9] */
2001#define WM8915_AIF1RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN1_SLOTS - [8:6] */
2002#define WM8915_AIF1RX_CHAN1_SLOTS_SHIFT 6 /* AIF1RX_CHAN1_SLOTS - [8:6] */
2003#define WM8915_AIF1RX_CHAN1_SLOTS_WIDTH 3 /* AIF1RX_CHAN1_SLOTS - [8:6] */
2004#define WM8915_AIF1RX_CHAN1_START_SLOT_MASK 0x003F /* AIF1RX_CHAN1_START_SLOT - [5:0] */
2005#define WM8915_AIF1RX_CHAN1_START_SLOT_SHIFT 0 /* AIF1RX_CHAN1_START_SLOT - [5:0] */
2006#define WM8915_AIF1RX_CHAN1_START_SLOT_WIDTH 6 /* AIF1RX_CHAN1_START_SLOT - [5:0] */
2007
2008/*
2009 * R785 (0x311) - AIF1RX Channel 2 Configuration
2010 */
2011#define WM8915_AIF1RX_CHAN2_DAT_INV 0x8000 /* AIF1RX_CHAN2_DAT_INV */
2012#define WM8915_AIF1RX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN2_DAT_INV */
2013#define WM8915_AIF1RX_CHAN2_DAT_INV_SHIFT 15 /* AIF1RX_CHAN2_DAT_INV */
2014#define WM8915_AIF1RX_CHAN2_DAT_INV_WIDTH 1 /* AIF1RX_CHAN2_DAT_INV */
2015#define WM8915_AIF1RX_CHAN2_SPACING_MASK 0x7E00 /* AIF1RX_CHAN2_SPACING - [14:9] */
2016#define WM8915_AIF1RX_CHAN2_SPACING_SHIFT 9 /* AIF1RX_CHAN2_SPACING - [14:9] */
2017#define WM8915_AIF1RX_CHAN2_SPACING_WIDTH 6 /* AIF1RX_CHAN2_SPACING - [14:9] */
2018#define WM8915_AIF1RX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN2_SLOTS - [8:6] */
2019#define WM8915_AIF1RX_CHAN2_SLOTS_SHIFT 6 /* AIF1RX_CHAN2_SLOTS - [8:6] */
2020#define WM8915_AIF1RX_CHAN2_SLOTS_WIDTH 3 /* AIF1RX_CHAN2_SLOTS - [8:6] */
2021#define WM8915_AIF1RX_CHAN2_START_SLOT_MASK 0x003F /* AIF1RX_CHAN2_START_SLOT - [5:0] */
2022#define WM8915_AIF1RX_CHAN2_START_SLOT_SHIFT 0 /* AIF1RX_CHAN2_START_SLOT - [5:0] */
2023#define WM8915_AIF1RX_CHAN2_START_SLOT_WIDTH 6 /* AIF1RX_CHAN2_START_SLOT - [5:0] */
2024
2025/*
2026 * R786 (0x312) - AIF1RX Channel 3 Configuration
2027 */
2028#define WM8915_AIF1RX_CHAN3_DAT_INV 0x8000 /* AIF1RX_CHAN3_DAT_INV */
2029#define WM8915_AIF1RX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN3_DAT_INV */
2030#define WM8915_AIF1RX_CHAN3_DAT_INV_SHIFT 15 /* AIF1RX_CHAN3_DAT_INV */
2031#define WM8915_AIF1RX_CHAN3_DAT_INV_WIDTH 1 /* AIF1RX_CHAN3_DAT_INV */
2032#define WM8915_AIF1RX_CHAN3_SPACING_MASK 0x7E00 /* AIF1RX_CHAN3_SPACING - [14:9] */
2033#define WM8915_AIF1RX_CHAN3_SPACING_SHIFT 9 /* AIF1RX_CHAN3_SPACING - [14:9] */
2034#define WM8915_AIF1RX_CHAN3_SPACING_WIDTH 6 /* AIF1RX_CHAN3_SPACING - [14:9] */
2035#define WM8915_AIF1RX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN3_SLOTS - [8:6] */
2036#define WM8915_AIF1RX_CHAN3_SLOTS_SHIFT 6 /* AIF1RX_CHAN3_SLOTS - [8:6] */
2037#define WM8915_AIF1RX_CHAN3_SLOTS_WIDTH 3 /* AIF1RX_CHAN3_SLOTS - [8:6] */
2038#define WM8915_AIF1RX_CHAN3_START_SLOT_MASK 0x003F /* AIF1RX_CHAN3_START_SLOT - [5:0] */
2039#define WM8915_AIF1RX_CHAN3_START_SLOT_SHIFT 0 /* AIF1RX_CHAN3_START_SLOT - [5:0] */
2040#define WM8915_AIF1RX_CHAN3_START_SLOT_WIDTH 6 /* AIF1RX_CHAN3_START_SLOT - [5:0] */
2041
2042/*
2043 * R787 (0x313) - AIF1RX Channel 4 Configuration
2044 */
2045#define WM8915_AIF1RX_CHAN4_DAT_INV 0x8000 /* AIF1RX_CHAN4_DAT_INV */
2046#define WM8915_AIF1RX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN4_DAT_INV */
2047#define WM8915_AIF1RX_CHAN4_DAT_INV_SHIFT 15 /* AIF1RX_CHAN4_DAT_INV */
2048#define WM8915_AIF1RX_CHAN4_DAT_INV_WIDTH 1 /* AIF1RX_CHAN4_DAT_INV */
2049#define WM8915_AIF1RX_CHAN4_SPACING_MASK 0x7E00 /* AIF1RX_CHAN4_SPACING - [14:9] */
2050#define WM8915_AIF1RX_CHAN4_SPACING_SHIFT 9 /* AIF1RX_CHAN4_SPACING - [14:9] */
2051#define WM8915_AIF1RX_CHAN4_SPACING_WIDTH 6 /* AIF1RX_CHAN4_SPACING - [14:9] */
2052#define WM8915_AIF1RX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN4_SLOTS - [8:6] */
2053#define WM8915_AIF1RX_CHAN4_SLOTS_SHIFT 6 /* AIF1RX_CHAN4_SLOTS - [8:6] */
2054#define WM8915_AIF1RX_CHAN4_SLOTS_WIDTH 3 /* AIF1RX_CHAN4_SLOTS - [8:6] */
2055#define WM8915_AIF1RX_CHAN4_START_SLOT_MASK 0x003F /* AIF1RX_CHAN4_START_SLOT - [5:0] */
2056#define WM8915_AIF1RX_CHAN4_START_SLOT_SHIFT 0 /* AIF1RX_CHAN4_START_SLOT - [5:0] */
2057#define WM8915_AIF1RX_CHAN4_START_SLOT_WIDTH 6 /* AIF1RX_CHAN4_START_SLOT - [5:0] */
2058
2059/*
2060 * R788 (0x314) - AIF1RX Channel 5 Configuration
2061 */
2062#define WM8915_AIF1RX_CHAN5_DAT_INV 0x8000 /* AIF1RX_CHAN5_DAT_INV */
2063#define WM8915_AIF1RX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN5_DAT_INV */
2064#define WM8915_AIF1RX_CHAN5_DAT_INV_SHIFT 15 /* AIF1RX_CHAN5_DAT_INV */
2065#define WM8915_AIF1RX_CHAN5_DAT_INV_WIDTH 1 /* AIF1RX_CHAN5_DAT_INV */
2066#define WM8915_AIF1RX_CHAN5_SPACING_MASK 0x7E00 /* AIF1RX_CHAN5_SPACING - [14:9] */
2067#define WM8915_AIF1RX_CHAN5_SPACING_SHIFT 9 /* AIF1RX_CHAN5_SPACING - [14:9] */
2068#define WM8915_AIF1RX_CHAN5_SPACING_WIDTH 6 /* AIF1RX_CHAN5_SPACING - [14:9] */
2069#define WM8915_AIF1RX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN5_SLOTS - [8:6] */
2070#define WM8915_AIF1RX_CHAN5_SLOTS_SHIFT 6 /* AIF1RX_CHAN5_SLOTS - [8:6] */
2071#define WM8915_AIF1RX_CHAN5_SLOTS_WIDTH 3 /* AIF1RX_CHAN5_SLOTS - [8:6] */
2072#define WM8915_AIF1RX_CHAN5_START_SLOT_MASK 0x003F /* AIF1RX_CHAN5_START_SLOT - [5:0] */
2073#define WM8915_AIF1RX_CHAN5_START_SLOT_SHIFT 0 /* AIF1RX_CHAN5_START_SLOT - [5:0] */
2074#define WM8915_AIF1RX_CHAN5_START_SLOT_WIDTH 6 /* AIF1RX_CHAN5_START_SLOT - [5:0] */
2075
2076/*
2077 * R789 (0x315) - AIF1RX Mono Configuration
2078 */
2079#define WM8915_AIF1RX_CHAN4_MONO_MODE 0x0004 /* AIF1RX_CHAN4_MONO_MODE */
2080#define WM8915_AIF1RX_CHAN4_MONO_MODE_MASK 0x0004 /* AIF1RX_CHAN4_MONO_MODE */
2081#define WM8915_AIF1RX_CHAN4_MONO_MODE_SHIFT 2 /* AIF1RX_CHAN4_MONO_MODE */
2082#define WM8915_AIF1RX_CHAN4_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN4_MONO_MODE */
2083#define WM8915_AIF1RX_CHAN2_MONO_MODE 0x0002 /* AIF1RX_CHAN2_MONO_MODE */
2084#define WM8915_AIF1RX_CHAN2_MONO_MODE_MASK 0x0002 /* AIF1RX_CHAN2_MONO_MODE */
2085#define WM8915_AIF1RX_CHAN2_MONO_MODE_SHIFT 1 /* AIF1RX_CHAN2_MONO_MODE */
2086#define WM8915_AIF1RX_CHAN2_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN2_MONO_MODE */
2087#define WM8915_AIF1RX_CHAN0_MONO_MODE 0x0001 /* AIF1RX_CHAN0_MONO_MODE */
2088#define WM8915_AIF1RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF1RX_CHAN0_MONO_MODE */
2089#define WM8915_AIF1RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF1RX_CHAN0_MONO_MODE */
2090#define WM8915_AIF1RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN0_MONO_MODE */
2091
2092/*
2093 * R794 (0x31A) - AIF1TX Test
2094 */
2095#define WM8915_AIF1TX45_DITHER_ENA 0x0004 /* AIF1TX45_DITHER_ENA */
2096#define WM8915_AIF1TX45_DITHER_ENA_MASK 0x0004 /* AIF1TX45_DITHER_ENA */
2097#define WM8915_AIF1TX45_DITHER_ENA_SHIFT 2 /* AIF1TX45_DITHER_ENA */
2098#define WM8915_AIF1TX45_DITHER_ENA_WIDTH 1 /* AIF1TX45_DITHER_ENA */
2099#define WM8915_AIF1TX23_DITHER_ENA 0x0002 /* AIF1TX23_DITHER_ENA */
2100#define WM8915_AIF1TX23_DITHER_ENA_MASK 0x0002 /* AIF1TX23_DITHER_ENA */
2101#define WM8915_AIF1TX23_DITHER_ENA_SHIFT 1 /* AIF1TX23_DITHER_ENA */
2102#define WM8915_AIF1TX23_DITHER_ENA_WIDTH 1 /* AIF1TX23_DITHER_ENA */
2103#define WM8915_AIF1TX01_DITHER_ENA 0x0001 /* AIF1TX01_DITHER_ENA */
2104#define WM8915_AIF1TX01_DITHER_ENA_MASK 0x0001 /* AIF1TX01_DITHER_ENA */
2105#define WM8915_AIF1TX01_DITHER_ENA_SHIFT 0 /* AIF1TX01_DITHER_ENA */
2106#define WM8915_AIF1TX01_DITHER_ENA_WIDTH 1 /* AIF1TX01_DITHER_ENA */
2107
2108/*
2109 * R800 (0x320) - AIF2 Control
2110 */
2111#define WM8915_AIF2_TRI 0x0004 /* AIF2_TRI */
2112#define WM8915_AIF2_TRI_MASK 0x0004 /* AIF2_TRI */
2113#define WM8915_AIF2_TRI_SHIFT 2 /* AIF2_TRI */
2114#define WM8915_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
2115#define WM8915_AIF2_FMT_MASK 0x0003 /* AIF2_FMT - [1:0] */
2116#define WM8915_AIF2_FMT_SHIFT 0 /* AIF2_FMT - [1:0] */
2117#define WM8915_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [1:0] */
2118
2119/*
2120 * R801 (0x321) - AIF2 BCLK
2121 */
2122#define WM8915_AIF2_BCLK_INV 0x0400 /* AIF2_BCLK_INV */
2123#define WM8915_AIF2_BCLK_INV_MASK 0x0400 /* AIF2_BCLK_INV */
2124#define WM8915_AIF2_BCLK_INV_SHIFT 10 /* AIF2_BCLK_INV */
2125#define WM8915_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
2126#define WM8915_AIF2_BCLK_FRC 0x0200 /* AIF2_BCLK_FRC */
2127#define WM8915_AIF2_BCLK_FRC_MASK 0x0200 /* AIF2_BCLK_FRC */
2128#define WM8915_AIF2_BCLK_FRC_SHIFT 9 /* AIF2_BCLK_FRC */
2129#define WM8915_AIF2_BCLK_FRC_WIDTH 1 /* AIF2_BCLK_FRC */
2130#define WM8915_AIF2_BCLK_MSTR 0x0100 /* AIF2_BCLK_MSTR */
2131#define WM8915_AIF2_BCLK_MSTR_MASK 0x0100 /* AIF2_BCLK_MSTR */
2132#define WM8915_AIF2_BCLK_MSTR_SHIFT 8 /* AIF2_BCLK_MSTR */
2133#define WM8915_AIF2_BCLK_MSTR_WIDTH 1 /* AIF2_BCLK_MSTR */
2134#define WM8915_AIF2_BCLK_DIV_MASK 0x000F /* AIF2_BCLK_DIV - [3:0] */
2135#define WM8915_AIF2_BCLK_DIV_SHIFT 0 /* AIF2_BCLK_DIV - [3:0] */
2136#define WM8915_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [3:0] */
2137
2138/*
2139 * R802 (0x322) - AIF2 TX LRCLK(1)
2140 */
2141#define WM8915_AIF2TX_RATE_MASK 0x07FF /* AIF2TX_RATE - [10:0] */
2142#define WM8915_AIF2TX_RATE_SHIFT 0 /* AIF2TX_RATE - [10:0] */
2143#define WM8915_AIF2TX_RATE_WIDTH 11 /* AIF2TX_RATE - [10:0] */
2144
2145/*
2146 * R803 (0x323) - AIF2 TX LRCLK(2)
2147 */
2148#define WM8915_AIF2TX_LRCLK_MODE 0x0008 /* AIF2TX_LRCLK_MODE */
2149#define WM8915_AIF2TX_LRCLK_MODE_MASK 0x0008 /* AIF2TX_LRCLK_MODE */
2150#define WM8915_AIF2TX_LRCLK_MODE_SHIFT 3 /* AIF2TX_LRCLK_MODE */
2151#define WM8915_AIF2TX_LRCLK_MODE_WIDTH 1 /* AIF2TX_LRCLK_MODE */
2152#define WM8915_AIF2TX_LRCLK_INV 0x0004 /* AIF2TX_LRCLK_INV */
2153#define WM8915_AIF2TX_LRCLK_INV_MASK 0x0004 /* AIF2TX_LRCLK_INV */
2154#define WM8915_AIF2TX_LRCLK_INV_SHIFT 2 /* AIF2TX_LRCLK_INV */
2155#define WM8915_AIF2TX_LRCLK_INV_WIDTH 1 /* AIF2TX_LRCLK_INV */
2156#define WM8915_AIF2TX_LRCLK_FRC 0x0002 /* AIF2TX_LRCLK_FRC */
2157#define WM8915_AIF2TX_LRCLK_FRC_MASK 0x0002 /* AIF2TX_LRCLK_FRC */
2158#define WM8915_AIF2TX_LRCLK_FRC_SHIFT 1 /* AIF2TX_LRCLK_FRC */
2159#define WM8915_AIF2TX_LRCLK_FRC_WIDTH 1 /* AIF2TX_LRCLK_FRC */
2160#define WM8915_AIF2TX_LRCLK_MSTR 0x0001 /* AIF2TX_LRCLK_MSTR */
2161#define WM8915_AIF2TX_LRCLK_MSTR_MASK 0x0001 /* AIF2TX_LRCLK_MSTR */
2162#define WM8915_AIF2TX_LRCLK_MSTR_SHIFT 0 /* AIF2TX_LRCLK_MSTR */
2163#define WM8915_AIF2TX_LRCLK_MSTR_WIDTH 1 /* AIF2TX_LRCLK_MSTR */
2164
2165/*
2166 * R804 (0x324) - AIF2 RX LRCLK(1)
2167 */
2168#define WM8915_AIF2RX_RATE_MASK 0x07FF /* AIF2RX_RATE - [10:0] */
2169#define WM8915_AIF2RX_RATE_SHIFT 0 /* AIF2RX_RATE - [10:0] */
2170#define WM8915_AIF2RX_RATE_WIDTH 11 /* AIF2RX_RATE - [10:0] */
2171
2172/*
2173 * R805 (0x325) - AIF2 RX LRCLK(2)
2174 */
2175#define WM8915_AIF2RX_LRCLK_INV 0x0004 /* AIF2RX_LRCLK_INV */
2176#define WM8915_AIF2RX_LRCLK_INV_MASK 0x0004 /* AIF2RX_LRCLK_INV */
2177#define WM8915_AIF2RX_LRCLK_INV_SHIFT 2 /* AIF2RX_LRCLK_INV */
2178#define WM8915_AIF2RX_LRCLK_INV_WIDTH 1 /* AIF2RX_LRCLK_INV */
2179#define WM8915_AIF2RX_LRCLK_FRC 0x0002 /* AIF2RX_LRCLK_FRC */
2180#define WM8915_AIF2RX_LRCLK_FRC_MASK 0x0002 /* AIF2RX_LRCLK_FRC */
2181#define WM8915_AIF2RX_LRCLK_FRC_SHIFT 1 /* AIF2RX_LRCLK_FRC */
2182#define WM8915_AIF2RX_LRCLK_FRC_WIDTH 1 /* AIF2RX_LRCLK_FRC */
2183#define WM8915_AIF2RX_LRCLK_MSTR 0x0001 /* AIF2RX_LRCLK_MSTR */
2184#define WM8915_AIF2RX_LRCLK_MSTR_MASK 0x0001 /* AIF2RX_LRCLK_MSTR */
2185#define WM8915_AIF2RX_LRCLK_MSTR_SHIFT 0 /* AIF2RX_LRCLK_MSTR */
2186#define WM8915_AIF2RX_LRCLK_MSTR_WIDTH 1 /* AIF2RX_LRCLK_MSTR */
2187
2188/*
2189 * R806 (0x326) - AIF2TX Data Configuration (1)
2190 */
2191#define WM8915_AIF2TX_WL_MASK 0xFF00 /* AIF2TX_WL - [15:8] */
2192#define WM8915_AIF2TX_WL_SHIFT 8 /* AIF2TX_WL - [15:8] */
2193#define WM8915_AIF2TX_WL_WIDTH 8 /* AIF2TX_WL - [15:8] */
2194#define WM8915_AIF2TX_SLOT_LEN_MASK 0x00FF /* AIF2TX_SLOT_LEN - [7:0] */
2195#define WM8915_AIF2TX_SLOT_LEN_SHIFT 0 /* AIF2TX_SLOT_LEN - [7:0] */
2196#define WM8915_AIF2TX_SLOT_LEN_WIDTH 8 /* AIF2TX_SLOT_LEN - [7:0] */
2197
2198/*
2199 * R807 (0x327) - AIF2TX Data Configuration (2)
2200 */
2201#define WM8915_AIF2TX_DAT_TRI 0x0001 /* AIF2TX_DAT_TRI */
2202#define WM8915_AIF2TX_DAT_TRI_MASK 0x0001 /* AIF2TX_DAT_TRI */
2203#define WM8915_AIF2TX_DAT_TRI_SHIFT 0 /* AIF2TX_DAT_TRI */
2204#define WM8915_AIF2TX_DAT_TRI_WIDTH 1 /* AIF2TX_DAT_TRI */
2205
2206/*
2207 * R808 (0x328) - AIF2RX Data Configuration
2208 */
2209#define WM8915_AIF2RX_WL_MASK 0xFF00 /* AIF2RX_WL - [15:8] */
2210#define WM8915_AIF2RX_WL_SHIFT 8 /* AIF2RX_WL - [15:8] */
2211#define WM8915_AIF2RX_WL_WIDTH 8 /* AIF2RX_WL - [15:8] */
2212#define WM8915_AIF2RX_SLOT_LEN_MASK 0x00FF /* AIF2RX_SLOT_LEN - [7:0] */
2213#define WM8915_AIF2RX_SLOT_LEN_SHIFT 0 /* AIF2RX_SLOT_LEN - [7:0] */
2214#define WM8915_AIF2RX_SLOT_LEN_WIDTH 8 /* AIF2RX_SLOT_LEN - [7:0] */
2215
2216/*
2217 * R809 (0x329) - AIF2TX Channel 0 Configuration
2218 */
2219#define WM8915_AIF2TX_CHAN0_DAT_INV 0x8000 /* AIF2TX_CHAN0_DAT_INV */
2220#define WM8915_AIF2TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN0_DAT_INV */
2221#define WM8915_AIF2TX_CHAN0_DAT_INV_SHIFT 15 /* AIF2TX_CHAN0_DAT_INV */
2222#define WM8915_AIF2TX_CHAN0_DAT_INV_WIDTH 1 /* AIF2TX_CHAN0_DAT_INV */
2223#define WM8915_AIF2TX_CHAN0_SPACING_MASK 0x7E00 /* AIF2TX_CHAN0_SPACING - [14:9] */
2224#define WM8915_AIF2TX_CHAN0_SPACING_SHIFT 9 /* AIF2TX_CHAN0_SPACING - [14:9] */
2225#define WM8915_AIF2TX_CHAN0_SPACING_WIDTH 6 /* AIF2TX_CHAN0_SPACING - [14:9] */
2226#define WM8915_AIF2TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN0_SLOTS - [8:6] */
2227#define WM8915_AIF2TX_CHAN0_SLOTS_SHIFT 6 /* AIF2TX_CHAN0_SLOTS - [8:6] */
2228#define WM8915_AIF2TX_CHAN0_SLOTS_WIDTH 3 /* AIF2TX_CHAN0_SLOTS - [8:6] */
2229#define WM8915_AIF2TX_CHAN0_START_SLOT_MASK 0x003F /* AIF2TX_CHAN0_START_SLOT - [5:0] */
2230#define WM8915_AIF2TX_CHAN0_START_SLOT_SHIFT 0 /* AIF2TX_CHAN0_START_SLOT - [5:0] */
2231#define WM8915_AIF2TX_CHAN0_START_SLOT_WIDTH 6 /* AIF2TX_CHAN0_START_SLOT - [5:0] */
2232
2233/*
2234 * R810 (0x32A) - AIF2TX Channel 1 Configuration
2235 */
2236#define WM8915_AIF2TX_CHAN1_DAT_INV 0x8000 /* AIF2TX_CHAN1_DAT_INV */
2237#define WM8915_AIF2TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN1_DAT_INV */
2238#define WM8915_AIF2TX_CHAN1_DAT_INV_SHIFT 15 /* AIF2TX_CHAN1_DAT_INV */
2239#define WM8915_AIF2TX_CHAN1_DAT_INV_WIDTH 1 /* AIF2TX_CHAN1_DAT_INV */
2240#define WM8915_AIF2TX_CHAN1_SPACING_MASK 0x7E00 /* AIF2TX_CHAN1_SPACING - [14:9] */
2241#define WM8915_AIF2TX_CHAN1_SPACING_SHIFT 9 /* AIF2TX_CHAN1_SPACING - [14:9] */
2242#define WM8915_AIF2TX_CHAN1_SPACING_WIDTH 6 /* AIF2TX_CHAN1_SPACING - [14:9] */
2243#define WM8915_AIF2TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN1_SLOTS - [8:6] */
2244#define WM8915_AIF2TX_CHAN1_SLOTS_SHIFT 6 /* AIF2TX_CHAN1_SLOTS - [8:6] */
2245#define WM8915_AIF2TX_CHAN1_SLOTS_WIDTH 3 /* AIF2TX_CHAN1_SLOTS - [8:6] */
2246#define WM8915_AIF2TX_CHAN1_START_SLOT_MASK 0x003F /* AIF2TX_CHAN1_START_SLOT - [5:0] */
2247#define WM8915_AIF2TX_CHAN1_START_SLOT_SHIFT 0 /* AIF2TX_CHAN1_START_SLOT - [5:0] */
2248#define WM8915_AIF2TX_CHAN1_START_SLOT_WIDTH 6 /* AIF2TX_CHAN1_START_SLOT - [5:0] */
2249
2250/*
2251 * R811 (0x32B) - AIF2RX Channel 0 Configuration
2252 */
2253#define WM8915_AIF2RX_CHAN0_DAT_INV 0x8000 /* AIF2RX_CHAN0_DAT_INV */
2254#define WM8915_AIF2RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN0_DAT_INV */
2255#define WM8915_AIF2RX_CHAN0_DAT_INV_SHIFT 15 /* AIF2RX_CHAN0_DAT_INV */
2256#define WM8915_AIF2RX_CHAN0_DAT_INV_WIDTH 1 /* AIF2RX_CHAN0_DAT_INV */
2257#define WM8915_AIF2RX_CHAN0_SPACING_MASK 0x7E00 /* AIF2RX_CHAN0_SPACING - [14:9] */
2258#define WM8915_AIF2RX_CHAN0_SPACING_SHIFT 9 /* AIF2RX_CHAN0_SPACING - [14:9] */
2259#define WM8915_AIF2RX_CHAN0_SPACING_WIDTH 6 /* AIF2RX_CHAN0_SPACING - [14:9] */
2260#define WM8915_AIF2RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN0_SLOTS - [8:6] */
2261#define WM8915_AIF2RX_CHAN0_SLOTS_SHIFT 6 /* AIF2RX_CHAN0_SLOTS - [8:6] */
2262#define WM8915_AIF2RX_CHAN0_SLOTS_WIDTH 3 /* AIF2RX_CHAN0_SLOTS - [8:6] */
2263#define WM8915_AIF2RX_CHAN0_START_SLOT_MASK 0x003F /* AIF2RX_CHAN0_START_SLOT - [5:0] */
2264#define WM8915_AIF2RX_CHAN0_START_SLOT_SHIFT 0 /* AIF2RX_CHAN0_START_SLOT - [5:0] */
2265#define WM8915_AIF2RX_CHAN0_START_SLOT_WIDTH 6 /* AIF2RX_CHAN0_START_SLOT - [5:0] */
2266
2267/*
2268 * R812 (0x32C) - AIF2RX Channel 1 Configuration
2269 */
2270#define WM8915_AIF2RX_CHAN1_DAT_INV 0x8000 /* AIF2RX_CHAN1_DAT_INV */
2271#define WM8915_AIF2RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN1_DAT_INV */
2272#define WM8915_AIF2RX_CHAN1_DAT_INV_SHIFT 15 /* AIF2RX_CHAN1_DAT_INV */
2273#define WM8915_AIF2RX_CHAN1_DAT_INV_WIDTH 1 /* AIF2RX_CHAN1_DAT_INV */
2274#define WM8915_AIF2RX_CHAN1_SPACING_MASK 0x7E00 /* AIF2RX_CHAN1_SPACING - [14:9] */
2275#define WM8915_AIF2RX_CHAN1_SPACING_SHIFT 9 /* AIF2RX_CHAN1_SPACING - [14:9] */
2276#define WM8915_AIF2RX_CHAN1_SPACING_WIDTH 6 /* AIF2RX_CHAN1_SPACING - [14:9] */
2277#define WM8915_AIF2RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN1_SLOTS - [8:6] */
2278#define WM8915_AIF2RX_CHAN1_SLOTS_SHIFT 6 /* AIF2RX_CHAN1_SLOTS - [8:6] */
2279#define WM8915_AIF2RX_CHAN1_SLOTS_WIDTH 3 /* AIF2RX_CHAN1_SLOTS - [8:6] */
2280#define WM8915_AIF2RX_CHAN1_START_SLOT_MASK 0x003F /* AIF2RX_CHAN1_START_SLOT - [5:0] */
2281#define WM8915_AIF2RX_CHAN1_START_SLOT_SHIFT 0 /* AIF2RX_CHAN1_START_SLOT - [5:0] */
2282#define WM8915_AIF2RX_CHAN1_START_SLOT_WIDTH 6 /* AIF2RX_CHAN1_START_SLOT - [5:0] */
2283
2284/*
2285 * R813 (0x32D) - AIF2RX Mono Configuration
2286 */
2287#define WM8915_AIF2RX_CHAN0_MONO_MODE 0x0001 /* AIF2RX_CHAN0_MONO_MODE */
2288#define WM8915_AIF2RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF2RX_CHAN0_MONO_MODE */
2289#define WM8915_AIF2RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF2RX_CHAN0_MONO_MODE */
2290#define WM8915_AIF2RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF2RX_CHAN0_MONO_MODE */
2291
2292/*
2293 * R815 (0x32F) - AIF2TX Test
2294 */
2295#define WM8915_AIF2TX_DITHER_ENA 0x0001 /* AIF2TX_DITHER_ENA */
2296#define WM8915_AIF2TX_DITHER_ENA_MASK 0x0001 /* AIF2TX_DITHER_ENA */
2297#define WM8915_AIF2TX_DITHER_ENA_SHIFT 0 /* AIF2TX_DITHER_ENA */
2298#define WM8915_AIF2TX_DITHER_ENA_WIDTH 1 /* AIF2TX_DITHER_ENA */
2299
2300/*
2301 * R1024 (0x400) - DSP1 TX Left Volume
2302 */
2303#define WM8915_DSP1TX_VU 0x0100 /* DSP1TX_VU */
2304#define WM8915_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */
2305#define WM8915_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */
2306#define WM8915_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */
2307#define WM8915_DSP1TXL_VOL_MASK 0x00FF /* DSP1TXL_VOL - [7:0] */
2308#define WM8915_DSP1TXL_VOL_SHIFT 0 /* DSP1TXL_VOL - [7:0] */
2309#define WM8915_DSP1TXL_VOL_WIDTH 8 /* DSP1TXL_VOL - [7:0] */
2310
2311/*
2312 * R1025 (0x401) - DSP1 TX Right Volume
2313 */
2314#define WM8915_DSP1TX_VU 0x0100 /* DSP1TX_VU */
2315#define WM8915_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */
2316#define WM8915_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */
2317#define WM8915_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */
2318#define WM8915_DSP1TXR_VOL_MASK 0x00FF /* DSP1TXR_VOL - [7:0] */
2319#define WM8915_DSP1TXR_VOL_SHIFT 0 /* DSP1TXR_VOL - [7:0] */
2320#define WM8915_DSP1TXR_VOL_WIDTH 8 /* DSP1TXR_VOL - [7:0] */
2321
2322/*
2323 * R1026 (0x402) - DSP1 RX Left Volume
2324 */
2325#define WM8915_DSP1RX_VU 0x0100 /* DSP1RX_VU */
2326#define WM8915_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */
2327#define WM8915_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */
2328#define WM8915_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */
2329#define WM8915_DSP1RXL_VOL_MASK 0x00FF /* DSP1RXL_VOL - [7:0] */
2330#define WM8915_DSP1RXL_VOL_SHIFT 0 /* DSP1RXL_VOL - [7:0] */
2331#define WM8915_DSP1RXL_VOL_WIDTH 8 /* DSP1RXL_VOL - [7:0] */
2332
2333/*
2334 * R1027 (0x403) - DSP1 RX Right Volume
2335 */
2336#define WM8915_DSP1RX_VU 0x0100 /* DSP1RX_VU */
2337#define WM8915_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */
2338#define WM8915_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */
2339#define WM8915_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */
2340#define WM8915_DSP1RXR_VOL_MASK 0x00FF /* DSP1RXR_VOL - [7:0] */
2341#define WM8915_DSP1RXR_VOL_SHIFT 0 /* DSP1RXR_VOL - [7:0] */
2342#define WM8915_DSP1RXR_VOL_WIDTH 8 /* DSP1RXR_VOL - [7:0] */
2343
2344/*
2345 * R1040 (0x410) - DSP1 TX Filters
2346 */
2347#define WM8915_DSP1TX_NF 0x2000 /* DSP1TX_NF */
2348#define WM8915_DSP1TX_NF_MASK 0x2000 /* DSP1TX_NF */
2349#define WM8915_DSP1TX_NF_SHIFT 13 /* DSP1TX_NF */
2350#define WM8915_DSP1TX_NF_WIDTH 1 /* DSP1TX_NF */
2351#define WM8915_DSP1TXL_HPF 0x1000 /* DSP1TXL_HPF */
2352#define WM8915_DSP1TXL_HPF_MASK 0x1000 /* DSP1TXL_HPF */
2353#define WM8915_DSP1TXL_HPF_SHIFT 12 /* DSP1TXL_HPF */
2354#define WM8915_DSP1TXL_HPF_WIDTH 1 /* DSP1TXL_HPF */
2355#define WM8915_DSP1TXR_HPF 0x0800 /* DSP1TXR_HPF */
2356#define WM8915_DSP1TXR_HPF_MASK 0x0800 /* DSP1TXR_HPF */
2357#define WM8915_DSP1TXR_HPF_SHIFT 11 /* DSP1TXR_HPF */
2358#define WM8915_DSP1TXR_HPF_WIDTH 1 /* DSP1TXR_HPF */
2359#define WM8915_DSP1TX_HPF_MODE_MASK 0x0018 /* DSP1TX_HPF_MODE - [4:3] */
2360#define WM8915_DSP1TX_HPF_MODE_SHIFT 3 /* DSP1TX_HPF_MODE - [4:3] */
2361#define WM8915_DSP1TX_HPF_MODE_WIDTH 2 /* DSP1TX_HPF_MODE - [4:3] */
2362#define WM8915_DSP1TX_HPF_CUT_MASK 0x0007 /* DSP1TX_HPF_CUT - [2:0] */
2363#define WM8915_DSP1TX_HPF_CUT_SHIFT 0 /* DSP1TX_HPF_CUT - [2:0] */
2364#define WM8915_DSP1TX_HPF_CUT_WIDTH 3 /* DSP1TX_HPF_CUT - [2:0] */
2365
2366/*
2367 * R1056 (0x420) - DSP1 RX Filters (1)
2368 */
2369#define WM8915_DSP1RX_MUTE 0x0200 /* DSP1RX_MUTE */
2370#define WM8915_DSP1RX_MUTE_MASK 0x0200 /* DSP1RX_MUTE */
2371#define WM8915_DSP1RX_MUTE_SHIFT 9 /* DSP1RX_MUTE */
2372#define WM8915_DSP1RX_MUTE_WIDTH 1 /* DSP1RX_MUTE */
2373#define WM8915_DSP1RX_MONO 0x0080 /* DSP1RX_MONO */
2374#define WM8915_DSP1RX_MONO_MASK 0x0080 /* DSP1RX_MONO */
2375#define WM8915_DSP1RX_MONO_SHIFT 7 /* DSP1RX_MONO */
2376#define WM8915_DSP1RX_MONO_WIDTH 1 /* DSP1RX_MONO */
2377#define WM8915_DSP1RX_MUTERATE 0x0020 /* DSP1RX_MUTERATE */
2378#define WM8915_DSP1RX_MUTERATE_MASK 0x0020 /* DSP1RX_MUTERATE */
2379#define WM8915_DSP1RX_MUTERATE_SHIFT 5 /* DSP1RX_MUTERATE */
2380#define WM8915_DSP1RX_MUTERATE_WIDTH 1 /* DSP1RX_MUTERATE */
2381#define WM8915_DSP1RX_UNMUTE_RAMP 0x0010 /* DSP1RX_UNMUTE_RAMP */
2382#define WM8915_DSP1RX_UNMUTE_RAMP_MASK 0x0010 /* DSP1RX_UNMUTE_RAMP */
2383#define WM8915_DSP1RX_UNMUTE_RAMP_SHIFT 4 /* DSP1RX_UNMUTE_RAMP */
2384#define WM8915_DSP1RX_UNMUTE_RAMP_WIDTH 1 /* DSP1RX_UNMUTE_RAMP */
2385
2386/*
2387 * R1057 (0x421) - DSP1 RX Filters (2)
2388 */
2389#define WM8915_DSP1RX_3D_GAIN_MASK 0x3E00 /* DSP1RX_3D_GAIN - [13:9] */
2390#define WM8915_DSP1RX_3D_GAIN_SHIFT 9 /* DSP1RX_3D_GAIN - [13:9] */
2391#define WM8915_DSP1RX_3D_GAIN_WIDTH 5 /* DSP1RX_3D_GAIN - [13:9] */
2392#define WM8915_DSP1RX_3D_ENA 0x0100 /* DSP1RX_3D_ENA */
2393#define WM8915_DSP1RX_3D_ENA_MASK 0x0100 /* DSP1RX_3D_ENA */
2394#define WM8915_DSP1RX_3D_ENA_SHIFT 8 /* DSP1RX_3D_ENA */
2395#define WM8915_DSP1RX_3D_ENA_WIDTH 1 /* DSP1RX_3D_ENA */
2396
2397/*
2398 * R1088 (0x440) - DSP1 DRC (1)
2399 */
2400#define WM8915_DSP1DRC_SIG_DET_RMS_MASK 0xF800 /* DSP1DRC_SIG_DET_RMS - [15:11] */
2401#define WM8915_DSP1DRC_SIG_DET_RMS_SHIFT 11 /* DSP1DRC_SIG_DET_RMS - [15:11] */
2402#define WM8915_DSP1DRC_SIG_DET_RMS_WIDTH 5 /* DSP1DRC_SIG_DET_RMS - [15:11] */
2403#define WM8915_DSP1DRC_SIG_DET_PK_MASK 0x0600 /* DSP1DRC_SIG_DET_PK - [10:9] */
2404#define WM8915_DSP1DRC_SIG_DET_PK_SHIFT 9 /* DSP1DRC_SIG_DET_PK - [10:9] */
2405#define WM8915_DSP1DRC_SIG_DET_PK_WIDTH 2 /* DSP1DRC_SIG_DET_PK - [10:9] */
2406#define WM8915_DSP1DRC_NG_ENA 0x0100 /* DSP1DRC_NG_ENA */
2407#define WM8915_DSP1DRC_NG_ENA_MASK 0x0100 /* DSP1DRC_NG_ENA */
2408#define WM8915_DSP1DRC_NG_ENA_SHIFT 8 /* DSP1DRC_NG_ENA */
2409#define WM8915_DSP1DRC_NG_ENA_WIDTH 1 /* DSP1DRC_NG_ENA */
2410#define WM8915_DSP1DRC_SIG_DET_MODE 0x0080 /* DSP1DRC_SIG_DET_MODE */
2411#define WM8915_DSP1DRC_SIG_DET_MODE_MASK 0x0080 /* DSP1DRC_SIG_DET_MODE */
2412#define WM8915_DSP1DRC_SIG_DET_MODE_SHIFT 7 /* DSP1DRC_SIG_DET_MODE */
2413#define WM8915_DSP1DRC_SIG_DET_MODE_WIDTH 1 /* DSP1DRC_SIG_DET_MODE */
2414#define WM8915_DSP1DRC_SIG_DET 0x0040 /* DSP1DRC_SIG_DET */
2415#define WM8915_DSP1DRC_SIG_DET_MASK 0x0040 /* DSP1DRC_SIG_DET */
2416#define WM8915_DSP1DRC_SIG_DET_SHIFT 6 /* DSP1DRC_SIG_DET */
2417#define WM8915_DSP1DRC_SIG_DET_WIDTH 1 /* DSP1DRC_SIG_DET */
2418#define WM8915_DSP1DRC_KNEE2_OP_ENA 0x0020 /* DSP1DRC_KNEE2_OP_ENA */
2419#define WM8915_DSP1DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP1DRC_KNEE2_OP_ENA */
2420#define WM8915_DSP1DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP1DRC_KNEE2_OP_ENA */
2421#define WM8915_DSP1DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP1DRC_KNEE2_OP_ENA */
2422#define WM8915_DSP1DRC_QR 0x0010 /* DSP1DRC_QR */
2423#define WM8915_DSP1DRC_QR_MASK 0x0010 /* DSP1DRC_QR */
2424#define WM8915_DSP1DRC_QR_SHIFT 4 /* DSP1DRC_QR */
2425#define WM8915_DSP1DRC_QR_WIDTH 1 /* DSP1DRC_QR */
2426#define WM8915_DSP1DRC_ANTICLIP 0x0008 /* DSP1DRC_ANTICLIP */
2427#define WM8915_DSP1DRC_ANTICLIP_MASK 0x0008 /* DSP1DRC_ANTICLIP */
2428#define WM8915_DSP1DRC_ANTICLIP_SHIFT 3 /* DSP1DRC_ANTICLIP */
2429#define WM8915_DSP1DRC_ANTICLIP_WIDTH 1 /* DSP1DRC_ANTICLIP */
2430#define WM8915_DSP1RX_DRC_ENA 0x0004 /* DSP1RX_DRC_ENA */
2431#define WM8915_DSP1RX_DRC_ENA_MASK 0x0004 /* DSP1RX_DRC_ENA */
2432#define WM8915_DSP1RX_DRC_ENA_SHIFT 2 /* DSP1RX_DRC_ENA */
2433#define WM8915_DSP1RX_DRC_ENA_WIDTH 1 /* DSP1RX_DRC_ENA */
2434#define WM8915_DSP1TXL_DRC_ENA 0x0002 /* DSP1TXL_DRC_ENA */
2435#define WM8915_DSP1TXL_DRC_ENA_MASK 0x0002 /* DSP1TXL_DRC_ENA */
2436#define WM8915_DSP1TXL_DRC_ENA_SHIFT 1 /* DSP1TXL_DRC_ENA */
2437#define WM8915_DSP1TXL_DRC_ENA_WIDTH 1 /* DSP1TXL_DRC_ENA */
2438#define WM8915_DSP1TXR_DRC_ENA 0x0001 /* DSP1TXR_DRC_ENA */
2439#define WM8915_DSP1TXR_DRC_ENA_MASK 0x0001 /* DSP1TXR_DRC_ENA */
2440#define WM8915_DSP1TXR_DRC_ENA_SHIFT 0 /* DSP1TXR_DRC_ENA */
2441#define WM8915_DSP1TXR_DRC_ENA_WIDTH 1 /* DSP1TXR_DRC_ENA */
2442
2443/*
2444 * R1089 (0x441) - DSP1 DRC (2)
2445 */
2446#define WM8915_DSP1DRC_ATK_MASK 0x1E00 /* DSP1DRC_ATK - [12:9] */
2447#define WM8915_DSP1DRC_ATK_SHIFT 9 /* DSP1DRC_ATK - [12:9] */
2448#define WM8915_DSP1DRC_ATK_WIDTH 4 /* DSP1DRC_ATK - [12:9] */
2449#define WM8915_DSP1DRC_DCY_MASK 0x01E0 /* DSP1DRC_DCY - [8:5] */
2450#define WM8915_DSP1DRC_DCY_SHIFT 5 /* DSP1DRC_DCY - [8:5] */
2451#define WM8915_DSP1DRC_DCY_WIDTH 4 /* DSP1DRC_DCY - [8:5] */
2452#define WM8915_DSP1DRC_MINGAIN_MASK 0x001C /* DSP1DRC_MINGAIN - [4:2] */
2453#define WM8915_DSP1DRC_MINGAIN_SHIFT 2 /* DSP1DRC_MINGAIN - [4:2] */
2454#define WM8915_DSP1DRC_MINGAIN_WIDTH 3 /* DSP1DRC_MINGAIN - [4:2] */
2455#define WM8915_DSP1DRC_MAXGAIN_MASK 0x0003 /* DSP1DRC_MAXGAIN - [1:0] */
2456#define WM8915_DSP1DRC_MAXGAIN_SHIFT 0 /* DSP1DRC_MAXGAIN - [1:0] */
2457#define WM8915_DSP1DRC_MAXGAIN_WIDTH 2 /* DSP1DRC_MAXGAIN - [1:0] */
2458
2459/*
2460 * R1090 (0x442) - DSP1 DRC (3)
2461 */
2462#define WM8915_DSP1DRC_NG_MINGAIN_MASK 0xF000 /* DSP1DRC_NG_MINGAIN - [15:12] */
2463#define WM8915_DSP1DRC_NG_MINGAIN_SHIFT 12 /* DSP1DRC_NG_MINGAIN - [15:12] */
2464#define WM8915_DSP1DRC_NG_MINGAIN_WIDTH 4 /* DSP1DRC_NG_MINGAIN - [15:12] */
2465#define WM8915_DSP1DRC_NG_EXP_MASK 0x0C00 /* DSP1DRC_NG_EXP - [11:10] */
2466#define WM8915_DSP1DRC_NG_EXP_SHIFT 10 /* DSP1DRC_NG_EXP - [11:10] */
2467#define WM8915_DSP1DRC_NG_EXP_WIDTH 2 /* DSP1DRC_NG_EXP - [11:10] */
2468#define WM8915_DSP1DRC_QR_THR_MASK 0x0300 /* DSP1DRC_QR_THR - [9:8] */
2469#define WM8915_DSP1DRC_QR_THR_SHIFT 8 /* DSP1DRC_QR_THR - [9:8] */
2470#define WM8915_DSP1DRC_QR_THR_WIDTH 2 /* DSP1DRC_QR_THR - [9:8] */
2471#define WM8915_DSP1DRC_QR_DCY_MASK 0x00C0 /* DSP1DRC_QR_DCY - [7:6] */
2472#define WM8915_DSP1DRC_QR_DCY_SHIFT 6 /* DSP1DRC_QR_DCY - [7:6] */
2473#define WM8915_DSP1DRC_QR_DCY_WIDTH 2 /* DSP1DRC_QR_DCY - [7:6] */
2474#define WM8915_DSP1DRC_HI_COMP_MASK 0x0038 /* DSP1DRC_HI_COMP - [5:3] */
2475#define WM8915_DSP1DRC_HI_COMP_SHIFT 3 /* DSP1DRC_HI_COMP - [5:3] */
2476#define WM8915_DSP1DRC_HI_COMP_WIDTH 3 /* DSP1DRC_HI_COMP - [5:3] */
2477#define WM8915_DSP1DRC_LO_COMP_MASK 0x0007 /* DSP1DRC_LO_COMP - [2:0] */
2478#define WM8915_DSP1DRC_LO_COMP_SHIFT 0 /* DSP1DRC_LO_COMP - [2:0] */
2479#define WM8915_DSP1DRC_LO_COMP_WIDTH 3 /* DSP1DRC_LO_COMP - [2:0] */
2480
2481/*
2482 * R1091 (0x443) - DSP1 DRC (4)
2483 */
2484#define WM8915_DSP1DRC_KNEE_IP_MASK 0x07E0 /* DSP1DRC_KNEE_IP - [10:5] */
2485#define WM8915_DSP1DRC_KNEE_IP_SHIFT 5 /* DSP1DRC_KNEE_IP - [10:5] */
2486#define WM8915_DSP1DRC_KNEE_IP_WIDTH 6 /* DSP1DRC_KNEE_IP - [10:5] */
2487#define WM8915_DSP1DRC_KNEE_OP_MASK 0x001F /* DSP1DRC_KNEE_OP - [4:0] */
2488#define WM8915_DSP1DRC_KNEE_OP_SHIFT 0 /* DSP1DRC_KNEE_OP - [4:0] */
2489#define WM8915_DSP1DRC_KNEE_OP_WIDTH 5 /* DSP1DRC_KNEE_OP - [4:0] */
2490
2491/*
2492 * R1092 (0x444) - DSP1 DRC (5)
2493 */
2494#define WM8915_DSP1DRC_KNEE2_IP_MASK 0x03E0 /* DSP1DRC_KNEE2_IP - [9:5] */
2495#define WM8915_DSP1DRC_KNEE2_IP_SHIFT 5 /* DSP1DRC_KNEE2_IP - [9:5] */
2496#define WM8915_DSP1DRC_KNEE2_IP_WIDTH 5 /* DSP1DRC_KNEE2_IP - [9:5] */
2497#define WM8915_DSP1DRC_KNEE2_OP_MASK 0x001F /* DSP1DRC_KNEE2_OP - [4:0] */
2498#define WM8915_DSP1DRC_KNEE2_OP_SHIFT 0 /* DSP1DRC_KNEE2_OP - [4:0] */
2499#define WM8915_DSP1DRC_KNEE2_OP_WIDTH 5 /* DSP1DRC_KNEE2_OP - [4:0] */
2500
2501/*
2502 * R1152 (0x480) - DSP1 RX EQ Gains (1)
2503 */
2504#define WM8915_DSP1RX_EQ_B1_GAIN_MASK 0xF800 /* DSP1RX_EQ_B1_GAIN - [15:11] */
2505#define WM8915_DSP1RX_EQ_B1_GAIN_SHIFT 11 /* DSP1RX_EQ_B1_GAIN - [15:11] */
2506#define WM8915_DSP1RX_EQ_B1_GAIN_WIDTH 5 /* DSP1RX_EQ_B1_GAIN - [15:11] */
2507#define WM8915_DSP1RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B2_GAIN - [10:6] */
2508#define WM8915_DSP1RX_EQ_B2_GAIN_SHIFT 6 /* DSP1RX_EQ_B2_GAIN - [10:6] */
2509#define WM8915_DSP1RX_EQ_B2_GAIN_WIDTH 5 /* DSP1RX_EQ_B2_GAIN - [10:6] */
2510#define WM8915_DSP1RX_EQ_B3_GAIN_MASK 0x003E /* DSP1RX_EQ_B3_GAIN - [5:1] */
2511#define WM8915_DSP1RX_EQ_B3_GAIN_SHIFT 1 /* DSP1RX_EQ_B3_GAIN - [5:1] */
2512#define WM8915_DSP1RX_EQ_B3_GAIN_WIDTH 5 /* DSP1RX_EQ_B3_GAIN - [5:1] */
2513#define WM8915_DSP1RX_EQ_ENA 0x0001 /* DSP1RX_EQ_ENA */
2514#define WM8915_DSP1RX_EQ_ENA_MASK 0x0001 /* DSP1RX_EQ_ENA */
2515#define WM8915_DSP1RX_EQ_ENA_SHIFT 0 /* DSP1RX_EQ_ENA */
2516#define WM8915_DSP1RX_EQ_ENA_WIDTH 1 /* DSP1RX_EQ_ENA */
2517
2518/*
2519 * R1153 (0x481) - DSP1 RX EQ Gains (2)
2520 */
2521#define WM8915_DSP1RX_EQ_B4_GAIN_MASK 0xF800 /* DSP1RX_EQ_B4_GAIN - [15:11] */
2522#define WM8915_DSP1RX_EQ_B4_GAIN_SHIFT 11 /* DSP1RX_EQ_B4_GAIN - [15:11] */
2523#define WM8915_DSP1RX_EQ_B4_GAIN_WIDTH 5 /* DSP1RX_EQ_B4_GAIN - [15:11] */
2524#define WM8915_DSP1RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B5_GAIN - [10:6] */
2525#define WM8915_DSP1RX_EQ_B5_GAIN_SHIFT 6 /* DSP1RX_EQ_B5_GAIN - [10:6] */
2526#define WM8915_DSP1RX_EQ_B5_GAIN_WIDTH 5 /* DSP1RX_EQ_B5_GAIN - [10:6] */
2527
2528/*
2529 * R1154 (0x482) - DSP1 RX EQ Band 1 A
2530 */
2531#define WM8915_DSP1RX_EQ_B1_A_MASK 0xFFFF /* DSP1RX_EQ_B1_A - [15:0] */
2532#define WM8915_DSP1RX_EQ_B1_A_SHIFT 0 /* DSP1RX_EQ_B1_A - [15:0] */
2533#define WM8915_DSP1RX_EQ_B1_A_WIDTH 16 /* DSP1RX_EQ_B1_A - [15:0] */
2534
2535/*
2536 * R1155 (0x483) - DSP1 RX EQ Band 1 B
2537 */
2538#define WM8915_DSP1RX_EQ_B1_B_MASK 0xFFFF /* DSP1RX_EQ_B1_B - [15:0] */
2539#define WM8915_DSP1RX_EQ_B1_B_SHIFT 0 /* DSP1RX_EQ_B1_B - [15:0] */
2540#define WM8915_DSP1RX_EQ_B1_B_WIDTH 16 /* DSP1RX_EQ_B1_B - [15:0] */
2541
2542/*
2543 * R1156 (0x484) - DSP1 RX EQ Band 1 PG
2544 */
2545#define WM8915_DSP1RX_EQ_B1_PG_MASK 0xFFFF /* DSP1RX_EQ_B1_PG - [15:0] */
2546#define WM8915_DSP1RX_EQ_B1_PG_SHIFT 0 /* DSP1RX_EQ_B1_PG - [15:0] */
2547#define WM8915_DSP1RX_EQ_B1_PG_WIDTH 16 /* DSP1RX_EQ_B1_PG - [15:0] */
2548
2549/*
2550 * R1157 (0x485) - DSP1 RX EQ Band 2 A
2551 */
2552#define WM8915_DSP1RX_EQ_B2_A_MASK 0xFFFF /* DSP1RX_EQ_B2_A - [15:0] */
2553#define WM8915_DSP1RX_EQ_B2_A_SHIFT 0 /* DSP1RX_EQ_B2_A - [15:0] */
2554#define WM8915_DSP1RX_EQ_B2_A_WIDTH 16 /* DSP1RX_EQ_B2_A - [15:0] */
2555
2556/*
2557 * R1158 (0x486) - DSP1 RX EQ Band 2 B
2558 */
2559#define WM8915_DSP1RX_EQ_B2_B_MASK 0xFFFF /* DSP1RX_EQ_B2_B - [15:0] */
2560#define WM8915_DSP1RX_EQ_B2_B_SHIFT 0 /* DSP1RX_EQ_B2_B - [15:0] */
2561#define WM8915_DSP1RX_EQ_B2_B_WIDTH 16 /* DSP1RX_EQ_B2_B - [15:0] */
2562
2563/*
2564 * R1159 (0x487) - DSP1 RX EQ Band 2 C
2565 */
2566#define WM8915_DSP1RX_EQ_B2_C_MASK 0xFFFF /* DSP1RX_EQ_B2_C - [15:0] */
2567#define WM8915_DSP1RX_EQ_B2_C_SHIFT 0 /* DSP1RX_EQ_B2_C - [15:0] */
2568#define WM8915_DSP1RX_EQ_B2_C_WIDTH 16 /* DSP1RX_EQ_B2_C - [15:0] */
2569
2570/*
2571 * R1160 (0x488) - DSP1 RX EQ Band 2 PG
2572 */
2573#define WM8915_DSP1RX_EQ_B2_PG_MASK 0xFFFF /* DSP1RX_EQ_B2_PG - [15:0] */
2574#define WM8915_DSP1RX_EQ_B2_PG_SHIFT 0 /* DSP1RX_EQ_B2_PG - [15:0] */
2575#define WM8915_DSP1RX_EQ_B2_PG_WIDTH 16 /* DSP1RX_EQ_B2_PG - [15:0] */
2576
2577/*
2578 * R1161 (0x489) - DSP1 RX EQ Band 3 A
2579 */
2580#define WM8915_DSP1RX_EQ_B3_A_MASK 0xFFFF /* DSP1RX_EQ_B3_A - [15:0] */
2581#define WM8915_DSP1RX_EQ_B3_A_SHIFT 0 /* DSP1RX_EQ_B3_A - [15:0] */
2582#define WM8915_DSP1RX_EQ_B3_A_WIDTH 16 /* DSP1RX_EQ_B3_A - [15:0] */
2583
2584/*
2585 * R1162 (0x48A) - DSP1 RX EQ Band 3 B
2586 */
2587#define WM8915_DSP1RX_EQ_B3_B_MASK 0xFFFF /* DSP1RX_EQ_B3_B - [15:0] */
2588#define WM8915_DSP1RX_EQ_B3_B_SHIFT 0 /* DSP1RX_EQ_B3_B - [15:0] */
2589#define WM8915_DSP1RX_EQ_B3_B_WIDTH 16 /* DSP1RX_EQ_B3_B - [15:0] */
2590
2591/*
2592 * R1163 (0x48B) - DSP1 RX EQ Band 3 C
2593 */
2594#define WM8915_DSP1RX_EQ_B3_C_MASK 0xFFFF /* DSP1RX_EQ_B3_C - [15:0] */
2595#define WM8915_DSP1RX_EQ_B3_C_SHIFT 0 /* DSP1RX_EQ_B3_C - [15:0] */
2596#define WM8915_DSP1RX_EQ_B3_C_WIDTH 16 /* DSP1RX_EQ_B3_C - [15:0] */
2597
2598/*
2599 * R1164 (0x48C) - DSP1 RX EQ Band 3 PG
2600 */
2601#define WM8915_DSP1RX_EQ_B3_PG_MASK 0xFFFF /* DSP1RX_EQ_B3_PG - [15:0] */
2602#define WM8915_DSP1RX_EQ_B3_PG_SHIFT 0 /* DSP1RX_EQ_B3_PG - [15:0] */
2603#define WM8915_DSP1RX_EQ_B3_PG_WIDTH 16 /* DSP1RX_EQ_B3_PG - [15:0] */
2604
2605/*
2606 * R1165 (0x48D) - DSP1 RX EQ Band 4 A
2607 */
2608#define WM8915_DSP1RX_EQ_B4_A_MASK 0xFFFF /* DSP1RX_EQ_B4_A - [15:0] */
2609#define WM8915_DSP1RX_EQ_B4_A_SHIFT 0 /* DSP1RX_EQ_B4_A - [15:0] */
2610#define WM8915_DSP1RX_EQ_B4_A_WIDTH 16 /* DSP1RX_EQ_B4_A - [15:0] */
2611
2612/*
2613 * R1166 (0x48E) - DSP1 RX EQ Band 4 B
2614 */
2615#define WM8915_DSP1RX_EQ_B4_B_MASK 0xFFFF /* DSP1RX_EQ_B4_B - [15:0] */
2616#define WM8915_DSP1RX_EQ_B4_B_SHIFT 0 /* DSP1RX_EQ_B4_B - [15:0] */
2617#define WM8915_DSP1RX_EQ_B4_B_WIDTH 16 /* DSP1RX_EQ_B4_B - [15:0] */
2618
2619/*
2620 * R1167 (0x48F) - DSP1 RX EQ Band 4 C
2621 */
2622#define WM8915_DSP1RX_EQ_B4_C_MASK 0xFFFF /* DSP1RX_EQ_B4_C - [15:0] */
2623#define WM8915_DSP1RX_EQ_B4_C_SHIFT 0 /* DSP1RX_EQ_B4_C - [15:0] */
2624#define WM8915_DSP1RX_EQ_B4_C_WIDTH 16 /* DSP1RX_EQ_B4_C - [15:0] */
2625
2626/*
2627 * R1168 (0x490) - DSP1 RX EQ Band 4 PG
2628 */
2629#define WM8915_DSP1RX_EQ_B4_PG_MASK 0xFFFF /* DSP1RX_EQ_B4_PG - [15:0] */
2630#define WM8915_DSP1RX_EQ_B4_PG_SHIFT 0 /* DSP1RX_EQ_B4_PG - [15:0] */
2631#define WM8915_DSP1RX_EQ_B4_PG_WIDTH 16 /* DSP1RX_EQ_B4_PG - [15:0] */
2632
2633/*
2634 * R1169 (0x491) - DSP1 RX EQ Band 5 A
2635 */
2636#define WM8915_DSP1RX_EQ_B5_A_MASK 0xFFFF /* DSP1RX_EQ_B5_A - [15:0] */
2637#define WM8915_DSP1RX_EQ_B5_A_SHIFT 0 /* DSP1RX_EQ_B5_A - [15:0] */
2638#define WM8915_DSP1RX_EQ_B5_A_WIDTH 16 /* DSP1RX_EQ_B5_A - [15:0] */
2639
2640/*
2641 * R1170 (0x492) - DSP1 RX EQ Band 5 B
2642 */
2643#define WM8915_DSP1RX_EQ_B5_B_MASK 0xFFFF /* DSP1RX_EQ_B5_B - [15:0] */
2644#define WM8915_DSP1RX_EQ_B5_B_SHIFT 0 /* DSP1RX_EQ_B5_B - [15:0] */
2645#define WM8915_DSP1RX_EQ_B5_B_WIDTH 16 /* DSP1RX_EQ_B5_B - [15:0] */
2646
2647/*
2648 * R1171 (0x493) - DSP1 RX EQ Band 5 PG
2649 */
2650#define WM8915_DSP1RX_EQ_B5_PG_MASK 0xFFFF /* DSP1RX_EQ_B5_PG - [15:0] */
2651#define WM8915_DSP1RX_EQ_B5_PG_SHIFT 0 /* DSP1RX_EQ_B5_PG - [15:0] */
2652#define WM8915_DSP1RX_EQ_B5_PG_WIDTH 16 /* DSP1RX_EQ_B5_PG - [15:0] */
2653
2654/*
2655 * R1280 (0x500) - DSP2 TX Left Volume
2656 */
2657#define WM8915_DSP2TX_VU 0x0100 /* DSP2TX_VU */
2658#define WM8915_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */
2659#define WM8915_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */
2660#define WM8915_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */
2661#define WM8915_DSP2TXL_VOL_MASK 0x00FF /* DSP2TXL_VOL - [7:0] */
2662#define WM8915_DSP2TXL_VOL_SHIFT 0 /* DSP2TXL_VOL - [7:0] */
2663#define WM8915_DSP2TXL_VOL_WIDTH 8 /* DSP2TXL_VOL - [7:0] */
2664
2665/*
2666 * R1281 (0x501) - DSP2 TX Right Volume
2667 */
2668#define WM8915_DSP2TX_VU 0x0100 /* DSP2TX_VU */
2669#define WM8915_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */
2670#define WM8915_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */
2671#define WM8915_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */
2672#define WM8915_DSP2TXR_VOL_MASK 0x00FF /* DSP2TXR_VOL - [7:0] */
2673#define WM8915_DSP2TXR_VOL_SHIFT 0 /* DSP2TXR_VOL - [7:0] */
2674#define WM8915_DSP2TXR_VOL_WIDTH 8 /* DSP2TXR_VOL - [7:0] */
2675
2676/*
2677 * R1282 (0x502) - DSP2 RX Left Volume
2678 */
2679#define WM8915_DSP2RX_VU 0x0100 /* DSP2RX_VU */
2680#define WM8915_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */
2681#define WM8915_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */
2682#define WM8915_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */
2683#define WM8915_DSP2RXL_VOL_MASK 0x00FF /* DSP2RXL_VOL - [7:0] */
2684#define WM8915_DSP2RXL_VOL_SHIFT 0 /* DSP2RXL_VOL - [7:0] */
2685#define WM8915_DSP2RXL_VOL_WIDTH 8 /* DSP2RXL_VOL - [7:0] */
2686
2687/*
2688 * R1283 (0x503) - DSP2 RX Right Volume
2689 */
2690#define WM8915_DSP2RX_VU 0x0100 /* DSP2RX_VU */
2691#define WM8915_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */
2692#define WM8915_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */
2693#define WM8915_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */
2694#define WM8915_DSP2RXR_VOL_MASK 0x00FF /* DSP2RXR_VOL - [7:0] */
2695#define WM8915_DSP2RXR_VOL_SHIFT 0 /* DSP2RXR_VOL - [7:0] */
2696#define WM8915_DSP2RXR_VOL_WIDTH 8 /* DSP2RXR_VOL - [7:0] */
2697
2698/*
2699 * R1296 (0x510) - DSP2 TX Filters
2700 */
2701#define WM8915_DSP2TX_NF 0x2000 /* DSP2TX_NF */
2702#define WM8915_DSP2TX_NF_MASK 0x2000 /* DSP2TX_NF */
2703#define WM8915_DSP2TX_NF_SHIFT 13 /* DSP2TX_NF */
2704#define WM8915_DSP2TX_NF_WIDTH 1 /* DSP2TX_NF */
2705#define WM8915_DSP2TXL_HPF 0x1000 /* DSP2TXL_HPF */
2706#define WM8915_DSP2TXL_HPF_MASK 0x1000 /* DSP2TXL_HPF */
2707#define WM8915_DSP2TXL_HPF_SHIFT 12 /* DSP2TXL_HPF */
2708#define WM8915_DSP2TXL_HPF_WIDTH 1 /* DSP2TXL_HPF */
2709#define WM8915_DSP2TXR_HPF 0x0800 /* DSP2TXR_HPF */
2710#define WM8915_DSP2TXR_HPF_MASK 0x0800 /* DSP2TXR_HPF */
2711#define WM8915_DSP2TXR_HPF_SHIFT 11 /* DSP2TXR_HPF */
2712#define WM8915_DSP2TXR_HPF_WIDTH 1 /* DSP2TXR_HPF */
2713#define WM8915_DSP2TX_HPF_MODE_MASK 0x0018 /* DSP2TX_HPF_MODE - [4:3] */
2714#define WM8915_DSP2TX_HPF_MODE_SHIFT 3 /* DSP2TX_HPF_MODE - [4:3] */
2715#define WM8915_DSP2TX_HPF_MODE_WIDTH 2 /* DSP2TX_HPF_MODE - [4:3] */
2716#define WM8915_DSP2TX_HPF_CUT_MASK 0x0007 /* DSP2TX_HPF_CUT - [2:0] */
2717#define WM8915_DSP2TX_HPF_CUT_SHIFT 0 /* DSP2TX_HPF_CUT - [2:0] */
2718#define WM8915_DSP2TX_HPF_CUT_WIDTH 3 /* DSP2TX_HPF_CUT - [2:0] */
2719
2720/*
2721 * R1312 (0x520) - DSP2 RX Filters (1)
2722 */
2723#define WM8915_DSP2RX_MUTE 0x0200 /* DSP2RX_MUTE */
2724#define WM8915_DSP2RX_MUTE_MASK 0x0200 /* DSP2RX_MUTE */
2725#define WM8915_DSP2RX_MUTE_SHIFT 9 /* DSP2RX_MUTE */
2726#define WM8915_DSP2RX_MUTE_WIDTH 1 /* DSP2RX_MUTE */
2727#define WM8915_DSP2RX_MONO 0x0080 /* DSP2RX_MONO */
2728#define WM8915_DSP2RX_MONO_MASK 0x0080 /* DSP2RX_MONO */
2729#define WM8915_DSP2RX_MONO_SHIFT 7 /* DSP2RX_MONO */
2730#define WM8915_DSP2RX_MONO_WIDTH 1 /* DSP2RX_MONO */
2731#define WM8915_DSP2RX_MUTERATE 0x0020 /* DSP2RX_MUTERATE */
2732#define WM8915_DSP2RX_MUTERATE_MASK 0x0020 /* DSP2RX_MUTERATE */
2733#define WM8915_DSP2RX_MUTERATE_SHIFT 5 /* DSP2RX_MUTERATE */
2734#define WM8915_DSP2RX_MUTERATE_WIDTH 1 /* DSP2RX_MUTERATE */
2735#define WM8915_DSP2RX_UNMUTE_RAMP 0x0010 /* DSP2RX_UNMUTE_RAMP */
2736#define WM8915_DSP2RX_UNMUTE_RAMP_MASK 0x0010 /* DSP2RX_UNMUTE_RAMP */
2737#define WM8915_DSP2RX_UNMUTE_RAMP_SHIFT 4 /* DSP2RX_UNMUTE_RAMP */
2738#define WM8915_DSP2RX_UNMUTE_RAMP_WIDTH 1 /* DSP2RX_UNMUTE_RAMP */
2739
2740/*
2741 * R1313 (0x521) - DSP2 RX Filters (2)
2742 */
2743#define WM8915_DSP2RX_3D_GAIN_MASK 0x3E00 /* DSP2RX_3D_GAIN - [13:9] */
2744#define WM8915_DSP2RX_3D_GAIN_SHIFT 9 /* DSP2RX_3D_GAIN - [13:9] */
2745#define WM8915_DSP2RX_3D_GAIN_WIDTH 5 /* DSP2RX_3D_GAIN - [13:9] */
2746#define WM8915_DSP2RX_3D_ENA 0x0100 /* DSP2RX_3D_ENA */
2747#define WM8915_DSP2RX_3D_ENA_MASK 0x0100 /* DSP2RX_3D_ENA */
2748#define WM8915_DSP2RX_3D_ENA_SHIFT 8 /* DSP2RX_3D_ENA */
2749#define WM8915_DSP2RX_3D_ENA_WIDTH 1 /* DSP2RX_3D_ENA */
2750
2751/*
2752 * R1344 (0x540) - DSP2 DRC (1)
2753 */
2754#define WM8915_DSP2DRC_SIG_DET_RMS_MASK 0xF800 /* DSP2DRC_SIG_DET_RMS - [15:11] */
2755#define WM8915_DSP2DRC_SIG_DET_RMS_SHIFT 11 /* DSP2DRC_SIG_DET_RMS - [15:11] */
2756#define WM8915_DSP2DRC_SIG_DET_RMS_WIDTH 5 /* DSP2DRC_SIG_DET_RMS - [15:11] */
2757#define WM8915_DSP2DRC_SIG_DET_PK_MASK 0x0600 /* DSP2DRC_SIG_DET_PK - [10:9] */
2758#define WM8915_DSP2DRC_SIG_DET_PK_SHIFT 9 /* DSP2DRC_SIG_DET_PK - [10:9] */
2759#define WM8915_DSP2DRC_SIG_DET_PK_WIDTH 2 /* DSP2DRC_SIG_DET_PK - [10:9] */
2760#define WM8915_DSP2DRC_NG_ENA 0x0100 /* DSP2DRC_NG_ENA */
2761#define WM8915_DSP2DRC_NG_ENA_MASK 0x0100 /* DSP2DRC_NG_ENA */
2762#define WM8915_DSP2DRC_NG_ENA_SHIFT 8 /* DSP2DRC_NG_ENA */
2763#define WM8915_DSP2DRC_NG_ENA_WIDTH 1 /* DSP2DRC_NG_ENA */
2764#define WM8915_DSP2DRC_SIG_DET_MODE 0x0080 /* DSP2DRC_SIG_DET_MODE */
2765#define WM8915_DSP2DRC_SIG_DET_MODE_MASK 0x0080 /* DSP2DRC_SIG_DET_MODE */
2766#define WM8915_DSP2DRC_SIG_DET_MODE_SHIFT 7 /* DSP2DRC_SIG_DET_MODE */
2767#define WM8915_DSP2DRC_SIG_DET_MODE_WIDTH 1 /* DSP2DRC_SIG_DET_MODE */
2768#define WM8915_DSP2DRC_SIG_DET 0x0040 /* DSP2DRC_SIG_DET */
2769#define WM8915_DSP2DRC_SIG_DET_MASK 0x0040 /* DSP2DRC_SIG_DET */
2770#define WM8915_DSP2DRC_SIG_DET_SHIFT 6 /* DSP2DRC_SIG_DET */
2771#define WM8915_DSP2DRC_SIG_DET_WIDTH 1 /* DSP2DRC_SIG_DET */
2772#define WM8915_DSP2DRC_KNEE2_OP_ENA 0x0020 /* DSP2DRC_KNEE2_OP_ENA */
2773#define WM8915_DSP2DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP2DRC_KNEE2_OP_ENA */
2774#define WM8915_DSP2DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP2DRC_KNEE2_OP_ENA */
2775#define WM8915_DSP2DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP2DRC_KNEE2_OP_ENA */
2776#define WM8915_DSP2DRC_QR 0x0010 /* DSP2DRC_QR */
2777#define WM8915_DSP2DRC_QR_MASK 0x0010 /* DSP2DRC_QR */
2778#define WM8915_DSP2DRC_QR_SHIFT 4 /* DSP2DRC_QR */
2779#define WM8915_DSP2DRC_QR_WIDTH 1 /* DSP2DRC_QR */
2780#define WM8915_DSP2DRC_ANTICLIP 0x0008 /* DSP2DRC_ANTICLIP */
2781#define WM8915_DSP2DRC_ANTICLIP_MASK 0x0008 /* DSP2DRC_ANTICLIP */
2782#define WM8915_DSP2DRC_ANTICLIP_SHIFT 3 /* DSP2DRC_ANTICLIP */
2783#define WM8915_DSP2DRC_ANTICLIP_WIDTH 1 /* DSP2DRC_ANTICLIP */
2784#define WM8915_DSP2RX_DRC_ENA 0x0004 /* DSP2RX_DRC_ENA */
2785#define WM8915_DSP2RX_DRC_ENA_MASK 0x0004 /* DSP2RX_DRC_ENA */
2786#define WM8915_DSP2RX_DRC_ENA_SHIFT 2 /* DSP2RX_DRC_ENA */
2787#define WM8915_DSP2RX_DRC_ENA_WIDTH 1 /* DSP2RX_DRC_ENA */
2788#define WM8915_DSP2TXL_DRC_ENA 0x0002 /* DSP2TXL_DRC_ENA */
2789#define WM8915_DSP2TXL_DRC_ENA_MASK 0x0002 /* DSP2TXL_DRC_ENA */
2790#define WM8915_DSP2TXL_DRC_ENA_SHIFT 1 /* DSP2TXL_DRC_ENA */
2791#define WM8915_DSP2TXL_DRC_ENA_WIDTH 1 /* DSP2TXL_DRC_ENA */
2792#define WM8915_DSP2TXR_DRC_ENA 0x0001 /* DSP2TXR_DRC_ENA */
2793#define WM8915_DSP2TXR_DRC_ENA_MASK 0x0001 /* DSP2TXR_DRC_ENA */
2794#define WM8915_DSP2TXR_DRC_ENA_SHIFT 0 /* DSP2TXR_DRC_ENA */
2795#define WM8915_DSP2TXR_DRC_ENA_WIDTH 1 /* DSP2TXR_DRC_ENA */
2796
2797/*
2798 * R1345 (0x541) - DSP2 DRC (2)
2799 */
2800#define WM8915_DSP2DRC_ATK_MASK 0x1E00 /* DSP2DRC_ATK - [12:9] */
2801#define WM8915_DSP2DRC_ATK_SHIFT 9 /* DSP2DRC_ATK - [12:9] */
2802#define WM8915_DSP2DRC_ATK_WIDTH 4 /* DSP2DRC_ATK - [12:9] */
2803#define WM8915_DSP2DRC_DCY_MASK 0x01E0 /* DSP2DRC_DCY - [8:5] */
2804#define WM8915_DSP2DRC_DCY_SHIFT 5 /* DSP2DRC_DCY - [8:5] */
2805#define WM8915_DSP2DRC_DCY_WIDTH 4 /* DSP2DRC_DCY - [8:5] */
2806#define WM8915_DSP2DRC_MINGAIN_MASK 0x001C /* DSP2DRC_MINGAIN - [4:2] */
2807#define WM8915_DSP2DRC_MINGAIN_SHIFT 2 /* DSP2DRC_MINGAIN - [4:2] */
2808#define WM8915_DSP2DRC_MINGAIN_WIDTH 3 /* DSP2DRC_MINGAIN - [4:2] */
2809#define WM8915_DSP2DRC_MAXGAIN_MASK 0x0003 /* DSP2DRC_MAXGAIN - [1:0] */
2810#define WM8915_DSP2DRC_MAXGAIN_SHIFT 0 /* DSP2DRC_MAXGAIN - [1:0] */
2811#define WM8915_DSP2DRC_MAXGAIN_WIDTH 2 /* DSP2DRC_MAXGAIN - [1:0] */
2812
2813/*
2814 * R1346 (0x542) - DSP2 DRC (3)
2815 */
2816#define WM8915_DSP2DRC_NG_MINGAIN_MASK 0xF000 /* DSP2DRC_NG_MINGAIN - [15:12] */
2817#define WM8915_DSP2DRC_NG_MINGAIN_SHIFT 12 /* DSP2DRC_NG_MINGAIN - [15:12] */
2818#define WM8915_DSP2DRC_NG_MINGAIN_WIDTH 4 /* DSP2DRC_NG_MINGAIN - [15:12] */
2819#define WM8915_DSP2DRC_NG_EXP_MASK 0x0C00 /* DSP2DRC_NG_EXP - [11:10] */
2820#define WM8915_DSP2DRC_NG_EXP_SHIFT 10 /* DSP2DRC_NG_EXP - [11:10] */
2821#define WM8915_DSP2DRC_NG_EXP_WIDTH 2 /* DSP2DRC_NG_EXP - [11:10] */
2822#define WM8915_DSP2DRC_QR_THR_MASK 0x0300 /* DSP2DRC_QR_THR - [9:8] */
2823#define WM8915_DSP2DRC_QR_THR_SHIFT 8 /* DSP2DRC_QR_THR - [9:8] */
2824#define WM8915_DSP2DRC_QR_THR_WIDTH 2 /* DSP2DRC_QR_THR - [9:8] */
2825#define WM8915_DSP2DRC_QR_DCY_MASK 0x00C0 /* DSP2DRC_QR_DCY - [7:6] */
2826#define WM8915_DSP2DRC_QR_DCY_SHIFT 6 /* DSP2DRC_QR_DCY - [7:6] */
2827#define WM8915_DSP2DRC_QR_DCY_WIDTH 2 /* DSP2DRC_QR_DCY - [7:6] */
2828#define WM8915_DSP2DRC_HI_COMP_MASK 0x0038 /* DSP2DRC_HI_COMP - [5:3] */
2829#define WM8915_DSP2DRC_HI_COMP_SHIFT 3 /* DSP2DRC_HI_COMP - [5:3] */
2830#define WM8915_DSP2DRC_HI_COMP_WIDTH 3 /* DSP2DRC_HI_COMP - [5:3] */
2831#define WM8915_DSP2DRC_LO_COMP_MASK 0x0007 /* DSP2DRC_LO_COMP - [2:0] */
2832#define WM8915_DSP2DRC_LO_COMP_SHIFT 0 /* DSP2DRC_LO_COMP - [2:0] */
2833#define WM8915_DSP2DRC_LO_COMP_WIDTH 3 /* DSP2DRC_LO_COMP - [2:0] */
2834
2835/*
2836 * R1347 (0x543) - DSP2 DRC (4)
2837 */
2838#define WM8915_DSP2DRC_KNEE_IP_MASK 0x07E0 /* DSP2DRC_KNEE_IP - [10:5] */
2839#define WM8915_DSP2DRC_KNEE_IP_SHIFT 5 /* DSP2DRC_KNEE_IP - [10:5] */
2840#define WM8915_DSP2DRC_KNEE_IP_WIDTH 6 /* DSP2DRC_KNEE_IP - [10:5] */
2841#define WM8915_DSP2DRC_KNEE_OP_MASK 0x001F /* DSP2DRC_KNEE_OP - [4:0] */
2842#define WM8915_DSP2DRC_KNEE_OP_SHIFT 0 /* DSP2DRC_KNEE_OP - [4:0] */
2843#define WM8915_DSP2DRC_KNEE_OP_WIDTH 5 /* DSP2DRC_KNEE_OP - [4:0] */
2844
2845/*
2846 * R1348 (0x544) - DSP2 DRC (5)
2847 */
2848#define WM8915_DSP2DRC_KNEE2_IP_MASK 0x03E0 /* DSP2DRC_KNEE2_IP - [9:5] */
2849#define WM8915_DSP2DRC_KNEE2_IP_SHIFT 5 /* DSP2DRC_KNEE2_IP - [9:5] */
2850#define WM8915_DSP2DRC_KNEE2_IP_WIDTH 5 /* DSP2DRC_KNEE2_IP - [9:5] */
2851#define WM8915_DSP2DRC_KNEE2_OP_MASK 0x001F /* DSP2DRC_KNEE2_OP - [4:0] */
2852#define WM8915_DSP2DRC_KNEE2_OP_SHIFT 0 /* DSP2DRC_KNEE2_OP - [4:0] */
2853#define WM8915_DSP2DRC_KNEE2_OP_WIDTH 5 /* DSP2DRC_KNEE2_OP - [4:0] */
2854
2855/*
2856 * R1408 (0x580) - DSP2 RX EQ Gains (1)
2857 */
2858#define WM8915_DSP2RX_EQ_B1_GAIN_MASK 0xF800 /* DSP2RX_EQ_B1_GAIN - [15:11] */
2859#define WM8915_DSP2RX_EQ_B1_GAIN_SHIFT 11 /* DSP2RX_EQ_B1_GAIN - [15:11] */
2860#define WM8915_DSP2RX_EQ_B1_GAIN_WIDTH 5 /* DSP2RX_EQ_B1_GAIN - [15:11] */
2861#define WM8915_DSP2RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B2_GAIN - [10:6] */
2862#define WM8915_DSP2RX_EQ_B2_GAIN_SHIFT 6 /* DSP2RX_EQ_B2_GAIN - [10:6] */
2863#define WM8915_DSP2RX_EQ_B2_GAIN_WIDTH 5 /* DSP2RX_EQ_B2_GAIN - [10:6] */
2864#define WM8915_DSP2RX_EQ_B3_GAIN_MASK 0x003E /* DSP2RX_EQ_B3_GAIN - [5:1] */
2865#define WM8915_DSP2RX_EQ_B3_GAIN_SHIFT 1 /* DSP2RX_EQ_B3_GAIN - [5:1] */
2866#define WM8915_DSP2RX_EQ_B3_GAIN_WIDTH 5 /* DSP2RX_EQ_B3_GAIN - [5:1] */
2867#define WM8915_DSP2RX_EQ_ENA 0x0001 /* DSP2RX_EQ_ENA */
2868#define WM8915_DSP2RX_EQ_ENA_MASK 0x0001 /* DSP2RX_EQ_ENA */
2869#define WM8915_DSP2RX_EQ_ENA_SHIFT 0 /* DSP2RX_EQ_ENA */
2870#define WM8915_DSP2RX_EQ_ENA_WIDTH 1 /* DSP2RX_EQ_ENA */
2871
2872/*
2873 * R1409 (0x581) - DSP2 RX EQ Gains (2)
2874 */
2875#define WM8915_DSP2RX_EQ_B4_GAIN_MASK 0xF800 /* DSP2RX_EQ_B4_GAIN - [15:11] */
2876#define WM8915_DSP2RX_EQ_B4_GAIN_SHIFT 11 /* DSP2RX_EQ_B4_GAIN - [15:11] */
2877#define WM8915_DSP2RX_EQ_B4_GAIN_WIDTH 5 /* DSP2RX_EQ_B4_GAIN - [15:11] */
2878#define WM8915_DSP2RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B5_GAIN - [10:6] */
2879#define WM8915_DSP2RX_EQ_B5_GAIN_SHIFT 6 /* DSP2RX_EQ_B5_GAIN - [10:6] */
2880#define WM8915_DSP2RX_EQ_B5_GAIN_WIDTH 5 /* DSP2RX_EQ_B5_GAIN - [10:6] */
2881
2882/*
2883 * R1410 (0x582) - DSP2 RX EQ Band 1 A
2884 */
2885#define WM8915_DSP2RX_EQ_B1_A_MASK 0xFFFF /* DSP2RX_EQ_B1_A - [15:0] */
2886#define WM8915_DSP2RX_EQ_B1_A_SHIFT 0 /* DSP2RX_EQ_B1_A - [15:0] */
2887#define WM8915_DSP2RX_EQ_B1_A_WIDTH 16 /* DSP2RX_EQ_B1_A - [15:0] */
2888
2889/*
2890 * R1411 (0x583) - DSP2 RX EQ Band 1 B
2891 */
2892#define WM8915_DSP2RX_EQ_B1_B_MASK 0xFFFF /* DSP2RX_EQ_B1_B - [15:0] */
2893#define WM8915_DSP2RX_EQ_B1_B_SHIFT 0 /* DSP2RX_EQ_B1_B - [15:0] */
2894#define WM8915_DSP2RX_EQ_B1_B_WIDTH 16 /* DSP2RX_EQ_B1_B - [15:0] */
2895
2896/*
2897 * R1412 (0x584) - DSP2 RX EQ Band 1 PG
2898 */
2899#define WM8915_DSP2RX_EQ_B1_PG_MASK 0xFFFF /* DSP2RX_EQ_B1_PG - [15:0] */
2900#define WM8915_DSP2RX_EQ_B1_PG_SHIFT 0 /* DSP2RX_EQ_B1_PG - [15:0] */
2901#define WM8915_DSP2RX_EQ_B1_PG_WIDTH 16 /* DSP2RX_EQ_B1_PG - [15:0] */
2902
2903/*
2904 * R1413 (0x585) - DSP2 RX EQ Band 2 A
2905 */
2906#define WM8915_DSP2RX_EQ_B2_A_MASK 0xFFFF /* DSP2RX_EQ_B2_A - [15:0] */
2907#define WM8915_DSP2RX_EQ_B2_A_SHIFT 0 /* DSP2RX_EQ_B2_A - [15:0] */
2908#define WM8915_DSP2RX_EQ_B2_A_WIDTH 16 /* DSP2RX_EQ_B2_A - [15:0] */
2909
2910/*
2911 * R1414 (0x586) - DSP2 RX EQ Band 2 B
2912 */
2913#define WM8915_DSP2RX_EQ_B2_B_MASK 0xFFFF /* DSP2RX_EQ_B2_B - [15:0] */
2914#define WM8915_DSP2RX_EQ_B2_B_SHIFT 0 /* DSP2RX_EQ_B2_B - [15:0] */
2915#define WM8915_DSP2RX_EQ_B2_B_WIDTH 16 /* DSP2RX_EQ_B2_B - [15:0] */
2916
2917/*
2918 * R1415 (0x587) - DSP2 RX EQ Band 2 C
2919 */
2920#define WM8915_DSP2RX_EQ_B2_C_MASK 0xFFFF /* DSP2RX_EQ_B2_C - [15:0] */
2921#define WM8915_DSP2RX_EQ_B2_C_SHIFT 0 /* DSP2RX_EQ_B2_C - [15:0] */
2922#define WM8915_DSP2RX_EQ_B2_C_WIDTH 16 /* DSP2RX_EQ_B2_C - [15:0] */
2923
2924/*
2925 * R1416 (0x588) - DSP2 RX EQ Band 2 PG
2926 */
2927#define WM8915_DSP2RX_EQ_B2_PG_MASK 0xFFFF /* DSP2RX_EQ_B2_PG - [15:0] */
2928#define WM8915_DSP2RX_EQ_B2_PG_SHIFT 0 /* DSP2RX_EQ_B2_PG - [15:0] */
2929#define WM8915_DSP2RX_EQ_B2_PG_WIDTH 16 /* DSP2RX_EQ_B2_PG - [15:0] */
2930
2931/*
2932 * R1417 (0x589) - DSP2 RX EQ Band 3 A
2933 */
2934#define WM8915_DSP2RX_EQ_B3_A_MASK 0xFFFF /* DSP2RX_EQ_B3_A - [15:0] */
2935#define WM8915_DSP2RX_EQ_B3_A_SHIFT 0 /* DSP2RX_EQ_B3_A - [15:0] */
2936#define WM8915_DSP2RX_EQ_B3_A_WIDTH 16 /* DSP2RX_EQ_B3_A - [15:0] */
2937
2938/*
2939 * R1418 (0x58A) - DSP2 RX EQ Band 3 B
2940 */
2941#define WM8915_DSP2RX_EQ_B3_B_MASK 0xFFFF /* DSP2RX_EQ_B3_B - [15:0] */
2942#define WM8915_DSP2RX_EQ_B3_B_SHIFT 0 /* DSP2RX_EQ_B3_B - [15:0] */
2943#define WM8915_DSP2RX_EQ_B3_B_WIDTH 16 /* DSP2RX_EQ_B3_B - [15:0] */
2944
2945/*
2946 * R1419 (0x58B) - DSP2 RX EQ Band 3 C
2947 */
2948#define WM8915_DSP2RX_EQ_B3_C_MASK 0xFFFF /* DSP2RX_EQ_B3_C - [15:0] */
2949#define WM8915_DSP2RX_EQ_B3_C_SHIFT 0 /* DSP2RX_EQ_B3_C - [15:0] */
2950#define WM8915_DSP2RX_EQ_B3_C_WIDTH 16 /* DSP2RX_EQ_B3_C - [15:0] */
2951
2952/*
2953 * R1420 (0x58C) - DSP2 RX EQ Band 3 PG
2954 */
2955#define WM8915_DSP2RX_EQ_B3_PG_MASK 0xFFFF /* DSP2RX_EQ_B3_PG - [15:0] */
2956#define WM8915_DSP2RX_EQ_B3_PG_SHIFT 0 /* DSP2RX_EQ_B3_PG - [15:0] */
2957#define WM8915_DSP2RX_EQ_B3_PG_WIDTH 16 /* DSP2RX_EQ_B3_PG - [15:0] */
2958
2959/*
2960 * R1421 (0x58D) - DSP2 RX EQ Band 4 A
2961 */
2962#define WM8915_DSP2RX_EQ_B4_A_MASK 0xFFFF /* DSP2RX_EQ_B4_A - [15:0] */
2963#define WM8915_DSP2RX_EQ_B4_A_SHIFT 0 /* DSP2RX_EQ_B4_A - [15:0] */
2964#define WM8915_DSP2RX_EQ_B4_A_WIDTH 16 /* DSP2RX_EQ_B4_A - [15:0] */
2965
2966/*
2967 * R1422 (0x58E) - DSP2 RX EQ Band 4 B
2968 */
2969#define WM8915_DSP2RX_EQ_B4_B_MASK 0xFFFF /* DSP2RX_EQ_B4_B - [15:0] */
2970#define WM8915_DSP2RX_EQ_B4_B_SHIFT 0 /* DSP2RX_EQ_B4_B - [15:0] */
2971#define WM8915_DSP2RX_EQ_B4_B_WIDTH 16 /* DSP2RX_EQ_B4_B - [15:0] */
2972
2973/*
2974 * R1423 (0x58F) - DSP2 RX EQ Band 4 C
2975 */
2976#define WM8915_DSP2RX_EQ_B4_C_MASK 0xFFFF /* DSP2RX_EQ_B4_C - [15:0] */
2977#define WM8915_DSP2RX_EQ_B4_C_SHIFT 0 /* DSP2RX_EQ_B4_C - [15:0] */
2978#define WM8915_DSP2RX_EQ_B4_C_WIDTH 16 /* DSP2RX_EQ_B4_C - [15:0] */
2979
2980/*
2981 * R1424 (0x590) - DSP2 RX EQ Band 4 PG
2982 */
2983#define WM8915_DSP2RX_EQ_B4_PG_MASK 0xFFFF /* DSP2RX_EQ_B4_PG - [15:0] */
2984#define WM8915_DSP2RX_EQ_B4_PG_SHIFT 0 /* DSP2RX_EQ_B4_PG - [15:0] */
2985#define WM8915_DSP2RX_EQ_B4_PG_WIDTH 16 /* DSP2RX_EQ_B4_PG - [15:0] */
2986
2987/*
2988 * R1425 (0x591) - DSP2 RX EQ Band 5 A
2989 */
2990#define WM8915_DSP2RX_EQ_B5_A_MASK 0xFFFF /* DSP2RX_EQ_B5_A - [15:0] */
2991#define WM8915_DSP2RX_EQ_B5_A_SHIFT 0 /* DSP2RX_EQ_B5_A - [15:0] */
2992#define WM8915_DSP2RX_EQ_B5_A_WIDTH 16 /* DSP2RX_EQ_B5_A - [15:0] */
2993
2994/*
2995 * R1426 (0x592) - DSP2 RX EQ Band 5 B
2996 */
2997#define WM8915_DSP2RX_EQ_B5_B_MASK 0xFFFF /* DSP2RX_EQ_B5_B - [15:0] */
2998#define WM8915_DSP2RX_EQ_B5_B_SHIFT 0 /* DSP2RX_EQ_B5_B - [15:0] */
2999#define WM8915_DSP2RX_EQ_B5_B_WIDTH 16 /* DSP2RX_EQ_B5_B - [15:0] */
3000
3001/*
3002 * R1427 (0x593) - DSP2 RX EQ Band 5 PG
3003 */
3004#define WM8915_DSP2RX_EQ_B5_PG_MASK 0xFFFF /* DSP2RX_EQ_B5_PG - [15:0] */
3005#define WM8915_DSP2RX_EQ_B5_PG_SHIFT 0 /* DSP2RX_EQ_B5_PG - [15:0] */
3006#define WM8915_DSP2RX_EQ_B5_PG_WIDTH 16 /* DSP2RX_EQ_B5_PG - [15:0] */
3007
3008/*
3009 * R1536 (0x600) - DAC1 Mixer Volumes
3010 */
3011#define WM8915_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */
3012#define WM8915_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */
3013#define WM8915_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */
3014#define WM8915_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */
3015#define WM8915_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */
3016#define WM8915_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */
3017
3018/*
3019 * R1537 (0x601) - DAC1 Left Mixer Routing
3020 */
3021#define WM8915_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */
3022#define WM8915_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */
3023#define WM8915_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */
3024#define WM8915_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */
3025#define WM8915_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */
3026#define WM8915_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */
3027#define WM8915_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */
3028#define WM8915_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */
3029#define WM8915_DSP2RXL_TO_DAC1L 0x0002 /* DSP2RXL_TO_DAC1L */
3030#define WM8915_DSP2RXL_TO_DAC1L_MASK 0x0002 /* DSP2RXL_TO_DAC1L */
3031#define WM8915_DSP2RXL_TO_DAC1L_SHIFT 1 /* DSP2RXL_TO_DAC1L */
3032#define WM8915_DSP2RXL_TO_DAC1L_WIDTH 1 /* DSP2RXL_TO_DAC1L */
3033#define WM8915_DSP1RXL_TO_DAC1L 0x0001 /* DSP1RXL_TO_DAC1L */
3034#define WM8915_DSP1RXL_TO_DAC1L_MASK 0x0001 /* DSP1RXL_TO_DAC1L */
3035#define WM8915_DSP1RXL_TO_DAC1L_SHIFT 0 /* DSP1RXL_TO_DAC1L */
3036#define WM8915_DSP1RXL_TO_DAC1L_WIDTH 1 /* DSP1RXL_TO_DAC1L */
3037
3038/*
3039 * R1538 (0x602) - DAC1 Right Mixer Routing
3040 */
3041#define WM8915_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */
3042#define WM8915_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */
3043#define WM8915_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */
3044#define WM8915_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */
3045#define WM8915_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */
3046#define WM8915_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */
3047#define WM8915_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */
3048#define WM8915_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */
3049#define WM8915_DSP2RXR_TO_DAC1R 0x0002 /* DSP2RXR_TO_DAC1R */
3050#define WM8915_DSP2RXR_TO_DAC1R_MASK 0x0002 /* DSP2RXR_TO_DAC1R */
3051#define WM8915_DSP2RXR_TO_DAC1R_SHIFT 1 /* DSP2RXR_TO_DAC1R */
3052#define WM8915_DSP2RXR_TO_DAC1R_WIDTH 1 /* DSP2RXR_TO_DAC1R */
3053#define WM8915_DSP1RXR_TO_DAC1R 0x0001 /* DSP1RXR_TO_DAC1R */
3054#define WM8915_DSP1RXR_TO_DAC1R_MASK 0x0001 /* DSP1RXR_TO_DAC1R */
3055#define WM8915_DSP1RXR_TO_DAC1R_SHIFT 0 /* DSP1RXR_TO_DAC1R */
3056#define WM8915_DSP1RXR_TO_DAC1R_WIDTH 1 /* DSP1RXR_TO_DAC1R */
3057
3058/*
3059 * R1539 (0x603) - DAC2 Mixer Volumes
3060 */
3061#define WM8915_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */
3062#define WM8915_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */
3063#define WM8915_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */
3064#define WM8915_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */
3065#define WM8915_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */
3066#define WM8915_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */
3067
3068/*
3069 * R1540 (0x604) - DAC2 Left Mixer Routing
3070 */
3071#define WM8915_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */
3072#define WM8915_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */
3073#define WM8915_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */
3074#define WM8915_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */
3075#define WM8915_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */
3076#define WM8915_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */
3077#define WM8915_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */
3078#define WM8915_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */
3079#define WM8915_DSP2RXL_TO_DAC2L 0x0002 /* DSP2RXL_TO_DAC2L */
3080#define WM8915_DSP2RXL_TO_DAC2L_MASK 0x0002 /* DSP2RXL_TO_DAC2L */
3081#define WM8915_DSP2RXL_TO_DAC2L_SHIFT 1 /* DSP2RXL_TO_DAC2L */
3082#define WM8915_DSP2RXL_TO_DAC2L_WIDTH 1 /* DSP2RXL_TO_DAC2L */
3083#define WM8915_DSP1RXL_TO_DAC2L 0x0001 /* DSP1RXL_TO_DAC2L */
3084#define WM8915_DSP1RXL_TO_DAC2L_MASK 0x0001 /* DSP1RXL_TO_DAC2L */
3085#define WM8915_DSP1RXL_TO_DAC2L_SHIFT 0 /* DSP1RXL_TO_DAC2L */
3086#define WM8915_DSP1RXL_TO_DAC2L_WIDTH 1 /* DSP1RXL_TO_DAC2L */
3087
3088/*
3089 * R1541 (0x605) - DAC2 Right Mixer Routing
3090 */
3091#define WM8915_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */
3092#define WM8915_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */
3093#define WM8915_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */
3094#define WM8915_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */
3095#define WM8915_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */
3096#define WM8915_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */
3097#define WM8915_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */
3098#define WM8915_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */
3099#define WM8915_DSP2RXR_TO_DAC2R 0x0002 /* DSP2RXR_TO_DAC2R */
3100#define WM8915_DSP2RXR_TO_DAC2R_MASK 0x0002 /* DSP2RXR_TO_DAC2R */
3101#define WM8915_DSP2RXR_TO_DAC2R_SHIFT 1 /* DSP2RXR_TO_DAC2R */
3102#define WM8915_DSP2RXR_TO_DAC2R_WIDTH 1 /* DSP2RXR_TO_DAC2R */
3103#define WM8915_DSP1RXR_TO_DAC2R 0x0001 /* DSP1RXR_TO_DAC2R */
3104#define WM8915_DSP1RXR_TO_DAC2R_MASK 0x0001 /* DSP1RXR_TO_DAC2R */
3105#define WM8915_DSP1RXR_TO_DAC2R_SHIFT 0 /* DSP1RXR_TO_DAC2R */
3106#define WM8915_DSP1RXR_TO_DAC2R_WIDTH 1 /* DSP1RXR_TO_DAC2R */
3107
3108/*
3109 * R1542 (0x606) - DSP1 TX Left Mixer Routing
3110 */
3111#define WM8915_ADC1L_TO_DSP1TXL 0x0002 /* ADC1L_TO_DSP1TXL */
3112#define WM8915_ADC1L_TO_DSP1TXL_MASK 0x0002 /* ADC1L_TO_DSP1TXL */
3113#define WM8915_ADC1L_TO_DSP1TXL_SHIFT 1 /* ADC1L_TO_DSP1TXL */
3114#define WM8915_ADC1L_TO_DSP1TXL_WIDTH 1 /* ADC1L_TO_DSP1TXL */
3115#define WM8915_DACL_TO_DSP1TXL 0x0001 /* DACL_TO_DSP1TXL */
3116#define WM8915_DACL_TO_DSP1TXL_MASK 0x0001 /* DACL_TO_DSP1TXL */
3117#define WM8915_DACL_TO_DSP1TXL_SHIFT 0 /* DACL_TO_DSP1TXL */
3118#define WM8915_DACL_TO_DSP1TXL_WIDTH 1 /* DACL_TO_DSP1TXL */
3119
3120/*
3121 * R1543 (0x607) - DSP1 TX Right Mixer Routing
3122 */
3123#define WM8915_ADC1R_TO_DSP1TXR 0x0002 /* ADC1R_TO_DSP1TXR */
3124#define WM8915_ADC1R_TO_DSP1TXR_MASK 0x0002 /* ADC1R_TO_DSP1TXR */
3125#define WM8915_ADC1R_TO_DSP1TXR_SHIFT 1 /* ADC1R_TO_DSP1TXR */
3126#define WM8915_ADC1R_TO_DSP1TXR_WIDTH 1 /* ADC1R_TO_DSP1TXR */
3127#define WM8915_DACR_TO_DSP1TXR 0x0001 /* DACR_TO_DSP1TXR */
3128#define WM8915_DACR_TO_DSP1TXR_MASK 0x0001 /* DACR_TO_DSP1TXR */
3129#define WM8915_DACR_TO_DSP1TXR_SHIFT 0 /* DACR_TO_DSP1TXR */
3130#define WM8915_DACR_TO_DSP1TXR_WIDTH 1 /* DACR_TO_DSP1TXR */
3131
3132/*
3133 * R1544 (0x608) - DSP2 TX Left Mixer Routing
3134 */
3135#define WM8915_ADC2L_TO_DSP2TXL 0x0002 /* ADC2L_TO_DSP2TXL */
3136#define WM8915_ADC2L_TO_DSP2TXL_MASK 0x0002 /* ADC2L_TO_DSP2TXL */
3137#define WM8915_ADC2L_TO_DSP2TXL_SHIFT 1 /* ADC2L_TO_DSP2TXL */
3138#define WM8915_ADC2L_TO_DSP2TXL_WIDTH 1 /* ADC2L_TO_DSP2TXL */
3139#define WM8915_DACL_TO_DSP2TXL 0x0001 /* DACL_TO_DSP2TXL */
3140#define WM8915_DACL_TO_DSP2TXL_MASK 0x0001 /* DACL_TO_DSP2TXL */
3141#define WM8915_DACL_TO_DSP2TXL_SHIFT 0 /* DACL_TO_DSP2TXL */
3142#define WM8915_DACL_TO_DSP2TXL_WIDTH 1 /* DACL_TO_DSP2TXL */
3143
3144/*
3145 * R1545 (0x609) - DSP2 TX Right Mixer Routing
3146 */
3147#define WM8915_ADC2R_TO_DSP2TXR 0x0002 /* ADC2R_TO_DSP2TXR */
3148#define WM8915_ADC2R_TO_DSP2TXR_MASK 0x0002 /* ADC2R_TO_DSP2TXR */
3149#define WM8915_ADC2R_TO_DSP2TXR_SHIFT 1 /* ADC2R_TO_DSP2TXR */
3150#define WM8915_ADC2R_TO_DSP2TXR_WIDTH 1 /* ADC2R_TO_DSP2TXR */
3151#define WM8915_DACR_TO_DSP2TXR 0x0001 /* DACR_TO_DSP2TXR */
3152#define WM8915_DACR_TO_DSP2TXR_MASK 0x0001 /* DACR_TO_DSP2TXR */
3153#define WM8915_DACR_TO_DSP2TXR_SHIFT 0 /* DACR_TO_DSP2TXR */
3154#define WM8915_DACR_TO_DSP2TXR_WIDTH 1 /* DACR_TO_DSP2TXR */
3155
3156/*
3157 * R1546 (0x60A) - DSP TX Mixer Select
3158 */
3159#define WM8915_DAC_TO_DSPTX_SRC 0x0001 /* DAC_TO_DSPTX_SRC */
3160#define WM8915_DAC_TO_DSPTX_SRC_MASK 0x0001 /* DAC_TO_DSPTX_SRC */
3161#define WM8915_DAC_TO_DSPTX_SRC_SHIFT 0 /* DAC_TO_DSPTX_SRC */
3162#define WM8915_DAC_TO_DSPTX_SRC_WIDTH 1 /* DAC_TO_DSPTX_SRC */
3163
3164/*
3165 * R1552 (0x610) - DAC Softmute
3166 */
3167#define WM8915_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */
3168#define WM8915_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */
3169#define WM8915_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */
3170#define WM8915_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */
3171#define WM8915_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */
3172#define WM8915_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */
3173#define WM8915_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */
3174#define WM8915_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
3175
3176/*
3177 * R1568 (0x620) - Oversampling
3178 */
3179#define WM8915_SPK_OSR128 0x0008 /* SPK_OSR128 */
3180#define WM8915_SPK_OSR128_MASK 0x0008 /* SPK_OSR128 */
3181#define WM8915_SPK_OSR128_SHIFT 3 /* SPK_OSR128 */
3182#define WM8915_SPK_OSR128_WIDTH 1 /* SPK_OSR128 */
3183#define WM8915_DMIC_OSR64 0x0004 /* DMIC_OSR64 */
3184#define WM8915_DMIC_OSR64_MASK 0x0004 /* DMIC_OSR64 */
3185#define WM8915_DMIC_OSR64_SHIFT 2 /* DMIC_OSR64 */
3186#define WM8915_DMIC_OSR64_WIDTH 1 /* DMIC_OSR64 */
3187#define WM8915_ADC_OSR128 0x0002 /* ADC_OSR128 */
3188#define WM8915_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */
3189#define WM8915_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */
3190#define WM8915_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
3191#define WM8915_DAC_OSR128 0x0001 /* DAC_OSR128 */
3192#define WM8915_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
3193#define WM8915_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
3194#define WM8915_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
3195
3196/*
3197 * R1569 (0x621) - Sidetone
3198 */
3199#define WM8915_ST_LPF 0x1000 /* ST_LPF */
3200#define WM8915_ST_LPF_MASK 0x1000 /* ST_LPF */
3201#define WM8915_ST_LPF_SHIFT 12 /* ST_LPF */
3202#define WM8915_ST_LPF_WIDTH 1 /* ST_LPF */
3203#define WM8915_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */
3204#define WM8915_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */
3205#define WM8915_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */
3206#define WM8915_ST_HPF 0x0040 /* ST_HPF */
3207#define WM8915_ST_HPF_MASK 0x0040 /* ST_HPF */
3208#define WM8915_ST_HPF_SHIFT 6 /* ST_HPF */
3209#define WM8915_ST_HPF_WIDTH 1 /* ST_HPF */
3210#define WM8915_STR_SEL 0x0002 /* STR_SEL */
3211#define WM8915_STR_SEL_MASK 0x0002 /* STR_SEL */
3212#define WM8915_STR_SEL_SHIFT 1 /* STR_SEL */
3213#define WM8915_STR_SEL_WIDTH 1 /* STR_SEL */
3214#define WM8915_STL_SEL 0x0001 /* STL_SEL */
3215#define WM8915_STL_SEL_MASK 0x0001 /* STL_SEL */
3216#define WM8915_STL_SEL_SHIFT 0 /* STL_SEL */
3217#define WM8915_STL_SEL_WIDTH 1 /* STL_SEL */
3218
3219/*
3220 * R1792 (0x700) - GPIO 1
3221 */
3222#define WM8915_GP1_DIR 0x8000 /* GP1_DIR */
3223#define WM8915_GP1_DIR_MASK 0x8000 /* GP1_DIR */
3224#define WM8915_GP1_DIR_SHIFT 15 /* GP1_DIR */
3225#define WM8915_GP1_DIR_WIDTH 1 /* GP1_DIR */
3226#define WM8915_GP1_PU 0x4000 /* GP1_PU */
3227#define WM8915_GP1_PU_MASK 0x4000 /* GP1_PU */
3228#define WM8915_GP1_PU_SHIFT 14 /* GP1_PU */
3229#define WM8915_GP1_PU_WIDTH 1 /* GP1_PU */
3230#define WM8915_GP1_PD 0x2000 /* GP1_PD */
3231#define WM8915_GP1_PD_MASK 0x2000 /* GP1_PD */
3232#define WM8915_GP1_PD_SHIFT 13 /* GP1_PD */
3233#define WM8915_GP1_PD_WIDTH 1 /* GP1_PD */
3234#define WM8915_GP1_POL 0x0400 /* GP1_POL */
3235#define WM8915_GP1_POL_MASK 0x0400 /* GP1_POL */
3236#define WM8915_GP1_POL_SHIFT 10 /* GP1_POL */
3237#define WM8915_GP1_POL_WIDTH 1 /* GP1_POL */
3238#define WM8915_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
3239#define WM8915_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
3240#define WM8915_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
3241#define WM8915_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
3242#define WM8915_GP1_DB 0x0100 /* GP1_DB */
3243#define WM8915_GP1_DB_MASK 0x0100 /* GP1_DB */
3244#define WM8915_GP1_DB_SHIFT 8 /* GP1_DB */
3245#define WM8915_GP1_DB_WIDTH 1 /* GP1_DB */
3246#define WM8915_GP1_LVL 0x0040 /* GP1_LVL */
3247#define WM8915_GP1_LVL_MASK 0x0040 /* GP1_LVL */
3248#define WM8915_GP1_LVL_SHIFT 6 /* GP1_LVL */
3249#define WM8915_GP1_LVL_WIDTH 1 /* GP1_LVL */
3250#define WM8915_GP1_FN_MASK 0x000F /* GP1_FN - [3:0] */
3251#define WM8915_GP1_FN_SHIFT 0 /* GP1_FN - [3:0] */
3252#define WM8915_GP1_FN_WIDTH 4 /* GP1_FN - [3:0] */
3253
3254/*
3255 * R1793 (0x701) - GPIO 2
3256 */
3257#define WM8915_GP2_DIR 0x8000 /* GP2_DIR */
3258#define WM8915_GP2_DIR_MASK 0x8000 /* GP2_DIR */
3259#define WM8915_GP2_DIR_SHIFT 15 /* GP2_DIR */
3260#define WM8915_GP2_DIR_WIDTH 1 /* GP2_DIR */
3261#define WM8915_GP2_PU 0x4000 /* GP2_PU */
3262#define WM8915_GP2_PU_MASK 0x4000 /* GP2_PU */
3263#define WM8915_GP2_PU_SHIFT 14 /* GP2_PU */
3264#define WM8915_GP2_PU_WIDTH 1 /* GP2_PU */
3265#define WM8915_GP2_PD 0x2000 /* GP2_PD */
3266#define WM8915_GP2_PD_MASK 0x2000 /* GP2_PD */
3267#define WM8915_GP2_PD_SHIFT 13 /* GP2_PD */
3268#define WM8915_GP2_PD_WIDTH 1 /* GP2_PD */
3269#define WM8915_GP2_POL 0x0400 /* GP2_POL */
3270#define WM8915_GP2_POL_MASK 0x0400 /* GP2_POL */
3271#define WM8915_GP2_POL_SHIFT 10 /* GP2_POL */
3272#define WM8915_GP2_POL_WIDTH 1 /* GP2_POL */
3273#define WM8915_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
3274#define WM8915_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
3275#define WM8915_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
3276#define WM8915_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
3277#define WM8915_GP2_DB 0x0100 /* GP2_DB */
3278#define WM8915_GP2_DB_MASK 0x0100 /* GP2_DB */
3279#define WM8915_GP2_DB_SHIFT 8 /* GP2_DB */
3280#define WM8915_GP2_DB_WIDTH 1 /* GP2_DB */
3281#define WM8915_GP2_LVL 0x0040 /* GP2_LVL */
3282#define WM8915_GP2_LVL_MASK 0x0040 /* GP2_LVL */
3283#define WM8915_GP2_LVL_SHIFT 6 /* GP2_LVL */
3284#define WM8915_GP2_LVL_WIDTH 1 /* GP2_LVL */
3285#define WM8915_GP2_FN_MASK 0x000F /* GP2_FN - [3:0] */
3286#define WM8915_GP2_FN_SHIFT 0 /* GP2_FN - [3:0] */
3287#define WM8915_GP2_FN_WIDTH 4 /* GP2_FN - [3:0] */
3288
3289/*
3290 * R1794 (0x702) - GPIO 3
3291 */
3292#define WM8915_GP3_DIR 0x8000 /* GP3_DIR */
3293#define WM8915_GP3_DIR_MASK 0x8000 /* GP3_DIR */
3294#define WM8915_GP3_DIR_SHIFT 15 /* GP3_DIR */
3295#define WM8915_GP3_DIR_WIDTH 1 /* GP3_DIR */
3296#define WM8915_GP3_PU 0x4000 /* GP3_PU */
3297#define WM8915_GP3_PU_MASK 0x4000 /* GP3_PU */
3298#define WM8915_GP3_PU_SHIFT 14 /* GP3_PU */
3299#define WM8915_GP3_PU_WIDTH 1 /* GP3_PU */
3300#define WM8915_GP3_PD 0x2000 /* GP3_PD */
3301#define WM8915_GP3_PD_MASK 0x2000 /* GP3_PD */
3302#define WM8915_GP3_PD_SHIFT 13 /* GP3_PD */
3303#define WM8915_GP3_PD_WIDTH 1 /* GP3_PD */
3304#define WM8915_GP3_POL 0x0400 /* GP3_POL */
3305#define WM8915_GP3_POL_MASK 0x0400 /* GP3_POL */
3306#define WM8915_GP3_POL_SHIFT 10 /* GP3_POL */
3307#define WM8915_GP3_POL_WIDTH 1 /* GP3_POL */
3308#define WM8915_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
3309#define WM8915_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
3310#define WM8915_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
3311#define WM8915_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
3312#define WM8915_GP3_DB 0x0100 /* GP3_DB */
3313#define WM8915_GP3_DB_MASK 0x0100 /* GP3_DB */
3314#define WM8915_GP3_DB_SHIFT 8 /* GP3_DB */
3315#define WM8915_GP3_DB_WIDTH 1 /* GP3_DB */
3316#define WM8915_GP3_LVL 0x0040 /* GP3_LVL */
3317#define WM8915_GP3_LVL_MASK 0x0040 /* GP3_LVL */
3318#define WM8915_GP3_LVL_SHIFT 6 /* GP3_LVL */
3319#define WM8915_GP3_LVL_WIDTH 1 /* GP3_LVL */
3320#define WM8915_GP3_FN_MASK 0x000F /* GP3_FN - [3:0] */
3321#define WM8915_GP3_FN_SHIFT 0 /* GP3_FN - [3:0] */
3322#define WM8915_GP3_FN_WIDTH 4 /* GP3_FN - [3:0] */
3323
3324/*
3325 * R1795 (0x703) - GPIO 4
3326 */
3327#define WM8915_GP4_DIR 0x8000 /* GP4_DIR */
3328#define WM8915_GP4_DIR_MASK 0x8000 /* GP4_DIR */
3329#define WM8915_GP4_DIR_SHIFT 15 /* GP4_DIR */
3330#define WM8915_GP4_DIR_WIDTH 1 /* GP4_DIR */
3331#define WM8915_GP4_PU 0x4000 /* GP4_PU */
3332#define WM8915_GP4_PU_MASK 0x4000 /* GP4_PU */
3333#define WM8915_GP4_PU_SHIFT 14 /* GP4_PU */
3334#define WM8915_GP4_PU_WIDTH 1 /* GP4_PU */
3335#define WM8915_GP4_PD 0x2000 /* GP4_PD */
3336#define WM8915_GP4_PD_MASK 0x2000 /* GP4_PD */
3337#define WM8915_GP4_PD_SHIFT 13 /* GP4_PD */
3338#define WM8915_GP4_PD_WIDTH 1 /* GP4_PD */
3339#define WM8915_GP4_POL 0x0400 /* GP4_POL */
3340#define WM8915_GP4_POL_MASK 0x0400 /* GP4_POL */
3341#define WM8915_GP4_POL_SHIFT 10 /* GP4_POL */
3342#define WM8915_GP4_POL_WIDTH 1 /* GP4_POL */
3343#define WM8915_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
3344#define WM8915_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
3345#define WM8915_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
3346#define WM8915_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
3347#define WM8915_GP4_DB 0x0100 /* GP4_DB */
3348#define WM8915_GP4_DB_MASK 0x0100 /* GP4_DB */
3349#define WM8915_GP4_DB_SHIFT 8 /* GP4_DB */
3350#define WM8915_GP4_DB_WIDTH 1 /* GP4_DB */
3351#define WM8915_GP4_LVL 0x0040 /* GP4_LVL */
3352#define WM8915_GP4_LVL_MASK 0x0040 /* GP4_LVL */
3353#define WM8915_GP4_LVL_SHIFT 6 /* GP4_LVL */
3354#define WM8915_GP4_LVL_WIDTH 1 /* GP4_LVL */
3355#define WM8915_GP4_FN_MASK 0x000F /* GP4_FN - [3:0] */
3356#define WM8915_GP4_FN_SHIFT 0 /* GP4_FN - [3:0] */
3357#define WM8915_GP4_FN_WIDTH 4 /* GP4_FN - [3:0] */
3358
3359/*
3360 * R1796 (0x704) - GPIO 5
3361 */
3362#define WM8915_GP5_DIR 0x8000 /* GP5_DIR */
3363#define WM8915_GP5_DIR_MASK 0x8000 /* GP5_DIR */
3364#define WM8915_GP5_DIR_SHIFT 15 /* GP5_DIR */
3365#define WM8915_GP5_DIR_WIDTH 1 /* GP5_DIR */
3366#define WM8915_GP5_PU 0x4000 /* GP5_PU */
3367#define WM8915_GP5_PU_MASK 0x4000 /* GP5_PU */
3368#define WM8915_GP5_PU_SHIFT 14 /* GP5_PU */
3369#define WM8915_GP5_PU_WIDTH 1 /* GP5_PU */
3370#define WM8915_GP5_PD 0x2000 /* GP5_PD */
3371#define WM8915_GP5_PD_MASK 0x2000 /* GP5_PD */
3372#define WM8915_GP5_PD_SHIFT 13 /* GP5_PD */
3373#define WM8915_GP5_PD_WIDTH 1 /* GP5_PD */
3374#define WM8915_GP5_POL 0x0400 /* GP5_POL */
3375#define WM8915_GP5_POL_MASK 0x0400 /* GP5_POL */
3376#define WM8915_GP5_POL_SHIFT 10 /* GP5_POL */
3377#define WM8915_GP5_POL_WIDTH 1 /* GP5_POL */
3378#define WM8915_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
3379#define WM8915_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
3380#define WM8915_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
3381#define WM8915_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
3382#define WM8915_GP5_DB 0x0100 /* GP5_DB */
3383#define WM8915_GP5_DB_MASK 0x0100 /* GP5_DB */
3384#define WM8915_GP5_DB_SHIFT 8 /* GP5_DB */
3385#define WM8915_GP5_DB_WIDTH 1 /* GP5_DB */
3386#define WM8915_GP5_LVL 0x0040 /* GP5_LVL */
3387#define WM8915_GP5_LVL_MASK 0x0040 /* GP5_LVL */
3388#define WM8915_GP5_LVL_SHIFT 6 /* GP5_LVL */
3389#define WM8915_GP5_LVL_WIDTH 1 /* GP5_LVL */
3390#define WM8915_GP5_FN_MASK 0x000F /* GP5_FN - [3:0] */
3391#define WM8915_GP5_FN_SHIFT 0 /* GP5_FN - [3:0] */
3392#define WM8915_GP5_FN_WIDTH 4 /* GP5_FN - [3:0] */
3393
3394/*
3395 * R1824 (0x720) - Pull Control (1)
3396 */
3397#define WM8915_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */
3398#define WM8915_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */
3399#define WM8915_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */
3400#define WM8915_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
3401#define WM8915_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */
3402#define WM8915_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */
3403#define WM8915_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */
3404#define WM8915_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
3405#define WM8915_MCLK2_PU 0x0200 /* MCLK2_PU */
3406#define WM8915_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */
3407#define WM8915_MCLK2_PU_SHIFT 9 /* MCLK2_PU */
3408#define WM8915_MCLK2_PU_WIDTH 1 /* MCLK2_PU */
3409#define WM8915_MCLK2_PD 0x0100 /* MCLK2_PD */
3410#define WM8915_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */
3411#define WM8915_MCLK2_PD_SHIFT 8 /* MCLK2_PD */
3412#define WM8915_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
3413#define WM8915_MCLK1_PU 0x0080 /* MCLK1_PU */
3414#define WM8915_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */
3415#define WM8915_MCLK1_PU_SHIFT 7 /* MCLK1_PU */
3416#define WM8915_MCLK1_PU_WIDTH 1 /* MCLK1_PU */
3417#define WM8915_MCLK1_PD 0x0040 /* MCLK1_PD */
3418#define WM8915_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */
3419#define WM8915_MCLK1_PD_SHIFT 6 /* MCLK1_PD */
3420#define WM8915_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
3421#define WM8915_DACDAT1_PU 0x0020 /* DACDAT1_PU */
3422#define WM8915_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */
3423#define WM8915_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */
3424#define WM8915_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
3425#define WM8915_DACDAT1_PD 0x0010 /* DACDAT1_PD */
3426#define WM8915_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */
3427#define WM8915_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */
3428#define WM8915_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
3429#define WM8915_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */
3430#define WM8915_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */
3431#define WM8915_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */
3432#define WM8915_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
3433#define WM8915_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */
3434#define WM8915_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */
3435#define WM8915_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */
3436#define WM8915_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
3437#define WM8915_BCLK1_PU 0x0002 /* BCLK1_PU */
3438#define WM8915_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */
3439#define WM8915_BCLK1_PU_SHIFT 1 /* BCLK1_PU */
3440#define WM8915_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
3441#define WM8915_BCLK1_PD 0x0001 /* BCLK1_PD */
3442#define WM8915_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */
3443#define WM8915_BCLK1_PD_SHIFT 0 /* BCLK1_PD */
3444#define WM8915_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
3445
3446/*
3447 * R1825 (0x721) - Pull Control (2)
3448 */
3449#define WM8915_LDO1ENA_PD 0x0100 /* LDO1ENA_PD */
3450#define WM8915_LDO1ENA_PD_MASK 0x0100 /* LDO1ENA_PD */
3451#define WM8915_LDO1ENA_PD_SHIFT 8 /* LDO1ENA_PD */
3452#define WM8915_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
3453#define WM8915_ADDR_PD 0x0040 /* ADDR_PD */
3454#define WM8915_ADDR_PD_MASK 0x0040 /* ADDR_PD */
3455#define WM8915_ADDR_PD_SHIFT 6 /* ADDR_PD */
3456#define WM8915_ADDR_PD_WIDTH 1 /* ADDR_PD */
3457#define WM8915_DACDAT2_PU 0x0020 /* DACDAT2_PU */
3458#define WM8915_DACDAT2_PU_MASK 0x0020 /* DACDAT2_PU */
3459#define WM8915_DACDAT2_PU_SHIFT 5 /* DACDAT2_PU */
3460#define WM8915_DACDAT2_PU_WIDTH 1 /* DACDAT2_PU */
3461#define WM8915_DACDAT2_PD 0x0010 /* DACDAT2_PD */
3462#define WM8915_DACDAT2_PD_MASK 0x0010 /* DACDAT2_PD */
3463#define WM8915_DACDAT2_PD_SHIFT 4 /* DACDAT2_PD */
3464#define WM8915_DACDAT2_PD_WIDTH 1 /* DACDAT2_PD */
3465#define WM8915_DACLRCLK2_PU 0x0008 /* DACLRCLK2_PU */
3466#define WM8915_DACLRCLK2_PU_MASK 0x0008 /* DACLRCLK2_PU */
3467#define WM8915_DACLRCLK2_PU_SHIFT 3 /* DACLRCLK2_PU */
3468#define WM8915_DACLRCLK2_PU_WIDTH 1 /* DACLRCLK2_PU */
3469#define WM8915_DACLRCLK2_PD 0x0004 /* DACLRCLK2_PD */
3470#define WM8915_DACLRCLK2_PD_MASK 0x0004 /* DACLRCLK2_PD */
3471#define WM8915_DACLRCLK2_PD_SHIFT 2 /* DACLRCLK2_PD */
3472#define WM8915_DACLRCLK2_PD_WIDTH 1 /* DACLRCLK2_PD */
3473#define WM8915_BCLK2_PU 0x0002 /* BCLK2_PU */
3474#define WM8915_BCLK2_PU_MASK 0x0002 /* BCLK2_PU */
3475#define WM8915_BCLK2_PU_SHIFT 1 /* BCLK2_PU */
3476#define WM8915_BCLK2_PU_WIDTH 1 /* BCLK2_PU */
3477#define WM8915_BCLK2_PD 0x0001 /* BCLK2_PD */
3478#define WM8915_BCLK2_PD_MASK 0x0001 /* BCLK2_PD */
3479#define WM8915_BCLK2_PD_SHIFT 0 /* BCLK2_PD */
3480#define WM8915_BCLK2_PD_WIDTH 1 /* BCLK2_PD */
3481
3482/*
3483 * R1840 (0x730) - Interrupt Status 1
3484 */
3485#define WM8915_GP5_EINT 0x0010 /* GP5_EINT */
3486#define WM8915_GP5_EINT_MASK 0x0010 /* GP5_EINT */
3487#define WM8915_GP5_EINT_SHIFT 4 /* GP5_EINT */
3488#define WM8915_GP5_EINT_WIDTH 1 /* GP5_EINT */
3489#define WM8915_GP4_EINT 0x0008 /* GP4_EINT */
3490#define WM8915_GP4_EINT_MASK 0x0008 /* GP4_EINT */
3491#define WM8915_GP4_EINT_SHIFT 3 /* GP4_EINT */
3492#define WM8915_GP4_EINT_WIDTH 1 /* GP4_EINT */
3493#define WM8915_GP3_EINT 0x0004 /* GP3_EINT */
3494#define WM8915_GP3_EINT_MASK 0x0004 /* GP3_EINT */
3495#define WM8915_GP3_EINT_SHIFT 2 /* GP3_EINT */
3496#define WM8915_GP3_EINT_WIDTH 1 /* GP3_EINT */
3497#define WM8915_GP2_EINT 0x0002 /* GP2_EINT */
3498#define WM8915_GP2_EINT_MASK 0x0002 /* GP2_EINT */
3499#define WM8915_GP2_EINT_SHIFT 1 /* GP2_EINT */
3500#define WM8915_GP2_EINT_WIDTH 1 /* GP2_EINT */
3501#define WM8915_GP1_EINT 0x0001 /* GP1_EINT */
3502#define WM8915_GP1_EINT_MASK 0x0001 /* GP1_EINT */
3503#define WM8915_GP1_EINT_SHIFT 0 /* GP1_EINT */
3504#define WM8915_GP1_EINT_WIDTH 1 /* GP1_EINT */
3505
3506/*
3507 * R1841 (0x731) - Interrupt Status 2
3508 */
3509#define WM8915_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */
3510#define WM8915_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */
3511#define WM8915_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */
3512#define WM8915_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */
3513#define WM8915_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */
3514#define WM8915_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */
3515#define WM8915_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */
3516#define WM8915_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */
3517#define WM8915_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */
3518#define WM8915_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */
3519#define WM8915_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */
3520#define WM8915_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
3521#define WM8915_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */
3522#define WM8915_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */
3523#define WM8915_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */
3524#define WM8915_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
3525#define WM8915_DSP2DRC_SIG_DET_EINT 0x0080 /* DSP2DRC_SIG_DET_EINT */
3526#define WM8915_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* DSP2DRC_SIG_DET_EINT */
3527#define WM8915_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* DSP2DRC_SIG_DET_EINT */
3528#define WM8915_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* DSP2DRC_SIG_DET_EINT */
3529#define WM8915_DSP1DRC_SIG_DET_EINT 0x0040 /* DSP1DRC_SIG_DET_EINT */
3530#define WM8915_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* DSP1DRC_SIG_DET_EINT */
3531#define WM8915_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* DSP1DRC_SIG_DET_EINT */
3532#define WM8915_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* DSP1DRC_SIG_DET_EINT */
3533#define WM8915_FLL_SW_CLK_DONE_EINT 0x0008 /* FLL_SW_CLK_DONE_EINT */
3534#define WM8915_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* FLL_SW_CLK_DONE_EINT */
3535#define WM8915_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* FLL_SW_CLK_DONE_EINT */
3536#define WM8915_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* FLL_SW_CLK_DONE_EINT */
3537#define WM8915_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */
3538#define WM8915_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */
3539#define WM8915_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */
3540#define WM8915_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
3541#define WM8915_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */
3542#define WM8915_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */
3543#define WM8915_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */
3544#define WM8915_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */
3545#define WM8915_MICD_EINT 0x0001 /* MICD_EINT */
3546#define WM8915_MICD_EINT_MASK 0x0001 /* MICD_EINT */
3547#define WM8915_MICD_EINT_SHIFT 0 /* MICD_EINT */
3548#define WM8915_MICD_EINT_WIDTH 1 /* MICD_EINT */
3549
3550/*
3551 * R1842 (0x732) - Interrupt Raw Status 2
3552 */
3553#define WM8915_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */
3554#define WM8915_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */
3555#define WM8915_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */
3556#define WM8915_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */
3557#define WM8915_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */
3558#define WM8915_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */
3559#define WM8915_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */
3560#define WM8915_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */
3561#define WM8915_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */
3562#define WM8915_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */
3563#define WM8915_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */
3564#define WM8915_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */
3565#define WM8915_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */
3566#define WM8915_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */
3567#define WM8915_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */
3568#define WM8915_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */
3569#define WM8915_DSP2DRC_SIG_DET_STS 0x0080 /* DSP2DRC_SIG_DET_STS */
3570#define WM8915_DSP2DRC_SIG_DET_STS_MASK 0x0080 /* DSP2DRC_SIG_DET_STS */
3571#define WM8915_DSP2DRC_SIG_DET_STS_SHIFT 7 /* DSP2DRC_SIG_DET_STS */
3572#define WM8915_DSP2DRC_SIG_DET_STS_WIDTH 1 /* DSP2DRC_SIG_DET_STS */
3573#define WM8915_DSP1DRC_SIG_DET_STS 0x0040 /* DSP1DRC_SIG_DET_STS */
3574#define WM8915_DSP1DRC_SIG_DET_STS_MASK 0x0040 /* DSP1DRC_SIG_DET_STS */
3575#define WM8915_DSP1DRC_SIG_DET_STS_SHIFT 6 /* DSP1DRC_SIG_DET_STS */
3576#define WM8915_DSP1DRC_SIG_DET_STS_WIDTH 1 /* DSP1DRC_SIG_DET_STS */
3577#define WM8915_FLL_LOCK_STS 0x0004 /* FLL_LOCK_STS */
3578#define WM8915_FLL_LOCK_STS_MASK 0x0004 /* FLL_LOCK_STS */
3579#define WM8915_FLL_LOCK_STS_SHIFT 2 /* FLL_LOCK_STS */
3580#define WM8915_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */
3581
3582/*
3583 * R1848 (0x738) - Interrupt Status 1 Mask
3584 */
3585#define WM8915_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
3586#define WM8915_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
3587#define WM8915_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
3588#define WM8915_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
3589#define WM8915_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
3590#define WM8915_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
3591#define WM8915_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
3592#define WM8915_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
3593#define WM8915_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
3594#define WM8915_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
3595#define WM8915_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
3596#define WM8915_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
3597#define WM8915_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
3598#define WM8915_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
3599#define WM8915_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
3600#define WM8915_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
3601#define WM8915_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
3602#define WM8915_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
3603#define WM8915_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
3604#define WM8915_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
3605
3606/*
3607 * R1849 (0x739) - Interrupt Status 2 Mask
3608 */
3609#define WM8915_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */
3610#define WM8915_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */
3611#define WM8915_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */
3612#define WM8915_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */
3613#define WM8915_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */
3614#define WM8915_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */
3615#define WM8915_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */
3616#define WM8915_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */
3617#define WM8915_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */
3618#define WM8915_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */
3619#define WM8915_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */
3620#define WM8915_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
3621#define WM8915_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */
3622#define WM8915_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */
3623#define WM8915_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */
3624#define WM8915_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
3625#define WM8915_IM_DSP2DRC_SIG_DET_EINT 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */
3626#define WM8915_IM_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */
3627#define WM8915_IM_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* IM_DSP2DRC_SIG_DET_EINT */
3628#define WM8915_IM_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP2DRC_SIG_DET_EINT */
3629#define WM8915_IM_DSP1DRC_SIG_DET_EINT 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */
3630#define WM8915_IM_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */
3631#define WM8915_IM_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* IM_DSP1DRC_SIG_DET_EINT */
3632#define WM8915_IM_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP1DRC_SIG_DET_EINT */
3633#define WM8915_IM_FLL_SW_CLK_DONE_EINT 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */
3634#define WM8915_IM_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */
3635#define WM8915_IM_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* IM_FLL_SW_CLK_DONE_EINT */
3636#define WM8915_IM_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* IM_FLL_SW_CLK_DONE_EINT */
3637#define WM8915_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */
3638#define WM8915_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */
3639#define WM8915_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */
3640#define WM8915_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
3641#define WM8915_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */
3642#define WM8915_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */
3643#define WM8915_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */
3644#define WM8915_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */
3645#define WM8915_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */
3646#define WM8915_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */
3647#define WM8915_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */
3648#define WM8915_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */
3649
3650/*
3651 * R1856 (0x740) - Interrupt Control
3652 */
3653#define WM8915_IM_IRQ 0x0001 /* IM_IRQ */
3654#define WM8915_IM_IRQ_MASK 0x0001 /* IM_IRQ */
3655#define WM8915_IM_IRQ_SHIFT 0 /* IM_IRQ */
3656#define WM8915_IM_IRQ_WIDTH 1 /* IM_IRQ */
3657
3658/*
3659 * R2048 (0x800) - Left PDM Speaker
3660 */
3661#define WM8915_SPKL_ENA 0x0010 /* SPKL_ENA */
3662#define WM8915_SPKL_ENA_MASK 0x0010 /* SPKL_ENA */
3663#define WM8915_SPKL_ENA_SHIFT 4 /* SPKL_ENA */
3664#define WM8915_SPKL_ENA_WIDTH 1 /* SPKL_ENA */
3665#define WM8915_SPKL_MUTE 0x0008 /* SPKL_MUTE */
3666#define WM8915_SPKL_MUTE_MASK 0x0008 /* SPKL_MUTE */
3667#define WM8915_SPKL_MUTE_SHIFT 3 /* SPKL_MUTE */
3668#define WM8915_SPKL_MUTE_WIDTH 1 /* SPKL_MUTE */
3669#define WM8915_SPKL_MUTE_ZC 0x0004 /* SPKL_MUTE_ZC */
3670#define WM8915_SPKL_MUTE_ZC_MASK 0x0004 /* SPKL_MUTE_ZC */
3671#define WM8915_SPKL_MUTE_ZC_SHIFT 2 /* SPKL_MUTE_ZC */
3672#define WM8915_SPKL_MUTE_ZC_WIDTH 1 /* SPKL_MUTE_ZC */
3673#define WM8915_SPKL_SRC_MASK 0x0003 /* SPKL_SRC - [1:0] */
3674#define WM8915_SPKL_SRC_SHIFT 0 /* SPKL_SRC - [1:0] */
3675#define WM8915_SPKL_SRC_WIDTH 2 /* SPKL_SRC - [1:0] */
3676
3677/*
3678 * R2049 (0x801) - Right PDM Speaker
3679 */
3680#define WM8915_SPKR_ENA 0x0010 /* SPKR_ENA */
3681#define WM8915_SPKR_ENA_MASK 0x0010 /* SPKR_ENA */
3682#define WM8915_SPKR_ENA_SHIFT 4 /* SPKR_ENA */
3683#define WM8915_SPKR_ENA_WIDTH 1 /* SPKR_ENA */
3684#define WM8915_SPKR_MUTE 0x0008 /* SPKR_MUTE */
3685#define WM8915_SPKR_MUTE_MASK 0x0008 /* SPKR_MUTE */
3686#define WM8915_SPKR_MUTE_SHIFT 3 /* SPKR_MUTE */
3687#define WM8915_SPKR_MUTE_WIDTH 1 /* SPKR_MUTE */
3688#define WM8915_SPKR_MUTE_ZC 0x0004 /* SPKR_MUTE_ZC */
3689#define WM8915_SPKR_MUTE_ZC_MASK 0x0004 /* SPKR_MUTE_ZC */
3690#define WM8915_SPKR_MUTE_ZC_SHIFT 2 /* SPKR_MUTE_ZC */
3691#define WM8915_SPKR_MUTE_ZC_WIDTH 1 /* SPKR_MUTE_ZC */
3692#define WM8915_SPKR_SRC_MASK 0x0003 /* SPKR_SRC - [1:0] */
3693#define WM8915_SPKR_SRC_SHIFT 0 /* SPKR_SRC - [1:0] */
3694#define WM8915_SPKR_SRC_WIDTH 2 /* SPKR_SRC - [1:0] */
3695
3696/*
3697 * R2050 (0x802) - PDM Speaker Mute Sequence
3698 */
3699#define WM8915_SPK_MUTE_ENDIAN 0x0100 /* SPK_MUTE_ENDIAN */
3700#define WM8915_SPK_MUTE_ENDIAN_MASK 0x0100 /* SPK_MUTE_ENDIAN */
3701#define WM8915_SPK_MUTE_ENDIAN_SHIFT 8 /* SPK_MUTE_ENDIAN */
3702#define WM8915_SPK_MUTE_ENDIAN_WIDTH 1 /* SPK_MUTE_ENDIAN */
3703#define WM8915_SPK_MUTE_SEQ1_MASK 0x00FF /* SPK_MUTE_SEQ1 - [7:0] */
3704#define WM8915_SPK_MUTE_SEQ1_SHIFT 0 /* SPK_MUTE_SEQ1 - [7:0] */
3705#define WM8915_SPK_MUTE_SEQ1_WIDTH 8 /* SPK_MUTE_SEQ1 - [7:0] */
3706
3707/*
3708 * R2051 (0x803) - PDM Speaker Volume
3709 */
3710#define WM8915_SPKR_VOL_MASK 0x00F0 /* SPKR_VOL - [7:4] */
3711#define WM8915_SPKR_VOL_SHIFT 4 /* SPKR_VOL - [7:4] */
3712#define WM8915_SPKR_VOL_WIDTH 4 /* SPKR_VOL - [7:4] */
3713#define WM8915_SPKL_VOL_MASK 0x000F /* SPKL_VOL - [3:0] */
3714#define WM8915_SPKL_VOL_SHIFT 0 /* SPKL_VOL - [3:0] */
3715#define WM8915_SPKL_VOL_WIDTH 4 /* SPKL_VOL - [3:0] */
3716
3717#endif
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
new file mode 100644
index 000000000000..0293763debe5
--- /dev/null
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -0,0 +1,1051 @@
1/*
2 * wm8958-dsp2.c -- WM8958 DSP2 support
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/slab.h>
21#include <sound/soc.h>
22#include <sound/initval.h>
23#include <sound/tlv.h>
24#include <trace/events/asoc.h>
25
26#include <linux/mfd/wm8994/core.h>
27#include <linux/mfd/wm8994/registers.h>
28#include <linux/mfd/wm8994/pdata.h>
29#include <linux/mfd/wm8994/gpio.h>
30
31#include "wm8994.h"
32
33#define WM_FW_BLOCK_INFO 0xff
34#define WM_FW_BLOCK_PM 0x00
35#define WM_FW_BLOCK_X 0x01
36#define WM_FW_BLOCK_Y 0x02
37#define WM_FW_BLOCK_Z 0x03
38#define WM_FW_BLOCK_I 0x06
39#define WM_FW_BLOCK_A 0x08
40#define WM_FW_BLOCK_C 0x0c
41
42static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
43 const struct firmware *fw, bool check)
44{
45 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
46 u64 data64;
47 u32 data32;
48 const u8 *data;
49 char *str;
50 size_t block_len, len;
51 int ret = 0;
52
53 /* Suppress unneeded downloads */
54 if (wm8994->cur_fw == fw)
55 return 0;
56
57 if (fw->size < 32) {
58 dev_err(codec->dev, "%s: firmware too short\n", name);
59 goto err;
60 }
61
62 if (memcmp(fw->data, "WMFW", 4) != 0) {
63 dev_err(codec->dev, "%s: firmware has bad file magic %08x\n",
64 name, data32);
65 goto err;
66 }
67
68 memcpy(&data32, fw->data + 4, sizeof(data32));
69 len = be32_to_cpu(data32);
70
71 memcpy(&data32, fw->data + 8, sizeof(data32));
72 data32 = be32_to_cpu(data32);
73 if ((data32 >> 24) & 0xff) {
74 dev_err(codec->dev, "%s: unsupported firmware version %d\n",
75 name, (data32 >> 24) & 0xff);
76 goto err;
77 }
78 if ((data32 & 0xffff) != 8958) {
79 dev_err(codec->dev, "%s: unsupported target device %d\n",
80 name, data32 & 0xffff);
81 goto err;
82 }
83 if (((data32 >> 16) & 0xff) != 0xc) {
84 dev_err(codec->dev, "%s: unsupported target core %d\n",
85 name, (data32 >> 16) & 0xff);
86 goto err;
87 }
88
89 if (check) {
90 memcpy(&data64, fw->data + 24, sizeof(u64));
91 dev_info(codec->dev, "%s timestamp %llx\n",
92 name, be64_to_cpu(data64));
93 } else {
94 snd_soc_write(codec, 0x102, 0x2);
95 snd_soc_write(codec, 0x900, 0x2);
96 }
97
98 data = fw->data + len;
99 len = fw->size - len;
100 while (len) {
101 if (len < 12) {
102 dev_err(codec->dev, "%s short data block of %zd\n",
103 name, len);
104 goto err;
105 }
106
107 memcpy(&data32, data + 4, sizeof(data32));
108 block_len = be32_to_cpu(data32);
109 if (block_len + 8 > len) {
110 dev_err(codec->dev, "%zd byte block longer than file\n",
111 block_len);
112 goto err;
113 }
114 if (block_len == 0) {
115 dev_err(codec->dev, "Zero length block\n");
116 goto err;
117 }
118
119 memcpy(&data32, data, sizeof(data32));
120 data32 = be32_to_cpu(data32);
121
122 switch ((data32 >> 24) & 0xff) {
123 case WM_FW_BLOCK_INFO:
124 /* Informational text */
125 if (!check)
126 break;
127
128 str = kzalloc(block_len + 1, GFP_KERNEL);
129 if (str) {
130 memcpy(str, data + 8, block_len);
131 dev_info(codec->dev, "%s: %s\n", name, str);
132 kfree(str);
133 } else {
134 dev_err(codec->dev, "Out of memory\n");
135 }
136 break;
137 case WM_FW_BLOCK_PM:
138 case WM_FW_BLOCK_X:
139 case WM_FW_BLOCK_Y:
140 case WM_FW_BLOCK_Z:
141 case WM_FW_BLOCK_I:
142 case WM_FW_BLOCK_A:
143 case WM_FW_BLOCK_C:
144 dev_dbg(codec->dev, "%s: %zd bytes of %x@%x\n", name,
145 block_len, (data32 >> 24) & 0xff,
146 data32 & 0xffffff);
147
148 if (check)
149 break;
150
151 data32 &= 0xffffff;
152
153 wm8994_bulk_write(codec->control_data,
154 data32 & 0xffffff,
155 block_len / 2,
156 (void *)(data + 8));
157
158 break;
159 default:
160 dev_warn(codec->dev, "%s: unknown block type %d\n",
161 name, (data32 >> 24) & 0xff);
162 break;
163 }
164
165 /* Round up to the next 32 bit word */
166 block_len += block_len % 4;
167
168 data += block_len + 8;
169 len -= block_len + 8;
170 }
171
172 if (!check) {
173 dev_dbg(codec->dev, "%s: download done\n", name);
174 wm8994->cur_fw = fw;
175 } else {
176 dev_info(codec->dev, "%s: got firmware\n", name);
177 }
178
179 goto ok;
180
181err:
182 ret = -EINVAL;
183ok:
184 if (!check) {
185 snd_soc_write(codec, 0x900, 0x0);
186 snd_soc_write(codec, 0x102, 0x0);
187 }
188
189 return ret;
190}
191
192static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path)
193{
194 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
195 struct wm8994_pdata *pdata = wm8994->pdata;
196 int i;
197
198 /* If the DSP is already running then noop */
199 if (snd_soc_read(codec, WM8958_DSP2_PROGRAM) & WM8958_DSP2_ENA)
200 return;
201
202 /* If we have MBC firmware download it */
203 if (wm8994->mbc)
204 wm8958_dsp2_fw(codec, "MBC", wm8994->mbc, false);
205
206 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
207 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
208
209 /* If we've got user supplied MBC settings use them */
210 if (pdata && pdata->num_mbc_cfgs) {
211 struct wm8958_mbc_cfg *cfg
212 = &pdata->mbc_cfgs[wm8994->mbc_cfg];
213
214 for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++)
215 snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1,
216 cfg->coeff_regs[i]);
217
218 for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++)
219 snd_soc_write(codec,
220 i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1,
221 cfg->cutoff_regs[i]);
222 }
223
224 /* Run the DSP */
225 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
226 WM8958_DSP2_RUNR);
227
228 /* And we're off! */
229 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
230 WM8958_MBC_ENA |
231 WM8958_MBC_SEL_MASK,
232 path << WM8958_MBC_SEL_SHIFT |
233 WM8958_MBC_ENA);
234}
235
236static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path)
237{
238 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
239 struct wm8994_pdata *pdata = wm8994->pdata;
240 int i, ena;
241
242 if (wm8994->mbc_vss)
243 wm8958_dsp2_fw(codec, "MBC+VSS", wm8994->mbc_vss, false);
244
245 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
246 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
247
248 /* If we've got user supplied settings use them */
249 if (pdata && pdata->num_mbc_cfgs) {
250 struct wm8958_mbc_cfg *cfg
251 = &pdata->mbc_cfgs[wm8994->mbc_cfg];
252
253 for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++)
254 snd_soc_write(codec, i + 0x2800,
255 cfg->combined_regs[i]);
256 }
257
258 if (pdata && pdata->num_vss_cfgs) {
259 struct wm8958_vss_cfg *cfg
260 = &pdata->vss_cfgs[wm8994->vss_cfg];
261
262 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
263 snd_soc_write(codec, i + 0x2600, cfg->regs[i]);
264 }
265
266 if (pdata && pdata->num_vss_hpf_cfgs) {
267 struct wm8958_vss_hpf_cfg *cfg
268 = &pdata->vss_hpf_cfgs[wm8994->vss_hpf_cfg];
269
270 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
271 snd_soc_write(codec, i + 0x2400, cfg->regs[i]);
272 }
273
274 /* Run the DSP */
275 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
276 WM8958_DSP2_RUNR);
277
278 /* Enable the algorithms we've selected */
279 ena = 0;
280 if (wm8994->mbc_ena[path])
281 ena |= 0x8;
282 if (wm8994->hpf2_ena[path])
283 ena |= 0x4;
284 if (wm8994->hpf1_ena[path])
285 ena |= 0x2;
286 if (wm8994->vss_ena[path])
287 ena |= 0x1;
288
289 snd_soc_write(codec, 0x2201, ena);
290
291 /* Switch the DSP into the data path */
292 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
293 WM8958_MBC_SEL_MASK | WM8958_MBC_ENA,
294 path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA);
295}
296
297static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path)
298{
299 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
300 struct wm8994_pdata *pdata = wm8994->pdata;
301 int i;
302
303 wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false);
304
305 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
306 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
307
308 /* If we've got user supplied settings use them */
309 if (pdata && pdata->num_enh_eq_cfgs) {
310 struct wm8958_enh_eq_cfg *cfg
311 = &pdata->enh_eq_cfgs[wm8994->enh_eq_cfg];
312
313 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
314 snd_soc_write(codec, i + 0x2200,
315 cfg->regs[i]);
316 }
317
318 /* Run the DSP */
319 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
320 WM8958_DSP2_RUNR);
321
322 /* Switch the DSP into the data path */
323 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
324 WM8958_MBC_SEL_MASK | WM8958_MBC_ENA,
325 path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA);
326}
327
328static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start)
329{
330 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
331 int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5);
332 int ena, reg, aif;
333
334 switch (path) {
335 case 0:
336 pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA);
337 aif = 0;
338 break;
339 case 1:
340 pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
341 aif = 0;
342 break;
343 case 2:
344 pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA);
345 aif = 1;
346 break;
347 default:
348 BUG();
349 return;
350 }
351
352 /* Do we have both an active AIF and an active algorithm? */
353 ena = wm8994->mbc_ena[path] || wm8994->vss_ena[path] ||
354 wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path] ||
355 wm8994->enh_eq_ena[path];
356 if (!pwr_reg)
357 ena = 0;
358
359 reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM);
360
361 dev_dbg(codec->dev, "DSP path %d %d startup: %d, power: %x, DSP: %x\n",
362 path, wm8994->dsp_active, start, pwr_reg, reg);
363
364 if (start && ena) {
365 /* If the DSP is already running then noop */
366 if (reg & WM8958_DSP2_ENA)
367 return;
368
369 /* If either AIFnCLK is not yet enabled postpone */
370 if (!(snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
371 & WM8994_AIF1CLK_ENA_MASK) &&
372 !(snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
373 & WM8994_AIF2CLK_ENA_MASK))
374 return;
375
376 /* Switch the clock over to the appropriate AIF */
377 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
378 WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA,
379 aif << WM8958_DSP2CLK_SRC_SHIFT |
380 WM8958_DSP2CLK_ENA);
381
382 if (wm8994->enh_eq_ena[path])
383 wm8958_dsp_start_enh_eq(codec, path);
384 else if (wm8994->vss_ena[path] || wm8994->hpf1_ena[path] ||
385 wm8994->hpf2_ena[path])
386 wm8958_dsp_start_vss(codec, path);
387 else if (wm8994->mbc_ena[path])
388 wm8958_dsp_start_mbc(codec, path);
389
390 wm8994->dsp_active = path;
391
392 dev_dbg(codec->dev, "DSP running in path %d\n", path);
393 }
394
395 if (!start && wm8994->dsp_active == path) {
396 /* If the DSP is already stopped then noop */
397 if (!(reg & WM8958_DSP2_ENA))
398 return;
399
400 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
401 WM8958_MBC_ENA, 0);
402 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
403 WM8958_DSP2_STOP);
404 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
405 WM8958_DSP2_ENA, 0);
406 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
407 WM8958_DSP2CLK_ENA, 0);
408
409 wm8994->dsp_active = -1;
410
411 dev_dbg(codec->dev, "DSP stopped\n");
412 }
413}
414
415int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
416 struct snd_kcontrol *kcontrol, int event)
417{
418 struct snd_soc_codec *codec = w->codec;
419 int i;
420
421 switch (event) {
422 case SND_SOC_DAPM_POST_PMU:
423 case SND_SOC_DAPM_PRE_PMU:
424 for (i = 0; i < 3; i++)
425 wm8958_dsp_apply(codec, i, 1);
426 break;
427 case SND_SOC_DAPM_POST_PMD:
428 case SND_SOC_DAPM_PRE_PMD:
429 for (i = 0; i < 3; i++)
430 wm8958_dsp_apply(codec, i, 0);
431 break;
432 }
433
434 return 0;
435}
436
437/* Check if DSP2 is in use on another AIF */
438static int wm8958_dsp2_busy(struct wm8994_priv *wm8994, int aif)
439{
440 int i;
441
442 for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) {
443 if (i == aif)
444 continue;
445 if (wm8994->mbc_ena[i] || wm8994->vss_ena[i] ||
446 wm8994->hpf1_ena[i] || wm8994->hpf2_ena[i])
447 return 1;
448 }
449
450 return 0;
451}
452
453static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_value *ucontrol)
455{
456 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
457 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
458 struct wm8994_pdata *pdata = wm8994->pdata;
459 int value = ucontrol->value.integer.value[0];
460 int reg;
461
462 /* Don't allow on the fly reconfiguration */
463 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
464 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
465 return -EBUSY;
466
467 if (value >= pdata->num_mbc_cfgs)
468 return -EINVAL;
469
470 wm8994->mbc_cfg = value;
471
472 return 0;
473}
474
475static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol,
476 struct snd_ctl_elem_value *ucontrol)
477{
478 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
479 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
480
481 ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg;
482
483 return 0;
484}
485
486static int wm8958_mbc_info(struct snd_kcontrol *kcontrol,
487 struct snd_ctl_elem_info *uinfo)
488{
489 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
490 uinfo->count = 1;
491 uinfo->value.integer.min = 0;
492 uinfo->value.integer.max = 1;
493 return 0;
494}
495
496static int wm8958_mbc_get(struct snd_kcontrol *kcontrol,
497 struct snd_ctl_elem_value *ucontrol)
498{
499 int mbc = kcontrol->private_value;
500 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
501 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
502
503 ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc];
504
505 return 0;
506}
507
508static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
509 struct snd_ctl_elem_value *ucontrol)
510{
511 int mbc = kcontrol->private_value;
512 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
513 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
514
515 if (wm8994->mbc_ena[mbc] == ucontrol->value.integer.value[0])
516 return 0;
517
518 if (ucontrol->value.integer.value[0] > 1)
519 return -EINVAL;
520
521 if (wm8958_dsp2_busy(wm8994, mbc)) {
522 dev_dbg(codec->dev, "DSP2 active on %d already\n", mbc);
523 return -EBUSY;
524 }
525
526 if (wm8994->enh_eq_ena[mbc])
527 return -EBUSY;
528
529 wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0];
530
531 wm8958_dsp_apply(codec, mbc, wm8994->mbc_ena[mbc]);
532
533 return 0;
534}
535
536#define WM8958_MBC_SWITCH(xname, xval) {\
537 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
538 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
539 .info = wm8958_mbc_info, \
540 .get = wm8958_mbc_get, .put = wm8958_mbc_put, \
541 .private_value = xval }
542
543static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_value *ucontrol)
545{
546 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
547 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
548 struct wm8994_pdata *pdata = wm8994->pdata;
549 int value = ucontrol->value.integer.value[0];
550 int reg;
551
552 /* Don't allow on the fly reconfiguration */
553 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
554 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
555 return -EBUSY;
556
557 if (value >= pdata->num_vss_cfgs)
558 return -EINVAL;
559
560 wm8994->vss_cfg = value;
561
562 return 0;
563}
564
565static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol,
566 struct snd_ctl_elem_value *ucontrol)
567{
568 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
569 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
570
571 ucontrol->value.enumerated.item[0] = wm8994->vss_cfg;
572
573 return 0;
574}
575
576static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol,
577 struct snd_ctl_elem_value *ucontrol)
578{
579 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
580 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
581 struct wm8994_pdata *pdata = wm8994->pdata;
582 int value = ucontrol->value.integer.value[0];
583 int reg;
584
585 /* Don't allow on the fly reconfiguration */
586 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
587 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
588 return -EBUSY;
589
590 if (value >= pdata->num_vss_hpf_cfgs)
591 return -EINVAL;
592
593 wm8994->vss_hpf_cfg = value;
594
595 return 0;
596}
597
598static int wm8958_get_vss_hpf_enum(struct snd_kcontrol *kcontrol,
599 struct snd_ctl_elem_value *ucontrol)
600{
601 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
602 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
603
604 ucontrol->value.enumerated.item[0] = wm8994->vss_hpf_cfg;
605
606 return 0;
607}
608
609static int wm8958_vss_info(struct snd_kcontrol *kcontrol,
610 struct snd_ctl_elem_info *uinfo)
611{
612 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
613 uinfo->count = 1;
614 uinfo->value.integer.min = 0;
615 uinfo->value.integer.max = 1;
616 return 0;
617}
618
619static int wm8958_vss_get(struct snd_kcontrol *kcontrol,
620 struct snd_ctl_elem_value *ucontrol)
621{
622 int vss = kcontrol->private_value;
623 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
624 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
625
626 ucontrol->value.integer.value[0] = wm8994->vss_ena[vss];
627
628 return 0;
629}
630
631static int wm8958_vss_put(struct snd_kcontrol *kcontrol,
632 struct snd_ctl_elem_value *ucontrol)
633{
634 int vss = kcontrol->private_value;
635 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
636 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
637
638 if (wm8994->vss_ena[vss] == ucontrol->value.integer.value[0])
639 return 0;
640
641 if (ucontrol->value.integer.value[0] > 1)
642 return -EINVAL;
643
644 if (!wm8994->mbc_vss)
645 return -ENODEV;
646
647 if (wm8958_dsp2_busy(wm8994, vss)) {
648 dev_dbg(codec->dev, "DSP2 active on %d already\n", vss);
649 return -EBUSY;
650 }
651
652 if (wm8994->enh_eq_ena[vss])
653 return -EBUSY;
654
655 wm8994->vss_ena[vss] = ucontrol->value.integer.value[0];
656
657 wm8958_dsp_apply(codec, vss, wm8994->vss_ena[vss]);
658
659 return 0;
660}
661
662
663#define WM8958_VSS_SWITCH(xname, xval) {\
664 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
665 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
666 .info = wm8958_vss_info, \
667 .get = wm8958_vss_get, .put = wm8958_vss_put, \
668 .private_value = xval }
669
670static int wm8958_hpf_info(struct snd_kcontrol *kcontrol,
671 struct snd_ctl_elem_info *uinfo)
672{
673 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
674 uinfo->count = 1;
675 uinfo->value.integer.min = 0;
676 uinfo->value.integer.max = 1;
677 return 0;
678}
679
680static int wm8958_hpf_get(struct snd_kcontrol *kcontrol,
681 struct snd_ctl_elem_value *ucontrol)
682{
683 int hpf = kcontrol->private_value;
684 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
685 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
686
687 if (hpf < 3)
688 ucontrol->value.integer.value[0] = wm8994->hpf1_ena[hpf % 3];
689 else
690 ucontrol->value.integer.value[0] = wm8994->hpf2_ena[hpf % 3];
691
692 return 0;
693}
694
695static int wm8958_hpf_put(struct snd_kcontrol *kcontrol,
696 struct snd_ctl_elem_value *ucontrol)
697{
698 int hpf = kcontrol->private_value;
699 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
700 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
701
702 if (hpf < 3) {
703 if (wm8994->hpf1_ena[hpf % 3] ==
704 ucontrol->value.integer.value[0])
705 return 0;
706 } else {
707 if (wm8994->hpf2_ena[hpf % 3] ==
708 ucontrol->value.integer.value[0])
709 return 0;
710 }
711
712 if (ucontrol->value.integer.value[0] > 1)
713 return -EINVAL;
714
715 if (!wm8994->mbc_vss)
716 return -ENODEV;
717
718 if (wm8958_dsp2_busy(wm8994, hpf % 3)) {
719 dev_dbg(codec->dev, "DSP2 active on %d already\n", hpf);
720 return -EBUSY;
721 }
722
723 if (wm8994->enh_eq_ena[hpf % 3])
724 return -EBUSY;
725
726 if (hpf < 3)
727 wm8994->hpf1_ena[hpf % 3] = ucontrol->value.integer.value[0];
728 else
729 wm8994->hpf2_ena[hpf % 3] = ucontrol->value.integer.value[0];
730
731 wm8958_dsp_apply(codec, hpf % 3, ucontrol->value.integer.value[0]);
732
733 return 0;
734}
735
736#define WM8958_HPF_SWITCH(xname, xval) {\
737 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
738 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
739 .info = wm8958_hpf_info, \
740 .get = wm8958_hpf_get, .put = wm8958_hpf_put, \
741 .private_value = xval }
742
743static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol,
744 struct snd_ctl_elem_value *ucontrol)
745{
746 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
747 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
748 struct wm8994_pdata *pdata = wm8994->pdata;
749 int value = ucontrol->value.integer.value[0];
750 int reg;
751
752 /* Don't allow on the fly reconfiguration */
753 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
754 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
755 return -EBUSY;
756
757 if (value >= pdata->num_enh_eq_cfgs)
758 return -EINVAL;
759
760 wm8994->enh_eq_cfg = value;
761
762 return 0;
763}
764
765static int wm8958_get_enh_eq_enum(struct snd_kcontrol *kcontrol,
766 struct snd_ctl_elem_value *ucontrol)
767{
768 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
769 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
770
771 ucontrol->value.enumerated.item[0] = wm8994->enh_eq_cfg;
772
773 return 0;
774}
775
776static int wm8958_enh_eq_info(struct snd_kcontrol *kcontrol,
777 struct snd_ctl_elem_info *uinfo)
778{
779 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
780 uinfo->count = 1;
781 uinfo->value.integer.min = 0;
782 uinfo->value.integer.max = 1;
783 return 0;
784}
785
786static int wm8958_enh_eq_get(struct snd_kcontrol *kcontrol,
787 struct snd_ctl_elem_value *ucontrol)
788{
789 int eq = kcontrol->private_value;
790 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
791 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
792
793 ucontrol->value.integer.value[0] = wm8994->enh_eq_ena[eq];
794
795 return 0;
796}
797
798static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol,
799 struct snd_ctl_elem_value *ucontrol)
800{
801 int eq = kcontrol->private_value;
802 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
803 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
804
805 if (wm8994->enh_eq_ena[eq] == ucontrol->value.integer.value[0])
806 return 0;
807
808 if (ucontrol->value.integer.value[0] > 1)
809 return -EINVAL;
810
811 if (!wm8994->enh_eq)
812 return -ENODEV;
813
814 if (wm8958_dsp2_busy(wm8994, eq)) {
815 dev_dbg(codec->dev, "DSP2 active on %d already\n", eq);
816 return -EBUSY;
817 }
818
819 if (wm8994->mbc_ena[eq] || wm8994->vss_ena[eq] ||
820 wm8994->hpf1_ena[eq] || wm8994->hpf2_ena[eq])
821 return -EBUSY;
822
823 wm8994->enh_eq_ena[eq] = ucontrol->value.integer.value[0];
824
825 wm8958_dsp_apply(codec, eq, ucontrol->value.integer.value[0]);
826
827 return 0;
828}
829
830#define WM8958_ENH_EQ_SWITCH(xname, xval) {\
831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
832 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
833 .info = wm8958_enh_eq_info, \
834 .get = wm8958_enh_eq_get, .put = wm8958_enh_eq_put, \
835 .private_value = xval }
836
837static const struct snd_kcontrol_new wm8958_mbc_snd_controls[] = {
838WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0),
839WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1),
840WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2),
841};
842
843static const struct snd_kcontrol_new wm8958_vss_snd_controls[] = {
844WM8958_VSS_SWITCH("AIF1DAC1 VSS Switch", 0),
845WM8958_VSS_SWITCH("AIF1DAC2 VSS Switch", 1),
846WM8958_VSS_SWITCH("AIF2DAC VSS Switch", 2),
847WM8958_HPF_SWITCH("AIF1DAC1 HPF1 Switch", 0),
848WM8958_HPF_SWITCH("AIF1DAC2 HPF1 Switch", 1),
849WM8958_HPF_SWITCH("AIF2DAC HPF1 Switch", 2),
850WM8958_HPF_SWITCH("AIF1DAC1 HPF2 Switch", 3),
851WM8958_HPF_SWITCH("AIF1DAC2 HPF2 Switch", 4),
852WM8958_HPF_SWITCH("AIF2DAC HPF2 Switch", 5),
853};
854
855static const struct snd_kcontrol_new wm8958_enh_eq_snd_controls[] = {
856WM8958_ENH_EQ_SWITCH("AIF1DAC1 Enhanced EQ Switch", 0),
857WM8958_ENH_EQ_SWITCH("AIF1DAC2 Enhanced EQ Switch", 1),
858WM8958_ENH_EQ_SWITCH("AIF2DAC Enhanced EQ Switch", 2),
859};
860
861static void wm8958_enh_eq_loaded(const struct firmware *fw, void *context)
862{
863 struct snd_soc_codec *codec = context;
864 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
865
866 if (fw && (wm8958_dsp2_fw(codec, "ENH_EQ", fw, true) == 0)) {
867 mutex_lock(&codec->mutex);
868 wm8994->enh_eq = fw;
869 mutex_unlock(&codec->mutex);
870 }
871}
872
873static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context)
874{
875 struct snd_soc_codec *codec = context;
876 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
877
878 if (fw && (wm8958_dsp2_fw(codec, "MBC+VSS", fw, true) == 0)) {
879 mutex_lock(&codec->mutex);
880 wm8994->mbc_vss = fw;
881 mutex_unlock(&codec->mutex);
882 }
883
884 /* We can't have more than one request outstanding at once so
885 * we daisy chain.
886 */
887 request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
888 "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL,
889 codec, wm8958_enh_eq_loaded);
890}
891
892static void wm8958_mbc_loaded(const struct firmware *fw, void *context)
893{
894 struct snd_soc_codec *codec = context;
895 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
896
897 if (wm8958_dsp2_fw(codec, "MBC", fw, true) != 0)
898 return;
899
900 mutex_lock(&codec->mutex);
901 wm8994->mbc = fw;
902 mutex_unlock(&codec->mutex);
903
904 /* We can't have more than one request outstanding at once so
905 * we daisy chain.
906 */
907 request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
908 "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL,
909 codec, wm8958_mbc_vss_loaded);
910}
911
912void wm8958_dsp2_init(struct snd_soc_codec *codec)
913{
914 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
915 struct wm8994_pdata *pdata = wm8994->pdata;
916 int ret, i;
917
918 wm8994->dsp_active = -1;
919
920 snd_soc_add_controls(codec, wm8958_mbc_snd_controls,
921 ARRAY_SIZE(wm8958_mbc_snd_controls));
922 snd_soc_add_controls(codec, wm8958_vss_snd_controls,
923 ARRAY_SIZE(wm8958_vss_snd_controls));
924 snd_soc_add_controls(codec, wm8958_enh_eq_snd_controls,
925 ARRAY_SIZE(wm8958_enh_eq_snd_controls));
926
927
928 /* We don't *require* firmware and don't want to delay boot */
929 request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
930 "wm8958_mbc.wfw", codec->dev, GFP_KERNEL,
931 codec, wm8958_mbc_loaded);
932
933 if (!pdata)
934 return;
935
936 if (pdata->num_mbc_cfgs) {
937 struct snd_kcontrol_new control[] = {
938 SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum,
939 wm8958_get_mbc_enum, wm8958_put_mbc_enum),
940 };
941
942 /* We need an array of texts for the enum API */
943 wm8994->mbc_texts = kmalloc(sizeof(char *)
944 * pdata->num_mbc_cfgs, GFP_KERNEL);
945 if (!wm8994->mbc_texts) {
946 dev_err(wm8994->codec->dev,
947 "Failed to allocate %d MBC config texts\n",
948 pdata->num_mbc_cfgs);
949 return;
950 }
951
952 for (i = 0; i < pdata->num_mbc_cfgs; i++)
953 wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name;
954
955 wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
956 wm8994->mbc_enum.texts = wm8994->mbc_texts;
957
958 ret = snd_soc_add_controls(wm8994->codec, control, 1);
959 if (ret != 0)
960 dev_err(wm8994->codec->dev,
961 "Failed to add MBC mode controls: %d\n", ret);
962 }
963
964 if (pdata->num_vss_cfgs) {
965 struct snd_kcontrol_new control[] = {
966 SOC_ENUM_EXT("VSS Mode", wm8994->vss_enum,
967 wm8958_get_vss_enum, wm8958_put_vss_enum),
968 };
969
970 /* We need an array of texts for the enum API */
971 wm8994->vss_texts = kmalloc(sizeof(char *)
972 * pdata->num_vss_cfgs, GFP_KERNEL);
973 if (!wm8994->vss_texts) {
974 dev_err(wm8994->codec->dev,
975 "Failed to allocate %d VSS config texts\n",
976 pdata->num_vss_cfgs);
977 return;
978 }
979
980 for (i = 0; i < pdata->num_vss_cfgs; i++)
981 wm8994->vss_texts[i] = pdata->vss_cfgs[i].name;
982
983 wm8994->vss_enum.max = pdata->num_vss_cfgs;
984 wm8994->vss_enum.texts = wm8994->vss_texts;
985
986 ret = snd_soc_add_controls(wm8994->codec, control, 1);
987 if (ret != 0)
988 dev_err(wm8994->codec->dev,
989 "Failed to add VSS mode controls: %d\n", ret);
990 }
991
992 if (pdata->num_vss_hpf_cfgs) {
993 struct snd_kcontrol_new control[] = {
994 SOC_ENUM_EXT("VSS HPF Mode", wm8994->vss_hpf_enum,
995 wm8958_get_vss_hpf_enum,
996 wm8958_put_vss_hpf_enum),
997 };
998
999 /* We need an array of texts for the enum API */
1000 wm8994->vss_hpf_texts = kmalloc(sizeof(char *)
1001 * pdata->num_vss_hpf_cfgs, GFP_KERNEL);
1002 if (!wm8994->vss_hpf_texts) {
1003 dev_err(wm8994->codec->dev,
1004 "Failed to allocate %d VSS HPF config texts\n",
1005 pdata->num_vss_hpf_cfgs);
1006 return;
1007 }
1008
1009 for (i = 0; i < pdata->num_vss_hpf_cfgs; i++)
1010 wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name;
1011
1012 wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs;
1013 wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts;
1014
1015 ret = snd_soc_add_controls(wm8994->codec, control, 1);
1016 if (ret != 0)
1017 dev_err(wm8994->codec->dev,
1018 "Failed to add VSS HPFmode controls: %d\n",
1019 ret);
1020 }
1021
1022 if (pdata->num_enh_eq_cfgs) {
1023 struct snd_kcontrol_new control[] = {
1024 SOC_ENUM_EXT("Enhanced EQ Mode", wm8994->enh_eq_enum,
1025 wm8958_get_enh_eq_enum,
1026 wm8958_put_enh_eq_enum),
1027 };
1028
1029 /* We need an array of texts for the enum API */
1030 wm8994->enh_eq_texts = kmalloc(sizeof(char *)
1031 * pdata->num_enh_eq_cfgs, GFP_KERNEL);
1032 if (!wm8994->enh_eq_texts) {
1033 dev_err(wm8994->codec->dev,
1034 "Failed to allocate %d enhanced EQ config texts\n",
1035 pdata->num_enh_eq_cfgs);
1036 return;
1037 }
1038
1039 for (i = 0; i < pdata->num_enh_eq_cfgs; i++)
1040 wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name;
1041
1042 wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs;
1043 wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts;
1044
1045 ret = snd_soc_add_controls(wm8994->codec, control, 1);
1046 if (ret != 0)
1047 dev_err(wm8994->codec->dev,
1048 "Failed to add enhanced EQ controls: %d\n",
1049 ret);
1050 }
1051}
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 500011eb8b2b..f90ae427242b 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -58,6 +58,7 @@ struct wm8962_priv {
58 int bclk; /* Desired BCLK */ 58 int bclk; /* Desired BCLK */
59 int lrclk; 59 int lrclk;
60 60
61 struct completion fll_lock;
61 int fll_src; 62 int fll_src;
62 int fll_fref; 63 int fll_fref;
63 int fll_fout; 64 int fll_fout;
@@ -2038,6 +2039,13 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
2038 return 0; 2039 return 0;
2039} 2040}
2040 2041
2042static const char *cap_hpf_mode_text[] = {
2043 "Hi-fi", "Application"
2044};
2045
2046static const struct soc_enum cap_hpf_mode =
2047 SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text);
2048
2041static const struct snd_kcontrol_new wm8962_snd_controls[] = { 2049static const struct snd_kcontrol_new wm8962_snd_controls[] = {
2042SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1), 2050SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1),
2043 2051
@@ -2063,6 +2071,9 @@ SOC_DOUBLE_R("Capture Switch", WM8962_LEFT_INPUT_VOLUME,
2063 WM8962_RIGHT_INPUT_VOLUME, 7, 1, 1), 2071 WM8962_RIGHT_INPUT_VOLUME, 7, 1, 1),
2064SOC_DOUBLE_R("Capture ZC Switch", WM8962_LEFT_INPUT_VOLUME, 2072SOC_DOUBLE_R("Capture ZC Switch", WM8962_LEFT_INPUT_VOLUME,
2065 WM8962_RIGHT_INPUT_VOLUME, 6, 1, 1), 2073 WM8962_RIGHT_INPUT_VOLUME, 6, 1, 1),
2074SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1),
2075SOC_ENUM("Capture HPF Mode", cap_hpf_mode),
2076SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0),
2066 2077
2067SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1, 2078SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1,
2068 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv), 2079 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv),
@@ -2467,6 +2478,7 @@ SND_SOC_DAPM_INPUT("IN3R"),
2467SND_SOC_DAPM_INPUT("IN4L"), 2478SND_SOC_DAPM_INPUT("IN4L"),
2468SND_SOC_DAPM_INPUT("IN4R"), 2479SND_SOC_DAPM_INPUT("IN4R"),
2469SND_SOC_DAPM_INPUT("Beep"), 2480SND_SOC_DAPM_INPUT("Beep"),
2481SND_SOC_DAPM_INPUT("DMICDAT"),
2470 2482
2471SND_SOC_DAPM_MICBIAS("MICBIAS", WM8962_PWR_MGMT_1, 1, 0), 2483SND_SOC_DAPM_MICBIAS("MICBIAS", WM8962_PWR_MGMT_1, 1, 0),
2472 2484
@@ -2486,6 +2498,8 @@ SND_SOC_DAPM_MIXER("MIXINL", WM8962_PWR_MGMT_1, 5, 0,
2486SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0, 2498SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0,
2487 mixinr, ARRAY_SIZE(mixinr)), 2499 mixinr, ARRAY_SIZE(mixinr)),
2488 2500
2501SND_SOC_DAPM_AIF_IN("DMIC", NULL, 0, WM8962_PWR_MGMT_1, 10, 0),
2502
2489SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0), 2503SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0),
2490SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0), 2504SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0),
2491 2505
@@ -2563,13 +2577,17 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
2563 2577
2564 { "MICBIAS", NULL, "SYSCLK" }, 2578 { "MICBIAS", NULL, "SYSCLK" },
2565 2579
2580 { "DMIC", NULL, "DMICDAT" },
2581
2566 { "ADCL", NULL, "SYSCLK" }, 2582 { "ADCL", NULL, "SYSCLK" },
2567 { "ADCL", NULL, "TOCLK" }, 2583 { "ADCL", NULL, "TOCLK" },
2568 { "ADCL", NULL, "MIXINL" }, 2584 { "ADCL", NULL, "MIXINL" },
2585 { "ADCL", NULL, "DMIC" },
2569 2586
2570 { "ADCR", NULL, "SYSCLK" }, 2587 { "ADCR", NULL, "SYSCLK" },
2571 { "ADCR", NULL, "TOCLK" }, 2588 { "ADCR", NULL, "TOCLK" },
2572 { "ADCR", NULL, "MIXINR" }, 2589 { "ADCR", NULL, "MIXINR" },
2590 { "ADCR", NULL, "DMIC" },
2573 2591
2574 { "STL", "Left", "ADCL" }, 2592 { "STL", "Left", "ADCL" },
2575 { "STL", "Right", "ADCR" }, 2593 { "STL", "Right", "ADCR" },
@@ -2990,7 +3008,6 @@ static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
2990 case WM8962_SYSCLK_FLL: 3008 case WM8962_SYSCLK_FLL:
2991 wm8962->sysclk = WM8962_SYSCLK_FLL; 3009 wm8962->sysclk = WM8962_SYSCLK_FLL;
2992 src = 1 << WM8962_SYSCLK_SRC_SHIFT; 3010 src = 1 << WM8962_SYSCLK_SRC_SHIFT;
2993 WARN_ON(freq != wm8962->fll_fout);
2994 break; 3011 break;
2995 default: 3012 default:
2996 return -EINVAL; 3013 return -EINVAL;
@@ -3172,12 +3189,12 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
3172 return 0; 3189 return 0;
3173} 3190}
3174 3191
3175static int wm8962_set_fll(struct snd_soc_dai *dai, int fll_id, int source, 3192static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
3176 unsigned int Fref, unsigned int Fout) 3193 unsigned int Fref, unsigned int Fout)
3177{ 3194{
3178 struct snd_soc_codec *codec = dai->codec;
3179 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 3195 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3180 struct _fll_div fll_div; 3196 struct _fll_div fll_div;
3197 unsigned long timeout;
3181 int ret; 3198 int ret;
3182 int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA; 3199 int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA;
3183 3200
@@ -3244,6 +3261,11 @@ static int wm8962_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
3244 3261
3245 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); 3262 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
3246 3263
3264 /* This should be a massive overestimate */
3265 timeout = msecs_to_jiffies(1);
3266
3267 wait_for_completion_timeout(&wm8962->fll_lock, timeout);
3268
3247 wm8962->fll_fref = Fref; 3269 wm8962->fll_fref = Fref;
3248 wm8962->fll_fout = Fout; 3270 wm8962->fll_fout = Fout;
3249 wm8962->fll_src = source; 3271 wm8962->fll_src = source;
@@ -3274,7 +3296,6 @@ static struct snd_soc_dai_ops wm8962_dai_ops = {
3274 .hw_params = wm8962_hw_params, 3296 .hw_params = wm8962_hw_params,
3275 .set_sysclk = wm8962_set_dai_sysclk, 3297 .set_sysclk = wm8962_set_dai_sysclk,
3276 .set_fmt = wm8962_set_dai_fmt, 3298 .set_fmt = wm8962_set_dai_fmt,
3277 .set_pll = wm8962_set_fll,
3278 .digital_mute = wm8962_mute, 3299 .digital_mute = wm8962_mute,
3279}; 3300};
3280 3301
@@ -3340,6 +3361,11 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3340 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); 3361 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
3341 active &= ~mask; 3362 active &= ~mask;
3342 3363
3364 if (active & WM8962_FLL_LOCK_EINT) {
3365 dev_dbg(codec->dev, "FLL locked\n");
3366 complete(&wm8962->fll_lock);
3367 }
3368
3343 if (active & WM8962_FIFOS_ERR_EINT) 3369 if (active & WM8962_FIFOS_ERR_EINT)
3344 dev_err(codec->dev, "FIFO error\n"); 3370 dev_err(codec->dev, "FIFO error\n");
3345 3371
@@ -3709,9 +3735,11 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3709 dev); 3735 dev);
3710 u16 *reg_cache = codec->reg_cache; 3736 u16 *reg_cache = codec->reg_cache;
3711 int i, trigger, irq_pol; 3737 int i, trigger, irq_pol;
3738 bool dmicclk, dmicdat;
3712 3739
3713 wm8962->codec = codec; 3740 wm8962->codec = codec;
3714 INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work); 3741 INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work);
3742 init_completion(&wm8962->fll_lock);
3715 3743
3716 codec->cache_sync = 1; 3744 codec->cache_sync = 1;
3717 codec->dapm.idle_bias_off = 1; 3745 codec->dapm.idle_bias_off = 1;
@@ -3845,6 +3873,29 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3845 3873
3846 wm8962_add_widgets(codec); 3874 wm8962_add_widgets(codec);
3847 3875
3876 /* Save boards having to disable DMIC when not in use */
3877 dmicclk = false;
3878 dmicdat = false;
3879 for (i = 0; i < WM8962_MAX_GPIO; i++) {
3880 switch (snd_soc_read(codec, WM8962_GPIO_BASE + i)
3881 & WM8962_GP2_FN_MASK) {
3882 case WM8962_GPIO_FN_DMICCLK:
3883 dmicclk = true;
3884 break;
3885 case WM8962_GPIO_FN_DMICDAT:
3886 dmicdat = true;
3887 break;
3888 default:
3889 break;
3890 }
3891 }
3892 if (!dmicclk || !dmicdat) {
3893 dev_dbg(codec->dev, "DMIC not in use, disabling\n");
3894 snd_soc_dapm_nc_pin(&codec->dapm, "DMICDAT");
3895 }
3896 if (dmicclk != dmicdat)
3897 dev_warn(codec->dev, "DMIC GPIOs partially configured\n");
3898
3848 wm8962_init_beep(codec); 3899 wm8962_init_beep(codec);
3849 wm8962_init_gpio(codec); 3900 wm8962_init_gpio(codec);
3850 3901
@@ -3868,9 +3919,10 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3868 i2c->irq, ret); 3919 i2c->irq, ret);
3869 /* Non-fatal */ 3920 /* Non-fatal */
3870 } else { 3921 } else {
3871 /* Enable error reporting IRQs by default */ 3922 /* Enable some IRQs by default */
3872 snd_soc_update_bits(codec, 3923 snd_soc_update_bits(codec,
3873 WM8962_INTERRUPT_STATUS_2_MASK, 3924 WM8962_INTERRUPT_STATUS_2_MASK,
3925 WM8962_FLL_LOCK_EINT |
3874 WM8962_TEMP_SHUT_EINT | 3926 WM8962_TEMP_SHUT_EINT |
3875 WM8962_FIFOS_ERR_EINT, 0); 3927 WM8962_FIFOS_ERR_EINT, 0);
3876 } 3928 }
@@ -3918,6 +3970,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
3918 .reg_cache_default = wm8962_reg, 3970 .reg_cache_default = wm8962_reg,
3919 .volatile_register = wm8962_volatile_register, 3971 .volatile_register = wm8962_volatile_register,
3920 .readable_register = wm8962_readable_register, 3972 .readable_register = wm8962_readable_register,
3973 .set_pll = wm8962_set_fll,
3921}; 3974};
3922 3975
3923#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 3976#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 056aef904347..9e5ff789b805 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -718,7 +718,8 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
718static int class_w_put(struct snd_kcontrol *kcontrol, 718static int class_w_put(struct snd_kcontrol *kcontrol,
719 struct snd_ctl_elem_value *ucontrol) 719 struct snd_ctl_elem_value *ucontrol)
720{ 720{
721 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 721 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
722 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
722 struct snd_soc_codec *codec = widget->codec; 723 struct snd_soc_codec *codec = widget->codec;
723 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 724 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
724 int ret; 725 int ret;
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 84e1bd1d2822..970a95c5360b 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -38,12 +38,6 @@
38#include "wm8994.h" 38#include "wm8994.h"
39#include "wm_hubs.h" 39#include "wm_hubs.h"
40 40
41struct fll_config {
42 int src;
43 int in;
44 int out;
45};
46
47#define WM8994_NUM_DRC 3 41#define WM8994_NUM_DRC 3
48#define WM8994_NUM_EQ 3 42#define WM8994_NUM_EQ 3
49 43
@@ -59,63 +53,11 @@ static int wm8994_retune_mobile_base[] = {
59 WM8994_AIF2_EQ_GAINS_1, 53 WM8994_AIF2_EQ_GAINS_1,
60}; 54};
61 55
62struct wm8994_micdet {
63 struct snd_soc_jack *jack;
64 int det;
65 int shrt;
66};
67
68/* codec private data */
69struct wm8994_priv {
70 struct wm_hubs_data hubs;
71 enum snd_soc_control_type control_type;
72 void *control_data;
73 struct snd_soc_codec *codec;
74 int sysclk[2];
75 int sysclk_rate[2];
76 int mclk[2];
77 int aifclk[2];
78 struct fll_config fll[2], fll_suspend[2];
79
80 int dac_rates[2];
81 int lrclk_shared[2];
82
83 int mbc_ena[3];
84
85 /* Platform dependent DRC configuration */
86 const char **drc_texts;
87 int drc_cfg[WM8994_NUM_DRC];
88 struct soc_enum drc_enum;
89
90 /* Platform dependent ReTune mobile configuration */
91 int num_retune_mobile_texts;
92 const char **retune_mobile_texts;
93 int retune_mobile_cfg[WM8994_NUM_EQ];
94 struct soc_enum retune_mobile_enum;
95
96 /* Platform dependent MBC configuration */
97 int mbc_cfg;
98 const char **mbc_texts;
99 struct soc_enum mbc_enum;
100
101 struct wm8994_micdet micdet[2];
102
103 wm8958_micdet_cb jack_cb;
104 void *jack_cb_data;
105 int micdet_irq;
106
107 int revision;
108 struct wm8994_pdata *pdata;
109
110 unsigned int aif1clk_enable:1;
111 unsigned int aif2clk_enable:1;
112
113 unsigned int aif1clk_disable:1;
114 unsigned int aif2clk_disable:1;
115};
116
117static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) 56static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
118{ 57{
58 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
59 struct wm8994 *control = wm8994->control_data;
60
119 switch (reg) { 61 switch (reg) {
120 case WM8994_GPIO_1: 62 case WM8994_GPIO_1:
121 case WM8994_GPIO_2: 63 case WM8994_GPIO_2:
@@ -132,6 +74,15 @@ static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
132 case WM8994_INTERRUPT_STATUS_2: 74 case WM8994_INTERRUPT_STATUS_2:
133 case WM8994_INTERRUPT_RAW_STATUS_2: 75 case WM8994_INTERRUPT_RAW_STATUS_2:
134 return 1; 76 return 1;
77
78 case WM8958_DSP2_PROGRAM:
79 case WM8958_DSP2_CONFIG:
80 case WM8958_DSP2_EXECCONTROL:
81 if (control->type == WM8958)
82 return 1;
83 else
84 return 0;
85
135 default: 86 default:
136 break; 87 break;
137 } 88 }
@@ -574,215 +525,6 @@ static const struct soc_enum dac_osr =
574static const struct soc_enum adc_osr = 525static const struct soc_enum adc_osr =
575 SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text); 526 SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text);
576 527
577static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start)
578{
579 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
580 struct wm8994_pdata *pdata = wm8994->pdata;
581 int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5);
582 int ena, reg, aif, i;
583
584 switch (mbc) {
585 case 0:
586 pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA);
587 aif = 0;
588 break;
589 case 1:
590 pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
591 aif = 0;
592 break;
593 case 2:
594 pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA);
595 aif = 1;
596 break;
597 default:
598 BUG();
599 return;
600 }
601
602 /* We can only enable the MBC if the AIF is enabled and we
603 * want it to be enabled. */
604 ena = pwr_reg && wm8994->mbc_ena[mbc];
605
606 reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM);
607
608 dev_dbg(codec->dev, "MBC %d startup: %d, power: %x, DSP: %x\n",
609 mbc, start, pwr_reg, reg);
610
611 if (start && ena) {
612 /* If the DSP is already running then noop */
613 if (reg & WM8958_DSP2_ENA)
614 return;
615
616 /* Switch the clock over to the appropriate AIF */
617 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
618 WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA,
619 aif << WM8958_DSP2CLK_SRC_SHIFT |
620 WM8958_DSP2CLK_ENA);
621
622 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
623 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
624
625 /* If we've got user supplied MBC settings use them */
626 if (pdata && pdata->num_mbc_cfgs) {
627 struct wm8958_mbc_cfg *cfg
628 = &pdata->mbc_cfgs[wm8994->mbc_cfg];
629
630 for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++)
631 snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1,
632 cfg->coeff_regs[i]);
633
634 for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++)
635 snd_soc_write(codec,
636 i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1,
637 cfg->cutoff_regs[i]);
638 }
639
640 /* Run the DSP */
641 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
642 WM8958_DSP2_RUNR);
643
644 /* And we're off! */
645 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
646 WM8958_MBC_ENA | WM8958_MBC_SEL_MASK,
647 mbc << WM8958_MBC_SEL_SHIFT |
648 WM8958_MBC_ENA);
649 } else {
650 /* If the DSP is already stopped then noop */
651 if (!(reg & WM8958_DSP2_ENA))
652 return;
653
654 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
655 WM8958_MBC_ENA, 0);
656 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
657 WM8958_DSP2_ENA, 0);
658 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
659 WM8958_DSP2CLK_ENA, 0);
660 }
661}
662
663static int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
664 struct snd_kcontrol *kcontrol, int event)
665{
666 struct snd_soc_codec *codec = w->codec;
667 int mbc;
668
669 switch (w->shift) {
670 case 13:
671 case 12:
672 mbc = 2;
673 break;
674 case 11:
675 case 10:
676 mbc = 1;
677 break;
678 case 9:
679 case 8:
680 mbc = 0;
681 break;
682 default:
683 BUG();
684 return -EINVAL;
685 }
686
687 switch (event) {
688 case SND_SOC_DAPM_POST_PMU:
689 wm8958_mbc_apply(codec, mbc, 1);
690 break;
691 case SND_SOC_DAPM_POST_PMD:
692 wm8958_mbc_apply(codec, mbc, 0);
693 break;
694 }
695
696 return 0;
697}
698
699static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_value *ucontrol)
701{
702 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
703 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
704 struct wm8994_pdata *pdata = wm8994->pdata;
705 int value = ucontrol->value.integer.value[0];
706 int reg;
707
708 /* Don't allow on the fly reconfiguration */
709 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
710 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
711 return -EBUSY;
712
713 if (value >= pdata->num_mbc_cfgs)
714 return -EINVAL;
715
716 wm8994->mbc_cfg = value;
717
718 return 0;
719}
720
721static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol,
722 struct snd_ctl_elem_value *ucontrol)
723{
724 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
725 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
726
727 ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg;
728
729 return 0;
730}
731
732static int wm8958_mbc_info(struct snd_kcontrol *kcontrol,
733 struct snd_ctl_elem_info *uinfo)
734{
735 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
736 uinfo->count = 1;
737 uinfo->value.integer.min = 0;
738 uinfo->value.integer.max = 1;
739 return 0;
740}
741
742static int wm8958_mbc_get(struct snd_kcontrol *kcontrol,
743 struct snd_ctl_elem_value *ucontrol)
744{
745 int mbc = kcontrol->private_value;
746 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
747 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
748
749 ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc];
750
751 return 0;
752}
753
754static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
755 struct snd_ctl_elem_value *ucontrol)
756{
757 int mbc = kcontrol->private_value;
758 int i;
759 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
760 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
761
762 if (ucontrol->value.integer.value[0] > 1)
763 return -EINVAL;
764
765 for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) {
766 if (mbc != i && wm8994->mbc_ena[i]) {
767 dev_dbg(codec->dev, "MBC %d active already\n", mbc);
768 return -EBUSY;
769 }
770 }
771
772 wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0];
773
774 wm8958_mbc_apply(codec, mbc, wm8994->mbc_ena[mbc]);
775
776 return 0;
777}
778
779#define WM8958_MBC_SWITCH(xname, xval) {\
780 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
781 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
782 .info = wm8958_mbc_info, \
783 .get = wm8958_mbc_get, .put = wm8958_mbc_put, \
784 .private_value = xval }
785
786static const struct snd_kcontrol_new wm8994_snd_controls[] = { 528static const struct snd_kcontrol_new wm8994_snd_controls[] = {
787SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, 529SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
788 WM8994_AIF1_ADC1_RIGHT_VOLUME, 530 WM8994_AIF1_ADC1_RIGHT_VOLUME,
@@ -924,9 +666,6 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
924 666
925static const struct snd_kcontrol_new wm8958_snd_controls[] = { 667static const struct snd_kcontrol_new wm8958_snd_controls[] = {
926SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), 668SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
927WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0),
928WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1),
929WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2),
930}; 669};
931 670
932static int clk_sys_event(struct snd_soc_dapm_widget *w, 671static int clk_sys_event(struct snd_soc_dapm_widget *w,
@@ -1032,6 +771,9 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w,
1032 break; 771 break;
1033 } 772 }
1034 773
774 /* We may also have postponed startup of DSP, handle that. */
775 wm8958_aif_ev(w, kcontrol, event);
776
1035 return 0; 777 return 0;
1036} 778}
1037 779
@@ -1135,7 +877,8 @@ static const char *hp_mux_text[] = {
1135static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol, 877static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol,
1136 struct snd_ctl_elem_value *ucontrol) 878 struct snd_ctl_elem_value *ucontrol)
1137{ 879{
1138 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol); 880 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
881 struct snd_soc_dapm_widget *w = wlist->widgets[0];
1139 struct snd_soc_codec *codec = w->codec; 882 struct snd_soc_codec *codec = w->codec;
1140 int ret; 883 int ret;
1141 884
@@ -1262,7 +1005,8 @@ SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
1262static int wm8994_put_class_w(struct snd_kcontrol *kcontrol, 1005static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
1263 struct snd_ctl_elem_value *ucontrol) 1006 struct snd_ctl_elem_value *ucontrol)
1264{ 1007{
1265 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol); 1008 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1009 struct snd_soc_dapm_widget *w = wlist->widgets[0];
1266 struct snd_soc_codec *codec = w->codec; 1010 struct snd_soc_codec *codec = w->codec;
1267 int ret; 1011 int ret;
1268 1012
@@ -2180,6 +1924,8 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2180 WM8994_VMID_BUF_ENA | 1924 WM8994_VMID_BUF_ENA |
2181 WM8994_VMID_RAMP_MASK, 0); 1925 WM8994_VMID_RAMP_MASK, 0);
2182 1926
1927 wm8994->cur_fw = NULL;
1928
2183 pm_runtime_put(codec->dev); 1929 pm_runtime_put(codec->dev);
2184 } 1930 }
2185 break; 1931 break;
@@ -2672,11 +2418,22 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2672static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) 2418static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
2673{ 2419{
2674 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2420 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2421 struct wm8994 *control = codec->control_data;
2675 int i, ret; 2422 int i, ret;
2676 2423
2424 switch (control->type) {
2425 case WM8994:
2426 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0);
2427 break;
2428 case WM8958:
2429 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2430 WM8958_MICD_ENA, 0);
2431 break;
2432 }
2433
2677 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 2434 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
2678 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i], 2435 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
2679 sizeof(struct fll_config)); 2436 sizeof(struct wm8994_fll_config));
2680 ret = _wm8994_set_fll(codec, i + 1, 0, 0, 0); 2437 ret = _wm8994_set_fll(codec, i + 1, 0, 0, 0);
2681 if (ret < 0) 2438 if (ret < 0)
2682 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n", 2439 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n",
@@ -2691,6 +2448,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
2691static int wm8994_resume(struct snd_soc_codec *codec) 2448static int wm8994_resume(struct snd_soc_codec *codec)
2692{ 2449{
2693 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2450 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2451 struct wm8994 *control = codec->control_data;
2694 int i, ret; 2452 int i, ret;
2695 unsigned int val, mask; 2453 unsigned int val, mask;
2696 2454
@@ -2729,6 +2487,19 @@ static int wm8994_resume(struct snd_soc_codec *codec)
2729 i + 1, ret); 2487 i + 1, ret);
2730 } 2488 }
2731 2489
2490 switch (control->type) {
2491 case WM8994:
2492 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
2493 snd_soc_update_bits(codec, WM8994_MICBIAS,
2494 WM8994_MICD_ENA, WM8994_MICD_ENA);
2495 break;
2496 case WM8958:
2497 if (wm8994->jack_cb)
2498 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2499 WM8958_MICD_ENA, WM8958_MICD_ENA);
2500 break;
2501 }
2502
2732 return 0; 2503 return 0;
2733} 2504}
2734#else 2505#else
@@ -2862,34 +2633,6 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2862 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n", 2633 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
2863 pdata->num_retune_mobile_cfgs); 2634 pdata->num_retune_mobile_cfgs);
2864 2635
2865 if (pdata->num_mbc_cfgs) {
2866 struct snd_kcontrol_new control[] = {
2867 SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum,
2868 wm8958_get_mbc_enum, wm8958_put_mbc_enum),
2869 };
2870
2871 /* We need an array of texts for the enum API */
2872 wm8994->mbc_texts = kmalloc(sizeof(char *)
2873 * pdata->num_mbc_cfgs, GFP_KERNEL);
2874 if (!wm8994->mbc_texts) {
2875 dev_err(wm8994->codec->dev,
2876 "Failed to allocate %d MBC config texts\n",
2877 pdata->num_mbc_cfgs);
2878 return;
2879 }
2880
2881 for (i = 0; i < pdata->num_mbc_cfgs; i++)
2882 wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name;
2883
2884 wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
2885 wm8994->mbc_enum.texts = wm8994->mbc_texts;
2886
2887 ret = snd_soc_add_controls(wm8994->codec, control, 1);
2888 if (ret != 0)
2889 dev_err(wm8994->codec->dev,
2890 "Failed to add MBC mode controls: %d\n", ret);
2891 }
2892
2893 if (pdata->num_retune_mobile_cfgs) 2636 if (pdata->num_retune_mobile_cfgs)
2894 wm8994_handle_retune_mobile_pdata(wm8994); 2637 wm8994_handle_retune_mobile_pdata(wm8994);
2895 else 2638 else
@@ -3343,14 +3086,23 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3343 case WM8958: 3086 case WM8958:
3344 snd_soc_add_controls(codec, wm8958_snd_controls, 3087 snd_soc_add_controls(codec, wm8958_snd_controls,
3345 ARRAY_SIZE(wm8958_snd_controls)); 3088 ARRAY_SIZE(wm8958_snd_controls));
3346 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
3347 ARRAY_SIZE(wm8994_lateclk_widgets));
3348 snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
3349 ARRAY_SIZE(wm8994_adc_widgets));
3350 snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
3351 ARRAY_SIZE(wm8994_dac_widgets));
3352 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, 3089 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3353 ARRAY_SIZE(wm8958_dapm_widgets)); 3090 ARRAY_SIZE(wm8958_dapm_widgets));
3091 if (wm8994->revision < 1) {
3092 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets,
3093 ARRAY_SIZE(wm8994_lateclk_revd_widgets));
3094 snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets,
3095 ARRAY_SIZE(wm8994_adc_revd_widgets));
3096 snd_soc_dapm_new_controls(dapm, wm8994_dac_revd_widgets,
3097 ARRAY_SIZE(wm8994_dac_revd_widgets));
3098 } else {
3099 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
3100 ARRAY_SIZE(wm8994_lateclk_widgets));
3101 snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
3102 ARRAY_SIZE(wm8994_adc_widgets));
3103 snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
3104 ARRAY_SIZE(wm8994_dac_widgets));
3105 }
3354 break; 3106 break;
3355 } 3107 }
3356 3108
@@ -3374,10 +3126,19 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3374 } 3126 }
3375 break; 3127 break;
3376 case WM8958: 3128 case WM8958:
3377 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon, 3129 if (wm8994->revision < 1) {
3378 ARRAY_SIZE(wm8994_lateclk_intercon)); 3130 snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon,
3379 snd_soc_dapm_add_routes(dapm, wm8958_intercon, 3131 ARRAY_SIZE(wm8994_revd_intercon));
3380 ARRAY_SIZE(wm8958_intercon)); 3132 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon,
3133 ARRAY_SIZE(wm8994_lateclk_revd_intercon));
3134 } else {
3135 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
3136 ARRAY_SIZE(wm8994_lateclk_intercon));
3137 snd_soc_dapm_add_routes(dapm, wm8958_intercon,
3138 ARRAY_SIZE(wm8958_intercon));
3139 }
3140
3141 wm8958_dsp2_init(codec);
3381 break; 3142 break;
3382 } 3143 }
3383 3144
@@ -3420,6 +3181,12 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3420 free_irq(wm8994->micdet_irq, wm8994); 3181 free_irq(wm8994->micdet_irq, wm8994);
3421 break; 3182 break;
3422 } 3183 }
3184 if (wm8994->mbc)
3185 release_firmware(wm8994->mbc);
3186 if (wm8994->mbc_vss)
3187 release_firmware(wm8994->mbc_vss);
3188 if (wm8994->enh_eq)
3189 release_firmware(wm8994->enh_eq);
3423 kfree(wm8994->retune_mobile_texts); 3190 kfree(wm8994->retune_mobile_texts);
3424 kfree(wm8994->drc_texts); 3191 kfree(wm8994->drc_texts);
3425 kfree(wm8994); 3192 kfree(wm8994);
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 999b8851226b..0a1db04b73bd 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -10,6 +10,9 @@
10#define _WM8994_H 10#define _WM8994_H
11 11
12#include <sound/soc.h> 12#include <sound/soc.h>
13#include <linux/firmware.h>
14
15#include "wm_hubs.h"
13 16
14/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */ 17/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
15#define WM8994_SYSCLK_MCLK1 1 18#define WM8994_SYSCLK_MCLK1 1
@@ -45,4 +48,98 @@ struct wm8994_access_mask {
45extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE]; 48extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE];
46extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE]; 49extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE];
47 50
51int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
52 struct snd_kcontrol *kcontrol, int event);
53
54void wm8958_dsp2_init(struct snd_soc_codec *codec);
55
56struct wm8994_micdet {
57 struct snd_soc_jack *jack;
58 int det;
59 int shrt;
60};
61
62/* codec private data */
63struct wm8994_fll_config {
64 int src;
65 int in;
66 int out;
67};
68
69#define WM8994_NUM_DRC 3
70#define WM8994_NUM_EQ 3
71
72struct wm8994_priv {
73 struct wm_hubs_data hubs;
74 enum snd_soc_control_type control_type;
75 void *control_data;
76 struct snd_soc_codec *codec;
77 int sysclk[2];
78 int sysclk_rate[2];
79 int mclk[2];
80 int aifclk[2];
81 struct wm8994_fll_config fll[2], fll_suspend[2];
82
83 int dac_rates[2];
84 int lrclk_shared[2];
85
86 int mbc_ena[3];
87 int hpf1_ena[3];
88 int hpf2_ena[3];
89 int vss_ena[3];
90 int enh_eq_ena[3];
91
92 /* Platform dependant DRC configuration */
93 const char **drc_texts;
94 int drc_cfg[WM8994_NUM_DRC];
95 struct soc_enum drc_enum;
96
97 /* Platform dependant ReTune mobile configuration */
98 int num_retune_mobile_texts;
99 const char **retune_mobile_texts;
100 int retune_mobile_cfg[WM8994_NUM_EQ];
101 struct soc_enum retune_mobile_enum;
102
103 /* Platform dependant MBC configuration */
104 int mbc_cfg;
105 const char **mbc_texts;
106 struct soc_enum mbc_enum;
107
108 /* Platform dependant VSS configuration */
109 int vss_cfg;
110 const char **vss_texts;
111 struct soc_enum vss_enum;
112
113 /* Platform dependant VSS HPF configuration */
114 int vss_hpf_cfg;
115 const char **vss_hpf_texts;
116 struct soc_enum vss_hpf_enum;
117
118 /* Platform dependant enhanced EQ configuration */
119 int enh_eq_cfg;
120 const char **enh_eq_texts;
121 struct soc_enum enh_eq_enum;
122
123 struct wm8994_micdet micdet[2];
124
125 wm8958_micdet_cb jack_cb;
126 void *jack_cb_data;
127 int micdet_irq;
128
129 int revision;
130 struct wm8994_pdata *pdata;
131
132 unsigned int aif1clk_enable:1;
133 unsigned int aif2clk_enable:1;
134
135 unsigned int aif1clk_disable:1;
136 unsigned int aif2clk_disable:1;
137
138 int dsp_active;
139 const struct firmware *cur_fw;
140 const struct firmware *mbc;
141 const struct firmware *mbc_vss;
142 const struct firmware *enh_eq;
143};
144
48#endif 145#endif
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 67eaaecbb42e..5ad873fda814 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -305,11 +305,11 @@ static int check_clk_sys(struct snd_soc_dapm_widget *source,
305static int wm8995_put_class_w(struct snd_kcontrol *kcontrol, 305static int wm8995_put_class_w(struct snd_kcontrol *kcontrol,
306 struct snd_ctl_elem_value *ucontrol) 306 struct snd_ctl_elem_value *ucontrol)
307{ 307{
308 struct snd_soc_dapm_widget *w; 308 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
309 struct snd_soc_dapm_widget *w = wlist->widgets[0];
309 struct snd_soc_codec *codec; 310 struct snd_soc_codec *codec;
310 int ret; 311 int ret;
311 312
312 w = snd_kcontrol_chip(kcontrol);
313 codec = w->codec; 313 codec = w->codec;
314 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); 314 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
315 wm8995_update_class_w(codec); 315 wm8995_update_class_w(codec);
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 47b357adabdd..646b58dda849 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -142,7 +142,7 @@ static const struct snd_soc_dapm_widget wm9705_dapm_widgets[] = {
142 * constantly enabled, we use the mutes on those inputs to simulate such 142 * constantly enabled, we use the mutes on those inputs to simulate such
143 * controls. 143 * controls.
144 */ 144 */
145static const struct snd_soc_dapm_route audio_map[] = { 145static const struct snd_soc_dapm_route wm9705_audio_map[] = {
146 /* HP mixer */ 146 /* HP mixer */
147 {"HP Mixer", "PCBeep Playback Switch", "PCBEEP PGA"}, 147 {"HP Mixer", "PCBeep Playback Switch", "PCBEEP PGA"},
148 {"HP Mixer", "CD Playback Switch", "CD PGA"}, 148 {"HP Mixer", "CD Playback Switch", "CD PGA"},
@@ -200,17 +200,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
200 {"Right ADC", NULL, "ADC PGA"}, 200 {"Right ADC", NULL, "ADC PGA"},
201}; 201};
202 202
203static int wm9705_add_widgets(struct snd_soc_codec *codec)
204{
205 struct snd_soc_dapm_context *dapm = &codec->dapm;
206
207 snd_soc_dapm_new_controls(dapm, wm9705_dapm_widgets,
208 ARRAY_SIZE(wm9705_dapm_widgets));
209 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
210
211 return 0;
212}
213
214/* We use a register cache to enhance read performance. */ 203/* We use a register cache to enhance read performance. */
215static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) 204static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg)
216{ 205{
@@ -364,7 +353,6 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
364 353
365 snd_soc_add_controls(codec, wm9705_snd_ac97_controls, 354 snd_soc_add_controls(codec, wm9705_snd_ac97_controls,
366 ARRAY_SIZE(wm9705_snd_ac97_controls)); 355 ARRAY_SIZE(wm9705_snd_ac97_controls));
367 wm9705_add_widgets(codec);
368 356
369 return 0; 357 return 0;
370 358
@@ -390,6 +378,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
390 .reg_word_size = sizeof(u16), 378 .reg_word_size = sizeof(u16),
391 .reg_cache_step = 2, 379 .reg_cache_step = 2,
392 .reg_cache_default = wm9705_reg, 380 .reg_cache_default = wm9705_reg,
381 .dapm_widgets = wm9705_dapm_widgets,
382 .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets),
383 .dapm_routes = wm9705_audio_map,
384 .num_dapm_routes = ARRAY_SIZE(wm9705_audio_map),
393}; 385};
394 386
395static __devinit int wm9705_probe(struct platform_device *pdev) 387static __devinit int wm9705_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index bf5d4ef1a2a6..90117f8156e8 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -332,7 +332,7 @@ SND_SOC_DAPM_INPUT("MIC1"),
332SND_SOC_DAPM_INPUT("MIC2"), 332SND_SOC_DAPM_INPUT("MIC2"),
333}; 333};
334 334
335static const struct snd_soc_dapm_route audio_map[] = { 335static const struct snd_soc_dapm_route wm9712_audio_map[] = {
336 /* virtual mixer - mixes left & right channels for spk and mono */ 336 /* virtual mixer - mixes left & right channels for spk and mono */
337 {"AC97 Mixer", NULL, "Left DAC"}, 337 {"AC97 Mixer", NULL, "Left DAC"},
338 {"AC97 Mixer", NULL, "Right DAC"}, 338 {"AC97 Mixer", NULL, "Right DAC"},
@@ -429,17 +429,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
429 {"ROUT2", NULL, "Speaker PGA"}, 429 {"ROUT2", NULL, "Speaker PGA"},
430}; 430};
431 431
432static int wm9712_add_widgets(struct snd_soc_codec *codec)
433{
434 struct snd_soc_dapm_context *dapm = &codec->dapm;
435
436 snd_soc_dapm_new_controls(dapm, wm9712_dapm_widgets,
437 ARRAY_SIZE(wm9712_dapm_widgets));
438 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
439
440 return 0;
441}
442
443static unsigned int ac97_read(struct snd_soc_codec *codec, 432static unsigned int ac97_read(struct snd_soc_codec *codec,
444 unsigned int reg) 433 unsigned int reg)
445{ 434{
@@ -651,7 +640,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
651 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 640 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
652 snd_soc_add_controls(codec, wm9712_snd_ac97_controls, 641 snd_soc_add_controls(codec, wm9712_snd_ac97_controls,
653 ARRAY_SIZE(wm9712_snd_ac97_controls)); 642 ARRAY_SIZE(wm9712_snd_ac97_controls));
654 wm9712_add_widgets(codec);
655 643
656 return 0; 644 return 0;
657 645
@@ -678,6 +666,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
678 .reg_word_size = sizeof(u16), 666 .reg_word_size = sizeof(u16),
679 .reg_cache_step = 2, 667 .reg_cache_step = 2,
680 .reg_cache_default = wm9712_reg, 668 .reg_cache_default = wm9712_reg,
669 .dapm_widgets = wm9712_dapm_widgets,
670 .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets),
671 .dapm_routes = wm9712_audio_map,
672 .num_dapm_routes = ARRAY_SIZE(wm9712_audio_map),
681}; 673};
682 674
683static __devinit int wm9712_probe(struct platform_device *pdev) 675static __devinit int wm9712_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 38ed98558718..7167cb6787db 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -487,7 +487,7 @@ SND_SOC_DAPM_INPUT("MIC2B"),
487SND_SOC_DAPM_VMID("VMID"), 487SND_SOC_DAPM_VMID("VMID"),
488}; 488};
489 489
490static const struct snd_soc_dapm_route audio_map[] = { 490static const struct snd_soc_dapm_route wm9713_audio_map[] = {
491 /* left HP mixer */ 491 /* left HP mixer */
492 {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"}, 492 {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"},
493 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"}, 493 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"},
@@ -644,18 +644,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
644 {"Capture Mono Mux", "Right", "Right Capture Source"}, 644 {"Capture Mono Mux", "Right", "Right Capture Source"},
645}; 645};
646 646
647static int wm9713_add_widgets(struct snd_soc_codec *codec)
648{
649 struct snd_soc_dapm_context *dapm = &codec->dapm;
650
651 snd_soc_dapm_new_controls(dapm, wm9713_dapm_widgets,
652 ARRAY_SIZE(wm9713_dapm_widgets));
653
654 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
655
656 return 0;
657}
658
659static unsigned int ac97_read(struct snd_soc_codec *codec, 647static unsigned int ac97_read(struct snd_soc_codec *codec,
660 unsigned int reg) 648 unsigned int reg)
661{ 649{
@@ -1231,7 +1219,6 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
1231 1219
1232 snd_soc_add_controls(codec, wm9713_snd_ac97_controls, 1220 snd_soc_add_controls(codec, wm9713_snd_ac97_controls,
1233 ARRAY_SIZE(wm9713_snd_ac97_controls)); 1221 ARRAY_SIZE(wm9713_snd_ac97_controls));
1234 wm9713_add_widgets(codec);
1235 1222
1236 return 0; 1223 return 0;
1237 1224
@@ -1262,6 +1249,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
1262 .reg_word_size = sizeof(u16), 1249 .reg_word_size = sizeof(u16),
1263 .reg_cache_step = 2, 1250 .reg_cache_step = 2,
1264 .reg_cache_default = wm9713_reg, 1251 .reg_cache_default = wm9713_reg,
1252 .dapm_widgets = wm9713_dapm_widgets,
1253 .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets),
1254 .dapm_routes = wm9713_audio_map,
1255 .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map),
1265}; 1256};
1266 1257
1267static __devinit int wm9713_probe(struct platform_device *pdev) 1258static __devinit int wm9713_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 4005e9af5d61..e55b298c14a0 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -787,17 +787,17 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
787static const struct snd_soc_dapm_route lineout1_diff_routes[] = { 787static const struct snd_soc_dapm_route lineout1_diff_routes[] = {
788 { "LINEOUT1 Mixer", "IN1L Switch", "IN1L PGA" }, 788 { "LINEOUT1 Mixer", "IN1L Switch", "IN1L PGA" },
789 { "LINEOUT1 Mixer", "IN1R Switch", "IN1R PGA" }, 789 { "LINEOUT1 Mixer", "IN1R Switch", "IN1R PGA" },
790 { "LINEOUT1 Mixer", "Output Switch", "Left Output Mixer" }, 790 { "LINEOUT1 Mixer", "Output Switch", "Left Output PGA" },
791 791
792 { "LINEOUT1N Driver", NULL, "LINEOUT1 Mixer" }, 792 { "LINEOUT1N Driver", NULL, "LINEOUT1 Mixer" },
793 { "LINEOUT1P Driver", NULL, "LINEOUT1 Mixer" }, 793 { "LINEOUT1P Driver", NULL, "LINEOUT1 Mixer" },
794}; 794};
795 795
796static const struct snd_soc_dapm_route lineout1_se_routes[] = { 796static const struct snd_soc_dapm_route lineout1_se_routes[] = {
797 { "LINEOUT1N Mixer", "Left Output Switch", "Left Output Mixer" }, 797 { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" },
798 { "LINEOUT1N Mixer", "Right Output Switch", "Left Output Mixer" }, 798 { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" },
799 799
800 { "LINEOUT1P Mixer", "Left Output Switch", "Left Output Mixer" }, 800 { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" },
801 801
802 { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" }, 802 { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" },
803 { "LINEOUT1P Driver", NULL, "LINEOUT1P Mixer" }, 803 { "LINEOUT1P Driver", NULL, "LINEOUT1P Mixer" },
@@ -806,17 +806,17 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = {
806static const struct snd_soc_dapm_route lineout2_diff_routes[] = { 806static const struct snd_soc_dapm_route lineout2_diff_routes[] = {
807 { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" }, 807 { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" },
808 { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" }, 808 { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" },
809 { "LINEOUT2 Mixer", "Output Switch", "Right Output Mixer" }, 809 { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" },
810 810
811 { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" }, 811 { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" },
812 { "LINEOUT2P Driver", NULL, "LINEOUT2 Mixer" }, 812 { "LINEOUT2P Driver", NULL, "LINEOUT2 Mixer" },
813}; 813};
814 814
815static const struct snd_soc_dapm_route lineout2_se_routes[] = { 815static const struct snd_soc_dapm_route lineout2_se_routes[] = {
816 { "LINEOUT2N Mixer", "Left Output Switch", "Left Output Mixer" }, 816 { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" },
817 { "LINEOUT2N Mixer", "Right Output Switch", "Left Output Mixer" }, 817 { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" },
818 818
819 { "LINEOUT2P Mixer", "Right Output Switch", "Right Output Mixer" }, 819 { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" },
820 820
821 { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" }, 821 { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" },
822 { "LINEOUT2P Driver", NULL, "LINEOUT2P Mixer" }, 822 { "LINEOUT2P Driver", NULL, "LINEOUT2P Mixer" },
@@ -836,17 +836,21 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
836 snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 836 snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME,
837 WM8993_IN2_VU, WM8993_IN2_VU); 837 WM8993_IN2_VU, WM8993_IN2_VU);
838 838
839 snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_LEFT,
840 WM8993_SPKOUT_VU, WM8993_SPKOUT_VU);
839 snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_RIGHT, 841 snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_RIGHT,
840 WM8993_SPKOUT_VU, WM8993_SPKOUT_VU); 842 WM8993_SPKOUT_VU, WM8993_SPKOUT_VU);
841 843
842 snd_soc_update_bits(codec, WM8993_LEFT_OUTPUT_VOLUME, 844 snd_soc_update_bits(codec, WM8993_LEFT_OUTPUT_VOLUME,
843 WM8993_HPOUT1L_ZC, WM8993_HPOUT1L_ZC); 845 WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC,
846 WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC);
844 snd_soc_update_bits(codec, WM8993_RIGHT_OUTPUT_VOLUME, 847 snd_soc_update_bits(codec, WM8993_RIGHT_OUTPUT_VOLUME,
845 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC, 848 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC,
846 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC); 849 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC);
847 850
848 snd_soc_update_bits(codec, WM8993_LEFT_OPGA_VOLUME, 851 snd_soc_update_bits(codec, WM8993_LEFT_OPGA_VOLUME,
849 WM8993_MIXOUTL_ZC, WM8993_MIXOUTL_ZC); 852 WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU,
853 WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU);
850 snd_soc_update_bits(codec, WM8993_RIGHT_OPGA_VOLUME, 854 snd_soc_update_bits(codec, WM8993_RIGHT_OPGA_VOLUME,
851 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU, 855 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU,
852 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU); 856 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU);
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index a5af834c8ef5..8566238db2a5 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -434,17 +434,21 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
434 mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); 434 mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
435 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE); 435 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
436 436
437 mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, (0x7 << 26)); 437 mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG,
438 ACLKX | AHCLKX | AFSX);
438 break; 439 break;
439 case SND_SOC_DAIFMT_CBM_CFS: 440 case SND_SOC_DAIFMT_CBM_CFS:
440 /* codec is clock master and frame slave */ 441 /* codec is clock master and frame slave */
441 mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE); 442 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
442 mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE); 443 mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
443 444
444 mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); 445 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
445 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE); 446 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
446 447
447 mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, (0x2d << 26)); 448 mcasp_clr_bits(base + DAVINCI_MCASP_PDIR_REG,
449 ACLKX | ACLKR);
450 mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG,
451 AFSX | AFSR);
448 break; 452 break;
449 case SND_SOC_DAIFMT_CBM_CFM: 453 case SND_SOC_DAIFMT_CBM_CFM:
450 /* codec is clock and frame master */ 454 /* codec is clock and frame master */
@@ -454,7 +458,8 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
454 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); 458 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
455 mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE); 459 mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
456 460
457 mcasp_clr_bits(base + DAVINCI_MCASP_PDIR_REG, (0x3f << 26)); 461 mcasp_clr_bits(base + DAVINCI_MCASP_PDIR_REG,
462 ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR);
458 break; 463 break;
459 464
460 default: 465 default:
@@ -644,7 +649,7 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
644 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask); 649 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask);
645 mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD); 650 mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD);
646 651
647 if ((dev->tdm_slots >= 2) || (dev->tdm_slots <= 32)) 652 if ((dev->tdm_slots >= 2) && (dev->tdm_slots <= 32))
648 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, 653 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG,
649 FSXMOD(dev->tdm_slots), FSXMOD(0x1FF)); 654 FSXMOD(dev->tdm_slots), FSXMOD(0x1FF));
650 else 655 else
@@ -660,7 +665,7 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
660 AHCLKRE); 665 AHCLKRE);
661 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask); 666 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask);
662 667
663 if ((dev->tdm_slots >= 2) || (dev->tdm_slots <= 32)) 668 if ((dev->tdm_slots >= 2) && (dev->tdm_slots <= 32))
664 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, 669 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG,
665 FSRMOD(dev->tdm_slots), FSRMOD(0x1FF)); 670 FSRMOD(dev->tdm_slots), FSRMOD(0x1FF));
666 else 671 else
@@ -904,6 +909,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
904 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; 909 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
905 dma_data->asp_chan_q = pdata->asp_chan_q; 910 dma_data->asp_chan_q = pdata->asp_chan_q;
906 dma_data->ram_chan_q = pdata->ram_chan_q; 911 dma_data->ram_chan_q = pdata->ram_chan_q;
912 dma_data->sram_size = pdata->sram_size_playback;
907 dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + 913 dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
908 mem->start); 914 mem->start);
909 915
@@ -920,6 +926,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
920 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; 926 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE];
921 dma_data->asp_chan_q = pdata->asp_chan_q; 927 dma_data->asp_chan_q = pdata->asp_chan_q;
922 dma_data->ram_chan_q = pdata->ram_chan_q; 928 dma_data->ram_chan_q = pdata->ram_chan_q;
929 dma_data->sram_size = pdata->sram_size_capture;
923 dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + 930 dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
924 mem->start); 931 mem->start);
925 932
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index ac2ded969253..5b13feca7537 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -667,12 +667,6 @@ static int imx_ssi_probe(struct platform_device *pdev)
667 if (res) 667 if (res)
668 ssi->dma_params_rx.dma = res->start; 668 ssi->dma_params_rx.dma = res->start;
669 669
670 if ((cpu_is_mx27() || cpu_is_mx21()) &&
671 !(ssi->flags & IMX_SSI_USE_AC97) &&
672 (ssi->flags & IMX_SSI_DMA)) {
673 ssi->flags |= IMX_SSI_DMA;
674 }
675
676 platform_set_drvdata(pdev, ssi); 670 platform_set_drvdata(pdev, ssi);
677 671
678 ret = snd_soc_register_dai(&pdev->dev, dai); 672 ret = snd_soc_register_dai(&pdev->dev, dai);
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 419bf4f5534a..cd22a54b2f14 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -133,7 +133,7 @@ static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream,
133 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); 133 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
134 uint32_t conf; 134 uint32_t conf;
135 135
136 if (!dai->active) 136 if (dai->active)
137 return; 137 return;
138 138
139 conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); 139 conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c
index 49723e3e7e38..c5fc339f68f1 100644
--- a/sound/soc/jz4740/qi_lb60.c
+++ b/sound/soc/jz4740/qi_lb60.c
@@ -27,11 +27,7 @@
27static int qi_lb60_spk_event(struct snd_soc_dapm_widget *widget, 27static int qi_lb60_spk_event(struct snd_soc_dapm_widget *widget,
28 struct snd_kcontrol *ctrl, int event) 28 struct snd_kcontrol *ctrl, int event)
29{ 29{
30 int on = 0; 30 int on = !SND_SOC_DAPM_EVENT_OFF(event);
31 if (event & SND_SOC_DAPM_POST_PMU)
32 on = 1;
33 else if (event & SND_SOC_DAPM_PRE_PMD)
34 on = 0;
35 31
36 gpio_set_value(QI_LB60_SND_GPIO, on); 32 gpio_set_value(QI_LB60_SND_GPIO, on);
37 gpio_set_value(QI_LB60_AMP_GPIO, on); 33 gpio_set_value(QI_LB60_AMP_GPIO, on);
@@ -70,12 +66,6 @@ static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd)
70 return ret; 66 return ret;
71 } 67 }
72 68
73 snd_soc_dapm_new_controls(dapm, qi_lb60_widgets,
74 ARRAY_SIZE(qi_lb60_widgets));
75 snd_soc_dapm_add_routes(dapm, qi_lb60_routes,
76 ARRAY_SIZE(qi_lb60_routes));
77 snd_soc_dapm_sync(dapm);
78
79 return 0; 69 return 0;
80} 70}
81 71
@@ -93,10 +83,20 @@ static struct snd_soc_card qi_lb60 = {
93 .name = "QI LB60", 83 .name = "QI LB60",
94 .dai_link = &qi_lb60_dai, 84 .dai_link = &qi_lb60_dai,
95 .num_links = 1, 85 .num_links = 1,
86
87 .dapm_widgets = qi_lb60_widgets,
88 .num_dapm_widgets = ARRAY_SIZE(qi_lb60_widgets),
89 .dapm_routes = qi_lb60_routes,
90 .num_dapm_routes = ARRAY_SIZE(qi_lb60_routes),
96}; 91};
97 92
98static struct platform_device *qi_lb60_snd_device; 93static struct platform_device *qi_lb60_snd_device;
99 94
95static const struct gpio qi_lb60_gpios[] = {
96 { QI_LB60_SND_GPIO, GPIOF_OUT_INIT_LOW, "SND" },
97 { QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" },
98};
99
100static int __init qi_lb60_init(void) 100static int __init qi_lb60_init(void)
101{ 101{
102 int ret; 102 int ret;
@@ -106,23 +106,12 @@ static int __init qi_lb60_init(void)
106 if (!qi_lb60_snd_device) 106 if (!qi_lb60_snd_device)
107 return -ENOMEM; 107 return -ENOMEM;
108 108
109 ret = gpio_request(QI_LB60_SND_GPIO, "SND"); 109 ret = gpio_request_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
110 if (ret) { 110 if (ret) {
111 pr_err("qi_lb60 snd: Failed to request SND GPIO(%d): %d\n", 111 pr_err("qi_lb60 snd: Failed to request gpios: %d\n", ret);
112 QI_LB60_SND_GPIO, ret);
113 goto err_device_put; 112 goto err_device_put;
114 } 113 }
115 114
116 ret = gpio_request(QI_LB60_AMP_GPIO, "AMP");
117 if (ret) {
118 pr_err("qi_lb60 snd: Failed to request AMP GPIO(%d): %d\n",
119 QI_LB60_AMP_GPIO, ret);
120 goto err_gpio_free_snd;
121 }
122
123 gpio_direction_output(QI_LB60_SND_GPIO, 0);
124 gpio_direction_output(QI_LB60_AMP_GPIO, 0);
125
126 platform_set_drvdata(qi_lb60_snd_device, &qi_lb60); 115 platform_set_drvdata(qi_lb60_snd_device, &qi_lb60);
127 116
128 ret = platform_device_add(qi_lb60_snd_device); 117 ret = platform_device_add(qi_lb60_snd_device);
@@ -135,10 +124,8 @@ static int __init qi_lb60_init(void)
135 124
136err_unset_pdata: 125err_unset_pdata:
137 platform_set_drvdata(qi_lb60_snd_device, NULL); 126 platform_set_drvdata(qi_lb60_snd_device, NULL);
138/*err_gpio_free_amp:*/ 127/*err_gpio_free_array:*/
139 gpio_free(QI_LB60_AMP_GPIO); 128 gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
140err_gpio_free_snd:
141 gpio_free(QI_LB60_SND_GPIO);
142err_device_put: 129err_device_put:
143 platform_device_put(qi_lb60_snd_device); 130 platform_device_put(qi_lb60_snd_device);
144 131
@@ -148,9 +135,8 @@ module_init(qi_lb60_init);
148 135
149static void __exit qi_lb60_exit(void) 136static void __exit qi_lb60_exit(void)
150{ 137{
151 gpio_free(QI_LB60_AMP_GPIO);
152 gpio_free(QI_LB60_SND_GPIO);
153 platform_device_unregister(qi_lb60_snd_device); 138 platform_device_unregister(qi_lb60_snd_device);
139 gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
154} 140}
155module_exit(qi_lb60_exit); 141module_exit(qi_lb60_exit);
156 142
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
index d567c322a2fb..5a946b4115a2 100644
--- a/sound/soc/mid-x86/sst_platform.c
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -249,10 +249,13 @@ static int sst_platform_open(struct snd_pcm_substream *substream)
249 return -ENOMEM; 249 return -ENOMEM;
250 } 250 }
251 stream->sstdrv_ops->vendor_id = MSIC_VENDOR_ID; 251 stream->sstdrv_ops->vendor_id = MSIC_VENDOR_ID;
252 stream->sstdrv_ops->module_name = SST_CARD_NAMES;
252 /* registering with SST driver to get access to SST APIs to use */ 253 /* registering with SST driver to get access to SST APIs to use */
253 ret_val = register_sst_card(stream->sstdrv_ops); 254 ret_val = register_sst_card(stream->sstdrv_ops);
254 if (ret_val) { 255 if (ret_val) {
255 pr_err("sst: sst card registration failed\n"); 256 pr_err("sst: sst card registration failed\n");
257 kfree(stream->sstdrv_ops);
258 kfree(stream);
256 return ret_val; 259 return ret_val;
257 } 260 }
258 runtime->private_data = stream; 261 runtime->private_data = stream;
@@ -270,6 +273,7 @@ static int sst_platform_close(struct snd_pcm_substream *substream)
270 str_id = stream->stream_info.str_id; 273 str_id = stream->stream_info.str_id;
271 if (str_id) 274 if (str_id)
272 ret_val = stream->sstdrv_ops->pcm_control->close(str_id); 275 ret_val = stream->sstdrv_ops->pcm_control->close(str_id);
276 unregister_sst_card(stream->sstdrv_ops);
273 kfree(stream->sstdrv_ops); 277 kfree(stream->sstdrv_ops);
274 kfree(stream); 278 kfree(stream);
275 return ret_val; 279 return ret_val;
@@ -376,6 +380,11 @@ static int sst_platform_pcm_hw_params(struct snd_pcm_substream *substream,
376 return 0; 380 return 0;
377} 381}
378 382
383static int sst_platform_pcm_hw_free(struct snd_pcm_substream *substream)
384{
385 return snd_pcm_lib_free_pages(substream);
386}
387
379static struct snd_pcm_ops sst_platform_ops = { 388static struct snd_pcm_ops sst_platform_ops = {
380 .open = sst_platform_open, 389 .open = sst_platform_open,
381 .close = sst_platform_close, 390 .close = sst_platform_close,
@@ -384,6 +393,7 @@ static struct snd_pcm_ops sst_platform_ops = {
384 .trigger = sst_platform_pcm_trigger, 393 .trigger = sst_platform_pcm_trigger,
385 .pointer = sst_platform_pcm_pointer, 394 .pointer = sst_platform_pcm_pointer,
386 .hw_params = sst_platform_pcm_hw_params, 395 .hw_params = sst_platform_pcm_hw_params,
396 .hw_free = sst_platform_pcm_hw_free,
387}; 397};
388 398
389static void sst_pcm_free(struct snd_pcm *pcm) 399static void sst_pcm_free(struct snd_pcm *pcm)
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 2175f09e57b6..07b772357244 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -4,7 +4,7 @@
4 * Copyright (C) 2008 Nokia Corporation 4 * Copyright (C) 2008 Nokia Corporation
5 * 5 *
6 * Contact: Jarkko Nikula <jhnikula@gmail.com> 6 * Contact: Jarkko Nikula <jhnikula@gmail.com>
7 * Peter Ujfalusi <peter.ujfalusi@nokia.com> 7 * Peter Ujfalusi <peter.ujfalusi@ti.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
@@ -146,7 +146,7 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
146 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) 146 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words)
147 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) 147 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words)
148 */ 148 */
149 if (cpu_is_omap343x() || cpu_is_omap44xx()) { 149 if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
150 /* 150 /*
151 * Rule for the buffer size. We should not allow 151 * Rule for the buffer size. We should not allow
152 * smaller buffer than the FIFO size to avoid underruns 152 * smaller buffer than the FIFO size to avoid underruns
@@ -258,7 +258,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
258 default: 258 default:
259 return -EINVAL; 259 return -EINVAL;
260 } 260 }
261 if (cpu_is_omap343x()) { 261 if (cpu_is_omap34xx()) {
262 dma_data->set_threshold = omap_mcbsp_set_threshold; 262 dma_data->set_threshold = omap_mcbsp_set_threshold;
263 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ 263 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
264 if (omap_mcbsp_get_dma_op_mode(bus_id) == 264 if (omap_mcbsp_get_dma_op_mode(bus_id) ==
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index 37dc7211ed3f..9a7dedd6f5a9 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -4,7 +4,7 @@
4 * Copyright (C) 2008 Nokia Corporation 4 * Copyright (C) 2008 Nokia Corporation
5 * 5 *
6 * Contact: Jarkko Nikula <jhnikula@gmail.com> 6 * Contact: Jarkko Nikula <jhnikula@gmail.com>
7 * Peter Ujfalusi <peter.ujfalusi@nokia.com> 7 * Peter Ujfalusi <peter.ujfalusi@ti.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 8caeb8d305c3..e6a6b991d05f 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -4,7 +4,7 @@
4 * Copyright (C) 2008 Nokia Corporation 4 * Copyright (C) 2008 Nokia Corporation
5 * 5 *
6 * Contact: Jarkko Nikula <jhnikula@gmail.com> 6 * Contact: Jarkko Nikula <jhnikula@gmail.com>
7 * Peter Ujfalusi <peter.ujfalusi@nokia.com> 7 * Peter Ujfalusi <peter.ujfalusi@ti.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
@@ -37,7 +37,8 @@ static const struct snd_pcm_hardware omap_pcm_hardware = {
37 SNDRV_PCM_INFO_MMAP_VALID | 37 SNDRV_PCM_INFO_MMAP_VALID |
38 SNDRV_PCM_INFO_INTERLEAVED | 38 SNDRV_PCM_INFO_INTERLEAVED |
39 SNDRV_PCM_INFO_PAUSE | 39 SNDRV_PCM_INFO_PAUSE |
40 SNDRV_PCM_INFO_RESUME, 40 SNDRV_PCM_INFO_RESUME |
41 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
41 .formats = SNDRV_PCM_FMTBIT_S16_LE | 42 .formats = SNDRV_PCM_FMTBIT_S16_LE |
42 SNDRV_PCM_FMTBIT_S32_LE, 43 SNDRV_PCM_FMTBIT_S32_LE,
43 .period_bytes_min = 32, 44 .period_bytes_min = 32,
@@ -195,7 +196,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
195 if ((cpu_is_omap1510())) 196 if ((cpu_is_omap1510()))
196 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | 197 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
197 OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); 198 OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
198 else 199 else if (!substream->runtime->no_period_wakeup)
199 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); 200 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ);
200 201
201 if (!(cpu_class_is_omap1())) { 202 if (!(cpu_class_is_omap1())) {
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
index fea0515331fb..a0ed1dbb52d6 100644
--- a/sound/soc/omap/omap-pcm.h
+++ b/sound/soc/omap/omap-pcm.h
@@ -4,7 +4,7 @@
4 * Copyright (C) 2008 Nokia Corporation 4 * Copyright (C) 2008 Nokia Corporation
5 * 5 *
6 * Contact: Jarkko Nikula <jhnikula@gmail.com> 6 * Contact: Jarkko Nikula <jhnikula@gmail.com>
7 * Peter Ujfalusi <peter.ujfalusi@nokia.com> 7 * Peter Ujfalusi <peter.ujfalusi@ti.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index d0986220eff9..0aae998b6540 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2008 - 2009 Nokia Corporation 4 * Copyright (C) 2008 - 2009 Nokia Corporation
5 * 5 *
6 * Contact: Peter Ujfalusi <peter.ujfalusi@nokia.com> 6 * Contact: Peter Ujfalusi <peter.ujfalusi@ti.com>
7 * Eduardo Valentin <eduardo.valentin@nokia.com> 7 * Eduardo Valentin <eduardo.valentin@nokia.com>
8 * Jarkko Nikula <jhnikula@gmail.com> 8 * Jarkko Nikula <jhnikula@gmail.com>
9 * 9 *
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 580f48571303..33ebc46b45b5 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -155,6 +155,15 @@ config SND_SOC_RAUMFELD
155 help 155 help
156 Say Y if you want to add support for SoC audio on Raumfeld devices 156 Say Y if you want to add support for SoC audio on Raumfeld devices
157 157
158config SND_PXA2XX_SOC_HX4700
159 tristate "SoC Audio support for HP iPAQ hx4700"
160 depends on SND_PXA2XX_SOC && MACH_H4700
161 select SND_PXA2XX_SOC_I2S
162 select SND_SOC_AK4641
163 help
164 Say Y if you want to add support for SoC audio on the
165 HP iPAQ hx4700.
166
158config SND_PXA2XX_SOC_MAGICIAN 167config SND_PXA2XX_SOC_MAGICIAN
159 tristate "SoC Audio support for HTC Magician" 168 tristate "SoC Audio support for HTC Magician"
160 depends on SND_PXA2XX_SOC && MACH_MAGICIAN 169 depends on SND_PXA2XX_SOC && MACH_MAGICIAN
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 07660165ec8d..af357623be9d 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -22,6 +22,7 @@ snd-soc-palm27x-objs := palm27x.o
22snd-soc-saarb-objs := saarb.o 22snd-soc-saarb-objs := saarb.o
23snd-soc-tavorevb3-objs := tavorevb3.o 23snd-soc-tavorevb3-objs := tavorevb3.o
24snd-soc-zylonite-objs := zylonite.o 24snd-soc-zylonite-objs := zylonite.o
25snd-soc-hx4700-objs := hx4700.o
25snd-soc-magician-objs := magician.o 26snd-soc-magician-objs := magician.o
26snd-soc-mioa701-objs := mioa701_wm9713.o 27snd-soc-mioa701-objs := mioa701_wm9713.o
27snd-soc-z2-objs := z2.o 28snd-soc-z2-objs := z2.o
@@ -37,6 +38,7 @@ obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o
37obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o 38obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o
38obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o 39obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
39obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o 40obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
41obj-$(CONFIG_SND_PXA2XX_SOC_HX4700) += snd-soc-hx4700.o
40obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o 42obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
41obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o 43obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
42obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o 44obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 9027da466cae..28757fb9df31 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -310,7 +310,7 @@ static struct snd_soc_dai_link corgi_dai = {
310 .cpu_dai_name = "pxa2xx-i2s", 310 .cpu_dai_name = "pxa2xx-i2s",
311 .codec_dai_name = "wm8731-hifi", 311 .codec_dai_name = "wm8731-hifi",
312 .platform_name = "pxa-pcm-audio", 312 .platform_name = "pxa-pcm-audio",
313 .codec_name = "wm8731-codec.0-001b", 313 .codec_name = "wm8731.0-001b",
314 .init = corgi_wm8731_init, 314 .init = corgi_wm8731_init,
315 .ops = &corgi_ops, 315 .ops = &corgi_ops,
316}; 316};
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c
new file mode 100644
index 000000000000..65c124831a00
--- /dev/null
+++ b/sound/soc/pxa/hx4700.c
@@ -0,0 +1,255 @@
1/*
2 * SoC audio for HP iPAQ hx4700
3 *
4 * Copyright (c) 2009 Philipp Zabel
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/timer.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17#include <linux/delay.h>
18#include <linux/gpio.h>
19
20#include <sound/core.h>
21#include <sound/jack.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25
26#include <mach/hx4700.h>
27#include <asm/mach-types.h>
28#include "pxa2xx-i2s.h"
29
30#include "../codecs/ak4641.h"
31
32static struct snd_soc_jack hs_jack;
33
34/* Headphones jack detection DAPM pin */
35static struct snd_soc_jack_pin hs_jack_pin[] = {
36 {
37 .pin = "Headphone Jack",
38 .mask = SND_JACK_HEADPHONE,
39 },
40 {
41 .pin = "Speaker",
42 /* disable speaker when hp jack is inserted */
43 .mask = SND_JACK_HEADPHONE,
44 .invert = 1,
45 },
46};
47
48/* Headphones jack detection GPIO */
49static struct snd_soc_jack_gpio hs_jack_gpio = {
50 .gpio = GPIO75_HX4700_EARPHONE_nDET,
51 .invert = true,
52 .name = "hp-gpio",
53 .report = SND_JACK_HEADPHONE,
54 .debounce_time = 200,
55};
56
57/*
58 * iPAQ hx4700 uses I2S for capture and playback.
59 */
60static int hx4700_hw_params(struct snd_pcm_substream *substream,
61 struct snd_pcm_hw_params *params)
62{
63 struct snd_soc_pcm_runtime *rtd = substream->private_data;
64 struct snd_soc_dai *codec_dai = rtd->codec_dai;
65 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
66 int ret = 0;
67
68 /* set codec DAI configuration */
69 ret = snd_soc_dai_set_fmt(codec_dai,
70 SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
71 SND_SOC_DAIFMT_CBS_CFS);
72 if (ret < 0)
73 return ret;
74
75 /* set cpu DAI configuration */
76 ret = snd_soc_dai_set_fmt(cpu_dai,
77 SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
78 SND_SOC_DAIFMT_CBS_CFS);
79 if (ret < 0)
80 return ret;
81
82 /* set the I2S system clock as output */
83 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
84 SND_SOC_CLOCK_OUT);
85 if (ret < 0)
86 return ret;
87
88 /* inform codec driver about clock freq *
89 * (PXA I2S always uses divider 256) */
90 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 256 * params_rate(params),
91 SND_SOC_CLOCK_IN);
92 if (ret < 0)
93 return ret;
94
95 return 0;
96}
97
98static struct snd_soc_ops hx4700_ops = {
99 .hw_params = hx4700_hw_params,
100};
101
102static int hx4700_spk_power(struct snd_soc_dapm_widget *w,
103 struct snd_kcontrol *k, int event)
104{
105 gpio_set_value(GPIO107_HX4700_SPK_nSD, !!SND_SOC_DAPM_EVENT_ON(event));
106 return 0;
107}
108
109static int hx4700_hp_power(struct snd_soc_dapm_widget *w,
110 struct snd_kcontrol *k, int event)
111{
112 gpio_set_value(GPIO92_HX4700_HP_DRIVER, !!SND_SOC_DAPM_EVENT_ON(event));
113 return 0;
114}
115
116/* hx4700 machine dapm widgets */
117static const struct snd_soc_dapm_widget hx4700_dapm_widgets[] = {
118 SND_SOC_DAPM_HP("Headphone Jack", hx4700_hp_power),
119 SND_SOC_DAPM_SPK("Speaker", hx4700_spk_power),
120 SND_SOC_DAPM_MIC("Built-in Microphone", NULL),
121};
122
123/* hx4700 machine audio_map */
124static const struct snd_soc_dapm_route hx4700_audio_map[] = {
125
126 /* Headphone connected to LOUT, ROUT */
127 {"Headphone Jack", NULL, "LOUT"},
128 {"Headphone Jack", NULL, "ROUT"},
129
130 /* Speaker connected to MOUT2 */
131 {"Speaker", NULL, "MOUT2"},
132
133 /* Microphone connected to MICIN */
134 {"MICIN", NULL, "Built-in Microphone"},
135 {"AIN", NULL, "MICOUT"},
136};
137
138/*
139 * Logic for a ak4641 as connected on a HP iPAQ hx4700
140 */
141static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd)
142{
143 struct snd_soc_codec *codec = rtd->codec;
144 struct snd_soc_dapm_context *dapm = &codec->dapm;
145 int err;
146
147 /* NC codec pins */
148 /* FIXME: is anything connected here? */
149 snd_soc_dapm_nc_pin(dapm, "MOUT1");
150 snd_soc_dapm_nc_pin(dapm, "MICEXT");
151 snd_soc_dapm_nc_pin(dapm, "AUX");
152
153 /* Jack detection API stuff */
154 err = snd_soc_jack_new(codec, "Headphone Jack",
155 SND_JACK_HEADPHONE, &hs_jack);
156 if (err)
157 return err;
158
159 err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pin),
160 hs_jack_pin);
161 if (err)
162 return err;
163
164 err = snd_soc_jack_add_gpios(&hs_jack, 1, &hs_jack_gpio);
165
166 return err;
167}
168
169/* hx4700 digital audio interface glue - connects codec <--> CPU */
170static struct snd_soc_dai_link hx4700_dai = {
171 .name = "ak4641",
172 .stream_name = "AK4641",
173 .cpu_dai_name = "pxa2xx-i2s",
174 .codec_dai_name = "ak4641-hifi",
175 .platform_name = "pxa-pcm-audio",
176 .codec_name = "ak4641.0-0012",
177 .init = hx4700_ak4641_init,
178 .ops = &hx4700_ops,
179};
180
181/* hx4700 audio machine driver */
182static struct snd_soc_card snd_soc_card_hx4700 = {
183 .name = "iPAQ hx4700",
184 .dai_link = &hx4700_dai,
185 .num_links = 1,
186 .dapm_widgets = hx4700_dapm_widgets,
187 .num_dapm_widgets = ARRAY_SIZE(hx4700_dapm_widgets),
188 .dapm_routes = hx4700_audio_map,
189 .num_dapm_routes = ARRAY_SIZE(hx4700_audio_map),
190};
191
192static struct gpio hx4700_audio_gpios[] = {
193 { GPIO107_HX4700_SPK_nSD, GPIOF_OUT_INIT_HIGH, "SPK_POWER" },
194 { GPIO92_HX4700_HP_DRIVER, GPIOF_OUT_INIT_LOW, "EP_POWER" },
195};
196
197static int __devinit hx4700_audio_probe(struct platform_device *pdev)
198{
199 int ret;
200
201 if (!machine_is_h4700())
202 return -ENODEV;
203
204 ret = gpio_request_array(hx4700_audio_gpios,
205 ARRAY_SIZE(hx4700_audio_gpios));
206 if (ret)
207 return ret;
208
209 snd_soc_card_hx4700.dev = &pdev->dev;
210 ret = snd_soc_register_card(&snd_soc_card_hx4700);
211 if (ret)
212 return ret;
213
214 return 0;
215}
216
217static int __devexit hx4700_audio_remove(struct platform_device *pdev)
218{
219 snd_soc_jack_free_gpios(&hs_jack, 1, &hs_jack_gpio);
220 snd_soc_unregister_card(&snd_soc_card_hx4700);
221
222 gpio_set_value(GPIO92_HX4700_HP_DRIVER, 0);
223 gpio_set_value(GPIO107_HX4700_SPK_nSD, 0);
224
225 gpio_free_array(hx4700_audio_gpios, ARRAY_SIZE(hx4700_audio_gpios));
226 return 0;
227}
228
229static struct platform_driver hx4700_audio_driver = {
230 .driver = {
231 .name = "hx4700-audio",
232 .owner = THIS_MODULE,
233 .pm = &snd_soc_pm_ops,
234 },
235 .probe = hx4700_audio_probe,
236 .remove = __devexit_p(hx4700_audio_remove),
237};
238
239static int __init hx4700_modinit(void)
240{
241 return platform_driver_register(&hx4700_audio_driver);
242}
243module_init(hx4700_modinit);
244
245static void __exit hx4700_modexit(void)
246{
247 platform_driver_unregister(&hx4700_audio_driver);
248}
249
250module_exit(hx4700_modexit);
251
252MODULE_AUTHOR("Philipp Zabel");
253MODULE_DESCRIPTION("ALSA SoC iPAQ hx4700");
254MODULE_LICENSE("GPL");
255MODULE_ALIAS("platform:hx4700-audio");
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index a7d4999f9b24..da3ae4316cf2 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -276,7 +276,7 @@ static struct snd_soc_dai_link poodle_dai = {
276 .cpu_dai_name = "pxa2xx-i2s", 276 .cpu_dai_name = "pxa2xx-i2s",
277 .codec_dai_name = "wm8731-hifi", 277 .codec_dai_name = "wm8731-hifi",
278 .platform_name = "pxa-pcm-audio", 278 .platform_name = "pxa-pcm-audio",
279 .codec_name = "wm8731-codec.0-001b", 279 .codec_name = "wm8731.0-001b",
280 .init = poodle_wm8731_init, 280 .init = poodle_wm8731_init,
281 .ops = &poodle_ops, 281 .ops = &poodle_ops,
282}; 282};
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 8e1571350630..b253d864868a 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -42,6 +42,7 @@
42 42
43static int spitz_jack_func; 43static int spitz_jack_func;
44static int spitz_spk_func; 44static int spitz_spk_func;
45static int spitz_mic_gpio;
45 46
46static void spitz_ext_control(struct snd_soc_codec *codec) 47static void spitz_ext_control(struct snd_soc_codec *codec)
47{ 48{
@@ -217,14 +218,7 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol,
217static int spitz_mic_bias(struct snd_soc_dapm_widget *w, 218static int spitz_mic_bias(struct snd_soc_dapm_widget *w,
218 struct snd_kcontrol *k, int event) 219 struct snd_kcontrol *k, int event)
219{ 220{
220 if (machine_is_borzoi() || machine_is_spitz()) 221 gpio_set_value_cansleep(spitz_mic_gpio, SND_SOC_DAPM_EVENT_ON(event));
221 gpio_set_value(SPITZ_GPIO_MIC_BIAS,
222 SND_SOC_DAPM_EVENT_ON(event));
223
224 if (machine_is_akita())
225 gpio_set_value(AKITA_GPIO_MIC_BIAS,
226 SND_SOC_DAPM_EVENT_ON(event));
227
228 return 0; 222 return 0;
229} 223}
230 224
@@ -339,22 +333,45 @@ static int __init spitz_init(void)
339 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) 333 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita()))
340 return -ENODEV; 334 return -ENODEV;
341 335
336 if (machine_is_borzoi() || machine_is_spitz())
337 spitz_mic_gpio = SPITZ_GPIO_MIC_BIAS;
338 else
339 spitz_mic_gpio = AKITA_GPIO_MIC_BIAS;
340
341 ret = gpio_request(spitz_mic_gpio, "MIC GPIO");
342 if (ret)
343 goto err1;
344
345 ret = gpio_direction_output(spitz_mic_gpio, 0);
346 if (ret)
347 goto err2;
348
342 spitz_snd_device = platform_device_alloc("soc-audio", -1); 349 spitz_snd_device = platform_device_alloc("soc-audio", -1);
343 if (!spitz_snd_device) 350 if (!spitz_snd_device) {
344 return -ENOMEM; 351 ret = -ENOMEM;
352 goto err2;
353 }
345 354
346 platform_set_drvdata(spitz_snd_device, &snd_soc_spitz); 355 platform_set_drvdata(spitz_snd_device, &snd_soc_spitz);
347 ret = platform_device_add(spitz_snd_device);
348 356
357 ret = platform_device_add(spitz_snd_device);
349 if (ret) 358 if (ret)
350 platform_device_put(spitz_snd_device); 359 goto err3;
360
361 return 0;
351 362
363err3:
364 platform_device_put(spitz_snd_device);
365err2:
366 gpio_free(spitz_mic_gpio);
367err1:
352 return ret; 368 return ret;
353} 369}
354 370
355static void __exit spitz_exit(void) 371static void __exit spitz_exit(void)
356{ 372{
357 platform_device_unregister(spitz_snd_device); 373 platform_device_unregister(spitz_snd_device);
374 gpio_free(spitz_mic_gpio);
358} 375}
359 376
360module_init(spitz_init); 377module_init(spitz_init);
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index a3fdfb631469..459566bfcd35 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -162,3 +162,18 @@ config SND_SOC_SAMSUNG_SMDK_SPDIF
162 select SND_SAMSUNG_SPDIF 162 select SND_SAMSUNG_SPDIF
163 help 163 help
164 Say Y if you want to add support for SoC S/PDIF audio on the SMDK. 164 Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
165
166config SND_SOC_SMDK_WM8580_PCM
167 tristate "SoC PCM Audio support for WM8580 on SMDK"
168 depends on SND_SOC_SAMSUNG && (MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110)
169 select SND_SOC_WM8580
170 select SND_SAMSUNG_PCM
171 help
172 Say Y if you want to add support for SoC audio on the SMDK.
173
174config SND_SOC_SPEYSIDE
175 tristate "Audio support for Wolfson Speyside"
176 depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
177 select SND_SAMSUNG_I2S
178 select SND_SOC_WM8915
179 select SND_SOC_WM9081
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 294dec05c26d..683843a2744f 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -34,6 +34,8 @@ snd-soc-smdk-wm9713-objs := smdk_wm9713.o
34snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o 34snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
35snd-soc-goni-wm8994-objs := goni_wm8994.o 35snd-soc-goni-wm8994-objs := goni_wm8994.o
36snd-soc-smdk-spdif-objs := smdk_spdif.o 36snd-soc-smdk-spdif-objs := smdk_spdif.o
37snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o
38snd-soc-speyside-objs := speyside.o
37 39
38obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o 40obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
39obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 41obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -51,3 +53,5 @@ obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o
51obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o 53obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o
52obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o 54obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o
53obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o 55obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o
56obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o
57obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c
index f6b3a3ce5919..eb6d72ed55a7 100644
--- a/sound/soc/samsung/goni_wm8994.c
+++ b/sound/soc/samsung/goni_wm8994.c
@@ -236,18 +236,17 @@ static struct snd_soc_dai_link goni_dai[] = {
236 .name = "WM8994", 236 .name = "WM8994",
237 .stream_name = "WM8994 HiFi", 237 .stream_name = "WM8994 HiFi",
238 .cpu_dai_name = "samsung-i2s.0", 238 .cpu_dai_name = "samsung-i2s.0",
239 .codec_dai_name = "wm8994-hifi", 239 .codec_dai_name = "wm8994-aif1",
240 .platform_name = "samsung-audio", 240 .platform_name = "samsung-audio",
241 .codec_name = "wm8994-codec.0-0x1a", 241 .codec_name = "wm8994-codec.0-001a",
242 .init = goni_wm8994_init, 242 .init = goni_wm8994_init,
243 .ops = &goni_hifi_ops, 243 .ops = &goni_hifi_ops,
244}, { 244}, {
245 .name = "WM8994 Voice", 245 .name = "WM8994 Voice",
246 .stream_name = "Voice", 246 .stream_name = "Voice",
247 .cpu_dai_name = "goni-voice-dai", 247 .cpu_dai_name = "goni-voice-dai",
248 .codec_dai_name = "wm8994-voice", 248 .codec_dai_name = "wm8994-aif2",
249 .platform_name = "samsung-audio", 249 .codec_name = "wm8994-codec.0-001a",
250 .codec_name = "wm8994-codec.0-0x1a",
251 .ops = &goni_voice_ops, 250 .ops = &goni_voice_ops,
252}, 251},
253}; 252};
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index 452230975632..16152ed08648 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -432,7 +432,6 @@ static struct snd_soc_dai_link neo1973_dai[] = {
432{ /* Voice via BT */ 432{ /* Voice via BT */
433 .name = "Bluetooth", 433 .name = "Bluetooth",
434 .stream_name = "Voice", 434 .stream_name = "Voice",
435 .platform_name = "samsung-audio",
436 .cpu_dai_name = "dfbmcs320-pcm", 435 .cpu_dai_name = "dfbmcs320-pcm",
437 .codec_dai_name = "wm8753-voice", 436 .codec_dai_name = "wm8753-voice",
438 .codec_name = "wm8753-codec.0-001a", 437 .codec_name = "wm8753-codec.0-001a",
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c
new file mode 100644
index 000000000000..0d12092df164
--- /dev/null
+++ b/sound/soc/samsung/smdk_wm8580pcm.c
@@ -0,0 +1,206 @@
1/*
2 * sound/soc/samsung/smdk_wm8580pcm.c
3 *
4 * Copyright (c) 2011 Samsung Electronics Co. Ltd
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11#include <sound/soc.h>
12#include <sound/pcm_params.h>
13#include <sound/pcm.h>
14
15#include <asm/mach-types.h>
16
17#include "../codecs/wm8580.h"
18#include "dma.h"
19#include "pcm.h"
20
21/*
22 * Board Settings:
23 * o '1' means 'ON'
24 * o '0' means 'OFF'
25 * o 'X' means 'Don't care'
26 *
27 * SMDK6410, SMDK6440, SMDK6450 Base B/D: CFG1-0000, CFG2-1111
28 * SMDKC110, SMDKV210: CFGB11-100100, CFGB12-0000
29 */
30
31#define SMDK_WM8580_EXT_OSC 12000000
32#define SMDK_WM8580_EXT_MCLK 4096000
33#define SMDK_WM8580_EXT_VOICE 2048000
34
35static unsigned long mclk_freq;
36static unsigned long xtal_freq;
37
38/*
39 * If MCLK clock directly gets from XTAL, we don't have to use PLL
40 * to make MCLK, but if XTAL clock source connects with other codec
41 * pin (like XTI), we should have to set codec's PLL to make MCLK.
42 * Because Samsung SoC does not support pcmcdclk output like I2S.
43 */
44
45static int smdk_wm8580_pcm_hw_params(struct snd_pcm_substream *substream,
46 struct snd_pcm_hw_params *params)
47{
48 struct snd_soc_pcm_runtime *rtd = substream->private_data;
49 struct snd_soc_dai *codec_dai = rtd->codec_dai;
50 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
51 int rfs, ret;
52
53 switch (params_rate(params)) {
54 case 8000:
55 break;
56 default:
57 printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n",
58 __func__, __LINE__, params_rate(params));
59 return -EINVAL;
60 }
61
62 rfs = mclk_freq / params_rate(params) / 2;
63
64 /* Set the codec DAI configuration */
65 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B
66 | SND_SOC_DAIFMT_IB_NF
67 | SND_SOC_DAIFMT_CBS_CFS);
68 if (ret < 0)
69 return ret;
70
71 /* Set the cpu DAI configuration */
72 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B
73 | SND_SOC_DAIFMT_IB_NF
74 | SND_SOC_DAIFMT_CBS_CFS);
75 if (ret < 0)
76 return ret;
77
78 if (mclk_freq == xtal_freq) {
79 ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_MCLK,
80 mclk_freq, SND_SOC_CLOCK_IN);
81 if (ret < 0)
82 return ret;
83
84 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
85 WM8580_CLKSRC_MCLK);
86 if (ret < 0)
87 return ret;
88 } else {
89 ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_PLLA,
90 mclk_freq, SND_SOC_CLOCK_IN);
91 if (ret < 0)
92 return ret;
93
94 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
95 WM8580_CLKSRC_PLLA);
96 if (ret < 0)
97 return ret;
98
99 ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0,
100 xtal_freq, mclk_freq);
101 if (ret < 0)
102 return ret;
103 }
104
105 /* Set PCM source clock on CPU */
106 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_PCM_CLKSRC_MUX,
107 mclk_freq, SND_SOC_CLOCK_IN);
108 if (ret < 0)
109 return ret;
110
111 /* Set SCLK_DIV for making bclk */
112 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, rfs);
113 if (ret < 0)
114 return ret;
115
116 return 0;
117}
118
119static struct snd_soc_ops smdk_wm8580_pcm_ops = {
120 .hw_params = smdk_wm8580_pcm_hw_params,
121};
122
123static struct snd_soc_dai_link smdk_dai[] = {
124 {
125 .name = "WM8580 PAIF PCM RX",
126 .stream_name = "Playback",
127 .cpu_dai_name = "samsung-pcm.0",
128 .codec_dai_name = "wm8580-hifi-playback",
129 .platform_name = "samsung-audio",
130 .codec_name = "wm8580-codec.0-001b",
131 .ops = &smdk_wm8580_pcm_ops,
132 }, {
133 .name = "WM8580 PAIF PCM TX",
134 .stream_name = "Capture",
135 .cpu_dai_name = "samsung-pcm.0",
136 .codec_dai_name = "wm8580-hifi-capture",
137 .platform_name = "samsung-audio",
138 .codec_name = "wm8580-codec.0-001b",
139 .ops = &smdk_wm8580_pcm_ops,
140 },
141};
142
143static struct snd_soc_card smdk_pcm = {
144 .name = "SMDK-PCM",
145 .dai_link = smdk_dai,
146 .num_links = 2,
147};
148
149/*
150 * After SMDKC110 Base Board's Rev is '0.1', 12MHz External OSC(X1)
151 * is absent (or not connected), so we connect EXT_VOICE_CLK(OSC4),
152 * 2.0484Mhz, directly with MCLK both Codec and SoC.
153 */
154static int __devinit snd_smdk_probe(struct platform_device *pdev)
155{
156 int ret = 0;
157
158 xtal_freq = SMDK_WM8580_EXT_OSC;
159 mclk_freq = SMDK_WM8580_EXT_MCLK;
160
161 if (machine_is_smdkc110() || machine_is_smdkv210())
162 xtal_freq = mclk_freq = SMDK_WM8580_EXT_VOICE;
163
164 smdk_pcm.dev = &pdev->dev;
165 ret = snd_soc_register_card(&smdk_pcm);
166 if (ret) {
167 dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret);
168 return ret;
169 }
170
171 return 0;
172}
173
174static int __devexit snd_smdk_remove(struct platform_device *pdev)
175{
176 snd_soc_unregister_card(&smdk_pcm);
177 platform_set_drvdata(pdev, NULL);
178 return 0;
179}
180
181static struct platform_driver snd_smdk_driver = {
182 .driver = {
183 .owner = THIS_MODULE,
184 .name = "samsung-smdk-pcm",
185 },
186 .probe = snd_smdk_probe,
187 .remove = __devexit_p(snd_smdk_remove),
188};
189
190static int __init smdk_audio_init(void)
191{
192 return platform_driver_register(&snd_smdk_driver);
193}
194
195module_init(smdk_audio_init);
196
197static void __exit smdk_audio_exit(void)
198{
199 platform_driver_unregister(&snd_smdk_driver);
200}
201
202module_exit(smdk_audio_exit);
203
204MODULE_AUTHOR("Sangbeom Kim, <sbkim73@samsung.com>");
205MODULE_DESCRIPTION("ALSA SoC SMDK WM8580 for PCM");
206MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
new file mode 100644
index 000000000000..360a333cb7c0
--- /dev/null
+++ b/sound/soc/samsung/speyside.c
@@ -0,0 +1,332 @@
1/*
2 * Speyside audio support
3 *
4 * Copyright 2011 Wolfson Microelectronics
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <sound/soc.h>
13#include <sound/soc-dapm.h>
14#include <sound/jack.h>
15#include <linux/gpio.h>
16
17#include "../codecs/wm8915.h"
18#include "../codecs/wm9081.h"
19
20#define WM8915_HPSEL_GPIO 214
21
22static int speyside_set_bias_level(struct snd_soc_card *card,
23 enum snd_soc_bias_level level)
24{
25 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
26 int ret;
27
28 switch (level) {
29 case SND_SOC_BIAS_STANDBY:
30 ret = snd_soc_dai_set_sysclk(codec_dai, WM8915_SYSCLK_MCLK1,
31 32768, SND_SOC_CLOCK_IN);
32 if (ret < 0)
33 return ret;
34
35 ret = snd_soc_dai_set_pll(codec_dai, WM8915_FLL_MCLK1,
36 0, 0, 0);
37 if (ret < 0) {
38 pr_err("Failed to stop FLL\n");
39 return ret;
40 }
41
42 default:
43 break;
44 }
45
46 return 0;
47}
48
49static int speyside_hw_params(struct snd_pcm_substream *substream,
50 struct snd_pcm_hw_params *params)
51{
52 struct snd_soc_pcm_runtime *rtd = substream->private_data;
53 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
54 struct snd_soc_dai *codec_dai = rtd->codec_dai;
55 int ret;
56
57 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
58 | SND_SOC_DAIFMT_NB_NF
59 | SND_SOC_DAIFMT_CBM_CFM);
60 if (ret < 0)
61 return ret;
62
63 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
64 | SND_SOC_DAIFMT_NB_NF
65 | SND_SOC_DAIFMT_CBM_CFM);
66 if (ret < 0)
67 return ret;
68
69 ret = snd_soc_dai_set_pll(codec_dai, 0, WM8915_FLL_MCLK1,
70 32768, 256 * 48000);
71 if (ret < 0)
72 return ret;
73
74 ret = snd_soc_dai_set_sysclk(codec_dai, WM8915_SYSCLK_FLL,
75 256 * 48000, SND_SOC_CLOCK_IN);
76 if (ret < 0)
77 return ret;
78
79 return 0;
80}
81
82static struct snd_soc_ops speyside_ops = {
83 .hw_params = speyside_hw_params,
84};
85
86static struct snd_soc_jack speyside_headset;
87
88/* Headset jack detection DAPM pins */
89static struct snd_soc_jack_pin speyside_headset_pins[] = {
90 {
91 .pin = "Headset Mic",
92 .mask = SND_JACK_MICROPHONE,
93 },
94 {
95 .pin = "Headphone",
96 .mask = SND_JACK_HEADPHONE,
97 },
98};
99
100/* Default the headphone selection to active high */
101static int speyside_jack_polarity;
102
103static int speyside_get_micbias(struct snd_soc_dapm_widget *source,
104 struct snd_soc_dapm_widget *sink)
105{
106 if (speyside_jack_polarity && (strcmp(source->name, "MICB1") == 0))
107 return 1;
108 if (!speyside_jack_polarity && (strcmp(source->name, "MICB2") == 0))
109 return 1;
110
111 return 0;
112}
113
114static void speyside_set_polarity(struct snd_soc_codec *codec,
115 int polarity)
116{
117 speyside_jack_polarity = !polarity;
118 gpio_direction_output(WM8915_HPSEL_GPIO, speyside_jack_polarity);
119
120 /* Re-run DAPM to make sure we're using the correct mic bias */
121 snd_soc_dapm_sync(&codec->dapm);
122}
123
124static int speyside_wm8915_init(struct snd_soc_pcm_runtime *rtd)
125{
126 struct snd_soc_dai *dai = rtd->codec_dai;
127 struct snd_soc_codec *codec = rtd->codec;
128 int ret;
129
130 ret = snd_soc_dai_set_sysclk(dai, WM8915_SYSCLK_MCLK1, 32768, 0);
131 if (ret < 0)
132 return ret;
133
134 ret = gpio_request(WM8915_HPSEL_GPIO, "HP_SEL");
135 if (ret != 0)
136 pr_err("Failed to request HP_SEL GPIO: %d\n", ret);
137 gpio_direction_output(WM8915_HPSEL_GPIO, speyside_jack_polarity);
138
139 ret = snd_soc_jack_new(codec, "Headset",
140 SND_JACK_HEADSET | SND_JACK_BTN_0,
141 &speyside_headset);
142 if (ret)
143 return ret;
144
145 ret = snd_soc_jack_add_pins(&speyside_headset,
146 ARRAY_SIZE(speyside_headset_pins),
147 speyside_headset_pins);
148 if (ret)
149 return ret;
150
151 wm8915_detect(codec, &speyside_headset, speyside_set_polarity);
152
153 return 0;
154}
155
156static int speyside_late_probe(struct snd_soc_card *card)
157{
158 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
159 snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic");
160 snd_soc_dapm_ignore_suspend(&card->dapm, "Main AMIC");
161 snd_soc_dapm_ignore_suspend(&card->dapm, "Main DMIC");
162 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
163 snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Output");
164 snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Input");
165
166 return 0;
167}
168
169static struct snd_soc_dai_link speyside_dai[] = {
170 {
171 .name = "CPU",
172 .stream_name = "CPU",
173 .cpu_dai_name = "samsung-i2s.0",
174 .codec_dai_name = "wm8915-aif1",
175 .platform_name = "samsung-audio",
176 .codec_name = "wm8915.1-001a",
177 .init = speyside_wm8915_init,
178 .ops = &speyside_ops,
179 },
180 {
181 .name = "Baseband",
182 .stream_name = "Baseband",
183 .cpu_dai_name = "wm8915-aif2",
184 .codec_dai_name = "wm1250-ev1",
185 .codec_name = "wm1250-ev1.1-0027",
186 .ops = &speyside_ops,
187 .ignore_suspend = 1,
188 },
189};
190
191static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm)
192{
193 snd_soc_dapm_nc_pin(dapm, "LINEOUT");
194
195 /* At any time the WM9081 is active it will have this clock */
196 return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK,
197 48000 * 256, 0);
198}
199
200static struct snd_soc_aux_dev speyside_aux_dev[] = {
201 {
202 .name = "wm9081",
203 .codec_name = "wm9081.1-006c",
204 .init = speyside_wm9081_init,
205 },
206};
207
208static struct snd_soc_codec_conf speyside_codec_conf[] = {
209 {
210 .dev_name = "wm9081.1-006c",
211 .name_prefix = "Sub",
212 },
213};
214
215static const struct snd_kcontrol_new controls[] = {
216 SOC_DAPM_PIN_SWITCH("Main Speaker"),
217 SOC_DAPM_PIN_SWITCH("Main DMIC"),
218 SOC_DAPM_PIN_SWITCH("Main AMIC"),
219 SOC_DAPM_PIN_SWITCH("WM1250 Input"),
220 SOC_DAPM_PIN_SWITCH("WM1250 Output"),
221};
222
223static struct snd_soc_dapm_widget widgets[] = {
224 SND_SOC_DAPM_HP("Headphone", NULL),
225 SND_SOC_DAPM_MIC("Headset Mic", NULL),
226
227 SND_SOC_DAPM_SPK("Main Speaker", NULL),
228
229 SND_SOC_DAPM_MIC("Main AMIC", NULL),
230 SND_SOC_DAPM_MIC("Main DMIC", NULL),
231};
232
233static struct snd_soc_dapm_route audio_paths[] = {
234 { "IN1RN", NULL, "MICB1" },
235 { "IN1RP", NULL, "MICB1" },
236 { "IN1RN", NULL, "MICB2" },
237 { "IN1RP", NULL, "MICB2" },
238 { "MICB1", NULL, "Headset Mic", speyside_get_micbias },
239 { "MICB2", NULL, "Headset Mic", speyside_get_micbias },
240
241 { "IN1LP", NULL, "MICB2" },
242 { "IN1RN", NULL, "MICB1" },
243 { "MICB2", NULL, "Main AMIC" },
244
245 { "DMIC1DAT", NULL, "MICB1" },
246 { "DMIC2DAT", NULL, "MICB1" },
247 { "MICB1", NULL, "Main DMIC" },
248
249 { "Headphone", NULL, "HPOUT1L" },
250 { "Headphone", NULL, "HPOUT1R" },
251
252 { "Sub IN1", NULL, "HPOUT2L" },
253 { "Sub IN2", NULL, "HPOUT2R" },
254
255 { "Main Speaker", NULL, "Sub SPKN" },
256 { "Main Speaker", NULL, "Sub SPKP" },
257 { "Main Speaker", NULL, "SPKDAT" },
258};
259
260static struct snd_soc_card speyside = {
261 .name = "Speyside",
262 .dai_link = speyside_dai,
263 .num_links = ARRAY_SIZE(speyside_dai),
264 .aux_dev = speyside_aux_dev,
265 .num_aux_devs = ARRAY_SIZE(speyside_aux_dev),
266 .codec_conf = speyside_codec_conf,
267 .num_configs = ARRAY_SIZE(speyside_codec_conf),
268
269 .set_bias_level = speyside_set_bias_level,
270
271 .controls = controls,
272 .num_controls = ARRAY_SIZE(controls),
273 .dapm_widgets = widgets,
274 .num_dapm_widgets = ARRAY_SIZE(widgets),
275 .dapm_routes = audio_paths,
276 .num_dapm_routes = ARRAY_SIZE(audio_paths),
277
278 .late_probe = speyside_late_probe,
279};
280
281static __devinit int speyside_probe(struct platform_device *pdev)
282{
283 struct snd_soc_card *card = &speyside;
284 int ret;
285
286 card->dev = &pdev->dev;
287
288 ret = snd_soc_register_card(card);
289 if (ret) {
290 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
291 ret);
292 return ret;
293 }
294
295 return 0;
296}
297
298static int __devexit speyside_remove(struct platform_device *pdev)
299{
300 struct snd_soc_card *card = platform_get_drvdata(pdev);
301
302 snd_soc_unregister_card(card);
303
304 return 0;
305}
306
307static struct platform_driver speyside_driver = {
308 .driver = {
309 .name = "speyside",
310 .owner = THIS_MODULE,
311 .pm = &snd_soc_pm_ops,
312 },
313 .probe = speyside_probe,
314 .remove = __devexit_p(speyside_remove),
315};
316
317static int __init speyside_audio_init(void)
318{
319 return platform_driver_register(&speyside_driver);
320}
321module_init(speyside_audio_init);
322
323static void __exit speyside_audio_exit(void)
324{
325 platform_driver_unregister(&speyside_driver);
326}
327module_exit(speyside_audio_exit);
328
329MODULE_DESCRIPTION("Speyside audio support");
330MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
331MODULE_LICENSE("GPL");
332MODULE_ALIAS("platform:speyside");
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 23c0e83d4c19..4a9da6b5f4e1 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -86,8 +86,8 @@
86#define SE (1 << 0) /* Fix the master clock */ 86#define SE (1 << 0) /* Fix the master clock */
87 87
88/* CLK_RST */ 88/* CLK_RST */
89#define B_CLK 0x00000010 89#define CRB (1 << 4)
90#define A_CLK 0x00000001 90#define CRA (1 << 0)
91 91
92/* IO SHIFT / MACRO */ 92/* IO SHIFT / MACRO */
93#define BI_SHIFT 12 93#define BI_SHIFT 12
@@ -146,11 +146,20 @@ struct fsi_priv {
146 void __iomem *base; 146 void __iomem *base;
147 struct fsi_master *master; 147 struct fsi_master *master;
148 148
149 int chan_num;
150 struct fsi_stream playback; 149 struct fsi_stream playback;
151 struct fsi_stream capture; 150 struct fsi_stream capture;
152 151
152 int chan_num:16;
153 int clk_master:1;
154
153 long rate; 155 long rate;
156
157 /* for suspend/resume */
158 u32 saved_do_fmt;
159 u32 saved_di_fmt;
160 u32 saved_ckg1;
161 u32 saved_ckg2;
162 u32 saved_out_sel;
154}; 163};
155 164
156struct fsi_core { 165struct fsi_core {
@@ -171,6 +180,14 @@ struct fsi_master {
171 struct fsi_core *core; 180 struct fsi_core *core;
172 struct sh_fsi_platform_info *info; 181 struct sh_fsi_platform_info *info;
173 spinlock_t lock; 182 spinlock_t lock;
183
184 /* for suspend/resume */
185 u32 saved_a_mclk;
186 u32 saved_b_mclk;
187 u32 saved_iemsk;
188 u32 saved_imsk;
189 u32 saved_clk_rst;
190 u32 saved_soft_rst;
174}; 191};
175 192
176/* 193/*
@@ -244,6 +261,11 @@ static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
244 return fsi->master; 261 return fsi->master;
245} 262}
246 263
264static int fsi_is_clk_master(struct fsi_priv *fsi)
265{
266 return fsi->clk_master;
267}
268
247static int fsi_is_port_a(struct fsi_priv *fsi) 269static int fsi_is_port_a(struct fsi_priv *fsi)
248{ 270{
249 return fsi->master->base == fsi->base; 271 return fsi->master->base == fsi->base;
@@ -535,20 +557,45 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
535} 557}
536 558
537/* 559/*
538 * ctrl function 560 * clock function
539 */ 561 */
562#define fsi_module_init(m, d) __fsi_module_clk_ctrl(m, d, 1)
563#define fsi_module_kill(m, d) __fsi_module_clk_ctrl(m, d, 0)
564static void __fsi_module_clk_ctrl(struct fsi_master *master,
565 struct device *dev,
566 int enable)
567{
568 pm_runtime_get_sync(dev);
569
570 if (enable) {
571 /* enable only SR */
572 fsi_master_mask_set(master, SOFT_RST, FSISR, FSISR);
573 fsi_master_mask_set(master, SOFT_RST, PASR | PBSR, 0);
574 } else {
575 /* clear all registers */
576 fsi_master_mask_set(master, SOFT_RST, FSISR, 0);
577 }
540 578
541static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable) 579 pm_runtime_put_sync(dev);
580}
581
582#define fsi_port_start(f) __fsi_port_clk_ctrl(f, 1)
583#define fsi_port_stop(f) __fsi_port_clk_ctrl(f, 0)
584static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int enable)
542{ 585{
543 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
544 struct fsi_master *master = fsi_get_master(fsi); 586 struct fsi_master *master = fsi_get_master(fsi);
587 u32 soft = fsi_is_port_a(fsi) ? PASR : PBSR;
588 u32 clk = fsi_is_port_a(fsi) ? CRA : CRB;
589 int is_master = fsi_is_clk_master(fsi);
545 590
546 if (enable) 591 fsi_master_mask_set(master, SOFT_RST, soft, (enable) ? soft : 0);
547 fsi_master_mask_set(master, CLK_RST, val, val); 592 if (is_master)
548 else 593 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
549 fsi_master_mask_set(master, CLK_RST, val, 0);
550} 594}
551 595
596/*
597 * ctrl function
598 */
552static void fsi_fifo_init(struct fsi_priv *fsi, 599static void fsi_fifo_init(struct fsi_priv *fsi,
553 int is_play, 600 int is_play,
554 struct snd_soc_dai *dai) 601 struct snd_soc_dai *dai)
@@ -601,18 +648,6 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
601 } 648 }
602} 649}
603 650
604static void fsi_soft_all_reset(struct fsi_master *master)
605{
606 /* port AB reset */
607 fsi_master_mask_set(master, SOFT_RST, PASR | PBSR, 0);
608 mdelay(10);
609
610 /* soft reset */
611 fsi_master_mask_set(master, SOFT_RST, FSISR, 0);
612 fsi_master_mask_set(master, SOFT_RST, FSISR, FSISR);
613 mdelay(10);
614}
615
616static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) 651static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
617{ 652{
618 struct snd_pcm_runtime *runtime; 653 struct snd_pcm_runtime *runtime;
@@ -793,14 +828,13 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
793 struct fsi_priv *fsi = fsi_get_priv(substream); 828 struct fsi_priv *fsi = fsi_get_priv(substream);
794 int is_play = fsi_is_play(substream); 829 int is_play = fsi_is_play(substream);
795 struct fsi_master *master = fsi_get_master(fsi); 830 struct fsi_master *master = fsi_get_master(fsi);
796 set_rate_func set_rate; 831 set_rate_func set_rate = fsi_get_info_set_rate(master);
797 832
798 fsi_irq_disable(fsi, is_play); 833 fsi_irq_disable(fsi, is_play);
799 fsi_clk_ctrl(fsi, 0);
800 834
801 set_rate = fsi_get_info_set_rate(master); 835 if (fsi_is_clk_master(fsi))
802 if (set_rate && fsi->rate)
803 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0); 836 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
837
804 fsi->rate = 0; 838 fsi->rate = 0;
805 839
806 pm_runtime_put_sync(dai->dev); 840 pm_runtime_put_sync(dai->dev);
@@ -821,8 +855,10 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
821 frames_to_bytes(runtime, runtime->period_size)); 855 frames_to_bytes(runtime, runtime->period_size));
822 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); 856 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
823 fsi_irq_enable(fsi, is_play); 857 fsi_irq_enable(fsi, is_play);
858 fsi_port_start(fsi);
824 break; 859 break;
825 case SNDRV_PCM_TRIGGER_STOP: 860 case SNDRV_PCM_TRIGGER_STOP:
861 fsi_port_stop(fsi);
826 fsi_irq_disable(fsi, is_play); 862 fsi_irq_disable(fsi, is_play);
827 fsi_stream_pop(fsi, is_play); 863 fsi_stream_pop(fsi, is_play);
828 break; 864 break;
@@ -876,6 +912,8 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
876static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 912static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
877{ 913{
878 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); 914 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
915 struct fsi_master *master = fsi_get_master(fsi);
916 set_rate_func set_rate = fsi_get_info_set_rate(master);
879 u32 flags = fsi_get_info_flags(fsi); 917 u32 flags = fsi_get_info_flags(fsi);
880 u32 data = 0; 918 u32 data = 0;
881 int ret; 919 int ret;
@@ -886,6 +924,7 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
886 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 924 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
887 case SND_SOC_DAIFMT_CBM_CFM: 925 case SND_SOC_DAIFMT_CBM_CFM:
888 data = DIMD | DOMD; 926 data = DIMD | DOMD;
927 fsi->clk_master = 1;
889 break; 928 break;
890 case SND_SOC_DAIFMT_CBS_CFS: 929 case SND_SOC_DAIFMT_CBS_CFS:
891 break; 930 break;
@@ -893,6 +932,13 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
893 ret = -EINVAL; 932 ret = -EINVAL;
894 goto set_fmt_exit; 933 goto set_fmt_exit;
895 } 934 }
935
936 if (fsi_is_clk_master(fsi) && !set_rate) {
937 dev_err(dai->dev, "platform doesn't have set_rate\n");
938 ret = -EINVAL;
939 goto set_fmt_exit;
940 }
941
896 fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data); 942 fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
897 943
898 /* set format */ 944 /* set format */
@@ -919,13 +965,12 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
919{ 965{
920 struct fsi_priv *fsi = fsi_get_priv(substream); 966 struct fsi_priv *fsi = fsi_get_priv(substream);
921 struct fsi_master *master = fsi_get_master(fsi); 967 struct fsi_master *master = fsi_get_master(fsi);
922 set_rate_func set_rate; 968 set_rate_func set_rate = fsi_get_info_set_rate(master);
923 int fsi_ver = master->core->ver; 969 int fsi_ver = master->core->ver;
924 long rate = params_rate(params); 970 long rate = params_rate(params);
925 int ret; 971 int ret;
926 972
927 set_rate = fsi_get_info_set_rate(master); 973 if (!fsi_is_clk_master(fsi))
928 if (!set_rate)
929 return 0; 974 return 0;
930 975
931 ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1); 976 ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1);
@@ -987,7 +1032,6 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
987 1032
988 fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data); 1033 fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
989 udelay(10); 1034 udelay(10);
990 fsi_clk_ctrl(fsi, 1);
991 ret = 0; 1035 ret = 0;
992 } 1036 }
993 1037
@@ -1202,9 +1246,7 @@ static int fsi_probe(struct platform_device *pdev)
1202 pm_runtime_enable(&pdev->dev); 1246 pm_runtime_enable(&pdev->dev);
1203 dev_set_drvdata(&pdev->dev, master); 1247 dev_set_drvdata(&pdev->dev, master);
1204 1248
1205 pm_runtime_get_sync(&pdev->dev); 1249 fsi_module_init(master, &pdev->dev);
1206 fsi_soft_all_reset(master);
1207 pm_runtime_put_sync(&pdev->dev);
1208 1250
1209 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, 1251 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED,
1210 id_entry->name, master); 1252 id_entry->name, master);
@@ -1248,6 +1290,8 @@ static int fsi_remove(struct platform_device *pdev)
1248 1290
1249 master = dev_get_drvdata(&pdev->dev); 1291 master = dev_get_drvdata(&pdev->dev);
1250 1292
1293 fsi_module_kill(master, &pdev->dev);
1294
1251 free_irq(master->irq, master); 1295 free_irq(master->irq, master);
1252 pm_runtime_disable(&pdev->dev); 1296 pm_runtime_disable(&pdev->dev);
1253 1297
@@ -1260,6 +1304,82 @@ static int fsi_remove(struct platform_device *pdev)
1260 return 0; 1304 return 0;
1261} 1305}
1262 1306
1307static void __fsi_suspend(struct fsi_priv *fsi,
1308 struct device *dev,
1309 set_rate_func set_rate)
1310{
1311 fsi->saved_do_fmt = fsi_reg_read(fsi, DO_FMT);
1312 fsi->saved_di_fmt = fsi_reg_read(fsi, DI_FMT);
1313 fsi->saved_ckg1 = fsi_reg_read(fsi, CKG1);
1314 fsi->saved_ckg2 = fsi_reg_read(fsi, CKG2);
1315 fsi->saved_out_sel = fsi_reg_read(fsi, OUT_SEL);
1316
1317 if (fsi_is_clk_master(fsi))
1318 set_rate(dev, fsi_is_port_a(fsi), fsi->rate, 0);
1319}
1320
1321static void __fsi_resume(struct fsi_priv *fsi,
1322 struct device *dev,
1323 set_rate_func set_rate)
1324{
1325 fsi_reg_write(fsi, DO_FMT, fsi->saved_do_fmt);
1326 fsi_reg_write(fsi, DI_FMT, fsi->saved_di_fmt);
1327 fsi_reg_write(fsi, CKG1, fsi->saved_ckg1);
1328 fsi_reg_write(fsi, CKG2, fsi->saved_ckg2);
1329 fsi_reg_write(fsi, OUT_SEL, fsi->saved_out_sel);
1330
1331 if (fsi_is_clk_master(fsi))
1332 set_rate(dev, fsi_is_port_a(fsi), fsi->rate, 1);
1333}
1334
1335static int fsi_suspend(struct device *dev)
1336{
1337 struct fsi_master *master = dev_get_drvdata(dev);
1338 set_rate_func set_rate = fsi_get_info_set_rate(master);
1339
1340 pm_runtime_get_sync(dev);
1341
1342 __fsi_suspend(&master->fsia, dev, set_rate);
1343 __fsi_suspend(&master->fsib, dev, set_rate);
1344
1345 master->saved_a_mclk = fsi_core_read(master, a_mclk);
1346 master->saved_b_mclk = fsi_core_read(master, b_mclk);
1347 master->saved_iemsk = fsi_core_read(master, iemsk);
1348 master->saved_imsk = fsi_core_read(master, imsk);
1349 master->saved_clk_rst = fsi_master_read(master, CLK_RST);
1350 master->saved_soft_rst = fsi_master_read(master, SOFT_RST);
1351
1352 fsi_module_kill(master, dev);
1353
1354 pm_runtime_put_sync(dev);
1355
1356 return 0;
1357}
1358
1359static int fsi_resume(struct device *dev)
1360{
1361 struct fsi_master *master = dev_get_drvdata(dev);
1362 set_rate_func set_rate = fsi_get_info_set_rate(master);
1363
1364 pm_runtime_get_sync(dev);
1365
1366 fsi_module_init(master, dev);
1367
1368 fsi_master_mask_set(master, SOFT_RST, 0xffff, master->saved_soft_rst);
1369 fsi_master_mask_set(master, CLK_RST, 0xffff, master->saved_clk_rst);
1370 fsi_core_mask_set(master, a_mclk, 0xffff, master->saved_a_mclk);
1371 fsi_core_mask_set(master, b_mclk, 0xffff, master->saved_b_mclk);
1372 fsi_core_mask_set(master, iemsk, 0xffff, master->saved_iemsk);
1373 fsi_core_mask_set(master, imsk, 0xffff, master->saved_imsk);
1374
1375 __fsi_resume(&master->fsia, dev, set_rate);
1376 __fsi_resume(&master->fsib, dev, set_rate);
1377
1378 pm_runtime_put_sync(dev);
1379
1380 return 0;
1381}
1382
1263static int fsi_runtime_nop(struct device *dev) 1383static int fsi_runtime_nop(struct device *dev)
1264{ 1384{
1265 /* Runtime PM callback shared between ->runtime_suspend() 1385 /* Runtime PM callback shared between ->runtime_suspend()
@@ -1273,6 +1393,8 @@ static int fsi_runtime_nop(struct device *dev)
1273} 1393}
1274 1394
1275static struct dev_pm_ops fsi_pm_ops = { 1395static struct dev_pm_ops fsi_pm_ops = {
1396 .suspend = fsi_suspend,
1397 .resume = fsi_resume,
1276 .runtime_suspend = fsi_runtime_nop, 1398 .runtime_suspend = fsi_runtime_nop,
1277 .runtime_resume = fsi_runtime_nop, 1399 .runtime_resume = fsi_runtime_nop,
1278}; 1400};
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 5d76da43b14c..06b7b81a1601 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -20,40 +20,28 @@
20 20
21#include <trace/events/asoc.h> 21#include <trace/events/asoc.h>
22 22
23static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, 23#ifdef CONFIG_SPI_MASTER
24 unsigned int reg) 24static int do_spi_write(void *control, const char *data, int len)
25{ 25{
26 struct spi_device *spi = control;
26 int ret; 27 int ret;
27 unsigned int val;
28
29 if (reg >= codec->driver->reg_cache_size ||
30 snd_soc_codec_volatile_register(codec, reg) ||
31 codec->cache_bypass) {
32 if (codec->cache_only)
33 return -1;
34
35 BUG_ON(!codec->hw_read);
36 return codec->hw_read(codec, reg);
37 }
38 28
39 ret = snd_soc_cache_read(codec, reg, &val); 29 ret = spi_write(spi, data, len);
40 if (ret < 0) 30 if (ret < 0)
41 return -1; 31 return ret;
42 return val; 32
33 return len;
43} 34}
35#endif
44 36
45static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, 37static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
46 unsigned int value) 38 unsigned int value, const void *data, int len)
47{ 39{
48 u8 data[2];
49 int ret; 40 int ret;
50 41
51 data[0] = (reg << 4) | ((value >> 8) & 0x000f);
52 data[1] = value & 0x00ff;
53
54 if (!snd_soc_codec_volatile_register(codec, reg) && 42 if (!snd_soc_codec_volatile_register(codec, reg) &&
55 reg < codec->driver->reg_cache_size && 43 reg < codec->driver->reg_cache_size &&
56 !codec->cache_bypass) { 44 !codec->cache_bypass) {
57 ret = snd_soc_cache_write(codec, reg, value); 45 ret = snd_soc_cache_write(codec, reg, value);
58 if (ret < 0) 46 if (ret < 0)
59 return -1; 47 return -1;
@@ -64,8 +52,8 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
64 return 0; 52 return 0;
65 } 53 }
66 54
67 ret = codec->hw_write(codec->control_data, data, 2); 55 ret = codec->hw_write(codec->control_data, data, len);
68 if (ret == 2) 56 if (ret == len)
69 return 0; 57 return 0;
70 if (ret < 0) 58 if (ret < 0)
71 return ret; 59 return ret;
@@ -73,50 +61,19 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
73 return -EIO; 61 return -EIO;
74} 62}
75 63
76#if defined(CONFIG_SPI_MASTER) 64static unsigned int do_hw_read(struct snd_soc_codec *codec, unsigned int reg)
77static int snd_soc_4_12_spi_write(void *control_data, const char *data,
78 int len)
79{
80 struct spi_device *spi = control_data;
81 struct spi_transfer t;
82 struct spi_message m;
83 u8 msg[2];
84
85 if (len <= 0)
86 return 0;
87
88 msg[0] = data[1];
89 msg[1] = data[0];
90
91 spi_message_init(&m);
92 memset(&t, 0, sizeof t);
93
94 t.tx_buf = &msg[0];
95 t.len = len;
96
97 spi_message_add_tail(&t, &m);
98 spi_sync(spi, &m);
99
100 return len;
101}
102#else
103#define snd_soc_4_12_spi_write NULL
104#endif
105
106static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
107 unsigned int reg)
108{ 65{
109 int ret; 66 int ret;
110 unsigned int val; 67 unsigned int val;
111 68
112 if (reg >= codec->driver->reg_cache_size || 69 if (reg >= codec->driver->reg_cache_size ||
113 snd_soc_codec_volatile_register(codec, reg) || 70 snd_soc_codec_volatile_register(codec, reg) ||
114 codec->cache_bypass) { 71 codec->cache_bypass) {
115 if (codec->cache_only) 72 if (codec->cache_only)
116 return -1; 73 return -1;
117 74
118 BUG_ON(!codec->hw_read); 75 BUG_ON(!codec->hw_read);
119 return codec->hw_read(codec, reg); 76 return codec->hw_read(codec, reg);
120 } 77 }
121 78
122 ret = snd_soc_cache_read(codec, reg, &val); 79 ret = snd_soc_cache_read(codec, reg, &val);
@@ -125,259 +82,117 @@ static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
125 return val; 82 return val;
126} 83}
127 84
128static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, 85static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
129 unsigned int value) 86 unsigned int reg)
130{ 87{
131 u8 data[2]; 88 return do_hw_read(codec, reg);
132 int ret;
133
134 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
135 data[1] = value & 0x00ff;
136
137 if (!snd_soc_codec_volatile_register(codec, reg) &&
138 reg < codec->driver->reg_cache_size &&
139 !codec->cache_bypass) {
140 ret = snd_soc_cache_write(codec, reg, value);
141 if (ret < 0)
142 return -1;
143 }
144
145 if (codec->cache_only) {
146 codec->cache_sync = 1;
147 return 0;
148 }
149
150 ret = codec->hw_write(codec->control_data, data, 2);
151 if (ret == 2)
152 return 0;
153 if (ret < 0)
154 return ret;
155 else
156 return -EIO;
157} 89}
158 90
159#if defined(CONFIG_SPI_MASTER) 91static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
160static int snd_soc_7_9_spi_write(void *control_data, const char *data, 92 unsigned int value)
161 int len)
162{ 93{
163 struct spi_device *spi = control_data; 94 u16 data;
164 struct spi_transfer t;
165 struct spi_message m;
166 u8 msg[2];
167 95
168 if (len <= 0) 96 data = cpu_to_be16((reg << 12) | (value & 0xffffff));
169 return 0;
170 97
171 msg[0] = data[0]; 98 return do_hw_write(codec, reg, value, &data, 2);
172 msg[1] = data[1]; 99}
173 100
174 spi_message_init(&m); 101static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
175 memset(&t, 0, sizeof t); 102 unsigned int reg)
103{
104 return do_hw_read(codec, reg);
105}
176 106
177 t.tx_buf = &msg[0]; 107static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
178 t.len = len; 108 unsigned int value)
109{
110 u8 data[2];
179 111
180 spi_message_add_tail(&t, &m); 112 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
181 spi_sync(spi, &m); 113 data[1] = value & 0x00ff;
182 114
183 return len; 115 return do_hw_write(codec, reg, value, data, 2);
184} 116}
185#else
186#define snd_soc_7_9_spi_write NULL
187#endif
188 117
189static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, 118static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
190 unsigned int value) 119 unsigned int value)
191{ 120{
192 u8 data[2]; 121 u8 data[2];
193 int ret;
194 122
195 reg &= 0xff; 123 reg &= 0xff;
196 data[0] = reg; 124 data[0] = reg;
197 data[1] = value & 0xff; 125 data[1] = value & 0xff;
198 126
199 if (!snd_soc_codec_volatile_register(codec, reg) && 127 return do_hw_write(codec, reg, value, data, 2);
200 reg < codec->driver->reg_cache_size &&
201 !codec->cache_bypass) {
202 ret = snd_soc_cache_write(codec, reg, value);
203 if (ret < 0)
204 return -1;
205 }
206
207 if (codec->cache_only) {
208 codec->cache_sync = 1;
209 return 0;
210 }
211
212 if (codec->hw_write(codec->control_data, data, 2) == 2)
213 return 0;
214 else
215 return -EIO;
216} 128}
217 129
218static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, 130static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
219 unsigned int reg) 131 unsigned int reg)
220{ 132{
221 int ret; 133 return do_hw_read(codec, reg);
222 unsigned int val;
223
224 reg &= 0xff;
225 if (reg >= codec->driver->reg_cache_size ||
226 snd_soc_codec_volatile_register(codec, reg) ||
227 codec->cache_bypass) {
228 if (codec->cache_only)
229 return -1;
230
231 BUG_ON(!codec->hw_read);
232 return codec->hw_read(codec, reg);
233 }
234
235 ret = snd_soc_cache_read(codec, reg, &val);
236 if (ret < 0)
237 return -1;
238 return val;
239}
240
241#if defined(CONFIG_SPI_MASTER)
242static int snd_soc_8_8_spi_write(void *control_data, const char *data,
243 int len)
244{
245 struct spi_device *spi = control_data;
246 struct spi_transfer t;
247 struct spi_message m;
248 u8 msg[2];
249
250 if (len <= 0)
251 return 0;
252
253 msg[0] = data[0];
254 msg[1] = data[1];
255
256 spi_message_init(&m);
257 memset(&t, 0, sizeof t);
258
259 t.tx_buf = &msg[0];
260 t.len = len;
261
262 spi_message_add_tail(&t, &m);
263 spi_sync(spi, &m);
264
265 return len;
266} 134}
267#else
268#define snd_soc_8_8_spi_write NULL
269#endif
270 135
271static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, 136static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
272 unsigned int value) 137 unsigned int value)
273{ 138{
274 u8 data[3]; 139 u8 data[3];
275 int ret;
276 140
277 data[0] = reg; 141 data[0] = reg;
278 data[1] = (value >> 8) & 0xff; 142 data[1] = (value >> 8) & 0xff;
279 data[2] = value & 0xff; 143 data[2] = value & 0xff;
280 144
281 if (!snd_soc_codec_volatile_register(codec, reg) && 145 return do_hw_write(codec, reg, value, data, 3);
282 reg < codec->driver->reg_cache_size &&
283 !codec->cache_bypass) {
284 ret = snd_soc_cache_write(codec, reg, value);
285 if (ret < 0)
286 return -1;
287 }
288
289 if (codec->cache_only) {
290 codec->cache_sync = 1;
291 return 0;
292 }
293
294 if (codec->hw_write(codec->control_data, data, 3) == 3)
295 return 0;
296 else
297 return -EIO;
298} 146}
299 147
300static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, 148static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
301 unsigned int reg) 149 unsigned int reg)
302{ 150{
303 int ret; 151 return do_hw_read(codec, reg);
304 unsigned int val;
305
306 if (reg >= codec->driver->reg_cache_size ||
307 snd_soc_codec_volatile_register(codec, reg) ||
308 codec->cache_bypass) {
309 if (codec->cache_only)
310 return -1;
311
312 BUG_ON(!codec->hw_read);
313 return codec->hw_read(codec, reg);
314 }
315
316 ret = snd_soc_cache_read(codec, reg, &val);
317 if (ret < 0)
318 return -1;
319 return val;
320}
321
322#if defined(CONFIG_SPI_MASTER)
323static int snd_soc_8_16_spi_write(void *control_data, const char *data,
324 int len)
325{
326 struct spi_device *spi = control_data;
327 struct spi_transfer t;
328 struct spi_message m;
329 u8 msg[3];
330
331 if (len <= 0)
332 return 0;
333
334 msg[0] = data[0];
335 msg[1] = data[1];
336 msg[2] = data[2];
337
338 spi_message_init(&m);
339 memset(&t, 0, sizeof t);
340
341 t.tx_buf = &msg[0];
342 t.len = len;
343
344 spi_message_add_tail(&t, &m);
345 spi_sync(spi, &m);
346
347 return len;
348} 152}
349#else
350#define snd_soc_8_16_spi_write NULL
351#endif
352 153
353#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 154#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
354static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, 155static unsigned int do_i2c_read(struct snd_soc_codec *codec,
355 unsigned int r) 156 void *reg, int reglen,
157 void *data, int datalen)
356{ 158{
357 struct i2c_msg xfer[2]; 159 struct i2c_msg xfer[2];
358 u8 reg = r;
359 u8 data;
360 int ret; 160 int ret;
361 struct i2c_client *client = codec->control_data; 161 struct i2c_client *client = codec->control_data;
362 162
363 /* Write register */ 163 /* Write register */
364 xfer[0].addr = client->addr; 164 xfer[0].addr = client->addr;
365 xfer[0].flags = 0; 165 xfer[0].flags = 0;
366 xfer[0].len = 1; 166 xfer[0].len = reglen;
367 xfer[0].buf = &reg; 167 xfer[0].buf = reg;
368 168
369 /* Read data */ 169 /* Read data */
370 xfer[1].addr = client->addr; 170 xfer[1].addr = client->addr;
371 xfer[1].flags = I2C_M_RD; 171 xfer[1].flags = I2C_M_RD;
372 xfer[1].len = 1; 172 xfer[1].len = datalen;
373 xfer[1].buf = &data; 173 xfer[1].buf = data;
374 174
375 ret = i2c_transfer(client->adapter, xfer, 2); 175 ret = i2c_transfer(client->adapter, xfer, 2);
376 if (ret != 2) { 176 if (ret == 2)
377 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
378 return 0; 177 return 0;
379 } 178 else if (ret < 0)
179 return ret;
180 else
181 return -EIO;
182}
183#endif
380 184
185#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
186static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
187 unsigned int r)
188{
189 u8 reg = r;
190 u8 data;
191 int ret;
192
193 ret = do_i2c_read(codec, &reg, 1, &data, 1);
194 if (ret < 0)
195 return 0;
381 return data; 196 return data;
382} 197}
383#else 198#else
@@ -388,30 +203,13 @@ static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
388static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, 203static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
389 unsigned int r) 204 unsigned int r)
390{ 205{
391 struct i2c_msg xfer[2];
392 u8 reg = r; 206 u8 reg = r;
393 u16 data; 207 u16 data;
394 int ret; 208 int ret;
395 struct i2c_client *client = codec->control_data;
396 209
397 /* Write register */ 210 ret = do_i2c_read(codec, &reg, 1, &data, 2);
398 xfer[0].addr = client->addr; 211 if (ret < 0)
399 xfer[0].flags = 0;
400 xfer[0].len = 1;
401 xfer[0].buf = &reg;
402
403 /* Read data */
404 xfer[1].addr = client->addr;
405 xfer[1].flags = I2C_M_RD;
406 xfer[1].len = 2;
407 xfer[1].buf = (u8 *)&data;
408
409 ret = i2c_transfer(client->adapter, xfer, 2);
410 if (ret != 2) {
411 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
412 return 0; 212 return 0;
413 }
414
415 return (data >> 8) | ((data & 0xff) << 8); 213 return (data >> 8) | ((data & 0xff) << 8);
416} 214}
417#else 215#else
@@ -422,30 +220,13 @@ static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
422static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, 220static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
423 unsigned int r) 221 unsigned int r)
424{ 222{
425 struct i2c_msg xfer[2];
426 u16 reg = r; 223 u16 reg = r;
427 u8 data; 224 u8 data;
428 int ret; 225 int ret;
429 struct i2c_client *client = codec->control_data;
430
431 /* Write register */
432 xfer[0].addr = client->addr;
433 xfer[0].flags = 0;
434 xfer[0].len = 2;
435 xfer[0].buf = (u8 *)&reg;
436
437 /* Read data */
438 xfer[1].addr = client->addr;
439 xfer[1].flags = I2C_M_RD;
440 xfer[1].len = 1;
441 xfer[1].buf = &data;
442 226
443 ret = i2c_transfer(client->adapter, xfer, 2); 227 ret = do_i2c_read(codec, &reg, 2, &data, 1);
444 if (ret != 2) { 228 if (ret < 0)
445 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
446 return 0; 229 return 0;
447 }
448
449 return data; 230 return data;
450} 231}
451#else 232#else
@@ -453,120 +234,34 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
453#endif 234#endif
454 235
455static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, 236static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
456 unsigned int reg) 237 unsigned int reg)
457{ 238{
458 int ret; 239 return do_hw_read(codec, reg);
459 unsigned int val;
460
461 reg &= 0xff;
462 if (reg >= codec->driver->reg_cache_size ||
463 snd_soc_codec_volatile_register(codec, reg) ||
464 codec->cache_bypass) {
465 if (codec->cache_only)
466 return -1;
467
468 BUG_ON(!codec->hw_read);
469 return codec->hw_read(codec, reg);
470 }
471
472 ret = snd_soc_cache_read(codec, reg, &val);
473 if (ret < 0)
474 return -1;
475 return val;
476} 240}
477 241
478static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, 242static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
479 unsigned int value) 243 unsigned int value)
480{ 244{
481 u8 data[3]; 245 u8 data[3];
482 int ret;
483 246
484 data[0] = (reg >> 8) & 0xff; 247 data[0] = (reg >> 8) & 0xff;
485 data[1] = reg & 0xff; 248 data[1] = reg & 0xff;
486 data[2] = value; 249 data[2] = value;
487 250
488 reg &= 0xff; 251 return do_hw_write(codec, reg, value, data, 3);
489 if (!snd_soc_codec_volatile_register(codec, reg) &&
490 reg < codec->driver->reg_cache_size &&
491 !codec->cache_bypass) {
492 ret = snd_soc_cache_write(codec, reg, value);
493 if (ret < 0)
494 return -1;
495 }
496
497 if (codec->cache_only) {
498 codec->cache_sync = 1;
499 return 0;
500 }
501
502 ret = codec->hw_write(codec->control_data, data, 3);
503 if (ret == 3)
504 return 0;
505 if (ret < 0)
506 return ret;
507 else
508 return -EIO;
509}
510
511#if defined(CONFIG_SPI_MASTER)
512static int snd_soc_16_8_spi_write(void *control_data, const char *data,
513 int len)
514{
515 struct spi_device *spi = control_data;
516 struct spi_transfer t;
517 struct spi_message m;
518 u8 msg[3];
519
520 if (len <= 0)
521 return 0;
522
523 msg[0] = data[0];
524 msg[1] = data[1];
525 msg[2] = data[2];
526
527 spi_message_init(&m);
528 memset(&t, 0, sizeof t);
529
530 t.tx_buf = &msg[0];
531 t.len = len;
532
533 spi_message_add_tail(&t, &m);
534 spi_sync(spi, &m);
535
536 return len;
537} 252}
538#else
539#define snd_soc_16_8_spi_write NULL
540#endif
541 253
542#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 254#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
543static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, 255static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
544 unsigned int r) 256 unsigned int r)
545{ 257{
546 struct i2c_msg xfer[2];
547 u16 reg = cpu_to_be16(r); 258 u16 reg = cpu_to_be16(r);
548 u16 data; 259 u16 data;
549 int ret; 260 int ret;
550 struct i2c_client *client = codec->control_data;
551
552 /* Write register */
553 xfer[0].addr = client->addr;
554 xfer[0].flags = 0;
555 xfer[0].len = 2;
556 xfer[0].buf = (u8 *)&reg;
557 261
558 /* Read data */ 262 ret = do_i2c_read(codec, &reg, 2, &data, 2);
559 xfer[1].addr = client->addr; 263 if (ret < 0)
560 xfer[1].flags = I2C_M_RD;
561 xfer[1].len = 2;
562 xfer[1].buf = (u8 *)&data;
563
564 ret = i2c_transfer(client->adapter, xfer, 2);
565 if (ret != 2) {
566 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
567 return 0; 264 return 0;
568 }
569
570 return be16_to_cpu(data); 265 return be16_to_cpu(data);
571} 266}
572#else 267#else
@@ -576,52 +271,59 @@ static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
576static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec, 271static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
577 unsigned int reg) 272 unsigned int reg)
578{ 273{
579 int ret; 274 return do_hw_read(codec, reg);
580 unsigned int val;
581
582 if (reg >= codec->driver->reg_cache_size ||
583 snd_soc_codec_volatile_register(codec, reg) ||
584 codec->cache_bypass) {
585 if (codec->cache_only)
586 return -1;
587
588 BUG_ON(!codec->hw_read);
589 return codec->hw_read(codec, reg);
590 }
591
592 ret = snd_soc_cache_read(codec, reg, &val);
593 if (ret < 0)
594 return -1;
595
596 return val;
597} 275}
598 276
599static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, 277static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
600 unsigned int value) 278 unsigned int value)
601{ 279{
602 u8 data[4]; 280 u8 data[4];
603 int ret;
604 281
605 data[0] = (reg >> 8) & 0xff; 282 data[0] = (reg >> 8) & 0xff;
606 data[1] = reg & 0xff; 283 data[1] = reg & 0xff;
607 data[2] = (value >> 8) & 0xff; 284 data[2] = (value >> 8) & 0xff;
608 data[3] = value & 0xff; 285 data[3] = value & 0xff;
609 286
610 if (!snd_soc_codec_volatile_register(codec, reg) && 287 return do_hw_write(codec, reg, value, data, 4);
611 reg < codec->driver->reg_cache_size && 288}
612 !codec->cache_bypass) {
613 ret = snd_soc_cache_write(codec, reg, value);
614 if (ret < 0)
615 return -1;
616 }
617 289
618 if (codec->cache_only) { 290/* Primitive bulk write support for soc-cache. The data pointed to by
619 codec->cache_sync = 1; 291 * `data' needs to already be in the form the hardware expects
620 return 0; 292 * including any leading register specific data. Any data written
293 * through this function will not go through the cache as it only
294 * handles writing to volatile or out of bounds registers.
295 */
296static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int reg,
297 const void *data, size_t len)
298{
299 int ret;
300
301 /* To ensure that we don't get out of sync with the cache, check
302 * whether the base register is volatile or if we've directly asked
303 * to bypass the cache. Out of bounds registers are considered
304 * volatile.
305 */
306 if (!codec->cache_bypass
307 && !snd_soc_codec_volatile_register(codec, reg)
308 && reg < codec->driver->reg_cache_size)
309 return -EINVAL;
310
311 switch (codec->control_type) {
312#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
313 case SND_SOC_I2C:
314 ret = i2c_master_send(codec->control_data, data, len);
315 break;
316#endif
317#if defined(CONFIG_SPI_MASTER)
318 case SND_SOC_SPI:
319 ret = spi_write(codec->control_data, data, len);
320 break;
321#endif
322 default:
323 BUG();
621 } 324 }
622 325
623 ret = codec->hw_write(codec->control_data, data, 4); 326 if (ret == len)
624 if (ret == 4)
625 return 0; 327 return 0;
626 if (ret < 0) 328 if (ret < 0)
627 return ret; 329 return ret;
@@ -629,79 +331,40 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
629 return -EIO; 331 return -EIO;
630} 332}
631 333
632#if defined(CONFIG_SPI_MASTER)
633static int snd_soc_16_16_spi_write(void *control_data, const char *data,
634 int len)
635{
636 struct spi_device *spi = control_data;
637 struct spi_transfer t;
638 struct spi_message m;
639 u8 msg[4];
640
641 if (len <= 0)
642 return 0;
643
644 msg[0] = data[0];
645 msg[1] = data[1];
646 msg[2] = data[2];
647 msg[3] = data[3];
648
649 spi_message_init(&m);
650 memset(&t, 0, sizeof t);
651
652 t.tx_buf = &msg[0];
653 t.len = len;
654
655 spi_message_add_tail(&t, &m);
656 spi_sync(spi, &m);
657
658 return len;
659}
660#else
661#define snd_soc_16_16_spi_write NULL
662#endif
663
664static struct { 334static struct {
665 int addr_bits; 335 int addr_bits;
666 int data_bits; 336 int data_bits;
667 int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int); 337 int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
668 int (*spi_write)(void *, const char *, int);
669 unsigned int (*read)(struct snd_soc_codec *, unsigned int); 338 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
670 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); 339 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
671} io_types[] = { 340} io_types[] = {
672 { 341 {
673 .addr_bits = 4, .data_bits = 12, 342 .addr_bits = 4, .data_bits = 12,
674 .write = snd_soc_4_12_write, .read = snd_soc_4_12_read, 343 .write = snd_soc_4_12_write, .read = snd_soc_4_12_read,
675 .spi_write = snd_soc_4_12_spi_write,
676 }, 344 },
677 { 345 {
678 .addr_bits = 7, .data_bits = 9, 346 .addr_bits = 7, .data_bits = 9,
679 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read, 347 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
680 .spi_write = snd_soc_7_9_spi_write,
681 }, 348 },
682 { 349 {
683 .addr_bits = 8, .data_bits = 8, 350 .addr_bits = 8, .data_bits = 8,
684 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read, 351 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
685 .i2c_read = snd_soc_8_8_read_i2c, 352 .i2c_read = snd_soc_8_8_read_i2c,
686 .spi_write = snd_soc_8_8_spi_write,
687 }, 353 },
688 { 354 {
689 .addr_bits = 8, .data_bits = 16, 355 .addr_bits = 8, .data_bits = 16,
690 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read, 356 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
691 .i2c_read = snd_soc_8_16_read_i2c, 357 .i2c_read = snd_soc_8_16_read_i2c,
692 .spi_write = snd_soc_8_16_spi_write,
693 }, 358 },
694 { 359 {
695 .addr_bits = 16, .data_bits = 8, 360 .addr_bits = 16, .data_bits = 8,
696 .write = snd_soc_16_8_write, .read = snd_soc_16_8_read, 361 .write = snd_soc_16_8_write, .read = snd_soc_16_8_read,
697 .i2c_read = snd_soc_16_8_read_i2c, 362 .i2c_read = snd_soc_16_8_read_i2c,
698 .spi_write = snd_soc_16_8_spi_write,
699 }, 363 },
700 { 364 {
701 .addr_bits = 16, .data_bits = 16, 365 .addr_bits = 16, .data_bits = 16,
702 .write = snd_soc_16_16_write, .read = snd_soc_16_16_read, 366 .write = snd_soc_16_16_write, .read = snd_soc_16_16_read,
703 .i2c_read = snd_soc_16_16_read_i2c, 367 .i2c_read = snd_soc_16_16_read_i2c,
704 .spi_write = snd_soc_16_16_spi_write,
705 }, 368 },
706}; 369};
707 370
@@ -709,7 +372,6 @@ static struct {
709 * snd_soc_codec_set_cache_io: Set up standard I/O functions. 372 * snd_soc_codec_set_cache_io: Set up standard I/O functions.
710 * 373 *
711 * @codec: CODEC to configure. 374 * @codec: CODEC to configure.
712 * @type: Type of cache.
713 * @addr_bits: Number of bits of register address data. 375 * @addr_bits: Number of bits of register address data.
714 * @data_bits: Number of bits of data per register. 376 * @data_bits: Number of bits of data per register.
715 * @control: Control bus used. 377 * @control: Control bus used.
@@ -744,6 +406,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
744 406
745 codec->write = io_types[i].write; 407 codec->write = io_types[i].write;
746 codec->read = io_types[i].read; 408 codec->read = io_types[i].read;
409 codec->bulk_write_raw = snd_soc_hw_bulk_write_raw;
747 410
748 switch (control) { 411 switch (control) {
749 case SND_SOC_CUSTOM: 412 case SND_SOC_CUSTOM:
@@ -762,8 +425,9 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
762 break; 425 break;
763 426
764 case SND_SOC_SPI: 427 case SND_SOC_SPI:
765 if (io_types[i].spi_write) 428#ifdef CONFIG_SPI_MASTER
766 codec->hw_write = io_types[i].spi_write; 429 codec->hw_write = do_spi_write;
430#endif
767 431
768 codec->control_data = container_of(codec->dev, 432 codec->control_data = container_of(codec->dev,
769 struct spi_device, 433 struct spi_device,
@@ -889,6 +553,8 @@ static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
889 rbnode = rb_entry(node, struct snd_soc_rbtree_node, node); 553 rbnode = rb_entry(node, struct snd_soc_rbtree_node, node);
890 if (rbnode->value == rbnode->defval) 554 if (rbnode->value == rbnode->defval)
891 continue; 555 continue;
556 WARN_ON(codec->writable_register &&
557 codec->writable_register(codec, rbnode->reg));
892 ret = snd_soc_cache_read(codec, rbnode->reg, &val); 558 ret = snd_soc_cache_read(codec, rbnode->reg, &val);
893 if (ret) 559 if (ret)
894 return ret; 560 return ret;
@@ -1149,6 +815,8 @@ static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
1149 815
1150 lzo_blocks = codec->reg_cache; 816 lzo_blocks = codec->reg_cache;
1151 for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { 817 for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
818 WARN_ON(codec->writable_register &&
819 codec->writable_register(codec, i));
1152 ret = snd_soc_cache_read(codec, i, &val); 820 ret = snd_soc_cache_read(codec, i, &val);
1153 if (ret) 821 if (ret)
1154 return ret; 822 return ret;
@@ -1407,6 +1075,8 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
1407 1075
1408 codec_drv = codec->driver; 1076 codec_drv = codec->driver;
1409 for (i = 0; i < codec_drv->reg_cache_size; ++i) { 1077 for (i = 0; i < codec_drv->reg_cache_size; ++i) {
1078 WARN_ON(codec->writable_register &&
1079 codec->writable_register(codec, i));
1410 ret = snd_soc_cache_read(codec, i, &val); 1080 ret = snd_soc_cache_read(codec, i, &val);
1411 if (ret) 1081 if (ret)
1412 return ret; 1082 return ret;
@@ -1523,7 +1193,7 @@ int snd_soc_cache_init(struct snd_soc_codec *codec)
1523 codec->cache_ops->name, codec->name); 1193 codec->cache_ops->name, codec->name);
1524 return codec->cache_ops->init(codec); 1194 return codec->cache_ops->init(codec);
1525 } 1195 }
1526 return -EINVAL; 1196 return -ENOSYS;
1527} 1197}
1528 1198
1529/* 1199/*
@@ -1538,7 +1208,7 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec)
1538 codec->cache_ops->name, codec->name); 1208 codec->cache_ops->name, codec->name);
1539 return codec->cache_ops->exit(codec); 1209 return codec->cache_ops->exit(codec);
1540 } 1210 }
1541 return -EINVAL; 1211 return -ENOSYS;
1542} 1212}
1543 1213
1544/** 1214/**
@@ -1562,7 +1232,7 @@ int snd_soc_cache_read(struct snd_soc_codec *codec,
1562 } 1232 }
1563 1233
1564 mutex_unlock(&codec->cache_rw_mutex); 1234 mutex_unlock(&codec->cache_rw_mutex);
1565 return -EINVAL; 1235 return -ENOSYS;
1566} 1236}
1567EXPORT_SYMBOL_GPL(snd_soc_cache_read); 1237EXPORT_SYMBOL_GPL(snd_soc_cache_read);
1568 1238
@@ -1587,7 +1257,7 @@ int snd_soc_cache_write(struct snd_soc_codec *codec,
1587 } 1257 }
1588 1258
1589 mutex_unlock(&codec->cache_rw_mutex); 1259 mutex_unlock(&codec->cache_rw_mutex);
1590 return -EINVAL; 1260 return -ENOSYS;
1591} 1261}
1592EXPORT_SYMBOL_GPL(snd_soc_cache_write); 1262EXPORT_SYMBOL_GPL(snd_soc_cache_write);
1593 1263
@@ -1610,7 +1280,7 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec)
1610 } 1280 }
1611 1281
1612 if (!codec->cache_ops || !codec->cache_ops->sync) 1282 if (!codec->cache_ops || !codec->cache_ops->sync)
1613 return -EINVAL; 1283 return -ENOSYS;
1614 1284
1615 if (codec->cache_ops->name) 1285 if (codec->cache_ops->name)
1616 name = codec->cache_ops->name; 1286 name = codec->cache_ops->name;
@@ -1677,3 +1347,17 @@ int snd_soc_default_readable_register(struct snd_soc_codec *codec,
1677 return codec->driver->reg_access_default[index].read; 1347 return codec->driver->reg_access_default[index].read;
1678} 1348}
1679EXPORT_SYMBOL_GPL(snd_soc_default_readable_register); 1349EXPORT_SYMBOL_GPL(snd_soc_default_readable_register);
1350
1351int snd_soc_default_writable_register(struct snd_soc_codec *codec,
1352 unsigned int reg)
1353{
1354 int index;
1355
1356 if (reg >= codec->driver->reg_cache_size)
1357 return 1;
1358 index = snd_soc_get_reg_access_index(codec, reg);
1359 if (index < 0)
1360 return 0;
1361 return codec->driver->reg_access_default[index].write;
1362}
1363EXPORT_SYMBOL_GPL(snd_soc_default_writable_register);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d8562ce4de7a..bb7cd5812945 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -242,7 +242,7 @@ static ssize_t codec_reg_write_file(struct file *file,
242 const char __user *user_buf, size_t count, loff_t *ppos) 242 const char __user *user_buf, size_t count, loff_t *ppos)
243{ 243{
244 char buf[32]; 244 char buf[32];
245 int buf_size; 245 size_t buf_size;
246 char *start = buf; 246 char *start = buf;
247 unsigned long reg, value; 247 unsigned long reg, value;
248 int step = 1; 248 int step = 1;
@@ -302,13 +302,7 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
302 printk(KERN_WARNING 302 printk(KERN_WARNING
303 "ASoC: Failed to create codec register debugfs file\n"); 303 "ASoC: Failed to create codec register debugfs file\n");
304 304
305 codec->dapm.debugfs_dapm = debugfs_create_dir("dapm", 305 snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root);
306 codec->debugfs_codec_root);
307 if (!codec->dapm.debugfs_dapm)
308 printk(KERN_WARNING
309 "Failed to create DAPM debugfs directory\n");
310
311 snd_soc_dapm_debugfs_init(&codec->dapm);
312} 306}
313 307
314static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) 308static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
@@ -555,7 +549,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
555 } 549 }
556 } 550 }
557 551
558 if (platform->driver->ops->open) { 552 if (platform->driver->ops && platform->driver->ops->open) {
559 ret = platform->driver->ops->open(substream); 553 ret = platform->driver->ops->open(substream);
560 if (ret < 0) { 554 if (ret < 0) {
561 printk(KERN_ERR "asoc: can't open platform %s\n", platform->name); 555 printk(KERN_ERR "asoc: can't open platform %s\n", platform->name);
@@ -685,7 +679,7 @@ machine_err:
685 codec_dai->driver->ops->shutdown(substream, codec_dai); 679 codec_dai->driver->ops->shutdown(substream, codec_dai);
686 680
687codec_dai_err: 681codec_dai_err:
688 if (platform->driver->ops->close) 682 if (platform->driver->ops && platform->driver->ops->close)
689 platform->driver->ops->close(substream); 683 platform->driver->ops->close(substream);
690 684
691platform_err: 685platform_err:
@@ -767,7 +761,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
767 if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown) 761 if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
768 rtd->dai_link->ops->shutdown(substream); 762 rtd->dai_link->ops->shutdown(substream);
769 763
770 if (platform->driver->ops->close) 764 if (platform->driver->ops && platform->driver->ops->close)
771 platform->driver->ops->close(substream); 765 platform->driver->ops->close(substream);
772 cpu_dai->runtime = NULL; 766 cpu_dai->runtime = NULL;
773 767
@@ -810,7 +804,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
810 } 804 }
811 } 805 }
812 806
813 if (platform->driver->ops->prepare) { 807 if (platform->driver->ops && platform->driver->ops->prepare) {
814 ret = platform->driver->ops->prepare(substream); 808 ret = platform->driver->ops->prepare(substream);
815 if (ret < 0) { 809 if (ret < 0) {
816 printk(KERN_ERR "asoc: platform prepare error\n"); 810 printk(KERN_ERR "asoc: platform prepare error\n");
@@ -899,7 +893,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
899 } 893 }
900 } 894 }
901 895
902 if (platform->driver->ops->hw_params) { 896 if (platform->driver->ops && platform->driver->ops->hw_params) {
903 ret = platform->driver->ops->hw_params(substream, params); 897 ret = platform->driver->ops->hw_params(substream, params);
904 if (ret < 0) { 898 if (ret < 0) {
905 printk(KERN_ERR "asoc: platform %s hw params failed\n", 899 printk(KERN_ERR "asoc: platform %s hw params failed\n",
@@ -952,7 +946,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
952 rtd->dai_link->ops->hw_free(substream); 946 rtd->dai_link->ops->hw_free(substream);
953 947
954 /* free any DMA resources */ 948 /* free any DMA resources */
955 if (platform->driver->ops->hw_free) 949 if (platform->driver->ops && platform->driver->ops->hw_free)
956 platform->driver->ops->hw_free(substream); 950 platform->driver->ops->hw_free(substream);
957 951
958 /* now free hw params for the DAIs */ 952 /* now free hw params for the DAIs */
@@ -980,7 +974,7 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
980 return ret; 974 return ret;
981 } 975 }
982 976
983 if (platform->driver->ops->trigger) { 977 if (platform->driver->ops && platform->driver->ops->trigger) {
984 ret = platform->driver->ops->trigger(substream, cmd); 978 ret = platform->driver->ops->trigger(substream, cmd);
985 if (ret < 0) 979 if (ret < 0)
986 return ret; 980 return ret;
@@ -1009,7 +1003,7 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
1009 snd_pcm_uframes_t offset = 0; 1003 snd_pcm_uframes_t offset = 0;
1010 snd_pcm_sframes_t delay = 0; 1004 snd_pcm_sframes_t delay = 0;
1011 1005
1012 if (platform->driver->ops->pointer) 1006 if (platform->driver->ops && platform->driver->ops->pointer)
1013 offset = platform->driver->ops->pointer(substream); 1007 offset = platform->driver->ops->pointer(substream);
1014 1008
1015 if (cpu_dai->driver->ops->delay) 1009 if (cpu_dai->driver->ops->delay)
@@ -1299,6 +1293,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
1299 struct snd_soc_codec *codec; 1293 struct snd_soc_codec *codec;
1300 struct snd_soc_platform *platform; 1294 struct snd_soc_platform *platform;
1301 struct snd_soc_dai *codec_dai, *cpu_dai; 1295 struct snd_soc_dai *codec_dai, *cpu_dai;
1296 const char *platform_name;
1302 1297
1303 if (rtd->complete) 1298 if (rtd->complete)
1304 return 1; 1299 return 1;
@@ -1351,13 +1346,18 @@ find_codec:
1351 dai_link->codec_name); 1346 dai_link->codec_name);
1352 1347
1353find_platform: 1348find_platform:
1354 /* do we already have the CODEC DAI for this link ? */ 1349 /* do we need a platform? */
1355 if (rtd->platform) { 1350 if (rtd->platform)
1356 goto out; 1351 goto out;
1357 } 1352
1358 /* no, then find CPU DAI from registered DAIs*/ 1353 /* if there's no platform we match on the empty platform */
1354 platform_name = dai_link->platform_name;
1355 if (!platform_name)
1356 platform_name = "snd-soc-dummy";
1357
1358 /* no, then find one from the set of registered platforms */
1359 list_for_each_entry(platform, &platform_list, list) { 1359 list_for_each_entry(platform, &platform_list, list) {
1360 if (!strcmp(platform->name, dai_link->platform_name)) { 1360 if (!strcmp(platform->name, platform_name)) {
1361 rtd->platform = platform; 1361 rtd->platform = platform;
1362 goto out; 1362 goto out;
1363 } 1363 }
@@ -1453,6 +1453,16 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
1453 } 1453 }
1454} 1454}
1455 1455
1456static void soc_remove_dai_links(struct snd_soc_card *card)
1457{
1458 int i;
1459
1460 for (i = 0; i < card->num_rtd; i++)
1461 soc_remove_dai_link(card, i);
1462
1463 card->num_rtd = 0;
1464}
1465
1456static void soc_set_name_prefix(struct snd_soc_card *card, 1466static void soc_set_name_prefix(struct snd_soc_card *card,
1457 struct snd_soc_codec *codec) 1467 struct snd_soc_codec *codec)
1458{ 1468{
@@ -1483,6 +1493,12 @@ static int soc_probe_codec(struct snd_soc_card *card,
1483 if (!try_module_get(codec->dev->driver->owner)) 1493 if (!try_module_get(codec->dev->driver->owner))
1484 return -ENODEV; 1494 return -ENODEV;
1485 1495
1496 soc_init_codec_debugfs(codec);
1497
1498 if (driver->dapm_widgets)
1499 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
1500 driver->num_dapm_widgets);
1501
1486 if (driver->probe) { 1502 if (driver->probe) {
1487 ret = driver->probe(codec); 1503 ret = driver->probe(codec);
1488 if (ret < 0) { 1504 if (ret < 0) {
@@ -1493,15 +1509,13 @@ static int soc_probe_codec(struct snd_soc_card *card,
1493 } 1509 }
1494 } 1510 }
1495 1511
1496 if (driver->dapm_widgets) 1512 if (driver->controls)
1497 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, 1513 snd_soc_add_controls(codec, driver->controls,
1498 driver->num_dapm_widgets); 1514 driver->num_controls);
1499 if (driver->dapm_routes) 1515 if (driver->dapm_routes)
1500 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes, 1516 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes,
1501 driver->num_dapm_routes); 1517 driver->num_dapm_routes);
1502 1518
1503 soc_init_codec_debugfs(codec);
1504
1505 /* mark codec as probed and add to card codec list */ 1519 /* mark codec as probed and add to card codec list */
1506 codec->probed = 1; 1520 codec->probed = 1;
1507 list_add(&codec->card_list, &card->codec_dev_list); 1521 list_add(&codec->card_list, &card->codec_dev_list);
@@ -1510,6 +1524,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
1510 return 0; 1524 return 0;
1511 1525
1512err_probe: 1526err_probe:
1527 soc_cleanup_codec_debugfs(codec);
1513 module_put(codec->dev->driver->owner); 1528 module_put(codec->dev->driver->owner);
1514 1529
1515 return ret; 1530 return ret;
@@ -1860,11 +1875,19 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1860 card->dapm.card = card; 1875 card->dapm.card = card;
1861 list_add(&card->dapm.list, &card->dapm_list); 1876 list_add(&card->dapm.list, &card->dapm_list);
1862 1877
1878#ifdef CONFIG_DEBUG_FS
1879 snd_soc_dapm_debugfs_init(&card->dapm, card->debugfs_card_root);
1880#endif
1881
1863#ifdef CONFIG_PM_SLEEP 1882#ifdef CONFIG_PM_SLEEP
1864 /* deferred resume work */ 1883 /* deferred resume work */
1865 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); 1884 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
1866#endif 1885#endif
1867 1886
1887 if (card->dapm_widgets)
1888 snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets,
1889 card->num_dapm_widgets);
1890
1868 /* initialise the sound card only once */ 1891 /* initialise the sound card only once */
1869 if (card->probe) { 1892 if (card->probe) {
1870 ret = card->probe(card); 1893 ret = card->probe(card);
@@ -1890,27 +1913,24 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1890 } 1913 }
1891 } 1914 }
1892 1915
1893 if (card->dapm_widgets) 1916 /* We should have a non-codec control add function but we don't */
1894 snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets, 1917 if (card->controls)
1895 card->num_dapm_widgets); 1918 snd_soc_add_controls(list_first_entry(&card->codec_dev_list,
1919 struct snd_soc_codec,
1920 card_list),
1921 card->controls,
1922 card->num_controls);
1923
1896 if (card->dapm_routes) 1924 if (card->dapm_routes)
1897 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, 1925 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
1898 card->num_dapm_routes); 1926 card->num_dapm_routes);
1899 1927
1900#ifdef CONFIG_DEBUG_FS
1901 card->dapm.debugfs_dapm = debugfs_create_dir("dapm",
1902 card->debugfs_card_root);
1903 if (!card->dapm.debugfs_dapm)
1904 printk(KERN_WARNING
1905 "Failed to create card DAPM debugfs directory\n");
1906
1907 snd_soc_dapm_debugfs_init(&card->dapm);
1908#endif
1909
1910 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), 1928 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
1911 "%s", card->name);
1912 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
1913 "%s", card->name); 1929 "%s", card->name);
1930 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
1931 "%s", card->long_name ? card->long_name : card->name);
1932 snprintf(card->snd_card->driver, sizeof(card->snd_card->driver),
1933 "%s", card->driver_name ? card->driver_name : card->name);
1914 1934
1915 if (card->late_probe) { 1935 if (card->late_probe) {
1916 ret = card->late_probe(card); 1936 ret = card->late_probe(card);
@@ -1949,8 +1969,7 @@ probe_aux_dev_err:
1949 soc_remove_aux_dev(card, i); 1969 soc_remove_aux_dev(card, i);
1950 1970
1951probe_dai_err: 1971probe_dai_err:
1952 for (i = 0; i < card->num_links; i++) 1972 soc_remove_dai_links(card);
1953 soc_remove_dai_link(card, i);
1954 1973
1955card_probe_error: 1974card_probe_error:
1956 if (card->remove) 1975 if (card->remove)
@@ -2012,8 +2031,7 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
2012 soc_remove_aux_dev(card, i); 2031 soc_remove_aux_dev(card, i);
2013 2032
2014 /* remove and free each DAI */ 2033 /* remove and free each DAI */
2015 for (i = 0; i < card->num_rtd; i++) 2034 soc_remove_dai_links(card);
2016 soc_remove_dai_link(card, i);
2017 2035
2018 soc_cleanup_card_debugfs(card); 2036 soc_cleanup_card_debugfs(card);
2019 2037
@@ -2021,6 +2039,8 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
2021 if (card->remove) 2039 if (card->remove)
2022 card->remove(card); 2040 card->remove(card);
2023 2041
2042 snd_soc_dapm_free(&card->dapm);
2043
2024 kfree(card->rtd); 2044 kfree(card->rtd);
2025 snd_card_free(card->snd_card); 2045 snd_card_free(card->snd_card);
2026 return 0; 2046 return 0;
@@ -2105,13 +2125,15 @@ static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2105 2125
2106 rtd->pcm = pcm; 2126 rtd->pcm = pcm;
2107 pcm->private_data = rtd; 2127 pcm->private_data = rtd;
2108 soc_pcm_ops.mmap = platform->driver->ops->mmap; 2128 if (platform->driver->ops) {
2109 soc_pcm_ops.pointer = platform->driver->ops->pointer; 2129 soc_pcm_ops.mmap = platform->driver->ops->mmap;
2110 soc_pcm_ops.ioctl = platform->driver->ops->ioctl; 2130 soc_pcm_ops.pointer = platform->driver->ops->pointer;
2111 soc_pcm_ops.copy = platform->driver->ops->copy; 2131 soc_pcm_ops.ioctl = platform->driver->ops->ioctl;
2112 soc_pcm_ops.silence = platform->driver->ops->silence; 2132 soc_pcm_ops.copy = platform->driver->ops->copy;
2113 soc_pcm_ops.ack = platform->driver->ops->ack; 2133 soc_pcm_ops.silence = platform->driver->ops->silence;
2114 soc_pcm_ops.page = platform->driver->ops->page; 2134 soc_pcm_ops.ack = platform->driver->ops->ack;
2135 soc_pcm_ops.page = platform->driver->ops->page;
2136 }
2115 2137
2116 if (playback) 2138 if (playback)
2117 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops); 2139 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops);
@@ -2119,10 +2141,13 @@ static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2119 if (capture) 2141 if (capture)
2120 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops); 2142 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops);
2121 2143
2122 ret = platform->driver->pcm_new(rtd->card->snd_card, codec_dai, pcm); 2144 if (platform->driver->pcm_new) {
2123 if (ret < 0) { 2145 ret = platform->driver->pcm_new(rtd->card->snd_card,
2124 printk(KERN_ERR "asoc: platform pcm constructor failed\n"); 2146 codec_dai, pcm);
2125 return ret; 2147 if (ret < 0) {
2148 pr_err("asoc: platform pcm constructor failed\n");
2149 return ret;
2150 }
2126 } 2151 }
2127 2152
2128 pcm->private_free = platform->driver->pcm_free; 2153 pcm->private_free = platform->driver->pcm_free;
@@ -2150,6 +2175,42 @@ int snd_soc_codec_volatile_register(struct snd_soc_codec *codec,
2150EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register); 2175EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register);
2151 2176
2152/** 2177/**
2178 * snd_soc_codec_readable_register: Report if a register is readable.
2179 *
2180 * @codec: CODEC to query.
2181 * @reg: Register to query.
2182 *
2183 * Boolean function indicating if a CODEC register is readable.
2184 */
2185int snd_soc_codec_readable_register(struct snd_soc_codec *codec,
2186 unsigned int reg)
2187{
2188 if (codec->readable_register)
2189 return codec->readable_register(codec, reg);
2190 else
2191 return 0;
2192}
2193EXPORT_SYMBOL_GPL(snd_soc_codec_readable_register);
2194
2195/**
2196 * snd_soc_codec_writable_register: Report if a register is writable.
2197 *
2198 * @codec: CODEC to query.
2199 * @reg: Register to query.
2200 *
2201 * Boolean function indicating if a CODEC register is writable.
2202 */
2203int snd_soc_codec_writable_register(struct snd_soc_codec *codec,
2204 unsigned int reg)
2205{
2206 if (codec->writable_register)
2207 return codec->writable_register(codec, reg);
2208 else
2209 return 0;
2210}
2211EXPORT_SYMBOL_GPL(snd_soc_codec_writable_register);
2212
2213/**
2153 * snd_soc_new_ac97_codec - initailise AC97 device 2214 * snd_soc_new_ac97_codec - initailise AC97 device
2154 * @codec: audio codec 2215 * @codec: audio codec
2155 * @ops: AC97 bus operations 2216 * @ops: AC97 bus operations
@@ -2231,6 +2292,13 @@ unsigned int snd_soc_write(struct snd_soc_codec *codec,
2231} 2292}
2232EXPORT_SYMBOL_GPL(snd_soc_write); 2293EXPORT_SYMBOL_GPL(snd_soc_write);
2233 2294
2295unsigned int snd_soc_bulk_write_raw(struct snd_soc_codec *codec,
2296 unsigned int reg, const void *data, size_t len)
2297{
2298 return codec->bulk_write_raw(codec, reg, data, len);
2299}
2300EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw);
2301
2234/** 2302/**
2235 * snd_soc_update_bits - update codec register bits 2303 * snd_soc_update_bits - update codec register bits
2236 * @codec: audio codec 2304 * @codec: audio codec
@@ -3291,6 +3359,8 @@ int snd_soc_register_card(struct snd_soc_card *card)
3291 if (!card->name || !card->dev) 3359 if (!card->name || !card->dev)
3292 return -EINVAL; 3360 return -EINVAL;
3293 3361
3362 dev_set_drvdata(card->dev, card);
3363
3294 snd_soc_initialize_card_lists(card); 3364 snd_soc_initialize_card_lists(card);
3295 3365
3296 soc_init_card_debugfs(card); 3366 soc_init_card_debugfs(card);
@@ -3412,7 +3482,7 @@ int snd_soc_register_dai(struct device *dev,
3412 3482
3413 dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); 3483 dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
3414 if (dai == NULL) 3484 if (dai == NULL)
3415 return -ENOMEM; 3485 return -ENOMEM;
3416 3486
3417 /* create DAI component name */ 3487 /* create DAI component name */
3418 dai->name = fmt_single_name(dev, &dai->id); 3488 dai->name = fmt_single_name(dev, &dai->id);
@@ -3551,7 +3621,7 @@ int snd_soc_register_platform(struct device *dev,
3551 3621
3552 platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL); 3622 platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL);
3553 if (platform == NULL) 3623 if (platform == NULL)
3554 return -ENOMEM; 3624 return -ENOMEM;
3555 3625
3556 /* create platform component name */ 3626 /* create platform component name */
3557 platform->name = fmt_single_name(dev, &platform->id); 3627 platform->name = fmt_single_name(dev, &platform->id);
@@ -3669,6 +3739,7 @@ int snd_soc_register_codec(struct device *dev,
3669 codec->read = codec_drv->read; 3739 codec->read = codec_drv->read;
3670 codec->volatile_register = codec_drv->volatile_register; 3740 codec->volatile_register = codec_drv->volatile_register;
3671 codec->readable_register = codec_drv->readable_register; 3741 codec->readable_register = codec_drv->readable_register;
3742 codec->writable_register = codec_drv->writable_register;
3672 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 3743 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
3673 codec->dapm.dev = dev; 3744 codec->dapm.dev = dev;
3674 codec->dapm.codec = codec; 3745 codec->dapm.codec = codec;
@@ -3703,6 +3774,8 @@ int snd_soc_register_codec(struct device *dev,
3703 codec->volatile_register = snd_soc_default_volatile_register; 3774 codec->volatile_register = snd_soc_default_volatile_register;
3704 if (!codec->readable_register) 3775 if (!codec->readable_register)
3705 codec->readable_register = snd_soc_default_readable_register; 3776 codec->readable_register = snd_soc_default_readable_register;
3777 if (!codec->writable_register)
3778 codec->writable_register = snd_soc_default_writable_register;
3706 } 3779 }
3707 3780
3708 for (i = 0; i < num_dai; i++) { 3781 for (i = 0; i < num_dai; i++) {
@@ -3791,12 +3864,16 @@ static int __init snd_soc_init(void)
3791 pr_warn("ASoC: Failed to create platform list debugfs file\n"); 3864 pr_warn("ASoC: Failed to create platform list debugfs file\n");
3792#endif 3865#endif
3793 3866
3867 snd_soc_util_init();
3868
3794 return platform_driver_register(&soc_driver); 3869 return platform_driver_register(&soc_driver);
3795} 3870}
3796module_init(snd_soc_init); 3871module_init(snd_soc_init);
3797 3872
3798static void __exit snd_soc_exit(void) 3873static void __exit snd_soc_exit(void)
3799{ 3874{
3875 snd_soc_util_exit();
3876
3800#ifdef CONFIG_DEBUG_FS 3877#ifdef CONFIG_DEBUG_FS
3801 debugfs_remove_recursive(snd_soc_debugfs_root); 3878 debugfs_remove_recursive(snd_soc_debugfs_root);
3802#endif 3879#endif
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 81c4052c127c..456617e63789 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -187,7 +187,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
187 case snd_soc_dapm_mixer_named_ctl: { 187 case snd_soc_dapm_mixer_named_ctl: {
188 int val; 188 int val;
189 struct soc_mixer_control *mc = (struct soc_mixer_control *) 189 struct soc_mixer_control *mc = (struct soc_mixer_control *)
190 w->kcontrols[i].private_value; 190 w->kcontrol_news[i].private_value;
191 unsigned int reg = mc->reg; 191 unsigned int reg = mc->reg;
192 unsigned int shift = mc->shift; 192 unsigned int shift = mc->shift;
193 int max = mc->max; 193 int max = mc->max;
@@ -204,7 +204,8 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
204 } 204 }
205 break; 205 break;
206 case snd_soc_dapm_mux: { 206 case snd_soc_dapm_mux: {
207 struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value; 207 struct soc_enum *e = (struct soc_enum *)
208 w->kcontrol_news[i].private_value;
208 int val, item, bitmask; 209 int val, item, bitmask;
209 210
210 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 211 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
@@ -220,7 +221,8 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
220 } 221 }
221 break; 222 break;
222 case snd_soc_dapm_virt_mux: { 223 case snd_soc_dapm_virt_mux: {
223 struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value; 224 struct soc_enum *e = (struct soc_enum *)
225 w->kcontrol_news[i].private_value;
224 226
225 p->connect = 0; 227 p->connect = 0;
226 /* since a virtual mux has no backing registers to 228 /* since a virtual mux has no backing registers to
@@ -235,7 +237,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
235 break; 237 break;
236 case snd_soc_dapm_value_mux: { 238 case snd_soc_dapm_value_mux: {
237 struct soc_enum *e = (struct soc_enum *) 239 struct soc_enum *e = (struct soc_enum *)
238 w->kcontrols[i].private_value; 240 w->kcontrol_news[i].private_value;
239 int val, item; 241 int val, item;
240 242
241 val = snd_soc_read(w->codec, e->reg); 243 val = snd_soc_read(w->codec, e->reg);
@@ -310,11 +312,11 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
310 312
311 /* search for mixer kcontrol */ 313 /* search for mixer kcontrol */
312 for (i = 0; i < dest->num_kcontrols; i++) { 314 for (i = 0; i < dest->num_kcontrols; i++) {
313 if (!strcmp(control_name, dest->kcontrols[i].name)) { 315 if (!strcmp(control_name, dest->kcontrol_news[i].name)) {
314 list_add(&path->list, &dapm->card->paths); 316 list_add(&path->list, &dapm->card->paths);
315 list_add(&path->list_sink, &dest->sources); 317 list_add(&path->list_sink, &dest->sources);
316 list_add(&path->list_source, &src->sinks); 318 list_add(&path->list_source, &src->sinks);
317 path->name = dest->kcontrols[i].name; 319 path->name = dest->kcontrol_news[i].name;
318 dapm_set_path_status(dest, path, i); 320 dapm_set_path_status(dest, path, i);
319 return 0; 321 return 0;
320 } 322 }
@@ -322,43 +324,26 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
322 return -ENODEV; 324 return -ENODEV;
323} 325}
324 326
325/* update dapm codec register bits */ 327static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
326static int dapm_update_bits(struct snd_soc_dapm_widget *widget) 328 const struct snd_kcontrol_new *kcontrol_new,
329 struct snd_kcontrol **kcontrol)
327{ 330{
328 int change, power; 331 struct snd_soc_dapm_widget *w;
329 unsigned int old, new; 332 int i;
330 struct snd_soc_codec *codec = widget->codec;
331 struct snd_soc_dapm_context *dapm = widget->dapm;
332 struct snd_soc_card *card = dapm->card;
333
334 /* check for valid widgets */
335 if (widget->reg < 0 || widget->id == snd_soc_dapm_input ||
336 widget->id == snd_soc_dapm_output ||
337 widget->id == snd_soc_dapm_hp ||
338 widget->id == snd_soc_dapm_mic ||
339 widget->id == snd_soc_dapm_line ||
340 widget->id == snd_soc_dapm_spk)
341 return 0;
342
343 power = widget->power;
344 if (widget->invert)
345 power = (power ? 0:1);
346 333
347 old = snd_soc_read(codec, widget->reg); 334 *kcontrol = NULL;
348 new = (old & ~(0x1 << widget->shift)) | (power << widget->shift);
349 335
350 change = old != new; 336 list_for_each_entry(w, &dapm->card->widgets, list) {
351 if (change) { 337 for (i = 0; i < w->num_kcontrols; i++) {
352 pop_dbg(dapm->dev, card->pop_time, 338 if (&w->kcontrol_news[i] == kcontrol_new) {
353 "pop test %s : %s in %d ms\n", 339 if (w->kcontrols)
354 widget->name, widget->power ? "on" : "off", 340 *kcontrol = w->kcontrols[i];
355 card->pop_time); 341 return 1;
356 pop_wait(card->pop_time); 342 }
357 snd_soc_write(codec, widget->reg, new); 343 }
358 } 344 }
359 dev_dbg(dapm->dev, "reg %x old %x new %x change %d\n", widget->reg, 345
360 old, new, change); 346 return 0;
361 return change;
362} 347}
363 348
364/* create new dapm mixer control */ 349/* create new dapm mixer control */
@@ -370,6 +355,8 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
370 struct snd_soc_dapm_path *path; 355 struct snd_soc_dapm_path *path;
371 struct snd_card *card = dapm->card->snd_card; 356 struct snd_card *card = dapm->card->snd_card;
372 const char *prefix; 357 const char *prefix;
358 struct snd_soc_dapm_widget_list *wlist;
359 size_t wlistsize;
373 360
374 if (dapm->codec) 361 if (dapm->codec)
375 prefix = dapm->codec->name_prefix; 362 prefix = dapm->codec->name_prefix;
@@ -388,23 +375,37 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
388 list_for_each_entry(path, &w->sources, list_sink) { 375 list_for_each_entry(path, &w->sources, list_sink) {
389 376
390 /* mixer/mux paths name must match control name */ 377 /* mixer/mux paths name must match control name */
391 if (path->name != (char*)w->kcontrols[i].name) 378 if (path->name != (char *)w->kcontrol_news[i].name)
392 continue; 379 continue;
393 380
381 wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
382 sizeof(struct snd_soc_dapm_widget *),
383 wlist = kzalloc(wlistsize, GFP_KERNEL);
384 if (wlist == NULL) {
385 dev_err(dapm->dev,
386 "asoc: can't allocate widget list for %s\n",
387 w->name);
388 return -ENOMEM;
389 }
390 wlist->num_widgets = 1;
391 wlist->widgets[0] = w;
392
394 /* add dapm control with long name. 393 /* add dapm control with long name.
395 * for dapm_mixer this is the concatenation of the 394 * for dapm_mixer this is the concatenation of the
396 * mixer and kcontrol name. 395 * mixer and kcontrol name.
397 * for dapm_mixer_named_ctl this is simply the 396 * for dapm_mixer_named_ctl this is simply the
398 * kcontrol name. 397 * kcontrol name.
399 */ 398 */
400 name_len = strlen(w->kcontrols[i].name) + 1; 399 name_len = strlen(w->kcontrol_news[i].name) + 1;
401 if (w->id != snd_soc_dapm_mixer_named_ctl) 400 if (w->id != snd_soc_dapm_mixer_named_ctl)
402 name_len += 1 + strlen(w->name); 401 name_len += 1 + strlen(w->name);
403 402
404 path->long_name = kmalloc(name_len, GFP_KERNEL); 403 path->long_name = kmalloc(name_len, GFP_KERNEL);
405 404
406 if (path->long_name == NULL) 405 if (path->long_name == NULL) {
406 kfree(wlist);
407 return -ENOMEM; 407 return -ENOMEM;
408 }
408 409
409 switch (w->id) { 410 switch (w->id) {
410 default: 411 default:
@@ -416,27 +417,30 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
416 */ 417 */
417 snprintf(path->long_name, name_len, "%s %s", 418 snprintf(path->long_name, name_len, "%s %s",
418 w->name + prefix_len, 419 w->name + prefix_len,
419 w->kcontrols[i].name); 420 w->kcontrol_news[i].name);
420 break; 421 break;
421 case snd_soc_dapm_mixer_named_ctl: 422 case snd_soc_dapm_mixer_named_ctl:
422 snprintf(path->long_name, name_len, "%s", 423 snprintf(path->long_name, name_len, "%s",
423 w->kcontrols[i].name); 424 w->kcontrol_news[i].name);
424 break; 425 break;
425 } 426 }
426 427
427 path->long_name[name_len - 1] = '\0'; 428 path->long_name[name_len - 1] = '\0';
428 429
429 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, 430 path->kcontrol = snd_soc_cnew(&w->kcontrol_news[i],
430 path->long_name, prefix); 431 wlist, path->long_name,
432 prefix);
431 ret = snd_ctl_add(card, path->kcontrol); 433 ret = snd_ctl_add(card, path->kcontrol);
432 if (ret < 0) { 434 if (ret < 0) {
433 dev_err(dapm->dev, 435 dev_err(dapm->dev,
434 "asoc: failed to add dapm kcontrol %s: %d\n", 436 "asoc: failed to add dapm kcontrol %s: %d\n",
435 path->long_name, ret); 437 path->long_name, ret);
438 kfree(wlist);
436 kfree(path->long_name); 439 kfree(path->long_name);
437 path->long_name = NULL; 440 path->long_name = NULL;
438 return ret; 441 return ret;
439 } 442 }
443 w->kcontrols[i] = path->kcontrol;
440 } 444 }
441 } 445 }
442 return ret; 446 return ret;
@@ -451,42 +455,80 @@ static int dapm_new_mux(struct snd_soc_dapm_context *dapm,
451 struct snd_card *card = dapm->card->snd_card; 455 struct snd_card *card = dapm->card->snd_card;
452 const char *prefix; 456 const char *prefix;
453 size_t prefix_len; 457 size_t prefix_len;
454 int ret = 0; 458 int ret;
455 459 struct snd_soc_dapm_widget_list *wlist;
456 if (!w->num_kcontrols) { 460 int shared, wlistentries;
457 dev_err(dapm->dev, "asoc: mux %s has no controls\n", w->name); 461 size_t wlistsize;
462 char *name;
463
464 if (w->num_kcontrols != 1) {
465 dev_err(dapm->dev,
466 "asoc: mux %s has incorrect number of controls\n",
467 w->name);
458 return -EINVAL; 468 return -EINVAL;
459 } 469 }
460 470
461 if (dapm->codec) 471 shared = dapm_is_shared_kcontrol(dapm, &w->kcontrol_news[0],
462 prefix = dapm->codec->name_prefix; 472 &kcontrol);
463 else 473 if (kcontrol) {
464 prefix = NULL; 474 wlist = kcontrol->private_data;
475 wlistentries = wlist->num_widgets + 1;
476 } else {
477 wlist = NULL;
478 wlistentries = 1;
479 }
480 wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
481 wlistentries * sizeof(struct snd_soc_dapm_widget *),
482 wlist = krealloc(wlist, wlistsize, GFP_KERNEL);
483 if (wlist == NULL) {
484 dev_err(dapm->dev,
485 "asoc: can't allocate widget list for %s\n", w->name);
486 return -ENOMEM;
487 }
488 wlist->num_widgets = wlistentries;
489 wlist->widgets[wlistentries - 1] = w;
465 490
466 if (prefix) 491 if (!kcontrol) {
467 prefix_len = strlen(prefix) + 1; 492 if (dapm->codec)
468 else 493 prefix = dapm->codec->name_prefix;
469 prefix_len = 0; 494 else
495 prefix = NULL;
496
497 if (shared) {
498 name = w->kcontrol_news[0].name;
499 prefix_len = 0;
500 } else {
501 name = w->name;
502 if (prefix)
503 prefix_len = strlen(prefix) + 1;
504 else
505 prefix_len = 0;
506 }
470 507
471 /* The control will get a prefix from the control creation 508 /*
472 * process but we're also using the same prefix for widgets so 509 * The control will get a prefix from the control creation
473 * cut the prefix off the front of the widget name. 510 * process but we're also using the same prefix for widgets so
474 */ 511 * cut the prefix off the front of the widget name.
475 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name + prefix_len, 512 */
476 prefix); 513 kcontrol = snd_soc_cnew(&w->kcontrol_news[0], wlist,
477 ret = snd_ctl_add(card, kcontrol); 514 name + prefix_len, prefix);
515 ret = snd_ctl_add(card, kcontrol);
516 if (ret < 0) {
517 dev_err(dapm->dev,
518 "asoc: failed to add kcontrol %s\n", w->name);
519 kfree(wlist);
520 return ret;
521 }
522 }
478 523
479 if (ret < 0) 524 kcontrol->private_data = wlist;
480 goto err; 525
526 w->kcontrols[0] = kcontrol;
481 527
482 list_for_each_entry(path, &w->sources, list_sink) 528 list_for_each_entry(path, &w->sources, list_sink)
483 path->kcontrol = kcontrol; 529 path->kcontrol = kcontrol;
484 530
485 return ret; 531 return 0;
486
487err:
488 dev_err(dapm->dev, "asoc: failed to add kcontrol %s\n", w->name);
489 return ret;
490} 532}
491 533
492/* create new dapm volume control */ 534/* create new dapm volume control */
@@ -644,57 +686,6 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
644} 686}
645EXPORT_SYMBOL_GPL(dapm_reg_event); 687EXPORT_SYMBOL_GPL(dapm_reg_event);
646 688
647/* Standard power change method, used to apply power changes to most
648 * widgets.
649 */
650static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w)
651{
652 int ret;
653
654 /* call any power change event handlers */
655 if (w->event)
656 dev_dbg(w->dapm->dev, "power %s event for %s flags %x\n",
657 w->power ? "on" : "off",
658 w->name, w->event_flags);
659
660 /* power up pre event */
661 if (w->power && w->event &&
662 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
663 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
664 if (ret < 0)
665 return ret;
666 }
667
668 /* power down pre event */
669 if (!w->power && w->event &&
670 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
671 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
672 if (ret < 0)
673 return ret;
674 }
675
676 dapm_update_bits(w);
677
678 /* power up post event */
679 if (w->power && w->event &&
680 (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
681 ret = w->event(w,
682 NULL, SND_SOC_DAPM_POST_PMU);
683 if (ret < 0)
684 return ret;
685 }
686
687 /* power down post event */
688 if (!w->power && w->event &&
689 (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
690 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
691 if (ret < 0)
692 return ret;
693 }
694
695 return 0;
696}
697
698/* Generic check to see if a widget should be powered. 689/* Generic check to see if a widget should be powered.
699 */ 690 */
700static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) 691static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
@@ -981,16 +972,6 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
981 NULL, SND_SOC_DAPM_POST_PMD); 972 NULL, SND_SOC_DAPM_POST_PMD);
982 break; 973 break;
983 974
984 case snd_soc_dapm_input:
985 case snd_soc_dapm_output:
986 case snd_soc_dapm_hp:
987 case snd_soc_dapm_mic:
988 case snd_soc_dapm_line:
989 case snd_soc_dapm_spk:
990 /* No register support currently */
991 ret = dapm_generic_apply_power(w);
992 break;
993
994 default: 975 default:
995 /* Queue it up for application */ 976 /* Queue it up for application */
996 cur_sort = sort[w->id]; 977 cur_sort = sort[w->id];
@@ -1201,6 +1182,15 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1201 } 1182 }
1202 } 1183 }
1203 1184
1185 /* Force all contexts in the card to the same bias state */
1186 power = 0;
1187 list_for_each_entry(d, &card->dapm_list, list)
1188 if (d->dev_power)
1189 power = 1;
1190 list_for_each_entry(d, &card->dapm_list, list)
1191 d->dev_power = power;
1192
1193
1204 /* Run all the bias changes in parallel */ 1194 /* Run all the bias changes in parallel */
1205 list_for_each_entry(d, &dapm->card->dapm_list, list) 1195 list_for_each_entry(d, &dapm->card->dapm_list, list)
1206 async_schedule_domain(dapm_pre_sequence_async, d, 1196 async_schedule_domain(dapm_pre_sequence_async, d,
@@ -1304,31 +1294,104 @@ static const struct file_operations dapm_widget_power_fops = {
1304 .llseek = default_llseek, 1294 .llseek = default_llseek,
1305}; 1295};
1306 1296
1307void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) 1297static int dapm_bias_open_file(struct inode *inode, struct file *file)
1298{
1299 file->private_data = inode->i_private;
1300 return 0;
1301}
1302
1303static ssize_t dapm_bias_read_file(struct file *file, char __user *user_buf,
1304 size_t count, loff_t *ppos)
1305{
1306 struct snd_soc_dapm_context *dapm = file->private_data;
1307 char *level;
1308
1309 switch (dapm->bias_level) {
1310 case SND_SOC_BIAS_ON:
1311 level = "On\n";
1312 break;
1313 case SND_SOC_BIAS_PREPARE:
1314 level = "Prepare\n";
1315 break;
1316 case SND_SOC_BIAS_STANDBY:
1317 level = "Standby\n";
1318 break;
1319 case SND_SOC_BIAS_OFF:
1320 level = "Off\n";
1321 break;
1322 default:
1323 BUG();
1324 level = "Unknown\n";
1325 break;
1326 }
1327
1328 return simple_read_from_buffer(user_buf, count, ppos, level,
1329 strlen(level));
1330}
1331
1332static const struct file_operations dapm_bias_fops = {
1333 .open = dapm_bias_open_file,
1334 .read = dapm_bias_read_file,
1335 .llseek = default_llseek,
1336};
1337
1338void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
1339 struct dentry *parent)
1308{ 1340{
1309 struct snd_soc_dapm_widget *w;
1310 struct dentry *d; 1341 struct dentry *d;
1311 1342
1312 if (!dapm->debugfs_dapm) 1343 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent);
1344
1345 if (!dapm->debugfs_dapm) {
1346 printk(KERN_WARNING
1347 "Failed to create DAPM debugfs directory\n");
1313 return; 1348 return;
1349 }
1314 1350
1315 list_for_each_entry(w, &dapm->card->widgets, list) { 1351 d = debugfs_create_file("bias_level", 0444,
1316 if (!w->name || w->dapm != dapm) 1352 dapm->debugfs_dapm, dapm,
1317 continue; 1353 &dapm_bias_fops);
1354 if (!d)
1355 dev_warn(dapm->dev,
1356 "ASoC: Failed to create bias level debugfs file\n");
1357}
1318 1358
1319 d = debugfs_create_file(w->name, 0444, 1359static void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
1320 dapm->debugfs_dapm, w, 1360{
1321 &dapm_widget_power_fops); 1361 struct snd_soc_dapm_context *dapm = w->dapm;
1322 if (!d) 1362 struct dentry *d;
1323 dev_warn(w->dapm->dev, 1363
1324 "ASoC: Failed to create %s debugfs file\n", 1364 if (!dapm->debugfs_dapm || !w->name)
1325 w->name); 1365 return;
1326 } 1366
1367 d = debugfs_create_file(w->name, 0444,
1368 dapm->debugfs_dapm, w,
1369 &dapm_widget_power_fops);
1370 if (!d)
1371 dev_warn(w->dapm->dev,
1372 "ASoC: Failed to create %s debugfs file\n",
1373 w->name);
1374}
1375
1376static void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
1377{
1378 debugfs_remove_recursive(dapm->debugfs_dapm);
1327} 1379}
1380
1328#else 1381#else
1329void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) 1382void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
1383 struct dentry *parent)
1384{
1385}
1386
1387static inline void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
1388{
1389}
1390
1391static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
1330{ 1392{
1331} 1393}
1394
1332#endif 1395#endif
1333 1396
1334/* test and update the power status of a mux widget */ 1397/* test and update the power status of a mux widget */
@@ -1496,32 +1559,49 @@ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
1496 kfree(p->long_name); 1559 kfree(p->long_name);
1497 kfree(p); 1560 kfree(p);
1498 } 1561 }
1562 kfree(w->kcontrols);
1499 kfree(w->name); 1563 kfree(w->name);
1500 kfree(w); 1564 kfree(w);
1501 } 1565 }
1502} 1566}
1503 1567
1504static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, 1568static struct snd_soc_dapm_widget *dapm_find_widget(
1505 const char *pin, int status) 1569 struct snd_soc_dapm_context *dapm, const char *pin,
1570 bool search_other_contexts)
1506{ 1571{
1507 struct snd_soc_dapm_widget *w; 1572 struct snd_soc_dapm_widget *w;
1573 struct snd_soc_dapm_widget *fallback = NULL;
1508 1574
1509 list_for_each_entry(w, &dapm->card->widgets, list) { 1575 list_for_each_entry(w, &dapm->card->widgets, list) {
1510 if (w->dapm != dapm)
1511 continue;
1512 if (!strcmp(w->name, pin)) { 1576 if (!strcmp(w->name, pin)) {
1513 dev_dbg(w->dapm->dev, "dapm: pin %s = %d\n", 1577 if (w->dapm == dapm)
1514 pin, status); 1578 return w;
1515 w->connected = status; 1579 else
1516 /* Allow disabling of forced pins */ 1580 fallback = w;
1517 if (status == 0)
1518 w->force = 0;
1519 return 0;
1520 } 1581 }
1521 } 1582 }
1522 1583
1523 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); 1584 if (search_other_contexts)
1524 return -EINVAL; 1585 return fallback;
1586
1587 return NULL;
1588}
1589
1590static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
1591 const char *pin, int status)
1592{
1593 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
1594
1595 if (!w) {
1596 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
1597 return -EINVAL;
1598 }
1599
1600 w->connected = status;
1601 if (status == 0)
1602 w->force = 0;
1603
1604 return 0;
1525} 1605}
1526 1606
1527/** 1607/**
@@ -1627,7 +1707,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
1627 } 1707 }
1628 1708
1629 /* connect dynamic paths */ 1709 /* connect dynamic paths */
1630 switch(wsink->id) { 1710 switch (wsink->id) {
1631 case snd_soc_dapm_adc: 1711 case snd_soc_dapm_adc:
1632 case snd_soc_dapm_dac: 1712 case snd_soc_dapm_dac:
1633 case snd_soc_dapm_pga: 1713 case snd_soc_dapm_pga:
@@ -1650,7 +1730,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
1650 case snd_soc_dapm_virt_mux: 1730 case snd_soc_dapm_virt_mux:
1651 case snd_soc_dapm_value_mux: 1731 case snd_soc_dapm_value_mux:
1652 ret = dapm_connect_mux(dapm, wsource, wsink, path, control, 1732 ret = dapm_connect_mux(dapm, wsource, wsink, path, control,
1653 &wsink->kcontrols[0]); 1733 &wsink->kcontrol_news[0]);
1654 if (ret != 0) 1734 if (ret != 0)
1655 goto err; 1735 goto err;
1656 break; 1736 break;
@@ -1730,6 +1810,14 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
1730 if (w->new) 1810 if (w->new)
1731 continue; 1811 continue;
1732 1812
1813 if (w->num_kcontrols) {
1814 w->kcontrols = kzalloc(w->num_kcontrols *
1815 sizeof(struct snd_kcontrol *),
1816 GFP_KERNEL);
1817 if (!w->kcontrols)
1818 return -ENOMEM;
1819 }
1820
1733 switch(w->id) { 1821 switch(w->id) {
1734 case snd_soc_dapm_switch: 1822 case snd_soc_dapm_switch:
1735 case snd_soc_dapm_mixer: 1823 case snd_soc_dapm_mixer:
@@ -1785,6 +1873,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
1785 } 1873 }
1786 1874
1787 w->new = 1; 1875 w->new = 1;
1876
1877 dapm_debugfs_add_widget(w);
1788 } 1878 }
1789 1879
1790 dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); 1880 dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
@@ -1804,7 +1894,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
1804int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, 1894int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
1805 struct snd_ctl_elem_value *ucontrol) 1895 struct snd_ctl_elem_value *ucontrol)
1806{ 1896{
1807 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1897 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1898 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1808 struct soc_mixer_control *mc = 1899 struct soc_mixer_control *mc =
1809 (struct soc_mixer_control *)kcontrol->private_value; 1900 (struct soc_mixer_control *)kcontrol->private_value;
1810 unsigned int reg = mc->reg; 1901 unsigned int reg = mc->reg;
@@ -1843,7 +1934,9 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
1843int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, 1934int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1844 struct snd_ctl_elem_value *ucontrol) 1935 struct snd_ctl_elem_value *ucontrol)
1845{ 1936{
1846 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1937 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1938 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1939 struct snd_soc_codec *codec = widget->codec;
1847 struct soc_mixer_control *mc = 1940 struct soc_mixer_control *mc =
1848 (struct soc_mixer_control *)kcontrol->private_value; 1941 (struct soc_mixer_control *)kcontrol->private_value;
1849 unsigned int reg = mc->reg; 1942 unsigned int reg = mc->reg;
@@ -1854,6 +1947,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1854 unsigned int val; 1947 unsigned int val;
1855 int connect, change; 1948 int connect, change;
1856 struct snd_soc_dapm_update update; 1949 struct snd_soc_dapm_update update;
1950 int wi;
1857 1951
1858 val = (ucontrol->value.integer.value[0] & mask); 1952 val = (ucontrol->value.integer.value[0] & mask);
1859 1953
@@ -1862,31 +1956,36 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1862 mask = mask << shift; 1956 mask = mask << shift;
1863 val = val << shift; 1957 val = val << shift;
1864 1958
1865 mutex_lock(&widget->codec->mutex); 1959 if (val)
1866 widget->value = val; 1960 /* new connection */
1961 connect = invert ? 0 : 1;
1962 else
1963 /* old connection must be powered down */
1964 connect = invert ? 1 : 0;
1965
1966 mutex_lock(&codec->mutex);
1867 1967
1868 change = snd_soc_test_bits(widget->codec, reg, mask, val); 1968 change = snd_soc_test_bits(widget->codec, reg, mask, val);
1869 if (change) { 1969 if (change) {
1870 if (val) 1970 for (wi = 0; wi < wlist->num_widgets; wi++) {
1871 /* new connection */ 1971 widget = wlist->widgets[wi];
1872 connect = invert ? 0:1;
1873 else
1874 /* old connection must be powered down */
1875 connect = invert ? 1:0;
1876 1972
1877 update.kcontrol = kcontrol; 1973 widget->value = val;
1878 update.widget = widget;
1879 update.reg = reg;
1880 update.mask = mask;
1881 update.val = val;
1882 widget->dapm->update = &update;
1883 1974
1884 dapm_mixer_update_power(widget, kcontrol, connect); 1975 update.kcontrol = kcontrol;
1976 update.widget = widget;
1977 update.reg = reg;
1978 update.mask = mask;
1979 update.val = val;
1980 widget->dapm->update = &update;
1885 1981
1886 widget->dapm->update = NULL; 1982 dapm_mixer_update_power(widget, kcontrol, connect);
1983
1984 widget->dapm->update = NULL;
1985 }
1887 } 1986 }
1888 1987
1889 mutex_unlock(&widget->codec->mutex); 1988 mutex_unlock(&codec->mutex);
1890 return 0; 1989 return 0;
1891} 1990}
1892EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw); 1991EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
@@ -1903,7 +2002,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
1903int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, 2002int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
1904 struct snd_ctl_elem_value *ucontrol) 2003 struct snd_ctl_elem_value *ucontrol)
1905{ 2004{
1906 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 2005 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2006 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1907 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2007 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1908 unsigned int val, bitmask; 2008 unsigned int val, bitmask;
1909 2009
@@ -1931,11 +2031,14 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
1931int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, 2031int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1932 struct snd_ctl_elem_value *ucontrol) 2032 struct snd_ctl_elem_value *ucontrol)
1933{ 2033{
1934 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 2034 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2035 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2036 struct snd_soc_codec *codec = widget->codec;
1935 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2037 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1936 unsigned int val, mux, change; 2038 unsigned int val, mux, change;
1937 unsigned int mask, bitmask; 2039 unsigned int mask, bitmask;
1938 struct snd_soc_dapm_update update; 2040 struct snd_soc_dapm_update update;
2041 int wi;
1939 2042
1940 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 2043 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1941 ; 2044 ;
@@ -1951,22 +2054,29 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1951 mask |= (bitmask - 1) << e->shift_r; 2054 mask |= (bitmask - 1) << e->shift_r;
1952 } 2055 }
1953 2056
1954 mutex_lock(&widget->codec->mutex); 2057 mutex_lock(&codec->mutex);
1955 widget->value = val; 2058
1956 change = snd_soc_test_bits(widget->codec, e->reg, mask, val); 2059 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
2060 if (change) {
2061 for (wi = 0; wi < wlist->num_widgets; wi++) {
2062 widget = wlist->widgets[wi];
1957 2063
1958 update.kcontrol = kcontrol; 2064 widget->value = val;
1959 update.widget = widget;
1960 update.reg = e->reg;
1961 update.mask = mask;
1962 update.val = val;
1963 widget->dapm->update = &update;
1964 2065
1965 dapm_mux_update_power(widget, kcontrol, change, mux, e); 2066 update.kcontrol = kcontrol;
2067 update.widget = widget;
2068 update.reg = e->reg;
2069 update.mask = mask;
2070 update.val = val;
2071 widget->dapm->update = &update;
1966 2072
1967 widget->dapm->update = NULL; 2073 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1968 2074
1969 mutex_unlock(&widget->codec->mutex); 2075 widget->dapm->update = NULL;
2076 }
2077 }
2078
2079 mutex_unlock(&codec->mutex);
1970 return change; 2080 return change;
1971} 2081}
1972EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); 2082EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
@@ -1981,7 +2091,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
1981int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol, 2091int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol,
1982 struct snd_ctl_elem_value *ucontrol) 2092 struct snd_ctl_elem_value *ucontrol)
1983{ 2093{
1984 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 2094 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2095 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
1985 2096
1986 ucontrol->value.enumerated.item[0] = widget->value; 2097 ucontrol->value.enumerated.item[0] = widget->value;
1987 2098
@@ -1999,22 +2110,33 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt);
1999int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol, 2110int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
2000 struct snd_ctl_elem_value *ucontrol) 2111 struct snd_ctl_elem_value *ucontrol)
2001{ 2112{
2002 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 2113 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2114 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2115 struct snd_soc_codec *codec = widget->codec;
2003 struct soc_enum *e = 2116 struct soc_enum *e =
2004 (struct soc_enum *)kcontrol->private_value; 2117 (struct soc_enum *)kcontrol->private_value;
2005 int change; 2118 int change;
2006 int ret = 0; 2119 int ret = 0;
2120 int wi;
2007 2121
2008 if (ucontrol->value.enumerated.item[0] >= e->max) 2122 if (ucontrol->value.enumerated.item[0] >= e->max)
2009 return -EINVAL; 2123 return -EINVAL;
2010 2124
2011 mutex_lock(&widget->codec->mutex); 2125 mutex_lock(&codec->mutex);
2012 2126
2013 change = widget->value != ucontrol->value.enumerated.item[0]; 2127 change = widget->value != ucontrol->value.enumerated.item[0];
2014 widget->value = ucontrol->value.enumerated.item[0]; 2128 if (change) {
2015 dapm_mux_update_power(widget, kcontrol, change, widget->value, e); 2129 for (wi = 0; wi < wlist->num_widgets; wi++) {
2130 widget = wlist->widgets[wi];
2016 2131
2017 mutex_unlock(&widget->codec->mutex); 2132 widget->value = ucontrol->value.enumerated.item[0];
2133
2134 dapm_mux_update_power(widget, kcontrol, change,
2135 widget->value, e);
2136 }
2137 }
2138
2139 mutex_unlock(&codec->mutex);
2018 return ret; 2140 return ret;
2019} 2141}
2020EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt); 2142EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
@@ -2035,7 +2157,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
2035int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol, 2157int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
2036 struct snd_ctl_elem_value *ucontrol) 2158 struct snd_ctl_elem_value *ucontrol)
2037{ 2159{
2038 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 2160 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2161 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2039 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2162 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2040 unsigned int reg_val, val, mux; 2163 unsigned int reg_val, val, mux;
2041 2164
@@ -2075,11 +2198,14 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_value_enum_double);
2075int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, 2198int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2076 struct snd_ctl_elem_value *ucontrol) 2199 struct snd_ctl_elem_value *ucontrol)
2077{ 2200{
2078 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 2201 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2202 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2203 struct snd_soc_codec *codec = widget->codec;
2079 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2204 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2080 unsigned int val, mux, change; 2205 unsigned int val, mux, change;
2081 unsigned int mask; 2206 unsigned int mask;
2082 struct snd_soc_dapm_update update; 2207 struct snd_soc_dapm_update update;
2208 int wi;
2083 2209
2084 if (ucontrol->value.enumerated.item[0] > e->max - 1) 2210 if (ucontrol->value.enumerated.item[0] > e->max - 1)
2085 return -EINVAL; 2211 return -EINVAL;
@@ -2093,22 +2219,29 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2093 mask |= e->mask << e->shift_r; 2219 mask |= e->mask << e->shift_r;
2094 } 2220 }
2095 2221
2096 mutex_lock(&widget->codec->mutex); 2222 mutex_lock(&codec->mutex);
2097 widget->value = val; 2223
2098 change = snd_soc_test_bits(widget->codec, e->reg, mask, val); 2224 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
2225 if (change) {
2226 for (wi = 0; wi < wlist->num_widgets; wi++) {
2227 widget = wlist->widgets[wi];
2099 2228
2100 update.kcontrol = kcontrol; 2229 widget->value = val;
2101 update.widget = widget;
2102 update.reg = e->reg;
2103 update.mask = mask;
2104 update.val = val;
2105 widget->dapm->update = &update;
2106 2230
2107 dapm_mux_update_power(widget, kcontrol, change, mux, e); 2231 update.kcontrol = kcontrol;
2232 update.widget = widget;
2233 update.reg = e->reg;
2234 update.mask = mask;
2235 update.val = val;
2236 widget->dapm->update = &update;
2108 2237
2109 widget->dapm->update = NULL; 2238 dapm_mux_update_power(widget, kcontrol, change, mux, e);
2239
2240 widget->dapm->update = NULL;
2241 }
2242 }
2110 2243
2111 mutex_unlock(&widget->codec->mutex); 2244 mutex_unlock(&codec->mutex);
2112 return change; 2245 return change;
2113} 2246}
2114EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); 2247EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double);
@@ -2346,22 +2479,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
2346int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, 2479int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
2347 const char *pin) 2480 const char *pin)
2348{ 2481{
2349 struct snd_soc_dapm_widget *w; 2482 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
2350 2483
2351 list_for_each_entry(w, &dapm->card->widgets, list) { 2484 if (!w) {
2352 if (w->dapm != dapm) 2485 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
2353 continue; 2486 return -EINVAL;
2354 if (!strcmp(w->name, pin)) {
2355 dev_dbg(w->dapm->dev,
2356 "dapm: force enable pin %s\n", pin);
2357 w->connected = 1;
2358 w->force = 1;
2359 return 0;
2360 }
2361 } 2487 }
2362 2488
2363 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); 2489 dev_dbg(w->dapm->dev, "dapm: force enable pin %s\n", pin);
2364 return -EINVAL; 2490 w->connected = 1;
2491 w->force = 1;
2492
2493 return 0;
2365} 2494}
2366EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); 2495EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin);
2367 2496
@@ -2413,14 +2542,10 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
2413int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, 2542int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
2414 const char *pin) 2543 const char *pin)
2415{ 2544{
2416 struct snd_soc_dapm_widget *w; 2545 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
2417 2546
2418 list_for_each_entry(w, &dapm->card->widgets, list) { 2547 if (w)
2419 if (w->dapm != dapm) 2548 return w->connected;
2420 continue;
2421 if (!strcmp(w->name, pin))
2422 return w->connected;
2423 }
2424 2549
2425 return 0; 2550 return 0;
2426} 2551}
@@ -2440,19 +2565,16 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
2440int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, 2565int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
2441 const char *pin) 2566 const char *pin)
2442{ 2567{
2443 struct snd_soc_dapm_widget *w; 2568 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, false);
2444 2569
2445 list_for_each_entry(w, &dapm->card->widgets, list) { 2570 if (!w) {
2446 if (w->dapm != dapm) 2571 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
2447 continue; 2572 return -EINVAL;
2448 if (!strcmp(w->name, pin)) {
2449 w->ignore_suspend = 1;
2450 return 0;
2451 }
2452 } 2573 }
2453 2574
2454 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); 2575 w->ignore_suspend = 1;
2455 return -EINVAL; 2576
2577 return 0;
2456} 2578}
2457EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); 2579EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
2458 2580
@@ -2465,6 +2587,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
2465void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm) 2587void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm)
2466{ 2588{
2467 snd_soc_dapm_sys_remove(dapm->dev); 2589 snd_soc_dapm_sys_remove(dapm->dev);
2590 dapm_debugfs_cleanup(dapm);
2468 dapm_free_widgets(dapm); 2591 dapm_free_widgets(dapm);
2469 list_del(&dapm->list); 2592 list_del(&dapm->list);
2470} 2593}
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index fc017c0a7b5d..7c17b98d5846 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -325,7 +325,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
325 gpio_handler, 325 gpio_handler,
326 IRQF_TRIGGER_RISING | 326 IRQF_TRIGGER_RISING |
327 IRQF_TRIGGER_FALLING, 327 IRQF_TRIGGER_FALLING,
328 jack->codec->dev->driver->name, 328 gpios[i].name,
329 &gpios[i]); 329 &gpios[i]);
330 if (ret) 330 if (ret)
331 goto err; 331 goto err;
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index 3f45e6a439bf..ec921ec99c26 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -13,6 +13,7 @@
13 * option) any later version. 13 * option) any later version.
14 */ 14 */
15 15
16#include <linux/platform_device.h>
16#include <sound/core.h> 17#include <sound/core.h>
17#include <sound/pcm.h> 18#include <sound/pcm.h>
18#include <sound/pcm_params.h> 19#include <sound/pcm_params.h>
@@ -55,3 +56,55 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params)
55 return ret; 56 return ret;
56} 57}
57EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk); 58EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk);
59
60static struct snd_soc_platform_driver dummy_platform;
61
62static __devinit int snd_soc_dummy_probe(struct platform_device *pdev)
63{
64 return snd_soc_register_platform(&pdev->dev, &dummy_platform);
65}
66
67static __devexit int snd_soc_dummy_remove(struct platform_device *pdev)
68{
69 snd_soc_unregister_platform(&pdev->dev);
70
71 return 0;
72}
73
74static struct platform_driver soc_dummy_driver = {
75 .driver = {
76 .name = "snd-soc-dummy",
77 .owner = THIS_MODULE,
78 },
79 .probe = snd_soc_dummy_probe,
80 .remove = __devexit_p(snd_soc_dummy_remove),
81};
82
83static struct platform_device *soc_dummy_dev;
84
85int __init snd_soc_util_init(void)
86{
87 int ret;
88
89 soc_dummy_dev = platform_device_alloc("snd-soc-dummy", -1);
90 if (!soc_dummy_dev)
91 return -ENOMEM;
92
93 ret = platform_device_add(soc_dummy_dev);
94 if (ret != 0) {
95 platform_device_put(soc_dummy_dev);
96 return ret;
97 }
98
99 ret = platform_driver_register(&soc_dummy_driver);
100 if (ret != 0)
101 platform_device_unregister(soc_dummy_dev);
102
103 return ret;
104}
105
106void __exit snd_soc_util_exit(void)
107{
108 platform_device_unregister(soc_dummy_dev);
109 platform_driver_unregister(&soc_dummy_driver);
110}
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 66b504f06c23..035d39a4beb4 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -1,26 +1,40 @@
1config SND_TEGRA_SOC 1config SND_SOC_TEGRA
2 tristate "SoC Audio for the Tegra System-on-Chip" 2 tristate "SoC Audio for the Tegra System-on-Chip"
3 depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA 3 depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA
4 default m
5 help 4 help
6 Say Y or M here if you want support for SoC audio on Tegra. 5 Say Y or M here if you want support for SoC audio on Tegra.
7 6
8config SND_TEGRA_SOC_I2S 7config SND_SOC_TEGRA_I2S
9 tristate 8 tristate
10 depends on SND_TEGRA_SOC 9 depends on SND_SOC_TEGRA
11 default m
12 help 10 help
13 Say Y or M if you want to add support for codecs attached to the 11 Say Y or M if you want to add support for codecs attached to the
14 Tegra I2S interface. You will also need to select the individual 12 Tegra I2S interface. You will also need to select the individual
15 machine drivers to support below. 13 machine drivers to support below.
16 14
17config SND_TEGRA_SOC_HARMONY 15config MACH_HAS_SND_SOC_TEGRA_WM8903
18 tristate "SoC Audio support for Tegra Harmony reference board" 16 bool
19 depends on SND_TEGRA_SOC && MACH_HARMONY && I2C 17 help
20 default m 18 Machines that use the SND_SOC_TEGRA_WM8903 driver should select
21 select SND_TEGRA_SOC_I2S 19 this config option, in order to allow the user to enable
20 SND_SOC_TEGRA_WM8903.
21
22config SND_SOC_TEGRA_WM8903
23 tristate "SoC Audio support for Tegra boards using a WM8903 codec"
24 depends on SND_SOC_TEGRA && I2C
25 depends on MACH_HAS_SND_SOC_TEGRA_WM8903
26 select SND_SOC_TEGRA_I2S
22 select SND_SOC_WM8903 27 select SND_SOC_WM8903
23 help 28 help
24 Say Y or M here if you want to add support for SoC audio on the 29 Say Y or M here if you want to add support for SoC audio on Tegra
25 Tegra Harmony reference board. 30 boards using the WM8093 codec. Currently, the supported boards are
31 Harmony, Ventana, Seaboard, Kaen, and Aebl.
26 32
33config SND_SOC_TEGRA_TRIMSLICE
34 tristate "SoC Audio support for TrimSlice board"
35 depends on SND_SOC_TEGRA && MACH_TRIMSLICE && I2C
36 select SND_SOC_TEGRA_I2S
37 select SND_SOC_TLV320AIC23
38 help
39 Say Y or M here if you want to add support for SoC audio on the
40 TrimSlice platform.
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index fd183d3ab4f1..fa6574d92a31 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -4,12 +4,14 @@ snd-soc-tegra-pcm-objs := tegra_pcm.o
4snd-soc-tegra-i2s-objs := tegra_i2s.o 4snd-soc-tegra-i2s-objs := tegra_i2s.o
5snd-soc-tegra-utils-objs += tegra_asoc_utils.o 5snd-soc-tegra-utils-objs += tegra_asoc_utils.o
6 6
7obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-utils.o 7obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o
8obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-das.o 8obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-das.o
9obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-pcm.o 9obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
10obj-$(CONFIG_SND_TEGRA_SOC_I2S) += snd-soc-tegra-i2s.o 10obj-$(CONFIG_SND_SOC_TEGRA_I2S) += snd-soc-tegra-i2s.o
11 11
12# Tegra machine Support 12# Tegra machine Support
13snd-soc-tegra-harmony-objs := harmony.o 13snd-soc-tegra-wm8903-objs := tegra_wm8903.o
14snd-soc-tegra-trimslice-objs := trimslice.o
14 15
15obj-$(CONFIG_SND_TEGRA_SOC_HARMONY) += snd-soc-tegra-harmony.o 16obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o
17obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o
diff --git a/sound/soc/tegra/harmony.c b/sound/soc/tegra/harmony.c
deleted file mode 100644
index 556a57133925..000000000000
--- a/sound/soc/tegra/harmony.c
+++ /dev/null
@@ -1,394 +0,0 @@
1/*
2 * harmony.c - Harmony machine ASoC driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010-2011 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd.
10 *
11 * Copyright 2007 Wolfson Microelectronics PLC.
12 * Author: Graeme Gregory
13 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#include <asm/mach-types.h>
32
33#include <linux/module.h>
34#include <linux/platform_device.h>
35#include <linux/slab.h>
36#include <linux/gpio.h>
37
38#include <mach/harmony_audio.h>
39
40#include <sound/core.h>
41#include <sound/jack.h>
42#include <sound/pcm.h>
43#include <sound/pcm_params.h>
44#include <sound/soc.h>
45
46#include "../codecs/wm8903.h"
47
48#include "tegra_das.h"
49#include "tegra_i2s.h"
50#include "tegra_pcm.h"
51#include "tegra_asoc_utils.h"
52
53#define DRV_NAME "tegra-snd-harmony"
54
55#define GPIO_SPKR_EN BIT(0)
56#define GPIO_INT_MIC_EN BIT(1)
57#define GPIO_EXT_MIC_EN BIT(2)
58
59struct tegra_harmony {
60 struct tegra_asoc_utils_data util_data;
61 struct harmony_audio_platform_data *pdata;
62 int gpio_requested;
63};
64
65static int harmony_asoc_hw_params(struct snd_pcm_substream *substream,
66 struct snd_pcm_hw_params *params)
67{
68 struct snd_soc_pcm_runtime *rtd = substream->private_data;
69 struct snd_soc_dai *codec_dai = rtd->codec_dai;
70 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
71 struct snd_soc_codec *codec = rtd->codec;
72 struct snd_soc_card *card = codec->card;
73 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
74 int srate, mclk, mclk_change;
75 int err;
76
77 srate = params_rate(params);
78 switch (srate) {
79 case 64000:
80 case 88200:
81 case 96000:
82 mclk = 128 * srate;
83 break;
84 default:
85 mclk = 256 * srate;
86 break;
87 }
88 /* FIXME: Codec only requires >= 3MHz if OSR==0 */
89 while (mclk < 6000000)
90 mclk *= 2;
91
92 err = tegra_asoc_utils_set_rate(&harmony->util_data, srate, mclk,
93 &mclk_change);
94 if (err < 0) {
95 dev_err(card->dev, "Can't configure clocks\n");
96 return err;
97 }
98
99 err = snd_soc_dai_set_fmt(codec_dai,
100 SND_SOC_DAIFMT_I2S |
101 SND_SOC_DAIFMT_NB_NF |
102 SND_SOC_DAIFMT_CBS_CFS);
103 if (err < 0) {
104 dev_err(card->dev, "codec_dai fmt not set\n");
105 return err;
106 }
107
108 err = snd_soc_dai_set_fmt(cpu_dai,
109 SND_SOC_DAIFMT_I2S |
110 SND_SOC_DAIFMT_NB_NF |
111 SND_SOC_DAIFMT_CBS_CFS);
112 if (err < 0) {
113 dev_err(card->dev, "cpu_dai fmt not set\n");
114 return err;
115 }
116
117 if (mclk_change) {
118 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
119 SND_SOC_CLOCK_IN);
120 if (err < 0) {
121 dev_err(card->dev, "codec_dai clock not set\n");
122 return err;
123 }
124 }
125
126 return 0;
127}
128
129static struct snd_soc_ops harmony_asoc_ops = {
130 .hw_params = harmony_asoc_hw_params,
131};
132
133static struct snd_soc_jack harmony_hp_jack;
134
135static struct snd_soc_jack_pin harmony_hp_jack_pins[] = {
136 {
137 .pin = "Headphone Jack",
138 .mask = SND_JACK_HEADPHONE,
139 },
140};
141
142static struct snd_soc_jack_gpio harmony_hp_jack_gpios[] = {
143 {
144 .name = "headphone detect",
145 .report = SND_JACK_HEADPHONE,
146 .debounce_time = 150,
147 .invert = 1,
148 }
149};
150
151static struct snd_soc_jack harmony_mic_jack;
152
153static struct snd_soc_jack_pin harmony_mic_jack_pins[] = {
154 {
155 .pin = "Mic Jack",
156 .mask = SND_JACK_MICROPHONE,
157 },
158};
159
160static int harmony_event_int_spk(struct snd_soc_dapm_widget *w,
161 struct snd_kcontrol *k, int event)
162{
163 struct snd_soc_codec *codec = w->codec;
164 struct snd_soc_card *card = codec->card;
165 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
166 struct harmony_audio_platform_data *pdata = harmony->pdata;
167
168 gpio_set_value_cansleep(pdata->gpio_spkr_en,
169 SND_SOC_DAPM_EVENT_ON(event));
170
171 return 0;
172}
173
174static const struct snd_soc_dapm_widget harmony_dapm_widgets[] = {
175 SND_SOC_DAPM_SPK("Int Spk", harmony_event_int_spk),
176 SND_SOC_DAPM_HP("Headphone Jack", NULL),
177 SND_SOC_DAPM_MIC("Mic Jack", NULL),
178};
179
180static const struct snd_soc_dapm_route harmony_audio_map[] = {
181 {"Headphone Jack", NULL, "HPOUTR"},
182 {"Headphone Jack", NULL, "HPOUTL"},
183 {"Int Spk", NULL, "ROP"},
184 {"Int Spk", NULL, "RON"},
185 {"Int Spk", NULL, "LOP"},
186 {"Int Spk", NULL, "LON"},
187 {"Mic Bias", NULL, "Mic Jack"},
188 {"IN1L", NULL, "Mic Bias"},
189};
190
191static const struct snd_kcontrol_new harmony_controls[] = {
192 SOC_DAPM_PIN_SWITCH("Int Spk"),
193};
194
195static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd)
196{
197 struct snd_soc_codec *codec = rtd->codec;
198 struct snd_soc_dapm_context *dapm = &codec->dapm;
199 struct snd_soc_card *card = codec->card;
200 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
201 struct harmony_audio_platform_data *pdata = harmony->pdata;
202 int ret;
203
204 ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
205 if (ret) {
206 dev_err(card->dev, "cannot get spkr_en gpio\n");
207 return ret;
208 }
209 harmony->gpio_requested |= GPIO_SPKR_EN;
210
211 gpio_direction_output(pdata->gpio_spkr_en, 0);
212
213 ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
214 if (ret) {
215 dev_err(card->dev, "cannot get int_mic_en gpio\n");
216 return ret;
217 }
218 harmony->gpio_requested |= GPIO_INT_MIC_EN;
219
220 /* Disable int mic; enable signal is active-high */
221 gpio_direction_output(pdata->gpio_int_mic_en, 0);
222
223 ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
224 if (ret) {
225 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
226 return ret;
227 }
228 harmony->gpio_requested |= GPIO_EXT_MIC_EN;
229
230 /* Enable ext mic; enable signal is active-low */
231 gpio_direction_output(pdata->gpio_ext_mic_en, 0);
232
233 ret = snd_soc_add_controls(codec, harmony_controls,
234 ARRAY_SIZE(harmony_controls));
235 if (ret < 0)
236 return ret;
237
238 snd_soc_dapm_new_controls(dapm, harmony_dapm_widgets,
239 ARRAY_SIZE(harmony_dapm_widgets));
240
241 snd_soc_dapm_add_routes(dapm, harmony_audio_map,
242 ARRAY_SIZE(harmony_audio_map));
243
244 harmony_hp_jack_gpios[0].gpio = pdata->gpio_hp_det;
245 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
246 &harmony_hp_jack);
247 snd_soc_jack_add_pins(&harmony_hp_jack,
248 ARRAY_SIZE(harmony_hp_jack_pins),
249 harmony_hp_jack_pins);
250 snd_soc_jack_add_gpios(&harmony_hp_jack,
251 ARRAY_SIZE(harmony_hp_jack_gpios),
252 harmony_hp_jack_gpios);
253
254 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
255 &harmony_mic_jack);
256 snd_soc_jack_add_pins(&harmony_mic_jack,
257 ARRAY_SIZE(harmony_mic_jack_pins),
258 harmony_mic_jack_pins);
259 wm8903_mic_detect(codec, &harmony_mic_jack, SND_JACK_MICROPHONE, 0);
260
261 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
262
263 snd_soc_dapm_nc_pin(dapm, "IN3L");
264 snd_soc_dapm_nc_pin(dapm, "IN3R");
265 snd_soc_dapm_nc_pin(dapm, "LINEOUTL");
266 snd_soc_dapm_nc_pin(dapm, "LINEOUTR");
267
268 snd_soc_dapm_sync(dapm);
269
270 return 0;
271}
272
273static struct snd_soc_dai_link harmony_wm8903_dai = {
274 .name = "WM8903",
275 .stream_name = "WM8903 PCM",
276 .codec_name = "wm8903.0-001a",
277 .platform_name = "tegra-pcm-audio",
278 .cpu_dai_name = "tegra-i2s.0",
279 .codec_dai_name = "wm8903-hifi",
280 .init = harmony_asoc_init,
281 .ops = &harmony_asoc_ops,
282};
283
284static struct snd_soc_card snd_soc_harmony = {
285 .name = "tegra-harmony",
286 .dai_link = &harmony_wm8903_dai,
287 .num_links = 1,
288};
289
290static __devinit int tegra_snd_harmony_probe(struct platform_device *pdev)
291{
292 struct snd_soc_card *card = &snd_soc_harmony;
293 struct tegra_harmony *harmony;
294 struct harmony_audio_platform_data *pdata;
295 int ret;
296
297 if (!machine_is_harmony()) {
298 dev_err(&pdev->dev, "Not running on Tegra Harmony!\n");
299 return -ENODEV;
300 }
301
302 pdata = pdev->dev.platform_data;
303 if (!pdata) {
304 dev_err(&pdev->dev, "no platform data supplied\n");
305 return -EINVAL;
306 }
307
308 harmony = kzalloc(sizeof(struct tegra_harmony), GFP_KERNEL);
309 if (!harmony) {
310 dev_err(&pdev->dev, "Can't allocate tegra_harmony\n");
311 return -ENOMEM;
312 }
313
314 harmony->pdata = pdata;
315
316 ret = tegra_asoc_utils_init(&harmony->util_data, &pdev->dev);
317 if (ret)
318 goto err_free_harmony;
319
320 card->dev = &pdev->dev;
321 platform_set_drvdata(pdev, card);
322 snd_soc_card_set_drvdata(card, harmony);
323
324 ret = snd_soc_register_card(card);
325 if (ret) {
326 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
327 ret);
328 goto err_clear_drvdata;
329 }
330
331 return 0;
332
333err_clear_drvdata:
334 snd_soc_card_set_drvdata(card, NULL);
335 platform_set_drvdata(pdev, NULL);
336 card->dev = NULL;
337 tegra_asoc_utils_fini(&harmony->util_data);
338err_free_harmony:
339 kfree(harmony);
340 return ret;
341}
342
343static int __devexit tegra_snd_harmony_remove(struct platform_device *pdev)
344{
345 struct snd_soc_card *card = platform_get_drvdata(pdev);
346 struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card);
347 struct harmony_audio_platform_data *pdata = harmony->pdata;
348
349 snd_soc_unregister_card(card);
350
351 snd_soc_card_set_drvdata(card, NULL);
352 platform_set_drvdata(pdev, NULL);
353 card->dev = NULL;
354
355 tegra_asoc_utils_fini(&harmony->util_data);
356
357 if (harmony->gpio_requested & GPIO_EXT_MIC_EN)
358 gpio_free(pdata->gpio_ext_mic_en);
359 if (harmony->gpio_requested & GPIO_INT_MIC_EN)
360 gpio_free(pdata->gpio_int_mic_en);
361 if (harmony->gpio_requested & GPIO_SPKR_EN)
362 gpio_free(pdata->gpio_spkr_en);
363
364 kfree(harmony);
365
366 return 0;
367}
368
369static struct platform_driver tegra_snd_harmony_driver = {
370 .driver = {
371 .name = DRV_NAME,
372 .owner = THIS_MODULE,
373 .pm = &snd_soc_pm_ops,
374 },
375 .probe = tegra_snd_harmony_probe,
376 .remove = __devexit_p(tegra_snd_harmony_remove),
377};
378
379static int __init snd_tegra_harmony_init(void)
380{
381 return platform_driver_register(&tegra_snd_harmony_driver);
382}
383module_init(snd_tegra_harmony_init);
384
385static void __exit snd_tegra_harmony_exit(void)
386{
387 platform_driver_unregister(&tegra_snd_harmony_driver);
388}
389module_exit(snd_tegra_harmony_exit);
390
391MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
392MODULE_DESCRIPTION("Harmony machine ASoC driver");
393MODULE_LICENSE("GPL");
394MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
index 52f0a3f9ce40..dfa85cbb05c8 100644
--- a/sound/soc/tegra/tegra_asoc_utils.c
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -28,9 +28,10 @@
28#include "tegra_asoc_utils.h" 28#include "tegra_asoc_utils.h"
29 29
30int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, 30int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
31 int mclk, int *mclk_change) 31 int mclk)
32{ 32{
33 int new_baseclock; 33 int new_baseclock;
34 bool clk_change;
34 int err; 35 int err;
35 36
36 switch (srate) { 37 switch (srate) {
@@ -52,10 +53,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
52 return -EINVAL; 53 return -EINVAL;
53 } 54 }
54 55
55 *mclk_change = ((new_baseclock != data->set_baseclock) || 56 clk_change = ((new_baseclock != data->set_baseclock) ||
56 (mclk != data->set_mclk)); 57 (mclk != data->set_mclk));
57 if (!*mclk_change) 58 if (!clk_change)
58 return 0; 59 return 0;
59 60
60 data->set_baseclock = 0; 61 data->set_baseclock = 0;
61 data->set_mclk = 0; 62 data->set_mclk = 0;
diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h
index bbba7afdfc2c..4818195da25c 100644
--- a/sound/soc/tegra/tegra_asoc_utils.h
+++ b/sound/soc/tegra/tegra_asoc_utils.h
@@ -36,7 +36,7 @@ struct tegra_asoc_utils_data {
36}; 36};
37 37
38int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, 38int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
39 int mclk, int *mclk_change); 39 int mclk);
40int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, 40int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
41 struct device *dev); 41 struct device *dev);
42void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data); 42void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data);
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c
index 4f5e2c90b020..6b817e20548c 100644
--- a/sound/soc/tegra/tegra_i2s.c
+++ b/sound/soc/tegra/tegra_i2s.c
@@ -114,7 +114,7 @@ static void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
114 debugfs_remove(i2s->debug); 114 debugfs_remove(i2s->debug);
115} 115}
116#else 116#else
117static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s) 117static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id)
118{ 118{
119} 119}
120 120
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
new file mode 100644
index 000000000000..0d6738a8b29a
--- /dev/null
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -0,0 +1,475 @@
1/*
2 * tegra_wm8903.c - Tegra machine ASoC driver for boards using WM8903 codec.
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010-2011 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd.
10 *
11 * Copyright 2007 Wolfson Microelectronics PLC.
12 * Author: Graeme Gregory
13 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#include <asm/mach-types.h>
32
33#include <linux/module.h>
34#include <linux/platform_device.h>
35#include <linux/slab.h>
36#include <linux/gpio.h>
37
38#include <mach/tegra_wm8903_pdata.h>
39
40#include <sound/core.h>
41#include <sound/jack.h>
42#include <sound/pcm.h>
43#include <sound/pcm_params.h>
44#include <sound/soc.h>
45
46#include "../codecs/wm8903.h"
47
48#include "tegra_das.h"
49#include "tegra_i2s.h"
50#include "tegra_pcm.h"
51#include "tegra_asoc_utils.h"
52
53#define DRV_NAME "tegra-snd-wm8903"
54
55#define GPIO_SPKR_EN BIT(0)
56#define GPIO_HP_MUTE BIT(1)
57#define GPIO_INT_MIC_EN BIT(2)
58#define GPIO_EXT_MIC_EN BIT(3)
59
60struct tegra_wm8903 {
61 struct tegra_asoc_utils_data util_data;
62 struct tegra_wm8903_platform_data *pdata;
63 int gpio_requested;
64};
65
66static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream,
67 struct snd_pcm_hw_params *params)
68{
69 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct snd_soc_dai *codec_dai = rtd->codec_dai;
71 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
72 struct snd_soc_codec *codec = rtd->codec;
73 struct snd_soc_card *card = codec->card;
74 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
75 int srate, mclk;
76 int err;
77
78 srate = params_rate(params);
79 switch (srate) {
80 case 64000:
81 case 88200:
82 case 96000:
83 mclk = 128 * srate;
84 break;
85 default:
86 mclk = 256 * srate;
87 break;
88 }
89 /* FIXME: Codec only requires >= 3MHz if OSR==0 */
90 while (mclk < 6000000)
91 mclk *= 2;
92
93 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
94 if (err < 0) {
95 dev_err(card->dev, "Can't configure clocks\n");
96 return err;
97 }
98
99 err = snd_soc_dai_set_fmt(codec_dai,
100 SND_SOC_DAIFMT_I2S |
101 SND_SOC_DAIFMT_NB_NF |
102 SND_SOC_DAIFMT_CBS_CFS);
103 if (err < 0) {
104 dev_err(card->dev, "codec_dai fmt not set\n");
105 return err;
106 }
107
108 err = snd_soc_dai_set_fmt(cpu_dai,
109 SND_SOC_DAIFMT_I2S |
110 SND_SOC_DAIFMT_NB_NF |
111 SND_SOC_DAIFMT_CBS_CFS);
112 if (err < 0) {
113 dev_err(card->dev, "cpu_dai fmt not set\n");
114 return err;
115 }
116
117 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
118 SND_SOC_CLOCK_IN);
119 if (err < 0) {
120 dev_err(card->dev, "codec_dai clock not set\n");
121 return err;
122 }
123
124 return 0;
125}
126
127static struct snd_soc_ops tegra_wm8903_ops = {
128 .hw_params = tegra_wm8903_hw_params,
129};
130
131static struct snd_soc_jack tegra_wm8903_hp_jack;
132
133static struct snd_soc_jack_pin tegra_wm8903_hp_jack_pins[] = {
134 {
135 .pin = "Headphone Jack",
136 .mask = SND_JACK_HEADPHONE,
137 },
138};
139
140static struct snd_soc_jack_gpio tegra_wm8903_hp_jack_gpio = {
141 .name = "headphone detect",
142 .report = SND_JACK_HEADPHONE,
143 .debounce_time = 150,
144 .invert = 1,
145};
146
147static struct snd_soc_jack tegra_wm8903_mic_jack;
148
149static struct snd_soc_jack_pin tegra_wm8903_mic_jack_pins[] = {
150 {
151 .pin = "Mic Jack",
152 .mask = SND_JACK_MICROPHONE,
153 },
154};
155
156static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w,
157 struct snd_kcontrol *k, int event)
158{
159 struct snd_soc_dapm_context *dapm = w->dapm;
160 struct snd_soc_card *card = dapm->card;
161 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
162 struct tegra_wm8903_platform_data *pdata = machine->pdata;
163
164 if (!(machine->gpio_requested & GPIO_SPKR_EN))
165 return 0;
166
167 gpio_set_value_cansleep(pdata->gpio_spkr_en,
168 SND_SOC_DAPM_EVENT_ON(event));
169
170 return 0;
171}
172
173static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w,
174 struct snd_kcontrol *k, int event)
175{
176 struct snd_soc_dapm_context *dapm = w->dapm;
177 struct snd_soc_card *card = dapm->card;
178 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
179 struct tegra_wm8903_platform_data *pdata = machine->pdata;
180
181 if (!(machine->gpio_requested & GPIO_HP_MUTE))
182 return 0;
183
184 gpio_set_value_cansleep(pdata->gpio_hp_mute,
185 !SND_SOC_DAPM_EVENT_ON(event));
186
187 return 0;
188}
189
190static const struct snd_soc_dapm_widget tegra_wm8903_dapm_widgets[] = {
191 SND_SOC_DAPM_SPK("Int Spk", tegra_wm8903_event_int_spk),
192 SND_SOC_DAPM_HP("Headphone Jack", tegra_wm8903_event_hp),
193 SND_SOC_DAPM_MIC("Mic Jack", NULL),
194};
195
196static const struct snd_soc_dapm_route harmony_audio_map[] = {
197 {"Headphone Jack", NULL, "HPOUTR"},
198 {"Headphone Jack", NULL, "HPOUTL"},
199 {"Int Spk", NULL, "ROP"},
200 {"Int Spk", NULL, "RON"},
201 {"Int Spk", NULL, "LOP"},
202 {"Int Spk", NULL, "LON"},
203 {"Mic Bias", NULL, "Mic Jack"},
204 {"IN1L", NULL, "Mic Bias"},
205};
206
207static const struct snd_soc_dapm_route seaboard_audio_map[] = {
208 {"Headphone Jack", NULL, "HPOUTR"},
209 {"Headphone Jack", NULL, "HPOUTL"},
210 {"Int Spk", NULL, "ROP"},
211 {"Int Spk", NULL, "RON"},
212 {"Int Spk", NULL, "LOP"},
213 {"Int Spk", NULL, "LON"},
214 {"Mic Bias", NULL, "Mic Jack"},
215 {"IN1R", NULL, "Mic Bias"},
216};
217
218static const struct snd_soc_dapm_route kaen_audio_map[] = {
219 {"Headphone Jack", NULL, "HPOUTR"},
220 {"Headphone Jack", NULL, "HPOUTL"},
221 {"Int Spk", NULL, "ROP"},
222 {"Int Spk", NULL, "RON"},
223 {"Int Spk", NULL, "LOP"},
224 {"Int Spk", NULL, "LON"},
225 {"Mic Bias", NULL, "Mic Jack"},
226 {"IN2R", NULL, "Mic Bias"},
227};
228
229static const struct snd_soc_dapm_route aebl_audio_map[] = {
230 {"Headphone Jack", NULL, "HPOUTR"},
231 {"Headphone Jack", NULL, "HPOUTL"},
232 {"Int Spk", NULL, "LINEOUTR"},
233 {"Int Spk", NULL, "LINEOUTL"},
234 {"Mic Bias", NULL, "Mic Jack"},
235 {"IN1R", NULL, "Mic Bias"},
236};
237
238static const struct snd_kcontrol_new tegra_wm8903_controls[] = {
239 SOC_DAPM_PIN_SWITCH("Int Spk"),
240};
241
242static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
243{
244 struct snd_soc_codec *codec = rtd->codec;
245 struct snd_soc_dapm_context *dapm = &codec->dapm;
246 struct snd_soc_card *card = codec->card;
247 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
248 struct tegra_wm8903_platform_data *pdata = machine->pdata;
249 int ret;
250
251 if (gpio_is_valid(pdata->gpio_spkr_en)) {
252 ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
253 if (ret) {
254 dev_err(card->dev, "cannot get spkr_en gpio\n");
255 return ret;
256 }
257 machine->gpio_requested |= GPIO_SPKR_EN;
258
259 gpio_direction_output(pdata->gpio_spkr_en, 0);
260 }
261
262 if (gpio_is_valid(pdata->gpio_hp_mute)) {
263 ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
264 if (ret) {
265 dev_err(card->dev, "cannot get hp_mute gpio\n");
266 return ret;
267 }
268 machine->gpio_requested |= GPIO_HP_MUTE;
269
270 gpio_direction_output(pdata->gpio_hp_mute, 0);
271 }
272
273 if (gpio_is_valid(pdata->gpio_int_mic_en)) {
274 ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
275 if (ret) {
276 dev_err(card->dev, "cannot get int_mic_en gpio\n");
277 return ret;
278 }
279 machine->gpio_requested |= GPIO_INT_MIC_EN;
280
281 /* Disable int mic; enable signal is active-high */
282 gpio_direction_output(pdata->gpio_int_mic_en, 0);
283 }
284
285 if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
286 ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
287 if (ret) {
288 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
289 return ret;
290 }
291 machine->gpio_requested |= GPIO_EXT_MIC_EN;
292
293 /* Enable ext mic; enable signal is active-low */
294 gpio_direction_output(pdata->gpio_ext_mic_en, 0);
295 }
296
297 if (gpio_is_valid(pdata->gpio_hp_det)) {
298 tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det;
299 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
300 &tegra_wm8903_hp_jack);
301 snd_soc_jack_add_pins(&tegra_wm8903_hp_jack,
302 ARRAY_SIZE(tegra_wm8903_hp_jack_pins),
303 tegra_wm8903_hp_jack_pins);
304 snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack,
305 1,
306 &tegra_wm8903_hp_jack_gpio);
307 }
308
309 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
310 &tegra_wm8903_mic_jack);
311 snd_soc_jack_add_pins(&tegra_wm8903_mic_jack,
312 ARRAY_SIZE(tegra_wm8903_mic_jack_pins),
313 tegra_wm8903_mic_jack_pins);
314 wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE,
315 0);
316
317 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
318
319 /* FIXME: Calculate automatically based on DAPM routes? */
320 if (!machine_is_harmony() && !machine_is_ventana())
321 snd_soc_dapm_nc_pin(dapm, "IN1L");
322 if (!machine_is_seaboard() && !machine_is_aebl())
323 snd_soc_dapm_nc_pin(dapm, "IN1R");
324 snd_soc_dapm_nc_pin(dapm, "IN2L");
325 if (!machine_is_kaen())
326 snd_soc_dapm_nc_pin(dapm, "IN2R");
327 snd_soc_dapm_nc_pin(dapm, "IN3L");
328 snd_soc_dapm_nc_pin(dapm, "IN3R");
329
330 if (machine_is_aebl()) {
331 snd_soc_dapm_nc_pin(dapm, "LON");
332 snd_soc_dapm_nc_pin(dapm, "RON");
333 snd_soc_dapm_nc_pin(dapm, "ROP");
334 snd_soc_dapm_nc_pin(dapm, "LOP");
335 } else {
336 snd_soc_dapm_nc_pin(dapm, "LINEOUTR");
337 snd_soc_dapm_nc_pin(dapm, "LINEOUTL");
338 }
339
340 snd_soc_dapm_sync(dapm);
341
342 return 0;
343}
344
345static struct snd_soc_dai_link tegra_wm8903_dai = {
346 .name = "WM8903",
347 .stream_name = "WM8903 PCM",
348 .codec_name = "wm8903.0-001a",
349 .platform_name = "tegra-pcm-audio",
350 .cpu_dai_name = "tegra-i2s.0",
351 .codec_dai_name = "wm8903-hifi",
352 .init = tegra_wm8903_init,
353 .ops = &tegra_wm8903_ops,
354};
355
356static struct snd_soc_card snd_soc_tegra_wm8903 = {
357 .name = "tegra-wm8903",
358 .dai_link = &tegra_wm8903_dai,
359 .num_links = 1,
360
361 .controls = tegra_wm8903_controls,
362 .num_controls = ARRAY_SIZE(tegra_wm8903_controls),
363 .dapm_widgets = tegra_wm8903_dapm_widgets,
364 .num_dapm_widgets = ARRAY_SIZE(tegra_wm8903_dapm_widgets),
365};
366
367static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
368{
369 struct snd_soc_card *card = &snd_soc_tegra_wm8903;
370 struct tegra_wm8903 *machine;
371 struct tegra_wm8903_platform_data *pdata;
372 int ret;
373
374 pdata = pdev->dev.platform_data;
375 if (!pdata) {
376 dev_err(&pdev->dev, "No platform data supplied\n");
377 return -EINVAL;
378 }
379
380 machine = kzalloc(sizeof(struct tegra_wm8903), GFP_KERNEL);
381 if (!machine) {
382 dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n");
383 return -ENOMEM;
384 }
385
386 machine->pdata = pdata;
387
388 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
389 if (ret)
390 goto err_free_machine;
391
392 card->dev = &pdev->dev;
393 platform_set_drvdata(pdev, card);
394 snd_soc_card_set_drvdata(card, machine);
395
396 if (machine_is_harmony() || machine_is_ventana()) {
397 card->dapm_routes = harmony_audio_map;
398 card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map);
399 } else if (machine_is_seaboard()) {
400 card->dapm_routes = seaboard_audio_map;
401 card->num_dapm_routes = ARRAY_SIZE(seaboard_audio_map);
402 } else if (machine_is_kaen()) {
403 card->dapm_routes = kaen_audio_map;
404 card->num_dapm_routes = ARRAY_SIZE(kaen_audio_map);
405 } else {
406 card->dapm_routes = aebl_audio_map;
407 card->num_dapm_routes = ARRAY_SIZE(aebl_audio_map);
408 }
409
410 ret = snd_soc_register_card(card);
411 if (ret) {
412 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
413 ret);
414 goto err_fini_utils;
415 }
416
417 return 0;
418
419err_fini_utils:
420 tegra_asoc_utils_fini(&machine->util_data);
421err_free_machine:
422 kfree(machine);
423 return ret;
424}
425
426static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
427{
428 struct snd_soc_card *card = platform_get_drvdata(pdev);
429 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
430 struct tegra_wm8903_platform_data *pdata = machine->pdata;
431
432 snd_soc_unregister_card(card);
433
434 tegra_asoc_utils_fini(&machine->util_data);
435
436 if (machine->gpio_requested & GPIO_EXT_MIC_EN)
437 gpio_free(pdata->gpio_ext_mic_en);
438 if (machine->gpio_requested & GPIO_INT_MIC_EN)
439 gpio_free(pdata->gpio_int_mic_en);
440 if (machine->gpio_requested & GPIO_HP_MUTE)
441 gpio_free(pdata->gpio_hp_mute);
442 if (machine->gpio_requested & GPIO_SPKR_EN)
443 gpio_free(pdata->gpio_spkr_en);
444
445 kfree(machine);
446
447 return 0;
448}
449
450static struct platform_driver tegra_wm8903_driver = {
451 .driver = {
452 .name = DRV_NAME,
453 .owner = THIS_MODULE,
454 .pm = &snd_soc_pm_ops,
455 },
456 .probe = tegra_wm8903_driver_probe,
457 .remove = __devexit_p(tegra_wm8903_driver_remove),
458};
459
460static int __init tegra_wm8903_modinit(void)
461{
462 return platform_driver_register(&tegra_wm8903_driver);
463}
464module_init(tegra_wm8903_modinit);
465
466static void __exit tegra_wm8903_modexit(void)
467{
468 platform_driver_unregister(&tegra_wm8903_driver);
469}
470module_exit(tegra_wm8903_modexit);
471
472MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
473MODULE_DESCRIPTION("Tegra+WM8903 machine ASoC driver");
474MODULE_LICENSE("GPL");
475MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
new file mode 100644
index 000000000000..8fc07e9adf2e
--- /dev/null
+++ b/sound/soc/tegra/trimslice.c
@@ -0,0 +1,228 @@
1/*
2 * trimslice.c - TrimSlice machine ASoC driver
3 *
4 * Copyright (C) 2011 - CompuLab, Ltd.
5 * Author: Mike Rapoport <mike@compulab.co.il>
6 *
7 * Based on code copyright/by:
8 * Author: Stephen Warren <swarren@nvidia.com>
9 * Copyright (C) 2010-2011 - NVIDIA, Inc.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 *
25 */
26
27#include <asm/mach-types.h>
28
29#include <linux/module.h>
30#include <linux/platform_device.h>
31#include <linux/slab.h>
32
33#include <sound/core.h>
34#include <sound/jack.h>
35#include <sound/pcm.h>
36#include <sound/pcm_params.h>
37#include <sound/soc.h>
38
39#include "../codecs/tlv320aic23.h"
40
41#include "tegra_das.h"
42#include "tegra_i2s.h"
43#include "tegra_pcm.h"
44#include "tegra_asoc_utils.h"
45
46#define DRV_NAME "tegra-snd-trimslice"
47
48struct tegra_trimslice {
49 struct tegra_asoc_utils_data util_data;
50};
51
52static int trimslice_asoc_hw_params(struct snd_pcm_substream *substream,
53 struct snd_pcm_hw_params *params)
54{
55 struct snd_soc_pcm_runtime *rtd = substream->private_data;
56 struct snd_soc_dai *codec_dai = rtd->codec_dai;
57 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
58 struct snd_soc_codec *codec = rtd->codec;
59 struct snd_soc_card *card = codec->card;
60 struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card);
61 int srate, mclk;
62 int err;
63
64 srate = params_rate(params);
65 mclk = 128 * srate;
66
67 err = tegra_asoc_utils_set_rate(&trimslice->util_data, srate, mclk);
68 if (err < 0) {
69 dev_err(card->dev, "Can't configure clocks\n");
70 return err;
71 }
72
73 err = snd_soc_dai_set_fmt(codec_dai,
74 SND_SOC_DAIFMT_I2S |
75 SND_SOC_DAIFMT_NB_NF |
76 SND_SOC_DAIFMT_CBS_CFS);
77 if (err < 0) {
78 dev_err(card->dev, "codec_dai fmt not set\n");
79 return err;
80 }
81
82 err = snd_soc_dai_set_fmt(cpu_dai,
83 SND_SOC_DAIFMT_I2S |
84 SND_SOC_DAIFMT_NB_NF |
85 SND_SOC_DAIFMT_CBS_CFS);
86 if (err < 0) {
87 dev_err(card->dev, "cpu_dai fmt not set\n");
88 return err;
89 }
90
91 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
92 SND_SOC_CLOCK_IN);
93 if (err < 0) {
94 dev_err(card->dev, "codec_dai clock not set\n");
95 return err;
96 }
97
98 return 0;
99}
100
101static struct snd_soc_ops trimslice_asoc_ops = {
102 .hw_params = trimslice_asoc_hw_params,
103};
104
105static const struct snd_soc_dapm_widget trimslice_dapm_widgets[] = {
106 SND_SOC_DAPM_HP("Line Out", NULL),
107 SND_SOC_DAPM_LINE("Line In", NULL),
108};
109
110static const struct snd_soc_dapm_route trimslice_audio_map[] = {
111 {"Line Out", NULL, "LOUT"},
112 {"Line Out", NULL, "ROUT"},
113
114 {"LLINEIN", NULL, "Line In"},
115 {"RLINEIN", NULL, "Line In"},
116};
117
118static int trimslice_asoc_init(struct snd_soc_pcm_runtime *rtd)
119{
120 struct snd_soc_codec *codec = rtd->codec;
121 struct snd_soc_dapm_context *dapm = &codec->dapm;
122
123 snd_soc_dapm_nc_pin(dapm, "LHPOUT");
124 snd_soc_dapm_nc_pin(dapm, "RHPOUT");
125 snd_soc_dapm_nc_pin(dapm, "MICIN");
126
127 snd_soc_dapm_sync(dapm);
128
129 return 0;
130}
131
132static struct snd_soc_dai_link trimslice_tlv320aic23_dai = {
133 .name = "TLV320AIC23",
134 .stream_name = "AIC23",
135 .codec_name = "tlv320aic23-codec.2-001a",
136 .platform_name = "tegra-pcm-audio",
137 .cpu_dai_name = "tegra-i2s.0",
138 .codec_dai_name = "tlv320aic23-hifi",
139 .init = trimslice_asoc_init,
140 .ops = &trimslice_asoc_ops,
141};
142
143static struct snd_soc_card snd_soc_trimslice = {
144 .name = "tegra-trimslice",
145 .dai_link = &trimslice_tlv320aic23_dai,
146 .num_links = 1,
147
148 .dapm_widgets = trimslice_dapm_widgets,
149 .num_dapm_widgets = ARRAY_SIZE(trimslice_dapm_widgets),
150 .dapm_routes = trimslice_audio_map,
151 .num_dapm_routes = ARRAY_SIZE(trimslice_audio_map),
152};
153
154static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
155{
156 struct snd_soc_card *card = &snd_soc_trimslice;
157 struct tegra_trimslice *trimslice;
158 int ret;
159
160 trimslice = kzalloc(sizeof(struct tegra_trimslice), GFP_KERNEL);
161 if (!trimslice) {
162 dev_err(&pdev->dev, "Can't allocate tegra_trimslice\n");
163 return -ENOMEM;
164 }
165
166 ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev);
167 if (ret)
168 goto err_free_trimslice;
169
170 card->dev = &pdev->dev;
171 platform_set_drvdata(pdev, card);
172 snd_soc_card_set_drvdata(card, trimslice);
173
174 ret = snd_soc_register_card(card);
175 if (ret) {
176 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
177 ret);
178 goto err_fini_utils;
179 }
180
181 return 0;
182
183err_fini_utils:
184 tegra_asoc_utils_fini(&trimslice->util_data);
185err_free_trimslice:
186 kfree(trimslice);
187 return ret;
188}
189
190static int __devexit tegra_snd_trimslice_remove(struct platform_device *pdev)
191{
192 struct snd_soc_card *card = platform_get_drvdata(pdev);
193 struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card);
194
195 snd_soc_unregister_card(card);
196
197 tegra_asoc_utils_fini(&trimslice->util_data);
198
199 kfree(trimslice);
200
201 return 0;
202}
203
204static struct platform_driver tegra_snd_trimslice_driver = {
205 .driver = {
206 .name = DRV_NAME,
207 .owner = THIS_MODULE,
208 },
209 .probe = tegra_snd_trimslice_probe,
210 .remove = __devexit_p(tegra_snd_trimslice_remove),
211};
212
213static int __init snd_tegra_trimslice_init(void)
214{
215 return platform_driver_register(&tegra_snd_trimslice_driver);
216}
217module_init(snd_tegra_trimslice_init);
218
219static void __exit snd_tegra_trimslice_exit(void)
220{
221 platform_driver_unregister(&tegra_snd_trimslice_driver);
222}
223module_exit(snd_tegra_trimslice_exit);
224
225MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
226MODULE_DESCRIPTION("Trimslice machine ASoC driver");
227MODULE_LICENSE("GPL");
228MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c
index 248463511186..ac828eff1a63 100644
--- a/sound/usb/6fire/control.c
+++ b/sound/usb/6fire/control.c
@@ -65,6 +65,15 @@ init_data[] = {
65 { 0 } /* TERMINATING ENTRY */ 65 { 0 } /* TERMINATING ENTRY */
66}; 66};
67 67
68static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 };
69/* values to write to soundcard register for all samplerates */
70static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
71static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00};
72
73enum {
74 DIGITAL_THRU_ONLY_SAMPLERATE = 3
75};
76
68static void usb6fire_control_master_vol_update(struct control_runtime *rt) 77static void usb6fire_control_master_vol_update(struct control_runtime *rt)
69{ 78{
70 struct comm_runtime *comm_rt = rt->chip->comm; 79 struct comm_runtime *comm_rt = rt->chip->comm;
@@ -95,6 +104,67 @@ static void usb6fire_control_opt_coax_update(struct control_runtime *rt)
95 } 104 }
96} 105}
97 106
107static int usb6fire_control_set_rate(struct control_runtime *rt, int rate)
108{
109 int ret;
110 struct usb_device *device = rt->chip->dev;
111 struct comm_runtime *comm_rt = rt->chip->comm;
112
113 if (rate < 0 || rate >= CONTROL_N_RATES)
114 return -EINVAL;
115
116 ret = usb_set_interface(device, 1, rates_altsetting[rate]);
117 if (ret < 0)
118 return ret;
119
120 /* set soundcard clock */
121 ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rate],
122 rates_6fire_vh[rate]);
123 if (ret < 0)
124 return ret;
125
126 return 0;
127}
128
129static int usb6fire_control_set_channels(
130 struct control_runtime *rt, int n_analog_out,
131 int n_analog_in, bool spdif_out, bool spdif_in)
132{
133 int ret;
134 struct comm_runtime *comm_rt = rt->chip->comm;
135
136 /* enable analog inputs and outputs
137 * (one bit per stereo-channel) */
138 ret = comm_rt->write16(comm_rt, 0x02, 0x02,
139 (1 << (n_analog_out / 2)) - 1,
140 (1 << (n_analog_in / 2)) - 1);
141 if (ret < 0)
142 return ret;
143
144 /* disable digital inputs and outputs */
145 /* TODO: use spdif_x to enable/disable digital channels */
146 ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00);
147 if (ret < 0)
148 return ret;
149
150 return 0;
151}
152
153static int usb6fire_control_streaming_update(struct control_runtime *rt)
154{
155 struct comm_runtime *comm_rt = rt->chip->comm;
156
157 if (comm_rt) {
158 if (!rt->usb_streaming && rt->digital_thru_switch)
159 usb6fire_control_set_rate(rt,
160 DIGITAL_THRU_ONLY_SAMPLERATE);
161 return comm_rt->write16(comm_rt, 0x02, 0x00, 0x00,
162 (rt->usb_streaming ? 0x01 : 0x00) |
163 (rt->digital_thru_switch ? 0x08 : 0x00));
164 }
165 return -EINVAL;
166}
167
98static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol, 168static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol,
99 struct snd_ctl_elem_info *uinfo) 169 struct snd_ctl_elem_info *uinfo)
100{ 170{
@@ -195,6 +265,28 @@ static int usb6fire_control_opt_coax_get(struct snd_kcontrol *kcontrol,
195 return 0; 265 return 0;
196} 266}
197 267
268static int usb6fire_control_digital_thru_put(struct snd_kcontrol *kcontrol,
269 struct snd_ctl_elem_value *ucontrol)
270{
271 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
272 int changed = 0;
273
274 if (rt->digital_thru_switch != ucontrol->value.integer.value[0]) {
275 rt->digital_thru_switch = ucontrol->value.integer.value[0];
276 usb6fire_control_streaming_update(rt);
277 changed = 1;
278 }
279 return changed;
280}
281
282static int usb6fire_control_digital_thru_get(struct snd_kcontrol *kcontrol,
283 struct snd_ctl_elem_value *ucontrol)
284{
285 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
286 ucontrol->value.integer.value[0] = rt->digital_thru_switch;
287 return 0;
288}
289
198static struct __devinitdata snd_kcontrol_new elements[] = { 290static struct __devinitdata snd_kcontrol_new elements[] = {
199 { 291 {
200 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 292 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -223,6 +315,15 @@ static struct __devinitdata snd_kcontrol_new elements[] = {
223 .get = usb6fire_control_opt_coax_get, 315 .get = usb6fire_control_opt_coax_get,
224 .put = usb6fire_control_opt_coax_put 316 .put = usb6fire_control_opt_coax_put
225 }, 317 },
318 {
319 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
320 .name = "Digital Thru Playback Route",
321 .index = 0,
322 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
323 .info = snd_ctl_boolean_mono_info,
324 .get = usb6fire_control_digital_thru_get,
325 .put = usb6fire_control_digital_thru_put
326 },
226 {} 327 {}
227}; 328};
228 329
@@ -238,6 +339,9 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip)
238 return -ENOMEM; 339 return -ENOMEM;
239 340
240 rt->chip = chip; 341 rt->chip = chip;
342 rt->update_streaming = usb6fire_control_streaming_update;
343 rt->set_rate = usb6fire_control_set_rate;
344 rt->set_channels = usb6fire_control_set_channels;
241 345
242 i = 0; 346 i = 0;
243 while (init_data[i].type) { 347 while (init_data[i].type) {
@@ -249,6 +353,7 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip)
249 usb6fire_control_opt_coax_update(rt); 353 usb6fire_control_opt_coax_update(rt);
250 usb6fire_control_line_phono_update(rt); 354 usb6fire_control_line_phono_update(rt);
251 usb6fire_control_master_vol_update(rt); 355 usb6fire_control_master_vol_update(rt);
356 usb6fire_control_streaming_update(rt);
252 357
253 i = 0; 358 i = 0;
254 while (elements[i].name) { 359 while (elements[i].name) {
diff --git a/sound/usb/6fire/control.h b/sound/usb/6fire/control.h
index b534c777ab02..8f5aeead2e3d 100644
--- a/sound/usb/6fire/control.h
+++ b/sound/usb/6fire/control.h
@@ -21,12 +21,29 @@ enum {
21 CONTROL_MAX_ELEMENTS = 32 21 CONTROL_MAX_ELEMENTS = 32
22}; 22};
23 23
24enum {
25 CONTROL_RATE_44KHZ,
26 CONTROL_RATE_48KHZ,
27 CONTROL_RATE_88KHZ,
28 CONTROL_RATE_96KHZ,
29 CONTROL_RATE_176KHZ,
30 CONTROL_RATE_192KHZ,
31 CONTROL_N_RATES
32};
33
24struct control_runtime { 34struct control_runtime {
35 int (*update_streaming)(struct control_runtime *rt);
36 int (*set_rate)(struct control_runtime *rt, int rate);
37 int (*set_channels)(struct control_runtime *rt, int n_analog_out,
38 int n_analog_in, bool spdif_out, bool spdif_in);
39
25 struct sfire_chip *chip; 40 struct sfire_chip *chip;
26 41
27 struct snd_kcontrol *element[CONTROL_MAX_ELEMENTS]; 42 struct snd_kcontrol *element[CONTROL_MAX_ELEMENTS];
28 bool opt_coax_switch; 43 bool opt_coax_switch;
29 bool line_phono_switch; 44 bool line_phono_switch;
45 bool digital_thru_switch;
46 bool usb_streaming;
30 u8 master_vol; 47 u8 master_vol;
31}; 48};
32 49
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c
index 86c1a3103760..d47beffedb0f 100644
--- a/sound/usb/6fire/firmware.c
+++ b/sound/usb/6fire/firmware.c
@@ -3,12 +3,6 @@
3 * 3 *
4 * Firmware loader 4 * Firmware loader
5 * 5 *
6 * Currently not working for all devices. To be able to use the device
7 * in linux, it is also possible to let the windows driver upload the firmware.
8 * For that, start the computer in windows and reboot.
9 * As long as the device is connected to the power supply, no firmware reload
10 * needs to be performed.
11 *
12 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
13 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
14 * Version: 0.3.0 8 * Version: 0.3.0
@@ -21,6 +15,7 @@
21 */ 15 */
22 16
23#include <linux/firmware.h> 17#include <linux/firmware.h>
18#include <linux/bitrev.h>
24 19
25#include "firmware.h" 20#include "firmware.h"
26#include "chip.h" 21#include "chip.h"
@@ -33,32 +28,6 @@ enum {
33 FPGA_BUFSIZE = 512, FPGA_EP = 2 28 FPGA_BUFSIZE = 512, FPGA_EP = 2
34}; 29};
35 30
36static const u8 BIT_REVERSE_TABLE[256] = {
37 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50,
38 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8,
39 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04,
40 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4,
41 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c,
42 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82,
43 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32,
44 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
45 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46,
46 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6,
47 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e,
48 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,
49 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71,
50 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99,
51 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25,
52 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
53 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d,
54 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3,
55 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b,
56 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb,
57 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67,
58 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f,
59 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f,
60 0xbf, 0x7f, 0xff };
61
62/* 31/*
63 * wMaxPacketSize of pcm endpoints. 32 * wMaxPacketSize of pcm endpoints.
64 * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c 33 * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c
@@ -72,6 +41,10 @@ static const u8 ep_w_max_packet_size[] = {
72 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */ 41 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */
73}; 42};
74 43
44static const u8 known_fw_versions[][4] = {
45 { 0x03, 0x01, 0x0b, 0x00 }
46};
47
75struct ihex_record { 48struct ihex_record {
76 u16 address; 49 u16 address;
77 u8 len; 50 u8 len;
@@ -340,7 +313,7 @@ static int usb6fire_fw_fpga_upload(
340 313
341 while (c != end) { 314 while (c != end) {
342 for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++) 315 for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++)
343 buffer[i] = BIT_REVERSE_TABLE[(u8) *c]; 316 buffer[i] = byte_rev_table[(u8) *c];
344 317
345 ret = usb6fire_fw_fpga_write(device, buffer, i); 318 ret = usb6fire_fw_fpga_write(device, buffer, i);
346 if (ret < 0) { 319 if (ret < 0) {
@@ -363,6 +336,25 @@ static int usb6fire_fw_fpga_upload(
363 return 0; 336 return 0;
364} 337}
365 338
339/* check, if the firmware version the devices has currently loaded
340 * is known by this driver. 'version' needs to have 4 bytes version
341 * info data. */
342static int usb6fire_fw_check(u8 *version)
343{
344 int i;
345
346 for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++)
347 if (!memcmp(version, known_fw_versions + i, 4))
348 return 0;
349
350 snd_printk(KERN_ERR PREFIX "invalid fimware version in device: "
351 "%02x %02x %02x %02x. "
352 "please reconnect to power. if this failure "
353 "still happens, check your firmware installation.",
354 version[0], version[1], version[2], version[3]);
355 return -EINVAL;
356}
357
366int usb6fire_fw_init(struct usb_interface *intf) 358int usb6fire_fw_init(struct usb_interface *intf)
367{ 359{
368 int i; 360 int i;
@@ -378,9 +370,7 @@ int usb6fire_fw_init(struct usb_interface *intf)
378 "firmware state.\n"); 370 "firmware state.\n");
379 return ret; 371 return ret;
380 } 372 }
381 if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55 373 if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55) {
382 || buffer[4] != 0x03 || buffer[5] != 0x01 || buffer[7]
383 != 0x00) {
384 snd_printk(KERN_ERR PREFIX "unknown device firmware state " 374 snd_printk(KERN_ERR PREFIX "unknown device firmware state "
385 "received from device: "); 375 "received from device: ");
386 for (i = 0; i < 8; i++) 376 for (i = 0; i < 8; i++)
@@ -389,7 +379,7 @@ int usb6fire_fw_init(struct usb_interface *intf)
389 return -EIO; 379 return -EIO;
390 } 380 }
391 /* do we need fpga loader ezusb firmware? */ 381 /* do we need fpga loader ezusb firmware? */
392 if (buffer[3] == 0x01 && buffer[6] == 0x19) { 382 if (buffer[3] == 0x01) {
393 ret = usb6fire_fw_ezusb_upload(intf, 383 ret = usb6fire_fw_ezusb_upload(intf,
394 "6fire/dmx6firel2.ihx", 0, NULL, 0); 384 "6fire/dmx6firel2.ihx", 0, NULL, 0);
395 if (ret < 0) 385 if (ret < 0)
@@ -397,7 +387,10 @@ int usb6fire_fw_init(struct usb_interface *intf)
397 return FW_NOT_READY; 387 return FW_NOT_READY;
398 } 388 }
399 /* do we need fpga firmware and application ezusb firmware? */ 389 /* do we need fpga firmware and application ezusb firmware? */
400 else if (buffer[3] == 0x02 && buffer[6] == 0x0b) { 390 else if (buffer[3] == 0x02) {
391 ret = usb6fire_fw_check(buffer + 4);
392 if (ret < 0)
393 return ret;
401 ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin"); 394 ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin");
402 if (ret < 0) 395 if (ret < 0)
403 return ret; 396 return ret;
@@ -410,8 +403,8 @@ int usb6fire_fw_init(struct usb_interface *intf)
410 return FW_NOT_READY; 403 return FW_NOT_READY;
411 } 404 }
412 /* all fw loaded? */ 405 /* all fw loaded? */
413 else if (buffer[3] == 0x03 && buffer[6] == 0x0b) 406 else if (buffer[3] == 0x03)
414 return 0; 407 return usb6fire_fw_check(buffer + 4);
415 /* unknown data? */ 408 /* unknown data? */
416 else { 409 else {
417 snd_printk(KERN_ERR PREFIX "unknown device firmware state " 410 snd_printk(KERN_ERR PREFIX "unknown device firmware state "
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index ba62c7468ba8..b137b25865cc 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -17,26 +17,23 @@
17#include "pcm.h" 17#include "pcm.h"
18#include "chip.h" 18#include "chip.h"
19#include "comm.h" 19#include "comm.h"
20#include "control.h"
20 21
21enum { 22enum {
22 OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4 23 OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4
23}; 24};
24 25
25/* keep next two synced with 26/* keep next two synced with
26 * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE */ 27 * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE
28 * and CONTROL_RATE_XXX in control.h */
27static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 }; 29static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 };
28static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 }; 30static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 };
29static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 }; 31static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 };
30static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 };
31static const int rates_alsaid[] = { 32static const int rates_alsaid[] = {
32 SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000, 33 SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000,
33 SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000, 34 SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000,
34 SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 }; 35 SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 };
35 36
36/* values to write to soundcard register for all samplerates */
37static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
38static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00};
39
40enum { /* settings for pcm */ 37enum { /* settings for pcm */
41 OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024 38 OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024
42}; 39};
@@ -48,15 +45,6 @@ enum { /* pcm streaming states */
48 STREAM_STOPPING 45 STREAM_STOPPING
49}; 46};
50 47
51enum { /* pcm sample rates (also index into RATES_XXX[]) */
52 RATE_44KHZ,
53 RATE_48KHZ,
54 RATE_88KHZ,
55 RATE_96KHZ,
56 RATE_176KHZ,
57 RATE_192KHZ
58};
59
60static const struct snd_pcm_hardware pcm_hw = { 48static const struct snd_pcm_hardware pcm_hw = {
61 .info = SNDRV_PCM_INFO_MMAP | 49 .info = SNDRV_PCM_INFO_MMAP |
62 SNDRV_PCM_INFO_INTERLEAVED | 50 SNDRV_PCM_INFO_INTERLEAVED |
@@ -64,7 +52,7 @@ static const struct snd_pcm_hardware pcm_hw = {
64 SNDRV_PCM_INFO_MMAP_VALID | 52 SNDRV_PCM_INFO_MMAP_VALID |
65 SNDRV_PCM_INFO_BATCH, 53 SNDRV_PCM_INFO_BATCH,
66 54
67 .formats = SNDRV_PCM_FMTBIT_S24_LE, 55 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
68 56
69 .rates = SNDRV_PCM_RATE_44100 | 57 .rates = SNDRV_PCM_RATE_44100 |
70 SNDRV_PCM_RATE_48000 | 58 SNDRV_PCM_RATE_48000 |
@@ -87,57 +75,34 @@ static const struct snd_pcm_hardware pcm_hw = {
87static int usb6fire_pcm_set_rate(struct pcm_runtime *rt) 75static int usb6fire_pcm_set_rate(struct pcm_runtime *rt)
88{ 76{
89 int ret; 77 int ret;
90 struct usb_device *device = rt->chip->dev; 78 struct control_runtime *ctrl_rt = rt->chip->control;
91 struct comm_runtime *comm_rt = rt->chip->comm;
92 79
93 if (rt->rate >= ARRAY_SIZE(rates)) 80 ctrl_rt->usb_streaming = false;
94 return -EINVAL; 81 ret = ctrl_rt->update_streaming(ctrl_rt);
95 /* disable streaming */
96 ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x00);
97 if (ret < 0) { 82 if (ret < 0) {
98 snd_printk(KERN_ERR PREFIX "error stopping streaming while " 83 snd_printk(KERN_ERR PREFIX "error stopping streaming while "
99 "setting samplerate %d.\n", rates[rt->rate]); 84 "setting samplerate %d.\n", rates[rt->rate]);
100 return ret; 85 return ret;
101 } 86 }
102 87
103 ret = usb_set_interface(device, 1, rates_altsetting[rt->rate]); 88 ret = ctrl_rt->set_rate(ctrl_rt, rt->rate);
104 if (ret < 0) {
105 snd_printk(KERN_ERR PREFIX "error setting interface "
106 "altsetting %d for samplerate %d.\n",
107 rates_altsetting[rt->rate], rates[rt->rate]);
108 return ret;
109 }
110
111 /* set soundcard clock */
112 ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rt->rate],
113 rates_6fire_vh[rt->rate]);
114 if (ret < 0) { 89 if (ret < 0) {
115 snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n", 90 snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n",
116 rates[rt->rate]); 91 rates[rt->rate]);
117 return ret; 92 return ret;
118 } 93 }
119 94
120 /* enable analog inputs and outputs 95 ret = ctrl_rt->set_channels(ctrl_rt, OUT_N_CHANNELS, IN_N_CHANNELS,
121 * (one bit per stereo-channel) */ 96 false, false);
122 ret = comm_rt->write16(comm_rt, 0x02, 0x02,
123 (1 << (OUT_N_CHANNELS / 2)) - 1,
124 (1 << (IN_N_CHANNELS / 2)) - 1);
125 if (ret < 0) { 97 if (ret < 0) {
126 snd_printk(KERN_ERR PREFIX "error initializing analog channels " 98 snd_printk(KERN_ERR PREFIX "error initializing channels "
127 "while setting samplerate %d.\n", 99 "while setting samplerate %d.\n",
128 rates[rt->rate]); 100 rates[rt->rate]);
129 return ret; 101 return ret;
130 } 102 }
131 /* disable digital inputs and outputs */
132 ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00);
133 if (ret < 0) {
134 snd_printk(KERN_ERR PREFIX "error initializing digital "
135 "channels while setting samplerate %d.\n",
136 rates[rt->rate]);
137 return ret;
138 }
139 103
140 ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x01); 104 ctrl_rt->usb_streaming = true;
105 ret = ctrl_rt->update_streaming(ctrl_rt);
141 if (ret < 0) { 106 if (ret < 0) {
142 snd_printk(KERN_ERR PREFIX "error starting streaming while " 107 snd_printk(KERN_ERR PREFIX "error starting streaming while "
143 "setting samplerate %d.\n", rates[rt->rate]); 108 "setting samplerate %d.\n", rates[rt->rate]);
@@ -168,12 +133,15 @@ static struct pcm_substream *usb6fire_pcm_get_substream(
168static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt) 133static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt)
169{ 134{
170 int i; 135 int i;
136 struct control_runtime *ctrl_rt = rt->chip->control;
171 137
172 if (rt->stream_state != STREAM_DISABLED) { 138 if (rt->stream_state != STREAM_DISABLED) {
173 for (i = 0; i < PCM_N_URBS; i++) { 139 for (i = 0; i < PCM_N_URBS; i++) {
174 usb_kill_urb(&rt->in_urbs[i].instance); 140 usb_kill_urb(&rt->in_urbs[i].instance);
175 usb_kill_urb(&rt->out_urbs[i].instance); 141 usb_kill_urb(&rt->out_urbs[i].instance);
176 } 142 }
143 ctrl_rt->usb_streaming = false;
144 ctrl_rt->update_streaming(ctrl_rt);
177 rt->stream_state = STREAM_DISABLED; 145 rt->stream_state = STREAM_DISABLED;
178 } 146 }
179} 147}
@@ -228,7 +196,7 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
228 unsigned int total_length = 0; 196 unsigned int total_length = 0;
229 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance); 197 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
230 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime; 198 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
231 u32 *src = (u32 *) urb->buffer; 199 u32 *src = NULL;
232 u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off 200 u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off
233 * (alsa_rt->frame_bits >> 3)); 201 * (alsa_rt->frame_bits >> 3));
234 u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size 202 u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
@@ -244,7 +212,12 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
244 else 212 else
245 frame_count = 0; 213 frame_count = 0;
246 214
247 src = (u32 *) (urb->buffer + total_length); 215 if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)
216 src = (u32 *) (urb->buffer + total_length);
217 else if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE)
218 src = (u32 *) (urb->buffer - 1 + total_length);
219 else
220 return;
248 src++; /* skip leading 4 bytes of every packet */ 221 src++; /* skip leading 4 bytes of every packet */
249 total_length += urb->packets[i].length; 222 total_length += urb->packets[i].length;
250 for (frame = 0; frame < frame_count; frame++) { 223 for (frame = 0; frame < frame_count; frame++) {
@@ -274,9 +247,18 @@ static void usb6fire_pcm_playback(struct pcm_substream *sub,
274 * (alsa_rt->frame_bits >> 3)); 247 * (alsa_rt->frame_bits >> 3));
275 u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size 248 u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
276 * (alsa_rt->frame_bits >> 3)); 249 * (alsa_rt->frame_bits >> 3));
277 u32 *dest = (u32 *) urb->buffer; 250 u32 *dest;
278 int bytes_per_frame = alsa_rt->channels << 2; 251 int bytes_per_frame = alsa_rt->channels << 2;
279 252
253 if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE)
254 dest = (u32 *) (urb->buffer - 1);
255 else if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)
256 dest = (u32 *) (urb->buffer);
257 else {
258 snd_printk(KERN_ERR PREFIX "Unknown sample format.");
259 return;
260 }
261
280 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) { 262 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
281 /* at least 4 header bytes for valid packet. 263 /* at least 4 header bytes for valid packet.
282 * after that: 32 bits per sample for analog channels */ 264 * after that: 32 bits per sample for analog channels */
@@ -456,7 +438,7 @@ static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
456 /* all substreams closed? if so, stop streaming */ 438 /* all substreams closed? if so, stop streaming */
457 if (!rt->playback.instance && !rt->capture.instance) { 439 if (!rt->playback.instance && !rt->capture.instance) {
458 usb6fire_pcm_stream_stop(rt); 440 usb6fire_pcm_stream_stop(rt);
459 rt->rate = -1; 441 rt->rate = ARRAY_SIZE(rates);
460 } 442 }
461 } 443 }
462 mutex_unlock(&rt->stream_mutex); 444 mutex_unlock(&rt->stream_mutex);
@@ -480,7 +462,6 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
480 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub); 462 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
481 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); 463 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
482 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime; 464 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
483 int i;
484 int ret; 465 int ret;
485 466
486 if (rt->panic) 467 if (rt->panic)
@@ -493,12 +474,10 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
493 sub->period_off = 0; 474 sub->period_off = 0;
494 475
495 if (rt->stream_state == STREAM_DISABLED) { 476 if (rt->stream_state == STREAM_DISABLED) {
496 for (i = 0; i < ARRAY_SIZE(rates); i++) 477 for (rt->rate = 0; rt->rate < ARRAY_SIZE(rates); rt->rate++)
497 if (alsa_rt->rate == rates[i]) { 478 if (alsa_rt->rate == rates[rt->rate])
498 rt->rate = i;
499 break; 479 break;
500 } 480 if (rt->rate == ARRAY_SIZE(rates)) {
501 if (i == ARRAY_SIZE(rates)) {
502 mutex_unlock(&rt->stream_mutex); 481 mutex_unlock(&rt->stream_mutex);
503 snd_printk("invalid rate %d in prepare.\n", 482 snd_printk("invalid rate %d in prepare.\n",
504 alsa_rt->rate); 483 alsa_rt->rate);
@@ -613,7 +592,7 @@ int __devinit usb6fire_pcm_init(struct sfire_chip *chip)
613 592
614 rt->chip = chip; 593 rt->chip = chip;
615 rt->stream_state = STREAM_DISABLED; 594 rt->stream_state = STREAM_DISABLED;
616 rt->rate = -1; 595 rt->rate = ARRAY_SIZE(rates);
617 init_waitqueue_head(&rt->stream_wait_queue); 596 init_waitqueue_head(&rt->stream_wait_queue);
618 mutex_init(&rt->stream_mutex); 597 mutex_init(&rt->stream_mutex);
619 598
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 97724d8fa9f6..8beb77563da2 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -100,19 +100,17 @@ config SND_USB_US122L
100 100
101config SND_USB_6FIRE 101config SND_USB_6FIRE
102 tristate "TerraTec DMX 6Fire USB" 102 tristate "TerraTec DMX 6Fire USB"
103 depends on EXPERIMENTAL
104 select FW_LOADER 103 select FW_LOADER
104 select BITREVERSE
105 select SND_RAWMIDI 105 select SND_RAWMIDI
106 select SND_PCM 106 select SND_PCM
107 help 107 help
108 Say Y here to include support for TerraTec 6fire DMX USB interface. 108 Say Y here to include support for TerraTec 6fire DMX USB interface.
109 109
110 You will need firmware files in order to be able to use the device 110 You will need firmware files in order to be able to use the device
111 after it has been coldstarted. This driver currently does not support 111 after it has been coldstarted. An install script for the firmware
112 firmware loading for all devices. If you own such a device, 112 and further help can be found at
113 you could start windows and let the windows driver upload 113 http://sixfireusb.sourceforge.net
114 the firmware. As long as you do not unplug your device from power,
115 it should be usable.
116 114
117endif # SND_USB 115endif # SND_USB
118 116
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 7754a1034545..075195e8661a 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -104,6 +104,15 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
104 int err; 104 int err;
105 unsigned char data; 105 unsigned char data;
106 struct usb_device *dev = chip->dev; 106 struct usb_device *dev = chip->dev;
107 struct uac_clock_source_descriptor *cs_desc =
108 snd_usb_find_clock_source(chip->ctrl_intf, source_id);
109
110 if (!cs_desc)
111 return 0;
112
113 /* If a clock source can't tell us whether it's valid, we assume it is */
114 if (!uac2_control_is_readable(cs_desc->bmControls, UAC2_CS_CONTROL_CLOCK_VALID))
115 return 1;
107 116
108 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, 117 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
109 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 118 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
@@ -114,7 +123,7 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
114 if (err < 0) { 123 if (err < 0) {
115 snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n", 124 snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n",
116 __func__, source_id); 125 __func__, source_id);
117 return err; 126 return 0;
118 } 127 }
119 128
120 return !!data; 129 return !!data;
diff --git a/sound/usb/debug.h b/sound/usb/debug.h
index 343ec2d9ee66..58030176f008 100644
--- a/sound/usb/debug.h
+++ b/sound/usb/debug.h
@@ -8,7 +8,7 @@
8#ifdef HW_CONST_DEBUG 8#ifdef HW_CONST_DEBUG
9#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args) 9#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args)
10#else 10#else
11#define hwc_debug(fmt, args...) /**/ 11#define hwc_debug(fmt, args...) do { } while(0)
12#endif 12#endif
13 13
14#endif /* __USBAUDIO_DEBUG_H */ 14#endif /* __USBAUDIO_DEBUG_H */
diff --git a/sound/usb/format.c b/sound/usb/format.c
index f079b5e2ab28..8d042dce0d16 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -30,6 +30,7 @@
30#include "helper.h" 30#include "helper.h"
31#include "debug.h" 31#include "debug.h"
32#include "clock.h" 32#include "clock.h"
33#include "format.h"
33 34
34/* 35/*
35 * parse the audio format type I descriptor 36 * parse the audio format type I descriptor
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 6ec33b62e6cf..eab06edcc9b7 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1097,11 +1097,13 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1097 append_ctl_name(kctl, control == UAC_FU_MUTE ? 1097 append_ctl_name(kctl, control == UAC_FU_MUTE ?
1098 " Switch" : " Volume"); 1098 " Switch" : " Volume");
1099 if (control == UAC_FU_VOLUME) { 1099 if (control == UAC_FU_VOLUME) {
1100 kctl->tlv.c = mixer_vol_tlv;
1101 kctl->vd[0].access |=
1102 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
1103 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1104 check_mapped_dB(map, cval); 1100 check_mapped_dB(map, cval);
1101 if (cval->dBmin < cval->dBmax) {
1102 kctl->tlv.c = mixer_vol_tlv;
1103 kctl->vd[0].access |=
1104 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
1105 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1106 }
1105 } 1107 }
1106 break; 1108 break;
1107 1109
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 73dcc8256bc0..9146cffa6ede 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -61,6 +61,7 @@ static const struct rc_config {
61 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */ 61 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
62 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */ 62 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
63 { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */ 63 { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */
64 { USB_ID(0x041e, 0x30df), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */
64 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ 65 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
65}; 66};
66 67
@@ -188,6 +189,12 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
188 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, 189 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
189 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 190 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
190 !value, 0, NULL, 0, 100); 191 !value, 0, NULL, 0, 100);
192 /* USB X-Fi S51 Pro */
193 if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df))
194 err = snd_usb_ctl_msg(mixer->chip->dev,
195 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
196 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
197 !value, 0, NULL, 0, 100);
191 else 198 else
192 err = snd_usb_ctl_msg(mixer->chip->dev, 199 err = snd_usb_ctl_msg(mixer->chip->dev,
193 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, 200 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
@@ -234,9 +241,13 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
234 /* USB X-Fi S51 doesn't have a CMSS LED */ 241 /* USB X-Fi S51 doesn't have a CMSS LED */
235 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0) 242 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0)
236 continue; 243 continue;
244 /* USB X-Fi S51 Pro doesn't have one either */
245 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) && i == 0)
246 continue;
237 if (i > 1 && /* Live24ext has 2 LEDs only */ 247 if (i > 1 && /* Live24ext has 2 LEDs only */
238 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || 248 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
239 mixer->chip->usb_id == USB_ID(0x041e, 0x3042) || 249 mixer->chip->usb_id == USB_ID(0x041e, 0x3042) ||
250 mixer->chip->usb_id == USB_ID(0x041e, 0x30df) ||
240 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))) 251 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
241 break; 252 break;
242 err = snd_ctl_add(mixer->chip->card, 253 err = snd_ctl_add(mixer->chip->card,
@@ -512,6 +523,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
512 case USB_ID(0x041e, 0x3020): 523 case USB_ID(0x041e, 0x3020):
513 case USB_ID(0x041e, 0x3040): 524 case USB_ID(0x041e, 0x3040):
514 case USB_ID(0x041e, 0x3042): 525 case USB_ID(0x041e, 0x3042):
526 case USB_ID(0x041e, 0x30df):
515 case USB_ID(0x041e, 0x3048): 527 case USB_ID(0x041e, 0x3048):
516 err = snd_audigy2nx_controls_create(mixer); 528 err = snd_audigy2nx_controls_create(mixer);
517 if (err < 0) 529 if (err < 0)
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index c66d3f64dcf8..78792a8900c3 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -1651,6 +1651,32 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1651 } 1651 }
1652 } 1652 }
1653}, 1653},
1654{
1655 USB_DEVICE(0x0582, 0x0127),
1656 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1657 /* .vendor_name = "Roland", */
1658 /* .product_name = "GR-55", */
1659 .ifnum = QUIRK_ANY_INTERFACE,
1660 .type = QUIRK_COMPOSITE,
1661 .data = (const struct snd_usb_audio_quirk[]) {
1662 {
1663 .ifnum = 0,
1664 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1665 },
1666 {
1667 .ifnum = 1,
1668 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1669 },
1670 {
1671 .ifnum = 2,
1672 .type = QUIRK_MIDI_STANDARD_INTERFACE
1673 },
1674 {
1675 .ifnum = -1
1676 }
1677 }
1678 }
1679},
1654 1680
1655/* Guillemot devices */ 1681/* Guillemot devices */
1656{ 1682{
@@ -1953,7 +1979,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1953 } 1979 }
1954}, 1980},
1955{ 1981{
1956 USB_DEVICE(0x0763, 0x2080), 1982 USB_DEVICE_VENDOR_SPEC(0x0763, 0x2080),
1957 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1983 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1958 /* .vendor_name = "M-Audio", */ 1984 /* .vendor_name = "M-Audio", */
1959 /* .product_name = "Fast Track Ultra", */ 1985 /* .product_name = "Fast Track Ultra", */
@@ -2020,7 +2046,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2020 } 2046 }
2021}, 2047},
2022{ 2048{
2023 USB_DEVICE(0x0763, 0x2081), 2049 USB_DEVICE_VENDOR_SPEC(0x0763, 0x2081),
2024 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 2050 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
2025 /* .vendor_name = "M-Audio", */ 2051 /* .vendor_name = "M-Audio", */
2026 /* .product_name = "Fast Track Ultra 8R", */ 2052 /* .product_name = "Fast Track Ultra 8R", */
@@ -2179,6 +2205,17 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2179 } 2205 }
2180}, 2206},
2181 2207
2208/* KORG devices */
2209{
2210 USB_DEVICE_VENDOR_SPEC(0x0944, 0x0200),
2211 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
2212 .vendor_name = "KORG, Inc.",
2213 /* .product_name = "PANDORA PX5D", */
2214 .ifnum = 3,
2215 .type = QUIRK_MIDI_STANDARD_INTERFACE,
2216 }
2217},
2218
2182/* AKAI devices */ 2219/* AKAI devices */
2183{ 2220{
2184 USB_DEVICE(0x09e8, 0x0062), 2221 USB_DEVICE(0x09e8, 0x0062),
@@ -2332,6 +2369,12 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2332 2369
2333/* Native Instruments MK2 series */ 2370/* Native Instruments MK2 series */
2334{ 2371{
2372 /* Komplete Audio 6 */
2373 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
2374 .idVendor = 0x17cc,
2375 .idProduct = 0x1000,
2376},
2377{
2335 /* Traktor Audio 6 */ 2378 /* Traktor Audio 6 */
2336 .match_flags = USB_DEVICE_ID_MATCH_DEVICE, 2379 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
2337 .idVendor = 0x17cc, 2380 .idVendor = 0x17cc,
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 1b94ec3a3368..bd13d7257240 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -540,6 +540,7 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
540 /* Access Music VirusTI Desktop */ 540 /* Access Music VirusTI Desktop */
541 return snd_usb_accessmusic_boot_quirk(dev); 541 return snd_usb_accessmusic_boot_quirk(dev);
542 542
543 case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */
543 case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */ 544 case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
544 case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */ 545 case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
545 return snd_usb_nativeinstruments_boot_quirk(dev); 546 return snd_usb_nativeinstruments_boot_quirk(dev);